st/wgl: add support for WGL_ARB_render_texture
authorBrian Paul <brianp@vmware.com>
Thu, 3 Dec 2015 16:12:20 +0000 (09:12 -0700)
committerBrian Paul <brianp@vmware.com>
Thu, 3 Dec 2015 16:12:20 +0000 (09:12 -0700)
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 <jfonseca@vmware.com>
Reviewed-by: Charmaine Lee <charmainel@vmware.com>
src/gallium/state_trackers/wgl/Makefile.sources
src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
src/gallium/state_trackers/wgl/stw_ext_pbuffer.c
src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
src/gallium/state_trackers/wgl/stw_framebuffer.h
src/gallium/state_trackers/wgl/stw_getprocaddress.c
src/gallium/state_trackers/wgl/stw_pixelformat.c
src/gallium/state_trackers/wgl/stw_pixelformat.h
src/gallium/state_trackers/wgl/stw_st.c

index 1e00caf97b700f2bccef4e9501f92a46c475ccee..2630b445d54246bed59b6a901f51b09ff81185db 100644 (file)
@@ -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 \
index a8c085a1341fd8b2250fc1ad27ecb0245099cb3b..86b93fb2e28e902a4e2c9c2b3ef81d4f78a74692 100644 (file)
@@ -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 " */
index c99fa3e513d5b8909c71421c6fc57a76d68b2ebf..d709faa60f24e2a1b70f77ee56f0989df67e49cb 100644 (file)
@@ -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;
index e38086e86d78b9f3558bfd749a35bb683a0af272..4ee4fcdd5adf5f7ce2d05b5acd663cdb516548c9 100644 (file)
@@ -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
index 109c79dd002eb3850a831ed68e3ba557d2847004..0e2c61ffe3eaae73eedfcdb6b4d9a2c6e5dc5024 100644 (file)
@@ -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 */
index 28d10d2e31212a9ef27e2f4f4ba76d49b14a42e0..66718c59eb39d28a79ee3851c0ae2b487910060e 100644 (file)
@@ -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 }
 };
 
index ef6158d36452b0d2dcfca2af1160bd1d0fa94f56..5360a8f6036f39a4f203ba620f60c122de2a5e65 100644 (file)
@@ -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) {
index 58ef7442ab8597b7c58604e7afa240e1b1303e4a..06753b09e1617afe4a9bb57912c8dfdc734b7bd1 100644 (file)
@@ -43,6 +43,10 @@ struct stw_pixelformat_info
    PIXELFORMATDESCRIPTOR pfd;
    
    struct st_visual stvis;
+
+   /** WGL_ARB_render_texture */
+   boolean bindToTextureRGB;
+   boolean bindToTextureRGBA;
 };
 
 void
index 78586db196941ed1ab402dc1456cf50fa0921640..20c2c8a09ca6f1356b51371e98a11b41f22f8d18 100644 (file)
@@ -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;
-}
 
 
 /**