From e68aef08d1249efd7f4e25e19031d517449e8674 Mon Sep 17 00:00:00 2001 From: ouczbs Date: Thu, 26 Dec 2024 21:54:38 +0800 Subject: [PATCH] add transfer command --- .../editor/window/editor_main_window.h | 3 +- .../engine/render/impl/renderapi_impl.inl | 2 +- .../render/{renderapi.h => render_api.h} | 2 - .../render/include/render/render_buffer.h | 2 +- .../render/include/render/render_context.h | 9 ++ .../render/include/render/render_type.h | 16 ++-- .../engine/render/src/graph/frame_graph.cpp | 6 +- .../engine/render/src/pass/demo_pass.cpp | 2 +- .../engine/render/src/tool/glsl_to_spirv.cpp | 2 +- .../engine/ui/impl/ui_render_device_help.inl | 3 - .../engine/ui/impl/ui_render_device_impl.inl | 66 ++++++++----- .../engine/ui/include/ui/ui_render_device.h | 9 +- .../vulkan/include/vkn/thread/buffer_worker.h | 6 +- .../modules/render/vulkan/include/vkn/type.h | 12 +++ .../render/vulkan/include/vkn/vulkan_api.h | 2 - .../vulkan/include/vkn/vulkan_context.h | 10 +- .../render/vulkan/include/vkn/vulkan_window.h | 2 + .../vulkan/src/thread/buffer_worker.cpp | 17 ++-- .../modules/render/vulkan/src/vulkan_api.cpp | 48 +--------- .../render/vulkan/src/vulkan_api_help.cpp | 24 +++-- .../render/vulkan/src/vulkan_context.cpp | 92 +++++++++++++++++-- .../render/vulkan/src/vulkan_window.cpp | 3 +- .../src/editor/window/editor_main_window.cpp | 16 ++-- 23 files changed, 223 insertions(+), 131 deletions(-) rename engine/modules/engine/render/include/render/{renderapi.h => render_api.h} (88%) diff --git a/engine/include/editor/window/editor_main_window.h b/engine/include/editor/window/editor_main_window.h index aaa5440..c135a1c 100644 --- a/engine/include/editor/window/editor_main_window.h +++ b/engine/include/editor/window/editor_main_window.h @@ -6,13 +6,14 @@ namespace api { public: using UIWindow::UIWindow; void InitializeComponent() override; - + }; class EditorMainWindow : public EditorWindow { public: Noesis::Ptr mView; public: EditorMainWindow(); + void DrawNoesisUI(); void Draw(FrameGraph& graph, RenderEditorContext& ctx) override; }; } \ No newline at end of file diff --git a/engine/modules/engine/render/impl/renderapi_impl.inl b/engine/modules/engine/render/impl/renderapi_impl.inl index 65dc4ab..4038e7d 100644 --- a/engine/modules/engine/render/impl/renderapi_impl.inl +++ b/engine/modules/engine/render/impl/renderapi_impl.inl @@ -1,4 +1,4 @@ -#include "render/renderapi.h" +#include "render/render_api.h" #include "render/render_module.h" namespace api { SINGLETON_DEFINE(RenderAPI) diff --git a/engine/modules/engine/render/include/render/renderapi.h b/engine/modules/engine/render/include/render/render_api.h similarity index 88% rename from engine/modules/engine/render/include/render/renderapi.h rename to engine/modules/engine/render/include/render/render_api.h index 5441577..582e8d1 100644 --- a/engine/modules/engine/render/include/render/renderapi.h +++ b/engine/modules/engine/render/include/render/render_api.h @@ -36,14 +36,12 @@ namespace api { virtual void CreateTexture(TextureDesc& desc) = 0; virtual ImageViewPtr CreateTextureView(TextureViewKey desc) = 0; virtual SamplerPtr CreateTextureSampler(TextureSampler sampler) = 0; - virtual void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) = 0; virtual void BeginFrame() = 0; virtual void EndFrame() = 0; virtual void RenderView(FRenderView& view); using FnEnterRenderPass = void(*)(RenderPassNode*); virtual void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) = 0; virtual void EndRenderPass(RenderPassNode* node) = 0; - virtual void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) = 0; void Render(); }; } \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/render_buffer.h b/engine/modules/engine/render/include/render/render_buffer.h index 9c45b7d..24252b2 100644 --- a/engine/modules/engine/render/include/render/render_buffer.h +++ b/engine/modules/engine/render/include/render/render_buffer.h @@ -1,6 +1,6 @@ #pragma once #define PREALLOCATED_DYNAMIC_BUFFER_PAGES 2 -#include "renderapi.h" +#include "render_api.h" namespace api { struct DynamicBufferDesc { uint32_t size; diff --git a/engine/modules/engine/render/include/render/render_context.h b/engine/modules/engine/render/include/render/render_context.h index d667251..96f4fd3 100644 --- a/engine/modules/engine/render/include/render/render_context.h +++ b/engine/modules/engine/render/include/render/render_context.h @@ -6,6 +6,12 @@ namespace api { struct FRenderView { RenderContext* context; }; + enum class RenderPassState : uint8_t { + Default, + BeginRecord, + BeginRender, + Present, + }; struct RenderContext { pmr::vector views; TextureDesc surface; @@ -13,6 +19,7 @@ namespace api { uint32_t frame{ 0 }; uint32_t presentFrame{ 0 }; uint32_t frameNumber{ 0 }; + RenderPassState renderPassState{ RenderPassState::Default }; virtual void SetViewport(float x, float y, float width, float height, float min_depth, float max_depth) = 0; virtual void SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0; virtual void BindIndexBuffer(BufferDesc desc, uint32_t index_stride) = 0; @@ -20,5 +27,7 @@ namespace api { virtual void BindVertexBuffers(uint32_t buffer_count, const BufferDesc* buffers, const uint32_t* offsets) = 0; virtual void DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex) = 0; virtual void ExecuteSurfaceBarriers(const ResourceBarrierDesc& desc) = 0; + virtual void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) = 0; + virtual void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) = 0; }; } \ No newline at end of file diff --git a/engine/modules/engine/render/include/render/render_type.h b/engine/modules/engine/render/include/render/render_type.h index d84d514..29a2a88 100644 --- a/engine/modules/engine/render/include/render/render_type.h +++ b/engine/modules/engine/render/include/render/render_type.h @@ -34,12 +34,14 @@ namespace api { LastOutput = 0x04, }; enum class BufferUsage : uint8_t { - STATIC = 0x01, //!< content modified once, used many times - DYNAMIC = 0x02, //!< content modified frequently, used many times - VERTEX = 0x04, - UNIFORM = 0x08, - SHADER_STORAGE = 0x10, - TRANSFER_SRC = 0x20, + None = 0, + STATIC, //!< content modified once, used many times + DYNAMIC, //!< content modified frequently, used many times + VERTEX, + INDEX, + UNIFORM, + SHADER_STORAGE, + TRANSFER_SRC, }; /* 扩展的内存用途标志: @@ -343,7 +345,6 @@ namespace api { return barrier; } struct ResourceBarrierDesc { - RenderPassType type; const BufferBarrier* pBufferBarriers; uint32_t bufferBarriersCount; const TextureBarrier* pTextureBarriers; @@ -369,6 +370,7 @@ namespace api { uint32_t y; uint32_t width; uint32_t height; + uint32_t mipLevel; const void* data; }; } diff --git a/engine/modules/engine/render/src/graph/frame_graph.cpp b/engine/modules/engine/render/src/graph/frame_graph.cpp index 829b1af..e074f29 100644 --- a/engine/modules/engine/render/src/graph/frame_graph.cpp +++ b/engine/modules/engine/render/src/graph/frame_graph.cpp @@ -1,5 +1,5 @@ #include "render/graph/frame_graph.h" -#include "render/renderapi.h" +#include "render/render_api.h" #include #include #include @@ -172,7 +172,6 @@ namespace api { barrier.mDstState = ResourceState::PRESENT; barrier.mTexture = surface; ResourceBarrierDesc desc{}; - desc.type = RenderPassType::Present; desc.textureBarriersCount = 1; desc.pTextureBarriers = &barrier; view.context->ExecuteSurfaceBarriers(desc); @@ -211,12 +210,11 @@ namespace api { return; } ResourceBarrierDesc desc{}; - desc.type = type; desc.bufferBarriersCount = bufferBarrier.size(); desc.pBufferBarriers = bufferBarrier.data(); desc.textureBarriersCount = textureBarrier.size(); desc.pTextureBarriers = textureBarrier.data(); - RenderAPI::Ptr()->ExecuteResourceBarriers(desc); + RenderAPI::Ptr()->context.ExecuteResourceBarriers(desc); } void FrameGraph::TransitionState(TextureDesc& desc, ResourceState state) { diff --git a/engine/modules/engine/render/src/pass/demo_pass.cpp b/engine/modules/engine/render/src/pass/demo_pass.cpp index 97ca325..9628010 100644 --- a/engine/modules/engine/render/src/pass/demo_pass.cpp +++ b/engine/modules/engine/render/src/pass/demo_pass.cpp @@ -1,7 +1,7 @@ #include "render/pass/demo_pass.h" #include "render/asset/shader.h" #include "render/asset/material.h" -#include "render/renderapi.h" +#include "render/render_api.h" #include "asset/resource_system.h" #include "render/asset/vertex.h" #include "render/asset/mesh.h" diff --git a/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp b/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp index 75fddf8..2b6327a 100644 --- a/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp +++ b/engine/modules/engine/render/src/tool/glsl_to_spirv.cpp @@ -1,6 +1,6 @@ #include "render/tool/glsl_to_spirv.h" #include "render/asset/ubo.h" -#include "render/renderapi.h" +#include "render/render_api.h" #include "zlog.h" #include #include diff --git a/engine/modules/engine/ui/impl/ui_render_device_help.inl b/engine/modules/engine/ui/impl/ui_render_device_help.inl index 98ef8db..7c3a9d8 100644 --- a/engine/modules/engine/ui/impl/ui_render_device_help.inl +++ b/engine/modules/engine/ui/impl/ui_render_device_help.inl @@ -30,7 +30,4 @@ namespace api{ bool isInverted = false; bool hasAlpha = false; }; - static Noesis::Ptr CreateUITexture(TextureDesc& desc) { - return Noesis::MakePtr(desc); - } } \ No newline at end of file diff --git a/engine/modules/engine/ui/impl/ui_render_device_impl.inl b/engine/modules/engine/ui/impl/ui_render_device_impl.inl index 629663d..e3060d5 100644 --- a/engine/modules/engine/ui/impl/ui_render_device_impl.inl +++ b/engine/modules/engine/ui/impl/ui_render_device_impl.inl @@ -1,10 +1,38 @@ #include "ui/ui_render_device.h" #include "ui/ui_module.h" #include "ui_render_device_help.inl" +#include "render/render_buffer.h" +#define CBUFFER_SIZE 16 * 1024 namespace api { + class UIRenderDeviceImpl { + public: + RenderAPI* mApi; + DynamicBuffer mVertices; + DynamicBuffer mIndices; + DynamicBuffer mConstants[4]; + Noesis::DeviceCaps mCaps; + UIRenderDeviceImpl(RenderAPI* api) : mApi(api){ + ResourceMemoryUsage memoryUsage = ResourceMemoryUsage::HOST_VISIBLE | + ResourceMemoryUsage::HOST_COHERENT | ResourceMemoryUsage::GPU_ONLY; + mVertices.InitBuffer(DYNAMIC_VB_SIZE, BufferUsage::VERTEX, memoryUsage); + mIndices.InitBuffer(DYNAMIC_IB_SIZE, BufferUsage::INDEX, memoryUsage); + mConstants[0].InitBuffer(CBUFFER_SIZE, BufferUsage::UNIFORM, memoryUsage); + mConstants[1].InitBuffer(CBUFFER_SIZE, BufferUsage::UNIFORM, memoryUsage); + mConstants[2].InitBuffer(CBUFFER_SIZE, BufferUsage::UNIFORM, memoryUsage); + mConstants[3].InitBuffer(CBUFFER_SIZE, BufferUsage::UNIFORM, memoryUsage); + } + Noesis::Ptr CreateTexture(TextureDesc& desc) { + mApi->CreateTexture(desc); + return Noesis::MakePtr(desc); + } + RenderContext& Context() { + return mApi->context; + } + }; SINGLETON_DEFINE(UIRenderDevice) - UIRenderDevice::UIRenderDevice(RenderAPI* api) : mApi(api) + UIRenderDevice::UIRenderDevice(RenderAPI* api) { + mImpl = new (GlobalPool()) UIRenderDeviceImpl(api); SINGLETON_PTR(); } UIRenderDevice::~UIRenderDevice() @@ -16,7 +44,7 @@ namespace api { } const Noesis::DeviceCaps& UIRenderDevice::GetCaps() const { - return mCaps; + return mImpl->mCaps; } Noesis::Ptr UIRenderDevice::CreateRenderTarget(const char* label, uint32_t width, uint32_t height, uint32_t sampleCount, bool needsStencil) { @@ -30,21 +58,23 @@ namespace api { { TextureDesc desc{}; desc.id = -1; - desc.format = VKFormat(format, mCaps.linearRendering); + desc.format = VKFormat(format, mImpl->mCaps.linearRendering); desc.width = width; desc.height = height; desc.mipLevel = numLevels; desc.sampleCount = SAMPLE_COUNT_1; desc.usage = TextureUsage::SAMPLEABLE | TextureUsage::BLIT_DST; desc.state = ResourceState::UNDEFINED; - mApi->CreateTexture(desc); - return CreateUITexture(desc); + desc.dimension = TextureDimension::TEX_2D; + desc.depth = 1; + desc.arraySize = 1; + return mImpl->CreateTexture(desc); } void UIRenderDevice::UpdateTexture(Noesis::Texture* texture, uint32_t level, uint32_t x, uint32_t y, uint32_t width, uint32_t height, const void* data) { UITexture* uiTex = (UITexture*)texture; - TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .data = data}; - mApi->UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST); + TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .mipLevel = level, .data = data}; + mImpl->Context().UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST); } void UIRenderDevice::BeginOffscreenRender() { @@ -104,33 +134,19 @@ namespace api { } void* UIRenderDevice::MapVertices(uint32_t bytes) { - int b = 10000; - for (int a = 1; a < b; a++) { - b--; - } - return nullptr; + auto& ctx = mImpl->Context(); + return mImpl->mVertices.MapBuffer(bytes, ctx.frameNumber, ctx.frameNumber - ctx.frameCount); } void UIRenderDevice::UnmapVertices() { - int b = 10000; - for (int a = 1; a < b; a++) { - b--; - } } void* UIRenderDevice::MapIndices(uint32_t bytes) { - int b = 10000; - for (int a = 1; a < b; a++) { - b--; - } - return nullptr; + auto& ctx = mImpl->Context(); + return mImpl->mIndices.MapBuffer(bytes, ctx.frameNumber, ctx.frameNumber - ctx.frameCount); } void UIRenderDevice::UnmapIndices() { - int b = 10000; - for (int a = 1; a < b; a++) { - b--; - } } void UIRenderDevice::DrawBatch(const Noesis::Batch& batch) { diff --git a/engine/modules/engine/ui/include/ui/ui_render_device.h b/engine/modules/engine/ui/include/ui/ui_render_device.h index cbe6b5c..ac5045d 100644 --- a/engine/modules/engine/ui/include/ui/ui_render_device.h +++ b/engine/modules/engine/ui/include/ui/ui_render_device.h @@ -1,15 +1,18 @@ #pragma once -#include "render/renderapi.h" +#include "render/render_api.h" #include namespace api { + class UIRenderDeviceImpl; class UI_API UIRenderDevice final : public Noesis::RenderDevice { private: - RenderAPI* mApi; - Noesis::DeviceCaps mCaps; + UIRenderDeviceImpl* mImpl; SINGLETON_IMPL(UIRenderDevice) public: UIRenderDevice(RenderAPI* api); ~UIRenderDevice(); + static void* operator new(size_t size) { + return GlobalPool()->allocate(size, 8); + } private: /// From RenderDevice //@{ diff --git a/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h b/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h index 9a61856..3734a99 100644 --- a/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h +++ b/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h @@ -42,10 +42,10 @@ namespace vkn { VkImage* image; }; struct ImageUpdator { + TextureUpdateArgs args; + VkCommandBuffer command; VkImage image; uint32_t size; - uint32_t mipLevel; - TextureUpdateArgs args; }; struct SyncTransferCommand { uint32_t frameNumber; @@ -85,6 +85,6 @@ namespace vkn { void UpdateImage(ImageUpdator& elem, TransferBufferType type = TransferBufferType::Graphics); bool BeginDynamicCommand(DynamicBufferPool*& poolRef, CommandBuffer& cmd, bool isTransfer); - void EndDynamicCommand(DynamicBufferPool* poolRef, CommandBuffer& cmd, bool isTransfer); + void EndDynamicCommand(DynamicBufferPool* poolRef, CommandBuffer cmd, bool isTransfer); }; }; diff --git a/engine/modules/render/vulkan/include/vkn/type.h b/engine/modules/render/vulkan/include/vkn/type.h index e03bd8f..859d165 100644 --- a/engine/modules/render/vulkan/include/vkn/type.h +++ b/engine/modules/render/vulkan/include/vkn/type.h @@ -7,6 +7,18 @@ #include "render/render_type.h" #include "render/type.h" #define Z_RENDER_DEBUG 1 +#define VKN_MACRO_BEGIN \ + __pragma(warning(push)) \ + __pragma(warning(disable:4127)) \ + do { +#define VKN_MACRO_END \ + } while(false) \ + __pragma(warning(pop)) +#define V(exp) \ + VKN_MACRO_BEGIN \ + VkResult err_ = (exp); \ + assert(err_ == VK_SUCCESS); \ + VKN_MACRO_END namespace vkn { using pmr::Name; using pmr::table; diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api.h b/engine/modules/render/vulkan/include/vkn/vulkan_api.h index 4cb341a..65c5cd2 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_api.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_api.h @@ -41,13 +41,11 @@ namespace vkn { void CreateTexture(TextureDesc& desc)override; ImageViewPtr CreateTextureView(TextureViewKey desc)override; SamplerPtr CreateTextureSampler(TextureSampler sampler) override; - void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) override; void BeginFrame()override; void EndFrame()override; void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) override; void EndRenderPass(RenderPassNode* node) override; - void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override; VkPipeline GetPipeline() { return nullptr; }; RenderPassInfo* GetRenderPassInfo(Name name, size_t hash); diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_context.h b/engine/modules/render/vulkan/include/vkn/vulkan_context.h index 5bd7399..eac1095 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_context.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_context.h @@ -1,13 +1,15 @@ #pragma once #include "type.h" -#include "render/renderapi.h" +#include "render/render_api.h" namespace vkn { using api::BufferDesc; + using api::RenderPassState; struct VulkanContext : public api::RenderContext { VkFence surfaceFence; VkSemaphore surfaceSemaphore; VkSemaphore presentSemaphore; VkSemaphore graphSemaphore; + VkCommandBuffer transferCommand; VkCommandBuffer surfaceCommand; VkCommandBuffer command; void SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override; @@ -17,9 +19,13 @@ namespace vkn { void BindVertexBuffers(uint32_t buffer_count, const BufferDesc* descs, const uint32_t* offsets)override; void DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex) override; void ExecuteSurfaceBarriers(const ResourceBarrierDesc& desc) override; + void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override; + void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) override; void ClearSurface(VkClearColorValue clearValue); - void BeginRecord(VkCommandBufferUsageFlags flag); + void BeginRecord(VkCommandBuffer cmd, VkCommandBufferUsageFlags flag); void EndRecord(VkQueue queue); + void FlushCommand(); + VkCommandBuffer GetTransferCommand(); }; } \ No newline at end of file diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_window.h b/engine/modules/render/vulkan/include/vkn/vulkan_window.h index 40367b5..95d3450 100644 --- a/engine/modules/render/vulkan/include/vkn/vulkan_window.h +++ b/engine/modules/render/vulkan/include/vkn/vulkan_window.h @@ -32,6 +32,7 @@ namespace vkn { VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args); void Aquire(VulkanContext& ctx); void Present(VulkanContext& ctx); + VkCommandBuffer GetTransferCommand(uint32_t frame) { return mCommands[frame + mFrames]; }; }; class VULKAN_API VulkanWindow : public api::Window { private: @@ -49,6 +50,7 @@ namespace vkn { } void Aquire(VulkanContext& ctx) { mSwapchain->Aquire(ctx); }; void Present(VulkanContext& ctx) { mSwapchain->Present(ctx); }; + VkCommandBuffer GetTransferCommand(uint32_t frame) { return mSwapchain->GetTransferCommand(frame); }; VulkanSwapchain* Swapchain() { return mSwapchain; } diff --git a/engine/modules/render/vulkan/src/thread/buffer_worker.cpp b/engine/modules/render/vulkan/src/thread/buffer_worker.cpp index a3f1271..8bca587 100644 --- a/engine/modules/render/vulkan/src/thread/buffer_worker.cpp +++ b/engine/modules/render/vulkan/src/thread/buffer_worker.cpp @@ -148,13 +148,14 @@ namespace vkn { allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY; VmaAllocation allocation; - VkResult result = vmaCreateImage(vmaAllocator, &elem.imageInfo, &allocCreateInfo, elem.image, &allocation, nullptr); + V(vmaCreateImage(vmaAllocator, &elem.imageInfo, &allocCreateInfo, elem.image, &allocation, nullptr)); + zlog::info("CreateImage {:#x} {} {}::{}",(uintptr_t)*elem.image, (uint32_t)elem.imageInfo.format, elem.imageInfo.extent.width, elem.imageInfo.extent.height); } void BufferWorker::UpdateImage(ImageUpdator& elem, TransferBufferType type) { bool isTransfer = type == TransferBufferType::Transfer; DynamicBufferPool* pPoolRef; - CommandBuffer command; + CommandBuffer command = elem.command; if (!BeginDynamicCommand(pPoolRef, command, isTransfer)) { Invoke(elem); return; @@ -162,25 +163,29 @@ namespace vkn { TextureUpdateArgs args = elem.args; // 将数据复制到 Staging Buffer DynamicBuffer* uploadBuffer = pPoolRef->FindUploadBuffer(elem.size, mFrameNumber + 1, args.data); - + zlog::info("update {:#x} {}::{} {}::{}", (uintptr_t)elem.image,args.x,args.y ,args.width, args.height); VkBufferImageCopy region{}; region.imageOffset.x = args.x; region.imageOffset.y = args.y; region.imageExtent.width = args.width; region.imageExtent.height = args.height; region.imageExtent.depth = 1; - region.imageSubresource.mipLevel = elem.mipLevel; + region.imageSubresource.mipLevel = args.mipLevel; region.bufferOffset = uploadBuffer->drawPos; region.imageSubresource.layerCount = 1; region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; vkCmdCopyBufferToImage(command.Ptr(), (VkBuffer)uploadBuffer->currentPage->pBuffer, elem.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - EndDynamicCommand(pPoolRef, command, isTransfer); + if(!elem.command) + EndDynamicCommand(pPoolRef, command, isTransfer); } bool BufferWorker::BeginDynamicCommand(DynamicBufferPool*& pPoolRef, CommandBuffer& command, bool isTransfer) { pPoolRef = isTransfer ? &mTransferBuffer : &mGraphicsBuffer; + if (command.Ptr()) { + return true; + } if (pPoolRef->commandIndex >= MAX_TRANSFER_SYNC_FENCES) { return false; } @@ -188,7 +193,7 @@ namespace vkn { command.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); return true; } - void BufferWorker::EndDynamicCommand(DynamicBufferPool* pPoolRef, CommandBuffer& command, bool isTransfer) + void BufferWorker::EndDynamicCommand(DynamicBufferPool* pPoolRef, CommandBuffer command, bool isTransfer) { command.EndRecord(); pPoolRef->commandIndex++; diff --git a/engine/modules/render/vulkan/src/vulkan_api.cpp b/engine/modules/render/vulkan/src/vulkan_api.cpp index ee2a949..69405c0 100644 --- a/engine/modules/render/vulkan/src/vulkan_api.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api.cpp @@ -340,31 +340,6 @@ namespace vkn { vkCreateSampler(backend.GetDevice().Ptr(), &samplerInfo, nullptr, &sampler); return sampler; } - void VulkanAPI::UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) - { - if (!texture.id) { - graph.AcquireTexture(texture); - } - if (texture.state != state) { - TextureBarrier barrier{}; - barrier.mSrcState = texture.state; - barrier.mDstState = state; - barrier.mTexture = texture; - ResourceBarrierDesc desc{}; - desc.pTextureBarriers = &barrier; - desc.textureBarriersCount = 1; - ExecuteResourceBarriers(desc); - } - VulkanContext& ctx = *(VulkanContext*)&context; - uint32_t texelBytes = texture.format == TinyImageFormat_R8_UNORM ? 1 : 4; - uint32_t size = update.width * update.height * texelBytes; - ImageUpdator updator{}; - updator.args = update; - updator.size = size; - updator.mipLevel = texture.mipLevel; - updator.image = (VkImage)texture.image; - Backend::TransferWorker->UpdateImage(updator); - } void VulkanAPI::BeginFrame() { VulkanContext& ctx = *(VulkanContext*)&context; @@ -375,28 +350,10 @@ namespace vkn { void VulkanAPI::EndFrame() { VulkanContext& ctx = *(VulkanContext*)&context; + ctx.FlushCommand(); window.Present(ctx); Backend::TransferWorker->TrySyncTransfer(ctx); } - void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) { - VulkanContext& ctx = *(VulkanContext*)&context; - pmr::vector bufferBarriers{ FramePool() }; - bufferBarriers.reserve(desc.bufferBarriersCount); - pmr::vector imageBarriers{ FramePool() }; - imageBarriers.reserve(desc.textureBarriersCount); - VkPipelineStageFlags srcStageMask = 0, dstStageMask = 0; - for (uint32_t i = 0; i < desc.textureBarriersCount; i++) - { - auto& barrier = desc.pTextureBarriers[i]; - auto desc = vkApiGetTextureTransition(srcStageMask, dstStageMask, barrier); - imageBarriers.push_back(desc); - } - if (dstStageMask == 0) { - dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; - } - VkCommandBuffer command = desc.type == RenderPassType::Present ? ctx.surfaceCommand : ctx.command; - vkCmdPipelineBarrier(command, srcStageMask, dstStageMask, 0, 0, NULL, 0, NULL, imageBarriers.size(), imageBarriers.data()); - } void VulkanAPI::BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) { RenderPassKey config{}; @@ -481,8 +438,10 @@ namespace vkn { CommandBuffer cmd = passInfo->commands[context.frame]; ctx.command = cmd.Ptr(); cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ctx.renderPassState = RenderPassState::BeginRecord; if(callback) callback(node); vkCmdBeginRenderPass(cmd.Ptr(), &beginInfo, VK_SUBPASS_CONTENTS_INLINE); + ctx.renderPassState = RenderPassState::BeginRender; if (clearSurfaceIndex != -1)ctx.ClearSurface(clearValues[clearSurfaceIndex].color); } void VulkanAPI::EndRenderPass(RenderPassNode* node) @@ -492,6 +451,7 @@ namespace vkn { CommandBuffer cmd = passInfo->commands[context.frame]; vkCmdEndRenderPass(cmd.Ptr()); cmd.EndRecord(); + ctx.renderPassState = RenderPassState::Default; VkSemaphore waitSemaphores[8]; VkPipelineStageFlags waitDstStageMasks[8]; uint32_t semaphoreCount = 0; diff --git a/engine/modules/render/vulkan/src/vulkan_api_help.cpp b/engine/modules/render/vulkan/src/vulkan_api_help.cpp index d68c1b9..79c2842 100644 --- a/engine/modules/render/vulkan/src/vulkan_api_help.cpp +++ b/engine/modules/render/vulkan/src/vulkan_api_help.cpp @@ -186,8 +186,12 @@ namespace vkn { usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; if (any(usage & TextureUsage::DEPTH_ATTACHMENT)) usageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - if(any(usage & TextureUsage::SAMPLEABLE)) + if (any(usage & TextureUsage::SAMPLEABLE)) usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT; + if (any(usage & TextureUsage::BLIT_DST)) + usageFlags |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; + if (any(usage & TextureUsage::BLIT_SRC)) + usageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; return usageFlags; } VkImageViewType vkApiGetImageViewType(TextureDimension dimension, uint32_t arraySize) @@ -369,19 +373,21 @@ namespace vkn { } VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage) { - if (any(usage & BufferUsage::VERTEX)) { + switch (usage) + { + case api::BufferUsage::VERTEX: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; - } - if (any(usage & BufferUsage::UNIFORM)) { + case api::BufferUsage::INDEX: + return VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + case api::BufferUsage::UNIFORM: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; - } - if (any(usage & BufferUsage::SHADER_STORAGE)) { + case api::BufferUsage::SHADER_STORAGE: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; - } - if (any(usage & BufferUsage::TRANSFER_SRC)) { + case api::BufferUsage::TRANSFER_SRC: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + default: + return {}; } - return {}; } VkMemoryPropertyFlags vkApiGetMemoryFlags(ResourceMemoryUsage usageFlags) { VkMemoryPropertyFlags flags = 0; diff --git a/engine/modules/render/vulkan/src/vulkan_context.cpp b/engine/modules/render/vulkan/src/vulkan_context.cpp index a34cce1..6da78e7 100644 --- a/engine/modules/render/vulkan/src/vulkan_context.cpp +++ b/engine/modules/render/vulkan/src/vulkan_context.cpp @@ -1,6 +1,9 @@ #include "vkn/backend.h" #include "vkn/vulkan_api.h" #include "vkn/thread/command_worker.h" +#include "vkn/vulkan_api_help.h" +#include "vkn/thread/buffer_worker.h" +#include "vkn/vulkan_window.h" #include "zlog.h" namespace vkn { void VulkanContext::SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) @@ -50,12 +53,6 @@ namespace vkn { { vkCmdDrawIndexed(command, index_count, 1, first_index, first_vertex, 0); } - void VulkanContext::ExecuteSurfaceBarriers(const ResourceBarrierDesc& desc) - { - BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); - VulkanAPI::Ptr()->ExecuteResourceBarriers(desc); - EndRecord(Backend::RenderWorker->GetQueue().Ptr()); - } void VulkanContext::ClearSurface(VkClearColorValue clearValue) { // 条件满足时,手动清除附件 @@ -73,14 +70,14 @@ namespace vkn { // 使用 vkCmdClearAttachments 清除颜色附件 vkCmdClearAttachments(command, 1, &clearAttachment, 1, &clearRect); } - void VulkanContext::BeginRecord(VkCommandBufferUsageFlags flag) + void VulkanContext::BeginRecord(VkCommandBuffer cmd, VkCommandBufferUsageFlags flag) { VkCommandBufferBeginInfo beginInfo{ VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,//sType nullptr, //pNext flag //flags }; - vkBeginCommandBuffer(surfaceCommand, &beginInfo); + vkBeginCommandBuffer(cmd, &beginInfo); } void VulkanContext::EndRecord(VkQueue queue) @@ -105,4 +102,83 @@ namespace vkn { vkQueueSubmit(queue, 1, &submitInfo, surfaceFence); graphSemaphore = presentSemaphore; } + void VulkanContext::FlushCommand() + { + if (transferCommand) { + vkEndCommandBuffer(transferCommand); + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &transferCommand; + vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, nullptr); + transferCommand = nullptr; + } + } + VkCommandBuffer VulkanContext::GetTransferCommand() + { + switch (renderPassState) + { + case api::RenderPassState::BeginRecord: + return command; + case api::RenderPassState::BeginRender: + { + if (!transferCommand) { + transferCommand = VulkanWindow::Ptr()->GetTransferCommand(frame); + BeginRecord(transferCommand, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + } + return transferCommand; + } + case api::RenderPassState::Present: + return surfaceCommand; + default: + return nullptr; + } + } + void VulkanContext::ExecuteSurfaceBarriers(const ResourceBarrierDesc& desc) + { + BeginRecord(surfaceCommand, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT); + ExecuteResourceBarriers(desc); + EndRecord(Backend::RenderWorker->GetQueue().Ptr()); + } + void VulkanContext::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) { + pmr::vector bufferBarriers{ FramePool() }; + bufferBarriers.reserve(desc.bufferBarriersCount); + pmr::vector imageBarriers{ FramePool() }; + imageBarriers.reserve(desc.textureBarriersCount); + VkPipelineStageFlags srcStageMask = 0, dstStageMask = 0; + for (uint32_t i = 0; i < desc.textureBarriersCount; i++) + { + auto& barrier = desc.pTextureBarriers[i]; + auto desc = vkApiGetTextureTransition(srcStageMask, dstStageMask, barrier); + imageBarriers.push_back(desc); + } + if (dstStageMask == 0) { + dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + } + vkCmdPipelineBarrier(GetTransferCommand(), srcStageMask, dstStageMask, 0, 0, NULL, 0, NULL, imageBarriers.size(), imageBarriers.data()); + } + void VulkanContext::UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) + { + if (!texture.id) { + VulkanAPI::Ptr()->graph.AcquireTexture(texture); + } + if (texture.state != state) { + TextureBarrier barrier{}; + barrier.mSrcState = texture.state; + barrier.mDstState = state; + barrier.mTexture = texture; + ResourceBarrierDesc desc{}; + desc.pTextureBarriers = &barrier; + desc.textureBarriersCount = 1; + ExecuteResourceBarriers(desc); + } + uint32_t texelBytes = texture.format == TinyImageFormat_R8_UNORM ? 1 : 4; + uint32_t size = update.width * update.height * texelBytes; + ImageUpdator updator{}; + updator.args = update; + updator.size = size; + updator.image = (VkImage)texture.image; + updator.command = GetTransferCommand(); + Backend::TransferWorker->UpdateImage(updator); + } } diff --git a/engine/modules/render/vulkan/src/vulkan_window.cpp b/engine/modules/render/vulkan/src/vulkan_window.cpp index 89ec2d1..9b9ee35 100644 --- a/engine/modules/render/vulkan/src/vulkan_window.cpp +++ b/engine/modules/render/vulkan/src/vulkan_window.cpp @@ -66,7 +66,7 @@ namespace vkn { vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data()); mFences.reserve(mFrames); mSurfaces.reserve(imageCount); - mCommands.reserve(mFrames); + mCommands.reserve(mFrames + mFrames); mSemaphores.reserve(mFrames + mFrames); TextureDesc desc{}; desc.width = args.width; @@ -84,6 +84,7 @@ namespace vkn { 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)); mFences.push_back(mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT)); } for (int i = mFrames; i < imageCount; i++) { diff --git a/engine/src/editor/window/editor_main_window.cpp b/engine/src/editor/window/editor_main_window.cpp index ac8bb85..7427c2d 100644 --- a/engine/src/editor/window/editor_main_window.cpp +++ b/engine/src/editor/window/editor_main_window.cpp @@ -18,8 +18,14 @@ namespace api { mView->SetFlags(RenderFlags_PPAA | RenderFlags_LCD); mView->SetSize(1024, 768); mView->GetRenderer()->Init(UIRenderDevice::Ptr()); - - + } + void EditorMainWindow::DrawNoesisUI() + { + mView->Update(0.033); + IRenderer* renderer = mView->GetRenderer(); + renderer->UpdateRenderTree(); + renderer->RenderOffscreen(); + renderer->Render(); } TextureSampler sampler{ .filterMag = SamplerMagFilter::LINEAR, @@ -79,10 +85,6 @@ namespace api { InitRenderSurface(graph, ctx.frameCount); } ImGui::End(); - //mView->Update(0.033); - //IRenderer* renderer = mView->GetRenderer(); - //renderer->UpdateRenderTree(); - //renderer->RenderOffscreen(); - //renderer->Render(); + DrawNoesisUI(); } } \ No newline at end of file