This commit is contained in:
2026-02-20 19:35:09 +02:00
parent 3ed689f801
commit c00ecf4081
35 changed files with 576 additions and 99 deletions

View File

@@ -74,5 +74,16 @@ BEGIN_VULKAN_COMMAND(SetViewport)
float fDepthMax = 1;
END_VULKAN_COMMAND(SetViewport)
BEGIN_VULKAN_COMMAND(CopyBufferToImage)
IBuffer *pBuffer;
VkFrameObject_t stOutputImage;
int iOffsetX = 0;
int iOffsetY = 0;
int iOffsetZ = 0;
uint32_t iImageX = 1;
uint32_t iImageY = 1;
uint32_t iImageZ = 1;
END_VULKAN_COMMAND(CopyBufferToImage)
#endif

View File

@@ -80,7 +80,7 @@ DECLARE_VULKAN_COMMAND(SetShader)
DECLARE_VULKAN_COMMAND(SetShaderData)
{
CVkMaterial *pMat = (CVkMaterial*)pShaderData;
vkCmdBindDescriptorSets(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pMat->m_pVkShader->m_hPipelineLayout, 0, 1, &pMat->m_hSet, 0, 0 );
vkCmdBindDescriptorSets(hCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pMat->m_pVkShader->m_hPipelineLayout, 0, pMat->m_hSets.GetSize(), pMat->m_hSets.GetData(), 0, 0 );
}
DECLARE_VULKAN_COMMAND(SetVertexBuffer)
@@ -122,3 +122,24 @@ DECLARE_VULKAN_COMMAND(SetViewport)
};
vkCmdSetViewportWithCount(hCommandBuffer, 1, &v);
}
DECLARE_VULKAN_COMMAND(CopyBufferToImage)
{
VkBufferImageCopy2 r = {
.sType = VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2,
.imageSubresource = {
.aspectMask = ((CVkImage*)VulkanGetObject(stOutputImage, iCurrentFrame))->m_range.aspectMask,
.layerCount = 1,
},
.imageOffset = {iOffsetX, iOffsetY, iOffsetZ},
.imageExtent = {iImageX, iImageY, iImageZ},
};
VkCopyBufferToImageInfo2 c = {
.sType = VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2,
.srcBuffer = ((CVkBuffer*)pBuffer)->m_buffer,
.dstImage = ((CVkImage*)VulkanGetObject(stOutputImage, iCurrentFrame))->m_image,
.dstImageLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.regionCount = 1,
.pRegions = &r,
};
vkCmdCopyBufferToImage2(hCommandBuffer, &c);
}

View File

