wined3d: Improve color fixups in atifs shaders.
The abilities of this hardware is too limited to support generic sign / swizzle fixups. A generic handler would consume 4 of the 8 available color instruction slots and 2 alpha instruction slots. The bump mapping handler code has its own way of handling the color fixups. It merges the fixup into the perturbation calculation without requiring extra shader instructions. In theory this is possible for the majority of d3d texture ops as well, but I don't think this is worth the effort. I expect that this code will only be used for the ddraw signed format test in practice.
This commit is contained in:
parent
baf32ced74
commit
92fee8c04f
|
@ -376,6 +376,69 @@ static GLuint find_tmpreg(const struct texture_stage_op op[MAX_TEXTURES])
|
|||
}
|
||||
}
|
||||
|
||||
static const struct color_fixup_desc color_fixup_rg =
|
||||
{
|
||||
1, CHANNEL_SOURCE_X,
|
||||
1, CHANNEL_SOURCE_Y,
|
||||
0, CHANNEL_SOURCE_ONE,
|
||||
0, CHANNEL_SOURCE_ONE
|
||||
};
|
||||
static const struct color_fixup_desc color_fixup_rgl =
|
||||
{
|
||||
1, CHANNEL_SOURCE_X,
|
||||
1, CHANNEL_SOURCE_Y,
|
||||
0, CHANNEL_SOURCE_Z,
|
||||
0, CHANNEL_SOURCE_W
|
||||
};
|
||||
static const struct color_fixup_desc color_fixup_rgba =
|
||||
{
|
||||
1, CHANNEL_SOURCE_X,
|
||||
1, CHANNEL_SOURCE_Y,
|
||||
1, CHANNEL_SOURCE_Z,
|
||||
1, CHANNEL_SOURCE_W
|
||||
};
|
||||
|
||||
static BOOL op_reads_texture(const struct texture_stage_op *op)
|
||||
{
|
||||
return (op->carg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op->carg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op->carg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op->aarg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op->aarg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op->aarg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| op->cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA;
|
||||
}
|
||||
|
||||
static void atifs_color_fixup(const struct wined3d_gl_info *gl_info, struct color_fixup_desc fixup, GLuint reg)
|
||||
{
|
||||
if(is_same_fixup(fixup, color_fixup_rg))
|
||||
{
|
||||
wrap_op1(gl_info, GL_MOV_ATI, reg, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, GL_NONE,
|
||||
reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
|
||||
wrap_op1(gl_info, GL_MOV_ATI, reg, GL_BLUE_BIT_ATI, GL_NONE,
|
||||
GL_ONE, GL_NONE, GL_NONE);
|
||||
wrap_op1(gl_info, GL_MOV_ATI, reg, GL_ALPHA, GL_NONE,
|
||||
GL_ONE, GL_NONE, GL_NONE);
|
||||
}
|
||||
else if(is_same_fixup(fixup, color_fixup_rgl))
|
||||
{
|
||||
wrap_op1(gl_info, GL_MOV_ATI, reg, GL_RED_BIT_ATI | GL_GREEN_BIT_ATI, GL_NONE,
|
||||
reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
|
||||
}
|
||||
else if (is_same_fixup(fixup, color_fixup_rgba))
|
||||
{
|
||||
wrap_op1(gl_info, GL_MOV_ATI, reg, GL_NONE, GL_NONE,
|
||||
reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
|
||||
wrap_op1(gl_info, GL_MOV_ATI, reg, GL_ALPHA, GL_NONE,
|
||||
reg, GL_NONE, GL_2X_BIT_ATI | GL_BIAS_BIT_ATI);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Should not happen - atifs_color_fixup_supported refuses other fixups. */
|
||||
ERR("Unsupported color fixup.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], const struct wined3d_gl_info *gl_info)
|
||||
{
|
||||
GLuint ret = GL_EXTCALL(glGenFragmentShadersATI(1));
|
||||
|
@ -491,13 +554,7 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
|
|||
swizzle = GL_SWIZZLE_STQ_DQ_ATI;
|
||||
}
|
||||
|
||||
if ((op[stage].carg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op[stage].carg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op[stage].carg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op[stage].aarg0 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op[stage].aarg1 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| (op[stage].aarg2 & WINED3DTA_SELECTMASK) == WINED3DTA_TEXTURE
|
||||
|| op[stage].cop == WINED3D_TOP_BLEND_TEXTURE_ALPHA)
|
||||
if (op_reads_texture(&op[stage]))
|
||||
{
|
||||
if (stage > 0
|
||||
&& (op[stage - 1].cop == WINED3D_TOP_BUMPENVMAP
|
||||
|
@ -545,6 +602,12 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
|
|||
dstreg = GL_REG_0_ATI;
|
||||
}
|
||||
|
||||
if (op[stage].cop == WINED3D_TOP_BUMPENVMAP || op[stage].cop == WINED3D_TOP_BUMPENVMAP_LUMINANCE)
|
||||
{
|
||||
/* Those are handled in the first pass of the shader (generation pass 1 and 2) already */
|
||||
continue;
|
||||
}
|
||||
|
||||
arg0 = register_for_arg(op[stage].carg0, gl_info, stage, &argmod0, &rep0, tmparg);
|
||||
arg1 = register_for_arg(op[stage].carg1, gl_info, stage, &argmod1, &rep1, tmparg);
|
||||
arg2 = register_for_arg(op[stage].carg2, gl_info, stage, &argmod2, &rep2, tmparg);
|
||||
|
@ -552,6 +615,9 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
|
|||
argmodextra = GL_NONE;
|
||||
extrarg = GL_NONE;
|
||||
|
||||
if (op_reads_texture(&op[stage]) && !is_identity_fixup(op[stage].color_fixup))
|
||||
atifs_color_fixup(gl_info, op[stage].color_fixup, GL_REG_0_ATI + stage);
|
||||
|
||||
switch (op[stage].cop)
|
||||
{
|
||||
case WINED3D_TOP_SELECT_ARG2:
|
||||
|
@ -683,11 +749,6 @@ static GLuint gen_ati_shader(const struct texture_stage_op op[MAX_TEXTURES], con
|
|||
arg2, rep2, argmod2);
|
||||
break;
|
||||
|
||||
case WINED3D_TOP_BUMPENVMAP:
|
||||
case WINED3D_TOP_BUMPENVMAP_LUMINANCE:
|
||||
/* Those are handled in the first pass of the shader(generation pass 1 and 2) already */
|
||||
break;
|
||||
|
||||
default: FIXME("Unhandled color operation %d on stage %d\n", op[stage].cop, stage);
|
||||
}
|
||||
|
||||
|
@ -1196,9 +1257,8 @@ static BOOL atifs_color_fixup_supported(struct color_fixup_desc fixup)
|
|||
}
|
||||
|
||||
/* We only support sign fixup of the first two channels. */
|
||||
if (fixup.x_source == CHANNEL_SOURCE_X && fixup.y_source == CHANNEL_SOURCE_Y
|
||||
&& fixup.z_source == CHANNEL_SOURCE_Z && fixup.w_source == CHANNEL_SOURCE_W
|
||||
&& !fixup.z_sign_fixup && !fixup.w_sign_fixup)
|
||||
if (is_identity_fixup(fixup) || is_same_fixup(fixup, color_fixup_rg)
|
||||
|| is_same_fixup(fixup, color_fixup_rgl) || is_same_fixup(fixup, color_fixup_rgba))
|
||||
{
|
||||
TRACE("[OK]\n");
|
||||
return TRUE;
|
||||
|
|
Loading…
Reference in New Issue