// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen // SPDX-License-Identifier: BSD-3-Clause #include "vtkOpenXRManagerD3DGraphics.h" #include "vtkObjectFactory.h" #include "vtkOpenXRManager.h" #include "vtkWin32OpenGLDXRenderWindow.h" #define XR_USE_GRAPHICS_API_D3D11 #include "d3d11.h" // Required headers for the XrGraphicsRequirementsD3D11KHR struct #include VTK_ABI_NAMESPACE_BEGIN class vtkOpenXRManagerD3DGraphics::PIMPL { public: // D3D swapchains std::vector ColorSwapchains; std::vector DepthSwapchains; }; vtkStandardNewMacro(vtkOpenXRManagerD3DGraphics); //------------------------------------------------------------------------------ vtkOpenXRManagerD3DGraphics::vtkOpenXRManagerD3DGraphics() { this->Private = new PIMPL; } //------------------------------------------------------------------------------ vtkOpenXRManagerD3DGraphics::~vtkOpenXRManagerD3DGraphics() { delete this->Private; } //------------------------------------------------------------------------------ void vtkOpenXRManagerD3DGraphics::SetNumberOfSwapchains(uint32_t viewCount) { this->Private->ColorSwapchains.resize(viewCount); this->Private->DepthSwapchains.resize(viewCount); } //------------------------------------------------------------------------------ void vtkOpenXRManagerD3DGraphics::GetColorSwapchainImage( uint32_t scIndex, uint32_t imgIndex, void* texture) { *(ID3D11Texture2D**)texture = this->Private->ColorSwapchains[scIndex].Images[imgIndex].texture; } //------------------------------------------------------------------------------ void vtkOpenXRManagerD3DGraphics::GetDepthSwapchainImage( uint32_t scIndex, uint32_t imgIndex, void* texture) { *(ID3D11Texture2D**)texture = this->Private->DepthSwapchains[scIndex].Images[imgIndex].texture; } //------------------------------------------------------------------------------ void vtkOpenXRManagerD3DGraphics::EnumerateColorSwapchainImages( XrSwapchain swapchain, uint32_t scIndex) { this->EnumerateSwapchainImages(swapchain, this->Private->ColorSwapchains[scIndex]); } //------------------------------------------------------------------------------ void vtkOpenXRManagerD3DGraphics::EnumerateDepthSwapchainImages( XrSwapchain swapchain, uint32_t scIndex) { this->EnumerateSwapchainImages(swapchain, this->Private->DepthSwapchains[scIndex]); } //------------------------------------------------------------------------------ const std::vector& vtkOpenXRManagerD3DGraphics::GetSupportedColorFormats() { const static std::vector supportedColorFormats = { DXGI_FORMAT_R8G8B8A8_UNORM }; return supportedColorFormats; } //------------------------------------------------------------------------------ const std::vector& vtkOpenXRManagerD3DGraphics::GetSupportedDepthFormats() { const static std::vector supportedDepthFormats = { DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_D32_FLOAT_S8X24_UINT }; return supportedDepthFormats; } //------------------------------------------------------------------------------ void vtkOpenXRManagerD3DGraphics::EnumerateSwapchainImages( XrSwapchain swapchain, SwapchainImagesD3D& swapchainImages) { uint32_t chainLength = this->GetChainLength(swapchain); swapchainImages.Images.resize(chainLength, { XR_TYPE_SWAPCHAIN_IMAGE_D3D11_KHR }); vtkOpenXRManager::GetInstance().XrCheckOutput(vtkOpenXRManager::ErrorOutput, xrEnumerateSwapchainImages(swapchain, (uint32_t)swapchainImages.Images.size(), &chainLength, reinterpret_cast(swapchainImages.Images.data())), "Failed to enumerate swapchain images"); } //------------------------------------------------------------------------------ bool vtkOpenXRManagerD3DGraphics::CreateGraphicsBinding(vtkOpenGLRenderWindow* helperWindow) { vtkWin32OpenGLDXRenderWindow* d3dWindow = vtkWin32OpenGLDXRenderWindow::SafeDownCast(helperWindow); if (d3dWindow) { auto graphicsBindingDXWin32 = std::shared_ptr(new XrGraphicsBindingD3D11KHR{ XR_TYPE_GRAPHICS_BINDING_D3D11_KHR, // .type nullptr, // .next { 0 } // ID3D11Device* device }); this->GraphicsBinding = graphicsBindingDXWin32; graphicsBindingDXWin32->device = d3dWindow->GetDevice(); } return true; } //------------------------------------------------------------------------------ bool vtkOpenXRManagerD3DGraphics::CheckGraphicsRequirements(XrInstance instance, XrSystemId id) { XrGraphicsRequirementsD3D11KHR graphicsRequirements{ XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR }; xr::GraphicsExtensionDispatchTable extensions; extensions.PopulateDispatchTable(instance); if (!vtkOpenXRManager::GetInstance().XrCheckOutput(vtkOpenXRManager::ErrorOutput, extensions.xrGetD3D11GraphicsRequirementsKHR(instance, id, &graphicsRequirements), "Failed to get DirectX graphics requirements!")) { return false; } // Create a list of feature levels which are both supported by the OpenXR runtime and this // application. vtkWin32OpenGLDXRenderWindow only supports D3D11 for now. constexpr D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_1 }; auto supportedLevel = std::lower_bound(std::begin(levels), std::end(levels), graphicsRequirements.minFeatureLevel); if (supportedLevel == std::end(levels)) { vtkErrorMacro("Unsupported minimum feature level!"); return false; }; return true; } //------------------------------------------------------------------------------ const char* vtkOpenXRManagerD3DGraphics::GetBackendExtensionName() { return XR_KHR_D3D11_ENABLE_EXTENSION_NAME; } VTK_ABI_NAMESPACE_END