st/oxr: Work on D3D11

This commit is contained in:
Ryan Pavlik 2022-05-16 10:44:47 -05:00 committed by Jakob Bornecrantz
parent 945603a8be
commit cdb8d54ca1
13 changed files with 354 additions and 1 deletions

View file

@ -2,4 +2,4 @@
- mr.1263
- mr.1295
---
Work toward support for D3D11 client applications on Windows.
Initial support for D3D11 client applications on Windows.

View file

@ -69,6 +69,12 @@ if(XRT_HAVE_EGL)
target_sources(st_oxr PRIVATE oxr_session_gfx_egl.c)
endif()
if(XRT_HAVE_D3D11)
target_compile_definitions(st_oxr PRIVATE XR_USE_GRAPHICS_API_D3D11)
target_sources(st_oxr PRIVATE oxr_session_gfx_d3d11.c oxr_swapchain_d3d11.c oxr_d3d11.cpp)
target_link_libraries(st_oxr PRIVATE aux_d3d)
endif()
if(ANDROID)
target_compile_definitions(st_oxr PRIVATE XR_USE_PLATFORM_ANDROID)
target_sources(st_oxr PRIVATE oxr_session_gfx_gles_android.c)

View file

@ -224,6 +224,14 @@ oxr_xrCreateVulkanDeviceKHR(XrInstance instance,
VkResult *vulkanResult);
#endif
#ifdef XR_USE_GRAPHICS_API_D3D11
//! OpenXR API function @ep{xrGetD3D11GraphicsRequirementsKHR}
XRAPI_ATTR XrResult XRAPI_CALL
oxr_xrGetD3D11GraphicsRequirementsKHR(XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsD3D11KHR *graphicsRequirements);
#endif // XR_USE_GRAPHICS_API_D3D11
/*
*

View file

@ -265,6 +265,10 @@ handle_non_null(struct oxr_instance *inst, struct oxr_logger *log, const char *n
ENTRY_IF_EXT(xrCreateVulkanInstanceKHR, KHR_vulkan_enable2);
#endif // OXR_HAVE_KHR_vulkan_enable2
#ifdef OXR_HAVE_KHR_D3D11_enable
ENTRY_IF_EXT(xrGetD3D11GraphicsRequirementsKHR, KHR_D3D11_enable);
#endif // OXR_HAVE_KHR_D3D11_enable
/*
* Not logging here because there's no need to loudly advertise
* which extensions the loader knows about (it calls this on

View file

@ -417,3 +417,30 @@ oxr_xrCreateVulkanDeviceKHR(XrInstance instance,
return oxr_vk_create_vulkan_device(&log, sys, createInfo, vulkanDevice, vulkanResult);
}
#endif
/*
*
* D3D11
*
*/
#ifdef XR_USE_GRAPHICS_API_D3D11
XrResult
oxr_xrGetD3D11GraphicsRequirementsKHR(XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsD3D11KHR *graphicsRequirements)
{
struct oxr_instance *inst;
struct oxr_logger log;
OXR_VERIFY_INSTANCE_AND_INIT_LOG(&log, instance, inst, "xrGetD3D11GraphicsRequirementsKHR");
OXR_VERIFY_ARG_TYPE_AND_NOT_NULL(&log, graphicsRequirements, XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR);
OXR_VERIFY_SYSTEM_AND_GET(&log, inst, systemId, sys);
sys->gotten_requirements = true;
return oxr_d3d11_get_requirements(&log, sys, graphicsRequirements);
}
#endif

View file