@@ -3,7 +3,7 @@ CVkMaterial::CVkMaterial( IShader *pShader )
{
m_pVkShader = (CVkShader*)pShader;
VkDescriptorPoolSize pools[2] =
VkDescriptorPoolSize pools[4] =
{
{
VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
@@ -12,43 +12,31 @@ CVkMaterial::CVkMaterial( IShader *pShader )
{
VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
128,
},
{
VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
128,
},
{
VK_DESCRIPTOR_TYPE_SAMPLER,
1,
}
};
VkDescriptorPoolCreateInfo stPool = {};
stPool.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
stPool.poolSizeCount = 2;
stPool.poolSizeCount = 4;
stPool.pPoolSizes = pools;
stPool.maxSets = 1;
stPool.maxSets = 16;
stPool.flags = VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT_EXT;
vkCreateDescriptorPool(m_pVkShader->m_hDevice, &stPool, NULL, &m_hPool);
VkDescriptorSetAllocateInfo stInfo = {};
stInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
stInfo.descriptorSetCount = 1;
stInfo.descriptorPool = m_hPool;
stInfo.descriptorSetCount = m_pVkShader->m_setLayouts.GetSize();
stInfo.pSetLayouts = m_pVkShader->m_setLayouts.GetData();
vkAllocateDescriptorSets(m_pVkShader->m_hDevice, &stInfo, &m_hSet);
for ( auto b: m_pVkShader->m_bindings )
{
VkWriteDescriptorSet write = {};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.dstSet = m_hSet;
write.dstBinding = b.uBinding;
write.dstArrayElement = 0;
write.descriptorType = b.eDescriptorType;
write.descriptorCount = 1;
switch (b.eDescriptorType)
{
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
write.pBufferInfo = new VkDescriptorBufferInfo;
break;
default:
break;
};
m_writes.AppendTail(write);
}
m_hSets.Resize(m_pVkShader->m_setLayouts.GetSize());
vkAllocateDescriptorSets(m_pVkShader->m_hDevice, &stInfo, m_hSets.GetData());
}
CVkMaterial::~CVkMaterial()
@@ -63,22 +51,27 @@ void CVkMaterial::Frame()
void CVkMaterial::VSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource )
{
SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pResource);
SetShaderResource(uRegister, 0, pResource);
}
void CVkMaterial::PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource )
{
SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pResource);
SetShaderResource(uRegister, 0, pResource);
}
void CVkMaterial::VSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants )
{
SetShaderResource(uRegister, SHADER_STAGE_VERTEX, pConstants);
SetShaderResource(uRegister, 0, pConstants);
}
void CVkMaterial::PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants )
{
SetShaderResource(uRegister, SHADER_STAGE_PIXEL, pConstants);
SetShaderResource(uRegister, 0, pConstants);
}
void CVkMaterial::PSSetTextureArray( uint32_t uSet, ITextureArray *pArray )
{
SetShaderResource(0, uSet, pArray);
}
void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderingObject *pObject)
@@ -86,13 +79,65 @@ void CVkMaterial::SetShaderResource( uint32_t uRegister, uint32_t uSet, IRenderi
union {
IRenderingObject *pVkObject;
CVkBuffer *pBuffer;
CVkTextureArray *pArray;
};
pVkObject = pObject;
if (dynamic_cast<IBuffer*>(pObject))
{
((VkDescriptorBufferInfo*)m_writes[uRegister].pBufferInfo)->buffer = pBuffer->m_buffer;
((VkDescriptorBufferInfo*)m_writes[uRegister].pBufferInfo)->range = pBuffer->m_nSize;
VkWriteDescriptorSet write = {};
VkDescriptorBufferInfo stInfo = {};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.dstSet = m_hSets[uSet];
write.dstBinding = uRegister;
write.dstArrayElement = 0;
write.descriptorType = pBuffer->m_eDescriptorType;
write.descriptorCount = 1;
write.pBufferInfo = &stInfo;
stInfo.buffer = pBuffer->m_buffer;
stInfo.range = pBuffer->m_nSize;
vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &write, 0, 0);
}
if (dynamic_cast<ITextureArray*>(pObject))
{
VkWriteDescriptorSet writes[2] = {};
VkDescriptorImageInfo stWrites[128];
VkDescriptorImageInfo stSampler = {};
for ( int i = 0; i < 128; i++ )
{
if (pArray->m_pImages[i] == NULL)
{
stWrites[i] = {
.imageView = pArray->m_pImages[0]->m_imageView,
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
};
continue;
}
stWrites[i] = {
.imageView = pArray->m_pImages[i]->m_imageView,
.imageLayout = VK_IMAGE_LAYOUT_GENERAL,
};
}
writes[0] = {};
writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[0].dstSet = m_hSets[uSet];
writes[0].dstBinding = 0;
writes[0].dstArrayElement = 0;
writes[0].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
writes[0].descriptorCount = 1;
writes[0].pImageInfo = &stSampler;
stSampler.sampler = pArray->m_hSampler;
writes[1] = {};
writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes[1].dstSet = m_hSets[uSet];
writes[1].dstBinding = 1;
writes[1].dstArrayElement = 0;
writes[1].descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
writes[1].descriptorCount = 128;
writes[1].pImageInfo = stWrites;
vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 2, writes, 0, 0);
}
vkUpdateDescriptorSets(m_pVkShader->m_hDevice, 1, &m_writes[uRegister], 0, 0);
}

View File

