wined3d: Implement SM4 loops in the GLSL shader backend.

This commit is contained in:
Henri Verbeet 2012-10-09 20:41:50 +02:00 committed by Alexandre Julliard
parent 6e4ecdf854
commit e34acc2251
1 changed files with 60 additions and 46 deletions

View File

@ -1181,10 +1181,14 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
}
/* Declare loop registers aLx */
for (i = 0; i < reg_maps->loop_depth; i++) {
if (reg_maps->shader_version.major < 4)
{
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");
@ -2954,18 +2958,21 @@ static void shader_glsl_sgn(const struct wined3d_shader_instruction *ins)
static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
{
struct wined3d_shader_loop_state *loop_state = ins->ctx->loop_state;
struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
const struct wined3d_shader *shader = ins->ctx->shader;
const struct wined3d_shader_lconst *constant;
struct glsl_src_param src1_param;
const DWORD *control_values = NULL;
if (ins->ctx->reg_maps->shader_version.major < 4)
{
shader_glsl_add_src_param(ins, &ins->src[1], WINED3DSP_WRITEMASK_ALL, &src1_param);
/* 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.
*/
/* 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 (ins->src[1].reg.type == WINED3DSPR_CONSTINT)
{
LIST_FOR_EACH_ENTRY(constant, &shader->constantsI, struct wined3d_shader_lconst, entry)
@ -2987,35 +2994,42 @@ static void shader_glsl_loop(const struct wined3d_shader_instruction *ins)
if (loop_control.step > 0)
{
shader_addline(ins->ctx->buffer, "for (aL%u = %u; aL%u < (%u * %d + %u); aL%u += %d) {\n",
shader_addline(buffer, "for (aL%u = %u; aL%u < (%u * %d + %u); aL%u += %d)\n{\n",
loop_state->current_depth, loop_control.start,
loop_state->current_depth, loop_control.count, loop_control.step, loop_control.start,
loop_state->current_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_addline(buffer, "for (aL%u = %u; aL%u > (%u * %d + %u); aL%u += %d)\n{\n",
loop_state->current_depth, loop_control.start,
loop_state->current_depth, loop_control.count, loop_control.step, loop_control.start,
loop_state->current_depth, loop_control.step);
}
else
{
shader_addline(ins->ctx->buffer, "for (aL%u = %u, tmpInt%u = 0; tmpInt%u < %u; tmpInt%u++) {\n",
shader_addline(buffer, "for (aL%u = %u, tmpInt%u = 0; tmpInt%u < %u; tmpInt%u++)\n{\n",
loop_state->current_depth, loop_control.start, loop_state->current_depth,
loop_state->current_depth, loop_control.count,
loop_state->current_depth);
}
} else {
shader_addline(ins->ctx->buffer,
"for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z) {\n",
}
else
{
shader_addline(buffer, "for (tmpInt%u = 0, aL%u = %s.y; tmpInt%u < %s.x; tmpInt%u++, aL%u += %s.z)\n{\n",
loop_state->current_depth, loop_state->current_reg,
src1_param.reg_name, loop_state->current_depth, src1_param.reg_name,
loop_state->current_depth, loop_state->current_reg, src1_param.reg_name);
}
++loop_state->current_depth;
++loop_state->current_reg;
}
else
{
shader_addline(buffer, "for (;;)\n{\n");
}
++loop_state->current_depth;
}
static void shader_glsl_end(const struct wined3d_shader_instruction *ins)