[Mesa-users] Multi-threaded usage of OSMesaContext

Jacek Blumenfeld jacek.blumenfeld at gmail.com
Fri Apr 8 13:30:22 UTC 2016


Hi,

I'm testing two builds of mesa 11.2.0-rc-4 with scons options:
scons build=debug libgl-gdi osmesa (llvmpipe)
scons build=debug openmp=yes llvm=no (softpipe)

I'm trying to run osmesa rendering in parallel with openMP. For both
methods I'm creating a vector of osmesa contexts (based on  mt_osdemo.c
<http://www.tux.org/pub/x/mesa/beta/MesaCVS/mtdemos/mt_osdemo.c>):

for (size_t i=0; i<MAXTHREADS; i++)
 {
/* create the OS Mesa contexts and result buffers */
ctx[i] = OSMesaCreateContextExt( OSMESA_RGBA, 8, 8, 8, NULL );
buffers[i] = calloc(Width * Height * 4, sizeof(GLubyte));
}

I'm binding buffer to context and render images in parallel as follow
(openmp case):

#pragma omp parallel for
for(int i = 0; i < MAXTHREADS; ++i)
{
if (!OSMesaMakeCurrent(ctx[i], buffers[i], GL_UNSIGNED_BYTE, 512, 512))
{
printf("OSMesaMakeCurrent failed!\n");
}
render_image();
}
As a results only random buffers contains rendered data (proper) and rest
of them are blank.
Do you have any ideas what may be wrong? Is it possible to use
OSMesaContexts in parallel?



//*********************************//
//                 Main openmp     //
//*********************************//

#define MAXTHREADS 8

void * buffers[MAXTHREADS]; /* these are the different result buffers */
OSMesaContext ctx[MAXTHREADS]; /* and these the used contexts */

int main(int argc, char *argv[])
{
char *filename = NULL;
if (argc < 2) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, "  osdemo filename [width height]\n");
return 0;
}

filename = argv[1];
if (argc == 4) {
Width = atoi(argv[2]);
Height = atoi(argv[3]);
}

for (size_t i=0; i<MAXTHREADS; i++) {
/* create the OS Mesa contexts and result buffers */
ctx[i] = OSMesaCreateContextExt( OSMESA_RGBA, 8, 8, 8, NULL );
//buffers[i] = calloc(Width * Height * 4, sizeof(GLubyte));
buffers[i] = malloc(Width * Height * 4 * sizeof(GLubyte));
}
#pragma omp parallel for
for(int i = 0; i < MAXTHREADS; ++i)
{
if (!OSMesaMakeCurrent(ctx[i], buffers[i], GL_UNSIGNED_BYTE, 512, 512))
{
printf("OSMesaMakeCurrent failed!\n");
}
render_image();
}
for (size_t i=0; i<MAXTHREADS; i++) {
OSMesaDestroyContext( ctx[i]);
free(buffers[i]);
}
return 0;
}


//*********************************//
//       Render functions          //
//*********************************//

static void render_image(void)
{
   GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
   GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
   GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
   GLfloat red_mat[]   = { 1.0, 0.2, 0.2, 1.0 };
   GLfloat green_mat[] = { 0.2, 1.0, 0.2, 1.0 };
   GLfloat blue_mat[]  = { 0.2, 0.2, 1.0, 1.0 };

   glViewport(0, 0, 512, 512);

   glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
   glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
   glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
   glLightfv(GL_LIGHT0, GL_POSITION, light_position);

   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(-2.5, 2.5, -2.5, 2.5, -10.0, 10.0);
   glMatrixMode(GL_MODELVIEW);

   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

   glPushMatrix();
   glRotatef(20.0, 1.0, 0.0, 0.0);

   glPushMatrix();
   glTranslatef(-0.75, 0.5, 0.0);
   glRotatef(90.0, 1.0, 0.0, 0.0);
   glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red_mat );
   Torus(0.275, 0.85, 20, 20);
   glPopMatrix();

   glPopMatrix();
   glFinish();
}

static void Torus(float innerRadius, float outerRadius, int sides, int
rings)
{
   /* from GLUT... */
   int i, j;
   GLfloat theta, phi, theta1;
   GLfloat cosTheta, sinTheta;
   GLfloat cosTheta1, sinTheta1;
   const GLfloat ringDelta = 2.0 * M_PI / rings;
   const GLfloat sideDelta = 2.0 * M_PI / sides;

   theta = 0.0;
   cosTheta = 1.0;
   sinTheta = 0.0;
   for (i = rings - 1; i >= 0; i--) {
      theta1 = theta + ringDelta;
      cosTheta1 = cos(theta1);
      sinTheta1 = sin(theta1);
      glBegin(GL_QUAD_STRIP);
      phi = 0.0;
      for (j = sides; j >= 0; j--) {
         GLfloat cosPhi, sinPhi, dist;

         phi += sideDelta;
         cosPhi = cos(phi);
         sinPhi = sin(phi);
         dist = outerRadius + innerRadius * cosPhi;

         glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
         glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, innerRadius *
sinPhi);
         glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
         glVertex3f(cosTheta * dist, -sinTheta * dist,  innerRadius *
sinPhi);
      }
      glEnd();
      theta = theta1;
      cosTheta = cosTheta1;
      sinTheta = sinTheta1;
   }
}

-- 
Pozdrawiam
Jacek Blumenfeld
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/mesa-users/attachments/20160408/81c75099/attachment.html>


More information about the mesa-users mailing list