From 0615c8e4545c46fd2405f794a600f8b9f15747c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sun, 28 Oct 2007 00:08:56 +0200 Subject: [PATCH] wined3d: Pixel Shader varying indexing. --- dlls/wined3d/glsl_shader.c | 58 +++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 2aadbfc7c77..e344badaf95 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++;