[WINED3D 1] Rework shader mode selection

Ivan Gyurdiev ivg231 at gmail.com
Tue Jul 4 02:21:53 CDT 2006


Yes, it's been changed a million times, but I think there's a lot of 
room for improvement.

Changes:

- currently half the shader selection code (GLSL vs ARB) is in 
fillGLcaps. The parts that check for software shaders are in 
GetDeviceCaps. That placement, will work, but is definitely not optimal. 
FillGLcaps should detect support - it should not make decision as to 
what's used, because that's not what the purpose of the function is. 
GetDeviceCaps should report support as it has already been selected. 
Instead, select shader mode in its own function, called in the 
appropriate places.

- unifying pixel and vertex shaders into a single selection is a 
mistake. A software vertex shader can be coupled with a hardware arb or 
glsl pixel shader, or no shader at all. Split them back into two and add 
a SHADER_NONE variant.

- drawprim is doing support checks for ARB_PROGRAM, and making shader 
decisions based on that - that's wrong, support has already been 
checked, and decided upon, and shaders can be implemented via software, 
ARB_PROGRAm or GLSL, so that support check isn't valid.

- Store the shader selected mode into the shader itself. Different types 
of shaders can be combined, so this is an improvement. In fact, storing 
the mode into the settings globally is a mistake as well - it should be 
done per device, since different cards have different capabilities.

-------------- next part --------------
---
 dlls/wined3d/baseshader.c      |   13 ++++-
 dlls/wined3d/device.c          |    4 +-
 dlls/wined3d/directx.c         |   95 ++++++++++++++++++++++++++--------------
 dlls/wined3d/drawprim.c        |   38 ++++++++--------
 dlls/wined3d/pixelshader.c     |    9 ++--
 dlls/wined3d/vertexshader.c    |   10 +++-
 dlls/wined3d/wined3d_private.h |    8 +++
 7 files changed, 108 insertions(+), 69 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index a1b987f..a0ea438 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -747,9 +747,14 @@ void shader_generate_main(
             /* Read opcode */
             opcode_token = *pToken++;
             curOpcode = shader_get_opcode(iface, opcode_token);
-            hw_fct = (curOpcode == NULL)? NULL:
-                     (wined3d_settings.shader_mode == SHADER_GLSL)?
-                         curOpcode->hw_glsl_fct : curOpcode->hw_fct;
+
+            /* Select handler */
+            if (curOpcode == NULL)
+                hw_fct = NULL;
+            else if (This->baseShader.shader_mode == SHADER_GLSL)
+                hw_fct = curOpcode->hw_glsl_fct;
+            else if (This->baseShader.shader_mode == SHADER_ARB)
+                hw_fct = curOpcode->hw_fct;
 
             /* Unknown opcode and its parameters */
             if (NULL == curOpcode) {
@@ -802,7 +807,7 @@ void shader_generate_main(
                 hw_fct(&hw_arg);
 
                 /* Process instruction modifiers for GLSL apps ( _sat, etc. ) */
-                if (wined3d_settings.shader_mode == SHADER_GLSL)
+                if (This->baseShader.shader_mode == SHADER_GLSL)
                     shader_glsl_add_instruction_modifiers(&hw_arg);
 
             /* Unhandled opcode */
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 6b2ae6e..2d6a1f3 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -567,9 +567,9 @@ static ULONG WINAPI IWineD3DDeviceImpl_R
         ** ***************************/
 
         /* Delete any GLSL shader programs that may exist */
-        if (wined3d_settings.shader_mode == SHADER_GLSL) {
+        if (wined3d_settings.vs_selected_mode == SHADER_GLSL ||
+            wined3d_settings.ps_selected_mode == SHADER_GLSL)
             delete_glsl_shader_list(iface);
-        }
     
         /* Release the update stateblock */
         if(IWineD3DStateBlock_Release((IWineD3DStateBlock *)This->updateStateBlock) > 0){
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index e7d225b..ae0ea82 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -199,6 +199,43 @@ static ULONG WINAPI IWineD3DImpl_Release
     return ref;
 }
 
+/* Set the shader type for this device, depending on the given capabilities,
+ * the device type, and the user preferences in wined3d_settings */
+
+static void select_shader_mode(
+    WineD3D_GL_Info *gl_info,
+    WINED3DDEVTYPE DeviceType,
+    int* ps_selected,
+    int* vs_selected) {
+
+    /* Give priority to user disable/emulation request.
+     * Then respect REF device for software.
+     * Then check capabilities for hardware, and fallback to software */
+
+    if (wined3d_settings.vs_mode == VS_NONE)
+        *vs_selected = SHADER_NONE;
+    else if (DeviceType == WINED3DDEVTYPE_REF || wined3d_settings.vs_mode == VS_SW)
+        *vs_selected = SHADER_SW;
+    else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested)
+        *vs_selected = SHADER_GLSL;
+    else if (gl_info->supported[ARB_VERTEX_PROGRAM])
+        *vs_selected = SHADER_ARB;
+    else
+        *vs_selected = SHADER_SW;
+
+    /* Fallback to SHADER_NONE where software pixel shaders should be used */
+    if (wined3d_settings.ps_mode == PS_NONE)
+        *ps_selected = SHADER_NONE;
+    else if (DeviceType == WINED3DDEVTYPE_REF)
+        *ps_selected = SHADER_NONE;
+    else if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested)
+        *ps_selected = SHADER_GLSL;
+    else if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
+        *ps_selected = SHADER_ARB;
+    else
+        *ps_selected = SHADER_NONE;
+}
+
 /**********************************************************
  * IWineD3D parts follows
  **********************************************************/
@@ -752,17 +789,6 @@ #define USE_GL_FUNC(type, pfn) gl_info->
     GLX_EXT_FUNCS_GEN;
 #undef USE_GL_FUNC
 
-    /* Determine shader mode to use based on GL caps */
-    if (gl_info->supported[ARB_SHADING_LANGUAGE_100] && wined3d_settings.glslRequested
-        && (wined3d_settings.vs_mode == VS_HW || wined3d_settings.ps_mode == PS_HW))
-        wined3d_settings.shader_mode = SHADER_GLSL;
-    else if ((gl_info->supported[ARB_VERTEX_PROGRAM] && wined3d_settings.vs_mode == VS_HW) ||
-              (gl_info->supported[ARB_FRAGMENT_PROGRAM] && wined3d_settings.ps_mode == PS_HW))
-        wined3d_settings.shader_mode = SHADER_ARB;
-    else
-        wined3d_settings.shader_mode = SHADER_SW;
-
-
     /* If we created a dummy context, throw it away */
     if (NULL != fake_ctx) WineD3D_ReleaseFakeGLContext(fake_ctx);
 
@@ -1467,6 +1493,8 @@ static HRESULT WINAPI IWineD3DImpl_GetDe
         return WINED3DERR_INVALIDCALL;
     }
 
