framegraph support semaphore
This commit is contained in:
parent
a362258a03
commit
0166774b26
2
engine/3rdparty/xmake.lua
vendored
2
engine/3rdparty/xmake.lua
vendored
@ -1,4 +1,4 @@
|
||||
add_requires("spdlog", "lemon", "libsdl", "vulkansdk","shaderc","spirv","spirv-cross")
|
||||
add_requires("mimalloc", {configs = {shared = true, debug = true, copy = true}})
|
||||
add_requires("imgui")
|
||||
add_requires("imgui",{configs = {shared = true, debug = true, copy = true}})
|
||||
includes("*/xmake.lua")
|
||||
1206
engine/modules/engine/render/3rdparty/imgui/imgui_impl_sdl2.cpp
vendored
Normal file
1206
engine/modules/engine/render/3rdparty/imgui/imgui_impl_sdl2.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
50
engine/modules/engine/render/3rdparty/imgui/imgui_impl_sdl2.h
vendored
Normal file
50
engine/modules/engine/render/3rdparty/imgui/imgui_impl_sdl2.h
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
// dear imgui: Platform Backend for SDL2
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
// (Info: SDL2 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support.
|
||||
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [x] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct SDL_Window;
|
||||
struct SDL_Renderer;
|
||||
struct _SDL_GameController;
|
||||
typedef union SDL_Event SDL_Event;
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOther(SDL_Window* window);
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
|
||||
|
||||
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||
enum ImGui_ImplSDL2_GamepadMode { ImGui_ImplSDL2_GamepadMode_AutoFirst, ImGui_ImplSDL2_GamepadMode_AutoAll, ImGui_ImplSDL2_GamepadMode_Manual };
|
||||
IMGUI_IMPL_API void ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode mode, struct _SDL_GameController** manual_gamepads_array = NULL, int manual_gamepads_count = -1);
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@ -1,5 +1,15 @@
|
||||
#include "render/renderapi.h"
|
||||
#include "render/module.h"
|
||||
#ifdef WITH_EDITOR
|
||||
#include "render/imgui_system.h"
|
||||
namespace api {
|
||||
SINGLETON_DEFINE(ImguiSystem)
|
||||
ImguiSystem::ImguiSystem()
|
||||
{
|
||||
SINGLETON_PTR();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
namespace api {
|
||||
SINGLETON_DEFINE(RenderAPI)
|
||||
IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
|
||||
@ -12,10 +22,12 @@ namespace api {
|
||||
}
|
||||
void RenderAPI::Render()
|
||||
{
|
||||
graph.mSurface = context.surface;
|
||||
for (auto view : context.views) {
|
||||
RenderView(view);
|
||||
}
|
||||
#ifdef WITH_EDITOR
|
||||
//ImguiSystem::Ptr()->Render();
|
||||
#endif
|
||||
}
|
||||
RenderAPI::RenderAPI(RenderContext* ctx) : context(*ctx)
|
||||
{
|
||||
|
||||
@ -22,7 +22,7 @@ namespace api {
|
||||
FrameGraphNodePtr AddPresent(const FrameGraphEdgePtr& edge);
|
||||
using TextureSetupFunction = std::function<void(FrameGraph&, class TextureBuilder&)>;
|
||||
FrameGraphEdgePtr CreateTexture(const TextureSetupFunction& setup);
|
||||
|
||||
void InitSurface(const pmr::vector<TextureDesc>& surfaces);
|
||||
void Compile();
|
||||
void Execute(FRenderView& view);
|
||||
void Clear();
|
||||
@ -45,7 +45,7 @@ namespace api {
|
||||
void ExecuteComputePass(RenderPassNode* node, FRenderView& view);
|
||||
void ExecuteCopyPass(RenderPassNode* node, FRenderView& view);
|
||||
|
||||
void ExecuteResourceBarriers(RenderPassNode* node);
|
||||
static void ExecuteResourceBarriers(RenderPassNode* node, RenderPassType type);
|
||||
};
|
||||
}
|
||||
#include "frame_graph_builder.inl"
|
||||
@ -26,12 +26,7 @@ namespace api {
|
||||
class RenderPass;
|
||||
class RenderPassNode;
|
||||
struct FrameGraphNodePtr {
|
||||
enum NodeType : uint8_t {
|
||||
Render,
|
||||
Present,
|
||||
Compute,
|
||||
Copy
|
||||
};
|
||||
using NodeType = RenderPassType;
|
||||
using GraphNodeRef = lemon::ListGraphBase::Node;
|
||||
GraphNodeRef ref;
|
||||
NodeType type{ NodeType::Render };
|
||||
|
||||
@ -1,12 +1,21 @@
|
||||
#pragma once
|
||||
#ifdef WITH_EDITOR
|
||||
#include "module/module_manager.h"
|
||||
namespace api {
|
||||
class RENDER_API ImguiSystem : public ISystem
|
||||
{
|
||||
SINGLETON_IMPL(ImguiSystem)
|
||||
public:
|
||||
ImguiSystem();
|
||||
// 渲染开始和结束
|
||||
// virtual void BeginFrame() = 0;
|
||||
// virtual void EndFrame(void* command_buffer) = 0;
|
||||
virtual void Render() {
|
||||
BeginEditorRender();
|
||||
EditorRender();
|
||||
EndEditorRender();
|
||||
}
|
||||
virtual void BeginEditorRender() = 0;
|
||||
virtual void EditorRender() = 0;
|
||||
virtual void EndEditorRender() = 0;
|
||||
};
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include "module/module_manager.h"
|
||||
namespace api {
|
||||
class RENDER_API RenderModule : public IStaticModule
|
||||
|
||||
@ -8,6 +8,7 @@ namespace api {
|
||||
struct RenderContext {
|
||||
pmr::vector<FRenderView> views;
|
||||
TextureDesc surface;
|
||||
uint32_t frameCount{0};
|
||||
uint32_t frame{ 0 };
|
||||
uint32_t presentFrame{ 0 };
|
||||
virtual void SetViewport(float x, float y, float width, float height, float min_depth, float max_depth) = 0;
|
||||
|
||||
@ -39,7 +39,8 @@ namespace api {
|
||||
virtual void BeginFrame() = 0;
|
||||
virtual void EndFrame() = 0;
|
||||
virtual void RenderView(FRenderView& view);
|
||||
virtual void BeginRenderPass(RenderPassNode* node) = 0;
|
||||
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();
|
||||
|
||||
@ -11,6 +11,12 @@ namespace api {
|
||||
Vulkan,
|
||||
D3D12
|
||||
};
|
||||
enum class RenderPassType : uint8_t {
|
||||
Render,
|
||||
Present,
|
||||
Compute,
|
||||
Copy
|
||||
};
|
||||
enum class BufferUsage {
|
||||
STATIC = 0x01, //!< content modified once, used many times
|
||||
DYNAMIC = 0x02, //!< content modified frequently, used many times
|
||||
@ -84,6 +90,7 @@ namespace api {
|
||||
};
|
||||
enum class TextureDimension
|
||||
{
|
||||
TEX_NULL = 0,
|
||||
TEX_1D = 0x01,
|
||||
TEX_2D = 0x02,
|
||||
TEX_3D = 0x04,
|
||||
@ -176,6 +183,15 @@ namespace api {
|
||||
static BufferDesc Make() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
struct TextureViewDesc {
|
||||
ImagePtr image;
|
||||
TinyImageFormat format : 16;
|
||||
TextureDimension dimension : 8;
|
||||
uint32_t baseArrayLayer : 8;
|
||||
uint32_t layerCount : 8;
|
||||
uint32_t baseMipLevel : 8;
|
||||
uint32_t levelCount : 8;
|
||||
};
|
||||
struct TextureDesc {
|
||||
ImagePtr image;
|
||||
@ -188,17 +204,18 @@ namespace api {
|
||||
uint32_t arraySize : 8;
|
||||
TextureDimension dimension : 4;
|
||||
uint32_t mipLevel : 4;
|
||||
TextureViewDesc ToTextureView() const{
|
||||
TextureViewDesc desc{};
|
||||
desc.image = image;
|
||||
desc.format = format;
|
||||
desc.baseArrayLayer = 0;
|
||||
desc.baseMipLevel = 0;
|
||||
desc.layerCount = 1;
|
||||
desc.levelCount = 1;
|
||||
desc.dimension = dimension;
|
||||
return desc;
|
||||
}
|
||||
};
|
||||
struct TextureViewDesc {
|
||||
ImagePtr image;
|
||||
TinyImageFormat format : 16;
|
||||
ResourceState state : 8;
|
||||
TextureDimension dimension: 8;
|
||||
uint32_t baseArrayLayer : 8;
|
||||
uint32_t layerCount : 8;
|
||||
uint32_t baseMipLevel : 8;
|
||||
uint32_t levelCount : 8;
|
||||
};
|
||||
struct AttachmentDesc {
|
||||
ImagePtr image;
|
||||
ImageViewPtr imageView;
|
||||
@ -213,13 +230,24 @@ namespace api {
|
||||
image = desc.image;
|
||||
return *this;
|
||||
}
|
||||
TextureDesc ToTexture() {
|
||||
TextureDesc ToTexture() const {
|
||||
return TextureDesc{
|
||||
.image = image,
|
||||
.width = width,
|
||||
.height = height,
|
||||
};
|
||||
}
|
||||
TextureViewDesc ToTextureView() const {
|
||||
TextureViewDesc desc{};
|
||||
desc.image = image;
|
||||
desc.format = colorFormat;
|
||||
desc.baseArrayLayer = 0;
|
||||
desc.baseMipLevel = 0;
|
||||
desc.layerCount = 1;
|
||||
desc.levelCount = 1;
|
||||
desc.dimension = dimension;
|
||||
return desc;
|
||||
}
|
||||
};
|
||||
struct TextureBarrier
|
||||
{
|
||||
@ -246,6 +274,7 @@ namespace api {
|
||||
uint8_t mEndOnly : 1;
|
||||
} BufferBarrier;
|
||||
struct ResourceBarrierDesc {
|
||||
RenderPassType type;
|
||||
const BufferBarrier* pBufferBarriers;
|
||||
uint32_t bufferBarriersCount;
|
||||
const TextureBarrier* pTextureBarriers;
|
||||
|
||||
@ -5,7 +5,6 @@ namespace api {
|
||||
if (k1.image != k2.image) return false;
|
||||
if (k1.format != k2.format) return false;
|
||||
if (k1.dimension != k2.dimension) return false;
|
||||
if (k1.state != k2.state) return false;
|
||||
if (k1.baseArrayLayer != k2.baseArrayLayer) return false;
|
||||
if (k1.layerCount != k2.layerCount) return false;
|
||||
if (k1.baseMipLevel != k2.baseMipLevel) return false;
|
||||
@ -49,6 +48,16 @@ namespace api {
|
||||
setup(*this, builder);
|
||||
return edge;
|
||||
}
|
||||
void FrameGraph::InitSurface(const pmr::vector<TextureDesc>& surfaces)
|
||||
{
|
||||
mSurface = surfaces[0];
|
||||
RenderAPI* API = RenderAPI::Ptr();
|
||||
for (auto& surface : surfaces) {
|
||||
TextureViewDesc desc = surface.ToTextureView();
|
||||
//ImageViewPtr view = API->CreateTextureView(desc);
|
||||
//mResourceViewPool.emplace(desc, view);
|
||||
}
|
||||
}
|
||||
void FrameGraph::Compile()
|
||||
{
|
||||
auto end = std::remove_if(mNodes.begin(), mNodes.end(), [this](FrameGraphNodePtr& node) {
|
||||
@ -64,16 +73,16 @@ namespace api {
|
||||
{
|
||||
for (auto node : mNodes) {
|
||||
switch (node.type) {
|
||||
case FrameGraphNodePtr::Render:
|
||||
case RenderPassType::Render:
|
||||
ExecuteRenderPass(node.node, view);
|
||||
break;
|
||||
case FrameGraphNodePtr::Present:
|
||||
case RenderPassType::Present:
|
||||
ExecutePresentPass(node.node, view);
|
||||
break;
|
||||
case FrameGraphNodePtr::Compute:
|
||||
case RenderPassType::Compute:
|
||||
ExecuteComputePass(node.node, view);
|
||||
break;
|
||||
case FrameGraphNodePtr::Copy:
|
||||
case RenderPassType::Copy:
|
||||
ExecuteCopyPass(node.node, view);
|
||||
break;
|
||||
}
|
||||
@ -86,15 +95,16 @@ namespace api {
|
||||
}
|
||||
void FrameGraph::ExecuteRenderPass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
ExecuteResourceBarriers(node);
|
||||
RenderAPI::Ptr()->BeginRenderPass(node);
|
||||
RenderAPI::Ptr()->BeginRenderPass(node, [](RenderPassNode* node) {
|
||||
ExecuteResourceBarriers(node, RenderPassType::Render);
|
||||
});
|
||||
RenderPassContext context{view.context, node};
|
||||
std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
|
||||
RenderAPI::Ptr()->EndRenderPass(node);
|
||||
}
|
||||
void FrameGraph::ExecutePresentPass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
ExecuteResourceBarriers(node);
|
||||
ExecuteResourceBarriers(node, RenderPassType::Present);
|
||||
}
|
||||
void FrameGraph::ExecuteComputePass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
@ -106,12 +116,12 @@ namespace api {
|
||||
CopyPassContext context{};
|
||||
std::get<CopyPassExecuteFunction>(node->executor)(*this, context);
|
||||
}
|
||||
void FrameGraph::ExecuteResourceBarriers(RenderPassNode* node)
|
||||
void FrameGraph::ExecuteResourceBarriers(RenderPassNode* node, RenderPassType type)
|
||||
{
|
||||
pmr::vector<BufferBarrier> bufferBarrier{FramePool()};
|
||||
pmr::vector<TextureBarrier> textureBarrier{ FramePool() };
|
||||
node->ForeachEdge([&, this](FrameResource* resource, FrameGraphEdgePtr edge) {
|
||||
edge.Resolve(this);
|
||||
node->ForeachEdge([&](FrameResource* resource, FrameGraphEdgePtr edge) {
|
||||
edge.Resolve(&RenderAPI::Ptr()->graph);
|
||||
if (!edge || edge.targetState == resource->sourceState) {
|
||||
return;
|
||||
}
|
||||
@ -140,6 +150,7 @@ namespace api {
|
||||
return;
|
||||
}
|
||||
ResourceBarrierDesc desc{};
|
||||
desc.type = type;
|
||||
desc.bufferBarriersCount = bufferBarrier.size();
|
||||
desc.pBufferBarriers = bufferBarrier.data();
|
||||
desc.textureBarriersCount = textureBarrier.size();
|
||||
|
||||
@ -69,7 +69,6 @@ namespace api {
|
||||
}
|
||||
FrameGraph::TextureBuilder& FrameGraph::TextureBuilder::Import(pmr::Name name, AttachmentDesc desc, ResourceState state)
|
||||
{
|
||||
desc.image = nullptr;
|
||||
edge->name = name;
|
||||
edge->resource = desc;
|
||||
edge.targetState = state;
|
||||
|
||||
@ -33,16 +33,8 @@ namespace api {
|
||||
}
|
||||
if (resource->IsAttachment()) {
|
||||
AttachmentDesc& attach = resource->CastTo<AttachmentDesc>();
|
||||
TextureViewDesc view{};
|
||||
view.image = attach.image;
|
||||
view.format = attach.colorFormat;
|
||||
view.state = targetState;
|
||||
view.baseArrayLayer = 0;
|
||||
view.baseMipLevel = 0;
|
||||
view.layerCount = 1;
|
||||
view.levelCount = 1;
|
||||
view.dimension = attach.dimension;
|
||||
attach.imageView = graph->ResolveTextureView(view);
|
||||
TextureViewDesc desc = attach.ToTextureView();
|
||||
attach.imageView = graph->ResolveTextureView(desc);
|
||||
}
|
||||
}
|
||||
FrameGraphNodePtr::FrameGraphNodePtr(GraphNodeRef ref, NodeType type)
|
||||
|
||||
@ -3,8 +3,8 @@ static_component("render","engine")
|
||||
files = {"include/render/asset/*.h"}
|
||||
})
|
||||
add_includedirs("3rdparty", {public = true})
|
||||
add_headerfiles("include/**.h", "include/**.inl")
|
||||
add_files("src/**.cpp")
|
||||
add_headerfiles("include/**.h", "include/**.inl", "3rdparty/imgui/*.h")
|
||||
add_files("src/**.cpp", "3rdparty/imgui/*.cpp")
|
||||
add_deps("asset", "zlib", "core")
|
||||
add_syslinks("user32", {public = true})
|
||||
add_packages("lemon", "libsdl","shaderc","spirv-cross", {public = true})
|
||||
|
||||
1960
engine/modules/render/vulkan/include/imgui/imgui_impl_vulkan.cpp
Normal file
1960
engine/modules/render/vulkan/include/imgui/imgui_impl_vulkan.cpp
Normal file
File diff suppressed because it is too large
Load Diff
211
engine/modules/render/vulkan/include/imgui/imgui_impl_vulkan.h
Normal file
211
engine/modules/render/vulkan/include/imgui/imgui_impl_vulkan.h
Normal file
@ -0,0 +1,211 @@
|
||||
// dear imgui: Renderer Backend for Vulkan
|
||||
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||
|
||||
// Implemented features:
|
||||
// [x] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app.
|
||||
// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h.
|
||||
// You will use those if you want to use this rendering backend in your engine/app.
|
||||
// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by
|
||||
// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code.
|
||||
// Read comments in imgui_impl_vulkan.h.
|
||||
|
||||
#pragma once
|
||||
#ifndef IMGUI_DISABLE
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
// [Configuration] in order to use a custom Vulkan function loader:
|
||||
// (1) You'll need to disable default Vulkan function prototypes.
|
||||
// We provide a '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' convenience configuration flag.
|
||||
// In order to make sure this is visible from the imgui_impl_vulkan.cpp compilation unit:
|
||||
// - Add '#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES' in your imconfig.h file
|
||||
// - Or as a compilation flag in your build system
|
||||
// - Or uncomment here (not recommended because you'd be modifying imgui sources!)
|
||||
// - Do not simply add it in a .cpp file!
|
||||
// (2) Call ImGui_ImplVulkan_LoadFunctions() before ImGui_ImplVulkan_Init() with your custom function.
|
||||
// If you have no idea what this is, leave it alone!
|
||||
//#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES
|
||||
|
||||
// Convenience support for Volk
|
||||
// (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().)
|
||||
//#define IMGUI_IMPL_VULKAN_USE_VOLK
|
||||
|
||||
#if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES)
|
||||
#define VK_NO_PROTOTYPES
|
||||
#endif
|
||||
#if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
// Vulkan includes
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_VOLK
|
||||
#include <volk.h>
|
||||
#else
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
#if defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering)
|
||||
#define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
#endif
|
||||
|
||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||
// [Please zero-clear before use!]
|
||||
// - About descriptor pool:
|
||||
// - A VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
|
||||
// and must contain a pool size large enough to hold a small number of VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptors.
|
||||
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
||||
// - Current version of the backend use 1 descriptor for the font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
|
||||
// - It is expected that as early as Q1 2025 the backend will use a few more descriptors, so aim at 10 + number of desierd calls to ImGui_ImplVulkan_AddTexture().
|
||||
// - About dynamic rendering:
|
||||
// - When using dynamic rendering, set UseDynamicRendering=true and fill PipelineRenderingCreateInfo structure.
|
||||
struct ImGui_ImplVulkan_InitInfo
|
||||
{
|
||||
VkInstance Instance;
|
||||
VkPhysicalDevice PhysicalDevice;
|
||||
VkDevice Device;
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
|
||||
// (Optional)
|
||||
VkPipelineCache PipelineCache;
|
||||
uint32_t Subpass;
|
||||
|
||||
// (Optional) Set to create internal descriptor pool instead of using DescriptorPool
|
||||
uint32_t DescriptorPoolSize;
|
||||
|
||||
// (Optional) Dynamic Rendering
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
bool UseDynamicRendering;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
|
||||
#endif
|
||||
|
||||
// (Optional) Allocation, Debugging
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// Register a texture (VkDescriptorSet == ImTextureID)
|
||||
// FIXME: This is experimental in the sense that we are unsure how to best design/tackle this problem
|
||||
// Please post to https://github.com/ocornut/imgui/pull/914 if you have suggestions.
|
||||
IMGUI_IMPL_API VkDescriptorSet ImGui_ImplVulkan_AddTexture(VkSampler sampler, VkImageView image_view, VkImageLayout image_layout);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet descriptor_set);
|
||||
|
||||
// Optional: load Vulkan functions with a custom function loader
|
||||
// This is only useful with IMGUI_IMPL_VULKAN_NO_PROTOTYPES / VK_NO_PROTOTYPES
|
||||
IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr);
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplVulkan_RenderState
|
||||
{
|
||||
VkCommandBuffer CommandBuffer;
|
||||
VkPipeline Pipeline;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
|
||||
//-------------------------------------------------------------------------
|
||||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
// 1) they facilitate the readability and maintenance of the multiple main.cpp examples files.
|
||||
// 2) the multi-viewport / platform window implementation needs them internally.
|
||||
// Generally we avoid exposing any kind of superfluous high-level helpers in the bindings,
|
||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
|
||||
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGui_ImplVulkanH_Frame;
|
||||
struct ImGui_ImplVulkanH_Window;
|
||||
|
||||
// Helpers
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator);
|
||||
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
||||
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
||||
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
||||
|
||||
// Helper structure to hold the data needed by one rendering frame
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||
// [Please zero-clear before use!]
|
||||
struct ImGui_ImplVulkanH_Frame
|
||||
{
|
||||
VkCommandPool CommandPool;
|
||||
VkCommandBuffer CommandBuffer;
|
||||
VkFence Fence;
|
||||
VkImage Backbuffer;
|
||||
VkImageView BackbufferView;
|
||||
VkFramebuffer Framebuffer;
|
||||
};
|
||||
|
||||
struct ImGui_ImplVulkanH_FrameSemaphores
|
||||
{
|
||||
VkSemaphore ImageAcquiredSemaphore;
|
||||
VkSemaphore RenderCompleteSemaphore;
|
||||
};
|
||||
|
||||
// Helper structure to hold the data needed by one rendering context into one OS window
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||
struct ImGui_ImplVulkanH_Window
|
||||
{
|
||||
int Width;
|
||||
int Height;
|
||||
VkSwapchainKHR Swapchain;
|
||||
VkSurfaceKHR Surface;
|
||||
VkSurfaceFormatKHR SurfaceFormat;
|
||||
VkPresentModeKHR PresentMode;
|
||||
VkRenderPass RenderPass;
|
||||
bool UseDynamicRendering;
|
||||
bool ClearEnable;
|
||||
VkClearValue ClearValue;
|
||||
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
||||
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||
uint32_t SemaphoreIndex; // Current set of swapchain wait semaphores we're using (needs to be distinct from per frame data)
|
||||
ImGui_ImplVulkanH_Frame* Frames;
|
||||
ImGui_ImplVulkanH_FrameSemaphores* FrameSemaphores;
|
||||
|
||||
ImGui_ImplVulkanH_Window()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
PresentMode = (VkPresentModeKHR)~0; // Ensure we get an error if user doesn't set this.
|
||||
ClearEnable = true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
@ -11,6 +11,7 @@
|
||||
namespace vkn {
|
||||
using pmr::Name;
|
||||
using pmr::table;
|
||||
using std::vector;
|
||||
using std::string_view;
|
||||
class CommandBuffer;
|
||||
using voidFn = std::function<void()>;
|
||||
@ -62,6 +63,14 @@ namespace vkn {
|
||||
return meta::MurmurHashFn(this);
|
||||
}
|
||||
};
|
||||
struct RenderPassInfo {
|
||||
RenderPassKey config;
|
||||
vector<VkSemaphore> semaphores;
|
||||
vector<VkCommandBuffer> commands;
|
||||
VkRenderPass Pass() {
|
||||
return config.pass;
|
||||
}
|
||||
};
|
||||
struct FramebufferKey {
|
||||
VkRenderPass pass;
|
||||
VkImageView imageViews[MAX_SUPPORTED_RENDER_TARGET_COUNT * 2 + 1];
|
||||
|
||||
@ -10,13 +10,14 @@ namespace vkn {
|
||||
using api::Material;
|
||||
using api::MaterialInstance;
|
||||
using api::RenderPassNode;
|
||||
using api::RenderPassType;
|
||||
class VULKAN_API VulkanAPI final : public api::RenderAPI{
|
||||
private:
|
||||
VulkanWindow& window;
|
||||
Backend backend;
|
||||
table<Guid, MeshVAO> MeshTable;
|
||||
table<Guid, VulkanPipeline> PipelineTable;
|
||||
table<size_t, RenderPassKey> RenderPassCache;
|
||||
table<size_t, RenderPassInfo> RenderPassCache;
|
||||
table<FramebufferKey, VkFramebuffer> FramebufferCache;
|
||||
public:
|
||||
VulkanAPI();
|
||||
@ -35,12 +36,11 @@ namespace vkn {
|
||||
|
||||
void BeginFrame()override;
|
||||
void EndFrame()override;
|
||||
void BeginRenderPass(RenderPassNode* node) override;
|
||||
void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) override;
|
||||
void EndRenderPass(RenderPassNode* node) override;
|
||||
void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override;
|
||||
|
||||
VkPipeline GetPipeline() { return nullptr; };
|
||||
VkRenderPass GetRenderPass(size_t hash, RenderPassKey& config);
|
||||
const RenderPassInfo& GetRenderPassInfo(size_t hash, const RenderPassKey& config = {});
|
||||
Backend& GetBackend() {
|
||||
return backend;
|
||||
}
|
||||
|
||||
@ -6,6 +6,8 @@ namespace vkn {
|
||||
VkFence surfaceFence;
|
||||
VkSemaphore surfaceSemaphore;
|
||||
VkSemaphore presentSemaphore;
|
||||
VkSemaphore graphSemaphore;
|
||||
VkCommandBuffer surfaceCommand;
|
||||
VkCommandBuffer command;
|
||||
void SetScissor(uint32_t x, uint32_t y, uint32_t width, uint32_t height) override;
|
||||
void SetViewport(float x, float y, float width, float height, float min_depth, float max_depth) override;
|
||||
|
||||
@ -4,6 +4,8 @@ namespace vkn {
|
||||
class VulkanImguiSystem : public api::ImguiSystem {
|
||||
void Initialize() override;
|
||||
void Finalize() override;
|
||||
|
||||
void BeginEditorRender() override;
|
||||
void EditorRender() override;
|
||||
void EndEditorRender() override;
|
||||
};
|
||||
}
|
||||
@ -32,6 +32,12 @@ namespace vkn {
|
||||
VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args);
|
||||
void Aquire(VulkanContext& ctx);
|
||||
void Present(VulkanContext& ctx);
|
||||
int FrameCount() {
|
||||
return mFrames;
|
||||
}
|
||||
const pmr::vector<TextureDesc>& GetSurface() {
|
||||
return mSurfaces;
|
||||
}
|
||||
};
|
||||
class VULKAN_API VulkanWindow : public api::Window {
|
||||
private:
|
||||
@ -50,5 +56,8 @@ namespace vkn {
|
||||
}
|
||||
void Aquire(VulkanContext& ctx) { mSwapchain->Aquire(ctx); };
|
||||
void Present(VulkanContext& ctx) { mSwapchain->Present(ctx); };
|
||||
VulkanSwapchain* Swapchain() {
|
||||
return mSwapchain;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -15,7 +15,6 @@ namespace vkn {
|
||||
void EndRecord();
|
||||
void CmdCopyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size);
|
||||
void Submit(VkQueue& queue,VkFence fence);
|
||||
|
||||
void BindVertexBuffer(VkBuffer buffer, uint32_t offset);
|
||||
void BindIndexBuffers(VkBuffer buffer, uint32_t offset, VkIndexType type);
|
||||
};
|
||||
|
||||
@ -17,6 +17,7 @@ namespace vkn {
|
||||
return mPtr;
|
||||
};
|
||||
CommandBuffer Pop();
|
||||
void PopList(vector<VkCommandBuffer>& list, int size);
|
||||
void Push(CommandBuffer& cmd);
|
||||
};
|
||||
}
|
||||
@ -27,6 +27,7 @@ namespace vkn {
|
||||
VkFence PopFence();
|
||||
void PushWaitFence(VkFence fence);
|
||||
VkSemaphore CreateSemaphore();
|
||||
void CreateSemaphores(vector<VkSemaphore>& list, int size);
|
||||
VkShaderModule CreateShaderModule(const pmr::vector<char>& code);
|
||||
VkShaderModule CreateShaderModule(const pmr::vector<uint32_t>& code);
|
||||
};
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
#include "xmalloc_new_delete.h"
|
||||
#include "vkn/module.h"
|
||||
#include "vkn/vulkan_imgui.h"
|
||||
#include "vkn/loader/vulkan_glsl_loader.h"
|
||||
#include "pmr/frame_allocator.h"
|
||||
using namespace vkn;
|
||||
void VulkanModule::OnLoad(int argc, char** argv)
|
||||
{
|
||||
VulkanGlslLoader::Init();
|
||||
#ifdef WITH_EDITOR
|
||||
AddSystem<VulkanImguiSystem>();
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
}
|
||||
|
||||
void VulkanModule::OnUnload()
|
||||
|
||||
@ -99,7 +99,7 @@ namespace vkn {
|
||||
if (itPass == RenderPassCache.end()) {
|
||||
return;
|
||||
}
|
||||
VkRenderPass renderpass = itPass->second.pass;
|
||||
VkRenderPass renderpass = itPass->second.Pass();
|
||||
pmr::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||
std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules;
|
||||
auto& device = backend.GetDevice();
|
||||
@ -343,6 +343,7 @@ namespace vkn {
|
||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||
window.Aquire(ctx);
|
||||
ctx.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
graph.mSurface = ctx.surface;
|
||||
}
|
||||
void VulkanAPI::EndFrame()
|
||||
{
|
||||
@ -366,9 +367,10 @@ namespace vkn {
|
||||
if (dstStageMask == 0) {
|
||||
dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
|
||||
}
|
||||
vkCmdPipelineBarrier(ctx.command, srcStageMask, dstStageMask, 0, 0, NULL, 0, NULL, imageBarriers.size(), imageBarriers.data());
|
||||
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)
|
||||
void VulkanAPI::BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback)
|
||||
{
|
||||
RenderPassKey config{};
|
||||
FramebufferKey frameKey{.layers = 1};
|
||||
@ -394,14 +396,14 @@ namespace vkn {
|
||||
}
|
||||
frameKey.attachmentCount = i;
|
||||
node->hash = config;
|
||||
VkRenderPass pass = GetRenderPass(node->hash, config);
|
||||
frameKey.pass = pass;
|
||||
RenderPassInfo passInfo = GetRenderPassInfo(node->hash, config);
|
||||
frameKey.pass = passInfo.Pass();
|
||||
auto it = FramebufferCache.find(frameKey);
|
||||
VkFramebuffer framebuffer = it->second;
|
||||
if (it == FramebufferCache.end()) {
|
||||
VkFramebufferCreateInfo framebufferInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
|
||||
.renderPass = pass,
|
||||
.renderPass = frameKey.pass,
|
||||
.attachmentCount = frameKey.attachmentCount,
|
||||
.pAttachments = frameKey.imageViews,
|
||||
.width = frameKey.width,
|
||||
@ -418,24 +420,57 @@ namespace vkn {
|
||||
VkRenderPassBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.pNext = VK_NULL_HANDLE,
|
||||
.renderPass = pass,
|
||||
.renderPass = frameKey.pass,
|
||||
.framebuffer = framebuffer,
|
||||
.renderArea = renderAarea,
|
||||
.clearValueCount = frameKey.attachmentCount,
|
||||
.pClearValues = clearValues
|
||||
};
|
||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||
vkCmdBeginRenderPass(ctx.command, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
CommandBuffer cmd = passInfo.commands[context.frame];
|
||||
ctx.command = cmd.Ptr();
|
||||
cmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
if(callback) callback(node);
|
||||
vkCmdBeginRenderPass(cmd.Ptr(), &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
}
|
||||
void VulkanAPI::EndRenderPass(RenderPassNode* node)
|
||||
{
|
||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||
vkCmdEndRenderPass(ctx.command);
|
||||
RenderPassInfo passInfo = GetRenderPassInfo(node->hash);
|
||||
CommandBuffer cmd = passInfo.commands[context.frame];
|
||||
vkCmdEndRenderPass(cmd.Ptr());
|
||||
cmd.EndRecord();
|
||||
VkSemaphore waitSemaphores[8];
|
||||
VkPipelineStageFlags waitDstStageMasks[8];
|
||||
uint32_t semaphoreCount = 0;
|
||||
if (ctx.surfaceSemaphore) {
|
||||
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
waitSemaphores[semaphoreCount++] = ctx.surfaceSemaphore;
|
||||
ctx.surfaceSemaphore = nullptr;
|
||||
}
|
||||
for (auto& it : node->inEdges) {
|
||||
RenderPassInfo inputInfo = GetRenderPassInfo(it->source->hash);
|
||||
waitDstStageMasks[semaphoreCount] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
waitSemaphores[semaphoreCount++] = inputInfo.semaphores[context.frame];
|
||||
}
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &cmd.Ptr();
|
||||
submitInfo.pSignalSemaphores = &passInfo.semaphores[context.frame];
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||
submitInfo.pWaitDstStageMask = waitDstStageMasks;
|
||||
submitInfo.waitSemaphoreCount = semaphoreCount;
|
||||
if (!ctx.graphSemaphore) {
|
||||
ctx.graphSemaphore = passInfo.semaphores[context.frame];
|
||||
}
|
||||
vkQueueSubmit(Backend::RenderWorker->GetQueue().Ptr(), 1, &submitInfo, nullptr);
|
||||
}
|
||||
VkRenderPass VulkanAPI::GetRenderPass(size_t hash, RenderPassKey& config) {
|
||||
const RenderPassInfo& VulkanAPI::GetRenderPassInfo(size_t hash, const RenderPassKey& config) {
|
||||
auto it = RenderPassCache.find(hash);
|
||||
if (it != RenderPassCache.end()) {
|
||||
return it->second.pass;
|
||||
return it->second;
|
||||
}
|
||||
// Set up some const aliases for terseness.
|
||||
const VkAttachmentLoadOp kClear = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
@ -599,8 +634,13 @@ namespace vkn {
|
||||
};
|
||||
}
|
||||
renderPassInfo.attachmentCount = attachmentIndex;
|
||||
VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &config.pass);
|
||||
RenderPassCache.emplace(hash, config);
|
||||
return config.pass;
|
||||
VkRenderPass pass;
|
||||
VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &pass);
|
||||
RenderPassInfo info{ config};
|
||||
info.config.pass = pass;
|
||||
backend.GetDevice().CreateSemaphores(info.semaphores, context.frameCount);
|
||||
Backend::RenderWorker->GetCommandPool().PopList(info.commands, context.frameCount);
|
||||
RenderPassCache.emplace(hash, info);
|
||||
return RenderPassCache[hash];
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +191,7 @@ namespace vkn {
|
||||
}
|
||||
VkImageViewType vkApiGetImageViewType(TextureDimension dimension, uint32_t arraySize)
|
||||
{
|
||||
if (any(dimension & TextureDimension::TEX_1D)) {
|
||||
if (dimension == TextureDimension::TEX_NULL || any(dimension & TextureDimension::TEX_1D)) {
|
||||
return arraySize > 1 ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D;
|
||||
}
|
||||
if (any(dimension & TextureDimension::TEX_CUBE)) {
|
||||
@ -203,7 +203,7 @@ namespace vkn {
|
||||
if (any(dimension & TextureDimension::TEX_3D)) {
|
||||
return VK_IMAGE_VIEW_TYPE_3D;
|
||||
}
|
||||
return VK_IMAGE_VIEW_TYPE_MAX_ENUM;
|
||||
return arraySize > 1 ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D;
|
||||
}
|
||||
VkImageType vkApiGetImageType(TextureDimension dimension)
|
||||
{
|
||||
|
||||
@ -55,18 +55,18 @@ namespace vkn {
|
||||
nullptr, //pNext
|
||||
flag //flags
|
||||
};
|
||||
vkBeginCommandBuffer(command, &beginInfo);
|
||||
vkBeginCommandBuffer(surfaceCommand, &beginInfo);
|
||||
}
|
||||
void VulkanContext::EndRecord(VkQueue queue)
|
||||
{
|
||||
vkEndCommandBuffer(command);
|
||||
vkEndCommandBuffer(surfaceCommand);
|
||||
VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; // 等待渲染阶段
|
||||
VkSemaphore waitSemaphores[] = { surfaceSemaphore };
|
||||
VkSemaphore waitSemaphores[] = { graphSemaphore };
|
||||
VkSemaphore signalSemaphores[] = { presentSemaphore };// 渲染完成信号量
|
||||
VkSubmitInfo submitInfo{};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &command;
|
||||
submitInfo.pCommandBuffers = &surfaceCommand;
|
||||
|
||||
submitInfo.waitSemaphoreCount = 1;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores;
|
||||
@ -75,5 +75,6 @@ namespace vkn {
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
submitInfo.pSignalSemaphores = signalSemaphores;
|
||||
vkQueueSubmit(queue, 1, &submitInfo, surfaceFence);
|
||||
graphSemaphore = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,18 +1,22 @@
|
||||
#include "vkn/vulkan_imgui.h"
|
||||
#include "vkn/vulkan_window.h"
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/vulkan_api_help.h"
|
||||
#include "vkn/backend.h"
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "vkn/wrapper/instance.h"
|
||||
#include "vkn/wrapper/queue.h"
|
||||
#include "render/window.h"
|
||||
#include "imgui.h"
|
||||
#include "backends/imgui_impl_sdl2.h"
|
||||
#include "backends/imgui_impl_vulkan.h"
|
||||
#include "imgui/imgui_impl_vulkan.h"
|
||||
#include "imgui/imgui_impl_sdl2.h"
|
||||
#include "tinyimageformat/tinyimageformat_apis.h"
|
||||
namespace vkn {
|
||||
static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE;
|
||||
void CreateDescriptorPool(VkDevice device, VkDescriptorPool& descriptorPool) {
|
||||
static VkRenderPass g_RenderPass = VK_NULL_HANDLE;
|
||||
static VkCommandPool g_CommandPool = VK_NULL_HANDLE;
|
||||
static std::vector<VkCommandBuffer> g_CommandBuffers;
|
||||
static std::vector<VkFramebuffer> g_FrameBuffers;
|
||||
static std::vector<VkSemaphore> g_RenderFinishSemaphores;
|
||||
VkDescriptorPool CreateDescriptorPool(VkDevice device) {
|
||||
VkDescriptorPoolSize pool_sizes[] =
|
||||
{
|
||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||
@ -33,42 +37,198 @@ namespace vkn {
|
||||
pool_info.maxSets = 1000 * IM_ARRAYSIZE(pool_sizes);
|
||||
pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes);
|
||||
pool_info.pPoolSizes = pool_sizes;
|
||||
VkResult err = vkCreateDescriptorPool(device, &pool_info, VK_NULL_HANDLE, &descriptorPool);
|
||||
VkDescriptorPool descriptorPool;
|
||||
vkCreateDescriptorPool(device, &pool_info, VK_NULL_HANDLE, &descriptorPool);
|
||||
return descriptorPool;
|
||||
}
|
||||
void CreateRenderPass(VulkanAPI* API) {
|
||||
RenderPassKey config{};
|
||||
config.colorFormat[0] = (VkFormat)TinyImageFormat_ToVkFormat(API->context.surface.format);
|
||||
config.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||
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_UNDEFINED;
|
||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
|
||||
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.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
dependency.srcAccessMask = 0; // or VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
||||
|
||||
VkRenderPassCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
|
||||
info.attachmentCount = 1;
|
||||
info.pAttachments = &colorAttachment;
|
||||
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 CreateFrameBuffer(VulkanAPI* API, VkRenderPass renderPass, const pmr::vector<TextureDesc>& surfaces) {
|
||||
VkDevice device = API->GetBackend().GetDevice().Ptr();
|
||||
g_FrameBuffers.resize(surfaces.size());
|
||||
VkFramebuffer* framebuffer = g_FrameBuffers.data();
|
||||
for (auto& surface : surfaces)
|
||||
{
|
||||
VkFramebufferCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
|
||||
info.renderPass = renderPass;
|
||||
info.pAttachments = (VkImageView*)API->graph.ResolveTextureView(surface.ToTextureView());
|
||||
info.attachmentCount = 1;
|
||||
info.width = surface.width;
|
||||
info.height = surface.height;
|
||||
info.layers = 1;
|
||||
vkCreateFramebuffer(device, &info, VK_NULL_HANDLE, framebuffer++);
|
||||
}
|
||||
}
|
||||
void CreateCommandPool(VkDevice device, int queueFamilyIndex, int frames) {
|
||||
VkCommandPool commandPool;
|
||||
// 创建一个专用的CommandPool
|
||||
{
|
||||
VkCommandPoolCreateInfo commandPoolCreateInfo = {};
|
||||
commandPoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex;
|
||||
commandPoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||
|
||||
if (vkCreateCommandPool(device, &commandPoolCreateInfo, VK_NULL_HANDLE, &commandPool) != VK_SUCCESS)
|
||||
throw std::runtime_error("Could not create graphics command pool");
|
||||
}
|
||||
|
||||
// 创建专用的CommandBuffer
|
||||
{
|
||||
g_CommandBuffers.resize(frames);
|
||||
|
||||
VkCommandBufferAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
allocInfo.commandPool = commandPool;
|
||||
allocInfo.commandBufferCount = frames;
|
||||
|
||||
if (vkAllocateCommandBuffers(device, &allocInfo, g_CommandBuffers.data()) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to allocate command buffers!");
|
||||
}
|
||||
g_RenderFinishSemaphores.resize(frames);
|
||||
|
||||
for (size_t i = 0; i < frames; i++)
|
||||
{
|
||||
VkSemaphoreCreateInfo semaphoreInfo = {};
|
||||
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &g_RenderFinishSemaphores[i]) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to create synchronization objects for a frame!");
|
||||
}
|
||||
}
|
||||
void VulkanImguiSystem::Initialize()
|
||||
{
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // 可选:启用键盘导航
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // 可选:启用Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // 可选:启用多视口
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
ImGui_ImplSDL2_InitForVulkan(api::Window::Ptr()->GetPtr());
|
||||
Backend& backend = VulkanAPI::Ptr()->GetBackend();
|
||||
VulkanAPI* API = VulkanAPI::Ptr();
|
||||
VulkanWindow* window = VulkanWindow::Ptr();
|
||||
Backend& backend = API->GetBackend();
|
||||
Queue* pQueue = backend.GetDevice().GetQueue(Queue::RenderQueue);
|
||||
CreateDescriptorPool(backend.GetDevice().Ptr(), g_DescriptorPool);
|
||||
VkDescriptorPool descriptorPool = CreateDescriptorPool(backend.GetDevice().Ptr());
|
||||
VkRenderPass renderPass = CreateRenderPass(API->graph.mSurface.format, backend.GetDevice().Ptr());
|
||||
|
||||
ImGui_ImplVulkan_InitInfo init_info = {};
|
||||
init_info.Instance = backend.GetInstance().Ptr();
|
||||
init_info.PhysicalDevice = backend.GetDevice().GetPhysical();
|
||||
init_info.Device = backend.GetDevice().Ptr();
|
||||
init_info.QueueFamily = pQueue->QueueFamilyIndex();
|
||||
init_info.Queue = pQueue->Ptr();
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.DescriptorPool = descriptorPool;
|
||||
init_info.MinImageCount = 2;
|
||||
init_info.ImageCount = swapchainImageCount;
|
||||
init_info.ImageCount = window->Swapchain()->FrameCount();
|
||||
init_info.RenderPass = renderPass;
|
||||
init_info.PipelineCache = VK_NULL_HANDLE;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = VK_NULL_HANDLE;
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
|
||||
ImGui_ImplVulkan_Init(&init_info, renderPass);
|
||||
g_RenderPass = renderPass;
|
||||
auto& surfaces = window->Swapchain()->GetSurface();
|
||||
//CreateFrameBuffer(API, renderPass, surfaces);
|
||||
//CreateCommandPool(backend.GetDevice().Ptr(), pQueue->QueueFamilyIndex(), surfaces.size());
|
||||
}
|
||||
void VulkanImguiSystem::Finalize()
|
||||
{
|
||||
|
||||
}
|
||||
void VulkanImguiSystem::BeginEditorRender()
|
||||
{
|
||||
ImGui_ImplVulkan_NewFrame();
|
||||
ImGui_ImplSDL2_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
void VulkanImguiSystem::EditorRender()
|
||||
{
|
||||
static float my_float = 0.5f;
|
||||
ImGui::Begin("Hello, ImGui!");
|
||||
ImGui::Text("This is some useful text.");
|
||||
ImGui::SliderFloat("float", &my_float, 0.0f, 1.0f);
|
||||
ImGui::End();
|
||||
|
||||
ImGui::Render();
|
||||
}
|
||||
void VulkanImguiSystem::EndEditorRender()
|
||||
{
|
||||
/*
|
||||
VulkanAPI* API = VulkanAPI::Ptr();
|
||||
uint32_t frame = API->context.frame;
|
||||
CommandBuffer commandBuffer = CommandBuffer(g_CommandBuffers[frame]);
|
||||
commandBuffer.Reset();
|
||||
commandBuffer.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
|
||||
|
||||
VkRenderPassBeginInfo renderPassinfo = {};
|
||||
renderPassinfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
renderPassinfo.renderPass = g_RenderPass;
|
||||
renderPassinfo.framebuffer = g_FrameBuffers[frame];
|
||||
renderPassinfo.renderArea.extent.width = API->graph.mSurface.width;
|
||||
renderPassinfo.renderArea.extent.height = API->graph.mSurface.height;
|
||||
renderPassinfo.clearValueCount = 0;
|
||||
vkCmdBeginRenderPass(commandBuffer.Ptr(), &renderPassinfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||
// Record Imgui Draw Data and draw funcs into command buffer
|
||||
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), commandBuffer.Ptr());
|
||||
vkCmdEndRenderPass(commandBuffer.Ptr());
|
||||
commandBuffer.EndRecord();
|
||||
|
||||
// 提交CommandBuffer
|
||||
pmr::vector<VkPipelineStageFlags> waitStages{FramePool()};
|
||||
waitStages.resize(renderAPI->curWaitSemaphores.size(), VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
|
||||
vector<VkSemaphore> waitSemaphores = renderAPI->curWaitSemaphores;
|
||||
|
||||
waitStages.push_back(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
|
||||
waitSemaphores.push_back(renderAPI->presentImageAvailableSemaphores[renderAPI->currentFrame]);
|
||||
|
||||
VkSubmitInfo submitInfo = {};
|
||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submitInfo.pCommandBuffers = &commandBuffer.Ptr();
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pWaitSemaphores = waitSemaphores.data();
|
||||
submitInfo.pWaitDstStageMask = waitStages.data();
|
||||
submitInfo.waitSemaphoreCount = static_cast<uint32_t>(waitSemaphores.size());
|
||||
submitInfo.pSignalSemaphores = &g_RenderFinishSemaphores[renderAPI->currentFrame];
|
||||
submitInfo.signalSemaphoreCount = 1;
|
||||
|
||||
VkFence fence = renderAPI->inFlightFences[renderAPI->currentFrame];
|
||||
if (vkQueueSubmit(renderAPI->graphicsQueue, 1, &submitInfo, fence) != VK_SUCCESS)
|
||||
throw std::runtime_error("failed to submit draw command buffer!");
|
||||
|
||||
renderAPI->curWaitSemaphores = { g_RenderFinishSemaphores[renderAPI->currentFrame] };*/
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,8 @@ namespace vkn {
|
||||
args.width = mWidth;
|
||||
args.height = mHeight;
|
||||
mSwapchain = new (GlobalPool()) VulkanSwapchain(backend.GetDevice(), surface, args);
|
||||
api->graph.mSurface = mSwapchain->mSurfaces[0];
|
||||
api->context.frameCount = args.frames;
|
||||
api->graph.InitSurface(mSwapchain->mSurfaces);
|
||||
return true;
|
||||
}
|
||||
VulkanSwapchain::VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args)
|
||||
@ -88,7 +89,7 @@ namespace vkn {
|
||||
VkFence surfaceFence = mFences[ctx.frame];
|
||||
VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame];
|
||||
ctx.surface = mSurfaces[ctx.frame];
|
||||
ctx.command = mCommands[ctx.frame];
|
||||
ctx.surfaceCommand = mCommands[ctx.frame];
|
||||
ctx.surfaceFence = surfaceFence;
|
||||
ctx.surfaceSemaphore = surfaceSemaphore;
|
||||
ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames];
|
||||
|
||||
@ -49,6 +49,13 @@ namespace vkn {
|
||||
mPool.pop_back();
|
||||
return buffer;
|
||||
}
|
||||
void CommandPool::PopList(vector<VkCommandBuffer>& list, int size)
|
||||
{
|
||||
list.reserve(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.push_back(AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY));
|
||||
}
|
||||
}
|
||||
void CommandPool::Push(CommandBuffer& cmd)
|
||||
{
|
||||
cmd.Reset();
|
||||
|
||||
@ -97,6 +97,13 @@ namespace vkn {
|
||||
VkResult result = vkCreateSemaphore(mPtr, &semaphoreInfo, nullptr, &semaphore);
|
||||
return semaphore;
|
||||
}
|
||||
void Device::CreateSemaphores(vector<VkSemaphore>& list, int size)
|
||||
{
|
||||
list.reserve(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
list.push_back(CreateSemaphore());
|
||||
}
|
||||
}
|
||||
VkShaderModule Device::CreateShaderModule(const pmr::vector<char>& code)
|
||||
{
|
||||
VkShaderModuleCreateInfo createInfo = {};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
shared_module("vulkan","engine")
|
||||
add_headerfiles("include/**.h","include/**.inl")
|
||||
add_files("src/**.cpp", "include/volk/volk.c")
|
||||
add_headerfiles("include/**.h")
|
||||
add_files("src/**.cpp", "include/volk/volk.c", "include/imgui/*.cpp")
|
||||
add_packages("vulkansdk", {public = true})
|
||||
add_dependency("engine", {public = true})
|
||||
on_load(function (target)
|
||||
|
||||
@ -2,10 +2,17 @@
|
||||
#include "data/global.h"
|
||||
#include "render/window.h"
|
||||
#include "render/renderapi.h"
|
||||
#include "imgui.h"
|
||||
namespace api {
|
||||
void EditorModule::OnLoad(int argc, char** argv)
|
||||
{
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // 可选:启用键盘导航
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // 可选:启用Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // 可选:启用多视口
|
||||
ImGui::StyleColorsDark();
|
||||
}
|
||||
|
||||
void EditorModule::OnUnload()
|
||||
|
||||
@ -3,6 +3,9 @@
|
||||
#include "data/global.h"
|
||||
#include "vkn/vulkan_window.h"
|
||||
#include "vkn/vulkan_api.h"
|
||||
#ifdef WITH_EDITOR
|
||||
#include "imgui/imgui_impl_sdl2.h"
|
||||
#endif
|
||||
#include "render/pass/demo_pass.h"
|
||||
#include <iostream>
|
||||
using namespace api;
|
||||
@ -20,8 +23,13 @@ void ZWorldModule::OnLoad(int argc, char** argv)
|
||||
}
|
||||
API->Init();
|
||||
API->context.views.push_back({});
|
||||
#ifdef WITH_EDITOR //绑定窗口交互
|
||||
ImGui_ImplSDL2_InitForVulkan(window->GetPtr());
|
||||
#endif
|
||||
}
|
||||
void ZWorldModule::Initialize()
|
||||
{
|
||||
}
|
||||
|
||||
void ZWorldModule::OnUnload()
|
||||
{
|
||||
}
|
||||
@ -37,10 +45,11 @@ void ZWorldModule::MainLoop()
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
API->graph.AddRenderPass<DemoPass>();
|
||||
API->BeginFrame();
|
||||
API->graph.AddRenderPass<DemoPass>();
|
||||
API->Render();
|
||||
API->EndFrame();
|
||||
FramePool()->reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@ class ZWORLD_API ZWorldModule : public api::IMainModule
|
||||
{
|
||||
public:
|
||||
void OnLoad(int argc, char** argv) override;
|
||||
void Initialize()override;
|
||||
void OnUnload() override;
|
||||
void InitMetaData(void) override;
|
||||
void MainLoop()override;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user