[PATCH 2/5] d3d10/effect: Implement numeric pass properties updates.

Nikolay Sivov nsivov at codeweavers.com
Thu Oct 28 02:46:36 CDT 2021


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3d10/d3d10_private.h |   9 +
 dlls/d3d10/effect.c        | 341 ++++++++++++++++++++++++++-----------
 dlls/d3d10/tests/effect.c  | 207 ++++++++++++++++++----
 3 files changed, 420 insertions(+), 137 deletions(-)

diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index 11b3b4e9482..f8e415f860b 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -95,6 +95,13 @@ struct d3d10_effect_shader_variable
     unsigned int isinline : 1;
 };
 
+struct d3d10_effect_prop_dependencies
+{
+    struct d3d10_effect_prop_dependency *entries;
+    SIZE_T count;
+    SIZE_T capacity;
+};
+
 struct d3d10_effect_sampler_desc
 {
     D3D10_SAMPLER_DESC desc;
@@ -118,6 +125,7 @@ struct d3d10_effect_state_object_variable
         ID3D10SamplerState *sampler;
         IUnknown *object;
     } object;
+    struct d3d10_effect_prop_dependencies dependencies;
 };
 
 struct d3d10_effect_resource_variable
@@ -217,6 +225,7 @@ struct d3d10_effect_pass
     char *name;
     struct d3d10_effect_annotations annotations;
 
+    struct d3d10_effect_prop_dependencies dependencies;
     struct d3d10_effect_pass_shader_desc vs;
     struct d3d10_effect_pass_shader_desc ps;
     struct d3d10_effect_pass_shader_desc gs;
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 23374fdb48f..34a5eb1b701 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -168,6 +168,27 @@ enum d3d10_effect_container_type
     D3D10_C_SAMPLER,
 };
 
