[2/2] d3dx9: Shader assembler ps_3_0 support.
Matteo Bruni
matteo.mystral at gmail.com
Wed May 19 08:02:45 CDT 2010
-------------- next part --------------
From 8d13547861140cc1f14144e86d7d2d2527601c58 Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Wed, 19 May 2010 14:57:38 +0200
Subject: d3dx9: Shader assembler ps_3_0 support.
---
dlls/d3dx9_36/asmparser.c | 79 ++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/asmshader.y | 3 +-
dlls/d3dx9_36/bytecodewriter.c | 78 +++++++++++++++++++++++++++++++++++++-
dlls/d3dx9_36/d3dx9_36_private.h | 1 +
dlls/d3dx9_36/tests/asm.c | 21 ++++++++++-
5 files changed, 178 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index bcdc85a..3062639 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -248,6 +248,36 @@ static void asmparser_srcreg_vs_3(struct asm_parser *This,
memcpy(&instr->src[num], src, sizeof(*src));
}
+static const struct allowed_reg_type ps_3_reg_allowed[] = {
+ { BWRITERSPR_INPUT, 10 },
+ { BWRITERSPR_TEMP, 32 },
+ { BWRITERSPR_CONST, 224 },
+ { BWRITERSPR_CONSTINT, 16 },
+ { BWRITERSPR_CONSTBOOL, 16 },
+ { BWRITERSPR_PREDICATE, 1 },
+ { BWRITERSPR_SAMPLER, 16 },
+ { BWRITERSPR_MISCTYPE, 2 }, /* vPos and vFace */
+ { BWRITERSPR_LOOP, 1 },
+ { BWRITERSPR_LABEL, 2048 },
+ { BWRITERSPR_COLOROUT, ~0U },
+ { BWRITERSPR_DEPTHOUT, 1 },
+ { ~0U, 0 } /* End tag */
+};
+
+static void asmparser_srcreg_ps_3(struct asm_parser *This,
+ struct instruction *instr, int num,
+ const struct shader_reg *src) {
+ if(!check_reg_type(src, ps_3_reg_allowed)) {
+ asmparser_message(This, "Line %u: Source register %s not supported in PS 3.0\n",
+ This->line_no,
+ debug_print_srcreg(src, ST_PIXEL));
+ 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) {
@@ -263,6 +293,20 @@ static void asmparser_dstreg_vs_3(struct asm_parser *This,
instr->has_dst = TRUE;
}
+static void asmparser_dstreg_ps_3(struct asm_parser *This,
+ struct instruction *instr,
+ const struct shader_reg *dst) {
+ if(!check_reg_type(dst, ps_3_reg_allowed)) {
+ asmparser_message(This, "Line %u: Destination register %s not supported in PS 3.0\n",
+ This->line_no,
+ debug_print_dstreg(dst, ST_PIXEL));
+ set_parse_status(This, PARSE_ERR);
+ }
+ check_shift_dstmod(This, instr->shift);
+ memcpy(&instr->dst, dst, sizeof(*dst));
+ instr->has_dst = TRUE;
+}
+
static void asmparser_predicate_supported(struct asm_parser *This,
const struct shader_reg *predicate) {
/* this sets the predicate of the last instruction added to the shader */
@@ -305,6 +349,26 @@ static const struct asmparser_backend parser_vs_3 = {
asmparser_instr,
};
+static const struct asmparser_backend parser_ps_3 = {
+ asmparser_constF,
+ asmparser_constI,
+ asmparser_constB,
+
+ asmparser_dstreg_ps_3,
+ asmparser_srcreg_ps_3,
+
+ asmparser_predicate_supported,
+ asmparser_coissue_unsupported,
+
+ asmparser_dcl_output,
+ asmparser_dcl_input,
+ asmparser_dcl_sampler,
+
+ asmparser_end,
+
+ asmparser_instr,
+};
+
void create_vs30_parser(struct asm_parser *ret) {
TRACE_(parsed_shader)("vs_3_0\n");
@@ -319,3 +383,18 @@ void create_vs30_parser(struct asm_parser *ret) {
ret->shader->version = BWRITERVS_VERSION(3, 0);
ret->funcs = &parser_vs_3;
}
+
+void create_ps30_parser(struct asm_parser *ret) {
+ TRACE_(parsed_shader)("ps_3_0\n");
+
+ ret->shader = asm_alloc(sizeof(*ret->shader));
+ if(!ret->shader) {
+ ERR("Failed to allocate memory for the shader\n");
+ set_parse_status(ret, PARSE_ERR);
+ return;
+ }
+
+ ret->shader->type = ST_PIXEL;
+ ret->shader->version = BWRITERPS_VERSION(3, 0);
+ ret->funcs = &parser_ps_3;
+}
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index 657ce3c..06a6825 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -342,8 +342,7 @@ version_marker: VER_VS10
| VER_PS30
{
TRACE("Pixel shader 3.0\n");
- set_parse_status(&asm_ctx, PARSE_ERR);
- YYABORT;
+ create_ps30_parser(&asm_ctx);
}
instructions: /* empty */
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index 087422f..464ec52 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -641,11 +641,87 @@ static const struct bytecode_backend vs_3_backend = {
vs_3_handlers
};
+static const struct instr_handler_table ps_3_handlers[] = {
+ {BWRITERSIO_ADD, instr_handler},
+ {BWRITERSIO_NOP, instr_handler},
+ {BWRITERSIO_MOV, instr_handler},
+ {BWRITERSIO_SUB, instr_handler},
+ {BWRITERSIO_MAD, instr_handler},
+ {BWRITERSIO_MUL, instr_handler},
+ {BWRITERSIO_RCP, instr_handler},
+ {BWRITERSIO_RSQ, instr_handler},
+ {BWRITERSIO_DP3, instr_handler},
+ {BWRITERSIO_DP4, instr_handler},
+ {BWRITERSIO_MIN, instr_handler},
+ {BWRITERSIO_MAX, instr_handler},
+ {BWRITERSIO_ABS, instr_handler},
+ {BWRITERSIO_EXP, instr_handler},
+ {BWRITERSIO_LOG, instr_handler},
+ {BWRITERSIO_EXPP, instr_handler},
+ {BWRITERSIO_LOGP, instr_handler},
+ {BWRITERSIO_LRP, instr_handler},
+ {BWRITERSIO_FRC, instr_handler},
+ {BWRITERSIO_CRS, instr_handler},
+ {BWRITERSIO_NRM, instr_handler},
+ {BWRITERSIO_SINCOS, instr_handler},
+ {BWRITERSIO_M4x4, instr_handler},
+ {BWRITERSIO_M4x3, instr_handler},
+ {BWRITERSIO_M3x4, instr_handler},
+ {BWRITERSIO_M3x3, instr_handler},
+ {BWRITERSIO_M3x2, instr_handler},
+ {BWRITERSIO_POW, instr_handler},
+ {BWRITERSIO_DP2ADD, instr_handler},
+ {BWRITERSIO_CMP, instr_handler},
+
+ {BWRITERSIO_CALL, instr_handler},
+ {BWRITERSIO_CALLNZ, instr_handler},
+ {BWRITERSIO_REP, instr_handler},
+ {BWRITERSIO_ENDREP, instr_handler},
+ {BWRITERSIO_IF, instr_handler},
+ {BWRITERSIO_LABEL, instr_handler},
+ {BWRITERSIO_IFC, instr_handler},
+ {BWRITERSIO_ELSE, instr_handler},
+ {BWRITERSIO_ENDIF, instr_handler},
+ {BWRITERSIO_BREAK, instr_handler},
+ {BWRITERSIO_BREAKC, instr_handler},
+ {BWRITERSIO_LOOP, instr_handler},
+ {BWRITERSIO_RET, instr_handler},
+ {BWRITERSIO_ENDLOOP, instr_handler},
+
+ {BWRITERSIO_SETP, instr_handler},
+ {BWRITERSIO_BREAKP, instr_handler},
+ {BWRITERSIO_TEXLDL, instr_handler},
+
+ {BWRITERSIO_TEX, instr_handler},
+ {BWRITERSIO_TEX | ( BWRITERSI_TEXLD_PROJECT << BWRITER_OPCODESPECIFICCONTROL_SHIFT ), instr_handler},
+ {BWRITERSIO_TEX | ( BWRITERSI_TEXLD_BIAS << BWRITER_OPCODESPECIFICCONTROL_SHIFT ), instr_handler},
+ {BWRITERSIO_TEXKILL, instr_handler},
+ {BWRITERSIO_DSX, instr_handler},
+ {BWRITERSIO_DSY, instr_handler},
+ {BWRITERSIO_TEXLDD, instr_handler},
+
+ {BWRITERSIO_END, NULL},
+};
+
+static const struct bytecode_backend ps_3_backend = {
+ sm_3_header,
+ end,
+ sm_3_srcreg,
+ sm_3_dstreg,
+ sm_2_opcode,
+ ps_3_handlers
+};
+
static void init_vs30_dx9_writer(struct bc_writer *writer) {
TRACE("Creating DirectX9 vertex shader 3.0 writer\n");
writer->funcs = &vs_3_backend;
}
+static void init_ps30_dx9_writer(struct bc_writer *writer) {
+ TRACE("Creating DirectX9 pixel shader 3.0 writer\n");
+ writer->funcs = &ps_3_backend;
+}
+
static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
struct bc_writer *ret = asm_alloc(sizeof(*ret));
@@ -748,7 +824,7 @@ static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
WARN("Unsupported dxversion for pixel shader 3.0 requested: %u\n", dxversion);
goto fail;
}
- /* TODO: Set the appropriate writer backend */
+ init_ps30_dx9_writer(ret);
break;
default:
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index e5816b3..923a0df 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -312,6 +312,7 @@ struct asm_parser {
extern struct asm_parser asm_ctx;
void create_vs30_parser(struct asm_parser *ret);
+void create_ps30_parser(struct asm_parser *ret);
struct bwriter_shader *parse_asm_shader(char **messages);
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index b4e0ee5..54894df 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -1125,6 +1125,22 @@ static void ps_3_0_test(void) {
"texldl r0, v0, s0\n",
{0xffff0300, 0x0300005f, 0x800f0000, 0x90e40000, 0xa0e40800, 0x0000ffff}
},
+ { /* shader 7 */
+ "ps_3_0\n"
+ "add_pp r0, r0, r1\n",
+ {0xffff0300, 0x03000002, 0x802f0000, 0x80e40000, 0x80e40001, 0x0000ffff}
+ },
+ { /* shader 8 */
+ "ps_3_0\n"
+ "dsx_sat r0, r1\n",
+ {0xffff0300, 0x0200005b, 0x801f0000, 0x80e40001, 0x0000ffff}
+ },
+ { /* shader 9 */
+ "ps_3_0\n"
+ "texldd_pp r0, r1, r2, r3, r4\n",
+ {0xffff0300, 0x0500005d, 0x802f0000, 0x80e40001, 0x80e40002, 0x80e40003,
+ 0x80e40004, 0x0000ffff}
+ },
};
exec_tests("ps_3_0", tests, sizeof(tests) / sizeof(tests[0]));
@@ -1212,6 +1228,9 @@ static void failure_test(void) {
/* shader 24: _pp instruction modifier not allowed in vertex shaders */
"vs_3_0\n"
"add_pp r0, r0, r1\n",
+ /* shader 25: _x4 instruction modified not allowed in > ps_1_x */
+ "ps_3_0\n"
+ "add_x4 r0, r0, r1\n",
};
HRESULT hr;
unsigned int i;
@@ -1437,7 +1456,7 @@ START_TEST(asm)
todo_wine ps_2_0_test();
todo_wine ps_2_x_test();
vs_3_0_test();
- todo_wine ps_3_0_test();
+ ps_3_0_test();
failure_test();
--
1.6.4.4
More information about the wine-patches
mailing list