diff --git a/engine/3rdparty/xmake.lua b/engine/3rdparty/xmake.lua
index 1b9be27..47a4a0f 100644
--- a/engine/3rdparty/xmake.lua
+++ b/engine/3rdparty/xmake.lua
@@ -1,4 +1,4 @@
-add_requires("spdlog", "vulkansdk","shaderc","spirv","spirv-cross")
+add_requires("spdlog", "vulkansdk","shaderc","spirv","spirv-cross","stb")
add_requires("mimalloc", {configs = {shared = true, debug = true, copy = true}})
--add_requires("imgui",{configs = {shared = true, debug = true, copy = true}})
add_requires("noesis",{configs = {shared = true, copy = true}})
diff --git a/engine/assets/noesis/Fonts/Aero Matics Regular.ttf b/engine/assets/noesis/Fonts/Aero Matics Regular.ttf
new file mode 100644
index 0000000..d3c7290
Binary files /dev/null and b/engine/assets/noesis/Fonts/Aero Matics Regular.ttf differ
diff --git a/engine/assets/noesis/Fonts/Caladea-Regular.ttf b/engine/assets/noesis/Fonts/Caladea-Regular.ttf
new file mode 100644
index 0000000..86b9381
Binary files /dev/null and b/engine/assets/noesis/Fonts/Caladea-Regular.ttf differ
diff --git a/engine/assets/noesis/Fonts/CourierPrime-Regular.ttf b/engine/assets/noesis/Fonts/CourierPrime-Regular.ttf
new file mode 100644
index 0000000..4f638f6
Binary files /dev/null and b/engine/assets/noesis/Fonts/CourierPrime-Regular.ttf differ
diff --git a/engine/assets/noesis/Fonts/Muli-Bold.ttf b/engine/assets/noesis/Fonts/Muli-Bold.ttf
new file mode 100644
index 0000000..9383139
Binary files /dev/null and b/engine/assets/noesis/Fonts/Muli-Bold.ttf differ
diff --git a/engine/assets/noesis/Fonts/Muli-Italic.ttf b/engine/assets/noesis/Fonts/Muli-Italic.ttf
new file mode 100644
index 0000000..207ab18
Binary files /dev/null and b/engine/assets/noesis/Fonts/Muli-Italic.ttf differ
diff --git a/engine/assets/noesis/Fonts/Muli-Regular.ttf b/engine/assets/noesis/Fonts/Muli-Regular.ttf
new file mode 100644
index 0000000..9776a3e
Binary files /dev/null and b/engine/assets/noesis/Fonts/Muli-Regular.ttf differ
diff --git a/engine/assets/noesis/Fonts/WidgetIcons.ttf b/engine/assets/noesis/Fonts/WidgetIcons.ttf
new file mode 100644
index 0000000..9d897fd
Binary files /dev/null and b/engine/assets/noesis/Fonts/WidgetIcons.ttf differ
diff --git a/engine/assets/noesis/Images/Nature.png b/engine/assets/noesis/Images/Nature.png
new file mode 100644
index 0000000..dbe4f72
Binary files /dev/null and b/engine/assets/noesis/Images/Nature.png differ
diff --git a/engine/assets/noesis/Images/file.png b/engine/assets/noesis/Images/file.png
new file mode 100644
index 0000000..5f2d923
Binary files /dev/null and b/engine/assets/noesis/Images/file.png differ
diff --git a/engine/assets/noesis/Images/floppy-disk.png b/engine/assets/noesis/Images/floppy-disk.png
new file mode 100644
index 0000000..4a2c34c
Binary files /dev/null and b/engine/assets/noesis/Images/floppy-disk.png differ
diff --git a/engine/assets/noesis/Images/folder-closed.png b/engine/assets/noesis/Images/folder-closed.png
new file mode 100644
index 0000000..10d62fe
Binary files /dev/null and b/engine/assets/noesis/Images/folder-closed.png differ
diff --git a/engine/assets/noesis/Images/folder-open.png b/engine/assets/noesis/Images/folder-open.png
new file mode 100644
index 0000000..a55cbd7
Binary files /dev/null and b/engine/assets/noesis/Images/folder-open.png differ
diff --git a/engine/assets/noesis/Images/recycling-bin.png b/engine/assets/noesis/Images/recycling-bin.png
new file mode 100644
index 0000000..f756f5f
Binary files /dev/null and b/engine/assets/noesis/Images/recycling-bin.png differ
diff --git a/engine/assets/noesis/Images/search.png b/engine/assets/noesis/Images/search.png
new file mode 100644
index 0000000..4347fff
Binary files /dev/null and b/engine/assets/noesis/Images/search.png differ
diff --git a/engine/assets/noesis/Menu.xaml b/engine/assets/noesis/Menu.xaml
new file mode 100644
index 0000000..676dcac
--- /dev/null
+++ b/engine/assets/noesis/Menu.xaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/engine/include/editor/window/editor_main_window.h b/engine/include/editor/window/editor_main_window.h
index 7167916..534608a 100644
--- a/engine/include/editor/window/editor_main_window.h
+++ b/engine/include/editor/window/editor_main_window.h
@@ -1,4 +1,10 @@
#pragma once
+#include "ui/ui_window.h"
namespace api {
+ class EditorMainWindow : public UIWindow {
+ public:
+ using UIWindow::UIWindow;
+ void InitializeComponent() override;
+ };
}
\ No newline at end of file
diff --git a/engine/modules/engine/app/impl/app_impl.inl b/engine/modules/engine/app/impl/app_impl.inl
index 87e82f9..77fb44d 100644
--- a/engine/modules/engine/app/impl/app_impl.inl
+++ b/engine/modules/engine/app/impl/app_impl.inl
@@ -2,5 +2,4 @@
#include "data/global.h"
namespace api {
APP_API EngineConfig gEngineConfig{};
- IMPLEMENT_STATIC_MODULE(APP_API, AppModule, app)
}
\ No newline at end of file
diff --git a/engine/modules/engine/asset/impl/resource_system_impl.inl b/engine/modules/engine/asset/impl/resource_system_impl.inl
index c4569d4..6a37a12 100644
--- a/engine/modules/engine/asset/impl/resource_system_impl.inl
+++ b/engine/modules/engine/asset/impl/resource_system_impl.inl
@@ -298,6 +298,5 @@ namespace api {
{
impl->SetFileFlag(name, flag);
}
- IMPLEMENT_STATIC_MODULE(ASSET_API, AssetModule, asset)
}
diff --git a/engine/modules/engine/core/impl/module_manager_impl.inl b/engine/modules/engine/core/impl/module_manager_impl.inl
index f880a70..761d7ef 100644
--- a/engine/modules/engine/core/impl/module_manager_impl.inl
+++ b/engine/modules/engine/core/impl/module_manager_impl.inl
@@ -246,5 +246,4 @@ namespace api {
{
return impl->spawnStaticModule(name);
}
- IMPLEMENT_STATIC_MODULE(CORE_API, CoreModule, core)
}
\ No newline at end of file
diff --git a/engine/modules/engine/core/include/os/package_path.h b/engine/modules/engine/core/include/os/package_path.h
index 41160b6..70c7638 100644
--- a/engine/modules/engine/core/include/os/package_path.h
+++ b/engine/modules/engine/core/include/os/package_path.h
@@ -66,5 +66,6 @@ namespace api
return "";
}
pmr::string RealPath()const;
+ static pmr::string RealPath(const char* str);
};
}
\ No newline at end of file
diff --git a/engine/modules/engine/core/src/os/package_path.cpp b/engine/modules/engine/core/src/os/package_path.cpp
index 2766ed9..1e36c90 100644
--- a/engine/modules/engine/core/src/os/package_path.cpp
+++ b/engine/modules/engine/core/src/os/package_path.cpp
@@ -5,5 +5,9 @@ namespace api {
{
return FileManager::Ptr()->RealPath(*this);
}
+ pmr::string PackagePath::RealPath(const char* str)
+ {
+ return FileManager::Ptr()->RealPath(str);
+ }
}
diff --git a/engine/modules/engine/render/impl/renderapi_impl.inl b/engine/modules/engine/render/impl/renderapi_impl.inl
index 0916c9f..65dc4ab 100644
--- a/engine/modules/engine/render/impl/renderapi_impl.inl
+++ b/engine/modules/engine/render/impl/renderapi_impl.inl
@@ -2,7 +2,6 @@
#include "render/render_module.h"
namespace api {
SINGLETON_DEFINE(RenderAPI)
- IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
void RenderAPI::RenderView(FRenderView& view)
{
view.context = &context;
diff --git a/engine/modules/engine/render/include/render/graph/frame_graph.h b/engine/modules/engine/render/include/render/graph/frame_graph.h
index 19cd273..3eb5df6 100644
--- a/engine/modules/engine/render/include/render/graph/frame_graph.h
+++ b/engine/modules/engine/render/include/render/graph/frame_graph.h
@@ -7,7 +7,7 @@ namespace api {
{
public:
struct TextureID{
- uint32_t id;
+ int32_t id;
uint32_t tick;
};
uint32_t mTickStamp{1};
@@ -45,7 +45,7 @@ namespace api {
void TransitionState(TextureDesc& desc, ResourceState state);
bool ResolveState(TextureDesc& desc, ResourceState& srcstart, ResourceState& dststate);
bool ResolveState(BufferDesc& desc, ResourceState& srcstart, ResourceState& dststate);
- TextureDesc& ResolveTexture(uint32_t id);
+ TextureDesc& ResolveTexture(int32_t id);
TextureDesc ResourceTexture(Name name, int num);
ImageViewPtr ResolveTextureView(TextureDesc& desc);
ImageViewPtr ResolveTextureView(TextureViewKey key);
diff --git a/engine/modules/engine/render/include/render/render_buffer.h b/engine/modules/engine/render/include/render/render_buffer.h
new file mode 100644
index 0000000..9c45b7d
--- /dev/null
+++ b/engine/modules/engine/render/include/render/render_buffer.h
@@ -0,0 +1,144 @@
+#pragma once
+#define PREALLOCATED_DYNAMIC_BUFFER_PAGES 2
+#include "renderapi.h"
+namespace api {
+ struct DynamicBufferDesc {
+ uint32_t size;
+ uint32_t pos;
+ uint32_t drawPos;
+ BufferUsage usage;
+ ResourceMemoryUsage memoryUsage;
+ };
+ struct DynamicBuffer : public DynamicBufferDesc
+ {
+ struct Page
+ {
+ uint32_t hash;
+ uint32_t frameNumber;
+ void* pBuffer;
+ void* pAllocation;
+ void* pMappingAddr;
+ Page* next;
+ };
+ struct PageAllocator
+ {
+ struct Block
+ {
+ Page pages[16];
+ Block* next;
+ };
+ uint32_t pageIndex;
+ uint32_t numPages;
+ Block* blocks = nullptr;
+ };
+ Page* currentPage;
+ Page* freePages;
+ Page* pendingPages;
+ PageAllocator allocator;
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ void InitBuffer(uint32_t _size, BufferUsage _usage, ResourceMemoryUsage _memoryUsage)
+ {
+ pos = 0;
+ drawPos = 0;
+ size = _size;
+ usage = _usage;
+ memoryUsage = _memoryUsage;
+
+ pendingPages = nullptr;
+ freePages = nullptr;
+ allocator.numPages = 0;
+ allocator.pageIndex = 0;
+ for (uint32_t i = 0; i < PREALLOCATED_DYNAMIC_BUFFER_PAGES; i++)
+ {
+ Page* page = AllocatePage();
+ page->next = freePages;
+ freePages = page;
+ }
+
+ currentPage = freePages;
+ freePages = freePages->next;
+ }
+ static Page* AllocatePageMemory(PageAllocator& allocator)
+ {
+ using Block = PageAllocator::Block;
+ if (!allocator.blocks || allocator.pageIndex == _countof(Block::pages))
+ {
+ Block* block = (Block*)xmalloc(sizeof(Block));
+ block->next = allocator.blocks;
+ allocator.blocks = block;
+ allocator.pageIndex = 0;
+ }
+ allocator.numPages++;
+ return allocator.blocks->pages + allocator.pageIndex++;
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ Page* AllocatePage()
+ {
+ Page* page = AllocatePageMemory(allocator);
+ memset(page, 0, sizeof(Page));
+ BufferDesc desc{};
+ desc.size = size;
+ desc.usage = usage;
+ desc.memoryUsage = memoryUsage;
+ RenderAPI::Ptr()->CreateBuffer(desc);
+ page->pAllocation = desc.pAllocation;
+ page->pBuffer = desc.buffer;
+ page->pMappingAddr = desc.pMappingAddr;
+ return page;
+ }
+ void* MapBuffer(uint32_t _size, uint32_t frameNumber, uint32_t safeFrameNumber) {
+ if (pos + _size > size)
+ {
+ // We ran out of space in the current page, get a new one
+ // Move the current one to pending and insert a GPU fence
+ currentPage->frameNumber = frameNumber;
+ currentPage->next = pendingPages;
+ pendingPages = currentPage;
+
+ // If there is one free slot get it
+ if (freePages != nullptr)
+ {
+ currentPage = freePages;
+ freePages = freePages->next;
+ }
+ else
+ {
+ // Move pages already processed by GPU from pending to free
+ Page** it = &pendingPages->next;
+ while (*it != nullptr)
+ {
+ if ((*it)->frameNumber > safeFrameNumber)
+ {
+ it = &((*it)->next);
+ }
+ else
+ {
+ // Once we find a processed page, the rest of pages must be also processed
+ Page* page = *it;
+ *it = nullptr;
+
+ freePages = page;
+ break;
+ }
+ }
+
+ if (freePages != nullptr)
+ {
+ currentPage = freePages;
+ freePages = freePages->next;
+ }
+ else
+ {
+ currentPage = AllocatePage();
+ }
+ }
+
+ pos = 0;
+ }
+
+ drawPos = pos;
+ pos = pos + _size;
+ return (uint8_t*)currentPage->pMappingAddr + drawPos;
+ }
+ };
+}
\ No newline at end of file
diff --git a/engine/modules/engine/render/include/render/render_context.h b/engine/modules/engine/render/include/render/render_context.h
index 3d972db..d667251 100644
--- a/engine/modules/engine/render/include/render/render_context.h
+++ b/engine/modules/engine/render/include/render/render_context.h
@@ -12,6 +12,7 @@ namespace api {
uint32_t frameCount{0};
uint32_t frame{ 0 };
uint32_t presentFrame{ 0 };
+ uint32_t frameNumber{ 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 BindIndexBuffer(BufferDesc desc, uint32_t index_stride) = 0;
diff --git a/engine/modules/engine/render/include/render/render_type.h b/engine/modules/engine/render/include/render/render_type.h
index 4e369cd..d84d514 100644
--- a/engine/modules/engine/render/include/render/render_type.h
+++ b/engine/modules/engine/render/include/render/render_type.h
@@ -38,21 +38,49 @@ namespace api {
DYNAMIC = 0x02, //!< content modified frequently, used many times
VERTEX = 0x04,
UNIFORM = 0x08,
- SHADER_STORAGE = 0x10
+ SHADER_STORAGE = 0x10,
+ TRANSFER_SRC = 0x20,
};
- enum class ResourceMemoryUsage : uint8_t
+ /*
+ 扩展的内存用途标志:
+ GPU_RENDERING:专门为渲染操作设计的内存,常用于存储纹理、帧缓冲等图形资源。
+ GPU_STORAGE:用于存储不需要频繁更新的数据,例如大容量缓冲区或其他不常变动的资源。
+ GPU_COMPUTE:用于计算着色器或其他 GPU 计算任务。可以是读取和写入的内存类型,但它主要用于计算而非渲染。
+
+ 与主机的交互:
+ HOST_VISIBLE:标志该内存可以被主机访问,适用于从 CPU 到 GPU 或反向传输的场景。
+ HOST_COHERENT:标志该内存在 CPU 和 GPU 之间的一致性,不需要显式同步。
+
+ 懒加载和静态数据:
+ LAZY_ALLOCATED:懒加载内存,适用于 GPU 程序中的延迟加载资源。
+ STATIC:静态数据,如常量缓冲区、着色器程序,通常在初始化时填充并且在后续使用中不变化。
+ */
+ enum class ResourceMemoryUsage : uint16_t
{
/// No intended memory usage specified.
UNKNOWN = 0,
/// Memory will be used on device only, no need to be mapped on host.
- GPU_ONLY = 1,
+ GPU_ONLY = 0x01,
/// Memory will be mapped on host. Could be used for transfer to device.
- CPU_ONLY = 2,
+ CPU_ONLY = 0x02,
/// Memory will be used for frequent (dynamic) updates from host and reads on device.
- CPU_TO_GPU = 3,
+ CPU_TO_GPU = 0x04,
/// Memory will be used for writing on device and readback on host.
- GPU_TO_CPU = 4,
- COUNT,
+ GPU_TO_CPU = 0x08,
+ /// Memory is intended to be used for rendering or graphics purposes.
+ GPU_RENDERING = 0x10,
+ /// Memory will be used for storage or large buffers that don't require frequent updates.
+ GPU_STORAGE = 0x20,
+ /// Memory is visible to the host and the device, can be used for both read and write.
+ HOST_VISIBLE = 0x40,
+ /// Memory will be lazily allocated and can be used for GPU resources that are not immediately needed.
+ LAZY_ALLOCATED = 0x80,
+ /// Memory is coherent for both host and device, meaning no explicit synchronization is needed.
+ HOST_COHERENT = 0x100,
+ /// Static data, such as constant buffers or shader resources, that will not change after initialization.
+ STATIC = 0x200,
+ /// Memory intended for use by a compute shader, can be mapped or un-mapped depending on use case.
+ GPU_COMPUTE = 0x400,
};
enum SampleCount : uint8_t
{
@@ -198,9 +226,10 @@ namespace api {
struct BufferBarrier;
struct TextureBarrier;
struct BufferDesc {
- BufferPtr buffer;
- void* mappingAddr;
- uint32_t size;
+ BufferPtr buffer;
+ void* pAllocation;
+ void* pMappingAddr;
+ uint32_t size;
BufferUsage usage;
ResourceMemoryUsage memoryUsage;
static BufferDesc Make() {
@@ -228,7 +257,7 @@ namespace api {
}
};
struct TextureKey {
- uint32_t id;
+ int32_t id;
uint16_t width;
uint16_t height;
uint16_t depth;
@@ -335,6 +364,13 @@ namespace api {
float clearDepth;
uint32_t clearStencil;
};
+ struct TextureUpdateArgs {
+ uint32_t x;
+ uint32_t y;
+ uint32_t width;
+ uint32_t height;
+ const void* data;
+ };
}
#include "meta/hash.h"
namespace std {
diff --git a/engine/modules/engine/render/include/render/renderapi.h b/engine/modules/engine/render/include/render/renderapi.h
index 53ad743..5441577 100644
--- a/engine/modules/engine/render/include/render/renderapi.h
+++ b/engine/modules/engine/render/include/render/renderapi.h
@@ -36,6 +36,7 @@ namespace api {
virtual void CreateTexture(TextureDesc& desc) = 0;
virtual ImageViewPtr CreateTextureView(TextureViewKey desc) = 0;
virtual SamplerPtr CreateTextureSampler(TextureSampler sampler) = 0;
+ virtual void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) = 0;
virtual void BeginFrame() = 0;
virtual void EndFrame() = 0;
virtual void RenderView(FRenderView& view);
diff --git a/engine/modules/engine/render/src/graph/frame_graph.cpp b/engine/modules/engine/render/src/graph/frame_graph.cpp
index 3c350fb..a6b2374 100644
--- a/engine/modules/engine/render/src/graph/frame_graph.cpp
+++ b/engine/modules/engine/render/src/graph/frame_graph.cpp
@@ -231,9 +231,9 @@ namespace api {
{
return true;
}
- TextureDesc& FrameGraph::ResolveTexture(uint32_t id)
+ TextureDesc& FrameGraph::ResolveTexture(int32_t id)
{
- if (!id || id > mTexturePool.size()) {
+ if (id <= 0 || id > mTexturePool.size()) {
return mTexturePool[0];//empty
}
TextureDesc& texture = mTexturePool[id - 1];
@@ -292,6 +292,7 @@ namespace api {
if (it != mTextureKeyMap.end()) {
for (auto& id : it->second) {
if (id.tick != mTickStamp) {
+ id.tick = mTickStamp;
desc.id = id.id;
return;
}
diff --git a/engine/modules/engine/ui/impl/ui_render_device_help.inl b/engine/modules/engine/ui/impl/ui_render_device_help.inl
new file mode 100644
index 0000000..98ef8db
--- /dev/null
+++ b/engine/modules/engine/ui/impl/ui_render_device_help.inl
@@ -0,0 +1,36 @@
+#include
+namespace api{
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ static TinyImageFormat VKFormat(Noesis::TextureFormat::Enum format, bool sRGB)
+ {
+ switch (format)
+ {
+ case Noesis::TextureFormat::RGBA8: return sRGB ? TinyImageFormat_B8G8R8A8_SRGB : TinyImageFormat_B8G8R8A8_UNORM;
+ case Noesis::TextureFormat::RGBX8: return sRGB ? TinyImageFormat_B8G8R8A8_SRGB : TinyImageFormat_B8G8R8A8_UNORM;
+ case Noesis::TextureFormat::R8: return TinyImageFormat_R8_UNORM;
+ default: NS_ASSERT_UNREACHABLE;
+ }
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ class UITexture final : public Noesis::Texture
+ {
+ public:
+ UITexture(TextureDesc desc) : desc(desc) {}
+ ~UITexture()
+ {
+
+ }
+ uint32_t GetWidth() const override { return desc.width; }
+ uint32_t GetHeight() const override { return desc.height; }
+ bool HasMipMaps() const override { return desc.mipLevel > 1; }
+ bool IsInverted() const override { return isInverted; }
+ bool HasAlpha() const override { return hasAlpha; }
+
+ TextureDesc desc;
+ bool isInverted = false;
+ bool hasAlpha = false;
+ };
+ static Noesis::Ptr CreateUITexture(TextureDesc& desc) {
+ return Noesis::MakePtr(desc);
+ }
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/impl/ui_render_device_impl.inl b/engine/modules/engine/ui/impl/ui_render_device_impl.inl
new file mode 100644
index 0000000..51dd2ca
--- /dev/null
+++ b/engine/modules/engine/ui/impl/ui_render_device_impl.inl
@@ -0,0 +1,141 @@
+#include "ui/ui_render_device.h"
+#include "ui/ui_module.h"
+#include "ui_render_device_help.inl"
+namespace api {
+ SINGLETON_DEFINE(UIRenderDevice)
+ UIRenderDevice::UIRenderDevice(RenderAPI* api) : mApi(api)
+ {
+ SINGLETON_PTR();
+ }
+ UIRenderDevice::~UIRenderDevice()
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ const Noesis::DeviceCaps& UIRenderDevice::GetCaps() const
+ {
+ return mCaps;
+ }
+ Noesis::Ptr UIRenderDevice::CreateRenderTarget(const char* label, uint32_t width, uint32_t height, uint32_t sampleCount, bool needsStencil)
+ {
+ return Noesis::Ptr();
+ }
+ Noesis::Ptr UIRenderDevice::CloneRenderTarget(const char* label, Noesis::RenderTarget* surface)
+ {
+ return Noesis::Ptr();
+ }
+ Noesis::Ptr UIRenderDevice::CreateTexture(const char* label, uint32_t width, uint32_t height, uint32_t numLevels, Noesis::TextureFormat::Enum format, const void** data)
+ {
+ TextureDesc desc{};
+ desc.id = -1;
+ desc.format = VKFormat(format, mCaps.linearRendering);
+ desc.width = width;
+ desc.height = height;
+ desc.mipLevel = numLevels;
+ desc.sampleCount = SAMPLE_COUNT_1;
+ desc.usage = TextureUsage::SAMPLEABLE | TextureUsage::BLIT_DST;
+ desc.state = ResourceState::UNDEFINED;
+ mApi->CreateTexture(desc);
+ return CreateUITexture(desc);
+ }
+ 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;
+
+ }
+ void UIRenderDevice::BeginOffscreenRender()
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::EndOffscreenRender()
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::BeginOnscreenRender()
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::EndOnscreenRender()
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::SetRenderTarget(Noesis::RenderTarget* surface)
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::BeginTile(Noesis::RenderTarget* surface, const Noesis::Tile& tile)
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::EndTile(Noesis::RenderTarget* surface)
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::ResolveRenderTarget(Noesis::RenderTarget* surface, const Noesis::Tile* tiles, uint32_t numTiles)
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void* UIRenderDevice::MapVertices(uint32_t bytes)
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ return nullptr;
+ }
+ void UIRenderDevice::UnmapVertices()
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void* UIRenderDevice::MapIndices(uint32_t bytes)
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ return nullptr;
+ }
+ void UIRenderDevice::UnmapIndices()
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+ void UIRenderDevice::DrawBatch(const Noesis::Batch& batch)
+ {
+ int b = 10000;
+ for (int a = 1; a < b; a++) {
+ b--;
+ }
+ }
+}
diff --git a/engine/modules/engine/ui/include/ui/noesis_font_provider.h b/engine/modules/engine/ui/include/ui/noesis_font_provider.h
new file mode 100644
index 0000000..2b474bf
--- /dev/null
+++ b/engine/modules/engine/ui/include/ui/noesis_font_provider.h
@@ -0,0 +1,18 @@
+#pragma once
+#include
+namespace api {
+ class UI_API NoesisFontProvider : public Noesis::FontProvider
+ {
+ public:
+ NoesisFontProvider();
+ ~NoesisFontProvider();
+
+ private:
+ /// From FontProvider
+ //@{
+ Noesis::FontSource MatchFont(const Noesis::Uri& baseUri, const char* familyName,
+ Noesis::FontWeight& weight, Noesis::FontStretch& stretch, Noesis::FontStyle& style) override;
+ bool FamilyExists(const Noesis::Uri& baseUri, const char* familyName) override;
+ //@}
+ };
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/include/ui/noesis_texture_provider.h b/engine/modules/engine/ui/include/ui/noesis_texture_provider.h
new file mode 100644
index 0000000..f3c53e1
--- /dev/null
+++ b/engine/modules/engine/ui/include/ui/noesis_texture_provider.h
@@ -0,0 +1,16 @@
+#pragma once
+#include
+namespace api {
+ class UI_API NoesisTextureProvider : public Noesis::TextureProvider
+ {
+ public:
+ NoesisTextureProvider();
+ ~NoesisTextureProvider();
+
+ private:
+ /// From TextureProvider
+ //@{
+ Noesis::TextureInfo GetTextureInfo(const Noesis::Uri& uri) override;
+ Noesis::Ptr LoadTexture(const Noesis::Uri& uri, Noesis::RenderDevice* device) override;
+ };
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/include/ui/noesis_xaml_provider.h b/engine/modules/engine/ui/include/ui/noesis_xaml_provider.h
new file mode 100644
index 0000000..3f0e0ae
--- /dev/null
+++ b/engine/modules/engine/ui/include/ui/noesis_xaml_provider.h
@@ -0,0 +1,17 @@
+#pragma once
+#include
+namespace api {
+ class UI_API NoesisXamlProvider : public Noesis::XamlProvider
+ {
+ public:
+ NoesisXamlProvider();
+ ~NoesisXamlProvider();
+
+ private:
+ /// From XamlProvider
+ //@{
+ Noesis::Ptr LoadXaml(const Noesis::Uri& uri) override;
+ //@}
+
+ };
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/include/ui/ui_module.h b/engine/modules/engine/ui/include/ui/ui_module.h
index 8d80a17..2167a6f 100644
--- a/engine/modules/engine/ui/include/ui/ui_module.h
+++ b/engine/modules/engine/ui/include/ui/ui_module.h
@@ -7,5 +7,8 @@ namespace api {
void OnLoad(int argc, char** argv) override;
void OnUnload() override;
void InitMetaData(void) override {};
+ void Initialize()override;
+
+ void SetThemeProviders();
};
}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/include/ui/ui_render_device.h b/engine/modules/engine/ui/include/ui/ui_render_device.h
new file mode 100644
index 0000000..cbe6b5c
--- /dev/null
+++ b/engine/modules/engine/ui/include/ui/ui_render_device.h
@@ -0,0 +1,41 @@
+#pragma once
+#include "render/renderapi.h"
+#include
+namespace api {
+ class UI_API UIRenderDevice final : public Noesis::RenderDevice {
+ private:
+ RenderAPI* mApi;
+ Noesis::DeviceCaps mCaps;
+ SINGLETON_IMPL(UIRenderDevice)
+ public:
+ UIRenderDevice(RenderAPI* api);
+ ~UIRenderDevice();
+ private:
+ /// From RenderDevice
+ //@{
+ const Noesis::DeviceCaps& GetCaps() const override;
+ Noesis::Ptr CreateRenderTarget(const char* label, uint32_t width,
+ uint32_t height, uint32_t sampleCount, bool needsStencil) override;
+ Noesis::Ptr CloneRenderTarget(const char* label,
+ Noesis::RenderTarget* surface) override;
+ Noesis::Ptr CreateTexture(const char* label, uint32_t width, uint32_t height,
+ uint32_t numLevels, Noesis::TextureFormat::Enum format, const void** data) override;
+ void UpdateTexture(Noesis::Texture* texture, uint32_t level, uint32_t x, uint32_t y,
+ uint32_t width, uint32_t height, const void* data) override;
+ void BeginOffscreenRender() override;
+ void EndOffscreenRender() override;
+ void BeginOnscreenRender() override;
+ void EndOnscreenRender() override;
+ void SetRenderTarget(Noesis::RenderTarget* surface) override;
+ void BeginTile(Noesis::RenderTarget* surface, const Noesis::Tile& tile) override;
+ void EndTile(Noesis::RenderTarget* surface) override;
+ void ResolveRenderTarget(Noesis::RenderTarget* surface, const Noesis::Tile* tiles,
+ uint32_t numTiles) override;
+ void* MapVertices(uint32_t bytes) override;
+ void UnmapVertices() override;
+ void* MapIndices(uint32_t bytes) override;
+ void UnmapIndices() override;
+ void DrawBatch(const Noesis::Batch& batch) override;
+ //@}
+ };
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/include/ui/ui_window.h b/engine/modules/engine/ui/include/ui/ui_window.h
new file mode 100644
index 0000000..df84bbc
--- /dev/null
+++ b/engine/modules/engine/ui/include/ui/ui_window.h
@@ -0,0 +1,19 @@
+#pragma once
+#include
+#include
+#include
+namespace api {
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ /// Provides the ability to create, configure, show, and manage the lifetime of windows.
+ ///
+ /// http://msdn.microsoft.com/en-us/library/system.windows.window.aspx
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ class UIWindow : public Noesis::UserControl
+ {
+ public:
+ UIWindow();
+ ~UIWindow();
+ virtual void InitializeComponent();
+ NS_DECLARE_REFLECTION(UIWindow, Noesis::UserControl)
+ };
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/src/noesis_font_provider.cpp b/engine/modules/engine/ui/src/noesis_font_provider.cpp
new file mode 100644
index 0000000..cc16bf9
--- /dev/null
+++ b/engine/modules/engine/ui/src/noesis_font_provider.cpp
@@ -0,0 +1,27 @@
+#include "ui/noesis_font_provider.h"
+#include
+#include
+namespace api {
+ using namespace Noesis;
+ NoesisFontProvider::NoesisFontProvider()
+ {
+
+ }
+ NoesisFontProvider::~NoesisFontProvider()
+ {
+ }
+ FontSource NoesisFontProvider::MatchFont(const Uri& baseUri, const char* familyName, FontWeight& weight, FontStretch& stretch, FontStyle& style)
+ {
+ auto uri = baseUri;
+ auto a1 = uri.Str();
+ auto a2 = uri.FullPath();
+ return FontSource();
+ }
+ bool NoesisFontProvider::FamilyExists(const Uri& baseUri, const char* familyName)
+ {
+ auto uri = baseUri;
+ auto a1 = uri.Str();
+ auto a2 = uri.FullPath();
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/src/noesis_texture_provider.cpp b/engine/modules/engine/ui/src/noesis_texture_provider.cpp
new file mode 100644
index 0000000..1bbeb04
--- /dev/null
+++ b/engine/modules/engine/ui/src/noesis_texture_provider.cpp
@@ -0,0 +1,65 @@
+#include "ui/noesis_texture_provider.h"
+#include "os/package_path.h"
+#include
+#include
+#include
+#include
+#define STB_IMAGE_IMPLEMENTATION
+#include "stb_image.h"
+namespace api {
+ using namespace Noesis;
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ static int Read(void* user, char* data, int size)
+ {
+ Stream* stream = (Stream*)user;
+ return stream->Read(data, size);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ static void Skip(void* user, int n)
+ {
+ Stream* stream = (Stream*)user;
+ stream->SetPosition((int)stream->GetPosition() + n);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ static int Eof(void* user)
+ {
+ Stream* stream = (Stream*)user;
+ return stream->GetPosition() >= stream->GetLength();
+ }
+ NoesisTextureProvider::NoesisTextureProvider()
+ {
+
+ }
+ NoesisTextureProvider::~NoesisTextureProvider()
+ {
+ }
+ TextureInfo NoesisTextureProvider::GetTextureInfo(const Uri& uri)
+ {
+ TextureInfo info;
+ Ptr file = OpenFileStream(PackagePath::RealPath(uri.FullPath()).c_str());
+ if (file != 0)
+ {
+ int x, y, n;
+ stbi_io_callbacks callbacks = { Read, Skip, Eof };
+ if (stbi_info_from_callbacks(&callbacks, file, &x, &y, &n))
+ {
+ info.width = x;
+ info.height = y;
+ }
+ else
+ {
+ NS_LOG_WARNING("%s: %s", uri.Str(), stbi_failure_reason());
+ }
+ file->Close();
+ }
+ return info;
+ }
+ Ptr NoesisTextureProvider::LoadTexture(const Uri& uri, RenderDevice* device)
+ {
+ auto a1 = uri.Str();
+ auto a2 = uri.FullPath();
+ return Ptr();
+ }
+}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/src/noesis_xaml_provider.cpp b/engine/modules/engine/ui/src/noesis_xaml_provider.cpp
new file mode 100644
index 0000000..b08b5d9
--- /dev/null
+++ b/engine/modules/engine/ui/src/noesis_xaml_provider.cpp
@@ -0,0 +1,18 @@
+#include "ui/noesis_xaml_provider.h"
+#include "os/package_path.h"
+#include
+#include
+namespace api {
+ using namespace Noesis;
+ NoesisXamlProvider::NoesisXamlProvider()
+ {
+
+ }
+ NoesisXamlProvider::~NoesisXamlProvider()
+ {
+ }
+ Ptr NoesisXamlProvider::LoadXaml(const Uri& uri)
+ {
+ return OpenFileStream(PackagePath::RealPath(uri.FullPath()).c_str());
+ }
+}
diff --git a/engine/modules/engine/ui/src/ui_module.cpp b/engine/modules/engine/ui/src/ui_module.cpp
index 0fac347..a8deef3 100644
--- a/engine/modules/engine/ui/src/ui_module.cpp
+++ b/engine/modules/engine/ui/src/ui_module.cpp
@@ -1,10 +1,18 @@
#include "zlog.h"
#include "ui/ui_module.h"
-#include "NoesisPCH.h"
+#include "ui/ui_window.h"
+#include "ui/ui_render_device.h"
+#include "ui/noesis_xaml_provider.h"
+#include "ui/noesis_font_provider.h"
+#include "ui/noesis_texture_provider.h"
+#include
+#include
+#include
namespace api {
+ using namespace Noesis;
void UIModule::OnLoad(int argc, char** argv)
{
- Noesis::SetLogHandler([](const char*, uint32_t, uint32_t level, const char*, const char* msg)
+ SetLogHandler([](const char*, uint32_t, uint32_t level, const char*, const char* msg)
{
switch (level) {
case 0:
@@ -23,12 +31,31 @@ namespace api {
}
});
// Sets the active license
- Noesis::GUI::SetLicense(NS_LICENSE_NAME, NS_LICENSE_KEY);
+ GUI::SetLicense(NS_LICENSE_NAME, NS_LICENSE_KEY);
// Noesis initialization. This must be the first step before using any NoesisGUI functionality
- Noesis::GUI::Init();
+ GUI::Init();
}
void UIModule::OnUnload()
{
-
+ // 清理资源提供者
+ GUI::SetFontProvider(nullptr);
+ GUI::SetTextureProvider(nullptr);
}
+ void UIModule::Initialize()
+ {
+ IStaticModule::Initialize();
+ GUI::SetXamlProvider(new NoesisXamlProvider());
+ GUI::SetFontProvider(new NoesisFontProvider());
+ GUI::SetTextureProvider(new NoesisTextureProvider());
+ RegisterComponent();
+ SetThemeProviders();
+ }
+ ////////////////////////////////////////////////////////////////////////////////////////////////////
+ void UIModule::SetThemeProviders()
+ {
+ const char* fonts[] = {"Arial"};
+
+ GUI::SetFontFallbacks(fonts, NS_COUNTOF(fonts));
+ GUI::SetFontDefaultProperties(15.0f, FontWeight_Normal, FontStretch_Normal, FontStyle_Normal);
+ }
}
\ No newline at end of file
diff --git a/engine/modules/engine/ui/src/ui_window.cpp b/engine/modules/engine/ui/src/ui_window.cpp
new file mode 100644
index 0000000..f3bfe60
--- /dev/null
+++ b/engine/modules/engine/ui/src/ui_window.cpp
@@ -0,0 +1,21 @@
+#include "ui/ui_window.h"
+namespace api {
+ UIWindow::UIWindow()
+ {
+
+ }
+ UIWindow::~UIWindow()
+ {
+ }
+ void UIWindow::InitializeComponent()
+ {
+
+ }
+ NS_IMPLEMENT_REFLECTION(UIWindow,"api.UIWindow")
+ {
+ int A = 1;
+ if (NS_UNLIKELY(A == 0)) {
+
+ }
+ }
+}
diff --git a/engine/modules/engine/ui/xmake.lua b/engine/modules/engine/ui/xmake.lua
index 8b3cd9b..7e3c7a6 100644
--- a/engine/modules/engine/ui/xmake.lua
+++ b/engine/modules/engine/ui/xmake.lua
@@ -2,4 +2,4 @@ static_component("ui","engine")
add_headerfiles("include/**.h")
add_files("src/**.cpp")
add_deps("core", "asset", "zlib", "render")
- add_packages("noesis", {public = true})
\ No newline at end of file
+ add_packages("noesis", "stb", {public = true})
\ No newline at end of file
diff --git a/engine/modules/engine/zlib/include/pmr/name.inl b/engine/modules/engine/zlib/include/pmr/name.inl
index f1beac5..9ba7b66 100644
--- a/engine/modules/engine/zlib/include/pmr/name.inl
+++ b/engine/modules/engine/zlib/include/pmr/name.inl
@@ -1,6 +1,6 @@
#include "name.h"
constexpr inline size_t meta_align_size(size_t size, size_t alignment = 8) {
- return (size + alignment - 1) / alignment * alignment;
+ return (size + (alignment - 1)) & ~(alignment - 1);
}
XMALLOC_API void* xmalloc(size_t size);
namespace pmr {
diff --git a/engine/modules/render/vulkan/include/vkn/backend.h b/engine/modules/render/vulkan/include/vkn/backend.h
index a14bae0..ec206e6 100644
--- a/engine/modules/render/vulkan/include/vkn/backend.h
+++ b/engine/modules/render/vulkan/include/vkn/backend.h
@@ -26,6 +26,5 @@ namespace vkn {
public:
static struct BufferWorker* TransferWorker;
static struct CommandWorker* RenderWorker;
- static struct CommandWorker* PresentWorker;
};
};
\ No newline at end of file
diff --git a/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h b/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h
index ddb6937..9a61856 100644
--- a/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h
+++ b/engine/modules/render/vulkan/include/vkn/thread/buffer_worker.h
@@ -1,17 +1,22 @@
#pragma once
#include "worker.h"
#include "vma/vk_mem_alloc.h"
+#include "render/render_buffer.h"
#include
-namespace api {
- struct BufferDesc;
-}
namespace vkn {
class Device;
class Queue;
+ class VulkanContext;
+ using api::DynamicBuffer;
extern pmr::FrameAllocatorPool vkCpuBufferPool;
inline pmr::FrameAllocatorPool* BufferPool(){
return &vkCpuBufferPool;
}
+
+ enum class TransferBufferType : uint8_t{
+ Transfer,
+ Graphics
+ };
struct Buffer {
VkBuffer buffer = VK_NULL_HANDLE;
VmaAllocation allocation = VK_NULL_HANDLE;
@@ -29,26 +34,57 @@ namespace vkn {
void** ppCpuData;
uint32_t size;
VkBufferUsageFlags usage;
+ VkMemoryPropertyFlags momoryFlags;
VmaMemoryUsage memoryUsage;
};
- struct BufferCommand {
- using Command = std::variant;
- Command cmd;
- BufferCommand(const BufferUpload& cmd) : cmd(cmd){}
- BufferCommand(const BufferCreator& cmd) : cmd(cmd) {}
- };
struct ImageCreator {
VkImageCreateInfo imageInfo;
VkImage* image;
};
+ struct ImageUpdator {
+ VkImage image;
+ uint32_t size;
+ uint32_t mipLevel;
+ TextureUpdateArgs args;
+ };
+ struct SyncTransferCommand {
+ uint32_t frameNumber;
+ };
+ struct BufferCommand {
+ using Command = std::variant;
+ Command cmd;
+ BufferCommand(const BufferUpload& cmd) : cmd(cmd) {}
+ BufferCommand(const BufferCreator& cmd) : cmd(cmd) {}
+ BufferCommand(const ImageUpdator& cmd) : cmd(cmd) {}
+ BufferCommand(const SyncTransferCommand& cmd) : cmd(cmd) {}
+ };
+ struct DynamicBufferPool {
+ TransferBufferType type;
+ uint32_t commandIndex{0};
+ uint32_t safeFrameNumber{0};
+ VkCommandBuffer* pCommands;
+ DynamicBuffer uploadBuffer;
+ DynamicBufferPool(TransferBufferType type) : type(type) {}
+ void CreateDynamicBuffers();
+ DynamicBuffer* FindUploadBuffer(uint32_t size,uint32_t frameNumber,const void* data);
+ };
class BufferWorker : public ThreadWorker{
public:
- //pmr::vector mPool{BufferPool()};
+ uint32_t mFrameNumber{ 0 };
+ DynamicBufferPool mTransferBuffer{ TransferBufferType::Transfer };
+ DynamicBufferPool mGraphicsBuffer{ TransferBufferType::Graphics };
using ThreadWorker::ThreadWorker;
+ void InitCommandBuffers(uint32_t frames);
void InitVmaAllocator(VkInstance instance);
+ void TrySyncTransfer(VulkanContext& ctx);
void Loop();
- void UploadBuffer(const BufferUpload& elem);
+ void SyncTransfer(const SyncTransferCommand& elem);
+ void UploadBuffer(const BufferUpload& elem, TransferBufferType type = TransferBufferType::Graphics);
void CreateBuffer(BufferCreator& elem);
void CreateImage(ImageCreator& elem);
+ void UpdateImage(ImageUpdator& elem, TransferBufferType type = TransferBufferType::Graphics);
+
+ bool BeginDynamicCommand(DynamicBufferPool*& poolRef, CommandBuffer& cmd, bool isTransfer);
+ void EndDynamicCommand(DynamicBufferPool* poolRef, CommandBuffer& cmd, bool isTransfer);
};
};
diff --git a/engine/modules/render/vulkan/include/vkn/thread/command_worker.h b/engine/modules/render/vulkan/include/vkn/thread/command_worker.h
index af53c2c..05ae3f1 100644
--- a/engine/modules/render/vulkan/include/vkn/thread/command_worker.h
+++ b/engine/modules/render/vulkan/include/vkn/thread/command_worker.h
@@ -12,9 +12,6 @@ namespace vkn {
void InvokeBuffer(const commandFn& fn, const Element& callback);
void Buffer(CommandBuffer& cmd, const commandFn& fn, const Element& callback);
void Flush();
- void ImmediatelyExecute(const commandFn& fn, const Element& callback) {
- Buffer(mImmediateExeCmd, fn , callback);
- }
bool Present(VkPresentInfoKHR& presentInfo);
void Loop();
void SyncInvoke(const Element& fn);
diff --git a/engine/modules/render/vulkan/include/vkn/thread/worker.h b/engine/modules/render/vulkan/include/vkn/thread/worker.h
index 2f7f63a..78596e3 100644
--- a/engine/modules/render/vulkan/include/vkn/thread/worker.h
+++ b/engine/modules/render/vulkan/include/vkn/thread/worker.h
@@ -12,8 +12,6 @@ namespace vkn {
Device& mDevice;
Queue& mQueue;
CommandPool mCommandPool;
- CommandBuffer mImmediateExeCmd;
- VkFence mImmediateFence;
public:
ThreadWorker(Name name, Device& device, Queue& queue, VkCommandPoolCreateFlags queueFlags)
: zstd::ThreadWorker(64)
@@ -21,8 +19,6 @@ namespace vkn {
, mDevice(device)
, mQueue(queue)
, mCommandPool(device, queueFlags, queue.QueueFamilyIndex())
- , mImmediateExeCmd(mCommandPool.AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY))
- , mImmediateFence(device.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT))
{}
CommandPool& GetCommandPool() {
return mCommandPool;
diff --git a/engine/modules/render/vulkan/include/vkn/type.h b/engine/modules/render/vulkan/include/vkn/type.h
index 1383f3a..e03bd8f 100644
--- a/engine/modules/render/vulkan/include/vkn/type.h
+++ b/engine/modules/render/vulkan/include/vkn/type.h
@@ -30,6 +30,7 @@ namespace vkn {
using api::ShaderDescriptorType;
using api::BufferUsage;
using api::MaterialInfo;
+ using api::TextureUpdateArgs;
constexpr string_view VulkanEngineName = "vulkan";
constexpr uint8_t MAX_SUPPORTED_RENDER_TARGET_COUNT = 8u;
diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api.h b/engine/modules/render/vulkan/include/vkn/vulkan_api.h
index 387ab69..4cb341a 100644
--- a/engine/modules/render/vulkan/include/vkn/vulkan_api.h
+++ b/engine/modules/render/vulkan/include/vkn/vulkan_api.h
@@ -41,11 +41,14 @@ namespace vkn {
void CreateTexture(TextureDesc& desc)override;
ImageViewPtr CreateTextureView(TextureViewKey desc)override;
SamplerPtr CreateTextureSampler(TextureSampler sampler) override;
+ void UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state) override;
+
void BeginFrame()override;
void EndFrame()override;
void BeginRenderPass(RenderPassNode* node, FnEnterRenderPass callback) override;
void EndRenderPass(RenderPassNode* node) override;
void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override;
+
VkPipeline GetPipeline() { return nullptr; };
RenderPassInfo* GetRenderPassInfo(Name name, size_t hash);
RenderPassInfo* GetRenderPassInfo(size_t& hash, const RenderPassKey& config);
diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h b/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h
index ba940a3..6a233e9 100644
--- a/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h
+++ b/engine/modules/render/vulkan/include/vkn/vulkan_api_help.h
@@ -5,6 +5,7 @@ namespace vkn {
using api::TextureBarrier;
using api::ShaderDescriptorType;
using api::ShaderStage;
+ using api::ResourceMemoryUsage;
struct VkTextureTransitionDesc {
VkAccessFlags srcAccessMask;
VkAccessFlags dstAccessMask;
@@ -25,6 +26,9 @@ namespace vkn {
VkDescriptorType vkApiGetDescriptorType(ShaderDescriptorType type);
VkShaderStageFlags vkApiGetShaderStageFlags(ShaderStage stage);
- VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage);
VkSamplerCreateInfo vkApiGetSamplerCreateInfo(TextureSampler sampler);
+
+ VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage);
+ VkMemoryPropertyFlags vkApiGetMemoryFlags(ResourceMemoryUsage usageFlags);
+ VmaMemoryUsage vkApiGetMemoryUsage(ResourceMemoryUsage usageFlags);
}
\ No newline at end of file
diff --git a/engine/modules/render/vulkan/include/vkn/vulkan_window.h b/engine/modules/render/vulkan/include/vkn/vulkan_window.h
index 33e2b10..40367b5 100644
--- a/engine/modules/render/vulkan/include/vkn/vulkan_window.h
+++ b/engine/modules/render/vulkan/include/vkn/vulkan_window.h
@@ -10,11 +10,11 @@ namespace vkn {
uint32_t frames;
uint32_t width;
uint32_t height;
+ uint32_t framesInFlight;
VkFormat imageFormat;
VkColorSpaceKHR imageColorSpace;
VkPresentModeKHR presentMode;
VkImageUsageFlags imageUsage;
- uint32_t maxFrameInFlightCount;
VkExtent2D EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities);
static VulkanWindowArgs Default(uint32_t frames);
};
diff --git a/engine/modules/render/vulkan/src/backend.cpp b/engine/modules/render/vulkan/src/backend.cpp
index 1c982f1..7b2afd0 100644
--- a/engine/modules/render/vulkan/src/backend.cpp
+++ b/engine/modules/render/vulkan/src/backend.cpp
@@ -10,7 +10,6 @@
namespace vkn {
BufferWorker* Backend::TransferWorker;
CommandWorker* Backend::RenderWorker;
- CommandWorker* Backend::PresentWorker;
template
inline Worker* Backend::InitWorker(Name name, VkCommandPoolCreateFlags flag)
{
@@ -28,8 +27,8 @@ namespace vkn {
deviceCreator.AddQueue(Queue::TransferQueue, VkQueueFlagBits::VK_QUEUE_TRANSFER_BIT, 1.0);
mDevice = new (GlobalPool()) Device(deviceCreator);
+ Backend::RenderWorker = InitWorker(Queue::RenderQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
Backend::TransferWorker = InitWorker(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
- Backend::RenderWorker = InitWorker(Queue::RenderQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
Backend::TransferWorker->InitVmaAllocator(mInstance->Ptr());
auto poolSizes = DescriptorPool::DefaultDescriptorPoolSize();
diff --git a/engine/modules/render/vulkan/src/thread/buffer_worker.cpp b/engine/modules/render/vulkan/src/thread/buffer_worker.cpp
index 0938b3e..a3f1271 100644
--- a/engine/modules/render/vulkan/src/thread/buffer_worker.cpp
+++ b/engine/modules/render/vulkan/src/thread/buffer_worker.cpp
@@ -1,11 +1,19 @@
#define VMA_IMPLEMENTATION
+#include "vkn/backend.h"
+#include "vkn/thread/command_worker.h"
#include "vkn/thread/buffer_worker.h"
#include "vkn/wrapper/queue.h"
#include "vkn/wrapper/device.h"
#include "vkn/vulkan_api_help.h"
+#include "vkn/vulkan_context.h"
#include "meta/variant.h"
#include "zlog.h"
+#define MAX_TRANSFER_SYNC_FENCES 11
+#define SYNC_TRANSFER_INTERVAL_MS 100 // 每秒同步一次
+#define DYNAMIC_TEX_SIZE 128 * 1024
namespace vkn {
+ static VkFence fenceList[MAX_TRANSFER_SYNC_FENCES - 1];
+ static VkCommandBuffer* commandList;
static pmr::FrameAllocatorPool vkCpuBufferPool;
static VmaAllocator vmaAllocator;
void BufferWorker::InitVmaAllocator(VkInstance instance)
@@ -25,40 +33,84 @@ namespace vkn {
vmaInfo.pVulkanFunctions = &vmaVkFunctions;
vmaCreateAllocator(&vmaInfo, &vmaAllocator);
+ mTransferBuffer.CreateDynamicBuffers();
+ mGraphicsBuffer.CreateDynamicBuffers();
+ }
+ void BufferWorker::InitCommandBuffers(uint32_t frames)
+ {
+ commandList = (VkCommandBuffer*)xmalloc(MAX_TRANSFER_SYNC_FENCES * (frames + 1) * sizeof(VkCommandBuffer));
+ for (uint32_t i = 0; i <= frames; i++) {
+ for (uint32_t j = 0; j < MAX_TRANSFER_SYNC_FENCES - 1; j++) {
+ uint32_t k = j + (MAX_TRANSFER_SYNC_FENCES - 1) * i;
+ if (i == frames) {
+ fenceList[j] = mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT);
+ commandList[k] = GetCommandPool().AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+ }
+ else {
+ commandList[k] = Backend::RenderWorker->GetCommandPool().AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+ }
+ }
+ }
+ vkResetFences(mDevice.Ptr(), MAX_TRANSFER_SYNC_FENCES - 1, fenceList);
+ mTransferBuffer.pCommands = commandList + (MAX_TRANSFER_SYNC_FENCES - 1) * frames;
+ mGraphicsBuffer.pCommands = commandList;
+ mFrameNumber = frames;
+ }
+ void BufferWorker::TrySyncTransfer(VulkanContext& ctx)
+ {
+ uint32_t frameNumber = ctx.frameNumber++;
+ if (frameNumber - mTransferBuffer.safeFrameNumber > SYNC_TRANSFER_INTERVAL_MS && mTransferBuffer.commandIndex < MAX_TRANSFER_SYNC_FENCES) {
+ mTransferBuffer.commandIndex += MAX_TRANSFER_SYNC_FENCES;
+ Invoke(SyncTransferCommand{ frameNumber });
+ }
+ mFrameNumber = frameNumber;//保守一点,慢一帧
+ mGraphicsBuffer.commandIndex = 0;
+ mGraphicsBuffer.pCommands = commandList + (MAX_TRANSFER_SYNC_FENCES - 1) * ctx.frame;
+ mGraphicsBuffer.safeFrameNumber = ctx.frameNumber - ctx.frameCount;
+ }
+ void BufferWorker::SyncTransfer(const SyncTransferCommand& elem)
+ {
+ DynamicBufferPool& bufferPoolRef = mTransferBuffer;
+ uint32_t index = bufferPoolRef.commandIndex % (MAX_TRANSFER_SYNC_FENCES);
+ if (index) { //没有提交任务时,不需要等待
+ vkWaitForFences(mDevice.Ptr(), index - 1, fenceList, VK_TRUE, UINT64_MAX);
+ vkResetFences(mDevice.Ptr(), index - 1, fenceList);
+ }
+ bufferPoolRef.safeFrameNumber = elem.frameNumber;
+ bufferPoolRef.commandIndex = 0;
}
void BufferWorker::Loop()
{
while (true) {
Element elem = mChannel.acquire();
std::visit(meta::overloaded{
- [&](BufferUpload& cmd) { UploadBuffer(cmd); },
+ [&](BufferUpload& cmd) { UploadBuffer(cmd, TransferBufferType::Transfer); },
[&](BufferCreator& cmd) { CreateBuffer(cmd); },
+ [&](ImageUpdator& cmd) { UpdateImage(cmd); },
+ [&](SyncTransferCommand& cmd) { SyncTransfer(cmd); },
}, elem.cmd);
}
}
- void BufferWorker::UploadBuffer(const BufferUpload& elem)
+ void BufferWorker::UploadBuffer(const BufferUpload& elem, TransferBufferType type)
{
- mImmediateExeCmd.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+ bool isTransfer = type == TransferBufferType::Transfer;
+ DynamicBufferPool* pPoolRef;
+ CommandBuffer command;
+ if (!BeginDynamicCommand(pPoolRef, command, isTransfer)) {
+ Invoke(elem);
+ return;
+ }
+ // 将数据复制到 Staging Buffer
+ DynamicBuffer* uploadBuffer = pPoolRef->FindUploadBuffer(elem.size, mFrameNumber + 1,elem.pCpuData);
+
+ VmaAllocationCreateInfo allocationInfo = {};
+ allocationInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
+
VkBufferCreateInfo bufferInfo = {};
bufferInfo.size = elem.size;
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-
- VmaAllocation stagingAllocation;
-
- VmaAllocationCreateInfo allocationInfo = {};
- allocationInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
-
- VkBuffer stagingBuffer;
- vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocationInfo, &stagingBuffer, &stagingAllocation, nullptr);
-
- // 将数据复制到 Staging Buffer
- void* data;
- vmaMapMemory(vmaAllocator, stagingAllocation, &data);
- memcpy(data, elem.pCpuData, elem.size);
- vmaUnmapMemory(vmaAllocator, stagingAllocation);
-
// 创建 GPU Buffer, GPU内部缓冲区,访问速度非常快
VkBuffer& gpuBuffer = *elem.pBuffer;
bufferInfo.usage = elem.usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
@@ -68,12 +120,10 @@ namespace vkn {
// 复制数据
VkBufferCopy copyRegion = {};
copyRegion.size = elem.size;
- vkCmdCopyBuffer(mImmediateExeCmd.Ptr(), stagingBuffer, gpuBuffer, 1, ©Region);
- mImmediateExeCmd.EndRecord();
- vkResetFences(mDevice.Ptr(), 1, &mImmediateFence);
- mImmediateExeCmd.Submit(mQueue.Ptr(), mImmediateFence);
- vkWaitForFences(mDevice.Ptr(), 1, &mImmediateFence, VK_TRUE, UINT64_MAX);
- vmaDestroyBuffer(vmaAllocator, stagingBuffer, stagingAllocation);
+ copyRegion.srcOffset = uploadBuffer->drawPos;
+ vkCmdCopyBuffer(command.Ptr(), (VkBuffer)uploadBuffer->currentPage->pBuffer, gpuBuffer, 1, ©Region);
+
+ EndDynamicCommand(pPoolRef, command, isTransfer);
}
void BufferWorker::CreateBuffer(BufferCreator& elem)
{
@@ -84,6 +134,7 @@ namespace vkn {
VmaAllocationCreateInfo allocationInfo = {};
allocationInfo.usage = elem.memoryUsage;
+ allocationInfo.requiredFlags = elem.momoryFlags;
if (elem.ppCpuData)
allocationInfo.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT;
vmaCreateBuffer(vmaAllocator, &bufferInfo, &allocationInfo, elem.pBuffer, elem.pAllocation, nullptr);
@@ -99,4 +150,69 @@ namespace vkn {
VmaAllocation allocation;
VkResult result = vmaCreateImage(vmaAllocator, &elem.imageInfo, &allocCreateInfo, elem.image, &allocation, nullptr);
}
+ void BufferWorker::UpdateImage(ImageUpdator& elem, TransferBufferType type)
+ {
+ bool isTransfer = type == TransferBufferType::Transfer;
+ DynamicBufferPool* pPoolRef;
+ CommandBuffer command;
+ if (!BeginDynamicCommand(pPoolRef, command, isTransfer)) {
+ Invoke(elem);
+ return;
+ }
+ TextureUpdateArgs args = elem.args;
+ // 将数据复制到 Staging Buffer
+ DynamicBuffer* uploadBuffer = pPoolRef->FindUploadBuffer(elem.size, mFrameNumber + 1, args.data);
+
+ VkBufferImageCopy region{};
+ region.imageOffset.x = args.x;
+ region.imageOffset.y = args.y;
+ region.imageExtent.width = args.width;
+ region.imageExtent.height = args.height;
+ region.imageExtent.depth = 1;
+ region.imageSubresource.mipLevel = elem.mipLevel;
+ region.bufferOffset = uploadBuffer->drawPos;
+ region.imageSubresource.layerCount = 1;
+ region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+
+ vkCmdCopyBufferToImage(command.Ptr(), (VkBuffer)uploadBuffer->currentPage->pBuffer, elem.image,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
+ EndDynamicCommand(pPoolRef, command, isTransfer);
+ }
+ bool BufferWorker::BeginDynamicCommand(DynamicBufferPool*& pPoolRef, CommandBuffer& command, bool isTransfer)
+ {
+ pPoolRef = isTransfer ? &mTransferBuffer : &mGraphicsBuffer;
+ if (pPoolRef->commandIndex >= MAX_TRANSFER_SYNC_FENCES) {
+ return false;
+ }
+ command = pPoolRef->pCommands[pPoolRef->commandIndex];
+ command.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+ return true;
+ }
+ void BufferWorker::EndDynamicCommand(DynamicBufferPool* pPoolRef, CommandBuffer& command, bool isTransfer)
+ {
+ command.EndRecord();
+ pPoolRef->commandIndex++;
+ if (isTransfer) {
+ command.Submit(mQueue.Ptr(), fenceList[pPoolRef->commandIndex - 1]);
+ if (pPoolRef->commandIndex >= MAX_TRANSFER_SYNC_FENCES) {
+ SyncTransfer(SyncTransferCommand{ mFrameNumber });
+ }
+ return;
+ }
+ command.Submit(Backend::RenderWorker->GetQueue().Ptr(), nullptr);
+ }
+ void DynamicBufferPool::CreateDynamicBuffers()
+ {
+ uploadBuffer.InitBuffer(DYNAMIC_TEX_SIZE, BufferUsage::TRANSFER_SRC,
+ ResourceMemoryUsage::HOST_VISIBLE | ResourceMemoryUsage::HOST_COHERENT);
+ }
+ DynamicBuffer* DynamicBufferPool::FindUploadBuffer(uint32_t size, uint32_t frameNumber, const void* data)
+ {
+ // 将数据复制到 Staging Buffer
+ void* pMappingAddr = uploadBuffer.MapBuffer(meta_align_size(size, 4), frameNumber, safeFrameNumber);
+ if (data) {
+ memcpy(pMappingAddr, data, size);
+ }
+ return &uploadBuffer;
+ }
}
diff --git a/engine/modules/render/vulkan/src/vulkan_api.cpp b/engine/modules/render/vulkan/src/vulkan_api.cpp
index 06e0f8c..ee2a949 100644
--- a/engine/modules/render/vulkan/src/vulkan_api.cpp
+++ b/engine/modules/render/vulkan/src/vulkan_api.cpp
@@ -19,7 +19,7 @@ namespace vkn {
}
void VulkanAPI::Init()
{
-
+ Backend::TransferWorker->InitCommandBuffers(context.frameCount);
}
void VulkanAPI::Shutdown()
{
@@ -267,7 +267,15 @@ namespace vkn {
}
void VulkanAPI::CreateBuffer(BufferDesc& desc)
{
-
+ BufferCreator creator{};
+ creator.size = desc.size;
+ creator.pBuffer = (VkBuffer*)&desc.buffer;
+ creator.pAllocation =(VmaAllocation*) &desc.pAllocation;
+ creator.ppCpuData = &desc.pMappingAddr;
+ creator.memoryUsage = vkApiGetMemoryUsage(desc.memoryUsage);
+ creator.momoryFlags = vkApiGetMemoryFlags(desc.memoryUsage);
+ creator.usage = vkApiGetBufferUsage(desc.usage);
+ Backend::TransferWorker->CreateBuffer(creator);
}
void VulkanAPI::CreateTexture(TextureDesc& desc)
{
@@ -332,6 +340,31 @@ namespace vkn {
vkCreateSampler(backend.GetDevice().Ptr(), &samplerInfo, nullptr, &sampler);
return sampler;
}
+ void VulkanAPI::UpdateTexture(TextureDesc& texture, const TextureUpdateArgs& update, ResourceState state)
+ {
+ if (!texture.id) {
+ graph.AcquireTexture(texture);
+ }
+ if (texture.state != state) {
+ TextureBarrier barrier{};
+ barrier.mSrcState = texture.state;
+ barrier.mDstState = state;
+ barrier.mTexture = texture;
+ ResourceBarrierDesc desc{};
+ desc.pTextureBarriers = &barrier;
+ desc.textureBarriersCount = 1;
+ ExecuteResourceBarriers(desc);
+ }
+ VulkanContext& ctx = *(VulkanContext*)&context;
+ uint32_t texelBytes = texture.format == TinyImageFormat_R8_UNORM ? 1 : 4;
+ uint32_t size = update.width * update.height * texelBytes;
+ ImageUpdator updator{};
+ updator.args = update;
+ updator.size = size;
+ updator.mipLevel = texture.mipLevel;
+ updator.image = (VkImage)texture.image;
+ Backend::TransferWorker->UpdateImage(updator);
+ }
void VulkanAPI::BeginFrame()
{
VulkanContext& ctx = *(VulkanContext*)&context;
@@ -343,6 +376,7 @@ namespace vkn {
{
VulkanContext& ctx = *(VulkanContext*)&context;
window.Present(ctx);
+ Backend::TransferWorker->TrySyncTransfer(ctx);
}
void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) {
VulkanContext& ctx = *(VulkanContext*)&context;
diff --git a/engine/modules/render/vulkan/src/vulkan_api_help.cpp b/engine/modules/render/vulkan/src/vulkan_api_help.cpp
index e5556e9..d68c1b9 100644
--- a/engine/modules/render/vulkan/src/vulkan_api_help.cpp
+++ b/engine/modules/render/vulkan/src/vulkan_api_help.cpp
@@ -256,19 +256,6 @@ namespace vkn {
}
return flags;
}
- VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage)
- {
- if (any(usage & BufferUsage::VERTEX)) {
- return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
- }
- if (any(usage & BufferUsage::UNIFORM)) {
- return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
- }
- if (any(usage & BufferUsage::SHADER_STORAGE)) {
- return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
- }
- return {};
- }
using api::SamplerWrapMode;
using api::SamplerMinFilter;
using api::SamplerMagFilter;
@@ -380,4 +367,52 @@ namespace vkn {
};
return samplerInfo;
}
+ VkBufferUsageFlagBits vkApiGetBufferUsage(BufferUsage usage)
+ {
+ if (any(usage & BufferUsage::VERTEX)) {
+ return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ }
+ if (any(usage & BufferUsage::UNIFORM)) {
+ return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+ }
+ if (any(usage & BufferUsage::SHADER_STORAGE)) {
+ return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
+ }
+ if (any(usage & BufferUsage::TRANSFER_SRC)) {
+ return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
+ }
+ return {};
+ }
+ VkMemoryPropertyFlags vkApiGetMemoryFlags(ResourceMemoryUsage usageFlags) {
+ VkMemoryPropertyFlags flags = 0;
+ if (any(usageFlags & ResourceMemoryUsage::HOST_VISIBLE)) {
+ flags |= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+ }
+ if (any(usageFlags & ResourceMemoryUsage::GPU_ONLY)) {
+ flags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
+ }
+ if (any(usageFlags & ResourceMemoryUsage::HOST_COHERENT)) {
+ flags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
+ }
+ if (any(usageFlags & ResourceMemoryUsage::LAZY_ALLOCATED)) {
+ flags |= VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT;
+ }
+ return flags;
+ }
+
+ VmaMemoryUsage vkApiGetMemoryUsage(ResourceMemoryUsage usageFlags) {
+ if (any(usageFlags & ResourceMemoryUsage::GPU_ONLY)) {
+ return VMA_MEMORY_USAGE_GPU_ONLY;
+ }
+ if (any(usageFlags & ResourceMemoryUsage::CPU_ONLY)) {
+ return VMA_MEMORY_USAGE_CPU_ONLY;
+ }
+ if (any(usageFlags & ResourceMemoryUsage::CPU_TO_GPU)) {
+ return VMA_MEMORY_USAGE_CPU_TO_GPU;
+ }
+ if (any(usageFlags & ResourceMemoryUsage::GPU_TO_CPU)) {
+ return VMA_MEMORY_USAGE_GPU_TO_CPU;
+ }
+ return VMA_MEMORY_USAGE_UNKNOWN; // 默认
+ }
}
\ No newline at end of file
diff --git a/engine/modules/render/vulkan/src/vulkan_window.cpp b/engine/modules/render/vulkan/src/vulkan_window.cpp
index b6d271a..89ec2d1 100644
--- a/engine/modules/render/vulkan/src/vulkan_window.cpp
+++ b/engine/modules/render/vulkan/src/vulkan_window.cpp
@@ -22,7 +22,8 @@ namespace vkn {
args.width = mWidth;
args.height = mHeight;
mSwapchain = new (GlobalPool()) VulkanSwapchain(backend.GetDevice(), surface, args);
- api->context.frameCount = args.frames;
+ api->context.frameCount = args.framesInFlight;
+ api->context.frameNumber = args.framesInFlight;
api->context.surface = mSwapchain->mSurfaces[0];
api->graph.InitSurface(mSwapchain->mSurfaces.data(), mSwapchain->mSurfaces.size());
return true;
@@ -57,7 +58,7 @@ namespace vkn {
if (result != VK_SUCCESS) {
zlog::error("Failed to create swap chain.");
}
- mFrames = args.frames;
+ mFrames = args.framesInFlight;
pmr::vector swapchain_images{ FramePool() };
uint32_t imageCount = 0;
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, nullptr);
@@ -138,11 +139,11 @@ namespace vkn {
{
return {
.frames = frames,
+ .framesInFlight = 2,
.imageFormat = VK_FORMAT_B8G8R8A8_SRGB,
.imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
.presentMode = VK_PRESENT_MODE_MAILBOX_KHR,
.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
- .maxFrameInFlightCount = 2
};
}
}
\ No newline at end of file
diff --git a/engine/src/editor/editor.cpp b/engine/src/editor/editor.cpp
index caba00b..233d6f0 100644
--- a/engine/src/editor/editor.cpp
+++ b/engine/src/editor/editor.cpp
@@ -1,8 +1,16 @@
#include "editor/editor.h"
+#include "editor/window/editor_main_window.h"
+#include "ui/ui_render_device.h"
+#include "event/event_system.h"
+#include "os/file_manager.h"
+#include
namespace api {
+ using namespace Noesis;
+ Ptr mView;
void EditorModule::OnLoad(int argc, char** argv)
{
-
+ PackagePath editor_noesis{"/engine/assets/noesis"};
+ FileManager::Ptr()->Mount("editor_noesis", editor_noesis.RealPath().c_str());
}
void EditorModule::OnUnload()
@@ -10,6 +18,17 @@ namespace api {
}
void EditorModule::Initialize(void)
{
-
+ Ptr xaml = GUI::LoadXaml("/editor_noesis/Menu.xaml");
+ mView = GUI::CreateView(xaml);
+ mView->SetFlags(RenderFlags_PPAA | RenderFlags_LCD);
+ mView->SetSize(1024, 768);
+ //mView->GetRenderer()->Init(UIRenderDevice::Ptr());
+ EventSystem::Ptr()->BeginRenderFrame.Subscribe(mInfo.name, [](FrameGraph& graph, int32_t frame) {
+ //mView->Update(0.033);
+ //IRenderer* renderer = mView->GetRenderer();
+ //renderer->UpdateRenderTree();
+ //renderer->RenderOffscreen();
+ //renderer->Render();
+ });
}
}
\ No newline at end of file
diff --git a/engine/src/editor/window/editor_main_window.cpp b/engine/src/editor/window/editor_main_window.cpp
new file mode 100644
index 0000000..5bea52f
--- /dev/null
+++ b/engine/src/editor/window/editor_main_window.cpp
@@ -0,0 +1,9 @@
+#include "editor/window/editor_main_window.h"
+namespace api {
+ void EditorMainWindow::InitializeComponent()
+ {
+ for (int i = 0; i < 1000; i++) {
+ int j = 1;
+ }
+ }
+}
\ No newline at end of file
diff --git a/engine/src/engine/api.cpp b/engine/src/engine/api.cpp
index cc73669..60b6907 100644
--- a/engine/src/engine/api.cpp
+++ b/engine/src/engine/api.cpp
@@ -1,24 +1,28 @@
#include "engine/api.h"
#include "os/file_manager.h"
+#include "ui/ui_render_device.h"
#include "xmalloc_new_delete.h"
-class ENGINE_API EngineModule : public api::IDynamicModule
-{
-public:
- void OnLoad(int argc, char** argv) override {
+namespace api {
+ class ENGINE_API EngineModule : public api::IDynamicModule
+ {
+ public:
+ void OnLoad(int argc, char** argv) override {
#ifdef ENGINE_ROOT
- api::FileManager::Ptr()->Mount("engine", TOSTRING(ENGINE_ROOT));
+ api::FileManager::Ptr()->Mount("engine", TOSTRING(ENGINE_ROOT));
#endif
- };
- void OnUnload() override {
- };
- void InitMetaData(void) override {
- mInfo.dependencies = {
- {"app","1.0.1", "static"},
- {"core", "1.0.1", "static" },
- {"asset", "1.0.1", "static" },
- {"render", "1.0.1", "static" },
- {"ui", "1.0.1", "static" },
+ new UIRenderDevice(RenderAPI::Ptr());
+ };
+ void OnUnload() override {
+ };
+ void InitMetaData(void) override {
+ mInfo.dependencies = {
+ {"app","1.0.1", "static"},
+ {"core", "1.0.1", "static" },
+ {"asset", "1.0.1", "static" },
+ {"render", "1.0.1", "static" },
+ {"ui", "1.0.1", "static" },
+ };
};
};
-};
-IMPLEMENT_DYNAMIC_MODULE(ENGINE_API, EngineModule, engine)
\ No newline at end of file
+ IMPLEMENT_DYNAMIC_MODULE(ENGINE_API, EngineModule, engine)
+}
\ No newline at end of file
diff --git a/engine/src/engine/plugin.cpp b/engine/src/engine/plugin.cpp
index 85ef34b..b125c6f 100644
--- a/engine/src/engine/plugin.cpp
+++ b/engine/src/engine/plugin.cpp
@@ -9,25 +9,33 @@
#include "zlog.h"
#include "module_manager_impl.inl"
#include "file_manager_impl.inl"
+IMPLEMENT_STATIC_MODULE(CORE_API, api::CoreModule, core)
#endif // !CORE_API_VAL
#ifndef ASSET_API_VAL
#define ASSET_API_VAL 1
#include "resource_system_impl.inl"
#include "asset_visit_impl.inl"
+IMPLEMENT_STATIC_MODULE(ASSET_API, api::AssetModule, asset)
#endif // !ASSET_API_VAL
#ifndef RENDER_API_VAL
#define RENDER_API_VAL 1
#include "renderapi_impl.inl"
#include "window_impl.inl"
+#include "render/render_module.h"
+IMPLEMENT_STATIC_MODULE(RENDER_API, api::RenderModule, render);
#endif // !RENDER_API_VAL
#ifndef APP_API_VAL
#define APP_API_VAL 1
#include "app_impl.inl"
#include "event_system_impl.inl"
+IMPLEMENT_STATIC_MODULE(APP_API, api::AppModule, app)
#endif // !APP_API_VAL
-#include "ui/ui_module.h"
-IMPLEMENT_STATIC_MODULE(UI_API, api::UIModule, ui)
\ No newline at end of file
+#ifndef UI_API_VAL
+#define UI_API_VAL 1
+#include "ui_render_device_impl.inl"
+IMPLEMENT_STATIC_MODULE(UI_API, api::UIModule, ui)
+#endif // !UI_API_VAL
diff --git a/engine/xmake.lua b/engine/xmake.lua
index 38e219a..7d756f0 100644
--- a/engine/xmake.lua
+++ b/engine/xmake.lua
@@ -12,7 +12,7 @@ target("editor")
set_kind("shared")
set_group("Engine")
add_rules("engine.api")
- add_headerfiles("include/editor/**.h")
+ add_headerfiles("include/editor/**.h","assets/noesis/*.xaml")
add_includedirs("include")
add_files("src/editor/**.cpp")
add_deps("engine",{public = true})
diff --git a/game/zworld/src/zworld.cpp b/game/zworld/src/zworld.cpp
index 3a05a63..cd65b80 100644
--- a/game/zworld/src/zworld.cpp
+++ b/game/zworld/src/zworld.cpp
@@ -20,9 +20,6 @@ void ZWorldModule::OnLoad(int argc, char** argv)
window->CreateRender(args);
API->Init();
API->context.views.push_back({});
- EventSystem::Ptr()->BeginRenderFrame.Subscribe(mInfo.name, [](FrameGraph& graph, uint32_t frame) {
- graph.AddRenderPass();
- });
}
void ZWorldModule::InitMetaData()
{
@@ -35,6 +32,9 @@ void ZWorldModule::InitMetaData()
}
void ZWorldModule::Initialize()
{
+ EventSystem::Ptr()->BeginRenderFrame.Subscribe(mInfo.name, [](FrameGraph& graph, uint32_t frame) {
+ graph.AddRenderPass();
+ });
}
void ZWorldModule::OnUnload()
{
diff --git a/xmake.lua b/xmake.lua
index 02cbfc5..5c62e25 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -6,7 +6,7 @@ set_languages("cxx20")
set_project("zengine")
set_toolchains("clang")
set_runtimes("MD","c++_shared")
-add_cxflags("-stdlib=libc++")
+add_cxxflags("-stdlib=libc++", "-Wno-parentheses-equality")
add_ldflags("-stdlib=libc++")
includes("engine")
includes("game/*/xmake.lua")