add transfer command
This commit is contained in:
parent
1bbddd1c7d
commit
e68aef08d1
@ -13,6 +13,7 @@ namespace api {
|
||||
Noesis::Ptr<Noesis::IView> mView;
|
||||
public:
|
||||
EditorMainWindow();
|
||||
void DrawNoesisUI();
|
||||
void Draw(FrameGraph& graph, RenderEditorContext& ctx) override;
|
||||
};
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
#include "render/renderapi.h"
|
||||
#include "render/render_api.h"
|
||||
#include "render/render_module.h"
|
||||
namespace api {
|
||||
SINGLETON_DEFINE(RenderAPI)
|
||||
|
||||
@ -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();
|
||||
};
|
||||
}
|
||||
@ -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;
|
||||
|
||||
@ -6,6 +6,12 @@ namespace api {
|
||||
struct FRenderView {
|
||||
RenderContext* context;
|
||||
};
|
||||
enum class RenderPassState : uint8_t {
|
||||
Default,
|
||||
BeginRecord,
|
||||
BeginRender,
|
||||
Present,
|
||||
};
|
||||
struct RenderContext {
|
||||
pmr::vector<FRenderView> 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;
|
||||
};
|
||||
}
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#include "render/graph/frame_graph.h"
|
||||
#include "render/renderapi.h"
|
||||
#include "render/render_api.h"
|
||||
#include <stack>
|
||||
#include <unordered_set>
|
||||
#include <algorithm>
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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 <shaderc/shaderc.hpp>
|
||||
#include <spirv_cross/spirv_reflect.hpp>
|
||||
|
||||
@ -30,7 +30,4 @@ namespace api{
|
||||
bool isInverted = false;
|
||||
bool hasAlpha = false;
|
||||
};
|
||||
static Noesis::Ptr<Noesis::Texture> CreateUITexture(TextureDesc& desc) {
|
||||
return Noesis::MakePtr<UITexture>(desc);
|
||||
}
|
||||
}
|
||||
@ -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<Noesis::Texture> CreateTexture(TextureDesc& desc) {
|
||||
mApi->CreateTexture(desc);
|
||||
return Noesis::MakePtr<UITexture>(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<Noesis::RenderTarget> 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)
|
||||
{
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
#pragma once
|
||||
#include "render/renderapi.h"
|
||||
#include "render/render_api.h"
|
||||
#include <NsRender/RenderDevice.h>
|
||||
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
|
||||
//@{
|
||||
|
||||
@ -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);
|
||||
};
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
};
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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++;
|
||||
|
||||
@ -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<VkBufferMemoryBarrier> bufferBarriers{ FramePool() };
|
||||
bufferBarriers.reserve(desc.bufferBarriersCount);
|
||||
pmr::vector<VkImageMemoryBarrier> 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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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<VkBufferMemoryBarrier> bufferBarriers{ FramePool() };
|
||||
bufferBarriers.reserve(desc.bufferBarriersCount);
|
||||
pmr::vector<VkImageMemoryBarrier> 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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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++) {
|
||||
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user