d3dx9: Add output dcl instruction partial support to the shader assembler.
This commit is contained in:
parent
c79be42057
commit
b627d13ea8
|
@ -38,6 +38,19 @@ static void asmparser_end(struct asm_parser *This) {
|
||||||
TRACE("Finalizing shader\n");
|
TRACE("Finalizing shader\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void asmparser_dcl_output(struct asm_parser *This, DWORD usage, DWORD num,
|
||||||
|
const struct shader_reg *reg) {
|
||||||
|
if(!This->shader) return;
|
||||||
|
if(This->shader->type == ST_PIXEL) {
|
||||||
|
asmparser_message(This, "Line %u: Output register declared in a pixel shader\n", This->line_no);
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
if(!record_declaration(This->shader, usage, num, TRUE, reg->regnum, reg->writemask)) {
|
||||||
|
ERR("Out of memory\n");
|
||||||
|
set_parse_status(This, PARSE_ERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void asmparser_instr(struct asm_parser *This, DWORD opcode,
|
static void asmparser_instr(struct asm_parser *This, DWORD opcode,
|
||||||
DWORD mod, DWORD shift,
|
DWORD mod, DWORD shift,
|
||||||
BWRITER_COMPARISON_TYPE comp,
|
BWRITER_COMPARISON_TYPE comp,
|
||||||
|
@ -135,6 +148,8 @@ static const struct asmparser_backend parser_vs_3 = {
|
||||||
asmparser_predicate_supported,
|
asmparser_predicate_supported,
|
||||||
asmparser_coissue_unsupported,
|
asmparser_coissue_unsupported,
|
||||||
|
|
||||||
|
asmparser_dcl_output,
|
||||||
|
|
||||||
asmparser_end,
|
asmparser_end,
|
||||||
|
|
||||||
asmparser_instr,
|
asmparser_instr,
|
||||||
|
|
|
@ -66,6 +66,8 @@ REG_PREDICATE p0
|
||||||
/* Not really a register, but it is considered as such */
|
/* Not really a register, but it is considered as such */
|
||||||
REG_LABEL l[0-9]+
|
REG_LABEL l[0-9]+
|
||||||
|
|
||||||
|
DCL_POSITION _position[0-9]*
|
||||||
|
|
||||||
PREPROCESSORDIRECTIVE #[^\n]*\n
|
PREPROCESSORDIRECTIVE #[^\n]*\n
|
||||||
|
|
||||||
/* Comments */
|
/* Comments */
|
||||||
|
@ -117,6 +119,7 @@ m4x3 {return INSTR_M4x3; }
|
||||||
m3x4 {return INSTR_M3x4; }
|
m3x4 {return INSTR_M3x4; }
|
||||||
m3x3 {return INSTR_M3x3; }
|
m3x3 {return INSTR_M3x3; }
|
||||||
m3x2 {return INSTR_M3x2; }
|
m3x2 {return INSTR_M3x2; }
|
||||||
|
dcl {return INSTR_DCL; }
|
||||||
rep {return INSTR_REP; }
|
rep {return INSTR_REP; }
|
||||||
endrep {return INSTR_ENDREP; }
|
endrep {return INSTR_ENDREP; }
|
||||||
if {return INSTR_IF; }
|
if {return INSTR_IF; }
|
||||||
|
@ -271,6 +274,15 @@ ps_3_0 {return VER_PS30; }
|
||||||
|
|
||||||
! {return SMOD_NOT; }
|
! {return SMOD_NOT; }
|
||||||
|
|
||||||
|
{DCL_POSITION} {
|
||||||
|
if(yytext[strlen("_position")] == '\0') {
|
||||||
|
asmshader_lval.regnum = 0;
|
||||||
|
} else {
|
||||||
|
asmshader_lval.regnum = atoi(yytext + strlen("_position"));
|
||||||
|
}
|
||||||
|
return USAGE_POSITION;
|
||||||
|
}
|
||||||
|
|
||||||
{PREPROCESSORDIRECTIVE} {
|
{PREPROCESSORDIRECTIVE} {
|
||||||
/* TODO: update current line information */
|
/* TODO: update current line information */
|
||||||
TRACE("line info update: %s", yytext);
|
TRACE("line info update: %s", yytext);
|
||||||
|
|
|
@ -80,6 +80,10 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
||||||
DWORD shift;
|
DWORD shift;
|
||||||
} modshift;
|
} modshift;
|
||||||
BWRITER_COMPARISON_TYPE comptype;
|
BWRITER_COMPARISON_TYPE comptype;
|
||||||
|
struct {
|
||||||
|
DWORD dclusage;
|
||||||
|
unsigned int regnum;
|
||||||
|
} declaration;
|
||||||
struct rel_reg rel_reg;
|
struct rel_reg rel_reg;
|
||||||
struct src_regs sregs;
|
struct src_regs sregs;
|
||||||
}
|
}
|
||||||
|
@ -117,6 +121,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
||||||
%token INSTR_M3x4
|
%token INSTR_M3x4
|
||||||
%token INSTR_M3x3
|
%token INSTR_M3x3
|
||||||
%token INSTR_M3x2
|
%token INSTR_M3x2
|
||||||
|
%token INSTR_DCL
|
||||||
%token INSTR_REP
|
%token INSTR_REP
|
||||||
%token INSTR_ENDREP
|
%token INSTR_ENDREP
|
||||||
%token INSTR_IF
|
%token INSTR_IF
|
||||||
|
@ -193,6 +198,9 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
||||||
%token SMOD_ABS
|
%token SMOD_ABS
|
||||||
%token SMOD_NOT
|
%token SMOD_NOT
|
||||||
|
|
||||||
|
/* Usage declaration tokens */
|
||||||
|
%token <regnum> USAGE_POSITION
|
||||||
|
|
||||||
/* Misc stuff */
|
/* Misc stuff */
|
||||||
%token <component> COMPONENT
|
%token <component> COMPONENT
|
||||||
%token <immval> IMMVAL
|
%token <immval> IMMVAL
|
||||||
|
@ -210,6 +218,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
||||||
%type <modshift> omods
|
%type <modshift> omods
|
||||||
%type <modshift> omodifier
|
%type <modshift> omodifier
|
||||||
%type <comptype> comp
|
%type <comptype> comp
|
||||||
|
%type <declaration> dclusage
|
||||||
%type <rel_reg> rel_reg
|
%type <rel_reg> rel_reg
|
||||||
%type <reg> predicate
|
%type <reg> predicate
|
||||||
%type <immval> immsum
|
%type <immval> immsum
|
||||||
|
@ -476,6 +485,30 @@ instruction: INSTR_ADD omods dreg ',' sregs
|
||||||
TRACE("M3x2\n");
|
TRACE("M3x2\n");
|
||||||
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x2, $2.mod, $2.shift, 0, &$3, &$5, 2);
|
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_M3x2, $2.mod, $2.shift, 0, &$3, &$5, 2);
|
||||||
}
|
}
|
||||||
|
| INSTR_DCL dclusage REG_OUTPUT
|
||||||
|
{
|
||||||
|
struct shader_reg reg;
|
||||||
|
TRACE("Output reg declaration\n");
|
||||||
|
ZeroMemory(®, sizeof(reg));
|
||||||
|
reg.type = BWRITERSPR_OUTPUT;
|
||||||
|
reg.regnum = $3;
|
||||||
|
reg.rel_reg = NULL;
|
||||||
|
reg.srcmod = 0;
|
||||||
|
reg.writemask = BWRITERSP_WRITEMASK_ALL;
|
||||||
|
asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, ®);
|
||||||
|
}
|
||||||
|
| INSTR_DCL dclusage REG_OUTPUT writemask
|
||||||
|
{
|
||||||
|
struct shader_reg reg;
|
||||||
|
TRACE("Output reg declaration\n");
|
||||||
|
ZeroMemory(®, sizeof(reg));
|
||||||
|
reg.type = BWRITERSPR_OUTPUT;
|
||||||
|
reg.regnum = $3;
|
||||||
|
reg.rel_reg = NULL;
|
||||||
|
reg.srcmod = 0;
|
||||||
|
reg.writemask = $4;
|
||||||
|
asm_ctx.funcs->dcl_output(&asm_ctx, $2.dclusage, $2.regnum, ®);
|
||||||
|
}
|
||||||
| INSTR_REP sregs
|
| INSTR_REP sregs
|
||||||
{
|
{
|
||||||
TRACE("REP\n");
|
TRACE("REP\n");
|
||||||
|
@ -1041,6 +1074,13 @@ comp: COMP_GT { $$ = BWRITER_COMPARISON_GT; }
|
||||||
| COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
|
| COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
|
||||||
| COMP_NE { $$ = BWRITER_COMPARISON_NE; }
|
| COMP_NE { $$ = BWRITER_COMPARISON_NE; }
|
||||||
|
|
||||||
|
dclusage: USAGE_POSITION
|
||||||
|
{
|
||||||
|
TRACE("dcl_position%u\n", $1);
|
||||||
|
$$.regnum = $1;
|
||||||
|
$$.dclusage = BWRITERDECLUSAGE_POSITION;
|
||||||
|
}
|
||||||
|
|
||||||
predicate: '(' REG_PREDICATE swizzle ')'
|
predicate: '(' REG_PREDICATE swizzle ')'
|
||||||
{
|
{
|
||||||
$$.type = BWRITERSPR_PREDICATE;
|
$$.type = BWRITERSPR_PREDICATE;
|
||||||
|
|
|
@ -162,6 +162,7 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
|
||||||
case BWRITERSIO_RET: return D3DSIO_RET;
|
case BWRITERSIO_RET: return D3DSIO_RET;
|
||||||
case BWRITERSIO_ENDLOOP: return D3DSIO_ENDLOOP;
|
case BWRITERSIO_ENDLOOP: return D3DSIO_ENDLOOP;
|
||||||
case BWRITERSIO_LABEL: return D3DSIO_LABEL;
|
case BWRITERSIO_LABEL: return D3DSIO_LABEL;
|
||||||
|
case BWRITERSIO_DCL: return D3DSIO_DCL;
|
||||||
case BWRITERSIO_POW: return D3DSIO_POW;
|
case BWRITERSIO_POW: return D3DSIO_POW;
|
||||||
case BWRITERSIO_CRS: return D3DSIO_CRS;
|
case BWRITERSIO_CRS: return D3DSIO_CRS;
|
||||||
case BWRITERSIO_SGN: return D3DSIO_SGN;
|
case BWRITERSIO_SGN: return D3DSIO_SGN;
|
||||||
|
@ -426,6 +427,7 @@ const char *debug_print_opcode(DWORD opcode) {
|
||||||
case BWRITERSIO_RET: return "ret";
|
case BWRITERSIO_RET: return "ret";
|
||||||
case BWRITERSIO_ENDLOOP: return "endloop";
|
case BWRITERSIO_ENDLOOP: return "endloop";
|
||||||
case BWRITERSIO_LABEL: return "label";
|
case BWRITERSIO_LABEL: return "label";
|
||||||
|
case BWRITERSIO_DCL: return "dcl";
|
||||||
case BWRITERSIO_POW: return "pow";
|
case BWRITERSIO_POW: return "pow";
|
||||||
case BWRITERSIO_CRS: return "crs";
|
case BWRITERSIO_CRS: return "crs";
|
||||||
case BWRITERSIO_SGN: return "sgn";
|
case BWRITERSIO_SGN: return "sgn";
|
||||||
|
|
|
@ -104,6 +104,54 @@ BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) {
|
||||||
return TRUE;
|
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;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if(!shader) return FALSE;
|
||||||
|
|
||||||
|
if(output) {
|
||||||
|
num = &shader->num_outputs;
|
||||||
|
decl = &shader->outputs;
|
||||||
|
} else {
|
||||||
|
num = &shader->num_inputs;
|
||||||
|
decl = &shader->inputs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*num == 0) {
|
||||||
|
*decl = asm_alloc(sizeof(**decl));
|
||||||
|
if(!*decl) {
|
||||||
|
ERR("Error allocating declarations array\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct declaration *newdecl;
|
||||||
|
for(i = 0; i < *num; i++) {
|
||||||
|
if((*decl)[i].regnum == regnum && ((*decl)[i].writemask & writemask)) {
|
||||||
|
WARN("Declaration of register %u already exists, writemask match 0x%x\n",
|
||||||
|
regnum, (*decl)[i].writemask & writemask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newdecl = asm_realloc(*decl,
|
||||||
|
sizeof(**decl) * ((*num) + 1));
|
||||||
|
if(!newdecl) {
|
||||||
|
ERR("Error reallocating declarations array\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*decl = newdecl;
|
||||||
|
}
|
||||||
|
(*decl)[*num].usage = usage;
|
||||||
|
(*decl)[*num].usage_idx = usage_idx;
|
||||||
|
(*decl)[*num].regnum = regnum;
|
||||||
|
(*decl)[*num].writemask = writemask;
|
||||||
|
(*num)++;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* shader bytecode buffer manipulation functions.
|
/* shader bytecode buffer manipulation functions.
|
||||||
* allocate_buffer creates a new buffer structure, put_dword adds a new
|
* allocate_buffer creates a new buffer structure, put_dword adds a new
|
||||||
* DWORD to the buffer. In the rare case of a memory allocation failure
|
* DWORD to the buffer. In the rare case of a memory allocation failure
|
||||||
|
@ -147,6 +195,35 @@ static void put_dword(struct bytecode_buffer *buffer, DWORD value) {
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* Implementation of the writer functions starts here *
|
* Implementation of the writer functions starts here *
|
||||||
******************************************************/
|
******************************************************/
|
||||||
|
static void write_declarations(struct bytecode_buffer *buffer, BOOL len,
|
||||||
|
const struct declaration *decls, unsigned int num, DWORD type) {
|
||||||
|
DWORD i;
|
||||||
|
DWORD instr_dcl = D3DSIO_DCL;
|
||||||
|
DWORD token;
|
||||||
|
|
||||||
|
if(len) {
|
||||||
|
instr_dcl |= 2 << D3DSI_INSTLENGTH_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < num; i++) {
|
||||||
|
/* Write the DCL instruction */
|
||||||
|
put_dword(buffer, instr_dcl);
|
||||||
|
|
||||||
|
/* Write the usage and index */
|
||||||
|
token = (1 << 31); /* Bit 31 of non-instruction opcodes is 1 */
|
||||||
|
token |= (decls[i].usage << D3DSP_DCL_USAGE_SHIFT) & D3DSP_DCL_USAGE_MASK;
|
||||||
|
token |= (decls[i].usage_idx << D3DSP_DCL_USAGEINDEX_SHIFT) & D3DSP_DCL_USAGEINDEX_MASK;
|
||||||
|
put_dword(buffer, token);
|
||||||
|
|
||||||
|
/* Write the dest register */
|
||||||
|
token = (1 << 31); /* Bit 31 of non-instruction opcodes is 1 */
|
||||||
|
token |= (type << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
|
||||||
|
token |= (d3d9_writemask(decls[i].writemask)) & D3DSP_WRITEMASK_ALL;
|
||||||
|
token |= decls[i].regnum & D3DSP_REGNUM_MASK;
|
||||||
|
put_dword(buffer, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
static void end(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
||||||
put_dword(buffer, D3DSIO_END);
|
put_dword(buffer, D3DSIO_END);
|
||||||
}
|
}
|
||||||
|
@ -206,6 +283,8 @@ static void sm_2_opcode(struct bc_writer *This,
|
||||||
static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
static void sm_3_header(struct bc_writer *This, const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
|
||||||
/* Declare the shader type and version */
|
/* Declare the shader type and version */
|
||||||
put_dword(buffer, This->version);
|
put_dword(buffer, This->version);
|
||||||
|
|
||||||
|
write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,9 @@ struct asmparser_backend {
|
||||||
const struct shader_reg *predicate);
|
const struct shader_reg *predicate);
|
||||||
void (*coissue)(struct asm_parser *This);
|
void (*coissue)(struct asm_parser *This);
|
||||||
|
|
||||||
|
void (*dcl_output)(struct asm_parser *This, DWORD usage, DWORD num,
|
||||||
|
const struct shader_reg *reg);
|
||||||
|
|
||||||
void (*end)(struct asm_parser *This);
|
void (*end)(struct asm_parser *This);
|
||||||
|
|
||||||
void (*instr)(struct asm_parser *This, DWORD opcode, DWORD mod, DWORD shift,
|
void (*instr)(struct asm_parser *This, DWORD opcode, DWORD mod, DWORD shift,
|
||||||
|
@ -262,6 +265,7 @@ struct asmparser_backend {
|
||||||
|
|
||||||
struct instruction *alloc_instr(unsigned int srcs);
|
struct instruction *alloc_instr(unsigned int srcs);
|
||||||
BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr);
|
BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr);
|
||||||
|
BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_idx, BOOL output, DWORD regnum, DWORD writemask);
|
||||||
|
|
||||||
#define MESSAGEBUFFER_INITIAL_SIZE 256
|
#define MESSAGEBUFFER_INITIAL_SIZE 256
|
||||||
|
|
||||||
|
@ -402,6 +406,7 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
|
||||||
BWRITERSIO_RET,
|
BWRITERSIO_RET,
|
||||||
BWRITERSIO_ENDLOOP,
|
BWRITERSIO_ENDLOOP,
|
||||||
BWRITERSIO_LABEL,
|
BWRITERSIO_LABEL,
|
||||||
|
BWRITERSIO_DCL,
|
||||||
BWRITERSIO_POW,
|
BWRITERSIO_POW,
|
||||||
BWRITERSIO_CRS,
|
BWRITERSIO_CRS,
|
||||||
BWRITERSIO_SGN,
|
BWRITERSIO_SGN,
|
||||||
|
@ -513,6 +518,10 @@ typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE {
|
||||||
#define BWRITERVS_SWIZZLE_Z (BWRITERVS_X_Z | BWRITERVS_Y_Z | BWRITERVS_Z_Z | BWRITERVS_W_Z)
|
#define BWRITERVS_SWIZZLE_Z (BWRITERVS_X_Z | BWRITERVS_Y_Z | BWRITERVS_Z_Z | BWRITERVS_W_Z)
|
||||||
#define BWRITERVS_SWIZZLE_W (BWRITERVS_X_W | BWRITERVS_Y_W | BWRITERVS_Z_W | BWRITERVS_W_W)
|
#define BWRITERVS_SWIZZLE_W (BWRITERVS_X_W | BWRITERVS_Y_W | BWRITERVS_Z_W | BWRITERVS_W_W)
|
||||||
|
|
||||||
|
typedef enum _BWRITERDECLUSAGE {
|
||||||
|
BWRITERDECLUSAGE_POSITION,
|
||||||
|
} BWRITERDECLUSAGE;
|
||||||
|
|
||||||
struct bwriter_shader *SlAssembleShader(const char *text, char **messages);
|
struct bwriter_shader *SlAssembleShader(const char *text, char **messages);
|
||||||
DWORD SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result);
|
DWORD SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result);
|
||||||
void SlDeleteShader(struct bwriter_shader *shader);
|
void SlDeleteShader(struct bwriter_shader *shader);
|
||||||
|
|
|
@ -1023,11 +1023,11 @@ static void vs_3_0_test(void) {
|
||||||
"dcl_2d s0\n",
|
"dcl_2d s0\n",
|
||||||
{0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
|
{0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
|
||||||
},*/
|
},*/
|
||||||
/* {*/ /* shader 2 */
|
{ /* shader 2 */
|
||||||
/* "vs_3_0\n"
|
"vs_3_0\n"
|
||||||
"dcl_position o0\n",
|
"dcl_position o0\n",
|
||||||
{0xfffe0300, 0x0200001f, 0x80000000, 0xe00f0000, 0x0000ffff}
|
{0xfffe0300, 0x0200001f, 0x80000000, 0xe00f0000, 0x0000ffff}
|
||||||
},*/
|
},
|
||||||
/* {*/ /* shader 3 */
|
/* {*/ /* shader 3 */
|
||||||
/* "vs_3_0\n"
|
/* "vs_3_0\n"
|
||||||
"dcl_texcoord12 o11\n",
|
"dcl_texcoord12 o11\n",
|
||||||
|
|
Loading…
Reference in New Issue