+    /* FIXME: both the gl_info and the shader_mode should be made per adapter */
+
     /* If we don't know the device settings, go query them now */
     if (This->isGLInfoValid == FALSE) {
         /* use the desktop window to fill gl caps */
@@ -1474,8 +1502,9 @@ static HRESULT WINAPI IWineD3DImpl_GetDe
 
         /* We are running off a real context, save the values */
         if (rc) This->isGLInfoValid = TRUE;
-
     }
+    select_shader_mode(&This->gl_info, DeviceType,
+        &wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
 
     /* ------------------------------------------------
        The following fields apply to both d3d8 and d3d9
@@ -1718,19 +1747,16 @@ #endif
     *pCaps->MaxStreams          = MAX_STREAMS;
     *pCaps->MaxStreamStride     = 1024;
 
-    if (wined3d_settings.vs_mode == VS_HW && wined3d_settings.shader_mode == SHADER_GLSL
-         && DeviceType != WINED3DDEVTYPE_REF) {
+    /* FIXME: the shader mode should be per adapter */
+    if (wined3d_settings.vs_selected_mode == SHADER_GLSL) {
         *pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
-        TRACE_(d3d_caps)("Hardware vertex shader versions 2.0+ enabled\n");
-         } else if (wined3d_settings.vs_mode == VS_HW
-                    && wined3d_settings.shader_mode == SHADER_ARB
-                    && DeviceType != WINED3DDEVTYPE_REF) {
+        TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n");
+    } else if (wined3d_settings.vs_selected_mode == SHADER_ARB) {
         *pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
-        TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled\n");
-    } else if (wined3d_settings.vs_mode == VS_SW || DeviceType == WINED3DDEVTYPE_REF) {
-        /* FIXME: Change the following line (when needed) to reflect the reported software vertex shader version implemented */
-        *pCaps->VertexShaderVersion = D3DVS_VERSION(1,1);
-        TRACE_(d3d_caps)("Software vertex shader version 1.1 enabled\n");
+        TRACE_(d3d_caps)("Hardware vertex shader version 1.1 enabled (ARB_PROGRAM)\n");
+    } else if (wined3d_settings.vs_selected_mode == SHADER_SW) {
+        *pCaps->VertexShaderVersion = D3DVS_VERSION(3,0);
+        TRACE_(d3d_caps)("Software vertex shader version 3.0 enabled\n");
     } else {
         *pCaps->VertexShaderVersion  = 0;
         TRACE_(d3d_caps)("Vertex shader functionality not available\n");
@@ -1742,23 +1768,21 @@ #endif
         *pCaps->MaxVertexShaderConst = WINED3D_VSHADER_MAX_CONSTANTS;
     }
 
-    if (wined3d_settings.ps_mode == PS_HW && wined3d_settings.shader_mode == SHADER_GLSL
-        && DeviceType != WINED3DDEVTYPE_REF) {
+    /* FIXME: the shader ode should be per adapter */
+    if (wined3d_settings.ps_selected_mode == SHADER_GLSL) {
         *pCaps->PixelShaderVersion = D3DPS_VERSION(3,0);
         /* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */
         *pCaps->PixelShader1xMaxValue = 1.0;
-        TRACE_(d3d_caps)("Hardware pixel shader versions 2.0+ enabled\n");
-        } else if (wined3d_settings.ps_mode == PS_HW
-                   && wined3d_settings.shader_mode == SHADER_ARB
-                   && DeviceType != WINED3DDEVTYPE_REF) {
+        TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n");
+    } else if (wined3d_settings.ps_selected_mode == SHADER_ARB) {
         *pCaps->PixelShaderVersion    = D3DPS_VERSION(1,4);
         *pCaps->PixelShader1xMaxValue = 1.0;
-        TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled\n");
-    /* FIXME: Uncomment this when there is support for software Pixel Shader 1.4 and PS_SW is defined
-    } else if (wined3d_settings.ps_mode == PS_SW || DeviceType == WINED3DDEVTYPE_REF) {
-        *pCaps->PixelShaderVersion    = D3DPS_VERSION(1,4);
+        TRACE_(d3d_caps)("Hardware pixel shader version 1.4 enabled (ARB_PROGRAM)\n");
+    /* FIXME: Uncomment this when there is support for software Pixel Shader 3.0 and PS_SW is defined
+    } else if (wined3d_settings.ps_selected_mode = SHADER_SW) {
+        *pCaps->PixelShaderVersion    = D3DPS_VERSION(3,0);
         *pCaps->PixelShader1xMaxValue = 1.0;
-        TRACE_(d3d_caps)("Software pixel shader version 1.4 enabled\n"); */
+        TRACE_(d3d_caps)("Software pixel shader version 3.0 enabled\n"); */
     } else {
         *pCaps->PixelShaderVersion    = 0;
         *pCaps->PixelShader1xMaxValue = 0.0;
@@ -1865,8 +1889,11 @@ static HRESULT  WINAPI IWineD3DImpl_Crea
 
     /* Setup some defaults for creating the implicit swapchain */
     ENTER_GL();
+    /* FIXME: both of those should be made per adapter */
     IWineD3DImpl_FillGLCaps(&This->gl_info, IWineD3DImpl_GetAdapterDisplay(iface, Adapter));
     LEAVE_GL();
+    select_shader_mode(&This->gl_info, DeviceType,
+        &wined3d_settings.ps_selected_mode, &wined3d_settings.vs_selected_mode);
 
     /* set the state of the device to valid */
     object->state = WINED3D_OK;
diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c
index 616e042..95ccc77 100644
--- a/dlls/wined3d/drawprim.c
+++ b/dlls/wined3d/drawprim.c
@@ -1962,7 +1962,9 @@ #endif
         TRACE("Loaded arrays\n");
 
         /* Bind the correct GLSL shader program based on the currently set vertex & pixel shaders. */
-        if (wined3d_settings.shader_mode == SHADER_GLSL) {
+        if (wined3d_settings.vs_selected_mode == SHADER_GLSL ||
+            wined3d_settings.ps_selected_mode == SHADER_GLSL) {
+
             set_glsl_shader_program(iface);
             /* Start using this program ID (if it's 0, there is no shader program to use, so 
              * glUseProgramObjectARB(0) will disable the use of any shaders) */
@@ -1977,7 +1979,7 @@ #endif
 
             TRACE("Using vertex shader\n");
 
-            if (wined3d_settings.shader_mode == SHADER_ARB) {
+            if (wined3d_settings.vs_selected_mode == SHADER_ARB) {
                 /* Bind the vertex program */
                 GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB,
                     ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.prgId));
@@ -1995,7 +1997,7 @@ #endif
 
             TRACE("Using pixel shader\n");
 
-            if (wined3d_settings.shader_mode == SHADER_ARB) {
+            if (wined3d_settings.ps_selected_mode == SHADER_ARB) {
                  /* Bind the fragment program */
                  GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB,
                      ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId));
@@ -2008,12 +2010,12 @@ #endif
                      This, ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.prgId);
             }
         }
-        
+       
         /* Load any global constants/uniforms that may have been set by the application */
-        if (wined3d_settings.shader_mode == SHADER_GLSL)
-            shader_glsl_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction); 
-        else if (wined3d_settings.shader_mode == SHADER_ARB)
-            shader_arb_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
+        if (wined3d_settings.vs_selected_mode == SHADER_GLSL || wined3d_settings.ps_selected_mode == SHADER_GLSL)
+          shader_glsl_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction);
+        else if (wined3d_settings.vs_selected_mode== SHADER_ARB || wined3d_settings.ps_selected_mode == SHADER_ARB)
+          shader_arb_load_constants((IWineD3DStateBlock*)This->stateBlock, usePixelShaderFunction, useVertexShaderFunction); 
         
 
         /* DirectX colours are in a different format to opengl colours
@@ -2046,12 +2048,12 @@ #endif
                 checkGLcall("glDisableVertexAttribArrayARB(reg);");
             }
 
-            if (wined3d_settings.shader_mode == SHADER_ARB)
+            if (wined3d_settings.vs_selected_mode == SHADER_ARB)
                 glDisable(GL_VERTEX_PROGRAM_ARB);
         }
 
         /* Cleanup fragment program */
