d3d10: Parse effect shaders as anonymous shaders.
diff --git a/dlls/d3d10/d3d10_private.h b/dlls/d3d10/d3d10_private.h
index 6fa60dd..85618f5 100644
--- a/dlls/d3d10/d3d10_private.h
+++ b/dlls/d3d10/d3d10_private.h
@@ -45,6 +45,12 @@
     D3D10_EOT_GEOMETRYSHADER = 8,
 };
 
+enum d3d10_effect_object_operation
+{
+    D3D10_EOO_VALUE = 1,
+    D3D10_EOO_ANONYMOUS_SHADER = 7,
+};
+
 struct d3d10_effect_object
 {
     struct d3d10_effect_pass *pass;
@@ -105,6 +111,7 @@
     struct d3d10_effect_type *type;
     struct d3d10_effect *effect;
 
+    void *data;
     char *name;
     char *semantic;
     DWORD buffer_offset;
@@ -143,6 +150,12 @@
     struct d3d10_effect_variable *annotations;
 };
 
+struct d3d10_effect_anonymous_shader
+{
+    struct d3d10_effect_variable shader;
+    struct d3d10_effect_type type;
+};
+
 /* ID3D10Effect */
 extern const struct ID3D10EffectVtbl d3d10_effect_vtbl DECLSPEC_HIDDEN;
 struct d3d10_effect
@@ -167,11 +180,14 @@
     DWORD rendertargetview_count;
     DWORD depthstencilview_count;
     DWORD shader_call_count;
-    DWORD shader_compile_count;
+    DWORD anonymous_shader_count;
+
+    DWORD anonymous_shader_current;
 
     struct wine_rb_tree types;
     struct d3d10_effect_variable *local_buffers;
     struct d3d10_effect_variable *local_variables;
+    struct d3d10_effect_anonymous_shader *anonymous_shaders;
     struct d3d10_effect_technique *techniques;
 };
 
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 12535aa..ae757f3 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -266,43 +266,49 @@
     return S_OK;
 }
 
-static HRESULT parse_shader(struct d3d10_effect_object *o, const char *data)
+static HRESULT parse_shader(struct d3d10_effect_variable *v, const char *data)
 {
-    ID3D10Device *device = o->pass->technique->effect->device;
+    ID3D10Device *device = v->effect->device;
     struct d3d10_effect_shader_variable *s;
     const char *ptr = data;
     DWORD dxbc_size;
     HRESULT hr;
 
-    o->data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct d3d10_effect_shader_variable));
-    if (!o->data)
+    s = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*s));
+    if (!s)
     {
         ERR("Failed to allocate shader variable memory\n");
         return E_OUTOFMEMORY;
     }
 
-    if (!ptr) return S_OK;
+    v->data = s;
 
-    s = o->data;
+    if (!ptr) return S_OK;
 
     read_dword(&ptr, &dxbc_size);
     TRACE("dxbc size: %#x\n", dxbc_size);
 
-    switch (o->type)
+    switch (v->type->basetype)
     {
-        case D3D10_EOT_VERTEXSHADER:
+        case D3D10_SVT_VERTEXSHADER:
             hr = ID3D10Device_CreateVertexShader(device, ptr, dxbc_size, &s->shader.vs);
             if (FAILED(hr)) return hr;
             break;
 
-        case D3D10_EOT_PIXELSHADER:
+        case D3D10_SVT_PIXELSHADER:
             hr = ID3D10Device_CreatePixelShader(device, ptr, dxbc_size, &s->shader.ps);
             if (FAILED(hr)) return hr;
             break;
-        case D3D10_EOT_GEOMETRYSHADER:
+
+        case D3D10_SVT_GEOMETRYSHADER:
             hr = ID3D10Device_CreateGeometryShader(device, ptr, dxbc_size, &s->shader.gs);
             if (FAILED(hr)) return hr;
             break;
+
+        default:
+            ERR("This should not happen!\n");
+            return E_FAIL;
+            break;
     }
 
     return parse_dxbc(ptr, dxbc_size, shader_chunk_handler, s);
@@ -820,56 +826,140 @@
     return S_OK;
 }
 
