From: Zebediah Figura Subject: [PATCH vkd3d v2 1/3] vkd3d: Move the ID3DBlob implementation to vkd3d-shader. Message-Id: <20200922223430.186685-1-zfigura@codeweavers.com> Date: Tue, 22 Sep 2020 17:34:28 -0500 Signed-off-by: Zebediah Figura --- v2: Add missing documentation for "blob" output parameter; don't use \ref for parameters. include/vkd3d_shader.h | 46 +++++++ libs/vkd3d-shader/vkd3d_shader.map | 1 + libs/vkd3d-shader/vkd3d_shader_main.c | 122 ++++++++++++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 1 + libs/vkd3d/vkd3d_main.c | 150 ++--------------------- 5 files changed, 182 insertions(+), 138 deletions(-) diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 3efd355f..4e32af0e 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -23,6 +23,11 @@ #include #include +#ifndef VKD3D_NO_WIN32_TYPES +# include +# include +#endif /* VKD3D_NO_WIN32_TYPES */ + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -1150,6 +1155,12 @@ static inline uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_com | ((w & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(3)); } +/** + * Type of a callback function used to free blob data. This function is passed + * to vkd3d_shader_create_blob(). + */ +typedef void (*PFN_vkd3d_shader_free_blob_data)(void *); + #ifndef VKD3D_SHADER_NO_PROTOTYPES /** @@ -1446,6 +1457,35 @@ struct vkd3d_shader_signature_element *vkd3d_shader_find_signature_element( */ void vkd3d_shader_free_shader_signature(struct vkd3d_shader_signature *signature); +/* 1.3 */ + +/** + * Create a blob object which contains the given data. The object returns + * \a buffer from ID3DBlob::GetBufferPointer(), and \a size from + * ID3DBlob::GetBufferSize(). The contents of \a buffer are allowed to be + * mutable. + * + * The blob object exposes the ID3D10Blob COM interface, and will be destroyed + * upon the final call to IUnknown::Release(). At this point, the + * \a pfn_free_data function will be called, with \a free_arg as an argument. + * + * \param buffer Data which this blob contains. + * + * \param size Size of \a buffer, in bytes. + * + * \param pfn_free_data Pointer to a callback function, which will be called + * when the blob object is destroyed. + * + * \param free_arg Argument to be passed to \a pfn_free_data. + * + * \param blob Output location for the ID3DBlob interface pointer of the newly + * created blob object. + * + * \return A member of \ref vkd3d_result. + */ +int vkd3d_shader_create_blob(void *buffer, SIZE_T size, PFN_vkd3d_shader_free_blob_data pfn_free_data, void *free_arg, + ID3DBlob **blob); + #endif /* VKD3D_SHADER_NO_PROTOTYPES */ /** Type of vkd3d_shader_get_version(). */ @@ -1495,6 +1535,12 @@ typedef struct vkd3d_shader_signature_element * (*PFN_vkd3d_shader_find_signatur /** Type of vkd3d_shader_free_shader_signature(). */ typedef void (*PFN_vkd3d_shader_free_shader_signature)(struct vkd3d_shader_signature *signature); +/* 1.3 */ + +/** Type of vkd3d_shader_create_blob(). */ +typedef int (*PFN_vkd3d_shader_create_blob)(void *buffer, SIZE_T size, PFN_vkd3d_shader_free_blob_data pfn_free_data, + void *free_arg, ID3DBlob **blob); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map index 1937131b..86aa902f 100644 --- a/libs/vkd3d-shader/vkd3d_shader.map +++ b/libs/vkd3d-shader/vkd3d_shader.map @@ -3,6 +3,7 @@ VKD3D_1_0 global: vkd3d_shader_compile; vkd3d_shader_convert_root_signature; + vkd3d_shader_create_blob; vkd3d_shader_find_signature_element; vkd3d_shader_free_messages; vkd3d_shader_free_root_signature; diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 16d895ff..3bbf2ebc 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -16,6 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#define INITGUID #include "vkd3d_shader_private.h" #include "vkd3d_version.h" @@ -1089,3 +1090,124 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( return NULL; } } + +struct d3d_blob +{ + ID3DBlob ID3DBlob_iface; + LONG refcount; + + void *buffer; + SIZE_T size; + PFN_vkd3d_shader_free_blob_data free_data; + void *free_arg; +}; + +static struct d3d_blob *impl_from_ID3DBlob(ID3DBlob *iface) +{ + return CONTAINING_RECORD(iface, struct d3d_blob, ID3DBlob_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d_blob_QueryInterface(ID3DBlob *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3DBlob) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D10Blob_AddRef(iface); + *object = iface; + return S_OK; + } + + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); + + *object = NULL; + return E_NOINTERFACE; +} + +static ULONG STDMETHODCALLTYPE d3d_blob_AddRef(ID3DBlob *iface) +{ + struct d3d_blob *blob = impl_from_ID3DBlob(iface); + ULONG refcount = InterlockedIncrement(&blob->refcount); + + TRACE("%p increasing refcount to %u.\n", blob, refcount); + + return refcount; +} + +static ULONG STDMETHODCALLTYPE d3d_blob_Release(ID3DBlob *iface) +{ + struct d3d_blob *blob = impl_from_ID3DBlob(iface); + ULONG refcount = InterlockedDecrement(&blob->refcount); + + TRACE("%p decreasing refcount to %u.\n", blob, refcount); + + if (!refcount) + { + blob->free_data(blob->free_arg); + vkd3d_free(blob); + } + + return refcount; +} + +static void * STDMETHODCALLTYPE d3d_blob_GetBufferPointer(ID3DBlob *iface) +{ + struct d3d_blob *blob = impl_from_ID3DBlob(iface); + + TRACE("iface %p.\n", iface); + + return blob->buffer; +} + +static SIZE_T STDMETHODCALLTYPE d3d_blob_GetBufferSize(ID3DBlob *iface) +{ + struct d3d_blob *blob = impl_from_ID3DBlob(iface); + + TRACE("iface %p.\n", iface); + + return blob->size; +} + +static const struct ID3D10BlobVtbl d3d_blob_vtbl = +{ + /* IUnknown methods */ + d3d_blob_QueryInterface, + d3d_blob_AddRef, + d3d_blob_Release, + /* ID3DBlob methods */ + d3d_blob_GetBufferPointer, + d3d_blob_GetBufferSize +}; + +static void d3d_blob_init(struct d3d_blob *blob, void *buffer, SIZE_T size, + PFN_vkd3d_shader_free_blob_data pfn_free_data, void *free_arg) +{ + blob->ID3DBlob_iface.lpVtbl = &d3d_blob_vtbl; + blob->refcount = 1; + + blob->buffer = buffer; + blob->size = size; + blob->free_data = pfn_free_data; + blob->free_arg = free_arg; +} + +int vkd3d_shader_create_blob(void *buffer, SIZE_T size, PFN_vkd3d_shader_free_blob_data pfn_free_data, void *free_arg, + ID3DBlob **blob) +{ + struct d3d_blob *object; + + TRACE("buffer %p, size %lu, pfn_free_data %p, free_arg %p, blob %p.\n", + buffer, size, pfn_free_data, free_arg, blob); + + if (!(object = vkd3d_malloc(sizeof(*object)))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + d3d_blob_init(object, buffer, size, pfn_free_data, free_arg); + + TRACE("Created blob object %p.\n", object); + + *blob = &object->ID3DBlob_iface; + + return VKD3D_OK; +} diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 00b2441e..ac268bcf 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -45,6 +45,7 @@ #ifndef __VKD3D_SHADER_PRIVATE_H #define __VKD3D_SHADER_PRIVATE_H +#define COBJMACROS #define NONAMELESSUNION #include "vkd3d_common.h" #include "vkd3d_memory.h" diff --git a/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/vkd3d_main.c index 327cdf88..7e92d214 100644 --- a/libs/vkd3d/vkd3d_main.c +++ b/libs/vkd3d/vkd3d_main.c @@ -423,129 +423,13 @@ HRESULT vkd3d_create_versioned_root_signature_deserializer(const void *data, SIZ &IID_ID3D12VersionedRootSignatureDeserializer, iid, deserializer); } -/* ID3DBlob */ -struct d3d_blob -{ - ID3D10Blob ID3DBlob_iface; - LONG refcount; - - void *buffer; - SIZE_T size; -}; - -static struct d3d_blob *impl_from_ID3DBlob(ID3DBlob *iface) -{ - return CONTAINING_RECORD(iface, struct d3d_blob, ID3DBlob_iface); -} - -static HRESULT STDMETHODCALLTYPE d3d_blob_QueryInterface(ID3DBlob *iface, REFIID riid, void **object) -{ - TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); - - if (IsEqualGUID(riid, &IID_ID3DBlob) - || IsEqualGUID(riid, &IID_IUnknown)) - { - ID3D10Blob_AddRef(iface); - *object = iface; - return S_OK; - } - - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); - - *object = NULL; - return E_NOINTERFACE; -} - -static ULONG STDMETHODCALLTYPE d3d_blob_AddRef(ID3DBlob *iface) -{ - struct d3d_blob *blob = impl_from_ID3DBlob(iface); - ULONG refcount = InterlockedIncrement(&blob->refcount); - - TRACE("%p increasing refcount to %u.\n", blob, refcount); - - return refcount; -} - -static ULONG STDMETHODCALLTYPE d3d_blob_Release(ID3DBlob *iface) -{ - struct d3d_blob *blob = impl_from_ID3DBlob(iface); - ULONG refcount = InterlockedDecrement(&blob->refcount); - - TRACE("%p decreasing refcount to %u.\n", blob, refcount); - - if (!refcount) - { - vkd3d_free(blob->buffer); - - vkd3d_free(blob); - } - - return refcount; -} - -static void * STDMETHODCALLTYPE d3d_blob_GetBufferPointer(ID3DBlob *iface) -{ - struct d3d_blob *blob = impl_from_ID3DBlob(iface); - - TRACE("iface %p.\n", iface); - - return blob->buffer; -} - -static SIZE_T STDMETHODCALLTYPE d3d_blob_GetBufferSize(ID3DBlob *iface) -{ - struct d3d_blob *blob = impl_from_ID3DBlob(iface); - - TRACE("iface %p.\n", iface); - - return blob->size; -} - -static const struct ID3D10BlobVtbl d3d_blob_vtbl = -{ - /* IUnknown methods */ - d3d_blob_QueryInterface, - d3d_blob_AddRef, - d3d_blob_Release, - /* ID3DBlob methods */ - d3d_blob_GetBufferPointer, - d3d_blob_GetBufferSize -}; - -static void d3d_blob_init(struct d3d_blob *blob, void *buffer, SIZE_T size) -{ - blob->ID3DBlob_iface.lpVtbl = &d3d_blob_vtbl; - blob->refcount = 1; - - blob->buffer = buffer; - blob->size = size; -} - -static HRESULT d3d_blob_create(void *buffer, SIZE_T size, struct d3d_blob **blob) -{ - struct d3d_blob *object; - - if (!(object = vkd3d_malloc(sizeof(*object)))) - return E_OUTOFMEMORY; - - d3d_blob_init(object, buffer, size); - - TRACE("Created blob object %p.\n", object); - - *blob = object; - - return S_OK; -} - HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc, D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob) { struct vkd3d_shader_versioned_root_signature_desc vkd3d_desc; struct vkd3d_shader_code dxbc; - struct d3d_blob *blob_object; + int ret, blob_ret; char *messages; - HRESULT hr; - int ret; TRACE("desc %p, version %#x, blob %p, error_blob %p.\n", desc, version, blob, error_blob); @@ -571,24 +455,20 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc, WARN("Failed to serialize root signature, vkd3d result %d.\n", ret); if (error_blob && messages) { - if (FAILED(hr = d3d_blob_create(messages, strlen(messages), &blob_object))) - ERR("Failed to create error blob, hr %#x.\n", hr); - else - *error_blob = &blob_object->ID3DBlob_iface; + if ((blob_ret = vkd3d_shader_create_blob(messages, strlen(messages), vkd3d_free, messages, error_blob)) < 0) + ERR("Failed to create error blob, vkd3d result %d.\n", blob_ret); } return hresult_from_vkd3d_result(ret); } vkd3d_shader_free_messages(messages); - if (FAILED(hr = d3d_blob_create((void *)dxbc.code, dxbc.size, &blob_object))) + if ((ret = vkd3d_shader_create_blob((void *)dxbc.code, dxbc.size, vkd3d_free, (void *)dxbc.code, blob)) < 0) { - WARN("Failed to create blob object, hr %#x.\n", hr); + WARN("Failed to create blob object, vkd3d result %d.\n", ret); vkd3d_shader_free_shader_code(&dxbc); - return hr; + return hresult_from_vkd3d_result(ret); } - *blob = &blob_object->ID3DBlob_iface; - return S_OK; } @@ -597,10 +477,8 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN { const struct vkd3d_shader_versioned_root_signature_desc *vkd3d_desc; struct vkd3d_shader_code dxbc; - struct d3d_blob *blob_object; + int ret, blob_ret; char *messages; - HRESULT hr; - int ret; TRACE("desc %p, blob %p, error_blob %p.\n", desc, blob, error_blob); @@ -619,23 +497,19 @@ HRESULT vkd3d_serialize_versioned_root_signature(const D3D12_VERSIONED_ROOT_SIGN WARN("Failed to serialize root signature, vkd3d result %d.\n", ret); if (error_blob && messages) { - if (FAILED(hr = d3d_blob_create(messages, strlen(messages), &blob_object))) - ERR("Failed to create error blob, hr %#x.\n", hr); - else - *error_blob = &blob_object->ID3DBlob_iface; + if ((blob_ret = vkd3d_shader_create_blob(messages, strlen(messages), vkd3d_free, messages, error_blob)) < 0) + ERR("Failed to create error blob, vkd3d result %d.\n", blob_ret); } return hresult_from_vkd3d_result(ret); } vkd3d_shader_free_messages(messages); - if (FAILED(hr = d3d_blob_create((void *)dxbc.code, dxbc.size, &blob_object))) + if ((ret = vkd3d_shader_create_blob((void *)dxbc.code, dxbc.size, vkd3d_free, (void *)dxbc.code, blob)) < 0) { - WARN("Failed to create blob object, hr %#x.\n", hr); + WARN("Failed to create blob object, vkd3d result %d.\n", ret); vkd3d_shader_free_shader_code(&dxbc); - return hr; + return hresult_from_vkd3d_result(ret); } - *blob = &blob_object->ID3DBlob_iface; - return S_OK; } -- 2.28.0