[WINED3D 1] Place immediate constants in the same array as global constants.

Ivan Gyurdiev ivg231 at gmail.com
Sun Jul 9 23:51:03 CDT 2006


Global constants are set with the Set*ShaderConstant calls.
Local/immediate constants are set inside the shader itself, and 
overwrite any global ones at the same index.

Currently we use an array notation for global constants, and a 
fixed-name notation for locals, and keep track of overrides. This is 
broken imho, because of relative addressing. Relative addressing allows 
to use a register as an offset into an array. Using a different 
notation/namespace for immediate constants means that: (1) you can't use 
relative addressing to access an immediate constants, since it only 
works with arrays, and (2) you can't use an offset that matches the 
index of an immediate constants for relative addressing - I've seen (2) 
attempted in the game Painkiller.

So, instead of dealing with any of this, do the following:

- move DEF, DEFI, DEFB handling into the register counting pass
- keep track of defined constants as a linked list (because there's a 
few of them)
- apply immediate constants after global constants in the constant 
loading function
- both types of constants now get loaded with array notation in the 
shader (into the same array)

==============================
Also note that there's diffrent lifetime rules for immediate constants 
in d3d8 and d3d9, and as far as I know we implement one of them wrong. 
Here I stick with the current behavior, which I think is d3d9-compliant.
-------------- next part --------------
---
 dlls/wined3d/arb_program_shader.c |  106 ++++++++---------
 dlls/wined3d/baseshader.c         |   60 +++++++---
 dlls/wined3d/glsl_shader.c        |  231 ++++++++++++++++++-------------------
 dlls/wined3d/pixelshader.c        |   25 +++-
 dlls/wined3d/vertexshader.c       |   22 +++-
 dlls/wined3d/wined3d_private.h    |   21 ++-
 6 files changed, 259 insertions(+), 206 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index a8f92fc..25f295a 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -46,6 +46,7 @@ #define GLINFO_LOCATION      (*gl_info)
  *  or GL_FRAGMENT_PROGRAM_ARB (for pixel shaders)
  */
 void shader_arb_load_constantsF(
+    IWineD3DBaseShaderImpl* This,
     WineD3D_GL_Info *gl_info,
     GLuint target_type,
     unsigned max_constants,
@@ -53,6 +54,7 @@ void shader_arb_load_constantsF(
     BOOL* constants_set) {
 
     int i;
+    struct list* ptr;
     
     for (i=0; i<max_constants; ++i) {
         if (NULL == constants_set || constants_set[i]) {
@@ -64,6 +66,22 @@ void shader_arb_load_constantsF(
             checkGLcall("glProgramEnvParameter4fvARB");
         }
     }
+
+    /* Load immediate constants */
+    ptr = list_head(&This->baseShader.constantsF);
+    while (ptr) {
+
+        local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
+        unsigned int idx = lconst->idx;
+        GLfloat* values = (GLfloat*) lconst->value;
+
+        TRACE("Loading local constants %i: %f, %f, %f, %f\n", idx,
+            values[0], values[1], values[2], values[3]);
+
+        GL_EXTCALL(glProgramEnvParameter4fvARB(target_type, idx, values));
+        checkGLcall("glProgramEnvParameter4fvARB");
+        ptr = list_next(&This->baseShader.constantsF, ptr);
+    }
 }
 
 /**
@@ -81,19 +99,20 @@ void shader_arb_load_constants(
     WineD3D_GL_Info *gl_info = &((IWineD3DImpl*)stateBlock->wineD3DDevice->wineD3D)->gl_info;
 
     if (useVertexShader) {
-        IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
+        IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
+        IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
         IWineD3DVertexDeclarationImpl* vertexDeclaration = 
-            (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
+            (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
 
         if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
             /* Load DirectX 8 float constants for vertex shader */
-            shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
+            shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
                                        WINED3D_VSHADER_MAX_CONSTANTS,
                                        vertexDeclaration->constants, NULL);
         }
 
         /* Load DirectX 9 float constants for vertex shader */
