diff options
author | Marek Olšák <marek.olsak@amd.com> | 2019-12-03 18:01:31 -0500 |
---|---|---|
committer | Marek Olšák <marek.olsak@amd.com> | 2020-05-13 13:46:53 -0400 |
commit | d6287a94b697ffe12a4e576a38943cdf4e90cdb0 (patch) | |
tree | bb84357d98dc74412e983693e09875bb355b467e /src/gallium/frontends/wgl/stw_ext_rendertexture.c | |
parent | b408734e5e2fe1e1ef08080c4425ad8a7ed33579 (diff) |
gallium: rename 'state tracker' to 'frontend'
Acked-by: Eric Anholt <eric@anholt.net>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4902>
Diffstat (limited to 'src/gallium/frontends/wgl/stw_ext_rendertexture.c')
-rw-r--r-- | src/gallium/frontends/wgl/stw_ext_rendertexture.c | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/src/gallium/frontends/wgl/stw_ext_rendertexture.c b/src/gallium/frontends/wgl/stw_ext_rendertexture.c new file mode 100644 index 00000000000..48b2b1f61a4 --- /dev/null +++ b/src/gallium/frontends/wgl/stw_ext_rendertexture.c @@ -0,0 +1,264 @@ +/************************************************************************** + * Copyright 2015 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include <windows.h> + +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + +#include "state_tracker/st_copytex.h" + +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" +#include "pipe/p_state.h" + +#include "gldrv.h" +#include "stw_context.h" +#include "stw_device.h" +#include "stw_pixelformat.h" +#include "stw_framebuffer.h" +#include "stw_st.h" + + +/** Translate a WGL buffer name to a GLenum */ +static GLenum +translate_ibuffer(int iBuffer) +{ + switch (iBuffer) { + case WGL_FRONT_LEFT_ARB: + return GL_FRONT_LEFT; + case WGL_BACK_LEFT_ARB: + return GL_BACK_LEFT; + case WGL_FRONT_RIGHT_ARB: + return GL_FRONT_RIGHT; + case WGL_BACK_RIGHT_ARB: + return GL_BACK_RIGHT; + case WGL_AUX0_ARB: + return GL_AUX0; + default: + return GL_NONE; + } +} + + +/** Translate a WGL texture target type to a GLenum */ +static GLenum +translate_target(unsigned textureTarget) +{ + switch (textureTarget) { + case WGL_TEXTURE_1D_ARB: + return GL_TEXTURE_1D; + case WGL_TEXTURE_2D_ARB: + return GL_TEXTURE_2D; + case WGL_TEXTURE_CUBE_MAP_ARB: + return GL_TEXTURE_CUBE_MAP; + case WGL_NO_TEXTURE_ARB: + default: + return GL_NONE; + } +} + + +/** Translate a WGL texture format to a GLenum */ +static GLenum +translate_texture_format(unsigned wgl_format) +{ + switch (wgl_format) { + case WGL_TEXTURE_RGB_ARB: + return GL_RGB; + case WGL_TEXTURE_RGBA_ARB: + return GL_RGBA; + case WGL_NO_TEXTURE_ARB: + default: + return GL_NONE; + } +} + + +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; + GLenum texFormat, srcBuffer, target; + boolean retVal; + int pixelFormatSave; + + /* + * Implementation notes: + * Ideally, we'd implement this function with the + * st_context_iface::teximage() function which replaces a specific + * texture image with a different resource (the pbuffer). + * The main problem however, is the pbuffer image is upside down relative + * to the texture image. + * Window system drawing surfaces (windows & pbuffers) are "top to bottom" + * while OpenGL texture images are "bottom to top". One possible solution + * to this is to invert rendering to pbuffers (as we do for renderbuffers) + * but that could lead to other issues (and would require extensive + * testing). + * + * The simple alternative is to use a copy-based approach which copies the + * pbuffer image into the texture via glCopyTex[Sub]Image. That's what + * we do here. + */ + + if (!curctx) { + debug_printf("No rendering context in wglBindTexImageARB()\n"); + SetLastError(ERROR_INVALID_OPERATION); + return FALSE; + } + + fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer); + if (!fb) { + debug_printf("Invalid pbuffer handle in wglBindTexImageARB()\n"); + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + srcBuffer = translate_ibuffer(iBuffer); + if (srcBuffer == GL_NONE) { + debug_printf("Invalid buffer 0x%x in wglBindTexImageARB()\n", iBuffer); + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } + + target = translate_target(fb->textureTarget); + if (target == GL_NONE) { + debug_printf("no texture target in wglBindTexImageARB()\n"); + return FALSE; + } + + texFormat = translate_texture_format(fb->textureFormat); + if (texFormat == GL_NONE) { + debug_printf("no texture format in wglBindTexImageARB()\n"); + return FALSE; + } + + /* + * Bind the pbuffer surface so we can read/copy from it. + * + * Before we can call stw_make_current() we have to temporarily + * change the pbuffer's pixel format to match the context to avoid + * an error condition. After the stw_make_current() we restore the + * buffer's pixel format. + */ + pixelFormatSave = fb->iPixelFormat; + fb->iPixelFormat = curctx->iPixelFormat; + dc = wglGetPbufferDCARB(hPbuffer); + retVal = stw_make_current(dc, dc, curctx->dhglrc); + fb->iPixelFormat = pixelFormatSave; + if (!retVal) { + debug_printf("stw_make_current(#1) failed in wglBindTexImageARB()\n"); + wglReleasePbufferDCARB(hPbuffer, dc); + return FALSE; + } + + st_copy_framebuffer_to_texture(srcBuffer, fb->width, fb->height, + target, fb->textureLevel, + fb->textureFace, texFormat); + + /* rebind previous drawing surface */ + retVal = stw_make_current(prevDrawable, prevReadable, curctx->dhglrc); + if (!retVal) { + debug_printf("stw_make_current(#2) failed in wglBindTexImageARB()\n"); + } + + wglReleasePbufferDCARB(hPbuffer, dc); + + return retVal; +} + + +BOOL WINAPI +wglReleaseTexImageARB(HPBUFFERARB hPbuffer, int iBuffer) +{ + struct stw_framebuffer *fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer); + GLenum srcBuffer; + + /* nothing to do here, but we do error checking anyway */ + + if (!fb) { + debug_printf("Invalid pbuffer handle in wglReleaseTexImageARB()\n"); + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + srcBuffer = translate_ibuffer(iBuffer); + if (srcBuffer == GL_NONE) { + debug_printf("Invalid buffer 0x%x in wglReleaseTexImageARB()\n", iBuffer); + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } + + return TRUE; +} + + +BOOL WINAPI +wglSetPbufferAttribARB(HPBUFFERARB hPbuffer, const int *piAttribList) +{ + struct stw_framebuffer *fb = stw_framebuffer_from_HPBUFFERARB(hPbuffer); + int face, i; + + if (!fb) { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + for (i = 0; piAttribList[i]; i += 2) { + switch (piAttribList[i]) { + case WGL_MIPMAP_LEVEL_ARB: + fb->textureLevel = piAttribList[i+1]; + break; + case WGL_CUBE_MAP_FACE_ARB: + face = piAttribList[i+1]; + if (face >= WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB && + face <= WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB) { + fb->textureFace = face - WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + } + else { + debug_printf("Invalid cube face 0x%x in " + "wglSetPbufferAttribARB()\n", + piAttribList[i]); + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } + break; + default: + debug_printf("Invalid attribute 0x%x in wglSetPbufferAttribARB()\n", + piAttribList[i]); + SetLastError(ERROR_INVALID_DATA); + return FALSE; + } + } + + return TRUE; +} |