3 Replies Latest reply on Mar 3, 2014 2:29 AM by user_ch

    AMD_GPU_association

    abholografika
      GPU association works strange on disabled devices, and when used in a single CPU thread.

      Dear All,

      My company has recently purchased a pair of ATI 5870 Eyefinity six cards from ASUS. I wanted to utilize WGL_AMD_gpu_association to leverage the computations required for us to get the correct image for all outputs. I am using Windows 7 x64 with the 10.7 driver suite. I was successful, but there are some things I do not understand.

      1. If I do not enable any graphics outputs on my secondary card, it's state becomes disabled in the catalyst control center. However wglGetGPUIDsAMD will enumerate it, but fails to create an associated context on it. Calling wglCreateAssociatedContextAMD with it's GPU ID returns 0, but GetLastError also returns 0. I think this is not working according to specs.
      2. I have created a small application that renders to an associated context on the second card and blits it to the first card. I have found the following problems:
      When I use wglBlitContextFramebufferAMD the call sometimes starts to block indefinitely causing the program to hang. Even if I use one of glFlush or glFinish to wait for command completion. (glWaitClientSync is not an option, as I am currently running on a single thread.) However if I call glReadPixels immediately before calling blit it works even if I just read a single pixel. Does the rendering for the associated context and the real context need to be in separate CPU threads? If so shouldn't this be stated in the extension specs?

       

      Any answer to these questions would be really appreciated. If necessary, I can also send you some source code.

       

      Best regards,

             Attila Barsi

        • AMD_GPU_association
          abholografika

          Dear All,

           

          I have also implemented this algorithm with 2 threads. I am protecting the rendering with 2 semaphores and a sync object. The same problem persists. If I don't call glReadPixels, the blit operation hangs. Any ideas?

           

          Best regards,

              Attila Barsi

            • AMD_GPU_association
              abholografika

              Dear All,

               

              I will include some source code, maybe someone will see an error that way. HoloSDK::GLFrameBuffer is a wrapper class for FBO functionality.

               

              Initialization:

              //------------------------------------------------------

                  glewInit();
                  glDisable(GL_DEPTH_TEST);
                  glMatrixMode(GL_MODELVIEW);
                  glLoadIdentity();

                  spheresList = glGenLists(1);

                  glNewList(spheresList,GL_COMPILE);

                  glutSolidSphere(1,400,400);

                  glEndList();

                  HGLRC currentContext = wglGetCurrentContext();

                  HDC currentDC = wglGetCurrentDC();

                  wglMakeCurrent(currentDC,currentContext);


                  framebufferMaster = new HoloSDK::GLFrameBuffer;

                  HoloSDK::GLFrameBuffer::BufferDeclaration declaration;

                  HoloSDK::GLFrameBuffer::BufferData colorBuffer;

                  colorBuffer.format = 4;

                  colorBuffer.textureTarget = GL_TEXTURE_2D;

                  colorBuffer.usage = HoloSDK::GLFrameBuffer::Usage_ColorBuffer0;

                  HoloSDK::GLFrameBuffer::BufferData depthBuffer;

                  depthBuffer.format = GL_DEPTH_COMPONENT24;

                  depthBuffer.textureTarget = GL_TEXTURE_2D;

                  depthBuffer.usage = HoloSDK::GLFrameBuffer::Usage_Depth;

                  declaration.push_back(colorBuffer);

                  declaration.push_back(depthBuffer);

                  bool framebufferMasterCreated = framebufferMaster->Create(512,512,declaration);

                  glClearColor(0,1,0,0);

                  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

                  UINT currentGPUId = wglGetContextGPUIDAMD(currentContext);

                  UINT offscreenGPUId = gpuIDs[0];

                  if(currentGPUId == gpuIDs[0])
                  {
                      offscreenGPUId = gpuIDs[1];
                  }

                  associatedContext = wglCreateAssociatedContextAMD(offscreenGPUId);

                  associatedContextRunnable = new  AssociatedContextRunnable(associatedContext,currentContext);

                  associatedContextThread = new HoloSDK::Thread(*associatedContextRunnable);

                  BOOL makeCurrentSuccess = wglMakeAssociatedContextCurrentAMD(associatedContext);

                  framebufferSlave = new HoloSDK::GLFrameBuffer;

                  bool framebufferSlaveCreated = framebufferSlave->Create(512,512,declaration);

                  //Render smthg.

                  framebufferSlave->Bind();

                  glClearColor(1,0,0,0);

                  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

                  makeCurrentSuccess = wglMakeAssociatedContextCurrentAMD(0);


                  bool associatedContextThreadStarted = associatedContextThread->Start();

              //------------------------------------------------------

              Render code running on the primary card's thread.

              //------------------------------------------------------

                  glClearColor(0,0,1,1);

                  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

                

                  glMatrixMode(GL_PROJECTION);

                  glLoadIdentity();

                  glFrustum(-10,10,-10,10,0.1,100);

                  glMatrixMode(GL_MODELVIEW);

                  glLoadIdentity();

                  glTranslatef(0,0,-2);


                     
                  for(int i = -2; i <2;i++)
                  {
                         for(int j = -10; j <10;j++)
                        {

                              glColor3f((i+50)/100.0f,(j+50)/100.0f,0);

                              glPushMatrix();
                              glTranslatef(4*j,4*i,0);
                              glCallList(spheresList);

                             glPopMatrix();
                       }
                   }
                 

                  associatedContextRunnable->masterReady();

                  associatedContextRunnable->waitSlaveReady();

                  glutSwapBuffers();

              //------------------------------------------------------

              Render code running in the thread's loop

              //------------------------------------------------------

              BOOL makeCurrentSuccess = wglMakeAssociatedContextCurrentAMD(associatedContext);

                  glEnable(GL_DEPTH_TEST);

                  glClearColor(0,0,1,1);

                  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

                  glMatrixMode(GL_PROJECTION);

                  glLoadIdentity();

                  glFrustum(-10,10,-10,10,0.1,100);

                  glMatrixMode(GL_MODELVIEW);

                  glLoadIdentity();

                  glTranslatef(0,0,-2);   

                  for(int i = -2; i <2;i++)
                  {
                      for(int j = -10; j <10;j++)
                      {

                          glColor3f((i+50)/100.0f,(j+50)/100.0f,0);

                          glPushMatrix();
                          glTranslatef(4*j,4*i,0);
                          glCallList(displayList);

                          glPopMatrix();
                      }
                  }

                  GLubyte pixel[4];

                  //If I don't call readpixels here, it hangs!!!


                  glReadPixels(0,0,1,1,GL_RGBA,GL_UNSIGNED_BYTE,pixel);

                  fenceSemaphorePre->WaitForSemaphore();

                       wglBlitContextFramebufferAMD(mainContext,0,0,512,512,0,0,512,512,GL_COLOR_BUFFER_BIT,GL_NEAREST);

                  fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE,0);

                  GLenum syncResult = 0;

                  do
                  {
                      syncResult = glClientWaitSync(fence,GL_SYNC_FLUSH_COMMANDS_BIT,GL_MAX_SERVER_WAIT_TIMEOUT);
                  }
                  while(syncResult == GL_TIMEOUT_EXPIRED);

                 

                  if (syncResult == GL_CONDITION_SATISFIED || syncResult == GL_ALREADY_SIGNALED)
                  {

                      glDeleteSync(fence);

                      fenceSemaphore->PostSemaphore(1);
                  }
                  else
                  {
                      glDeleteSync(fence);

                      Terminate();
                  }

              //------------------------------------------------------

               

              Any ideas anyone?

               

              Best regards,

                 Attila Barsi