Matteo Bruni : d3dx9: Add some version-specific checks in the shader assembler.
Alexandre Julliard
julliard at winehq.org
Tue May 18 12:32:59 CDT 2010
Module: wine
Branch: master
Commit: c1f7faca453489b056a7cd18302a00793f2366b6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c1f7faca453489b056a7cd18302a00793f2366b6
Author: Matteo Bruni <matteo.mystral at gmail.com>
Date: Tue May 18 14:11:42 2010 +0200
d3dx9: Add some version-specific checks in the shader assembler.
---
dlls/d3dx9_36/asmparser.c | 97 ++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/d3dx9_36_private.h | 10 ++++
dlls/d3dx9_36/tests/asm.c | 6 ++
3 files changed, 113 insertions(+), 0 deletions(-)
diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index d1d75ba..bcdc85a 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -153,15 +153,112 @@ static void asmparser_instr(struct asm_parser *This, DWORD opcode,
}
}
+/* Checks for unsupported source modifiers in VS (all versions) or
+ PS 2.0 and newer */
+static void check_legacy_srcmod(struct asm_parser *This, DWORD srcmod) {
+ if(srcmod == BWRITERSPSM_BIAS || srcmod == BWRITERSPSM_BIASNEG ||
+ srcmod == BWRITERSPSM_SIGN || srcmod == BWRITERSPSM_SIGNNEG ||
+ srcmod == BWRITERSPSM_COMP || srcmod == BWRITERSPSM_X2 ||
+ srcmod == BWRITERSPSM_X2NEG || srcmod == BWRITERSPSM_DZ ||
+ srcmod == BWRITERSPSM_DW) {
+ asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
+ This->line_no,
+ debug_print_srcmod(srcmod));
+ set_parse_status(This, PARSE_ERR);
+ }
+}
+
+static void check_loop_swizzle(struct asm_parser *This,
+ const struct shader_reg *src) {
+ if((src->type == BWRITERSPR_LOOP && src->swizzle != BWRITERVS_NOSWIZZLE) ||
+ (src->rel_reg && src->rel_reg->type == BWRITERSPR_LOOP &&
+ src->rel_reg->swizzle != BWRITERVS_NOSWIZZLE)) {
+ asmparser_message(This, "Line %u: Swizzle not allowed on aL register\n", This->line_no);
+ set_parse_status(This, PARSE_ERR);
+ }
+}
+
+static void check_shift_dstmod(struct asm_parser *This, DWORD shift) {
+ if(shift != 0) {
+ asmparser_message(This, "Line %u: Shift modifiers not supported in this shader version\n",
+ This->line_no);
+ set_parse_status(This, PARSE_ERR);
+ }
+}
+
+static void check_ps_dstmod(struct asm_parser *This, DWORD dstmod) {
+ if(dstmod == BWRITERSPDM_PARTIALPRECISION ||
+ dstmod == BWRITERSPDM_MSAMPCENTROID) {
+ asmparser_message(This, "Line %u: Instruction modifier %s not supported in this shader version\n",
+ This->line_no,
+ debug_print_dstmod(dstmod));
+ set_parse_status(This, PARSE_ERR);
+ }
+}
+
+struct allowed_reg_type {
+ DWORD type;
+ DWORD count;
+};
+
+static BOOL check_reg_type(const struct shader_reg *reg,
+ const struct allowed_reg_type *allowed) {
+ unsigned int i = 0;
+
+ while(allowed[i].type != ~0U) {
+ if(reg->type == allowed[i].type) {
+ if(reg->rel_reg) return TRUE; /* The relative addressing register
+ can have a negative value, we
+ can't check the register index */
+ if(reg->regnum < allowed[i].count) return TRUE;
+ return FALSE;
+ }
+ i++;
+ }
+ return FALSE;
+}
+
+/* Native assembler doesn't do separate checks for src and dst registers */
+static const struct allowed_reg_type vs_3_reg_allowed[] = {
+ { BWRITERSPR_TEMP, 32 },
+ { BWRITERSPR_INPUT, 16 },
+ { BWRITERSPR_CONST, ~0U },
+ { BWRITERSPR_ADDR, 1 },
+ { BWRITERSPR_CONSTBOOL, 16 },
+ { BWRITERSPR_CONSTINT, 16 },
+ { BWRITERSPR_LOOP, 1 },
+ { BWRITERSPR_LABEL, 2048 },
+ { BWRITERSPR_PREDICATE, 1 },
+ { BWRITERSPR_SAMPLER, 4 },
+ { BWRITERSPR_OUTPUT, 12 },
+ { ~0U, 0 } /* End tag */
+};
+
static void asmparser_srcreg_vs_3(struct asm_parser *This,
struct instruction *instr, int num,
const struct shader_reg *src) {
+ if(!check_reg_type(src, vs_3_reg_allowed)) {
+ asmparser_message(This, "Line %u: Source register %s not supported in VS 3.0\n",
+ This->line_no,
+ debug_print_srcreg(src, ST_VERTEX));
+ set_parse_status(This, PARSE_ERR);
+ }
+ check_loop_swizzle(This, src);
+ check_legacy_srcmod(This, src->srcmod);
memcpy(&instr->src[num], src, sizeof(*src));
}
static void asmparser_dstreg_vs_3(struct asm_parser *This,
struct instruction *instr,
const struct shader_reg *dst) {
+ if(!check_reg_type(dst, vs_3_reg_allowed)) {
+ asmparser_message(This, "Line %u: Destination register %s not supported in VS 3.0\n",
+ This->line_no,
+ debug_print_dstreg(dst, ST_VERTEX));
+ set_parse_status(This, PARSE_ERR);
+ }
+ check_ps_dstmod(This, instr->dstmod);
+ check_shift_dstmod(This, instr->shift);
memcpy(&instr->dst, dst, sizeof(*dst));
instr->has_dst = TRUE;
}
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index a12cb99..ffecd31 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -371,6 +371,7 @@ struct bc_writer {
};
/* Debug utility routines */
+const char *debug_print_srcmod(DWORD mod);
const char *debug_print_dstmod(DWORD mod);
const char *debug_print_dstreg(const struct shader_reg *reg, shader_type st);
const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st);
@@ -510,6 +511,15 @@ typedef enum _BWRITERSAMPLER_TEXTURE_TYPE {
typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE {
BWRITERSPSM_NONE = 0,
BWRITERSPSM_NEG,
+ BWRITERSPSM_BIAS,
+ BWRITERSPSM_BIASNEG,
+ BWRITERSPSM_SIGN,
+ BWRITERSPSM_SIGNNEG,
+ BWRITERSPSM_COMP,
+ BWRITERSPSM_X2,
+ BWRITERSPSM_X2NEG,
+ BWRITERSPSM_DZ,
+ BWRITERSPSM_DW,
BWRITERSPSM_ABS,
BWRITERSPSM_ABSNEG,
BWRITERSPSM_NOT,
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index 8a79dd4..b4e0ee5 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -1206,6 +1206,12 @@ static void failure_test(void) {
/* shader 22: register r5 doesn't exist in PS < 1.4 */
"ps_1_3\n"
"mov r5, r0\n",
+ /* shader 23: can't declare output registers in a pixel shader */
+ "ps_3_0\n"
+ "dcl_positiont o0\n",
+ /* shader 24: _pp instruction modifier not allowed in vertex shaders */
+ "vs_3_0\n"
+ "add_pp r0, r0, r1\n",
};
HRESULT hr;
unsigned int i;
More information about the wine-cvs
mailing list