[PATCH 1/5] wined3d: Properly handle negative loop step in shader_glsl_loop().

Henri Verbeet hverbeet at codeweavers.com
Mon Aug 10 02:30:48 CDT 2009


---
 dlls/wined3d/arb_program_shader.c |   11 +--------
 dlls/wined3d/glsl_shader.c        |   41 +++++++++++++++++++++++-------------
 dlls/wined3d/wined3d_private.h    |    7 ++++++
 3 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 4ed57a0..c7eeb8f 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -91,13 +91,6 @@ static inline BOOL ffp_clip_emul(IWineD3DStateBlockImpl *stateblock)
 
 /* ARB_program_shader private data */
 
-struct loop_control
-{
-    unsigned int count;
-    unsigned int start;
-    int step;
-};
-
 struct control_frame
 {
     struct                          list entry;
@@ -115,7 +108,7 @@ struct control_frame
         unsigned int                loop_no;
         unsigned int                ifc_no;
     };
-    struct loop_control             loop_control;
+    struct wined3d_shader_loop_control loop_control;
     BOOL                            had_else;
 };
 
@@ -4686,7 +4679,7 @@ static inline BOOL get_bool_const(const struct wined3d_shader_instruction *ins,
 }
 
 static void get_loop_control_const(const struct wined3d_shader_instruction *ins,
-        IWineD3DBaseShaderImpl *This, UINT idx, struct loop_control *loop_control)
+        IWineD3DBaseShaderImpl *This, UINT idx, struct wined3d_shader_loop_control *loop_control)
 {
     struct shader_arb_ctx_priv *priv = ins->ctx->backend_data;
 
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 1239b0a..0f5871e 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2485,22 +2485,33 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
         }
     }
 
-    if(control_values) {
-        if(control_values[2] > 0) {
-            shader_addline(ins->ctx->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(ins->ctx->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],
+    if (control_values)
+    {
+        struct wined3d_shader_loop_control loop_control;
+        loop_control.count = control_values[0];
+        loop_control.start = control_values[1];
+        loop_control.step = (int)control_values[2];
+
+        if (loop_control.step > 0)
+        {
+            shader_addline(ins->ctx->buffer, "for (aL%u = %u; aL%u < (%u * %d + %u); aL%u += %d) {\n",
+                    shader->baseShader.cur_loop_depth, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.count, loop_control.step, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.step);
+        }
+        else if (loop_control.step < 0)
+        {
+            shader_addline(ins->ctx->buffer, "for (aL%u = %u; aL%u > (%u * %d + %u); aL%u += %d) {\n",
+                    shader->baseShader.cur_loop_depth, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.count, loop_control.step, loop_control.start,
+                    shader->baseShader.cur_loop_depth, loop_control.step);
+        }
+        else
+        {
+            shader_addline(ins->ctx->buffer, "for (aL%u = %u, tmpInt%u = 0; tmpInt%u < %u; tmpInt%u++) {\n",
+                    shader->baseShader.cur_loop_depth, loop_control.start, shader->baseShader.cur_loop_depth,
+                    shader->baseShader.cur_loop_depth, loop_control.count,
                     shader->baseShader.cur_loop_depth);
-        } else {
-            shader_addline(ins->ctx->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(ins->ctx->buffer,
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d3e1053..aaa2c71 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -727,6 +727,13 @@ struct wined3d_shader_attribute
     UINT usage_idx;
 };
 
+struct wined3d_shader_loop_control
+{
+    unsigned int count;
+    unsigned int start;
+    int step;
+};
+
 struct wined3d_shader_frontend
 {
     void *(*shader_init)(const DWORD *ptr, const struct wined3d_shader_signature *output_signature);
-- 
1.6.0.6




More information about the wine-patches mailing list