+static HRESULT parse_fx10_anonymous_shader(struct d3d10_effect *e, struct d3d10_effect_anonymous_shader *s,
+    enum d3d10_effect_object_type otype)
+{
+    struct d3d10_effect_variable *v = &s->shader;
+    struct d3d10_effect_type *t = &s->type;
+    const char *shader = NULL;
+
+    switch (otype)
+    {
+        case D3D10_EOT_VERTEXSHADER:
+            shader = "vertexshader";
+            t->basetype = D3D10_SVT_VERTEXSHADER;
+            break;
+
+        case D3D10_EOT_PIXELSHADER:
+            shader = "pixelshader";
+            t->basetype = D3D10_SVT_PIXELSHADER;
+            break;
+
+        case D3D10_EOT_GEOMETRYSHADER:
+            shader = "geometryshader";
+            t->basetype = D3D10_SVT_GEOMETRYSHADER;
+            break;
+    }
+
+    if (!copy_name(shader, &t->name))
+    {
+        ERR("Failed to copy name.\n");
+        return E_OUTOFMEMORY;
+    }
+    TRACE("Type name: %s.\n", debugstr_a(t->name));
+
+    t->type_class = D3D10_SVC_OBJECT;
+
+    t->vtbl = &d3d10_effect_type_vtbl;
+
+    v->type = t;
+    v->effect = e;
+    set_variable_vtbl(v);
+
+    if (!copy_name("$Anonymous", &v->name))
+    {
+        ERR("Failed to copy semantic.\n");
+        return E_OUTOFMEMORY;
+    }
+    TRACE("Variable name: %s.\n", debugstr_a(v->name));
+
+    if (!copy_name(NULL, &v->semantic))
+    {
+        ERR("Failed to copy semantic.\n");
+        return E_OUTOFMEMORY;
+    }
+    TRACE("Variable semantic: %s.\n", debugstr_a(v->semantic));
+
+    return S_OK;
+}
+
 static HRESULT parse_fx10_object(struct d3d10_effect_object *o, const char **ptr, const char *data)
 {
-    const char *data_ptr;
-    DWORD offset;
+    const char *data_ptr = NULL;
+    DWORD offset, index;
+    enum d3d10_effect_object_operation operation;
     HRESULT hr;
+    struct d3d10_effect *effect = o->pass->technique->effect;
 
     read_dword(ptr, &o->type);
     TRACE("Effect object is of type %#x.\n", o->type);
 
-    skip_dword_unknown(ptr, 2);
+    read_dword(ptr, &index);
+    TRACE("Effect object index %#x.\n", index);
+
+    read_dword(ptr, &operation);
+    TRACE("Effect object operation %#x.\n", operation);
 
     read_dword(ptr, &offset);
     TRACE("Effect object idx is at offset %#x.\n", offset);
 
-    data_ptr = data + offset;
-    read_dword(&data_ptr, &offset);
-
-    TRACE("Effect object starts at offset %#x.\n", offset);
-
-    /* FIXME: This probably isn't completely correct. */
-    if (offset == 1)
+    switch(operation)
     {
-        WARN("Skipping effect object.\n");
-        data_ptr = NULL;
-    }
-    else
-    {
-        data_ptr = data + offset;
-    }
-
-    switch (o->type)
-    {
-        case D3D10_EOT_VERTEXSHADER:
-            TRACE("Vertex shader\n");
-            hr = parse_shader(o, data_ptr);
+        /* FIXME: This probably isn't completely correct. */
+        case D3D10_EOO_VALUE:
+            FIXME("Copy variable value\n");
+            hr = E_FAIL;
             break;
 
-        case D3D10_EOT_PIXELSHADER:
-            TRACE("Pixel shader\n");
-            hr = parse_shader(o, data_ptr);
-            break;
+        case D3D10_EOO_ANONYMOUS_SHADER:
+            TRACE("Anonymous shader\n");
 
-        case D3D10_EOT_GEOMETRYSHADER:
-            TRACE("Geometry shader\n");
-            hr = parse_shader(o, data_ptr);
+            /* check anonymous_shader_current for validity */
+            if (effect->anonymous_shader_current >= effect->anonymous_shader_count)
+            {
+                ERR("Anonymous shader count is wrong!\n");
+                return E_FAIL;
+            }
+
+            data_ptr = data + offset;
+            read_dword(&data_ptr, &offset);
+            TRACE("Effect object starts at offset %#x.\n", offset);
+
+            data_ptr = data + offset;
+
+            hr = parse_fx10_anonymous_shader(effect, &effect->anonymous_shaders[effect->anonymous_shader_current], o->type);
+            if (FAILED(hr)) return hr;
+
+            o->data = &effect->anonymous_shaders[effect->anonymous_shader_current].shader;
+            ++effect->anonymous_shader_current;
+
+            switch (o->type)
+            {
+                case D3D10_EOT_VERTEXSHADER:
+                    TRACE("Vertex shader\n");
+                    hr = parse_shader(o->data, data_ptr);
+                    break;
+
+                case D3D10_EOT_PIXELSHADER:
+                    TRACE("Pixel shader\n");
+                    hr = parse_shader(o->data, data_ptr);
+                    break;
+
+                case D3D10_EOT_GEOMETRYSHADER:
+                    TRACE("Geometry shader\n");
+                    hr = parse_shader(o->data, data_ptr);
+                    break;
+
+                default:
+                    FIXME("Unhandled object type %#x\n", o->type);
+                    hr = E_FAIL;
+                    break;
+            }
             break;
 
         default:
-            FIXME("Unhandled object type %#x\n", o->type);
             hr = E_FAIL;
+            FIXME("Unhandled operation %#x.\n", operation);
             break;
     }
 
@@ -1408,6 +1498,13 @@
         return E_OUTOFMEMORY;
     }
 
