Commit a006d256 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Fix texdepth instruction.

parent a305af0b
......@@ -884,6 +884,32 @@ void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg) {
current_state->current_row = 0;
}
void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg) {
SHADER_BUFFER* buffer = arg->buffer;
char dst_name[50];
/* texdepth has an implicit destination, the fragment depth value. It's only parameter,
* which is essentially an input, is the destiantion register because it is the first
* param. According to the msdn, this must be register r5, but let's keep it more flexible
* here
*/
pshader_get_register_name(arg->dst, dst_name);
/* According to the msdn, the source register(must be r5) is unusable after
* the texdepth instruction, so we're free to modify it
*/
shader_addline(buffer, "MIN %s.g, %s.g, one.g;\n", dst_name, dst_name);
/* How to deal with the special case dst_name.g == 0? if r != 0, then
* the r * (1 / 0) will give infinity, which is clamped to 1.0, the correct
* result. But if r = 0.0, then 0 * inf = 0, which is incorrect.
*/
shader_addline(buffer, "RCP %s.g, %s.g;\n", dst_name, dst_name);
shader_addline(buffer, "MUL TMP.x, %s.r, %s.g;\n", dst_name, dst_name);
shader_addline(buffer, "MIN TMP.x, TMP.x, one.r;\n", dst_name, dst_name);
shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n", dst_name, dst_name);
}
/** Handles transforming all WINED3DSIO_M?x? opcodes for
Vertex shaders to ARB_vertex_program codes */
void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg) {
......
......@@ -1733,7 +1733,13 @@ void pshader_glsl_texdepth(SHADER_OPCODE_ARG* arg) {
shader_glsl_add_dst_param(arg, arg->dst, 0, &dst_param);
shader_addline(arg->buffer, "gl_FragDepth = %s.x / %s.y;\n", dst_param.reg_name, dst_param.reg_name);
/* Tests show that texdepth never returns anything below 0.0, and that r5.y is clamped to 1.0.
* Negative input is accepted, -0.25 / -0.5 returns 0.5. GL should clamp gl_FragDepth to [0;1], but
* this doesn't always work, so clamp the results manually. Wether or not the x value is clamped at 1
* too is irrelevant, since if x = 0, any y value < 1.0(and > 1.0 is not allowed) results in a result
* >= 1.0 or < 0.0
*/
shader_addline(arg->buffer, "gl_FragDepth = (%s.y == 0.0) ? 1.0 : clamp((%s.x / min(%s.y, 1.0)), 0.0, 1.0);\n", dst_param.reg_name, dst_param.reg_name, dst_param.reg_name);
}
/** Process the WINED3DSIO_TEXM3X2DEPTH instruction in GLSL:
......
......@@ -238,7 +238,7 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = {
{WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texm3x2depth, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXDP3, "texdp3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texdp3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXM3x3, "texm3x3", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)},
{WINED3DSIO_TEXDEPTH, "texdepth", GLNAME_REQUIRE_GLSL, 1, 1, NULL, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_TEXDEPTH, "texdepth", NULL, 1, 1, pshader_hw_texdepth, pshader_glsl_texdepth, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_BEM, "bem", "undefined", 1, 3, pshader_hw_bem, pshader_glsl_bem, WINED3DPS_VERSION(1,4), WINED3DPS_VERSION(1,4)},
{WINED3DSIO_DSX, "dsx", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1},
{WINED3DSIO_DSY, "dsy", NULL, 1, 2, NULL, shader_glsl_map2gl, WINED3DPS_VERSION(2,1), -1},
......
......@@ -1785,6 +1785,7 @@ extern void pshader_hw_texm3x3pad(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3tex(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3spec(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texm3x3vspec(SHADER_OPCODE_ARG* arg);
extern void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg);
/* ARB vertex shader prototypes */
extern void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment