Stefan Dösinger : wined3d: Nested loop support.
Alexandre Julliard
julliard at winehq.org
Thu Oct 4 06:21:20 CDT 2007
Module: wine
Branch: master
Commit: 3f16f029405f7a243b4b42c81d617463b252b81e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3f16f029405f7a243b4b42c81d617463b252b81e
Author: Stefan Dösinger <stefan at codeweavers.com>
Date: Fri Sep 14 13:21:52 2007 +0200
wined3d: Nested loop support.
---
dlls/wined3d/baseshader.c | 12 ++++++++++--
dlls/wined3d/glsl_shader.c | 40 ++++++++++++++++++++++++++++++----------
dlls/wined3d/wined3d_private.h | 5 +++--
3 files changed, 43 insertions(+), 14 deletions(-)
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 67888b2..cba756e 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -193,6 +193,7 @@ HRESULT shader_get_registers_used(
IWineD3DStateBlockImpl *stateBlock) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
+ unsigned int cur_loop_depth = 0, max_loop_depth = 0;
/* There are some minor differences between pixel and vertex shaders */
char pshader = shader_is_pshader_version(This->baseShader.hex_version);
@@ -305,9 +306,15 @@ HRESULT shader_get_registers_used(
/* If there's a loop in the shader */
} else if (WINED3DSIO_LOOP == curOpcode->opcode ||
WINED3DSIO_REP == curOpcode->opcode) {
- reg_maps->loop = 1;
+ cur_loop_depth++;
+ if(cur_loop_depth > max_loop_depth)
+ max_loop_depth = cur_loop_depth;
pToken += curOpcode->num_params;
-
+
+ } else if (WINED3DSIO_ENDLOOP == curOpcode->opcode ||
+ WINED3DSIO_ENDREP == curOpcode->opcode) {
+ cur_loop_depth--;
+
/* For subroutine prototypes */
} else if (WINED3DSIO_LABEL == curOpcode->opcode) {
@@ -424,6 +431,7 @@ HRESULT shader_get_registers_used(
}
}
}
+ reg_maps->loop_depth = max_loop_depth;
return WINED3D_OK;
}
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index f05cd72..8a0603b 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -640,12 +640,12 @@ void shader_generate_glsl_declarations(
shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
}
- /* Declare loop register aL */
- if (reg_maps->loop) {
- shader_addline(buffer, "int aL;\n");
- shader_addline(buffer, "int tmpInt;\n");
+ /* Declare loop registers aLx */
+ for (i = 0; i < reg_maps->loop_depth; i++) {
+ shader_addline(buffer, "int aL%u;\n", i);
+ shader_addline(buffer, "int tmpInt%u;\n", i);
}
-
+
/* Temporary variables for matrix operations */
shader_addline(buffer, "vec4 tmp0;\n");
shader_addline(buffer, "vec4 tmp1;\n");
@@ -829,7 +829,7 @@ static void shader_glsl_get_register_name(
}
break;
case WINED3DSPR_LOOP:
- sprintf(tmpStr, "aL");
+ sprintf(tmpStr, "aL%u", This->baseShader.cur_loop_regno - 1);
break;
case WINED3DSPR_SAMPLER:
if (pshader)
@@ -1817,22 +1817,42 @@ void shader_glsl_sincos(SHADER_OPCODE_ARG* arg) {
/* FIXME: I don't think nested loops will work correctly this way. */
void shader_glsl_loop(SHADER_OPCODE_ARG* arg) {
glsl_src_param_t src1_param;
+ IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
shader_glsl_add_src_param(arg, arg->src[1], arg->src_addr[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
-
- shader_addline(arg->buffer, "for (tmpInt = 0, aL = %s.y; tmpInt < %s.x; tmpInt++, aL += %s.z) {\n",
- src1_param.reg_name, src1_param.reg_name, src1_param.reg_name);
+
+ 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++;
}
void shader_glsl_end(SHADER_OPCODE_ARG* arg) {
+ IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
+
shader_addline(arg->buffer, "}\n");
+
+ if(arg->opcode->opcode == WINED3DSIO_ENDLOOP) {
+ shader->baseShader.cur_loop_depth--;
+ shader->baseShader.cur_loop_regno--;
+ }
+ if(arg->opcode->opcode == WINED3DSIO_ENDREP) {
+ shader->baseShader.cur_loop_depth--;
+ }
}
void shader_glsl_rep(SHADER_OPCODE_ARG* arg) {
+ IWineD3DBaseShaderImpl* shader = (IWineD3DBaseShaderImpl*) arg->shader;
glsl_src_param_t src0_param;
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_0, &src0_param);
- shader_addline(arg->buffer, "for (tmpInt = 0; tmpInt < %s; tmpInt++) {\n", src0_param.param_str);
+ shader_addline(arg->buffer, "for (tmpInt%d = 0; tmpInt%d < %s; tmpInt%d++) {\n",
+ shader->baseShader.cur_loop_depth, shader->baseShader.cur_loop_depth,
+ src0_param.param_str, shader->baseShader.cur_loop_depth);
+ shader->baseShader.cur_loop_depth++;
}
void shader_glsl_if(SHADER_OPCODE_ARG* arg) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index da4a90c..431160d 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1654,8 +1654,8 @@ typedef struct shader_reg_maps {
char bumpmat, luminanceparams;
char usesnrm, vpos;
- /* Whether or not a loop is used in this shader */
- char loop;
+ /* Whether or not loops are used in this shader, and nesting depth */
+ unsigned loop_depth;
/* Whether or not this shader uses fog */
char fog;
@@ -1885,6 +1885,7 @@ typedef struct IWineD3DBaseShaderClass
UINT functionLength;
GLuint prgId;
BOOL is_compiled;
+ UINT cur_loop_depth, cur_loop_regno;
/* Type of shader backend */
int shader_mode;
More information about the wine-cvs
mailing list