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");
|
||||
}
|
||||
|
||||
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,
|
||||
DWORD mod, DWORD shift,
|
||||
BWRITER_COMPARISON_TYPE comp,
|
||||
|
@ -135,6 +148,8 @@ static const struct asmparser_backend parser_vs_3 = {
|
|||
asmparser_predicate_supported,
|
||||
asmparser_coissue_unsupported,
|
||||
|
||||
asmparser_dcl_output,
|
||||
|
||||
asmparser_end,
|
||||
|
||||
asmparser_instr,
|
||||
|
|
|
@ -66,6 +66,8 @@ REG_PREDICATE p0
|
|||
/* Not really a register, but it is considered as such */
|
||||
REG_LABEL l[0-9]+
|
||||
|
||||
DCL_POSITION _position[0-9]*
|
||||
|
||||
PREPROCESSORDIRECTIVE #[^\n]*\n
|
||||
|
||||
/* Comments */
|
||||
|
@ -117,6 +119,7 @@ m4x3 {return INSTR_M4x3; }
|
|||
m3x4 {return INSTR_M3x4; }
|
||||
m3x3 {return INSTR_M3x3; }
|
||||
m3x2 {return INSTR_M3x2; }
|
||||
dcl {return INSTR_DCL; }
|
||||
rep {return INSTR_REP; }
|
||||
endrep {return INSTR_ENDREP; }
|
||||
if {return INSTR_IF; }
|
||||
|
@ -271,6 +274,15 @@ ps_3_0 {return VER_PS30; }
|
|||
|
||||
! {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} {
|
||||
/* TODO: update current line information */
|
||||
TRACE("line info update: %s", yytext);
|
||||
|
|
|
@ -80,6 +80,10 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
|||
DWORD shift;
|
||||
} modshift;
|
||||
BWRITER_COMPARISON_TYPE comptype;
|
||||
struct {
|
||||
DWORD dclusage;
|
||||
unsigned int regnum;
|
||||
} declaration;
|
||||
struct rel_reg rel_reg;
|
||||
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_M3x3
|
||||
%token INSTR_M3x2
|
||||
%token INSTR_DCL
|
||||
%token INSTR_REP
|
||||
%token INSTR_ENDREP
|
||||
%token INSTR_IF
|
||||
|
@ -193,6 +198,9 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
|||
%token SMOD_ABS
|
||||
%token SMOD_NOT
|
||||
|
||||
/* Usage declaration tokens */
|
||||
%token <regnum> USAGE_POSITION
|
||||
|
||||
/* Misc stuff */
|
||||
%token <component> COMPONENT
|
||||
%token <immval> IMMVAL
|
||||
|
@ -210,6 +218,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
|||
%type <modshift> omods
|
||||
%type <modshift> omodifier
|
||||
%type <comptype> comp
|
||||
%type <declaration> dclusage
|
||||
%type <rel_reg> rel_reg
|
||||
%type <reg> predicate
|
||||
%type <immval> immsum
|
||||
|
@ -476,6 +485,30 @@ instruction: INSTR_ADD omods dreg ',' sregs
|
|||
TRACE("M3x2\n");
|
||||
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
|
||||
{
|
||||
TRACE("REP\n");
|
||||
|
@ -1041,6 +1074,13 @@ comp: COMP_GT { $$ = BWRITER_COMPARISON_GT; }
|
|||
| COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
|
||||
| COMP_NE { $$ = BWRITER_COMPARISON_NE; }
|
||||
|
||||
dclusage: USAGE_POSITION
|
||||
{
|
||||
TRACE("dcl_position%u\n", $1);
|
||||
$$.regnum = $1;
|
||||
$$.dclusage = BWRITERDECLUSAGE_POSITION;
|
||||
}
|
||||
|
||||
predicate: '(' REG_PREDICATE swizzle ')'
|
||||
{
|
||||
$$.type = BWRITERSPR_PREDICATE;
|
||||
|
|
|
@ -162,6 +162,7 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
|
|||
case BWRITERSIO_RET: return D3DSIO_RET;
|
||||
case BWRITERSIO_ENDLOOP: return D3DSIO_ENDLOOP;
|
||||
case BWRITERSIO_LABEL: return D3DSIO_LABEL;
|
||||
case BWRITERSIO_DCL: return D3DSIO_DCL;
|
||||
case BWRITERSIO_POW: return D3DSIO_POW;
|
||||
case BWRITERSIO_CRS: return D3DSIO_CRS;
|
||||
case BWRITERSIO_SGN: return D3DSIO_SGN;
|
||||
|
@ -426,6 +427,7 @@ const char *debug_print_opcode(DWORD opcode) {
|
|||
case BWRITERSIO_RET: return "ret";
|
||||
case BWRITERSIO_ENDLOOP: return "endloop";
|
||||
case BWRITERSIO_LABEL: return "label";
|
||||
case BWRITERSIO_DCL: return "dcl";
|
||||
case BWRITERSIO_POW: return "pow";
|
||||
case BWRITERSIO_CRS: return "crs";
|
||||
case BWRITERSIO_SGN: return "sgn";
|
||||
|
|
|
@ -104,6 +104,54 @@ BOOL add_instruction(struct bwriter_shader *shader, struct instruction *instr) {
|
|||
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.
|
||||
* 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
|
||||
|
@ -147,6 +195,35 @@ static void put_dword(struct bytecode_buffer *buffer, DWORD value) {
|
|||
/******************************************************
|
||||
* 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) {
|
||||
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) {
|
||||
/* Declare the shader type and version */
|
||||
put_dword(buffer, This->version);
|
||||
|
||||
write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -253,6 +253,9 @@ struct asmparser_backend {
|
|||
const struct shader_reg *predicate);
|
||||
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 (*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);
|
||||
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
|
||||
|
||||
|
@ -402,6 +406,7 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
|
|||
BWRITERSIO_RET,
|
||||
BWRITERSIO_ENDLOOP,
|
||||
BWRITERSIO_LABEL,
|
||||
BWRITERSIO_DCL,
|
||||
BWRITERSIO_POW,
|
||||
BWRITERSIO_CRS,
|
||||
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_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);
|
||||
DWORD SlWriteBytecode(const struct bwriter_shader *shader, int dxversion, DWORD **result);
|
||||
void SlDeleteShader(struct bwriter_shader *shader);
|
||||
|
|
|
@ -1023,11 +1023,11 @@ static void vs_3_0_test(void) {
|
|||
"dcl_2d s0\n",
|
||||
{0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
|
||||
},*/
|
||||
/* {*/ /* shader 2 */
|
||||
/* "vs_3_0\n"
|
||||
{ /* shader 2 */
|
||||
"vs_3_0\n"
|
||||
"dcl_position o0\n",
|
||||
{0xfffe0300, 0x0200001f, 0x80000000, 0xe00f0000, 0x0000ffff}
|
||||
},*/
|
||||
},
|
||||
/* {*/ /* shader 3 */
|
||||
/* "vs_3_0\n"
|
||||
"dcl_texcoord12 o11\n",
|
||||
|
|
Loading…
Reference in New Issue