wined3d: Nested loop support.
This commit is contained in:
parent
3c6d97278f
commit
3f16f02940
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue