Skip to content

Commit

Permalink
SSGI stubbed but fucked and perf is abysmal
Browse files Browse the repository at this point in the history
  • Loading branch information
tadgem committed Jul 1, 2024
1 parent b8c68d7 commit 8c33f17
Show file tree
Hide file tree
Showing 6 changed files with 389 additions and 55 deletions.
4 changes: 3 additions & 1 deletion examples/pipeline-abstraction/compile_shaders.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
%VULKAN_SDK%/bin/glslc.exe shaders/gbuffer.frag -o shaders/gbuffer.frag.spv

%VULKAN_SDK%/bin/glslc.exe shaders/lights.vert -o shaders/lights.vert.spv
%VULKAN_SDK%/bin/glslc.exe shaders/lights.frag -o shaders/lights.frag.spv
%VULKAN_SDK%/bin/glslc.exe shaders/lights.frag -o shaders/lights.frag.spv

%VULKAN_SDK%/bin/glslc.exe shaders/SSGI.frag -o shaders/ssgi.frag.spv
201 changes: 148 additions & 53 deletions examples/pipeline-abstraction/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ struct ViewData
View m_View;
Mesh m_ViewQuad;
};
Pipeline CreateViewPipeline(VulkanAPI& vk, LvkIm3dState& im3dState, ShaderProgram& gbufferProg, ShaderProgram& lightPassProg)

Pipeline CreateViewPipeline(VulkanAPI& vk, LvkIm3dState& im3dState, ShaderProgram& gbufferProg, ShaderProgram& lightPassProg, ShaderProgram& ssgiProg)
{
Pipeline p{};
auto* gbuffer = p.AddFramebuffer(vk);
Expand All @@ -103,17 +104,29 @@ Pipeline CreateViewPipeline(VulkanAPI& vk, LvkIm3dState& im3dState, ShaderProgra
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_ASPECT_DEPTH_BIT);
gbuffer->Build(vk);

auto* lightPassImage = p.AddFramebuffer(vk);
lightPassImage->AddColourAttachment(vk, ResolutionScale::Full, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R16G16B16A16_SFLOAT, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
lightPassImage->Build(vk);

auto* lightPassMat = p.AddMaterial(vk, lightPassProg);
lightPassMat->SetColourAttachment(vk, "positionBufferSampler", *gbuffer, 1);
lightPassMat->SetColourAttachment(vk, "normalBufferSampler", *gbuffer, 2);
lightPassMat->SetColourAttachment(vk, "colourBufferSampler", *gbuffer, 0);

auto* finalImage = p.AddFramebuffer(vk);
finalImage->AddColourAttachment(vk, ResolutionScale::Full, 1, VK_SAMPLE_COUNT_1_BIT, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_ASPECT_COLOR_BIT);
finalImage->Build(vk);

auto* ssgiMat = p.AddMaterial(vk, ssgiProg);
ssgiMat->SetDepthAttachment(vk, "depthImageSampler", *gbuffer);
ssgiMat->SetColourAttachment(vk, "positionBufferSampler", *gbuffer, 1);
ssgiMat->SetColourAttachment(vk, "normalBufferSampler", *gbuffer, 2);
ssgiMat->SetColourAttachment(vk, "lightPassImageSampler", *lightPassImage, 0);

p.SetOutputFramebuffer(finalImage);

auto* lightPassMat = p.AddMaterial(vk, lightPassProg);
lightPassMat->SetColourAttachment(vk, "positionBufferSampler", *gbuffer, 1);
lightPassMat->SetColourAttachment(vk, "normalBufferSampler", *gbuffer, 2);
lightPassMat->SetColourAttachment(vk, "colourBufferSampler", *gbuffer, 0);

// create gbuffer pipeline
VkPipelineLayout gbufferPipelineLayout;
Expand All @@ -133,27 +146,45 @@ Pipeline CreateViewPipeline(VulkanAPI& vk, LvkIm3dState& im3dState, ShaderProgra
lightPassProg,
Vector<VkVertexInputBindingDescription>{VertexDataPosUv::GetBindingDescription() },
VertexDataPosUv::GetAttributeDescriptions(),
finalImage->m_RenderPass,
lightPassImage->m_RenderPass,
vk.m_SwapChainImageExtent.width, vk.m_SwapChainImageExtent.height,
VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, false,
VK_COMPARE_OP_LESS, lightPassPipelineLayout);

VkPipelineLayout ssgiPassPipelineLayout;
VkPipeline ssgiPassPipeline= vk.CreateRasterizationGraphicsPipeline(
ssgiProg,
Vector<VkVertexInputBindingDescription>{VertexDataPosUv::GetBindingDescription() },
VertexDataPosUv::GetAttributeDescriptions(),
finalImage->m_RenderPass,
vk.m_SwapChainImageExtent.width, vk.m_SwapChainImageExtent.height,
VK_POLYGON_MODE_FILL, VK_CULL_MODE_NONE, false,
VK_COMPARE_OP_LESS, ssgiPassPipelineLayout);


VkPipelineData* gbufferPipelineData = p.AddPipeline(vk, gbufferPipeline, gbufferPipelineLayout );
VkPipelineData* lightPassPipelineData = p.AddPipeline(vk, lightPassPipeline, lightPassPipelineLayout );
VkPipelineData* lightPassPipelineData = p.AddPipeline(vk, lightPassPipeline, lightPassPipelineLayout);
VkPipelineData* ssgiPassPipelineData = p.AddPipeline(vk, ssgiPassPipeline, ssgiPassPipelineLayout);

auto* im3dViewState = p.AddIm3d(vk, im3dState);

p.RecordCommands(
[gbuffer, gbufferPipelineData, finalImage, lightPassPipelineData, lightPassMat, &vk, &im3dState, im3dViewState](auto& commandBuffer, uint32_t frameIndex, View& view, Mesh& screenQuad, Vector<Renderable> renderables)
[
gbuffer, gbufferPipelineData,
lightPassImage, lightPassPipelineData, lightPassMat,
finalImage, ssgiPassPipelineData, ssgiMat,
&vk, &im3dState, im3dViewState
]
(auto& commandBuffer, uint32_t frameIndex, View& view, Mesh& screenQuad, Vector<Renderable> renderables)
{
static int frameCount = 0;
// prepare push constant data
struct PCViewData
{
glm::mat4 view;
glm::mat4 proj;
};


PCViewData pcData{ view.m_Camera.View, view.m_Camera.Proj };
VkExtent2D viewExtent = view.m_CurrentResolution;

Expand All @@ -172,7 +203,7 @@ Pipeline CreateViewPipeline(VulkanAPI& vk, LvkIm3dState& im3dState, ShaderProgra

vkCmdUpdateBuffer(commandBuffer, screenQuad.m_VertexBuffer, 0, 4 * sizeof(VertexDataPosUv), &newScreenQuadData[0]);
}

// Gbuffer pass
{
Array<VkClearValue, 4> clearValues{};
clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} };
Expand Down Expand Up @@ -217,60 +248,123 @@ Pipeline CreateViewPipeline(VulkanAPI& vk, LvkIm3dState& im3dState, ShaderProgra
}
vkCmdEndRenderPass(commandBuffer);
}
// Light pass
{
Array<VkClearValue, 1> clearValues{};
clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} };

Array<VkClearValue, 2> clearValues{};
clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} };
clearValues[1].depthStencil = { 1.0f, 0 };
VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = lightPassImage->m_RenderPass;
renderPassInfo.framebuffer = lightPassImage->m_SwapchainFramebuffers[frameIndex];
renderPassInfo.renderArea.offset = { 0,0 };
renderPassInfo.renderArea.extent = viewExtent;

VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = finalImage->m_RenderPass;
renderPassInfo.framebuffer = finalImage->m_SwapchainFramebuffers[frameIndex];
renderPassInfo.renderArea.offset = { 0,0 };
renderPassInfo.renderArea.extent = viewExtent;
renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
renderPassInfo.pClearValues = clearValues.data();

renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
renderPassInfo.pClearValues = clearValues.data();
vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);

vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, lightPassPipelineData->m_Pipeline);
VkViewport viewport{};
viewport.x = 0.0f;
viewport.x = 0.0f;
viewport.width = static_cast<float>(viewExtent.width);
viewport.height = static_cast<float>(viewExtent.height);
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;

vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, lightPassPipelineData->m_Pipeline);
VkViewport viewport{};
viewport.x = 0.0f;
viewport.x = 0.0f;
viewport.width = static_cast<float>(viewExtent.width);
viewport.height = static_cast<float>(viewExtent.height);
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
VkRect2D scissor{};
scissor.offset = { 0,0 };
scissor.extent = VkExtent2D{
static_cast<uint32_t>(viewExtent.width) ,
static_cast<uint32_t>(viewExtent.height)
};

VkRect2D scissor{};
scissor.offset = { 0,0 };
scissor.extent = VkExtent2D{
static_cast<uint32_t>(viewExtent.width) ,
static_cast<uint32_t>(viewExtent.height)
};
// issue with lighting pass is that uvs are just 0,0 -> 1,1
// meaning the entire buffer will be resampled
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
vkCmdPushConstants(commandBuffer, lightPassPipelineData->m_PipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PCViewData), &pcData);
VkDeviceSize sizes[] = { 0 };
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &screenQuad.m_VertexBuffer, sizes);
vkCmdBindIndexBuffer(commandBuffer, screenQuad.m_IndexBuffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, lightPassPipelineData->m_PipelineLayout, 0, 1, &lightPassMat->m_DescriptorSets[0].m_Sets[frameIndex], 0, nullptr);
vkCmdDrawIndexed(commandBuffer, screenQuad.m_IndexCount, 1, 0, 0, 0);

// issue with lighting pass is that uvs are just 0,0 -> 1,1
// meaning the entire buffer will be resampled
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
vkCmdPushConstants(commandBuffer, lightPassPipelineData->m_PipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(PCViewData), &pcData);
VkDeviceSize sizes[] = { 0 };
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &screenQuad.m_VertexBuffer, sizes);
vkCmdBindIndexBuffer(commandBuffer, screenQuad.m_IndexBuffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, lightPassPipelineData->m_PipelineLayout, 0, 1, &lightPassMat->m_DescriptorSets[0].m_Sets[frameIndex], 0, nullptr);
vkCmdDrawIndexed(commandBuffer, screenQuad.m_IndexCount, 1, 0, 0, 0);

DrawIm3d(vk, commandBuffer, frameIndex, im3dState, *im3dViewState, view.m_Camera.Proj * view.m_Camera.View, viewExtent.width, viewExtent.height);
vkCmdEndRenderPass(commandBuffer);
vkCmdEndRenderPass(commandBuffer);
}
// SS Horizon GI pass
{
struct SSGIPCData
{
glm::mat4 view;
glm::mat4 proj;
glm::vec4 resolutionFov;
glm::vec4 eyePos;
uint32_t frameIndex;
};

SSGIPCData data{};
data.view = view.m_Camera.View;
data.proj = view.m_Camera.Proj;
data.resolutionFov = glm::vec4{ static_cast<float>(view.m_CurrentResolution.width), static_cast<float>(view.m_CurrentResolution.height), view.m_Camera.FOV, 0.0f };
data.eyePos = glm::vec4(view.m_Camera.Position, 0.0);
data.frameIndex = frameCount++;

Array<VkClearValue, 1> clearValues{};
clearValues[0].color = { {0.0f, 0.0f, 0.0f, 1.0f} };

VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = finalImage->m_RenderPass;
renderPassInfo.framebuffer = finalImage->m_SwapchainFramebuffers[frameIndex];
renderPassInfo.renderArea.offset = { 0,0 };
renderPassInfo.renderArea.extent = viewExtent;

renderPassInfo.clearValueCount = static_cast<uint32_t>(clearValues.size());
renderPassInfo.pClearValues = clearValues.data();

vkCmdBeginRenderPass(commandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);

vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ssgiPassPipelineData->m_Pipeline);
VkViewport viewport{};
viewport.x = 0.0f;
viewport.x = 0.0f;
viewport.width = static_cast<float>(viewExtent.width);
viewport.height = static_cast<float>(viewExtent.height);
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;

VkRect2D scissor{};
scissor.offset = { 0,0 };
scissor.extent = VkExtent2D{
static_cast<uint32_t>(viewExtent.width),
static_cast<uint32_t>(viewExtent.height)
};

// issue with lighting pass is that uvs are just 0,0 -> 1,1
// meaning the entire buffer will be resampled
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
vkCmdPushConstants(commandBuffer, ssgiPassPipelineData->m_PipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(SSGIPCData), &data);
VkDeviceSize sizes[] = { 0 };
vkCmdBindVertexBuffers(commandBuffer, 0, 1, &screenQuad.m_VertexBuffer, sizes);
vkCmdBindIndexBuffer(commandBuffer, screenQuad.m_IndexBuffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, ssgiPassPipelineData->m_PipelineLayout, 0, 1, &ssgiMat->m_DescriptorSets[0].m_Sets[frameIndex], 0, nullptr);
vkCmdDrawIndexed(commandBuffer, screenQuad.m_IndexCount, 1, 0, 0, 0);

DrawIm3d(vk, commandBuffer, frameIndex, im3dState, *im3dViewState, view.m_Camera.Proj * view.m_Camera.View, viewExtent.width, viewExtent.height);
vkCmdEndRenderPass(commandBuffer);
}
}
);
return p;
}

ViewData CreateView(VulkanAPI& vk, LvkIm3dState im3dState, ShaderProgram gbufferProg, ShaderProgram lightPassProg)
ViewData CreateView(VulkanAPI& vk, LvkIm3dState im3dState, ShaderProgram gbufferProg, ShaderProgram lightPassProg, ShaderProgram& ssgiProg)
{
Pipeline pipeline = CreateViewPipeline(vk, im3dState, gbufferProg, lightPassProg);
Pipeline pipeline = CreateViewPipeline(vk, im3dState, gbufferProg, lightPassProg, ssgiProg);

static Vector<VertexDataPosUv> screenQuadVerts = {
{ { -1.0f, -1.0f , 0.0f}, { 0.0f, 0.0f } },
Expand Down Expand Up @@ -589,10 +683,11 @@ int main() {

ShaderProgram gbufferProg = ShaderProgram::Create(vk, "shaders/gbuffer.vert.spv", "shaders/gbuffer.frag.spv");
ShaderProgram lightPassProg = ShaderProgram::Create(vk, "shaders/lights.vert.spv", "shaders/lights.frag.spv");
ShaderProgram ssgiProg = ShaderProgram::Create(vk, "shaders/lights.vert.spv", "shaders/ssgi.frag.spv");

ViewData viewA = CreateView(vk, im3dState, gbufferProg, lightPassProg);
ViewData viewA = CreateView(vk, im3dState, gbufferProg, lightPassProg, ssgiProg);
viewA.m_View.m_Camera.Position = { -40.0, 10.0f, 30.0f };
ViewData viewB = CreateView(vk, im3dState, gbufferProg, lightPassProg);
ViewData viewB = CreateView(vk, im3dState, gbufferProg, lightPassProg, ssgiProg);
viewB.m_View.m_Camera.Position = { 30.0, 0.0f, -20.0f };

Vector<ViewData*> views{ &viewA, &viewB };
Expand Down
Loading

0 comments on commit 8c33f17

Please sign in to comment.