Skip to content

Commit 48fef6e

Browse files
committed
now does a depth prepass
1 parent 26ee4f1 commit 48fef6e

File tree

3 files changed

+142
-83
lines changed

3 files changed

+142
-83
lines changed

src/vulkan/Pipeline.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Pipeline::Pipeline(vk::Device device, vk::Format colorAttachmentFormat,
7878
if (depthAttachmentFormat != vk::Format::eUndefined) {
7979
depthStencil.depthTestEnable = VK_TRUE;
8080
depthStencil.depthWriteEnable = depthWriteEnable ? VK_TRUE : VK_FALSE;
81-
depthStencil.depthCompareOp = vk::CompareOp::eLess;
81+
depthStencil.depthCompareOp = vk::CompareOp::eLessOrEqual;
8282
depthStencil.depthBoundsTestEnable = VK_FALSE;
8383
depthStencil.stencilTestEnable = VK_FALSE;
8484
}
@@ -133,6 +133,11 @@ Pipeline::Pipeline(vk::Device device, vk::Format colorAttachmentFormat,
133133
pipelineInfo.pDynamicState = &dynamicState;
134134
pipelineInfo.pNext = &renderingInfo;
135135

136+
// assign depth stencil state to the pipeline info if specified
137+
if (depthAttachmentFormat != vk::Format::eUndefined) {
138+
pipelineInfo.pDepthStencilState = &depthStencil;
139+
}
140+
136141
auto pipelineResult = m_device.createGraphicsPipeline({}, pipelineInfo);
137142
if (pipelineResult.result != vk::Result::eSuccess) {
138143
throw std::runtime_error("Failed to create graphics pipeline!");

src/vulkan/VulkanRenderer.cpp

Lines changed: 91 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ VulkanRenderer::VulkanRenderer(const RendererConfig& config, Window& window, Cam
2626
createDepthImages();
2727
createSampler();
2828
createDescriptorSets();
29+
createDepthPipelineAndDescriptorSets();
2930

3031
}
3132

@@ -62,7 +63,7 @@ void VulkanRenderer::createPipelineAndDescriptors() {
6263
const std::vector setLayouts = {m_descriptorSet->getLayout()};
6364

6465
m_pipeline = std::make_unique<Pipeline>(m_context->device(), vk::Format::eR16G16B16A16Sfloat,
65-
vertShaderPath, fragShaderPath, setLayouts, 4);
66+
vertShaderPath, fragShaderPath, setLayouts, 4, vk::Format::eD32Sfloat, true);
6667

6768
const std::vector compositeBindings = {
6869
vk::DescriptorSetLayoutBinding(0, vk::DescriptorType::eCombinedImageSampler, 1, vk::ShaderStageFlagBits::eFragment),
@@ -74,8 +75,12 @@ void VulkanRenderer::createPipelineAndDescriptors() {
7475

7576
vk::Format swapchainFormat = m_swapchain->getFormat();
7677

77-
m_compositePipeline = std::make_unique<Pipeline>(m_context->device(), swapchainFormat,
78-
m_config.compositeVertShaderPath, m_config.compositeFragShaderPath, compositeSetLayouts, 1);
78+
m_compositePipeline = std::make_unique<Pipeline>(
79+
m_context->device(),
80+
swapchainFormat,
81+
m_config.compositeVertShaderPath,
82+
m_config.compositeFragShaderPath,
83+
compositeSetLayouts, 1);
7984
}
8085

8186
void VulkanRenderer::handleSwapchainResizing() {
@@ -101,6 +106,7 @@ VulkanRenderer::~VulkanRenderer() {
101106
m_context->device().destroyImageView(m_msaaColorViews[i]);
102107
m_context->device().destroyImageView(m_resolveViews[i]);
103108
m_context->device().destroyImageView(m_sceneViewViews[i]);
109+
m_context->device().destroyImageView(m_depthViews[i]);
104110
}
105111
}
106112

@@ -115,7 +121,7 @@ void VulkanRenderer::bindDescriptorSets(vk::CommandBuffer cmd) {
115121
}
116122

117123
void VulkanRenderer::drawGeometry(vk::CommandBuffer cmd) {
118-
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, m_pipeline->get());
124+
//cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, m_pipeline->get());
119125
cmd.draw(36, 1, 0, 0);
120126
}
121127

@@ -134,22 +140,39 @@ void VulkanRenderer::submitAndPresent(uint32_t imageIndex) {
134140
m_swapchain->get(), imageIndex);
135141
}
136142

137-
void VulkanRenderer::beginDynamicRendering(vk::CommandBuffer cmd, vk::ImageView imageView,
138-
vk::Extent2D extent, bool clear=true) {
139-
constexpr vk::ClearValue clearColor = vk::ClearColorValue(std::array{0.0f, 0.0f, 0.0f, 1.0f});
143+
void VulkanRenderer::beginDynamicRendering(
144+
vk::CommandBuffer cmd,
145+
vk::ImageView colorImageView,
146+
vk::ImageView depthImageView,
147+
vk::Extent2D extent,
148+
bool clearColor=true,
149+
bool clearDepth=false)
150+
{
151+
constexpr vk::ClearValue clearColorValue = vk::ClearColorValue(std::array{0.0f, 0.0f, 0.0f, 1.0f});
140152
vk::RenderingAttachmentInfo colorAttachment{};
141-
colorAttachment.imageView = imageView;
153+
colorAttachment.imageView = colorImageView;
142154
colorAttachment.imageLayout = vk::ImageLayout::eColorAttachmentOptimal;
143-
colorAttachment.loadOp = clear ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad;
155+
colorAttachment.loadOp = clearColor ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad;
144156
colorAttachment.storeOp = vk::AttachmentStoreOp::eStore;
145-
colorAttachment.clearValue = clearColor;
157+
colorAttachment.clearValue = clearColorValue;
158+
159+
vk::ClearValue depthClearValue{};
160+
depthClearValue.depthStencil = vk::ClearDepthStencilValue(1.0f, 0);
161+
162+
vk::RenderingAttachmentInfo depthAttachment{};
163+
depthAttachment.imageView = depthImageView;
164+
depthAttachment.imageLayout = vk::ImageLayout::eDepthStencilAttachmentOptimal;
165+
depthAttachment.loadOp = clearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad;
166+
depthAttachment.storeOp = vk::AttachmentStoreOp::eStore;
167+
depthAttachment.clearValue = depthClearValue;
146168

147169
vk::RenderingInfo renderingInfo{};
148170
renderingInfo.renderArea.offset = vk::Offset2D{0, 0};
149171
renderingInfo.renderArea.extent = extent;
150172
renderingInfo.layerCount = 1;
151173
renderingInfo.colorAttachmentCount = 1;
152174
renderingInfo.pColorAttachments = &colorAttachment;
175+
renderingInfo.pDepthAttachment = &depthAttachment;
153176

154177
cmd.beginRendering(renderingInfo);
155178
}
@@ -185,27 +208,8 @@ void VulkanRenderer::drawFrame() {
185208
compositeData.uExposure = m_imgui->getExposure();
186209
compositeData.uContrast = m_imgui->getContrast();
187210
compositeData.uSaturation = m_imgui->getSaturation();
188-
189211
m_uniformManager->update<CompositeUBO>(frameIdx, compositeData);
190212

191-
beginCommandBuffer(cmd);
192-
193-
// --- 1. Geometry Pass ---
194-
// Transition the MSAA image so we can render the main scene into it.
195-
// Its layout was likely UNDEFINED (on first use) or TRANSFER_SRC (from previous frame's resolve).
196-
m_imageStateTracker.transition(
197-
cmd,
198-
msaaImage,
199-
vk::ImageLayout::eColorAttachmentOptimal,
200-
vk::PipelineStageFlagBits::eTopOfPipe, // Source Stage
201-
vk::PipelineStageFlagBits::eColorAttachmentOutput, // Destination Stage
202-
{}, // Source Access
203-
vk::AccessFlagBits::eColorAttachmentWrite // Destination Access
204-
);
205-
206-
beginDynamicRendering(cmd, msaaView, extent);
207-
utils::setupViewportAndScissor(cmd, extent);
208-
209213
SceneUBO ubo{};
210214
ubo.view = m_camera.getView();
211215
ubo.projection = m_camera.getProjection();
@@ -222,7 +226,35 @@ void VulkanRenderer::drawFrame() {
222226

223227
m_descriptorSet->updateSet({sceneWrite});
224228

229+
beginCommandBuffer(cmd);
230+
231+
// get depth image view for this frame
232+
vk::ImageView depthView = m_depthViews[frameIdx];
233+
234+
beginDynamicRendering(cmd, nullptr, depthView, extent, false, true);
235+
utils::setupViewportAndScissor(cmd, extent);
236+
bindDescriptorSets(cmd);
237+
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, m_depthPipeline->get());
238+
drawGeometry(cmd);
239+
endDynamicRendering(cmd);
240+
241+
// --- 1. Geometry Pass ---
242+
// Transition the MSAA image so we can render the main scene into it.
243+
// Its layout was likely UNDEFINED (on first use) or TRANSFER_SRC (from previous frame's resolve).
244+
m_imageStateTracker.transition(
245+
cmd,
246+
msaaImage,
247+
vk::ImageLayout::eColorAttachmentOptimal,
248+
vk::PipelineStageFlagBits::eTopOfPipe, // Source Stage
249+
vk::PipelineStageFlagBits::eColorAttachmentOutput, // Destination Stage
250+
{}, // Source Access
251+
vk::AccessFlagBits::eColorAttachmentWrite // Destination Access
252+
);
253+
254+
beginDynamicRendering(cmd, msaaView, depthView, extent, true, false);
255+
utils::setupViewportAndScissor(cmd, extent);
225256
bindDescriptorSets(cmd);
257+
cmd.bindPipeline(vk::PipelineBindPoint::eGraphics, m_pipeline->get());
226258
drawGeometry(cmd);
227259
endDynamicRendering(cmd);
228260

@@ -279,7 +311,7 @@ void VulkanRenderer::drawFrame() {
279311
vk::AccessFlagBits::eColorAttachmentWrite
280312
);
281313

282-
beginDynamicRendering(cmd, m_sceneViewViews[frameIdx], extent, true);
314+
beginDynamicRendering(cmd, m_sceneViewViews[frameIdx], depthView, extent, true);
283315
utils::setupViewportAndScissor(cmd, extent);
284316

285317
vk::DescriptorBufferInfo compositeBufferInfo = m_uniformManager->getDescriptorInfo<CompositeUBO>(frameIdx);
@@ -342,7 +374,7 @@ void VulkanRenderer::drawFrame() {
342374
// --- 4. UI Pass ---
343375
// The UI is rendered on top of the composited scene.
344376
// The swapchain image is already in COLOR_ATTACHMENT_OPTIMAL, so no transition is needed.
345-
beginDynamicRendering(cmd, m_swapchain->getImageViews()[imageIndex], extent, false);
377+
beginDynamicRendering(cmd, m_swapchain->getImageViews()[imageIndex], nullptr, extent, false);
346378

347379
m_imgui->setSceneDescriptorSet(m_sceneViewImageDescriptorSets[frameIdx]);
348380
renderUI(cmd);
@@ -538,9 +570,9 @@ void VulkanRenderer::createDescriptorSets() {
538570
}
539571
}
540572
void VulkanRenderer::createDepthImages() {
541-
vk::Format format = vk::Format::eD32Sfloat; // Common depth format
542-
vk::Extent2D extent = m_swapchain->getExtent();
543-
size_t framesInFlight = m_frameManager->getFramesInFlightCount();
573+
vk::Format format = vk::Format::eD32Sfloat; // Common depth format
574+
vk::Extent2D extent = m_swapchain->getExtent();
575+
size_t framesInFlight = m_frameManager->getFramesInFlightCount();
544576

545577
for (size_t i = 0; i < m_depthImages.size(); ++i) {
546578
m_context->device().destroyImageView(m_depthViews[i]);
@@ -561,12 +593,13 @@ void VulkanRenderer::createDepthImages() {
561593
imageInfo.format = format;
562594
imageInfo.tiling = vk::ImageTiling::eOptimal;
563595
imageInfo.initialLayout = vk::ImageLayout::eUndefined;
564-
imageInfo.usage = vk::ImageUsageFlagBits::eDepthStencilAttachment |
565-
vk::ImageUsageFlagBits::eSampled;
566-
imageInfo.samples = vk::SampleCountFlagBits::e1;
596+
imageInfo.usage =
597+
vk::ImageUsageFlagBits::eDepthStencilAttachment | vk::ImageUsageFlagBits::eSampled;
598+
imageInfo.samples = vk::SampleCountFlagBits::e4;
567599
imageInfo.sharingMode = vk::SharingMode::eExclusive;
568600

569-
m_depthImages[i] = std::make_unique<Image>(*m_allocator, imageInfo, VMA_MEMORY_USAGE_GPU_ONLY);
601+
m_depthImages[i] =
602+
std::make_unique<Image>(*m_allocator, imageInfo, VMA_MEMORY_USAGE_GPU_ONLY);
570603
m_imageStateTracker.recordState(m_depthImages[i]->get(), vk::ImageLayout::eUndefined);
571604

572605
vk::ImageViewCreateInfo viewInfo{};
@@ -581,6 +614,26 @@ void VulkanRenderer::createDepthImages() {
581614

582615
m_depthViews[i] = m_context->device().createImageView(viewInfo);
583616
}
617+
}
618+
void VulkanRenderer::createDepthPipelineAndDescriptorSets() {
619+
620+
const std::string depthVertexShaderPath = m_config.vertShaderPath;
621+
const std::string emptyFragShaderPath = ""; // no fragment shader
622+
623+
std::vector<vk::DescriptorSetLayout> setLayouts = {
624+
m_descriptorSet->getLayout()};
625+
626+
m_depthPipeline = std::make_unique<Pipeline>(
627+
m_context->device(),
628+
vk::Format::eUndefined,
629+
depthVertexShaderPath,
630+
emptyFragShaderPath,
631+
setLayouts,
632+
4,
633+
vk::Format::eD32Sfloat,
634+
true
635+
);
636+
584637

585638
}
586639

src/vulkan/VulkanRenderer.hpp

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,54 +18,55 @@
1818

1919
namespace reactor {
2020

21-
struct RendererConfig {
22-
uint32_t windowWidth;
23-
uint32_t windowHeight;
24-
std::string windowTitle;
25-
std::string vertShaderPath;
26-
std::string fragShaderPath;
27-
std::string compositeVertShaderPath;
28-
std::string compositeFragShaderPath;
29-
};
21+
struct RendererConfig {
22+
uint32_t windowWidth;
23+
uint32_t windowHeight;
24+
std::string windowTitle;
25+
std::string vertShaderPath;
26+
std::string fragShaderPath;
27+
std::string compositeVertShaderPath;
28+
std::string compositeFragShaderPath;
29+
};
3030

3131
class VulkanRenderer {
32-
public:
33-
VulkanRenderer(const RendererConfig& config, Window& window, Camera& camera);
32+
public:
33+
VulkanRenderer(const RendererConfig &config, Window &window, Camera &camera);
3434
~VulkanRenderer();
3535

3636
void drawFrame();
3737

38-
private:
39-
const RendererConfig& m_config;
40-
Window& m_window;
41-
Camera& m_camera;
42-
43-
std::unique_ptr<VulkanContext> m_context;
44-
std::unique_ptr<Swapchain> m_swapchain;
45-
std::unique_ptr<Allocator> m_allocator;
46-
std::unique_ptr<FrameManager> m_frameManager;
47-
std::unique_ptr<DescriptorSet> m_descriptorSet;
48-
std::unique_ptr<Pipeline> m_pipeline;
49-
std::unique_ptr<Pipeline> m_compositePipeline;
50-
std::unique_ptr<DescriptorSet> m_compositeDescriptorSet;
51-
std::unique_ptr<Sampler> m_sampler;
38+
private:
39+
const RendererConfig &m_config;
40+
Window &m_window;
41+
Camera &m_camera;
42+
43+
std::unique_ptr<VulkanContext> m_context;
44+
std::unique_ptr<Swapchain> m_swapchain;
45+
std::unique_ptr<Allocator> m_allocator;
46+
std::unique_ptr<FrameManager> m_frameManager;
47+
std::unique_ptr<DescriptorSet> m_descriptorSet;
48+
std::unique_ptr<Pipeline> m_pipeline;
49+
std::unique_ptr<Pipeline> m_compositePipeline;
50+
std::unique_ptr<Pipeline> m_depthPipeline;
51+
std::unique_ptr<DescriptorSet> m_compositeDescriptorSet;
52+
std::unique_ptr<Sampler> m_sampler;
5253
std::unique_ptr<UniformManager> m_uniformManager;
53-
std::unique_ptr<Imgui> m_imgui;
54+
std::unique_ptr<Imgui> m_imgui;
5455

5556
ImageStateTracker m_imageStateTracker;
5657

5758
std::vector<std::unique_ptr<Image>> m_msaaImages;
58-
std::vector<vk::ImageView> m_msaaColorViews;
59+
std::vector<vk::ImageView> m_msaaColorViews;
5960

6061
std::vector<std::unique_ptr<Image>> m_resolveImages;
61-
std::vector<vk::ImageView> m_resolveViews;
62+
std::vector<vk::ImageView> m_resolveViews;
6263
std::vector<std::unique_ptr<Image>> m_sceneViewImages;
63-
std::vector<vk::ImageView> m_sceneViewViews;
64-
std::vector<vk::DescriptorSet> m_sceneViewImageDescriptorSets;
64+
std::vector<vk::ImageView> m_sceneViewViews;
65+
std::vector<vk::DescriptorSet> m_sceneViewImageDescriptorSets;
6566

6667
std::vector<std::unique_ptr<Image>> m_depthImages;
67-
std::vector<vk::ImageView> m_depthViews;
68-
std::vector<vk::DescriptorSet> m_depthImageDescriptorSets;
68+
std::vector<vk::ImageView> m_depthViews;
69+
std::vector<vk::DescriptorSet> m_depthImageDescriptorSets;
6970

7071
void createCoreVulkanObjects();
7172
void createSwapchainAndFrameManager();
@@ -77,19 +78,19 @@ class VulkanRenderer {
7778
void createSampler();
7879
void createDescriptorSets();
7980
void createDepthImages();
80-
81-
void handleSwapchainResizing();
82-
void beginCommandBuffer(vk::CommandBuffer cmd);
83-
void beginDynamicRendering(vk::CommandBuffer cmd, vk::ImageView imageView, vk::Extent2D extent, bool clear);
84-
void bindDescriptorSets(vk::CommandBuffer cmd);
85-
void drawGeometry(vk::CommandBuffer cmd);
86-
void renderUI(vk::CommandBuffer cmd) const;
81+
void createDepthPipelineAndDescriptorSets();
82+
83+
void handleSwapchainResizing();
84+
void beginCommandBuffer(vk::CommandBuffer cmd);
85+
void beginDynamicRendering(vk::CommandBuffer cmd, vk::ImageView colorImageView,
86+
vk::ImageView depthImageView, vk::Extent2D extent,
87+
bool clearColor, bool clearDepth);
88+
void bindDescriptorSets(vk::CommandBuffer cmd);
89+
void drawGeometry(vk::CommandBuffer cmd);
90+
void renderUI(vk::CommandBuffer cmd) const;
8791
static void endDynamicRendering(vk::CommandBuffer cmd);
8892
static void endCommandBuffer(vk::CommandBuffer cmd);
89-
void submitAndPresent(uint32_t imageIndex);
90-
91-
93+
void submitAndPresent(uint32_t imageIndex);
9294
};
9395

94-
}
95-
96+
} // namespace reactor

0 commit comments

Comments
 (0)