PDA

View Full Version : opengl batch size memory limit?



blubee
01-14-2016, 08:06 PM
according this this opengl documentation (https://www.opengl.org/wiki/Vertex_Specification_Best_Practices) an optimal batch size can be anywhere from 1-4 mb.

I currently have 3 vbo one for vertex, one for color and one for indices.

I can make one draw call and fit 16,000 sprites on my machine and it renders smoothly at 60fps. I am using opengl debugging tools to watch my fps.



printf(
"size of:%d sprites * %d bytes per sprite for vertex total:%d bytes\n",
sc, cg_sprite_get_sizeof_vert(), (sc * cg_sprite_get_sizeof_vert()));
printf(
"size of:%d sprites * %d bytes per sprite for color total:%d bytes\n",
sc, cg_sprite_get_sizeof_col(), (sc * cg_sprite_get_sizeof_col()));
printf(
"size of:%d sprites * %d bytes per sprite for textures total:%d "
"bytes\n",
sc, cg_sprite_get_sizeof_tex_coord(),
(sc * cg_sprite_get_sizeof_tex_coord()));
printf(
"size of:%d sprites * %d bytes per sprite for indices total:%d bytes\n",
sc, cg_sprite_get_sizeof_ind(), (sc * cg_sprite_get_sizeof_ind()));

sc = number of sprites, The above code output this result:


size of:16000 sprites * 48 bytes per sprite for vertex total:768000 bytes
size of:16000 sprites * 64 bytes per sprite for color total:1024000 bytes
size of:16000 sprites * 32 bytes per sprite for textures total:512000 bytes
size of:16000 sprites * 12 bytes per sprite for indices total:192000 bytes


now rendering up to 16,000 sprites in 1 draw call coming in at about 2.5mb works just fine.

If I go up to 17,000 nothing gets rendered at all:

size of:17000 sprites * 48 bytes per sprite for vertex total:816000 bytes
size of:17000 sprites * 64 bytes per sprite for color total:1088000 bytes
size of:17000 sprites * 32 bytes per sprite for textures total:544000 bytes
size of:17000 sprites * 12 bytes per sprite for indices total:204000 bytes


I am unsure why?

my gpu device is

lspci -v -s 01:0.0
01:00.0 VGA compatible controller: NVIDIA Corporation GK107M [GeForce GT 750M Mac Edition] (rev a1) (prog-if 00 [VGA controller])
Subsystem: Apple Inc. Device 0130
Flags: bus master, fast devsel, latency 0, IRQ 39
Memory at c0000000 (32-bit, non-prefetchable) [size=16M]
Memory at 80000000 (64-bit, prefetchable) [size=256M]
Memory at 90000000 (64-bit, prefetchable) [size=32M]
I/O ports at 1000 [size=128]
[virtual] Expansion ROM at c1000000 [disabled] [size=512K]
Capabilities: <access denied>
Kernel driver in use: nvidia


and while I am developing this more for mobile than desktop, I though I should be able to push more sprites per draw call.
Is it just a matter of leaving the max sprite count at 16,000 and doing multiple draw calls if I would like to draw more than 16,000 sprites?

GClements
01-14-2016, 09:44 PM
now rendering up to 16,000 sprites in 1 draw call coming in at about 2.5mb works just fine.

If I go up to 17,000 nothing gets rendered at all:

I am unsure why?

You're using GLshort (16 bits) for the vertex indices, which limits you to 65536 vertices (16384 quads). I wouldn't expect exceeding that value to result in getting nothing, though; it should just cause the first quads to be drawn again instead of the later quads.



Is it just a matter of leaving the max sprite count at 16,000 and doing multiple draw calls if I would like to draw more than 16,000 sprites?


You could use GLuint (and GL_UNSIGNED_INT) for indices, but it's not going to hurt performance if you split it into multiple draw calls (not like using a draw call per quad would).

As for memory consumption: I'd suggest using GLubyte for vertex colours rather than GL_float. And either GLubyte or GLushort for texture coordinates. Using GLshort for the vertex positions may suffice (although the cost of the float-to-int conversions may exceed the cost of transferring the extra data).

blubee
01-14-2016, 10:59 PM
rendering 16385 - 9 quads you are right, the first ones disappear and the additional ones drawn at the end. I stopped checking at 16388, although if I jump up to 17,000 draws it just draws a blank screen and no errors reporting.

I use this function to check for errors in my rendering loop:


void debug_opengl(char* tag) {
GLenum err = GL_NO_ERROR;
while ((err = glGetError()) != GL_NO_ERROR) {
printf("%s\n", tag);
if (err == GL_INVALID_ENUM) printf("invalid enum\n");
if (err == GL_INVALID_VALUE) printf("invalid VALUE\n");
if (err == GL_INVALID_OPERATION) printf("invalid OPERATION\n");
if (err == GL_STACK_OVERFLOW) printf("invalid stack overflow\n");
if (err == GL_STACK_UNDERFLOW) printf("invalid stack underflow\n");
if (err == GL_OUT_OF_MEMORY) printf("invalid out of mem\n");
if (err == GL_INVALID_FRAMEBUFFER_OPERATION) printf("invalid ifbo\n");
if (err == GL_TABLE_TOO_LARGE) printf("invalid table too large\n");
}
}


I think I will use the GLubyte for vertex colors since they shouldn't be larger than 255.
The texture coordinate's i'll leave that decision for a bit later since I will be making sprite atlas and I am not sure about the max size just yet.