wined3d: Implement more GLSL instructions

Jason Green jave27 at gmail.com
Mon Jul 24 21:52:38 CDT 2006


Resend using Chris's simplified implementation - verfied that the
produced output is the same between ARB and GLSL modes.  Other than
that, nothing has changed.

- Implement D3DSIO_TEXREG2AR, TEXREG2GB, TEXREG2RGB, TEXM3X3TEX, TEXM3X3SPEC

On 7/21/06, Jason Green <jave27 at gmail.com> wrote:
> On 7/21/06, Chris <chris.kcat at gmail.com> wrote:
> > On Friday 21 July 2006 11:19, Jason Green wrote:
> > > + /* 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);
> >
> > I'm hardly an expert, but couldn't this be simplified to:
> >
> > shader_addline(buffer, "tmp0 = reflect(-%s, vec3(tmp0));\n", src1_str);
> >
>
> Yeah, looks correct from the GLSL spec.  I basically just copied the
> formula from the arb_shader routine and it seemed to display
> everything the same in both modes.  It's probably worth simplifying,
> though.  Either way should work.
>
-------------- next part --------------
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index ea99f49..4aa8b5b 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1398,6 +1398,75 @@ 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 */
+    shader_addline(buffer, "tmp0.xyz = reflect(-vec3(%s), vec3(tmp0));\n", src1_str);
+
+    /* Sample the texture */
+    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 +1516,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 813919a..63dbf05 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1510,9 +1510,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,


More information about the wine-patches mailing list