Stefan Dösinger : wined3d: Clear the constant list before finding constants.

Alexandre Julliard julliard at winehq.org
Mon Jan 14 09:33:24 CST 2008


Module: wine
Branch: master
Commit: 5426cd6317f1f388102606cce111adaaee8046f7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5426cd6317f1f388102606cce111adaaee8046f7

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Jan  8 22:31:24 2008 +0100

wined3d: Clear the constant list before finding constants.

shader_get_registers_used is delayed until compile time for some 1.x
shaders, mostly to wait for the right vertex declaration to be
set. This means that on a recompile it will be run again, adding
another instance of each local constant, which in turn causes compile
errors because of constant redeclaration. Just purging the lists
before finding the constants is a simple and reliable solution.

---

 dlls/wined3d/baseshader.c |   35 +++++++++++++++++++++--------------
 1 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 858bf7f..870d92e 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -181,6 +181,20 @@ unsigned int shader_get_float_offset(const DWORD reg) {
      }
 }
 
+static void shader_delete_constant_list(struct list* clist) {
+
+    struct list *ptr;
+    struct local_constant* constant;
+
+    ptr = list_head(clist);
+    while (ptr) {
+        constant = LIST_ENTRY(ptr, struct local_constant, entry);
+        ptr = list_next(clist, ptr);
+        HeapFree(GetProcessHeap(), 0, constant);
+    }
+    list_init(clist);
+}
+
 /* Note that this does not count the loop register
  * as an address register. */
 
@@ -204,6 +218,13 @@ HRESULT shader_get_registers_used(
     if (pToken == NULL)
         return WINED3D_OK;
 
+    /* get_registers_used is called on every compile on some 1.x shaders, which can result
+     * in stacking up a collection of local constants. Delete the old constants if existing
+     */
+    shader_delete_constant_list(&This->baseShader.constantsF);
+    shader_delete_constant_list(&This->baseShader.constantsB);
+    shader_delete_constant_list(&This->baseShader.constantsI);
+
     while (WINED3DVS_END() != *pToken) {
         CONST SHADER_OPCODE* curOpcode;
         DWORD opcode_token;
@@ -1075,20 +1096,6 @@ void shader_trace_init(
     }
 }
 
-static void shader_delete_constant_list(
-    struct list* clist) {
-
-    struct list *ptr;
-    struct local_constant* constant;
-
-    ptr = list_head(clist);
-    while (ptr) {
-        constant = LIST_ENTRY(ptr, struct local_constant, entry);
-        ptr = list_next(clist, ptr);
-        HeapFree(GetProcessHeap(), 0, constant);
-    }
-}
-
 static void shader_none_select(IWineD3DDevice *iface, BOOL usePS, BOOL useVS) {}
 static void shader_none_select_depth_blt(IWineD3DDevice *iface) {}
 static void shader_none_load_constants(IWineD3DDevice *iface, char usePS, char useVS) {}




More information about the wine-cvs mailing list