From 9337ea375c80ccc19cdd1f734f9b5e8983824d65 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Mon, 2 May 2022 16:48:23 -0500 Subject: [PATCH] auxiliary: Add new d3d helper library --- src/xrt/auxiliary/CMakeLists.txt | 24 +++ src/xrt/auxiliary/d3d/d3d_d3d11_allocator.cpp | 188 ++++++++++++++++++ src/xrt/auxiliary/d3d/d3d_d3d11_allocator.h | 34 ++++ src/xrt/auxiliary/d3d/d3d_d3d11_allocator.hpp | 49 +++++ src/xrt/auxiliary/d3d/d3d_dxgi_formats.h | 93 +++++++++ src/xrt/auxiliary/d3d/d3d_helpers.cpp | 144 ++++++++++++++ src/xrt/auxiliary/d3d/d3d_helpers.hpp | 64 ++++++ 7 files changed, 596 insertions(+) create mode 100644 src/xrt/auxiliary/d3d/d3d_d3d11_allocator.cpp create mode 100644 src/xrt/auxiliary/d3d/d3d_d3d11_allocator.h create mode 100644 src/xrt/auxiliary/d3d/d3d_d3d11_allocator.hpp create mode 100644 src/xrt/auxiliary/d3d/d3d_dxgi_formats.h create mode 100644 src/xrt/auxiliary/d3d/d3d_helpers.cpp create mode 100644 src/xrt/auxiliary/d3d/d3d_helpers.hpp diff --git a/src/xrt/auxiliary/CMakeLists.txt b/src/xrt/auxiliary/CMakeLists.txt index 1402d1199..8ce58be57 100644 --- a/src/xrt/auxiliary/CMakeLists.txt +++ b/src/xrt/auxiliary/CMakeLists.txt @@ -32,6 +32,30 @@ if(XRT_HAVE_OPENGL OR XRT_HAVE_OPENGLES) endif() endif() +# Direct3D library +if(XRT_HAVE_D3D11 AND XRT_HAVE_VULKAN) + add_library( + aux_d3d STATIC + d3d/d3d_d3d11_allocator.cpp + d3d/d3d_d3d11_allocator.h + d3d/d3d_d3d11_allocator.hpp + d3d/d3d_dxgi_formats.h + d3d/d3d_helpers.cpp + d3d/d3d_helpers.hpp + ) + target_link_libraries( + aux_d3d + PUBLIC + aux-includes + xrt-interfaces + ${DXGI_LIBRARY} + ${D3D11_LIBRARY} + WIL::WIL + ) + # needed for format includes + target_include_directories(aux_d3d PUBLIC ${Vulkan_INCLUDE_DIR}) +endif() + # Math library. add_library( aux_math STATIC diff --git a/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.cpp b/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.cpp new file mode 100644 index 000000000..7408099bf --- /dev/null +++ b/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.cpp @@ -0,0 +1,188 @@ +// Copyright 2020-2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief D3D backed image buffer allocator. + * @author Ryan Pavlik + * @ingroup aux_d3d + */ + +#include "d3d_d3d11_allocator.h" +#include "d3d_d3d11_allocator.hpp" + +#include "d3d_dxgi_formats.h" + +#include "util/u_misc.h" +#include "util/u_logging.h" +#include "util/u_debug.h" +#include "util/u_handles.h" + +#include "xrt/xrt_windows.h" + +#include +#include +#include +#include + +#include +#include + +#define DEFAULT_CATCH(...) \ + catch (wil::ResultException const &e) \ + { \ + U_LOG_E("Caught exception: %s", e.what()); \ + return __VA_ARGS__; \ + } \ + catch (std::exception const &e) \ + { \ + U_LOG_E("Caught exception: %s", e.what()); \ + return __VA_ARGS__; \ + } \ + catch (...) \ + { \ + U_LOG_E("Caught exception"); \ + return __VA_ARGS__; \ + } + + +DEBUG_GET_ONCE_LOG_OPTION(d3d11_log, "DXGI_LOG", U_LOGGING_WARN) +#define D3DA_TRACE(...) U_LOG_IFL_T(debug_get_log_option_d3d11_log(), __VA_ARGS__) +#define D3DA_DEBUG(...) U_LOG_IFL_D(debug_get_log_option_d3d11_log(), __VA_ARGS__) +#define D3DA_INFO(...) U_LOG_IFL_I(debug_get_log_option_d3d11_log(), __VA_ARGS__) +#define D3DA_WARN(...) U_LOG_IFL_W(debug_get_log_option_d3d11_log(), __VA_ARGS__) +#define D3DA_ERROR(...) U_LOG_IFL_E(debug_get_log_option_d3d11_log(), __VA_ARGS__) + +namespace xrt::auxiliary::d3d { + +wil::unique_handle +createSharedHandle(const wil::com_ptr &image) +{ + + wil::com_ptr dxgiRes; + image.query_to(dxgiRes.put()); + wil::unique_handle h; + THROW_IF_FAILED(dxgiRes->CreateSharedHandle( // + nullptr, // pAttributes + DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, // dwAccess + nullptr, // lpName + h.put())); // pHandle + return h; +} + +xrt_result_t +allocateSharedImages(ID3D11Device5 &device, + const xrt_swapchain_create_info &xsci, + size_t image_count, + bool keyed_mutex, + std::vector> &out_images, + std::vector &out_handles) +try { + if (0 != (xsci.create & XRT_SWAPCHAIN_CREATE_PROTECTED_CONTENT)) { + return XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED; + } + + if (0 != (xsci.create & XRT_SWAPCHAIN_CREATE_STATIC_IMAGE) && image_count > 1) { + D3DA_ERROR("Got XRT_SWAPCHAIN_CREATE_STATIC_IMAGE but an image count greater than 1!"); + return XRT_ERROR_ALLOCATION; + } + CD3D11_TEXTURE2D_DESC1 desc{d3d_dxgi_format_to_typeless_dxgi((DXGI_FORMAT)xsci.format), + xsci.width, + xsci.height, + xsci.array_size, + xsci.mip_count, + d3d_convert_usage_bits_to_bind_flags(xsci.bits)}; + desc.SampleDesc.Count = xsci.sample_count; + desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE; + if (keyed_mutex) { + desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX; + } else { + desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; + } + if (desc.Format == 0) { + D3DA_ERROR("Invalid format %04" PRIx64 "!", (uint64_t)xsci.format); + return XRT_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED; + } + if (xsci.face_count == 6) { + //! @todo implement instead of erroring out + D3DA_ERROR("No idea how to do cube maps in d3d11!"); + return XRT_ERROR_ALLOCATION; + } + // Create textures + std::vector> images; + for (size_t i = 0; i < image_count; ++i) { + wil::com_ptr tex; + THROW_IF_FAILED(device.CreateTexture2D1(&desc, nullptr, tex.put())); + images.emplace_back(std::move(tex)); + } + std::vector handles; + handles.reserve(image_count); + for (const auto &tex : images) { + handles.emplace_back(createSharedHandle(tex)); + } + out_images = std::move(images); + out_handles = std::move(handles); + return XRT_SUCCESS; +} +DEFAULT_CATCH(XRT_ERROR_ALLOCATION) + +} // namespace xrt::auxiliary::d3d + +struct d3d11_allocator +{ + struct xrt_image_native_allocator base; + wil::com_ptr device; +}; + + +static xrt_result_t +d3d11_images_allocate(struct xrt_image_native_allocator *xina, + const struct xrt_swapchain_create_info *xsci, + size_t image_count, + struct xrt_image_native *out_images) +{ + try { + d3d11_allocator *d3da = reinterpret_cast(xina); + + std::vector> images; + std::vector handles; + auto result = xrt::auxiliary::d3d::allocateSharedImages(*(d3da->device), *xsci, image_count, false, + images, handles); + if (XRT_SUCCESS != result) { + return result; + } + // if we made it this far without exceptions, we can safely report back the output. + for (size_t i = 0; i < image_count; ++i) { + out_images[i].handle = handles[i].release(); + } + return XRT_SUCCESS; + } + DEFAULT_CATCH(XRT_ERROR_ALLOCATION) +} + +static xrt_result_t +d3d11_images_free(struct xrt_image_native_allocator *xina, size_t image_count, struct xrt_image_native *images) +{ + for (size_t i = 0; i < image_count; ++i) { + u_graphics_buffer_unref(&(images[i].handle)); + } + return XRT_SUCCESS; +} + +static void +d3d11_destroy(struct xrt_image_native_allocator *xina) +{ + d3d11_allocator *d3da = reinterpret_cast(xina); + delete d3da; +} + +struct xrt_image_native_allocator * +d3d11_allocator_create(ID3D11Device *device) +try { + auto ret = std::make_unique(); + U_ZERO(&(ret->base)); + ret->base.images_allocate = d3d11_images_allocate; + ret->base.images_free = d3d11_images_free; + ret->base.destroy = d3d11_destroy; + return &(ret.release()->base); +} +DEFAULT_CATCH(nullptr) diff --git a/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.h b/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.h new file mode 100644 index 000000000..279161ff8 --- /dev/null +++ b/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.h @@ -0,0 +1,34 @@ +// Copyright 2020-2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Header exposing factory function for D3D11-backed image + buffer allocator. + * @author Ryan Pavlik + * @ingroup aux_d3d + */ + +#pragma once + +#include "xrt/xrt_compositor.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create a XINA that allocates D3D11 textures. + * + * @param device A device to allocate the textures with. Be sure it will not be used from other threads while this + * allocator allocates. + * + * @return struct xrt_image_native_allocator* + */ +struct xrt_image_native_allocator * +d3d11_allocator_create(ID3D11Device *device); + +#ifdef __cplusplus +} +#endif diff --git a/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.hpp b/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.hpp new file mode 100644 index 000000000..6c50ba8d4 --- /dev/null +++ b/src/xrt/auxiliary/d3d/d3d_d3d11_allocator.hpp @@ -0,0 +1,49 @@ +// Copyright 2020-2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Higher-level D3D11-backed image buffer allocation routine + * @author Ryan Pavlik + * @ingroup aux_d3d + */ + +#pragma once + +#include "xrt/xrt_compositor.h" + +#include +#include +#include +#include +#include + +#include + + +namespace xrt::auxiliary::d3d { +/** + * Allocate images (ID3D11Texture2D1) that have a corresponding native handle. + * + * @param device A D3D device to allocate with. + * @param xsci Swapchain create info: note that the format is assumed to be a DXGI_FORMAT (conversion to typeless is + * automatic) + * @param image_count The number of images to create. + * @param keyed_mutex Whether to create images with a shared "keyed mutex" as well + * @param[out] out_images A vector that will be cleared and populated with the images. + * @param[out] out_handles A vector that will be cleared and populated with the corresponding native handles. + * + * @return xrt_result_t, one of: + * - @ref XRT_SUCCESS + * - @ref XRT_ERROR_ALLOCATION + * - @ref XRT_ERROR_SWAPCHAIN_FORMAT_UNSUPPORTED + * - @ref XRT_ERROR_SWAPCHAIN_FLAG_VALID_BUT_UNSUPPORTED + * - @ref XRT_ERROR_D3D11 + */ +xrt_result_t +allocateSharedImages(ID3D11Device5 &device, + const xrt_swapchain_create_info &xsci, + size_t image_count, + bool keyed_mutex, + std::vector> &out_images, + std::vector &out_handles); +}; // namespace xrt::auxiliary::d3d diff --git a/src/xrt/auxiliary/d3d/d3d_dxgi_formats.h b/src/xrt/auxiliary/d3d/d3d_dxgi_formats.h new file mode 100644 index 000000000..a94d80bf5 --- /dev/null +++ b/src/xrt/auxiliary/d3d/d3d_dxgi_formats.h @@ -0,0 +1,93 @@ +// Copyright 2020-2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Format conversion for DXGI/D3D. + * @author Ryan Pavlik + * @ingroup aux_d3d + */ + +#include "xrt/xrt_windows.h" +#include "xrt/xrt_vulkan_includes.h" + +#include + +static inline DXGI_FORMAT +d3d_vk_format_to_dxgi(int64_t format) +{ + switch (format) { + case VK_FORMAT_B8G8R8A8_SRGB: return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + case VK_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_UNORM; + case VK_FORMAT_D16_UNORM: return DXGI_FORMAT_D16_UNORM; + case VK_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT; + case VK_FORMAT_D32_SFLOAT_S8_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case VK_FORMAT_D32_SFLOAT: return DXGI_FORMAT_D32_FLOAT; + case VK_FORMAT_R16G16B16_SFLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; /// @todo OK to just add A? + case VK_FORMAT_R16G16B16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; /// @todo OK to just add A? + case VK_FORMAT_R16G16B16A16_SFLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; + case VK_FORMAT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_UNORM; + case VK_FORMAT_R8G8B8A8_SRGB: return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; + case VK_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_UNORM; // Should not be used, colour precision. + + case VK_FORMAT_X8_D24_UNORM_PACK32: /// @todo DXGI_FORMAT_D24_UNORM_S8_UINT ? + return (DXGI_FORMAT)0; + case VK_FORMAT_A2B10G10R10_UNORM_PACK32: /// @todo DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM ? + return (DXGI_FORMAT)0; + + default: return (DXGI_FORMAT)0; + } +} +static inline DXGI_FORMAT +d3d_dxgi_format_to_typeless_dxgi(DXGI_FORMAT format) +{ + switch (format) { + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return DXGI_FORMAT_B8G8R8A8_TYPELESS; + case DXGI_FORMAT_B8G8R8A8_UNORM: return DXGI_FORMAT_B8G8R8A8_TYPELESS; + case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS; + // case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_D24_UNORM_S8_UINT; + // case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; + case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS; + case DXGI_FORMAT_R16G16B16A16_FLOAT: return DXGI_FORMAT_R16G16B16A16_TYPELESS; + case DXGI_FORMAT_R16G16B16A16_UNORM: return DXGI_FORMAT_R16G16B16A16_TYPELESS; + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return DXGI_FORMAT_R8G8B8A8_TYPELESS; + case DXGI_FORMAT_R8G8B8A8_UNORM: return DXGI_FORMAT_R8G8B8A8_TYPELESS; + default: return format; + } +} + +static inline int64_t +d3d_dxgi_format_to_vk(DXGI_FORMAT format) +{ + switch (format) { + case DXGI_FORMAT_R8G8B8A8_UNORM: return VK_FORMAT_R8G8B8A8_UNORM; // Should not be used, colour precision. + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: return VK_FORMAT_R8G8B8A8_SRGB; + case DXGI_FORMAT_B8G8R8A8_UNORM: return VK_FORMAT_B8G8R8A8_UNORM; + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: return VK_FORMAT_B8G8R8A8_SRGB; + case DXGI_FORMAT_R16G16B16A16_UNORM: return VK_FORMAT_R16G16B16A16_UNORM; + case DXGI_FORMAT_R16G16B16A16_SNORM: return VK_FORMAT_R16G16B16A16_SFLOAT; + case DXGI_FORMAT_D16_UNORM: return VK_FORMAT_D16_UNORM; + case DXGI_FORMAT_D32_FLOAT: return VK_FORMAT_D32_SFLOAT; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return VK_FORMAT_D24_UNORM_S8_UINT; + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return VK_FORMAT_D32_SFLOAT_S8_UINT; + default: return 0; + } +} + +static inline UINT +d3d_convert_usage_bits_to_bind_flags(enum xrt_swapchain_usage_bits xsub) +{ + int ret = 0; + if ((xsub & XRT_SWAPCHAIN_USAGE_COLOR) != 0) { + ret |= D3D11_BIND_RENDER_TARGET; + } + if ((xsub & XRT_SWAPCHAIN_USAGE_DEPTH_STENCIL) != 0) { + ret |= D3D11_BIND_DEPTH_STENCIL; + } + if ((xsub & XRT_SWAPCHAIN_USAGE_UNORDERED_ACCESS) != 0) { + ret |= D3D11_BIND_UNORDERED_ACCESS; + } + if ((xsub & XRT_SWAPCHAIN_USAGE_SAMPLED) != 0) { + ret |= D3D11_BIND_SHADER_RESOURCE; + } + return ret; +} diff --git a/src/xrt/auxiliary/d3d/d3d_helpers.cpp b/src/xrt/auxiliary/d3d/d3d_helpers.cpp new file mode 100644 index 000000000..4968630da --- /dev/null +++ b/src/xrt/auxiliary/d3d/d3d_helpers.cpp @@ -0,0 +1,144 @@ +// Copyright 2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Misc D3D11 helper routines. + * @author Ryan Pavlik + * @ingroup aux_d3d + */ + +#include "d3d_helpers.hpp" + +#include "util/u_logging.h" + +#include +#include +#include +#include + +#include + +namespace xrt::auxiliary::d3d { +template +static wil::com_ptr +try_create_dxgi_factory() +{ + + wil::com_ptr factory; + LOG_IF_FAILED(CreateDXGIFactory1(__uuidof(T), factory.put_void())); + + return factory; +} + +wil::com_ptr +getAdapterByIndex(uint16_t index, u_logging_level log_level) +{ + + wil::com_ptr ret; + auto factory6 = try_create_dxgi_factory(); + if (factory6 != nullptr) { + U_LOG_IFL_I(log_level, "Using IDXGIFactory6::EnumAdapterByGpuPreference to select adapter to use."); + LOG_IF_FAILED(factory6->EnumAdapterByGpuPreference(index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, + __uuidof(IDXGIAdapter), ret.put_void())); + if (ret) { + return ret; + } + // Otherwise fall through to the other factory + } + + auto factory = try_create_dxgi_factory(); + if (factory != nullptr) { + U_LOG_IFL_I(log_level, + "IDXGIFactory6 unavailable, using IDXGIFactory::EnumAdapters to select adapter to use."); + LOG_IF_FAILED(factory->EnumAdapters(index, ret.put())); + return ret; + } + return ret; +} + +wil::com_ptr +getAdapterByLUID(const xrt_luid_t &luid, u_logging_level log_level) +{ + LUID realLuid = reinterpret_cast(luid); + wil::com_ptr ret; + auto factory4 = try_create_dxgi_factory(); + if (factory4 != nullptr) { + U_LOG_IFL_I(log_level, "Using IDXGIFactory4::EnumAdapterByLuid to select adapter to use."); + LOG_IF_FAILED(factory4->EnumAdapterByLuid(realLuid, __uuidof(IDXGIAdapter), ret.put_void())); + if (ret) { + return ret; + } + // Otherwise fall through to the other factory + } + + // This basically is manual implementation of EnumAdapterByLuid + auto factory1 = try_create_dxgi_factory(); + if (factory1 != nullptr) { + U_LOG_IFL_I(log_level, + "IDXGIFactory6 unavailable, using IDXGIFactory1::EnumAdapters1 to select adapter to use."); + for (unsigned int i = 0;; ++i) { + + wil::com_ptr adapter; + if (!SUCCEEDED(factory1->EnumAdapters1(i, adapter.put()))) { + U_LOG_IFL_W(log_level, + "Ran out of adapters using IDXGIFactory1::EnumAdapters1 before finding a " + "matching LUID."); + break; + } + DXGI_ADAPTER_DESC1 desc{}; + if (!SUCCEEDED(adapter->GetDesc1(&desc))) { + continue; + } + if (realLuid.HighPart == desc.AdapterLuid.HighPart && + realLuid.LowPart == desc.AdapterLuid.LowPart) { + ret = adapter; + break; + } + } + } + return ret; +} + +HRESULT +tryCreateD3D11Device(const wil::com_ptr &adapter, + D3D_DRIVER_TYPE driver_type, + unsigned int creation_flags, + const std::vector &feature_levels, + wil::com_ptr &out_device, + wil::com_ptr &out_context) +{ + return D3D11CreateDevice(wil::com_raw_ptr(adapter), driver_type, nullptr, creation_flags, feature_levels.data(), + (UINT)feature_levels.size(), D3D11_SDK_VERSION, out_device.put(), nullptr, + out_context.put()); +} + +std::pair, wil::com_ptr> +createD3D11Device(const wil::com_ptr &adapter, u_logging_level log_level) +{ + D3D_DRIVER_TYPE driver_type = D3D_DRIVER_TYPE_HARDWARE; + if (adapter) { + // needed if we pass an adapter. + U_LOG_IFL_D(log_level, "Adapter provided."); + driver_type = D3D_DRIVER_TYPE_UNKNOWN; + } + unsigned int creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT; +#ifndef NDEBUG + U_LOG_IFL_D(log_level, "Will attempt to create our device using the debug layer."); + creation_flags |= D3D11_CREATE_DEVICE_DEBUG; +#endif + + std::vector feature_levels{D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0}; + wil::com_ptr device; + wil::com_ptr context; + HRESULT hr = tryCreateD3D11Device(adapter, driver_type, creation_flags, feature_levels, device, context); +#ifndef NDEBUG + if (hr == DXGI_ERROR_SDK_COMPONENT_MISSING) { + U_LOG_IFL_D(log_level, "Removing the debug layer flag: not successful."); + creation_flags &= ~D3D11_CREATE_DEVICE_DEBUG; + hr = tryCreateD3D11Device(adapter, driver_type, creation_flags, feature_levels, device, context); + } +#endif + THROW_IF_FAILED(hr); + return {device, context}; +} +} // namespace xrt::auxiliary::d3d diff --git a/src/xrt/auxiliary/d3d/d3d_helpers.hpp b/src/xrt/auxiliary/d3d/d3d_helpers.hpp new file mode 100644 index 000000000..b58bba445 --- /dev/null +++ b/src/xrt/auxiliary/d3d/d3d_helpers.hpp @@ -0,0 +1,64 @@ +// Copyright 2022, Collabora, Ltd. +// SPDX-License-Identifier: BSL-1.0 +/*! + * @file + * @brief Misc D3D11 helper routines. + * @author Ryan Pavlik + * @ingroup aux_d3d + */ + +#pragma once + +#include "xrt/xrt_defines.h" +#include "xrt/xrt_compositor.h" + +#include "util/u_logging.h" + +#include +#include +#include + +#include + +namespace xrt::auxiliary::d3d { + +/** + * @brief Create a DXGI Adapter, using our priorities. + * + * We try to use IDXGIFactory6::EnumAdapterByGpuPreference preferring HIGH_PERFORMANCE, if it's available + * + * @param index The requested adapter index + * @param log_level The level to compare against for internal log messages + * + * @throws wil::ResultException in case of error + * + * @return wil::com_ptr + */ +wil::com_ptr +getAdapterByIndex(uint16_t index, u_logging_level log_level = U_LOGGING_INFO); + +/** + * @brief Create a DXGI Adapter, for the provided LUID. + * + * @param luid The requested adapter luid + * @param log_level The level to compare against for internal log messages + * @throws wil::ResultException in case of error + * + * @return wil::com_ptr + */ +wil::com_ptr +getAdapterByLUID(const xrt_luid_t &luid, u_logging_level log_level = U_LOGGING_INFO); + +/** + * @brief Create a D3D11 Device object + * + * @param adapter optional: adapter to create on. + * @param log_level The level to compare against for internal log messages + * + * @throws wil::ResultException in case of error + * + * @return std::pair, wil::com_ptr> + */ +std::pair, wil::com_ptr> +createD3D11Device(const wil::com_ptr &adapter = nullptr, u_logging_level log_level = U_LOGGING_INFO); +} // namespace xrt::auxiliary::d3d