Precompute Display List Size
Precompute Display List Size
Short story: I'd like to precompute the size of the display list so it is always the appropriate size given a static set of vertices and their format. The display list contains only vertex data, no state changes. I can't find any documentation on the proper way to compute a display list's size, so I'm asking here.
I've read that GX_EndDispList() will return the actual size of the display list, which is then passed on to GX_CallDispList(). So far, so good, but it can return 0, indicating that the display list was too small. Since I know how many vertices and all of the attributes and their sizes, I'd like to precompute the size of a display list so that it will never return 0, but not overallocate by blindly just allocating large chunks memory or "guess" the size and redo the display list until it is the right size, etc.
Just by reading libogc/gx.c, I think the following functions have the following byte sizes when placed in a display list:
GX_Begin(): 3 bytes
GX_End(): 0 (no-op)
GX_Position3f32(): 12 bytes (3x 32-bit floats)
GX_Position2f32(): 8 bytes (2x 32-bit floats)
... follows same general pattern based on datatype ...
I see "the display buffer should be at least 32 bytes larger than the maximum expected amount." Ok, so size += 32. Then, is the appropriate formula:
displayListSize = vertexSize * vertexCount + 32 + 3
...where vertexSize is the size of all of the per-vertex attributes (position, color, texcoords, etc)?
I've read that GX_EndDispList() will return the actual size of the display list, which is then passed on to GX_CallDispList(). So far, so good, but it can return 0, indicating that the display list was too small. Since I know how many vertices and all of the attributes and their sizes, I'd like to precompute the size of a display list so that it will never return 0, but not overallocate by blindly just allocating large chunks memory or "guess" the size and redo the display list until it is the right size, etc.
Just by reading libogc/gx.c, I think the following functions have the following byte sizes when placed in a display list:
GX_Begin(): 3 bytes
GX_End(): 0 (no-op)
GX_Position3f32(): 12 bytes (3x 32-bit floats)
GX_Position2f32(): 8 bytes (2x 32-bit floats)
... follows same general pattern based on datatype ...
I see "the display buffer should be at least 32 bytes larger than the maximum expected amount." Ok, so size += 32. Then, is the appropriate formula:
displayListSize = vertexSize * vertexCount + 32 + 3
...where vertexSize is the size of all of the per-vertex attributes (position, color, texcoords, etc)?
Re: Precompute Display List Size
Rather than calculate it manually, run it once with a large preallocated list and check the size returned by GX_EndDispList. Then reduce the preallocated size to match.
Re: Precompute Display List Size
Eh, I'd rather not playing guessing games. The GameCube has 24MB of RAM, and I don't want to fragment the heap unnecessarily. In fact, I'd like to have a fixed region of memory, say a few MB, and use that solely as a geometry cache in a streaming engine architecture. This means I will make 1 call to malloc() and then none after it. Because I would be managing the memory myself, I would need to know the size of a display list ahead of time to see whether I need to evict geometry from the cache or simply pick a region.
I've found that the above equation nearly works, but modifying it so it rounds up to the nearest 32 bytes seems to do it, i.e:
Still, this "just works" -- it isn't based on any documentation or hardware probing, just an absolutely random guess based on the hardware's love for 32-byte aligned/multiple buffers. I wish there was more information about simple stuff like this -- the API is cryptic enough as is.
I've found that the above equation nearly works, but modifying it so it rounds up to the nearest 32 bytes seems to do it, i.e:
Code: Select all
guessSize = aboveEquation();
guessSize = (guessSize & 0x1F) + 32;
Still, this "just works" -- it isn't based on any documentation or hardware probing, just an absolutely random guess based on the hardware's love for 32-byte aligned/multiple buffers. I wish there was more information about simple stuff like this -- the API is cryptic enough as is.
Re: Precompute Display List Size
I don't think you understood what I meant. If your display lists are static, run your program once to find the required size then hardcode that size into the source and recompile. This takes the guesswork out of manually counting the byte size of the static lists.
Re: Precompute Display List Size
Yes, the final display list buffer needs to be rounded up to the nearest 32-byte boundary. Pretty much any access by the GP to main memory needs this alignment, so you'll see it often. Also make sure your buffer gets flushed out to RAM.figgles wrote:I've found that the above equation nearly works, but modifying it so it rounds up to the nearest 32 bytes seems to do it, i.e:
Code: Select all
guessSize = aboveEquation(); guessSize = (guessSize & 0x1F) + 32;
Still, this "just works" -- it isn't based on any documentation or hardware probing, just an absolutely random guess based on the hardware's love for 32-byte aligned/multiple buffers. I wish there was more information about simple stuff like this -- the API is cryptic enough as is.
Re: Precompute Display List Size
This is totally wrong. guessSize will always be between 32-63 with this code. I think you're looking for this to round up to the next 32-bytes-alignment:figgles wrote:I've found that the above equation nearly works, but modifying it so it rounds up to the nearest 32 bytes seems to do it, i.e:
Code: Select all
guessSize = aboveEquation(); guessSize = (guessSize & 0x1F) + 32;
Code: Select all
guessSize = aboveEquation();
guessSize = (guessSize + 0x1F) & (~0x1F);
Code: Select all
guessSize = aboveEquation();
char* myFreeablePointer = malloc(guessSize + 32);
char* myAlignedPointer = (myFreeablePointer + 0x1F) & (~0x1F);
Re: Precompute Display List Size
The easier way to get aligned memory is to use memalign instead of malloc.
Who is online
Users browsing this forum: No registered users and 1 guest