Stefan Dösinger : wined3d: Keep track of used float constants.

Alexandre Julliard julliard at winehq.org
Fri May 8 08:06:26 CDT 2009


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Thu May  7 17:31:20 2009 +0200

wined3d: Keep track of used float constants.

---

 dlls/wined3d/baseshader.c      |   60 +++++++++++++++++++++++++++++++++++++++-
 dlls/wined3d/pixelshader.c     |    3 +-
 dlls/wined3d/vertexshader.c    |    3 +-
 dlls/wined3d/wined3d_private.h |    3 +-
 4 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 105128d..957ec61 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -237,6 +237,14 @@ static void shader_delete_constant_list(struct list* clist) {
     list_init(clist);
 }
 
+static inline void set_bitmap_bit(DWORD *bitmap, DWORD bit)
+{
+    DWORD idx, shift;
+    idx = bit >> 5;
+    shift = bit & 0x1f;
+    bitmap[idx] |= (1 << shift);
+}
+
 static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct shader_reg_maps *reg_maps,
         DWORD register_type, UINT register_idx, BOOL has_rel_addr, BOOL pshader)
 {
@@ -293,6 +301,10 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh
                 }
                 reg_maps->usesrelconstF = TRUE;
             }
+            else
+            {
+                set_bitmap_bit(reg_maps->constf, register_idx);
+            }
             break;
 
         case WINED3DSPR_CONSTINT:
@@ -309,12 +321,32 @@ static void shader_record_register_usage(IWineD3DBaseShaderImpl *This, struct sh
     }
 }
 
+static unsigned char get_instr_regcount(enum WINED3D_SHADER_INSTRUCTION_HANDLER instr, int param)
+{
+    switch(instr)
+    {
+        case WINED3DSIH_M4x4:
+        case WINED3DSIH_M3x4:
+            return param == 1 ? 4 : 1;
+
+        case WINED3DSIH_M4x3:
+        case WINED3DSIH_M3x3:
+            return param == 1 ? 3 : 1;
+
+        case WINED3DSIH_M3x2:
+            return param == 1 ? 2 : 1;
+
+        default:
+            return 1;
+    }
+}
+
 /* Note that this does not count the loop register
  * as an address register. */
 
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
         struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
-        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code)
+        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size)
 {
     IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
     void *fe_data = This->baseShader.frontend_data;
@@ -338,6 +370,13 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
     reg_maps->shader_version = shader_version;
     pshader = shader_is_pshader_version(shader_version.type);
 
+    reg_maps->constf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+                                 sizeof(*reg_maps->constf) * ((constf_size + 31) / 32));
+    if(!reg_maps->constf) {
+        ERR("Out of memory\n");
+        return E_OUTOFMEMORY;
+    }
+
     while (!fe->shader_is_end(fe_data, &pToken))
     {
         struct wined3d_shader_instruction ins;
@@ -582,6 +621,24 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
                 fe->shader_read_src_param(fe_data, &pToken, &src_param, &src_rel_addr);
                 shader_record_register_usage(This, reg_maps, src_param.reg.type,
                         src_param.reg.idx, !!src_param.reg.rel_addr, pshader);
+                switch(get_instr_regcount(ins.handler_idx, i))
+                {
+                    case 4:
+                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
+                                src_param.reg.idx + 3, !!src_param.reg.rel_addr, pshader);
+                        /* drop through */
+                    case 3:
+                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
+                                src_param.reg.idx + 2, !!src_param.reg.rel_addr, pshader);
+                        /* drop through */
+                    case 2:
+                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
+                                src_param.reg.idx + 1, !!src_param.reg.rel_addr, pshader);
+                        /* drop through */
+                    case 1:
+                        shader_record_register_usage(This, reg_maps, src_param.reg.type,
+                                src_param.reg.idx, !!src_param.reg.rel_addr, pshader);
+                }
             }
         }
     }
@@ -1158,6 +1215,7 @@ void shader_cleanup(IWineD3DBaseShader *iface)
     IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *)iface;
 
     ((IWineD3DDeviceImpl *)This->baseShader.device)->shader_backend->shader_destroy(iface);
+    HeapFree(GetProcessHeap(), 0, This->baseShader.reg_maps.constf);
     HeapFree(GetProcessHeap(), 0, This->baseShader.function);
     shader_delete_constant_list(&This->baseShader.constantsF);
     shader_delete_constant_list(&This->baseShader.constantsB);
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 485857c..a2e182d 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -238,7 +238,8 @@ static HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *i
     list_init(&This->baseShader.constantsI);
 
     /* Second pass: figure out which registers are used, what the semantics are, etc.. */
-    hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction);
+    hr = shader_get_registers_used((IWineD3DBaseShader *)This, fe, reg_maps, This->semantics_in, NULL, pFunction,
+                                    GL_LIMITS(pshader_constantsF));
     if (FAILED(hr)) return hr;
 
     pshader_set_limits(This);
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index e8171ba..e5fb20f 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -279,7 +279,8 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
     This->min_rel_offset = GL_LIMITS(vshader_constantsF);
     This->max_rel_offset = 0;
     hr = shader_get_registers_used((IWineD3DBaseShader*) This, fe,
-            reg_maps, This->semantics_in, This->semantics_out, pFunction);
+            reg_maps, This->semantics_in, This->semantics_out, pFunction,
+            GL_LIMITS(vshader_constantsF));
     if (hr != WINED3D_OK) return hr;
 
     vshader_set_limits(This);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index c5f74fb..d40d0ab 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -625,6 +625,7 @@ typedef struct shader_reg_maps
     char packed_output[MAX_REG_OUTPUT];     /* vertex >= 3.0 */
     char attributes[MAX_ATTRIBS];           /* vertex */
     char labels[MAX_LABELS];                /* pixel, vertex */
+    DWORD *constf;                          /* pixel, vertex */
     DWORD texcoord_mask[MAX_REG_TEXCRD];    /* vertex < 3.0 */
     WORD integer_constants;                 /* MAX_CONST_I, 16 */
     WORD boolean_constants;                 /* MAX_CONST_B, 16 */
@@ -2579,7 +2580,7 @@ void shader_generate_main(IWineD3DBaseShader *iface, SHADER_BUFFER *buffer,
         const shader_reg_maps *reg_maps, const DWORD *pFunction);
 HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3d_shader_frontend *fe,
         struct shader_reg_maps *reg_maps, struct wined3d_shader_semantic *semantics_in,
-        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code);
+        struct wined3d_shader_semantic *semantics_out, const DWORD *byte_code, DWORD constf_size);
 void shader_init(struct IWineD3DBaseShaderClass *shader, IWineD3DDevice *device);
 const struct wined3d_shader_frontend *shader_select_frontend(DWORD version_token);
 void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe_data, const DWORD *pFunction);




More information about the wine-cvs mailing list