mirror of
https://github.com/reactos/wine.git
synced 2024-11-25 04:39:45 +00:00
d3dx9: Add DEF instruction support in the shader assembler.
This commit is contained in:
parent
af93f1ab33
commit
dc1fa014ac
@ -38,6 +38,16 @@ static void asmparser_end(struct asm_parser *This) {
|
||||
TRACE("Finalizing shader\n");
|
||||
}
|
||||
|
||||
static void asmparser_constF(struct asm_parser *This, DWORD reg, float x, float y, float z, float w) {
|
||||
if(!This->shader) return;
|
||||
TRACE("Adding float constant %u at pos %u\n", reg, This->shader->num_cf);
|
||||
TRACE_(parsed_shader)("def c%u, %f, %f, %f, %f\n", reg, x, y, z, w);
|
||||
if(!add_constF(This->shader, reg, x, y, z, w)) {
|
||||
ERR("Out of memory\n");
|
||||
set_parse_status(This, PARSE_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
static void asmparser_dcl_output(struct asm_parser *This, DWORD usage, DWORD num,
|
||||
const struct shader_reg *reg) {
|
||||
if(!This->shader) return;
|
||||
@ -159,6 +169,8 @@ static void asmparser_coissue_unsupported(struct asm_parser *This) {
|
||||
}
|
||||
|
||||
static const struct asmparser_backend parser_vs_3 = {
|
||||
asmparser_constF,
|
||||
|
||||
asmparser_dstreg_vs_3,
|
||||
asmparser_srcreg_vs_3,
|
||||
|
||||
|
@ -138,6 +138,7 @@ m3x4 {return INSTR_M3x4; }
|
||||
m3x3 {return INSTR_M3x3; }
|
||||
m3x2 {return INSTR_M3x2; }
|
||||
dcl {return INSTR_DCL; }
|
||||
def {return INSTR_DEF; }
|
||||
rep {return INSTR_REP; }
|
||||
endrep {return INSTR_ENDREP; }
|
||||
if {return INSTR_IF; }
|
||||
|
@ -123,6 +123,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
||||
%token INSTR_M3x3
|
||||
%token INSTR_M3x2
|
||||
%token INSTR_DCL
|
||||
%token INSTR_DEF
|
||||
%token INSTR_REP
|
||||
%token INSTR_ENDREP
|
||||
%token INSTR_IF
|
||||
@ -573,6 +574,10 @@ instruction: INSTR_ADD omods dreg ',' sregs
|
||||
asm_ctx.line_no);
|
||||
set_parse_status(&asm_ctx, PARSE_WARN);
|
||||
}
|
||||
| INSTR_DEF REG_CONSTFLOAT ',' IMMVAL ',' IMMVAL ',' IMMVAL ',' IMMVAL
|
||||
{
|
||||
asm_ctx.funcs->constF(&asm_ctx, $2, $4.val, $6.val, $8.val, $10.val);
|
||||
}
|
||||
| INSTR_REP sregs
|
||||
{
|
||||
TRACE("REP\n");
|
||||
|
@ -191,6 +191,7 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
|
||||
case BWRITERSIO_MOVA: return D3DSIO_MOVA;
|
||||
case BWRITERSIO_EXPP: return D3DSIO_EXPP;
|
||||
case BWRITERSIO_LOGP: return D3DSIO_LOGP;
|
||||
case BWRITERSIO_DEF: return D3DSIO_DEF;
|
||||
case BWRITERSIO_SETP: return D3DSIO_SETP;
|
||||
case BWRITERSIO_TEXLDL: return D3DSIO_TEXLDL;
|
||||
case BWRITERSIO_BREAKP: return D3DSIO_BREAKP;
|
||||
@ -456,6 +457,7 @@ const char *debug_print_opcode(DWORD opcode) {
|
||||
case BWRITERSIO_MOVA: return "mova";
|
||||
case BWRITERSIO_EXPP: return "expp";
|
||||
case BWRITERSIO_LOGP: return "logp";
|
||||
case BWRITERSIO_DEF: return "def";
|
||||
case BWRITERSIO_SETP: return "setp";
|
||||
case BWRITERSIO_TEXLDL: return "texldl";
|
||||
case BWRITERSIO_BREAKP: return "breakp";
|
||||
|
@ -104,6 +104,42 @@ BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w) {
|
||||
struct constant *newconst;
|
||||
|
||||
if(shader->num_cf) {
|
||||
struct constant **newarray;
|
||||
newarray = asm_realloc(shader->constF,
|
||||
sizeof(*shader->constF) * (shader->num_cf + 1));
|
||||
if(!newarray) {
|
||||
ERR("Failed to grow the constants array\n");
|
||||
return FALSE;
|
||||
}
|
||||
shader->constF = newarray;
|
||||
} else {
|
||||
shader->constF = asm_alloc(sizeof(*shader->constF));
|
||||
if(!shader->constF) {
|
||||
ERR("Failed to allocate the constants array\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
newconst = asm_alloc(sizeof(*newconst));
|
||||
if(!newconst) {
|
||||
ERR("Failed to allocate a new constant\n");
|
||||
return FALSE;
|
||||
}
|
||||
newconst->regnum = reg;
|
||||
newconst->value[0].f = x;
|
||||
newconst->value[1].f = y;
|
||||
newconst->value[2].f = z;
|
||||
newconst->value[3].f = w;
|
||||
shader->constF[shader->num_cf] = newconst;
|
||||
|
||||
shader->num_cf++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask) {
|
||||
unsigned int *num;
|
||||
struct declaration **decl;
|
||||
@ -262,6 +298,29 @@ static void write_declarations(struct bytecode_buffer *buffer, BOOL len,
|
||||
}
|
||||
}
|
||||
|
||||
static void write_constF(const struct bwriter_shader *shader, struct bytecode_buffer *buffer, BOOL len) {
|
||||
DWORD i;
|
||||
DWORD instr_def = D3DSIO_DEF;
|
||||
const DWORD reg = (1<<31) |
|
||||
((D3DSPR_CONST << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) |
|
||||
D3DSP_WRITEMASK_ALL;
|
||||
|
||||
if(len) {
|
||||
instr_def |= 5 << D3DSI_INSTLENGTH_SHIFT;
|
||||
}
|
||||
|
||||
for(i = 0; i < shader->num_cf; i++) {
|
||||
/* Write the DEF instruction */
|
||||
put_dword(buffer, instr_def);
|
||||
|
||||
put_dword(buffer, reg | (shader->constF[i]->regnum & D3DSP_REGNUM_MASK));
|
||||
put_dword(buffer, shader->constF[i]->value[0].d);
|
||||
put_dword(buffer, shader->constF[i]->value[1].d);
|
||||
put_dword(buffer, shader->constF[i]->value[2].d);
|
||||
put_dword(buffer, shader->constF[i]->value[3].d);
|
||||
}
|
||||
}
|
||||
|
||||
static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
||||
put_dword(buffer, D3DSIO_END);
|
||||
}
|
||||
@ -344,6 +403,7 @@ static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *sha
|
||||
|
||||
write_declarations(buffer, TRUE, shader->inputs, shader->num_inputs, D3DSPR_INPUT);
|
||||
write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT);
|
||||
write_constF(shader, buffer, TRUE);
|
||||
write_samplers(shader, buffer);
|
||||
return;
|
||||
}
|
||||
|
@ -146,6 +146,16 @@ typedef enum BWRITER_COMPARISON_TYPE {
|
||||
BWRITER_COMPARISON_LE
|
||||
} BWRITER_COMPARISON_TYPE;
|
||||
|
||||
struct constant {
|
||||
DWORD regnum;
|
||||
union {
|
||||
float f;
|
||||
INT i;
|
||||
BOOL b;
|
||||
DWORD d;
|
||||
} value[4];
|
||||
};
|
||||
|
||||
struct shader_reg {
|
||||
DWORD type;
|
||||
DWORD regnum;
|
||||
@ -243,6 +253,8 @@ struct src_regs {
|
||||
};
|
||||
|
||||
struct asmparser_backend {
|
||||
void (*constF)(struct asm_parser *This, DWORD reg, float x, float y, float z, float w);
|
||||
|
||||
void (*dstreg)(struct asm_parser *This, struct instruction *instr,
|
||||
const struct shader_reg *dst);
|
||||
void (*srcreg)(struct asm_parser *This, struct instruction *instr, int num,
|
||||
@ -268,6 +280,7 @@ struct asmparser_backend {
|
||||
|
||||
struct instruction *alloc_instr(unsigned int srcs);
|
||||
BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr);
|
||||
BOOL add_constF(struct bwriter_shader *shader, DWORD reg, float x, float y, float z, float w);
|
||||
BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask);
|
||||
BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum);
|
||||
|
||||
@ -430,6 +443,7 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
|
||||
|
||||
BWRITERSIO_EXPP,
|
||||
BWRITERSIO_LOGP,
|
||||
BWRITERSIO_DEF,
|
||||
BWRITERSIO_SETP,
|
||||
BWRITERSIO_TEXLDL,
|
||||
BWRITERSIO_BREAKP,
|
||||
|
@ -1074,6 +1074,12 @@ static void vs_3_0_test(void) {
|
||||
"sincos r0, r1\n",
|
||||
{0xfffe0300, 0x02000025, 0x800f0000, 0x80e40001, 0x0000ffff}
|
||||
},
|
||||
{ /* shader 13 */
|
||||
"vs_3_0\n"
|
||||
"def c0, 1.0f, 1.0f, 1.0f, 0.5f\n",
|
||||
{0xfffe0300, 0x05000051, 0xa00f0000, 0x3f800000, 0x3f800000, 0x3f800000,
|
||||
0x3f000000, 0x0000ffff}
|
||||
},
|
||||
};
|
||||
|
||||
exec_tests("vs_3_0", tests, sizeof(tests) / sizeof(tests[0]));
|
||||
|
Loading…
Reference in New Issue
Block a user