introduces ios support? still needs metal

This commit is contained in:
2025-06-29 01:21:55 +03:00
parent af4f0c3cad
commit cdeaac7c0c
79 changed files with 2176 additions and 1349 deletions

View File

@@ -9,6 +9,19 @@
#include "vulkan/vulkan_core.h"
#define STB_IMAGE_IMPLEMENTATION
#if defined(__APPLE__) && defined(__MACH__)
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE
// iOS
#define STBI_NO_THREAD_LOCALS
#else
// macOS
#endif
#else
// Other platforms
#define STBI_THREAD_LOCAL thread_local
#endif
#include "stb_image.h"
#define VULKAN_RENDERING_IMPLEMENTATION
@@ -21,13 +34,58 @@ CameraProjection *g_cameraDataMap;
mat4 g_cameraView;
IMaterial *g_pDefaultMaterial;
IMaterial *g_pCurrentMaterial;
IImage *g_meshDepth;
IImage *g_meshDepthMSAA;
IImage *g_meshColor;
IImage *g_meshColorMSAA;
class CVkGraphicsPipeline: public IGraphicsPipeline
{
public:
vk_tripipeline_t m_pipeline;
};
vk_image2d_t g_meshDepth;
vk_image2d_t g_meshDepthMSAA;
vk_image2d_t g_meshColor;
vk_image2d_t g_meshColorMSAA;
class CVkComputePipeline: public IComputePipeline
{
public:
vk_comppipeline_t m_pipeline;
};
class CVkRayTracingPipeline: public IRayTracingPipeline
{
public:
};
VkFormat IRenderer_FormatToVk( EImageFormat format )
{
switch (format)
{
case IMAGE_FORMAT_R8G8B8A8: return VK_FORMAT_R8G8B8A8_UNORM;
case IMAGE_FORMAT_R16G16B16A16: return VK_FORMAT_R16G16B16A16_UNORM;
case IMAGE_FORMAT_DEPTH: return VK_FORMAT_D32_SFLOAT;
default: return VK_FORMAT_R8G8B8A8_UNORM;
}
};
VkAttachmentLoadOp IRenderer_LoadOpVk( EAttachmentLoadMode mode )
{
switch (mode)
{
case ATTACHMENT_LOAD_MODE_DONT_CARE: return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
case ATTACHMENT_LOAD_MODE_CLEAR: return VK_ATTACHMENT_LOAD_OP_CLEAR;
case ATTACHMENT_LOAD_MODE_LOAD: return VK_ATTACHMENT_LOAD_OP_LOAD;
default: return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
}
}
VkAttachmentStoreOp IRenderer_StoreOpVk( EAttachmentStoreMode mode )
{
switch (mode)
{
case ATTACHMENT_STORE_MODE_DONT_CARE: return VK_ATTACHMENT_STORE_OP_DONT_CARE;
case ATTACHMENT_STORE_MODE_STORE: return VK_ATTACHMENT_STORE_OP_STORE;
default: return VK_ATTACHMENT_STORE_OP_DONT_CARE;
}
}
void IVulkan::Init()
{
@@ -65,15 +123,25 @@ void IVulkan::Init()
g_cameraProperties.Create(sizeof(CameraProjection), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
g_cameraDataMap = (CameraProjection*)g_cameraProperties.Map(0, 64);
g_meshDepth.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshDepthMSAA.Create(1280, 720, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT);
g_meshColor.Create(1280, 720, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshColorMSAA.Create(1280, 720, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT);
g_meshDepth = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, 1280, 720, 1);
g_meshDepthMSAA = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, 1280, 720, 4);
g_meshColor = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, 1280, 720, 1);
g_meshColorMSAA = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, 1280, 720, 4);
glm_mat4_identity(g_cameraView);
IMeshRenderer::Init();
IPostProcessRenderer::Init();
};
void IVulkan::CreatePipelines()
{
for (auto &step: g_StepPrepass)
step.pPipeline->Init();
for (auto &step: g_StepMeshRendering)
step.pPipeline->Init();
for (auto &step: g_StepShading)
step.pPipeline->Init();
for (auto &step: g_StepPostProcessing)
step.pPipeline->Init();
for (auto &step: g_StepUI)
step.pPipeline->Init();
}
void IVulkan::Frame()
{
@@ -87,19 +155,42 @@ void IVulkan::Frame()
if (g_bConfigNotify)
{
g_meshDepth.Destroy();
g_meshDepthMSAA.Destroy();
g_meshColor.Destroy();
g_meshColorMSAA.Destroy();
g_meshDepth.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshDepthMSAA.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_D32_SFLOAT, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT);
g_meshColor.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT, VK_SAMPLE_COUNT_1_BIT);
g_meshColorMSAA.Create(g_nWindowWidth, g_nWindowHeight, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, VK_SAMPLE_COUNT_4_BIT);
IRenderer::DestroyImage(g_meshDepth);
IRenderer::DestroyImage(g_meshDepthMSAA);
IRenderer::DestroyImage(g_meshColor);
IRenderer::DestroyImage(g_meshColorMSAA);
g_meshDepth = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 1);
g_meshDepthMSAA = IRenderer::CreateImage(IMAGE_FORMAT_DEPTH, IMAGE_USAGE_DEPTH_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 4);
g_meshColor = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 1);
g_meshColorMSAA = IRenderer::CreateImage(IMAGE_FORMAT_R8G8B8A8, IMAGE_USAGE_COLOR_ATTACHMENT, g_nWindowWidth, g_nWindowHeight, 4);
}
IMeshRenderer::Frame(0);
IPostProcessRenderer::Frame(0);
for (auto &step: g_StepPrepass)
step.pPipeline->Frame(0);
IRenderer::Begin(g_nWindowWidth, g_nWindowHeight,
{
{
g_meshColor,
g_meshColorMSAA,
ATTACHMENT_LOAD_MODE_DONT_CARE,
ATTACHMENT_STORE_MODE_STORE,
}
},
{
g_meshDepth,
g_meshDepthMSAA,
ATTACHMENT_LOAD_MODE_DONT_CARE,
ATTACHMENT_STORE_MODE_STORE,
});
for (auto &step: g_StepMeshRendering)
step.pPipeline->Frame(0);
IRenderer::End();
for (auto &step: g_StepShading)
step.pPipeline->Frame(0);
for (auto &step: g_StepPostProcessing)
step.pPipeline->Frame(0);
for (auto &step: g_StepUI)
step.pPipeline->Frame(0);
};
void vk_shader_t::Create( const char *szPath, VkShaderStageFlagBits shaderStage )
@@ -384,27 +475,13 @@ void vk_image2d_t::Destroy()
void CopyTo(struct vk_image2d_t *image);
void CopyTo(struct vk_buffer_t *buffer);
void *CVertexBuffer::Map()
void *CVkBuffer::Map()
{
if (!m_pAllocated)
m_pAllocated = m_buffer.Map(0, m_buffer.m_nSize);
return m_pAllocated;
};
void CVertexBuffer::Unmap()
{
if (!m_pAllocated)
return;
m_buffer.Unmap();
m_pAllocated = 0;
};
void *CIndexBuffer::Map()
{
if (!m_pAllocated)
m_pAllocated = m_buffer.Map(0, m_buffer.m_nSize);
return m_pAllocated;
};
void CIndexBuffer::Unmap()
void CVkBuffer::Unmap()
{
if (!m_pAllocated)
return;
@@ -415,21 +492,9 @@ void CIndexBuffer::Unmap()
CUtlVector<ITexture*> g_textures;
CUtlVector<ITexture*> g_newtextures;
uint32_t ITextureManager::GetTexture(ITexture *pTexture)
{
uint32_t i = 0;
for (ITexture *texture: g_textures)
{
if (texture == pTexture)
return i;
i++;
};
return 0;
}
ITexture *ITextureManager::LoadTexture( void *pData, uint32_t X, uint32_t Y, uint32_t numChannels )
{
CTexture *pTexture = new CTexture;
CVkTexture *pTexture = new CVkTexture;
*pTexture = {};
VkDeviceSize imageSize = X*Y*4;
vk_buffer_t gpu_buffer = {};
@@ -562,28 +627,265 @@ ITexture *ITextureManager::LoadTexture( const char *szName )
return pTexture;
};
IMaterial *IRenderer::LoadMaterial( const char *szMaterial )
{
FileHandle_t file = IFileSystem::Open(szMaterial, IFILE_READ);
IMaterial *pMaterial = new IMaterial;
if (!file)
{
return g_pDefaultMaterial;
}
IFileSystem::Close(file);
IStorageBuffer *IRenderer::CreateStorageBuffer( uint32_t uSize )
{
CVkBuffer *pBuffer = new CVkBuffer();
pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
return pBuffer;
}
IUniformBuffer *IRenderer::CreateUniformBuffer( uint32_t uSize )
{
CVkBuffer *pBuffer = new CVkBuffer();
pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
return pBuffer;
}
IVertexBuffer *IRenderer::CreateVertexBuffer( uint32_t uSize )
{
CVertexBuffer *pBuffer = new CVertexBuffer();
CVkBuffer *pBuffer = new CVkBuffer();
pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
return pBuffer;
}
IIndexBuffer *IRenderer::CreateIndexBuffer( uint32_t uSize )
{
CIndexBuffer *pBuffer = new CIndexBuffer();
CVkBuffer *pBuffer = new CVkBuffer();
pBuffer->m_buffer.Create(uSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
return pBuffer;
}
IImage *IRenderer::CreateImage( EImageFormat format, uint32_t usage, uint32_t nWidth, uint32_t nHeight, uint32_t nSamples )
{
VkFormat vkformat;
VkImageUsageFlags vkusage;
CVkImage *pImage = new CVkImage();
VkSampleCountFlagBits samples;
switch (format)
{
case IMAGE_FORMAT_R8G8B8A8: vkformat = VK_FORMAT_R8G8B8A8_UNORM; break;
case IMAGE_FORMAT_R16G16B16A16: vkformat = VK_FORMAT_R16G16B16A16_UNORM; break;
case IMAGE_FORMAT_DEPTH: vkformat = VK_FORMAT_D32_SFLOAT; break;
default: return 0;
};
if (usage&IMAGE_USAGE_COLOR_ATTACHMENT) vkusage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
if (usage&IMAGE_USAGE_DEPTH_ATTACHMENT) vkusage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
if (usage&IMAGE_USAGE_STORAGE) vkusage |= VK_IMAGE_USAGE_STORAGE_BIT;
switch (nSamples)
{
case 1: samples = VK_SAMPLE_COUNT_1_BIT; break;
case 4: samples = VK_SAMPLE_COUNT_4_BIT; break;
default: samples = VK_SAMPLE_COUNT_1_BIT; break;
}
pImage->m_image.Create(nWidth, nHeight, vkformat, vkusage, samples);
return pImage;
};
void IRenderer::DestroyBuffer( IBuffer *pBuffer )
{
CVkBuffer *pVkBuffer = (CVkBuffer*)pBuffer;
if (pVkBuffer)
pVkBuffer->m_buffer.Destroy();
}
void IRenderer::DestroyImage( IImage *pImage )
{
CVkImage *pVkImage = (CVkImage*)pImage;
if (pVkImage)
pVkImage->m_image.Destroy();
}
void IRenderer::SetConstants( uint32_t nSize, uint32_t nOffset, void *pData )
{
}
void IRenderer::Barrier( EBarrierStage stageIn, uint32_t stageOut, CUtlVector<BufferBarrier_t> buffers, CUtlVector<ImageBarrier_t> images )
{
}
void IRenderer::BindData( uint32_t binding, IBuffer *pBuffer, IImage* pImage)
{
}
void IRenderer::BindPipeline( IPipeline *pPipeline )
{
if (!pPipeline)
return;
if (pPipeline->type == PIPELINE_TYPE_RASTERIZATION)
{
CVkGraphicsPipeline *pVkPipeline = (CVkGraphicsPipeline*)pPipeline;
vkCmdBindPipeline(g_vkCommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pVkPipeline->m_pipeline.m_pipeline);
}
}
void IRenderer::Begin( uint32_t nWidth, uint32_t nHeight, CUtlVector<RenderingColorAttachment_t> attachments, RenderingDepthAttachment_t depth )
{
CUtlVector<VkRenderingAttachmentInfo> colorAttachments = {};
VkRenderingAttachmentInfo depthAttachment = {};
for (auto &attachment: attachments)
{
VkRenderingAttachmentInfo vkattachment = {};
vkattachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
CVkImage *pImage = (CVkImage*)attachment.pTemporary;
CVkImage *pTemporary = (CVkImage*)attachment.pTemporary;
if (attachment.pTemporary)
{
vkattachment.imageView = pTemporary->m_image.m_imageView;
vkattachment.resolveImageView = pImage->m_image.m_imageView;
vkattachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
vkattachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
} else
{
vkattachment.imageView = pImage->m_image.m_imageView;
vkattachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
}
vkattachment.loadOp = IRenderer_LoadOpVk(attachment.loadMode);
vkattachment.storeOp = IRenderer_StoreOpVk(attachment.storeMode);
colorAttachments.AppendTail(vkattachment);
}
depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
CVkImage *pDepthImage = (CVkImage*)depth.pTemporary;
CVkImage *pDepthTemporary = (CVkImage*)depth.pTemporary;
if (depth.pTemporary)
{
depthAttachment.imageView = pDepthTemporary->m_image.m_imageView;
depthAttachment.resolveImageView = pDepthImage->m_image.m_imageView;
depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
depthAttachment.resolveImageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
} else
{
depthAttachment.imageView = pDepthImage->m_image.m_imageView;
depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
}
depthAttachment.loadOp = IRenderer_LoadOpVk(depth.loadMode);
depthAttachment.storeOp = IRenderer_StoreOpVk(depth.storeMode);
VkRenderingInfo renderInfo = {
.sType = VK_STRUCTURE_TYPE_RENDERING_INFO,
.renderArea = {{0, 0}, {nWidth, nHeight}},
.layerCount = 1,
.colorAttachmentCount = (uint32_t)colorAttachments.GetSize(),
.pColorAttachments = colorAttachments.GetData(),
.pDepthAttachment = &depthAttachment,
};
vkCmdBeginRendering(g_vkCommandBuffer, &renderInfo);
}
void IRenderer::ResetState()
{
}
void IRenderer::SetDepthMode( EDepthMode mode )
{
}
void IRenderer::Draw( IVertexBuffer *pVertex, IIndexBuffer *pIndex )
{
}
void IRenderer::End()
{
vkCmdEndRendering(g_vkCommandBuffer);
}
IGraphicsPipeline *IRenderer::CreateGraphicsPipeline(
CUtlVector<Shader_t> shaders,
CUtlVector<ShaderInput_t> inputs,
uint32_t nConstantsSize,
CUtlVector<EImageFormat> outputFormats
)
{
CVkGraphicsPipeline *pipeline = new CVkGraphicsPipeline;
pipeline->type = PIPELINE_TYPE_RASTERIZATION;
CUtlVector<vk_shader_t> vkshaders(shaders.GetSize());
CUtlVector<VkDescriptorSetLayoutBinding> vkbindings(inputs.GetSize());
CUtlVector<VkFormat> vkformats(outputFormats.GetSize());
for ( uint32_t i = 0; i < vkshaders.GetSize(); i++ )
{
VkShaderStageFlagBits flags;
if (shaders[i].type == SHADER_TYPE_VERTEX) flags = VK_SHADER_STAGE_VERTEX_BIT;
if (shaders[i].type == SHADER_TYPE_FRAGMENT) flags = VK_SHADER_STAGE_FRAGMENT_BIT;
vkshaders[i].Create(shaders[i].szPath, flags);
}
for ( uint32_t i = 0; i < vkbindings.GetSize(); i++ )
{
vkbindings[i].binding = inputs[i].binding;
vkbindings[i].descriptorCount = 1;
if (inputs[i].type == SHADER_INPUT_TYPE_IMAGE) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
if (inputs[i].type == SHADER_INPUT_TYPE_UNIFORM_BUFFER) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
if (inputs[i].type == SHADER_INPUT_TYPE_STORAGE_BUFFER) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
if (inputs[i].type == SHADER_INPUT_TYPE_TLAS) vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR;
if (inputs[i].type == SHADER_INPUT_TYPE_TEXTURES)
{
vkbindings[i].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
vkbindings[i].descriptorCount = 1024;
}
}
for ( uint32_t i = 0; i < vkformats.GetSize(); i++ )
{
vkformats[i] = IRenderer_FormatToVk(outputFormats[i]);
}
pipeline->m_pipeline.Create(vkshaders, vkbindings, nConstantsSize, vkformats);
return 0;
};
CUtlVector<RenderingStep_t> g_StepPrepass;
CUtlVector<RenderingStep_t> g_StepMeshRendering;
CUtlVector<RenderingStep_t> g_StepShading;
CUtlVector<RenderingStep_t> g_StepPostProcessing;
CUtlVector<RenderingStep_t> g_StepUI;
CRenderingStep::CRenderingStep()
{
}
CRenderingStep::CRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
}
CPrepassRenderingStep::CPrepassRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
g_StepPrepass.AppendTail({pfn(), szStepName});
}
CMeshRenderingStep::CMeshRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
g_StepMeshRendering.AppendTail({pfn(), szStepName});
}
CShadingRenderingStep::CShadingRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
g_StepShading.AppendTail({pfn(), szStepName});
}
CPostProcessingRenderingStep::CPostProcessingRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
g_StepPostProcessing.AppendTail({pfn(), szStepName});
}
CUIRenderingStep::CUIRenderingStep(const char *szStepName, CreateRenderStepFn pfn)
{
g_StepUI.AppendTail({pfn(), szStepName});
}