[Mesa-dev] R600 tiling halves the frame rate

Matt Turner mattst88 at gmail.com
Sat Oct 27 19:37:10 PDT 2012


On Sat, Oct 27, 2012 at 4:51 PM, Tzvetan Mikov <tmikov at jupiter.com> wrote:
> On 10/26/2012 08:45 PM, Jerome Glisse wrote:
>>> This is interesting. All I am doing is rotating a big texture on the
>>> screen. I am using EGL+Gallium, so it is as simple as it gets.
>>>
>>> The hack I am using to disable texture tiling is also extremely simple
>>> (see below). It speeds up the FPS measurably, up to the extreme
>>> case of doubling it on HD6460.
>>>
>>> What am I missing?
>>>
>>> Regards,
>>> Tzvetan
>>>
>>
>> Could you provide a simple gl demo or point to one that shows the same
>> behavior with your patch. So i have something to know if i am
>> reproducing or not
>>
>> Cheers,
>> Jerome
>>
>
> The source of my test app is included below.
>
> thanks!
> Tzvetan
>
> #include <EGL/egl.h>
> #include <EGL/eglmesaext.h>
> #include <GL/gl.h>
>
> #include <stdio.h>
> #include <string.h>
> #include <sys/time.h>
> #include <stdint.h>
> #include <err.h>
> #include <unistd.h>
> #include <assert.h>
> #include <stdarg.h>
> #include <stdlib.h>
>
> #define NELEM(x)  (sizeof(x) / sizeof((x)[0]))
>
> #define TW 1024
> #define TH  768
>
> static GLubyte texImg[TH][TW][4];
> static GLuint texName;
>
> static void makeTexImg ()
> {
>   for ( int i = 0; i < TH; ++i )
>     for ( int j = 0; j < TW; ++j )
>     {
>       int c = (((i&8)==0) ^ ((j&8)==0)) * 255;
>       texImg[i][j][0] = 0;
>       texImg[i][j][1] = (GLubyte)c;
>       texImg[i][j][2] = 0;
>       texImg[i][j][3] = 255;
>     }
> }
>
> static void init ()
> {
>   makeTexImg();
>
>   glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
>   glPixelStorei( GL_UNPACK_ROW_LENGTH, TW );
>   glGenTextures( 1, &texName );
>   glBindTexture( GL_TEXTURE_2D, texName );
>
>   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
>   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
>   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
>   glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
>
>   glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, TW, TH, 0, GL_RGBA,
> GL_UNSIGNED_BYTE, texImg );
>
>   glClearColor( 0, 0, 0, 0 );
>   glShadeModel( GL_FLAT );
>   glEnable( GL_DEPTH_TEST );
> }
>
> static void reshape ( int w, int h )
> {
>   glViewport( 0, 0, (GLsizei)w, (GLsizei)h );
>   glMatrixMode( GL_PROJECTION );
>   glLoadIdentity();
>   glOrtho( 0, 1, 0, 1, -1, 1 );
>   glMatrixMode( GL_MODELVIEW );
>   glLoadIdentity();
> }
>
> static void rect ()
> {
>   glBegin( GL_QUADS );
>     glTexCoord2f( 0, 1 ); glVertex3f( 0, 0, 0.0 );
>     glTexCoord2f( 1, 1 ); glVertex3f( 1, 0, 0.0 );
>     glTexCoord2f( 1, 0 ); glVertex3f( 1, 1, 0.0 );
>     glTexCoord2f( 0, 0 ); glVertex3f( 0, 1, 0.0 );
>   glEnd();
> }
>
> static void display ( float angle )
> {
>   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
>   glEnable( GL_TEXTURE_2D );
>   glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
>   glBindTexture( GL_TEXTURE_2D, texName );
>
>   glMatrixMode( GL_MODELVIEW );
>   glLoadIdentity();
>   glPushMatrix();
>
>   glTranslatef( 0.1, 0.1, 0 );
>   glScalef( 0.8, 0.8, 1 );
>   rect();
>
>   glPopMatrix();
>
>   glTranslatef(  0.1,  0.1, 0 );
>   glTranslatef(  0.4,  0.4, 0 );
>   glRotatef( angle, 0, 0, 1 );
>   glTranslatef( -0.4, -0.4, 0 );
>   glScalef( 0.8, 0.8, 1 );
>   glTranslatef( 0, 0, -0.2 );
>   rect();
> }
>
> static void errEgl ( int code, const char * msg, ... )
> {
>   va_list ap;
>   EGLint err = eglGetError();
>   va_start( ap, msg );
>   vfprintf( stderr, msg, ap );
>   fprintf( stderr, ": EGL error %d\n", (int)err );
>   va_end( ap );
>   exit( code );
> }
>
> static uint32_t getTickMs ()
> {
>   struct timeval tv;
>   gettimeofday( &tv, NULL );
>   return tv.tv_sec * 1000 + tv.tv_usec/1000;
> }
>
> int main(int argc, char** argv)
> {
>   EGLDisplay dpy = eglGetDisplay( EGL_DEFAULT_DISPLAY );
>   assert( dpy );
>
>   EGLint major, minor;
>
>   if (!eglInitialize( dpy, &major, &minor ))
>     errEgl( 1, "eglInitialize" );
>
>   printf( "EGL version = %d.%d\n", major, minor );
>   printf( "EGL_VENDOR = %s\n", eglQueryString( dpy, EGL_VENDOR ) );
>   if (!strstr( eglQueryString( dpy, EGL_EXTENSIONS
> ),"EGL_MESA_screen_surface"))
>     errEgl( 1, "EGL_MESA_screen_surface is not supported" );
>
>   EGLConfig configs[32];
>   EGLint numConfigs;
>
>   if (!eglGetConfigs( dpy, configs, NELEM(configs), &numConfigs ))
>     errEgl( 1, "eglGetConfigs" );
>
>
>   EGLScreenMESA screens[16];
>   EGLint numScreens;
>   if (!eglGetScreensMESA( dpy, screens, NELEM(screens), &numScreens ))
>     errEgl( 1, "eglGetScreensMESA" );
>
>   EGLModeMESA modes[16];
>   EGLint numModes;
>   if (!eglGetModesMESA( dpy, screens[0], modes, NELEM(modes), &numModes ))
>     errEgl( 1, "eglGetModesMESA" );
>
>   if (!eglBindAPI( EGL_OPENGL_API ))
>     errEgl( 1, "eglBindAPI" );
>
>   EGLContext ctx;
>   if ( (ctx = eglCreateContext( dpy, configs[0], NULL, NULL )) ==
> EGL_NO_CONTEXT)
>     errEgl( 1, "eglCreateContext" );
>
>   EGLint attribs[32], * pa;
>   pa = attribs;
>
>   *pa++ = EGL_WIDTH;
>   eglGetModeAttribMESA( dpy, modes[0], EGL_WIDTH, pa++ );
>   *pa++ = EGL_HEIGHT;
>   eglGetModeAttribMESA( dpy, modes[0], EGL_HEIGHT, pa++ );
>   *pa++ = EGL_NONE;
>
>   EGLSurface screenSurf;
>   if ( (screenSurf = eglCreateScreenSurfaceMESA( dpy, configs[0],
> attribs )) == EGL_NO_SURFACE)
>     errEgl( 1, "eglCreateScreenSurfaceMESA" );
>   eglSurfaceAttrib( dpy, screenSurf, EGL_SWAP_BEHAVIOR,
> EGL_BUFFER_DESTROYED );
>
>   if (!eglShowScreenSurfaceMESA( dpy, screens[0], screenSurf, modes[0] ))
>     errEgl( 1, "eglShowScreenSurfaceMESA" );
>
>   if (!eglMakeCurrent( dpy, screenSurf, screenSurf, ctx ))
>     errEgl( 1, "eglMakeCurrent" );
>
>   init();
>   reshape( attribs[1], attribs[3] );
>   eglSwapInterval( dpy, 0 );
>
>   unsigned cnt = 0;
>   uint32_t t1 = getTickMs();
>
>   for ( float angle = 0; ; angle += 0.5 )
>   {
>     if (angle >= 360)
>       angle -= 360;
>
>     display( angle );
>     glFlush();
>     eglSwapBuffers( dpy, screenSurf );

Do you actually need glFlush()?

It might be a case of
http://www.opengl.org/wiki/Common_Mistakes#glFinish_and_glFlush

>
>     ++cnt;
>     uint32_t t = getTickMs() - t1;
>     if (t >= 5000)
>     {
>       printf( "FPS=%u\n", cnt * 1000 / t );
>       t1 = getTickMs();
>       cnt = 0;
>     }
>   }
>
>   eglDestroyContext( dpy, ctx );
>   eglTerminate( dpy );
>
>   return 0;
> }


More information about the mesa-dev mailing list