From e832b5b7fa196853bc61895869bd20c8b85f0ea9 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 3 Dec 2015 09:12:20 -0700 Subject: st/wgl: add support for WGL_ARB_render_texture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Charmaine Lee --- src/gallium/state_trackers/wgl/Makefile.sources | 1 + .../state_trackers/wgl/stw_ext_extensionsstring.c | 1 + src/gallium/state_trackers/wgl/stw_ext_pbuffer.c | 63 ++++++++++++++++++++-- .../state_trackers/wgl/stw_ext_pixelformat.c | 16 +++++- src/gallium/state_trackers/wgl/stw_framebuffer.h | 27 ++++++++++ .../state_trackers/wgl/stw_getprocaddress.c | 5 ++ src/gallium/state_trackers/wgl/stw_pixelformat.c | 6 +++ src/gallium/state_trackers/wgl/stw_pixelformat.h | 4 ++ src/gallium/state_trackers/wgl/stw_st.c | 5 -- 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 +#include +#include + #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; -} /** -- cgit v1.2.3