d3dx9: Add sampler dcl instruction support to the shader assembler.
This commit is contained in:
parent
6cbd511475
commit
745b5fe8f1
|
@ -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,
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ®);
|
||||
}
|
||||
| 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in New Issue