[PATCH] WineD3D: Let the shader backend decide the constant =

Stefan Doesinger stefan at codeweavers.com
Thu Nov 27 01:20:02 CST 2008


dependencies=0A=
=0A=
This allows the shader model to decide if it has to load all=0A=
constants at once or not, and wether it has to wait for the=0A=
shader to be set before loading the constants. This frees the arb=0A=
shader backend from the glsl constraints and makes the state=0A=
management simpler. The shader backend now asks the state manager=0A=
for specific states if needed.=0A=
=0A=
This also fixes a bug that could cause glsl constants to be=0A=
loaded more than once per draw=0A=
---=0A=
 dlls/wined3d/arb_program_shader.c |  105 =
+++++++++++++++++++------------------=0A=
 dlls/wined3d/baseshader.c         |    5 +-=0A=
 dlls/wined3d/glsl_shader.c        |   36 +++++++++++--=0A=
 dlls/wined3d/state.c              |   42 +++++----------=0A=
 dlls/wined3d/wined3d_private.h    |    9 ++-=0A=
 5 files changed, 107 insertions(+), 90 deletions(-)=0A=
=0A=
diff --git a/dlls/wined3d/arb_program_shader.c =
b/dlls/wined3d/arb_program_shader.c=0A=
index 9194673..f193904 100644=0A=
--- a/dlls/wined3d/arb_program_shader.c=0A=
+++ b/dlls/wined3d/arb_program_shader.c=0A=
@@ -167,59 +167,64 @@ static unsigned int =
shader_arb_load_constantsF(IWineD3DBaseShaderImpl* This, con=0A=
  * We only support float constants in ARB at the moment, so don't =0A=
  * worry about the Integers or Booleans=0A=
  */=0A=
-static void shader_arb_load_constants(=0A=
-    IWineD3DDevice* device,=0A=
-    char usePixelShader,=0A=
-    char useVertexShader) {=0A=
-   =0A=
-    IWineD3DDeviceImpl* deviceImpl =3D (IWineD3DDeviceImpl*) device; =0A=
+static void shader_arb_load_vs_constants(IWineD3DDevice* device, =
WineD3DContext *context) {=0A=
+    IWineD3DDeviceImpl* deviceImpl =3D (IWineD3DDeviceImpl*) device;=0A=
     IWineD3DStateBlockImpl* stateBlock =3D deviceImpl->stateBlock;=0A=
     const WineD3D_GL_Info *gl_info =3D &deviceImpl->adapter->gl_info;=0A=
-    unsigned char i;=0A=
 =0A=
-    if (useVertexShader) {=0A=
-        IWineD3DBaseShaderImpl* vshader =3D (IWineD3DBaseShaderImpl*) =
stateBlock->vertexShader;=0A=
+    IWineD3DBaseShaderImpl* vshader =3D (IWineD3DBaseShaderImpl*) =
stateBlock->vertexShader;=0A=
 =0A=
-        /* Load DirectX 9 float constants for vertex shader */=0A=
-        deviceImpl->highest_dirty_vs_const =3D =
shader_arb_load_constantsF(=0A=
-                vshader, gl_info, GL_VERTEX_PROGRAM_ARB,=0A=
-                deviceImpl->highest_dirty_vs_const,=0A=
-                stateBlock->vertexShaderConstantF,=0A=
-                deviceImpl->activeContext->vshader_const_dirty);=0A=
+    /* Load DirectX 9 float constants for vertex shader */=0A=
+    deviceImpl->highest_dirty_vs_const =3D shader_arb_load_constantsF(=0A=
+            vshader, gl_info, GL_VERTEX_PROGRAM_ARB,=0A=
+            deviceImpl->highest_dirty_vs_const,=0A=
+            stateBlock->vertexShaderConstantF,=0A=
+            deviceImpl->activeContext->vshader_const_dirty);=0A=
 =0A=
-        /* Upload the position fixup */=0A=
-        GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, =
ARB_SHADER_PRIVCONST_POS, deviceImpl->posFixup));=0A=
-    }=0A=
+    /* Upload the position fixup */=0A=
+    GL_EXTCALL(glProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, =
ARB_SHADER_PRIVCONST_POS, deviceImpl->posFixup));=0A=
+}=0A=
+=0A=
+static void shader_arb_load_ps_constants(IWineD3DDevice* device, =
WineD3DContext *context) {=0A=
+    IWineD3DDeviceImpl* deviceImpl =3D (IWineD3DDeviceImpl*) device;=0A=
+    IWineD3DStateBlockImpl* stateBlock =3D deviceImpl->stateBlock;=0A=
+    const WineD3D_GL_Info *gl_info =3D &deviceImpl->adapter->gl_info;=0A=
+    unsigned char i;=0A=
 =0A=
-    if (usePixelShader) {=0A=
+    IWineD3DBaseShaderImpl* pshader =3D (IWineD3DBaseShaderImpl*) =
stateBlock->pixelShader;=0A=
+    IWineD3DPixelShaderImpl *psi =3D (IWineD3DPixelShaderImpl *) =
pshader;=0A=
 =0A=
-        IWineD3DBaseShaderImpl* pshader =3D (IWineD3DBaseShaderImpl*) =
stateBlock->pixelShader;=0A=
-        IWineD3DPixelShaderImpl *psi =3D (IWineD3DPixelShaderImpl *) =
pshader;=0A=
+    /* Don't load constants without a pixel shader. If the ARB fixed =
function pipeline replacement=0A=
+     * is used, this could overwrite some fixed function constants. In =
theory, loading the constants=0A=
+     * when not using the ARB ffp replacement is fine, but it doesn't =
do any good either. Due to the=0A=
+     * dynamic location of the bump mapping constants this function is =
called whenever the shader is=0A=
+     * changed anyway=0A=
+     */=0A=
+    if(!pshader) return;=0A=
 =0A=
-        /* Load DirectX 9 float constants for pixel shader */=0A=
-        deviceImpl->highest_dirty_ps_const =3D =
shader_arb_load_constantsF(=0A=
-                pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,=0A=
-                deviceImpl->highest_dirty_ps_const,=0A=
-                stateBlock->pixelShaderConstantF,=0A=
-                deviceImpl->activeContext->pshader_const_dirty);=0A=
+    /* Load DirectX 9 float constants for pixel shader */=0A=
+    deviceImpl->highest_dirty_ps_const =3D shader_arb_load_constantsF(=0A=
+            pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB,=0A=
+            deviceImpl->highest_dirty_ps_const,=0A=
+            stateBlock->pixelShaderConstantF,=0A=
+            deviceImpl->activeContext->pshader_const_dirty);=0A=
 =0A=
-        for(i =3D 0; i < psi->numbumpenvmatconsts; i++) {=0A=
+    for(i =3D 0; i < psi->numbumpenvmatconsts; i++) {=0A=
             /* The state manager takes care that this function is =
always called if the bump env matrix changes=0A=
+            */=0A=
+        float *data =3D (float *) &stateBlock->textureState[(int) =
psi->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];=0A=
+        GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, =
psi->bumpenvmatconst[i].const_num, data));=0A=
+        =
deviceImpl->activeContext->pshader_const_dirty[psi->bumpenvmatconst[i].co=
nst_num] =3D 1;=0A=
+=0A=
+        if(psi->luminanceconst[i].const_num !=3D -1) {=0A=
+            /* WINED3DTSS_BUMPENVLSCALE and WINED3DTSS_BUMPENVLOFFSET =
are next to each other.=0A=
+             * point gl to the scale, and load 4 floats. x =3D scale, y =
=3D offset, z and w are junk, we=0A=
+             * don't care about them. The pointers are valid for sure =
because the stateblock is bigger.=0A=
+             * (they're WINED3DTSS_TEXTURETRANSFORMFLAGS and =
WINED3DTSS_ADDRESSW, so most likely 0 or NaN=0A=
              */=0A=
-            const float *data =3D (const float =
*)&stateBlock->textureState[(int) =
psi->bumpenvmatconst[i].texunit][WINED3DTSS_BUMPENVMAT00];=0A=
-            =
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, =
psi->bumpenvmatconst[i].const_num, data));=0A=
-            =
deviceImpl->activeContext->pshader_const_dirty[psi->bumpenvmatconst[i].co=
nst_num] =3D 1;=0A=
-=0A=
-            if(psi->luminanceconst[i].const_num !=3D -1) {=0A=
-                /* WINED3DTSS_BUMPENVLSCALE and =
WINED3DTSS_BUMPENVLOFFSET are next to each other.=0A=
-                 * point gl to the scale, and load 4 floats. x =3D =
scale, y =3D offset, z and w are junk, we=0A=
-                 * don't care about them. The pointers are valid for =
sure because the stateblock is bigger.=0A=
-                 * (they're WINED3DTSS_TEXTURETRANSFORMFLAGS and =
WINED3DTSS_ADDRESSW, so most likely 0 or NaN=0A=
-                 */=0A=
-                const float *scale =3D (const float =
*)&stateBlock->textureState[(int) =
psi->luminanceconst[i].texunit][WINED3DTSS_BUMPENVLSCALE];=0A=
-                =
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, =
psi->luminanceconst[i].const_num, scale));=0A=
-                =
deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst[i].con=
st_num] =3D 1;=0A=
-            }=0A=
+            float *scale =3D (float *) &stateBlock->textureState[(int) =
psi->luminanceconst[i].texunit][WINED3DTSS_BUMPENVLSCALE];=0A=
+            =
GL_EXTCALL(glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, =
psi->luminanceconst[i].const_num, scale));=0A=
+            =
deviceImpl->activeContext->pshader_const_dirty[psi->luminanceconst[i].con=
st_num] =3D 1;=0A=
         }=0A=
     }=0A=
 }=0A=
