Skip to content

Commit d6caeb2

Browse files
OpenXRUtilities: added GetOpenXRSwapchainImage function
1 parent 5185619 commit d6caeb2

File tree

6 files changed

+239
-6
lines changed

6 files changed

+239
-6
lines changed

Graphics/GraphicsTools/interface/OpenXRUtilities.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,36 @@ void DILIGENT_GLOBAL_FUNCTION(AllocateOpenXRSwapchainImageData)(RENDER_DEVICE_TY
8989
Uint32 ImageCount,
9090
IDataBlob** ppSwapchainImageData);
9191

92+
/// Returns the texture object that corresponds to the specified OpenXR swapchain image.
93+
///
94+
/// \param [in] pDevice - Pointer to the render device.
95+
/// \param [in] ImageData - Pointer to the OpenXR swapchain image data returned by xrEnumerateSwapchainImages.
96+
/// \param [in] ImageIndex - Index of the swapchain image.
97+
/// \param [in] TexDesc - Texture description.
98+
/// \param [out] ppImage - Address of the memory location where the pointer to the texture object
99+
/// will be stored.
100+
///
101+
/// \remarks The function creates a texture object that corresponds to the specified OpenXR
102+
/// swapchain image.
103+
///
104+
/// Typically, ImageData should be allocated by AllocateOpenXRSwapchainImageData and
105+
/// filled by xrEnumerateSwapchainImages (see AllocateOpenXRSwapchainImageData):
106+
///
107+
/// RefCntAutoPtr<ITexture> pImage;
108+
/// GetOpenXRSwapchainImage(pDevice, pSwapchainImageData->GetConstDataPtr<XrSwapchainImageBaseHeader>(),
109+
/// ImageIndex, Desc, &pImage);
110+
///
111+
/// TexDesc should be filled with the texture description that corresponds to the swapchain.
112+
/// On Direct3D, the texture parameters will be derived from the swapchain resource.
113+
/// On Vulkan, the texture description should be filled manually since Vulkan does not
114+
/// provide a way to query texture parameters from the image.
115+
///
116+
void DILIGENT_GLOBAL_FUNCTION(GetOpenXRSwapchainImage)(IRenderDevice* pDevice,
117+
const XrSwapchainImageBaseHeader* ImageData,
118+
Uint32 ImageIndex,
119+
const Diligent::TextureDesc REF TexDesc,
120+
ITexture** ppImage);
121+
92122
#include "../../../Primitives/interface/UndefRefMacro.h"
93123

94124
DILIGENT_END_NAMESPACE // namespace Diligent

Graphics/GraphicsTools/src/OpenXRUtilities.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ void GetOpenXRGraphicsBindingD3D11(IRenderDevice* pDevice,
3838

3939
void AllocateOpenXRSwapchainImageDataD3D11(Uint32 ImageCount,
4040
IDataBlob** ppSwapchainImageData);
41+
42+
void GetOpenXRSwapchainImageD3D11(IRenderDevice* pDevice,
43+
const XrSwapchainImageBaseHeader* ImageData,
44+
Uint32 ImageIndex,
45+
ITexture** ppImage);
4146
#endif
4247

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

4853
void AllocateOpenXRSwapchainImageDataD3D12(Uint32 ImageCount,
4954
IDataBlob** ppSwapchainImageData);
55+
56+
void GetOpenXRSwapchainImageD3D12(IRenderDevice* pDevice,
57+
const XrSwapchainImageBaseHeader* ImageData,
58+
Uint32 ImageIndex,
59+
ITexture** ppImage);
5060
#endif
5161

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

5767
void AllocateOpenXRSwapchainImageDataGL(Uint32 ImageCount,
5868
IDataBlob** ppSwapchainImageData);
69+
70+
void GetOpenXRSwapchainImageGL(IRenderDevice* pDevice,
71+
const XrSwapchainImageBaseHeader* ImageData,
72+
Uint32 ImageIndex,
73+
ITexture** ppImage);
5974
#endif
6075

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

6681
void AllocateOpenXRSwapchainImageDataVk(Uint32 ImageCount,
6782
IDataBlob** ppSwapchainImageData);
83+
84+
void GetOpenXRSwapchainImageVk(IRenderDevice* pDevice,
85+
const XrSwapchainImageBaseHeader* ImageData,
86+
Uint32 ImageIndex,
87+
const TextureDesc& TexDesc,
88+
ITexture** ppImage);
6889
#endif
6990

7091

@@ -165,6 +186,63 @@ void AllocateOpenXRSwapchainImageData(RENDER_DEVICE_TYPE DeviceType,
165186
}
166187
}
167188

