Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
For RenderDoc in Wine.
--- dlls/dxgi/adapter.c | 18 +++++++++++++++--- include/wine/winedxgi.idl | 9 +++++++++ 2 files changed, 24 insertions(+), 3 deletions(-)
diff --git a/dlls/dxgi/adapter.c b/dlls/dxgi/adapter.c index 5440f2a64517..2ebf24e9b48e 100644 --- a/dlls/dxgi/adapter.c +++ b/dlls/dxgi/adapter.c @@ -33,7 +33,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryInterface(IDXGIAdapter1 *ifac { TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_IDXGIAdapter1) + if (IsEqualGUID(iid, &IID_IWineDXGIAdapter) + || IsEqualGUID(iid, &IID_IDXGIAdapter1) || IsEqualGUID(iid, &IID_IDXGIAdapter) || IsEqualGUID(iid, &IID_IDXGIObject) || IsEqualGUID(iid, &IID_IUnknown)) @@ -260,10 +261,21 @@ static const struct IDXGIAdapter1Vtbl dxgi_adapter_vtbl =
struct dxgi_adapter *unsafe_impl_from_IDXGIAdapter1(IDXGIAdapter1 *iface) { + IWineDXGIAdapter *wine_adapter; + struct dxgi_adapter *adapter; + HRESULT hr; + if (!iface) return NULL; - assert(iface->lpVtbl == &dxgi_adapter_vtbl); - return CONTAINING_RECORD(iface, struct dxgi_adapter, IDXGIAdapter1_iface); + if (FAILED(hr = IDXGIAdapter1_QueryInterface(iface, &IID_IWineDXGIAdapter, (void **)&wine_adapter))) + { + ERR("Failed to get IWineDXGIAdapter interface, hr %#x.\n", hr); + return NULL; + } + assert(wine_adapter->lpVtbl == (void *)&dxgi_adapter_vtbl); + adapter = CONTAINING_RECORD(wine_adapter, struct dxgi_adapter, IDXGIAdapter1_iface); + IWineDXGIAdapter_Release(wine_adapter); + return adapter; }
static void dxgi_adapter_init(struct dxgi_adapter *adapter, struct dxgi_factory *factory, UINT ordinal) diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index a4f715b60766..983cdba68d14 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -50,3 +50,12 @@ interface IWineDXGIDeviceParent : IUnknown { struct wined3d_device_parent *get_wined3d_device_parent(); } + +[ + object, + local, + uuid(17399d75-964e-4c03-99f8-9d4fd196dd62) +] +interface IWineDXGIAdapter : IDXGIAdapter1 +{ +}
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
Fixes memory corruption when processing winedxgi.idl after changes in one of the next patches.
--- tools/widl/parser.l | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 6520ce72e6b3..6afc3e7ef19c 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -78,7 +78,7 @@ static int attr_token(const char *kw);
static warning_list_t *disabled_warnings = NULL;
-#define MAX_IMPORT_DEPTH 10 +#define MAX_IMPORT_DEPTH 20 struct { YY_BUFFER_STATE state; char *input_name; @@ -524,6 +524,9 @@ int do_import(char *fname) else if (!(path = wpp_find_include( fname, input_name ))) error_loc("Unable to open include file %s\n", fname);
+ if (import_stack_ptr == MAX_IMPORT_DEPTH) + error_loc("Exceeded max import depth\n"); + import_stack[ptr].temp_name = temp_name; import_stack[ptr].input_name = input_name; import_stack[ptr].line_number = line_number;
Use 4-space indents.
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
4 spaces are consistent with more recent changes in the file, e.g. warning_enable(), do_warning(), is_warning_enabled().
--- tools/widl/parser.l | 88 ++++++++++++++++++++++++++--------------------------- 1 file changed, 44 insertions(+), 44 deletions(-)
diff --git a/tools/widl/parser.l b/tools/widl/parser.l index 6afc3e7ef19c..a57ac648b8cd 100644 --- a/tools/widl/parser.l +++ b/tools/widl/parser.l @@ -495,63 +495,63 @@ void pop_import(void) }
struct imports { - char *name; - struct imports *next; + char *name; + struct imports *next; } *first_import;
int do_import(char *fname) { - FILE *f; - char *path, *name; - struct imports *import; - int ptr = import_stack_ptr; - int ret, fd; - - import = first_import; - while (import && strcmp(import->name, fname)) - import = import->next; - if (import) return 0; /* already imported */ - - import = xmalloc(sizeof(struct imports)); - import->name = xstrdup(fname); - import->next = first_import; - first_import = import; - - /* don't search for a file name with a path in the include directories, - * for compatibility with MIDL */ - if (strchr( fname, '/' ) || strchr( fname, '\' )) - path = xstrdup( fname ); - else if (!(path = wpp_find_include( fname, input_name ))) - error_loc("Unable to open include file %s\n", fname); + FILE *f; + char *path, *name; + struct imports *import; + int ptr = import_stack_ptr; + int ret, fd; + + import = first_import; + while (import && strcmp(import->name, fname)) + import = import->next; + if (import) return 0; /* already imported */ + + import = xmalloc(sizeof(struct imports)); + import->name = xstrdup(fname); + import->next = first_import; + first_import = import; + + /* don't search for a file name with a path in the include directories, + * for compatibility with MIDL */ + if (strchr( fname, '/' ) || strchr( fname, '\' )) + path = xstrdup( fname ); + else if (!(path = wpp_find_include( fname, input_name ))) + error_loc("Unable to open include file %s\n", fname);
if (import_stack_ptr == MAX_IMPORT_DEPTH) error_loc("Exceeded max import depth\n");
- import_stack[ptr].temp_name = temp_name; - import_stack[ptr].input_name = input_name; - import_stack[ptr].line_number = line_number; - import_stack_ptr++; - input_name = path; - line_number = 1; + import_stack[ptr].temp_name = temp_name; + import_stack[ptr].input_name = input_name; + import_stack[ptr].line_number = line_number; + import_stack_ptr++; + input_name = path; + line_number = 1;
- name = xstrdup( "widl.XXXXXX" ); - if((fd = mkstemps( name, 0 )) == -1) - error("Could not generate a temp name from %s\n", name); + name = xstrdup( "widl.XXXXXX" ); + if((fd = mkstemps( name, 0 )) == -1) + error("Could not generate a temp name from %s\n", name);
- temp_name = name; - if (!(f = fdopen(fd, "wt"))) - error("Could not open fd %s for writing\n", name); + temp_name = name; + if (!(f = fdopen(fd, "wt"))) + error("Could not open fd %s for writing\n", name);
- ret = wpp_parse( path, f ); - fclose( f ); - if (ret) exit(1); + ret = wpp_parse( path, f ); + fclose( f ); + if (ret) exit(1);
- if((f = fopen(temp_name, "r")) == NULL) - error_loc("Unable to open %s\n", temp_name); + if((f = fopen(temp_name, "r")) == NULL) + error_loc("Unable to open %s\n", temp_name);
- import_stack[ptr].state = YY_CURRENT_BUFFER; - yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); - return 1; + import_stack[ptr].state = YY_CURRENT_BUFFER; + yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE)); + return 1; }
void abort_import(void)
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
For RenderDoc in Wine.
--- dlls/d3d11/d3d11_private.h | 2 +- dlls/dxgi/factory.c | 18 +++++++++++++++--- include/wine/winedxgi.idl | 11 ++++++++++- 3 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d11/d3d11_private.h b/dlls/d3d11/d3d11_private.h index 9089398e5dfc..c286e768d9cb 100644 --- a/dlls/d3d11/d3d11_private.h +++ b/dlls/d3d11/d3d11_private.h @@ -29,7 +29,7 @@ #include "winuser.h" #include "objbase.h"
-#include "d3d11_1.h" +#include "d3d11_4.h" #ifdef D3D11_INIT_GUID #include "initguid.h" #endif diff --git a/dlls/dxgi/factory.c b/dlls/dxgi/factory.c index 8d2407895029..3f8816b3c23b 100644 --- a/dlls/dxgi/factory.c +++ b/dlls/dxgi/factory.c @@ -35,7 +35,8 @@ static HRESULT STDMETHODCALLTYPE dxgi_factory_QueryInterface(IDXGIFactory4 *ifac
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
- if (IsEqualGUID(iid, &IID_IDXGIFactory4) + if (IsEqualGUID(iid, &IID_IWineDXGIFactory) + || IsEqualGUID(iid, &IID_IDXGIFactory4) || IsEqualGUID(iid, &IID_IDXGIFactory3) || IsEqualGUID(iid, &IID_IDXGIFactory2) || (factory->extended && IsEqualGUID(iid, &IID_IDXGIFactory1)) @@ -504,10 +505,21 @@ static const struct IDXGIFactory4Vtbl dxgi_factory_vtbl =
struct dxgi_factory *unsafe_impl_from_IDXGIFactory4(IDXGIFactory4 *iface) { + IWineDXGIFactory *wine_factory; + struct dxgi_factory *factory; + HRESULT hr; + if (!iface) return NULL; - assert(iface->lpVtbl == &dxgi_factory_vtbl); - return CONTAINING_RECORD(iface, struct dxgi_factory, IDXGIFactory4_iface); + if (FAILED(hr = IDXGIFactory4_QueryInterface(iface, &IID_IWineDXGIFactory, (void **)&wine_factory))) + { + ERR("Failed to get IWineDXGIFactory interface, hr %#x.\n", hr); + return NULL; + } + assert(wine_factory->lpVtbl == (void *)&dxgi_factory_vtbl); + factory = CONTAINING_RECORD(wine_factory, struct dxgi_factory, IDXGIFactory4_iface); + IWineDXGIFactory_Release(wine_factory); + return factory; }
static HRESULT dxgi_factory_init(struct dxgi_factory *factory, BOOL extended) diff --git a/include/wine/winedxgi.idl b/include/wine/winedxgi.idl index 983cdba68d14..c3564d50800b 100644 --- a/include/wine/winedxgi.idl +++ b/include/wine/winedxgi.idl @@ -18,7 +18,7 @@
#pragma makedep header
-import "dxgi.idl"; +import "dxgi1_5.idl";
[ object, @@ -59,3 +59,12 @@ interface IWineDXGIDeviceParent : IUnknown interface IWineDXGIAdapter : IDXGIAdapter1 { } + +[ + object, + local, + uuid(ea02a0d1-4c95-488a-a82c-6034621e8c4f) +] +interface IWineDXGIFactory : IDXGIFactory4 +{ +}
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com ---
DXGI object wrapping changes are for RenderDoc in Wine. Unfortunately, more fixes are needed to run RenderDoc in Wine: SHGetKnownFolderPath(), PathCchCombineEx(), D3D11 1D textures and D3D11 multisample textures.
--- dlls/dxgi/tests/device.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
diff --git a/dlls/dxgi/tests/device.c b/dlls/dxgi/tests/device.c index 4ad5b9f6745c..d3ba6bb7dce9 100644 --- a/dlls/dxgi/tests/device.c +++ b/dlls/dxgi/tests/device.c @@ -3452,6 +3452,135 @@ static void test_output_desc(void) ok(!refcount, "IDXGIFactory has %u references left.\n", refcount); }
+struct dxgi_adapter +{ + IDXGIAdapter IDXGIAdapter_iface; + IDXGIAdapter *wrapped_iface; +}; + +static inline struct dxgi_adapter *impl_from_IDXGIAdapter(IDXGIAdapter *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_adapter, IDXGIAdapter_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_QueryInterface(IDXGIAdapter *iface, REFIID iid, void **out) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_QueryInterface(adapter->wrapped_iface, iid, out); +} + +static ULONG STDMETHODCALLTYPE dxgi_adapter_AddRef(IDXGIAdapter *iface) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_AddRef(adapter->wrapped_iface); +} + +static ULONG STDMETHODCALLTYPE dxgi_adapter_Release(IDXGIAdapter *iface) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_Release(adapter->wrapped_iface); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetPrivateData(IDXGIAdapter *iface, + REFGUID guid, UINT data_size, const void *data) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_SetPrivateData(adapter->wrapped_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_SetPrivateDataInterface(IDXGIAdapter *iface, + REFGUID guid, const IUnknown *object) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_SetPrivateDataInterface(adapter->wrapped_iface, guid, object); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetPrivateData(IDXGIAdapter *iface, + REFGUID guid, UINT *data_size, void *data) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_GetPrivateData(adapter->wrapped_iface, guid, data_size, data); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetParent(IDXGIAdapter *iface, REFIID iid, void **parent) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_GetParent(adapter->wrapped_iface, iid, parent); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_EnumOutputs(IDXGIAdapter *iface, + UINT output_idx, IDXGIOutput **output) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_EnumOutputs(adapter->wrapped_iface, output_idx, output); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_GetDesc(IDXGIAdapter *iface, DXGI_ADAPTER_DESC *desc) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_GetDesc(adapter->wrapped_iface, desc); +} + +static HRESULT STDMETHODCALLTYPE dxgi_adapter_CheckInterfaceSupport(IDXGIAdapter *iface, + REFGUID guid, LARGE_INTEGER *umd_version) +{ + struct dxgi_adapter *adapter = impl_from_IDXGIAdapter(iface); + return IDXGIAdapter_CheckInterfaceSupport(adapter->wrapped_iface, guid, umd_version); +} + +static const struct IDXGIAdapterVtbl dxgi_adapter_vtbl = +{ + dxgi_adapter_QueryInterface, + dxgi_adapter_AddRef, + dxgi_adapter_Release, + dxgi_adapter_SetPrivateData, + dxgi_adapter_SetPrivateDataInterface, + dxgi_adapter_GetPrivateData, + dxgi_adapter_GetParent, + dxgi_adapter_EnumOutputs, + dxgi_adapter_GetDesc, + dxgi_adapter_CheckInterfaceSupport, +}; + +static void test_object_wrapping(void) +{ + struct dxgi_adapter wrapper; + DXGI_ADAPTER_DESC desc; + IDXGIAdapter *adapter; + IDXGIFactory *factory; + ID3D10Device1 *device; + ULONG refcount; + HRESULT hr; + + hr = CreateDXGIFactory(&IID_IDXGIFactory, (void **)&factory); + ok(hr == S_OK, "Failed to create DXGI factory, hr %#x.\n", hr); + + hr = IDXGIFactory_EnumAdapters(factory, 0, &adapter); + if (hr == DXGI_ERROR_NOT_FOUND) + { + skip("Could not enumerate adapters.\n"); + IDXGIFactory_Release(factory); + return; + } + ok(hr == S_OK, "Failed to enumerate adapter, hr %#x.\n", hr); + + wrapper.IDXGIAdapter_iface.lpVtbl = &dxgi_adapter_vtbl; + wrapper.wrapped_iface = adapter; + + hr = D3D10CreateDevice1(&wrapper.IDXGIAdapter_iface, D3D10_DRIVER_TYPE_HARDWARE, NULL, + 0, D3D10_FEATURE_LEVEL_10_0, D3D10_1_SDK_VERSION, &device); + ok(hr == S_OK, "Failed to create device, hr %#x.\n", hr); + refcount = ID3D10Device1_Release(device); + ok(!refcount, "Device has %u references left.\n", refcount); + + hr = IDXGIAdapter_GetDesc(&wrapper.IDXGIAdapter_iface, &desc); + ok(hr == S_OK, "Failed to get adapter desc, hr %#x.\n", hr); + + IDXGIAdapter_Release(&wrapper.IDXGIAdapter_iface); + refcount = IDXGIFactory_Release(factory); + ok(!refcount, "Factory has %u references left.\n", refcount); +} + START_TEST(device) { HMODULE dxgi_module = GetModuleHandleA("dxgi.dll"); @@ -3480,4 +3609,5 @@ START_TEST(device) test_swapchain_parameters(); test_maximum_frame_latency(); test_output_desc(); + test_object_wrapping(); }
On 27 January 2018 at 00:39, Józef Kucia jkucia@codeweavers.com wrote:
dlls/dxgi/tests/device.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
This fails and crashes when Direct3D 10 is not available, for example with MaxVersionGL=0x00010000.
Józef Kucia jkucia@codeweavers.com writes:
Signed-off-by: Józef Kucia jkucia@codeweavers.com
DXGI object wrapping changes are for RenderDoc in Wine. Unfortunately, more fixes are needed to run RenderDoc in Wine: SHGetKnownFolderPath(), PathCchCombineEx(), D3D11 1D textures and D3D11 multisample textures.
dlls/dxgi/tests/device.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
You'd probably want to skip on device creation failure, like in the other tests:
../../../tools/runtest -q -P wine -T ../../.. -M dxgi.dll -p dxgi_test.exe.so device && touch device.ok device.c:414: Tests skipped: Failed to create device, skipping tests. device.c:488: Tests skipped: Failed to create device. device.c:601: Tests skipped: Failed to create device. device.c:654: Tests skipped: Failed to create device, skipping tests. device.c:692: Tests skipped: Failed to create device, skipping tests. device.c:760: Tests skipped: Failed to create device, skipping tests. device.c:867: Tests skipped: Failed to create device. device.c:1076: Tests skipped: Failed to create device, skipping tests. device.c:1501: Tests skipped: Failed to create device. device.c:1861: Tests skipped: Failed to create device. device.c:1954: Tests skipped: Failed to create device. device.c:2234: Tests skipped: Failed to create device. device.c:2371: Tests skipped: Failed to create device. device.c:2625: Tests skipped: Failed to create device, skipping tests. device.c:2754: Tests skipped: Failed to create device, skipping tests. device.c:3147: Tests skipped: Failed to create device, skipping tests. device.c:3331: Tests skipped: Failed to create device. device.c:3572: Test failed: Failed to create device, hr 0x80004005. wine: Unhandled page fault on read access to 0x00000000 at address 0x7ecb3795 (thread 013f), starting debugger...