summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c4
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pbuffer.c154
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pixelformat.c18
4 files changed, 169 insertions, 11 deletions
diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 37809d084ce..7227dc276ab 100644
--- a/src/gallium/state_trackers/wgl/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -96,6 +96,10 @@ stw_init(const struct stw_winsys *stw_winsys)
stw_dev->smapi->get_param = stw_get_param;
stw_dev->screen = screen;
+ stw_dev->max_2d_levels =
+ screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+ stw_dev->max_2d_length = 1 << (stw_dev->max_2d_levels - 1);
+
pipe_mutex_init( stw_dev->ctx_mutex );
pipe_mutex_init( stw_dev->fb_mutex );
diff --git a/src/gallium/state_trackers/wgl/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index 1b836960d0d..3c2b6d9c076 100644
--- a/src/gallium/state_trackers/wgl/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -50,6 +50,10 @@ struct stw_device
struct pipe_screen *screen;
+ /* Cache some PIPE_CAP_* */
+ unsigned max_2d_levels;
+ unsigned max_2d_length;
+
struct st_api *stapi;
struct st_manager *smapi;
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
index 0866d41d718..32636c603dc 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
@@ -32,24 +32,132 @@
#include <GL/gl.h>
#include <GL/wglext.h>
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+
+#include "stw_device.h"
+#include "stw_pixelformat.h"
+#include "stw_framebuffer.h"
+
HPBUFFERARB WINAPI
-wglCreatePbufferARB(HDC hDC,
+wglCreatePbufferARB(HDC _hDC,
int iPixelFormat,
int iWidth,
int iHeight,
const int *piAttribList)
{
- /* FIXME */
- return NULL;
+ static boolean first = TRUE;
+ const int *piAttrib;
+ int useLargest = 0;
+ const struct stw_pixelformat_info *info;
+ struct stw_framebuffer *fb;
+ HWND hWnd;
+ HDC hDC;
+
+ info = stw_pixelformat_get_info(iPixelFormat);
+ if (!info) {
+ SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+ return 0;
+ }
+
+ if (iWidth <= 0 || iHeight <= 0) {
+ SetLastError(ERROR_INVALID_DATA);
+ 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 (iWidth > stw_dev->max_2d_length) {
+ if (useLargest) {
+ iWidth = stw_dev->max_2d_length;
+ } else {
+ SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+ }
+
+ if (iHeight > stw_dev->max_2d_length) {
+ if (useLargest) {
+ iHeight = stw_dev->max_2d_length;
+ } else {
+ SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ return 0;
+ }
+ }
+
+ /*
+ * Implement pbuffers through invisible windows
+ */
+
+ if (first) {
+ WNDCLASS wc;
+ memset(&wc, 0, sizeof wc);
+ wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wc.lpfnWndProc = DefWindowProc;
+ wc.lpszClassName = "wglpbuffer";
+ wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
+ RegisterClass(&wc);
+ first = FALSE;
+ }
+
+ hWnd = CreateWindowEx(0,
+ "wglpbuffer", /* wc.lpszClassName */
+ "wglpbuffer",
+#if 0 /* Useful for debugging what the application is drawing */
+ WS_VISIBLE |
+#endif
+ WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
+ CW_USEDEFAULT, CW_USEDEFAULT, /* x, y */
+ iWidth, iHeight,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (!hWnd) {
+ return 0;
+ }
+
+ hDC = GetDC(hWnd);
+ if (!hDC) {
+ return 0;
+ }
+
+ SetPixelFormat(hDC, iPixelFormat, &info->pfd);
+
+ fb = stw_framebuffer_create(hDC, iPixelFormat);
+ if (!fb) {
+ SetLastError(ERROR_NO_SYSTEM_RESOURCES);
+ }
+
+ return (HPBUFFERARB)fb;
}
HDC WINAPI
wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
{
- /* FIXME */
- return NULL;
+ struct stw_framebuffer *fb;
+ HDC hDC;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ hDC = GetDC(fb->hWnd);
+ SetPixelFormat(hDC, fb->iPixelFormat, &fb->pfi->pfd);
+
+ return hDC;
}
@@ -57,16 +165,23 @@ int WINAPI
wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
HDC hDC)
{
- /* FIXME */
- return 0;
+ struct stw_framebuffer *fb;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ return ReleaseDC(fb->hWnd, hDC);
}
BOOL WINAPI
wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
{
- /* FIXME */
- return FALSE;
+ struct stw_framebuffer *fb;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ /* This will destroy all our data */
+ return DestroyWindow(fb->hWnd);
}
@@ -75,6 +190,23 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer,
int iAttribute,
int *piValue)
{
- /* FIXME */
- return FALSE;
+ struct stw_framebuffer *fb;
+
+ fb = (struct stw_framebuffer *)hPbuffer;
+
+ switch (iAttribute) {
+ case WGL_PBUFFER_WIDTH_ARB:
+ *piValue = fb->width;
+ return TRUE;
+ case WGL_PBUFFER_HEIGHT_ARB:
+ *piValue = fb->width;
+ return TRUE;
+ case WGL_PBUFFER_LOST_ARB:
+ /* We assume that no content is ever lost due to display mode change */
+ *piValue = FALSE;
+ return TRUE;
+ default:
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
}
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
index ab56800e28d..d0a95863bb4 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
@@ -43,6 +43,7 @@
#include "pipe/p_compiler.h"
#include "util/u_memory.h"
+#include "stw_device.h"
#include "stw_pixelformat.h"
@@ -234,6 +235,23 @@ stw_query_attrib(
*pvalue = pfi->stvis.samples;
break;
+
+ /* WGL_ARB_pbuffer */
+
+ case WGL_MAX_PBUFFER_WIDTH_ARB:
+ case WGL_MAX_PBUFFER_HEIGHT_ARB:
+ *pvalue = stw_dev->max_2d_length;
+ break;
+
+ case WGL_MAX_PBUFFER_PIXELS_ARB:
+ *pvalue = stw_dev->max_2d_length * stw_dev->max_2d_length;
+ break;
+
+ case WGL_DRAW_TO_PBUFFER_ARB:
+ *pvalue = 1;
+ break;
+
+
default:
return FALSE;
}