Skip to content

Commit

Permalink
OpenXRUtilities: added GetOpenXRSwapchainImage function
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Dec 16, 2024
1 parent bf05c1b commit 05a3371
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 6 deletions.
30 changes: 30 additions & 0 deletions Graphics/GraphicsTools/interface/OpenXRUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,36 @@ void DILIGENT_GLOBAL_FUNCTION(AllocateOpenXRSwapchainImageData)(RENDER_DEVICE_TY
Uint32 ImageCount,
IDataBlob** ppSwapchainImageData);

/// Returns the texture object that corresponds to the specified OpenXR swapchain image.
///
/// \param [in] pDevice - Pointer to the render device.
/// \param [in] ImageData - Pointer to the OpenXR swapchain image data returned by xrEnumerateSwapchainImages.
/// \param [in] ImageIndex - Index of the swapchain image.
/// \param [in] TexDesc - Texture description.
/// \param [out] ppImage - Address of the memory location where the pointer to the texture object
/// will be stored.
///
/// \remarks The function creates a texture object that corresponds to the specified OpenXR
/// swapchain image.
///
/// Typically, ImageData should be allocated by AllocateOpenXRSwapchainImageData and
/// filled by xrEnumerateSwapchainImages (see AllocateOpenXRSwapchainImageData):
///
/// RefCntAutoPtr<ITexture> pImage;
/// GetOpenXRSwapchainImage(pDevice, pSwapchainImageData->GetConstDataPtr<XrSwapchainImageBaseHeader>(),
/// ImageIndex, Desc, &pImage);
///
/// TexDesc should be filled with the texture description that corresponds to the swapchain.
/// On Direct3D, the texture parameters will be derived from the swapchain resource.
/// On Vulkan, the texture description should be filled manually since Vulkan does not
/// provide a way to query texture parameters from the image.
///
void DILIGENT_GLOBAL_FUNCTION(GetOpenXRSwapchainImage)(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
const Diligent::TextureDesc REF TexDesc,
ITexture** ppImage);

#include "../../../Primitives/interface/UndefRefMacro.h"

