intel/perf: create a vtable entry for store_register_mem64
[mesa.git] / src / gallium / state_trackers / wgl / stw_ext_pbuffer.c
index fb5d5e8b9296f1a848f9a014f1ea9cadf914c973..02ccb76e277a8e63a4b44952ccb823dd8f4a3101 100644 (file)
 #include "pipe/p_defines.h"
 #include "pipe/p_screen.h"
 
+#include "util/u_debug.h"
+
 #include "stw_device.h"
 #include "stw_pixelformat.h"
 #include "stw_framebuffer.h"
 
 
+#define LARGE_WINDOW_SIZE 60000
+
+
+static LRESULT CALLBACK
+WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    MINMAXINFO *pMMI;
+    switch (uMsg) {
+    case WM_GETMINMAXINFO:
+        // Allow to create a window bigger than the desktop
+        pMMI = (MINMAXINFO *)lParam;
+        pMMI->ptMaxSize.x = LARGE_WINDOW_SIZE;
+        pMMI->ptMaxSize.y = LARGE_WINDOW_SIZE;
+        pMMI->ptMaxTrackSize.x = LARGE_WINDOW_SIZE;
+        pMMI->ptMaxTrackSize.y = LARGE_WINDOW_SIZE;
+        break;
+    default:
+        break;
+    }
+
+    return DefWindowProc(hWnd, uMsg, wParam, lParam);
+}
+
+
 HPBUFFERARB WINAPI