@@ -1822,7 +1827,7 @@ static GLuint =
create_arb_blt_fragment_program(const WineD3D_GL_Info *gl_info, en=0A=
     return program_id;=0A=
 }=0A=
 =0A=
-static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS) {=0A=
+static void shader_arb_select(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS, WineD3DContext *context) {=0A=
     IWineD3DDeviceImpl *This =3D (IWineD3DDeviceImpl *)iface;=0A=
     struct shader_arb_priv *priv =3D (struct shader_arb_priv *) =
This->shader_priv;=0A=
     const WineD3D_GL_Info *gl_info =3D &This->adapter->gl_info;=0A=
@@ -1864,6 +1869,8 @@ static void shader_arb_select(IWineD3DDevice =
*iface, BOOL usePS, BOOL useVS) {=0A=
             checkGLcall("glEnable(GL_FRAGMENT_PROGRAM_ARB);");=0A=
         }=0A=
         TRACE("(%p) : Bound fragment program %u and enabled =
GL_FRAGMENT_PROGRAM_ARB\n", This, priv->current_fprogram_id);=0A=
+=0A=
+        shader_arb_load_ps_constants(iface, context);=0A=
     } else if(GL_SUPPORT(ARB_FRAGMENT_PROGRAM) && =
!priv->use_arbfp_fixed_func) {=0A=
         /* Disable only if we're not using arbfp fixed function =
fragment processing. If this is used,=0A=
          * keep GL_FRAGMENT_PROGRAM_ARB enabled, and the fixed function =
pipeline will bind the fixed function=0A=
@@ -2328,7 +2335,8 @@ const shader_backend_t arb_program_shader_backend =
=3D {=0A=
     shader_arb_select,=0A=
     shader_arb_select_depth_blt,=0A=
     shader_arb_deselect_depth_blt,=0A=
-    shader_arb_load_constants,=0A=
+    shader_arb_load_vs_constants,=0A=
+    shader_arb_load_ps_constants,=0A=
     shader_arb_cleanup,=0A=
     shader_arb_color_correction,=0A=
     shader_arb_destroy,=0A=
@@ -3108,14 +3116,7 @@ static void fragment_prog_arbfp(DWORD state, =
IWineD3DStateBlockImpl *stateblock,=0A=
      * to be compiled before activating them(needs some cleanups in the =
shader backend interface)=0A=
      */=0A=
     if(!isStateDirty(context, =
device->StateTable[STATE_VSHADER].representative)) {=0A=
-        device->shader_backend->shader_select((IWineD3DDevice =
*)stateblock->wineD3DDevice, use_pshader, use_vshader);=0A=
-=0A=
-        if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && =
(use_vshader || use_pshader)) {=0A=
-            =
device->StateTable[STATE_VERTEXSHADERCONSTANT].apply(STATE_VERTEXSHADERCO=
NSTANT, stateblock, context);=0A=
-        }=0A=
-    }=0A=
-    if(use_pshader) {=0A=
-        =
device->StateTable[STATE_PIXELSHADERCONSTANT].apply(STATE_PIXELSHADERCONS=
TANT, stateblock, context);=0A=
+        device->shader_backend->shader_select((IWineD3DDevice =
*)stateblock->wineD3DDevice, use_pshader, use_vshader, context);=0A=
     }=0A=
 }=0A=
 =0A=
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c=0A=
index 92f0d8a..5f66cfe 100644=0A=
--- a/dlls/wined3d/baseshader.c=0A=
+++ b/dlls/wined3d/baseshader.c=0A=
@@ -1086,10 +1086,10 @@ void shader_trace_init(=0A=
 }=0A=
 =0A=
 static const SHADER_HANDLER =
shader_none_instruction_handler_table[WINED3DSIH_TABLE_SIZE] =3D {0};=0A=
-static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS) {}=0A=
+static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS, WineD3DContext *context) {}=0A=
 static void shader_none_select_depth_blt(IWineD3DDevice *iface, enum =
tex_types tex_type) {}=0A=
 static void shader_none_deselect_depth_blt(IWineD3DDevice *iface) {}=0A=
