The open source OpenXR runtime
at main 6.3 kB view raw
1// Copyright 2022, Collabora, Ltd. 2// SPDX-License-Identifier: BSL-1.0 3/*! 4 * @file 5 * @brief Direct3D 11 tests. 6 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 7 */ 8#include "catch_amalgamated.hpp" 9 10#include "aux_d3d_dxgi_formats.hpp" 11 12#include <iostream> 13 14#include <xrt/xrt_config_have.h> 15#include <d3d/d3d_dxgi_helpers.hpp> 16#include <d3d/d3d_d3d11_helpers.hpp> 17#include <d3d/d3d_d3d11_allocator.hpp> 18#include <util/u_win32_com_guard.hpp> 19 20#ifdef XRT_HAVE_VULKAN 21#include "vktest_init_bundle.hpp" 22#include <vk/vk_image_allocator.h> 23#include <util/u_handles.h> 24#include <d3d/d3d_dxgi_formats.h> 25#endif 26 27#include <d3d11_4.h> 28 29using namespace xrt::auxiliary::d3d; 30using namespace xrt::auxiliary::d3d::d3d11; 31using namespace xrt::auxiliary::util; 32 33 34TEST_CASE("dxgi_adapter", "[.][needgpu]") 35{ 36 ComGuard comGuard; 37 wil::com_ptr<IDXGIAdapter> adapter; 38 39 CHECK_NOTHROW(adapter = getAdapterByIndex(0, U_LOGGING_TRACE)); 40 CHECK(adapter); 41 auto adapter1 = adapter.query<IDXGIAdapter1>(); 42 DXGI_ADAPTER_DESC1 desc{}; 43 REQUIRE(SUCCEEDED(adapter1->GetDesc1(&desc))); 44 45 xrt_luid_t luid{}; 46 memcpy(&luid, &(desc.AdapterLuid), sizeof(luid)); 47 48 49 wil::com_ptr<IDXGIAdapter> adapterFromLuid; 50 CHECK_NOTHROW(adapterFromLuid = getAdapterByLUID(luid, U_LOGGING_TRACE)); 51 CHECK(adapterFromLuid); 52} 53 54TEST_CASE("d3d11_device", "[.][needgpu]") 55{ 56 ComGuard comGuard; 57 wil::com_ptr<IDXGIAdapter> adapter; 58 59 CHECK_NOTHROW(adapter = getAdapterByIndex(0, U_LOGGING_TRACE)); 60 CHECK(adapter); 61 wil::com_ptr<ID3D11Device> device; 62 wil::com_ptr<ID3D11DeviceContext> context; 63 CHECK_NOTHROW(std::tie(device, context) = createDevice(adapter, U_LOGGING_TRACE)); 64 CHECK(device); 65 CHECK(context); 66} 67 68#ifdef XRT_HAVE_VULKAN 69 70static inline bool 71tryImport(struct vk_bundle *vk, std::vector<HANDLE> const &handles, const struct xrt_swapchain_create_info &xsci) 72{ 73 74 INFO("Testing import into Vulkan"); 75 76 static constexpr bool use_dedicated_allocation = false; 77 xrt_swapchain_create_info vk_info = xsci; 78 vk_info.format = d3d_dxgi_format_to_vk((DXGI_FORMAT)xsci.format); 79 const auto free_vk_ic = [&](struct vk_image_collection *vkic) { 80 vk_ic_destroy(vk, vkic); 81 delete vkic; 82 }; 83 84 std::shared_ptr<vk_image_collection> vkic{new vk_image_collection, free_vk_ic}; 85 86 uint32_t image_count = static_cast<uint32_t>(handles.size()); 87 // Populate for import 88 std::vector<xrt_image_native> xins; 89 xins.reserve(image_count); 90 91 for (HANDLE handle : handles) { 92 /*! 93 * If shared resources have been allocated without using NT handles we can't use DuplicateHandle 94 *(like u_graphics_buffer_ref does internally) or CloseHandle (which wil::~unique_handle will call). 95 * More info: 96 * https://learn.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgiresource-getsharedhandle#remarks 97 * When using KMT handles, their validity is tied to the underlying video memory (I guess that means a 98 * ID3D11Texture2D object). 99 */ 100 xrt_image_native xin; 101 xin.handle = handle; 102 xin.size = 0; 103 xin.use_dedicated_allocation = use_dedicated_allocation; 104 xin.is_dxgi_handle = true; 105 106 xins.emplace_back(xin); 107 } 108 109 // Import into a vulkan image collection 110 const VkResult ret = vk_ic_from_natives(vk, &vk_info, xins.data(), (uint32_t)xins.size(), vkic.get()); 111 VK_CHK_WITH_RET(ret, "vk_ic_from_natives", false); 112 113 return true; 114} 115#else 116 117static inline bool 118tryImport(struct vk_bundle * /* vk */, 119 std::vector<wil::unique_handle> const & /* handles */, 120 const struct xrt_swapchain_create_info & /* xsci */) 121{ 122 return true; 123} 124 125#endif 126 127TEST_CASE("d3d11_allocate", "[.][needgpu]") 128{ 129 unique_vk_bundle vk = makeVkBundle(); 130 131#ifdef XRT_HAVE_VULKAN 132 REQUIRE(vktest_init_bundle(vk.get())); 133#endif 134 135 ComGuard comGuard; 136 wil::com_ptr<ID3D11Device> device; 137 wil::com_ptr<ID3D11DeviceContext> context; 138 std::tie(device, context) = createDevice(); 139 auto device5 = device.query<ID3D11Device5>(); 140 std::vector<wil::com_ptr<ID3D11Texture2D1>> images; 141 std::vector<HANDLE> handles; 142 143 static constexpr bool kKeyedMutex = true; 144 size_t imageCount = 3; 145 146 xrt_swapchain_create_info xsci{}; 147 CAPTURE(xsci.sample_count = 1); 148 CAPTURE(xsci.width = 800); 149 CAPTURE(xsci.height = 600); 150 151 CAPTURE(xsci.mip_count = 1); 152 xsci.face_count = 1; 153 xsci.array_size = 1; 154 SECTION("create images") 155 { 156 auto nameAndFormat = GENERATE(values(namesAndFormats)); 157 DYNAMIC_SECTION("Texture format " << nameAndFormat.first) 158 { 159 auto format = nameAndFormat.second; 160 CAPTURE(isDepthStencilFormat(format)); 161 xsci.format = format; 162 if (isDepthStencilFormat(format)) { 163 xsci.bits = XRT_SWAPCHAIN_USAGE_DEPTH_STENCIL; 164 } else { 165 xsci.bits = XRT_SWAPCHAIN_USAGE_COLOR; 166 } 167 xsci.bits = (xrt_swapchain_usage_bits)(xsci.bits | XRT_SWAPCHAIN_USAGE_SAMPLED); 168 images.clear(); 169 handles.clear(); 170 SECTION("invalid array size 0") 171 { 172 CAPTURE(xsci.array_size = 0); 173 REQUIRE(XRT_SUCCESS != 174 allocateSharedImages(*device5, xsci, imageCount, kKeyedMutex, images, handles)); 175 CHECK(images.empty()); 176 CHECK(handles.empty()); 177 } 178 SECTION("not array") 179 { 180 CAPTURE(xsci.array_size); 181 REQUIRE(XRT_SUCCESS == 182 allocateSharedImages(*device5, xsci, imageCount, kKeyedMutex, images, handles)); 183 CHECK(images.size() == imageCount); 184 CHECK(handles.size() == imageCount); 185 CHECK(tryImport(vk.get(), handles, xsci)); 186 } 187 SECTION("array of 2") 188 { 189 CAPTURE(xsci.array_size = 2); 190 REQUIRE(XRT_SUCCESS == 191 allocateSharedImages(*device5, xsci, imageCount, kKeyedMutex, images, handles)); 192 CHECK(images.size() == imageCount); 193 CHECK(handles.size() == imageCount); 194 CHECK(tryImport(vk.get(), handles, xsci)); 195 } 196 SECTION("cubemaps not implemented") 197 { 198 CAPTURE(xsci.array_size); 199 CAPTURE(xsci.face_count = 6); 200 REQUIRE(XRT_ERROR_ALLOCATION == 201 allocateSharedImages(*device5, xsci, imageCount, kKeyedMutex, images, handles)); 202 CHECK(images.empty()); 203 CHECK(handles.empty()); 204 } 205 SECTION("protected content not implemented") 206 { 207 CAPTURE(xsci.array_size); 208 CAPTURE(xsci.create = XRT_SWAPCHAIN_CREATE_PROTECTED_CONTENT); 209 REQUIRE(XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED == 210 allocateSharedImages(*device5, xsci, imageCount, kKeyedMutex, images, handles)); 211 CHECK(images.empty()); 212 CHECK(handles.empty()); 213 } 214 } 215 } 216}