Multi-threaded usage of OSMesaContext

Jacek Blumenfeld <[email protected]>
Newsgroups gmane.comp.video.mesa3d.user
Message-ID <CAF=2CiAST6=zduMcMoFFtM1dL-ri2yeZAxoaqcE3bba72HtREg@mail.gmail.com>
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

_______________________________________________
mesa-users mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.