opengl batch size memory limit?

according this this opengl documentation 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
",
        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
",
        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
",
        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
",
        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?

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.

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).

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
", tag);
        if (err == GL_INVALID_ENUM) printf("invalid enum
");
        if (err == GL_INVALID_VALUE) printf("invalid VALUE
");
        if (err == GL_INVALID_OPERATION) printf("invalid OPERATION
");
        if (err == GL_STACK_OVERFLOW) printf("invalid stack overflow
");
        if (err == GL_STACK_UNDERFLOW) printf("invalid stack underflow
");
        if (err == GL_OUT_OF_MEMORY) printf("invalid out of mem
");
        if (err == GL_INVALID_FRAMEBUFFER_OPERATION) printf("invalid ifbo
");
        if (err == GL_TABLE_TOO_LARGE) printf("invalid table too large
");
    }
}

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.