From 9531a108971f519a791b56137f52108f5fb81080 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Tue, 25 Sep 2007 01:00:27 +0200 Subject: [PATCH] wined3d: Add support for some unimplemented instructions to arb shaders. --- dlls/wined3d/arb_program_shader.c | 78 +++++++++++++++++++++++++++++++ dlls/wined3d/pixelshader.c | 8 ++-- dlls/wined3d/wined3d_private.h | 4 ++ 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index d534bb56ed5..fc543d6dd93 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1283,6 +1283,84 @@ void pshader_hw_texdepth(SHADER_OPCODE_ARG* arg) { shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n", dst_name, dst_name); } +/** Process the WINED3DSIO_TEXDP3TEX instruction in ARB: + * Take a 3-component dot product of the TexCoord[dstreg] and src, + * then perform a 1D texture lookup from stage dstregnum, place into dst. */ +void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg) { + SHADER_BUFFER* buffer = arg->buffer; + DWORD sampler_idx = arg->dst & WINED3DSP_REGNUM_MASK; + char src0[50]; + char dst_str[8]; + + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0); + shader_addline(buffer, "MOV TMP, 0.0;\n"); + shader_addline(buffer, "DP3 TMP.x, T%u, %s;\n", sampler_idx, src0); + + sprintf(dst_str, "T%u", sampler_idx); + shader_hw_sample(arg, sampler_idx, dst_str, "TMP", FALSE /* Only one coord, can't be projected */); +} + +/** Process the WINED3DSIO_TEXDP3 instruction in ARB: + * Take a 3-component dot product of the TexCoord[dstreg] and src. */ +void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg) { + char src0[50]; + char dst_str[50]; + char dst_mask[6]; + DWORD dstreg = arg->dst & WINED3DSP_REGNUM_MASK; + SHADER_BUFFER* buffer = arg->buffer; + + /* Handle output register */ + pshader_get_register_name(arg->dst, dst_str); + shader_arb_get_write_mask(arg, arg->dst, dst_mask); + + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0); + shader_addline(buffer, "DP3 %s%s, T%u, %s;\n", dst_str, dst_mask, dstreg, src0); + + /* TODO: Handle output modifiers */ +} + +/** Process the WINED3DSIO_TEXM3X3 instruction in ARB + * Perform the 3rd row of a 3x3 matrix multiply */ +void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg) { + SHADER_BUFFER* buffer = arg->buffer; + char dst_str[50]; + char dst_mask[6]; + char src0[50]; + DWORD dst_reg = arg->dst & WINED3DSP_REGNUM_MASK; + + pshader_get_register_name(arg->dst, dst_str); + shader_arb_get_write_mask(arg, arg->dst, dst_mask); + + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0); + shader_addline(buffer, "DP3 TMP.z, T%u, %s;\n", dst_reg, src0); + shader_addline(buffer, "MOV %s%s, TMP;\n", dst_str, dst_mask); + + /* TODO: Handle output modifiers */ +} + +/** Process the WINED3DSIO_TEXM3X2DEPTH instruction in ARB: + * Last row of a 3x2 matrix multiply, use the result to calculate the depth: + * Calculate tmp0.y = TexCoord[dstreg] . src.xyz; (tmp0.x has already been calculated) + * depth = (tmp0.y == 0.0) ? 1.0 : tmp0.x / tmp0.y + */ +void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg) { + SHADER_BUFFER* buffer = arg->buffer; + DWORD dst_reg = arg->dst & WINED3DSP_REGNUM_MASK; + char src0[50]; + + pshader_gen_input_modifier_line(buffer, arg->src[0], 0, src0); + shader_addline(buffer, "DP3 TMP.y, T%u, %s;\n", dst_reg, src0); + + /* 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 TMP.y, TMP.y;\n"); + shader_addline(buffer, "MUL TMP.x, TMP.x, TMP.y;\n"); + shader_addline(buffer, "MIN TMP.x, TMP.x, one.r;\n"); + shader_addline(buffer, "MAX result.depth, TMP.x, 0.0;\n"); +} + /** Handles transforming all WINED3DSIO_M?x? opcodes for Vertex shaders to ARB_vertex_program codes */ void vshader_hw_mnxn(SHADER_OPCODE_ARG* arg) { diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index 02704d110dd..24c025d6906 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -238,10 +238,10 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { {WINED3DSIO_TEXM3x3SPEC, "texm3x3spec", "undefined", 1, 3, pshader_hw_texm3x3spec, pshader_glsl_texm3x3spec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x3VSPEC, "texm3x3vspec", "undefined", 1, 2, pshader_hw_texm3x3vspec, pshader_glsl_texm3x3vspec, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, {WINED3DSIO_TEXM3x3TEX, "texm3x3tex", "undefined", 1, 2, pshader_hw_texm3x3tex, pshader_glsl_texm3x3tex, WINED3DPS_VERSION(1,0), WINED3DPS_VERSION(1,3)}, - {WINED3DSIO_TEXDP3TEX, "texdp3tex", GLNAME_REQUIRE_GLSL, 1, 2, NULL, pshader_glsl_texdp3tex, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, - {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_TEXDP3TEX, "texdp3tex", NULL, 1, 2, pshader_hw_texdp3tex, pshader_glsl_texdp3tex, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, pshader_hw_texm3x2depth, pshader_glsl_texm3x2depth, WINED3DPS_VERSION(1,3), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXDP3, "texdp3", NULL, 1, 2, pshader_hw_texdp3, pshader_glsl_texdp3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, + {WINED3DSIO_TEXM3x3, "texm3x3", NULL, 1, 2, pshader_hw_texm3x3, pshader_glsl_texm3x3, WINED3DPS_VERSION(1,2), WINED3DPS_VERSION(1,3)}, {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}, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 67edc0a3000..8844ffa0b42 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1782,6 +1782,10 @@ 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); extern void pshader_hw_texkill(SHADER_OPCODE_ARG* arg); +extern void pshader_hw_texdp3tex(SHADER_OPCODE_ARG* arg); +extern void pshader_hw_texdp3(SHADER_OPCODE_ARG* arg); +extern void pshader_hw_texm3x3(SHADER_OPCODE_ARG* arg); +extern void pshader_hw_texm3x2depth(SHADER_OPCODE_ARG* arg); /* ARB vertex shader prototypes */ extern void vshader_hw_map2gl(SHADER_OPCODE_ARG* arg);