[6/18] d3dx9: Shader assembler VS/PS 3.0 support

Matteo Bruni matteo.mystral at gmail.com
Sun Aug 16 12:52:03 CDT 2009


-------------- next part --------------
From dd8c1742a8617b4586c0741f1f561e123898bffd Mon Sep 17 00:00:00 2001
From: Matteo Bruni <matteo.mystral at gmail.com>
Date: Sat, 15 Aug 2009 21:28:02 +0200
Subject: d3dx9: Shader assembler VS/PS 3.0 support

---
 dlls/d3dx9_36/asmparser.c      |  219 ++++++++++++++++++++++++++++++++++
 dlls/d3dx9_36/asmshader.y      |    4 +-
 dlls/d3dx9_36/bytecodewriter.c |  257 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 476 insertions(+), 4 deletions(-)

diff --git a/dlls/d3dx9_36/asmparser.c b/dlls/d3dx9_36/asmparser.c
index a880b62..6f34ffb 100644
--- a/dlls/d3dx9_36/asmparser.c
+++ b/dlls/d3dx9_36/asmparser.c
@@ -154,3 +154,222 @@ static void asmparser_instr(struct asm_parser *This, DWORD opcode,
     }
 }
 
+/* Checks if the source modifier is not supported in VS (all versions) or
+   PS 2.0 and newer */
+static void check_legacy_srcmod(struct asm_parser *This, DWORD srcmod) {
+    if(srcmod == BWRITERSPSM_BIAS || srcmod == BWRITERSPSM_BIASNEG ||
+       srcmod == BWRITERSPSM_SIGN || srcmod == BWRITERSPSM_SIGNNEG ||
+       srcmod == BWRITERSPSM_COMP || srcmod == BWRITERSPSM_X2 ||
+       srcmod == BWRITERSPSM_X2NEG || srcmod == BWRITERSPSM_DZ ||
+       srcmod == BWRITERSPSM_DW) {
+        asmparser_message(This, "Line %u: Source modifier %s not supported in this shader version\n",
+                          This->line_no,
+                          debug_print_srcmod(srcmod));
+        set_parse_status(This, PARSE_ERR);
+    }
+}
+
+static void check_loop_swizzle(struct asm_parser *This,
+                               const struct shader_reg *src) {
+    if((src->type == BWRITERSPR_LOOP && src->swizzle != BWRITERVS_NOSWIZZLE) ||
+       (src->rel_reg && src->rel_reg->type == BWRITERSPR_LOOP &&
+        src->rel_reg->swizzle != BWRITERVS_NOSWIZZLE)) {
+        asmparser_message(This, "Line %u: Swizzle not allowed on aL register\n", This->line_no);
+        set_parse_status(This, PARSE_ERR);
+    }
+}
+
+struct allowed_reg_type {
+    DWORD type;
+    DWORD count;
+};
+
+static BOOL check_reg_type(const struct shader_reg *reg,
+                           const struct allowed_reg_type *allowed) {
+    unsigned int i = 0;
+
+    while(allowed[i].type != ~0U) {
+        if(reg->type == allowed[i].type) {
+            if(reg->rel_reg) return TRUE; /* The relative addressing register
+                                             can have a negative value, we
+                                             can't check the register index */
+            if(reg->regnum < allowed[i].count) return TRUE;
+            else return FALSE;
+        }
+        i++;
+    }
+    return FALSE;
+}
+
+struct allowed_reg_type vs_3_reg_allowed[] = {
+    { BWRITERSPR_TEMP,      32 },
+    { BWRITERSPR_INPUT,     16 },
+    { BWRITERSPR_CONST,    ~0U },
+    { BWRITERSPR_ADDR,       1 },
+    { BWRITERSPR_CONSTBOOL, 16 },
+    { BWRITERSPR_CONSTINT,  16 },
+    { BWRITERSPR_LOOP,       1 },
+    { BWRITERSPR_LABEL,   2048 },
+    { BWRITERSPR_PREDICATE,  1 },
+    { BWRITERSPR_SAMPLER,    4 },
+    { BWRITERSPR_OUTPUT,    12 },
+    { ~0U, 0 } /* End tag */
+};
+
+static void asmparser_srcreg_vs_3(struct asm_parser *This,
+                                  struct instruction *instr, int num,
+                                  const struct shader_reg *src) {
+    if(!check_reg_type(src, vs_3_reg_allowed)) {
+        asmparser_message(This, "Line %u: Source register %s not supported in VS 3.0\n",
+                          This->line_no,
+                          debug_print_srcreg(src, ST_VERTEX));
+        set_parse_status(This, PARSE_ERR);
+    }
+    check_loop_swizzle(This, src);
+    check_legacy_srcmod(This, src->srcmod);
+    memcpy(&instr->src[num], src, sizeof(*src));
+}
+
+struct allowed_reg_type ps_3_reg_allowed[] = {
+    { BWRITERSPR_INPUT,     10 },
+    { BWRITERSPR_TEMP,      32 },
+    { BWRITERSPR_CONST,    224 },
+    { BWRITERSPR_CONSTINT,  16 },
+    { BWRITERSPR_CONSTBOOL, 16 },
+    { BWRITERSPR_PREDICATE,  1 },
+    { BWRITERSPR_SAMPLER,   16 },
+    { BWRITERSPR_MISCTYPE,   2 }, /* vPos and vFace */
+    { BWRITERSPR_LOOP,       1 },
+    { BWRITERSPR_LABEL,   2048 },
+    { BWRITERSPR_COLOROUT, ~0U },
+    { BWRITERSPR_DEPTHOUT,   1 },
+    { ~0U, 0 } /* End tag */
+};
+
+static void asmparser_srcreg_ps_3(struct asm_parser *This,
+                                  struct instruction *instr, int num,
+                                  const struct shader_reg *src) {
+    if(!check_reg_type(src, ps_3_reg_allowed)) {
+        asmparser_message(This, "Line %u: Source register %s not supported in PS 3.0\n",
+                          This->line_no,
+                          debug_print_srcreg(src, ST_PIXEL));
+        set_parse_status(This, PARSE_ERR);
+    }
+    check_loop_swizzle(This, src);
+    check_legacy_srcmod(This, src->srcmod);
+    memcpy(&instr->src[num], src, sizeof(*src));
+}
+
+static void asmparser_dstreg_vs_3(struct asm_parser *This,
+                                  struct instruction *instr,
+                                  const struct shader_reg *dst) {
+    if(!check_reg_type(dst, vs_3_reg_allowed)) {
+        asmparser_message(This, "Line %u: Destination register %s not supported in VS 3.0\n",
+                          This->line_no,
+                          debug_print_dstreg(dst, ST_VERTEX));
+        set_parse_status(This, PARSE_ERR);
+    }
+    memcpy(&instr->dst, dst, sizeof(*dst));
+    instr->has_dst = TRUE;
+}
+
+static void asmparser_dstreg_ps_3(struct asm_parser *This,
+                                  struct instruction *instr,
+                                  const struct shader_reg *dst) {
+    if(!check_reg_type(dst, ps_3_reg_allowed)) {
+        asmparser_message(This, "Line %u: Destination register %s not supported in PS 3.0\n",
+                          This->line_no,
+                          debug_print_dstreg(dst, ST_PIXEL));
+        set_parse_status(This, PARSE_ERR);
+    }
+    memcpy(&instr->dst, dst, sizeof(*dst));
+    instr->has_dst = TRUE;
+}
+
+static void asmparser_predicate_supported(struct asm_parser *This,
+                                          const struct shader_reg *predicate) {
+    /* this sets the predicate of the last instruction added to the shader */
+    if(!This->shader) return;
+    if(This->shader->num_instrs == 0){
+        asmparser_message(This, "Line %u: Predicate on the first shader instruction\n", This->line_no);
+        set_parse_status(This, PARSE_ERR);
+        return;
+    }
+    This->shader->instr[This->shader->num_instrs-1]->has_predicate = TRUE;
+    memcpy(&This->shader->instr[This->shader->num_instrs-1]->predicate, predicate, sizeof(*predicate));
+}
+
+static void asmparser_coissue_unsupported(struct asm_parser *This) {
+    asmparser_message(This, "Line %u: Coissue is only supported in pixel shaders versions <= 1.4\n", This->line_no);
+    set_parse_status(This, PARSE_ERR);
+}
+
+static struct asmparser_backend parser_vs_3 = {
+    asmparser_constF,
+    asmparser_constI,
+    asmparser_constB,
+
+    asmparser_dstreg_vs_3,
+    asmparser_srcreg_vs_3,
+
+    asmparser_predicate_supported,
+    asmparser_coissue_unsupported,
+
+    asmparser_dcl_output,
+    asmparser_dcl_input,
+    asmparser_dcl_sampler,
+
+    asmparser_end,
+
+    asmparser_instr,
+};
+
+static struct asmparser_backend parser_ps_3 = {
+    asmparser_constF,
+    asmparser_constI,
+    asmparser_constB,
+
+    asmparser_dstreg_ps_3,
+    asmparser_srcreg_ps_3,
+
+    asmparser_predicate_supported,
+    asmparser_coissue_unsupported,
+
+    asmparser_dcl_output,
+    asmparser_dcl_input,
+    asmparser_dcl_sampler,
+
+    asmparser_end,
+
+    asmparser_instr,
+};
+
+void create_vs30_parser(struct asm_parser *ret) {
+    TRACE_(parsed_shader)("vs_3_0\n");
+
+    ret->shader = asm_alloc(sizeof(*ret->shader));
+    if(!ret->shader) {
+        ERR("Failed to allocate memory for the shader\n");
+        set_parse_status(ret, PARSE_ERR);
+        return;
+    }
+
+    ret->shader->type = ST_VERTEX;
+    ret->shader->version = BWRITERVS_VERSION(3, 0);
+    ret->funcs = &parser_vs_3;
+}
+
+void create_ps30_parser(struct asm_parser *ret) {
+    TRACE_(parsed_shader)("ps_3_0\n");
+
+    ret->shader = asm_alloc(sizeof(*ret->shader));
+    if(!ret->shader) {
+        ERR("Failed to allocate memory for the shader\n");
+        set_parse_status(ret, PARSE_ERR);
+        return;
+    }
+
+    ret->shader->type = ST_PIXEL;
+    ret->shader->version = BWRITERPS_VERSION(3, 0);
+    ret->funcs = &parser_ps_3;
+}
diff --git a/dlls/d3dx9_36/asmshader.y b/dlls/d3dx9_36/asmshader.y
index 6e2f78e..fe2e204 100644
--- a/dlls/d3dx9_36/asmshader.y
+++ b/dlls/d3dx9_36/asmshader.y
@@ -320,7 +320,7 @@ version_marker:       VER_VS10
                     | VER_VS30
                         {
                             TRACE("Vertex shader 3.0\n");
-                            /* TODO: create the appropriate parser context */
+                            create_vs30_parser(ctx);
                         }
                     | VER_PS10
                         {
@@ -360,7 +360,7 @@ version_marker:       VER_VS10
                     | VER_PS30
                         {
                             TRACE("Pixel  shader 3.0\n");
-                            /* TODO: create the appropriate parser context */
+                            create_ps30_parser(ctx);
                         }
 
 instructions:         /* empty */
diff --git a/dlls/d3dx9_36/bytecodewriter.c b/dlls/d3dx9_36/bytecodewriter.c
index abdb78a..665d1db 100644
--- a/dlls/d3dx9_36/bytecodewriter.c
+++ b/dlls/d3dx9_36/bytecodewriter.c
@@ -489,6 +489,19 @@ static void write_constI(const struct bwriter_shader *shader, struct bytecode_bu
     }
 }
 
