diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 61553657f..4ddef4052 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,8 +29,9 @@ set(tests if(XRT_HAVE_D3D11) list(APPEND tests tests_aux_d3d_d3d11 tests_comp_client_d3d11) endif() -# if(XRT_HAVE_D3D12) -# endif() +if(XRT_HAVE_D3D12) + list(APPEND tests tests_comp_client_d3d12) +endif() if(XRT_HAVE_VULKAN) list(APPEND tests tests_comp_client_vulkan) endif() @@ -66,7 +67,7 @@ if(XRT_HAVE_D3D11) endif() if(XRT_HAVE_D3D12) - # target_link_libraries(tests_comp_client_d3d12 PRIVATE comp_client comp_mock) + target_link_libraries(tests_comp_client_d3d12 PRIVATE comp_client comp_mock) endif() if(XRT_HAVE_VULKAN) diff --git a/tests/tests_comp_client_d3d12.cpp b/tests/tests_comp_client_d3d12.cpp new file mode 100644 index 000000000..7e4d05980 --- /dev/null +++ b/tests/tests_comp_client_d3d12.cpp @@ -0,0 +1,95 @@ +// Copyright 2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Direct3D 12 tests. + * @author Ryan Pavlik + */ + + +#include "mock/mock_compositor.h" +#include "client/comp_d3d12_client.h" + +#include "catch/catch.hpp" +#include "util/u_handles.h" + +#include +#include +#include +#include + +#include + + +using namespace xrt::auxiliary::d3d; +using namespace xrt::auxiliary::d3d::d3d12; +using namespace xrt::auxiliary::util; + +TEST_CASE("d3d12_client_compositor", "[.][needgpu]") +{ + xrt_compositor_native *xcn = mock_create_native_compositor(); + struct mock_compositor *mc = mock_compositor(&(xcn->base)); + + ComGuard comGuard; + + wil::com_ptr device = createDevice(); + wil::com_ptr queue; + D3D12_COMMAND_QUEUE_DESC desc{D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_PRIORITY_NORMAL, + D3D12_COMMAND_QUEUE_FLAG_NONE, 0}; + device->CreateCommandQueue(&desc, IID_PPV_ARGS(queue.put())); + struct xrt_compositor_d3d12 *xcd3d = client_d3d12_compositor_create(xcn, device.get(), queue.get()); + struct xrt_compositor *xc = &xcd3d->base; + + SECTION("Swapchain create and import") + { + struct Data + { + bool nativeCreateCalled = false; + + bool nativeImportCalled = false; + } data; + mc->userdata = &data; + mc->compositor_hooks.create_swapchain = + [](struct mock_compositor *mc, struct mock_compositor_swapchain *mcsc, + const struct xrt_swapchain_create_info *info, struct xrt_swapchain **out_xsc) { + auto *data = static_cast(mc->userdata); + data->nativeCreateCalled = true; + return XRT_SUCCESS; + }; + mc->compositor_hooks.import_swapchain = + [](struct mock_compositor *mc, struct mock_compositor_swapchain *mcsc, + const struct xrt_swapchain_create_info *info, struct xrt_image_native *native_images, + uint32_t image_count, struct xrt_swapchain **out_xscc) { + auto *data = static_cast(mc->userdata); + data->nativeImportCalled = true; + // need to release the native handles to avoid leaks + for (uint32_t i = 0; i < image_count; ++i) { + u_graphics_buffer_unref(&native_images[i].handle); + } + return XRT_SUCCESS; + }; + xrt_swapchain_create_info xsci{}; + xsci.format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + xsci.bits = (xrt_swapchain_usage_bits)(XRT_SWAPCHAIN_USAGE_COLOR | XRT_SWAPCHAIN_USAGE_SAMPLED); + xsci.sample_count = 1; + xsci.width = 800; + xsci.height = 600; + xsci.face_count = 1; + xsci.array_size = 1; + xsci.mip_count = 1; + SECTION("Swapchain Create") + { + struct xrt_swapchain *xsc = nullptr; + // This will fail because the mock compositor doesn't actually import, but it will get far + // enough to trigger our hook and update the flag. + xrt_comp_create_swapchain(xc, &xsci, &xsc); + // D3D always imports into the native compositor + CHECK(data.nativeImportCalled); + CHECK_FALSE(data.nativeCreateCalled); + xrt_swapchain_reference(&xsc, nullptr); + } + } + + xrt_comp_destroy(&xc); + xrt_comp_native_destroy(&xcn); +}