+    e->anonymous_shaders = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, e->anonymous_shader_count * sizeof(*e->anonymous_shaders));
+    if (!e->anonymous_shaders)
+    {
+        ERR("Failed to allocate techniques memory\n");
+        return E_OUTOFMEMORY;
+    }
+
     e->techniques = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, e->technique_count * sizeof(*e->techniques));
     if (!e->techniques)
     {
@@ -1513,8 +1610,8 @@
     read_dword(&ptr, &e->shader_call_count);
     TRACE("Shader call count: %u\n", e->shader_call_count);
 
-    read_dword(&ptr, &e->shader_compile_count);
-    TRACE("Shader compile count: %u\n", e->shader_compile_count);
+    read_dword(&ptr, &e->anonymous_shader_count);
+    TRACE("Anonymous shader count: %u\n", e->anonymous_shader_count);
 
     return parse_fx10_body(e, ptr, data_size - (ptr - data));
 }
@@ -1543,42 +1640,25 @@
     return parse_dxbc(data, data_size, fx10_chunk_handler, This);
 }
 
-static void d3d10_effect_object_destroy(struct d3d10_effect_object *o)
-{
-    TRACE("effect object %p.\n", o);
-
-    switch(o->type)
-    {
-        case D3D10_EOT_VERTEXSHADER:
-        case D3D10_EOT_PIXELSHADER:
-        case D3D10_EOT_GEOMETRYSHADER:
-            HeapFree(GetProcessHeap(), 0, ((struct d3d10_effect_shader_variable *)o->data)->input_signature);
-            break;
-
-        default:
-            break;
-    }
-    HeapFree(GetProcessHeap(), 0, o->data);
-}
-
 static HRESULT d3d10_effect_object_apply(struct d3d10_effect_object *o)
 {
     ID3D10Device *device = o->pass->technique->effect->device;
+    struct d3d10_effect_variable *v = (struct d3d10_effect_variable*) o->data;
 
     TRACE("effect object %p, type %#x.\n", o, o->type);
 
     switch(o->type)
     {
         case D3D10_EOT_VERTEXSHADER:
-            ID3D10Device_VSSetShader(device, ((struct d3d10_effect_shader_variable *)o->data)->shader.vs);
+            ID3D10Device_VSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.vs);
             return S_OK;
 
         case D3D10_EOT_PIXELSHADER:
-            ID3D10Device_PSSetShader(device, ((struct d3d10_effect_shader_variable *)o->data)->shader.ps);
+            ID3D10Device_PSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.ps);
             return S_OK;
 
         case D3D10_EOT_GEOMETRYSHADER:
-            ID3D10Device_GSSetShader(device, ((struct d3d10_effect_shader_variable *)o->data)->shader.gs);
+            ID3D10Device_GSSetShader(device, ((struct d3d10_effect_shader_variable *)v->data)->shader.gs);
             return S_OK;
 
         default:
@@ -1621,6 +1701,22 @@
         }
         HeapFree(GetProcessHeap(), 0, v->elements);
     }
+
+    if (v->data)
+    {
+        switch(v->type->basetype)
+        {
+            case D3D10_SVT_VERTEXSHADER:
+            case D3D10_SVT_PIXELSHADER:
+            case D3D10_SVT_GEOMETRYSHADER:
+                HeapFree(GetProcessHeap(), 0, ((struct d3d10_effect_shader_variable *)v->data)->input_signature);
+                break;
+
+            default:
+                break;
+        }
+        HeapFree(GetProcessHeap(), 0, v->data);
+    }
 }
 
 static void d3d10_effect_pass_destroy(struct d3d10_effect_pass *p)
@@ -1632,10 +1728,6 @@
     HeapFree(GetProcessHeap(), 0, p->name);
     if (p->objects)
     {
-        for (i = 0; i < p->object_count; ++i)
-        {
-            d3d10_effect_object_destroy(&p->objects[i]);
-        }
         HeapFree(GetProcessHeap(), 0, p->objects);
     }
 
@@ -1647,7 +1739,6 @@
         }
         HeapFree(GetProcessHeap(), 0, p->annotations);
     }
-
 }
 
 static void d3d10_effect_technique_destroy(struct d3d10_effect_technique *t)
@@ -1783,6 +1874,16 @@
             HeapFree(GetProcessHeap(), 0, This->local_buffers);
         }
 
+        if (This->anonymous_shaders)
+        {
+            for (i = 0; i < This->anonymous_shader_count; ++i)
+            {
+                d3d10_effect_variable_destroy(&This->anonymous_shaders[i].shader);
+                HeapFree(GetProcessHeap(), 0, &This->anonymous_shaders[i].type.name);
+            }
+            HeapFree(GetProcessHeap(), 0, This->anonymous_shaders);
+        }
+
         wine_rb_destroy(&This->types, d3d10_effect_type_destroy, NULL);
 
         ID3D10Device_Release(This->device);
@@ -2212,7 +2313,8 @@
         struct d3d10_effect_object *o = &This->objects[i];
         if (o->type == D3D10_EOT_VERTEXSHADER)
         {
-            struct d3d10_effect_shader_variable *s = o->data;
+            struct d3d10_effect_variable *v = o->data;
+            struct d3d10_effect_shader_variable *s = v->data;
             desc->pIAInputSignature = (BYTE *)s->input_signature;
             desc->IAInputSignatureSize = s->input_signature_size;
             break;