-wglCreatePbufferARB(HDC _hDC,
+wglCreatePbufferARB(HDC hCurrentDC,
                     int iPixelFormat,
                     int iWidth,
                     int iHeight,
@@ -57,8 +83,14 @@ wglCreatePbufferARB(HDC _hDC,
    RECT rect;
    HWND hWnd;
    HDC hDC;
-
-   info = stw_pixelformat_get_info(iPixelFormat);
+   int iDisplayablePixelFormat;
+   PIXELFORMATDESCRIPTOR pfd;
+   BOOL bRet;
+   int textureFormat = WGL_NO_TEXTURE_ARB;
+   int textureTarget = WGL_NO_TEXTURE_ARB;
+   BOOL textureMipmap = FALSE;
+
+   info = stw_pixelformat_get_info(iPixelFormat - 1);
    if (!info) {
       SetLastError(ERROR_INVALID_PIXEL_FORMAT);
       return 0;
@@ -69,15 +101,47 @@ wglCreatePbufferARB(HDC _hDC,
       return 0;
    }
 
-   for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
-      switch (*piAttrib) {
-      case WGL_PBUFFER_LARGEST_ARB:
-         piAttrib++;
-         useLargest = *piAttrib;
-         break;
-      default:
-         SetLastError(ERROR_INVALID_DATA);
-         return 0;
+   if (piAttribList) {
+      for (piAttrib = piAttribList; *piAttrib; piAttrib++) {
+         switch (*piAttrib) {
+         case WGL_PBUFFER_LARGEST_ARB:
+            piAttrib++;
+            useLargest = *piAttrib;
+            break;
+          case WGL_TEXTURE_FORMAT_ARB:
+             /* WGL_ARB_render_texture */
+             piAttrib++;
+             textureFormat = *piAttrib;
+             if (textureFormat != WGL_TEXTURE_RGB_ARB &&
+                textureFormat != WGL_TEXTURE_RGBA_ARB &&
+                textureFormat != WGL_NO_TEXTURE_ARB) {
+                SetLastError(ERROR_INVALID_DATA);
+                return 0;
+             }
+             break;
+          case WGL_TEXTURE_TARGET_ARB:
+             /* WGL_ARB_render_texture */
+             piAttrib++;
+             textureTarget = *piAttrib;
+             if (textureTarget != WGL_TEXTURE_CUBE_MAP_ARB &&
+                 textureTarget != WGL_TEXTURE_1D_ARB &&
+                 textureTarget != WGL_TEXTURE_2D_ARB &&
+                 textureTarget != WGL_NO_TEXTURE_ARB) {
+                SetLastError(ERROR_INVALID_DATA);
+                return 0;
+             }
+             break;
+         case WGL_MIPMAP_TEXTURE_ARB:
+            /* WGL_ARB_render_texture */
+            piAttrib++;
+            textureMipmap = !!*piAttrib;
+            break;
+         default:
+            SetLastError(ERROR_INVALID_DATA);
+            debug_printf("wgl: Unsupported attribute 0x%x in %s\n",
+                         *piAttrib, __func__);
+            return 0;
+         }
       }
    }
 
@@ -109,7 +173,7 @@ wglCreatePbufferARB(HDC _hDC,
       wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
       wc.hCursor = LoadCursor(NULL, IDC_ARROW);
       wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
-      wc.lpfnWndProc = DefWindowProc;
+      wc.lpfnWndProc = WndProc;
       wc.lpszClassName = "wglpbuffer";
       wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
       RegisterClass(&wc);
@@ -180,13 +244,34 @@ wglCreatePbufferARB(HDC _hDC,
       return 0;
    }
 
-   SetPixelFormat(hDC, iPixelFormat, &info->pfd);
-
+   /*
+    * We can't pass non-displayable pixel formats to GDI, which is why we
+    * create the framebuffer object before calling SetPixelFormat().
+    */
    fb = stw_framebuffer_create(hDC, iPixelFormat);
    if (!fb) {
       SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+      return NULL;
    }
 
+   fb->bPbuffer = TRUE;
+
+   /* WGL_ARB_render_texture fields */
+   fb->textureTarget = textureTarget;
+   fb->textureFormat = textureFormat;
+   fb->textureMipmap = textureMipmap;
+
+   iDisplayablePixelFormat = fb->iDisplayablePixelFormat;
+
+   stw_framebuffer_unlock(fb);
+
+   /*
+    * We need to set a displayable pixel format on the hidden window DC
+    * so that wglCreateContext and wglMakeCurrent are not overruled by GDI.
+    */
+   bRet = SetPixelFormat(hDC, iDisplayablePixelFormat, &pfd);
+   assert(bRet);
+
    return (HPBUFFERARB)fb;
 }
 
@@ -197,10 +282,14 @@ wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
    struct stw_framebuffer *fb;
    HDC hDC;
 
-   fb = (struct stw_framebuffer *)hPbuffer;
+   if (!hPbuffer) {
+      SetLastError(ERROR_INVALID_HANDLE);
+      return NULL;
+   }
+
+   fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
 
    hDC = GetDC(fb->hWnd);
-   SetPixelFormat(hDC, fb->iPixelFormat, &fb->pfi->pfd);
 
    return hDC;
 }
@@ -212,7 +301,12 @@ wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
 {
    struct stw_framebuffer *fb;
 
-   fb = (struct stw_framebuffer *)hPbuffer;
+   if (!hPbuffer) {
+      SetLastError(ERROR_INVALID_HANDLE);
+      return 0;
+   }
+
+   fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
 
    return ReleaseDC(fb->hWnd, hDC);
 }
@@ -223,7 +317,12 @@ wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
 {
    struct stw_framebuffer *fb;
 
-   fb = (struct stw_framebuffer *)hPbuffer;
+   if (!hPbuffer) {
+      SetLastError(ERROR_INVALID_HANDLE);
+      return FALSE;
+   }
+
+   fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
 
    /* This will destroy all our data */
    return DestroyWindow(fb->hWnd);
@@ -237,19 +336,40 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer,
 {
    struct stw_framebuffer *fb;
 
-   fb = (struct stw_framebuffer *)hPbuffer;
+   if (!hPbuffer) {
+      SetLastError(ERROR_INVALID_HANDLE);
+      return FALSE;
+   }
+
+   fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
 
    switch (iAttribute) {
    case WGL_PBUFFER_WIDTH_ARB:
       *piValue = fb->width;
       return TRUE;
    case WGL_PBUFFER_HEIGHT_ARB:
-      *piValue = fb->width;
+      *piValue = fb->height;
       return TRUE;
    case WGL_PBUFFER_LOST_ARB:
       /* We assume that no content is ever lost due to display mode change */
       *piValue = FALSE;
       return TRUE;
+   /* WGL_ARB_render_texture */
+   case WGL_TEXTURE_TARGET_ARB:
+      *piValue = fb->textureTarget;
+      return TRUE;
+   case WGL_TEXTURE_FORMAT_ARB:
+      *piValue = fb->textureFormat;
+      return TRUE;
+   case WGL_MIPMAP_TEXTURE_ARB:
+      *piValue = fb->textureMipmap;
+      return TRUE;
+   case WGL_MIPMAP_LEVEL_ARB:
+      *piValue = fb->textureLevel;
+      return TRUE;
+   case WGL_CUBE_MAP_FACE_ARB:
+      *piValue = fb->textureFace + WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
+      return TRUE;
    default:
       SetLastError(ERROR_INVALID_DATA);
       return FALSE;