-- v2: d3dx9: Link versions 42 and 43 to the corresponding d3dcompiler DLL. d3dx9: Reimplement D3DXCompileShader() for versions before 42. d3dcompiler: Use D3DCompile2VKD3D() from vkd3d-utils. d3dcompiler: Use D3DPreprocess() from vkd3d-utils. vkd3d: Import vkd3d-utils.
From: Elizabeth Figura zfigura@codeweavers.com
--- configure.ac | 10 +- dlls/wined3d/wined3d_main.c | 4 +- libs/vkd3d/Makefile.in | 2 + libs/vkd3d/include/vkd3d_utils.h | 155 +++ libs/vkd3d/libs/vkd3d-utils/reflection.c | 1116 +++++++++++++++++ .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 1039 +++++++++++++++ .../libs/vkd3d-utils/vkd3d_utils_private.h | 44 + 7 files changed, 2363 insertions(+), 7 deletions(-) create mode 100644 libs/vkd3d/include/vkd3d_utils.h create mode 100644 libs/vkd3d/libs/vkd3d-utils/reflection.c create mode 100644 libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c create mode 100644 libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_private.h
diff --git a/configure.ac b/configure.ac index 6596f653fb1..45885232c55 100644 --- a/configure.ac +++ b/configure.ac @@ -1134,14 +1134,14 @@ then WINE_NOTICE([libxslt ${notice_platform}MinGW development files not found; using bundled version.]) fi
- WINE_MINGW_PACKAGE_FLAGS(VKD3D,[libvkd3d libvkd3d-shader],[-lvkd3d -lvkd3d-shader], - [WINE_CHECK_MINGW_HEADER(vkd3d.h) + WINE_MINGW_PACKAGE_FLAGS(VKD3D,[libvkd3d-utils libvkd3d libvkd3d-shader],[-lvkd3d-utils -lvkd3d -lvkd3d-shader], + [WINE_CHECK_MINGW_HEADER(vkd3d_utils.h) WINE_CHECK_MINGW_HEADER(vkd3d_shader.h) - if test "$ac_cv_mingw_header_vkd3d_h" = "yes" -a "$ac_cv_mingw_header_vkd3d_shader_h" = "yes" + if test "$ac_cv_mingw_header_vkd3d_utils_h" = "yes" -a "$ac_cv_mingw_header_vkd3d_shader_h" = "yes" then - WINE_CHECK_MINGW_LIB(vkd3d,vkd3d_set_log_callback,[:],[:],[$VKD3D_PE_LIBS]) + WINE_CHECK_MINGW_LIB(vkd3d-utils,vkd3d_utils_set_log_callback,[:],[:],[$VKD3D_PE_LIBS]) WINE_CHECK_MINGW_LIB(vkd3d-shader,vkd3d_shader_build_varying_map,[:],[:],[$VKD3D_PE_LIBS]) - if test "$ac_cv_mingw_lib_vkd3d" = "no" -o "$ac_cv_mingw_lib_vkd3d_shader" = "no" + if test "$ac_cv_mingw_lib_vkd3d_utils" = "no" -o "$ac_cv_mingw_lib_vkd3d_shader" = "no" then VKD3D_PE_CFLAGS="" VKD3D_PE_LIBS="" diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c index 3b436919559..91d8dd567ff 100644 --- a/dlls/wined3d/wined3d_main.c +++ b/dlls/wined3d/wined3d_main.c @@ -30,7 +30,7 @@ #include "d3d12.h" #define VK_NO_PROTOTYPES #include "wine/vulkan.h" -#include <vkd3d.h> +#include <vkd3d_utils.h>
WINE_DEFAULT_DEBUG_CHANNEL(d3d); WINE_DECLARE_DEBUG_CHANNEL(vkd3d); @@ -490,7 +490,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL) else putenv( "VKD3D_SHADER_DEBUG=none" ); }
- vkd3d_set_log_callback(vkd3d_log_callback); + vkd3d_utils_set_log_callback(vkd3d_log_callback);
return TRUE; } diff --git a/libs/vkd3d/Makefile.in b/libs/vkd3d/Makefile.in index b073790d986..a9d88c54eb6 100644 --- a/libs/vkd3d/Makefile.in +++ b/libs/vkd3d/Makefile.in @@ -31,6 +31,8 @@ SOURCES = \ libs/vkd3d-shader/spirv.c \ libs/vkd3d-shader/tpf.c \ libs/vkd3d-shader/vkd3d_shader_main.c \ + libs/vkd3d-utils/reflection.c \ + libs/vkd3d-utils/vkd3d_utils_main.c \ libs/vkd3d/cache.c \ libs/vkd3d/command.c \ libs/vkd3d/device.c \ diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h new file mode 100644 index 00000000000..f5bd79c8e37 --- /dev/null +++ b/libs/vkd3d/include/vkd3d_utils.h @@ -0,0 +1,155 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VKD3D_UTILS_H +#define __VKD3D_UTILS_H + +#include <vkd3d.h> +#include <d3dcompiler.h> + +#ifndef VKD3D_UTILS_API_VERSION +#define VKD3D_UTILS_API_VERSION VKD3D_API_VERSION_1_0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/** + * \file vkd3d_utils.h + * + * This file contains definitions for the vkd3d-utils library. + * + * The vkd3d-utils library is a collections of routines to ease the + * porting of a Direct3D 12 application to vkd3d. + * + * \since 1.0 + */ + +#define VKD3D_WAIT_OBJECT_0 (0) +#define VKD3D_WAIT_TIMEOUT (1) +#define VKD3D_WAIT_FAILED (~0u) +#define VKD3D_INFINITE (~0u) + +#ifdef LIBVKD3D_UTILS_SOURCE +# define VKD3D_UTILS_API VKD3D_EXPORT +#else +# define VKD3D_UTILS_API VKD3D_IMPORT +#endif + +/* 1.0 */ +VKD3D_UTILS_API HANDLE vkd3d_create_event(void); +VKD3D_UTILS_API HRESULT vkd3d_signal_event(HANDLE event); +VKD3D_UTILS_API unsigned int vkd3d_wait_event(HANDLE event, unsigned int milliseconds); +VKD3D_UTILS_API void vkd3d_destroy_event(HANDLE event); + +#if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L +# define D3D12CreateDevice(...) D3D12CreateDeviceVKD3D(__VA_ARGS__, VKD3D_UTILS_API_VERSION) +#else +# define D3D12CreateDevice(a, b, c, d) D3D12CreateDeviceVKD3D(a, b, c, d, VKD3D_UTILS_API_VERSION) +#endif +VKD3D_UTILS_API HRESULT WINAPI D3D12CreateRootSignatureDeserializer( + const void *data, SIZE_T data_size, REFIID iid, void **deserializer); +VKD3D_UTILS_API HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debug); +VKD3D_UTILS_API HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *desc, + D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob); + +/* 1.2 */ +VKD3D_UTILS_API HRESULT WINAPI D3D12CreateDeviceVKD3D(IUnknown *adapter, D3D_FEATURE_LEVEL feature_level, + REFIID iid, void **device, enum vkd3d_api_version api_version); +VKD3D_UTILS_API HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer(const void *data, + SIZE_T data_size, REFIID iid, void **deserializer); +VKD3D_UTILS_API HRESULT WINAPI D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc, + ID3DBlob **blob, ID3DBlob **error_blob); + +/* 1.3 */ +VKD3D_UTILS_API HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, + const char *target, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages); +/** + * D3DCompile2() targets the behaviour of d3dcompiler_47.dll. To target the + * behaviour of other d3dcompiler versions, use D3DCompile2VKD3D(). + * + * \since 1.3 + */ +VKD3D_UTILS_API HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, + const char *target, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, + ID3DBlob **error_messages); +VKD3D_UTILS_API HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob); +VKD3D_UTILS_API HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, + const D3D_SHADER_MACRO *defines, ID3DInclude *include, + ID3DBlob **shader, ID3DBlob **error_messages); + +/** + * Set a callback to be called when vkd3d-utils outputs debug logging. + * + * If NULL, or if this function has not been called, libvkd3d-utils will print + * all enabled log output to stderr. + * + * Calling this function will also set the log callback for libvkd3d and + * libvkd3d-shader. + * + * \param callback Callback function to set. + * + * \since 1.4 + */ +VKD3D_UTILS_API void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback); + +/** \since 1.10 */ +VKD3D_UTILS_API HRESULT WINAPI D3DGetBlobPart(const void *data, + SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob); +/** \since 1.10 */ +VKD3D_UTILS_API HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob); +/** \since 1.10 */ +VKD3D_UTILS_API HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); +/** \since 1.10 */ +VKD3D_UTILS_API HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); +/** \since 1.10 */ +VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); +/** \since 1.10 */ +VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob); + +/** \since 1.11 */ +VKD3D_UTILS_API HRESULT WINAPI D3DDisassemble(const void *data, + SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob); +/** \since 1.11 */ +VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection); + +/** + * As D3DCompile2(), but with an extra argument that allows targeting + * different d3dcompiler versions. + * + * \param compiler_version The d3dcompiler version to target. This should be + * set to the numerical value in the d3dcompiler library name. E.g. to target + * the behaviour of d3dcompiler_36.dll, set this parameter to 36. + * + * \since 1.14 + */ +VKD3D_UTILS_API HRESULT WINAPI D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, + const char *target, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, + ID3DBlob **error_messages, unsigned int compiler_version); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __VKD3D_UTILS_H */ diff --git a/libs/vkd3d/libs/vkd3d-utils/reflection.c b/libs/vkd3d/libs/vkd3d-utils/reflection.c new file mode 100644 index 00000000000..d6d9ce2a508 --- /dev/null +++ b/libs/vkd3d/libs/vkd3d-utils/reflection.c @@ -0,0 +1,1116 @@ +/* + * Copyright 2009 Henri Verbeet for CodeWeavers + * Copyright 2010 Rico Schüller + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "vkd3d_utils_private.h" +#include <d3dcommon.h> +#include <d3d12shader.h> + +struct d3d12_type +{ + ID3D12ShaderReflectionType ID3D12ShaderReflectionType_iface; + D3D12_SHADER_TYPE_DESC desc; + + struct d3d12_field *fields; +}; + +struct d3d12_field +{ + struct d3d12_type type; +}; + +struct d3d12_variable +{ + ID3D12ShaderReflectionVariable ID3D12ShaderReflectionVariable_iface; + D3D12_SHADER_VARIABLE_DESC desc; + struct d3d12_buffer *buffer; + + struct d3d12_type type; +}; + +struct d3d12_buffer +{ + ID3D12ShaderReflectionConstantBuffer ID3D12ShaderReflectionConstantBuffer_iface; + D3D12_SHADER_BUFFER_DESC desc; + + struct d3d12_variable *variables; +}; + +struct d3d12_reflection +{ + ID3D12ShaderReflection ID3D12ShaderReflection_iface; + unsigned int refcount; + + struct vkd3d_shader_scan_signature_info signature_info; + + D3D12_SHADER_DESC desc; + + struct d3d12_buffer *buffers; + + D3D12_SHADER_INPUT_BIND_DESC *bindings; +}; + +static struct d3d12_buffer null_buffer; +static struct d3d12_variable null_variable; +static struct d3d12_type null_type; + +static struct d3d12_type *impl_from_ID3D12ShaderReflectionType(ID3D12ShaderReflectionType *iface) +{ + return CONTAINING_RECORD(iface, struct d3d12_type, ID3D12ShaderReflectionType_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d12_type_GetDesc( + ID3D12ShaderReflectionType *iface, D3D12_SHADER_TYPE_DESC *desc) +{ + struct d3d12_type *type = impl_from_ID3D12ShaderReflectionType(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (type == &null_type) + { + WARN("Null type, returning E_FAIL.\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("NULL pointer, returning E_FAIL.\n"); + return E_FAIL; + } + + *desc = type->desc; + return S_OK; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3d12_type_GetMemberTypeByIndex( + ID3D12ShaderReflectionType *iface, UINT index) +{ + struct d3d12_type *type = impl_from_ID3D12ShaderReflectionType(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (index >= type->desc.Members) + { + WARN("Invalid index %u.\n", index); + return &null_type.ID3D12ShaderReflectionType_iface; + } + + return &type->fields[index].type.ID3D12ShaderReflectionType_iface; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3d12_type_GetMemberTypeByName( + ID3D12ShaderReflectionType *iface, const char *name) +{ + FIXME("iface %p, name %s, stub!\n", iface, debugstr_a(name)); + + return NULL; +} + +static const char * STDMETHODCALLTYPE d3d12_type_GetMemberTypeName( + ID3D12ShaderReflectionType *iface, UINT index) +{ + FIXME("iface %p, index %u, stub!\n", iface, index); + + return NULL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_type_IsEqual( + ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *other) +{ + FIXME("iface %p, other %p, stub!\n", iface, other); + return E_NOTIMPL; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3d12_type_GetSubType( + ID3D12ShaderReflectionType *iface) +{ + FIXME("iface %p stub!\n", iface); + + return NULL; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3d12_type_GetBaseClass( + ID3D12ShaderReflectionType *iface) +{ + FIXME("iface %p stub!\n", iface); + + return NULL; +} + +static UINT STDMETHODCALLTYPE d3d12_type_GetNumInterfaces( + ID3D12ShaderReflectionType *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3d12_type_GetInterfaceByIndex( + ID3D12ShaderReflectionType *iface, UINT index) +{ + FIXME("iface %p, index %u stub!\n", iface, index); + + return NULL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_type_IsOfType( + ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *type) +{ + FIXME("iface %p, type %p stub!\n", iface, type); + + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_type_ImplementsInterface( + ID3D12ShaderReflectionType *iface, ID3D12ShaderReflectionType *base) +{ + FIXME("iface %p, base %p stub!\n", iface, base); + + return E_NOTIMPL; +} + +static const struct ID3D12ShaderReflectionTypeVtbl d3d12_type_vtbl = +{ + d3d12_type_GetDesc, + d3d12_type_GetMemberTypeByIndex, + d3d12_type_GetMemberTypeByName, + d3d12_type_GetMemberTypeName, + d3d12_type_IsEqual, + d3d12_type_GetSubType, + d3d12_type_GetBaseClass, + d3d12_type_GetNumInterfaces, + d3d12_type_GetInterfaceByIndex, + d3d12_type_IsOfType, + d3d12_type_ImplementsInterface, +}; + +static struct d3d12_type null_type = {{&d3d12_type_vtbl}}; + +static struct d3d12_variable *impl_from_ID3D12ShaderReflectionVariable(ID3D12ShaderReflectionVariable *iface) +{ + return CONTAINING_RECORD(iface, struct d3d12_variable, ID3D12ShaderReflectionVariable_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d12_variable_GetDesc( + ID3D12ShaderReflectionVariable *iface, D3D12_SHADER_VARIABLE_DESC *desc) +{ + struct d3d12_variable *variable = impl_from_ID3D12ShaderReflectionVariable(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (variable == &null_variable) + { + WARN("Null variable, returning E_FAIL.\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("NULL pointer, returning E_FAIL.\n"); + return E_FAIL; + } + + *desc = variable->desc; + return S_OK; +} + +static ID3D12ShaderReflectionType * STDMETHODCALLTYPE d3d12_variable_GetType( + ID3D12ShaderReflectionVariable *iface) +{ + struct d3d12_variable *variable = impl_from_ID3D12ShaderReflectionVariable(iface); + + TRACE("iface %p.\n", iface); + + if (variable == &null_variable) + return &null_type.ID3D12ShaderReflectionType_iface; + + return &variable->type.ID3D12ShaderReflectionType_iface; +} + +static ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3d12_variable_GetBuffer( + ID3D12ShaderReflectionVariable *iface) +{ + struct d3d12_variable *variable = impl_from_ID3D12ShaderReflectionVariable(iface); + + TRACE("iface %p.\n", iface); + + return &variable->buffer->ID3D12ShaderReflectionConstantBuffer_iface; +} + +static UINT STDMETHODCALLTYPE d3d12_variable_GetInterfaceSlot( + ID3D12ShaderReflectionVariable *iface, UINT index) +{ + FIXME("iface %p, index %u, stub!\n", iface, index); + + return 0; +} + +static const struct ID3D12ShaderReflectionVariableVtbl d3d12_variable_vtbl = +{ + d3d12_variable_GetDesc, + d3d12_variable_GetType, + d3d12_variable_GetBuffer, + d3d12_variable_GetInterfaceSlot, +}; + +static struct d3d12_variable null_variable = {{&d3d12_variable_vtbl}}; + +static struct d3d12_buffer *impl_from_ID3D12ShaderReflectionConstantBuffer(ID3D12ShaderReflectionConstantBuffer *iface) +{ + return CONTAINING_RECORD(iface, struct d3d12_buffer, ID3D12ShaderReflectionConstantBuffer_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d12_buffer_GetDesc( + ID3D12ShaderReflectionConstantBuffer *iface, D3D12_SHADER_BUFFER_DESC *desc) +{ + struct d3d12_buffer *buffer = impl_from_ID3D12ShaderReflectionConstantBuffer(iface); + + TRACE("iface %p, desc %p.\n", iface, desc); + + if (buffer == &null_buffer) + { + WARN("Null constant buffer, returning E_FAIL.\n"); + return E_FAIL; + } + + if (!desc) + { + WARN("NULL pointer, returning E_FAIL.\n"); + return E_FAIL; + } + + *desc = buffer->desc; + return S_OK; +} + +static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3d12_buffer_GetVariableByIndex( + ID3D12ShaderReflectionConstantBuffer *iface, UINT index) +{ + struct d3d12_buffer *buffer = impl_from_ID3D12ShaderReflectionConstantBuffer(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (index >= buffer->desc.Variables) + { + WARN("Invalid index %u.\n", index); + return &null_variable.ID3D12ShaderReflectionVariable_iface; + } + + return &buffer->variables[index].ID3D12ShaderReflectionVariable_iface; +} + +static ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3d12_buffer_GetVariableByName( + ID3D12ShaderReflectionConstantBuffer *iface, const char *name) +{ + FIXME("iface %p, name %s, stub!\n", iface, debugstr_a(name)); + + return NULL; +} + +static const struct ID3D12ShaderReflectionConstantBufferVtbl d3d12_buffer_vtbl = +{ + d3d12_buffer_GetDesc, + d3d12_buffer_GetVariableByIndex, + d3d12_buffer_GetVariableByName, +}; + +static struct d3d12_buffer null_buffer = {{&d3d12_buffer_vtbl}}; + +static struct d3d12_reflection *impl_from_ID3D12ShaderReflection(ID3D12ShaderReflection *iface) +{ + return CONTAINING_RECORD(iface, struct d3d12_reflection, ID3D12ShaderReflection_iface); +} + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_QueryInterface( + ID3D12ShaderReflection *iface, REFIID riid, void **object) +{ + TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object); + + if (IsEqualGUID(riid, &IID_ID3D12ShaderReflection) + || IsEqualGUID(riid, &IID_IUnknown)) + { + ID3D12ShaderReflection_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 d3d12_reflection_AddRef(ID3D12ShaderReflection *iface) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + unsigned int refcount = vkd3d_atomic_increment_u32(&reflection->refcount); + + TRACE("%p increasing refcount to %u.\n", reflection, refcount); + + return refcount; +} + +static void free_type(struct d3d12_type *type) +{ + for (UINT i = 0; i < type->desc.Members; ++i) + free_type(&type->fields[i].type); + vkd3d_free(type->fields); + vkd3d_free((void *)type->desc.Name); +} + +static ULONG STDMETHODCALLTYPE d3d12_reflection_Release(ID3D12ShaderReflection *iface) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + unsigned int refcount = vkd3d_atomic_decrement_u32(&reflection->refcount); + + TRACE("%p decreasing refcount to %u.\n", reflection, refcount); + + if (!refcount) + { + for (UINT i = 0; i < reflection->desc.ConstantBuffers; ++i) + { + struct d3d12_buffer *buffer = &reflection->buffers[i]; + + for (UINT j = 0; j < buffer->desc.Variables; ++j) + { + struct d3d12_variable *variable = &buffer->variables[j]; + + free_type(&variable->type); + vkd3d_free((void *)variable->desc.DefaultValue); + vkd3d_free((void *)variable->desc.Name); + } + vkd3d_free(buffer->variables); + vkd3d_free((void *)buffer->desc.Name); + } + vkd3d_free(reflection->buffers); + + for (UINT i = 0; i < reflection->desc.BoundResources; ++i) + vkd3d_free((void *)reflection->bindings[i].Name); + vkd3d_free(reflection->bindings); + + vkd3d_shader_free_scan_signature_info(&reflection->signature_info); + free(reflection); + } + + return refcount; +} + +/* ID3D12ShaderReflection methods */ + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetDesc(ID3D12ShaderReflection *iface, D3D12_SHADER_DESC *desc) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + FIXME("iface %p, desc %p partial stub!\n", iface, desc); + + *desc = reflection->desc; + + return S_OK; +} + +static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3d12_reflection_GetConstantBufferByIndex( + ID3D12ShaderReflection *iface, UINT index) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, index %u.\n", iface, index); + + if (index >= reflection->desc.ConstantBuffers) + { + WARN("Invalid index %u.\n", index); + return &null_buffer.ID3D12ShaderReflectionConstantBuffer_iface; + } + + return &reflection->buffers[index].ID3D12ShaderReflectionConstantBuffer_iface; +} + +static struct ID3D12ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3d12_reflection_GetConstantBufferByName( + ID3D12ShaderReflection *iface, const char *name) +{ + FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name)); + + return NULL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetResourceBindingDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SHADER_INPUT_BIND_DESC *desc) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + if (index >= reflection->desc.BoundResources) + { + WARN("Invalid index %u.\n", index); + return E_INVALIDARG; + } + + *desc = reflection->bindings[index]; + return S_OK; +} + +static HRESULT get_signature_parameter(const struct vkd3d_shader_signature *signature, + unsigned int index, D3D12_SIGNATURE_PARAMETER_DESC *desc, bool output) +{ + const struct vkd3d_shader_signature_element *e; + + if (!desc || index >= signature->element_count) + { + WARN("Invalid argument specified.\n"); + return E_INVALIDARG; + } + e = &signature->elements[index]; + + desc->SemanticName = e->semantic_name; + desc->SemanticIndex = e->semantic_index; + desc->Register = e->register_index; + desc->SystemValueType = (D3D_NAME)e->sysval_semantic; + desc->ComponentType = (D3D_REGISTER_COMPONENT_TYPE)e->component_type; + desc->Mask = e->mask; + desc->ReadWriteMask = output ? (0xf ^ e->used_mask) : e->used_mask; + desc->Stream = e->stream_index; + desc->MinPrecision = (D3D_MIN_PRECISION)e->min_precision; + + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetInputParameterDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + return get_signature_parameter(&reflection->signature_info.input, index, desc, false); +} + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetOutputParameterDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + return get_signature_parameter(&reflection->signature_info.output, index, desc, true); +} + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetPatchConstantParameterDesc( + ID3D12ShaderReflection *iface, UINT index, D3D12_SIGNATURE_PARAMETER_DESC *desc) +{ + struct d3d12_reflection *reflection = impl_from_ID3D12ShaderReflection(iface); + bool output = ((reflection->desc.Version & 0xffff0000) >> 16) == D3D12_SHVER_HULL_SHADER; + + TRACE("iface %p, index %u, desc %p.\n", iface, index, desc); + + return get_signature_parameter(&reflection->signature_info.patch_constant, index, desc, output); +} + +static struct ID3D12ShaderReflectionVariable * STDMETHODCALLTYPE d3d12_reflection_GetVariableByName( + ID3D12ShaderReflection *iface, const char *name) +{ + FIXME("iface %p, name %s stub!\n", iface, debugstr_a(name)); + + return NULL; +} + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetResourceBindingDescByName( + ID3D12ShaderReflection *iface, const char *name, D3D12_SHADER_INPUT_BIND_DESC *desc) +{ + FIXME("iface %p, name %s, desc %p stub!\n", iface, debugstr_a(name), desc); + + return E_NOTIMPL; +} + +static UINT STDMETHODCALLTYPE d3d12_reflection_GetMovInstructionCount(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static UINT STDMETHODCALLTYPE d3d12_reflection_GetMovcInstructionCount(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static UINT STDMETHODCALLTYPE d3d12_reflection_GetConversionInstructionCount(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static UINT STDMETHODCALLTYPE d3d12_reflection_GetBitwiseInstructionCount(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static D3D_PRIMITIVE STDMETHODCALLTYPE d3d12_reflection_GetGSInputPrimitive(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static BOOL STDMETHODCALLTYPE d3d12_reflection_IsSampleFrequencyShader(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return FALSE; +} + +static UINT STDMETHODCALLTYPE d3d12_reflection_GetNumInterfaceSlots(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static HRESULT STDMETHODCALLTYPE d3d12_reflection_GetMinFeatureLevel( + ID3D12ShaderReflection *iface, D3D_FEATURE_LEVEL *level) +{ + FIXME("iface %p, level %p stub!\n", iface, level); + + return E_NOTIMPL; +} + +static UINT STDMETHODCALLTYPE d3d12_reflection_GetThreadGroupSize( + ID3D12ShaderReflection *iface, UINT *sizex, UINT *sizey, UINT *sizez) +{ + FIXME("iface %p, sizex %p, sizey %p, sizez %p stub!\n", iface, sizex, sizey, sizez); + + return 0; +} + +static UINT64 STDMETHODCALLTYPE d3d12_reflection_GetRequiresFlags(ID3D12ShaderReflection *iface) +{ + FIXME("iface %p stub!\n", iface); + + return 0; +} + +static const struct ID3D12ShaderReflectionVtbl d3d12_reflection_vtbl = +{ + /* IUnknown methods */ + d3d12_reflection_QueryInterface, + d3d12_reflection_AddRef, + d3d12_reflection_Release, + /* ID3D12ShaderReflection methods */ + d3d12_reflection_GetDesc, + d3d12_reflection_GetConstantBufferByIndex, + d3d12_reflection_GetConstantBufferByName, + d3d12_reflection_GetResourceBindingDesc, + d3d12_reflection_GetInputParameterDesc, + d3d12_reflection_GetOutputParameterDesc, + d3d12_reflection_GetPatchConstantParameterDesc, + d3d12_reflection_GetVariableByName, + d3d12_reflection_GetResourceBindingDescByName, + d3d12_reflection_GetMovInstructionCount, + d3d12_reflection_GetMovcInstructionCount, + d3d12_reflection_GetConversionInstructionCount, + d3d12_reflection_GetBitwiseInstructionCount, + d3d12_reflection_GetGSInputPrimitive, + d3d12_reflection_IsSampleFrequencyShader, + d3d12_reflection_GetNumInterfaceSlots, + d3d12_reflection_GetMinFeatureLevel, + d3d12_reflection_GetThreadGroupSize, + d3d12_reflection_GetRequiresFlags, +}; + +static bool require_space(size_t offset, size_t count, size_t size, size_t data_size) +{ + return !count || (data_size - offset) / count >= size; +} + +/* Return a pointer to data in a code blob, with bounds checking. */ +static const void *get_data_ptr(const struct vkd3d_shader_code *code, + uint32_t offset, uint32_t count, uint32_t size) +{ + if (!require_space(offset, count, size, code->size)) + { + WARN("Offset %#x and size %#x exceeds section size %#zx.\n", offset, size, code->size); + return NULL; + } + + return (const uint8_t *)code->code + offset; +} + +static HRESULT get_string(const struct vkd3d_shader_code *code, uint32_t offset, char **ret) +{ + const char *str; + char *end; + + if (offset >= code->size) + { + WARN("Offset %#x exceeds size %#zx.\n", offset, code->size); + return E_INVALIDARG; + } + + str = (const char *)code->code + offset; + if (!(end = memchr(str, 0, code->size - offset))) + { + WARN("String at %#x is not properly zero-terminated.\n", offset); + return E_INVALIDARG; + } + + if (!(*ret = vkd3d_memdup(str, end + 1 - str))) + return E_OUTOFMEMORY; + return S_OK; +} + +struct rdef_header +{ + uint32_t buffer_count; + uint32_t buffers_offset; + uint32_t binding_count; + uint32_t bindings_offset; + uint8_t minor_version; + uint8_t major_version; + uint16_t type; + uint32_t compile_flags; + uint32_t creator_offset; +}; + +struct rdef_rd11 +{ + uint32_t magic; + uint32_t header_size; + uint32_t buffer_size; + uint32_t binding_size; + uint32_t variable_size; + uint32_t type_size; + uint32_t field_size; + /* Always zero. Possibly either padding or a null terminator? */ + uint32_t zero; +}; + +struct rdef_buffer +{ + uint32_t name_offset; + uint32_t var_count; + uint32_t vars_offset; + uint32_t size; + uint32_t flags; + uint32_t type; +}; + +struct rdef_variable +{ + uint32_t name_offset; + uint32_t offset; + uint32_t size; + uint32_t flags; + uint32_t type_offset; + uint32_t default_value_offset; + uint32_t resource_binding; + uint32_t resource_count; + uint32_t sampler_binding; + uint32_t sampler_count; +}; + +struct rdef_type +{ + uint16_t class; + uint16_t base_type; + uint16_t row_count; + uint16_t column_count; + uint16_t element_count; + uint16_t field_count; + uint32_t fields_offset; + /* Probably related to interfaces. */ + uint32_t unknown[4]; + uint32_t name_offset; +}; + +struct rdef_field +{ + uint32_t name_offset; + uint32_t type_offset; + uint32_t offset; +}; + +struct rdef_binding +{ + uint32_t name_offset; + uint32_t type; + uint32_t resource_format; + uint32_t dimension; + uint32_t multisample_count; + uint32_t index; + uint32_t count; + uint32_t flags; + uint32_t space; + uint32_t id; +}; + +static HRESULT d3d12_type_init(struct d3d12_type *type, uint32_t type_offset, uint32_t type_size, + const struct vkd3d_shader_code *section, uint32_t field_offset) +{ + struct rdef_type normalized_type = {0}; + const struct rdef_type *rdef_type; + char *name = NULL; + HRESULT hr; + + if (!(rdef_type = get_data_ptr(section, type_offset, 1, type_size))) + return E_INVALIDARG; + memcpy(&normalized_type, rdef_type, type_size); + + if (normalized_type.name_offset && FAILED(hr = get_string(section, normalized_type.name_offset, &name))) + return hr; + + type->ID3D12ShaderReflectionType_iface.lpVtbl = &d3d12_type_vtbl; + + type->desc.Class = normalized_type.class; + type->desc.Type = normalized_type.base_type; + type->desc.Rows = normalized_type.row_count; + type->desc.Columns = normalized_type.column_count; + type->desc.Elements = normalized_type.element_count; + type->desc.Members = normalized_type.field_count; + type->desc.Offset = field_offset; + type->desc.Name = name; + + if (normalized_type.field_count) + { + const struct rdef_field *rdef_fields; + + if (!(rdef_fields = get_data_ptr(section, normalized_type.fields_offset, + normalized_type.field_count, sizeof(*rdef_fields)))) + return E_INVALIDARG; + + if (!(type->fields = vkd3d_calloc(normalized_type.field_count, sizeof(*type->fields)))) + return false; + + for (uint32_t i = 0; i < normalized_type.field_count; ++i) + { + const struct rdef_field *rdef_field = &rdef_fields[i]; + + if ((hr = d3d12_type_init(&type->fields[i].type, rdef_field->type_offset, + type_size, section, rdef_field->offset))) + return hr; + } + } + + return S_OK; +} + +static HRESULT d3d12_variable_init(struct d3d12_variable *variable, const struct rdef_variable *rdef_variable, + const struct vkd3d_shader_code *section, uint32_t type_size) +{ + HRESULT hr; + char *name; + + if (FAILED(hr = get_string(section, rdef_variable->name_offset, &name))) + return hr; + + variable->ID3D12ShaderReflectionVariable_iface.lpVtbl = &d3d12_variable_vtbl; + + variable->desc.Name = name; + variable->desc.StartOffset = rdef_variable->offset; + variable->desc.Size = rdef_variable->size; + variable->desc.uFlags = rdef_variable->flags; + variable->desc.StartTexture = rdef_variable->resource_binding; + variable->desc.TextureSize = rdef_variable->resource_count; + variable->desc.StartSampler = rdef_variable->sampler_binding; + variable->desc.SamplerSize = rdef_variable->sampler_count; + + if (rdef_variable->default_value_offset) + { + const void *default_value; + + if (!(default_value = get_data_ptr(section, rdef_variable->default_value_offset, 1, rdef_variable->size))) + return E_INVALIDARG; + + if (!(variable->desc.DefaultValue = vkd3d_memdup(default_value, rdef_variable->size))) + return E_OUTOFMEMORY; + } + + return d3d12_type_init(&variable->type, rdef_variable->type_offset, type_size, section, 0); +} + +static HRESULT d3d12_buffer_init(struct d3d12_buffer *buffer, const struct rdef_buffer *rdef_buffer, + const struct vkd3d_shader_code *section, uint32_t variable_size, uint32_t type_size) +{ + HRESULT hr; + char *name; + + if ((FAILED(hr = get_string(section, rdef_buffer->name_offset, &name)))) + return hr; + + buffer->ID3D12ShaderReflectionConstantBuffer_iface.lpVtbl = &d3d12_buffer_vtbl; + + buffer->desc.Type = rdef_buffer->type; + buffer->desc.Variables = rdef_buffer->var_count; + buffer->desc.Size = rdef_buffer->size; + buffer->desc.uFlags = rdef_buffer->flags; + buffer->desc.Name = name; + + if (!(buffer->variables = vkd3d_calloc(rdef_buffer->var_count, sizeof(*buffer->variables)))) + return E_OUTOFMEMORY; + + for (uint32_t i = 0; i < rdef_buffer->var_count; ++i) + { + struct rdef_variable normalized_variable = {0}; + const struct rdef_variable *rdef_variable; + + if (!(rdef_variable = get_data_ptr(section, rdef_buffer->vars_offset + (i * variable_size), 1, variable_size))) + return E_INVALIDARG; + + normalized_variable.resource_binding = ~0u; + normalized_variable.sampler_binding = ~0u; + memcpy(&normalized_variable, rdef_variable, variable_size); + + if ((hr = d3d12_variable_init(&buffer->variables[i], &normalized_variable, section, type_size))) + return hr; + } + + return S_OK; +} + +static HRESULT parse_rdef(struct d3d12_reflection *reflection, const struct vkd3d_shader_code *section) +{ + uint32_t variable_size = offsetof(struct rdef_variable, resource_binding); + uint32_t binding_size = offsetof(struct rdef_binding, space); + uint32_t type_size = offsetof(struct rdef_type, unknown); + const struct rdef_header *header; + const struct rdef_rd11 *rd11; + HRESULT hr; + + if (!(header = get_data_ptr(section, 0, 1, sizeof(*header)))) + return E_INVALIDARG; + + if (header->major_version >= 5) + { + if (!(rd11 = get_data_ptr(section, sizeof(*header), 1, sizeof(*rd11)))) + return E_INVALIDARG; + + /* RD11 is emitted for 5.0, the reversed version for 5.1 and 6.0. + * This corresponds to a difference in the binding_size member, but + * it's not clear why the magic also changed there. */ + if (rd11->magic != TAG_RD11 && rd11->magic != TAG_RD11_REVERSE) + { + FIXME("Unknown tag %#x.\n", rd11->magic); + return E_INVALIDARG; + } + + if (rd11->header_size != sizeof(struct rdef_header) + sizeof(struct rdef_rd11)) + { + FIXME("Unexpected header size %#x.\n", rd11->header_size); + return E_INVALIDARG; + } + + if (rd11->buffer_size != sizeof(struct rdef_buffer)) + { + FIXME("Unexpected buffer size %#x.\n", rd11->buffer_size); + return E_INVALIDARG; + } + + if (rd11->variable_size != sizeof(struct rdef_variable)) + { + FIXME("Unexpected variable size %#x.\n", rd11->variable_size); + return E_INVALIDARG; + } + variable_size = rd11->variable_size; + + if (rd11->binding_size != sizeof(struct rdef_binding) + && rd11->binding_size != offsetof(struct rdef_binding, space)) + { + FIXME("Unexpected binding size %#x.\n", rd11->binding_size); + return E_INVALIDARG; + } + binding_size = rd11->binding_size; + + if (rd11->type_size != sizeof(struct rdef_type)) + { + FIXME("Unexpected type size %#x.\n", rd11->type_size); + return E_INVALIDARG; + } + type_size = rd11->type_size; + + if (rd11->zero) + { + FIXME("Unexpected field %#x.\n", rd11->zero); + return E_INVALIDARG; + } + } + + reflection->desc.ConstantBuffers = header->buffer_count; + + if (header->buffer_count) + { + const struct rdef_buffer *rdef_buffers; + + if (!(rdef_buffers = get_data_ptr(section, header->buffers_offset, + header->buffer_count, sizeof(*rdef_buffers)))) + return E_INVALIDARG; + + if (!(reflection->buffers = vkd3d_calloc(header->buffer_count, sizeof(*reflection->buffers)))) + return E_OUTOFMEMORY; + + for (uint32_t i = 0; i < header->buffer_count; ++i) + { + if ((hr = d3d12_buffer_init(&reflection->buffers[i], &rdef_buffers[i], section, variable_size, type_size))) + return hr; + } + } + + reflection->desc.BoundResources = header->binding_count; + + if (header->binding_count) + { + if (!(reflection->bindings = vkd3d_calloc(header->binding_count, sizeof(*reflection->bindings)))) + return E_OUTOFMEMORY; + + for (uint32_t i = 0; i < header->binding_count; ++i) + { + const struct rdef_binding *rdef_binding; + D3D12_SHADER_INPUT_BIND_DESC *binding; + char *name; + + if (!(rdef_binding = get_data_ptr(section, header->bindings_offset + (i * binding_size), 1, binding_size))) + return E_INVALIDARG; + + if (FAILED(hr = get_string(section, rdef_binding->name_offset, &name))) + return hr; + + binding = &reflection->bindings[i]; + + binding->Name = name; + binding->Type = rdef_binding->type; + binding->BindPoint = rdef_binding->index; + binding->BindCount = rdef_binding->count; + binding->uFlags = rdef_binding->flags; + binding->ReturnType = rdef_binding->resource_format; + binding->Dimension = rdef_binding->dimension; + binding->NumSamples = rdef_binding->multisample_count; + if (binding_size == sizeof(*rdef_binding)) + { + binding->Space = rdef_binding->space; + binding->uID = rdef_binding->id; + } + else + { + binding->Space = 0; + binding->uID = rdef_binding->index; + } + } + } + + return S_OK; +} + +static HRESULT d3d12_reflection_init(struct d3d12_reflection *reflection, const void *data, size_t data_size) +{ + struct vkd3d_shader_compile_info compile_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; + struct vkd3d_shader_dxbc_desc dxbc_desc; + bool found_rdef = false; + enum vkd3d_result ret; + HRESULT hr; + + reflection->ID3D12ShaderReflection_iface.lpVtbl = &d3d12_reflection_vtbl; + reflection->refcount = 1; + + compile_info.source.code = data; + compile_info.source.size = data_size; + compile_info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; + + compile_info.next = &reflection->signature_info; + reflection->signature_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO; + + if (FAILED(hr = hresult_from_vkd3d_result(vkd3d_shader_scan(&compile_info, NULL)))) + return hr; + + if ((ret = vkd3d_shader_parse_dxbc(&compile_info.source, 0, &dxbc_desc, NULL))) + { + vkd3d_shader_free_scan_signature_info(&reflection->signature_info); + return hresult_from_vkd3d_result(ret); + } + + for (unsigned int i = 0; i < dxbc_desc.section_count; ++i) + { + const struct vkd3d_shader_dxbc_section_desc *section = &dxbc_desc.sections[i]; + + if (section->tag == TAG_RDEF) + { + if (found_rdef) + { + FIXME("Multiple RDEF chunks.\n"); + continue; + } + + if (FAILED(hr = parse_rdef(reflection, §ion->data))) + goto fail; + found_rdef = true; + } + else if (section->tag == TAG_SHDR || section->tag == TAG_SHEX) + { + const uint32_t *version; + + if (!(version = get_data_ptr(§ion->data, 0, 1, sizeof(*version)))) + { + hr = E_INVALIDARG; + goto fail; + } + reflection->desc.Version = *version; + } + } + + reflection->desc.InputParameters = reflection->signature_info.input.element_count; + reflection->desc.OutputParameters = reflection->signature_info.output.element_count; + reflection->desc.PatchConstantParameters = reflection->signature_info.patch_constant.element_count; + + vkd3d_shader_free_dxbc(&dxbc_desc); + + return S_OK; + +fail: + vkd3d_shader_free_scan_signature_info(&reflection->signature_info); + vkd3d_shader_free_dxbc(&dxbc_desc); + return hr; +} + +HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection) +{ + struct d3d12_reflection *object; + HRESULT hr; + + TRACE("data %p, data_size %"PRIuPTR", iid %s, reflection %p.\n", + data, (uintptr_t)data_size, debugstr_guid(iid), reflection); + + if (!IsEqualGUID(iid, &IID_ID3D12ShaderReflection)) + { + WARN("Invalid iid %s.\n", debugstr_guid(iid)); + return E_INVALIDARG; + } + + if (!(object = vkd3d_calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + if (FAILED(hr = d3d12_reflection_init(object, data, data_size))) + { + free(object); + return hr; + } + + *reflection = &object->ID3D12ShaderReflection_iface; + TRACE("Created reflection %p.\n", object); + return S_OK; +} diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c new file mode 100644 index 00000000000..88374e4c74d --- /dev/null +++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c @@ -0,0 +1,1039 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "vkd3d_utils_private.h" +#undef D3D12CreateDevice + +static const char *debug_d3d_blob_part(D3D_BLOB_PART part) +{ + switch (part) + { +#define TO_STR(x) case x: return #x + TO_STR(D3D_BLOB_INPUT_SIGNATURE_BLOB); + TO_STR(D3D_BLOB_OUTPUT_SIGNATURE_BLOB); + TO_STR(D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB); + TO_STR(D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB); + TO_STR(D3D_BLOB_ALL_SIGNATURE_BLOB); + TO_STR(D3D_BLOB_DEBUG_INFO); + TO_STR(D3D_BLOB_LEGACY_SHADER); + TO_STR(D3D_BLOB_XNA_PREPASS_SHADER); + TO_STR(D3D_BLOB_XNA_SHADER); + TO_STR(D3D_BLOB_PDB); + TO_STR(D3D_BLOB_PRIVATE_DATA); + TO_STR(D3D_BLOB_ROOT_SIGNATURE); + TO_STR(D3D_BLOB_DEBUG_NAME); + + TO_STR(D3D_BLOB_TEST_ALTERNATE_SHADER); + TO_STR(D3D_BLOB_TEST_COMPILE_DETAILS); + TO_STR(D3D_BLOB_TEST_COMPILE_PERF); + TO_STR(D3D_BLOB_TEST_COMPILE_REPORT); +#undef TO_STR + default: + return vkd3d_dbg_sprintf("<D3D_BLOB_PART %#x>", part); + } +} + +HRESULT WINAPI D3D12GetDebugInterface(REFIID iid, void **debug) +{ + FIXME("iid %s, debug %p stub!\n", debugstr_guid(iid), debug); + + return E_NOTIMPL; +} + +HRESULT WINAPI D3D12CreateDeviceVKD3D(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level, + REFIID iid, void **device, enum vkd3d_api_version api_version) +{ + struct vkd3d_optional_instance_extensions_info optional_instance_extensions_info; + struct vkd3d_optional_device_extensions_info optional_device_extensions_info; + struct vkd3d_instance_create_info instance_create_info; + struct vkd3d_device_create_info device_create_info; + + static const char * const optional_instance_extensions[] = + { + VK_KHR_SURFACE_EXTENSION_NAME, + "VK_KHR_android_surface", + "VK_KHR_wayland_surface", + "VK_KHR_win32_surface", + "VK_KHR_xcb_surface", + "VK_KHR_xlib_surface", + "VK_EXT_metal_surface", + "VK_MVK_macos_surface", + "VK_MVK_ios_surface", + }; + static const char * const optional_device_extensions[] = + { + VK_KHR_SWAPCHAIN_EXTENSION_NAME, + }; + struct vkd3d_application_info application_info = + { + .type = VKD3D_STRUCTURE_TYPE_APPLICATION_INFO, + .api_version = api_version, + }; + + TRACE("adapter %p, minimum_feature_level %#x, iid %s, device %p, api_version %#x.\n", + adapter, minimum_feature_level, debugstr_guid(iid), device, api_version); + + if (adapter) + FIXME("Ignoring adapter %p.\n", adapter); + + memset(&optional_instance_extensions_info, 0, sizeof(optional_instance_extensions_info)); + optional_instance_extensions_info.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO; + optional_instance_extensions_info.next = &application_info; + optional_instance_extensions_info.extensions = optional_instance_extensions; + optional_instance_extensions_info.extension_count = ARRAY_SIZE(optional_instance_extensions); + + memset(&instance_create_info, 0, sizeof(instance_create_info)); + instance_create_info.type = VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + instance_create_info.next = &optional_instance_extensions_info; + instance_create_info.pfn_signal_event = vkd3d_signal_event; + instance_create_info.wchar_size = sizeof(WCHAR); + + memset(&optional_device_extensions_info, 0, sizeof(optional_device_extensions_info)); + optional_device_extensions_info.type = VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO; + optional_device_extensions_info.extensions = optional_device_extensions; + optional_device_extensions_info.extension_count = ARRAY_SIZE(optional_device_extensions); + + memset(&device_create_info, 0, sizeof(device_create_info)); + device_create_info.type = VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + device_create_info.next = &optional_device_extensions_info; + device_create_info.minimum_feature_level = minimum_feature_level; + device_create_info.instance_create_info = &instance_create_info; + + return vkd3d_create_device(&device_create_info, iid, device); +} + +VKD3D_UTILS_API HRESULT WINAPI D3D12CreateDevice(IUnknown *adapter, + D3D_FEATURE_LEVEL minimum_feature_level, REFIID iid, void **device) +{ + return D3D12CreateDeviceVKD3D(adapter, minimum_feature_level, iid, device, VKD3D_API_VERSION_1_0); +} + +HRESULT WINAPI D3D12CreateRootSignatureDeserializer(const void *data, SIZE_T data_size, + REFIID iid, void **deserializer) +{ + TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", + data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); + + return vkd3d_create_root_signature_deserializer(data, data_size, iid, deserializer); +} + +HRESULT WINAPI D3D12CreateVersionedRootSignatureDeserializer(const void *data, SIZE_T data_size, + REFIID iid,void **deserializer) +{ + TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", + data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); + + return vkd3d_create_versioned_root_signature_deserializer(data, data_size, iid, deserializer); +} + +HRESULT WINAPI D3D12SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC *desc, + D3D_ROOT_SIGNATURE_VERSION version, ID3DBlob **blob, ID3DBlob **error_blob) +{ + TRACE("desc %p, version %#x, blob %p, error_blob %p.\n", desc, version, blob, error_blob); + + return vkd3d_serialize_root_signature(desc, version, blob, error_blob); +} + +HRESULT WINAPI D3D12SerializeVersionedRootSignature(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC *desc, + ID3DBlob **blob, ID3DBlob **error_blob) +{ + TRACE("desc %p, blob %p, error_blob %p.\n", desc, blob, error_blob); + + return vkd3d_serialize_versioned_root_signature(desc, blob, error_blob); +} + +static int open_include(const char *filename, bool local, const char *parent_data, void *context, + struct vkd3d_shader_code *code) +{ + ID3DInclude *iface = context; + unsigned int size = 0; + + if (!iface) + return VKD3D_ERROR; + + memset(code, 0, sizeof(*code)); + if (FAILED(ID3DInclude_Open(iface, local ? D3D_INCLUDE_LOCAL : D3D_INCLUDE_SYSTEM, + filename, parent_data, &code->code, &size))) + return VKD3D_ERROR; + + code->size = size; + return VKD3D_OK; +} + +static void close_include(const struct vkd3d_shader_code *code, void *context) +{ + ID3DInclude *iface = context; + + ID3DInclude_Close(iface, code->code); +} + +static enum vkd3d_shader_target_type get_target_for_profile(const char *profile) +{ + size_t profile_len, i; + + static const char * const d3dbc_profiles[] = + { + "ps.1.", + "ps.2.", + "ps.3.", + + "ps_1_", + "ps_2_", + "ps_3_", + + "vs.1.", + "vs.2.", + "vs.3.", + + "vs_1_", + "vs_2_", + "vs_3_", + + "tx_1_", + }; + + static const char * const fx_profiles[] = + { + "fx_2_0", + "fx_4_0", + "fx_4_1", + "fx_5_0", + }; + + profile_len = strlen(profile); + for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i) + { + size_t len = strlen(d3dbc_profiles[i]); + + if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len)) + return VKD3D_SHADER_TARGET_D3D_BYTECODE; + } + + for (i = 0; i < ARRAY_SIZE(fx_profiles); ++i) + { + if (!strcmp(profile, fx_profiles[i])) + return VKD3D_SHADER_TARGET_FX; + } + + return VKD3D_SHADER_TARGET_DXBC_TPF; +} + +HRESULT WINAPI D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point, + const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob, + ID3DBlob **messages_blob, unsigned int compiler_version) +{ + struct vkd3d_shader_preprocess_info preprocess_info; + struct vkd3d_shader_hlsl_source_info hlsl_info; + struct vkd3d_shader_compile_option options[7]; + struct vkd3d_shader_compile_info compile_info; + struct vkd3d_shader_compile_option *option; + struct vkd3d_shader_code byte_code; + const D3D_SHADER_MACRO *macro; + char *messages; + HRESULT hr; + int ret; + + TRACE("data %p, data_size %"PRIuPTR", filename %s, macros %p, include %p, entry_point %s, " + "profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, " + "secondary_data_size %"PRIuPTR", shader_blob %p, messages_blob %p, compiler_version %u.\n", + data, (uintptr_t)data_size, debugstr_a(filename), macros, include, debugstr_a(entry_point), + debugstr_a(profile), flags, effect_flags, secondary_flags, secondary_data, + (uintptr_t)secondary_data_size, shader_blob, messages_blob, compiler_version); + + if (flags & ~(D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR)) + FIXME("Ignoring flags %#x.\n", flags); + if (effect_flags & ~D3DCOMPILE_EFFECT_CHILD_EFFECT) + FIXME("Ignoring effect flags %#x.\n", effect_flags); + if (secondary_flags) + FIXME("Ignoring secondary flags %#x.\n", secondary_flags); + + if (messages_blob) + *messages_blob = NULL; + + option = &options[0]; + option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; + option->value = VKD3D_SHADER_API_VERSION_1_14; + + compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; + compile_info.next = &preprocess_info; + compile_info.source.code = data; + compile_info.source.size = data_size; + compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; + compile_info.target_type = get_target_for_profile(profile); + compile_info.options = options; + compile_info.option_count = 1; + compile_info.log_level = VKD3D_SHADER_LOG_INFO; + compile_info.source_name = filename; + + preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO; + preprocess_info.next = &hlsl_info; + preprocess_info.macros = (const struct vkd3d_shader_macro *)macros; + preprocess_info.macro_count = 0; + if (macros) + { + for (macro = macros; macro->Name; ++macro) + ++preprocess_info.macro_count; + } + preprocess_info.pfn_open_include = open_include; + preprocess_info.pfn_close_include = close_include; + preprocess_info.include_context = include; + + hlsl_info.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO; + hlsl_info.next = NULL; + hlsl_info.profile = profile; + hlsl_info.entry_point = entry_point; + hlsl_info.secondary_code.code = secondary_data; + hlsl_info.secondary_code.size = secondary_data_size; + + if (!(flags & D3DCOMPILE_DEBUG)) + { + option = &options[compile_info.option_count++]; + option->name = VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG; + option->value = true; + } + + if (flags & (D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR)) + { + option = &options[compile_info.option_count++]; + option->name = VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER; + option->value = 0; + if (flags & D3DCOMPILE_PACK_MATRIX_ROW_MAJOR) + option->value |= VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR; + if (flags & D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR) + option->value |= VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR; + } + + if (flags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY) + { + option = &options[compile_info.option_count++]; + option->name = VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY; + option->value = VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES; + } + + if (effect_flags & D3DCOMPILE_EFFECT_CHILD_EFFECT) + { + option = &options[compile_info.option_count++]; + option->name = VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT; + option->value = true; + } + + if (compiler_version <= 39) + { + option = &options[compile_info.option_count++]; + option->name = VKD3D_SHADER_COMPILE_OPTION_INCLUDE_EMPTY_BUFFERS_IN_EFFECTS; + option->value = true; + } + + if (compiler_version < 42) + { + option = &options[compile_info.option_count++]; + option->name = VKD3D_SHADER_COMPILE_OPTION_WARN_IMPLICIT_TRUNCATION; + option->value = false; + } + + ret = vkd3d_shader_compile(&compile_info, &byte_code, &messages); + + if (messages && messages_blob) + { + if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), messages_blob))) + { + vkd3d_shader_free_messages(messages); + vkd3d_shader_free_shader_code(&byte_code); + return hr; + } + messages = NULL; + } + vkd3d_shader_free_messages(messages); + + if (!ret) + { + /* Unlike other effect profiles fx_4_x is using DXBC container. */ + if (!strcmp(profile, "fx_4_0") || !strcmp(profile, "fx_4_1")) + { + struct vkd3d_shader_dxbc_section_desc section = { .tag = TAG_FX10, .data = byte_code }; + struct vkd3d_shader_code dxbc; + + ret = vkd3d_shader_serialize_dxbc(1, §ion, &dxbc, NULL); + vkd3d_shader_free_shader_code(&byte_code); + if (ret) + return hresult_from_vkd3d_result(ret); + + byte_code = dxbc; + } + + if (FAILED(hr = vkd3d_blob_create((void *)byte_code.code, byte_code.size, shader_blob))) + { + vkd3d_shader_free_shader_code(&byte_code); + return hr; + } + } + + return hresult_from_vkd3d_result(ret); +} + +HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point, + const char *profile, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader_blob, + ID3DBlob **messages_blob) +{ + TRACE("data %p, data_size %"PRIuPTR", filename %s, macros %p, include %p, entry_point %s, " + "profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, " + "secondary_data_size %"PRIuPTR", shader_blob %p, messages_blob %p.\n", + data, (uintptr_t)data_size, debugstr_a(filename), macros, include, debugstr_a(entry_point), + debugstr_a(profile), flags, effect_flags, secondary_flags, secondary_data, + (uintptr_t)secondary_data_size, shader_blob, messages_blob); + + return D3DCompile2VKD3D(data, data_size, filename, macros, include, + entry_point, profile, flags, effect_flags, secondary_flags, + secondary_data, secondary_data_size, shader_blob, messages_blob, 47); +} + +HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint, + const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages) +{ + TRACE("data %p, data_size %"PRIuPTR", filename %s, macros %p, include %p, entrypoint %s, " + "profile %s, flags %#x, effect_flags %#x, shader %p, error_messages %p.\n", + data, (uintptr_t)data_size, debugstr_a(filename), macros, include, debugstr_a(entrypoint), + debugstr_a(profile), flags, effect_flags, shader, error_messages); + + return D3DCompile2(data, data_size, filename, macros, include, entrypoint, profile, flags, + effect_flags, 0, NULL, 0, shader, error_messages); +} + +HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, + ID3DBlob **preprocessed_blob, ID3DBlob **messages_blob) +{ + struct vkd3d_shader_preprocess_info preprocess_info; + struct vkd3d_shader_compile_info compile_info; + struct vkd3d_shader_code preprocessed_code; + const D3D_SHADER_MACRO *macro; + char *messages; + HRESULT hr; + int ret; + + static const struct vkd3d_shader_compile_option options[] = + { + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_14}, + }; + + TRACE("data %p, size %"PRIuPTR", filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", + data, (uintptr_t)size, debugstr_a(filename), macros, include, preprocessed_blob, messages_blob); + + if (messages_blob) + *messages_blob = NULL; + + compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; + compile_info.next = &preprocess_info; + compile_info.source.code = data; + compile_info.source.size = size; + compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; + compile_info.target_type = VKD3D_SHADER_TARGET_NONE; + compile_info.options = options; + compile_info.option_count = ARRAY_SIZE(options); + compile_info.log_level = VKD3D_SHADER_LOG_INFO; + compile_info.source_name = filename; + + preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO; + preprocess_info.next = NULL; + preprocess_info.macros = (const struct vkd3d_shader_macro *)macros; + preprocess_info.macro_count = 0; + if (macros) + { + for (macro = macros; macro->Name; ++macro) + ++preprocess_info.macro_count; + } + preprocess_info.pfn_open_include = open_include; + preprocess_info.pfn_close_include = close_include; + preprocess_info.include_context = include; + + ret = vkd3d_shader_preprocess(&compile_info, &preprocessed_code, &messages); + + if (messages && messages_blob) + { + if (FAILED(hr = vkd3d_blob_create(messages, strlen(messages), messages_blob))) + { + vkd3d_shader_free_messages(messages); + vkd3d_shader_free_shader_code(&preprocessed_code); + return hr; + } + messages = NULL; + } + vkd3d_shader_free_messages(messages); + + if (!ret) + { + if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, preprocessed_code.size, preprocessed_blob))) + { + vkd3d_shader_free_shader_code(&preprocessed_code); + return hr; + } + } + + return hresult_from_vkd3d_result(ret); +} + +/* Events */ + +#ifdef _WIN32 + +HANDLE vkd3d_create_event(void) +{ + return CreateEventA(NULL, FALSE, FALSE, NULL); +} + +HRESULT vkd3d_signal_event(HANDLE event) +{ + SetEvent(event); + return S_OK; +} + +unsigned int vkd3d_wait_event(HANDLE event, unsigned int milliseconds) +{ + return WaitForSingleObject(event, milliseconds); +} + +void vkd3d_destroy_event(HANDLE event) +{ + CloseHandle(event); +} + +#else /* _WIN32 */ + +#include <pthread.h> + +struct vkd3d_event +{ + pthread_mutex_t mutex; + pthread_cond_t cond; + BOOL is_signaled; +}; + +HANDLE vkd3d_create_event(void) +{ + struct vkd3d_event *event; + int rc; + + TRACE(".\n"); + + if (!(event = vkd3d_malloc(sizeof(*event)))) + return NULL; + + if ((rc = pthread_mutex_init(&event->mutex, NULL))) + { + ERR("Failed to initialize mutex, error %d.\n", rc); + vkd3d_free(event); + return NULL; + } + if ((rc = pthread_cond_init(&event->cond, NULL))) + { + ERR("Failed to initialize condition variable, error %d.\n", rc); + pthread_mutex_destroy(&event->mutex); + vkd3d_free(event); + return NULL; + } + + event->is_signaled = false; + + TRACE("Created event %p.\n", event); + + return event; +} + +unsigned int vkd3d_wait_event(HANDLE event, unsigned int milliseconds) +{ + struct vkd3d_event *impl = event; + int rc; + + TRACE("event %p, milliseconds %u.\n", event, milliseconds); + + if ((rc = pthread_mutex_lock(&impl->mutex))) + { + ERR("Failed to lock mutex, error %d.\n", rc); + return VKD3D_WAIT_FAILED; + } + + if (impl->is_signaled || !milliseconds) + { + bool is_signaled = impl->is_signaled; + impl->is_signaled = false; + pthread_mutex_unlock(&impl->mutex); + return is_signaled ? VKD3D_WAIT_OBJECT_0 : VKD3D_WAIT_TIMEOUT; + } + + if (milliseconds == VKD3D_INFINITE) + { + do + { + if ((rc = pthread_cond_wait(&impl->cond, &impl->mutex))) + { + ERR("Failed to wait on condition variable, error %d.\n", rc); + pthread_mutex_unlock(&impl->mutex); + return VKD3D_WAIT_FAILED; + } + } while (!impl->is_signaled); + + impl->is_signaled = false; + pthread_mutex_unlock(&impl->mutex); + return VKD3D_WAIT_OBJECT_0; + } + + pthread_mutex_unlock(&impl->mutex); + FIXME("Timed wait not implemented yet.\n"); + return VKD3D_WAIT_FAILED; +} + +HRESULT vkd3d_signal_event(HANDLE event) +{ + struct vkd3d_event *impl = event; + int rc; + + TRACE("event %p.\n", event); + + if ((rc = pthread_mutex_lock(&impl->mutex))) + { + ERR("Failed to lock mutex, error %d.\n", rc); + return E_FAIL; + } + impl->is_signaled = true; + pthread_cond_signal(&impl->cond); + pthread_mutex_unlock(&impl->mutex); + + return S_OK; +} + +void vkd3d_destroy_event(HANDLE event) +{ + struct vkd3d_event *impl = event; + int rc; + + TRACE("event %p.\n", event); + + if ((rc = pthread_mutex_destroy(&impl->mutex))) + ERR("Failed to destroy mutex, error %d.\n", rc); + if ((rc = pthread_cond_destroy(&impl->cond))) + ERR("Failed to destroy condition variable, error %d.\n", rc); + vkd3d_free(impl); +} + +#endif /* _WIN32 */ + +HRESULT WINAPI D3DCreateBlob(SIZE_T data_size, ID3DBlob **blob) +{ + HRESULT hr; + void *data; + + TRACE("data_size %"PRIuPTR", blob %p.\n", (uintptr_t)data_size, blob); + + if (!blob) + { + WARN("Invalid 'blob' pointer specified.\n"); + return D3DERR_INVALIDCALL; + } + + if (!(data = vkd3d_calloc(data_size, 1))) + return E_OUTOFMEMORY; + + if (FAILED(hr = vkd3d_blob_create(data, data_size, blob))) + { + WARN("Failed to create blob object, hr %s.\n", debugstr_hresult(hr)); + vkd3d_free(data); + } + return hr; +} + +static bool check_blob_part(uint32_t tag, D3D_BLOB_PART part) +{ + bool add = false; + + switch (part) + { + case D3D_BLOB_INPUT_SIGNATURE_BLOB: + if (tag == TAG_ISGN) + add = true; + break; + + case D3D_BLOB_OUTPUT_SIGNATURE_BLOB: + if (tag == TAG_OSGN || tag == TAG_OSG5) + add = true; + break; + + case D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB: + if (tag == TAG_ISGN || tag == TAG_OSGN || tag == TAG_OSG5) + add = true; + break; + + case D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB: + if (tag == TAG_PCSG) + add = true; + break; + + case D3D_BLOB_ALL_SIGNATURE_BLOB: + if (tag == TAG_ISGN || tag == TAG_OSGN || tag == TAG_OSG5 || tag == TAG_PCSG) + add = true; + break; + + case D3D_BLOB_DEBUG_INFO: + if (tag == TAG_SDBG) + add = true; + break; + + case D3D_BLOB_LEGACY_SHADER: + if (tag == TAG_AON9) + add = true; + break; + + case D3D_BLOB_XNA_PREPASS_SHADER: + if (tag == TAG_XNAP) + add = true; + break; + + case D3D_BLOB_XNA_SHADER: + if (tag == TAG_XNAS) + add = true; + break; + + default: + FIXME("Unhandled D3D_BLOB_PART %s.\n", debug_d3d_blob_part(part)); + break; + } + + TRACE("%s tag %s.\n", add ? "Add" : "Skip", debugstr_an((const char *)&tag, 4)); + + return add; +} + +static HRESULT get_blob_part(const void *data, SIZE_T data_size, + D3D_BLOB_PART part, unsigned int flags, ID3DBlob **blob) +{ + const struct vkd3d_shader_code src_dxbc = {.code = data, .size = data_size}; + struct vkd3d_shader_dxbc_section_desc *sections; + struct vkd3d_shader_dxbc_desc src_dxbc_desc; + struct vkd3d_shader_code dst_dxbc; + unsigned int section_count, i; + HRESULT hr; + int ret; + + if (!data || !data_size || flags || !blob) + { + WARN("Invalid arguments: data %p, data_size %"PRIuPTR", flags %#x, blob %p.\n", + data, (uintptr_t)data_size, flags, blob); + return D3DERR_INVALIDCALL; + } + + if (part > D3D_BLOB_TEST_COMPILE_PERF + || (part < D3D_BLOB_TEST_ALTERNATE_SHADER && part > D3D_BLOB_XNA_SHADER)) + { + WARN("Invalid D3D_BLOB_PART %s.\n", debug_d3d_blob_part(part)); + return D3DERR_INVALIDCALL; + } + + if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0) + { + WARN("Failed to parse source data, ret %d.\n", ret); + return D3DERR_INVALIDCALL; + } + + if (!(sections = vkd3d_calloc(src_dxbc_desc.section_count, sizeof(*sections)))) + { + ERR("Failed to allocate sections memory.\n"); + vkd3d_shader_free_dxbc(&src_dxbc_desc); + return E_OUTOFMEMORY; + } + + for (i = 0, section_count = 0; i < src_dxbc_desc.section_count; ++i) + { + const struct vkd3d_shader_dxbc_section_desc *src_section = &src_dxbc_desc.sections[i]; + + if (check_blob_part(src_section->tag, part)) + sections[section_count++] = *src_section; + } + + switch (part) + { + case D3D_BLOB_INPUT_SIGNATURE_BLOB: + case D3D_BLOB_OUTPUT_SIGNATURE_BLOB: + case D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB: + case D3D_BLOB_DEBUG_INFO: + case D3D_BLOB_LEGACY_SHADER: + case D3D_BLOB_XNA_PREPASS_SHADER: + case D3D_BLOB_XNA_SHADER: + if (section_count != 1) + section_count = 0; + break; + + case D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB: + if (section_count != 2) + section_count = 0; + break; + + case D3D_BLOB_ALL_SIGNATURE_BLOB: + if (section_count != 3) + section_count = 0; + break; + + default: + FIXME("Unhandled D3D_BLOB_PART %s.\n", debug_d3d_blob_part(part)); + break; + } + + if (!section_count) + { + WARN("Nothing to write into the blob.\n"); + hr = E_FAIL; + goto done; + } + + /* Some parts aren't full DXBCs, they contain only the data. */ + if (section_count == 1 && (part == D3D_BLOB_DEBUG_INFO || part == D3D_BLOB_LEGACY_SHADER + || part == D3D_BLOB_XNA_PREPASS_SHADER || part == D3D_BLOB_XNA_SHADER)) + { + dst_dxbc = sections[0].data; + } + else if ((ret = vkd3d_shader_serialize_dxbc(section_count, sections, &dst_dxbc, NULL)) < 0) + { + WARN("Failed to serialise DXBC, ret %d.\n", ret); + hr = hresult_from_vkd3d_result(ret); + goto done; + } + + if (FAILED(hr = D3DCreateBlob(dst_dxbc.size, blob))) + WARN("Failed to create blob, hr %s.\n", debugstr_hresult(hr)); + else + memcpy(ID3D10Blob_GetBufferPointer(*blob), dst_dxbc.code, dst_dxbc.size); + if (dst_dxbc.code != sections[0].data.code) + vkd3d_shader_free_shader_code(&dst_dxbc); + +done: + vkd3d_free(sections); + vkd3d_shader_free_dxbc(&src_dxbc_desc); + + return hr; +} + +HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob) +{ + TRACE("data %p, data_size %"PRIuPTR", part %s, flags %#x, blob %p.\n", + data, (uintptr_t)data_size, debug_d3d_blob_part(part), flags, blob); + + return get_blob_part(data, data_size, part, flags, blob); +} + +HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob) +{ + TRACE("data %p, data_size %"PRIuPTR", blob %p.\n", data, (uintptr_t)data_size, blob); + + return get_blob_part(data, data_size, D3D_BLOB_DEBUG_INFO, 0, blob); +} + +HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob) +{ + TRACE("data %p, data_size %"PRIuPTR", blob %p.\n", data, (uintptr_t)data_size, blob); + + return get_blob_part(data, data_size, D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB, 0, blob); +} + +HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob) +{ + TRACE("data %p, data_size %"PRIuPTR", blob %p.\n", data, (uintptr_t)data_size, blob); + + return get_blob_part(data, data_size, D3D_BLOB_INPUT_SIGNATURE_BLOB, 0, blob); +} + +HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob) +{ + TRACE("data %p, data_size %"PRIuPTR", blob %p.\n", data, (uintptr_t)data_size, blob); + + return get_blob_part(data, data_size, D3D_BLOB_OUTPUT_SIGNATURE_BLOB, 0, blob); +} + +static bool check_blob_strip(uint32_t tag, uint32_t flags) +{ + bool add = true; + + switch (tag) + { + case TAG_RDEF: + case TAG_STAT: + if (flags & D3DCOMPILER_STRIP_REFLECTION_DATA) + add = false; + break; + + case TAG_SDBG: + if (flags & D3DCOMPILER_STRIP_DEBUG_INFO) + add = false; + break; + + default: + break; + } + + TRACE("%s tag %s.\n", add ? "Add" : "Skip", debugstr_an((const char *)&tag, 4)); + + return add; +} + +HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob) +{ + const struct vkd3d_shader_code src_dxbc = {.code = data, .size = data_size}; + struct vkd3d_shader_dxbc_section_desc *sections; + struct vkd3d_shader_dxbc_desc src_dxbc_desc; + struct vkd3d_shader_code dst_dxbc; + unsigned int section_count, i; + HRESULT hr; + int ret; + + TRACE("data %p, data_size %"PRIuPTR", flags %#x, blob %p.\n", data, (uintptr_t)data_size, flags, blob); + + if (!blob) + { + WARN("Invalid 'blob' pointer specified.\n"); + return E_FAIL; + } + + if (!data || !data_size) + { + WARN("Invalid arguments: data %p, data_size %"PRIuPTR".\n", data, (uintptr_t)data_size); + return D3DERR_INVALIDCALL; + } + + if ((ret = vkd3d_shader_parse_dxbc(&src_dxbc, 0, &src_dxbc_desc, NULL)) < 0) + { + WARN("Failed to parse source data, ret %d.\n", ret); + return D3DERR_INVALIDCALL; + } + + if (!(sections = vkd3d_calloc(src_dxbc_desc.section_count, sizeof(*sections)))) + { + ERR("Failed to allocate sections memory.\n"); + vkd3d_shader_free_dxbc(&src_dxbc_desc); + return E_OUTOFMEMORY; + } + + if (flags & ~(D3DCOMPILER_STRIP_REFLECTION_DATA | D3DCOMPILER_STRIP_DEBUG_INFO)) + FIXME("Unhandled flags %#x.\n", flags); + + for (i = 0, section_count = 0; i < src_dxbc_desc.section_count; ++i) + { + const struct vkd3d_shader_dxbc_section_desc *src_section = &src_dxbc_desc.sections[i]; + + if (check_blob_strip(src_section->tag, flags)) + sections[section_count++] = *src_section; + } + + if ((ret = vkd3d_shader_serialize_dxbc(section_count, sections, &dst_dxbc, NULL)) < 0) + { + WARN("Failed to serialise DXBC, ret %d.\n", ret); + hr = hresult_from_vkd3d_result(ret); + goto done; + } + + if (FAILED(hr = D3DCreateBlob(dst_dxbc.size, blob))) + WARN("Failed to create blob, hr %s.\n", debugstr_hresult(hr)); + else + memcpy(ID3D10Blob_GetBufferPointer(*blob), dst_dxbc.code, dst_dxbc.size); + vkd3d_shader_free_shader_code(&dst_dxbc); + +done: + vkd3d_free(sections); + vkd3d_shader_free_dxbc(&src_dxbc_desc); + + return hr; +} + +void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback) +{ + vkd3d_set_log_callback(callback); + vkd3d_dbg_set_log_callback(callback); +} + +HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, + UINT flags, const char *comments, ID3DBlob **blob) +{ + enum vkd3d_shader_source_type source_type; + struct vkd3d_shader_compile_info info; + struct vkd3d_shader_code output; + const char *p, *q, *end; + char *messages; + HRESULT hr; + int ret; + + static const struct vkd3d_shader_compile_option options[] = + { + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_14}, + }; + + TRACE("data %p, data_size %"PRIuPTR", flags %#x, comments %p, blob %p.\n", + data, (uintptr_t)data_size, flags, comments, blob); + + if (flags) + FIXME("Ignoring flags %#x.\n", flags); + + if (comments) + FIXME("Ignoring comments %s.\n", debugstr_a(comments)); + + if (!data_size) + return E_INVALIDARG; + + if (data_size >= sizeof(uint32_t) && *(uint32_t *)data == TAG_DXBC) + source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; + else + source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE; + + info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; + info.next = NULL; + info.source.code = data; + info.source.size = data_size; + info.source_type = source_type; + info.target_type = VKD3D_SHADER_TARGET_D3D_ASM; + info.options = options; + info.option_count = ARRAY_SIZE(options); + info.log_level = VKD3D_SHADER_LOG_INFO; + info.source_name = NULL; + + ret = vkd3d_shader_compile(&info, &output, &messages); + if (messages && *messages && WARN_ON()) + { + WARN("Compiler log:\n"); + for (p = messages, end = p + strlen(p); p < end; p = q) + { + if (!(q = memchr(p, '\n', end - p))) + q = end; + else + ++q; + WARN(" %.*s", (int)(q - p), p); + } + WARN("\n"); + } + vkd3d_shader_free_messages(messages); + + if (ret < 0) + { + WARN("Failed to disassemble shader, ret %d.\n", ret); + return hresult_from_vkd3d_result(ret); + } + + if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size, blob))) + vkd3d_shader_free_shader_code(&output); + + return hr; +} diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_private.h b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_private.h new file mode 100644 index 00000000000..11113e1e55e --- /dev/null +++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_private.h @@ -0,0 +1,44 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __VKD3D_UTILS_PRIVATE_H +#define __VKD3D_UTILS_PRIVATE_H + +#ifndef __MINGW32__ +#define WIDL_C_INLINE_WRAPPERS +#endif +#define COBJMACROS +#define NONAMELESSUNION +#define VK_NO_PROTOTYPES +#define CONST_VTABLE + +#include <vkd3d.h> +#include <vkd3d_shader.h> +#include <d3dcompiler.h> + +#include "vkd3d_blob.h" +#include "vkd3d_memory.h" +#include <vkd3d_utils.h> + +#include <inttypes.h> + +#ifndef D3DERR_INVALIDCALL +#define D3DERR_INVALIDCALL _HRESULT_TYPEDEF_(0x8876086c) +#endif + +#endif /* __VKD3D_UTILS_PRIVATE_H */
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3dcompiler_43/compiler.c | 86 ++-------------------------------- dlls/wined3d/wined3d.spec | 2 + 2 files changed, 7 insertions(+), 81 deletions(-)
diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c index 6fffcfb82ab..184af0ddd10 100644 --- a/dlls/d3dcompiler_43/compiler.c +++ b/dlls/d3dcompiler_43/compiler.c @@ -188,18 +188,15 @@ static const char *get_line(const char **ptr) return p; }
+HRESULT WINAPI vkd3d_D3DPreprocess(const void *data, SIZE_T size, const char *filename, + const D3D_SHADER_MACRO *macros, ID3DInclude *include, + ID3DBlob **preprocessed_blob, ID3DBlob **messages_blob); + static HRESULT preprocess_shader(const void *data, SIZE_T data_size, const char *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, ID3DBlob **shader_blob, ID3DBlob **messages_blob) { struct d3dcompiler_include_from_file include_from_file; - struct vkd3d_shader_preprocess_info preprocess_info; - struct vkd3d_shader_compile_info compile_info; - const D3D_SHADER_MACRO *def = defines; - struct vkd3d_shader_code byte_code; - char *messages; - HRESULT hr; - int ret;
if (include == D3D_COMPILE_STANDARD_FILE_INCLUDE) { @@ -208,78 +205,7 @@ static HRESULT preprocess_shader(const void *data, SIZE_T data_size, const char include = &include_from_file.ID3DInclude_iface; }
- compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; - compile_info.next = &preprocess_info; - compile_info.source.code = data; - compile_info.source.size = data_size; - compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; - compile_info.target_type = VKD3D_SHADER_TARGET_NONE; - compile_info.options = NULL; - compile_info.option_count = 0; - compile_info.log_level = VKD3D_SHADER_LOG_INFO; - compile_info.source_name = filename; - - preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO; - preprocess_info.next = NULL; - preprocess_info.macros = (const struct vkd3d_shader_macro *)defines; - preprocess_info.macro_count = 0; - if (defines) - { - for (def = defines; def->Name; ++def) - ++preprocess_info.macro_count; - } - preprocess_info.pfn_open_include = open_include; - preprocess_info.pfn_close_include = close_include; - preprocess_info.include_context = include; - - ret = vkd3d_shader_preprocess(&compile_info, &byte_code, &messages); - - if (ret) - ERR("Failed to preprocess shader, vkd3d result %d.\n", ret); - - if (messages) - { - if (*messages && ERR_ON(d3dcompiler)) - { - const char *ptr = messages; - const char *line; - - ERR("Shader log:\n"); - while ((line = get_line(&ptr))) - { - ERR(" %.*s", (int)(ptr - line), line); - } - ERR("\n"); - } - - if (messages_blob) - { - size_t size = strlen(messages); - if (FAILED(hr = D3DCreateBlob(size, messages_blob))) - { - vkd3d_shader_free_messages(messages); - vkd3d_shader_free_shader_code(&byte_code); - return hr; - } - memcpy(ID3D10Blob_GetBufferPointer(*messages_blob), messages, size); - } - else - { - vkd3d_shader_free_messages(messages); - } - } - - if (!ret) - { - if (FAILED(hr = D3DCreateBlob(byte_code.size, shader_blob))) - { - vkd3d_shader_free_shader_code(&byte_code); - return hr; - } - memcpy(ID3D10Blob_GetBufferPointer(*shader_blob), byte_code.code, byte_code.size); - } - - return hresult_from_vkd3d_result(ret); + return vkd3d_D3DPreprocess(data, data_size, filename, defines, include, shader_blob, messages_blob); }
static HRESULT assemble_shader(const char *preproc_shader, ID3DBlob **shader_blob, ID3DBlob **error_messages) @@ -377,7 +303,6 @@ HRESULT WINAPI D3DAssemble(const void *data, SIZE_T datasize, const char *filena if (flags) FIXME("flags %x\n", flags);
if (shader) *shader = NULL; - if (error_messages) *error_messages = NULL;
hr = preprocess_shader(data, datasize, filename, defines, include, &preproc_shader, error_messages); if (SUCCEEDED(hr)) @@ -660,7 +585,6 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename return E_INVALIDARG;
if (shader) *shader = NULL; - if (error_messages) *error_messages = NULL;
return preprocess_shader(data, size, filename, defines, include, shader, error_messages); } diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index 16c7624eb9c..d921be9511c 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -337,6 +337,8 @@ @ cdecl wined3d_vertex_declaration_get_parent(ptr) @ cdecl wined3d_vertex_declaration_incref(ptr)
+@ stdcall vkd3d_D3DPreprocess(ptr long ptr ptr ptr ptr ptr) D3DPreprocess + @ cdecl vkd3d_acquire_vk_queue(ptr) @ cdecl vkd3d_create_device(ptr ptr ptr) @ cdecl vkd3d_create_image_resource(ptr ptr ptr)
From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/d3dcompiler_43/compiler.c | 243 +-------------------------------- dlls/wined3d/wined3d.spec | 1 + 2 files changed, 8 insertions(+), 236 deletions(-)
diff --git a/dlls/d3dcompiler_43/compiler.c b/dlls/d3dcompiler_43/compiler.c index 184af0ddd10..5bf50dd3a28 100644 --- a/dlls/d3dcompiler_43/compiler.c +++ b/dlls/d3dcompiler_43/compiler.c @@ -146,31 +146,6 @@ const struct ID3DIncludeVtbl d3dcompiler_include_from_file_vtbl = d3dcompiler_include_from_file_close };
-static int open_include(const char *filename, bool local, const char *parent_data, void *context, - struct vkd3d_shader_code *code) -{ - ID3DInclude *iface = context; - unsigned int size = 0; - - if (!iface) - return VKD3D_ERROR; - - memset(code, 0, sizeof(*code)); - if (FAILED(ID3DInclude_Open(iface, local ? D3D_INCLUDE_LOCAL : D3D_INCLUDE_SYSTEM, - filename, parent_data, &code->code, &size))) - return VKD3D_ERROR; - - code->size = size; - return VKD3D_OK; -} - -static void close_include(const struct vkd3d_shader_code *code, void *context) -{ - ID3DInclude *iface = context; - - ID3DInclude_Close(iface, code->code); -} - static const char *get_line(const char **ptr) { const char *p, *q; @@ -322,56 +297,11 @@ HRESULT WINAPI D3DAssemble(const void *data, SIZE_T datasize, const char *filena return hr; }
-static enum vkd3d_shader_target_type get_target_for_profile(const char *profile) -{ - size_t profile_len, i; - - static const char * const d3dbc_profiles[] = - { - "ps.1.", - "ps.2.", - "ps.3.", - - "ps_1_", - "ps_2_", - "ps_3_", - - "vs.1.", - "vs.2.", - "vs.3.", - - "vs_1_", - "vs_2_", - "vs_3_", - - "tx_1_", - }; - - static const char * const fx_profiles[] = - { - "fx_2_0", - "fx_4_0", - "fx_4_1", - "fx_5_0", - }; - - profile_len = strlen(profile); - for (i = 0; i < ARRAY_SIZE(d3dbc_profiles); ++i) - { - size_t len = strlen(d3dbc_profiles[i]); - - if (len <= profile_len && !memcmp(profile, d3dbc_profiles[i], len)) - return VKD3D_SHADER_TARGET_D3D_BYTECODE; - } - - for (i = 0; i < ARRAY_SIZE(fx_profiles); ++i) - { - if (!strcmp(profile, fx_profiles[i])) - return VKD3D_SHADER_TARGET_FX; - } - - return VKD3D_SHADER_TARGET_DXBC_TPF; -} +HRESULT WINAPI vkd3d_D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, + const char *target, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, + ID3DBlob **error_messages, unsigned int compiler_version);
HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filename, const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entry_point, @@ -380,16 +310,6 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen ID3DBlob **messages_blob) { struct d3dcompiler_include_from_file include_from_file; - struct vkd3d_shader_preprocess_info preprocess_info; - struct vkd3d_shader_hlsl_source_info hlsl_info; - struct vkd3d_shader_compile_option options[6]; - struct vkd3d_shader_compile_info compile_info; - struct vkd3d_shader_compile_option *option; - struct vkd3d_shader_code byte_code; - const D3D_SHADER_MACRO *macro; - char *messages; - HRESULT hr; - int ret;
TRACE("data %p, data_size %Iu, filename %s, macros %p, include %p, entry_point %s, " "profile %s, flags %#x, effect_flags %#x, secondary_flags %#x, secondary_data %p, " @@ -405,160 +325,11 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen include = &include_from_file.ID3DInclude_iface; }
- if (flags & ~(D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR - | D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY)) - { - FIXME("Ignoring flags %#x.\n", flags); - } - if (effect_flags & ~D3DCOMPILE_EFFECT_CHILD_EFFECT) - FIXME("Ignoring effect flags %#x.\n", effect_flags & ~D3DCOMPILE_EFFECT_CHILD_EFFECT); - if (secondary_flags) - FIXME("Ignoring secondary flags %#x.\n", secondary_flags); - if (shader_blob) *shader_blob = NULL; - if (messages_blob) - *messages_blob = NULL; - - option = &options[0]; - option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; - option->value = VKD3D_SHADER_API_VERSION_1_3; - - compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; - compile_info.next = &preprocess_info; - compile_info.source.code = data; - compile_info.source.size = data_size; - compile_info.source_type = VKD3D_SHADER_SOURCE_HLSL; - compile_info.target_type = get_target_for_profile(profile); - compile_info.options = options; - compile_info.option_count = 1; - compile_info.log_level = VKD3D_SHADER_LOG_INFO; - compile_info.source_name = filename; - - preprocess_info.type = VKD3D_SHADER_STRUCTURE_TYPE_PREPROCESS_INFO; - preprocess_info.next = &hlsl_info; - preprocess_info.macros = (const struct vkd3d_shader_macro *)macros; - preprocess_info.macro_count = 0; - if (macros) - { - for (macro = macros; macro->Name; ++macro) - ++preprocess_info.macro_count; - } - preprocess_info.pfn_open_include = open_include; - preprocess_info.pfn_close_include = close_include; - preprocess_info.include_context = include; - - hlsl_info.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO; - hlsl_info.next = NULL; - hlsl_info.profile = profile; - hlsl_info.entry_point = entry_point; - hlsl_info.secondary_code.code = secondary_data; - hlsl_info.secondary_code.size = secondary_data_size; - - if (!(flags & D3DCOMPILE_DEBUG)) - { - option = &options[compile_info.option_count++]; - option->name = VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG; - option->value = true; - } - - if (flags & D3DCOMPILE_PACK_MATRIX_ROW_MAJOR) - { - option = &options[compile_info.option_count++]; - option->name = VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER; - option->value = VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR; - } - else if (flags & D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR) - { - option = &options[compile_info.option_count++]; - option->name = VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER; - option->value = VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR; - } - - if (flags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY) - { - option = &options[compile_info.option_count++]; - option->name = VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY; - option->value = VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES; - } - - if (effect_flags & D3DCOMPILE_EFFECT_CHILD_EFFECT) - { - option = &options[compile_info.option_count++]; - option->name = VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT; - option->value = true; - } - -#if D3D_COMPILER_VERSION <= 39 - option = &options[compile_info.option_count++]; - option->name = VKD3D_SHADER_COMPILE_OPTION_INCLUDE_EMPTY_BUFFERS_IN_EFFECTS; - option->value = true; -#endif - - ret = vkd3d_shader_compile(&compile_info, &byte_code, &messages); - - if (ret) - ERR("Failed to compile shader, vkd3d result %d.\n", ret); - - if (messages) - { - if (*messages && ERR_ON(d3dcompiler)) - { - const char *ptr = messages; - const char *line; - - ERR("Shader log:\n"); - while ((line = get_line(&ptr))) - { - ERR(" %.*s", (int)(ptr - line), line); - } - ERR("\n"); - }
- if (messages_blob) - { - size_t size = strlen(messages); - if (FAILED(hr = D3DCreateBlob(size, messages_blob))) - { - vkd3d_shader_free_messages(messages); - vkd3d_shader_free_shader_code(&byte_code); - return hr; - } - memcpy(ID3D10Blob_GetBufferPointer(*messages_blob), messages, size); - } - - vkd3d_shader_free_messages(messages); - } - - if (ret) - return hresult_from_vkd3d_result(ret); - - if (!shader_blob) - { - vkd3d_shader_free_shader_code(&byte_code); - return S_OK; - } - - /* Unlike other effect profiles fx_4_x is using DXBC container. */ - if (!strcmp(profile, "fx_4_0") || !strcmp(profile, "fx_4_1")) - { - struct vkd3d_shader_dxbc_section_desc section = { .tag = TAG_FX10, .data = byte_code }; - struct vkd3d_shader_code dxbc; - - ret = vkd3d_shader_serialize_dxbc(1, §ion, &dxbc, NULL); - vkd3d_shader_free_shader_code(&byte_code); - if (ret) - return hresult_from_vkd3d_result(ret); - - byte_code = dxbc; - } - - if (SUCCEEDED(hr = D3DCreateBlob(byte_code.size, shader_blob))) - memcpy(ID3D10Blob_GetBufferPointer(*shader_blob), byte_code.code, byte_code.size); - - vkd3d_shader_free_shader_code(&byte_code); - - return hr; + return vkd3d_D3DCompile2VKD3D(data, data_size, filename, macros, include, entry_point, profile, flags, effect_flags, + secondary_flags, secondary_data, secondary_data_size, shader_blob, messages_blob, D3D_COMPILER_VERSION); }
HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec index d921be9511c..f4a8cf5c0b5 100644 --- a/dlls/wined3d/wined3d.spec +++ b/dlls/wined3d/wined3d.spec @@ -338,6 +338,7 @@ @ cdecl wined3d_vertex_declaration_incref(ptr)
@ stdcall vkd3d_D3DPreprocess(ptr long ptr ptr ptr ptr ptr) D3DPreprocess +@ stdcall vkd3d_D3DCompile2VKD3D(ptr long ptr ptr ptr ptr ptr long long long ptr long ptr ptr long) D3DCompile2VKD3D
@ cdecl vkd3d_acquire_vk_queue(ptr) @ cdecl vkd3d_create_device(ptr ptr ptr)
From: Elizabeth Figura zfigura@codeweavers.com
This reflects native, and may be necessary to reflect changes in behaviour before version 33 (although no such differences are yet known to matter).
By supplying the D3DX SDK version we also now reflect differences in behaviour between different D3DX versions.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=33770 --- dlls/d3dx9_24/Makefile.in | 2 +- dlls/d3dx9_25/Makefile.in | 2 +- dlls/d3dx9_26/Makefile.in | 2 +- dlls/d3dx9_27/Makefile.in | 2 +- dlls/d3dx9_28/Makefile.in | 2 +- dlls/d3dx9_29/Makefile.in | 2 +- dlls/d3dx9_30/Makefile.in | 2 +- dlls/d3dx9_31/Makefile.in | 2 +- dlls/d3dx9_32/Makefile.in | 2 +- dlls/d3dx9_33/Makefile.in | 2 +- dlls/d3dx9_34/Makefile.in | 2 +- dlls/d3dx9_35/Makefile.in | 2 +- dlls/d3dx9_36/Makefile.in | 2 +- dlls/d3dx9_36/shader.c | 28 +++++++++++++++++----------- dlls/d3dx9_37/Makefile.in | 2 +- dlls/d3dx9_38/Makefile.in | 2 +- dlls/d3dx9_39/Makefile.in | 2 +- dlls/d3dx9_40/Makefile.in | 2 +- dlls/d3dx9_41/Makefile.in | 2 +- 19 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/dlls/d3dx9_24/Makefile.in b/dlls/d3dx9_24/Makefile.in index d0fef3bebd0..3f3fc57bfb5 100644 --- a/dlls/d3dx9_24/Makefile.in +++ b/dlls/d3dx9_24/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=24 MODULE = d3dx9_24.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_25/Makefile.in b/dlls/d3dx9_25/Makefile.in index 869c1162904..93691cfb23d 100644 --- a/dlls/d3dx9_25/Makefile.in +++ b/dlls/d3dx9_25/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=25 MODULE = d3dx9_25.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_26/Makefile.in b/dlls/d3dx9_26/Makefile.in index ae3f2e18953..b7369e7810e 100644 --- a/dlls/d3dx9_26/Makefile.in +++ b/dlls/d3dx9_26/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=26 MODULE = d3dx9_26.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_27/Makefile.in b/dlls/d3dx9_27/Makefile.in index 4f2993638f3..da4e396db86 100644 --- a/dlls/d3dx9_27/Makefile.in +++ b/dlls/d3dx9_27/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=27 MODULE = d3dx9_27.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_28/Makefile.in b/dlls/d3dx9_28/Makefile.in index 3c7ddb93c2e..b321e3605af 100644 --- a/dlls/d3dx9_28/Makefile.in +++ b/dlls/d3dx9_28/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=28 MODULE = d3dx9_28.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_29/Makefile.in b/dlls/d3dx9_29/Makefile.in index 75eb3e73243..c1bee84ca0c 100644 --- a/dlls/d3dx9_29/Makefile.in +++ b/dlls/d3dx9_29/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=29 MODULE = d3dx9_29.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_30/Makefile.in b/dlls/d3dx9_30/Makefile.in index 9b8eb133611..da162dae334 100644 --- a/dlls/d3dx9_30/Makefile.in +++ b/dlls/d3dx9_30/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=30 MODULE = d3dx9_30.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_31/Makefile.in b/dlls/d3dx9_31/Makefile.in index 52d3a3d0986..d973244f620 100644 --- a/dlls/d3dx9_31/Makefile.in +++ b/dlls/d3dx9_31/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=31 MODULE = d3dx9_31.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_32/Makefile.in b/dlls/d3dx9_32/Makefile.in index 70a1696de97..1b2fb450b92 100644 --- a/dlls/d3dx9_32/Makefile.in +++ b/dlls/d3dx9_32/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=32 MODULE = d3dx9_32.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_33/Makefile.in b/dlls/d3dx9_33/Makefile.in index 2c01e9da3d9..038280385e3 100644 --- a/dlls/d3dx9_33/Makefile.in +++ b/dlls/d3dx9_33/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=33 MODULE = d3dx9_33.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_34/Makefile.in b/dlls/d3dx9_34/Makefile.in index 1e317f37226..1cb2deace74 100644 --- a/dlls/d3dx9_34/Makefile.in +++ b/dlls/d3dx9_34/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=34 MODULE = d3dx9_34.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_35/Makefile.in b/dlls/d3dx9_35/Makefile.in index 859cef9b1ce..0c8d93acf7e 100644 --- a/dlls/d3dx9_35/Makefile.in +++ b/dlls/d3dx9_35/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=35 MODULE = d3dx9_35.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_36/Makefile.in b/dlls/d3dx9_36/Makefile.in index 5370b3e7e7a..798ae4c2c1d 100644 --- a/dlls/d3dx9_36/Makefile.in +++ b/dlls/d3dx9_36/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=36 MODULE = d3dx9_36.dll IMPORTLIB = d3dx9 -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d DELAYIMPORTS = windowscodecs
EXTRADLLFLAGS = -Wb,--prefer-native diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c index 88c4916b74d..dec6352d174 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c @@ -431,6 +431,12 @@ HRESULT WINAPI D3DXAssembleShaderFromResourceW(HMODULE module, const WCHAR *reso shader, error_messages); }
+HRESULT WINAPI vkd3d_D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char *filename, + const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, + const char *target, UINT flags, UINT effect_flags, UINT secondary_flags, + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, + ID3DBlob **error_messages, unsigned int compiler_version); + HRESULT WINAPI D3DXCompileShader(const char *data, UINT length, const D3DXMACRO *defines, ID3DXInclude *include, const char *function, const char *profile, DWORD flags, ID3DXBuffer **shader, ID3DXBuffer **error_msgs, ID3DXConstantTable **constant_table) @@ -443,10 +449,18 @@ HRESULT WINAPI D3DXCompileShader(const char *data, UINT length, const D3DXMACRO flags, shader, error_msgs, constant_table);
if (D3DX_SDK_VERSION <= 36) - flags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; + flags |= D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY; + +#if D3DX_SDK_VERSION < 42 + if (shader) + *shader = NULL;
+ hr = vkd3d_D3DCompile2VKD3D(data, length, NULL, (D3D_SHADER_MACRO *)defines, (ID3DInclude *)include, + function, profile, flags, 0, 0, NULL, 0, (ID3DBlob **)shader, (ID3DBlob **)error_msgs, D3DX_SDK_VERSION); +#else hr = D3DCompile(data, length, NULL, (D3D_SHADER_MACRO *)defines, (ID3DInclude *)include, function, profile, flags, 0, (ID3DBlob **)shader, (ID3DBlob **)error_msgs); +#endif
if (SUCCEEDED(hr) && constant_table) { @@ -526,16 +540,8 @@ HRESULT WINAPI D3DXCompileShaderFromFileW(const WCHAR *filename, const D3DXMACRO return D3DXERR_INVALIDDATA; }
- if (D3DX_SDK_VERSION <= 36) - flags |= D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY; - - hr = D3DCompile(buffer, len, filename_a, (const D3D_SHADER_MACRO *)defines, - (ID3DInclude *)include, entrypoint, profile, flags, 0, - (ID3DBlob **)shader, (ID3DBlob **)error_messages); - - if (SUCCEEDED(hr) && constant_table) - hr = D3DXGetShaderConstantTable(ID3DXBuffer_GetBufferPointer(*shader), - constant_table); + hr = D3DXCompileShader(buffer, len, defines, include, entrypoint, + profile, flags, shader, error_messages, constant_table);
ID3DXInclude_Close(include, buffer); LeaveCriticalSection(&from_file_mutex); diff --git a/dlls/d3dx9_37/Makefile.in b/dlls/d3dx9_37/Makefile.in index 150f1ceb215..b61c8ceddf5 100644 --- a/dlls/d3dx9_37/Makefile.in +++ b/dlls/d3dx9_37/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=37 MODULE = d3dx9_37.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_38/Makefile.in b/dlls/d3dx9_38/Makefile.in index 5706fe9b203..4d9a11580bc 100644 --- a/dlls/d3dx9_38/Makefile.in +++ b/dlls/d3dx9_38/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=38 MODULE = d3dx9_38.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_39/Makefile.in b/dlls/d3dx9_39/Makefile.in index 9e8f8f6199e..6ff59e7b98e 100644 --- a/dlls/d3dx9_39/Makefile.in +++ b/dlls/d3dx9_39/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=39 MODULE = d3dx9_39.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_40/Makefile.in b/dlls/d3dx9_40/Makefile.in index fe10a5d3dcb..ae63a814403 100644 --- a/dlls/d3dx9_40/Makefile.in +++ b/dlls/d3dx9_40/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=40 MODULE = d3dx9_40.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_41/Makefile.in b/dlls/d3dx9_41/Makefile.in index bc02a280d33..9fdc2884e1b 100644 --- a/dlls/d3dx9_41/Makefile.in +++ b/dlls/d3dx9_41/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=41 MODULE = d3dx9_41.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 wined3d PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
From: Elizabeth Figura zfigura@codeweavers.com
Instead of linking both versions to version 47. --- dlls/d3dcompiler_42/Makefile.in | 1 + dlls/d3dx9_42/Makefile.in | 2 +- dlls/d3dx9_43/Makefile.in | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/d3dcompiler_42/Makefile.in b/dlls/d3dcompiler_42/Makefile.in index 9f4f571b5bd..a94eb9a2f63 100644 --- a/dlls/d3dcompiler_42/Makefile.in +++ b/dlls/d3dcompiler_42/Makefile.in @@ -1,4 +1,5 @@ MODULE = d3dcompiler_42.dll +IMPORTLIB = d3dcompiler_42 IMPORTS = wined3d EXTRADEFS = -DD3D_COMPILER_VERSION=42 PARENTSRC = ../d3dcompiler_43 diff --git a/dlls/d3dx9_42/Makefile.in b/dlls/d3dx9_42/Makefile.in index 5efa6cc00cd..853a70af106 100644 --- a/dlls/d3dx9_42/Makefile.in +++ b/dlls/d3dx9_42/Makefile.in @@ -1,6 +1,6 @@ EXTRADEFS = -DD3DX_SDK_VERSION=42 MODULE = d3dx9_42.dll -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler_42 dxguid d3dxof ole32 gdi32 user32 PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
diff --git a/dlls/d3dx9_43/Makefile.in b/dlls/d3dx9_43/Makefile.in index 1d661859876..0ba2e5e8fe0 100644 --- a/dlls/d3dx9_43/Makefile.in +++ b/dlls/d3dx9_43/Makefile.in @@ -1,7 +1,7 @@ EXTRADEFS = -DD3DX_SDK_VERSION=43 MODULE = d3dx9_43.dll IMPORTLIB = d3dx9_43 -IMPORTS = d3d9 d3dcompiler dxguid d3dxof ole32 gdi32 user32 +IMPORTS = d3d9 d3dcompiler_43 dxguid d3dxof ole32 gdi32 user32 PARENTSRC = ../d3dx9_36 DELAYIMPORTS = windowscodecs
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150275
Your paranoid android.
=== debian11 (build log) ===
error: patch failed: configure.ac:1134 error: patch failed: dlls/wined3d/wined3d_main.c:30 error: patch failed: libs/vkd3d/Makefile.in:31 Task: Patch failed to apply
=== debian11b (build log) ===
error: patch failed: configure.ac:1134 error: patch failed: dlls/wined3d/wined3d_main.c:30 error: patch failed: libs/vkd3d/Makefile.in:31 Task: Patch failed to apply
I've submitted a new version that uses D3DCompile2VKD3D() directly, including from d3dx9.
This does require the latest version of vkd3d, which can make e.g. bisecting difficult. This is not a new problem, but it was raised to me off-list. Unfortunately there is not really a way to prevent this without significant changes. The vkd3d headers do not include any indication of the version, and we cannot rely on compile tests since we cannot access config.h.
On Fri Dec 6 20:53:38 2024 +0000, Elizabeth Figura wrote:
I've submitted a new version that uses D3DCompile2VKD3D() directly, including from d3dx9. This does require the latest version of vkd3d, which can make e.g. bisecting difficult. This is not a new problem, but it was raised to me off-list. Unfortunately there is not really a way to prevent this without significant changes. The vkd3d headers do not include any indication of the version, and we cannot rely on compile tests since we cannot access config.h.
Yeah, it's tricky, but if we have to "break" bisecting better sooner rather than later, I guess.
Honest question: which version do you prefer, this or the old one? Having now seen both, I'm okay with either.
The failing tests seem legitimate, pointing to (small) issues with the vkd3d-utils implementation.
Honest question: which version do you prefer, this or the old one? Having now seen both, I'm okay with either.
I think deferring to vkd3d-utils is a significant improvement.
Wrt bisecting, I think any bisect of vkd3d-shader can be more easily done by just using vkd3d-compiler directly anyway, so I wouldn't place all that much weight on that concern personally.
The failing tests seem legitimate, pointing to (small) issues with the vkd3d-utils implementation.
Indeed. I've sent a vkd3d merge request. This can wait until the next vkd3d merge, then.