wined3d: Call activate_dimensions from the atifs code.
authorStefan Dösinger <stefan@codeweavers.com>
Wed, 23 Apr 2008 20:23:57 +0000 (22:23 +0200)
committerAlexandre Julliard <julliard@winehq.org>
Thu, 24 Apr 2008 09:54:28 +0000 (11:54 +0200)
dlls/wined3d/ati_fragment_shader.c
dlls/wined3d/state.c
dlls/wined3d/utils.c
dlls/wined3d/wined3d_private.h

index 0d3687eb7e71bc099ba18e5da079ee04d2a13dab..c4815294d44ddf892a942821fb6237172ff68f23 100644 (file)
@@ -45,6 +45,7 @@ struct atifs_ffp_desc
 {
     struct ffp_desc parent;
     GLuint shader;
+    unsigned int num_textures_used;
 };
 
 struct atifs_private_data
@@ -782,6 +783,8 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
     struct atifs_ffp_desc       *desc;
     struct texture_stage_op     op[MAX_TEXTURES];
     struct atifs_private_data   *priv = (struct atifs_private_data *) This->shader_priv;
+    DWORD mapped_stage;
+    unsigned int i;
 
     gen_ffp_op(stateblock, op);
     desc = (struct atifs_ffp_desc *) find_ffp_shader(&priv->fragment_shaders, op);
@@ -791,12 +794,31 @@ static void set_tex_op_atifs(DWORD state, IWineD3DStateBlockImpl *stateblock, Wi
             ERR("Out of memory\n");
             return;
         }
+        desc->num_textures_used = 0;
+        for(i = 0; i < GL_LIMITS(texture_stages); i++) {
+            if(op[i].cop == WINED3DTOP_DISABLE) break;
+            desc->num_textures_used = i;
+        }
+
         memcpy(desc->parent.op, op, sizeof(op));
         desc->shader = gen_ati_shader(op, &GLINFO_LOCATION);
         add_ffp_shader(&priv->fragment_shaders, &desc->parent);
         TRACE("Allocated fixed function replacement shader descriptor %p\n", desc);
     }
 
+    /* GL_ATI_fragment_shader depends on the GL_TEXTURE_xD enable settings. Update the texture stages
+     * used by this shader
+     */
+    for(i = 0; i < desc->num_textures_used; i++) {
+        mapped_stage = This->texUnitMap[i];
+        if(mapped_stage != -1) {
+            const struct StateEntry *StateTable = stateblock->wineD3DDevice->shader_backend->StateTable;
+            GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
+            checkGLcall("glActiveTextureARB");
+            texture_activate_dimensions(i, stateblock, context);
+        }
+    }
+
     GL_EXTCALL(glBindFragmentShaderATI(desc->shader));
 }
 
index 8aad2be54fd6f0b5a045bee43735c758be5126f3..1f6bb8e815e66bfb5b34fa291083f56e05645762 100644 (file)
@@ -1810,118 +1810,6 @@ static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, Win
     }
 }
 
