[v2 PATCH] dxgi: Translate DXGI_USAGE_UNORDERED_ACCESS to corresponding wined3d bind flag.

Nikolay Sivov nsivov at codeweavers.com
Thu May 7 15:15:16 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---

v2: handle surface creation failure on some systems.

 dlls/dxgi/tests/dxgi.c | 78 +++++++++++++++++++++++++++++++++++++++++-
 dlls/dxgi/utils.c      |  4 ++-
 2 files changed, 80 insertions(+), 2 deletions(-)

diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index f04cd2be06..c33b9981f9 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -44,6 +44,10 @@ static NTSTATUS (WINAPI *pD3DKMTCheckVidPnExclusiveOwnership)(const D3DKMT_CHECK
 static NTSTATUS (WINAPI *pD3DKMTCloseAdapter)(const D3DKMT_CLOSEADAPTER *desc);
 static NTSTATUS (WINAPI *pD3DKMTOpenAdapterFromGdiDisplayName)(D3DKMT_OPENADAPTERFROMGDIDISPLAYNAME *desc);
 
+static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
+        const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
+        D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
+
 static PFN_D3D12_CREATE_DEVICE pD3D12CreateDevice;
 static PFN_D3D12_GET_DEBUG_INTERFACE pD3D12GetDebugInterface;
 
@@ -624,6 +628,40 @@ success:
     return dxgi_device;
 }
 
+static IDXGIDevice *create_d3d11_device(void)
+{
+    static const D3D_FEATURE_LEVEL feature_level[] =
+    {
+        D3D_FEATURE_LEVEL_11_0,
+        D3D_FEATURE_LEVEL_10_1,
+        D3D_FEATURE_LEVEL_10_0,
+    };
+    unsigned int feature_level_count = ARRAY_SIZE(feature_level);
+    ID3D11Device *d3d_device;
+    IDXGIDevice *device = NULL;
+    HRESULT hr;
+
+    if (!pD3D11CreateDevice)
+        return NULL;
+
+    hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, feature_level, feature_level_count,
+            D3D11_SDK_VERSION, &d3d_device, NULL, NULL);
+    if (FAILED(hr))
+        hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0, feature_level, feature_level_count,
+                D3D11_SDK_VERSION, &d3d_device, NULL, NULL);
+    if (FAILED(hr))
+        hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0, feature_level, feature_level_count,
+                D3D11_SDK_VERSION, &d3d_device, NULL, NULL);
+
+    if (SUCCEEDED(hr))
+    {
+        hr = ID3D11Device_QueryInterface(d3d_device, &IID_IDXGIDevice, (void **)&device);
+        ID3D11Device_Release(d3d_device);
+    }
+
+    return device;
+}
+
 static ID3D12Device *create_d3d12_device(void)
 {
     IDXGIAdapter *adapter;
@@ -1079,6 +1117,7 @@ static void test_check_interface_support(void)
 
 static void test_create_surface(void)
 {
+    ID3D11Texture2D *texture2d;
     DXGI_SURFACE_DESC desc;
     IDXGISurface *surface;
     IDXGIDevice *device;
@@ -1109,6 +1148,40 @@ static void test_create_surface(void)
     IDXGISurface_Release(surface);
     refcount = IDXGIDevice_Release(device);
     ok(!refcount, "Device has %u references left.\n", refcount);
+
+    /* DXGI_USAGE_UNORDERED_ACCESS */
+    if (!(device = create_d3d11_device()))
+    {
+        skip("Failed to create D3D11 device.\n");
+        return;
+    }
+
+    surface = NULL;
+    hr = IDXGIDevice_CreateSurface(device, &desc, 1, DXGI_USAGE_UNORDERED_ACCESS, NULL, &surface);
+    ok(SUCCEEDED(hr) || broken(hr == E_INVALIDARG), "Failed to create a dxgi surface, hr %#x\n", hr);
+
+    if (surface)
+    {
+        ID3D11UnorderedAccessView *uav;
+        ID3D11Device *d3d_device;
+
+        hr = IDXGISurface_QueryInterface(surface, &IID_ID3D11Texture2D, (void **)&texture2d);
+        ok(hr == S_OK, "Failed to get texture interface, hr %#x.\n", hr);
+
+        ID3D11Texture2D_GetDevice(texture2d, &d3d_device);
+
+        hr = ID3D11Device_CreateUnorderedAccessView(d3d_device, (ID3D11Resource *)texture2d, NULL, &uav);
+        ok(hr == S_OK, "Failed to create unordered access view, hr %#x.\n", hr);
+        ID3D11UnorderedAccessView_Release(uav);
+
+        ID3D11Device_Release(d3d_device);
+        ID3D11Texture2D_Release(texture2d);
+
+        IDXGISurface_Release(surface);
+    }
+
+    refcount = IDXGIDevice_Release(device);
+    ok(!refcount, "Device has %u references left.\n", refcount);
 }
 
 static void test_parents(void)
@@ -6483,7 +6556,7 @@ static void run_on_d3d12(void (*test_func)(IUnknown *device, BOOL is_d3d12))
 
 START_TEST(dxgi)
 {
-    HMODULE dxgi_module, d3d12_module, gdi32_module;
+    HMODULE dxgi_module, d3d11_module, d3d12_module, gdi32_module;
     BOOL enable_debug_layer = FALSE;
     unsigned int argc, i;
     ID3D12Debug *debug;
@@ -6498,6 +6571,9 @@ START_TEST(dxgi)
     pD3DKMTCloseAdapter = (void *)GetProcAddress(gdi32_module, "D3DKMTCloseAdapter");
     pD3DKMTOpenAdapterFromGdiDisplayName = (void *)GetProcAddress(gdi32_module, "D3DKMTOpenAdapterFromGdiDisplayName");
 
+    d3d11_module = LoadLibraryA("d3d11.dll");
+    pD3D11CreateDevice = (void *)GetProcAddress(d3d11_module, "D3D11CreateDevice");
+
     registry_mode.dmSize = sizeof(registry_mode);
     ok(EnumDisplaySettingsW(NULL, ENUM_REGISTRY_SETTINGS, &registry_mode), "Failed to get display mode.\n");
 
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index aece3a6af1..a32c7ee129 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -503,8 +503,10 @@ unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE dxgi_usage)
         wined3d_bind_flags |= WINED3D_BIND_SHADER_RESOURCE;
     if (dxgi_usage & DXGI_USAGE_RENDER_TARGET_OUTPUT)
         wined3d_bind_flags |= WINED3D_BIND_RENDER_TARGET;
+    if (dxgi_usage & DXGI_USAGE_UNORDERED_ACCESS)
+        wined3d_bind_flags |= WINED3D_BIND_UNORDERED_ACCESS;
 
-    dxgi_usage &= ~(DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT);
+    dxgi_usage &= ~(DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS);
     if (dxgi_usage)
         FIXME("Unhandled DXGI usage %#x.\n", dxgi_usage);
     return wined3d_bind_flags;
-- 
2.26.2




More information about the wine-devel mailing list