wined3d: Implement more GLSL instructions

Jason Green jave27 at gmail.com
Fri Jul 21 13:19:56 CDT 2006


- Implement D3DSIO_TEXREG2AR, TEXREG2GB, TEXREG2RGB, TEXM3X3TEX, TEXM3X3SPEC

These are the last instructions that were implemented in ARB shaders
and not in GLSL.  At this point, GLSL is more complete than ARB, but
still needs some more testing.
-------------- next part --------------
From nobody Mon Sep 17 00:00:00 2001
From: Jason <jason at jave02.(none)>
Date: Fri, 21 Jul 2006 14:18:06 -0400
Subject: [PATCH] Implement more GLSL instructions

- Implement D3DSIO_TEXREG2AR, TEXREG2GB, TEXREG2RGB, TEXM3X3TEX, TEXM3X3SPEC

These are the last instructions that were implemented in ARB shaders and not in GLSL.  At this point, GLSL is more complete than ARB, but still needs some more testing.

---

 dlls/wined3d/glsl_shader.c     |  135 ++++++++++++++++++++++++++++++++++++++++
 dlls/wined3d/pixelshader.c     |   10 +--
 dlls/wined3d/wined3d_private.h |    5 +
 3 files changed, 145 insertions(+), 5 deletions(-)

f7b8c6809c353156af5f4a0ddb7d78b71b060343
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index ea99f49..c405884 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1398,6 +1398,76 @@ void pshader_glsl_texm3x2tex(SHADER_OPCO
     shader_addline(buffer, "T%lu = texture2D(Psampler%lu, tmp0.st);\n", reg, reg);
 }
 
+/** Process the D3DSIO_TEXM3X3TEX instruction in GLSL
+ * Perform the 3rd row of a 3x3 matrix multiply, then sample the texture using the calculate coordinates */
+void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg) {
+
+    char src0_str[100];
+    char src0_name[50];
+    char src0_mask[6];
+    char dimensions[5];
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
+    DWORD stype = arg->reg_maps->samplers[src0_regnum] & D3DSP_TEXTURETYPE_MASK;
+    IWineD3DPixelShaderImpl* This = (IWineD3DPixelShaderImpl*) arg->shader;
+    SHADER_PARSE_STATE* current_state = &This->baseShader.parse_state;
+    
+    switch (stype) {
+        case D3DSTT_2D:     strcpy(dimensions, "2D");   break;
+        case D3DSTT_CUBE:   strcpy(dimensions, "Cube"); break;
+        case D3DSTT_VOLUME: strcpy(dimensions, "3D");   break;
+        default:
+            strcpy(dimensions, ""); break;
+            FIXME("Unrecognized sampler type: %#lx\n", stype);
+            break;
+    }
+
+    shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
+    shader_addline(arg->buffer, "tmp0.z = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
+    shader_addline(arg->buffer, "T%lu = texture%s(Psampler%lu, tmp0.%s);\n", 
+            reg, dimensions, reg, (stype == D3DSTT_2D) ? "xy" : "xyz");
+    current_state->current_row = 0;
+}
+
+/** Process the D3DSIO_TEXM3X3SPEC instruction in GLSL 
+ * Peform the final texture lookup based on the previous 2 3x3 matrix multiplies */
+void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg) {
+
+    IWineD3DPixelShaderImpl* shader = (IWineD3DPixelShaderImpl*) arg->shader;
+    DWORD reg = arg->dst & D3DSP_REGNUM_MASK;
+    char dimensions[5];
+    char src0_str[100], src0_name[50], src0_mask[6];
+    char src1_str[100], src1_name[50], src1_mask[6];
+    SHADER_BUFFER* buffer = arg->buffer;
+    SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
+    DWORD stype = arg->reg_maps->samplers[reg] & D3DSP_TEXTURETYPE_MASK;
+
+    switch (stype) {
+        case D3DSTT_2D:     strcpy(dimensions, "2D");   break;
+        case D3DSTT_CUBE:   strcpy(dimensions, "Cube"); break;
+        case D3DSTT_VOLUME: strcpy(dimensions, "3D");   break;
+        default:
+            strcpy(dimensions, ""); break;
+            FIXME("Unrecognized sampler type: %#lx\n", stype);
+            break;
+    }
+
+    shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_name, src0_mask, src0_str);
+    shader_glsl_add_param(arg, arg->src[1], arg->src_addr[1], TRUE, src1_name, src1_mask, src1_str);
+
+    /* Perform the last matrix multiply operation */
+    shader_addline(buffer, "tmp0.z = dot(vec3(T%lu), vec3(%s));\n", reg, src0_str);
+
+    /* Calculate reflection vector (Assume normal is normalized): RF = 2*(N.E)*N -E */
+    shader_addline(buffer, "tmp0.w = dot(vec3(tmp0), %s);\n", src1_str);
+    shader_addline(buffer, "tmp0 = tmp0.w * tmp0;\n");
+    shader_addline(buffer, "tmp0 = (2.0 * tmp0) - %s;\n", src1_str);
+
+    shader_addline(buffer, "T%lu = texture%s(Psampler%lu, tmp0.%s);\n", 
+            reg, dimensions, reg, (stype == D3DSTT_2D) ? "xy" : "xyz");
+    current_state->current_row = 0;
+}
+
 /** Process the D3DSIO_TEXM3X3VSPEC instruction in GLSL 
  * Peform the final texture lookup based on the previous 2 3x3 matrix multiplies */
 void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg) {
@@ -1447,6 +1517,71 @@ void pshader_glsl_texbem(SHADER_OPCODE_A
             reg1, reg1, reg1, reg2);
 }
 