-        shader_arb_load_constantsF(gl_info, GL_VERTEX_PROGRAM_ARB,
+        shader_arb_load_constantsF(vshader, gl_info, GL_VERTEX_PROGRAM_ARB,
                                    WINED3D_VSHADER_MAX_CONSTANTS,
                                    stateBlock->vertexShaderConstantF,
                                    stateBlock->set.vertexShaderConstantsF);
@@ -101,8 +120,10 @@ void shader_arb_load_constants(
 
     if (usePixelShader) {
 
+        IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
+
         /* Load DirectX 9 float constants for pixel shader */
-        shader_arb_load_constantsF(gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
+        shader_arb_load_constantsF(pshader, gl_info, GL_FRAGMENT_PROGRAM_ARB, WINED3D_PSHADER_MAX_CONSTANTS,
                                    stateBlock->pixelShaderConstantF,
                                    stateBlock->set.pixelShaderConstantsF);
     }
@@ -264,7 +285,8 @@ static void vshader_program_add_input_pa
     }
 }
 
-static void pshader_get_register_name(const DWORD param, char* regstr, CHAR *constants) {
+static void pshader_get_register_name(
+    const DWORD param, char* regstr) {
 
     DWORD reg = param & D3DSP_REGNUM_MASK;
     DWORD regtype = shader_get_regtype(param);
@@ -281,10 +303,7 @@ static void pshader_get_register_name(co
         }
     break;
     case D3DSPR_CONST:
-        if (constants[reg])
-            sprintf(regstr, "C%lu", reg);
-        else
-            sprintf(regstr, "C[%lu]", reg);
+        sprintf(regstr, "C[%lu]", reg);
     break;
     case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
         sprintf(regstr,"T%lu", reg);
@@ -347,15 +366,7 @@ static void vshader_program_add_param(SH
     strcat(hwLine, tmpReg);
     break;
   case D3DSPR_CONST:
-    /* FIXME: some constants are named so we need a constants map*/
-    if (arg->reg_maps->constantsF[reg]) {
-        if (param & D3DVS_ADDRMODE_RELATIVE) {
-            FIXME("Relative addressing not expected for a named constant %lu\n", reg);
-        }
-        sprintf(tmpReg, "C%lu", reg);
-    } else {
-        sprintf(tmpReg, "C[%s%lu]", (param & D3DVS_ADDRMODE_RELATIVE) ? "A0.x + " : "", reg);
-    }
+    sprintf(tmpReg, "C[%s%lu]", (param & D3DVS_ADDRMODE_RELATIVE) ? "A0.x + " : "", reg);
     strcat(hwLine, tmpReg);
     break;
   case D3DSPR_ADDR: /*case D3DSPR_TEXTURE:*/
@@ -394,8 +405,7 @@ static void pshader_gen_input_modifier_l
     SHADER_BUFFER* buffer,
     const DWORD instr,
     int tmpreg,
-    char *outregstr,
-    CHAR *constants) {
+    char *outregstr) {
 
     /* Generate a line that does the input modifier computation and return the input register to use */
     char regstr[256];
@@ -406,7 +416,7 @@ static void pshader_gen_input_modifier_l
     insert_line = 1;
 
     /* Get register name */
-    pshader_get_register_name(instr, regstr, constants);
+    pshader_get_register_name(instr, regstr);
     pshader_get_input_register_swizzle(instr, swzstr);
 
     switch (instr & D3DSP_SRCMOD_MASK) {
@@ -469,22 +479,6 @@ inline static void pshader_gen_output_mo
         regstr, write_mask, regstr, shift_tab[shift]);
 }
 
-/** Process the D3DSIO_DEF opcode into an ARB string - creates a local vec4
- * float constant, and stores it's usage on the regmaps. */
-void shader_hw_def(SHADER_OPCODE_ARG* arg) {
-
-    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
-
-    shader_addline(arg->buffer, 
-                   "PARAM C%lu = { %f, %f, %f, %f };\n", reg,
-                   *((const float *)(arg->src + 0)),
-                   *((const float *)(arg->src + 1)),
-                   *((const float *)(arg->src + 2)),
-                   *((const float *)(arg->src + 3)) );
-
-    arg->reg_maps->constantsF[reg] = 1;
-}
-
 void pshader_hw_cnd(SHADER_OPCODE_ARG* arg) {
 
     SHADER_BUFFER* buffer = arg->buffer;
@@ -495,14 +489,14 @@ void pshader_hw_cnd(SHADER_OPCODE_ARG* a
     /* FIXME: support output modifiers */
 
     /* Handle output register */
-    pshader_get_register_name(arg->dst, dst_name, arg->reg_maps->constantsF);
+    pshader_get_register_name(arg->dst, dst_name);
     pshader_get_write_mask(arg->dst, dst_wmask);
     strcat(dst_name, dst_wmask);
 
     /* Generate input register names (with modifiers) */
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0], arg->reg_maps->constantsF);
-    pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1], arg->reg_maps->constantsF);
-    pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2], arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0]);
+    pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1]);
+    pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2]);
 
     shader_addline(buffer, "ADD TMP, -%s, coefdiv.x;\n", src_name[0]);
     shader_addline(buffer, "CMP %s, TMP, %s, %s;\n", dst_name, src_name[1], src_name[2]);
@@ -518,14 +512,14 @@ void pshader_hw_cmp(SHADER_OPCODE_ARG* a
     /* FIXME: support output modifiers */
 
     /* Handle output register */
-    pshader_get_register_name(arg->dst, dst_name, arg->reg_maps->constantsF);
+    pshader_get_register_name(arg->dst, dst_name);
     pshader_get_write_mask(arg->dst, dst_wmask);
     strcat(dst_name, dst_wmask);
 
     /* Generate input register names (with modifiers) */
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0], arg->reg_maps->constantsF);
-    pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1], arg->reg_maps->constantsF);
-    pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2], arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src_name[0]);
+    pshader_gen_input_modifier_line(buffer, arg->src[1], 1, src_name[1]);
+    pshader_gen_input_modifier_line(buffer, arg->src[2], 2, src_name[2]);
 
     shader_addline(buffer, "CMP %s, %s, %s, %s;\n", dst_name,
         src_name[0], src_name[2], src_name[1]);