-static void shader_none_load_constants(IWineD3DDevice *iface, char =
usePS, char useVS) {}=0A=
+static void shader_none_load_constants(IWineD3DDevice *iface, =
WineD3DContext *context) {}=0A=
 static void shader_none_cleanup(IWineD3DDevice *iface) {}=0A=
 static void shader_none_color_correction(const SHADER_OPCODE_ARG *arg) =
{}=0A=
 static void shader_none_destroy(IWineD3DBaseShader *iface) {}=0A=
@@ -1136,6 +1136,7 @@ const shader_backend_t none_shader_backend =3D {=0A=
     shader_none_select_depth_blt,=0A=
     shader_none_deselect_depth_blt,=0A=
     shader_none_load_constants,=0A=
+    shader_none_load_constants,=0A=
     shader_none_cleanup,=0A=
     shader_none_color_correction,=0A=
     shader_none_destroy,=0A=
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c=0A=
index 424f7bc..6732e8d 100644=0A=
--- a/dlls/wined3d/glsl_shader.c=0A=
+++ b/dlls/wined3d/glsl_shader.c=0A=
@@ -385,9 +385,8 @@ static void =
shader_glsl_load_constantsB(IWineD3DBaseShaderImpl *This, const Wine=0A=
  */=0A=
 static void shader_glsl_load_constants(=0A=
     IWineD3DDevice* device,=0A=
-    char usePixelShader,=0A=
-    char useVertexShader) {=0A=
-   =0A=
+    WineD3DContext *context) {=0A=
+=0A=
     IWineD3DDeviceImpl* deviceImpl =3D (IWineD3DDeviceImpl*) device;=0A=
     const struct shader_glsl_priv *priv =3D (struct shader_glsl_priv =
*)deviceImpl->shader_priv;=0A=
     IWineD3DStateBlockImpl* stateBlock =3D deviceImpl->stateBlock;=0A=
@@ -399,13 +398,24 @@ static void shader_glsl_load_constants(=0A=
     const struct glsl_shader_prog_link *prog =3D priv->glsl_program;=0A=
     int i;=0A=
 =0A=
+    /* TODO: If we're called by shader_glsl_select, we know that both =
we get past both checks.=0A=
+     * is it cheaper to have a wrapper function check those? Inline =
some common code? Extra=0A=
+     * parameter?=0A=
+     */=0A=
     if (!prog) {=0A=
         /* No GLSL program set - nothing to do. */=0A=
         return;=0A=
+    } else if(isStateDirty(context, STATE_PIXELSHADER) ||=0A=
+              isStateDirty(context, STATE_VDECL) ||=0A=
+              isStateDirty(context, STATE_PIXELSHADERCONSTANT) ||=0A=
+              isStateDirty(context, STATE_VERTEXSHADERCONSTANT)) {=0A=
+        /* Will be called again later */=0A=
+        return;=0A=
     }=0A=
+=0A=
     programId =3D prog->programId;=0A=
 =0A=
-    if (useVertexShader) {=0A=
+    if (use_vs(deviceImpl)) {=0A=
         IWineD3DBaseShaderImpl* vshader =3D (IWineD3DBaseShaderImpl*) =
stateBlock->vertexShader;=0A=
 =0A=
         constant_locations =3D prog->vuniformF_locations;=0A=
@@ -432,7 +442,7 @@ static void shader_glsl_load_constants(=0A=
         checkGLcall("glUniform4fvARB");=0A=
     }=0A=
 =0A=
-    if (usePixelShader) {=0A=
+    if (use_ps(deviceImpl)) {=0A=
 =0A=
         IWineD3DBaseShaderImpl* pshader =3D (IWineD3DBaseShaderImpl*) =
stateBlock->pixelShader;=0A=
 =0A=
@@ -3468,13 +3478,19 @@ static GLhandleARB create_glsl_blt_shader(const =
WineD3D_GL_Info *gl_info, enum t=0A=
     return program_id;=0A=
 }=0A=
 =0A=
-static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS) {=0A=
+static void shader_glsl_select(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS, WineD3DContext *context) {=0A=
     IWineD3DDeviceImpl *This =3D (IWineD3DDeviceImpl *)iface;=0A=
     struct shader_glsl_priv *priv =3D (struct shader_glsl_priv =
*)This->shader_priv;=0A=
     const WineD3D_GL_Info *gl_info =3D &This->adapter->gl_info;=0A=
     GLhandleARB program_id =3D 0;=0A=
     GLenum old_vertex_color_clamp, current_vertex_color_clamp;=0A=
 =0A=
+    /* Don't do anything unless both vertex and pixel shader are sorted =
out by the state=0A=
+     * manager=0A=
+     */=0A=
+    if(isStateDirty(context, STATE_PIXELSHADER)) return;=0A=
+    if(isStateDirty(context, STATE_VDECL)) return;=0A=
+=0A=
     old_vertex_color_clamp =3D priv->glsl_program ? =
priv->glsl_program->vertex_color_clamp : GL_FIXED_ONLY_ARB;=0A=
 =0A=
     if (useVS || usePS) set_glsl_shader_program(iface, usePS, useVS);=0A=
@@ -3495,6 +3511,13 @@ static void shader_glsl_select(IWineD3DDevice =
*iface, BOOL usePS, BOOL useVS) {=0A=
     if (program_id) TRACE("Using GLSL program %u\n", program_id);=0A=
     GL_EXTCALL(glUseProgramObjectARB(program_id));=0A=
     checkGLcall("glUseProgramObjectARB");=0A=
+=0A=
+    /* Reload the constants if that isn't scheduled anyway */=0A=
+    if(program_id &&=0A=
+       !isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&=0A=
+       !isStateDirty(context, STATE_VERTEXSHADERCONSTANT)) {=0A=
+        shader_glsl_load_constants(iface, context);=0A=
+    }=0A=
 }=0A=
 =0A=
 static void shader_glsl_select_depth_blt(IWineD3DDevice *iface, enum =
tex_types tex_type) {=0A=
@@ -3953,6 +3976,7 @@ const shader_backend_t glsl_shader_backend =3D {=0A=
     shader_glsl_select_depth_blt,=0A=
     shader_glsl_deselect_depth_blt,=0A=
     shader_glsl_load_constants,=0A=
+    shader_glsl_load_constants,=0A=
     shader_glsl_cleanup,=0A=
     shader_glsl_color_correction,=0A=
     shader_glsl_destroy,=0A=
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c=0A=
index 9e74d49..6fd138a 100644=0A=
--- a/dlls/wined3d/state.c=0A=
+++ b/dlls/wined3d/state.c=0A=
@@ -3345,18 +3345,16 @@ static void tex_coordindex(DWORD state, =
IWineD3DStateBlockImpl *stateblock, Wine=0A=
     }=0A=
 }=0A=
 =0A=
-static void shaderconstant(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
+static void vshaderconstant(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
     IWineD3DDeviceImpl *device =3D stateblock->wineD3DDevice;=0A=
 =0A=
-    /* Vertex and pixel shader states will call a shader upload, don't =
do anything as long one of them=0A=
-     * has an update pending=0A=
-     */=0A=
-    if(isStateDirty(context, STATE_VDECL) ||=0A=
-       isStateDirty(context, STATE_PIXELSHADER)) {=0A=
-       return;=0A=
-    }=0A=
+    device->shader_backend->shader_load_vs_constants((IWineD3DDevice *) =
device, context);=0A=
+}=0A=
+=0A=
+static void pshaderconstant(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
+    IWineD3DDeviceImpl *device =3D stateblock->wineD3DDevice;=0A=
 =0A=
-    device->shader_backend->shader_load_constants((IWineD3DDevice *) =
device, use_ps(device), use_vs(device));=0A=
+    device->shader_backend->shader_load_ps_constants((IWineD3DDevice *) =
device, context);=0A=
 }=0A=
 =0A=
 static void tex_bumpenvlscale(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *context) {=0A=
@@ -3367,9 +3365,8 @@ static void tex_bumpenvlscale(DWORD state, =
IWineD3DStateBlockImpl *stateblock, W=0A=
         /* The pixel shader has to know the luminance scale. Do a =
constants update if it=0A=
          * isn't scheduled anyway=0A=
          */=0A=
-        if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&=0A=
-           !isStateDirty(context, STATE_PIXELSHADER)) {=0A=
-            shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, =
context);=0A=
+        if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) {=0A=
+            pshaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, =
context);=0A=
         }=0A=
     }=0A=
 }=0A=
@@ -3524,11 +3521,7 @@ void apply_pixelshader(DWORD state, =
IWineD3DStateBlockImpl *stateblock, WineD3DC=0A=
     }=0A=
 =0A=
     if(!isStateDirty(context, =
device->StateTable[STATE_VSHADER].representative)) {=0A=
-        device->shader_backend->shader_select((IWineD3DDevice =
*)stateblock->wineD3DDevice, use_pshader, use_vshader);=0A=
-=0A=
-        if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && =
(use_vshader || use_pshader)) {=0A=
-            shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, =
context);=0A=
-        }=0A=
+        device->shader_backend->shader_select((IWineD3DDevice =
*)stateblock->wineD3DDevice, use_pshader, use_vshader, context);=0A=
     }=0A=
 }=0A=
 =0A=
@@ -3539,9 +3532,8 @@ static void shader_bumpenvmat(DWORD state, =
IWineD3DStateBlockImpl *stateblock, W=0A=
         /* The pixel shader has to know the bump env matrix. Do a =
constants update if it isn't scheduled=0A=
          * anyway=0A=
          */=0A=
-        if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT) &&=0A=
-            !isStateDirty(context, STATE_PIXELSHADER)) {=0A=
-            shaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, =
context);=0A=
+        if(!isStateDirty(context, STATE_PIXELSHADERCONSTANT)) {=0A=
+            pshaderconstant(STATE_PIXELSHADERCONSTANT, stateblock, =
context);=0A=
         }=0A=
     }=0A=
 }=0A=
@@ -4538,11 +4530,7 @@ static void vertexdeclaration(DWORD state, =
IWineD3DStateBlockImpl *stateblock, W=0A=
      * application=0A=
      */=0A=
     if (!isStateDirty(context, STATE_PIXELSHADER)) {=0A=
-        device->shader_backend->shader_select((IWineD3DDevice *)device, =
usePixelShaderFunction, useVertexShaderFunction);=0A=
-=0A=
-        if (!isStateDirty(context, STATE_VERTEXSHADERCONSTANT) && =
(useVertexShaderFunction || usePixelShaderFunction)) {=0A=
-            shaderconstant(STATE_VERTEXSHADERCONSTANT, stateblock, =
context);=0A=
-        }=0A=
+        device->shader_backend->shader_select((IWineD3DDevice *)device, =
usePixelShaderFunction, useVertexShaderFunction, context);=0A=
     }=0A=
 =0A=
     context->last_was_vshader =3D useVertexShaderFunction;=0A=
@@ -4768,8 +4756,8 @@ const struct StateEntryTemplate =
misc_state_template[] =3D {=0A=
     /* TODO: Move shader constant loading to vertex and fragment =
pipeline repectively, as soon as the pshader and=0A=
      * vshader loadings are untied from each other=0A=
      */=0A=
-    { STATE_VERTEXSHADERCONSTANT,                         { =
STATE_VERTEXSHADERCONSTANT,                         shaderconstant      =
}, 0                               },=0A=
-    { STATE_PIXELSHADERCONSTANT,                          { =
STATE_VERTEXSHADERCONSTANT,                         shaderconstant      =
}, 0                               },=0A=
+    { STATE_VERTEXSHADERCONSTANT,                         { =
STATE_VERTEXSHADERCONSTANT,                         vshaderconstant     =
}, 0                               },=0A=
+    { STATE_PIXELSHADERCONSTANT,                          { =
STATE_PIXELSHADERCONSTANT,                          pshaderconstant     =
}, 0                               },=0A=
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     { =
STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   =
}, 0                               },=0A=
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT01),     { =
STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   =
}, 0                               },=0A=
     { STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT10),     { =
STATE_TEXTURESTAGE(0, WINED3DTSS_BUMPENVMAT00),     shader_bumpenvmat   =
}, 0                               },=0A=
diff --git a/dlls/wined3d/wined3d_private.h =
b/dlls/wined3d/wined3d_private.h=0A=
index 9c74fbe..497862a 100644=0A=
--- a/dlls/wined3d/wined3d_private.h=0A=
+++ b/dlls/wined3d/wined3d_private.h=0A=
@@ -87,6 +87,9 @@ void hash_table_remove(struct hash_table_t *table, =
void *key);=0A=
 #define MAX_CONST_I 16=0A=
 #define MAX_CONST_B 16=0A=
 =0A=
