vulkan ui system
This commit is contained in:
parent
53e206e7c2
commit
2ea409e6d2
@ -44,6 +44,7 @@ namespace api {
|
||||
mWindows.push_back(ptr);
|
||||
return ptr;
|
||||
}
|
||||
virtual void Render(FrameGraph& graph, RenderPassContext& ctx) = 0;
|
||||
ImTextureID AddTexture(FrameGraph& graph, TextureDesc& desc, TextureSampler sampler);
|
||||
virtual ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) = 0;
|
||||
};
|
||||
|
||||
@ -84,6 +84,11 @@ namespace api {
|
||||
UITexture* uiTex = (UITexture*)texture;
|
||||
TextureUpdateArgs args{.x = x, .y = y, .width = width,.height = height, .mipLevel = level, .data = data};
|
||||
Context().UpdateTexture(uiTex->desc, args, ResourceState::TRANSFER_DST);
|
||||
for (auto& barrier : mTextureBarriers) {
|
||||
if (barrier.mTexture.image == uiTex->desc.image) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
mTextureBarriers.push_back(uiTex->desc.ToBarrier(ResourceState::TRANSFER_DST, ResourceState::READ_ONLY));
|
||||
}
|
||||
void UIRenderDevice::BeginOffscreenRender()
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include "asset/res/guid.h"
|
||||
#include "backend.h"
|
||||
#ifdef API_DEBUG
|
||||
#define gLogSemaphore(...) zlog::error(__VA_ARGS__)
|
||||
#define gLogSemaphore(...) //zlog::info(__VA_ARGS__)
|
||||
#else
|
||||
#define gLogSemaphore(...)
|
||||
#endif
|
||||
|
||||
@ -6,20 +6,15 @@ namespace vkn {
|
||||
using api::FrameGraph;
|
||||
using api::RenderPassContext;
|
||||
using api::RenderPassBuilder;
|
||||
using api::RenderEditorContext;
|
||||
class VulkanImguiEditor : public api::EditorSystem {
|
||||
public:
|
||||
void Initialize() override;
|
||||
void Finalize() override;
|
||||
|
||||
void Render(FrameGraph& graph, RenderPassContext& ctx) override;
|
||||
ImTextureID AddTexture(ImageViewPtr imageview, SamplerPtr sampler, ResourceState state) override;
|
||||
|
||||
void Render(FrameGraph& graph, RenderEditorContext& ctx);
|
||||
void OnBeginRenderFrame(FrameGraph& graph, uint32_t frame);
|
||||
static VulkanImguiEditor* Ptr() {
|
||||
return (VulkanImguiEditor*)api::EditorSystem::Ptr();
|
||||
};
|
||||
static void Setup(FrameGraph& graph, RenderPassBuilder& builder);
|
||||
static void Execute(FrameGraph&, RenderPassContext&);
|
||||
};
|
||||
}
|
||||
@ -2,10 +2,16 @@
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "ui/ui_render_system.h"
|
||||
#include "editor/editor_system.h"
|
||||
#include "render/graph/frame_graph.h"
|
||||
#include <NsCore/HashMap.h>
|
||||
namespace vkn {
|
||||
using Noesis::BaseVector;
|
||||
using api::UITexture;
|
||||
using api::FrameGraph;
|
||||
using api::RenderPassContext;
|
||||
using api::RenderPassBuilder;
|
||||
using api::RenderEditorContext;
|
||||
struct Layout
|
||||
{
|
||||
uint32_t signature;
|
||||
@ -52,9 +58,14 @@ namespace vkn {
|
||||
VkShaderModule mPixelShaders[Noesis::Shader::Count];
|
||||
Layout mLayouts[Noesis::Shader::Count];
|
||||
public:
|
||||
inline static Name UIPassName{ "UIPass" };
|
||||
void InitNoesisRender(bool linearRendering, bool stereoSupport, SampleCount sampleCount)override;
|
||||
void BeginRender(api::RenderContext* context) override;
|
||||
void DrawBatch(const Noesis::Batch& batch) override;
|
||||
public:
|
||||
void OnBeginRenderFrame(FrameGraph& graph, uint32_t frame);
|
||||
static void Setup(FrameGraph& graph, RenderPassBuilder& builder);
|
||||
static void Execute(FrameGraph&, RenderPassContext&);
|
||||
public:
|
||||
void SetBuffers(const Noesis::Batch& batch);
|
||||
void BindDescriptors(const Noesis::Batch& batch, const Layout& layout);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "vkn/wrapper/instance.h"
|
||||
#include "vkn/wrapper/queue.h"
|
||||
#include "vkn/vulkan_ui_system.h"
|
||||
#include "imgui/imgui_impl_vulkan.h"
|
||||
#include "imgui/imgui_impl_sdl2.h"
|
||||
#include "data/global.h"
|
||||
@ -40,59 +41,6 @@ namespace vkn {
|
||||
vkCreateDescriptorPool(device, &pool_info, VK_NULL_HANDLE, &descriptorPool);
|
||||
return descriptorPool;
|
||||
}
|
||||
VkRenderPass CreateRenderPass(TinyImageFormat format, VkDevice device) {
|
||||
VkAttachmentDescription colorAttachment = {};
|
||||
colorAttachment.format = (VkFormat)TinyImageFormat_ToVkFormat(format);
|
||||
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
VkAttachmentDescription stencilAttachment = {};
|
||||
stencilAttachment.format = VK_FORMAT_S8_UINT;
|
||||
stencilAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
stencilAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
stencilAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
stencilAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
stencilAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
stencilAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
stencilAttachment.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkAttachmentReference colorAttachmentRef = {};
|
||||
colorAttachmentRef.attachment = 0;
|
||||
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkSubpassDescription subpass = {};
|
||||
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
subpass.colorAttachmentCount = 1;
|
||||
subpass.pColorAttachments = &colorAttachmentRef;
|
||||
|
||||
VkSubpassDependency dependency = {};
|
||||
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
|
||||
dependency.dstSubpass = 0;
|
||||
dependency.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
|
||||
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT;
|
||||
VkAttachmentDescription attachmentList[2] = { colorAttachment , stencilAttachment };
|
||||
VkRenderPassCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
info.attachmentCount = 2;
|
||||
info.pAttachments = attachmentList;
|
||||
info.subpassCount = 1;
|
||||
info.pSubpasses = &subpass;
|
||||
info.dependencyCount = 1;
|
||||
info.pDependencies = &dependency;
|
||||
VkRenderPass renderPass;
|
||||
if (vkCreateRenderPass(device, &info, VK_NULL_HANDLE, &renderPass) != VK_SUCCESS)
|
||||
throw std::runtime_error("Could not create Dear ImGui's render pass");
|
||||
return renderPass;
|
||||
}
|
||||
void VulkanImguiEditor::Initialize()
|
||||
{
|
||||
VulkanAPI* API = VulkanAPI::Ptr();
|
||||
@ -101,7 +49,8 @@ namespace vkn {
|
||||
Queue* pQueue = backend.GetDevice().GetQueue(Queue::RenderQueue);
|
||||
VkDescriptorPool descriptorPool = CreateDescriptorPool(backend.GetDevice().Ptr());
|
||||
TextureDesc surface = API->context.surface;
|
||||
VkRenderPass renderPass = CreateRenderPass(surface.format, backend.GetDevice().Ptr());
|
||||
auto renderInfo = API->GetRenderPassInfo(VulkanUISystem::UIPassName, 0);
|
||||
VkRenderPass renderPass = renderInfo->pass;
|
||||
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
init_info.Instance = backend.GetInstance().Ptr();
|
||||
@ -118,8 +67,6 @@ namespace vkn {
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = VK_NULL_HANDLE;
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
API->SetRenderPassInfo(ImguiPassName, renderPass);
|
||||
EventSystem::Ptr()->BeginRenderFrame.Subscribe(&VulkanImguiEditor::OnBeginRenderFrame, this);
|
||||
}
|
||||
void VulkanImguiEditor::Finalize()
|
||||
{
|
||||
@ -130,52 +77,17 @@ namespace vkn {
|
||||
VkDescriptorSet descriptorSet = ImGui_ImplVulkan_AddTexture((VkSampler)sampler, (VkImageView)imageview, vkApiGetImageLayout(state));
|
||||
return reinterpret_cast<ImTextureID>(descriptorSet);
|
||||
}
|
||||
void VulkanImguiEditor::Render(FrameGraph& graph, RenderEditorContext& ctx)
|
||||
void VulkanImguiEditor::Render(FrameGraph& graph, RenderPassContext& context)
|
||||
{
|
||||
for (auto win : mWindows)
|
||||
{
|
||||
win->Draw(graph, ctx);
|
||||
}
|
||||
}
|
||||
void VulkanImguiEditor::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame)
|
||||
{
|
||||
graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface;
|
||||
if (gEngineConfig.IsRenderEditorSurface) {
|
||||
graph.mEditorSurfaceID = graph.mSurfaceID;
|
||||
graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame);
|
||||
}
|
||||
graph.AddRenderPass<VulkanImguiEditor>();
|
||||
}
|
||||
void VulkanImguiEditor::Setup(FrameGraph& graph, RenderPassBuilder& builder)
|
||||
{
|
||||
TextureDesc stencil = graph.GetRenderSurface();
|
||||
stencil.id = 0;
|
||||
stencil.format = TinyImageFormat_S8_UINT;
|
||||
stencil.image = nullptr;
|
||||
stencil.usage = TextureUsage::STENCIL_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT;
|
||||
graph.AcquireTexture(stencil);
|
||||
builder.Name(ImguiPassName)
|
||||
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
|
||||
.Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT)
|
||||
.Write(stencil, ResourceState::DEPTH_ATTACHMENT);
|
||||
if (gEngineConfig.IsRenderEditorSurface) {
|
||||
builder.Read(graph.GetSurface(), ResourceState::READ_ONLY);
|
||||
}
|
||||
}
|
||||
void VulkanImguiEditor::Execute(FrameGraph& graph, RenderPassContext& context)
|
||||
{
|
||||
auto& surface = graph.GetRenderSurface();
|
||||
context->SetViewport(0.0f, 0.0f, (float)surface.width, (float)surface.height, 0.f, 1.f);
|
||||
context->SetScissor(0, 0, surface.width, surface.height);
|
||||
|
||||
graph.GetRenderSurface().state = ResourceState::PRESENT;
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
VulkanImguiEditor* editor = VulkanImguiEditor::Ptr();
|
||||
RenderEditorContext editorContext{.editor = editor, .frame = context->frame, .frameCount = context->frameCount };
|
||||
editor->Render(graph, editorContext);
|
||||
RenderEditorContext editorContext{ .editor = this, .frame = context->frame, .frameCount = context->frameCount };
|
||||
for (auto win : mWindows)
|
||||
{
|
||||
win->Draw(graph, editorContext);
|
||||
}
|
||||
|
||||
ImGui::Render();
|
||||
VulkanContext& ctx = *(VulkanContext*)context.parent;
|
||||
|
||||
@ -10,10 +10,10 @@ using namespace vkn;
|
||||
void VulkanModule::OnLoad(int argc, char** argv)
|
||||
{
|
||||
VulkanGlslLoader::Init();
|
||||
AddSystem<VulkanUISystem>();
|
||||
#ifdef WITH_EDITOR
|
||||
AddSystem<VulkanImguiEditor>();
|
||||
#endif // WITH_EDITOR
|
||||
AddSystem<VulkanUISystem>();
|
||||
}
|
||||
|
||||
void VulkanModule::OnUnload()
|
||||
|
||||
@ -1,29 +1,71 @@
|
||||
#include "vkn/vulkan_ui_system.h"
|
||||
#include "noesis/vulkan_noesis_help.h"
|
||||
#include "vkn/vulkan_api_help.h"
|
||||
#include "vkn/vulkan_api.h"
|
||||
#ifdef WTIH_EDITOR
|
||||
#include "editor/editor_system.h"
|
||||
#endif // WTIH_EDITOR
|
||||
#include "ui/utils/fast_lz.h"
|
||||
#include "event/event_system.h"
|
||||
#include "data/global.h"
|
||||
#include "noesis/vulkan_noesis_help.h"
|
||||
#define DESCRIPTOR_POOL_MAX_SETS 128
|
||||
namespace vkn {
|
||||
using api::FastLZ;
|
||||
using api::DynamicBuffer;
|
||||
using api::UITexture;
|
||||
using namespace api;
|
||||
void vkn::VulkanUISystem::OnBeginRenderFrame(FrameGraph& graph, uint32_t frame)
|
||||
{
|
||||
#ifdef WITH_EDITOR
|
||||
graph.mIsRenderEditorSurface = gEngineConfig.IsRenderEditorSurface;
|
||||
if (gEngineConfig.IsRenderEditorSurface) {
|
||||
graph.mEditorSurfaceID = graph.mSurfaceID;
|
||||
graph.mSurfaceID = graph.GetTextureID(FrameGraph::NameEditorSurface, frame);
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
graph.AddRenderPass<VulkanUISystem>();
|
||||
}
|
||||
void VulkanUISystem::Setup(FrameGraph& graph, RenderPassBuilder& builder)
|
||||
{
|
||||
TextureDesc stencil = graph.GetRenderSurface();
|
||||
stencil.id = 0;
|
||||
stencil.format = TinyImageFormat_S8_UINT;
|
||||
stencil.image = nullptr;
|
||||
stencil.usage = TextureUsage::STENCIL_ATTACHMENT | TextureUsage::DEPTH_ATTACHMENT;
|
||||
graph.AcquireTexture(stencil);
|
||||
builder.Name(UIPassName)
|
||||
.Type(RenderPassNodeType::Imgui, RenderPassNodeFlag::Output)
|
||||
.Write(graph.GetRenderSurface(), ResourceState::COLOR_ATTACHMENT)
|
||||
.Write(stencil, ResourceState::DEPTH_ATTACHMENT);
|
||||
if (gEngineConfig.IsRenderEditorSurface) {
|
||||
builder.Read(graph.GetSurface(), ResourceState::READ_ONLY);
|
||||
}
|
||||
}
|
||||
void VulkanUISystem::Execute(FrameGraph& graph, RenderPassContext& context)
|
||||
{
|
||||
auto& surface = graph.GetRenderSurface();
|
||||
context->SetViewport(0.0f, 0.0f, (float)surface.width, (float)surface.height, 0.f, 1.f);
|
||||
context->SetScissor(0, 0, surface.width, surface.height);
|
||||
graph.GetRenderSurface().state = ResourceState::PRESENT;
|
||||
#ifdef WITH_EDITOR
|
||||
EditorSystem::Ptr()->Render(graph, context);
|
||||
#endif // WITH_EDITOR
|
||||
}
|
||||
void VulkanUISystem::InitNoesisRender(bool linearRendering, bool stereoSupport, SampleCount sampleCount_)
|
||||
{
|
||||
mDevice = &VulkanAPI::Ptr()->GetBackend().GetDevice();
|
||||
auto info = VulkanAPI::Ptr()->GetRenderPassInfo("ImguiPass", 0);
|
||||
mRenderPass = info->pass;
|
||||
VulkanAPI* API = VulkanAPI::Ptr();
|
||||
mDevice = &API->GetBackend().GetDevice();
|
||||
mHasExtendedDynamicState = false;
|
||||
mIsLinearRendering = linearRendering;
|
||||
VkPhysicalDeviceProperties mDeviceProperties;
|
||||
vkGetPhysicalDeviceProperties(mDevice->GetPhysical(), &mDeviceProperties);
|
||||
mMinUniformBufferOffsetAlignment = mDeviceProperties.limits.minUniformBufferOffsetAlignment;
|
||||
VkSampleCountFlagBits sampleCount = vkApiGetSmpleCountFlag(sampleCount_);
|
||||
//CreateRenderPass(sampleCount);
|
||||
CreateRenderPass(sampleCount);
|
||||
CreateLayouts();
|
||||
LoadShaders(stereoSupport);
|
||||
CreatePipelines(sampleCount);
|
||||
CreateSamplers();
|
||||
CreateDescriptorPool();
|
||||
EventSystem::Ptr()->BeginRenderFrame.Subscribe(&VulkanUISystem::OnBeginRenderFrame, this);
|
||||
API->SetRenderPassInfo(UIPassName, mRenderPass);
|
||||
}
|
||||
void VulkanUISystem::BeginRender(api::RenderContext* context) {
|
||||
VulkanContext* ctx = (VulkanContext*)context;
|
||||
@ -31,6 +73,8 @@ namespace vkn {
|
||||
mFrameNumber = ctx->frameNumber;
|
||||
mSafeFrameNumber = ctx->frameNumber - ctx->frameCount;
|
||||
mWaitTransferCount = 0;
|
||||
mCachedIndexBuffer = nullptr;
|
||||
mCachedPipeline = nullptr;
|
||||
}
|
||||
void VulkanUISystem::DrawBatch(const Noesis::Batch& batch)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user