@@ -574,10 +568,10 @@ void pshader_hw_map2gl(SHADER_OPCODE_ARG
 
           /* Generate input register names (with modifiers) */
           for (i = 1; i < curOpcode->num_params; ++i)
-              pshader_gen_input_modifier_line(buffer, src[i-1], i-1, operands[i], arg->reg_maps->constantsF);
+              pshader_gen_input_modifier_line(buffer, src[i-1], i-1, operands[i]);
 
           /* Handle output register */
-          pshader_get_register_name(dst, output_rname, arg->reg_maps->constantsF);
+          pshader_get_register_name(dst, output_rname);
           strcpy(operands[0], output_rname);
           pshader_get_write_mask(dst, output_wmask);
           strcat(operands[0], output_wmask);
@@ -614,14 +608,14 @@ void pshader_hw_tex(SHADER_OPCODE_ARG* a
 
     /* All versions have a destination register */
     reg_dest_code = dst & D3DSP_REGNUM_MASK;
-    pshader_get_register_name(dst, reg_dest, arg->reg_maps->constantsF);
+    pshader_get_register_name(dst, reg_dest);
 
     /* 1.0-1.3: Use destination register as coordinate source.
        1.4+: Use provided coordinate source register. */
    if (hex_version < D3DPS_VERSION(1,4))
       strcpy(reg_coord, reg_dest);
    else
-      pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord, arg->reg_maps->constantsF);
+      pshader_gen_input_modifier_line(buffer, src[0], 0, reg_coord);
 
   /* 1.0-1.4: Use destination register number as texture code.
      2.0+: Use provided sampler number as texure code. */
@@ -693,7 +687,7 @@ void pshader_hw_texm3x2pad(SHADER_OPCODE
     SHADER_BUFFER* buffer = arg->buffer;
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.x, T%lu, %s;\n", reg, src0_name);
 }
 
@@ -703,7 +697,7 @@ void pshader_hw_texm3x2tex(SHADER_OPCODE
     SHADER_BUFFER* buffer = arg->buffer;
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.y, T%lu, %s;\n", reg, src0_name);
     shader_addline(buffer, "TEX T%lu, TMP, texture[%lu], 2D;\n", reg, reg);
 }
@@ -716,7 +710,7 @@ void pshader_hw_texm3x3pad(SHADER_OPCODE
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.%c, T%lu, %s;\n", 'x' + current_state->current_row, reg, src0_name);
     current_state->texcoord_w[current_state->current_row++] = reg;
 }
@@ -729,7 +723,7 @@ void pshader_hw_texm3x3tex(SHADER_OPCODE
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
 
     /* Cubemap textures will be more used than 3D ones. */
@@ -745,7 +739,7 @@ void pshader_hw_texm3x3vspec(SHADER_OPCO
     SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
 
     /* Construct the eye-ray vector from w coordinates */
@@ -772,7 +766,7 @@ void pshader_hw_texm3x3spec(SHADER_OPCOD
     SHADER_BUFFER* buffer = arg->buffer;
     char src0_name[50];
 
-    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name, arg->reg_maps->constantsF);
+    pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0_name);
     shader_addline(buffer, "DP3 TMP.z, T%lu, %s;\n", reg, src0_name);
 
     /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 84c86c7..5baca25 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -174,7 +174,7 @@ unsigned int shader_get_float_offset(con
 /* Note that this does not count the loop register
  * as an address register. */
 
-void shader_get_registers_used(
+HRESULT shader_get_registers_used(
     IWineD3DBaseShader *iface,
     shader_reg_maps* reg_maps,
     semantic* semantics_in,
@@ -187,7 +187,7 @@ void shader_get_registers_used(
     char pshader = shader_is_pshader_version(This->baseShader.hex_version);
 
     if (pToken == NULL)
-        return;
+        return WINED3D_OK;
 
     while (D3DVS_END() != *pToken) {
         CONST SHADER_OPCODE* curOpcode;
@@ -245,8 +245,31 @@ void shader_get_registers_used(
             } else if (D3DSPR_SAMPLER == regtype)
                 reg_maps->samplers[regnum] = usage;
 
-        /* Skip definitions (for now) */
         } else if (D3DSIO_DEF == curOpcode->opcode) {
+
+            local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
+            if (!lconst) return E_OUTOFMEMORY;
+            lconst->idx = *pToken & D3DSP_REGNUM_MASK;
+            memcpy(&lconst->value, pToken + 1, 4 * sizeof(DWORD));
+            list_add_head(&This->baseShader.constantsF, &lconst->entry);
+            pToken += curOpcode->num_params;
+
+        } else if (D3DSIO_DEFI == curOpcode->opcode) {
+
+            local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
+            if (!lconst) return E_OUTOFMEMORY;
+            lconst->idx = *pToken & D3DSP_REGNUM_MASK;
+            memcpy(&lconst->value, pToken + 1, 4 * sizeof(DWORD));
+            list_add_head(&This->baseShader.constantsI, &lconst->entry);
+            pToken += curOpcode->num_params;
+
+        } else if (D3DSIO_DEFB == curOpcode->opcode) {
+
+            local_constant* lconst = HeapAlloc(GetProcessHeap(), 0, sizeof(local_constant));
+            if (!lconst) return E_OUTOFMEMORY;
+            lconst->idx = *pToken & D3DSP_REGNUM_MASK;
+            memcpy(&lconst->value, pToken + 1, 1 * sizeof(DWORD));
+            list_add_head(&This->baseShader.constantsB, &lconst->entry);
             pToken += curOpcode->num_params;
 
         /* If there's a loop in the shader */
@@ -315,6 +338,8 @@ void shader_get_registers_used(
              }
         }
     }
+
+    return WINED3D_OK;
 }
 
 static void shader_dump_decl_usage(
@@ -655,7 +680,10 @@ void shader_generate_main(
 
             /* Nothing to do */
             } else if (D3DSIO_DCL == curOpcode->opcode ||
-                       D3DSIO_NOP == curOpcode->opcode) {
+                       D3DSIO_NOP == curOpcode->opcode ||
+                       D3DSIO_DEF == curOpcode->opcode ||
+                       D3DSIO_DEFI == curOpcode->opcode ||
+                       D3DSIO_DEFB == curOpcode->opcode) {
 
                 pToken += shader_skip_opcode(This, curOpcode, opcode_token);
 
@@ -682,15 +710,7 @@ void shader_generate_main(
 
                     DWORD param, addr_token = 0; 
 
-                    /* DEF* instructions have constant src parameters, not registers */
-                    if (curOpcode->opcode == D3DSIO_DEF || 
-                        curOpcode->opcode == D3DSIO_DEFI || 
-                        curOpcode->opcode == D3DSIO_DEFB) {
-                        param = *pToken++;
-
-                    } else
-                        pToken += shader_get_param(iface, pToken, &param, &addr_token);
-
+                    pToken += shader_get_param(iface, pToken, &param, &addr_token);
                     hw_arg.src[i-1] = param;
                     hw_arg.src_addr[i-1] = addr_token;
                 }
@@ -882,4 +902,16 @@ void shader_trace_init(
     }
 }
 
-/* TODO: Move other shared code here */
+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);
+    }
+}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 46965bf..f132dec 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -78,17 +78,19 @@ void shader_glsl_load_psamplers(
  * When @constants_set == NULL, it will load all the constants.
  */
 void shader_glsl_load_constantsF(
+    IWineD3DBaseShaderImpl* This,
     WineD3D_GL_Info *gl_info,
     GLhandleARB programId,
     unsigned max_constants,
     float* constants,
-    BOOL* constants_set,
-    char is_pshader) {
+    BOOL* constants_set) {
         
     GLhandleARB tmp_loc;
     int i;
     char tmp_name[7];
+    char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
     const char* prefix = is_pshader? "PC":"VC";
+    struct list* ptr;
 
     for (i=0; i<max_constants; ++i) {
         if (NULL == constants_set || constants_set[i]) {
@@ -108,6 +110,26 @@ void shader_glsl_load_constantsF(
             }
         }
     }
+
+    /* Load immediate constants */
+    ptr = list_head(&This->baseShader.constantsF);
+    while (ptr) {
+        local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
+        unsigned int idx = lconst->idx;
+        GLfloat* values = (GLfloat*) lconst->value;
+
+        TRACE("Loading local constants %i: %f, %f, %f, %f\n", idx,
+            values[0], values[1], values[2], values[3]);
+
+        snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
+        tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+        if (tmp_loc != -1) {
+            /* We found this uniform name in the program - go ahead and send the data */
+            GL_EXTCALL(glUniform4fvARB(tmp_loc, 1, values));
+            checkGLcall("glUniform4fvARB");
+        }
+        ptr = list_next(&This->baseShader.constantsF, ptr);
+    }
 }
 
 /** 
@@ -115,17 +137,19 @@ void shader_glsl_load_constantsF(
  * When @constants_set == NULL, it will load all the constants.
  */
 void shader_glsl_load_constantsI(
+    IWineD3DBaseShaderImpl* This,
     WineD3D_GL_Info *gl_info,
     GLhandleARB programId,
     unsigned max_constants,
     int* constants,
-    BOOL* constants_set,
-    char is_pshader) {
+    BOOL* constants_set) {
     
     GLhandleARB tmp_loc;
     int i;
     char tmp_name[7];
+    char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
     const char* prefix = is_pshader? "PI":"VI";
+    struct list* ptr;
 
     for (i=0; i<max_constants; ++i) {
         if (NULL == constants_set || constants_set[i]) {
@@ -144,6 +168,26 @@ void shader_glsl_load_constantsI(
             }
         }
     }
+
+    /* Load immediate constants */
+    ptr = list_head(&This->baseShader.constantsI);
+    while (ptr) {
+        local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
+        unsigned int idx = lconst->idx;
+        GLint* values = (GLint*) lconst->value;
+
+        TRACE("Loading local constants %i: %i, %i, %i, %i\n", idx,
+            values[0], values[1], values[2], values[3]);
+
+        snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
+        tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+        if (tmp_loc != -1) {
+            /* We found this uniform name in the program - go ahead and send the data */
+            GL_EXTCALL(glUniform4ivARB(tmp_loc, 1, values));
+            checkGLcall("glUniform4ivARB");
+        }
+        ptr = list_next(&This->baseShader.constantsI, ptr);
+    }
 }
 
 /** 
@@ -151,17 +195,19 @@ void shader_glsl_load_constantsI(
  * When @constants_set == NULL, it will load all the constants.
  */
 void shader_glsl_load_constantsB(
+    IWineD3DBaseShaderImpl* This,
     WineD3D_GL_Info *gl_info,
     GLhandleARB programId,
     unsigned max_constants,
     BOOL* constants,
-    BOOL* constants_set,
-    char is_pshader) {
+    BOOL* constants_set) {
     
     GLhandleARB tmp_loc;
     int i;
     char tmp_name[7];
+    char is_pshader = shader_is_pshader_version(This->baseShader.hex_version);
     const char* prefix = is_pshader? "PB":"VB";
+    struct list* ptr;
 
     for (i=0; i<max_constants; ++i) {
         if (NULL == constants_set || constants_set[i]) {
@@ -179,6 +225,25 @@ void shader_glsl_load_constantsB(
             }
         }
     }
+
+    /* Load immediate constants */
+    ptr = list_head(&This->baseShader.constantsB);
+    while (ptr) {
+        local_constant* lconst = LIST_ENTRY(ptr, struct local_constant, entry);
+        unsigned int idx = lconst->idx;
+        GLint* values = (GLint*) lconst->value;
+
+        TRACE("Loading local constants %i: %i\n", idx, values[0]);
+
+        snprintf(tmp_name, sizeof(tmp_name), "%s[%i]", prefix, idx);
+        tmp_loc = GL_EXTCALL(glGetUniformLocationARB(programId, tmp_name));
+        if (tmp_loc != -1) {
+            /* We found this uniform name in the program - go ahead and send the data */
+            GL_EXTCALL(glUniform1ivARB(tmp_loc, 1, values));
+            checkGLcall("glUniform1ivARB");
+        }
+        ptr = list_next(&This->baseShader.constantsB, ptr);
+    }
 }
 
 
@@ -201,51 +266,55 @@ void shader_glsl_load_constants(
     }
 
     if (useVertexShader) {
-        IWineD3DVertexShaderImpl* vshader = (IWineD3DVertexShaderImpl*) stateBlock->vertexShader;
+        IWineD3DBaseShaderImpl* vshader = (IWineD3DBaseShaderImpl*) stateBlock->vertexShader;
+        IWineD3DVertexShaderImpl* vshader_impl = (IWineD3DVertexShaderImpl*) vshader;
+
         IWineD3DVertexDeclarationImpl* vertexDeclaration =
-            (IWineD3DVertexDeclarationImpl*) vshader->vertexDeclaration;
+            (IWineD3DVertexDeclarationImpl*) vshader_impl->vertexDeclaration;
 
         if (NULL != vertexDeclaration && NULL != vertexDeclaration->constants) {
             /* Load DirectX 8 float constants/uniforms for vertex shader */
-            shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
-                                        vertexDeclaration->constants, NULL, 0);
+            shader_glsl_load_constantsF(vshader, gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
+                                        vertexDeclaration->constants, NULL);
         }
 
         /* Load DirectX 9 float constants/uniforms for vertex shader */
-        shader_glsl_load_constantsF(gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
+        shader_glsl_load_constantsF(vshader, gl_info, programId, WINED3D_VSHADER_MAX_CONSTANTS,
                                     stateBlock->vertexShaderConstantF, 
-                                    stateBlock->set.vertexShaderConstantsF, 0);
+                                    stateBlock->set.vertexShaderConstantsF);
 
         /* Load DirectX 9 integer constants/uniforms for vertex shader */
-        shader_glsl_load_constantsI(gl_info, programId, MAX_CONST_I,
+        shader_glsl_load_constantsI(vshader, gl_info, programId, MAX_CONST_I,
                                     stateBlock->vertexShaderConstantI,
-                                    stateBlock->set.vertexShaderConstantsI, 0);
+                                    stateBlock->set.vertexShaderConstantsI);
 
         /* Load DirectX 9 boolean constants/uniforms for vertex shader */
-        shader_glsl_load_constantsB(gl_info, programId, MAX_CONST_B,
+        shader_glsl_load_constantsB(vshader, gl_info, programId, MAX_CONST_B,
                                     stateBlock->vertexShaderConstantB,
-                                    stateBlock->set.vertexShaderConstantsB, 0);
+                                    stateBlock->set.vertexShaderConstantsB);
     }
 
     if (usePixelShader) {
 
+        IWineD3DBaseShaderImpl* pshader = (IWineD3DBaseShaderImpl*) stateBlock->pixelShader;
+
         /* Load pixel shader samplers */
         shader_glsl_load_psamplers(gl_info, iface);
 
         /* Load DirectX 9 float constants/uniforms for pixel shader */
-        shader_glsl_load_constantsF(gl_info, programId, WINED3D_PSHADER_MAX_CONSTANTS,
+        shader_glsl_load_constantsF(pshader, gl_info, programId, WINED3D_PSHADER_MAX_CONSTANTS,
                                     stateBlock->pixelShaderConstantF,
-                                    stateBlock->set.pixelShaderConstantsF, 1);
+                                    stateBlock->set.pixelShaderConstantsF);
 
         /* Load DirectX 9 integer constants/uniforms for pixel shader */
-        shader_glsl_load_constantsI(gl_info, programId, MAX_CONST_I,
+        shader_glsl_load_constantsI(pshader, gl_info, programId, MAX_CONST_I,
                                     stateBlock->pixelShaderConstantI, 
-                                    stateBlock->set.pixelShaderConstantsI, 1);
+                                    stateBlock->set.pixelShaderConstantsI);
         
         /* Load DirectX 9 boolean constants/uniforms for pixel shader */
-        shader_glsl_load_constantsB(gl_info, programId, MAX_CONST_B,
+        shader_glsl_load_constantsB(pshader, gl_info, programId, MAX_CONST_B,
                                     stateBlock->pixelShaderConstantB, 
-                                    stateBlock->set.pixelShaderConstantsB, 1);
+                                    stateBlock->set.pixelShaderConstantsB);
     }
 }
 
@@ -510,61 +579,34 @@ static void shader_glsl_get_register_nam
     {
         const char* prefix = pshader? "PC":"VC";
 
-        if (arg->reg_maps->constantsF[reg]) {
-            /* Use a local constant declared by "def" */
-            
-            if (param & D3DVS_ADDRMODE_RELATIVE) {
-                 /* FIXME: Copy all constants (local & global) into a single array
-                  * to handle this case where we want a relative address from a 
-                  * local constant. */
-                FIXME("Relative addressing not yet supported on named constants\n");
-            } else {
-                sprintf(tmpStr, "%s%lu", prefix, reg);
-            }
-        } else {
-            /* Use a global constant declared in Set____ShaderConstantF() */
-            if (param & D3DVS_ADDRMODE_RELATIVE) {
-                /* Relative addressing on shaders 2.0+ have a relative address token, 
-                 * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
-                if (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2)  {
-                    char relStr[100], relReg[50], relMask[6];
-                    shader_glsl_add_param(arg, addr_token, 0, TRUE, relReg, relMask, relStr);
-                    sprintf(tmpStr, "%s[%s + %lu]", prefix, relStr, reg);
-                } else {
-                    sprintf(tmpStr, "%s[A0.x + %lu]", prefix, reg);
-                }
-            } else {
-                /* Just a normal global constant - no relative addressing */
-                sprintf(tmpStr, "%s[%lu]", prefix, reg);
-            }
-        }
+        /* Relative addressing */
+        if (param & D3DVS_ADDRMODE_RELATIVE) {
+
+           /* Relative addressing on shaders 2.0+ have a relative address token, 
+            * prior to that, it was hard-coded as "A0.x" because there's only 1 register */
+           if (D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2)  {
+               char relStr[100], relReg[50], relMask[6];
+               shader_glsl_add_param(arg, addr_token, 0, TRUE, relReg, relMask, relStr);
+               sprintf(tmpStr, "%s[%s + %lu]", prefix, relStr, reg);
+           } else
+               sprintf(tmpStr, "%s[A0.x + %lu]", prefix, reg);
+
+        } else
+             sprintf(tmpStr, "%s[%lu]", prefix, reg);
+
         break;
     }
     case D3DSPR_CONSTINT:
-        if (arg->reg_maps->constantsI[reg]) {
-            /* Integer vector was defined locally using "defi" */
-            sprintf(tmpStr, "I%lu", reg);
-        } else {
-            /* Uniform integer value - pixel or vertex specific */
-            if (pshader) {
-                sprintf(tmpStr, "PI[%lu]", reg);
-            } else {
-                sprintf(tmpStr, "VI[%lu]", reg);
-            }
-        }
+        if (pshader)
+            sprintf(tmpStr, "PI[%lu]", reg);
+        else
+            sprintf(tmpStr, "VI[%lu]", reg);
         break;
     case D3DSPR_CONSTBOOL:
-        if (arg->reg_maps->constantsB[reg]) {
-            /* Boolean was defined locally using "defb" */
-            sprintf(tmpStr, "B%lu", reg);
-        } else {
-            /* Uniform boolean value - pixel or vertex specific */
-            if (pshader) {
-                sprintf(tmpStr, "PB[%lu]", reg);
-            } else {
-                sprintf(tmpStr, "VB[%lu]", reg);
-            }
-        }
+        if (pshader)
+            sprintf(tmpStr, "PB[%lu]", reg);
+        else
+            sprintf(tmpStr, "VB[%lu]", reg);
         break;
     case D3DSPR_TEXTURE: /* case D3DSPR_ADDR: */
         if (pshader) {
@@ -1041,51 +1083,6 @@ void shader_glsl_lrp(SHADER_OPCODE_ARG* 
                    tmpLine, src2_str, src0_str, src1_str, src2_str, dst_mask);
 }
 
-/** Process the D3DSIO_DEF opcode into a GLSL string - creates a local vec4
- * float constant, and stores it's usage on the regmaps. */
-void shader_glsl_def(SHADER_OPCODE_ARG* arg) {
-
-    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
-
-    IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
-    char pshader = shader_is_pshader_version(This->baseShader.hex_version);
-    const char* prefix = pshader? "PC":"VC";
-
-    shader_addline(arg->buffer, 
-                   "const vec4 %s%lu = vec4(%f, %f, %f, %f);\n", prefix, reg,
-                   *((const float *)(arg->src + 0)),
-                   *((const float *)(arg->src + 1)),
-                   *((const float *)(arg->src + 2)),
-                   *((const float *)(arg->src + 3)) );
-
-    arg->reg_maps->constantsF[reg] = 1;
-}
-
-/** Process the D3DSIO_DEFI opcode into a GLSL string - creates a local ivec4
- * integer constant, and stores it's usage on the regmaps. */
-void shader_glsl_defi(SHADER_OPCODE_ARG* arg) {
-
-    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
-
-    shader_addline(arg->buffer, 
-                   "const ivec4 I%lu = ivec4(%ld, %ld, %ld, %ld);\n", reg,
-                   (long)arg->src[0], (long)arg->src[1],
-                   (long)arg->src[2], (long)arg->src[3]);
-
-    arg->reg_maps->constantsI[reg] = 1;
-}
-
-/** Process the D3DSIO_DEFB opcode into a GLSL string - creates a local boolean
- * constant, and stores it's usage on the regmaps. */
-void shader_glsl_defb(SHADER_OPCODE_ARG* arg) {
-
-    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
-
-    shader_addline(arg->buffer, "const bool B%lu = %s;\n", reg, (arg->src[0]) ? "true" : "false");
-
-    arg->reg_maps->constantsB[reg] = 1;
-}
-
 /** Process the D3DSIO_LIT instruction in GLSL:
  * dst.x = dst.w = 1.0
  * dst.y = (src0.x > 0) ? src0.x
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index bc15dc9..40d7a40 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -72,13 +72,16 @@ static ULONG  WINAPI IWineD3DPixelShader
     TRACE("(%p) : Releasing from %ld\n", This, This->ref);
     ref = InterlockedDecrement(&This->ref);
     if (ref == 0) {
-        HeapFree(GetProcessHeap(), 0, This);
         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));
             checkGLcall("glDeleteObjectARB");
         }
+        shader_delete_constant_list(&This->baseShader.constantsF);
+        shader_delete_constant_list(&This->baseShader.constantsB);
+        shader_delete_constant_list(&This->baseShader.constantsI);
+        HeapFree(GetProcessHeap(), 0, This);
     }
     return ref;
 }
@@ -690,9 +693,9 @@ CONST SHADER_OPCODE IWineD3DPixelShaderI
     {D3DSIO_LABEL,    "label",    GLNAME_REQUIRE_GLSL, 0, 1, pshader_label,   NULL, NULL, 0, 0},
 
     /* Constant definitions */
-    {D3DSIO_DEF,      "def",      "undefined",         1, 5, pshader_def,     shader_hw_def, shader_glsl_def, 0, 0},
-    {D3DSIO_DEFB,     "defb",     GLNAME_REQUIRE_GLSL, 1, 2, pshader_defb,    NULL, shader_glsl_defb, 0, 0},
-    {D3DSIO_DEFI,     "defi",     GLNAME_REQUIRE_GLSL, 1, 5, pshader_defi,    NULL, shader_glsl_defi, 0, 0},
+    {D3DSIO_DEF,      "def",      "undefined",         1, 5, pshader_def,     NULL, NULL, 0, 0},
+    {D3DSIO_DEFB,     "defb",     GLNAME_REQUIRE_GLSL, 1, 2, pshader_defb,    NULL, NULL, 0, 0},
+    {D3DSIO_DEFI,     "defi",     GLNAME_REQUIRE_GLSL, 1, 5, pshader_defi,    NULL, NULL, 0, 0},
 
     /* Texture */
     {D3DSIO_TEXCOORD, "texcoord", "undefined", 1, 1, pshader_texcoord,    pshader_hw_texcoord, pshader_glsl_texcoord, 0, D3DPS_VERSION(1,3)},
@@ -898,16 +901,23 @@ #endif
 static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, CONST DWORD *pFunction) {
 
     IWineD3DPixelShaderImpl *This =(IWineD3DPixelShaderImpl *)iface;
+    HRESULT hr;
     shader_reg_maps reg_maps;
 
     /* First pass: trace shader */
     shader_trace_init((IWineD3DBaseShader*) This, pFunction);
     pshader_set_limits(This);
 
+    /* Initialize immediate constant lists */
+    list_init(&This->baseShader.constantsF);
+    list_init(&This->baseShader.constantsB);
+    list_init(&This->baseShader.constantsI);
+
     /* Second pass: figure out which registers are used, what the semantics are, etc.. */
-    memset(&reg_maps, 0, sizeof(shader_reg_maps)); 
-    shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
+    memset(&reg_maps, 0, sizeof(shader_reg_maps));
+    hr = shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
         This->semantics_in, NULL, pFunction);
+    if (hr != WINED3D_OK) return hr;
     /* FIXME: validate reg_maps against OpenGL */
 
     /* Generate HW shader in needed */
@@ -920,13 +930,12 @@ static HRESULT WINAPI IWineD3DPixelShade
     TRACE("(%p) : Copying the function\n", This);
     if (NULL != pFunction) {
         This->baseShader.function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
+        if (!This->baseShader.function) return E_OUTOFMEMORY;
         memcpy((void *)This->baseShader.function, pFunction, This->baseShader.functionLength);
     } else {
         This->baseShader.function = NULL;
     }
 
-    /* TODO: Some proper return values for failures */
-    TRACE("(%p) : Returning WINED3D_OK\n", This);
     return WINED3D_OK;
 }
 
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index db07675..d71b5c5 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -531,9 +531,9 @@ CONST SHADER_OPCODE IWineD3DVertexShader
     {D3DSIO_DCL,      "dcl",      NULL,                0, 2, vshader_dcl,     NULL, NULL, 0, 0},
 
     /* Constant definitions */
-    {D3DSIO_DEF,      "def",      NULL,                1, 5, vshader_def,     shader_hw_def, shader_glsl_def, 0, 0},
-    {D3DSIO_DEFB,     "defb",     GLNAME_REQUIRE_GLSL, 1, 2, vshader_defb,    NULL, shader_glsl_defb, 0, 0},
-    {D3DSIO_DEFI,     "defi",     GLNAME_REQUIRE_GLSL, 1, 5, vshader_defi,    NULL, shader_glsl_defi, 0, 0},
+    {D3DSIO_DEF,      "def",      NULL,                1, 5, vshader_def,     NULL, NULL, 0, 0},
+    {D3DSIO_DEFB,     "defb",     GLNAME_REQUIRE_GLSL, 1, 2, vshader_defb,    NULL, NULL, 0, 0},
+    {D3DSIO_DEFI,     "defi",     GLNAME_REQUIRE_GLSL, 1, 5, vshader_defi,    NULL, NULL, 0, 0},
 
     /* Flow control - requires GLSL or software shaders */
     {D3DSIO_REP ,     "rep",      GLNAME_REQUIRE_GLSL, 0, 1, vshader_rep,     NULL, NULL, 0, 0},
