15bd8deadSopenharmony_ciName
25bd8deadSopenharmony_ci
35bd8deadSopenharmony_ci      WGL_NV_gpu_affinity
45bd8deadSopenharmony_ci
55bd8deadSopenharmony_ciName Strings
65bd8deadSopenharmony_ci
75bd8deadSopenharmony_ci      WGL_NV_gpu_affinity
85bd8deadSopenharmony_ci
95bd8deadSopenharmony_ciContact
105bd8deadSopenharmony_ci
115bd8deadSopenharmony_ci      Barthold Lichtenbelt, NVIDIA (blichtenbelt 'at' nvidia.com)
125bd8deadSopenharmony_ci
135bd8deadSopenharmony_ciNotice
145bd8deadSopenharmony_ci
155bd8deadSopenharmony_ci      Copyright NVIDIA Corporation, 2005-2006.
165bd8deadSopenharmony_ci
175bd8deadSopenharmony_ciStatus
185bd8deadSopenharmony_ci
195bd8deadSopenharmony_ci      Completed.
205bd8deadSopenharmony_ci
215bd8deadSopenharmony_ciVersion
225bd8deadSopenharmony_ci
235bd8deadSopenharmony_ci      Last Modified Date: 11/08/2006
245bd8deadSopenharmony_ci      Author revision: 11
255bd8deadSopenharmony_ci
265bd8deadSopenharmony_ciNumber
275bd8deadSopenharmony_ci
285bd8deadSopenharmony_ci      355
295bd8deadSopenharmony_ci
305bd8deadSopenharmony_ciDependencies
315bd8deadSopenharmony_ci
325bd8deadSopenharmony_ci      WGL_ARB_extensions_string is required.
335bd8deadSopenharmony_ci
345bd8deadSopenharmony_ci      This extension interacts with WGL_ARB_make_current_read.
355bd8deadSopenharmony_ci
365bd8deadSopenharmony_ci      This extension interacts with WGL_ARB_pbuffer.
375bd8deadSopenharmony_ci
385bd8deadSopenharmony_ci      This extension interacts with GL_EXT_framebuffer_object
395bd8deadSopenharmony_ci
405bd8deadSopenharmony_ciOverview
415bd8deadSopenharmony_ci
425bd8deadSopenharmony_ci      On systems with more than one GPU it is desirable to be able to
435bd8deadSopenharmony_ci      select which GPU(s) in the system become the target for OpenGL
445bd8deadSopenharmony_ci      rendering commands. This extension introduces the concept of a GPU
455bd8deadSopenharmony_ci      affinity mask. OpenGL rendering commands are directed to the
465bd8deadSopenharmony_ci      GPU(s) specified by the affinity mask. GPU affinity is immutable.
475bd8deadSopenharmony_ci      Once set, it cannot be changed.
485bd8deadSopenharmony_ci
495bd8deadSopenharmony_ci      This extension also introduces the concept called affinity-DC. An
505bd8deadSopenharmony_ci      affinity-DC is a device context with a GPU affinity mask embedded
515bd8deadSopenharmony_ci      in it. This restricts the device context to only allow OpenGL
525bd8deadSopenharmony_ci      commands to be sent to the GPU(s) in the affinity mask.
535bd8deadSopenharmony_ci
545bd8deadSopenharmony_ci      Handles for the GPUs present in a system are enumerated with the
555bd8deadSopenharmony_ci      command wglEnumGpusNV. An affinity-DC is created by calling
565bd8deadSopenharmony_ci      wglCreateAffinityDCNV. This function takes a list of GPU handles,
575bd8deadSopenharmony_ci      which make up the affinity mask. An affinity-DC can also
585bd8deadSopenharmony_ci      indirectly be created by obtaining a DC from a pBuffer handle, by
595bd8deadSopenharmony_ci      calling wglGetPbufferDC, which in turn was created from an
605bd8deadSopenharmony_ci      affinity-DC by calling wglCreatePbuffer.
615bd8deadSopenharmony_ci
625bd8deadSopenharmony_ci      A context created from an affinity DC will inherit the GPU
635bd8deadSopenharmony_ci      affinity mask from the DC. Once inherited, it cannot be changed.
645bd8deadSopenharmony_ci      Such a context is called an affinity-context. This restricts the
655bd8deadSopenharmony_ci      affinity-context to only allow OpenGL commands to be sent to those
665bd8deadSopenharmony_ci      GPU(s) in its affinity mask. Once created, this context can be
675bd8deadSopenharmony_ci      used in two ways:
685bd8deadSopenharmony_ci
695bd8deadSopenharmony_ci        1. Make the affinity-context current to an affinity-DC. This
705bd8deadSopenharmony_ci           will only succeed if the context's affinity mask is the same
715bd8deadSopenharmony_ci           as the affinity mask in the DC. There is no window
725bd8deadSopenharmony_ci           associated with an affinity DC, therefore this is a way to
735bd8deadSopenharmony_ci           achieve off-screen rendering to an OpenGL context. This can
745bd8deadSopenharmony_ci           either be rendering to a pBuffer, or an application created
755bd8deadSopenharmony_ci           framebuffer object. In the former case, the affinity-mask of
765bd8deadSopenharmony_ci           the pBuffer DC, which is obtained from a pBuffer handle,
775bd8deadSopenharmony_ci           will be the same affinity-mask as the DC used to created the
785bd8deadSopenharmony_ci           pBuffer handle.  In the latter case, the default framebuffer
795bd8deadSopenharmony_ci           object will be incomplete because there is no window-system
805bd8deadSopenharmony_ci           created framebuffer. Therefore, the application will have to
815bd8deadSopenharmony_ci           create and bind a framebuffer object as the target for
825bd8deadSopenharmony_ci           rendering.
835bd8deadSopenharmony_ci        2. Make the affinity-context current to a DC obtained from a
845bd8deadSopenharmony_ci           window. Rendering only happens to the sub rectangles(s) of
855bd8deadSopenharmony_ci           the window that overlap the parts of the desktop that are
865bd8deadSopenharmony_ci           displayed by the GPU(s) in the affinity mask of the context.
875bd8deadSopenharmony_ci
885bd8deadSopenharmony_ci      Sharing OpenGL objects between affinity-contexts, by calling
895bd8deadSopenharmony_ci      wglShareLists, will only succeed if the contexts have identical
905bd8deadSopenharmony_ci      affinity masks.
915bd8deadSopenharmony_ci
925bd8deadSopenharmony_ci      It is not possible to make a regular context (one without an
935bd8deadSopenharmony_ci      affinity mask) current to an affinity-DC. This would mean a way
945bd8deadSopenharmony_ci      for a context to inherit affinity information, which makes the
955bd8deadSopenharmony_ci      context affinity mutable, which is counter to the premise of this
965bd8deadSopenharmony_ci      extension.
975bd8deadSopenharmony_ci
985bd8deadSopenharmony_ciNew Procedures, Functions and Structures:
995bd8deadSopenharmony_ci
1005bd8deadSopenharmony_ci      DECLARE_HANDLE(HGPUNV);
1015bd8deadSopenharmony_ci
1025bd8deadSopenharmony_ci      typedef struct _GPU_DEVICE {
1035bd8deadSopenharmony_ci        DWORD  cb;
1045bd8deadSopenharmony_ci        CHAR   DeviceName[32];
1055bd8deadSopenharmony_ci        CHAR   DeviceString[128];
1065bd8deadSopenharmony_ci        DWORD  Flags;
1075bd8deadSopenharmony_ci        RECT   rcVirtualScreen;
1085bd8deadSopenharmony_ci      } GPU_DEVICE, *PGPU_DEVICE;
1095bd8deadSopenharmony_ci
1105bd8deadSopenharmony_ci      BOOL wglEnumGpusNV(UINT iGpuIndex,
1115bd8deadSopenharmony_ci                         HGPUNV *phGpu);
1125bd8deadSopenharmony_ci
1135bd8deadSopenharmony_ci      BOOL wglEnumGpuDevicesNV(HGPUNV hGpu,
1145bd8deadSopenharmony_ci                               UINT iDeviceIndex,
1155bd8deadSopenharmony_ci                               PGPU_DEVICE lpGpuDevice);
1165bd8deadSopenharmony_ci
1175bd8deadSopenharmony_ci      HDC wglCreateAffinityDCNV(const HGPUNV *phGpuList);
1185bd8deadSopenharmony_ci
1195bd8deadSopenharmony_ci      BOOL wglEnumGpusFromAffinityDCNV(HDC hAffinityDC,
1205bd8deadSopenharmony_ci                                       UINT iGpuIndex,
1215bd8deadSopenharmony_ci                                       HGPUNV *hGpu);
1225bd8deadSopenharmony_ci
1235bd8deadSopenharmony_ci      BOOL wglDeleteDCNV(HDC hdc);
1245bd8deadSopenharmony_ci
1255bd8deadSopenharmony_ciNew Tokens
1265bd8deadSopenharmony_ci
1275bd8deadSopenharmony_ci      New error codes set by wglShareLists, wglMakeCurrent and
1285bd8deadSopenharmony_ci      wglMakeContextCurrentARB:
1295bd8deadSopenharmony_ci
1305bd8deadSopenharmony_ci      ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV    0x20D0
1315bd8deadSopenharmony_ci
1325bd8deadSopenharmony_ci      New error codes set by wglMakeCurrent and
1335bd8deadSopenharmony_ci      wglMakeContextCurrentARB:
1345bd8deadSopenharmony_ci
1355bd8deadSopenharmony_ci      ERROR_MISSING_AFFINITY_MASK_NV          0x20D1
1365bd8deadSopenharmony_ci
1375bd8deadSopenharmony_ciAdditions to the WGL Specification
1385bd8deadSopenharmony_ci
1395bd8deadSopenharmony_ci      GPU Affinity
1405bd8deadSopenharmony_ci
1415bd8deadSopenharmony_ci      To query handles for all GPUs in a system call:
1425bd8deadSopenharmony_ci
1435bd8deadSopenharmony_ci           BOOL wglEnumGpusNV(UINT iGpuIndex, HGPUNV *phGPU);
1445bd8deadSopenharmony_ci
1455bd8deadSopenharmony_ci      <iGpuIndex> is an index value that specifies a GPU.
1465bd8deadSopenharmony_ci
1475bd8deadSopenharmony_ci      <phGPU> upon return will contain a handle for GPU number
1485bd8deadSopenharmony_ci      <iGpuIndex>. The first GPU will be index 0.
1495bd8deadSopenharmony_ci
1505bd8deadSopenharmony_ci      By looping over wglEnumGpusNV and incrementing <iGpuIndex>,
1515bd8deadSopenharmony_ci      starting at index 0, all GPU handles can be queried. If the
1525bd8deadSopenharmony_ci      function succeeds, the return value is TRUE. If the function
1535bd8deadSopenharmony_ci      fails, the return value is FALSE and <phGPU> will be unmodified.
1545bd8deadSopenharmony_ci      The function fails if <iGpuIndex> is greater or equal than the
1555bd8deadSopenharmony_ci      number of GPUs supported by the system.
1565bd8deadSopenharmony_ci
1575bd8deadSopenharmony_ci      To retrieve information about the display devices supported by a
1585bd8deadSopenharmony_ci      GPU call:
1595bd8deadSopenharmony_ci
1605bd8deadSopenharmony_ci           BOOL wglEnumGpuDevicesNV(HGPUNV hGpu,
1615bd8deadSopenharmony_ci                                   UINT iDeviceIndex,
1625bd8deadSopenharmony_ci                                   PGPU_DEVICE lpGpuDevice);
1635bd8deadSopenharmony_ci
1645bd8deadSopenharmony_ci      <hGpu> is a handle to the GPU to query.
1655bd8deadSopenharmony_ci
1665bd8deadSopenharmony_ci      <iDeviceIndex> is an index value that specifies a display device,
1675bd8deadSopenharmony_ci      supported by <hGpu>, to query. The first display device will be
1685bd8deadSopenharmony_ci      index 0.
1695bd8deadSopenharmony_ci
1705bd8deadSopenharmony_ci      <lpGpuDevice> pointer to a GPU_DEVICE structure which will receive
1715bd8deadSopenharmony_ci      information about the display device at index <iDeviceIndex>.
1725bd8deadSopenharmony_ci
1735bd8deadSopenharmony_ci      By looping over the function wglEnumGpuDevicesNV and incrementing
1745bd8deadSopenharmony_ci      <iDeviceIndex>, starting at index 0, all display devices can be
1755bd8deadSopenharmony_ci      queried. If the function succeeds, the return value is TRUE. If
1765bd8deadSopenharmony_ci      the function fails, the return value is FALSE and <lpGpuDevice>
1775bd8deadSopenharmony_ci      will be unmodified. The function fails if <iDeviceIndex> is
1785bd8deadSopenharmony_ci      greater or equal than the number of display devices supported by
1795bd8deadSopenharmony_ci      <hGpu>.
1805bd8deadSopenharmony_ci
1815bd8deadSopenharmony_ci      The GPU_DEVICE structure has the following members:
1825bd8deadSopenharmony_ci
1835bd8deadSopenharmony_ci           typedef struct _GPU_DEVICE {
1845bd8deadSopenharmony_ci             DWORD  cb;
1855bd8deadSopenharmony_ci             CHAR   DeviceName[32];
1865bd8deadSopenharmony_ci             CHAR   DeviceString[128];
1875bd8deadSopenharmony_ci             DWORD  Flags;
1885bd8deadSopenharmony_ci             RECT   rcVirtualScreen;
1895bd8deadSopenharmony_ci           } GPU_DEVICE, *PGPU_DEVICE;
1905bd8deadSopenharmony_ci
1915bd8deadSopenharmony_ci      <cb> is the size of the GPU_DEVICE structure. Before calling
1925bd8deadSopenharmony_ci      wglEnumGpuDevicesNV, set <cb> to the size, in bytes, of
1935bd8deadSopenharmony_ci      GPU_DEVICE.
1945bd8deadSopenharmony_ci
1955bd8deadSopenharmony_ci      <DeviceName> is a string identifying the display device name. This
1965bd8deadSopenharmony_ci      will be the same string as stored in the <DeviceName> field of the
1975bd8deadSopenharmony_ci      DISPLAY_DEVICE structure, which is filled in by
1985bd8deadSopenharmony_ci      EnumDisplayDevices.
1995bd8deadSopenharmony_ci
2005bd8deadSopenharmony_ci      <DeviceString> is a string describing the GPU for this display
2015bd8deadSopenharmony_ci      device. It is the same string as stored in the <DeviceString>
2025bd8deadSopenharmony_ci      field in the DISPLAY_DEVICE structure that is filled in by
2035bd8deadSopenharmony_ci      EnumDisplayDevices when it describes a display adapter (and not a
2045bd8deadSopenharmony_ci      monitor).
2055bd8deadSopenharmony_ci
2065bd8deadSopenharmony_ci      <Flags> Indicates the state of the display device. It can be a
2075bd8deadSopenharmony_ci      combination of any of the following:
2085bd8deadSopenharmony_ci
2095bd8deadSopenharmony_ci      DISPLAY_DEVICE_ATTACHED_TO_DESKTOP      If set, the device is part
2105bd8deadSopenharmony_ci      of the desktop.
2115bd8deadSopenharmony_ci
2125bd8deadSopenharmony_ci      DISPLAY_DEVICE_PRIMARY_DEVICE           If set, the primary
2135bd8deadSopenharmony_ci      desktop is on this device. Only one device in the system can have
2145bd8deadSopenharmony_ci      this set.
2155bd8deadSopenharmony_ci
2165bd8deadSopenharmony_ci      <rcVirtualScreen> specifies the display device rectangle, in
2175bd8deadSopenharmony_ci      virtual screen coordinates. The value of <rcVirtualScreen> is
2185bd8deadSopenharmony_ci      undefined if the device is not part of the desktop, i.e.
2195bd8deadSopenharmony_ci      DISPLAY_DEVICE_ATTACHED_TO_DESKTOP is not set in the <Flags>
2205bd8deadSopenharmony_ci      field.
2215bd8deadSopenharmony_ci
2225bd8deadSopenharmony_ci      The function wglEnumGpuDevicesNV can fail for a variety of
2235bd8deadSopenharmony_ci      reasons. Call GetLastError to get extended error information.
2245bd8deadSopenharmony_ci      Possible errors are as follows:
2255bd8deadSopenharmony_ci
2265bd8deadSopenharmony_ci      ERROR_INVALID_HANDLE   <hGpu> is not a valid GPU handle.
2275bd8deadSopenharmony_ci
2285bd8deadSopenharmony_ci      A new type of DC, called an affinity-DC, can be used to direct
2295bd8deadSopenharmony_ci      OpenGL commands to a specific GPU or set of GPUs. An affinity-DC
2305bd8deadSopenharmony_ci      is a device context with a GPU affinity mask embedded in it. This
2315bd8deadSopenharmony_ci      restricts the device context to only allow OpenGL commands to be
2325bd8deadSopenharmony_ci      sent to the GPU(s) in the affinity mask. An affinity-DC can be
2335bd8deadSopenharmony_ci      created directly, using the new function wglCreateAffinityDCNV and
2345bd8deadSopenharmony_ci      also indirectly by calling wglCreatePbufferARB followed by
2355bd8deadSopenharmony_ci      wglGetPbufferDCARB. To create an affinity-DC directly call:
2365bd8deadSopenharmony_ci
2375bd8deadSopenharmony_ci           HDC wglCreateAffinityDCNV(const HGPUNV *phGpuList);
2385bd8deadSopenharmony_ci
2395bd8deadSopenharmony_ci      <phGpuList> is a NULL-terminated array of GPU handles to which the
2405bd8deadSopenharmony_ci      affinity-DC will be restricted. If an element in the list is not a
2415bd8deadSopenharmony_ci      GPU handle, as returned by wglEnumGpusNV, it is silently ignored.
2425bd8deadSopenharmony_ci
2435bd8deadSopenharmony_ci      If successful, the function returns an affinity-DC. If it fails,
2445bd8deadSopenharmony_ci      NULL will be returned.
2455bd8deadSopenharmony_ci
2465bd8deadSopenharmony_ci      To create an affinity-DC indirectly, first call
2475bd8deadSopenharmony_ci      wglCreatePbufferARB passing it an affinity-DC. Next, pass the
2485bd8deadSopenharmony_ci      handle returned by the call to wglCreatePbufferARB to
2495bd8deadSopenharmony_ci      wglGetPbufferDCARB to create an affinity-DC for the pBuffer. The
2505bd8deadSopenharmony_ci      DC returned by wglGetPbufferDCARB will have the same affinity mask
2515bd8deadSopenharmony_ci      as the DC used to create the pBuffer handle by calling
2525bd8deadSopenharmony_ci      wglCreatePbufferARB.
2535bd8deadSopenharmony_ci
2545bd8deadSopenharmony_ci      An affinity-DC has no window associated with it, and therefore it
2555bd8deadSopenharmony_ci      has no default window-system-provided framebuffer. (Note: This is
2565bd8deadSopenharmony_ci      terminology borrowed from EXT_framebuffer_object). A context made
2575bd8deadSopenharmony_ci      current to an affinity-DC will only be able to render into an
2585bd8deadSopenharmony_ci      application-created framebuffer object, or a pBuffer. The default
2595bd8deadSopenharmony_ci      window-system-framebuffer object, when bound, will be incomplete.
2605bd8deadSopenharmony_ci      The EXT_framebuffer_object specification defines what 'incomplete'
2615bd8deadSopenharmony_ci      means exactly.
2625bd8deadSopenharmony_ci
2635bd8deadSopenharmony_ci      A context created from an affinity-DC, by calling wglCreateContext
2645bd8deadSopenharmony_ci      and passing it an affinity-DC, is called an affinity-context. This
2655bd8deadSopenharmony_ci      context will inherit the affinity mask from the DC. This affinity-
2665bd8deadSopenharmony_ci      mask cannot be changed. The affinity mask restricts the affinity-
2675bd8deadSopenharmony_ci      context to only allow OpenGL commands to be sent to those GPU(s)
2685bd8deadSopenharmony_ci      in its affinity mask.
2695bd8deadSopenharmony_ci
2705bd8deadSopenharmony_ci      The function wglCreateAffinityDCNV can fail for a variety of
2715bd8deadSopenharmony_ci      reasons. Call GetLastError to get extended error information.
2725bd8deadSopenharmony_ci      Possible errors are as follows:
2735bd8deadSopenharmony_ci
2745bd8deadSopenharmony_ci      ERROR_NO_SYSTEM_RESOURCES    Insufficient resources exist to
2755bd8deadSopenharmony_ci      create the affinity-DC.
2765bd8deadSopenharmony_ci
2775bd8deadSopenharmony_ci      ERROR_INVALID_DATA           <phGpuList> is empty or contains no
2785bd8deadSopenharmony_ci      valid GPU handles
2795bd8deadSopenharmony_ci
2805bd8deadSopenharmony_ci      An affinity-context can only be made current to an affinity-DC
2815bd8deadSopenharmony_ci      with the same affinity-mask, otherwise wglMakeCurrent and
2825bd8deadSopenharmony_ci      wglMakeContextCurrentARB will fail and return FALSE. In the case
2835bd8deadSopenharmony_ci      of wglMakeContextCurrentARB, the affinity masks of both the "read"
2845bd8deadSopenharmony_ci      and "draw" DCs need to match the affinity-mask of the context.
2855bd8deadSopenharmony_ci
2865bd8deadSopenharmony_ci      If a context that has no affinity mask is made current to an
2875bd8deadSopenharmony_ci      affinity-DC, wglMakeCurrent and wglMakeContextCurrentARB will fail
2885bd8deadSopenharmony_ci      and return FALSE. In the case of wglMakeContextCurrentARB it will
2895bd8deadSopenharmony_ci      fail if either the "read" or "draw" DC is an affinity-DC.
2905bd8deadSopenharmony_ci
2915bd8deadSopenharmony_ci      If an affinity-context is made current to a DC obtained from a
2925bd8deadSopenharmony_ci      window, by calling GetDC, then rendering will only happen to the
2935bd8deadSopenharmony_ci      subrectangle(s) of the window that overlap the parts of the
2945bd8deadSopenharmony_ci      desktop that are displayed by the GPU(s) in the affinity-mask of
2955bd8deadSopenharmony_ci      the context. Note that a DC obtained from a window does not have
2965bd8deadSopenharmony_ci      an affinity mask set.
2975bd8deadSopenharmony_ci
2985bd8deadSopenharmony_ci      The following error codes are added to the description of
2995bd8deadSopenharmony_ci      wglMakeCurrent and wglMakeContextCurrentARB:
3005bd8deadSopenharmony_ci
3015bd8deadSopenharmony_ci      ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV    The device context(s) and
3025bd8deadSopenharmony_ci      rendering context have non-matching affinity masks.
3035bd8deadSopenharmony_ci
3045bd8deadSopenharmony_ci      ERROR_MISSING_AFFINITY_MASK_NV          The rendering context does
3055bd8deadSopenharmony_ci      not have an affinity mask set.
3065bd8deadSopenharmony_ci
3075bd8deadSopenharmony_ci      Sharing OpenGL objects between affinity-contexts, by calling
3085bd8deadSopenharmony_ci      wglShareLists, will only succeed if the contexts have identical
3095bd8deadSopenharmony_ci      affinity masks. The following error codes are added to the
3105bd8deadSopenharmony_ci      description of wglShareLists:
3115bd8deadSopenharmony_ci
3125bd8deadSopenharmony_ci      ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV    The contexts have non-
3135bd8deadSopenharmony_ci      matching affinity masks.
3145bd8deadSopenharmony_ci
3155bd8deadSopenharmony_ci      To delete an affinity-DC call:
3165bd8deadSopenharmony_ci
3175bd8deadSopenharmony_ci           BOOL wglDeleteDCNV(HDC hdc)
3185bd8deadSopenharmony_ci
3195bd8deadSopenharmony_ci      <hdc> Is a handle of an affinity-DC to delete.
3205bd8deadSopenharmony_ci
3215bd8deadSopenharmony_ci      If the function succeeds, TRUE is returned. If the function fails,
3225bd8deadSopenharmony_ci      FALSE is returned. Call GetLastError to get extended error
3235bd8deadSopenharmony_ci      information. Possible errors are as follows:
3245bd8deadSopenharmony_ci
3255bd8deadSopenharmony_ci      ERROR_INVALID_HANDLE   <hdc> is not a handle of an affinity-DC.
3265bd8deadSopenharmony_ci
3275bd8deadSopenharmony_ci      To retrieve a list of GPU handles that make up the affinity-mask
3285bd8deadSopenharmony_ci      of an affinity-DC, call:
3295bd8deadSopenharmony_ci
3305bd8deadSopenharmony_ci           BOOL wglEnumGpusFromAffinityDCNV(HDC hAffinityDC,
3315bd8deadSopenharmony_ci                                           UINT iGpuIndex,
3325bd8deadSopenharmony_ci                                           HGPUNV *phGpu);
3335bd8deadSopenharmony_ci
3345bd8deadSopenharmony_ci      <hAffinityDC> is a handle of the affinity-DC to query.
3355bd8deadSopenharmony_ci
3365bd8deadSopenharmony_ci      <iGpuIndex> is an index value of the GPU handle in the affinity
3375bd8deadSopenharmony_ci      mask of <hAffinityDC> to query.
3385bd8deadSopenharmony_ci
3395bd8deadSopenharmony_ci      <phGpu> upon return will contain a handle for GPU number
3405bd8deadSopenharmony_ci      <iGpuIndex>. The first GPU will be at index 0.
3415bd8deadSopenharmony_ci
3425bd8deadSopenharmony_ci      By looping over wglEnumGpusFromAffinityDCNV and incrementing
3435bd8deadSopenharmony_ci      <iGpuIndex>, starting at index 0, all GPU handles associated with
3445bd8deadSopenharmony_ci      the DC can be queried. If the function succeeds, the return value
3455bd8deadSopenharmony_ci      is TRUE. If the function fails, the return value is FALSE and
3465bd8deadSopenharmony_ci      <phGPU> will be unmodified. The function fails if <iGpuIndex> is
3475bd8deadSopenharmony_ci      greater or equal than the number of GPUs associated with
3485bd8deadSopenharmony_ci      <hAffinityDC>.
3495bd8deadSopenharmony_ci
3505bd8deadSopenharmony_ci      Call GetLastError to get extended error information. Possible
3515bd8deadSopenharmony_ci      errors are as follows:
3525bd8deadSopenharmony_ci
3535bd8deadSopenharmony_ci      ERROR_INVALID_HANDLE   <hAffinityDC> is not a handle of an
3545bd8deadSopenharmony_ci      affinity-DC.
3555bd8deadSopenharmony_ci
3565bd8deadSopenharmony_ciInteractions with WGL_ARB_make_current_read
3575bd8deadSopenharmony_ci
3585bd8deadSopenharmony_ci      If the make current read extension is not supported, all language
3595bd8deadSopenharmony_ci      referring to wglMakeContextCurrentARB is deleted.
3605bd8deadSopenharmony_ci
3615bd8deadSopenharmony_ciInteractions with WGL_ARB_pbuffer
3625bd8deadSopenharmony_ci
3635bd8deadSopenharmony_ci      If the pbuffer extension is not supported, all language referring
3645bd8deadSopenharmony_ci      to puffers, wglGetPbuferDC and wglCreatePbuffer are deleted.
3655bd8deadSopenharmony_ci
3665bd8deadSopenharmony_ciInteractions with GL_EXT_framebuffer_object
3675bd8deadSopenharmony_ci
3685bd8deadSopenharmony_ci      If the framebuffer object extension is not supported, all language
3695bd8deadSopenharmony_ci      referring to framebuffer objects is deleted.
3705bd8deadSopenharmony_ci
3715bd8deadSopenharmony_ciUsage examples
3725bd8deadSopenharmony_ci
3735bd8deadSopenharmony_ci      // Example 1 - Normal window creation, DC setup and
3745bd8deadSopenharmony_ci      // context creation.
3755bd8deadSopenharmony_ci
3765bd8deadSopenharmony_ci      PIXELFORMATDESCRIPTOR pfd;
3775bd8deadSopenharmony_ci      int   pf;
3785bd8deadSopenharmony_ci      HDC   hDC;
3795bd8deadSopenharmony_ci      HGLRC hRC;
3805bd8deadSopenharmony_ci      HWND  hWnd;
3815bd8deadSopenharmony_ci
3825bd8deadSopenharmony_ci      hWnd = CreateWindow(...);
3835bd8deadSopenharmony_ci      hDC = GetDC(hWnd);
3845bd8deadSopenharmony_ci
3855bd8deadSopenharmony_ci      memset(&pfd, 0, sizeof(pfd));
3865bd8deadSopenharmony_ci      pfd.nSize        = sizeof(pfd);
3875bd8deadSopenharmony_ci      pfd.nVersion     = 1;
3885bd8deadSopenharmony_ci      pfd.dwFlags      = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
3895bd8deadSopenharmony_ci      pfd.iPixelType   = PFD_TYPE_RGBA;
3905bd8deadSopenharmony_ci      pfd.cColorBits   = 32;
3915bd8deadSopenharmony_ci
3925bd8deadSopenharmony_ci      // Note, for ease of code reading no error checking is done.
3935bd8deadSopenharmony_ci      pf = ChoosePixelFormat(hDC, &pfd);
3945bd8deadSopenharmony_ci      SetPixelFormat(hDC, pf, &pfd);
3955bd8deadSopenharmony_ci      DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR),
3965bd8deadSopenharmony_ci                          &pfd);
3975bd8deadSopenharmony_ci
3985bd8deadSopenharmony_ci      hRC = wglCreateContext(hDC);
3995bd8deadSopenharmony_ci      wglMakeCurrent(hDC, hRC);
4005bd8deadSopenharmony_ci
4015bd8deadSopenharmony_ci
4025bd8deadSopenharmony_ci      // Example 2 - Offscreen rendering to one GPU using a FBO
4035bd8deadSopenharmony_ci      // It is assumed that a context already has been created (and
4045bd8deadSopenharmony_ci      // possibly destroyed) and was used to query the proc addresses
4055bd8deadSopenharmony_ci      // of the WGL affinity related entrypoints.
4065bd8deadSopenharmony_ci
4075bd8deadSopenharmony_ci      #define MAX_GPU 4
4085bd8deadSopenharmony_ci
4095bd8deadSopenharmony_ci      PIXELFORMATDESCRIPTOR pfd;
4105bd8deadSopenharmony_ci      int    pf, gpuIndex = 0;
4115bd8deadSopenharmony_ci      HGPUNV hGPU[MAX_GPU];
4125bd8deadSopenharmony_ci      HGPUNV GpuMask[MAX_GPU];
4135bd8deadSopenharmony_ci      HDC    affDC;
4145bd8deadSopenharmony_ci      HGLRC  affRC;
4155bd8deadSopenharmony_ci
4165bd8deadSopenharmony_ci      // Get a list of the first MAX_GPU GPUs in the system
4175bd8deadSopenharmony_ci      while ((gpuIndex < MAX_GPU) && wglEnumGpusNV(gpuIndex,
4185bd8deadSopenharmony_ci      &hGPU[gpuIndex])) {
4195bd8deadSopenharmony_ci            gpuIndex++;
4205bd8deadSopenharmony_ci      }
4215bd8deadSopenharmony_ci
4225bd8deadSopenharmony_ci      // Create an affinity-DC associated with the first GPU
4235bd8deadSopenharmony_ci      GpuMask[0] = hGPU[0];
4245bd8deadSopenharmony_ci      GpuMask[1] = NULL;
4255bd8deadSopenharmony_ci
4265bd8deadSopenharmony_ci      affDC = wglCreateAffinityDCNV(GpuMask);
4275bd8deadSopenharmony_ci
4285bd8deadSopenharmony_ci      // Set a pixelformat on the affinity-DC
4295bd8deadSopenharmony_ci      pf = ChoosePixelFormat(affDC, &pfd);
4305bd8deadSopenharmony_ci      SetPixelFormat(affDC, pf, &pfd);
4315bd8deadSopenharmony_ci      DescribePixelFormat(affDC, pf, sizeof(PIXELFORMATDESCRIPTOR),
4325bd8deadSopenharmony_ci      &pfd);
4335bd8deadSopenharmony_ci
4345bd8deadSopenharmony_ci      affRC = wglCreateContext(affDC);
4355bd8deadSopenharmony_ci      wglMakeCurrent(affDC, affRC);
4365bd8deadSopenharmony_ci
4375bd8deadSopenharmony_ci      // Make a previously created FBO current so we have something
4385bd8deadSopenharmony_ci      // to render into. Since there's no window, the default system
4395bd8deadSopenharmony_ci      // created FBO is incomplete.
4405bd8deadSopenharmony_ci      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
4415bd8deadSopenharmony_ci
4425bd8deadSopenharmony_ci       <Now draw>
4435bd8deadSopenharmony_ci
4445bd8deadSopenharmony_ci      // Example 3 - Offscreen rendering to one GPU using a pBuffer
4455bd8deadSopenharmony_ci      // It is assumed that a context already has been created (and
4465bd8deadSopenharmony_ci      // possibly destroyed) and was used to query the proc addresses
4475bd8deadSopenharmony_ci      // of the WGL affinity and pbuffer related entrypoints.
4485bd8deadSopenharmony_ci
4495bd8deadSopenharmony_ci      #define MAX_GPU 4
4505bd8deadSopenharmony_ci
4515bd8deadSopenharmony_ci      int    gpuIndex = 0;
4525bd8deadSopenharmony_ci      HGPUNV hGPU[MAX_GPU];
4535bd8deadSopenharmony_ci      HGPUNV GpuMask[MAX_GPU];
4545bd8deadSopenharmony_ci      HDC    affDC, pBufferAffDC;
4555bd8deadSopenharmony_ci      HGLRC  affRC;
4565bd8deadSopenharmony_ci
4575bd8deadSopenharmony_ci      // Get a list of the first MAX_GPU GPUs in the system
4585bd8deadSopenharmony_ci      while ((gpuIndex < MAX_GPU) && wglEnumGpusNV(gpuIndex,
4595bd8deadSopenharmony_ci      &hGPU[gpuIndex])) {
4605bd8deadSopenharmony_ci            gpuIndex++;
4615bd8deadSopenharmony_ci      }
4625bd8deadSopenharmony_ci
4635bd8deadSopenharmony_ci      // Create an affinity-DC associated with the first GPU
4645bd8deadSopenharmony_ci      GpuMask[0] = hGPU[0];
4655bd8deadSopenharmony_ci      GpuMask[1] = NULL;
4665bd8deadSopenharmony_ci
4675bd8deadSopenharmony_ci      affDC = wglCreateAffinityDCNV(GpuMask);
4685bd8deadSopenharmony_ci
4695bd8deadSopenharmony_ci      // Setup desired pixelformat attributes for the pbuffer
4705bd8deadSopenharmony_ci      // including WGL_DRAW_TO_PBUFFER_ARB.
4715bd8deadSopenharmony_ci      HPBUFFERARB  handle;
4725bd8deadSopenharmony_ci      int          width = 512, height = 512, format = 0;
4735bd8deadSopenharmony_ci      unsigned int nformats;
4745bd8deadSopenharmony_ci
4755bd8deadSopenharmony_ci      int attribList[] =
4765bd8deadSopenharmony_ci      {
4775bd8deadSopenharmony_ci          WGL_RED_BITS_ARB,               8,
4785bd8deadSopenharmony_ci          WGL_GREEN_BITS_ARB,             8,
4795bd8deadSopenharmony_ci          WGL_BLUE_BITS_ARB,              8,
4805bd8deadSopenharmony_ci          WGL_ALPHA_BITS_ARB,             8,
4815bd8deadSopenharmony_ci          WGL_STENCIL_BITS_ARB,           0,
4825bd8deadSopenharmony_ci          WGL_DEPTH_BITS_ARB,             0,
4835bd8deadSopenharmony_ci          WGL_DRAW_TO_PBUFFER_ARB,        true,
4845bd8deadSopenharmony_ci          0,
4855bd8deadSopenharmony_ci      };
4865bd8deadSopenharmony_ci
4875bd8deadSopenharmony_ci      wglChoosePixelFormatARB(affDC, attribList, NULL, 1,
4885bd8deadSopenharmony_ci                              &format, &nformats);
4895bd8deadSopenharmony_ci
4905bd8deadSopenharmony_ci      handle = wglCreatePbufferARB(affDC, format, width, height, NULL);
4915bd8deadSopenharmony_ci
4925bd8deadSopenharmony_ci      // pbufferAffDC will have the same affinity-mask as affDC.
4935bd8deadSopenharmony_ci      pBufferAffDC = wglGetPbufferDCARB(handle);
4945bd8deadSopenharmony_ci
4955bd8deadSopenharmony_ci      // affRC will inherit the affinity-mask from pBufferAffDC.
4965bd8deadSopenharmony_ci      affRC = wglCreateContext(pBufferAffDC);
4975bd8deadSopenharmony_ci      wglMakeCurrent(pBufferAffDC, affRC);
4985bd8deadSopenharmony_ci
4995bd8deadSopenharmony_ci      <Now draw into the pBuffer>
5005bd8deadSopenharmony_ci
5015bd8deadSopenharmony_ciIssues
5025bd8deadSopenharmony_ci
5035bd8deadSopenharmony_ci      1) Do we really need an affinity-DC, or can we do with just an
5045bd8deadSopenharmony_ci      affinity context?
5055bd8deadSopenharmony_ci
5065bd8deadSopenharmony_ci      DISCUSSION: If affinity is not part of a DC, a new function will
5075bd8deadSopenharmony_ci      need to be defined to create an affinity-context or set an
5085bd8deadSopenharmony_ci      affinity-mask for an existing context. Passing NULL as a HDC to
5095bd8deadSopenharmony_ci      wglMakeCurrent will then be one way to create an off-screen
5105bd8deadSopenharmony_ci      rendering context, where rendering will have to go to a FBO. If
5115bd8deadSopenharmony_ci      the HDC passed to wglMakeCurrent is one for a pBuffer, the
5125bd8deadSopenharmony_ci      affinity-mask in the affinity-context dictates where rendering is
5135bd8deadSopenharmony_ci      direct to. This might mean pBuffer resources will have to move, or
5145bd8deadSopenharmony_ci      alternatively, duplicated across all GPUs in a system. That is
5155bd8deadSopenharmony_ci      counter to the whole idea of this extension. Thus an affinity-DC
5165bd8deadSopenharmony_ci      is definitely needed for a pBuffer.
5175bd8deadSopenharmony_ci
5185bd8deadSopenharmony_ci      Thus the question reduces to, do we need an affinity-DC in order
5195bd8deadSopenharmony_ci      to facilitate off-screen rendering to a FBO? Having an affinity-DC
5205bd8deadSopenharmony_ci      has the following advantages:
5215bd8deadSopenharmony_ci
5225bd8deadSopenharmony_ci      a)  It is consistent with making current to a pBuffer or window,
5235bd8deadSopenharmony_ci      that does need a DC.
5245bd8deadSopenharmony_ci      b) passing NULL as a HDC to wglMakeCurrent might be filtered out
5255bd8deadSopenharmony_ci      by the MS layer on future OSes.
5265bd8deadSopenharmony_ci      c) The driver implementation might benefit from knowing at DC
5275bd8deadSopenharmony_ci      creation time what the affinity-mask is, rather than at
5285bd8deadSopenharmony_ci      wglMakeCurrent time.
5295bd8deadSopenharmony_ci
5305bd8deadSopenharmony_ci      RESOLUTION: Yes.
5315bd8deadSopenharmony_ci
5325bd8deadSopenharmony_ci      2) Should the GPU affinity concept also apply to D3D and/or GDI
5335bd8deadSopenharmony_ci      commands?
5345bd8deadSopenharmony_ci
5355bd8deadSopenharmony_ci      DISCUSSION:  It could be especially desirable to apply the
5365bd8deadSopenharmony_ci      affinity concept to D3D. However, D3D is sufficiently different
5375bd8deadSopenharmony_ci      that this extension doesn't directly apply.
5385bd8deadSopenharmony_ci
5395bd8deadSopenharmony_ci      RESOLUTION: That falls outside this extension.
5405bd8deadSopenharmony_ci
5415bd8deadSopenharmony_ci      3) Should setting a pixelformat on an affinity-DC be required?
5425bd8deadSopenharmony_ci
5435bd8deadSopenharmony_ci      DISCUSSION: Setting a pixelformat on an affinity-DC is not
5445bd8deadSopenharmony_ci      strictly necessary if the application does off-screen rendering to
5455bd8deadSopenharmony_ci      a FBO. However, the Microsoft layer of wglMakeCurrent requires
5465bd8deadSopenharmony_ci      that the pixelformats of the DC and RC passed to it match. This
5475bd8deadSopenharmony_ci      becomes an issue when making an affinity-context current to a DC
5485bd8deadSopenharmony_ci      obtained from a window. The DC has a pixelformat set by the
5495bd8deadSopenharmony_ci      application, and therefore the affinity-context needs to have the
5505bd8deadSopenharmony_ci      same pixelformat. This means the affinity-DC, that the affinity-
5515bd8deadSopenharmony_ci      context is created from, needs to have the same pixelformat set.
5525bd8deadSopenharmony_ci
5535bd8deadSopenharmony_ci      RESOLUTION: YES. Setting a pixelformat on an affinity-DC is
5545bd8deadSopenharmony_ci      required.
5555bd8deadSopenharmony_ci
5565bd8deadSopenharmony_ci      4) Is it allowed to make an affinity-context current to an
5575bd8deadSopenharmony_ci      affinity-DC where the mask of the context spans more GPUs than the
5585bd8deadSopenharmony_ci      mask in the DC?
5595bd8deadSopenharmony_ci
5605bd8deadSopenharmony_ci      5) Is it allowed to make an affinity-context current to an
5615bd8deadSopenharmony_ci      affinity-DC where the mask of the context spans less GPUs than the
5625bd8deadSopenharmony_ci      mask in the DC?
5635bd8deadSopenharmony_ci
5645bd8deadSopenharmony_ci      DISCUSSION: Issues 4 and 5 are lumped together in this discussion.
5655bd8deadSopenharmony_ci      For example, is this scenario something we want to support: An
5665bd8deadSopenharmony_ci      application wants to share objects across two contexts and have
5675bd8deadSopenharmony_ci      these two contexts each render to a different GPU. It can do this
5685bd8deadSopenharmony_ci      by creating two affinity-DCs. One has an affinity mask for the
5695bd8deadSopenharmony_ci      first GPU, the other for the second GPU. It also creates two
5705bd8deadSopenharmony_ci      affinity-contexts that both have an affinity-mask that spans both
5715bd8deadSopenharmony_ci      GPUs. Making one context current to the first affinity-DC will
5725bd8deadSopenharmony_ci      lock the context to the GPU in the mask of that affinity-DC. Make
5735bd8deadSopenharmony_ci      another context current to the second affinity-DC will lock that
5745bd8deadSopenharmony_ci      context to the second GPU. This is effectively what issue 4) is
5755bd8deadSopenharmony_ci      asking. . The simplest solution is to disallow these cases, and
5765bd8deadSopenharmony_ci      that is how the spec is currently written.
5775bd8deadSopenharmony_ci
5785bd8deadSopenharmony_ci      RESOLUTION: NO, we will not allow this to keep the spec simple. If
5795bd8deadSopenharmony_ci      necessary, these restrictions can always be lifted later.
5805bd8deadSopenharmony_ci
5815bd8deadSopenharmony_ci      6) What should an application do if the enum functions that return
5825bd8deadSopenharmony_ci      BOOL fail for another reason than they are done? For example, if
5835bd8deadSopenharmony_ci      they fail because they run out of memory?
5845bd8deadSopenharmony_ci
5855bd8deadSopenharmony_ci      RESOLUTION: An application will have to call GetLastError to find
5865bd8deadSopenharmony_ci      out the reason of failure.
5875bd8deadSopenharmony_ci
5885bd8deadSopenharmony_ci      7) The "Enum" API commands in this extension assume that the list
5895bd8deadSopenharmony_ci      of things being enumerated does not change dynamically. Is that
5905bd8deadSopenharmony_ci      reasonable?
5915bd8deadSopenharmony_ci
5925bd8deadSopenharmony_ci      DISCUSSION: Display devices, and possibly GPUs in the future, can
5935bd8deadSopenharmony_ci      be changed dynamically and/or hotplugged. Thus yes, this is a
5945bd8deadSopenharmony_ci      potential issue. Existing OS functionality like EnumDisplayDevices
5955bd8deadSopenharmony_ci      and even wglMakeCurrent will suffer from this too. In the latter
5965bd8deadSopenharmony_ci      case, the application could make a context current to a device
5975bd8deadSopenharmony_ci      that was removed from the system. A possible solution would be
5985bd8deadSopenharmony_ci      some sort of notification mechanism to the application. Possibly
5995bd8deadSopenharmony_ci      combined with being able to snapshot state first, then enumerate
6005bd8deadSopenharmony_ci      that snapshot. That snapshot of state might immediately become
6015bd8deadSopenharmony_ci      invalid, but at least the enumeration will walk a consistent list.
6025bd8deadSopenharmony_ci
6035bd8deadSopenharmony_ci      RESOLUTION: This is a wider issue than just this specification,
6045bd8deadSopenharmony_ci      and not currently addressed.
6055bd8deadSopenharmony_ci
6065bd8deadSopenharmony_ci      8) How do I transfer data efficiently between two affinity-
6075bd8deadSopenharmony_ci      contexts?
6085bd8deadSopenharmony_ci
6095bd8deadSopenharmony_ci      DISCUSSION: It is desired for an application to render in one
6105bd8deadSopenharmony_ci      context, and transfer the result of that rendering to another
6115bd8deadSopenharmony_ci      context. These two contexts can be on different GPUs. If they are,
6125bd8deadSopenharmony_ci      how does the application efficiently transfer this data? Currently
6135bd8deadSopenharmony_ci      OpenGL provides two mechanisms, neither of which are ideal:
6145bd8deadSopenharmony_ci
6155bd8deadSopenharmony_ci      1) The application can do a ReadPixels followed by a DrawPixels /
6165bd8deadSopenharmony_ci      TexImage call. This involves transfer through host memory, which
6175bd8deadSopenharmony_ci      can be slow.
6185bd8deadSopenharmony_ci
6195bd8deadSopenharmony_ci      2) The application can share objects among the two contexts using
6205bd8deadSopenharmony_ci      wglShareLists(). This will work, but is counter to the premise of
6215bd8deadSopenharmony_ci      this extension where each GPU has its own set of resources, not
6225bd8deadSopenharmony_ci      shared with another GPU.
6235bd8deadSopenharmony_ci
6245bd8deadSopenharmony_ci      RESOLUTION: This is a hole which needs to be addressed separately.
6255bd8deadSopenharmony_ci
6265bd8deadSopenharmony_ciRevision history
6275bd8deadSopenharmony_ci
6285bd8deadSopenharmony_ci      None
629