work on basic VR

This commit is contained in:
2026-05-30 20:43:02 +03:00
parent 4811ad0820
commit 3b128315e7
18 changed files with 716 additions and 29 deletions

View File

@@ -21,8 +21,7 @@ BEGIN_VULKAN_COMMAND(ClearColor)
float g;
float b;
float a;
IImage *pImage = NULL;
IImage **ppSwapchainImages = NULL;
VkFrameObject_t stImage;
END_VULKAN_COMMAND(ClearColor)
BEGIN_VULKAN_COMMAND(Begin)

View File

@@ -10,22 +10,13 @@ DECLARE_VULKAN_COMMAND(ClearColor)
CVkImage *pImg;
if (pImage)
pImg = (CVkImage*)pImage;
if (ppSwapchainImages)
pImg = (CVkImage*)ppSwapchainImages[iCurrentFrame];
if (pImg == NULL)
Plat_FatalErrorFunc("pImage and *ppSwapchainImages are NULL\n");
VkClearColorValue color = {.float32 = {r,g,b,a}};
VkImageSubresourceRange range = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.levelCount = 1,
.layerCount = 1,
};
vkCmdClearColorImage(hCommandBuffer, pImg->m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &range);
vkCmdClearColorImage(hCommandBuffer, ((CVkImage*)VulkanGetObject(stImage, iCurrentFrame))->m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &range);
}
DECLARE_VULKAN_COMMAND(Begin)

View File

@@ -1,6 +1,7 @@
REQUIRED_EXTENSION(VK_KHR_SWAPCHAIN)
REQUIRED_EXTENSION(VK_KHR_PIPELINE_LIBRARY)
REQUIRED_EXTENSION(VK_EXT_GRAPHICS_PIPELINE_LIBRARY)
REQUIRED_EXTENSION(VK_KHR_EXTERNAL_FENCE_CAPABILITIES)
OPTIONAL_EXTENSION(VK_KHR_RAY_TRACING_PIPELINE)
OPTIONAL_EXTENSION(VK_KHR_ACCELERATION_STRUCTURE)
OPTIONAL_EXTENSION(VK_KHR_DEFERRED_HOST_OPERATIONS)

View File

@@ -198,6 +198,57 @@ void CVkRenderCommandList::DrawPrimitivesIndexed( uint32_t nIndexCount, uint32_t
}
void CVkRenderCommandList::CopyImageToImage( IImage *pSrc, IImage *pDst )
{
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
}
void CVkRenderCommandList::BlitImageToImage( IImage *pSrc, ImageSector_t src, IImage *pDst, ImageSector_t dst )
{
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
CVkBlitCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, Blit);
pCmd->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pCmd->stInputImage.m_pSingle = pSrc;
pCmd->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pCmd->stOutputImage.m_pSingle = pDst;
pCmd->AddDependency(pSrc, DEPENDENCY_MODE_BLIT_IMAGE_SOURCE);
pCmd->AddDependency(pDst, DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION);
pCmd->iSrcMin[0] = src.m_iX;
pCmd->iSrcMin[1] = src.m_iY;
pCmd->iSrcMin[2] = 0;
pCmd->iDstMin[0] = dst.m_iX;
pCmd->iDstMin[1] = dst.m_iY;
pCmd->iDstMin[2] = 0;
pCmd->iSrcMax[0] = src.m_iWidth;
pCmd->iSrcMax[1] = src.m_iHeight;
pCmd->iSrcMax[2] = 1;
pCmd->iDstMax[0] = dst.m_iWidth;
pCmd->iDstMax[1] = dst.m_iHeight;
pCmd->iDstMax[2] = 1;
m_pPostRaster->AddCommand(pCmd);
}
void CVkRenderCommandList::ClearImage( IImage *pImage, float fR, float fG, float fB, float fA )
{
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
CVkClearColorCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, ClearColor);
pCmd->AddDependency(pImage, DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION);
pCmd->r = fR;
pCmd->g = fG;
pCmd->b = fB;
pCmd->a = fA;
pCmd->stImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pCmd->stImage.m_pSingle = pImage;
m_pPostRaster->AddCommand(pCmd);
}
void CVkRenderCommandList::ClearDepth( IImage *pImage, float fVal )
{
}
void CVkRenderCommandList::ResolveImage( IImage *pOriginal, IImage *pResolved )
{
SwitchRenderingStage(RENDERING_STAGE_POST_RASTER);
@@ -251,8 +302,11 @@ void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage )
};
if (eStage == RENDERING_STAGE_POST_RASTER)
{
m_pPostRaster = m_pCommandBufferManager->CreateCommandBuffer();
m_pPostRaster->Reset();
if (m_eCurrentStage != RENDERING_STAGE_POST_RASTER)
{
m_pPostRaster = m_pCommandBufferManager->CreateCommandBuffer();
m_pPostRaster->Reset();
}
}
else
{
@@ -262,6 +316,7 @@ void CVkRenderCommandList::SwitchRenderingStage( EVulkanRenderingStage eStage )
m_pCommandBuffers.AppendTail(m_pPostRaster);
}
}
m_eCurrentStage = eStage;
}
VulkanRenderOutput_t *CVkRenderCommandList::FindOrCreateRenderOutput( uint32_t uIndex )

