d3dx9: Add other flow control instructions in the shader assembler.

This commit is contained in:
Matteo Bruni 2009-11-24 02:08:32 +01:00 committed by Alexandre Julliard
parent 25c929ab61
commit 93b2648c49
6 changed files with 84 additions and 3 deletions

View File

@ -50,8 +50,9 @@ static void asmparser_instr(struct asm_parser *This, DWORD opcode,
if(!This->shader) return;
TRACE_(parsed_shader)("%s%s ", debug_print_opcode(opcode),
debug_print_dstmod(mod));
TRACE_(parsed_shader)("%s%s%s ", debug_print_opcode(opcode),
debug_print_dstmod(mod),
debug_print_comp(comp));
if(dst) {
TRACE_(parsed_shader)("%s", debug_print_dstreg(dst, This->shader->type));
firstreg = FALSE;

View File

@ -243,6 +243,14 @@ ps_3_0 {return VER_PS30; }
\_pp {return MOD_PP; }
\_centroid {return MOD_CENTROID; }
/* compare params */
\_gt {return COMP_GT; }
\_lt {return COMP_LT; }
\_ge {return COMP_GE; }
\_le {return COMP_LE; }
\_eq {return COMP_EQ; }
\_ne {return COMP_NE; }
{IMMVAL} {
asmshader_lval.immval.val = atof(yytext);
asmshader_lval.immval.integer = ((strstr(yytext, ".") == NULL) && (strstr(yytext, "f") == NULL));

View File

@ -79,6 +79,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
DWORD mod;
DWORD shift;
} modshift;
BWRITER_COMPARISON_TYPE comptype;
struct rel_reg rel_reg;
struct src_regs sregs;
}
@ -178,6 +179,14 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
%token MOD_PP
%token MOD_CENTROID
/* Compare tokens */
%token COMP_GT
%token COMP_LT
%token COMP_GE
%token COMP_LE
%token COMP_EQ
%token COMP_NE
/* Source register modifiers */
%token SMOD_ABS
%token SMOD_NOT
@ -198,6 +207,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
%type <sw_components> sw_components
%type <modshift> omods
%type <modshift> omodifier
%type <comptype> comp
%type <rel_reg> rel_reg
%type <immval> immsum
%type <sregs> sregs
@ -473,6 +483,11 @@ instruction: INSTR_ADD omods dreg ',' sregs
TRACE("IF\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IF, 0, 0, 0, 0, &$2, 1);
}
| INSTR_IF comp sregs
{
TRACE("IFC\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_IFC, 0, 0, $2, 0, &$3, 2);
}
| INSTR_ELSE
{
TRACE("ELSE\n");
@ -488,6 +503,11 @@ instruction: INSTR_ADD omods dreg ',' sregs
TRACE("BREAK\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAK, 0, 0, 0, 0, 0, 0);
}
| INSTR_BREAK comp sregs
{
TRACE("BREAKC\n");
asm_ctx.funcs->instr(&asm_ctx, BWRITERSIO_BREAKC, 0, 0, $2, 0, &$3, 2);
}
| INSTR_CALL sregs
{
TRACE("CALL\n");
@ -996,6 +1016,13 @@ sreg_name: REG_TEMP
$$.regnum = $1; $$.type = BWRITERSPR_LABEL;
}
comp: COMP_GT { $$ = BWRITER_COMPARISON_GT; }
| COMP_LT { $$ = BWRITER_COMPARISON_LT; }
| COMP_GE { $$ = BWRITER_COMPARISON_GE; }
| COMP_LE { $$ = BWRITER_COMPARISON_LE; }
| COMP_EQ { $$ = BWRITER_COMPARISON_EQ; }
| COMP_NE { $$ = BWRITER_COMPARISON_NE; }
%%
void asmshader_error (char const *s) {

View File

@ -91,6 +91,20 @@ DWORD d3d9_dstmod(DWORD bwriter_mod) {
return ret;
}
DWORD d3d9_comparetype(DWORD asmshader_comparetype) {
switch(asmshader_comparetype) {
case BWRITER_COMPARISON_GT: return D3DSPC_GT;
case BWRITER_COMPARISON_EQ: return D3DSPC_EQ;
case BWRITER_COMPARISON_GE: return D3DSPC_GE;
case BWRITER_COMPARISON_LT: return D3DSPC_LT;
case BWRITER_COMPARISON_NE: return D3DSPC_NE;
case BWRITER_COMPARISON_LE: return D3DSPC_LE;
default:
FIXME("Unexpected BWRITER_COMPARISON type %u\n", asmshader_comparetype);
return 0;
}
}
DWORD d3d9_register(DWORD bwriter_register) {
if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
if(bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT;
@ -157,9 +171,11 @@ DWORD d3d9_opcode(DWORD bwriter_opcode) {
case BWRITERSIO_REP: return D3DSIO_REP;
case BWRITERSIO_ENDREP: return D3DSIO_ENDREP;
case BWRITERSIO_IF: return D3DSIO_IF;
case BWRITERSIO_IFC: return D3DSIO_IFC;
case BWRITERSIO_ELSE: return D3DSIO_ELSE;
case BWRITERSIO_ENDIF: return D3DSIO_ENDIF;
case BWRITERSIO_BREAK: return D3DSIO_BREAK;
case BWRITERSIO_BREAKC: return D3DSIO_BREAKC;
case BWRITERSIO_MOVA: return D3DSIO_MOVA;
case BWRITERSIO_EXPP: return D3DSIO_EXPP;
case BWRITERSIO_LOGP: return D3DSIO_LOGP;
@ -362,6 +378,19 @@ const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st) {
return "Unknown modifier";
}
const char *debug_print_comp(DWORD comp) {
switch(comp) {
case BWRITER_COMPARISON_NONE: return "";
case BWRITER_COMPARISON_GT: return "_gt";
case BWRITER_COMPARISON_EQ: return "_eq";
case BWRITER_COMPARISON_GE: return "_ge";
case BWRITER_COMPARISON_LT: return "_lt";
case BWRITER_COMPARISON_NE: return "_ne";
case BWRITER_COMPARISON_LE: return "_le";
default: return "_unknown";
}
}
const char *debug_print_opcode(DWORD opcode) {
switch(opcode){
case BWRITERSIO_NOP: return "nop";
@ -404,9 +433,11 @@ const char *debug_print_opcode(DWORD opcode) {
case BWRITERSIO_REP: return "rep";
case BWRITERSIO_ENDREP: return "endrep";
case BWRITERSIO_IF: return "if";
case BWRITERSIO_IFC: return "ifc";
case BWRITERSIO_ELSE: return "else";
case BWRITERSIO_ENDIF: return "endif";
case BWRITERSIO_BREAK: return "break";
case BWRITERSIO_BREAKC: return "breakc";
case BWRITERSIO_MOVA: return "mova";
case BWRITERSIO_EXPP: return "expp";
case BWRITERSIO_LOGP: return "logp";

View File

@ -196,6 +196,8 @@ static void sm_2_opcode(struct bc_writer *This,
/* From sm 2 onwards instruction length is encoded in the opcode field */
int dsts = instr->has_dst ? 1 : 0;
token |= instrlen(instr, instr->num_srcs, dsts) << D3DSI_INSTLENGTH_SHIFT;
if(instr->comptype)
token |= (d3d9_comparetype(instr->comptype) << 16) & (0xf << 16);
put_dword(buffer,token);
}
@ -324,9 +326,11 @@ static const struct instr_handler_table vs_3_handlers[] = {
{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},

View File

@ -137,7 +137,13 @@ typedef enum _shader_type {
} shader_type;
typedef enum BWRITER_COMPARISON_TYPE {
BWRITER_COMPARISON_NONE = 0,
BWRITER_COMPARISON_NONE,
BWRITER_COMPARISON_GT,
BWRITER_COMPARISON_EQ,
BWRITER_COMPARISON_GE,
BWRITER_COMPARISON_LT,
BWRITER_COMPARISON_NE,
BWRITER_COMPARISON_LE
} BWRITER_COMPARISON_TYPE;
struct shader_reg {
@ -345,6 +351,7 @@ const char *debug_print_dstreg(const struct shader_reg *reg, shader_type st);
const char *debug_print_srcreg(const struct shader_reg *reg, shader_type st);
const char *debug_print_swizzle(DWORD swizzle);
const char *debug_print_writemask(DWORD mask);
const char *debug_print_comp(DWORD comp);
const char *debug_print_opcode(DWORD opcode);
/* Utilities for internal->d3d constant mapping */
@ -352,6 +359,7 @@ DWORD d3d9_swizzle(DWORD bwriter_swizzle);
DWORD d3d9_writemask(DWORD bwriter_writemask);
DWORD d3d9_srcmod(DWORD bwriter_srcmod);
DWORD d3d9_dstmod(DWORD bwriter_mod);
DWORD d3d9_comparetype(DWORD bwriter_comparetype);
DWORD d3d9_register(DWORD bwriter_register);
DWORD d3d9_opcode(DWORD bwriter_opcode);
@ -403,9 +411,11 @@ typedef enum _BWRITERSHADER_INSTRUCTION_OPCODE_TYPE {
BWRITERSIO_REP,
BWRITERSIO_ENDREP,
BWRITERSIO_IF,
BWRITERSIO_IFC,
BWRITERSIO_ELSE,
BWRITERSIO_ENDIF,
BWRITERSIO_BREAK,
BWRITERSIO_BREAKC,
BWRITERSIO_MOVA,
BWRITERSIO_EXPP,