@@ -1045,7 +1045,11 @@ static ULONG WINAPI IWineD3DVertexShader
             GL_EXTCALL(glDeleteObjectARB(This->baseShader.prgId));
             checkGLcall("glDeleteObjectARB");
         }
-            HeapFree(GetProcessHeap(), 0, This);
+        shader_delete_constant_list(&This->baseShader.constantsF);
+        shader_delete_constant_list(&This->baseShader.constantsB);
+        shader_delete_constant_list(&This->baseShader.constantsI);
+        HeapFree(GetProcessHeap(), 0, This);
+
     }
     return ref;
 }
@@ -1099,12 +1103,18 @@ static HRESULT WINAPI IWineD3DVertexShad
 static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface, CONST DWORD *pFunction) {
 
     IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
+    HRESULT hr;
     shader_reg_maps reg_maps;
 
     /* First pass: trace shader */
     shader_trace_init((IWineD3DBaseShader*) This, pFunction);
     vshader_set_limits(This);
 
+    /* Initialize immediate constant lists */
+    list_init(&This->baseShader.constantsF);
+    list_init(&This->baseShader.constantsB);
+    list_init(&This->baseShader.constantsI);
+
     /* Preload semantics for d3d8 shaders */
     if (This->vertexDeclaration) {
        IWineD3DVertexDeclarationImpl* vdecl = (IWineD3DVertexDeclarationImpl*) This->vertexDeclaration;
@@ -1117,8 +1127,9 @@ static HRESULT WINAPI IWineD3DVertexShad
 
     /* Second pass: figure out registers used, semantics, etc.. */
     memset(&reg_maps, 0, sizeof(shader_reg_maps));
-    shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
+    hr = shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps,
        This->semantics_in, This->semantics_out, pFunction);
+    if (hr != WINED3D_OK) return hr;
 
     /* Generate HW shader in needed */
     This->baseShader.shader_mode = wined3d_settings.vs_selected_mode;
@@ -1128,6 +1139,7 @@ static HRESULT WINAPI IWineD3DVertexShad
     /* copy the function ... because it will certainly be released by application */
     if (NULL != pFunction) {
         This->baseShader.function = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->baseShader.functionLength);
+        if (!This->baseShader.function) return E_OUTOFMEMORY;
         memcpy((void *)This->baseShader.function, pFunction, This->baseShader.functionLength);
     } else {
         This->baseShader.function = NULL;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0f6d85e..0fc8b3f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1279,7 +1279,6 @@ #define MAX_REG_TEXCRD 8
 #define MAX_REG_INPUT 12
 #define MAX_REG_OUTPUT 12
 #define MAX_ATTRIBS 16
-#define MAX_CONST_F 256
 #define MAX_CONST_I 16
 #define MAX_CONST_B 16
 
@@ -1288,6 +1287,12 @@ typedef struct semantic {
     DWORD reg;
 } semantic;
 
+typedef struct local_constant {
+    struct list entry;
+    unsigned int idx;
+    DWORD value[4];
+} local_constant;
+
 typedef struct shader_reg_maps {
 
     char texcoord[MAX_REG_TEXCRD];          /* pixel < 3.0 */
@@ -1297,10 +1302,6 @@ typedef struct shader_reg_maps {
     char packed_output[MAX_REG_OUTPUT];     /* vertex >= 3.0 */
     char attributes[MAX_ATTRIBS];           /* vertex */
 
-    char constantsF[MAX_CONST_F];           /* pixel, vertex */
-    char constantsI[MAX_CONST_I];           /* pixel & vertex >= 2.0 */
-    char constantsB[MAX_CONST_B];           /* pixel & vertex >= 2.0 */
-    
     /* Sampler usage tokens 
      * Use 0 as default (bit 31 is always 1 on a valid token) */
     DWORD samplers[MAX_SAMPLERS];
@@ -1372,6 +1373,9 @@ extern const SHADER_OPCODE* shader_get_o
     IWineD3DBaseShader *iface, 
     const DWORD code);
 
+extern void shader_delete_constant_list(
+    struct list* clist);
+
 /* Vertex shader utility functions */
 extern BOOL vshader_get_input(
     IWineD3DVertexShader* iface,
@@ -1475,6 +1479,11 @@ typedef struct IWineD3DBaseShaderClass
     /* Type of shader backend */
     int shader_mode;
 
+    /* Immediate constants (override global ones) */
+    struct list constantsB;
+    struct list constantsF;
+    struct list constantsI;
+
 } IWineD3DBaseShaderClass;
 
 typedef struct IWineD3DBaseShaderImpl {
@@ -1486,7 +1495,7 @@ typedef struct IWineD3DBaseShaderImpl {
     IWineD3DBaseShaderClass         baseShader;
 } IWineD3DBaseShaderImpl;
 
-extern void shader_get_registers_used(
+extern HRESULT shader_get_registers_used(
     IWineD3DBaseShader *iface,
     shader_reg_maps* reg_maps,
     semantic* semantics_in,
-- 
1.4.0



More information about the wine-patches mailing list