+static void sm_2_opcode(struct bc_writer *This,
+                        const struct instruction *instr,
+                        DWORD token, struct bytecode_buffer *buffer) {
+    /* 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);
+    if(instr->has_predicate)
+        token |= D3DSHADER_INSTRUCTION_PREDICATED;
+    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);
@@ -509,6 +522,246 @@ static void write_samplers(const struct bwriter_shader *shader, struct bytecode_
     }
 }
 
+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_constF(shader, buffer, TRUE);
+    write_constB(shader, buffer, TRUE);
+    write_constI(shader, buffer, TRUE);
+    write_samplers(shader, buffer);
+    return;
+}
+
+static void sm_3_srcreg(struct bc_writer *This,
+                        const struct shader_reg *reg,
+                        struct bytecode_buffer *buffer) {
+    DWORD token = (1 << 31); /* Bit 31 of registers is 1 */
+    DWORD d3d9reg;
+
+    d3d9reg = d3d9_register(reg->type);
+    token |= (d3d9reg << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
+    token |= (d3d9reg << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2;
+    token |= reg->regnum & D3DSP_REGNUM_MASK;
+
+    token |= d3d9_swizzle(reg->swizzle) & D3DVS_SWIZZLE_MASK;
+    token |= d3d9_srcmod(reg->srcmod);
+
+    if(reg->rel_reg) {
+        if(reg->type == BWRITERSPR_CONST && This->version == BWRITERPS_VERSION(3, 0)){
+            WARN("c%u[...] is unsupported in ps_3_0\n", reg->regnum);
+            This->state = E_INVALIDARG;
+            return;
+        }
+        if(((reg->rel_reg->type == BWRITERSPR_ADDR && This->version == BWRITERVS_VERSION(3, 0)) ||
+           reg->rel_reg->type == BWRITERSPR_LOOP) &&
+           reg->rel_reg->regnum == 0) {
+            token |= D3DVS_ADDRMODE_RELATIVE & D3DVS_ADDRESSMODE_MASK;
+        } else {
+            WARN("Unsupported relative addressing register\n");
+            This->state = E_INVALIDARG;
+            return;
+        }
+    }
+
+    put_dword(buffer, token);
+
+    /* vs_2_0 and newer write the register containing the index explicitly in the
+     * binary code
+     */
+    if(token & D3DVS_ADDRMODE_RELATIVE) {
+        sm_3_srcreg(This, reg->rel_reg, buffer);
+    }
+}
+
+static void sm_3_dstreg(struct bc_writer *This,
+                        const struct shader_reg *reg,
+                        struct bytecode_buffer *buffer,
+                        DWORD shift, DWORD mod) {
+    DWORD token = (1 << 31); /* Bit 31 of registers is 1 */
+    DWORD d3d9reg;
+
+    if(reg->rel_reg){
+        if(This->version == BWRITERVS_VERSION(3, 0) &&
+           reg->type == BWRITERSPR_OUTPUT) {
+            token |= D3DVS_ADDRMODE_RELATIVE & D3DVS_ADDRESSMODE_MASK;
+        }
+        else {
+            WARN("Relative addressing not supported for this shader type or register type\n");
+            This->state = E_INVALIDARG;
+            return;
+        }
+    }
+
+    d3d9reg = d3d9_register(reg->type);
+    token |= (d3d9reg << D3DSP_REGTYPE_SHIFT) & D3DSP_REGTYPE_MASK;
+    token |= (d3d9reg << D3DSP_REGTYPE_SHIFT2) & D3DSP_REGTYPE_MASK2;
+    token |= reg->regnum & D3DSP_REGNUM_MASK; /* No shift */
+
+    token |= (shift << D3DSP_DSTSHIFT_SHIFT) & D3DSP_DSTSHIFT_MASK;
+    token |= d3d9_dstmod(mod);
+
+    token |= d3d9_writemask(reg->writemask);
+    put_dword(buffer, token);
+
+    /* vs_2_0 and newer write the register containing the index explicitly in the
+     * binary code
+     */
+    if(token & D3DVS_ADDRMODE_RELATIVE) {
+        sm_3_srcreg(This, reg->rel_reg, buffer);
+    }
+}
+
+struct instr_handler_table vs_3_handlers[] = {
+    {BWRITERSIO_ADD,            instr_handler},
+    {BWRITERSIO_NOP,            instr_handler},
+    {BWRITERSIO_MOV,            instr_handler},
+    {BWRITERSIO_SUB,            instr_handler},
+    {BWRITERSIO_MAD,            instr_handler},
+    {BWRITERSIO_MUL,            instr_handler},
+    {BWRITERSIO_RCP,            instr_handler},
+    {BWRITERSIO_RSQ,            instr_handler},
+    {BWRITERSIO_DP3,            instr_handler},
+    {BWRITERSIO_DP4,            instr_handler},
+    {BWRITERSIO_MIN,            instr_handler},
+    {BWRITERSIO_MAX,            instr_handler},
+    {BWRITERSIO_SLT,            instr_handler},
+    {BWRITERSIO_SGE,            instr_handler},
+    {BWRITERSIO_ABS,            instr_handler},
+    {BWRITERSIO_EXP,            instr_handler},
+    {BWRITERSIO_LOG,            instr_handler},
+    {BWRITERSIO_EXPP,           instr_handler},
+    {BWRITERSIO_LOGP,           instr_handler},
+    {BWRITERSIO_DST,            instr_handler},
+    {BWRITERSIO_LRP,            instr_handler},
+    {BWRITERSIO_FRC,            instr_handler},
+    {BWRITERSIO_CRS,            instr_handler},
+    {BWRITERSIO_SGN,            instr_handler},
+    {BWRITERSIO_NRM,            instr_handler},
+    {BWRITERSIO_SINCOS,         instr_handler},
+    {BWRITERSIO_M4x4,           instr_handler},
+    {BWRITERSIO_M4x3,           instr_handler},
+    {BWRITERSIO_M3x4,           instr_handler},
+    {BWRITERSIO_M3x3,           instr_handler},
+    {BWRITERSIO_M3x2,           instr_handler},
+    {BWRITERSIO_LIT,            instr_handler},
+    {BWRITERSIO_POW,            instr_handler},
+    {BWRITERSIO_MOVA,           instr_handler},
+
+    {BWRITERSIO_CALL,           instr_handler},
+    {BWRITERSIO_CALLNZ,         instr_handler},
+    {BWRITERSIO_REP,            instr_handler},
+    {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},
+
+    {BWRITERSIO_SETP,           instr_handler},
+    {BWRITERSIO_BREAKP,         instr_handler},
+    {BWRITERSIO_TEXLDL,         instr_handler},
+
+    {BWRITERSIO_END,            NULL},
+};
+
+static struct bytecode_backend vs_3_backend = {
+    sm_3_header,
+    end,
+    sm_3_srcreg,
+    sm_3_dstreg,
+    sm_2_opcode,
+    vs_3_handlers
+};
+
+struct instr_handler_table ps_3_handlers[] = {
+    {BWRITERSIO_ADD,            instr_handler},
+    {BWRITERSIO_NOP,            instr_handler},
+    {BWRITERSIO_MOV,            instr_handler},
+    {BWRITERSIO_SUB,            instr_handler},
+    {BWRITERSIO_MAD,            instr_handler},
+    {BWRITERSIO_MUL,            instr_handler},
+    {BWRITERSIO_RCP,            instr_handler},
+    {BWRITERSIO_RSQ,            instr_handler},
+    {BWRITERSIO_DP3,            instr_handler},
+    {BWRITERSIO_DP4,            instr_handler},
+    {BWRITERSIO_MIN,            instr_handler},
+    {BWRITERSIO_MAX,            instr_handler},
+    {BWRITERSIO_ABS,            instr_handler},
+    {BWRITERSIO_EXP,            instr_handler},
+    {BWRITERSIO_LOG,            instr_handler},
+    {BWRITERSIO_EXPP,           instr_handler},
+    {BWRITERSIO_LOGP,           instr_handler},
+    {BWRITERSIO_LRP,            instr_handler},
+    {BWRITERSIO_FRC,            instr_handler},
+    {BWRITERSIO_CRS,            instr_handler},
+    {BWRITERSIO_NRM,            instr_handler},
+    {BWRITERSIO_SINCOS,         instr_handler},
+    {BWRITERSIO_M4x4,           instr_handler},
+    {BWRITERSIO_M4x3,           instr_handler},
+    {BWRITERSIO_M3x4,           instr_handler},
+    {BWRITERSIO_M3x3,           instr_handler},
+    {BWRITERSIO_M3x2,           instr_handler},
+    {BWRITERSIO_POW,            instr_handler},
+    {BWRITERSIO_DP2ADD,         instr_handler},
+    {BWRITERSIO_CMP,            instr_handler},
+
+    {BWRITERSIO_CALL,           instr_handler},
+    {BWRITERSIO_CALLNZ,         instr_handler},
+    {BWRITERSIO_REP,            instr_handler},
+    {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},
+
+    {BWRITERSIO_SETP,           instr_handler},
+    {BWRITERSIO_BREAKP,         instr_handler},
+    {BWRITERSIO_TEXLDL,         instr_handler},
+
+    {BWRITERSIO_TEX,            instr_handler},
+    {BWRITERSIO_TEX | ( BWRITERSI_TEXLD_PROJECT << BWRITER_OPCODESPECIFICCONTROL_SHIFT ),                       instr_handler},
+    {BWRITERSIO_TEX | ( BWRITERSI_TEXLD_BIAS << BWRITER_OPCODESPECIFICCONTROL_SHIFT ),                          instr_handler},
+    {BWRITERSIO_TEXKILL,        instr_handler},
+    {BWRITERSIO_DSX,            instr_handler},
+    {BWRITERSIO_DSY,            instr_handler},
+    {BWRITERSIO_TEXLDD,         instr_handler},
+
+    {BWRITERSIO_END,            NULL},
+};
+
+static struct bytecode_backend ps_3_backend = {
+    sm_3_header,
+    end,
+    sm_3_srcreg,
+    sm_3_dstreg,
+    sm_2_opcode,
+    ps_3_handlers
+};
+
+static void init_vs30_dx9_writer(struct bc_writer *writer) {
+    TRACE("Creating DirectX9 vertex shader 3.0 writer\n");
+    writer->funcs = &vs_3_backend;
+}
+
+static void init_ps30_dx9_writer(struct bc_writer *writer) {
+    TRACE("Creating DirectX9 pixel shader 3.0 writer\n");
+    writer->funcs = &ps_3_backend;
+}
+
 static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
     struct bc_writer *ret = asm_alloc(sizeof(*ret));
 
@@ -551,7 +804,7 @@ static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
                 WARN("Unsupported dxversion for vertex shader 3.0 requested: %u\n", dxversion);
                 goto fail;
             }
-            /* TODO: Set the appropriate writer backend */
+            init_vs30_dx9_writer(ret);
             break;
 
         case BWRITERPS_VERSION(1, 0):
@@ -611,7 +864,7 @@ static struct bc_writer *create_writer(DWORD version, DWORD dxversion) {
                 WARN("Unsupported dxversion for pixel shader 3.0 requested: %u\n", dxversion);
                 goto fail;
             }
-            /* TODO: Set the appropriate writer backend */
+            init_ps30_dx9_writer(ret);
             break;
 
         default:
-- 
1.6.3.3


More information about the wine-patches mailing list