summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c77
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.h5
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_context.c15
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c1
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_rendertexture.c5
-rw-r--r--src/gallium/state_trackers/wgl/stw_getprocaddress.c3
-rw-r--r--src/gallium/state_trackers/wgl/stw_wgl.c7
-rw-r--r--src/gallium/state_trackers/wgl/stw_wgl.h10
8 files changed, 107 insertions, 16 deletions
diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c
index 85cffa63529..18273ac3e95 100644
--- a/src/gallium/state_trackers/wgl/stw_context.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -187,6 +187,7 @@ stw_create_context_attribs(HDC hdc, INT iLayerPlane, DHGLRC hShareContext,
goto no_ctx;
ctx->hdc = hdc;
+ ctx->hReadDC = hdc;
ctx->iPixelFormat = iPixelFormat;
ctx->shared = shareCtx != NULL;
@@ -357,7 +358,7 @@ DrvReleaseContext(DHGLRC dhglrc)
if (ctx != stw_current_context())
return FALSE;
- if (stw_make_current( NULL, 0 ) == FALSE)
+ if (stw_make_current( NULL, NULL, 0 ) == FALSE)
return FALSE;
return TRUE;
@@ -389,9 +390,20 @@ stw_get_current_dc( void )
return ctx->hdc;
}
+HDC
+stw_get_current_read_dc( void )
+{
+ struct stw_context *ctx;
+
+ ctx = stw_current_context();
+ if (!ctx)
+ return NULL;
+
+ return ctx->hReadDC;
+}
BOOL
-stw_make_current(HDC hdc, DHGLRC dhglrc)
+stw_make_current(HDC hdc, HDC hReadDC, DHGLRC dhglrc)
{
struct stw_context *old_ctx = NULL;
struct stw_context *ctx = NULL;
@@ -403,7 +415,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
old_ctx = stw_current_context();
if (old_ctx != NULL) {
if (old_ctx->dhglrc == dhglrc) {
- if (old_ctx->hdc == hdc) {
+ if (old_ctx->hdc == hdc && old_ctx->hReadDC == hReadDC) {
/* Return if already current. */
return TRUE;
}
@@ -421,6 +433,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
if (dhglrc) {
struct stw_framebuffer *fb = NULL;
+ struct stw_framebuffer *fbRead = NULL;
stw_lock_contexts(stw_dev);
ctx = stw_lookup_context_locked( dhglrc );
stw_unlock_contexts(stw_dev);
@@ -454,6 +467,7 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
/* Bind the new framebuffer */
ctx->hdc = hdc;
+ ctx->hReadDC = hReadDC;
struct stw_framebuffer *old_fb = ctx->current_framebuffer;
if (old_fb != fb) {
@@ -462,12 +476,47 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
}
stw_framebuffer_unlock(fb);
- /* Note: when we call this function we will wind up in the
- * stw_st_framebuffer_validate_locked() function which will incur
- * a recursive fb->mutex lock.
- */
- ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
- fb->stfb, fb->stfb);
+ if (hReadDC) {
+ if (hReadDC == hDrawDC) {
+ fbRead = fb;
+ }
+ else {
+ fbRead = stw_framebuffer_from_hdc( hReadDC );
+
+ if (fbRead) {
+ stw_framebuffer_update(fbRead);
+ }
+ else {
+ /* Applications should call SetPixelFormat before creating a
+ * context, but not all do, and the opengl32 runtime seems to
+ * use a default pixel format in some cases, so we must create
+ * a framebuffer for those here.
+ */
+ int iPixelFormat = GetPixelFormat(hReadDC);
+ if (iPixelFormat)
+ fbRead = stw_framebuffer_create( hReadDC, iPixelFormat );
+ if (!fbRead)
+ goto fail;
+ }
+
+ if (fbRead->iPixelFormat != ctx->iPixelFormat) {
+ stw_framebuffer_unlock(fbRead);
+ SetLastError(ERROR_INVALID_PIXEL_FORMAT);
+ goto fail;
+ }
+ stw_framebuffer_unlock(fbRead);
+ }
+ ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
+ fb->stfb, fbRead->stfb);
+ }
+ else {
+ /* Note: when we call this function we will wind up in the
+ * stw_st_framebuffer_validate_locked() function which will incur
+ * a recursive fb->mutex lock.
+ */
+ ret = stw_dev->stapi->make_current(stw_dev->stapi, ctx->st,
+ fb->stfb, fb->stfb);
+ }
if (old_fb && old_fb != fb) {
stw_lock_framebuffers(stw_dev);
@@ -477,14 +526,16 @@ stw_make_current(HDC hdc, DHGLRC dhglrc)
}
fail:
- /* fb must be unlocked at this point. */
- assert(!stw_own_mutex(&fb->mutex));
+ if (fb) {
+ /* fb must be unlocked at this point. */
+ assert(!stw_own_mutex(&fb->mutex));
+ }
/* On failure, make the thread's current rendering context not current
* before returning.
*/
if (!ret) {
- stw_make_current(NULL, 0);
+ stw_make_current(NULL, NULL, 0);
}
} else {
ret = stw_dev->stapi->make_current(stw_dev->stapi, NULL, NULL, NULL);
@@ -870,7 +921,7 @@ DrvSetContext(HDC hdc, DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable)
{
PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
- if (!stw_make_current(hdc, dhglrc))
+ if (!stw_make_current(hdc, hdc, dhglrc))
r = NULL;
return r;
diff --git a/src/gallium/state_trackers/wgl/stw_context.h b/src/gallium/state_trackers/wgl/stw_context.h
index 0f180c8e2ec..d0e7f2c9f94 100644
--- a/src/gallium/state_trackers/wgl/stw_context.h
+++ b/src/gallium/state_trackers/wgl/stw_context.h
@@ -40,6 +40,7 @@ struct stw_context
DHGLRC dhglrc;
int iPixelFormat;
HDC hdc;
+ HDC hReadDC;
BOOL shared;
struct stw_framebuffer *current_framebuffer;
@@ -59,7 +60,9 @@ struct stw_context *stw_current_context(void);
HDC stw_get_current_dc( void );
-BOOL stw_make_current( HDC hdc, DHGLRC dhglrc );
+HDC stw_get_current_read_dc( void );
+
+BOOL stw_make_current( HDC hdc, HDC hReadDC, DHGLRC dhglrc );
void stw_notify_current_locked( struct stw_framebuffer *fb );
diff --git a/src/gallium/state_trackers/wgl/stw_ext_context.c b/src/gallium/state_trackers/wgl/stw_ext_context.c
index 4c58316a0e1..6326d20ba82 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_context.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_context.c
@@ -195,3 +195,18 @@ wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList)
return context;
}
+
+
+/** Defined by WGL_ARB_make_current_read */
+BOOL APIENTRY
+wglMakeContextCurrentARB(HDC hDrawDC, HDC hReadDC, HGLRC hglrc)
+{
+ DHGLRC dhglrc = 0;
+
+ if (stw_dev && stw_dev->callbacks.wglCbGetDhglrc) {
+ /* Convert HGLRC to DHGLRC */
+ dhglrc = stw_dev->callbacks.wglCbGetDhglrc(hglrc);
+ }
+
+ return stw_make_current(hDrawDC, hReadDC, dhglrc);
+}
diff --git a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
index 86b93fb2e28..06af8b1e994 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
@@ -44,6 +44,7 @@ static const char *stw_extension_string =
"WGL_ARB_render_texture "
"WGL_EXT_create_context_es_profile "
"WGL_EXT_create_context_es2_profile "
+ "WGL_ARB_make_current_read "
/* "WGL_EXT_swap_interval " */
"WGL_EXT_extensions_string";
diff --git a/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c b/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
index 9d766966771..5503102bc98 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_rendertexture.c
@@ -104,6 +104,7 @@ BOOL WINAPI
wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
{
HDC prevDrawable = stw_get_current_dc();
+ HDC prevReadable = stw_get_current_read_dc();
HDC dc;
struct stw_context *curctx = stw_current_context();
struct stw_framebuffer *fb;
@@ -172,7 +173,7 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
pixelFormatSave = fb->iPixelFormat;
fb->iPixelFormat = curctx->iPixelFormat;
dc = wglGetPbufferDCARB(hPbuffer);
- retVal = stw_make_current(dc, curctx->dhglrc);
+ retVal = stw_make_current(dc, dc, curctx->dhglrc);
fb->iPixelFormat = pixelFormatSave;
if (!retVal) {
debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n");
@@ -185,7 +186,7 @@ wglBindTexImageARB(HPBUFFERARB hPbuffer, int iBuffer)
fb->textureFace, texFormat);
/* rebind previous drawing surface */
- retVal = stw_make_current(prevDrawable, curctx->dhglrc);
+ retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc);
if (!retVal) {
debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n");
}
diff --git a/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
index 66718c59eb3..9273d103310 100644
--- a/src/gallium/state_trackers/wgl/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
@@ -79,6 +79,9 @@ static const struct stw_extension_entry stw_extension_entries[] = {
STW_EXTENSION_ENTRY( wglReleaseTexImageARB ),
STW_EXTENSION_ENTRY( wglSetPbufferAttribARB ),
+ /* WGL_ARB_make_current_read */
+ STW_EXTENSION_ENTRY( wglMakeContextCurrentARB ),
+ STW_EXTENSION_ENTRY( wglGetCurrentReadDCARB ),
{ NULL, NULL }
};
diff --git a/src/gallium/state_trackers/wgl/stw_wgl.c b/src/gallium/state_trackers/wgl/stw_wgl.c
index 5146e6a5b79..de4b4f6f3b0 100644
--- a/src/gallium/state_trackers/wgl/stw_wgl.c
+++ b/src/gallium/state_trackers/wgl/stw_wgl.c
@@ -99,6 +99,13 @@ wglGetCurrentDC( VOID )
return stw_get_current_dc();
}
+WINGDIAPI HDC APIENTRY
+wglGetCurrentReadDCARB( VOID )
+{
+ return stw_get_current_read_dc();
+}
+
+
WINGDIAPI BOOL APIENTRY
wglMakeCurrent(
HDC hdc,
diff --git a/src/gallium/state_trackers/wgl/stw_wgl.h b/src/gallium/state_trackers/wgl/stw_wgl.h
index 31a391d960e..92d70b5da9e 100644
--- a/src/gallium/state_trackers/wgl/stw_wgl.h
+++ b/src/gallium/state_trackers/wgl/stw_wgl.h
@@ -59,6 +59,16 @@ wglSetPixelFormat(HDC hdc,
int iPixelFormat,
CONST PIXELFORMATDESCRIPTOR *ppfd);
+WINGDIAPI HDC APIENTRY
+wglGetCurrentReadDCARB( VOID );
+
+WINGDIAPI BOOL APIENTRY
+wglMakeContextCurrentARB(
+ HDC hDrawDC,
+ HDC hReadDC,
+ HGLRC hglrc );
+
+
#ifndef WGL_SWAPMULTIPLE_MAX
typedef struct _WGLSWAP