Hi,
attached is a hacky patch which forwards the reflection interface from
d3dcompiler_41 to d3dcompiler_43.
I have a question to that implementation:
DEFINE_GUID is used twice (dlls/dxguid/dx10guid.c and
dlls/d3dcompiler_41/reflection.c) which could be bad. But the define was
removed from the d3d11shader.h from ms, so it isn't officially available
anymore. Should that be in a separate header to reduce redundancy or is
the usage of both defines fine here?
Cheers
Rico
diff --git a/dlls/d3dcompiler_41/Makefile.in b/dlls/d3dcompiler_41/Makefile.in
index 338d408..ca31e89 100644
--- a/dlls/d3dcompiler_41/Makefile.in
+++ b/dlls/d3dcompiler_41/Makefile.in
@@ -1,7 +1,9 @@
MODULE = d3dcompiler_41.dll
+IMPORTS = dxguid uuid
C_SRCS = \
- d3dcompiler_41_main.c
+ d3dcompiler_41_main.c \
+ reflection.c
RC_SRCS = version.rc
diff --git a/dlls/d3dcompiler_41/d3dcompiler_41.spec b/dlls/d3dcompiler_41/d3dcompiler_41.spec
index 84adee3..fb55e54 100644
--- a/dlls/d3dcompiler_41/d3dcompiler_41.spec
+++ b/dlls/d3dcompiler_41/d3dcompiler_41.spec
@@ -8,6 +8,6 @@
@ stdcall D3DGetInputSignatureBlob(ptr long ptr) d3dcompiler_43.D3DGetInputSignatureBlob
@ stdcall D3DGetOutputSignatureBlob(ptr long ptr) d3dcompiler_43.D3DGetOutputSignatureBlob
@ stdcall D3DPreprocess(ptr long str ptr ptr ptr ptr) d3dcompiler_43.D3DPreprocess
-@ stdcall D3DReflect(ptr long ptr ptr) d3dcompiler_43.D3DReflect
+@ stdcall D3DReflect(ptr long ptr ptr)
@ stub D3DReturnFailure1
@ stdcall D3DStripShader(ptr long long ptr) d3dcompiler_43.D3DStripShader
diff --git a/dlls/d3dcompiler_41/reflection.c b/dlls/d3dcompiler_41/reflection.c
new file mode 100644
index 0000000..3589e1c
--- /dev/null
+++ b/dlls/d3dcompiler_41/reflection.c
@@ -0,0 +1,397 @@
+/*
+ * 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 "config.h"
+#include "wine/port.h"
+
+#include "wine/debug.h"
+#include "wine/list.h"
+#include "wine/rbtree.h"
+
+#define COBJMACROS
+#include "windef.h"
+#include "winbase.h"
+#include "objbase.h"
+
+#include "d3dcompiler.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(d3dcompiler);
+
+DEFINE_GUID(IID_ID3D11ShaderReflection41, 0x17f27486, 0xa342, 0x4d10, 0x88, 0x42, 0xab, 0x08, 0x74, 0xe7, 0xf6, 0x70);
+
+#define INTERFACE ID3D11ShaderReflection41
+DECLARE_INTERFACE_(ID3D11ShaderReflection41, IUnknown)
+{
+ /* IUnknown methods */
+ STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *object) PURE;
+ STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+ STDMETHOD_(ULONG, Release)(THIS) PURE;
+ /* ID3D11ShaderReflection methods */
+ STDMETHOD(GetDesc)(THIS_ D3D11_SHADER_DESC *desc) PURE;
+ STDMETHOD_(struct ID3D11ShaderReflectionConstantBuffer *, GetConstantBufferByIndex)(THIS_ UINT index) PURE;
+ STDMETHOD_(struct ID3D11ShaderReflectionConstantBuffer *, GetConstantBufferByName)(THIS_ LPCSTR name) PURE;
+ STDMETHOD(GetResourceBindingDesc)(THIS_ UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc) PURE;
+ STDMETHOD(GetInputParameterDesc)(THIS_ UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) PURE;
+ STDMETHOD(GetOutputParameterDesc)(THIS_ UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) PURE;
+ STDMETHOD(GetPatchConstantParameterDesc)(THIS_ UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc) PURE;
+ STDMETHOD_(struct ID3D11ShaderReflectionVariable *, GetVariableByName)(THIS_ LPCSTR name) PURE;
+ STDMETHOD(GetResourceBindingDescByName)(THIS_ LPCSTR name, D3D11_SHADER_INPUT_BIND_DESC *desc) PURE;
+ STDMETHOD_(UINT, GetMovInstructionCount)(THIS) PURE;
+ STDMETHOD_(UINT, GetMovcInstructionCount)(THIS) PURE;
+ STDMETHOD_(UINT, GetConversionInstructionCount)(THIS) PURE;
+ STDMETHOD_(UINT, GetBitwiseInstructionCount)(THIS) PURE;
+ STDMETHOD_(D3D_PRIMITIVE, GetGSInputPrimitive)(THIS) PURE;
+ STDMETHOD_(BOOL, IsSampleFrequencyShader)(THIS) PURE;
+ STDMETHOD_(UINT, GetNumInterfaceSlots)(THIS) PURE;
+ STDMETHOD(GetMinFeatureLevel)(THIS_ enum D3D_FEATURE_LEVEL *level) PURE;
+};
+#undef INTERFACE
+
+/* ID3D11ShaderReflection */
+struct d3dcompiler_shader_reflection
+{
+ ID3D11ShaderReflection41 ID3D11ShaderReflection_iface;
+ LONG refcount;
+
+ ID3D11ShaderReflection *reflection;
+};
+
+/* IUnknown methods */
+
+static inline struct d3dcompiler_shader_reflection *impl_from_ID3D11ShaderReflection(ID3D11ShaderReflection *iface)
+{
+ return CONTAINING_RECORD(iface, struct d3dcompiler_shader_reflection, ID3D11ShaderReflection_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_QueryInterface(ID3D11ShaderReflection *iface, REFIID riid, void **object)
+{
+ TRACE("iface %p, riid %s, object %p\n", iface, debugstr_guid(riid), object);
+
+ if (IsEqualGUID(riid, &IID_ID3D11ShaderReflection41)
+ || IsEqualGUID(riid, &IID_IUnknown))
+ {
+ IUnknown_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 d3dcompiler_shader_reflection_AddRef(ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ULONG refcount = InterlockedIncrement(&This->refcount);
+
+ TRACE("%p increasing refcount to %u\n", This, refcount);
+
+ return refcount;
+}
+
+static ULONG STDMETHODCALLTYPE d3dcompiler_shader_reflection_Release(ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+ ULONG refcount = InterlockedDecrement(&This->refcount);
+
+ TRACE("%p decreasing refcount to %u\n", This, refcount);
+
+ if (!refcount)
+ {
+ ref->lpVtbl->Release(ref);
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return refcount;
+}
+
+/* ID3D11ShaderReflection methods */
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetDesc(ID3D11ShaderReflection *iface, D3D11_SHADER_DESC *desc)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, desc %p\n", iface, desc);
+
+ return ref->lpVtbl->GetDesc(ref, desc);
+}
+
+static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByIndex(
+ ID3D11ShaderReflection *iface, UINT index)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, index %u\n", iface, index);
+
+ return ref->lpVtbl->GetConstantBufferByIndex(ref, index);
+}
+
+static struct ID3D11ShaderReflectionConstantBuffer * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConstantBufferByName(
+ ID3D11ShaderReflection *iface, LPCSTR name)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, name %s\n", iface, debugstr_a(name));
+
+ return ref->lpVtbl->GetConstantBufferByName(ref, name);
+}
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDesc(
+ ID3D11ShaderReflection *iface, UINT index, D3D11_SHADER_INPUT_BIND_DESC *desc)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
+
+ return ref->lpVtbl->GetResourceBindingDesc(ref, index, desc);
+}
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetInputParameterDesc(
+ ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
+
+ return ref->lpVtbl->GetInputParameterDesc(ref, index, desc);
+}
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetOutputParameterDesc(
+ ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
+
+ return ref->lpVtbl->GetOutputParameterDesc(ref, index, desc);
+}
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetPatchConstantParameterDesc(
+ ID3D11ShaderReflection *iface, UINT index, D3D11_SIGNATURE_PARAMETER_DESC *desc)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, index %u, desc %p\n", iface, index, desc);
+
+ return ref->lpVtbl->GetPatchConstantParameterDesc(ref, index, desc);
+}
+
+static struct ID3D11ShaderReflectionVariable * STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetVariableByName(
+ ID3D11ShaderReflection *iface, LPCSTR name)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, name %s\n", iface, debugstr_a(name));
+
+ return ref->lpVtbl->GetVariableByName(ref, name);
+}
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetResourceBindingDescByName(
+ ID3D11ShaderReflection *iface, LPCSTR name, D3D11_SHADER_INPUT_BIND_DESC *desc)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, name %s, desc %p\n", iface, debugstr_a(name), desc);
+
+ return ref->lpVtbl->GetResourceBindingDescByName(ref, name, desc);
+}
+
+static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovInstructionCount(
+ ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p\n", iface);
+
+ return ref->lpVtbl->GetMovInstructionCount(ref);
+}
+
+static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMovcInstructionCount(
+ ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p\n", iface);
+
+ return ref->lpVtbl->GetMovcInstructionCount(ref);
+}
+
+static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetConversionInstructionCount(
+ ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p\n", iface);
+
+ return ref->lpVtbl->GetConversionInstructionCount(ref);
+}
+
+static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetBitwiseInstructionCount(
+ ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p\n", iface);
+
+ return ref->lpVtbl->GetBitwiseInstructionCount(ref);
+}
+
+static D3D_PRIMITIVE STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetGSInputPrimitive(
+ ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p\n", iface);
+
+ return ref->lpVtbl->GetGSInputPrimitive(ref);
+}
+
+static BOOL STDMETHODCALLTYPE d3dcompiler_shader_reflection_IsSampleFrequencyShader(
+ ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p\n", iface);
+
+ return ref->lpVtbl->IsSampleFrequencyShader(ref);
+}
+
+static UINT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetNumInterfaceSlots(
+ ID3D11ShaderReflection *iface)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p\n", iface);
+
+ return ref->lpVtbl->GetNumInterfaceSlots(ref);
+}
+
+static HRESULT STDMETHODCALLTYPE d3dcompiler_shader_reflection_GetMinFeatureLevel(
+ ID3D11ShaderReflection *iface, D3D_FEATURE_LEVEL *level)
+{
+ struct d3dcompiler_shader_reflection *This = impl_from_ID3D11ShaderReflection(iface);
+ ID3D11ShaderReflection *ref = This->reflection;
+
+ TRACE("iface %p, level %p\n", iface, level);
+
+ return ref->lpVtbl->GetMinFeatureLevel(ref, level);
+}
+
+const struct ID3D11ShaderReflectionVtbl d3dcompiler_shader_reflection_vtbl =
+{
+ /* IUnknown methods */
+ d3dcompiler_shader_reflection_QueryInterface,
+ d3dcompiler_shader_reflection_AddRef,
+ d3dcompiler_shader_reflection_Release,
+ /* ID3D11ShaderReflection methods */
+ d3dcompiler_shader_reflection_GetDesc,
+ d3dcompiler_shader_reflection_GetConstantBufferByIndex,
+ d3dcompiler_shader_reflection_GetConstantBufferByName,
+ d3dcompiler_shader_reflection_GetResourceBindingDesc,
+ d3dcompiler_shader_reflection_GetInputParameterDesc,
+ d3dcompiler_shader_reflection_GetOutputParameterDesc,
+ d3dcompiler_shader_reflection_GetPatchConstantParameterDesc,
+ d3dcompiler_shader_reflection_GetVariableByName,
+ d3dcompiler_shader_reflection_GetResourceBindingDescByName,
+ d3dcompiler_shader_reflection_GetMovInstructionCount,
+ d3dcompiler_shader_reflection_GetMovcInstructionCount,
+ d3dcompiler_shader_reflection_GetConversionInstructionCount,
+ d3dcompiler_shader_reflection_GetBitwiseInstructionCount,
+ d3dcompiler_shader_reflection_GetGSInputPrimitive,
+ d3dcompiler_shader_reflection_IsSampleFrequencyShader,
+ d3dcompiler_shader_reflection_GetNumInterfaceSlots,
+ d3dcompiler_shader_reflection_GetMinFeatureLevel,
+};
+
+HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID riid, void **reflector)
+{
+ struct d3dcompiler_shader_reflection *object;
+ HRESULT hr;
+ HMODULE dll_handle = NULL;
+ HRESULT (WINAPI * d3dreflect)(const void *data, SIZE_T data_size, REFIID riid, void **reflector);
+
+ TRACE("data %p, data_size %lu, riid %s, blob %p\n", data, data_size, debugstr_guid(riid), reflector);
+
+ if (!IsEqualGUID(riid, &IID_ID3D11ShaderReflection41))
+ {
+ WARN("Wrong riid %s, accept only %s!\n", debugstr_guid(riid), debugstr_guid(&IID_ID3D11ShaderReflection41));
+ return E_NOINTERFACE;
+ }
+
+ dll_handle = LoadLibraryA("d3dcompiler_43.dll");
+ if (!dll_handle)
+ {
+ ERR("Could not load d3dcompiler_43.dll.\n");
+ return E_FAIL;
+ }
+
+ d3dreflect = (void *)GetProcAddress(dll_handle, "D3DReflect");
+ if (!d3dreflect)
+ {
+ FreeLibrary(dll_handle);
+ ERR("Could not get function pointer D3DReflect in d3dcompiler_43.dll.\n");
+ return E_FAIL;
+ }
+
+ object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
+ if (!object)
+ {
+ ERR("Failed to allocate D3D compiler shader reflection object memory\n");
+ return E_OUTOFMEMORY;
+ }
+
+ hr = d3dreflect(data, data_size, &IID_ID3D11ShaderReflection, (void **)&object->reflection);
+ FreeLibrary(dll_handle);
+
+ if (FAILED(hr))
+ {
+ WARN("Failed to initialize shader reflection\n");
+ HeapFree(GetProcessHeap(), 0, object);
+ return hr;
+ }
+
+ object->ID3D11ShaderReflection_iface.lpVtbl = &d3dcompiler_shader_reflection_vtbl;
+ object->refcount = 1;
+
+ *reflector = object;
+
+ TRACE("Created ID3D11ShaderReflection %p\n", object);
+
+ return S_OK;
+}
diff --git a/dlls/dxguid/dx10guid.c b/dlls/dxguid/dx10guid.c
index 1d07a4d..bd567ec 100644
--- a/dlls/dxguid/dx10guid.c
+++ b/dlls/dxguid/dx10guid.c
@@ -35,3 +35,7 @@
#include "d3d11.h"
#include "d3d10_1shader.h"
#include "d3d11shader.h"
+
+/* d3d11 guid for reflection interface version 41/42 */
+DEFINE_GUID(IID_ID3D11ShaderReflection41, 0x17f27486, 0xa342, 0x4d10, 0x88, 0x42, 0xab, 0x08, 0x74, 0xe7, 0xf6, 0x70);
+