d3dx9: Add sampler dcl instruction support to the shader assembler.

This commit is contained in:
Matteo Bruni 2010-05-13 17:21:59 +02:00 committed by Alexandre Julliard
parent 6cbd511475
commit 745b5fe8f1
7 changed files with 148 additions and 8 deletions

View File

@ -60,6 +60,14 @@ static void asmparser_dcl_input(struct asm_parser *This, DWORD usage, DWORD num,
}
}
static void asmparser_dcl_sampler(struct asm_parser *This, DWORD samptype, DWORD regnum, unsigned int line_no) {
if(!This->shader) return;
if(!record_sampler(This->shader, samptype, regnum)) {
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,
@ -159,6 +167,7 @@ static const struct asmparser_backend parser_vs_3 = {
asmparser_dcl_output,
asmparser_dcl_input,
asmparser_dcl_sampler,
asmparser_end,

View File

@ -81,6 +81,11 @@ DCL_FOG _fog[0-9]*
DCL_DEPTH _depth[0-9]*
DCL_SAMPLE _sample[0-9]*
DCL_SAMPLER1D _1d
DCL_SAMPLER2D _2d
DCL_SAMPLERCUBE _cube
DCL_SAMPLERVOLUME _volume
PREPROCESSORDIRECTIVE #[^\n]*\n
/* Comments */
@ -400,6 +405,11 @@ ps_3_0 {return VER_PS30; }
return USAGE_SAMPLE;
}
{DCL_SAMPLER1D} { return SAMPTYPE_1D; }
{DCL_SAMPLER2D} { return SAMPTYPE_2D; }
{DCL_SAMPLERCUBE} { return SAMPTYPE_CUBE; }
{DCL_SAMPLERVOLUME} { return SAMPTYPE_VOLUME; }
{PREPROCESSORDIRECTIVE} {
/* TODO: update current line information */
TRACE("line info update: %s", yytext);

View File

@ -84,6 +84,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
DWORD dclusage;
unsigned int regnum;
} declaration;
BWRITERSAMPLER_TEXTURE_TYPE samplertype;
struct rel_reg rel_reg;
struct src_regs sregs;
}
@ -198,6 +199,12 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
%token SMOD_ABS
%token SMOD_NOT
/* Sampler types */
%token SAMPTYPE_1D
%token SAMPTYPE_2D
%token SAMPTYPE_CUBE
%token SAMPTYPE_VOLUME
/* Usage declaration tokens */
%token <regnum> USAGE_POSITION
%token <regnum> USAGE_BLENDWEIGHT
@ -232,6 +239,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
%type <modshift> omodifier
%type <comptype> comp
%type <declaration> dclusage
%type <samplertype> sampdcl
%type <rel_reg> rel_reg
%type <reg> predicate
%type <immval> immsum
@ -546,6 +554,25 @@ instruction: INSTR_ADD omods dreg ',' sregs
reg.writemask = $4;
asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, &reg);
}
| INSTR_DCL sampdcl REG_SAMPLER
{
TRACE("Sampler declared\n");
asm_ctx.funcs->dcl_sampler(&asm_ctx, $2, $3, asm_ctx.line_no);
}
| INSTR_DCL sampdcl REG_INPUT
{
TRACE("Error rule: sampler decl of input reg\n");
asmparser_message(&asm_ctx, "Line %u: Sampler declarations of input regs is not valid\n",
asm_ctx.line_no);
set_parse_status(&asm_ctx, PARSE_WARN);
}
| INSTR_DCL sampdcl REG_OUTPUT
{
TRACE("Error rule: sampler decl of output reg\n");
asmparser_message(&asm_ctx, "Line %u: Sampler declarations of output regs is not valid\n",
asm_ctx.line_no);
set_parse_status(&asm_ctx, PARSE_WARN);
}
| INSTR_REP sregs
{
TRACE("REP\n");
@ -1196,6 +1223,23 @@ dclusage: USAGE_POSITION
$$.dclusage = BWRITERDECLUSAGE_SAMPLE;
}
sampdcl: SAMPTYPE_1D
{
$$ = BWRITERSTT_1D;
}
| SAMPTYPE_2D
{
$$ = BWRITERSTT_2D;
}
| SAMPTYPE_CUBE
{
$$ = BWRITERSTT_CUBE;
}
| SAMPTYPE_VOLUME
{
$$ = BWRITERSTT_VOLUME;
}
predicate: '(' REG_PREDICATE swizzle ')'
{
$$.type = BWRITERSPR_PREDICATE;

View File

@ -105,6 +105,17 @@ DWORD d3d9_comparetype(DWORD asmshader_comparetype) {
}
}
DWORD d3d9_sampler(DWORD bwriter_sampler) {
if(bwriter_sampler == BWRITERSTT_UNKNOWN) return D3DSTT_UNKNOWN;
if(bwriter_sampler == BWRITERSTT_1D) return D3DSTT_1D;
if(bwriter_sampler == BWRITERSTT_2D) return D3DSTT_2D;
if(bwriter_sampler == BWRITERSTT_CUBE) return D3DSTT_CUBE;
if(bwriter_sampler == BWRITERSTT_VOLUME) return D3DSTT_VOLUME;
FIXME("Unexpected BWRITERSAMPLER_TEXTURE_TYPE type %u\n", bwriter_sampler);
return 0;
}
DWORD d3d9_register(DWORD bwriter_register) {
if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
if(bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT;

View File

@ -151,6 +151,44 @@ BOOL record_declaration(struct bwriter_shader *shader, DWORD usage, DWORD usage_
return TRUE;
}
BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum) {
unsigned int i;
if(!shader) return FALSE;
if(shader->num_samplers == 0) {
shader->samplers = asm_alloc(sizeof(*shader->samplers));
if(!shader->samplers) {
ERR("Error allocating samplers array\n");
return FALSE;
}
} else {
struct samplerdecl *newarray;
for(i = 0; i < shader->num_samplers; i++) {
if(shader->samplers[i].regnum == regnum) {
WARN("Sampler %u already declared\n", regnum);
/* This is not an error as far as the assembler is concerned.
* Direct3D might refuse to load the compiled shader though
*/
}
}
newarray = asm_realloc(shader->samplers,
sizeof(*shader->samplers) * (shader->num_samplers + 1));
if(!newarray) {
ERR("Error reallocating samplers array\n");
return FALSE;
}
shader->samplers = newarray;
}
shader->samplers[shader->num_samplers].type = samptype;
shader->samplers[shader->num_samplers].regnum = regnum;
shader->num_samplers++;
return TRUE;
}
/* shader bytecode buffer manipulation functions.
* allocate_buffer creates a new buffer structure, put_dword adds a new
@ -280,12 +318,33 @@ static void sm_2_opcode(struct bc_writer *This,
put_dword(buffer,token);
}
static void write_samplers(const struct bwriter_shader *shader, struct bytecode_buffer *buffer) {
DWORD i;
DWORD instr_dcl = D3DSIO_DCL | (2 << D3DSI_INSTLENGTH_SHIFT);
DWORD token;
const DWORD reg = (1<<31) |
((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK) |
((D3DSPR_SAMPLER << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2) |
D3DSP_WRITEMASK_ALL;
for(i = 0; i < shader->num_samplers; i++) {
/* Write the DCL instruction */
put_dword(buffer, instr_dcl);
token = (1<<31);
/* Already shifted */
token |= (d3d9_sampler(shader->samplers[i].type)) & D3DSP_TEXTURETYPE_MASK;
put_dword(buffer, token);
put_dword(buffer, reg | (shader->samplers[i].regnum & D3DSP_REGNUM_MASK));
}
}
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->inputs, shader->num_inputs, D3DSPR_INPUT);
write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT);
write_samplers(shader, buffer);
return;
}