189+
void GetOpenXRSwapchainImage(IRenderDevice* pDevice,
190+
const XrSwapchainImageBaseHeader* ImageData,
191+
Uint32 ImageIndex,
192+
const TextureDesc& TexDesc,
193+
ITexture** ppImage)
194+
{
195+
if (pDevice == nullptr)
196+
{
197+
UNEXPECTED("pDevice must not be null");
198+
return;
199+
}
200+
201+
if (ImageData == nullptr)
202+
{
203+
UNEXPECTED("ImageData must not be null");
204+
return;
205+
}
206+
207+
if (ppImage == nullptr)
208+
{
209+
UNEXPECTED("ppImage must not be null");
210+
return;
211+
}
212+
213+
RENDER_DEVICE_TYPE DeviceType = pDevice->GetDeviceInfo().Type;
214+
switch (DeviceType)
215+
{
216+
#if D3D11_SUPPORTED
217+
case RENDER_DEVICE_TYPE_D3D11:
218+
GetOpenXRSwapchainImageD3D11(pDevice, ImageData, ImageIndex, ppImage);
219+
break;
220+
#endif
221+
222+
#if D3D12_SUPPORTED
223+
case RENDER_DEVICE_TYPE_D3D12:
224+
GetOpenXRSwapchainImageD3D12(pDevice, ImageData, ImageIndex, ppImage);
225+
break;
226+
#endif
227+
228+
#if GL_SUPPORTED || GLES_SUPPORTED
229+
case RENDER_DEVICE_TYPE_GL:
230+
case RENDER_DEVICE_TYPE_GLES:
231+
GetOpenXRSwapchainImageGL(pDevice, ImageData, ImageIndex, ppImage);
232+
break;
233+
#endif
234+
235+
#if VULKAN_SUPPORTED
236+
case RENDER_DEVICE_TYPE_VULKAN:
237+
GetOpenXRSwapchainImageVk(pDevice, ImageData, ImageIndex, TexDesc, ppImage);
238+
break;
239+
#endif
240+
241+
default:
242+
UNSUPPORTED("Unsupported device type");
243+
}
244+
}
245+
168246
static XrBool32 OpenXRMessageCallbackFunction(XrDebugUtilsMessageSeverityFlagsEXT xrMessageSeverity,
169247
XrDebugUtilsMessageTypeFlagsEXT xrMessageType,
170248
const XrDebugUtilsMessengerCallbackDataEXT* pCallbackData,
@@ -294,4 +372,13 @@ extern "C"
294372
{
295373
Diligent::AllocateOpenXRSwapchainImageData(DeviceType, ImageCount, ppSwapchainImageData);
296374
}
375+
376+
void Diligent_GetOpenXRSwapchainImage(Diligent::IRenderDevice* pDevice,
377+
const XrSwapchainImageBaseHeader* ImageData,
378+
Diligent::Uint32 ImageIndex,
379+
const Diligent::TextureDesc& TexDesc,
380+
Diligent::ITexture** ppImage)
381+
{
382+
Diligent::GetOpenXRSwapchainImage(pDevice, ImageData, ImageIndex, TexDesc, ppImage);
383+
}
297384
}

Graphics/GraphicsTools/src/OpenXRUtilitiesD3D11.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,30 @@ void AllocateOpenXRSwapchainImageDataD3D11(Uint32 ImageCount,
7373
*ppSwapchainImageData = pDataBlob.Detach();
7474
}
7575

