Texture Range Readme
---------------------------------------------------

This demo show the fundimental techniques required to fast texture upload performance:

This is an updated and improved version of the texture range demo.

There are 3 levels of optimization to implement to get the full benefit.  Depending on what you're looking to do you can get anywhere from a 70% performance boost to a 800% performance boost.  The first optimization is good for anything you're doing, the second two are only of non-power of two textures.

1) Using GL_UNPACK_CLIENT_STORAGE_APPLE

This sequence should get you a ~70% texture performance improvement because this eliminates one data copy.  Beware of of the fact that this tells OpenGL to use the app copy of the data.  So don't trash your copy until you've deleted the texture from OpenGL.

Create the texture with:

glBindTextures( target, &texID);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image_ptr);

Update the texture with:

glTexSubImage2D(target, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image_ptr);

2) Enabling GL_TEXTURE_RECTANGLE_EXT.  This will allow you to draw non-power of two textures.  Be aware that using non-power of two textures also changes the textures coords from normalized coords to pixel coords.  Make sure you check for the GL_TEXTURE_RECTANGLE_EXT extension before enabling.  The Rage128 doesn't fulling support this extension.  I'm working to add some code to the attached demo to show how to best optimize on the Rage128.

Create the texture with:

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, &texID);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image_ptr);

Update the texture with:

glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image_ptr);

3) Texture Range.  This is a hint to OpenGL telling the system that you want VRAM or AGP texturing. Set the GL_TEXTURE_STORAGE_HINT_APPLE to GL_STORAGE_CACHED_APPLE or GL_STORAGE_SHARED_APPLE for requesting VRAM or AGP texturing respectively.  GL_STORAGE_PRIVATE_APPLE is the default and specifies OpenGL normal texuring path.  Additionally, you can use glTextureRangeAPPLEto specify an area of memory to be mapped vice each individual texture.  This is useful for tiled or multiple textures in contiguous memory.

Create the texture with:

glBindTexture(GL_TEXTURE_RECTANGLE_EXT, &texID);
if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, IMAGE_COUNT * width * height * (IMAGE_DEPTH >> 3), image_ptr);
else glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, 0, NULL);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_CACHED_APPLE);
glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, 1);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image_ptr);

Update the texture with:

glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, image_ptr);

With all 3 of these options correctly managed, what you get is async AGP/PCI DMA transfers straight from your memory to texture memory.  Meaning that the driver never touches the pixels with the CPU.