@ -276,6 +276,10 @@ oxr_verify_XrGraphicsBindingOpenGLESAndroidKHR(struct oxr_logger *, const XrGrap
#endif // defined(XR_USE_PLATFORM_ANDROID) &&
// defined(XR_USE_GRAPHICS_API_OPENGL_ES)
#if defined(XR_USE_GRAPHICS_API_D3D11)
XrResult
oxr_verify_XrGraphicsBindingD3D11KHR(struct oxr_logger *, const XrGraphicsBindingD3D11KHR *);
#endif // defined(XR_USE_GRAPHICS_API_D3D11)
/*!
* @}
*/

View file

@ -0,0 +1,92 @@
// Copyright 2021, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Holds D3D11 related functions that didn't fit somewhere else.
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
* @ingroup oxr_main
*/
#include "xrt/xrt_gfx_d3d11.h"
#include "util/u_misc.h"
#include "util/u_debug.h"
#include "d3d/d3d_helpers.hpp"
#include "oxr_objects.h"
#include "oxr_logger.h"
#include <dxgi1_6.h>
#include <d3d11_4.h>
#include <wil/com.h>
#include <wil/result.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define DEFAULT_CATCH(MSG) \
catch (wil::ResultException const &e) \
{ \
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, MSG ": %s", e.what()); \
} \
catch (std::exception const &e) \
{ \
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, MSG ": %s", e.what()); \
} \
catch (...) \
{ \
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, MSG); \
}
using namespace xrt::auxiliary::d3d;
XrResult
oxr_d3d11_get_requirements(struct oxr_logger *log,
struct oxr_system *sys,
XrGraphicsRequirementsD3D11KHR *graphicsRequirements)
{
try {
if (sys->xsysc->info.client_d3d_deviceLUID_valid) {
sys->suggested_d3d_luid =
reinterpret_cast<const LUID &>(sys->xsysc->info.client_d3d_deviceLUID);
} else {
auto adapter = getAdapterByIndex(0, U_LOGGING_INFO);
if (adapter == nullptr) {
return oxr_error(log, XR_ERROR_RUNTIME_FAILURE, " failure enumerating adapter LUIDs.");
}
DXGI_ADAPTER_DESC desc{};
THROW_IF_FAILED(adapter->GetDesc(&desc));
sys->suggested_d3d_luid = desc.AdapterLuid;
}
sys->suggested_d3d_luid_valid = true;
graphicsRequirements->adapterLuid = sys->suggested_d3d_luid;
//! @todo implement better?
graphicsRequirements->minFeatureLevel = D3D_FEATURE_LEVEL_11_0;
return XR_SUCCESS;
}
DEFAULT_CATCH(" failure determining adapter LUID")
}
XrResult
oxr_d3d11_check_device(struct oxr_logger *log, struct oxr_system *sys, ID3D11Device *device)
{
try {
wil::com_ptr<IDXGIDevice> dxgiDevice;
THROW_IF_FAILED(device->QueryInterface(dxgiDevice.put()));
wil::com_ptr<IDXGIAdapter> adapter;
THROW_IF_FAILED(dxgiDevice->GetAdapter(adapter.put()));
DXGI_ADAPTER_DESC desc{};
adapter->GetDesc(&desc);
if (desc.AdapterLuid.HighPart != sys->suggested_d3d_luid.HighPart ||
desc.AdapterLuid.LowPart != sys->suggested_d3d_luid.LowPart) {
return oxr_error(log, XR_ERROR_GRAPHICS_DEVICE_INVALID,
" supplied device does not match required LUID.");
}
return XR_SUCCESS;
}
DEFAULT_CATCH(" failure checking adapter LUID")
}

View file