+/* Context management */=0A=
+typedef struct WineD3DContext WineD3DContext;=0A=
+=0A=
 /* Used for CreateStateBlock */=0A=
 #define NUM_SAVEDPIXELSTATES_R     35=0A=
 #define NUM_SAVEDPIXELSTATES_T     18=0A=
@@ -345,10 +348,11 @@ enum tex_types=0A=
 =0A=
 typedef struct {=0A=
     const SHADER_HANDLER *shader_instruction_handler_table;=0A=
-    void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS);=0A=
+    void (*shader_select)(IWineD3DDevice *iface, BOOL usePS, BOOL =
useVS, WineD3DContext *context);=0A=
     void (*shader_select_depth_blt)(IWineD3DDevice *iface, enum =
tex_types tex_type);=0A=
     void (*shader_deselect_depth_blt)(IWineD3DDevice *iface);=0A=
-    void (*shader_load_constants)(IWineD3DDevice *iface, char usePS, =
char useVS);=0A=
+    void (*shader_load_vs_constants)(IWineD3DDevice *iface, =
WineD3DContext *context);=0A=
+    void (*shader_load_ps_constants)(IWineD3DDevice *iface, =
WineD3DContext *context);=0A=
     void (*shader_cleanup)(IWineD3DDevice *iface);=0A=
     void (*shader_color_correction)(const struct SHADER_OPCODE_ARG =
*arg);=0A=
     void (*shader_destroy)(IWineD3DBaseShader *iface);=0A=
@@ -576,7 +580,6 @@ extern glAttribFunc =
texcoord_funcs[WINED3DDECLTYPE_UNUSED];=0A=
     (((((d3dvtVertexType) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1)=0A=
 =0A=
 /* Routines and structures related to state management */=0A=
-typedef struct WineD3DContext WineD3DContext;=0A=
 typedef void (*APPLYSTATEFUNC)(DWORD state, IWineD3DStateBlockImpl =
*stateblock, WineD3DContext *ctx);=0A=
 =0A=
 #define STATE_RENDER(a) (a)=0A=
-- =0A=
1.5.6.4=0A=
=0A=

------=_NextPart_000_0008_01C958CA.50DE16E0--




More information about the wine-patches mailing list