mirror of
https://github.com/bailwillharr/engine.git
synced 2024-09-21 04:51:18 +00:00
Replace renderpass with dynamic rendering (imgui broken)
This commit is contained in:
parent
f04c516d2b
commit
dcd71d3a14
@ -224,9 +224,9 @@ void Application::GameLoop()
|
||||
debug_menu_state.show_info_window = !debug_menu_state.show_info_window;
|
||||
}
|
||||
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
//ImGui_ImplVulkan_NewFrame();
|
||||
//ImGui_ImplSDL2_NewFrame();
|
||||
//ImGui::NewFrame();
|
||||
|
||||
if (debug_menu_state.menu_active) {
|
||||
if (ImGui::Begin("debugMenu", 0)) {
|
||||
@ -269,7 +269,7 @@ void Application::GameLoop()
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
//ImGui::Render();
|
||||
|
||||
const RenderList* static_list = nullptr;
|
||||
const RenderList* dynamic_list = nullptr;
|
||||
|
@ -424,39 +424,42 @@ GFXDevice::GFXDevice(const char* appName, const char* appVersion, SDL_Window* wi
|
||||
deviceRequirements.optionalExtensions.push_back(VK_EXT_MEMORY_BUDGET_EXTENSION_NAME);
|
||||
deviceRequirements.requiredFeatures.samplerAnisotropy = VK_TRUE;
|
||||
// deviceRequirements.requiredFeatures.fillModeNonSolid = VK_TRUE;
|
||||
// extension feature memoryPriority is enabled if extension is specified above
|
||||
// synchronization2 is always required as it's part of Vulkan 1.3
|
||||
// dynamic_rendering is always required as it's part of Vulkan 1.3
|
||||
deviceRequirements.formats.push_back(
|
||||
FormatRequirements{.format = VK_FORMAT_R8G8B8A8_SRGB,
|
||||
FormatRequirements{.format = VK_FORMAT_R8G8B8A8_SRGB, // 2D textures and cubemaps
|
||||
.properties = VkFormatProperties{
|
||||
.linearTilingFeatures = {},
|
||||
.optimalTilingFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
|
||||
VK_FORMAT_FEATURE_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_TRANSFER_DST_BIT,
|
||||
.bufferFeatures = {},
|
||||
}});
|
||||
deviceRequirements.formats.push_back(FormatRequirements{.format = VK_FORMAT_R32G32_SFLOAT,
|
||||
deviceRequirements.formats.push_back(FormatRequirements{.format = VK_FORMAT_R32G32_SFLOAT, // vec2 vertex attribute
|
||||
.properties = VkFormatProperties{
|
||||
.linearTilingFeatures = {},
|
||||
.optimalTilingFeatures = {},
|
||||
.bufferFeatures = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT,
|
||||
}});
|
||||
deviceRequirements.formats.push_back(FormatRequirements{.format = VK_FORMAT_R32G32B32_SFLOAT,
|
||||
deviceRequirements.formats.push_back(FormatRequirements{.format = VK_FORMAT_R32G32B32_SFLOAT, // vec3 vertex attribute
|
||||
.properties = VkFormatProperties{
|
||||
.linearTilingFeatures = {},
|
||||
.optimalTilingFeatures = {},
|
||||
.bufferFeatures = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT,
|
||||
}});
|
||||
deviceRequirements.formats.push_back(FormatRequirements{.format = VK_FORMAT_R32G32B32A32_SFLOAT,
|
||||
deviceRequirements.formats.push_back(FormatRequirements{.format = VK_FORMAT_R32G32B32A32_SFLOAT, // vec4 vertex attribute
|
||||
.properties = VkFormatProperties{
|
||||
.linearTilingFeatures = {},
|
||||
.optimalTilingFeatures = {},
|
||||
.bufferFeatures = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT,
|
||||
}});
|
||||
deviceRequirements.formats.push_back( // Depth buffer format
|
||||
FormatRequirements{.format = VK_FORMAT_D16_UNORM,
|
||||
.properties = VkFormatProperties{
|
||||
.linearTilingFeatures = {},
|
||||
.optimalTilingFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
.bufferFeatures = {},
|
||||
}});
|
||||
deviceRequirements.formats.push_back(FormatRequirements{.format = VK_FORMAT_D16_UNORM, // depth buffer format
|
||||
.properties = VkFormatProperties{
|
||||
.linearTilingFeatures = {},
|
||||
.optimalTilingFeatures = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
.bufferFeatures = {},
|
||||
}});
|
||||
// the surface format is found later in createSwapchain();
|
||||
|
||||
pimpl->device = createDevice(pimpl->instance.instance, deviceRequirements, pimpl->surface);
|
||||
|
||||
@ -572,6 +575,8 @@ void GFXDevice::GetViewportSize(uint32_t* w, uint32_t* h)
|
||||
|
||||
void GFXDevice::SetupImguiBackend()
|
||||
{
|
||||
// disable imgui for now
|
||||
#if 0
|
||||
ImGui_ImplVulkan_InitInfo initInfo{};
|
||||
initInfo.Instance = pimpl->instance.instance;
|
||||
initInfo.PhysicalDevice = pimpl->device.physicalDevice;
|
||||
@ -621,13 +626,23 @@ void GFXDevice::SetupImguiBackend()
|
||||
vkFreeCommandBuffers(pimpl->device.device, pimpl->graphicsCommandPool, 1, &commandBuffer);
|
||||
|
||||
ImGui_ImplVulkan_DestroyFontUploadObjects();
|
||||
#endif
|
||||
}
|
||||
|
||||
void GFXDevice::ShutdownImguiBackend() { ImGui_ImplVulkan_Shutdown(); }
|
||||
void GFXDevice::ShutdownImguiBackend()
|
||||
{
|
||||
// disable imgui for now
|
||||
#if 0
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
void GFXDevice::CmdRenderImguiDrawData(gfx::DrawBuffer* draw_buffer, ImDrawData* draw_data)
|
||||
{
|
||||
// disable imgui rendering for now
|
||||
#if 0
|
||||
ImGui_ImplVulkan_RenderDrawData(draw_data, draw_buffer->frameData.drawBuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
gfx::DrawBuffer* GFXDevice::BeginRender()
|
||||
@ -640,14 +655,15 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
|
||||
vmaSetCurrentFrameIndex(pimpl->allocator, (uint32_t)pimpl->FRAMECOUNT);
|
||||
|
||||
/* wait until the previous frame RENDERING has finished */
|
||||
// this allows for images acquired by vkAcquireNextImageKHR to be used immediately
|
||||
res = vkWaitForFences(pimpl->device.device, 1, &frameData.renderFence, VK_TRUE, 1000000000LL);
|
||||
VKCHECK(res);
|
||||
res = vkResetFences(pimpl->device.device, 1, &frameData.renderFence);
|
||||
VKCHECK(res);
|
||||
|
||||
/* perform any pending uniform buffer writes */
|
||||
VKCHECK(vkResetCommandPool(pimpl->device.device, frameData.transferPool, 0)); // TODO: possibly delete this
|
||||
|
||||
VKCHECK(vkResetCommandPool(pimpl->device.device, frameData.transferPool, 0));
|
||||
VkCommandBufferBeginInfo transferBeginInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
@ -658,28 +674,7 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
|
||||
|
||||
// transfer cmds...
|
||||
|
||||
if (pimpl->FRAMECOUNT >= FRAMES_IN_FLIGHT) { // cannot (and don't need to) do ownership transfer on first frame[s]
|
||||
// acquire ownership of buffers
|
||||
std::vector<VkBufferMemoryBarrier2> acquireBarriers{};
|
||||
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[currentFrameIndex].uniform_buffer_writes) {
|
||||
VkBufferMemoryBarrier2& barrier = acquireBarriers.emplace_back();
|
||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2;
|
||||
barrier.srcStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
|
||||
barrier.srcAccessMask = 0;
|
||||
barrier.dstStageMask = VK_PIPELINE_STAGE_2_COPY_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT;
|
||||
barrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||
barrier.dstQueueFamilyIndex = pimpl->device.queues.transferQueueFamily;
|
||||
barrier.buffer = uniformBuffer->gpuBuffers[currentFrameIndex].buffer;
|
||||
barrier.offset = 0;
|
||||
barrier.size = uniformBuffer->gpuBuffers[currentFrameIndex].size;
|
||||
}
|
||||
VkDependencyInfo dependencyInfo{};
|
||||
dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
||||
dependencyInfo.bufferMemoryBarrierCount = (uint32_t)acquireBarriers.size();
|
||||
dependencyInfo.pBufferMemoryBarriers = acquireBarriers.data();
|
||||
vkCmdPipelineBarrier2(frameData.transferBuf, &dependencyInfo);
|
||||
}
|
||||
// ownership transfer isn't needed since the data isn't accessed it's just overwritten
|
||||
|
||||
{
|
||||
// copy stagings buffers to GPU buffer
|
||||
@ -759,9 +754,9 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
|
||||
res = vkBeginCommandBuffer(frameData.drawBuf, &beginInfo);
|
||||
VKCHECK(res);
|
||||
|
||||
{ // RECORDING
|
||||
{ // RECORDING, this is executed after the uniform write semaphore is signalled
|
||||
|
||||
// acquire ownership of buffers
|
||||
// acquire ownership of uniform buffers
|
||||
std::vector<VkBufferMemoryBarrier2> acquireBarriers{};
|
||||
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[currentFrameIndex].uniform_buffer_writes) {
|
||||
VkBufferMemoryBarrier2& barrier = acquireBarriers.emplace_back();
|
||||
@ -782,6 +777,51 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
|
||||
dependencyInfo.pBufferMemoryBarriers = acquireBarriers.data();
|
||||
vkCmdPipelineBarrier2(frameData.drawBuf, &dependencyInfo);
|
||||
|
||||
VkImageMemoryBarrier2 colorImageBarrier{};
|
||||
colorImageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
||||
colorImageBarrier.pNext = nullptr;
|
||||
colorImageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
colorImageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
colorImageBarrier.srcAccessMask = 0;
|
||||
colorImageBarrier.dstAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
colorImageBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
colorImageBarrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
colorImageBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
colorImageBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
colorImageBarrier.image = pimpl->swapchain.swapchainImages[swapchainImageIndex].first;
|
||||
VkImageSubresourceRange colorImageRange{};
|
||||
colorImageRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
colorImageRange.baseMipLevel = 0;
|
||||
colorImageRange.levelCount = 1;
|
||||
colorImageRange.baseArrayLayer = 0;
|
||||
colorImageRange.layerCount = 1;
|
||||
colorImageBarrier.subresourceRange = colorImageRange;
|
||||
|
||||
VkImageMemoryBarrier2 depthImageBarrier{};
|
||||
depthImageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
||||
depthImageBarrier.pNext = nullptr;
|
||||
depthImageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
|
||||
depthImageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT;
|
||||
depthImageBarrier.srcAccessMask = 0;
|
||||
depthImageBarrier.dstAccessMask = VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
||||
depthImageBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
depthImageBarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
depthImageBarrier.image = pimpl->swapchain.depthImages[swapchainImageIndex].image;
|
||||
VkImageSubresourceRange depthImageRange{};
|
||||
depthImageRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
depthImageRange.baseMipLevel = 0;
|
||||
depthImageRange.levelCount = 1;
|
||||
depthImageRange.baseArrayLayer = 0;
|
||||
depthImageRange.layerCount = 1;
|
||||
depthImageBarrier.subresourceRange = depthImageRange;
|
||||
|
||||
std::array<VkImageMemoryBarrier2, 2> imageBarriers{colorImageBarrier, depthImageBarrier};
|
||||
VkDependencyInfo imageDependencyInfo{};
|
||||
imageDependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
||||
imageDependencyInfo.imageMemoryBarrierCount = imageBarriers.size();
|
||||
imageDependencyInfo.pImageMemoryBarriers = imageBarriers.data();
|
||||
vkCmdPipelineBarrier2(frameData.drawBuf, &imageDependencyInfo);
|
||||
|
||||
std::array<VkClearValue, 2> clearValues{}; // Using same value for all components enables
|
||||
// compression according to NVIDIA Best Practices
|
||||
clearValues[0].color.float32[0] = 1.0f;
|
||||
@ -790,16 +830,37 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
|
||||
clearValues[0].color.float32[3] = 1.0f;
|
||||
clearValues[1].depthStencil.depth = 1.0f;
|
||||
|
||||
VkRenderPassBeginInfo passBegin{};
|
||||
passBegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
passBegin.pNext = nullptr;
|
||||
passBegin.renderPass = pimpl->swapchain.renderpass;
|
||||
passBegin.framebuffer = pimpl->swapchain.framebuffers[swapchainImageIndex];
|
||||
passBegin.renderArea.extent = pimpl->swapchain.extent;
|
||||
passBegin.renderArea.offset = {0, 0};
|
||||
passBegin.clearValueCount = (uint32_t)clearValues.size();
|
||||
passBegin.pClearValues = clearValues.data();
|
||||
vkCmdBeginRenderPass(frameData.drawBuf, &passBegin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
VkRenderingAttachmentInfo colorAttachment{};
|
||||
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
||||
colorAttachment.pNext = nullptr;
|
||||
colorAttachment.imageView = pimpl->swapchain.swapchainImages[swapchainImageIndex].second;
|
||||
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
colorAttachment.resolveMode = VK_RESOLVE_MODE_NONE;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
colorAttachment.clearValue = clearValues[0];
|
||||
VkRenderingAttachmentInfo depthAttachment{};
|
||||
depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
|
||||
depthAttachment.pNext = nullptr;
|
||||
depthAttachment.imageView = pimpl->swapchain.depthImages[swapchainImageIndex].view;
|
||||
depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
depthAttachment.resolveMode = VK_RESOLVE_MODE_NONE;
|
||||
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
depthAttachment.clearValue = clearValues[1];
|
||||
|
||||
VkRenderingInfo renderingInfo{};
|
||||
renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
|
||||
renderingInfo.pNext = nullptr;
|
||||
renderingInfo.flags = 0;
|
||||
renderingInfo.renderArea = VkRect2D{VkOffset2D{0, 0}, VkExtent2D{pimpl->swapchain.extent.width, pimpl->swapchain.extent.height}};
|
||||
renderingInfo.layerCount = 1;
|
||||
renderingInfo.viewMask = 0;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachments = &colorAttachment;
|
||||
renderingInfo.pDepthAttachment = &depthAttachment;
|
||||
renderingInfo.pStencilAttachment = nullptr;
|
||||
vkCmdBeginRendering(frameData.drawBuf, &renderingInfo);
|
||||
|
||||
VkViewport viewport{};
|
||||
if (flip_viewport) {
|
||||
@ -824,6 +885,9 @@ gfx::DrawBuffer* GFXDevice::BeginRender()
|
||||
vkCmdSetScissor(frameData.drawBuf, 0, 1, &scissor);
|
||||
}
|
||||
|
||||
// clear write queue
|
||||
pimpl->write_queues[currentFrameIndex].uniform_buffer_writes.clear();
|
||||
|
||||
// hand command buffer over to caller
|
||||
gfx::DrawBuffer* drawBuffer = new gfx::DrawBuffer;
|
||||
drawBuffer->frameData = frameData;
|
||||
@ -839,8 +903,9 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
|
||||
uint32_t swapchainImageIndex = drawBuffer->imageIndex;
|
||||
VkResult res;
|
||||
|
||||
vkCmdEndRenderPass(drawBuffer->frameData.drawBuf);
|
||||
vkCmdEndRendering(drawBuffer->frameData.drawBuf);
|
||||
|
||||
#if 0
|
||||
// transfer ownership of uniform buffers back to transfer queue
|
||||
std::vector<VkBufferMemoryBarrier2> releaseBarriers{};
|
||||
for (gfx::UniformBuffer* uniformBuffer : pimpl->write_queues[drawBuffer->currentFrameIndex].uniform_buffer_writes) {
|
||||
@ -861,6 +926,35 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
|
||||
dependencyInfo.bufferMemoryBarrierCount = (uint32_t)releaseBarriers.size();
|
||||
dependencyInfo.pBufferMemoryBarriers = releaseBarriers.data();
|
||||
vkCmdPipelineBarrier2(drawBuffer->frameData.drawBuf, &dependencyInfo);
|
||||
#endif
|
||||
|
||||
// Make color attachment presentable.
|
||||
// The present and draw queues are part of the same family so no ownership transfer needed
|
||||
VkImageMemoryBarrier2 colorImageBarrier{};
|
||||
colorImageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2;
|
||||
colorImageBarrier.pNext = nullptr;
|
||||
colorImageBarrier.srcStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
colorImageBarrier.dstStageMask = VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT; // semaphore takes care of this
|
||||
colorImageBarrier.srcAccessMask = VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
colorImageBarrier.dstAccessMask = 0;
|
||||
colorImageBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
colorImageBarrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
colorImageBarrier.srcQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||
colorImageBarrier.dstQueueFamilyIndex = pimpl->device.queues.presentAndDrawQueueFamily;
|
||||
colorImageBarrier.image = pimpl->swapchain.swapchainImages[swapchainImageIndex].first;
|
||||
VkImageSubresourceRange colorImageRange{};
|
||||
colorImageRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
colorImageRange.baseMipLevel = 0;
|
||||
colorImageRange.levelCount = 1;
|
||||
colorImageRange.baseArrayLayer = 0;
|
||||
colorImageRange.layerCount = 1;
|
||||
colorImageBarrier.subresourceRange = colorImageRange;
|
||||
|
||||
VkDependencyInfo imageDependencyInfo{};
|
||||
imageDependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
|
||||
imageDependencyInfo.imageMemoryBarrierCount = 1;
|
||||
imageDependencyInfo.pImageMemoryBarriers = &colorImageBarrier;
|
||||
vkCmdPipelineBarrier2(drawBuffer->frameData.drawBuf, &imageDependencyInfo);
|
||||
|
||||
res = vkEndCommandBuffer(drawBuffer->frameData.drawBuf);
|
||||
VKCHECK(res);
|
||||
@ -870,9 +964,9 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
|
||||
std::vector<VkSemaphore> waitSemaphores{};
|
||||
std::vector<VkPipelineStageFlags> waitDstStageMasks{};
|
||||
|
||||
waitSemaphores.push_back(drawBuffer->frameData.presentSemaphore);
|
||||
waitSemaphores.push_back(drawBuffer->frameData.presentSemaphore); // wait for image from 2nd last frame to be presented so it can be rendered to again
|
||||
waitDstStageMasks.push_back(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
waitSemaphores.push_back(drawBuffer->frameData.transferSemaphore);
|
||||
waitSemaphores.push_back(drawBuffer->frameData.transferSemaphore); // wait for uniform buffer copies to complete
|
||||
waitDstStageMasks.push_back(VK_PIPELINE_STAGE_VERTEX_SHADER_BIT);
|
||||
|
||||
VkSubmitInfo submitInfo{
|
||||
@ -907,9 +1001,6 @@ void GFXDevice::FinishRender(gfx::DrawBuffer* drawBuffer)
|
||||
else if (res != VK_SUCCESS)
|
||||
throw std::runtime_error("Failed to queue present! Code: " + std::to_string(res));
|
||||
|
||||
// clear write queue
|
||||
pimpl->write_queues[drawBuffer->currentFrameIndex].uniform_buffer_writes.clear();
|
||||
|
||||
pimpl->FRAMECOUNT++;
|
||||
|
||||
delete drawBuffer;
|
||||
@ -1162,11 +1253,19 @@ gfx::Pipeline* GFXDevice::CreatePipeline(const gfx::PipelineInfo& info)
|
||||
createInfo.pColorBlendState = &colorBlending;
|
||||
createInfo.pDynamicState = &dynamicState;
|
||||
createInfo.layout = pipeline->layout;
|
||||
createInfo.renderPass = pimpl->swapchain.renderpass;
|
||||
createInfo.renderPass = VK_NULL_HANDLE;
|
||||
createInfo.subpass = 0;
|
||||
createInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||
createInfo.basePipelineIndex = -1;
|
||||
|
||||
VkPipelineRenderingCreateInfo renderingInfo{};
|
||||
renderingInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
|
||||
renderingInfo.colorAttachmentCount = 1;
|
||||
renderingInfo.pColorAttachmentFormats = &pimpl->swapchain.surfaceFormat.format;
|
||||
renderingInfo.depthAttachmentFormat = pimpl->swapchain.depthStencilFormat;
|
||||
|
||||
createInfo.pNext = &renderingInfo;
|
||||
|
||||
res = vkCreateGraphicsPipelines(pimpl->device.device, VK_NULL_HANDLE, 1, &createInfo, nullptr, &pipeline->handle);
|
||||
assert(res == VK_SUCCESS);
|
||||
|
||||
|
@ -250,10 +250,10 @@ void Renderer::PreRender(bool window_is_resized, glm::mat4 camera_transform)
|
||||
device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
|
||||
|
||||
// override with light matrix
|
||||
frame_uniform.uniform_buffer_data.data = glm::mat4{1.0f};
|
||||
device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
|
||||
global_uniform.uniform_buffer_data.data.proj = global_uniform.uniform_buffer_data.data.lightSpaceMatrix;
|
||||
device_->WriteUniformBuffer(global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
|
||||
//frame_uniform.uniform_buffer_data.data = glm::mat4{1.0f};
|
||||
//device_->WriteUniformBuffer(frame_uniform.uniform_buffer, 0, sizeof(frame_uniform.uniform_buffer_data), &frame_uniform.uniform_buffer_data);
|
||||
//global_uniform.uniform_buffer_data.data.proj = global_uniform.uniform_buffer_data.data.lightSpaceMatrix;
|
||||
//device_->WriteUniformBuffer(global_uniform.uniform_buffer, 0, sizeof(global_uniform.uniform_buffer_data), &global_uniform.uniform_buffer_data);
|
||||
}
|
||||
|
||||
void Renderer::Render(const RenderList* static_list, const RenderList* dynamic_list, const std::vector<Line>& debug_lines)
|
||||
|
@ -75,8 +75,11 @@ Device createDevice(VkInstance instance, const DeviceRequirements& requirements,
|
||||
}
|
||||
|
||||
/* check features */
|
||||
VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures{};
|
||||
dynamicRenderingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES;
|
||||
VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeatures{};
|
||||
memoryPriorityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT;
|
||||
memoryPriorityFeatures.pNext = &dynamicRenderingFeatures;
|
||||
VkPhysicalDeviceSynchronization2Features synchronization2Features{};
|
||||
synchronization2Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES;
|
||||
synchronization2Features.pNext = &memoryPriorityFeatures;
|
||||
@ -199,6 +202,9 @@ Device createDevice(VkInstance instance, const DeviceRequirements& requirements,
|
||||
/* ensure synchronization 2 is found */
|
||||
if (synchronization2Features.synchronization2 == VK_FALSE) continue;
|
||||
|
||||
/* ensure dynamic_rendering is found */
|
||||
if (dynamicRenderingFeatures.dynamicRendering == VK_FALSE) continue;
|
||||
|
||||
/* check the memory priority extension was even requested */
|
||||
bool memoryPriorityRequired = false;
|
||||
for (const char* ext : requirements.requiredExtensions) {
|
||||
@ -341,8 +347,12 @@ Device createDevice(VkInstance instance, const DeviceRequirements& requirements,
|
||||
}
|
||||
|
||||
/* set enabled features */
|
||||
VkPhysicalDeviceDynamicRenderingFeatures dynamicRenderingFeatures{};
|
||||
dynamicRenderingFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES;
|
||||
dynamicRenderingFeatures.dynamicRendering = VK_TRUE;
|
||||
VkPhysicalDeviceMemoryPriorityFeaturesEXT memoryPriorityFeatures{};
|
||||
memoryPriorityFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT;
|
||||
memoryPriorityFeatures.pNext = &dynamicRenderingFeatures;
|
||||
memoryPriorityFeatures.memoryPriority = d.memoryPriorityFeature ? VK_TRUE : VK_FALSE;
|
||||
VkPhysicalDeviceSynchronization2Features synchronization2Features{};
|
||||
synchronization2Features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES;
|
||||
@ -391,6 +401,7 @@ Device createDevice(VkInstance instance, const DeviceRequirements& requirements,
|
||||
d.enabledExtensions.emplace_back(ext);
|
||||
}
|
||||
|
||||
// wtf is going on here??
|
||||
if (transferFamily != graphicsFamily) {
|
||||
vkGetDeviceQueue(d.device, graphicsFamily, 0, &d.queues.presentQueue);
|
||||
if (queueFamilies[graphicsFamily].queueCount >= 2) {
|
||||
|
@ -149,89 +149,6 @@ namespace engine {
|
||||
vkDestroySwapchainKHR(info.device, scInfo.oldSwapchain, nullptr);
|
||||
}
|
||||
|
||||
/* create the render pass */
|
||||
if (sc->renderpass != VK_NULL_HANDLE) {
|
||||
vkDestroyRenderPass(sc->device, sc->renderpass, nullptr);
|
||||
}
|
||||
VkAttachmentDescription colorAttachment{
|
||||
.flags = 0,
|
||||
.format = sc->surfaceFormat.format,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, // ignored
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // ignored
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
|
||||
};
|
||||
VkAttachmentDescription depthStencilAttachment{
|
||||
.flags = 0,
|
||||
.format = sc->depthStencilFormat,
|
||||
.samples = VK_SAMPLE_COUNT_1_BIT,
|
||||
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // the depth buffer is not used after the fragment shader
|
||||
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, // ignored
|
||||
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, // ignored
|
||||
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
std::array<VkAttachmentDescription, 2> attachments { colorAttachment, depthStencilAttachment };
|
||||
VkAttachmentReference colorAttachmentRef{
|
||||
.attachment = 0,
|
||||
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
VkAttachmentReference depthStencilAttachmentRef{
|
||||
.attachment = 1,
|
||||
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
|
||||
};
|
||||
VkSubpassDescription subpass{
|
||||
.flags = 0,
|
||||
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
|
||||
.inputAttachmentCount = 0,
|
||||
.pInputAttachments = nullptr,
|
||||
.colorAttachmentCount = 1,
|
||||
.pColorAttachments = &colorAttachmentRef,
|
||||
.pResolveAttachments = nullptr,
|
||||
.pDepthStencilAttachment = &depthStencilAttachmentRef,
|
||||
.preserveAttachmentCount = 0,
|
||||
.pPreserveAttachments = nullptr,
|
||||
};
|
||||
VkSubpassDependency attachmentDependencies[2] = {
|
||||
{
|
||||
// Depth buffer
|
||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
||||
.dstSubpass = 0,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_NONE,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dependencyFlags = 0,
|
||||
},
|
||||
{
|
||||
// Image Layout Transition
|
||||
.srcSubpass = VK_SUBPASS_EXTERNAL,
|
||||
.dstSubpass = 0,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
.srcAccessMask = 0,
|
||||
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
|
||||
.dependencyFlags = 0,
|
||||
},
|
||||
};
|
||||
VkRenderPassCreateInfo renderPassInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.attachmentCount = (uint32_t)attachments.size(),
|
||||
.pAttachments = attachments.data(),
|
||||
.subpassCount = 1,
|
||||
.pSubpasses = &subpass,
|
||||
.dependencyCount = 2,
|
||||
.pDependencies = attachmentDependencies,
|
||||
};
|
||||
res = vkCreateRenderPass(sc->device, &renderPassInfo, nullptr, &sc->renderpass);
|
||||
if (res != EXIT_SUCCESS) throw std::runtime_error("Failed to create renderpass!");
|
||||
|
||||
// get all the image handles
|
||||
uint32_t swapchainImageCount = 0;
|
||||
res = vkGetSwapchainImagesKHR(info.device, sc->swapchain, &swapchainImageCount, nullptr);
|
||||
@ -240,23 +157,20 @@ namespace engine {
|
||||
res = vkGetSwapchainImagesKHR(info.device, sc->swapchain, &swapchainImageCount, swapchainImages.data());
|
||||
assert(res == VK_SUCCESS);
|
||||
|
||||
/* create image view and framebuffer for each image */
|
||||
/* create image view for each image */
|
||||
if (sc->swapchainImages.size() == 0) {
|
||||
sc->swapchainImages.resize(swapchainImageCount);
|
||||
sc->depthImages.resize(swapchainImageCount);
|
||||
sc->framebuffers.resize(swapchainImageCount);
|
||||
}
|
||||
for (uint32_t i = 0; i < swapchainImageCount; i++) {
|
||||
auto& [swapchainImage, swapchainImageView] = sc->swapchainImages.at(i);
|
||||
auto& [depthImage, depthAllocation, depthImageView] = sc->depthImages.at(i);
|
||||
auto& framebuffer = sc->framebuffers.at(i);
|
||||
|
||||
if (swapchainImageView != VK_NULL_HANDLE) vkDestroyImageView(sc->device, swapchainImageView, nullptr);
|
||||
if (depthImageView != VK_NULL_HANDLE) {
|
||||
vkDestroyImageView(sc->device, depthImageView, nullptr);
|
||||
vmaDestroyImage(sc->allocator, depthImage, depthAllocation);
|
||||
}
|
||||
if (framebuffer != VK_NULL_HANDLE) vkDestroyFramebuffer(sc->device, framebuffer, nullptr);
|
||||
|
||||
swapchainImage = swapchainImages[i];
|
||||
|
||||
@ -333,33 +247,12 @@ namespace engine {
|
||||
res = vkCreateImageView(info.device, &depthViewInfo, nullptr, &depthImageView);
|
||||
assert(res == VK_SUCCESS);
|
||||
|
||||
std::array<VkImageView, 2> attachments {
|
||||
swapchainImageView, depthImageView
|
||||
};
|
||||
|
||||
VkFramebufferCreateInfo fbInfo{};
|
||||
fbInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
fbInfo.pNext = nullptr;
|
||||
fbInfo.flags = 0;
|
||||
fbInfo.renderPass = sc->renderpass;
|
||||
fbInfo.attachmentCount = (uint32_t)attachments.size();
|
||||
fbInfo.pAttachments = attachments.data();
|
||||
fbInfo.width = sc->extent.width;
|
||||
fbInfo.height = sc->extent.height;
|
||||
fbInfo.layers = 1;
|
||||
|
||||
res = vkCreateFramebuffer(sc->device, &fbInfo, nullptr, &framebuffer);
|
||||
if (res != VK_SUCCESS) throw std::runtime_error("Failed to create framebuffer for swapchain image!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void destroySwapchain(const Swapchain& sc)
|
||||
{
|
||||
for (VkFramebuffer framebuffer : sc.framebuffers) {
|
||||
vkDestroyFramebuffer(sc.device, framebuffer, nullptr);
|
||||
}
|
||||
for (const auto& [image, view] : sc.swapchainImages) {
|
||||
vkDestroyImageView(sc.device, view, nullptr);
|
||||
}
|
||||
@ -367,8 +260,6 @@ namespace engine {
|
||||
vkDestroyImageView(sc.device, view, nullptr);
|
||||
vmaDestroyImage(sc.allocator, image, allocation);
|
||||
}
|
||||
|
||||
vkDestroyRenderPass(sc.device, sc.renderpass, nullptr);
|
||||
vkDestroySwapchainKHR(sc.device, sc.swapchain, nullptr);
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,11 @@ namespace engine {
|
||||
VkSurfaceCapabilitiesKHR surfaceCapabilities{};
|
||||
VkPresentModeKHR presentMode{};
|
||||
VkExtent2D extent{};
|
||||
VkRenderPass renderpass = VK_NULL_HANDLE;
|
||||
//VkRenderPass renderpass = VK_NULL_HANDLE;
|
||||
VkFormat depthStencilFormat;
|
||||
std::vector<std::pair<VkImage, VkImageView>> swapchainImages{};
|
||||
std::vector<DepthStencil> depthImages{};
|
||||
std::vector<VkFramebuffer> framebuffers{};
|
||||
//std::vector<VkFramebuffer> framebuffers{};
|
||||
};
|
||||
|
||||
struct SwapchainInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user