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,
|
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,
|
||||||
|
@ -159,6 +167,7 @@ static const struct asmparser_backend parser_vs_3 = {
|
||||||
|
|
||||||
asmparser_dcl_output,
|
asmparser_dcl_output,
|
||||||
asmparser_dcl_input,
|
asmparser_dcl_input,
|
||||||
|
asmparser_dcl_sampler,
|
||||||
|
|
||||||
asmparser_end,
|
asmparser_end,
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,11 @@ DCL_FOG _fog[0-9]*
|
||||||
DCL_DEPTH _depth[0-9]*
|
DCL_DEPTH _depth[0-9]*
|
||||||
DCL_SAMPLE _sample[0-9]*
|
DCL_SAMPLE _sample[0-9]*
|
||||||
|
|
||||||
|
DCL_SAMPLER1D _1d
|
||||||
|
DCL_SAMPLER2D _2d
|
||||||
|
DCL_SAMPLERCUBE _cube
|
||||||
|
DCL_SAMPLERVOLUME _volume
|
||||||
|
|
||||||
PREPROCESSORDIRECTIVE #[^\n]*\n
|
PREPROCESSORDIRECTIVE #[^\n]*\n
|
||||||
|
|
||||||
/* Comments */
|
/* Comments */
|
||||||
|
@ -400,6 +405,11 @@ ps_3_0 {return VER_PS30; }
|
||||||
return USAGE_SAMPLE;
|
return USAGE_SAMPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{DCL_SAMPLER1D} { return SAMPTYPE_1D; }
|
||||||
|
{DCL_SAMPLER2D} { return SAMPTYPE_2D; }
|
||||||
|
{DCL_SAMPLERCUBE} { return SAMPTYPE_CUBE; }
|
||||||
|
{DCL_SAMPLERVOLUME} { return SAMPTYPE_VOLUME; }
|
||||||
|
|
||||||
{PREPROCESSORDIRECTIVE} {
|
{PREPROCESSORDIRECTIVE} {
|
||||||
/* TODO: update current line information */
|
/* TODO: update current line information */
|
||||||
TRACE("line info update: %s", yytext);
|
TRACE("line info update: %s", yytext);
|
||||||
|
|
|
@ -84,6 +84,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
||||||
DWORD dclusage;
|
DWORD dclusage;
|
||||||
unsigned int regnum;
|
unsigned int regnum;
|
||||||
} declaration;
|
} declaration;
|
||||||
|
BWRITERSAMPLER_TEXTURE_TYPE samplertype;
|
||||||
struct rel_reg rel_reg;
|
struct rel_reg rel_reg;
|
||||||
struct src_regs sregs;
|
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_ABS
|
||||||
%token SMOD_NOT
|
%token SMOD_NOT
|
||||||
|
|
||||||
|
/* Sampler types */
|
||||||
|
%token SAMPTYPE_1D
|
||||||
|
%token SAMPTYPE_2D
|
||||||
|
%token SAMPTYPE_CUBE
|
||||||
|
%token SAMPTYPE_VOLUME
|
||||||
|
|
||||||
/* Usage declaration tokens */
|
/* Usage declaration tokens */
|
||||||
%token <regnum> USAGE_POSITION
|
%token <regnum> USAGE_POSITION
|
||||||
%token <regnum> USAGE_BLENDWEIGHT
|
%token <regnum> USAGE_BLENDWEIGHT
|
||||||
|
@ -232,6 +239,7 @@ void set_rel_reg(struct shader_reg *reg, struct rel_reg *rel) {
|
||||||
%type <modshift> omodifier
|
%type <modshift> omodifier
|
||||||
%type <comptype> comp
|
%type <comptype> comp
|
||||||
%type <declaration> dclusage
|
%type <declaration> dclusage
|
||||||
|
%type <samplertype> sampdcl
|
||||||
%type <rel_reg> rel_reg
|
%type <rel_reg> rel_reg
|
||||||
%type <reg> predicate
|
%type <reg> predicate
|
||||||
%type <immval> immsum
|
%type <immval> immsum
|
||||||
|
@ -546,6 +554,25 @@ instruction: INSTR_ADD omods dreg ',' sregs
|
||||||
reg.writemask = $4;
|
reg.writemask = $4;
|
||||||
asm_ctx.funcs->dcl_input(&asm_ctx, $2.dclusage, $2.regnum, ®);
|
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
|
| INSTR_REP sregs
|
||||||
{
|
{
|
||||||
TRACE("REP\n");
|
TRACE("REP\n");
|
||||||
|
@ -1196,6 +1223,23 @@ dclusage: USAGE_POSITION
|
||||||
$$.dclusage = BWRITERDECLUSAGE_SAMPLE;
|
$$.dclusage = BWRITERDECLUSAGE_SAMPLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sampdcl: SAMPTYPE_1D
|
||||||
|
{
|
||||||
|
$$ = BWRITERSTT_1D;
|
||||||
|
}
|
||||||
|
| SAMPTYPE_2D
|
||||||
|
{
|
||||||
|
$$ = BWRITERSTT_2D;
|
||||||
|
}
|
||||||
|
| SAMPTYPE_CUBE
|
||||||
|
{
|
||||||
|
$$ = BWRITERSTT_CUBE;
|
||||||
|
}
|
||||||
|
| SAMPTYPE_VOLUME
|
||||||
|
{
|
||||||
|
$$ = BWRITERSTT_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
predicate: '(' REG_PREDICATE swizzle ')'
|
predicate: '(' REG_PREDICATE swizzle ')'
|
||||||
{
|
{
|
||||||
$$.type = BWRITERSPR_PREDICATE;
|
$$.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) {
|
DWORD d3d9_register(DWORD bwriter_register) {
|
||||||
if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
|
if(bwriter_register == BWRITERSPR_TEMP) return D3DSPR_TEMP;
|
||||||
if(bwriter_register == BWRITERSPR_INPUT) return D3DSPR_INPUT;
|
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;
|
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.
|
/* 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
|
||||||
|
@ -280,12 +318,33 @@ static void sm_2_opcode(struct bc_writer *This,
|
||||||
put_dword(buffer,token);
|
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) {
|
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->inputs, shader->num_inputs, D3DSPR_INPUT);
|
write_declarations(buffer, TRUE, shader->inputs, shader->num_inputs, D3DSPR_INPUT);
|
||||||
write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT);
|
write_declarations(buffer, TRUE, shader->outputs, shader->num_outputs, D3DSPR_OUTPUT);
|
||||||
|
write_samplers(shader, buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,6 @@ struct declaration {
|
||||||
struct samplerdecl {
|
struct samplerdecl {
|
||||||
DWORD type;
|
DWORD type;
|
||||||
DWORD regnum;
|
DWORD regnum;
|
||||||
unsigned int line_no; /* for error messages */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INSTRARRAY_INITIAL_SIZE 8
|
#define INSTRARRAY_INITIAL_SIZE 8
|
||||||
|
@ -257,6 +256,8 @@ struct asmparser_backend {
|
||||||
const struct shader_reg *reg);
|
const struct shader_reg *reg);
|
||||||
void (*dcl_input)(struct asm_parser *This, DWORD usage, DWORD num,
|
void (*dcl_input)(struct asm_parser *This, DWORD usage, DWORD num,
|
||||||
const struct shader_reg *reg);
|
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);
|
void (*end)(struct asm_parser *This);
|
||||||
|
|
||||||
|
@ -268,6 +269,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);
|
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
|
#define MESSAGEBUFFER_INITIAL_SIZE 256
|
||||||
|
|
||||||
|
@ -366,6 +368,7 @@ DWORD d3d9_writemask(DWORD bwriter_writemask);
|
||||||
DWORD d3d9_srcmod(DWORD bwriter_srcmod);
|
DWORD d3d9_srcmod(DWORD bwriter_srcmod);
|
||||||
DWORD d3d9_dstmod(DWORD bwriter_mod);
|
DWORD d3d9_dstmod(DWORD bwriter_mod);
|
||||||
DWORD d3d9_comparetype(DWORD bwriter_comparetype);
|
DWORD d3d9_comparetype(DWORD bwriter_comparetype);
|
||||||
|
DWORD d3d9_sampler(DWORD bwriter_sampler);
|
||||||
DWORD d3d9_register(DWORD bwriter_register);
|
DWORD d3d9_register(DWORD bwriter_register);
|
||||||
DWORD d3d9_opcode(DWORD bwriter_opcode);
|
DWORD d3d9_opcode(DWORD bwriter_opcode);
|
||||||
|
|
||||||
|
@ -476,6 +479,14 @@ typedef enum _BWRITERSHADER_PARAM_DSTMOD_TYPE {
|
||||||
BWRITERSPDM_MSAMPCENTROID = 4,
|
BWRITERSPDM_MSAMPCENTROID = 4,
|
||||||
} BWRITERSHADER_PARAM_DSTMOD_TYPE;
|
} 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 {
|
typedef enum _BWRITERSHADER_PARAM_SRCMOD_TYPE {
|
||||||
BWRITERSPSM_NONE = 0,
|
BWRITERSPSM_NONE = 0,
|
||||||
BWRITERSPSM_NEG,
|
BWRITERSPSM_NEG,
|
||||||
|
|
|
@ -1008,21 +1008,17 @@ static void ps_2_x_test(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vs_3_0_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[] = {
|
struct shader_test tests[] = {
|
||||||
{ /* shader 0 */
|
{ /* shader 0 */
|
||||||
"vs_3_0\n"
|
"vs_3_0\n"
|
||||||
"mov r0, c0\n",
|
"mov r0, c0\n",
|
||||||
{0xfffe0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
|
{0xfffe0300, 0x02000001, 0x800f0000, 0xa0e40000, 0x0000ffff}
|
||||||
},
|
},
|
||||||
/* {*/ /* shader 1 */
|
{ /* shader 1 */
|
||||||
/* "vs_3_0\n"
|
"vs_3_0\n"
|
||||||
"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",
|
||||||
|
|
Loading…
Reference in New Issue