-/* Activates the texture dimension according to the bound D3D texture.
- * Does not care for the colorop or correct gl texture unit(when using nvrc)
- * Requires the caller to activate the correct unit before
- */
-static void activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
-    BOOL bumpmap = FALSE;
-
-    if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
-                     stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP)) {
-        bumpmap = TRUE;
-        context->texShaderBumpMap |= (1 << stage);
-    } else {
-        context->texShaderBumpMap &= ~(1 << stage);
-    }
-
-    if(stateblock->textures[stage]) {
-        switch(stateblock->textureDimensions[stage]) {
-            case GL_TEXTURE_2D:
-                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
-                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
-                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
-                } else {
-                    glDisable(GL_TEXTURE_3D);
-                    checkGLcall("glDisable(GL_TEXTURE_3D)");
-                    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
-                        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
-                    }
-                    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
-                        glDisable(GL_TEXTURE_RECTANGLE_ARB);
-                        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
-                    }
-                    glEnable(GL_TEXTURE_2D);
-                    checkGLcall("glEnable(GL_TEXTURE_2D)");
-                }
-                break;
-            case GL_TEXTURE_RECTANGLE_ARB:
-                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
-                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_RECTANGLE_ARB);
-                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
-                } else {
-                    glDisable(GL_TEXTURE_2D);
-                    checkGLcall("glDisable(GL_TEXTURE_2D)");
-                    glDisable(GL_TEXTURE_3D);
-                    checkGLcall("glDisable(GL_TEXTURE_3D)");
-                    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
-                        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
-                    }
-                    glEnable(GL_TEXTURE_RECTANGLE_ARB);
-                    checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
-                }
-                break;
-            case GL_TEXTURE_3D:
-                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
-                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
-                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D)");
-                } else {
-                    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
-                        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
-                    }
-                    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
-                        glDisable(GL_TEXTURE_RECTANGLE_ARB);
-                        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
-                    }
-                    glDisable(GL_TEXTURE_2D);
-                    checkGLcall("glDisable(GL_TEXTURE_2D)");
-                    glEnable(GL_TEXTURE_3D);
-                    checkGLcall("glEnable(GL_TEXTURE_3D)");
-                }
-                break;
-            case GL_TEXTURE_CUBE_MAP_ARB:
-                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
-                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
-                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
-                } else {
-                    glDisable(GL_TEXTURE_2D);
-                    checkGLcall("glDisable(GL_TEXTURE_2D)");
-                    glDisable(GL_TEXTURE_3D);
-                    checkGLcall("glDisable(GL_TEXTURE_3D)");
-                    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
-                        glDisable(GL_TEXTURE_RECTANGLE_ARB);
-                        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
-                    }
-                    glEnable(GL_TEXTURE_CUBE_MAP_ARB);
-                    checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
-                }
-              break;
-        }
-    } else {
-        if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
-            glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
-            checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
-        } else {
-            glEnable(GL_TEXTURE_2D);
-            checkGLcall("glEnable(GL_TEXTURE_2D)");
-            glDisable(GL_TEXTURE_3D);
-            checkGLcall("glDisable(GL_TEXTURE_3D)");
-            if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
-                glDisable(GL_TEXTURE_CUBE_MAP_ARB);
-                checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
-            }
-            if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
-                glDisable(GL_TEXTURE_RECTANGLE_ARB);
-                checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
-            }
-            /* Binding textures is done by samplers. A dummy texture will be bound */
-        }
-    }
-}
-
 static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
     DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE;
     DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage];
@@ -1987,7 +1875,7 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
      * if the sampler for this stage is dirty
      */
     if(!isStateDirty(context, STATE_SAMPLER(stage))) {
-        if (tex_used) activate_dimensions(stage, stateblock, context);
+        if (tex_used) texture_activate_dimensions(stage, stateblock, context);
     }
 
     /* Set the texture combiners */
@@ -2010,7 +1898,7 @@ static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3D
             if(usesBump != usedBump) {
                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage + 1));
                 checkGLcall("glActiveTextureARB");
-                activate_dimensions(stage + 1, stateblock, context);
+                texture_activate_dimensions(stage + 1, stateblock, context);
                 GL_EXTCALL(glActiveTextureARB(GL_TEXTURE0_ARB + mapped_stage));
                 checkGLcall("glActiveTextureARB");
             }
@@ -2539,7 +2427,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
             checkGLcall("glEnable(stateblock->textureDimensions[sampler])");
         } else if(sampler < stateblock->lowest_disabled_stage) {
             if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
-                activate_dimensions(sampler, stateblock, context);
+                texture_activate_dimensions(sampler, stateblock, context);
             }
 
             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
