diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c index 3c29da8faa4..0869ee68be6 100644 --- a/dlls/d3dx9_36/asmparser.c +++ b/dlls/d3dx9_36/asmparser.c @@ -133,9 +133,19 @@ static void asmparser_dcl_input(struct asm_parser *This, DWORD usage, DWORD num, } } -static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype, DWORD regnum, unsigned int line_no) { +static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype, + DWORD mod, DWORD regnum, + unsigned int line_no) { if(!This->shader) return; - if(!record_sampler(This->shader, samptype, regnum)) { + if(mod != 0 && + (This->shader->version != BWRITERPS_VERSION(3, 0) || + (mod != BWRITERSPDM_MSAMPCENTROID && + mod != BWRITERSPDM_PARTIALPRECISION))) { + asmparser_message(This, "Line %u: Unsupported modifier in dcl instruction\n", This->line_no); + set_parse_status(This, PARSE_ERR); + return; + } + if(!record_sampler(This->shader, samptype, mod, regnum)) { ERR("Out of memory\n"); set_parse_status(This, PARSE_ERR); } diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y index c0c289caec5..9bd84a36351 100644 --- a/dlls/d3dx9_36/asmshader.y +++ b/dlls/d3dx9_36/asmshader.y @@ -573,19 +573,24 @@ instruction: INSTR_ADD omods dreg ',' sregs reg.writemask = $5; asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, $3.mod, ®); } - | INSTR_DCL sampdcl REG_SAMPLER + | INSTR_DCL sampdcl omods REG_SAMPLER { TRACE("Sampler declared\n"); - asm_ctx.funcs->dcl_sampler(&asm_ctx, $2, $3, asm_ctx.line_no); + if($3.shift != 0) { + asmparser_message(&asm_ctx, "Line %u: Shift modifier not allowed here\n", + asm_ctx.line_no); + set_parse_status(&asm_ctx, PARSE_ERR); + } + asm_ctx.funcs->dcl_sampler(&asm_ctx, $2, $3.mod, $4, asm_ctx.line_no); } - | INSTR_DCL sampdcl REG_INPUT + | INSTR_DCL sampdcl omods REG_INPUT { TRACE("Error rule: sampler decl of input reg\n"); asmparser_message(&asm_ctx, "Line %u: Sampler declarations of input regs is not valid\n", asm_ctx.line_no); set_parse_status(&asm_ctx, PARSE_WARN); } - | INSTR_DCL sampdcl REG_OUTPUT + | INSTR_DCL sampdcl omods REG_OUTPUT { TRACE("Error rule: sampler decl of output reg\n"); asmparser_message(&asm_ctx, "Line %u: Sampler declarations of output regs is not valid\n", diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c index 3d05dadef40..84fefee6be1 100644 --- a/dlls/d3dx9_36/bytecodewriter.c +++ b/dlls/d3dx9_36/bytecodewriter.c @@ -257,7 +257,7 @@ BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_ return TRUE; } -BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum) { +BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD mod, DWORD regnum) { unsigned int i; if(!shader) return FALSE; @@ -290,6 +290,7 @@ BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum) } shader->samplers[shader->num_samplers].type = samptype; + shader->samplers[shader->num_samplers].mod = mod; shader->samplers[shader->num_samplers].regnum = regnum; shader->num_samplers++; return TRUE; @@ -1151,9 +1152,9 @@ static void write_samplers(const struct bwriter_shader *shader, struct bytecode_ DWORD instr_dcl = D3DSIO_DCL | (2 << D3DSI_INSTLENGTH_SHIFT); DWORD token; const DWORD reg = (1<<31) | - ((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) | - ((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2) | - D3DSP_WRITEMASK_ALL; + ((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) | + ((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2) | + D3DSP_WRITEMASK_ALL; for(i = 0; i < shader->num_samplers; i++) { /* Write the DCL instruction */ @@ -1162,7 +1163,9 @@ static void write_samplers(const struct bwriter_shader *shader, struct bytecode_ /* Already shifted */ token |= (d3d9_sampler(shader->samplers[i].type)) & D3DSP_TEXTURETYPE_MASK; put_dword(buffer, token); - put_dword(buffer, reg | (shader->samplers[i].regnum & D3DSP_REGNUM_MASK)); + token = reg | (shader->samplers[i].regnum & D3DSP_REGNUM_MASK); + token |= d3d9_dstmod(shader->samplers[i].mod); + put_dword(buffer, token); } } diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h index c1a4195f5cf..2daf1bef81a 100644 --- a/dlls/d3dx9_36/d3dx9_36_private.h +++ b/dlls/d3dx9_36/d3dx9_36_private.h @@ -191,6 +191,7 @@ struct declaration { struct samplerdecl { DWORD type; DWORD regnum; + DWORD mod; }; #define INSTRARRAY_INITIAL_SIZE 8 @@ -272,8 +273,8 @@ struct asmparser_backend { const struct shader_reg *reg); void (*dcl_input)(struct asm_parser *This, DWORD usage, DWORD num, DWORD mod, const struct shader_reg *reg); - void (*dcl_sampler)(struct asm_parser *This, DWORD samptype, DWORD regnum, - unsigned int line_no); + void (*dcl_sampler)(struct asm_parser *This, DWORD samptype, DWORD mod, + DWORD regnum, unsigned int line_no); void (*end)(struct asm_parser *This); @@ -288,7 +289,8 @@ BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, floa BOOL add_constI(struct bwriter_shader *shader, DWORD reg, INT x, INT y, INT z, INT w); BOOL add_constB(struct bwriter_shader *shader, DWORD reg, BOOL x); BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, DWORD mod, BOOL output, DWORD regnum, DWORD writemask); -BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum); +BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, + DWORD mod, DWORD regnum); #define MESSAGEBUFFER_INITIAL_SIZE 256 diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c index 59ed942a882..cc0b6ae0efe 100644 --- a/dlls/d3dx9_36/tests/asm.c +++ b/dlls/d3dx9_36/tests/asm.c @@ -1185,6 +1185,16 @@ static void ps_3_0_test(void) { "dcl_texcoord0_centroid v0\n", {0xffff0300, 0x0200001f, 0x80000005, 0x904f0000, 0x0000ffff} }, + { /* shader 13 */ + "ps_3_0\n" + "dcl_2d_centroid s0\n", + {0xffff0300, 0x0200001f, 0x90000000, 0xa04f0800, 0x0000ffff} + }, + { /* shader 14 */ + "ps_3_0\n" + "dcl_2d_pp s0\n", + {0xffff0300, 0x0200001f, 0x90000000, 0xa02f0800, 0x0000ffff} + }, }; exec_tests("ps_3_0", tests, sizeof(tests) / sizeof(tests[0])); @@ -1323,6 +1333,9 @@ static void failure_test(void) { /* shader 41: no modifier allowed with dcl instruction in vs */ "vs_3_0\n" "dcl_texcoord0_centroid v0\n", + /* shader 42: no modifiers with vs dcl sampler instruction */ + "vs_3_0\n" + "dcl_2d_pp s0\n", }; HRESULT hr; unsigned int i;