View File

@@ -13,6 +13,7 @@
#include "materialsystem/igamewindow.h"
#include "libraries.h"
#include "stb/stb_image.h"
#include "ixr.h"
#define REQUIRED_EXTENSION(ext) ext##_EXTENSION_NAME,
@@ -137,6 +138,8 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat )
return VK_FORMAT_R8G8B8A8_UINT;
case IMAGE_FORMAT_RGBA8_SINT:
return VK_FORMAT_R8G8B8A8_SINT;
case IMAGE_FORMAT_RGBA8_SRGB:
return VK_FORMAT_R8G8B8A8_SRGB;
case IMAGE_FORMAT_RGBA16_UINT:
return VK_FORMAT_R16G16B16A16_UINT;
@@ -451,6 +454,7 @@ public:
virtual void Init() override;
virtual void Frame( float fDeltaTime ) override;
virtual void Shutdown() override;
virtual void ConnectInterface( void *pIface, const char *szName ) override;
virtual IVertexBuffer *CreateVertexBuffer( uint32_t nSize ) override;
virtual IIndexBuffer *CreateIndexBuffer( uint32_t nSize ) override;
@@ -478,8 +482,6 @@ public:
virtual void DestroyCommandList( IRenderCommandList *pCommandList ) override;
virtual void SubmitCommandList(IRenderCommandList *pList) override;
virtual void SetMainWindowManager( IGameWindowManager *pWindowManager ) override;
virtual void RenderGameWindow( IGameWindow *pWindow ) override;
virtual void RegisterGameWindow( IGameWindow *pWindow ) override;
virtual void UnregisterGameWindow( IGameWindow *pWindow ) override;
@@ -488,6 +490,11 @@ public:
virtual void DestroyTextureArray() override;
virtual ISampler *GetDefaultSampler() override;
virtual void *GetVulkanInstance() override;
virtual void *GetVulkanPhysicalDevice() override;
virtual void *GetVulkanDevice() override;
virtual IImage *CreateImageFromVkImage( void *pVkImage, uint32_t x, uint32_t y, uint64_t optimalLayout, EImageFormat eFormat, EMultisampleType eMultisampleType ) override;
private:
VkPhysicalDevice SelectPhysicalDevice( CUtlVector<VkPhysicalDevice> physicalDevices );
CUtlVector<const char *> GetDeviceExtensions();
@@ -497,7 +504,8 @@ private:
VulkanWindow_t CreateSwapchain( IGameWindow *pWindow );
void DestroySwapchain( uint32_t uIndex );
IGameWindowManager *m_pWindowManager;
IGameWindowManager *m_pWindowManager = NULL;
IXRManager *m_pXRManager = NULL;
IVkCommandBufferManager *m_pCommandBufferManager;
IVkCommandBufferManager *m_pAssetsCommandBufferManager;
@@ -515,6 +523,14 @@ private:
EXPOSE_INTERFACE(CVkRenderContext, IRenderContext, RENDER_CONTEXT_INTERFACE_VERSION);
void CVkRenderContext::ConnectInterface( void *pIface, const char *szName )
{
if (!V_strcmp(szName, GAME_WINDOW_MANAGER_INTERFACE_VERSION))
m_pWindowManager = (IGameWindowManager*)pIface;
if (!V_strcmp(szName, XR_INTERFACE_VERSION))
m_pXRManager = (IXRManager*)pIface;
}
//-----------------------------------------------------------------------------
// Creates vertex buffer. Wrapper over CreateBuffer
//-----------------------------------------------------------------------------
@@ -660,11 +676,6 @@ void CVkRenderContext::RenderGameWindow( IGameWindow *pWindow )
{
}
void CVkRenderContext::SetMainWindowManager( IGameWindowManager *pWindowManager )
{
m_pWindowManager = pWindowManager;
}
void CVkRenderContext::RegisterGameWindow( IGameWindow *pWindow )
{
VulkanWindow_t window = CreateSwapchain(pWindow);
@@ -696,6 +707,35 @@ ISampler *CVkRenderContext::GetDefaultSampler()
}
void *CVkRenderContext::GetVulkanInstance()
{
return s_vkInstance;
}
void *CVkRenderContext::GetVulkanPhysicalDevice()
{
return s_vkPhysicalDevice;
}
void *CVkRenderContext::GetVulkanDevice()
{
return s_vkDevice;
}
IImage *CVkRenderContext::CreateImageFromVkImage( void *pVkImage, uint32_t x, uint32_t y, uint64_t optimalLayout, EImageFormat eFormat, EMultisampleType eMultisampleType )
{
CVkImage *pImage;
pImage = new CVkImage;
pImage->m_image = (VkImage)pVkImage;
pImage->m_eImageType = IMAGE_TYPE_2D;
pImage->m_eMultisampleType = eMultisampleType;
pImage->m_eFormat = eFormat;
pImage->m_nHeight = x;
pImage->m_nWidth = y;
pImage->m_ePreferredLayout = (VkImageLayout)optimalLayout;
pImage->CreateImageView();
return pImage;
}
VkPipelineLayout g_pLibraryEmptyLayout;
static IVkCommandBuffer *s_pPresentCommandBuffer;
@@ -746,6 +786,7 @@ void CVkRenderContext::Init()
stInstanceCreateInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
stInstanceCreateInfo.pApplicationInfo = &stApplicationInfo;
enabledInstanceExtensions.AppendTail(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
stInstanceCreateInfo.enabledExtensionCount = enabledInstanceExtensions.GetSize();
stInstanceCreateInfo.ppEnabledExtensionNames = enabledInstanceExtensions.GetData();
@@ -814,6 +855,7 @@ void CVkRenderContext::Init()
vk11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
vk11Features.pNext = &vk12Features;
vk11Features.shaderDrawParameters = VK_TRUE;
vk11Features.multiview = VK_TRUE;
stDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
@@ -915,6 +957,7 @@ void CVkRenderContext::Frame( float fDeltaTime )
uImageIndexes.AppendTail(s.m_uCurrentFrame);
}
uSwapchainImageIndexes.Resize(m_renderWindows.GetSize());
vkWaitForFences(s_vkDevice, fences.GetSize(), fences.GetData(), VK_TRUE, UINT64_MAX);
vkResetFences(s_vkDevice, fences.GetSize(), fences.GetData());
@@ -925,6 +968,9 @@ void CVkRenderContext::Frame( float fDeltaTime )
VkResult r = vkAcquireNextImageKHR(s_vkDevice, s.m_swapchain, UINT64_MAX, s.m_imageAvailable[s.m_uCurrentFrame], NULL, &uSwapchainImageIndexes[i]);
i++;
}
if (m_pXRManager)
m_pXRManager->PreRender();
s_pPresentCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer();
@@ -965,6 +1011,9 @@ void CVkRenderContext::Frame( float fDeltaTime )
s_pPresentCommandBuffer->Render();
s_pPresentCommandBuffer->Submit(0);
if (m_pXRManager)
m_pXRManager->CopySwapchain();
VkPipelineStageFlags uPipelineStageFlags = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
VkSubmitInfo stSubmitInfo = {};
@@ -992,6 +1041,8 @@ void CVkRenderContext::Frame( float fDeltaTime )
vkQueuePresentKHR(s_vkPresentQueue, &stPresentInfo);
vkDeviceWaitIdle(s_vkDevice);
if (m_pXRManager)
m_pXRManager->PostRender();
for ( auto &s: m_renderWindows )
{

View File

@@ -491,6 +491,11 @@ public:
virtual void Barrier( IRenderingObject *pObject, bool bIsRead, bool bIsWrite ) override;
virtual void CopyImageToImage( IImage *pSrc, IImage *pDst ) override;
virtual void BlitImageToImage( IImage *pSrc, ImageSector_t src, IImage *pDst, ImageSector_t dst ) override;
virtual void ClearImage( IImage *pImage, float fR, float fG, float fB, float fA ) override;
virtual void ClearDepth( IImage *pImage, float fVal ) override;
void Submit();
IVkCommandBufferManager *m_pCommandBufferManager;
@@ -514,6 +519,8 @@ private:
CUtlVector<IVkCommandBuffer*> m_pCommandBuffers = {};
CUtlVector<IVkCommandBuffer*> m_pScheduledDestroyPostRaster = {};
CUtlVector<VkRenderBarrier_t> m_barriers = {};
EVulkanRenderingStage m_eCurrentStage = RENDERING_STAGE_SETUP_RASTER;
};