[v3 1/3] d3dx9: Support relative addressing in preshader.

Paul Gofman gofmanp at gmail.com
Wed Mar 29 04:37:23 CDT 2017


Signed-off-by: Paul Gofman <gofmanp at gmail.com>
---
v3:
    - Used correct offset for updating table sizes when relative addressing is used in operand. I didn't change
        table size update to update temporary register table size only, as doing so currently breaks one test. It
        is test_effect_preshader_op(), which writes instructions to the effect blob and unintentionally corrupts the 
        data past end of the preshader code being updated. This effectively results in destroying 'CTAB' for the next
        preshader in blob, so that preshader is parsed ok but it does not have input constant definition anymore, and
        thus no table sizes set from input registers definition. Still such an effect and preshader is created ok by
        native implementation, and also by our current implementation. So I presume it is better to keep the current
        logic of table size updates based on actual register access in preshader for all tables, as according to this
        test native implementation does not fail preshader creation if it access the constants outside defined input
        range.
    - Fixed comments formatting;
    - Added WARN on wrapping register index.
---
 dlls/d3dx9_36/preshader.c    | 164 ++++++++++++++++++++++++++++++++++---------
 dlls/d3dx9_36/tests/effect.c |  38 +++++-----
 2 files changed, 151 insertions(+), 51 deletions(-)

diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c
index 9aedc99..f6f595e 100644
--- a/dlls/d3dx9_36/preshader.c
+++ b/dlls/d3dx9_36/preshader.c
@@ -185,7 +185,7 @@ static const enum pres_reg_tables shad_regset2table[] =
     PRES_REGTAB_COUNT,     /* D3DXRS_SAMPLER */
 };
 
