Stefan Dösinger : wined3d: Pixel Shader varying indexing.

Alexandre Julliard julliard at winehq.org
Tue Nov 6 08:24:40 CST 2007


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

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Sun Oct 28 00:08:56 2007 +0200

wined3d: Pixel Shader varying indexing.

---

 dlls/wined3d/glsl_shader.c |   58 ++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 51 insertions(+), 7 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 2aadbfc..e344bad 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -773,9 +773,16 @@ static void shader_glsl_get_register_name(
     case WINED3DSPR_INPUT:
         if (pshader) {
             /* Pixel shaders >= 3.0 */
-            if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3)
-                sprintf(tmpStr, "IN[%u]", reg);
-             else {
+            if (WINED3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 3) {
+                if (param & WINED3DSHADER_ADDRMODE_RELATIVE) {
+                    glsl_src_param_t rel_param;
+                    shader_glsl_add_src_param(arg, addr_token, 0, WINED3DSP_WRITEMASK_0, &rel_param);
+
+                    sprintf(tmpStr, "IN[%s + %u]", rel_param.param_str, reg);
+                } else {
+                    sprintf(tmpStr, "IN[%u]", reg);
+                }
+            } else {
                 if (reg==0)
                     strcpy(tmpStr, "gl_Color");
                 else
@@ -1817,13 +1824,50 @@ void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) {
 void shader_glsl_loop(SHADER_OPCODE_ARG* arg) {
     glsl_src_param_t src1_param;
     IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
+    DWORD regtype = shader_get_regtype(arg->src[1]);
+    DWORD reg = arg->src[1] & WINED3DSP_REGNUM_MASK;
+    const DWORD *control_values = NULL;
+    local_constant *constant;
 
     shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
 
-    shader_addline(arg->buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z) {\n",
-                   shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno,
-                   src1_param.reg_name, shader->baseShader.cur_loop_depth, src1_param.reg_name,
-                   shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno, src1_param.reg_name);
+    /* Try to hardcode the loop control parameters if possible. Direct3D 9 class hardware doesn't support real
+     * varying indexing, but Microsoft designed this feature for Shader model 2.x+. If the loop control is
+     * known at compile time, the GLSL compiler can unroll the loop, and replace indirect addressing with direct
+     * addressing.
+     */
+    if(regtype == WINED3DSPR_CONSTINT) {
+        LIST_FOR_EACH_ENTRY(constant, &shader->baseShader.constantsI, local_constant, entry) {
+            if(constant->idx == reg) {
+                control_values = constant->value;
+                break;
+            }
+        }
+    }
+
+    if(control_values) {
+        if(control_values[2] > 0) {
+            shader_addline(arg->buffer, "for (aL%u = %d; aL%u < (%d * %d + %d); aL%u += %d) {\n",
+                           shader->baseShader.cur_loop_depth, control_values[1],
+                           shader->baseShader.cur_loop_depth, control_values[0], control_values[2], control_values[1],
+                           shader->baseShader.cur_loop_depth, control_values[2]);
+        } else if(control_values[2] == 0) {
+            shader_addline(arg->buffer, "for (aL%u = %d, tmpInt%u = 0; tmpInt%u < %d; tmpInt%u++) {\n",
+                           shader->baseShader.cur_loop_depth, control_values[1], shader->baseShader.cur_loop_depth,
+                           shader->baseShader.cur_loop_depth, control_values[0],
+                           shader->baseShader.cur_loop_depth);
+        } else {
+            shader_addline(arg->buffer, "for (aL%u = %d; aL%u > (%d * %d + %d); aL%u += %d) {\n",
+                           shader->baseShader.cur_loop_depth, control_values[1],
+                           shader->baseShader.cur_loop_depth, control_values[0], control_values[2], control_values[1],
+                           shader->baseShader.cur_loop_depth, control_values[2]);
+        }
+    } else {
+        shader_addline(arg->buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z) {\n",
+                       shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno,
+                       src1_param.reg_name, shader->baseShader.cur_loop_depth, src1_param.reg_name,
+                       shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_regno, src1_param.reg_name);
+    }
 
     shader->baseShader.cur_loop_depth++;
     shader->baseShader.cur_loop_regno++;




More information about the wine-cvs mailing list