-        if (usePixelShaderFunction && wined3d_settings.shader_mode == SHADER_ARB) {
+        if (usePixelShaderFunction && wined3d_settings.ps_selected_mode == SHADER_ARB) {
             glDisable(GL_FRAGMENT_PROGRAM_ARB);
         }
     }
@@ -2278,19 +2280,15 @@ void drawPrimitive(IWineD3DDevice *iface
     int                           useHW = FALSE, i;
     BOOL                          fixup = FALSE;
 
-    if (This->stateBlock->vertexShader != NULL && wined3d_settings.vs_mode != VS_NONE 
-            &&((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function != NULL
-            && GL_SUPPORT(ARB_VERTEX_PROGRAM)) {
+    /* Shaders can be implemented using ARB_PROGRAM, GLSL, or software - 
+     * here simply check whether a shader was set, or the user disabled shaders */
+    if (wined3d_settings.vs_selected_mode != SHADER_NONE && This->stateBlock->vertexShader && 
+        ((IWineD3DVertexShaderImpl *)This->stateBlock->vertexShader)->baseShader.function != NULL) 
         useVertexShaderFunction = TRUE;
-    } else {
-        useVertexShaderFunction = FALSE;
-    }
 
-    if (wined3d_settings.ps_mode != PS_NONE && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)
-            && This->stateBlock->pixelShader
-            && ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function) {
+    if (wined3d_settings.ps_selected_mode != SHADER_NONE && This->stateBlock->pixelShader &&
+        ((IWineD3DPixelShaderImpl *)This->stateBlock->pixelShader)->baseShader.function) 
         usePixelShaderFunction = TRUE;
-    }
 
     if (This->stateBlock->vertexDecl == NULL) {
         /* Work out what the FVF should look like */
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index a61fa83..933cfc3 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -73,7 +73,7 @@ static ULONG  WINAPI IWineD3DPixelShader
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
         HeapFree(GetProcessHeap(), 0, This);
-        if (wined3d_settings.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
+        if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
             /* If this shader is still attached to a program, GL will perform a lazy delete */
             TRACE("Deleting shader object %u\n", This->baseShader.prgId);
             GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
@@ -829,7 +829,7 @@ #endif
     buffer.bsize = 0;
     buffer.lineNo = 0;
 
-    if (wined3d_settings.shader_mode == SHADER_GLSL) {
+    if (This->baseShader.shader_mode == SHADER_GLSL) {
 
         /* Create the hw GLSL shader object and assign it as the baseShader.prgId */
         GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
@@ -857,7 +857,7 @@ #endif
         /* Store the shader object */
         This->baseShader.prgId = shader_obj;
 
-    } else if (wined3d_settings.shader_mode == SHADER_ARB) {
+    } else if (wined3d_settings.ps_selected_mode == SHADER_ARB) {
         /*  Create the hw ARB shader */
         shader_addline(&buffer, "!!ARBfp1.0\n");
 
@@ -913,7 +913,8 @@ static HRESULT WINAPI IWineD3DPixelShade
     pshader_set_limits(This);
 
     /* Generate HW shader in needed */
-    if (NULL != pFunction  && wined3d_settings.vs_mode == VS_HW) {
+    This->baseShader.shader_mode = wined3d_settings.ps_selected_mode;
+    if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) {
         TRACE("(%p) : Generating hardware program\n", This);
         IWineD3DPixelShaderImpl_GenerateShader(iface, pFunction);
     }
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index c3c2e4f..aa68081 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -644,7 +644,7 @@ #endif
     buffer.bsize = 0;
     buffer.lineNo = 0;
 
-    if (wined3d_settings.shader_mode == SHADER_GLSL) {
+    if (This->baseShader.shader_mode == SHADER_GLSL) {
 
         /* Create the hw GLSL shader program and assign it as the baseShader.prgId */
         GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
@@ -669,7 +669,7 @@ #endif
         /* Store the shader object */
         This->baseShader.prgId = shader_obj;
 
-    } else if (wined3d_settings.shader_mode == SHADER_ARB) {
+    } else if (This->baseShader.shader_mode == SHADER_ARB) {
 
         /*  Create the hw ARB shader */
         shader_addline(&buffer, "!!ARBvp1.0\n");
@@ -990,7 +990,7 @@ static ULONG WINAPI IWineD3DVertexShader
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
         if (This->vertexDeclaration) IWineD3DVertexDeclaration_Release(This->vertexDeclaration);
-        if (wined3d_settings.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
+        if (This->baseShader.shader_mode == SHADER_GLSL && This->baseShader.prgId != 0) {
             /* If this shader is still attached to a program, GL will perform a lazy delete */
             TRACE("Deleting shader object %u\n", This->baseShader.prgId);
             GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
@@ -1055,7 +1055,8 @@ static HRESULT WINAPI IWineD3DVertexShad
     vshader_set_limits(This);
 
     /* Generate HW shader in needed */
-    if (NULL != pFunction  && wined3d_settings.vs_mode == VS_HW) 
+    This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
+    if (NULL != pFunction && This->baseShader.shader_mode != SHADER_SW) 
         IWineD3DVertexShaderImpl_GenerateShader(iface, pFunction);
 
     /* copy the function ... because it will certainly be released by application */
@@ -1065,6 +1066,7 @@ static HRESULT WINAPI IWineD3DVertexShad
     } else {
         This->baseShader.function = NULL;
     }
+
     return WINED3D_OK;
 }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index ab5eddf..0f354c1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -136,6 +136,7 @@ #define NP2_REPACK 1
 #define SHADER_SW   0
 #define SHADER_ARB  1
 #define SHADER_GLSL 2
+#define SHADER_NONE 3
 
 typedef struct wined3d_settings_s {
 /* vertex and pixel shader modes */
@@ -146,7 +147,8 @@ typedef struct wined3d_settings_s {
     we should use it.  However, until it's fully implemented, we'll leave it as a registry
     setting for developers. */
   BOOL glslRequested;
-  int shader_mode;
+  int vs_selected_mode;
+  int ps_selected_mode;
 /* nonpower 2 function */
   int nonpower2_mode;
 } wined3d_settings_t;
@@ -1460,6 +1462,10 @@ typedef struct IWineD3DBaseShaderClass
     CONST DWORD                     *function;
     UINT                            functionLength;
     GLuint                          prgId;
+
+    /* Type of shader backend */
+    int shader_mode;
+
 } IWineD3DBaseShaderClass;
 
 typedef struct IWineD3DBaseShaderImpl {
-- 
1.4.0



More information about the wine-patches mailing list