@ -1110,6 +1110,42 @@ oxr_session_populate_egl(struct oxr_logger *log,
#endif
/*
*
* D3D11, located in various files.
*
*/
#ifdef XR_USE_GRAPHICS_API_D3D11
XrResult
oxr_d3d11_get_requirements(struct oxr_logger *log,
struct oxr_system *sys,
XrGraphicsRequirementsD3D11KHR *graphicsRequirements);
/**
* @brief Check to ensure the device provided at session create matches the LUID we returned earlier.
*
* @return XR_SUCCESS if the device matches the LUID
*/
XrResult
oxr_d3d11_check_device(struct oxr_logger *log, struct oxr_system *sys, ID3D11Device *device);
XrResult
oxr_session_populate_d3d11(struct oxr_logger *log,
struct oxr_system *sys,
XrGraphicsBindingD3D11KHR const *next,
struct oxr_session *sess);
XrResult
oxr_swapchain_d3d11_create(struct oxr_logger *,
struct oxr_session *sess,
const XrSwapchainCreateInfo *,
struct oxr_swapchain **out_swapchain);
#endif
/*
*
* Structs
@ -1205,6 +1241,10 @@ struct oxr_system
} vk;
#endif
#ifdef XR_USE_GRAPHICS_API_D3D11
LUID suggested_d3d_luid;
bool suggested_d3d_luid_valid;
#endif
};
#define GET_XDEV_BY_ROLE(SYS, ROLE) ((SYS)->xsysd->roles.ROLE)
@ -1219,6 +1259,7 @@ struct oxr_extension_status
{
OXR_EXTENSION_SUPPORT_GENERATE(MAKE_EXT_STATUS)
};
#undef MAKE_EXT_STATUS
/*!
* Main object that ties everything together.

View file

@ -734,6 +734,28 @@ oxr_session_create_impl(struct oxr_logger *log,
}
#endif
#ifdef XR_USE_GRAPHICS_API_D3D11
XrGraphicsBindingD3D11KHR const *d3d11 =
OXR_GET_INPUT_FROM_CHAIN(createInfo, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR, XrGraphicsBindingD3D11KHR);
if (d3d11 != NULL) {
OXR_VERIFY_ARG_NOT_NULL(log, d3d11->device);
if (!sys->gotten_requirements) {
return oxr_error(log, XR_ERROR_GRAPHICS_REQUIREMENTS_CALL_MISSING,
"Has not called xrGetD3D11GraphicsRequirementsKHR");
}
XrResult result = oxr_d3d11_check_device(log, sys, d3d11->device);
if (!XR_SUCCEEDED(result)) {
return result;
}
OXR_SESSION_ALLOCATE(log, sys, *out_session);
OXR_ALLOCATE_NATIVE_COMPOSITOR(log, xsi, *out_session);
return oxr_session_populate_d3d11(log, sys, d3d11, *out_session);
}
#endif
/*
* Add any new graphics binding structs here - before the headless
* check. (order for non-headless checks not specified in standard.)

View file

@ -0,0 +1,44 @@
// Copyright 2018-2021, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Holds D3D11 specific session functions.
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup oxr_main
* @ingroup comp_client
*/
#include <stdlib.h>
#include "util/u_misc.h"
#include "xrt/xrt_instance.h"
#include "xrt/xrt_gfx_d3d11.h"
#include "oxr_objects.h"
#include "oxr_logger.h"
#include "oxr_two_call.h"
#include "oxr_handle.h"
XrResult
oxr_session_populate_d3d11(struct oxr_logger *log,
struct oxr_system *sys,
XrGraphicsBindingD3D11KHR const *next,
struct oxr_session *sess)
{
struct xrt_compositor_native *xcn = sess->xcn;
struct xrt_compositor_d3d11 *xcd3d = xrt_gfx_d3d11_provider_create( //
xcn, //
next->device); //
if (xcd3d == NULL) {
return oxr_error(log, XR_ERROR_INITIALIZATION_FAILED, "Failed to create a d3d11 client compositor");
}
sess->compositor = &xcd3d->base;
sess->create_swapchain = oxr_swapchain_d3d11_create;
return XR_SUCCESS;
}

View file

@ -0,0 +1,78 @@
// Copyright 2019-2021, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Holds D3D11 swapchain related functions.
* @author Ryan Pavlik <ryan.pavlik@collabora.com>
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup oxr_main
* @ingroup comp_client
*/
#include <stdlib.h>
#include "xrt/xrt_gfx_d3d11.h"
#include "util/u_debug.h"
#include "oxr_objects.h"
#include "oxr_logger.h"
static XrResult
oxr_swapchain_d3d11_destroy(struct oxr_logger *log, struct oxr_swapchain *sc)
{
// Release any waited image.
if (sc->waited.yes) {
sc->release_image(log, sc, NULL);
}
// Release any acquired images.
XrSwapchainImageWaitInfo waitInfo = {0};
while (!u_index_fifo_is_empty(&sc->acquired.fifo)) {
sc->wait_image(log, sc, &waitInfo);
sc->release_image(log, sc, NULL);
}
// Drop our reference, does NULL checking.
xrt_swapchain_reference(&sc->swapchain, NULL);
return XR_SUCCESS;
}
static XrResult
oxr_swapchain_d3d11_enumerate_images(struct oxr_logger *log,
struct oxr_swapchain *sc,
uint32_t count,
XrSwapchainImageBaseHeader *images)
{
struct xrt_swapchain_d3d11 *xscd3d = (struct xrt_swapchain_d3d11 *)sc->swapchain;
XrSwapchainImageD3D11KHR *d3d_imgs = (XrSwapchainImageD3D11KHR *)images;
for (uint32_t i = 0; i < count; i++) {
d3d_imgs[i].texture = xscd3d->images[i];
}
return oxr_session_success_result(sc->sess);
}
XrResult
oxr_swapchain_d3d11_create(struct oxr_logger *log,
struct oxr_session *sess,
const XrSwapchainCreateInfo *createInfo,
struct oxr_swapchain **out_swapchain)
{
struct oxr_swapchain *sc;
XrResult ret;
ret = oxr_create_swapchain(log, sess, createInfo, &sc);
if (ret != XR_SUCCESS) {
return ret;
}
sc->destroy = oxr_swapchain_d3d11_destroy;
sc->enumerate_images = oxr_swapchain_d3d11_enumerate_images;
*out_swapchain = sc;
return XR_SUCCESS;
}

View file

@ -103,6 +103,10 @@ oxr_system_fill_in(struct oxr_logger *log, struct oxr_instance *inst, XrSystemId
sys->vulkan_enable2_instance = VK_NULL_HANDLE;
sys->suggested_vulkan_physical_device = VK_NULL_HANDLE;
#endif
#ifdef XR_USE_GRAPHICS_API_D3D11
U_ZERO(&(sys->suggested_d3d_luid));
sys->suggested_d3d_luid_valid = false;
#endif
// Headless.
if (sys->xsysc == NULL) {

View file

@ -494,6 +494,15 @@ oxr_verify_XrSessionCreateInfo(struct oxr_logger *log,
}
#endif // defined(XR_USE_PLATFORM_ANDROID) && defined(XR_USE_GRAPHICS_API_OPENGL_ES)
#if defined(XR_USE_GRAPHICS_API_D3D11)
XrGraphicsBindingD3D11KHR const *d3d11 =
OXR_GET_INPUT_FROM_CHAIN(createInfo, XR_TYPE_GRAPHICS_BINDING_D3D11_KHR, XrGraphicsBindingD3D11KHR);
if (d3d11 != NULL) {
OXR_VERIFY_EXTENSION(log, inst, KHR_D3D11_enable);
return oxr_verify_XrGraphicsBindingD3D11KHR(log, d3d11);
}
#endif // XR_USE_GRAPHICS_API_D3D11
/*
* Add any new graphics binding structs here - before the headless
* check. (order for non-headless checks not specified in standard.)
@ -603,3 +612,17 @@ oxr_verify_XrGraphicsBindingOpenGLESAndroidKHR(struct oxr_logger *log, const XrG
}
#endif // defined(XR_USE_PLATFORM_ANDROID) &&
// defined(XR_USE_GRAPHICS_API_OPENGL_ES)
#if defined(XR_USE_GRAPHICS_API_D3D11)
XrResult
oxr_verify_XrGraphicsBindingD3D11KHR(struct oxr_logger *log, const XrGraphicsBindingD3D11KHR *next)
{
if (next->type != XR_TYPE_GRAPHICS_BINDING_D3D11_KHR) {
return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, "Graphics binding has invalid type");
}
if (next->device == NULL) {
return oxr_error(log, XR_ERROR_VALIDATION_FAILURE, "XrGraphicsBindingD3D11KHR::device cannot be NULL");
}
return XR_SUCCESS;
}
#endif // defined(XR_USE_GRAPHICS_API_D3D11)