mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-29 11:06:18 +00:00
tests: D3D11 and Vulkan client compositor tests
This commit is contained in:
parent
fcc18cf839
commit
2168e0b93c
|
@ -24,7 +24,10 @@ set(tests
|
||||||
tests_worker
|
tests_worker
|
||||||
)
|
)
|
||||||
if(XRT_HAVE_D3D11)
|
if(XRT_HAVE_D3D11)
|
||||||
list(APPEND tests tests_aux_d3d)
|
list(APPEND tests tests_aux_d3d tests_comp_client_d3d11)
|
||||||
|
endif()
|
||||||
|
if(XRT_HAVE_VULKAN)
|
||||||
|
list(APPEND tests tests_comp_client_vulkan)
|
||||||
endif()
|
endif()
|
||||||
foreach(testname ${tests})
|
foreach(testname ${tests})
|
||||||
|
|
||||||
|
@ -46,4 +49,9 @@ target_link_libraries(tests_rational PRIVATE aux_math)
|
||||||
|
|
||||||
if(XRT_HAVE_D3D11)
|
if(XRT_HAVE_D3D11)
|
||||||
target_link_libraries(tests_aux_d3d PRIVATE aux_d3d)
|
target_link_libraries(tests_aux_d3d PRIVATE aux_d3d)
|
||||||
|
target_link_libraries(tests_comp_client_d3d11 PRIVATE comp_client comp_mock)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(XRT_HAVE_VULKAN)
|
||||||
|
target_link_libraries(tests_comp_client_vulkan PRIVATE comp_client comp_mock comp_util aux_vk)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -82,12 +82,9 @@ isDepthStencilFormat(DXGI_FORMAT format)
|
||||||
TEST_CASE("d3d11_allocate", "[.][needgpu]")
|
TEST_CASE("d3d11_allocate", "[.][needgpu]")
|
||||||
{
|
{
|
||||||
ComGuard comGuard;
|
ComGuard comGuard;
|
||||||
wil::com_ptr<IDXGIAdapter> adapter;
|
|
||||||
|
|
||||||
CHECK_NOTHROW(adapter = getAdapterByIndex(0, U_LOGGING_TRACE));
|
|
||||||
wil::com_ptr<ID3D11Device> device;
|
wil::com_ptr<ID3D11Device> device;
|
||||||
wil::com_ptr<ID3D11DeviceContext> context;
|
wil::com_ptr<ID3D11DeviceContext> context;
|
||||||
CHECK_NOTHROW(std::tie(device, context) = createD3D11Device(adapter, U_LOGGING_TRACE));
|
std::tie(device, context) = createD3D11Device();
|
||||||
auto device5 = device.query<ID3D11Device5>();
|
auto device5 = device.query<ID3D11Device5>();
|
||||||
std::vector<wil::com_ptr<ID3D11Texture2D1>> images;
|
std::vector<wil::com_ptr<ID3D11Texture2D1>> images;
|
||||||
std::vector<wil::unique_handle> handles;
|
std::vector<wil::unique_handle> handles;
|
||||||
|
|
91
tests/tests_comp_client_d3d11.cpp
Normal file
91
tests/tests_comp_client_d3d11.cpp
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
// Copyright 2022, Collabora, Ltd.
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Direct3D 11 tests.
|
||||||
|
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "mock/mock_compositor.h"
|
||||||
|
#include "client/comp_d3d11_client.h"
|
||||||
|
|
||||||
|
#include "catch/catch.hpp"
|
||||||
|
#include "util/u_handles.h"
|
||||||
|
|
||||||
|
#include <d3d/d3d_helpers.hpp>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <util/u_win32_com_guard.hpp>
|
||||||
|
|
||||||
|
#include <d3d11_4.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace xrt::auxiliary::d3d;
|
||||||
|
using namespace xrt::auxiliary::util;
|
||||||
|
|
||||||
|
TEST_CASE("client_compositor", "[.][needgpu]")
|
||||||
|
{
|
||||||
|
xrt_compositor_native *xcn = mock_create_native_compositor();
|
||||||
|
struct mock_compositor *mc = mock_compositor(&(xcn->base));
|
||||||
|
|
||||||
|
ComGuard comGuard;
|
||||||
|
|
||||||
|
wil::com_ptr<ID3D11Device> device;
|
||||||
|
wil::com_ptr<ID3D11DeviceContext> context;
|
||||||
|
std::tie(device, context) = createD3D11Device();
|
||||||
|
struct xrt_compositor_d3d11 *xcd3d = client_d3d11_compositor_create(xcn, device.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<Data *>(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<Data *>(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);
|
||||||
|
}
|
205
tests/tests_comp_client_vulkan.cpp
Normal file
205
tests/tests_comp_client_vulkan.cpp
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
// Copyright 2022, Collabora, Ltd.
|
||||||
|
// SPDX-License-Identifier: BSL-1.0
|
||||||
|
/*!
|
||||||
|
* @file
|
||||||
|
* @brief Basic Vulkan compositor tests.
|
||||||
|
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "mock/mock_compositor.h"
|
||||||
|
#include "client/comp_vk_client.h"
|
||||||
|
#include "xrt/xrt_results.h"
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#undef Always
|
||||||
|
#undef None
|
||||||
|
|
||||||
|
#include "catch/catch.hpp"
|
||||||
|
#include "util/comp_vulkan.h"
|
||||||
|
#include "util/u_logging.h"
|
||||||
|
#include "util/u_string_list.h"
|
||||||
|
#include "vk/vk_helpers.h"
|
||||||
|
#include "xrt/xrt_compositor.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct Deleter
|
||||||
|
{
|
||||||
|
void
|
||||||
|
operator()(struct xrt_compositor_native *xcn) const
|
||||||
|
{
|
||||||
|
xrt_comp_native_destroy(&xcn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
using unique_native_compositor = std::unique_ptr<xrt_compositor_native, Deleter>;
|
||||||
|
// clang-format off
|
||||||
|
#define COMP_INSTANCE_EXTENSIONS_COMMON \
|
||||||
|
VK_EXT_DEBUG_REPORT_EXTENSION_NAME, \
|
||||||
|
VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME, \
|
||||||
|
VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, \
|
||||||
|
VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, \
|
||||||
|
VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, \
|
||||||
|
VK_KHR_SURFACE_EXTENSION_NAME
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
static const char *instance_extensions_common[] = {
|
||||||
|
COMP_INSTANCE_EXTENSIONS_COMMON,
|
||||||
|
};
|
||||||
|
static const char *required_device_extensions[] = {
|
||||||
|
VK_KHR_SWAPCHAIN_EXTENSION_NAME, //
|
||||||
|
VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, //
|
||||||
|
VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME, //
|
||||||
|
VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, //
|
||||||
|
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, //
|
||||||
|
VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, //
|
||||||
|
|
||||||
|
// Platform version of "external_memory"
|
||||||
|
#if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD)
|
||||||
|
VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
|
||||||
|
|
||||||
|
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER)
|
||||||
|
VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
|
||||||
|
|
||||||
|
#elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE)
|
||||||
|
VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Need port!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Platform version of "external_fence" and "external_semaphore"
|
||||||
|
#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD) // Optional
|
||||||
|
|
||||||
|
#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE)
|
||||||
|
VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
|
||||||
|
VK_KHR_EXTERNAL_FENCE_WIN32_EXTENSION_NAME,
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Need port!"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StringListDeleter
|
||||||
|
{
|
||||||
|
void
|
||||||
|
operator()(u_string_list *usl) const
|
||||||
|
{
|
||||||
|
u_string_list_destroy(&usl);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using unique_string_list = std::unique_ptr<u_string_list, StringListDeleter>;
|
||||||
|
struct CompDeleter
|
||||||
|
{
|
||||||
|
void
|
||||||
|
operator()(struct xrt_compositor *xc) const
|
||||||
|
{
|
||||||
|
xrt_comp_destroy(&xc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
operator()(struct xrt_compositor_vk *xcvk) const
|
||||||
|
{
|
||||||
|
xrt_compositor *xc = &xcvk->base;
|
||||||
|
xrt_comp_destroy(&xc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using unique_compositor_vulkan = std::unique_ptr<struct xrt_compositor_vk, CompDeleter>;
|
||||||
|
|
||||||
|
TEST_CASE("client_compositor", "[.][needgpu]")
|
||||||
|
{
|
||||||
|
xrt_compositor_native *xcn = mock_create_native_compositor();
|
||||||
|
struct mock_compositor *mc = mock_compositor(&(xcn->base));
|
||||||
|
|
||||||
|
// every backend needs at least the common extensions
|
||||||
|
unique_string_list required_instance_ext_list{
|
||||||
|
u_string_list_create_from_array(instance_extensions_common, ARRAY_SIZE(instance_extensions_common))};
|
||||||
|
|
||||||
|
unique_string_list optional_instance_ext_list{u_string_list_create()};
|
||||||
|
|
||||||
|
unique_string_list required_device_extension_list{
|
||||||
|
u_string_list_create_from_array(required_device_extensions, ARRAY_SIZE(required_device_extensions))};
|
||||||
|
|
||||||
|
unique_string_list optional_device_extension_list{u_string_list_create()};
|
||||||
|
|
||||||
|
comp_vulkan_arguments args{VK_MAKE_VERSION(1, 0, 0),
|
||||||
|
vkGetInstanceProcAddr,
|
||||||
|
required_instance_ext_list.get(),
|
||||||
|
optional_instance_ext_list.get(),
|
||||||
|
required_device_extension_list.get(),
|
||||||
|
optional_device_extension_list.get(),
|
||||||
|
U_LOGGING_TRACE,
|
||||||
|
false /* only_compute_queue */,
|
||||||
|
true /*timeline_semaphore*/,
|
||||||
|
-1,
|
||||||
|
-1};
|
||||||
|
vk_bundle vk_bundle_storage{};
|
||||||
|
vk_bundle *vk = &vk_bundle_storage;
|
||||||
|
comp_vulkan_results results{};
|
||||||
|
REQUIRE(comp_vulkan_init_bundle(vk, &args, &results));
|
||||||
|
struct xrt_compositor_vk *xcvk = xrt_gfx_vk_provider_create( //
|
||||||
|
xcn, //
|
||||||
|
vk->instance, //
|
||||||
|
vkGetInstanceProcAddr, //
|
||||||
|
vk->physical_device, //
|
||||||
|
vk->device,
|
||||||
|
#if defined(XRT_GRAPHICS_SYNC_HANDLE_IS_FD) //
|
||||||
|
vk->external.fence_sync_fd, //
|
||||||
|
vk->external.binary_semaphore_sync_fd, //
|
||||||
|
vk->external.timeline_semaphore_sync_fd, //
|
||||||
|
#elif defined(XRT_GRAPHICS_SYNC_HANDLE_IS_WIN32_HANDLE)
|
||||||
|
vk->external.fence_win32_handle, //
|
||||||
|
vk->external.binary_semaphore_win32_handle, //
|
||||||
|
vk->external.timeline_semaphore_win32_handle, //
|
||||||
|
#else
|
||||||
|
#error "Need port for fence sync handles checkers"
|
||||||
|
#endif
|
||||||
|
vk->queue_family_index, //
|
||||||
|
vk->queue_index);
|
||||||
|
struct xrt_compositor *xc = &xcvk->base;
|
||||||
|
|
||||||
|
SECTION("CreateSwapchain calls native create")
|
||||||
|
{
|
||||||
|
bool nativeCreateCalled = false;
|
||||||
|
mc->userdata = &nativeCreateCalled;
|
||||||
|
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) {
|
||||||
|
*static_cast<bool *>(mc->userdata) = true;
|
||||||
|
return XRT_SUCCESS;
|
||||||
|
};
|
||||||
|
xrt_swapchain_create_info xsci{};
|
||||||
|
xsci.format = VK_FORMAT_B8G8R8A8_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;
|
||||||
|
|
||||||
|
struct xrt_swapchain *xsc = nullptr;
|
||||||
|
// This will fail because the mock compositor doesn't actually create images for Vulkan to import, but
|
||||||
|
// it will get far enough to trigger our hook and update the flag.
|
||||||
|
xrt_comp_create_swapchain(xc, &xsci, &xsc);
|
||||||
|
CHECK(nativeCreateCalled);
|
||||||
|
xrt_swapchain_reference(&xsc, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
xrt_comp_destroy(&xc);
|
||||||
|
|
||||||
|
if (vk->cmd_pool != VK_NULL_HANDLE) {
|
||||||
|
vk->vkDeviceWaitIdle(vk->device);
|
||||||
|
vk->vkDestroyCommandPool(vk->device, vk->cmd_pool, NULL);
|
||||||
|
vk->cmd_pool = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
vk_deinit_mutex(vk);
|
||||||
|
|
||||||
|
xrt_comp_native_destroy(&xcn);
|
||||||
|
}
|
Loading…
Reference in a new issue