diff options
Diffstat (limited to 'src/gallium/state_trackers')
-rw-r--r-- | src/gallium/state_trackers/wgl/stw_device.c | 4 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/stw_device.h | 4 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/stw_ext_pbuffer.c | 154 | ||||
-rw-r--r-- | src/gallium/state_trackers/wgl/stw_ext_pixelformat.c | 18 |
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; } |