[4/4] d3dx9: Add sampler dcl instruction support to the shader assembler.
Matteo Bruni
matteo.mystral at gmail.com
Thu May 13 10:25:30 CDT 2010
-------------- next part --------------
From 1fda7e7e2d49cb565e695276c9d7c37673824d6c Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Thu, 13 May 2010 17:21:59 +0200
Subject: d3dx9: Add sampler dcl instruction support to the shader assembler.
---
dlls/d3dx9_36/asmparser.c | 9 ++++++
dlls/d3dx9_36/asmshader.l | 10 ++++++
dlls/d3dx9_36/asmshader.y | 44 ++++++++++++++++++++++++++++
dlls/d3dx9_36/asmutils.c | 11 +++++++
dlls/d3dx9_36/bytecodewriter.c | 59 ++++++++++++++++++++++++++++++++++++++
dlls/d3dx9_36/d3dx9_36_private.h | 13 ++++++++-
dlls/d3dx9_36/tests/asm.c | 10 ++----
7 files changed, 148 insertions(+), 8 deletions(-)
diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index bee92f6..6d0d31f 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -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,
diff --git a/dlls/d3dx9_36/asmshader.l b/dlls/d3dx9_36/asmshader.l
index b7835a8..9486b53 100644
--- a/dlls/d3dx9_36/asmshader.l
+++ b/dlls/d3dx9_36/asmshader.l
@@ -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);
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index ca4d24c..a6ab57e 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -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;
diff --git a/dlls/d3dx9_36/asmutils.c b/dlls/d3dx9_36/asmutils.c
index c5098ca..c34f5f5 100644
--- a/dlls/d3dx9_36/asmutils.c
+++ b/dlls/d3dx9_36/asmutils.c
@@ -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;
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index 4d62465..82a3655 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -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;
}
diff --git a/dlls/d3dx9_36/d3dx9_36_private.h b/dlls/d3dx9_36/d3dx9_36_private.h
index 344bdbf..a102e65 100644
--- a/dlls/d3dx9_36/d3dx9_36_private.h
+++ b/dlls/d3dx9_36/d3dx9_36_private.h
@@ -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,
diff --git a/dlls/d3dx9_36/tests/asm.c b/dlls/d3dx9_36/tests/asm.c
index dd51a95..21adb81 100644
--- a/dlls/d3dx9_36/tests/asm.c
+++ b/dlls/d3dx9_36/tests/asm.c
@@ -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",
--
1.6.4.4
More information about the wine-patches
mailing list