Stefan Dösinger : wined3d: Add support for some unimplemented instructions to arb shaders.

Alexandre Julliard julliard at winehq.org
Tue Sep 25 07:50:51 CDT 2007


Module: wine
Branch: master
Commit: 9531a108971f519a791b56137f52108f5fb81080
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9531a108971f519a791b56137f52108f5fb81080

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Tue Sep 25 01:00:27 2007 +0200

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 d534bb5..fc543d6 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 02704d1..24c025d 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 67edc0a..8844ffa 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);




More information about the wine-cvs mailing list