+/** Process the D3DSIO_TEXREG2AR instruction in GLSL
+ * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
+void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg) {
+    
+    char tmpLine[255];
+    char dst_str[100], src0_str[100];
+    char dst_reg[50], src0_reg[50];
+    char dst_mask[6], src0_mask[6];
+    DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
+
+    shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
+    shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
+
+    shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
+    shader_addline(arg->buffer, "%stexture2D(Psampler%lu, %s.yz))%s;\n",
+            tmpLine, src0_regnum, dst_reg, dst_mask);
+}
+
+/** Process the D3DSIO_TEXREG2GB instruction in GLSL
+ * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
+void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg) {
+
+    char tmpLine[255];
+    char dst_str[100], src0_str[100];
+    char dst_reg[50], src0_reg[50];
+    char dst_mask[6], src0_mask[6];
+    DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
+
+    shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
+    shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
+
+    shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
+    shader_addline(arg->buffer, "%stexture2D(Psampler%lu, %s.yz))%s;\n",
+            tmpLine, src0_regnum, dst_reg, dst_mask);
+}
+
+/** Process the D3DSIO_TEXREG2RGB instruction in GLSL
+ * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
+void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg) {
+
+    char tmpLine[255];
+    char dst_str[100], src0_str[100];
+    char dst_reg[50], src0_reg[50];
+    char dst_mask[6], src0_mask[6];
+    char dimensions[5];
+    DWORD src0_regnum = arg->src[0] & D3DSP_REGNUM_MASK;
+    DWORD stype = arg->reg_maps->samplers[src0_regnum] & D3DSP_TEXTURETYPE_MASK;
+    switch (stype) {
+        case D3DSTT_2D:     strcpy(dimensions, "2D");   break;
+        case D3DSTT_CUBE:   strcpy(dimensions, "Cube"); break;
+        case D3DSTT_VOLUME: strcpy(dimensions, "3D");   break;
+        default:
+            strcpy(dimensions, ""); break;
+            FIXME("Unrecognized sampler type: %#lx\n", stype);
+            break;
+    }
+
+    shader_glsl_add_param(arg, arg->dst, 0, FALSE, dst_reg, dst_mask, dst_str);
+    shader_glsl_add_param(arg, arg->src[0], arg->src_addr[0], TRUE, src0_reg, src0_mask, src0_str);
+
+    shader_glsl_add_dst(arg->dst, dst_reg, dst_mask, tmpLine);
+    shader_addline(arg->buffer, "%stexture%s(Psampler%lu, %s.%s))%s;\n",
+            tmpLine, dimensions, src0_regnum, dst_reg, (stype == D3DSTT_2D) ? "xy" : "xyz", dst_mask);
+}
+
 /** Process the D3DSIO_TEXKILL instruction in GLSL.
  * If any of the first 3 components are < 0, discard this pixel */
 void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg) {
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index a1c8bf0..adea97a 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -707,16 +707,16 @@ CONST SHADER_OPCODE IWineD3DPixelShaderI
     {D3DSIO_TEX,      "texld",    "undefined", 1, 3, pshader_texld,       pshader_hw_tex, pshader_glsl_tex, D3DPS_VERSION(2,0), -1},
     {D3DSIO_TEXBEM,   "texbem",   "undefined", 1, 2, pshader_texbem,      pshader_hw_texbem, pshader_glsl_texbem, 0, D3DPS_VERSION(1,3)},
     {D3DSIO_TEXBEML,  "texbeml",  GLNAME_REQUIRE_GLSL, 1, 2, pshader_texbeml, NULL, NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXREG2AR,"texreg2ar","undefined", 1, 2, pshader_texreg2ar,   pshader_hw_texreg2ar, NULL, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXREG2GB,"texreg2gb","undefined", 1, 2, pshader_texreg2gb,   pshader_hw_texreg2gb, NULL, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXREG2RGB,   "texreg2rgb",   GLNAME_REQUIRE_GLSL, 1, 2, pshader_texreg2rgb,  NULL, NULL, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXREG2AR,"texreg2ar","undefined", 1, 2, pshader_texreg2ar,   pshader_hw_texreg2ar, pshader_glsl_texreg2ar, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXREG2GB,"texreg2gb","undefined", 1, 2, pshader_texreg2gb,   pshader_hw_texreg2gb, pshader_glsl_texreg2gb, D3DPS_VERSION(1,1), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXREG2RGB,   "texreg2rgb",   GLNAME_REQUIRE_GLSL, 1, 2, pshader_texreg2rgb,  NULL, pshader_glsl_texreg2rgb, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x2PAD,   "texm3x2pad",   "undefined", 1, 2, pshader_texm3x2pad,   pshader_hw_texm3x2pad, pshader_glsl_texm3x2pad, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x2TEX,   "texm3x2tex",   "undefined", 1, 2, pshader_texm3x2tex,   pshader_hw_texm3x2tex, pshader_glsl_texm3x2tex, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x3PAD,   "texm3x3pad",   "undefined", 1, 2, pshader_texm3x3pad,   pshader_hw_texm3x3pad, pshader_glsl_texm3x3pad, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x3DIFF,  "texm3x3diff",  GLNAME_REQUIRE_GLSL, 1, 2, pshader_texm3x3diff,  NULL, NULL, D3DPS_VERSION(0,0), D3DPS_VERSION(0,0)},
-    {D3DSIO_TEXM3x3SPEC,  "texm3x3spec",  "undefined", 1, 3, pshader_texm3x3spec,  pshader_hw_texm3x3spec, NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x3SPEC,  "texm3x3spec",  "undefined", 1, 3, pshader_texm3x3spec,  pshader_hw_texm3x3spec, pshader_glsl_texm3x3spec, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x3VSPEC, "texm3x3vspec",  "undefined", 1, 2, pshader_texm3x3vspec, pshader_hw_texm3x3vspec, pshader_glsl_texm3x3vspec, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
-    {D3DSIO_TEXM3x3TEX,   "texm3x3tex",   "undefined", 1, 2, pshader_texm3x3tex,   pshader_hw_texm3x3tex, NULL, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
+    {D3DSIO_TEXM3x3TEX,   "texm3x3tex",   "undefined", 1, 2, pshader_texm3x3tex,   pshader_hw_texm3x3tex, pshader_glsl_texm3x3tex, D3DPS_VERSION(1,0), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXDP3TEX,    "texdp3tex",    GLNAME_REQUIRE_GLSL, 1, 2, pshader_texdp3tex,   NULL, NULL, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXM3x2DEPTH, "texm3x2depth", GLNAME_REQUIRE_GLSL, 1, 2, pshader_texm3x2depth, NULL, NULL, D3DPS_VERSION(1,3), D3DPS_VERSION(1,3)},
     {D3DSIO_TEXDP3,   "texdp3",   GLNAME_REQUIRE_GLSL, 1, 2, pshader_texdp3,   NULL, NULL, D3DPS_VERSION(1,2), D3DPS_VERSION(1,3)},
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index daedc52..62af2b4 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1491,9 +1491,14 @@ extern void pshader_glsl_texcoord(SHADER
 extern void pshader_glsl_texm3x2pad(SHADER_OPCODE_ARG* arg);
 extern void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg);
 extern void pshader_glsl_texm3x3pad(SHADER_OPCODE_ARG* arg);
+extern void pshader_glsl_texm3x3tex(SHADER_OPCODE_ARG* arg);
+extern void pshader_glsl_texm3x3spec(SHADER_OPCODE_ARG* arg);
 extern void pshader_glsl_texm3x3vspec(SHADER_OPCODE_ARG* arg);
 extern void pshader_glsl_texkill(SHADER_OPCODE_ARG* arg);
 extern void pshader_glsl_texbem(SHADER_OPCODE_ARG* arg);
+extern void pshader_glsl_texreg2ar(SHADER_OPCODE_ARG* arg);
+extern void pshader_glsl_texreg2gb(SHADER_OPCODE_ARG* arg);
+extern void pshader_glsl_texreg2rgb(SHADER_OPCODE_ARG* arg);
 extern void pshader_glsl_dp2add(SHADER_OPCODE_ARG* arg);
 extern void pshader_glsl_input_pack(
    SHADER_BUFFER* buffer,
-- 
1.3.3


More information about the wine-patches mailing list