From afa74b5c0f1c3aeda4e529ea3b59282a834628a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3zef=20Kucia?= Date: Tue, 29 Mar 2016 12:14:54 +0200 Subject: [PATCH] wined3d: Introduce wined3d_shader_create_hs(). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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 e7435981281..b4614c0ac56 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 deafdf178c9..8a53e89f722 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 0659e2ae8ab..a91bec7bde0 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 c0a7c784ed7..4baa72aa90b 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 51110f8c100..5c5a2a4b544 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 7c90d601db2..21cb0db9c3f 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 aacf4db2c11..7bb4e094fe7 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 c681c78ffc9..cb057ab3298 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,