summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2015-12-03 09:12:20 -0700
committerBrian Paul <[email protected]>2015-12-03 09:12:20 -0700
commite832b5b7fa196853bc61895869bd20c8b85f0ea9 (patch)
tree732d0ae1817d473f225dadd47d6ae290081a5af2 /src/gallium
parent47b9ef872b70066756e004a6dd52482ea2899d43 (diff)
st/wgl: add support for WGL_ARB_render_texture
There are a few legacy OpenGL apps on Windows which need this extension. We basically use glCopyTex[Sub]Image to implement wglBindTexImageARB (see the implementation notes for details). v2: refactor code to use st_copy_framebuffer_to_texture() helper function. Reviewed-by: José Fonseca <[email protected]> Reviewed-by: Charmaine Lee <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/state_trackers/wgl/Makefile.sources1
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c1
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pbuffer.c63
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pixelformat.c16
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.h27
-rw-r--r--src/gallium/state_trackers/wgl/stw_getprocaddress.c5
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c6
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.h4
-rw-r--r--src/gallium/state_trackers/wgl/stw_st.c5
9 files changed, 118 insertions, 10 deletions
diff --git a/src/gallium/state_trackers/wgl/Makefile.sources b/src/gallium/state_trackers/wgl/Makefile.sources
index 1e00caf97b7..2630b445d54 100644
--- a/src/gallium/state_trackers/wgl/Makefile.sources
+++ b/src/gallium/state_trackers/wgl/Makefile.sources
@@ -5,6 +5,7 @@ C_SOURCES := \
stw_ext_extensionsstring.c \
stw_ext_pbuffer.c \
stw_ext_pixelformat.c \
+ stw_ext_rendertexture.c \
stw_ext_swapinterval.c \
stw_framebuffer.c \
stw_getprocaddress.c \
diff --git a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
index a8c085a1341..86b93fb2e28 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
@@ -41,6 +41,7 @@ static const char *stw_extension_string =
"WGL_ARB_multisample "
"WGL_ARB_pbuffer "
"WGL_ARB_pixel_format "
+ "WGL_ARB_render_texture "
"WGL_EXT_create_context_es_profile "
"WGL_EXT_create_context_es2_profile "
/* "WGL_EXT_swap_interval " */
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
index c99fa3e513d..d709faa60f2 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
@@ -86,6 +86,9 @@ wglCreatePbufferARB(HDC hCurrentDC,
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) {
@@ -104,8 +107,38 @@ wglCreatePbufferARB(HDC hCurrentDC,
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;
}
}
@@ -220,6 +253,12 @@ wglCreatePbufferARB(HDC hCurrentDC,
}
fb->bPbuffer = TRUE;
+
+ /* WGL_ARB_render_texture fields */
+ fb->textureTarget = textureTarget;
+ fb->textureFormat = textureFormat;
+ fb->textureMipmap = textureMipmap;
+
iDisplayablePixelFormat = fb->iDisplayablePixelFormat;
stw_framebuffer_unlock(fb);
@@ -246,7 +285,7 @@ wglGetPbufferDCARB(HPBUFFERARB hPbuffer)
return NULL;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
hDC = GetDC(fb->hWnd);
@@ -265,7 +304,7 @@ wglReleasePbufferDCARB(HPBUFFERARB hPbuffer,
return 0;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
return ReleaseDC(fb->hWnd, hDC);
}
@@ -281,7 +320,7 @@ wglDestroyPbufferARB(HPBUFFERARB hPbuffer)
return FALSE;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
/* This will destroy all our data */
return DestroyWindow(fb->hWnd);
@@ -300,7 +339,7 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer,
return FALSE;
}
- fb = (struct stw_framebuffer *)hPbuffer;
+ fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer);
switch (iAttribute) {
case WGL_PBUFFER_WIDTH_ARB:
@@ -313,6 +352,22 @@ wglQueryPbufferARB(HPBUFFERARB hPbuffer,
/* 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;
diff --git a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
index e38086e86d7..4ee4fcdd5ad 100644
--- a/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
@@ -107,6 +107,16 @@ stw_query_attrib(
case WGL_NUMBER_UNDERLAYS_ARB:
*pvalue = 0;
return TRUE;
+
+ case WGL_BIND_TO_TEXTURE_RGB_ARB:
+ /* WGL_ARB_render_texture */
+ *pvalue = pfi->bindToTextureRGB;
+ return TRUE;
+
+ case WGL_BIND_TO_TEXTURE_RGBA_ARB:
+ /* WGL_ARB_render_texture */
+ *pvalue = pfi->bindToTextureRGBA;
+ return TRUE;
}
if (iLayerPlane != 0)
@@ -311,7 +321,11 @@ static const struct attrib_match_info attrib_match[] = {
/* WGL_ARB_multisample */
{ WGL_SAMPLE_BUFFERS_ARB, 2, FALSE },
- { WGL_SAMPLES_ARB, 2, FALSE }
+ { WGL_SAMPLES_ARB, 2, FALSE },
+
+ /* WGL_ARB_render_texture */
+ { WGL_BIND_TO_TEXTURE_RGB_ARB, 0, FALSE },
+ { WGL_BIND_TO_TEXTURE_RGBA_ARB, 0, FALSE },
};
struct stw_pixelformat_score
diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
index 109c79dd002..0e2c61ffe3e 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
@@ -30,6 +30,9 @@
#include <windows.h>
+#include <GL/gl.h>
+#include <GL/wglext.h>
+
#include "util/u_debug.h"
@@ -85,6 +88,15 @@ struct stw_framebuffer
unsigned width;
unsigned height;
+ /** WGL_ARB_render_texture - set at Pbuffer creation time */
+ unsigned textureFormat; /**< WGL_NO_TEXTURE or WGL_TEXTURE_RGB[A]_ARB */
+ unsigned textureTarget; /**< WGL_NO_TEXTURE or WGL_TEXTURE_1D/2D/
+ CUBE_MAP_ARB */
+ boolean textureMipmap; /**< TRUE/FALSE */
+ /** WGL_ARB_render_texture - set with wglSetPbufferAttribARB() */
+ unsigned textureLevel;
+ unsigned textureFace; /**< [0..6] */
+
/**
* Client area rectangle, relative to the window upper-left corner.
*
@@ -177,4 +189,19 @@ stw_framebuffer_unlock(struct stw_framebuffer *fb)
void
stw_framebuffer_cleanup(void);
+
+static inline struct stw_st_framebuffer *
+stw_st_framebuffer(struct st_framebuffer_iface *stfb)
+{
+ return (struct stw_st_framebuffer *) stfb;
+}
+
+
+static inline struct stw_framebuffer *
+stw_framebuffer_from_HPBUFFERARB(HPBUFFERARB hPbuffer)
+{
+ return (struct stw_framebuffer *) hPbuffer;
+}
+
+
#endif /* STW_FRAMEBUFFER_H */
diff --git a/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
index 28d10d2e312..66718c59eb3 100644
--- a/src/gallium/state_trackers/wgl/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
@@ -74,6 +74,11 @@ static const struct stw_extension_entry stw_extension_entries[] = {
/* WGL_ARB_create_context */
STW_EXTENSION_ENTRY( wglCreateContextAttribsARB ),
+ /* WGL_ARB_render_texture */
+ STW_EXTENSION_ENTRY( wglBindTexImageARB ),
+ STW_EXTENSION_ENTRY( wglReleaseTexImageARB ),
+ STW_EXTENSION_ENTRY( wglSetPbufferAttribARB ),
+
{ NULL, NULL }
};
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index ef6158d3645..5360a8f6036 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -205,6 +205,12 @@ stw_pixelformat_add(
pfi->stvis.samples = samples;
pfi->stvis.render_buffer = ST_ATTACHMENT_INVALID;
+ /* WGL_ARB_render_texture */
+ if (color->bits.alpha)
+ pfi->bindToTextureRGBA = TRUE;
+ else
+ pfi->bindToTextureRGB = TRUE;
+
++stw_dev->pixelformat_extended_count;
if(!extended) {
diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.h b/src/gallium/state_trackers/wgl/stw_pixelformat.h
index 58ef7442ab8..06753b09e16 100644
--- a/src/gallium/state_trackers/wgl/stw_pixelformat.h
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.h
@@ -43,6 +43,10 @@ struct stw_pixelformat_info
PIXELFORMATDESCRIPTOR pfd;
struct st_visual stvis;
+
+ /** WGL_ARB_render_texture */
+ boolean bindToTextureRGB;
+ boolean bindToTextureRGBA;
};
void
diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
index 78586db1969..20c2c8a09ca 100644
--- a/src/gallium/state_trackers/wgl/stw_st.c
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -46,11 +46,6 @@ struct stw_st_framebuffer {
unsigned texture_mask;
};
-static inline struct stw_st_framebuffer *
-stw_st_framebuffer(struct st_framebuffer_iface *stfb)
-{
- return (struct stw_st_framebuffer *) stfb;
-}
/**