bake files

This commit is contained in:
ouczbs 2024-12-30 17:18:21 +08:00
parent 26a1d91319
commit 53e206e7c2
15 changed files with 95 additions and 21 deletions

View File

@ -10,6 +10,7 @@ namespace api {
int32_t id; int32_t id;
uint32_t tick; uint32_t tick;
}; };
FrameGraphNodePtr mCurrentNode;
uint32_t mTickStamp{1}; uint32_t mTickStamp{1};
uint32_t mSurfaceID{0}; uint32_t mSurfaceID{0};
table<TextureSampler, void*> mTextureSamplerPool; table<TextureSampler, void*> mTextureSamplerPool;
@ -28,6 +29,7 @@ namespace api {
TextureDesc& GetEditorSurface() { return ResolveTexture(mEditorSurfaceID); } TextureDesc& GetEditorSurface() { return ResolveTexture(mEditorSurfaceID); }
#endif // #endif //
public: public:
FrameGraphNodePtr GetCurrentNode() { return mCurrentNode; };
template<typename T> template<typename T>
FrameGraphNodePtr AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); } FrameGraphNodePtr AddRenderPass() { return AddRenderPass(&T::Setup, &T::Execute); }
FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor); FrameGraphNodePtr AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor);

View File

@ -73,6 +73,8 @@ namespace api{
bool IsOutput() { return any(flag & RenderPassNodeFlag::Output); } bool IsOutput() { return any(flag & RenderPassNodeFlag::Output); }
bool IsFirstInput() { return any(flag & RenderPassNodeFlag::FirstInput); } bool IsFirstInput() { return any(flag & RenderPassNodeFlag::FirstInput); }
bool IsLastOutput() { return any(flag & RenderPassNodeFlag::LastOutput); } bool IsLastOutput() { return any(flag & RenderPassNodeFlag::LastOutput); }
bool IsWaitTransfer() { return any(flag & RenderPassNodeFlag::WaitTransfer); }
void SetWaitTransfer() { flag |= RenderPassNodeFlag::WaitTransfer; }
FrameGraphEdgePtr GetInput(int i) { return inEdges[i]; }; FrameGraphEdgePtr GetInput(int i) { return inEdges[i]; };
FrameGraphEdgePtr GetOutput(int i) { return outEdges[i]; }; FrameGraphEdgePtr GetOutput(int i) { return outEdges[i]; };
FrameGraphEdgePtr FindInput(Name name) FrameGraphEdgePtr FindInput(Name name)

View File

@ -32,6 +32,7 @@ namespace api {
Output = 0x01, Output = 0x01,
FirstInput = 0x02, FirstInput = 0x02,
LastOutput = 0x04, LastOutput = 0x04,
WaitTransfer = 0x08,
}; };
enum class BufferUsage : uint8_t { enum class BufferUsage : uint8_t {
None = 0, None = 0,

View File

@ -127,6 +127,7 @@ namespace api {
void FrameGraph::Execute(FRenderView& view) void FrameGraph::Execute(FRenderView& view)
{ {
for (auto& node : mNodes) { for (auto& node : mNodes) {
mCurrentNode = node;
switch (node.type) { switch (node.type) {
case RenderPassType::Render: case RenderPassType::Render:
ExecuteRenderPass(node.node, view); ExecuteRenderPass(node.node, view);

View File

@ -7,6 +7,7 @@ namespace api{
RenderAPI* mApi; RenderAPI* mApi;
UIRenderSystem* mRenderSystem; UIRenderSystem* mRenderSystem;
Noesis::DeviceCaps mCaps; Noesis::DeviceCaps mCaps;
std::vector<TextureBarrier> mTextureBarriers;
bool mStereoSupport; bool mStereoSupport;
SINGLETON_IMPL(UIRenderDevice) SINGLETON_IMPL(UIRenderDevice)
public: public:

View File

@ -84,6 +84,7 @@ namespace api {
UITexture* uiTex = (UITexture*)texture; UITexture* uiTex = (UITexture*)texture;
TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .mipLevel = level, .data = data}; TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .mipLevel = level, .data = data};
Context().UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST); Context().UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST);
mTextureBarriers.push_back(uiTex->desc.ToBarrier(ResourceState::TRANSFER_DST, ResourceState::READ_ONLY));
} }
void UIRenderDevice::BeginOffscreenRender() void UIRenderDevice::BeginOffscreenRender()
{ {
@ -94,9 +95,12 @@ namespace api {
} }
void UIRenderDevice::EndOffscreenRender() void UIRenderDevice::EndOffscreenRender()
{ {
int b = 10000; if (!mTextureBarriers.empty()) {
for (int a = 1; a < b; a++) { ResourceBarrierDesc desc{};
b--; desc.textureBarriersCount = mTextureBarriers.size();
desc.pTextureBarriers = mTextureBarriers.data();
Context().ExecuteResourceBarriers(desc);
mTextureBarriers.clear();
} }
} }
void UIRenderDevice::BeginOnscreenRender() void UIRenderDevice::BeginOnscreenRender()
@ -156,6 +160,7 @@ namespace api {
} }
void UIRenderDevice::DrawBatch(const Noesis::Batch& batch) void UIRenderDevice::DrawBatch(const Noesis::Batch& batch)
{ {
EndOffscreenRender();
mRenderSystem->DrawBatch(batch); mRenderSystem->DrawBatch(batch);
} }
} }

View File

@ -3,7 +3,7 @@
#include "asset/res/guid.h" #include "asset/res/guid.h"
#include "backend.h" #include "backend.h"
#ifdef API_DEBUG #ifdef API_DEBUG
#define gLogSemaphore(...) //zlog::info(__VA_ARGS__) #define gLogSemaphore(...) zlog::error(__VA_ARGS__)
#else #else
#define gLogSemaphore(...) #define gLogSemaphore(...)
#endif #endif

View File

@ -6,9 +6,12 @@ namespace vkn {
using api::RenderPassState; using api::RenderPassState;
struct VulkanContext : public api::RenderContext { struct VulkanContext : public api::RenderContext {
VkFence surfaceFence; VkFence surfaceFence;
VkFence transferFence;
uint8_t waitFenceNums[8]{ 2,2,2,2,2,2,2,2 };//最多不能超过8个
VkSemaphore surfaceSemaphore; VkSemaphore surfaceSemaphore;
VkSemaphore presentSemaphore; VkSemaphore presentSemaphore;
VkSemaphore graphSemaphore; VkSemaphore graphSemaphore;
VkSemaphore transferSemaphore;
VkCommandBuffer transferCommand; VkCommandBuffer transferCommand;
VkCommandBuffer surfaceCommand; VkCommandBuffer surfaceCommand;
VkCommandBuffer command; VkCommandBuffer command;

View File

@ -23,6 +23,7 @@ namespace vkn {
class VulkanUISystem : public api::UIRenderSystem { class VulkanUISystem : public api::UIRenderSystem {
private: private:
Device* mDevice; Device* mDevice;
uint8_t mWaitTransferCount;
bool mIsLinearRendering; bool mIsLinearRendering;
bool mHasExtendedDynamicState; bool mHasExtendedDynamicState;
uint32_t mLastTextureHashValue{1}; uint32_t mLastTextureHashValue{1};

View File

@ -460,6 +460,12 @@ namespace vkn {
waitSemaphores[semaphoreCount++] = ctx.surfaceSemaphore; waitSemaphores[semaphoreCount++] = ctx.surfaceSemaphore;
gLogSemaphore("-----wait {:#x}", (uintptr_t)ctx.surfaceSemaphore); gLogSemaphore("-----wait {:#x}", (uintptr_t)ctx.surfaceSemaphore);
} }
if (node->IsWaitTransfer()) {
ctx.FlushCommand();
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_TRANSFER_BIT;
waitSemaphores[semaphoreCount++] = ctx.transferSemaphore;
gLogSemaphore("-----wait {:#x}", (uintptr_t)ctx.transferSemaphore);
}
for (auto& it : node->dependencies) { for (auto& it : node->dependencies) {
RenderPassInfo* inputInfo = GetRenderPassInfo(it->name ,it->hash); RenderPassInfo* inputInfo = GetRenderPassInfo(it->name ,it->hash);
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;

View File

@ -50,7 +50,7 @@ namespace vkn {
VkImageMemoryBarrier vkApiGetTextureTransition(VkPipelineStageFlags& mSrcStage, VkPipelineStageFlags& mDstStage, const TextureBarrier& barrier) { VkImageMemoryBarrier vkApiGetTextureTransition(VkPipelineStageFlags& mSrcStage, VkPipelineStageFlags& mDstStage, const TextureBarrier& barrier) {
VkAccessFlags srcAccessMask, dstAccessMask; VkAccessFlags srcAccessMask, dstAccessMask;
VkPipelineStageFlags srcStage, dstStage; VkPipelineStageFlags srcStage, dstStage;
VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
switch (barrier.mSrcState) { switch (barrier.mSrcState) {
case ResourceState::UNDEFINED: case ResourceState::UNDEFINED:
srcAccessMask = 0; srcAccessMask = 0;
@ -115,12 +115,14 @@ namespace vkn {
dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; dstStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
break; break;
case ResourceState::DEPTH_SAMPLER: case ResourceState::DEPTH_SAMPLER:
dstAccessMask = dstAccessMask =
VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | dstStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
break; break;
case ResourceState::PRESENT: case ResourceState::PRESENT:
case ResourceState::UNDEFINED: case ResourceState::UNDEFINED:
@ -131,7 +133,7 @@ namespace vkn {
mSrcStage |= srcStage; mSrcStage |= srcStage;
mDstStage |= dstStage; mDstStage |= dstStage;
VkImageSubresourceRange subresources{ VkImageSubresourceRange subresources{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .aspectMask = aspectMask,
.baseMipLevel = 0, .baseMipLevel = 0,
.levelCount = 1, .levelCount = 1,
.baseArrayLayer = 0, .baseArrayLayer = 0,

View File

@ -104,14 +104,21 @@ namespace vkn {
} }
void VulkanContext::FlushCommand() void VulkanContext::FlushCommand()
{ {
if (waitFenceNums[frame])
return;
waitFenceNums[frame] = 1;
if (transferCommand) { if (transferCommand) {
vkEndCommandBuffer(transferCommand); vkEndCommandBuffer(transferCommand);
VkSubmitInfo submitInfo{}; VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &transferCommand; submitInfo.pCommandBuffers = &transferCommand;
vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, nullptr); submitInfo.pSignalSemaphores = &transferSemaphore;
submitInfo.signalSemaphoreCount = 1;
gLogSemaphore("+++++sign {:#x}", (uintptr_t)transferSemaphore);
vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, transferFence);
transferCommand = nullptr; transferCommand = nullptr;
waitFenceNums[frame] = 2;
} }
} }
VkCommandBuffer VulkanContext::GetTransferCommand() VkCommandBuffer VulkanContext::GetTransferCommand()
@ -150,6 +157,7 @@ namespace vkn {
{ {
auto& barrier = desc.pTextureBarriers[i]; auto& barrier = desc.pTextureBarriers[i];
auto desc = vkApiGetTextureTransition(srcStageMask, dstStageMask, barrier); auto desc = vkApiGetTextureTransition(srcStageMask, dstStageMask, barrier);
zlog::info("textureBarrier::{:#x} {} {}::{}", (uintptr_t)barrier.mTexture.image,(uint8_t)renderPassState,(uint8_t)barrier.mSrcState, (uint8_t)barrier.mDstState);
imageBarriers.push_back(desc); imageBarriers.push_back(desc);
} }
if (dstStageMask == 0) { if (dstStageMask == 0) {

View File

@ -51,6 +51,16 @@ namespace vkn {
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; colorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentDescription stencilAttachment = {};
stencilAttachment.format = VK_FORMAT_S8_UINT;
stencilAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
stencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
stencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
stencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
stencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
stencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
stencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference colorAttachmentRef = {}; VkAttachmentReference colorAttachmentRef = {};
colorAttachmentRef.attachment = 0; colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@ -63,15 +73,17 @@ namespace vkn {
VkSubpassDependency dependency = {}; VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0; dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
VkAttachmentDescription attachmentList[2] = { colorAttachment , stencilAttachment };
VkRenderPassCreateInfo info = {}; VkRenderPassCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
info.attachmentCount = 1; info.attachmentCount = 2;
info.pAttachments = &colorAttachment; info.pAttachments = attachmentList;
info.subpassCount = 1; info.subpassCount = 1;
info.pSubpasses = &subpass; info.pSubpasses = &subpass;
info.dependencyCount = 1; info.dependencyCount = 1;
@ -136,15 +148,26 @@ namespace vkn {
} }
void VulkanImguiEditor::Setup(FrameGraph& graph, RenderPassBuilder& builder) void VulkanImguiEditor::Setup(FrameGraph& graph, RenderPassBuilder& builder)
{ {
TextureDesc stencil = graph.GetRenderSurface();
stencil.id = 0;
stencil.format = TinyImageFormat_S8_UINT;
stencil.image = nullptr;
stencil.usage = TextureUsage::STENCIL_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT;
graph.AcquireTexture(stencil);
builder.Name(ImguiPassName) builder.Name(ImguiPassName)
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output) .Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
.Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT); .Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT)
.Write(stencil, ResourceState::DEPTH_ATTACHMENT);
if (gEngineConfig.IsRenderEditorSurface) { if (gEngineConfig.IsRenderEditorSurface) {
builder.Read(graph.GetSurface(), ResourceState::READ_ONLY); builder.Read(graph.GetSurface(), ResourceState::READ_ONLY);
} }
} }
void VulkanImguiEditor::Execute(FrameGraph& graph, RenderPassContext& context) void VulkanImguiEditor::Execute(FrameGraph& graph, RenderPassContext& context)
{ {
auto& surface = graph.GetRenderSurface();
context->SetViewport(0.0f, 0.0f, (float)surface.width, (float)surface.height, 0.f, 1.f);
context->SetScissor(0, 0, surface.width, surface.height);
graph.GetRenderSurface().state = ResourceState::PRESENT; graph.GetRenderSurface().state = ResourceState::PRESENT;
ImGui_ImplVulkan_NewFrame(); ImGui_ImplVulkan_NewFrame();
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL2_NewFrame();

View File

@ -10,13 +10,15 @@ namespace vkn {
void VulkanUISystem::InitNoesisRender(bool linearRendering, bool stereoSupport, SampleCount sampleCount_) void VulkanUISystem::InitNoesisRender(bool linearRendering, bool stereoSupport, SampleCount sampleCount_)
{ {
mDevice = &VulkanAPI::Ptr()->GetBackend().GetDevice(); mDevice = &VulkanAPI::Ptr()->GetBackend().GetDevice();
auto info = VulkanAPI::Ptr()->GetRenderPassInfo("ImguiPass", 0);
mRenderPass = info->pass;
mHasExtendedDynamicState = false; mHasExtendedDynamicState = false;
mIsLinearRendering = linearRendering; mIsLinearRendering = linearRendering;
VkPhysicalDeviceProperties mDeviceProperties; VkPhysicalDeviceProperties mDeviceProperties;
vkGetPhysicalDeviceProperties(mDevice->GetPhysical(), &mDeviceProperties); vkGetPhysicalDeviceProperties(mDevice->GetPhysical(), &mDeviceProperties);
mMinUniformBufferOffsetAlignment = mDeviceProperties.limits.minUniformBufferOffsetAlignment; mMinUniformBufferOffsetAlignment = mDeviceProperties.limits.minUniformBufferOffsetAlignment;
VkSampleCountFlagBits sampleCount = vkApiGetSmpleCountFlag(sampleCount_); VkSampleCountFlagBits sampleCount = vkApiGetSmpleCountFlag(sampleCount_);
CreateRenderPass(sampleCount); //CreateRenderPass(sampleCount);
CreateLayouts(); CreateLayouts();
LoadShaders(stereoSupport); LoadShaders(stereoSupport);
CreatePipelines(sampleCount); CreatePipelines(sampleCount);
@ -28,6 +30,7 @@ namespace vkn {
mCommandBuffer = ctx->command; mCommandBuffer = ctx->command;
mFrameNumber = ctx->frameNumber; mFrameNumber = ctx->frameNumber;
mSafeFrameNumber = ctx->frameNumber - ctx->frameCount; mSafeFrameNumber = ctx->frameNumber - ctx->frameCount;
mWaitTransferCount = 0;
} }
void VulkanUISystem::DrawBatch(const Noesis::Batch& batch) void VulkanUISystem::DrawBatch(const Noesis::Batch& batch)
{ {
@ -56,6 +59,10 @@ namespace vkn {
{ {
vkCmdDrawIndexed(mCommandBuffer, batch.numIndices, 1, firstIndex, 0, 0); vkCmdDrawIndexed(mCommandBuffer, batch.numIndices, 1, firstIndex, 0, 0);
} }
if (mWaitTransferCount == 1) {
mWaitTransferCount += 100;
VulkanAPI::Ptr()->graph.GetCurrentNode()->SetWaitTransfer();
}
} }
void VulkanUISystem::SetBuffers(const Noesis::Batch& batch) void VulkanUISystem::SetBuffers(const Noesis::Batch& batch)
{ {
@ -192,6 +199,9 @@ namespace vkn {
} }
void VulkanUISystem::FillImageInfo(UITexture* texture, uint8_t sampler, VkDescriptorSet set, BaseVector<VkDescriptorImageInfo>& images, BaseVector<VkWriteDescriptorSet>& writes, uint32_t& binding) void VulkanUISystem::FillImageInfo(UITexture* texture, uint8_t sampler, VkDescriptorSet set, BaseVector<VkDescriptorImageInfo>& images, BaseVector<VkWriteDescriptorSet>& writes, uint32_t& binding)
{ {
if (texture->desc.state != ResourceState::READ_ONLY) {
mWaitTransferCount++;
}
VkDescriptorImageInfo& info = images.EmplaceBack(); VkDescriptorImageInfo& info = images.EmplaceBack();
info.sampler = mSamplers[sampler]; info.sampler = mSamplers[sampler];
info.imageView = (VkImageView)texture->imageView; info.imageView = (VkImageView)texture->imageView;

View File

@ -59,15 +59,16 @@ namespace vkn {
zlog::error("Failed to create swap chain."); zlog::error("Failed to create swap chain.");
} }
mFrames = args.framesInFlight; mFrames = args.framesInFlight;
uint32_t flightFrames = args.framesInFlight * 2;
pmr::vector<VkImage> swapchain_images{ FramePool() }; pmr::vector<VkImage> swapchain_images{ FramePool() };
uint32_t imageCount = 0; uint32_t imageCount = 0;
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, nullptr); vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, nullptr);
swapchain_images.resize(imageCount); swapchain_images.resize(imageCount);
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data()); vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data());
mFences.reserve(mFrames); mFences.reserve(flightFrames);
mSurfaces.reserve(imageCount); mSurfaces.reserve(imageCount);
mCommands.reserve(mFrames + mFrames); mCommands.reserve(flightFrames);
mSemaphores.reserve(mFrames + mFrames); mSemaphores.reserve(flightFrames + mFrames);
TextureDesc desc{}; TextureDesc desc{};
desc.width = args.width; desc.width = args.width;
desc.height = args.height; desc.height = args.height;
@ -83,9 +84,11 @@ namespace vkn {
mSurfaces.push_back(desc); mSurfaces.push_back(desc);
mSemaphores.push_back(mDevice.CreateSemaphore()); mSemaphores.push_back(mDevice.CreateSemaphore());
mSemaphores.push_back(mDevice.CreateSemaphore()); mSemaphores.push_back(mDevice.CreateSemaphore());
mSemaphores.push_back(mDevice.CreateSemaphore());
mCommands.push_back(Backend::RenderWorker->AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY)); mCommands.push_back(Backend::RenderWorker->AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY));
mCommands.push_back(Backend::RenderWorker->AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY)); mCommands.push_back(Backend::RenderWorker->AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY));
mFences.push_back(mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT)); mFences.push_back(mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT));
mFences.push_back(mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT));
} }
for (int i = mFrames; i < imageCount; i++) { for (int i = mFrames; i < imageCount; i++) {
desc.image = swapchain_images[i]; desc.image = swapchain_images[i];
@ -95,18 +98,23 @@ namespace vkn {
void VulkanSwapchain::Aquire(VulkanContext& ctx) void VulkanSwapchain::Aquire(VulkanContext& ctx)
{ {
VkFence surfaceFence = mFences[ctx.frame]; VkFence surfaceFence = mFences[ctx.frame];
VkFence transferFence = mFences[ctx.frame];
VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame]; VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame];
ctx.surfaceCommand = mCommands[ctx.frame]; ctx.surfaceCommand = mCommands[ctx.frame];
ctx.surfaceFence = surfaceFence; ctx.surfaceFence = surfaceFence;
ctx.surfaceSemaphore = surfaceSemaphore; ctx.surfaceSemaphore = surfaceSemaphore;
ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames]; ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames];
if (vkWaitForFences(mDevice.Ptr(), 1, &surfaceFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS) ctx.transferSemaphore = mSemaphores[ctx.frame + mFrames + mFrames];
VkFence waitFence[2] = { surfaceFence, transferFence };
uint32_t fenceNum = ctx.waitFenceNums[ctx.frame];
if (vkWaitForFences(mDevice.Ptr(), fenceNum, waitFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS)
throw std::runtime_error("Failed to wait for fence!"); throw std::runtime_error("Failed to wait for fence!");
vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, surfaceSemaphore, VK_NULL_HANDLE, &ctx.presentFrame); vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, surfaceSemaphore, VK_NULL_HANDLE, &ctx.presentFrame);
vkResetFences(mDevice.Ptr(), 1, &surfaceFence); vkResetFences(mDevice.Ptr(), fenceNum, waitFence);
ctx.surface = mSurfaces[ctx.presentFrame]; ctx.surface = mSurfaces[ctx.presentFrame];
ctx.graphSemaphore = nullptr; ctx.graphSemaphore = nullptr;
gLogSemaphore("aquire------------:: {:#x}", (uintptr_t)surfaceSemaphore); ctx.waitFenceNums[ctx.frame] = 0;
gLogSemaphore("aquire------------:: {:#x} transfer::{:#x}", (uintptr_t)surfaceSemaphore, (uintptr_t)ctx.transferSemaphore);
} }
void VulkanSwapchain::Present(VulkanContext& ctx) void VulkanSwapchain::Present(VulkanContext& ctx)
{ {
@ -119,6 +127,7 @@ namespace vkn {
presentInfo.swapchainCount = 1; presentInfo.swapchainCount = 1;
presentInfo.pImageIndices = &ctx.presentFrame; presentInfo.pImageIndices = &ctx.presentFrame;
presentInfo.pResults = VK_NULL_HANDLE; presentInfo.pResults = VK_NULL_HANDLE;
zlog::flush();
Backend::RenderWorker->Present(presentInfo); Backend::RenderWorker->Present(presentInfo);
ctx.frame = (ctx.frame + 1) % mFrames; ctx.frame = (ctx.frame + 1) % mFrames;
} }