-struct d3dx_pres_operand
+struct d3dx_pres_reg
 {
     enum pres_reg_tables table;
     /* offset is component index, not register index, e. g.
@@ -193,6 +193,12 @@ struct d3dx_pres_operand
     unsigned int offset;
 };
 
+struct d3dx_pres_operand
+{
+    struct d3dx_pres_reg reg;
+    struct d3dx_pres_reg index_reg;
+};
+
 #define MAX_INPUTS_COUNT 8
 
 struct d3dx_pres_ins
@@ -368,7 +374,7 @@ static unsigned int *find_bytecode_comment(unsigned int *ptr, unsigned int count
     return NULL;
 }
 
-static unsigned int *parse_pres_arg(unsigned int *ptr, unsigned int count, struct d3dx_pres_operand *opr)
+static unsigned int *parse_pres_reg(unsigned int *ptr, struct d3dx_pres_reg *reg)
 {
     static const enum pres_reg_tables reg_table[8] =
     {
@@ -376,29 +382,46 @@ static unsigned int *parse_pres_arg(unsigned int *ptr, unsigned int count, struc
         PRES_REGTAB_OCONST, PRES_REGTAB_OBCONST, PRES_REGTAB_OICONST, PRES_REGTAB_TEMP
     };
 
-    if (count < 3)
+    if (*ptr >= ARRAY_SIZE(reg_table) || reg_table[*ptr] == PRES_REGTAB_COUNT)
     {
-        WARN("Byte code buffer ends unexpectedly.\n");
+        FIXME("Unsupported register table %#x.\n", *ptr);
         return NULL;
     }
 
-    if (*ptr)
+    reg->table = reg_table[*ptr++];
+    reg->offset = *ptr++;
+    return ptr;
+}
+
+static unsigned int *parse_pres_arg(unsigned int *ptr, unsigned int count, struct d3dx_pres_operand *opr)
+{
+    if (count < 3 || (*ptr && count < 5))
     {
-        FIXME("Relative addressing not supported yet, word %#x.\n", *ptr);
+        WARN("Byte code buffer ends unexpectedly, count %u.\n", count);
         return NULL;
     }
-    ++ptr;
 
-    if (*ptr >= ARRAY_SIZE(reg_table) || reg_table[*ptr] == PRES_REGTAB_COUNT)
+    if (*ptr)
     {
-        FIXME("Unsupported register table %#x.\n", *ptr);
-        return NULL;
+        if (*ptr != 1)
+        {
+            FIXME("Unknown relative addressing flag, word %#x.\n", *ptr);
+            return NULL;
+        }
+        ptr = parse_pres_reg(ptr + 1, &opr->index_reg);
+        if (!ptr)
+            return NULL;
     }
-    opr->table = reg_table[*ptr++];
-    opr->offset = *ptr++;
+    else
+    {
+        opr->index_reg.table = PRES_REGTAB_COUNT;
+        ++ptr;
+    }
+
+    ptr = parse_pres_reg(ptr, &opr->reg);
 
-    if (opr->table == PRES_REGTAB_OBCONST)
-        opr->offset /= 4;
+    if (opr->reg.table == PRES_REGTAB_OBCONST)
+        opr->reg.offset /= 4;
     return ptr;
 }
 
@@ -452,6 +475,12 @@ static unsigned int *parse_pres_ins(unsigned int *ptr, unsigned int count, struc
         ptr = p;
     }
     ptr = parse_pres_arg(ptr, count, &ins->output);
+    if (ins->output.index_reg.table != PRES_REGTAB_COUNT)
+    {
+        FIXME("Relative addressing in output register not supported.\n");
+        return NULL;
+    }
+
     return ptr;
 }
 
@@ -566,20 +595,33 @@ static void dump_arg(struct d3dx_regstore *rs, const struct d3dx_pres_operand *a
     static const char *xyzw_str = "xyzw";
     unsigned int i, table;
 
-    table = arg->table;
-    if (table == PRES_REGTAB_IMMED)
+    table = arg->reg.table;
+    if (table == PRES_REGTAB_IMMED && arg->index_reg.table == PRES_REGTAB_COUNT)
     {
         TRACE("(");
         for (i = 0; i < component_count; ++i)
             TRACE(i < component_count - 1 ? "%.16e, " : "%.16e",
-                    ((double *)rs->tables[PRES_REGTAB_IMMED])[arg->offset + i]);
+                    ((double *)rs->tables[PRES_REGTAB_IMMED])[arg->reg.offset + i]);
         TRACE(")");
     }
     else
     {
-        TRACE("%s%u.", table_symbol[table], get_reg_offset(table, arg->offset));
+        if (arg->index_reg.table == PRES_REGTAB_COUNT)
+        {
+            TRACE("%s%u.", table_symbol[table], get_reg_offset(table, arg->reg.offset));
+        }
+        else
+        {
+            unsigned int index_reg;
+
+            index_reg = get_reg_offset(arg->index_reg.table, arg->index_reg.offset);
+            TRACE("%s[%u + %s%u.%c].", table_symbol[table], get_reg_offset(table, arg->reg.offset),
+                    table_symbol[arg->index_reg.table], index_reg,
+                    xyzw_str[arg->index_reg.offset
+                    - index_reg * table_info[arg->index_reg.table].reg_component_count]);
+        }
         for (i = 0; i < component_count; ++i)
-            TRACE("%c", xyzw_str[(arg->offset + i) % 4]);
+            TRACE("%c", xyzw_str[(arg->reg.offset + i) % 4]);
     }
 }
 
@@ -697,13 +739,26 @@ static HRESULT parse_preshader(struct d3dx_preshader *pres, unsigned int *ptr, u
     for (i = 0; i < pres->ins_count; ++i)
     {
         for (j = 0; j < pres_op_info[pres->ins[i].op].input_count; ++j)
-            update_table_size(pres->regs.table_sizes, pres->ins[i].inputs[j].table,
-                    get_reg_offset(pres->ins[i].inputs[j].table,
-                    pres->ins[i].inputs[j].offset + pres->ins[i].component_count - 1));
+        {
+            enum pres_reg_tables table;
+            unsigned int reg_idx;
 
-        update_table_size(pres->regs.table_sizes, pres->ins[i].output.table,
-                get_reg_offset(pres->ins[i].output.table,
-                pres->ins[i].output.offset + pres->ins[i].component_count - 1));
+            if (pres->ins[i].inputs[j].index_reg.table == PRES_REGTAB_COUNT)
+            {
+                table = pres->ins[i].inputs[j].reg.table;
+                reg_idx = get_reg_offset(table, pres->ins[i].inputs[j].reg.offset
+                        + pres->ins[i].component_count - 1);
+            }
+            else
+            {
+                table = pres->ins[i].inputs[j].index_reg.table;
+                reg_idx = get_reg_offset(table, pres->ins[i].inputs[j].index_reg.offset);
+            }
+            update_table_size(pres->regs.table_sizes, table, reg_idx);
+        }
+        update_table_size(pres->regs.table_sizes, pres->ins[i].output.reg.table,
+                get_reg_offset(pres->ins[i].output.reg.table,
+                pres->ins[i].output.reg.offset + pres->ins[i].component_count - 1));
     }
     update_table_sizes_consts(pres->regs.table_sizes, &pres->inputs);
     if (FAILED(regstore_alloc_table(&pres->regs, PRES_REGTAB_IMMED)))
@@ -1088,18 +1143,63 @@ static HRESULT init_set_constants(struct d3dx_const_tab *const_tab, ID3DXConstan
     return ret;
 }
 
+static double exec_get_reg_value(struct d3dx_regstore *rs, enum pres_reg_tables table, unsigned int offset)
+{
+    if (!regstore_is_val_set_reg(rs, table, offset / table_info[table].reg_component_count))
+        WARN("Using uninitialized input, table %u, offset %u.\n", table, offset);
+
+    return regstore_get_double(rs, table, offset);
+}
+
 static double exec_get_arg(struct d3dx_regstore *rs, const struct d3dx_pres_operand *opr, unsigned int comp)
 {
-    if (!regstore_is_val_set_reg(rs, opr->table, (opr->offset + comp) / table_info[opr->table].reg_component_count))
-        WARN("Using uninitialized input, table %u, offset %u.\n", opr->table, opr->offset + comp);
+    unsigned int offset, base_index, reg_index, table;
+
+    table = opr->reg.table;
+
+    if (opr->index_reg.table == PRES_REGTAB_COUNT)
+        base_index = 0;
+    else
+        base_index = lrint(exec_get_reg_value(rs, opr->index_reg.table, opr->index_reg.offset));
+
+    /* '4' is used instead of reg_component_count, as immediate constants (which have
+     *  reg_component_count of 1) are still indexed as 4 values according to the tests. */
+    offset = base_index * 4 + opr->reg.offset + comp;
+    reg_index = offset / table_info[table].reg_component_count;
+
+    if (reg_index >= rs->table_sizes[table])
+    {
+        unsigned int wrap_size;
+
+        if (table == PRES_REGTAB_CONST)
+        {
+            /* As it can be guessed from tests, offset into floating constant table is wrapped
+             * to the nearest power of 2 and not to the actual table size. */
+            for (wrap_size = 1; wrap_size < rs->table_sizes[table]; wrap_size <<= 1)
+                ;
+        }
+        else
+        {
+            wrap_size = rs->table_sizes[table];
+        }
+        WARN("Wrapping register index %u, table %u, wrap_size %u, table size %u.\n",
+                reg_index, table, wrap_size, rs->table_sizes[table]);
+        reg_index %= wrap_size;
+
+        if (reg_index >= rs->table_sizes[table])
+            return 0.0;
+
+        offset = reg_index * table_info[table].reg_component_count
+                + offset % table_info[table].reg_component_count;
+    }
 
-    return regstore_get_double(rs, opr->table, opr->offset + comp);
+    return exec_get_reg_value(rs, table, offset);
 }
 