76+
void GetOpenXRSwapchainImageD3D11(IRenderDevice* pDevice,
77+
const XrSwapchainImageBaseHeader* ImageData,
78+
Uint32 ImageIndex,
79+
ITexture** ppImage)
80+
{
81+
const XrSwapchainImageD3D11KHR* ImageD3D11 = reinterpret_cast<const XrSwapchainImageD3D11KHR*>(ImageData);
82+
83+
if (ImageData->type != XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR || ImageD3D11[ImageIndex].type != XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR)
84+
{
85+
UNEXPECTED("Unexpected swapchain image type");
86+
return;
87+
}
88+
89+
ID3D11Texture2D* texture = ImageD3D11[ImageIndex].texture;
90+
if (texture == nullptr)
91+
{
92+
UNEXPECTED("D3D11 texture is null");
93+
return;
94+
}
95+
96+
RefCntAutoPtr<IRenderDeviceD3D11> pDeviceD3D11{pDevice, IID_RenderDeviceD3D11};
97+
VERIFY_EXPR(pDeviceD3D11 != nullptr);
98+
99+
pDeviceD3D11->CreateTexture2DFromD3DResource(texture, RESOURCE_STATE_RENDER_TARGET, ppImage);
100+
}
101+
76102
} // namespace Diligent

Graphics/GraphicsTools/src/OpenXRUtilitiesD3D12.cpp

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,27 @@ void GetOpenXRGraphicsBindingD3D12(IRenderDevice* pDevice,
5252

5353
RefCntAutoPtr<IRenderDeviceD3D12> pDeviceD3D12{pDevice, IID_RenderDeviceD3D12};
5454
VERIFY_EXPR(pDeviceD3D12 != nullptr);
55-
RefCntAutoPtr<ICommandQueueD3D12> pQueueD3D12{pContext->LockCommandQueue(), IID_CommandQueueD3D12};
56-
VERIFY_EXPR(pQueueD3D12 != nullptr);
55+
56+
ID3D12CommandQueue* pd3d12Queue = nullptr;
57+
{
58+
ICommandQueue* pQueue = pContext->LockCommandQueue();
59+
VERIFY_EXPR(pQueue != nullptr);
60+
if (RefCntAutoPtr<ICommandQueueD3D12> pQueueD3D12{pQueue, IID_CommandQueueD3D12})
61+
{
62+
pd3d12Queue = pQueueD3D12->GetD3D12CommandQueue();
63+
}
64+
else
65+
{
66+
UNEXPECTED("Command queue is not D3D12 command queue");
67+
}
68+
pContext->UnlockCommandQueue();
69+
}
5770

5871
XrGraphicsBindingD3D12KHR& Binding = *reinterpret_cast<XrGraphicsBindingD3D12KHR*>(pDataBlob->GetDataPtr());
5972
Binding.type = XR_TYPE_GRAPHICS_BINDING_D3D12_KHR;
6073
Binding.next = nullptr;
6174
Binding.device = pDeviceD3D12->GetD3D12Device();
62-
Binding.queue = pQueueD3D12->GetD3D12CommandQueue();
75+
Binding.queue = pd3d12Queue;
6376

6477
*ppGraphicsBinding = pDataBlob.Detach();
6578
}
@@ -78,4 +91,32 @@ void AllocateOpenXRSwapchainImageDataD3D12(Uint32 ImageCount,
7891
*ppSwapchainImageData = pDataBlob.Detach();
7992
}
8093

94+
95+
void GetOpenXRSwapchainImageD3D12(IRenderDevice* pDevice,
96+
const XrSwapchainImageBaseHeader* ImageData,
97+
Uint32 ImageIndex,
98+
ITexture** ppImage)
99+
{
100+
const XrSwapchainImageD3D12KHR* ImageD3D12 = reinterpret_cast<const XrSwapchainImageD3D12KHR*>(ImageData);
101+
102+
if (ImageData->type != XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR || ImageD3D12[ImageIndex].type != XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR)
103+
{
104+
UNEXPECTED("Unexpected swapchain image type");
105+
return;
106+
}
107+
108+
ID3D12Resource* texture = ImageD3D12[ImageIndex].texture;
109+
if (texture == nullptr)
110+
{
111+
UNEXPECTED("D3D12 texture is null");
112+
return;
113+
}
114+
115+
RefCntAutoPtr<IRenderDeviceD3D12> pDeviceD3D12{pDevice, IID_RenderDeviceD3D12};
116+
VERIFY_EXPR(pDeviceD3D12 != nullptr);
117+
118+
pDeviceD3D12->CreateTextureFromD3DResource(texture, RESOURCE_STATE_RENDER_TARGET, ppImage);
119+
}
120+
121+
81122
} // namespace Diligent

