Module: wine Branch: master Commit: 8d746c31bacd8e76d01c8c53c4033289aa18b269 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8d746c31bacd8e76d01c8c53c4...
Author: Henri Verbeet hverbeet@codeweavers.com Date: Mon Aug 10 09:30:48 2009 +0200
wined3d: Properly handle negative loop step in shader_glsl_loop().
---
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 d791092..0e01b09 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -725,6 +725,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);