-static void exec_set_arg(struct d3dx_regstore *rs, const struct d3dx_pres_operand *opr,
+static void exec_set_arg(struct d3dx_regstore *rs, const struct d3dx_pres_reg *reg,
         unsigned int comp, double res)
 {
-    regstore_set_double(rs, opr->table, opr->offset + comp, res);
+    regstore_set_double(rs, reg->table, reg->offset + comp, res);
 }
 
 #define ARGS_ARRAY_SIZE 8
@@ -1130,7 +1230,7 @@ static HRESULT execute_preshader(struct d3dx_preshader *pres)
             res = oi->func(args, ins->component_count);
 
             /* only 'dot' instruction currently falls here */
-            exec_set_arg(&pres->regs, &ins->output, 0, res);
+            exec_set_arg(&pres->regs, &ins->output.reg, 0, res);
         }
         else
         {
@@ -1139,7 +1239,7 @@ static HRESULT execute_preshader(struct d3dx_preshader *pres)
                 for (k = 0; k < oi->input_count; ++k)
                     args[k] = exec_get_arg(&pres->regs, &ins->inputs[k], ins->scalar_op && !k ? 0 : j);
                 res = oi->func(args, ins->component_count);
-                exec_set_arg(&pres->regs, &ins->output, j, res);
+                exec_set_arg(&pres->regs, &ins->output.reg, j, res);
             }
         }
     }
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 54f5377..622a8d5 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -3971,7 +3971,7 @@ test_effect_preshader_op_expected[] =
     {"prec",   {FALSE, FALSE,  TRUE, FALSE}, {0x2b8cbccc, 0x2c0cbccc, 0xac531800, 0x00000000}},
 
     {"dotswiz", {FALSE, FALSE, FALSE, FALSE}, {0xc00ccccd, 0xc0d33334, 0xc10ccccd, 0}},