@@ -2553,7 +2441,7 @@ static void sampler(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DCont
         if(sampler < stateblock->lowest_disabled_stage) {
             /* TODO: What should I do with pixel shaders here ??? */
             if(!isStateDirty(context, STATE_TEXTURESTAGE(sampler, WINED3DTSS_COLOROP))) {
-                activate_dimensions(sampler, stateblock, context);
+                texture_activate_dimensions(sampler, stateblock, context);
             }
 
             if(stateblock->renderState[WINED3DRS_COLORKEYENABLE] && sampler == 0) {
index e2949ddbed32cab2e7aea15c1f2153a8689298cc..0038bd08809926685410fe2db3a991f03af3ad75 100644 (file)
@@ -3384,3 +3384,117 @@ struct ffp_desc *find_ffp_shader(struct list *shaders, struct texture_stage_op o
 void add_ffp_shader(struct list *shaders, struct ffp_desc *desc) {
     list_add_head(shaders, &desc->entry);
 }
+
+/* Activates the texture dimension according to the bound D3D texture.
+ * Does not care for the colorop or correct gl texture unit(when using nvrc)
+ * Requires the caller to activate the correct unit before
+ */
+#define GLINFO_LOCATION stateblock->wineD3DDevice->adapter->gl_info
+void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) {
+    BOOL bumpmap = FALSE;
+
+    if(stage > 0 && (stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAPLUMINANCE ||
+                     stateblock->textureState[stage - 1][WINED3DTSS_COLOROP] == WINED3DTOP_BUMPENVMAP)) {
+        bumpmap = TRUE;
+        context->texShaderBumpMap |= (1 << stage);
+    } else {
+        context->texShaderBumpMap &= ~(1 << stage);
+    }
+
+    if(stateblock->textures[stage]) {
+        switch(stateblock->textureDimensions[stage]) {
+            case GL_TEXTURE_2D:
+                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
+                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_2D);
+                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
+                } else {
+                    glDisable(GL_TEXTURE_3D);
+                    checkGLcall("glDisable(GL_TEXTURE_3D)");
+                    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
+                        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+                        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+                    }
+                    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
+                        glDisable(GL_TEXTURE_RECTANGLE_ARB);
+                        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+                    }
+                    glEnable(GL_TEXTURE_2D);
+                    checkGLcall("glEnable(GL_TEXTURE_2D)");
+                }
+                break;
+            case GL_TEXTURE_RECTANGLE_ARB:
+                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
+                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, bumpmap ? GL_OFFSET_TEXTURE_2D_NV : GL_TEXTURE_RECTANGLE_ARB);
+                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, ...)");
+                } else {
+                    glDisable(GL_TEXTURE_2D);
+                    checkGLcall("glDisable(GL_TEXTURE_2D)");
+                    glDisable(GL_TEXTURE_3D);
+                    checkGLcall("glDisable(GL_TEXTURE_3D)");
+                    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
+                        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+                        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+                    }
+                    glEnable(GL_TEXTURE_RECTANGLE_ARB);
+                    checkGLcall("glEnable(GL_TEXTURE_RECTANGLE_ARB)");
+                }
+                break;
+            case GL_TEXTURE_3D:
+                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
+                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D);
+                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_3D)");
+                } else {
+                    if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
+                        glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+                        checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+                    }
+                    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
+                        glDisable(GL_TEXTURE_RECTANGLE_ARB);
+                        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+                    }
+                    glDisable(GL_TEXTURE_2D);
+                    checkGLcall("glDisable(GL_TEXTURE_2D)");
+                    glEnable(GL_TEXTURE_3D);
+                    checkGLcall("glEnable(GL_TEXTURE_3D)");
+                }
+                break;
+            case GL_TEXTURE_CUBE_MAP_ARB:
+                if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
+                    glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB);
+                    checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_CUBE_MAP_ARB)");
+                } else {
+                    glDisable(GL_TEXTURE_2D);
+                    checkGLcall("glDisable(GL_TEXTURE_2D)");
+                    glDisable(GL_TEXTURE_3D);
+                    checkGLcall("glDisable(GL_TEXTURE_3D)");
+                    if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
+                        glDisable(GL_TEXTURE_RECTANGLE_ARB);
+                        checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+                    }
+                    glEnable(GL_TEXTURE_CUBE_MAP_ARB);
+                    checkGLcall("glEnable(GL_TEXTURE_CUBE_MAP_ARB)");
+                }
+              break;
+        }
+    } else {
+        if(GL_SUPPORT(NV_TEXTURE_SHADER2)) {
+            glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE);
+            checkGLcall("glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_NONE)");
+        } else {
+            glEnable(GL_TEXTURE_2D);
+            checkGLcall("glEnable(GL_TEXTURE_2D)");
+            glDisable(GL_TEXTURE_3D);
+            checkGLcall("glDisable(GL_TEXTURE_3D)");
+            if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
+                glDisable(GL_TEXTURE_CUBE_MAP_ARB);
+                checkGLcall("glDisable(GL_TEXTURE_CUBE_MAP_ARB)");
+            }
+            if(GL_SUPPORT(ARB_TEXTURE_RECTANGLE)) {
+                glDisable(GL_TEXTURE_RECTANGLE_ARB);
+                checkGLcall("glDisable(GL_TEXTURE_RECTANGLE_ARB)");
+            }
+            /* Binding textures is done by samplers. A dummy texture will be bound */
+        }
+    }
+}
+#undef GLINFO_LOCATION
index 24045054687a48861c3afbdff3ffb8387f3b1773..b0d489273e7d38ec5342641f622ff722f4141f33 100644 (file)
@@ -1737,6 +1737,7 @@ GLenum CompareFunc(DWORD func);
 void   set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3);
 void   set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst);
 void   set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype);
+void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);
 
 void surface_set_compatible_renderbuffer(IWineD3DSurface *iface, unsigned int width, unsigned int height);
 GLenum surface_get_gl_buffer(IWineD3DSurface *iface, IWineD3DSwapChain *swapchain);