View File

@ -179,7 +179,6 @@ struct declaration {
struct samplerdecl {
DWORD type;
DWORD regnum;
unsigned int line_no; /* for error messages */
};
#define INSTRARRAY_INITIAL_SIZE 8
@ -257,6 +256,8 @@ struct asmparser_backend {
const struct shader_reg *reg);
void (*dcl_input)(struct asm_parser *This, DWORD usage, DWORD num,
const struct shader_reg *reg);
void (*dcl_sampler)(struct asm_parser *This, DWORD samptype, DWORD regnum,
unsigned int line_no);
void (*end)(struct asm_parser *This);
@ -268,6 +269,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);
BOOL record_sampler(struct bwriter_shader *shader, DWORD samptype, DWORD regnum);
#define MESSAGEBUFFER_INITIAL_SIZE 256
@ -366,6 +368,7 @@ 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_sampler(DWORD bwriter_sampler);
DWORD d3d9_register(DWORD bwriter_register);
DWORD d3d9_opcode(DWORD bwriter_opcode);
@ -476,6 +479,14 @@ typedef enum _BWRITERSHADER_PARAM_DSTMOD_TYPE {
BWRITERSPDM_MSAMPCENTROID = 4,
} BWRITERSHADER_PARAM_DSTMOD_TYPE;
typedef enum _BWRITERSAMPLER_TEXTURE_TYPE {
BWRITERSTT_UNKNOWN = 0,
BWRITERSTT_1D = 1,
BWRITERSTT_2D = 2,
BWRITERSTT_CUBE = 3,
BWRITERSTT_VOLUME = 4,
} BWRITERSAMPLER_TEXTURE_TYPE;
typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE {
BWRITERSPSM_NONE = 0,
BWRITERSPSM_NEG,

View File

@ -1008,21 +1008,17 @@ static void ps_2_x_test(void) {
}
static void vs_3_0_test(void) {
/* FIXME: Some tests are temporarily commented out, because the
current implementation doesn't support the entire vs_3_0 syntax
and it is not trivial to remove todo_wine only from
a subset of the tests here */
struct shader_test tests[] = {
{ /* shader 0 */
"vs_3_0\n"
"mov r0, c0\n",
{0xfffe0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
},
/* {*/ /* shader 1 */
/* "vs_3_0\n"
{ /* shader 1 */
"vs_3_0\n"
"dcl_2d s0\n",
{0xfffe0300, 0x0200001f, 0x90000000, 0xa00f0800, 0x0000ffff}
},*/
},
{ /* shader 2 */
"vs_3_0\n"
"dcl_position o0\n",