-    {"reladdr", { TRUE,  TRUE,  TRUE,  TRUE}, {0xc00ccccd, 0x40000000, 0x41a00000, 0x41500000}},
+    {"reladdr", {FALSE, FALSE, FALSE, FALSE}, {0xc00ccccd, 0x40000000, 0x41a00000, 0x41500000}},
 };
 
 enum expected_state_update
@@ -4207,7 +4207,7 @@ static void test_effect_preshader(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "SetVector failed, hr %#x.\n", hr);
 
     hr = effect->lpVtbl->BeginPass(effect, 0);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = effect->lpVtbl->BeginPass(effect, 0);
     ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
@@ -4375,7 +4375,7 @@ static void test_preshader_op(IDirect3DDevice9 *device, const DWORD *sample_effe
     }
 
     hr = effect->lpVtbl->BeginPass(effect, 0);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = IDirect3DDevice9_GetLight(device, blob_position[test->args_count].result_index, &light);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
@@ -4674,7 +4674,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = effect->lpVtbl->BeginPass(effect, 0);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     for (i = 0; i < ARRAY_SIZE(check_op_parameters); ++i)
     {
@@ -4692,7 +4692,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
         hr = effect->lpVtbl->SetValue(effect, param, &fvect, sizeof(fvect));
         ok(hr == D3D_OK, "Got result %#x.\n", hr);
         hr = effect->lpVtbl->CommitChanges(effect);
-        todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+        ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
         test_effect_preshader_op_results(device, check_op_parameters[i].state_updated,
                 check_op_parameters[i].param_name);
@@ -4710,7 +4710,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
         hr = effect->lpVtbl->SetValue(effect, param, buffer, sizeof(buffer));
         ok(hr == D3D_OK, "Got result %#x.\n", hr);
         hr = effect->lpVtbl->CommitChanges(effect);
-        todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+        ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
         test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[i].const_updated_mask,
                 check_vconsts_parameters[i].param_name);
@@ -4723,7 +4723,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetVectorArray(effect, param, &fvect, 1);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[0].const_updated_mask,
                 check_vconsts_parameters[0].param_name);
 
@@ -4735,7 +4735,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetFloat(effect, param, 92.0f);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, const_no_update_mask,
                 check_vconsts_parameters[10].param_name);
 
@@ -4748,7 +4748,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetValue(effect, param, &fvect.x, sizeof(fvect.x));
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[10].const_updated_mask,
                 check_vconsts_parameters[10].param_name);
 
@@ -4759,7 +4759,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetFloatArray(effect, param, &fvect.x, 1);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[10].const_updated_mask,
                 check_vconsts_parameters[10].param_name);
 
@@ -4771,7 +4771,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetInt(effect, param, 93);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, const_no_update_mask,
                 check_vconsts_parameters[10].param_name);
 
@@ -4782,7 +4782,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetVector(effect, param, &fvect);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[1].const_updated_mask,
                 check_vconsts_parameters[1].param_name);
 
@@ -4797,7 +4797,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetValue(effect, param, &fvect.x, sizeof(float));
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, check_vconsts_parameters[7].const_updated_mask,
                 check_vconsts_parameters[7].param_name);
 
@@ -4822,7 +4822,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetValue(effect, param, &fvect, sizeof(float) * 3);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGDENSITY, &value);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     ok(value == 0, "Unexpected fog density %g.\n", *(float *)&value);
@@ -4861,7 +4861,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetValue(effect, param, &fvect.x, sizeof(float));
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = IDirect3DDevice9_GetRenderState(device, D3DRS_FOGDENSITY, &value);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     ok(*(float *)&value == 9999.0f, "Unexpected fog density %g.\n", *(float *)&value);
@@ -4897,7 +4897,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     test_effect_preshader_clear_vconsts(device);
 
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
 
     hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
@@ -4918,7 +4918,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     ok(!vshader, "Got non NULL vshader.\n");
@@ -4928,7 +4928,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = IDirect3DDevice9_GetVertexShader(device, &vshader);
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     ok(!!vshader, "Got NULL vshader.\n");
@@ -4945,7 +4945,7 @@ static void test_effect_commitchanges(IDirect3DDevice9 *device)
     hr = effect->lpVtbl->SetValue(effect, param, ivect, sizeof(ivect));
     ok(hr == D3D_OK, "Got result %#x.\n", hr);
     hr = effect->lpVtbl->CommitChanges(effect);
-    todo_wine ok(hr == D3D_OK, "Got result %#x.\n", hr);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
     test_effect_preshader_compare_vconsts(device, NULL, NULL);
 
     hr = effect->lpVtbl->EndPass(effect);
-- 
2.9.3




More information about the wine-patches mailing list