Commit 5cc00e82 authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

d3dx9: Shader assembler ps_3_0 support.

parent abb489b2
......@@ -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;
}
......@@ -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 */
......
......@@ -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:
......
......@@ -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);
......
......@@ -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();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment