[PATCH 4/8] wined3d: Introduce wined3d_shader_create_hs().

Józef Kucia jkucia at codeweavers.com
Tue Mar 29 05:14:54 CDT 2016


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 dlls/d3d11/d3d11_private.h     |  1 +
 dlls/d3d11/device.c            |  2 +-
 dlls/d3d11/shader.c            | 84 ++++++++++++++++++++++++++++++++++++++----
 dlls/wined3d/shader.c          | 41 ++++++++++++++++++++-
 dlls/wined3d/shader_sm4.c      | 10 +++--
 dlls/wined3d/wined3d.spec      |  1 +
 dlls/wined3d/wined3d_private.h |  1 +
 include/wine/wined3d.h         |  2 +
 8 files changed, 129 insertions(+), 13 deletions(-)

diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h
index e743598..b4614c0 100644
--- a/dlls/d3d11/d3d11_private.h
+++ b/dlls/d3d11/d3d11_private.h
@@ -257,6 +257,7 @@ struct d3d11_hull_shader
     LONG refcount;
 
     struct wined3d_private_store private_store;
+    struct wined3d_shader *wined3d_shader;
     ID3D11Device *device;
 };
 
diff --git a/dlls/d3d11/device.c b/dlls/d3d11/device.c
index deafdf1..8a53e89 100644
--- a/dlls/d3d11/device.c
+++ b/dlls/d3d11/device.c
@@ -2182,7 +2182,7 @@ static HRESULT STDMETHODCALLTYPE d3d11_device_CreateHullShader(ID3D11Device *ifa
     struct d3d11_hull_shader *object;
     HRESULT hr;
 
-    FIXME("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p partial-stub!\n",
+    TRACE("iface %p, byte_code %p, byte_code_length %lu, class_linkage %p, shader %p.\n",
             iface, byte_code, byte_code_length, class_linkage, shader);
 
     if (class_linkage)
diff --git a/dlls/d3d11/shader.c b/dlls/d3d11/shader.c
index 0659e2a..a91bec7 100644
--- a/dlls/d3d11/shader.c
+++ b/dlls/d3d11/shader.c
@@ -517,8 +517,15 @@ static ULONG STDMETHODCALLTYPE d3d11_hull_shader_Release(ID3D11HullShader *iface
 
     if (!refcount)
     {
-        ID3D11Device_Release(shader->device);
-        HeapFree(GetProcessHeap(), 0, shader);
+        ID3D11Device *device = shader->device;
+
+        wined3d_mutex_lock();
+        wined3d_shader_decref(shader->wined3d_shader);
+        wined3d_mutex_unlock();
+
+        /* Release the device last, it may cause the wined3d device to be
+         * destroyed. */
+        ID3D11Device_Release(device);
     }
 
     return refcount;
@@ -578,20 +585,81 @@ static const struct ID3D11HullShaderVtbl d3d11_hull_shader_vtbl =
     d3d11_hull_shader_SetPrivateDataInterface,
 };
 
+static void STDMETHODCALLTYPE d3d11_hull_shader_wined3d_object_destroyed(void *parent)
+{
+    struct d3d11_hull_shader *shader = parent;
+
+    wined3d_private_store_cleanup(&shader->private_store);
+    HeapFree(GetProcessHeap(), 0, parent);
+}
+
+static const struct wined3d_parent_ops d3d11_hull_shader_wined3d_parent_ops =
+{
+    d3d11_hull_shader_wined3d_object_destroyed,
+};
+
+static HRESULT d3d11_hull_shader_init(struct d3d11_hull_shader *shader, struct d3d_device *device,
+        const void *byte_code, SIZE_T byte_code_length)
+{
+    struct wined3d_shader_signature output_signature;
+    struct wined3d_shader_signature input_signature;
+    struct d3d_shader_info shader_info;
+    struct wined3d_shader_desc desc;
+    HRESULT hr;
+
+    shader->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl;
+    shader->refcount = 1;
+    wined3d_mutex_lock();
+    wined3d_private_store_init(&shader->private_store);
+
+    shader_info.input_signature = &input_signature;
+    shader_info.output_signature = &output_signature;
+    if (FAILED(hr = shader_extract_from_dxbc(byte_code, byte_code_length, &shader_info)))
+    {
+        WARN("Failed to extract shader, hr %#x.\n", hr);
+        wined3d_private_store_cleanup(&shader->private_store);
+        wined3d_mutex_unlock();
+        return hr;
+    }
+
+    desc.byte_code = shader_info.shader_code;
+    desc.input_signature = &input_signature;
+    desc.output_signature = &output_signature;
+    desc.max_version = d3d_sm_from_feature_level(device->feature_level);
+
+    hr = wined3d_shader_create_hs(device->wined3d_device, &desc, shader,
+            &d3d11_hull_shader_wined3d_parent_ops, &shader->wined3d_shader);
+    shader_free_signature(&input_signature);
+    shader_free_signature(&output_signature);
+    if (FAILED(hr))
+    {
+        WARN("Failed to create wined3d hull shader, hr %#x.\n", hr);
+        wined3d_private_store_cleanup(&shader->private_store);
+        wined3d_mutex_unlock();
+        return E_INVALIDARG;
+    }
+    wined3d_mutex_unlock();
+
+    shader->device = &device->ID3D11Device_iface;
+    ID3D11Device_AddRef(shader->device);
+
+    return S_OK;
+}
+
 HRESULT d3d11_hull_shader_create(struct d3d_device *device, const void *byte_code, SIZE_T byte_code_length,
         struct d3d11_hull_shader **shader)
 {
     struct d3d11_hull_shader *object;
+    HRESULT hr;
 
     if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
         return E_OUTOFMEMORY;
 
-    object->ID3D11HullShader_iface.lpVtbl = &d3d11_hull_shader_vtbl;
-    object->refcount = 1;
-    wined3d_private_store_init(&object->private_store);
-
-    object->device = &device->ID3D11Device_iface;
-    ID3D11Device_AddRef(object->device);
+    if (FAILED(hr = d3d11_hull_shader_init(object, device, byte_code, byte_code_length)))
+    {
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
 
     TRACE("Created hull shader %p.\n", object);
     *shader = object;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index c0a7c78..4baa72a 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -297,10 +297,11 @@ static const struct wined3d_shader_frontend *shader_select_frontend(DWORD versio
         case WINED3D_SM4_PS:
         case WINED3D_SM4_VS:
         case WINED3D_SM4_GS:
+        case WINED3D_SM5_HS:
             return &sm4_shader_frontend;
 
         default:
-            FIXME("Unrecognised version token %#x\n", version_token);
+            FIXME("Unrecognised version token %#x.\n", version_token);
             return NULL;
     }
 }
@@ -2686,6 +2687,19 @@ static HRESULT vertexshader_init(struct wined3d_shader *shader, struct wined3d_d
     return WINED3D_OK;
 }
 
+static HRESULT hullshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
+        const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
+{
+    HRESULT hr;
+
+    if (FAILED(hr = shader_init(shader, device, desc, 0, WINED3D_SHADER_TYPE_HULL, parent, parent_ops)))
+        return hr;
+
+    shader->load_local_constsF = shader->lconst_inf_or_nan;
+
+    return WINED3D_OK;
+}
+
 static HRESULT geometryshader_init(struct wined3d_shader *shader, struct wined3d_device *device,
         const struct wined3d_shader_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
 {
@@ -3030,6 +3044,31 @@ HRESULT CDECL wined3d_shader_create_gs(struct wined3d_device *device, const stru
     return WINED3D_OK;
 }
 
+HRESULT CDECL wined3d_shader_create_hs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
+{
+    struct wined3d_shader *object;
+    HRESULT hr;
+
+    TRACE("device %p, desc %p, parent %p, parent_ops %p, shader %p.\n",
+            device, desc, parent, parent_ops, shader);
+
+    if (!(object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    if (FAILED(hr = hullshader_init(object, device, desc, parent, parent_ops)))
+    {
+        WARN("Failed to initialize hull shader, hr %#x.\n", hr);
+        HeapFree(GetProcessHeap(), 0, object);
+        return hr;
+    }
+
+    TRACE("Created hull shader %p.\n", object);
+    *shader = object;
+
+    return WINED3D_OK;
+}
+
 HRESULT CDECL wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader)
 {
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index 51110f8..5c5a2a4 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -607,9 +607,9 @@ static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d
     priv->end = *ptr;
 
     version_token = *(*ptr)++;
-    TRACE("version: 0x%08x\n", version_token);
+    TRACE("Version: 0x%08x.\n", version_token);
 
-    TRACE("token count: %u\n", **ptr);
+    TRACE("Token count: %u.\n", **ptr);
     priv->end += *(*ptr)++;
 
     switch (version_token >> 16)
@@ -626,8 +626,12 @@ static void shader_sm4_read_header(void *data, const DWORD **ptr, struct wined3d
             priv->shader_version.type = WINED3D_SHADER_TYPE_GEOMETRY;
             break;
 
+        case WINED3D_SM5_HS:
+            priv->shader_version.type = WINED3D_SHADER_TYPE_HULL;
+            break;
+
         default:
-            FIXME("Unrecognized shader type %#x\n", version_token >> 16);
+            FIXME("Unrecognized shader type %#x.\n", version_token >> 16);
     }
     priv->shader_version.major = WINED3D_SM4_VERSION_MAJOR(version_token);
     priv->shader_version.minor = WINED3D_SM4_VERSION_MINOR(version_token);
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 7c90d60..21cb0db 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -201,6 +201,7 @@
 @ cdecl wined3d_sampler_incref(ptr)
 
 @ cdecl wined3d_shader_create_gs(ptr ptr ptr ptr ptr)
+@ cdecl wined3d_shader_create_hs(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_shader_create_ps(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_shader_create_vs(ptr ptr ptr ptr ptr)
 @ cdecl wined3d_shader_decref(ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d37ea79..c7843bd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -461,6 +461,7 @@ enum wined3d_shader_rel_op
 #define WINED3D_SM4_PS  0x0000u
 #define WINED3D_SM4_VS  0x0001u
 #define WINED3D_SM4_GS  0x0002u
+#define WINED3D_SM5_HS  0x0003u
 
 /* Shader version tokens, and shader end tokens */
 #define WINED3DPS_VERSION(major, minor) ((WINED3D_SM1_PS << 16) | ((major) << 8) | (minor))
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index c681c78..cb057ab 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2375,6 +2375,8 @@ ULONG __cdecl wined3d_sampler_incref(struct wined3d_sampler *sampler);
 
 HRESULT __cdecl wined3d_shader_create_gs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
+HRESULT __cdecl wined3d_shader_create_hs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
+        void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
 HRESULT __cdecl wined3d_shader_create_ps(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
         void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_shader **shader);
 HRESULT __cdecl wined3d_shader_create_vs(struct wined3d_device *device, const struct wined3d_shader_desc *desc,
-- 
2.4.10




More information about the wine-patches mailing list