add transfer command
This commit is contained in:
parent
1bbddd1c7d
commit
e68aef08d1
@ -6,13 +6,14 @@ namespace api {
|
|||||||
public:
|
public:
|
||||||
using UIWindow::UIWindow;
|
using UIWindow::UIWindow;
|
||||||
void InitializeComponent() override;
|
void InitializeComponent() override;
|
||||||
|
|
||||||
};
|
};
|
||||||
class EditorMainWindow : public EditorWindow {
|
class EditorMainWindow : public EditorWindow {
|
||||||
public:
|
public:
|
||||||
Noesis::Ptr<Noesis::IView> mView;
|
Noesis::Ptr<Noesis::IView> mView;
|
||||||
public:
|
public:
|
||||||
EditorMainWindow();
|
EditorMainWindow();
|
||||||
|
void DrawNoesisUI();
|
||||||
void Draw(FrameGraph& graph, RenderEditorContext& ctx) override;
|
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"
|
#include "render/render_module.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
SINGLETON_DEFINE(RenderAPI)
|
SINGLETON_DEFINE(RenderAPI)
|
||||||
|
|||||||
@ -36,14 +36,12 @@ namespace api {
|
|||||||
virtual void CreateTexture(TextureDesc& desc) = 0;
|
virtual void CreateTexture(TextureDesc& desc) = 0;
|
||||||
virtual ImageViewPtr CreateTextureView(TextureViewKey desc) = 0;
|
virtual ImageViewPtr CreateTextureView(TextureViewKey desc) = 0;
|
||||||
virtual SamplerPtr CreateTextureSampler(TextureSampler sampler) = 0;
|
virtual SamplerPtr CreateTextureSampler(TextureSampler sampler) = 0;
|
||||||
virtual void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) = 0;
|
|
||||||
virtual void BeginFrame() = 0;
|
virtual void BeginFrame() = 0;
|
||||||
virtual void EndFrame() = 0;
|
virtual void EndFrame() = 0;
|
||||||
virtual void RenderView(FRenderView& view);
|
virtual void RenderView(FRenderView& view);
|
||||||
using FnEnterRenderPass = void(*)(RenderPassNode*);
|
using FnEnterRenderPass = void(*)(RenderPassNode*);
|
||||||
virtual void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) = 0;
|
virtual void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) = 0;
|
||||||
virtual void EndRenderPass(RenderPassNode* node) = 0;
|
virtual void EndRenderPass(RenderPassNode* node) = 0;
|
||||||
virtual void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) = 0;
|
|
||||||
void Render();
|
void Render();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define PREALLOCATED_DYNAMIC_BUFFER_PAGES 2
|
#define PREALLOCATED_DYNAMIC_BUFFER_PAGES 2
|
||||||
#include "renderapi.h"
|
#include "render_api.h"
|
||||||
namespace api {
|
namespace api {
|
||||||
struct DynamicBufferDesc {
|
struct DynamicBufferDesc {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|||||||
@ -6,6 +6,12 @@ namespace api {
|
|||||||
struct FRenderView {
|
struct FRenderView {
|
||||||
RenderContext* context;
|
RenderContext* context;
|
||||||
};
|
};
|
||||||
|
enum class RenderPassState : uint8_t {
|
||||||
|
Default,
|
||||||
|
BeginRecord,
|
||||||
|
BeginRender,
|
||||||
|
Present,
|
||||||
|
};
|
||||||
struct RenderContext {
|
struct RenderContext {
|
||||||
pmr::vector<FRenderView> views;
|
pmr::vector<FRenderView> views;
|
||||||
TextureDesc surface;
|
TextureDesc surface;
|
||||||
@ -13,6 +19,7 @@ namespace api {
|
|||||||
uint32_t frame{ 0 };
|
uint32_t frame{ 0 };
|
||||||
uint32_t presentFrame{ 0 };
|
uint32_t presentFrame{ 0 };
|
||||||
uint32_t frameNumber{ 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 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 SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) = 0;
|
||||||
virtual void BindIndexBuffer(BufferDesc desc, uint32_t index_stride) = 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 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 DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex) = 0;
|
||||||
virtual void ExecuteSurfaceBarriers(const ResourceBarrierDesc& desc) = 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,
|
LastOutput = 0x04,
|
||||||
};
|
};
|
||||||
enum class BufferUsage : uint8_t {
|
enum class BufferUsage : uint8_t {
|
||||||
STATIC = 0x01, //!< content modified once, used many times
|
None = 0,
|
||||||
DYNAMIC = 0x02, //!< content modified frequently, used many times
|
STATIC, //!< content modified once, used many times
|
||||||
VERTEX = 0x04,
|
DYNAMIC, //!< content modified frequently, used many times
|
||||||
UNIFORM = 0x08,
|
VERTEX,
|
||||||
SHADER_STORAGE = 0x10,
|
INDEX,
|
||||||
TRANSFER_SRC = 0x20,
|
UNIFORM,
|
||||||
|
SHADER_STORAGE,
|
||||||
|
TRANSFER_SRC,
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
扩展的内存用途标志:
|
扩展的内存用途标志:
|
||||||
@ -343,7 +345,6 @@ namespace api {
|
|||||||
return barrier;
|
return barrier;
|
||||||
}
|
}
|
||||||
struct ResourceBarrierDesc {
|
struct ResourceBarrierDesc {
|
||||||
RenderPassType type;
|
|
||||||
const BufferBarrier* pBufferBarriers;
|
const BufferBarrier* pBufferBarriers;
|
||||||
uint32_t bufferBarriersCount;
|
uint32_t bufferBarriersCount;
|
||||||
const TextureBarrier* pTextureBarriers;
|
const TextureBarrier* pTextureBarriers;
|
||||||
@ -369,6 +370,7 @@ namespace api {
|
|||||||
uint32_t y;
|
uint32_t y;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
|
uint32_t mipLevel;
|
||||||
const void* data;
|
const void* data;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#include "render/graph/frame_graph.h"
|
#include "render/graph/frame_graph.h"
|
||||||
#include "render/renderapi.h"
|
#include "render/render_api.h"
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -172,7 +172,6 @@ namespace api {
|
|||||||
barrier.mDstState = ResourceState::PRESENT;
|
barrier.mDstState = ResourceState::PRESENT;
|
||||||
barrier.mTexture = surface;
|
barrier.mTexture = surface;
|
||||||
ResourceBarrierDesc desc{};
|
ResourceBarrierDesc desc{};
|
||||||
desc.type = RenderPassType::Present;
|
|
||||||
desc.textureBarriersCount = 1;
|
desc.textureBarriersCount = 1;
|
||||||
desc.pTextureBarriers = &barrier;
|
desc.pTextureBarriers = &barrier;
|
||||||
view.context->ExecuteSurfaceBarriers(desc);
|
view.context->ExecuteSurfaceBarriers(desc);
|
||||||
@ -211,12 +210,11 @@ namespace api {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ResourceBarrierDesc desc{};
|
ResourceBarrierDesc desc{};
|
||||||
desc.type = type;
|
|
||||||
desc.bufferBarriersCount = bufferBarrier.size();
|
desc.bufferBarriersCount = bufferBarrier.size();
|
||||||
desc.pBufferBarriers = bufferBarrier.data();
|
desc.pBufferBarriers = bufferBarrier.data();
|
||||||
desc.textureBarriersCount = textureBarrier.size();
|
desc.textureBarriersCount = textureBarrier.size();
|
||||||
desc.pTextureBarriers = textureBarrier.data();
|
desc.pTextureBarriers = textureBarrier.data();
|
||||||
RenderAPI::Ptr()->ExecuteResourceBarriers(desc);
|
RenderAPI::Ptr()->context.ExecuteResourceBarriers(desc);
|
||||||
}
|
}
|
||||||
void FrameGraph::TransitionState(TextureDesc& desc, ResourceState state)
|
void FrameGraph::TransitionState(TextureDesc& desc, ResourceState state)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#include "render/pass/demo_pass.h"
|
#include "render/pass/demo_pass.h"
|
||||||
#include "render/asset/shader.h"
|
#include "render/asset/shader.h"
|
||||||
#include "render/asset/material.h"
|
#include "render/asset/material.h"
|
||||||
#include "render/renderapi.h"
|
#include "render/render_api.h"
|
||||||
#include "asset/resource_system.h"
|
#include "asset/resource_system.h"
|
||||||
#include "render/asset/vertex.h"
|
#include "render/asset/vertex.h"
|
||||||
#include "render/asset/mesh.h"
|
#include "render/asset/mesh.h"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#include "render/tool/glsl_to_spirv.h"
|
#include "render/tool/glsl_to_spirv.h"
|
||||||
#include "render/asset/ubo.h"
|
#include "render/asset/ubo.h"
|
||||||
#include "render/renderapi.h"
|
#include "render/render_api.h"
|
||||||
#include "zlog.h"
|
#include "zlog.h"
|
||||||
#include <shaderc/shaderc.hpp>
|
#include <shaderc/shaderc.hpp>
|
||||||
#include <spirv_cross/spirv_reflect.hpp>
|
#include <spirv_cross/spirv_reflect.hpp>
|
||||||
|
|||||||
@ -30,7 +30,4 @@ namespace api{
|
|||||||
bool isInverted = false;
|
bool isInverted = false;
|
||||||
bool hasAlpha = 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_render_device.h"
|
||||||
#include "ui/ui_module.h"
|
#include "ui/ui_module.h"
|
||||||
#include "ui_render_device_help.inl"
|
#include "ui_render_device_help.inl"
|
||||||
|
#include "render/render_buffer.h"
|
||||||
|
#define CBUFFER_SIZE 16 * 1024
|
||||||
namespace api {
|
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)
|
SINGLETON_DEFINE(UIRenderDevice)
|
||||||
UIRenderDevice::UIRenderDevice(RenderAPI* api) : mApi(api)
|
UIRenderDevice::UIRenderDevice(RenderAPI* api)
|
||||||
{
|
{
|
||||||
|
mImpl = new (GlobalPool()) UIRenderDeviceImpl(api);
|
||||||
SINGLETON_PTR();
|
SINGLETON_PTR();
|
||||||
}
|
}
|
||||||
UIRenderDevice::~UIRenderDevice()
|
UIRenderDevice::~UIRenderDevice()
|
||||||
@ -16,7 +44,7 @@ namespace api {
|
|||||||
}
|
}
|
||||||
const Noesis::DeviceCaps& UIRenderDevice::GetCaps() const
|
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)
|
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{};
|
TextureDesc desc{};
|
||||||
desc.id = -1;
|
desc.id = -1;
|
||||||
desc.format = VKFormat(format, mCaps.linearRendering);
|
desc.format = VKFormat(format, mImpl->mCaps.linearRendering);
|
||||||
desc.width = width;
|
desc.width = width;
|
||||||
desc.height = height;
|
desc.height = height;
|
||||||
desc.mipLevel = numLevels;
|
desc.mipLevel = numLevels;
|
||||||
desc.sampleCount = SAMPLE_COUNT_1;
|
desc.sampleCount = SAMPLE_COUNT_1;
|
||||||
desc.usage = TextureUsage::SAMPLEABLE | TextureUsage::BLIT_DST;
|
desc.usage = TextureUsage::SAMPLEABLE | TextureUsage::BLIT_DST;
|
||||||
desc.state = ResourceState::UNDEFINED;
|
desc.state = ResourceState::UNDEFINED;
|
||||||
mApi->CreateTexture(desc);
|
desc.dimension = TextureDimension::TEX_2D;
|
||||||
return CreateUITexture(desc);
|
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)
|
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;
|
UITexture* uiTex = (UITexture*)texture;
|
||||||
TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .data = data};
|
TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .mipLevel = level, .data = data};
|
||||||
mApi->UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST);
|
mImpl->Context().UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST);
|
||||||
}
|
}
|
||||||
void UIRenderDevice::BeginOffscreenRender()
|
void UIRenderDevice::BeginOffscreenRender()
|
||||||
{
|
{
|
||||||
@ -104,33 +134,19 @@ namespace api {
|
|||||||
}
|
}
|
||||||
void* UIRenderDevice::MapVertices(uint32_t bytes)
|
void* UIRenderDevice::MapVertices(uint32_t bytes)
|
||||||
{
|
{
|
||||||
int b = 10000;
|
auto& ctx = mImpl->Context();
|
||||||
for (int a = 1; a < b; a++) {
|
return mImpl->mVertices.MapBuffer(bytes, ctx.frameNumber, ctx.frameNumber - ctx.frameCount);
|
||||||
b--;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
void UIRenderDevice::UnmapVertices()
|
void UIRenderDevice::UnmapVertices()
|
||||||
{
|
{
|
||||||
int b = 10000;
|
|
||||||
for (int a = 1; a < b; a++) {
|
|
||||||
b--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void* UIRenderDevice::MapIndices(uint32_t bytes)
|
void* UIRenderDevice::MapIndices(uint32_t bytes)
|
||||||
{
|
{
|
||||||
int b = 10000;
|
auto& ctx = mImpl->Context();
|
||||||
for (int a = 1; a < b; a++) {
|
return mImpl->mIndices.MapBuffer(bytes, ctx.frameNumber, ctx.frameNumber - ctx.frameCount);
|
||||||
b--;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
void UIRenderDevice::UnmapIndices()
|
void UIRenderDevice::UnmapIndices()
|
||||||
{
|
{
|
||||||
int b = 10000;
|
|
||||||
for (int a = 1; a < b; a++) {
|
|
||||||
b--;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void UIRenderDevice::DrawBatch(const Noesis::Batch& batch)
|
void UIRenderDevice::DrawBatch(const Noesis::Batch& batch)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,15 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "render/renderapi.h"
|
#include "render/render_api.h"
|
||||||
#include <NsRender/RenderDevice.h>
|
#include <NsRender/RenderDevice.h>
|
||||||
namespace api {
|
namespace api {
|
||||||
|
class UIRenderDeviceImpl;
|
||||||
class UI_API UIRenderDevice final : public Noesis::RenderDevice {
|
class UI_API UIRenderDevice final : public Noesis::RenderDevice {
|
||||||
private:
|
private:
|
||||||
RenderAPI* mApi;
|
UIRenderDeviceImpl* mImpl;
|
||||||
Noesis::DeviceCaps mCaps;
|
|
||||||
SINGLETON_IMPL(UIRenderDevice)
|
SINGLETON_IMPL(UIRenderDevice)
|
||||||
public:
|
public:
|
||||||
UIRenderDevice(RenderAPI* api);
|
UIRenderDevice(RenderAPI* api);
|
||||||
~UIRenderDevice();
|
~UIRenderDevice();
|
||||||
|
static void* operator new(size_t size) {
|
||||||
|
return GlobalPool()->allocate(size, 8);
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
/// From RenderDevice
|
/// From RenderDevice
|
||||||
//@{
|
//@{
|
||||||
|
|||||||
@ -42,10 +42,10 @@ namespace vkn {
|
|||||||
VkImage* image;
|
VkImage* image;
|
||||||
};
|
};
|
||||||
struct ImageUpdator {
|
struct ImageUpdator {
|
||||||
|
TextureUpdateArgs args;
|
||||||
|
VkCommandBuffer command;
|
||||||
VkImage image;
|
VkImage image;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t mipLevel;
|
|
||||||
TextureUpdateArgs args;
|
|
||||||
};
|
};
|
||||||
struct SyncTransferCommand {
|
struct SyncTransferCommand {
|
||||||
uint32_t frameNumber;
|
uint32_t frameNumber;
|
||||||
@ -85,6 +85,6 @@ namespace vkn {
|
|||||||
void UpdateImage(ImageUpdator& elem, TransferBufferType type = TransferBufferType::Graphics);
|
void UpdateImage(ImageUpdator& elem, TransferBufferType type = TransferBufferType::Graphics);
|
||||||
|
|
||||||
bool BeginDynamicCommand(DynamicBufferPool*& poolRef, CommandBuffer& cmd, bool isTransfer);
|
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/render_type.h"
|
||||||
#include "render/type.h"
|
#include "render/type.h"
|
||||||
#define Z_RENDER_DEBUG 1
|
#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 {
|
namespace vkn {
|
||||||
using pmr::Name;
|
using pmr::Name;
|
||||||
using pmr::table;
|
using pmr::table;
|
||||||
|
|||||||
@ -41,13 +41,11 @@ namespace vkn {
|
|||||||
void CreateTexture(TextureDesc& desc)override;
|
void CreateTexture(TextureDesc& desc)override;
|
||||||
ImageViewPtr CreateTextureView(TextureViewKey desc)override;
|
ImageViewPtr CreateTextureView(TextureViewKey desc)override;
|
||||||
SamplerPtr CreateTextureSampler(TextureSampler sampler) override;
|
SamplerPtr CreateTextureSampler(TextureSampler sampler) override;
|
||||||
void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) override;
|
|
||||||
|
|
||||||
void BeginFrame()override;
|
void BeginFrame()override;
|
||||||
void EndFrame()override;
|
void EndFrame()override;
|
||||||
void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) override;
|
void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) override;
|
||||||
void EndRenderPass(RenderPassNode* node) override;
|
void EndRenderPass(RenderPassNode* node) override;
|
||||||
void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override;
|
|
||||||
|
|
||||||
VkPipeline GetPipeline() { return nullptr; };
|
VkPipeline GetPipeline() { return nullptr; };
|
||||||
RenderPassInfo* GetRenderPassInfo(Name name, size_t hash);
|
RenderPassInfo* GetRenderPassInfo(Name name, size_t hash);
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "render/renderapi.h"
|
#include "render/render_api.h"
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
using api::BufferDesc;
|
using api::BufferDesc;
|
||||||
|
using api::RenderPassState;
|
||||||
struct VulkanContext : public api::RenderContext {
|
struct VulkanContext : public api::RenderContext {
|
||||||
VkFence surfaceFence;
|
VkFence surfaceFence;
|
||||||
VkSemaphore surfaceSemaphore;
|
VkSemaphore surfaceSemaphore;
|
||||||
VkSemaphore presentSemaphore;
|
VkSemaphore presentSemaphore;
|
||||||
VkSemaphore graphSemaphore;
|
VkSemaphore graphSemaphore;
|
||||||
|
VkCommandBuffer transferCommand;
|
||||||
VkCommandBuffer surfaceCommand;
|
VkCommandBuffer surfaceCommand;
|
||||||
VkCommandBuffer command;
|
VkCommandBuffer command;
|
||||||
void SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override;
|
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 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 DrawIndexed(uint32_t index_count, uint32_t first_index, uint32_t first_vertex) override;
|
||||||
void ExecuteSurfaceBarriers(const ResourceBarrierDesc& desc) 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 ClearSurface(VkClearColorValue clearValue);
|
||||||
void BeginRecord(VkCommandBufferUsageFlags flag);
|
void BeginRecord(VkCommandBuffer cmd, VkCommandBufferUsageFlags flag);
|
||||||
void EndRecord(VkQueue queue);
|
void EndRecord(VkQueue queue);
|
||||||
|
void FlushCommand();
|
||||||
|
VkCommandBuffer GetTransferCommand();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -32,6 +32,7 @@ namespace vkn {
|
|||||||
VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args);
|
VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args);
|
||||||
void Aquire(VulkanContext& ctx);
|
void Aquire(VulkanContext& ctx);
|
||||||
void Present(VulkanContext& ctx);
|
void Present(VulkanContext& ctx);
|
||||||
|
VkCommandBuffer GetTransferCommand(uint32_t frame) { return mCommands[frame + mFrames]; };
|
||||||
};
|
};
|
||||||
class VULKAN_API VulkanWindow : public api::Window {
|
class VULKAN_API VulkanWindow : public api::Window {
|
||||||
private:
|
private:
|
||||||
@ -49,6 +50,7 @@ namespace vkn {
|
|||||||
}
|
}
|
||||||
void Aquire(VulkanContext& ctx) { mSwapchain->Aquire(ctx); };
|
void Aquire(VulkanContext& ctx) { mSwapchain->Aquire(ctx); };
|
||||||
void Present(VulkanContext& ctx) { mSwapchain->Present(ctx); };
|
void Present(VulkanContext& ctx) { mSwapchain->Present(ctx); };
|
||||||
|
VkCommandBuffer GetTransferCommand(uint32_t frame) { return mSwapchain->GetTransferCommand(frame); };
|
||||||
VulkanSwapchain* Swapchain() {
|
VulkanSwapchain* Swapchain() {
|
||||||
return mSwapchain;
|
return mSwapchain;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,13 +148,14 @@ namespace vkn {
|
|||||||
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
allocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
|
||||||
|
|
||||||
VmaAllocation allocation;
|
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)
|
void BufferWorker::UpdateImage(ImageUpdator& elem, TransferBufferType type)
|
||||||
{
|
{
|
||||||
bool isTransfer = type == TransferBufferType::Transfer;
|
bool isTransfer = type == TransferBufferType::Transfer;
|
||||||
DynamicBufferPool* pPoolRef;
|
DynamicBufferPool* pPoolRef;
|
||||||
CommandBuffer command;
|
CommandBuffer command = elem.command;
|
||||||
if (!BeginDynamicCommand(pPoolRef, command, isTransfer)) {
|
if (!BeginDynamicCommand(pPoolRef, command, isTransfer)) {
|
||||||
Invoke(elem);
|
Invoke(elem);
|
||||||
return;
|
return;
|
||||||
@ -162,25 +163,29 @@ namespace vkn {
|
|||||||
TextureUpdateArgs args = elem.args;
|
TextureUpdateArgs args = elem.args;
|
||||||
// 将数据复制到 Staging Buffer
|
// 将数据复制到 Staging Buffer
|
||||||
DynamicBuffer* uploadBuffer = pPoolRef->FindUploadBuffer(elem.size, mFrameNumber + 1, args.data);
|
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{};
|
VkBufferImageCopy region{};
|
||||||
region.imageOffset.x = args.x;
|
region.imageOffset.x = args.x;
|
||||||
region.imageOffset.y = args.y;
|
region.imageOffset.y = args.y;
|
||||||
region.imageExtent.width = args.width;
|
region.imageExtent.width = args.width;
|
||||||
region.imageExtent.height = args.height;
|
region.imageExtent.height = args.height;
|
||||||
region.imageExtent.depth = 1;
|
region.imageExtent.depth = 1;
|
||||||
region.imageSubresource.mipLevel = elem.mipLevel;
|
region.imageSubresource.mipLevel = args.mipLevel;
|
||||||
region.bufferOffset = uploadBuffer->drawPos;
|
region.bufferOffset = uploadBuffer->drawPos;
|
||||||
region.imageSubresource.layerCount = 1;
|
region.imageSubresource.layerCount = 1;
|
||||||
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
|
||||||
vkCmdCopyBufferToImage(command.Ptr(), (VkBuffer)uploadBuffer->currentPage->pBuffer, elem.image,
|
vkCmdCopyBufferToImage(command.Ptr(), (VkBuffer)uploadBuffer->currentPage->pBuffer, elem.image,
|
||||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
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)
|
bool BufferWorker::BeginDynamicCommand(DynamicBufferPool*& pPoolRef, CommandBuffer& command, bool isTransfer)
|
||||||
{
|
{
|
||||||
pPoolRef = isTransfer ? &mTransferBuffer : &mGraphicsBuffer;
|
pPoolRef = isTransfer ? &mTransferBuffer : &mGraphicsBuffer;
|
||||||
|
if (command.Ptr()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (pPoolRef->commandIndex >= MAX_TRANSFER_SYNC_FENCES) {
|
if (pPoolRef->commandIndex >= MAX_TRANSFER_SYNC_FENCES) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -188,7 +193,7 @@ namespace vkn {
|
|||||||
command.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
command.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void BufferWorker::EndDynamicCommand(DynamicBufferPool* pPoolRef, CommandBuffer& command, bool isTransfer)
|
void BufferWorker::EndDynamicCommand(DynamicBufferPool* pPoolRef, CommandBuffer command, bool isTransfer)
|
||||||
{
|
{
|
||||||
command.EndRecord();
|
command.EndRecord();
|
||||||
pPoolRef->commandIndex++;
|
pPoolRef->commandIndex++;
|
||||||
|
|||||||
@ -340,31 +340,6 @@ namespace vkn {
|
|||||||
vkCreateSampler(backend.GetDevice().Ptr(), &samplerInfo, nullptr, &sampler);
|
vkCreateSampler(backend.GetDevice().Ptr(), &samplerInfo, nullptr, &sampler);
|
||||||
return 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()
|
void VulkanAPI::BeginFrame()
|
||||||
{
|
{
|
||||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
@ -375,28 +350,10 @@ namespace vkn {
|
|||||||
void VulkanAPI::EndFrame()
|
void VulkanAPI::EndFrame()
|
||||||
{
|
{
|
||||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||||
|
ctx.FlushCommand();
|
||||||
window.Present(ctx);
|
window.Present(ctx);
|
||||||
Backend::TransferWorker->TrySyncTransfer(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)
|
void VulkanAPI::BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback)
|
||||||
{
|
{
|
||||||
RenderPassKey config{};
|
RenderPassKey config{};
|
||||||
@ -481,8 +438,10 @@ namespace vkn {
|
|||||||
CommandBuffer cmd = passInfo->commands[context.frame];
|
CommandBuffer cmd = passInfo->commands[context.frame];
|
||||||
ctx.command = cmd.Ptr();
|
ctx.command = cmd.Ptr();
|
||||||
cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||||
|
ctx.renderPassState = RenderPassState::BeginRecord;
|
||||||
if(callback) callback(node);
|
if(callback) callback(node);
|
||||||
vkCmdBeginRenderPass(cmd.Ptr(), &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(cmd.Ptr(), &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
ctx.renderPassState = RenderPassState::BeginRender;
|
||||||
if (clearSurfaceIndex != -1)ctx.ClearSurface(clearValues[clearSurfaceIndex].color);
|
if (clearSurfaceIndex != -1)ctx.ClearSurface(clearValues[clearSurfaceIndex].color);
|
||||||
}
|
}
|
||||||
void VulkanAPI::EndRenderPass(RenderPassNode* node)
|
void VulkanAPI::EndRenderPass(RenderPassNode* node)
|
||||||
@ -492,6 +451,7 @@ namespace vkn {
|
|||||||
CommandBuffer cmd = passInfo->commands[context.frame];
|
CommandBuffer cmd = passInfo->commands[context.frame];
|
||||||
vkCmdEndRenderPass(cmd.Ptr());
|
vkCmdEndRenderPass(cmd.Ptr());
|
||||||
cmd.EndRecord();
|
cmd.EndRecord();
|
||||||
|
ctx.renderPassState = RenderPassState::Default;
|
||||||
VkSemaphore waitSemaphores[8];
|
VkSemaphore waitSemaphores[8];
|
||||||
VkPipelineStageFlags waitDstStageMasks[8];
|
VkPipelineStageFlags waitDstStageMasks[8];
|
||||||
uint32_t semaphoreCount = 0;
|
uint32_t semaphoreCount = 0;
|
||||||
|
|||||||
@ -186,8 +186,12 @@ namespace vkn {
|
|||||||
usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
usageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||||
if (any(usage & TextureUsage::DEPTH_ATTACHMENT))
|
if (any(usage & TextureUsage::DEPTH_ATTACHMENT))
|
||||||
usageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
usageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
|
||||||
if(any(usage & TextureUsage::SAMPLEABLE))
|
if (any(usage & TextureUsage::SAMPLEABLE))
|
||||||
usageFlags |= VK_IMAGE_USAGE_SAMPLED_BIT;
|
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;
|
return usageFlags;
|
||||||
}
|
}
|
||||||
VkImageViewType vkApiGetImageViewType(TextureDimension dimension, uint32_t arraySize)
|
VkImageViewType vkApiGetImageViewType(TextureDimension dimension, uint32_t arraySize)
|
||||||
@ -369,19 +373,21 @@ namespace vkn {
|
|||||||
}
|
}
|
||||||
VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage)
|
VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage)
|
||||||
{
|
{
|
||||||
if (any(usage & BufferUsage::VERTEX)) {
|
switch (usage)
|
||||||
|
{
|
||||||
|
case api::BufferUsage::VERTEX:
|
||||||
return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
|
||||||
}
|
case api::BufferUsage::INDEX:
|
||||||
if (any(usage & BufferUsage::UNIFORM)) {
|
return VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
|
||||||
|
case api::BufferUsage::UNIFORM:
|
||||||
return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
|
||||||
}
|
case api::BufferUsage::SHADER_STORAGE:
|
||||||
if (any(usage & BufferUsage::SHADER_STORAGE)) {
|
|
||||||
return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
|
||||||
}
|
case api::BufferUsage::TRANSFER_SRC:
|
||||||
if (any(usage & BufferUsage::TRANSFER_SRC)) {
|
|
||||||
return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||||
|
default:
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
VkMemoryPropertyFlags vkApiGetMemoryFlags(ResourceMemoryUsage usageFlags) {
|
VkMemoryPropertyFlags vkApiGetMemoryFlags(ResourceMemoryUsage usageFlags) {
|
||||||
VkMemoryPropertyFlags flags = 0;
|
VkMemoryPropertyFlags flags = 0;
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
#include "vkn/backend.h"
|
#include "vkn/backend.h"
|
||||||
#include "vkn/vulkan_api.h"
|
#include "vkn/vulkan_api.h"
|
||||||
#include "vkn/thread/command_worker.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"
|
#include "zlog.h"
|
||||||
namespace vkn {
|
namespace vkn {
|
||||||
void VulkanContext::SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height)
|
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);
|
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)
|
void VulkanContext::ClearSurface(VkClearColorValue clearValue)
|
||||||
{
|
{
|
||||||
// 条件满足时,手动清除附件
|
// 条件满足时,手动清除附件
|
||||||
@ -73,14 +70,14 @@ namespace vkn {
|
|||||||
// 使用 vkCmdClearAttachments 清除颜色附件
|
// 使用 vkCmdClearAttachments 清除颜色附件
|
||||||
vkCmdClearAttachments(command, 1, &clearAttachment, 1, &clearRect);
|
vkCmdClearAttachments(command, 1, &clearAttachment, 1, &clearRect);
|
||||||
}
|
}
|
||||||
void VulkanContext::BeginRecord(VkCommandBufferUsageFlags flag)
|
void VulkanContext::BeginRecord(VkCommandBuffer cmd, VkCommandBufferUsageFlags flag)
|
||||||
{
|
{
|
||||||
VkCommandBufferBeginInfo beginInfo{
|
VkCommandBufferBeginInfo beginInfo{
|
||||||
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,//sType
|
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,//sType
|
||||||
nullptr, //pNext
|
nullptr, //pNext
|
||||||
flag //flags
|
flag //flags
|
||||||
};
|
};
|
||||||
vkBeginCommandBuffer(surfaceCommand, &beginInfo);
|
vkBeginCommandBuffer(cmd, &beginInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VulkanContext::EndRecord(VkQueue queue)
|
void VulkanContext::EndRecord(VkQueue queue)
|
||||||
@ -105,4 +102,83 @@ namespace vkn {
|
|||||||
vkQueueSubmit(queue, 1, &submitInfo, surfaceFence);
|
vkQueueSubmit(queue, 1, &submitInfo, surfaceFence);
|
||||||
graphSemaphore = presentSemaphore;
|
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());
|
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data());
|
||||||
mFences.reserve(mFrames);
|
mFences.reserve(mFrames);
|
||||||
mSurfaces.reserve(imageCount);
|
mSurfaces.reserve(imageCount);
|
||||||
mCommands.reserve(mFrames);
|
mCommands.reserve(mFrames + mFrames);
|
||||||
mSemaphores.reserve(mFrames + mFrames);
|
mSemaphores.reserve(mFrames + mFrames);
|
||||||
TextureDesc desc{};
|
TextureDesc desc{};
|
||||||
desc.width = args.width;
|
desc.width = args.width;
|
||||||
@ -84,6 +84,7 @@ namespace vkn {
|
|||||||
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));
|
||||||
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++) {
|
||||||
|
|||||||
@ -18,8 +18,14 @@ namespace api {
|
|||||||
mView->SetFlags(RenderFlags_PPAA | RenderFlags_LCD);
|
mView->SetFlags(RenderFlags_PPAA | RenderFlags_LCD);
|
||||||
mView->SetSize(1024, 768);
|
mView->SetSize(1024, 768);
|
||||||
mView->GetRenderer()->Init(UIRenderDevice::Ptr());
|
mView->GetRenderer()->Init(UIRenderDevice::Ptr());
|
||||||
|
}
|
||||||
|
void EditorMainWindow::DrawNoesisUI()
|
||||||
|
{
|
||||||
|
mView->Update(0.033);
|
||||||
|
IRenderer* renderer = mView->GetRenderer();
|
||||||
|
renderer->UpdateRenderTree();
|
||||||
|
renderer->RenderOffscreen();
|
||||||
|
renderer->Render();
|
||||||
}
|
}
|
||||||
TextureSampler sampler{
|
TextureSampler sampler{
|
||||||
.filterMag = SamplerMagFilter::LINEAR,
|
.filterMag = SamplerMagFilter::LINEAR,
|
||||||
@ -79,10 +85,6 @@ namespace api {
|
|||||||
InitRenderSurface(graph, ctx.frameCount);
|
InitRenderSurface(graph, ctx.frameCount);
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
//mView->Update(0.033);
|
DrawNoesisUI();
|
||||||
//IRenderer* renderer = mView->GetRenderer();
|
|
||||||
//renderer->UpdateRenderTree();
|
|
||||||
//renderer->RenderOffscreen();
|
|
||||||
//renderer->Render();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user