[Mesa-dev] R600 tiling halves the frame rate

Tzvetan Mikov tmikov at jupiter.com
Sat Oct 27 16:51:11 PDT 2012


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

    ++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