@@ -84,7 +84,7 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
if (bWasCreated)
{
m_pCurrentMaterialBuffer->Reset();
CVkBeginCommand *pBeginCommand = CREATE_COMMAND(Begin);
CVkBeginCommand *pBeginCommand = CREATE_COMMAND(m_pCommandBufferManager, Begin);
pBeginCommand->images = m_pOutput;
pBeginCommand->nResolutionX = m_uWidth;
pBeginCommand->nResolutionY = m_uHeight;
@@ -101,20 +101,20 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
}
m_pCurrentMaterialBuffer->AddCommand(pBeginCommand);
CVkSetShaderCommand *pSetShader = CREATE_COMMAND(SetShader);
CVkSetShaderCommand *pSetShader = CREATE_COMMAND(m_pCommandBufferManager, SetShader);
pSetShader->pShader = ((CVkMaterial*)pMaterial)->m_pVkShader;
m_pCurrentMaterialBuffer->AddCommand(pSetShader);
CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(SetShaderData);
CVkSetShaderDataCommand *pSetShaderData = CREATE_COMMAND(m_pCommandBufferManager, SetShaderData);
pSetShaderData->pShaderData = pMaterial;
m_pCurrentMaterialBuffer->AddCommand(pSetShaderData);
CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(SetScissors);
CVkSetScissorsCommand *pScissorsCommand = CREATE_COMMAND(m_pCommandBufferManager, SetScissors);
pScissorsCommand->uWidth = m_uWidth;
pScissorsCommand->uHeight = m_uHeight;
m_pCurrentMaterialBuffer->AddCommand(pScissorsCommand);
CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(SetViewport);
CVkSetViewportCommand *pViewportCommand = CREATE_COMMAND(m_pCommandBufferManager, SetViewport);
pViewportCommand->fX = 0;
pViewportCommand->fY = 0;
pViewportCommand->fWidth = m_uWidth;
@@ -128,7 +128,7 @@ void CVkRenderCommandList::SetMaterial( IMaterial *pMaterial )
void CVkRenderCommandList::SetVertexBuffer( uint32_t uBinding, IVertexBuffer *pBuffer )
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(SetVertexBuffer);
CVkSetVertexBufferCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, SetVertexBuffer);
pCmd->uBinding = uBinding;
pCmd->pBuffer = pBuffer;
m_pCurrentMaterialBuffer->AddCommand(pCmd);
@@ -143,7 +143,7 @@ void CVkRenderCommandList::DrawPrimitives( uint32_t nVertexCount, uint32_t nFirs
{
SwitchRenderingStage(RENDERING_STAGE_RASTER);
CVkDrawPrimitivesCommand *pCmd = CREATE_COMMAND(DrawPrimitives);
CVkDrawPrimitivesCommand *pCmd = CREATE_COMMAND(m_pCommandBufferManager, DrawPrimitives);
pCmd->nVertexCount = nVertexCount;
pCmd->nFirstVertex = nFirstVertex;
pCmd->nInstanceCount = nInstanceCount;
@@ -174,7 +174,7 @@ void CVkRenderCommandList::EndRecording()
{
for ( auto m: m_materials)
{
CVkEndCommand *pEndCommand = CREATE_COMMAND(End);
CVkEndCommand *pEndCommand = CREATE_COMMAND(m_pCommandBufferManager, End);
m.m_pCommandBuffer->AddCommand(pEndCommand);
m.m_pCommandBuffer->Render();
}

View File

@@ -6,11 +6,13 @@
#include "tier1/interface.h"
#include "tier1/utlstring.h"
#include "tier1/utlvector.h"
#include "tier2/ifilesystem.h"
#define VK_NO_PROTOTYPES
#include "vulkan/vulkan_core.h"
#include "vulkan_state.h"
#include "materialsystem/igamewindow.h"
#include "libraries.h"
#include "stb/stb_image.h"
#define REQUIRED_EXTENSION(ext) ext##_EXTENSION_NAME,
@@ -103,21 +105,64 @@ VkFormat CVkImage::GetImageFormat( enum EImageFormat eImageFormat )
{
case IMAGE_FORMAT_R8_UINT:
return VK_FORMAT_R8_UINT;
case IMAGE_FORMAT_RGB8_UINT:
return VK_FORMAT_R8G8B8_UINT;
case IMAGE_FORMAT_RGB8_SINT:
return VK_FORMAT_R8G8B8_SINT;
case IMAGE_FORMAT_RGB8_UNORM:
return VK_FORMAT_R8G8B8_UNORM;
case IMAGE_FORMAT_RGB8_SNORM:
return VK_FORMAT_R8G8B8_SNORM;
case IMAGE_FORMAT_RGB16_UINT:
return VK_FORMAT_R16G16B16_UINT;
case IMAGE_FORMAT_RGB16_SINT:
return VK_FORMAT_R16G16B16_SINT;
case IMAGE_FORMAT_RGB16_UNORM:
return VK_FORMAT_R16G16B16_UNORM;
case IMAGE_FORMAT_RGB16_SNORM:
return VK_FORMAT_R16G16B16_SNORM;
case IMAGE_FORMAT_RGB16_SFLOAT:
return VK_FORMAT_R16G16B16_SFLOAT;
case IMAGE_FORMAT_RGB32_SFLOAT:
return VK_FORMAT_R32G32B32_SFLOAT;
case IMAGE_FORMAT_RGBA8_UNORM:
return VK_FORMAT_R8G8B8A8_UNORM;
case IMAGE_FORMAT_BGRA8_UNORM:
return VK_FORMAT_B8G8R8A8_UNORM;
case IMAGE_FORMAT_RGBA8_UINT:
return VK_FORMAT_R8G8B8A8_UINT;
case IMAGE_FORMAT_RGBA8_SINT:
return VK_FORMAT_R8G8B8A8_SINT;
case IMAGE_FORMAT_RGBA16_UINT:
return VK_FORMAT_R16G16B16A16_UINT;
case IMAGE_FORMAT_RGBA16_SINT:
return VK_FORMAT_R16G16B16A16_SINT;
case IMAGE_FORMAT_RGBA16_UNORM:
return VK_FORMAT_R16G16B16A16_UNORM;
case IMAGE_FORMAT_RGBA16_SNORM:
return VK_FORMAT_R16G16B16A16_SNORM;
case IMAGE_FORMAT_RGBA16_SFLOAT:
return VK_FORMAT_R16G16B16A16_SFLOAT;
case IMAGE_FORMAT_RGBA32_SFLOAT:
return VK_FORMAT_R32G32B32A32_SFLOAT;
case IMAGE_FORMAT_BC1:
return VK_FORMAT_BC1_RGB_UNORM_BLOCK;
case IMAGE_FORMAT_BC3:
return VK_FORMAT_BC3_UNORM_BLOCK;
case IMAGE_FORMAT_BC7:
return VK_FORMAT_BC7_UNORM_BLOCK;
case IMAGE_FORMAT_D32_SFLOAT:
return VK_FORMAT_D32_SFLOAT;
}
return VK_FORMAT_UNDEFINED;
}
VkSampleCountFlagBits CVkImage::GetMultisampling( enum EMultisampleType eImageFormat )
@@ -211,6 +256,14 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig
stUsage.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO;
stUsage.usage = eUsage | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT;
if (eUsage & VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT)
{
m_eDescriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
}
if (eUsage & VK_BUFFER_USAGE_2_UNIFORM_BUFFER_BIT)
{
m_eDescriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
}
stBufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
stBufferInfo.size = nSize;
@@ -219,7 +272,8 @@ CVkBuffer::CVkBuffer( uint32_t nSize, VkBufferUsageFlags2 eUsage, uint32_t nAlig
stAllocInfo.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE;
stAllocInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
vmaCreateBuffer(s_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL);
VkResult r = vmaCreateBuffer(s_vkAllocator, &stBufferInfo, &stAllocInfo, &m_buffer, &m_allocation, NULL);
stAddress.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO;
stAddress.buffer = m_buffer;
@@ -267,6 +321,118 @@ uint32_t CVkBuffer::GetSize()
{
return m_nSize;
}
CVkTextureArray::~CVkTextureArray()
{
}
CVkTextureArray::CVkTextureArray()
{
for (uint32_t i = 0; i < 128; i++ )
m_pImages[i] = NULL;
}
void CVkTextureArray::Build()
{
for (uint32_t i = 0; i < 128; i++ )
m_pImages[i] = NULL;
VkSamplerCreateInfo samplerInfo = {};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT;
samplerInfo.borderColor = VK_BORDER_COLOR_INT_OPAQUE_BLACK;
samplerInfo.unnormalizedCoordinates = VK_FALSE;
samplerInfo.compareEnable = VK_FALSE;
samplerInfo.compareOp = VK_COMPARE_OP_ALWAYS;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerInfo.mipLodBias = 0.0f;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = VK_LOD_CLAMP_NONE;
vkCreateSampler(m_hDevice, &samplerInfo, nullptr, &m_hSampler);
LoadTexture("game/core/textures/error.png");
}
void CVkTextureArray::SetDebugName( const char *szPath )
{
}
uint32_t CVkTextureArray::LoadTexture( const char *szPath )
{
for (uint32_t i = 0; i < 128; i++ )
{
if (m_pImages[i] == NULL)
return CreateTexture(i, szPath);
}
return 0;
}
extern IFileSystem *filesystem;
uint32_t CVkTextureArray::CreateTexture( uint32_t i, const char *szPath )
{
if ( filesystem == NULL )
{
CreateInterfaceFn pFilesystemFactory = Sys_GetFactory("filesystem_std");
filesystem = (IFileSystem*)pFilesystemFactory(FILESYSTEM_INTERFACE_VERSION, NULL);
}
IFileHandle *pHandle = filesystem->Open(szPath, FILEMODE_READ);
CUtlBuffer<unsigned char> data = filesystem->Size(pHandle);
filesystem->Read(pHandle, data.GetMemory(), data.GetSize());
filesystem->Close(pHandle);
int uWidth = 0;
int uHeight = 0;
int uChannels = 0;
unsigned char *pImg = stbi_load_from_memory(data.GetMemory(), data.GetSize(), &uWidth, &uHeight, &uChannels, 4);
IBuffer *pBuffer = m_pRenderContext->CreateStorageBuffer(uWidth*uHeight*uChannels);
pBuffer->Lock();
void *pData = pBuffer->Map();
V_memcpy(pData, pImg, uWidth*uHeight*uChannels);
pBuffer->Unmap();
pBuffer->Unlock();
IImage *pImage = m_pRenderContext->CreateTexture(uWidth, uHeight, IMAGE_FORMAT_RGBA8_UNORM, MULTISAMPLE_TYPE_NONE);
IImage *pCompressedImage = m_pRenderContext->CreateTexture(uWidth, uHeight, IMAGE_FORMAT_BC1, MULTISAMPLE_TYPE_NONE);
m_pImages[i] = (CVkImage*)pImage;
stbi_image_free(pImg);
CVkCopyBufferToImageCommand *pCopyCommand = NULL;
IVkCommandBuffer *pCommandBuffer = m_pCommandBufferManager->CreateCommandBuffer();
pCommandBuffer->Reset();
pCopyCommand = CREATE_COMMAND(m_pCommandBufferManager, CopyBufferToImage);
pCopyCommand->AddDependency((IRenderingObject*)pBuffer, DEPENDENCY_MODE_BUFFER_SOURCE);
pCopyCommand->AddDependency((IRenderingObject*)pImage, DEPENDENCY_MODE_IMAGE_DESTINATION);
pCopyCommand->pBuffer = pBuffer;
pCopyCommand->stOutputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;
pCopyCommand->stOutputImage.m_pSingle = pImage;
pCopyCommand->iImageX = uWidth;
pCopyCommand->iImageY = uWidth;
pCommandBuffer->AddCommand(pCopyCommand);
pCommandBuffer->Render();
pCommandBuffer->Submit();
return i;
}
uint32_t CVkTextureArray::GetTextureID( const char *szPath )
{
}
void CVkTextureArray::UnloadTexture( uint32_t uTextureID )
{
}
void CVkTextureArray::Frame()
{
}
class CVkRenderContext: public IRenderContext
{
public:
@@ -281,6 +447,7 @@ public:
virtual void DestroyBuffer( IBuffer *pBuffer ) override;
virtual IImage *CreateRenderTarget( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override;
virtual IImage *CreateTexture( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override;
virtual IImage *CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType ) override;
virtual void DestroyImage( IImage *pImage ) override;
@@ -302,6 +469,9 @@ public:
virtual void RenderGameWindow( IGameWindow *pWindow ) override;
virtual void RegisterGameWindow( IGameWindow *pWindow ) override;
virtual void UnregisterGameWindow( IGameWindow *pWindow ) override;
virtual ITextureArray *CreateTextureArray() override;
virtual void DestroyTextureArray() override;
private:
VkPhysicalDevice SelectPhysicalDevice( CUtlVector<VkPhysicalDevice> physicalDevices );
CUtlVector<const char *> GetDeviceExtensions();
@@ -313,11 +483,14 @@ private:
IGameWindowManager *m_pWindowManager;
IVkCommandBufferManager *m_pCommandBufferManager;
IVkCommandBufferManager *m_pAssetsCommandBufferManager;
CUtlVector<VulkanWindow_t> m_renderWindows;
CUtlVector<CVkMaterial*> m_pMaterials;
CUtlVector<CVkTextureArray*> m_pTextureArrays;
CUtlVector<CVkRenderCommandList*> m_scheduledRemovalLists;
CUtlVector<CVkTextureArray*> m_scheduledRemovalTextureArrays;
CUtlVector<CVkBuffer*> m_scheduledRemovalBuffers;
CUtlVector<CVkImage*> m_scheduledRemovalImages;
};
@@ -382,6 +555,10 @@ IImage *CVkRenderContext::CreateRenderTarget( uint32_t x, uint32_t y, EImageForm
else
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
}
IImage *CVkRenderContext::CreateTexture( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType )
{
return new CVkImage(x, y, 1, eFormat, eMultisampleType, IMAGE_TYPE_2D, VK_IMAGE_USAGE_SAMPLED_BIT);
}
IImage *CVkRenderContext::CreateStorageImage( uint32_t x, uint32_t y, EImageFormat eFormat, EMultisampleType eMultisampleType )
{
@@ -447,7 +624,6 @@ void CVkRenderContext::SubmitCommandList(IRenderCommandList *pList)
}
void CVkRenderContext::RenderGameWindow( IGameWindow *pWindow )
{
}
void CVkRenderContext::SetMainWindowManager( IGameWindowManager *pWindowManager )
@@ -463,9 +639,24 @@ void CVkRenderContext::RegisterGameWindow( IGameWindow *pWindow )
void CVkRenderContext::UnregisterGameWindow( IGameWindow *pWindow )
{
}
ITextureArray *CVkRenderContext::CreateTextureArray()
{
CVkTextureArray *pArray = new CVkTextureArray();
pArray->m_hDevice = s_vkDevice;
pArray->m_pRenderContext = this;
pArray->m_pCommandBufferManager = m_pCommandBufferManager;
pArray->Build();
return pArray;
}
void CVkRenderContext::DestroyTextureArray()
{
}
VkPipelineLayout g_pLibraryEmptyLayout;
static IVkCommandBuffer *s_pPresentCommandBuffer;
@@ -576,13 +767,21 @@ void CVkRenderContext::Init()
vk12Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
vk12Features.pNext = &vk13Features;
vk12Features.bufferDeviceAddress = VK_TRUE;
vk12Features.runtimeDescriptorArray = VK_TRUE;
vk12Features.descriptorBindingPartiallyBound = VK_TRUE;
vk12Features.descriptorBindingVariableDescriptorCount = VK_TRUE;
VkPhysicalDeviceVulkan11Features vk11Features = {};
vk11Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
vk11Features.pNext = &vk12Features;
vk11Features.shaderDrawParameters = VK_TRUE;
stDeviceCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
stDeviceCreateInfo.queueCreateInfoCount = 1;
stDeviceCreateInfo.pQueueCreateInfos = &stDeviceQueueCreateInfo;
stDeviceCreateInfo.enabledExtensionCount = enabledDeviceExtensions.GetSize();
stDeviceCreateInfo.ppEnabledExtensionNames = enabledDeviceExtensions.GetData();
stDeviceCreateInfo.pNext = &vk12Features;
stDeviceCreateInfo.pNext = &vk11Features;
r = vkCreateDevice(s_vkPhysicalDevice, &stDeviceCreateInfo, NULL, &s_vkDevice);
VULKAN_RESULT_PRINT(r, vkEnumeratePhysicalDevices);
for (auto &extension: enabledDeviceExtensions)
@@ -631,6 +830,7 @@ void CVkRenderContext::Frame( float fDeltaTime )
for ( auto &m: m_pMaterials)
{
m->Frame();
}
i = 0;
@@ -679,10 +879,11 @@ void CVkRenderContext::Frame( float fDeltaTime )
for ( auto &s: m_renderWindows )
{
CVkBlitCommand *pBlitCommand = NULL;
if (s.m_pWindow->GetOutputImage())
{
pBlitCommand = CREATE_COMMAND(Blit);
pBlitCommand = CREATE_COMMAND(m_pCommandBufferManager, Blit);
pBlitCommand->AddDependency(s.m_pWindow->GetOutputImage(), DEPENDENCY_MODE_BLIT_IMAGE_SOURCE);
pBlitCommand->AddDependency((IRenderingObject*)s.m_images[uSwapchainImageIndexes[i]], DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION);
pBlitCommand->stInputImage.m_eObjectType = FRAME_OBJECT_TYPE_SINGLE;

View File

@@ -70,7 +70,7 @@ void CVkShader::Build()
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT,
};
VkPipelineLayoutCreateInfo stPipelineLayout = {};
CUtlVector<VkDescriptorSetLayoutBinding> bindings = {};
CUtlVector<CUtlVector<VkDescriptorSetLayoutBinding>> bindings = {};
// TODO: Filter by vulkan shaders at some points
stages.Resize(m_shader.m_objects.GetSize());
@@ -82,21 +82,33 @@ void CVkShader::Build()
{
VulkanDescriptor_t stDescriptor = ((VulkanDescriptor_t*)m_shader.GetLumpPtr(pMetaData->pDescriptorSets))[u];
bool bFound = false;
for ( auto &b: bindings )
if (bindings.GetSize()<=stDescriptor.uSet)
bindings.Resize(stDescriptor.uSet+1);
uint32_t i = 0;
for ( auto &set: bindings )
{
if (b.binding != stDescriptor.uBinding)
continue;
bFound = true;
break;
for ( auto &b: set )
{
if (i != stDescriptor.uSet)
continue;
if (b.binding != stDescriptor.uBinding)
continue;
bFound = true;
break;
}
i++;
if (bFound)
break;
}
if (bFound)
break;
continue;
VkDescriptorSetLayoutBinding bind = {};
bind.binding = stDescriptor.uBinding;
bind.descriptorCount = 1;
bind.descriptorCount = stDescriptor.uCount;
bind.descriptorType = stDescriptor.eDescriptorType;
bind.stageFlags = VK_SHADER_STAGE_ALL;
bindings.AppendTail(bind);
bindings[stDescriptor.uSet].AppendTail(bind);
m_bindings.AppendTail(stDescriptor);
}
modules[i].sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
@@ -110,14 +122,19 @@ void CVkShader::Build()
if ( bindings.GetSize() >= 0 )
{
m_setLayouts.Resize(1);
VkDescriptorSetLayoutCreateInfo stSetLayoutCreateInfo = {};
stSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
stSetLayoutCreateInfo.pBindings = bindings.GetData();
stSetLayoutCreateInfo.bindingCount = bindings.GetSize();
stSetLayoutCreateInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
vkCreateDescriptorSetLayout(m_hDevice, &stSetLayoutCreateInfo, NULL, m_setLayouts.GetData());
stPipelineLayout.setLayoutCount = 1;
m_setLayouts.Reserve(bindings.GetSize());
for ( int u = 0; u < bindings.GetSize(); u++ )
{
VkDescriptorSetLayoutCreateInfo stSetLayoutCreateInfo = {};
VkDescriptorSetLayout l = NULL;
stSetLayoutCreateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
stSetLayoutCreateInfo.pBindings = bindings[u].GetData();
stSetLayoutCreateInfo.bindingCount = bindings[u].GetSize();
stSetLayoutCreateInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT;
vkCreateDescriptorSetLayout(m_hDevice, &stSetLayoutCreateInfo, NULL, &l);
m_setLayouts.AppendTail(l);
}
stPipelineLayout.setLayoutCount = m_setLayouts.GetSize();
stPipelineLayout.pSetLayouts = m_setLayouts.GetData();
}

View File

@@ -23,8 +23,17 @@ VkAccessFlags2 VulkanGetAccessFlags( EDependencyMode eMode )
case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT;
case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_ACCESS_2_NONE;
case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: return VK_ACCESS_2_TRANSFER_WRITE_BIT;
case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: return VK_ACCESS_2_TRANSFER_READ_BIT;
case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE:
case DEPENDENCY_MODE_IMAGE_SOURCE:
case DEPENDENCY_MODE_BUFFER_SOURCE:
return VK_ACCESS_2_TRANSFER_READ_BIT;
case DEPENDENCY_MODE_IMAGE_DESTINATION:
case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION:
case DEPENDENCY_MODE_BUFFER_DESTINATION:
return VK_ACCESS_2_TRANSFER_WRITE_BIT;
default:
return VK_ACCESS_2_NONE;
}
@@ -39,9 +48,17 @@ VkPipelineStageFlags2 VulkanGetStageFlags( EDependencyMode eMode )
case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT;
case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_PIPELINE_STAGE_2_TRANSFER_BIT;
case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION:
case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE:
return VK_PIPELINE_STAGE_2_BLIT_BIT;
case DEPENDENCY_MODE_BUFFER_SOURCE:
case DEPENDENCY_MODE_BUFFER_DESTINATION:
case DEPENDENCY_MODE_IMAGE_SOURCE:
case DEPENDENCY_MODE_IMAGE_DESTINATION:
return VK_PIPELINE_STAGE_2_COPY_BIT;
default:
return VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT;
}
@@ -56,8 +73,14 @@ VkImageLayout VulkanGetImageLayout( EDependencyMode eMode )
case DEPENDENCY_MODE_DRAWCALL_OUTPUT_DEPTH_IMAGE: return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
case DEPENDENCY_MODE_COLOR_CLEAR_DESTINATION: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
case DEPENDENCY_MODE_IMAGE_PRESENT: return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION: return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE: return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case DEPENDENCY_MODE_BLIT_IMAGE_SOURCE:
case DEPENDENCY_MODE_IMAGE_SOURCE:
case DEPENDENCY_MODE_BUFFER_SOURCE:
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
case DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION:
case DEPENDENCY_MODE_IMAGE_DESTINATION:
case DEPENDENCY_MODE_BUFFER_DESTINATION:
return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
default:
return VK_IMAGE_LAYOUT_UNDEFINED;
}

View File

@@ -57,8 +57,10 @@ enum EDependencyMode
DEPENDENCY_MODE_DRAWCALL_INPUT_IMAGE,
DEPENDENCY_MODE_DRAWCALL_MIXED_IMAGE,
DEPENDENCY_MODE_BUFFER_SOURCE,
DEPENDENCY_MODE_IMAGE_SOURCE,
DEPENDENCY_MODE_IMAGE_DESTINATION,
DEPENDENCY_MODE_BUFFER_DESTINATION,
DEPENDENCY_MODE_BLIT_IMAGE_SOURCE,
DEPENDENCY_MODE_BLIT_IMAGE_DESTINATION,
@@ -140,8 +142,8 @@ class CVkCommandRegistry
public:
CVkCommandRegistry( const char *szName, fnCreateVulkanCommand_t pfnCreate );
};
#define CREATE_COMMAND(name) \
(CVk##name##Command*)m_pCommandBufferManager->CreateCommand(#name)
#define CREATE_COMMAND(cb, name) \
(CVk##name##Command*)cb->CreateCommand(#name)
#define BEGIN_VULKAN_COMMAND( name ) \
class CVk##name##Command : public CVkCommand \
@@ -217,6 +219,7 @@ public:
VmaAllocation m_allocation;
VkBuffer m_buffer;
VkDescriptorType m_eDescriptorType;
VkDeviceAddress m_address;
uint32_t m_nSize;
};
@@ -287,6 +290,27 @@ private:
};
class CVkTextureArray: public ITextureArray
{
public:
~CVkTextureArray();
CVkTextureArray();
virtual void Build() override;
virtual void SetDebugName( const char *szName ) override;
virtual uint32_t LoadTexture( const char *szPath ) override;
virtual uint32_t GetTextureID( const char *szPath ) override;
virtual void UnloadTexture( uint32_t uTextureID ) override;
void Frame();
uint32_t CreateTexture( uint32_t i, const char *szPath );
VkDevice m_hDevice;
IRenderContext *m_pRenderContext;
IVkCommandBufferManager *m_pCommandBufferManager;
VkSampler m_hSampler;
CVkImage *m_pImages[128];
};
class CVkMaterial: public IMaterial
{
public:
@@ -300,9 +324,10 @@ public:
virtual void PSSetShaderResource( uint32_t uRegister, IRenderingObject *pResource ) override;
virtual void PSSetConstantsBuffer( uint32_t uRegister, IBuffer *pConstants ) override;
virtual void PSSetTextureArray( uint32_t uSet, ITextureArray *pArray ) override;
CVkShader *m_pVkShader;
VkDescriptorSet m_hSet;
CUtlVector<VkDescriptorSet> m_hSets;
private:
VkDescriptorPool m_hPool;
CUtlVector<VkWriteDescriptorSet> m_writes = {};