Multiple GPU and the WGL_nv_gpu_affinity_extension

Hi there,

I have some questions about Multi-GPU and the WGL_nv_gpu_affinity_extension:

I read that the default behaviour for a system with multiple graphics boards is, that all OpenGL commands you send to a “conventionally” created WGLRC (without affinity mask) are executed on all installed graphics boards.
Does that mean, if i create a window (and rendering context from that window) on a monitor connected to GPU1, I can drag that window to a monitor on GPU2 and the OpenGL content is still updated (because all opengl resources and commands are directed to all gpus in the system)?

In contrast, I also heard that if I create a window and rendering context on a monitor connected to GPU1, all opengl commands are automatically directed ONLY to GPU1. Is that really true?
And if so, what is the point of the GPU affinity extension?
As far as I understand the affinity concept right, the aim is to being able to direct opengl commands to a specific list of “affinity” gpus in the system. A concept that would be redundant if the above sentence was true. Is that right?

And finally i want to ask, if there are some known issues with the WGL_nv_gpu_affinity_extension and Windows 7 64bit. I wrote a little program according to the extension spec, to target rendering to either (and both) of the QUADRO FX3800 boards in my system, which doesn’t work properly.

Thanks a lot!

The behaviour is dependent on the “Multi Display/Mixed GPU Acceleration” setting in the nvidia control panel.
In “Multi Display Mode”, a standard RC is being created in a way that you can drag the window across monitors connected to different GPUs and still get correct updates.
In “Single Display Mode”, the rendering is only send to the GPU conntected to the primary monitor. If you then drag your OpenGL window to another GPU, nothing will get rendered there.

To remedy your problem, you may download the “Equalizer” framework and try one of its examples.

I’ve had a lot of issues with things like mapped VBOs when using 2 GPUs that don’t have GPU affinity setup. Generally the VBO will only be correct on one of the cards.

Hi,

six months later I am still facing the same problem.
That is what happens:

  • create Window on Display A (GPU 0) and another Window on Display B (GPU 1)
  • Create Affinity Context using the function below
  • pass iGPU = 0 (index of my main screen gpu) and then render in both contexts
  • Result: succesful rendering on both displays (even though I restrict affinity in both contexts to GPU0), Moving the windows over both displays still shows the rendering.

if I pass iGPU = 1 (the index of my other GPU) both windows stay black.

Does anyone know what could be going wrong? Is there a mistake in my CreateContext function??

int CreateContext(int hdc, int iGPU)
{

PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0};

HGPUNV hGPU[2];
HGPUNV GpuMask[2];

GLint iPixelFormat = ChoosePixelFormat((HDC)hDC, &pfd);
SetPixelFormat((HDC)hDC, iPixelFormat, &pfd);
HGLRC tempHGLRC = wglCreateContext((HDC)m_hDC);
wglMakeCurrent((HDC)m_hDC, tempHGLRC);

wglEnumGpusNV(0, &hGPU[0]);
wglEnumGpusNV(1, &hGPU[1]);

GpuMask[0] = hGPU[iGPU];
GpuMask[1] = NULL;

HDC affDC = wglCreateAffinityDCNV(GpuMask);

iPixelFormat = ChoosePixelFormat(affDC, &pfd);
SetPixelFormat(affDC, iPixelFormat, &pfd);
m_hGLrc = (int)wglCreateContext(affDC);

wglMakeCurrent((HDC)m_hDC, (HGLRC)m_hGLrc);

wglDeleteContext(tempHGLRC);

return 1;

}

nVidia changed the behaviour of WGL_gpu_affinity for drivers >= version 190.0.
You cannot render into non-affinity DCs (i.e. windows) anymore. Instead you are expected to render offscreen into an FBO (using the affinity DC) and then copy the image over to the window using NV_copy_image.

Thank you skynet.
I changed my code and am now using the affinity Context to render via FBO to a texture. Then I use nv_copy_image to copy the image to a texture generated in my window context. Finally I just render that texture on the window. It seems to work now. (Even though I don’t know how to determine whether the offscreen rendering is in deed running only on the specified GPU).

I am also wondering about the performance of nv_copy_image. As far as I understand, a texture in a “regular” (non-affinity) window Context is always created on all GPUs. So when i do the copying from my offscreen texture to the actual window context texture, the texture data gets copied from one GPU to the other.
Can that transfer be really fast?

So when i do the copying from my offscreen texture to the actual window context texture, the texture data gets copied from one GPU to the other.
Can that transfer be really fast?

I don’t know, I haven’t thought about this yet, but it sounds logical.
Maybe the people of nVidia should clarify this… Piers, Barthold?