DILIGENT_END_NAMESPACE // namespace Diligent
87 changes: 87 additions & 0 deletions Graphics/GraphicsTools/src/OpenXRUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ void GetOpenXRGraphicsBindingD3D11(IRenderDevice* pDevice,

void AllocateOpenXRSwapchainImageDataD3D11(Uint32 ImageCount,
IDataBlob** ppSwapchainImageData);

void GetOpenXRSwapchainImageD3D11(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
ITexture** ppImage);
#endif

#if D3D12_SUPPORTED
Expand All @@ -47,6 +52,11 @@ void GetOpenXRGraphicsBindingD3D12(IRenderDevice* pDevice,

void AllocateOpenXRSwapchainImageDataD3D12(Uint32 ImageCount,
IDataBlob** ppSwapchainImageData);

void GetOpenXRSwapchainImageD3D12(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
ITexture** ppImage);
#endif

#if GL_SUPPORTED || GLES_SUPPORTED
Expand All @@ -56,6 +66,11 @@ void GetOpenXRGraphicsBindingGL(IRenderDevice* pDevice,

void AllocateOpenXRSwapchainImageDataGL(Uint32 ImageCount,
IDataBlob** ppSwapchainImageData);

void GetOpenXRSwapchainImageGL(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
ITexture** ppImage);
#endif

#if VULKAN_SUPPORTED
Expand All @@ -65,6 +80,12 @@ void GetOpenXRGraphicsBindingVk(IRenderDevice* pDevice,

void AllocateOpenXRSwapchainImageDataVk(Uint32 ImageCount,
IDataBlob** ppSwapchainImageData);

void GetOpenXRSwapchainImageVk(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
const TextureDesc& TexDesc,
ITexture** ppImage);
#endif


Expand Down Expand Up @@ -165,6 +186,63 @@ void AllocateOpenXRSwapchainImageData(RENDER_DEVICE_TYPE DeviceType,
}
}

void GetOpenXRSwapchainImage(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
const TextureDesc& TexDesc,
ITexture** ppImage)
{
if (pDevice == nullptr)
{
UNEXPECTED("pDevice must not be null");
return;
}

if (ImageData == nullptr)
{
UNEXPECTED("ImageData must not be null");
return;
}

if (ppImage == nullptr)
{
UNEXPECTED("ppImage must not be null");
return;
}

RENDER_DEVICE_TYPE DeviceType = pDevice->GetDeviceInfo().Type;
switch (DeviceType)
{
#if D3D11_SUPPORTED
case RENDER_DEVICE_TYPE_D3D11:
GetOpenXRSwapchainImageD3D11(pDevice, ImageData, ImageIndex, ppImage);
break;
#endif

#if D3D12_SUPPORTED
case RENDER_DEVICE_TYPE_D3D12:
GetOpenXRSwapchainImageD3D12(pDevice, ImageData, ImageIndex, ppImage);
break;
#endif

#if GL_SUPPORTED || GLES_SUPPORTED
case RENDER_DEVICE_TYPE_GL:
case RENDER_DEVICE_TYPE_GLES:
GetOpenXRSwapchainImageGL(pDevice, ImageData, ImageIndex, ppImage);
break;
#endif

#if VULKAN_SUPPORTED
case RENDER_DEVICE_TYPE_VULKAN:
GetOpenXRSwapchainImageVk(pDevice, ImageData, ImageIndex, TexDesc, ppImage);
break;
#endif

default:
UNSUPPORTED("Unsupported device type");
}
}

static XrBool32 OpenXRMessageCallbackFunction(XrDebugUtilsMessageSeverityFlagsEXT xrMessageSeverity,
XrDebugUtilsMessageTypeFlagsEXT xrMessageType,
const XrDebugUtilsMessengerCallbackDataEXT* pCallbackData,
Expand Down Expand Up @@ -294,4 +372,13 @@ extern "C"
{
Diligent::AllocateOpenXRSwapchainImageData(DeviceType, ImageCount, ppSwapchainImageData);
}

void Diligent_GetOpenXRSwapchainImage(Diligent::IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Diligent::Uint32 ImageIndex,
const Diligent::TextureDesc& TexDesc,
Diligent::ITexture** ppImage)
{
Diligent::GetOpenXRSwapchainImage(pDevice, ImageData, ImageIndex, TexDesc, ppImage);
}
}
26 changes: 26 additions & 0 deletions Graphics/GraphicsTools/src/OpenXRUtilitiesD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,30 @@ void AllocateOpenXRSwapchainImageDataD3D11(Uint32 ImageCount,
*ppSwapchainImageData = pDataBlob.Detach();
}

void GetOpenXRSwapchainImageD3D11(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
ITexture** ppImage)
{
const XrSwapchainImageD3D11KHR* ImageD3D11 = reinterpret_cast<const XrSwapchainImageD3D11KHR*>(ImageData);

if (ImageData->type != XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR || ImageD3D11[ImageIndex].type != XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR)
{
UNEXPECTED("Unexpected swapchain image type");
return;
}

ID3D11Texture2D* texture = ImageD3D11[ImageIndex].texture;
if (texture == nullptr)
{
UNEXPECTED("D3D11 texture is null");
return;
}

RefCntAutoPtr<IRenderDeviceD3D11> pDeviceD3D11{pDevice, IID_RenderDeviceD3D11};
VERIFY_EXPR(pDeviceD3D11 != nullptr);

pDeviceD3D11->CreateTexture2DFromD3DResource(texture, RESOURCE_STATE_RENDER_TARGET, ppImage);
}

} // namespace Diligent
47 changes: 44 additions & 3 deletions Graphics/GraphicsTools/src/OpenXRUtilitiesD3D12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,27 @@ void GetOpenXRGraphicsBindingD3D12(IRenderDevice* pDevice,

RefCntAutoPtr<IRenderDeviceD3D12> pDeviceD3D12{pDevice, IID_RenderDeviceD3D12};
VERIFY_EXPR(pDeviceD3D12 != nullptr);
RefCntAutoPtr<ICommandQueueD3D12> pQueueD3D12{pContext->LockCommandQueue(), IID_CommandQueueD3D12};
VERIFY_EXPR(pQueueD3D12 != nullptr);

ID3D12CommandQueue* pd3d12Queue = nullptr;
{
ICommandQueue* pQueue = pContext->LockCommandQueue();
VERIFY_EXPR(pQueue != nullptr);
if (RefCntAutoPtr<ICommandQueueD3D12> pQueueD3D12{pQueue, IID_CommandQueueD3D12})
{
pd3d12Queue = pQueueD3D12->GetD3D12CommandQueue();
}
else
{
UNEXPECTED("Command queue is not D3D12 command queue");
}
pContext->UnlockCommandQueue();
}

XrGraphicsBindingD3D12KHR& Binding = *reinterpret_cast<XrGraphicsBindingD3D12KHR*>(pDataBlob->GetDataPtr());
Binding.type = XR_TYPE_GRAPHICS_BINDING_D3D12_KHR;
Binding.next = nullptr;
Binding.device = pDeviceD3D12->GetD3D12Device();
Binding.queue = pQueueD3D12->GetD3D12CommandQueue();
Binding.queue = pd3d12Queue;

*ppGraphicsBinding = pDataBlob.Detach();
}
Expand All @@ -78,4 +91,32 @@ void AllocateOpenXRSwapchainImageDataD3D12(Uint32 ImageCount,
*ppSwapchainImageData = pDataBlob.Detach();
}


void GetOpenXRSwapchainImageD3D12(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
ITexture** ppImage)
{
const XrSwapchainImageD3D12KHR* ImageD3D12 = reinterpret_cast<const XrSwapchainImageD3D12KHR*>(ImageData);

if (ImageData->type != XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR || ImageD3D12[ImageIndex].type != XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR)
{
UNEXPECTED("Unexpected swapchain image type");
return;
}

ID3D12Resource* texture = ImageD3D12[ImageIndex].texture;
if (texture == nullptr)
{
UNEXPECTED("D3D12 texture is null");
return;
}

RefCntAutoPtr<IRenderDeviceD3D12> pDeviceD3D12{pDevice, IID_RenderDeviceD3D12};
VERIFY_EXPR(pDeviceD3D12 != nullptr);

pDeviceD3D12->CreateTextureFromD3DResource(texture, RESOURCE_STATE_RENDER_TARGET, ppImage);
}


} // namespace Diligent
9 changes: 9 additions & 0 deletions Graphics/GraphicsTools/src/OpenXRUtilitiesGL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,13 @@ void AllocateOpenXRSwapchainImageDataGL(Uint32 ImageCount,
*ppSwapchainImageData = pDataBlob.Detach();
}


void GetOpenXRSwapchainImageGL(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
ITexture** ppImage)
{
UNSUPPORTED("Not yet implemented");
}

} // namespace Diligent
46 changes: 43 additions & 3 deletions Graphics/GraphicsTools/src/OpenXRUtilitiesVk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,29 @@ void GetOpenXRGraphicsBindingVk(IRenderDevice* pDevice,

RefCntAutoPtr<IRenderDeviceVk> pDeviceVk{pDevice, IID_RenderDeviceVk};
VERIFY_EXPR(pDeviceVk != nullptr);
RefCntAutoPtr<ICommandQueueVk> pQueueVk{pContext->LockCommandQueue(), IID_CommandQueueVk};
VERIFY_EXPR(pQueueVk != nullptr);

uint32_t queueFamilyIndex = 0;
{
ICommandQueue* pQueue = pContext->LockCommandQueue();
VERIFY_EXPR(pQueue != nullptr);
if (RefCntAutoPtr<ICommandQueueVk> pQueueVk{pQueue, IID_CommandQueueVk})
{
queueFamilyIndex = pQueueVk->GetQueueFamilyIndex();
}
else
{
UNEXPECTED("Command queue is not a Vulkan queue");
}
pContext->UnlockCommandQueue();
}

XrGraphicsBindingVulkanKHR& Binding = *reinterpret_cast<XrGraphicsBindingVulkanKHR*>(pDataBlob->GetDataPtr());
Binding.type = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR;
Binding.next = nullptr;
Binding.instance = pDeviceVk->GetVkInstance();
Binding.physicalDevice = pDeviceVk->GetVkPhysicalDevice();
Binding.device = pDeviceVk->GetVkDevice();
Binding.queueFamilyIndex = pQueueVk->GetQueueFamilyIndex();
Binding.queueFamilyIndex = queueFamilyIndex;
Binding.queueIndex = pContext->GetDesc().ContextId;

*ppGraphicsBinding = pDataBlob.Detach();
Expand All @@ -77,4 +90,31 @@ void AllocateOpenXRSwapchainImageDataVk(Uint32 ImageCount,
*ppSwapchainImageData = pDataBlob.Detach();
}

void GetOpenXRSwapchainImageVk(IRenderDevice* pDevice,
const XrSwapchainImageBaseHeader* ImageData,
Uint32 ImageIndex,
const TextureDesc& TexDesc,
ITexture** ppImage)
{
const XrSwapchainImageVulkanKHR* ImageVk = reinterpret_cast<const XrSwapchainImageVulkanKHR*>(ImageData);

if (ImageData->type != XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR || ImageVk[ImageIndex].type != XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR)
{
UNEXPECTED("Unexpected swapchain image type");
return;
}

VkImage image = ImageVk[ImageIndex].image;
if (image == VK_NULL_HANDLE)
{
UNEXPECTED("Vulkan image is null");
return;
}

RefCntAutoPtr<IRenderDeviceVk> pDeviceVk{pDevice, IID_RenderDeviceVk};
VERIFY_EXPR(pDeviceVk != nullptr);

pDeviceVk->CreateTextureFromVulkanImage(image, TexDesc, RESOURCE_STATE_RENDER_TARGET, ppImage);
}

} // namespace Diligent

0 comments on commit 05a3371

Please sign in to comment.