Here’s a small program that demonstrates the bug. I realize that populating a PBO and immediately using it is not ideal. However, the performance I’m seeing has got to be a bug. If I don’t use a PBO, then the texture subload is lightning fast. With a PBO, it’s taking 16 ms for 8 bytes of data. Larger mipmaps take over 100 ms. I tried the latest beta driver too.
#define GL_GLEXT_PROTOTYPES 1
#include <GL/glut.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <GL/glext.h>
#include <sys/time.h>
using namespace std;
static GLuint bind_name;
void draw(void)
{
static GLuint pbo_handle;
static GLsizeiptr pbo_size = 8;
GLsizeiptr subload_size = 8;
unsigned char subload_buf[8] = {0};
if ( pbo_handle == 0 )
glGenBuffers( 1, &pbo_handle );
// Bind PBO
glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, pbo_handle );
// Bind Texture
glBindMultiTextureEXT ( GL_TEXTURE0, GL_TEXTURE_2D_ARRAY, bind_name ) ;
pbo_size = std::max( pbo_size, subload_size );
glBufferData( GL_PIXEL_UNPACK_BUFFER_ARB, pbo_size, 0,
GL_STREAM_DRAW );
glBufferSubData( GL_PIXEL_UNPACK_BUFFER_ARB, 0, subload_size,
subload_buf);
glFinish();
timeval tv ;
gettimeofday ( & tv, NULL ) ;
double start = (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0 ;
glCompressedTextureSubImage3DEXT( bind_name, GL_TEXTURE_2D_ARRAY, 9, 0, 0,
999, 1, 1, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8, subload_buf);
gettimeofday ( & tv, NULL ) ;
double end = (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0 ;
std::cout << "Why is this taking so long?: " << (end - start)*1000.0 << " ms" <<endl;
// Unbind PBO
glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
glutPostRedisplay();
}
void
display(void)
{
draw();
glutSwapBuffers();
}
void
init(void)
{
cout << glGetString(GL_VERSION) <<endl;
glGenTextures(1, &bind_name);
glBindMultiTextureEXT ( GL_TEXTURE0, GL_TEXTURE_2D_ARRAY, bind_name ) ;
int size[] = { 8000, 8000, 8000, 32000, 128000, 512000, 2048000, 8192000, 32768000, 131072000 };
for ( int i = 0; i < 10; ++i )
glCompressedTextureImage3DEXT( bind_name, GL_TEXTURE_2D_ARRAY, i,
GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 512>>i, 512>>i, 1000, 0, size[9-i], 0);
}
int
main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(640, 480);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Terrible Driver Bug");
glutDisplayFunc(display);
init();
glutMainLoop();
return 0;
}