Graphics/GraphicsTools/src/OpenXRUtilitiesGL.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,4 +56,13 @@ void AllocateOpenXRSwapchainImageDataGL(Uint32 ImageCount,
5656
*ppSwapchainImageData = pDataBlob.Detach();
5757
}
5858

59+
60+
void GetOpenXRSwapchainImageGL(IRenderDevice* pDevice,
61+
const XrSwapchainImageBaseHeader* ImageData,
62+
Uint32 ImageIndex,
63+
ITexture** ppImage)
64+
{
65+
UNSUPPORTED("Not yet implemented");
66+
}
67+
5968
} // namespace Diligent

Graphics/GraphicsTools/src/OpenXRUtilitiesVk.cpp

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,29 @@ void GetOpenXRGraphicsBindingVk(IRenderDevice* pDevice,
4848

4949
RefCntAutoPtr<IRenderDeviceVk> pDeviceVk{pDevice, IID_RenderDeviceVk};
5050
VERIFY_EXPR(pDeviceVk != nullptr);
51-
RefCntAutoPtr<ICommandQueueVk> pQueueVk{pContext->LockCommandQueue(), IID_CommandQueueVk};
52-
VERIFY_EXPR(pQueueVk != nullptr);
51+
52+
uint32_t queueFamilyIndex = 0;
53+
{
54+
ICommandQueue* pQueue = pContext->LockCommandQueue();
55+
VERIFY_EXPR(pQueue != nullptr);
56+
if (RefCntAutoPtr<ICommandQueueVk> pQueueVk{pQueue, IID_CommandQueueVk})
57+
{
58+
queueFamilyIndex = pQueueVk->GetQueueFamilyIndex();
59+
}
60+
else
61+
{
62+
UNEXPECTED("Command queue is not a Vulkan queue");
63+
}
64+
pContext->UnlockCommandQueue();
65+
}
5366

5467
XrGraphicsBindingVulkanKHR& Binding = *reinterpret_cast<XrGraphicsBindingVulkanKHR*>(pDataBlob->GetDataPtr());
5568
Binding.type = XR_TYPE_GRAPHICS_BINDING_VULKAN_KHR;
5669
Binding.next = nullptr;
5770
Binding.instance = pDeviceVk->GetVkInstance();
5871
Binding.physicalDevice = pDeviceVk->GetVkPhysicalDevice();
5972
Binding.device = pDeviceVk->GetVkDevice();
60-
Binding.queueFamilyIndex = pQueueVk->GetQueueFamilyIndex();
73+
Binding.queueFamilyIndex = queueFamilyIndex;
6174
Binding.queueIndex = pContext->GetDesc().ContextId;
6275

6376
*ppGraphicsBinding = pDataBlob.Detach();
@@ -77,4 +90,31 @@ void AllocateOpenXRSwapchainImageDataVk(Uint32 ImageCount,
7790
*ppSwapchainImageData = pDataBlob.Detach();
7891
}
7992

93+
void GetOpenXRSwapchainImageVk(IRenderDevice* pDevice,
94+
const XrSwapchainImageBaseHeader* ImageData,
95+
Uint32 ImageIndex,
96+
const TextureDesc& TexDesc,
97+
ITexture** ppImage)
98+
{
99+
const XrSwapchainImageVulkanKHR* ImageVk = reinterpret_cast<const XrSwapchainImageVulkanKHR*>(ImageData);
100+
101+
if (ImageData->type != XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR || ImageVk[ImageIndex].type != XR_TYPE_SWAPCHAIN_IMAGE_VULKAN_KHR)
102+
{
103+
UNEXPECTED("Unexpected swapchain image type");
104+
return;
105+
}
106+
107+
VkImage image = ImageVk[ImageIndex].image;
108+
if (image == VK_NULL_HANDLE)
109+
{
110+
UNEXPECTED("Vulkan image is null");
111+
return;
112+
}
113+
114+
RefCntAutoPtr<IRenderDeviceVk> pDeviceVk{pDevice, IID_RenderDeviceVk};
115+
VERIFY_EXPR(pDeviceVk != nullptr);
116+
117+
pDeviceVk->CreateTextureFromVulkanImage(image, TexDesc, RESOURCE_STATE_RENDER_TARGET, ppImage);
118+
}
119+
80120
} // namespace Diligent

0 commit comments

Comments
 (0)