The open source OpenXR runtime
at main 6.2 kB view raw
1// Copyright 2022, Collabora, Ltd. 2// Copyright 2025, Holo-Light GmbH 3// SPDX-License-Identifier: BSL-1.0 4/*! 5 * @file 6 * @brief Direct3D 12 tests. 7 * @author Rylie Pavlik <rylie.pavlik@collabora.com> 8 * @author Krzysztof Lesiak <c-k.lesiak@holo-light.com> 9 */ 10 11#include "catch_amalgamated.hpp" 12 13#include <util/u_win32_com_guard.hpp> 14#include <d3d/d3d_dxgi_helpers.hpp> 15#include <d3d/d3d_d3d12_helpers.hpp> 16#include <d3d/d3d_d3d12_allocator.hpp> 17#include "aux_d3d_dxgi_formats.hpp" 18 19#ifdef XRT_HAVE_VULKAN 20#include "vktest_init_bundle.hpp" 21#include <vk/vk_image_allocator.h> 22#include <util/u_handles.h> 23#include <d3d/d3d_dxgi_formats.h> 24#endif 25 26using namespace xrt::auxiliary::util; 27 28TEST_CASE("d3d12_device", "[.][needgpu]") 29{ 30 ComGuard comGuard; 31 32 wil::com_ptr<IDXGIAdapter> adapter; 33 CHECK_NOTHROW(adapter = xrt::auxiliary::d3d::getAdapterByIndex(0, U_LOGGING_TRACE)); 34 CHECK(adapter); 35 36 wil::com_ptr<ID3D12Device> device; 37 CHECK_NOTHROW(device = xrt::auxiliary::d3d::d3d12::createDevice(adapter, U_LOGGING_TRACE)); 38 CHECK(device); 39} 40 41#ifdef XRT_HAVE_VULKAN 42 43static inline bool 44tryImport(struct vk_bundle *vk, 45 std::vector<wil::unique_handle> &handles, 46 const struct xrt_swapchain_create_info &xsci, 47 size_t image_mem_size) 48{ 49 // in d3d11 tryImport handles is const..here we do away with it so we can call release on handles passed in? 50 // I need to read more about wil and figure out lifetime semantics of all this. 51 52 INFO("Testing import into Vulkan"); 53 54 static constexpr bool use_dedicated_allocation = false; 55 xrt_swapchain_create_info vk_info = xsci; 56 vk_info.format = d3d_dxgi_format_to_vk((DXGI_FORMAT)xsci.format); 57 const auto free_vk_ic = [&](struct vk_image_collection *vkic) { 58 vk_ic_destroy(vk, vkic); 59 delete vkic; 60 }; 61 62 std::shared_ptr<vk_image_collection> vkic{new vk_image_collection, free_vk_ic}; 63 64 uint32_t image_count = static_cast<uint32_t>(handles.size()); 65 66 // Populate for import 67 std::vector<xrt_image_native> xins; 68 xins.reserve(image_count); 69 70 for (auto &handle : handles) { 71 xrt_image_native xin; 72 xin.handle = handle.get(); 73 xin.size = image_mem_size; 74 xin.use_dedicated_allocation = use_dedicated_allocation; 75 xin.is_dxgi_handle = false; 76 77 xins.emplace_back(xin); 78 } 79 80 // Import into a vulkan image collection 81 bool result = VK_SUCCESS == vk_ic_from_natives(vk, &vk_info, xins.data(), (uint32_t)xins.size(), vkic.get()); 82 83 if (result) { 84 // The imported swapchain took ownership of them now, release them from ownership here. 85 for (wil::unique_handle &h : handles) { 86 h.release(); 87 } 88 } 89 return result; 90} 91#else 92 93static inline bool 94tryImport(struct vk_bundle * /* vk */, 95 std::vector<wil::unique_handle> const & /* handles */, 96 const struct xrt_swapchain_create_info & /* xsci */) 97{ 98 return true; 99} 100 101#endif 102 103TEST_CASE("d3d12_allocate", "[.][needgpu]") 104{ 105 unique_vk_bundle vk = makeVkBundle(); 106 107#ifdef XRT_HAVE_VULKAN 108 REQUIRE(vktest_init_bundle(vk.get())); 109#endif 110 111 ComGuard comGuard; 112 113 wil::com_ptr<IDXGIAdapter> adapter = xrt::auxiliary::d3d::getAdapterByIndex(0, U_LOGGING_TRACE); 114 wil::com_ptr<ID3D12Device> device = xrt::auxiliary::d3d::d3d12::createDevice(adapter, U_LOGGING_TRACE); 115 std::vector<wil::com_ptr<ID3D12Resource>> images; 116 std::vector<wil::unique_handle> handles; 117 size_t out_image_mem_size = 0; 118 119 size_t image_count = 3; 120 121 xrt_swapchain_create_info xsci{}; 122 CAPTURE(xsci.sample_count = 1); 123 CAPTURE(xsci.width = 800); 124 CAPTURE(xsci.height = 600); 125 126 CAPTURE(xsci.mip_count = 1); 127 xsci.face_count = 1; 128 xsci.array_size = 1; 129 130 SECTION("create images") 131 { 132 auto nameAndFormat = GENERATE(values(namesAndFormats)); 133 DYNAMIC_SECTION("Texture format " << nameAndFormat.first) 134 { 135 auto format = nameAndFormat.second; 136 CAPTURE(isDepthStencilFormat(format)); 137 xsci.format = format; 138 if (isDepthStencilFormat(format)) { 139 xsci.bits = XRT_SWAPCHAIN_USAGE_DEPTH_STENCIL; 140 } else { 141 xsci.bits = XRT_SWAPCHAIN_USAGE_COLOR; 142 } 143 xsci.bits = (xrt_swapchain_usage_bits)(xsci.bits | XRT_SWAPCHAIN_USAGE_SAMPLED); 144 images.clear(); 145 handles.clear(); 146 147 SECTION("invalid array size 0") 148 { 149 CAPTURE(xsci.array_size = 0); 150 REQUIRE(XRT_SUCCESS != 151 xrt::auxiliary::d3d::d3d12::allocateSharedImages( 152 *device.get(), xsci, image_count, images, handles, out_image_mem_size)); 153 CHECK(images.empty()); 154 CHECK(handles.empty()); 155 } 156 SECTION("not array") 157 { 158 CAPTURE(xsci.array_size); 159 REQUIRE(XRT_SUCCESS == 160 xrt::auxiliary::d3d::d3d12::allocateSharedImages( 161 *device.get(), xsci, image_count, images, handles, out_image_mem_size)); 162 CHECK(images.size() == image_count); 163 CHECK(handles.size() == image_count); 164 CHECK(tryImport(vk.get(), handles, xsci, out_image_mem_size)); 165 } 166 SECTION("array of 2") 167 { 168 CAPTURE(xsci.array_size = 2); 169 REQUIRE(XRT_SUCCESS == 170 xrt::auxiliary::d3d::d3d12::allocateSharedImages( 171 *device.get(), xsci, image_count, images, handles, out_image_mem_size)); 172 CHECK(images.size() == image_count); 173 CHECK(handles.size() == image_count); 174 CHECK(tryImport(vk.get(), handles, xsci, out_image_mem_size)); 175 } 176 // this does not return an error...so i guess allocating cubemaps with d3d12 is fine? 177 // SECTION("cubemaps not implemented") 178 // { 179 // CAPTURE(xsci.array_size); 180 // CAPTURE(xsci.face_count = 6); 181 // REQUIRE(XRT_ERROR_ALLOCATION == 182 // xrt::auxiliary::d3d::d3d12::allocateSharedImages(*device.get(), xsci, 183 // imageCount, 184 // images, handles, 185 // outImageMemSize)); 186 // CHECK(images.empty()); 187 // CHECK(handles.empty()); 188 // } 189 SECTION("protected content not implemented") 190 { 191 CAPTURE(xsci.array_size); 192 CAPTURE(xsci.create = XRT_SWAPCHAIN_CREATE_PROTECTED_CONTENT); 193 REQUIRE(XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED == 194 xrt::auxiliary::d3d::d3d12::allocateSharedImages( 195 *device.get(), xsci, image_count, images, handles, out_image_mem_size)); 196 CHECK(images.empty()); 197 CHECK(handles.empty()); 198 } 199 } 200 } 201}