+struct d3d10_effect_prop_dependency
+{
+    unsigned int id;
+    unsigned int idx;
+    unsigned int operation;
+    union
+    {
+        struct
+        {
+            struct d3d10_effect_variable *v;
+            unsigned int offset;
+        } var;
+    } u;
+};
+
+static void d3d10_effect_clear_prop_dependencies(struct d3d10_effect_prop_dependencies *d)
+{
+    heap_free(d->entries);
+    memset(d, 0, sizeof(*d));
+}
+
 static enum d3d10_effect_container_type get_var_container_type(const struct d3d10_effect_variable *v)
 {
     switch (v->type->basetype)
@@ -386,6 +407,148 @@ static const char *debug_d3d10_shader_variable_type(D3D10_SHADER_VARIABLE_TYPE t
 
 #undef WINE_D3D10_TO_STR
 
+static HRESULT d3d10_effect_variable_get_raw_value(struct d3d10_effect_variable *v,
+        void *data, unsigned int offset, unsigned int count)
+{
+    BOOL is_buffer;
+
+    is_buffer = v->type->basetype == D3D10_SVT_CBUFFER || v->type->basetype == D3D10_SVT_TBUFFER;
+
+    if (v->type->type_class == D3D10_SVC_OBJECT && !is_buffer)
+    {
+        WARN("Not supported on object variables of type %s.\n",
+                debug_d3d10_shader_variable_type(v->type->basetype));
+        return D3DERR_INVALIDCALL;
+    }
+
+    if (!is_buffer)
+    {
+        offset += v->buffer_offset;
+        v = v->buffer;
+    }
+
+    memcpy(data, v->u.buffer.local_buffer + offset, count);
+
+    return S_OK;
+}
+
+static BOOL read_float_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, float *out_data, UINT idx)
+{
+    switch (in_type)
+    {
+        case D3D10_SVT_FLOAT:
+            out_data[idx] = *(float *)&value;
+            return TRUE;
+
+        case D3D10_SVT_INT:
+            out_data[idx] = (INT)value;
+            return TRUE;
+
+        case D3D10_SVT_UINT:
+            out_data[idx] = value;
+            return TRUE;
+
+        default:
+            FIXME("Unhandled in_type %#x.\n", in_type);
+            return FALSE;
+    }
+}
+
+static BOOL read_int32_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT *out_data, UINT idx)
+{
+    switch (in_type)
+    {
+        case D3D10_SVT_FLOAT:
+            out_data[idx] = *(float *)&value;
+            return TRUE;
+
+        case D3D10_SVT_INT:
+        case D3D10_SVT_UINT:
+        case D3D10_SVT_BOOL:
+            out_data[idx] = value;
+            return TRUE;
+
+        default:
+            FIXME("Unhandled in_type %#x.\n", in_type);
+            return FALSE;
+    }
+}
+
+static BOOL read_int8_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT8 *out_data, UINT idx)
+{
+    switch (in_type)
+    {
+        case D3D10_SVT_INT:
+        case D3D10_SVT_UINT:
+            out_data[idx] = value;
+            return TRUE;
+
+        default:
+            FIXME("Unhandled in_type %#x.\n", in_type);
+            return FALSE;
+    }
+}
+
+static BOOL d3d10_effect_read_numeric_value(uint32_t value, D3D_SHADER_VARIABLE_TYPE in_type,
+        D3D_SHADER_VARIABLE_TYPE out_type, void *out_data, unsigned int out_idx)
+{
+    switch (out_type)
+    {
+        case D3D10_SVT_FLOAT:
+            return read_float_value(value, in_type, out_data, out_idx);
+        case D3D10_SVT_INT:
+        case D3D10_SVT_UINT:
+        case D3D10_SVT_BOOL:
+            return read_int32_value(value, in_type, out_data, out_idx);
+        case D3D10_SVT_UINT8:
+            return read_int8_value(value, in_type, out_data, out_idx);
+        default:
+            FIXME("Unsupported property type %u.\n", out_type);
+            return FALSE;
+    }
+}
+
+static void d3d10_effect_update_dependent_props(struct d3d10_effect_prop_dependencies *deps,
+        void *container)
+{
+    const struct d3d10_effect_state_property_info *property_info;
+    struct d3d10_effect_prop_dependency *d;
+    struct d3d10_effect_variable *v;
+    unsigned int i, j, count;
+    uint32_t value;
+    void *dst;
+
+    for (i = 0; i < deps->count; ++i)
+    {
+        d = &deps->entries[i];
+
+        property_info = &property_infos[d->id];
+
+        dst = (char *)container + property_info->offset;
+
+        switch (d->operation)
+        {
+            case D3D10_EOO_VAR:
+            case D3D10_EOO_CONST_INDEX:
+
+                v = d->u.var.v;
+
+                count = v->type->type_class == D3D10_SVC_VECTOR ? 4 : 1;
+
+                for (j = 0; j < count; ++j)
+                {
+                    d3d10_effect_variable_get_raw_value(v, &value, d->u.var.offset + j * sizeof(value), sizeof(value));
+                    d3d10_effect_read_numeric_value(value, v->type->basetype, property_info->type, dst, j);
+                }
+
+                break;
+
+            default:
+                FIXME("Unsupported property update for %u.\n", d->operation);
+        }
+    }
+}
+
 static BOOL d3d_array_reserve(void **elements, SIZE_T *capacity, SIZE_T count, SIZE_T size)
 {
     SIZE_T max_capacity, new_capacity;
@@ -1567,63 +1730,6 @@ static const struct d3d10_effect_state_storage_info *get_storage_info(D3D_SHADER
     return NULL;
 }
 
-static BOOL read_float_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, float *out_data, UINT idx)
-{
-    switch (in_type)
-    {
-        case D3D10_SVT_FLOAT:
-            out_data[idx] = *(float *)&value;
-            return TRUE;
-
-        case D3D10_SVT_INT:
-            out_data[idx] = (INT)value;
-            return TRUE;
-
-        case D3D10_SVT_UINT:
-            out_data[idx] = value;
-            return TRUE;
-
-        default:
-            FIXME("Unhandled in_type %#x.\n", in_type);
-            return FALSE;
-    }
-}
-
-static BOOL read_int32_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT *out_data, UINT idx)
-{
-    switch (in_type)
-    {
-        case D3D10_SVT_FLOAT:
-            out_data[idx] = *(float *)&value;
-            return TRUE;
-
-        case D3D10_SVT_INT:
-        case D3D10_SVT_UINT:
-        case D3D10_SVT_BOOL:
-            out_data[idx] = value;
-            return TRUE;
-
-        default:
-            FIXME("Unhandled in_type %#x.\n", in_type);
-            return FALSE;
-    }
-}
-
-static BOOL read_int8_value(DWORD value, D3D_SHADER_VARIABLE_TYPE in_type, INT8 *out_data, UINT idx)
-{
-    switch (in_type)
-    {
-        case D3D10_SVT_INT:
-        case D3D10_SVT_UINT:
-            out_data[idx] = value;
-            return TRUE;
-
-        default:
-            FIXME("Unhandled in_type %#x.\n", in_type);
-            return FALSE;
-    }
-}
-
 static BOOL read_value_list(const char *data, size_t data_size, DWORD offset,
         D3D_SHADER_VARIABLE_TYPE out_type, UINT out_base, UINT out_size, void *out_data)
 {
@@ -1663,19 +1769,11 @@ static BOOL read_value_list(const char *data, size_t data_size, DWORD offset,
         switch (out_type)
         {
             case D3D10_SVT_FLOAT:
-                if (!read_float_value(value, in_type, out_data, out_idx))
-                    return FALSE;
-                break;
-
             case D3D10_SVT_INT:
             case D3D10_SVT_UINT:
             case D3D10_SVT_BOOL:
-                if (!read_int32_value(value, in_type, out_data, out_idx))
-                    return FALSE;
-                break;
-
             case D3D10_SVT_UINT8:
-                if (!read_int8_value(value, in_type, out_data, out_idx))
+                if (!d3d10_effect_read_numeric_value(value, in_type, out_type, out_data, out_idx))
                     return FALSE;
                 break;
 
@@ -1695,6 +1793,14 @@ static BOOL read_value_list(const char *data, size_t data_size, DWORD offset,
                 *(void **)out_data = &null_shader_resource_variable;
                 break;
 
+            case D3D10_SVT_DEPTHSTENCIL:
+                *(void **)out_data = &null_depth_stencil_variable;
+                break;
+
+            case D3D10_SVT_BLEND:
+                *(void **)out_data = &null_blend_variable;
+                break;
+
             default:
                 FIXME("Unhandled out_type %#x.\n", out_type);
                 return FALSE;
@@ -1745,21 +1851,31 @@ static BOOL is_object_property_type_matching(const struct d3d10_effect_state_pro
     }
 }
 
+static HRESULT d3d10_effect_add_prop_dependency(struct d3d10_effect_prop_dependencies *d,
+        const struct d3d10_effect_prop_dependency *dep)
+{
+    if (!d3d_array_reserve((void **)&d->entries, &d->capacity, d->count + 1, sizeof(*d->entries)))
+        return E_OUTOFMEMORY;
+
+    d->entries[d->count++] = *dep;
+
+    return S_OK;
+}
+
 static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size,
         const char **ptr, enum d3d10_effect_container_type container_type,
-        struct d3d10_effect *effect, void *container)
+        struct d3d10_effect *effect, void *container, struct d3d10_effect_prop_dependencies *d)
 {
     const struct d3d10_effect_state_property_info *property_info;
+    unsigned int variable_idx, *dst_index, offset, idx, id;
     UINT value_offset, sodecl_offset, operation;
+    struct d3d10_effect_prop_dependency dep;
     struct d3d10_effect_variable *variable;
-    unsigned int variable_idx, *dst_index;
     const char *data_ptr;
     const char *name;
     size_t name_len;
     HRESULT hr;
     void *dst;
-    UINT idx;
-    UINT id;
 
     read_dword(ptr, &id);
     read_dword(ptr, &idx);
@@ -1844,8 +1960,20 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size
             }
             else
             {
-                FIXME("Assigning variables to numeric fields is not supported.\n");
-                return E_FAIL;
+                if (property_info->size * sizeof(float) > variable->type->size_unpacked)
+                {
+                    WARN("Mismatching variable size %u, property size %u.\n",
+                            variable->type->size_unpacked, property_info->size);
+                    return E_FAIL;
+                }
+
+                dep.id = id;
+                dep.idx = idx;
+                dep.operation = operation;
+                dep.u.var.v = variable;
+                dep.u.var.offset = 0;
+
+                return d3d10_effect_add_prop_dependency(d, &dep);
             }
 
             break;
@@ -1868,7 +1996,8 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size
                 return E_FAIL;
             }
 
