From 7e90aba97be15e746839bda89f71bbd146af8c19 Mon Sep 17 00:00:00 2001 From: Jason Green Date: Mon, 24 Jul 2006 22:52:38 -0400 Subject: [PATCH] wined3d: Implement more GLSL instructions. Implement D3DSIO_TEXREG2AR, TEXREG2GB, TEXREG2RGB, TEXM3X3TEX, TEXM3X3SPEC. --- dlls/wined3d/glsl_shader.c | 134 +++++++++++++++++++++++++++++++++ dlls/wined3d/pixelshader.c | 10 +-- dlls/wined3d/wined3d_private.h | 5 ++ 3 files changed, 144 insertions(+), 5 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index ea99f4969ff..4aa8b5b58f9 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1398,6 +1398,75 @@ void pshader_glsl_texm3x2tex(SHADER_OPCODE_ARG* arg) { 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_ARG* arg) { 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 4a242131f4c..7e11c471b83 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -707,16 +707,16 @@ CONST SHADER_OPCODE IWineD3DPixelShaderImpl_shader_ins[] = { {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 1017c7704ec..1f51e3b19ad 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1510,9 +1510,14 @@ extern void pshader_glsl_texcoord(SHADER_OPCODE_ARG* arg); 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,