-            TRACE("Variable name %s[%u].\n", debugstr_a(name), variable_idx);
+            TRACE("Variable name %s[%s%u].\n", debugstr_a(name), is_object_property(property_info) ?
+                    "" : "offset ", variable_idx);
 
             if (!(variable = d3d10_effect_get_variable_by_name(effect, name)))
             {
@@ -1876,15 +2005,14 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size
                 return E_FAIL;
             }
 
-            /* Has to be an array */
-            if (!variable->type->element_count || variable_idx >= variable->type->element_count)
-            {
-                WARN("Invalid array size %u.\n", variable->type->element_count);
-                return E_FAIL;
-            }
-
             if (is_object_property(property_info))
             {
+                if (!variable->type->element_count || variable_idx >= variable->type->element_count)
+                {
+                    WARN("Invalid array size %u.\n", variable->type->element_count);
+                    return E_FAIL;
+                }
+
                 if (!is_object_property_type_matching(property_info, variable))
                 {
                     WARN("Object type mismatch. Variable type %#x, property type %#x.\n",
@@ -1907,8 +2035,22 @@ static HRESULT parse_fx10_property_assignment(const char *data, size_t data_size
             }
             else
             {
-                FIXME("Assigning indexed variables to numeric fields is not supported.\n");
-                return E_FAIL;
+                offset = variable_idx * sizeof(float);
+
+                if (offset >= variable->type->size_unpacked ||
+                        variable->type->size_unpacked - offset < property_info->size * sizeof(float))
+                {
+                    WARN("Invalid numeric variable data offset %u.\n", variable_idx);
+                    return E_FAIL;
+                }
+
+                dep.id = id;
+                dep.idx = idx;
+                dep.operation = operation;
+                dep.u.var.v = variable;
+                dep.u.var.offset = offset;
+
+                return d3d10_effect_add_prop_dependency(d, &dep);
             }
 
             break;
@@ -2016,7 +2158,7 @@ static HRESULT parse_fx10_pass(const char *data, size_t data_size,
     for (i = 0; i < object_count; ++i)
     {
         if (FAILED(hr = parse_fx10_property_assignment(data, data_size, ptr,
-                D3D10_C_PASS, p->technique->effect, p)))
+                D3D10_C_PASS, p->technique->effect, p, &p->dependencies)))
         {
             WARN("Failed to parse pass assignment %u, hr %#x.\n", i, hr);
             return hr;
@@ -2385,7 +2527,8 @@ static HRESULT parse_fx10_object_variable(const char *data, size_t data_size,
                     for (j = 0; j < prop_count; ++j)
                     {
                         if (FAILED(hr = parse_fx10_property_assignment(data, data_size, ptr,
-                                get_var_container_type(var), var->effect, &var->u.state.desc)))
+                                get_var_container_type(var), var->effect, &var->u.state.desc,
+                                &var->u.state.dependencies)))
                         {
                             ERR("Failed to read property list.\n");
                             return hr;
@@ -3063,6 +3206,7 @@ static void d3d10_effect_variable_destroy(struct d3d10_effect_variable *v)
             case D3D10_SVT_SAMPLER:
                 if (v->u.state.object.object)
                     IUnknown_Release(v->u.state.object.object);
+                d3d10_effect_clear_prop_dependencies(&v->u.state.dependencies);
                 break;
 
             case D3D10_SVT_TEXTURE1D:
@@ -3106,6 +3250,7 @@ static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p)
 
     heap_free(p->name);
     d3d10_effect_annotations_destroy(&p->annotations);
+    d3d10_effect_clear_prop_dependencies(&p->dependencies);
 }
 
 static void d3d10_effect_technique_destroy(struct d3d10_effect_technique *t)
@@ -3820,6 +3965,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_GetDesc(ID3D10EffectPass *ifa
         return E_INVALIDARG;
     }
 
+    d3d10_effect_update_dependent_props(&pass->dependencies, pass);
+
     vs = d3d10_array_get_element(pass->vs.shader, pass->vs.index);
     input_signature = vs->u.shader.input_signature;
 
@@ -4105,6 +4252,8 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_pass_Apply(ID3D10EffectPass *iface
 
     if (flags) FIXME("Ignoring flags (%#x)\n", flags);
 
+    d3d10_effect_update_dependent_props(&pass->dependencies, pass);
+
     if (pass->vs.shader != &null_shader_variable)
         d3d10_effect_pass_set_shader(pass, &pass->vs);
     if (pass->gs.shader != &null_shader_variable)
@@ -4550,7 +4699,6 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectV
         void *data, UINT offset, UINT count)
 {
     struct d3d10_effect_variable *v = impl_from_ID3D10EffectVariable(iface);
-    BOOL is_buffer;
 
     TRACE("iface %p, data %p, offset %u, count %u.\n", iface, data, offset, count);
 
@@ -4560,24 +4708,7 @@ static HRESULT STDMETHODCALLTYPE d3d10_effect_variable_GetRawValue(ID3D10EffectV
         return E_FAIL;
     }
 
-    is_buffer = v->type->basetype == D3D10_SVT_CBUFFER || v->type->basetype == D3D10_SVT_TBUFFER;
-
-    if (v->type->type_class == D3D10_SVC_OBJECT && !is_buffer)
-    {
-        WARN("Not supported on object variables of type %s.\n",
-                debug_d3d10_shader_variable_type(v->type->basetype));
-        return D3DERR_INVALIDCALL;
-    }
-
-    if (!is_buffer)
-    {
-        offset += v->buffer_offset;
-        v = v->buffer;
-    }
-
-    memcpy(data, v->u.buffer.local_buffer + offset, count);
-
-    return S_OK;
+    return d3d10_effect_variable_get_raw_value(v, data, offset, count);
 }
 
 static const struct ID3D10EffectVariableVtbl d3d10_effect_variable_vtbl =
@@ -4873,6 +5004,7 @@ static BOOL get_value_as_bool(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_typ
     {
         case D3D10_SVT_FLOAT:
         case D3D10_SVT_INT:
+        case D3D10_SVT_UINT:
         case D3D10_SVT_BOOL:
             if (*(DWORD *)src_data)
                 return -1;
@@ -4893,6 +5025,7 @@ static int get_value_as_int(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_type)
             return (int)(*(float *)src_data);
 
         case D3D10_SVT_INT:
+        case D3D10_SVT_UINT:
             return *(int *)src_data;
 
         case D3D10_SVT_BOOL:
@@ -4911,6 +5044,7 @@ static float get_value_as_float(void *src_data, D3D10_SHADER_VARIABLE_TYPE src_t
             return *(float *)src_data;
 
         case D3D10_SVT_INT:
+        case D3D10_SVT_UINT:
             return (float)(*(int *)src_data);
 
         case D3D10_SVT_BOOL:
@@ -4941,6 +5075,7 @@ static void get_vector_as_type(BYTE *dst_data, D3D_SHADER_VARIABLE_TYPE dst_type
                     break;
 
                 case D3D10_SVT_INT:
+                case D3D10_SVT_UINT:
                     *(int *)dst_data_dword = get_value_as_int(src_data_dword, src_type);
                     break;
 
diff --git a/dlls/d3d10/tests/effect.c b/dlls/d3d10/tests/effect.c
index a8a64a6ed0d..b379fc7bddc 100644
--- a/dlls/d3d10/tests/effect.c
+++ b/dlls/d3d10/tests/effect.c
@@ -4843,43 +4843,32 @@ cbuffer cb
     float f0, f_a[2];
     int i0, i_a[2];
     bool b0, b_a[2];
+    uint i1, i1_a[2];
 };
 #endif
 static DWORD fx_test_scalar_variable[] =
 {
-    0x43425844, 0xe4da4aa6, 0x1380ddc5, 0x445edad5,
-    0x08581666, 0x00000001, 0x0000020b, 0x00000001,
-    0x00000024, 0x30315846, 0x000001df, 0xfeff1001,
-    0x00000001, 0x00000006, 0x00000000, 0x00000000,
-    0x00000000, 0x00000000, 0x00000000, 0x000000d3,
-    0x00000000, 0x00000000, 0x00000000, 0x00000000,
-    0x00000000, 0x00000000, 0x00000000, 0x00000000,
-    0x00000000, 0x00000000, 0x00000000, 0x66006263,
-    0x74616f6c, 0x00000700, 0x00000100, 0x00000000,
-    0x00000400, 0x00001000, 0x00000400, 0x00090900,
-    0x00306600, 0x00000007, 0x00000001, 0x00000002,
-    0x00000014, 0x00000010, 0x00000008, 0x00000909,
-    0x00615f66, 0x00746e69, 0x0000004c, 0x00000001,
-    0x00000000, 0x00000004, 0x00000010, 0x00000004,
-    0x00000911, 0x4c003069, 0x01000000, 0x02000000,
-    0x14000000, 0x10000000, 0x08000000, 0x11000000,
-    0x69000009, 0x6200615f, 0x006c6f6f, 0x0000008f,
-    0x00000001, 0x00000000, 0x00000004, 0x00000010,
-    0x00000004, 0x00000921, 0x8f003062, 0x01000000,
-    0x02000000, 0x14000000, 0x10000000, 0x08000000,
-    0x21000000, 0x62000009, 0x0400615f, 0x70000000,
-    0x00000000, 0x06000000, 0xff000000, 0x00ffffff,
-    0x29000000, 0x0d000000, 0x00000000, 0x00000000,
-    0x00000000, 0x00000000, 0x00000000, 0x48000000,
-    0x2c000000, 0x00000000, 0x10000000, 0x00000000,
-    0x00000000, 0x00000000, 0x6c000000, 0x50000000,
-    0x00000000, 0x24000000, 0x00000000, 0x00000000,
-    0x00000000, 0x8b000000, 0x6f000000, 0x00000000,
-    0x30000000, 0x00000000, 0x00000000, 0x00000000,
-    0xb0000000, 0x94000000, 0x00000000, 0x44000000,
-    0x00000000, 0x00000000, 0x00000000, 0xcf000000,
-    0xb3000000, 0x00000000, 0x50000000, 0x00000000,
-    0x00000000, 0x00000000, 0x00000000,
+    0x43425844, 0x7d97f44c, 0x1da4b110, 0xb710407e, 0x26750c1c, 0x00000001, 0x00000288, 0x00000001,
+    0x00000024, 0x30315846, 0x0000025c, 0xfeff1001, 0x00000001, 0x00000008, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000118, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x66006263,
+    0x74616f6c, 0x00000700, 0x00000100, 0x00000000, 0x00000400, 0x00001000, 0x00000400, 0x00090900,
+    0x00306600, 0x00000007, 0x00000001, 0x00000002, 0x00000014, 0x00000010, 0x00000008, 0x00000909,
+    0x00615f66, 0x00746e69, 0x0000004c, 0x00000001, 0x00000000, 0x00000004, 0x00000010, 0x00000004,
+    0x00000911, 0x4c003069, 0x01000000, 0x02000000, 0x14000000, 0x10000000, 0x08000000, 0x11000000,
+    0x69000009, 0x6200615f, 0x006c6f6f, 0x0000008f, 0x00000001, 0x00000000, 0x00000004, 0x00000010,
+    0x00000004, 0x00000921, 0x8f003062, 0x01000000, 0x02000000, 0x14000000, 0x10000000, 0x08000000,
+    0x21000000, 0x62000009, 0x7500615f, 0x00746e69, 0x000000d3, 0x00000001, 0x00000000, 0x00000004,
+    0x00000010, 0x00000004, 0x00000919, 0xd3003169, 0x01000000, 0x02000000, 0x14000000, 0x10000000,
+    0x08000000, 0x19000000, 0x69000009, 0x00615f31, 0x00000004, 0x00000090, 0x00000000, 0x00000008,
+    0xffffffff, 0x00000000, 0x00000029, 0x0000000d, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000048, 0x0000002c, 0x00000000, 0x00000010, 0x00000000, 0x00000000, 0x00000000,
+    0x0000006c, 0x00000050, 0x00000000, 0x00000024, 0x00000000, 0x00000000, 0x00000000, 0x0000008b,
+    0x0000006f, 0x00000000, 0x00000030, 0x00000000, 0x00000000, 0x00000000, 0x000000b0, 0x00000094,
+    0x00000000, 0x00000044, 0x00000000, 0x00000000, 0x00000000, 0x000000cf, 0x000000b3, 0x00000000,
+    0x00000050, 0x00000000, 0x00000000, 0x00000000, 0x000000f4, 0x000000d8, 0x00000000, 0x00000064,
+    0x00000000, 0x00000000, 0x00000000, 0x00000113, 0x000000f7, 0x00000000, 0x00000070, 0x00000000,
+    0x00000000, 0x00000000,
 };
 
 static void test_scalar_methods(ID3D10EffectScalarVariable *var, D3D10_SHADER_VARIABLE_TYPE type,
@@ -5146,6 +5135,7 @@ static void test_effect_scalar_variable(void)
         {"f0", D3D10_SVT_FLOAT},
         {"i0", D3D10_SVT_INT},
         {"b0", D3D10_SVT_BOOL},
+        {"i1", D3D10_SVT_UINT},
         {"f_a", D3D10_SVT_FLOAT, TRUE},
         {"i_a", D3D10_SVT_INT, TRUE},
         {"b_a", D3D10_SVT_BOOL, TRUE},
@@ -5178,7 +5168,7 @@ static void test_effect_scalar_variable(void)
             effect_desc.ConstantBuffers);
     ok(effect_desc.SharedConstantBuffers == 0, "Unexpected shared constant buffers count %u.\n",
             effect_desc.SharedConstantBuffers);
-    ok(effect_desc.GlobalVariables == 6, "Unexpected global variables count %u.\n",
+    ok(effect_desc.GlobalVariables == 8, "Unexpected global variables count %u.\n",
             effect_desc.GlobalVariables);
     ok(effect_desc.SharedGlobalVariables == 0, "Unexpected shared global variables count %u.\n",
             effect_desc.SharedGlobalVariables);
@@ -7638,6 +7628,154 @@ static void test_effect_raw_value(void)
     ok(!refcount, "Device has %u references left.\n", refcount);
 }
 
+#if 0
+uint i1;
+uint i1_a[2];
+float4 fv1 = {0.5f, 0.6f, 0.7f, 0.8f};
+float4 fv1_a[2] = { { 1.0f, 1.1f, 1.2f, 1.3f }, {0.1f, 0.2f, 0.3f, 0.4f} };
+int i2 = 0x123;
+int i2_a[2] = { 0x1, 0x2 };
+float f1 = 0.3f;
+
+technique10 tech
+{
+    pass P0
+    {
+        SetBlendState(NULL, fv1, i2);
+        SetDepthStencilState(NULL, i1);
+    }
+    pass P1
+    {
+        SetBlendState(NULL, fv1_a[1], i2_a[1]);
+        SetDepthStencilState(NULL, i1_a[1]);
+    }
+}
+#endif
+static DWORD fx_test_effect_dynamic_numeric_field[] =
+{
+    0x43425844, 0xc53c7634, 0x9d90c190, 0x5a0b43ea, 0x77aab553, 0x00000001, 0x000003af, 0x00000001,
+    0x00000024, 0x30315846, 0x00000383, 0xfeff1001, 0x00000001, 0x00000007, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000001, 0x00000197, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x6f6c4724,
+    0x736c6162, 0x6e697500, 0x000d0074, 0x00010000, 0x00000000, 0x00040000, 0x00100000, 0x00040000,
+    0x09190000, 0x31690000, 0x00000d00, 0x00000100, 0x00000200, 0x00001400, 0x00001000, 0x00000800,
+    0x00091900, 0x5f316900, 0x6c660061, 0x3474616f, 0x00005200, 0x00000100, 0x00000000, 0x00001000,
+    0x00001000, 0x00001000, 0x00210a00, 0x31766600, 0x00000000, 0x19999a3f, 0x3333333f, 0x4ccccd3f,
+    0x0000523f, 0x00000100, 0x00000200, 0x00002000, 0x00001000, 0x00002000, 0x00210a00, 0x31766600,
+    0x0000615f, 0xcd3f8000, 0x9a3f8ccc, 0x663f9999, 0xcd3fa666, 0xcd3dcccc, 0x9a3e4ccc, 0xcd3e9999,
+    0x693ecccc, 0xcb00746e, 0x01000000, 0x00000000, 0x04000000, 0x10000000, 0x04000000, 0x11000000,
+    0x69000009, 0x01230032, 0x00cb0000, 0x00010000, 0x00020000, 0x00140000, 0x00100000, 0x00080000,
+    0x09110000, 0x32690000, 0x0100615f, 0x02000000, 0x66000000, 0x74616f6c, 0x00011b00, 0x00000100,
+    0x00000000, 0x00000400, 0x00001000, 0x00000400, 0x00090900, 0x00316600, 0x3e99999a, 0x68636574,
+    0x00305000, 0x00000001, 0x00000002, 0x00000000, 0x00000001, 0x00000002, 0x00000000, 0xa5003150,
+    0x04000000, 0x0e000000, 0x04000001, 0x01000000, 0x02000000, 0x00000000, 0x4d000000, 0x04000000,
+    0x01000000, 0x02000000, 0x00000000, 0x04000000, 0x90000000, 0x00000000, 0x07000000, 0xff000000,
+    0x00ffffff, 0x2e000000, 0x12000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    0x4d000000, 0x31000000, 0x00000000, 0x10000000, 0x00000000, 0x00000000, 0x00000000, 0x75000000,
+    0x59000000, 0x00000000, 0x30000000, 0x79000000, 0x00000000, 0x00000000, 0xa5000000, 0x89000000,
+    0x00000000, 0x40000000, 0xab000000, 0x00000000, 0x00000000, 0xeb000000, 0xcf000000, 0x00000000,
+    0x60000000, 0xee000000, 0x00000000, 0x00000000, 0x0e000000, 0xf2000001, 0x00000000, 0x70000000,
+    0x13000000, 0x00000001, 0x00000000, 0x3d000000, 0x21000001, 0x00000001, 0x84000000, 0x40000000,
+    0x00000001, 0x00000000, 0x44000000, 0x02000001, 0x00000000, 0x49000000, 0x05000001, 0x00000000,
+    0x0a000000, 0x00000000, 0x02000000, 0x75000000, 0x0b000000, 0x00000000, 0x02000000, 0xeb000000,
+    0x02000000, 0x00000000, 0x01000000, 0x4c000000, 0x09000001, 0x00000000, 0x02000000, 0x2e000000,
+    0x01000000, 0x00000000, 0x01000000, 0x58000000, 0x64000001, 0x05000001, 0x00000000, 0x0a000000,
+    0x00000000, 0x03000000, 0x67000000, 0x0b000001, 0x00000000, 0x03000000, 0x6f000000, 0x02000001,
+    0x00000000, 0x01000000, 0x77000000, 0x09000001, 0x00000000, 0x03000000, 0x83000000, 0x01000001,
+    0x00000000, 0x01000000, 0x8b000000, 0x00000001,
+};
+
+static void test_effect_dynamic_numeric_field(void)
+{
+    ID3D10EffectScalarVariable *scalar;
+    ID3D10DepthStencilState *ds_state;
+    ID3D10BlendState *blend_state;
+    UINT stencil_ref, sample_mask;
+    ID3D10EffectTechnique *tech;
+    D3D10_PASS_DESC pass_desc;
+    ID3D10EffectVariable *v;
+    ID3D10EffectPass *pass;
+    float blend_factor[4];
+    ID3D10Effect *effect;
+    ID3D10Device *device;
+    ULONG refcount;
+    HRESULT hr;
+
+    if (!(device = create_device()))
+    {
+        skip("Failed to create device, skipping tests.\n");
+        return;
+    }
+
+    hr = create_effect(fx_test_effect_dynamic_numeric_field, 0, device, NULL, &effect);
+    ok(SUCCEEDED(hr), "Failed to create an effect, hr %#x.\n", hr);
+
+    tech = effect->lpVtbl->GetTechniqueByIndex(effect, 0);
+    ok(tech->lpVtbl->IsValid(tech), "Expected valid technique.\n");
+
+    /* Pass fields */
+    pass = tech->lpVtbl->GetPassByName(tech, "P0");
+
+    ID3D10Device_OMSetDepthStencilState(device, NULL, 0x1);
+    memset(blend_factor, 0, sizeof(blend_factor));
+    ID3D10Device_OMSetBlendState(device, NULL, blend_factor, 0);
+    hr = pass->lpVtbl->Apply(pass, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref);
+    ok(!stencil_ref, "Unexpected stencil ref value %#x.\n", stencil_ref);
+    ID3D10Device_OMGetBlendState(device, &blend_state, blend_factor, &sample_mask);
+    ok(blend_factor[0] == 0.5f, "Got unexpected blend_factor[0] %.8e.\n", blend_factor[0]);
+    ok(blend_factor[1] == 0.6f, "Got unexpected blend_factor[1] %.8e.\n", blend_factor[1]);
+    ok(blend_factor[2] == 0.7f, "Got unexpected blend_factor[2] %.8e.\n", blend_factor[2]);
+    ok(blend_factor[3] == 0.8f, "Got unexpected blend_factor[3] %.8e.\n", blend_factor[3]);
+    ok(sample_mask == 0x123, "Unexpected sample mask %#x.\n", sample_mask);
+
+    v = effect->lpVtbl->GetVariableByName(effect, "i1");
+    scalar = v->lpVtbl->AsScalar(v);
+    hr = scalar->lpVtbl->SetInt(scalar, 2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = pass->lpVtbl->Apply(pass, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref);
+    ok(stencil_ref == 0x2, "Unexpected stencil ref value %#x.\n", stencil_ref);
+
+    hr = scalar->lpVtbl->SetInt(scalar, 3);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    hr = pass->lpVtbl->GetDesc(pass, &pass_desc);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(pass_desc.StencilRef == 0x3, "Unexpected stencil ref value %#x.\n", stencil_ref);
+    ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref);
+    ok(stencil_ref == 0x2, "Unexpected stencil ref value %#x.\n", stencil_ref);
+
+    pass = tech->lpVtbl->GetPassByName(tech, "P1");
+
+    v = effect->lpVtbl->GetVariableByName(effect, "i1_a");
+    v = v->lpVtbl->GetElement(v, 1);
+    scalar = v->lpVtbl->AsScalar(v);
+    hr = scalar->lpVtbl->SetInt(scalar, 4);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    ID3D10Device_OMSetDepthStencilState(device, NULL, 0x1);
+    memset(blend_factor, 0, sizeof(blend_factor));
+    ID3D10Device_OMSetBlendState(device, NULL, blend_factor, 0);
+    hr = pass->lpVtbl->Apply(pass, 0);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ID3D10Device_OMGetDepthStencilState(device, &ds_state, &stencil_ref);
+    ok(stencil_ref == 0x4, "Unexpected stencil ref value %#x.\n", stencil_ref);
+    ID3D10Device_OMGetBlendState(device, &blend_state, blend_factor, &sample_mask);
+    ok(blend_factor[0] == 0.1f, "Got unexpected blend_factor[0] %.8e.\n", blend_factor[0]);
+    ok(blend_factor[1] == 0.2f, "Got unexpected blend_factor[1] %.8e.\n", blend_factor[1]);
+    ok(blend_factor[2] == 0.3f, "Got unexpected blend_factor[2] %.8e.\n", blend_factor[2]);
+    ok(blend_factor[3] == 0.4f, "Got unexpected blend_factor[3] %.8e.\n", blend_factor[3]);
+    ok(sample_mask == 0x2, "Unexpected sample mask %#x.\n", sample_mask);
+
+    effect->lpVtbl->Release(effect);
+
+    refcount = ID3D10Device_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
+}
+
 START_TEST(effect)
 {
     test_effect_constant_buffer_type();
@@ -7661,4 +7799,5 @@ START_TEST(effect)
     test_effect_pool();
     test_effect_default_variable_value();
     test_effect_raw_value();
+    test_effect_dynamic_numeric_field();
 }
-- 
2.33.0




More information about the wine-devel mailing list