From c39c9edb063a7603060344b5106d110aec86f40f Mon Sep 17 00:00:00 2001 From: FlyAntNotDown <461425614@qq.com> Date: Sun, 23 Mar 2025 21:11:33 +0800 Subject: [PATCH 1/4] feat: update margins in widget samples --- Editor/Qml/EWidgetSamples.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Editor/Qml/EWidgetSamples.qml b/Editor/Qml/EWidgetSamples.qml index d458bdfe5..e39bf4de3 100644 --- a/Editor/Qml/EWidgetSamples.qml +++ b/Editor/Qml/EWidgetSamples.qml @@ -146,7 +146,7 @@ Rectangle { RowLayout { Layout.leftMargin: 5 - Layout.topMargin: 15 + Layout.topMargin: 35 EText { text: 'Texts' @@ -195,7 +195,7 @@ Rectangle { RowLayout { Layout.leftMargin: 5 - Layout.topMargin: 15 + Layout.topMargin: 35 EText { text: 'Icons' @@ -275,7 +275,7 @@ Rectangle { RowLayout { Layout.leftMargin: 5 - Layout.topMargin: 15 + Layout.topMargin: 35 EText { text: 'Switches' style: EText.Style.Title1 @@ -316,7 +316,7 @@ Rectangle { RowLayout { Layout.leftMargin: 5 - Layout.topMargin: 15 + Layout.topMargin: 35 EText { text: 'TextInput' style: EText.Style.Title1 From 4510ccacfc58267ecebdca8b736a3ac605b6b877 Mon Sep 17 00:00:00 2001 From: John Kindem <461425614@qq.com> Date: Mon, 24 Mar 2025 21:16:24 +0800 Subject: [PATCH 2/4] feat: misc update --- Editor/Include/Editor/EditorModule.h | 2 +- Editor/Src/Widget/GraphicsSampleWidget.cpp | 3 +- .../Launch/Include/Launch/GameApplication.h | 29 ++ .../Source/Launch/Include/Launch/GameClient.h | 2 +- .../Launch/Include/Launch/GameViewport.h | 40 ++- Engine/Source/Launch/Src/GameApplication.cpp | 69 ++++ Engine/Source/Launch/Src/GameViewport.cpp | 115 ++++++- Engine/Source/Launch/Src/Main.cpp | 12 +- Engine/Source/RHI-DirectX12/Src/Device.cpp | 2 +- Engine/Source/RHI-Vulkan/Src/Device.cpp | 6 - .../Render/Include/Render/RenderGraph.h | 15 +- .../Source/Render/Include/Render/Renderer.h | 5 + .../Include/Render/SceneProxy/Primitive.h | 15 + Engine/Source/Render/Include/Render/Shader.h | 2 + Engine/Source/Render/Include/Render/View.h | 23 +- Engine/Source/Render/Src/RenderGraph.cpp | 38 ++- Engine/Source/Render/Src/Renderer.cpp | 4 +- Engine/Source/Render/Src/View.cpp | 26 +- .../Runtime/Include/Runtime/Asset/Asset.h | 15 +- .../Runtime/Include/Runtime/Asset/Level.h | 6 +- .../Runtime/Include/Runtime/Asset/Material.h | 29 +- .../Runtime/Include/Runtime/Asset/Mesh.h | 4 +- .../Runtime/Include/Runtime/Asset/Texture.h | 128 +++++++ .../Include/Runtime/Component/Primitive.h | 20 ++ .../Runtime/Include/Runtime/Component/Scene.h | 3 +- .../Source/Runtime/Include/Runtime/Engine.h | 2 +- .../Runtime/Include/Runtime/GameModule.h | 15 + .../Runtime/Include/Runtime/RenderThreadPtr.h | 118 +++++++ .../Runtime/Include/Runtime/System/Render.h | 1 + .../Runtime/Include/Runtime/System/Scene.h | 12 +- .../Source/Runtime/Include/Runtime/Viewport.h | 7 +- Engine/Source/Runtime/Src/Asset/Asset.cpp | 15 +- Engine/Source/Runtime/Src/Asset/Level.cpp | 5 + Engine/Source/Runtime/Src/Asset/Material.cpp | 9 +- Engine/Source/Runtime/Src/Asset/Texture.cpp | 316 ++++++++++++++++++ .../Runtime/Src/Component/Primitive.cpp | 9 + Engine/Source/Runtime/Src/Engine.cpp | 2 +- Engine/Source/Runtime/Src/System/Render.cpp | 5 +- Engine/Source/Runtime/Src/System/Scene.cpp | 6 +- Engine/Source/Runtime/Src/Viewport.cpp | 2 +- Engine/Source/Runtime/Src/World.cpp | 4 +- .../Source/Runtime/Test/RuntimeTestModule.h | 2 +- Sample/Base/Application.cpp | 1 + 43 files changed, 1047 insertions(+), 97 deletions(-) create mode 100644 Engine/Source/Launch/Include/Launch/GameApplication.h create mode 100644 Engine/Source/Launch/Src/GameApplication.cpp create mode 100644 Engine/Source/Render/Include/Render/SceneProxy/Primitive.h create mode 100644 Engine/Source/Runtime/Include/Runtime/Asset/Texture.h create mode 100644 Engine/Source/Runtime/Include/Runtime/Component/Primitive.h create mode 100644 Engine/Source/Runtime/Include/Runtime/GameModule.h create mode 100644 Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h create mode 100644 Engine/Source/Runtime/Src/Asset/Texture.cpp create mode 100644 Engine/Source/Runtime/Src/Component/Primitive.cpp diff --git a/Editor/Include/Editor/EditorModule.h b/Editor/Include/Editor/EditorModule.h index 3caee2ee2..7ebb2d17c 100644 --- a/Editor/Include/Editor/EditorModule.h +++ b/Editor/Include/Editor/EditorModule.h @@ -7,7 +7,7 @@ #include namespace Editor { - class EditorModule final : public Runtime::IEngineModule { + class EditorModule final : public Runtime::EngineModule { public: void OnUnload() override; ::Core::ModuleType Type() const override; diff --git a/Editor/Src/Widget/GraphicsSampleWidget.cpp b/Editor/Src/Widget/GraphicsSampleWidget.cpp index b01cd42b4..20e02f8ec 100644 --- a/Editor/Src/Widget/GraphicsSampleWidget.cpp +++ b/Editor/Src/Widget/GraphicsSampleWidget.cpp @@ -143,7 +143,8 @@ namespace Editor { { static std::vector formatQualifiers = { RHI::PixelFormat::rgba8Unorm, - RHI::PixelFormat::bgra8Unorm}; + RHI::PixelFormat::bgra8Unorm + }; if (swapChain != nullptr) { WaitDeviceIdle(); diff --git a/Engine/Source/Launch/Include/Launch/GameApplication.h b/Engine/Source/Launch/Include/Launch/GameApplication.h new file mode 100644 index 000000000..3a749ea49 --- /dev/null +++ b/Engine/Source/Launch/Include/Launch/GameApplication.h @@ -0,0 +1,29 @@ +// +// Created by johnk on 2025/3/24. +// + +#pragma once + +#include +#include +#include +#include + +namespace Launch { + class GameApplication { + public: + GameApplication(int argc, char* argv[]); + ~GameApplication(); + + void Tick(); + bool ShouldClose() const; + + private: + double lastFrameTimeSeconds; + double thisFrameTimeSeconds; + float deltaTimeSeconds; + Common::UniquePtr viewport; + Runtime::Engine* engine; + Runtime::GameModule* gameModule; + }; +} diff --git a/Engine/Source/Launch/Include/Launch/GameClient.h b/Engine/Source/Launch/Include/Launch/GameClient.h index e2310b521..76829934b 100644 --- a/Engine/Source/Launch/Include/Launch/GameClient.h +++ b/Engine/Source/Launch/Include/Launch/GameClient.h @@ -10,7 +10,7 @@ namespace Launch { class GameViewport; - class GameClient : public Runtime::Client { + class GameClient final : public Runtime::Client { public: explicit GameClient(GameViewport& inViewport); ~GameClient() override; diff --git a/Engine/Source/Launch/Include/Launch/GameViewport.h b/Engine/Source/Launch/Include/Launch/GameViewport.h index 8ab3c92d0..c053993b8 100644 --- a/Engine/Source/Launch/Include/Launch/GameViewport.h +++ b/Engine/Source/Launch/Include/Launch/GameViewport.h @@ -4,22 +4,50 @@ #pragma once +#include +#if PLATFORM_WINDOWS +#define GLFW_EXPOSE_NATIVE_WIN32 +#elif PLATFORM_MACOS +#define GLFW_EXPOSE_NATIVE_COCOA +#endif +#include + +#include #include +#include +#include namespace Launch { + struct GameViewportDesc { + std::string title; + uint32_t width; + uint32_t height; + }; + class GameViewport final : public Runtime::Viewport { public: - GameViewport(); + explicit GameViewport(const GameViewportDesc& inDesc); ~GameViewport() override; Runtime::Client& GetClient() override; Runtime::PresentInfo GetNextPresentInfo() override; - size_t GetWidth() const override; - size_t GetHeight() const override; + uint32_t GetWidth() const override; + uint32_t GetHeight() const override; + void Resize(uint32_t inWidth, uint32_t inHeight) override; + + bool ShouldClose() const; + void PollEvents() const; + void RecreateSwapChain(uint32_t inWidth, uint32_t inHeight); + void WaitDeviceIdle() const; private: - // TODO glfw window - // TODO rhi swap chain - // TODO game client + Render::RenderModule& renderModule; + GameClient client; + GLFWwindow* window; + RHI::Device* device; + Common::UniquePtr imageReadySemaphore; + Common::UniquePtr renderFinishedSemaphore; + Common::UniquePtr surface; + Common::UniquePtr swapChain; }; } diff --git a/Engine/Source/Launch/Src/GameApplication.cpp b/Engine/Source/Launch/Src/GameApplication.cpp new file mode 100644 index 000000000..ae1e9ff89 --- /dev/null +++ b/Engine/Source/Launch/Src/GameApplication.cpp @@ -0,0 +1,69 @@ +// +// Created by johnk on 2025/3/24. +// + +#include +#include +#include +#include +#include +#include +#include + +namespace Launch { + extern std::string gameModuleName; + + static Core::CmdlineArgValue caRhiType( + "rhiType", "-rhi", RHI::GetPlatformDefaultRHIAbbrString(), + "rhi abbr string, can be 'dx12' or 'vulkan'"); + + GameApplication::GameApplication(int argc, char* argv[]) + : lastFrameTimeSeconds(Common::TimePoint::Now().ToSeconds()) + , thisFrameTimeSeconds(Common::TimePoint::Now().ToSeconds()) + , deltaTimeSeconds(0) + { + Core::Cli::Get().Parse(argc, argv); + + Runtime::EngineInitParams engineInitParams; + engineInitParams.logToFile = true; + engineInitParams.rhiType = caRhiType.GetValue(); + Runtime::EngineHolder::Load(gameModuleName, engineInitParams); + + engine = &Runtime::EngineHolder::Get(); + gameModule = &Core::ModuleManager::Get().GetTyped(gameModuleName); + + GameViewportDesc viewportDesc; + viewportDesc.title = gameModule->GetGameName(); + // TODO load from config + viewportDesc.width = 1024; + viewportDesc.height = 768; + viewport = Common::MakeUnique(viewportDesc); + + auto& settingRegistry = Runtime::SettingsRegistry::Get(); + settingRegistry.LoadAllSettings(); + + const auto& gameSettings = Runtime::SettingsRegistry::Get().GetSettings(); + const auto startupLevel = Runtime::AssetManager::Get().SyncLoad(gameSettings.gameStartupLevel); + viewport->GetClient().GetWorld().LoadFrom(startupLevel); + } + + GameApplication::~GameApplication() + { + Runtime::EngineHolder::Unload(); + } + + void GameApplication::Tick() + { + thisFrameTimeSeconds = Common::TimePoint::Now().ToSeconds(); + deltaTimeSeconds = thisFrameTimeSeconds - lastFrameTimeSeconds; + lastFrameTimeSeconds = thisFrameTimeSeconds; + + engine->Tick(deltaTimeSeconds); + viewport->PollEvents(); + } + + bool GameApplication::ShouldClose() const + { + return viewport->ShouldClose(); + } +} diff --git a/Engine/Source/Launch/Src/GameViewport.cpp b/Engine/Source/Launch/Src/GameViewport.cpp index 8f2caad5c..be530fcd3 100644 --- a/Engine/Source/Launch/Src/GameViewport.cpp +++ b/Engine/Source/Launch/Src/GameViewport.cpp @@ -4,38 +4,127 @@ #include +namespace Launch::Internal { + static void* GetGlfwPlatformWindow(GLFWwindow* inWindow) + { +#if PLATFORM_WINDOWS + return glfwGetWin32Window(inWindow); +#elif PLATFORM_MACOS + return glfwGetCocoaView(inWindow); +#else + Unimplement(); + return nullptr; +#endif + } +} + namespace Launch { - GameViewport::GameViewport() + GameViewport::GameViewport(const GameViewportDesc& inDesc) + : renderModule(Runtime::EngineHolder::Get().GetRenderModule()) + , client(*this) { - // TODO + glfwInit(); + window = glfwCreateWindow(static_cast(inDesc.width), static_cast(inDesc.height), inDesc.title.c_str(), nullptr, nullptr); + + device = renderModule.GetDevice(); + imageReadySemaphore = device->CreateSemaphore(); + renderFinishedSemaphore = device->CreateSemaphore(); + + surface = device->CreateSurface(RHI::SurfaceCreateInfo(Internal::GetGlfwPlatformWindow(window))); + RecreateSwapChain(inDesc.width, inDesc.height); } GameViewport::~GameViewport() { - // TODO + WaitDeviceIdle(); + glfwDestroyWindow(window); + glfwTerminate(); } Runtime::Client& GameViewport::GetClient() { - // TODO - return *static_cast(nullptr); + return client; } Runtime::PresentInfo GameViewport::GetNextPresentInfo() { - // TODO - return Runtime::PresentInfo(); + const auto backTextureIndex = swapChain->AcquireBackTexture(imageReadySemaphore.Get()); + + Runtime::PresentInfo result; + result.backTexture = swapChain->GetTexture(backTextureIndex); + result.imageReadySemaphore = imageReadySemaphore.Get(); + result.renderFinishedSemaphore = renderFinishedSemaphore.Get(); + return result; + } + + uint32_t GameViewport::GetWidth() const + { + int width; + glfwGetWindowSize(window, &width, nullptr); + return static_cast(width); + } + + uint32_t GameViewport::GetHeight() const + { + int height; + glfwGetWindowSize(window, nullptr, &height); + return static_cast(height); } - size_t GameViewport::GetWidth() const + void GameViewport::Resize(uint32_t inWidth, uint32_t inHeight) { - // TODO - return 0; + glfwSetWindowSize(window, static_cast(inWidth), static_cast(inHeight)); + RecreateSwapChain(inWidth, inHeight); } - size_t GameViewport::GetHeight() const + bool GameViewport::ShouldClose() const { - // TODO - return 0; + return static_cast(glfwWindowShouldClose(window)); + } + + void GameViewport::PollEvents() const // NOLINT + { + glfwPollEvents(); + } + + void GameViewport::RecreateSwapChain(uint32_t inWidth, uint32_t inHeight) + { + static std::vector formatQualifiers = { + RHI::PixelFormat::rgba8Unorm, + RHI::PixelFormat::bgra8Unorm + }; + + WaitDeviceIdle(); + if (swapChain.Valid()) { + swapChain.Reset(); + } + + std::optional pixelFormat = {}; + for (const auto format : formatQualifiers) { + if (device->CheckSwapChainFormatSupport(surface.Get(), format)) { + pixelFormat = format; + break; + } + } + Assert(pixelFormat.has_value()); + + swapChain = device->CreateSwapChain( + RHI::SwapChainCreateInfo() + .SetPresentQueue(device->GetQueue(RHI::QueueType::graphics, 0)) + .SetSurface(surface.Get()) + .SetTextureNum(2) + .SetFormat(pixelFormat.value()) + .SetWidth(inWidth) + .SetHeight(inHeight) + .SetPresentMode(RHI::PresentMode::immediately)); + } + + void GameViewport::WaitDeviceIdle() const + { + renderModule.GetRenderThread().Flush(); + + const Common::UniquePtr fence = device->CreateFence(false); + device->GetQueue(RHI::QueueType::graphics, 0)->Flush(fence.Get()); + fence->Wait(); } } diff --git a/Engine/Source/Launch/Src/Main.cpp b/Engine/Source/Launch/Src/Main.cpp index bdbf61526..68e074c71 100644 --- a/Engine/Source/Launch/Src/Main.cpp +++ b/Engine/Source/Launch/Src/Main.cpp @@ -2,13 +2,13 @@ // Created by johnk on 2025/2/19. // +#include + int main(int argc, char* argv[]) { - // TODO parse command line arguments - // TODO load runtime module - // TODO load engine - // TODO create game viewport - // TODO load startup level to world - // TODO main loop tick + Launch::GameApplication app(argc, argv); + while (!app.ShouldClose()) { + app.Tick(); + } return 0; } diff --git a/Engine/Source/RHI-DirectX12/Src/Device.cpp b/Engine/Source/RHI-DirectX12/Src/Device.cpp index 470badfe7..040afecd8 100644 --- a/Engine/Source/RHI-DirectX12/Src/Device.cpp +++ b/Engine/Source/RHI-DirectX12/Src/Device.cpp @@ -264,7 +264,7 @@ namespace RHI::DirectX12 { const auto createInfo = texture.GetCreateInfo(); const auto nativeResourceDesc = dx12Texture.GetNative()->GetDesc(); - const size_t nativeSubResourceIndex = D3D12CalcSubresource(subResourceInfo.mipLevel, subResourceInfo.arrayLayer, 0, createInfo.mipLevels, createInfo.dimension == TextureDimension::t3D ? 1 : createInfo.depthOrArraySize); + const size_t nativeSubResourceIndex = D3D12CalcSubresource(subResourceInfo.mipLevel, subResourceInfo.arrayLayer, 0, 1, 1); D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint; nativeDevice->GetCopyableFootprints(&nativeResourceDesc, nativeSubResourceIndex, 1, 0, &footprint, nullptr, nullptr, nullptr); diff --git a/Engine/Source/RHI-Vulkan/Src/Device.cpp b/Engine/Source/RHI-Vulkan/Src/Device.cpp index 5b6e0ebc9..e96888021 100644 --- a/Engine/Source/RHI-Vulkan/Src/Device.cpp +++ b/Engine/Source/RHI-Vulkan/Src/Device.cpp @@ -169,14 +169,8 @@ namespace RHI::Vulkan { TextureSubResourceCopyFootprint VulkanDevice::GetTextureSubResourceCopyFootprint(const Texture& texture, const TextureSubResourceInfo& subResourceInfo) { - const auto& vkTexture = static_cast(texture); const auto& createInfo = texture.GetCreateInfo(); - VkImageSubresource subResource {}; - subResource.mipLevel = subResourceInfo.mipLevel; - subResource.arrayLayer = subResourceInfo.arrayLayer; - subResource.aspectMask = EnumCast(subResourceInfo.aspect); - TextureSubResourceCopyFootprint result {}; result.extent = { createInfo.width, createInfo.height, createInfo.dimension == TextureDimension::t3D ? createInfo.depthOrArraySize : 1 }; result.bytesPerPixel = GetBytesPerPixel(createInfo.format); diff --git a/Engine/Source/Render/Include/Render/RenderGraph.h b/Engine/Source/Render/Include/Render/RenderGraph.h index cf4c6c834..0288b8bbb 100644 --- a/Engine/Source/Render/Include/Render/RenderGraph.h +++ b/Engine/Source/Render/Include/Render/RenderGraph.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -236,13 +237,21 @@ namespace Render { using RGBindGroupRef = RGBindGroup*; struct RGBufferUploadInfo { - void* data; - size_t size; + struct DataView { + void* data; + size_t size; + }; + + struct DataCopy { + std::vector data; + }; + + std::variant src; size_t srcOffset; size_t dstOffset; RGBufferUploadInfo(); - RGBufferUploadInfo(void* inData, size_t inSize, size_t inSrcOffset = 0, size_t inDstOffset = 0); + RGBufferUploadInfo(void* inData, size_t inSize, size_t inSrcOffset = 0, size_t inDstOffset = 0, bool inCopy = false); }; class RGPass { diff --git a/Engine/Source/Render/Include/Render/Renderer.h b/Engine/Source/Render/Include/Render/Renderer.h index f40ecfafc..200ab0a1f 100644 --- a/Engine/Source/Render/Include/Render/Renderer.h +++ b/Engine/Source/Render/Include/Render/Renderer.h @@ -6,6 +6,7 @@ #include #include +#include namespace RHI { class Texture; @@ -17,6 +18,7 @@ namespace Render { class Renderer { public: struct Params { + RHI::Device* device; const Scene* scene; const RHI::Texture* surface; Common::UVec2 surfaceExtent; @@ -32,6 +34,7 @@ namespace Render { virtual void Render(float inDeltaTimeSeconds) = 0; protected: + RHI::Device* device; const Scene* scene; const RHI::Texture* surface; Common::UVec2 surfaceExtent; @@ -52,5 +55,7 @@ namespace Render { private: void FinalizeViews() const; + + RGBuilder rgBuilder; }; } diff --git a/Engine/Source/Render/Include/Render/SceneProxy/Primitive.h b/Engine/Source/Render/Include/Render/SceneProxy/Primitive.h new file mode 100644 index 000000000..6e3543b49 --- /dev/null +++ b/Engine/Source/Render/Include/Render/SceneProxy/Primitive.h @@ -0,0 +1,15 @@ +// +// Created by johnk on 2025/3/24. +// + +#pragma once + +#include + +namespace Render { + struct PrimitiveSceneProxy { + PrimitiveSceneProxy(); + + // TODO + }; +} diff --git a/Engine/Source/Render/Include/Render/Shader.h b/Engine/Source/Render/Include/Render/Shader.h index 991208f75..65ec149ed 100644 --- a/Engine/Source/Render/Include/Render/Shader.h +++ b/Engine/Source/Render/Include/Render/Shader.h @@ -272,6 +272,8 @@ namespace Render { return 0; \ }(); \ +#define ALIGN_AS_GPU alignas(16) + namespace Render { class MaterialShader : public Shader {}; } diff --git a/Engine/Source/Render/Include/Render/View.h b/Engine/Source/Render/Include/Render/View.h index c42c73161..720c27abc 100644 --- a/Engine/Source/Render/Include/Render/View.h +++ b/Engine/Source/Render/Include/Render/View.h @@ -6,14 +6,35 @@ #include #include +#include namespace Render { struct ViewData { ViewData(); + Common::FVec3 origin; + Common::URect viewport; Common::FMat4x4 viewMatrix; Common::FMat4x4 projectionMatrix; - Common::URect viewport; + }; + + struct ALIGN_AS_GPU ViewUniform { + ViewUniform(const ViewData& inViewData, const ViewData& inPrevViewData); + + Common::FVec3 origin; + Common::FMat4x4 worldToViewMatrix; + Common::FMat4x4 viewToWorldMatrix; + Common::FMat4x4 viewToClipMatrix; + Common::FMat4x4 clipToViewMatrix; + Common::FMat4x4 worldToClipMatrix; + Common::FMat4x4 clipToWorldMatrix; + Common::FVec3 prevOrigin; + Common::FMat4x4 prevWorldToViewMatrix; + Common::FMat4x4 prevViewToWorldMatrix; + Common::FMat4x4 prevViewToClipMatrix; + Common::FMat4x4 prevClipToViewMatrix; + Common::FMat4x4 prevWorldToClipMatrix; + Common::FMat4x4 prevClipToWorldMatrix; }; struct ViewState { diff --git a/Engine/Source/Render/Src/RenderGraph.cpp b/Engine/Source/Render/Src/RenderGraph.cpp index f1b2f7d24..2c74e49f1 100644 --- a/Engine/Source/Render/Src/RenderGraph.cpp +++ b/Engine/Source/Render/Src/RenderGraph.cpp @@ -322,19 +322,22 @@ namespace Render { } RGBufferUploadInfo::RGBufferUploadInfo() - : data(nullptr) - , size(0) - , srcOffset(0) + : srcOffset(0) , dstOffset(0) { } - RGBufferUploadInfo::RGBufferUploadInfo(void* inData, size_t inSize, size_t inSrcOffset, size_t inDstOffset) - : data(inData) - , size(inSize) - , srcOffset(inSrcOffset) + RGBufferUploadInfo::RGBufferUploadInfo(void* inData, size_t inSize, size_t inSrcOffset, size_t inDstOffset, bool inCopy) + : srcOffset(inSrcOffset) , dstOffset(inDstOffset) { + if (inCopy) { + auto& [data] = src.emplace(); + data.resize(inSize); + memcpy(data.data(), inData, inSize); + } else { + src.emplace(inData, inSize); + } } RGPass::RGPass(std::string inName, RGPassType inType) @@ -850,9 +853,24 @@ namespace Render { auto* rhiBuffer = GetRHI(buffer); bufferUploadTasks.emplace_back(RenderWorkerThreads::Get().EmplaceTask([rhiBuffer, uploadInfo]() -> void { - const auto* src = static_cast(uploadInfo.data) + uploadInfo.srcOffset; - auto* dst = rhiBuffer->Map(RHI::MapMode::write, uploadInfo.dstOffset, uploadInfo.size); - memcpy(dst, src, uploadInfo.size); + const uint8_t* srcDataPtr = nullptr; + size_t srcDataSize = 0; + if (uploadInfo.src.index() == 1) { + const auto& [srcData, srcSize] = std::get(uploadInfo.src); + srcDataPtr = static_cast(srcData); + srcDataSize = srcSize; + } else if (uploadInfo.src.index() == 2) { + const auto& [srcData] = std::get(uploadInfo.src); + srcDataPtr = srcData.data(); + srcDataSize = srcData.size() * sizeof(uint8_t); + } else { + Unimplement(); + } + + Assert(srcDataPtr != nullptr && srcDataSize > 0); + const auto* src = srcDataPtr + uploadInfo.srcOffset; // NOLINT + auto* dst = rhiBuffer->Map(RHI::MapMode::write, uploadInfo.dstOffset, srcDataSize); + memcpy(dst, src, srcDataSize); rhiBuffer->UnMap(); })); } diff --git a/Engine/Source/Render/Src/Renderer.cpp b/Engine/Source/Render/Src/Renderer.cpp index 22ffa92cd..971b2474d 100644 --- a/Engine/Source/Render/Src/Renderer.cpp +++ b/Engine/Source/Render/Src/Renderer.cpp @@ -6,7 +6,8 @@ namespace Render { Renderer::Renderer(const Params& inParams) - : scene(inParams.scene) + : device(inParams.device) + , scene(inParams.scene) , surface(inParams.surface) , surfaceExtent(inParams.surfaceExtent) , views(inParams.views) @@ -20,6 +21,7 @@ namespace Render { StandardRenderer::StandardRenderer(const Params& inParams) : Renderer(inParams) + , rgBuilder(*device) { } diff --git a/Engine/Source/Render/Src/View.cpp b/Engine/Source/Render/Src/View.cpp index 51f285bcd..95d2404b4 100644 --- a/Engine/Source/Render/Src/View.cpp +++ b/Engine/Source/Render/Src/View.cpp @@ -8,11 +8,31 @@ namespace Render { ViewData::ViewData() : viewMatrix(Common::FMat4x4Consts::identity) , projectionMatrix(Common::FMat4x4Consts::identity) - , viewport() { } - ViewState::ViewState() {} + ViewUniform::ViewUniform(const ViewData& inViewData, const ViewData& inPrevViewData) + : origin(inViewData.origin) + , worldToViewMatrix(inViewData.viewMatrix) + , viewToWorldMatrix(worldToViewMatrix.Inverse()) + , viewToClipMatrix(inViewData.projectionMatrix) + , clipToViewMatrix(viewToClipMatrix.Inverse()) + , worldToClipMatrix(viewToClipMatrix * worldToViewMatrix) + , clipToWorldMatrix(worldToClipMatrix.Inverse()) + , prevOrigin(inViewData.origin) + , prevWorldToViewMatrix(inPrevViewData.viewMatrix) + , prevViewToWorldMatrix(prevWorldToViewMatrix.Inverse()) + , prevViewToClipMatrix(inPrevViewData.projectionMatrix) + , prevClipToViewMatrix(prevViewToClipMatrix.Inverse()) + , prevWorldToClipMatrix(prevViewToClipMatrix * prevWorldToViewMatrix) + , prevClipToWorldMatrix(prevWorldToClipMatrix.Inverse()) + { + } + + ViewState::ViewState() = default; - View::View() {} + View::View() + : state(nullptr) + { + } } \ No newline at end of file diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h b/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h index 625c068cb..0a17d5e3e 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h @@ -19,13 +19,20 @@ #include namespace Runtime { - struct RUNTIME_API EClass() Asset { + class RUNTIME_API EClass() Asset { EPolyClassBody(Asset) + public: Asset(); explicit Asset(Core::Uri inUri); virtual ~Asset(); + const Core::Uri& Uri() const; + void SetUri(Core::Uri inUri); + + virtual void PostLoad(); + + private: EProperty() Core::Uri uri; }; @@ -251,7 +258,7 @@ namespace Runtime { const Core::Uri& AssetPtr::Uri() const { Assert(ptr != nullptr); - return ptr->uri; + return ptr->Uri(); } template A> @@ -579,8 +586,8 @@ namespace Runtime { Mirror::Any ref = std::ref(*result.Get()); ref.Deserialize(stream); - // reset uri is useful for moved asset - result->uri = uri; + result->SetUri(uri); + result->PostLoad(); return result; } } diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Level.h b/Engine/Source/Runtime/Include/Runtime/Asset/Level.h index 3db1f3397..5e43bae1d 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Level.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Level.h @@ -10,12 +10,16 @@ #include namespace Runtime { - struct RUNTIME_API EClass() Level final : Asset { + class RUNTIME_API EClass() Level final : public Asset { EPolyClassBody(Level) + public: explicit Level(Core::Uri inUri); ~Level() override; + EFunc() ECArchive& GetArchive(); + + private: EProperty() ECArchive archive; }; } diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Material.h b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h index 9dd175ad6..cbc2283b7 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Material.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h @@ -4,6 +4,8 @@ #pragma once +#include + #include #include #include @@ -16,26 +18,25 @@ namespace Runtime { max }; - class RUNTIME_API EClass() MaterialGraph { - EClassBody(MaterialGraph) + // TODO material parameter + + class RUNTIME_API EClass() Material : public Asset { + EPolyClassBody(Material) public: - MaterialGraph(); + explicit Material(Core::Uri inUri); + ~Material() override; private: - // TODO nodes etc. + EProperty() MaterialType type; + EProperty() std::string sourceCode; }; - struct RUNTIME_API EClass() Material final : Asset { - EPolyClassBody(Material) + class RUNTIME_API EClass() MaterialInstance final : public Material { + EPolyClassBody(MaterialInstance) - explicit Material(Core::Uri inUri); - ~Material() override; - - MaterialType type; - std::string sourceCode; -#if BUILD_EDITOR - MaterialGraph graph; -#endif + public: + explicit MaterialInstance(Core::Uri inUri); + ~MaterialInstance() override; }; } diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h index d494f825e..4760624a8 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h @@ -32,12 +32,14 @@ namespace Runtime { // TODO voxel data ? }; - struct RUNTIME_API EClass() StaticMesh final : Asset { + class RUNTIME_API EClass() StaticMesh final : public Asset { EPolyClassBody(StaticMesh) + public: explicit StaticMesh(Core::Uri inUri); ~StaticMesh() override; + private: EProperty() AssetPtr material; EProperty() std::vector lodVec; }; diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Texture.h b/Engine/Source/Runtime/Include/Runtime/Asset/Texture.h new file mode 100644 index 000000000..6c102ff8c --- /dev/null +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Texture.h @@ -0,0 +1,128 @@ +// +// Created by johnk on 2025/3/24. +// + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace Runtime { + enum class EEnum() TextureType : uint8_t { + t1D, + t2D, + t2DArray, + tCube, + tCubeArray, + t3D, + max + }; + + enum class EEnum() TextureFormat : uint8_t { + // 8-Bits + begin8Bits, + r8Unorm, + r8Snorm, + r8Uint, + r8Sint, + // 16-Bits + begin16Bits, + r16Uint, + r16Sint, + r16Float, + rg8Unorm, + rg8Snorm, + rg8Uint, + rg8Sint, + d16Unorm, + // 32-Bits + begin32Bits, + r32Uint, + r32Sint, + r32Float, + rg16Uint, + rg16Sint, + rg16Float, + rgba8Unorm, + rgba8UnormSrgb, + rgba8Snorm, + rgba8Uint, + rgba8Sint, + bgra8Unorm, + bgra8UnormSrgb, + rgb9E5Float, + rgb10A2Unorm, + rg11B10Float, + d24UnormS8Uint, + d32Float, + // 64-Bits + begin64Bits, + rg32Uint, + rg32Sint, + rg32Float, + rgba16Uint, + rgba16Sint, + rgba16Float, + d32FloatS8Uint, + // 128-Bits + begin128Bits, + rgba32Uint, + rgba32Sint, + rgba32Float, + max + }; + static_assert(static_cast(TextureFormat::max) == static_cast(RHI::PixelFormat::max)); + + class RUNTIME_API Texture final : public Asset { + EPolyClassBody(Texture) + + public: + using MipPixels = std::vector; + + explicit Texture(Core::Uri inUri); + ~Texture() override; + + void PostLoad() override; + + EFunc() TextureType GetType() const; + EFunc() TextureFormat GetFormat() const; + EFunc() uint32_t GetWidth() const; + EFunc() uint32_t GetHeight() const; + EFunc() uint32_t GetDepthOrArraySize() const; + EFunc() uint8_t GetMipLevels() const; + EFunc() uint8_t GetSamples() const; + EFunc() const std::string& GetName() const; + EFunc() MipPixels& GetMipPixels(uint8_t inMipLevel); + EFunc() const MipPixels& GetMipPixels(uint8_t inMipLevel) const; + + EFunc() void SetType(TextureType inType); + EFunc() void SetFormat(TextureFormat inFormat); + EFunc() void SetWidth(uint32_t inWidth); + EFunc() void SetHeight(uint32_t inHeight); + EFunc() void SetDepthOrArraySize(uint32_t inDepthOrArraySize); + EFunc() void SetMipLevels(uint8_t inMipLevels); + EFunc() void SetSamples(uint8_t inSamples); + EFunc() void SetName(const std::string& inName); + + EFunc() void UpdateMips(); + EFunc() void UpdateRHI(); + + private: + EProperty() TextureType type; + EProperty() TextureFormat format; + EProperty() uint32_t width; + EProperty() uint32_t height; + EProperty() uint32_t depthOrArraySize; + EProperty() uint8_t mipLevels; + EProperty() uint8_t samples; + EProperty() std::string name; + EProperty() std::vector mipsData; + RenderThreadPtr texture; + RenderThreadPtr textureView; + }; +} diff --git a/Engine/Source/Runtime/Include/Runtime/Component/Primitive.h b/Engine/Source/Runtime/Include/Runtime/Component/Primitive.h new file mode 100644 index 000000000..ce553a70c --- /dev/null +++ b/Engine/Source/Runtime/Include/Runtime/Component/Primitive.h @@ -0,0 +1,20 @@ +// +// Created by johnk on 2025/3/24. +// + +#pragma once + +#include +#include +#include +#include + +namespace Runtime { + struct RUNTIME_API EClass() StaticPrimitive final { + EClassBody(StaticPrimitive) + + StaticPrimitive(); + + EProperty() AssetPtr mesh; + }; +} diff --git a/Engine/Source/Runtime/Include/Runtime/Component/Scene.h b/Engine/Source/Runtime/Include/Runtime/Component/Scene.h index 2fa706fcd..ee1104b4d 100644 --- a/Engine/Source/Runtime/Include/Runtime/Component/Scene.h +++ b/Engine/Source/Runtime/Include/Runtime/Component/Scene.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include @@ -14,6 +15,6 @@ namespace Runtime { explicit SceneHolder(Render::Scene* inScene); - Render::Scene* scene; + RenderThreadPtr scene; }; } diff --git a/Engine/Source/Runtime/Include/Runtime/Engine.h b/Engine/Source/Runtime/Include/Runtime/Engine.h index b65f1a92b..3ad0662cc 100644 --- a/Engine/Source/Runtime/Include/Runtime/Engine.h +++ b/Engine/Source/Runtime/Include/Runtime/Engine.h @@ -53,7 +53,7 @@ namespace Runtime { bool IsEditor() override; }; - struct RUNTIME_API IEngineModule : Core::Module { // NOLINT + struct RUNTIME_API EngineModule : Core::Module { // NOLINT virtual Engine* CreateEngine(const EngineInitParams& inParams) = 0; }; diff --git a/Engine/Source/Runtime/Include/Runtime/GameModule.h b/Engine/Source/Runtime/Include/Runtime/GameModule.h new file mode 100644 index 000000000..bf9656c03 --- /dev/null +++ b/Engine/Source/Runtime/Include/Runtime/GameModule.h @@ -0,0 +1,15 @@ +// +// Created by johnk on 2025/3/24. +// + +#pragma once + +#include + +namespace Runtime { + struct RUNTIME_API GameModule : EngineModule { // NOLINT + Engine* CreateEngine(const EngineInitParams& inParams) override = 0; + + virtual std::string_view GetGameName() const = 0; + }; +} diff --git a/Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h b/Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h new file mode 100644 index 000000000..c80241675 --- /dev/null +++ b/Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h @@ -0,0 +1,118 @@ +// +// Created by johnk on 2025/3/25. +// + +#pragma once + +#include +#include + +namespace Runtime { + template + class RenderThreadPtr { + public: + RenderThreadPtr(); + RenderThreadPtr(T* inPtr); // NOLINT + RenderThreadPtr(Common::SharedPtr inPtr); // NOLINT + RenderThreadPtr(Common::UniquePtr&& inPtr); // NOLINT + ~RenderThreadPtr(); + + DefaultCopyable(RenderThreadPtr) // NOLINT + DefaultMovable(RenderThreadPtr) // NOLINT + + T* operator->() const noexcept; + T& operator*() const noexcept; + bool operator==(nullptr_t) const noexcept; + bool operator!=(nullptr_t) const noexcept; + explicit operator bool() const noexcept; + + bool Valid() const; + T* Get() const; + void Reset(T* pointer = nullptr); + + private: + Common::SharedPtr ptr; + }; +} + +namespace Runtime { + template + RenderThreadPtr::RenderThreadPtr() = default; + + template + RenderThreadPtr::RenderThreadPtr(T* inPtr) + : ptr(inPtr) + { + } + + template + RenderThreadPtr::RenderThreadPtr(Common::SharedPtr inPtr) + : ptr(std::move(inPtr)) + { + } + + template + RenderThreadPtr::RenderThreadPtr(Common::UniquePtr&& inPtr) + : ptr(std::move(inPtr)) + { + } + + template + RenderThreadPtr::~RenderThreadPtr() + { + EngineHolder::Get().GetRenderModule().GetRenderThread().EmplaceTask([transferPtr = std::move(ptr)]() mutable -> void { + transferPtr.Reset(); + }); + } + + template + T* RenderThreadPtr::operator->() const noexcept + { + Assert(Core::ThreadContext::IsGameThread()); + return ptr.Get(); + } + + template + T& RenderThreadPtr::operator*() const noexcept + { + Assert(Core::ThreadContext::IsGameThread()); + return *ptr; + } + + template + bool RenderThreadPtr::operator==(nullptr_t) const noexcept + { + return ptr == nullptr; + } + + template + bool RenderThreadPtr::operator!=(nullptr_t) const noexcept + { + return ptr != nullptr; + } + + template + RenderThreadPtr::operator bool() const noexcept + { + return Valid(); + } + + template + bool RenderThreadPtr::Valid() const + { + return ptr != nullptr; + } + + template + T* RenderThreadPtr::Get() const + { + Assert(Core::ThreadContext::IsGameThread()); + return ptr.Get(); + } + + template + void RenderThreadPtr::Reset(T* pointer) + { + ptr.Reset(pointer); + } +} diff --git a/Engine/Source/Runtime/Include/Runtime/System/Render.h b/Engine/Source/Runtime/Include/Runtime/System/Render.h index d55d834b8..c1725e860 100644 --- a/Engine/Source/Runtime/Include/Runtime/System/Render.h +++ b/Engine/Source/Runtime/Include/Runtime/System/Render.h @@ -55,6 +55,7 @@ namespace Runtime { view.state = player.viewState; view.data.viewport = GetPlayerViewport(width, height, inPlayerNum, inPlayerIndex); view.data.viewMatrix = worldTransform.localToWorld.GetTransformMatrixNoScale().Inverse(); + view.data.origin = worldTransform.localToWorld.translation; if (camera.perspective) { const Common::FReversedZPerspectiveProjection projection(camera.fov.value(), static_cast(width), static_cast(height), camera.nearPlane, camera.farPlane); view.data.projectionMatrix = projection.GetProjectionMatrix(); diff --git a/Engine/Source/Runtime/Include/Runtime/System/Scene.h b/Engine/Source/Runtime/Include/Runtime/System/Scene.h index cc91f83bb..5bf203d3d 100644 --- a/Engine/Source/Runtime/Include/Runtime/System/Scene.h +++ b/Engine/Source/Runtime/Include/Runtime/System/Scene.h @@ -13,6 +13,7 @@ #include #include #include +#include namespace Runtime { class RUNTIME_API EClass() SceneSystem final : public System { @@ -38,6 +39,7 @@ namespace Runtime { EventsObserver directionalLightsObserver; EventsObserver pointLightsObserver; EventsObserver spotLightsObserver; + // TODO primitive }; } @@ -86,6 +88,8 @@ namespace Runtime::Internal { outSceneProxy.color = inComponent.color; outSceneProxy.intensity = inComponent.intensity; } + + // TODO primitive } namespace Runtime { @@ -95,7 +99,7 @@ namespace Runtime { const auto& sceneHolder = registry.GGet(); const auto& component = registry.Get(inEntity); const auto* transform = registry.Find(inEntity); - renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene, inEntity, component, transform = Internal::GetOptional(transform)]() -> void { + renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene.Get(), inEntity, component, transform = Internal::GetOptional(transform)]() -> void { SceneProxy sceneProxy; Internal::UpdateSceneProxyContent(sceneProxy, component); if (transform.has_value()) { @@ -110,7 +114,7 @@ namespace Runtime { { const auto& sceneHolder = registry.GGet(); const auto& component = registry.Get(inEntity); - renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene, inEntity, component]() -> void { + renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene.Get(), inEntity, component]() -> void { auto& sceneProxy = scene->Get(inEntity); Internal::UpdateSceneProxyContent(sceneProxy, component); }); @@ -121,7 +125,7 @@ namespace Runtime { { const auto& sceneHolder = registry.GGet(); const auto& transform = registry.Get(inEntity); - renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene, inEntity, transform]() -> void { + renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene.Get(), inEntity, transform]() -> void { auto& sceneProxy = scene->Get(inEntity); Internal::UpdateSceneProxyWorldTransform(sceneProxy, transform, false); }); @@ -131,7 +135,7 @@ namespace Runtime { void SceneSystem::QueueRemoveSceneProxy(Entity inEntity) { const auto& sceneHolder = registry.GGet(); - renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene, inEntity]() -> void { + renderModule.GetRenderThread().EmplaceTask([scene = sceneHolder.scene.Get(), inEntity]() -> void { scene->Remove(inEntity); }); } diff --git a/Engine/Source/Runtime/Include/Runtime/Viewport.h b/Engine/Source/Runtime/Include/Runtime/Viewport.h index 5a828018d..7bb0adc14 100644 --- a/Engine/Source/Runtime/Include/Runtime/Viewport.h +++ b/Engine/Source/Runtime/Include/Runtime/Viewport.h @@ -13,7 +13,7 @@ namespace Runtime { struct PresentInfo { PresentInfo(); - RHI::Texture* backBuffer; + RHI::Texture* backTexture; RHI::Semaphore* imageReadySemaphore; RHI::Semaphore* renderFinishedSemaphore; }; @@ -24,8 +24,9 @@ namespace Runtime { virtual Client& GetClient() = 0; virtual PresentInfo GetNextPresentInfo() = 0; - virtual size_t GetWidth() const = 0; - virtual size_t GetHeight() const = 0; + virtual uint32_t GetWidth() const = 0; + virtual uint32_t GetHeight() const = 0; + virtual void Resize(uint32_t inWidth, uint32_t inHeight) = 0; // TODO mouse keyboard inputs etc. protected: diff --git a/Engine/Source/Runtime/Src/Asset/Asset.cpp b/Engine/Source/Runtime/Src/Asset/Asset.cpp index 0d76ab3a6..238ee996f 100644 --- a/Engine/Source/Runtime/Src/Asset/Asset.cpp +++ b/Engine/Source/Runtime/Src/Asset/Asset.cpp @@ -14,6 +14,18 @@ namespace Runtime { Asset::~Asset() = default; + const Core::Uri& Asset::Uri() const + { + return uri; + } + + void Asset::SetUri(Core::Uri inUri) + { + uri = std::move(inUri); + } + + void Asset::PostLoad() {} + AssetManager& AssetManager::Get() { static AssetManager instance; @@ -21,8 +33,7 @@ namespace Runtime { } AssetManager::AssetManager() - : weakAssetRefs() - , threadPool("AssetThreadPool", 4) + : threadPool("AssetThreadPool", 4) { } diff --git a/Engine/Source/Runtime/Src/Asset/Level.cpp b/Engine/Source/Runtime/Src/Asset/Level.cpp index 44aa90604..2716daed0 100644 --- a/Engine/Source/Runtime/Src/Asset/Level.cpp +++ b/Engine/Source/Runtime/Src/Asset/Level.cpp @@ -11,4 +11,9 @@ namespace Runtime { } Level::~Level() = default; + + ECArchive& Level::GetArchive() + { + return archive; + } } diff --git a/Engine/Source/Runtime/Src/Asset/Material.cpp b/Engine/Source/Runtime/Src/Asset/Material.cpp index 56fb584bb..0739ef7d8 100644 --- a/Engine/Source/Runtime/Src/Asset/Material.cpp +++ b/Engine/Source/Runtime/Src/Asset/Material.cpp @@ -5,8 +5,6 @@ #include namespace Runtime { - MaterialGraph::MaterialGraph() = default; - Material::Material(Core::Uri inUri) : Asset(std::move(inUri)) , type(MaterialType::max) @@ -14,4 +12,11 @@ namespace Runtime { } Material::~Material() = default; + + MaterialInstance::MaterialInstance(Core::Uri inUri) + : Material(std::move(inUri)) + { + } + + MaterialInstance::~MaterialInstance() = default; } diff --git a/Engine/Source/Runtime/Src/Asset/Texture.cpp b/Engine/Source/Runtime/Src/Asset/Texture.cpp new file mode 100644 index 000000000..dafab90d9 --- /dev/null +++ b/Engine/Source/Runtime/Src/Asset/Texture.cpp @@ -0,0 +1,316 @@ +// +// Created by johnk on 2025/3/24. +// + +#include + +namespace Runtime::Internal { + static RHI::TextureDimension GetTextureDimension(TextureType inType) + { + static std::unordered_map map = { + { TextureType::t1D, RHI::TextureDimension::t1D }, + { TextureType::t2D, RHI::TextureDimension::t2D }, + { TextureType::t2DArray, RHI::TextureDimension::t2D }, + { TextureType::tCube, RHI::TextureDimension::t2D }, + { TextureType::tCubeArray, RHI::TextureDimension::t2D }, + { TextureType::t3D, RHI::TextureDimension::t3D } + }; + return map.at(inType); + } + + static bool IsDepthOnlyFormat(TextureFormat inFormat) + { + return inFormat == TextureFormat::d16Unorm + || inFormat == TextureFormat::d32Float; + } + + static bool IsDepthAndStencilFormat(TextureFormat inFormat) + { + return inFormat == TextureFormat::d24UnormS8Uint + || inFormat == TextureFormat::d32FloatS8Uint; + } + + static bool IsDepthOrStencilFormat(TextureFormat inFormat) + { + return IsDepthOnlyFormat(inFormat) + || IsDepthAndStencilFormat(inFormat); + } + + static RHI::TextureAspect GetTextureAspect(TextureFormat inFormat) + { + if (IsDepthOnlyFormat(inFormat)) { + return RHI::TextureAspect::depth; + } + if (IsDepthAndStencilFormat(inFormat)) { + return RHI::TextureAspect::depthStencil; + } + return RHI::TextureAspect::color; + } + + static void Upload3DTexture( + RHI::Device& inDevice, + RHI::Texture& inTexture, + TextureFormat inFormat, + uint32_t inWidth, + uint32_t inHeight, + uint32_t inDepthOrArraySize, + uint8_t inMipLevels, + RHI::TextureAspect inAspect, + const std::vector& inMipsData, + const std::string& inName) + { + std::vector copyFootprints; + copyFootprints.reserve(inMipLevels); + for (auto i = 0; i < inMipLevels; i++) { + copyFootprints.emplace_back(inDevice.GetTextureSubResourceCopyFootprint(inTexture, RHI::TextureSubResourceInfo(i, 0, inAspect))); + } + + size_t totalBytes = 0; + for (const auto& copyFootprint : copyFootprints) { + totalBytes += copyFootprint.totalBytes; + } + + const Common::UniquePtr stagingBuffer = inDevice.CreateBuffer( + RHI::BufferCreateInfo() + .SetSize(totalBytes) + .SetUsages(RHI::BufferUsageBits::copySrc | RHI::BufferUsageBits::mapWrite) + .SetInitialState(RHI::BufferState::staging) + .SetDebugName(std::format("StagingBuffer-{}", inName))); + + size_t dstMipOffset = 0; + auto* dstData = stagingBuffer->Map(RHI::MapMode::write, 0, totalBytes); + for (auto m = 0; m < inMipLevels; m++) { + const auto& srcPixels = inMipsData[m]; + const auto& dstCopyFootprints = copyFootprints[m]; + const auto srcRowPitch = inWidth * RHI::GetBytesPerPixel(static_cast(inFormat)); + const auto srcSlicePitch = inWidth * inHeight * RHI::GetBytesPerPixel(static_cast(inFormat)); + for (auto z = 0; z < inDepthOrArraySize; z++) { + for (auto y = 0; y < inHeight; y++) { + const auto* src = srcPixels.data() + srcSlicePitch * z + srcRowPitch * y; // NOLINT + auto* dst = dstData + dstMipOffset + dstCopyFootprints.slicePitch * z + dstCopyFootprints.rowPitch * y; // NOLINT + memcpy(dst, src, srcRowPitch); + } + } + dstMipOffset += dstCopyFootprints.totalBytes; + } + stagingBuffer->UnMap(); + + const Common::UniquePtr cmdBuffer = inDevice.CreateCommandBuffer(); + const auto recoder = cmdBuffer->Begin(); + { + const auto passRecoder = recoder->BeginCopyPass(); + + dstMipOffset = 0; + for (auto m = 0; m < inMipLevels; m++) { + passRecoder->CopyBufferToTexture( + stagingBuffer.Get(), + &inTexture, + RHI::BufferTextureCopyInfo() + .SetBufferOffset(dstMipOffset) + .SetTextureSubResource(RHI::TextureSubResourceInfo(m, 0, inAspect)) + .SetTextureOrigin({ 0, 0, 0 }) + .SetCopyRegion({ inWidth, inHeight, inDepthOrArraySize })); + dstMipOffset += copyFootprints[m].totalBytes; + } + passRecoder->EndPass(); + } + recoder->End(); + + const Common::UniquePtr fence = inDevice.CreateFence(false); + inDevice.GetQueue(RHI::QueueType::transfer, 0) + ->Submit(cmdBuffer.Get(), RHI::QueueSubmitInfo().SetSignalFence(fence.Get())); + fence->Wait(); + } + + static void UploadTextureOrArray( + RHI::Device& inDevice, + RHI::Texture& inTexture, + TextureFormat inFormat, + uint32_t inWidth, + uint32_t inHeight, + uint32_t inDepthOrArraySize, + uint8_t inMipLevels, + RHI::TextureAspect inAspect, + const std::vector& inMipsData, + const std::string& inName) + { + std::vector copyFootprints; + copyFootprints.reserve(inMipLevels * inDepthOrArraySize); + + for (auto m = 0; m < inMipLevels; m++) { + for (auto a = 0; a < inDepthOrArraySize; a++) { + copyFootprints.emplace_back(inDevice.GetTextureSubResourceCopyFootprint(inTexture, RHI::TextureSubResourceInfo(m, a, inAspect))); + } + } + + // TODO + } +} + +namespace Runtime { + Texture::Texture(Core::Uri inUri) + : Asset(std::move(inUri)) + , type(TextureType::max) + , format(TextureFormat::max) + , width(1) + , height(1) + , depthOrArraySize(1) + , mipLevels(1) + , samples(1) + { + } + + Texture::~Texture() = default; + + void Texture::PostLoad() + { + UpdateRHI(); + } + + TextureType Texture::GetType() const + { + return type; + } + + TextureFormat Texture::GetFormat() const + { + return format; + } + + uint32_t Texture::GetWidth() const + { + return width; + } + + uint32_t Texture::GetHeight() const + { + return height; + } + + uint32_t Texture::GetDepthOrArraySize() const + { + return depthOrArraySize; + } + + uint8_t Texture::GetMipLevels() const + { + return mipLevels; + } + + uint8_t Texture::GetSamples() const + { + return samples; + } + + const std::string& Texture::GetName() const + { + return name; + } + + Texture::MipPixels& Texture::GetMipPixels(uint8_t inMipLevel) + { + return mipsData[inMipLevel]; + } + + const Texture::MipPixels& Texture::GetMipPixels(uint8_t inMipLevel) const + { + return mipsData[inMipLevel]; + } + + void Texture::SetType(TextureType inType) + { + type = inType; + } + + void Texture::SetFormat(TextureFormat inFormat) + { + format = inFormat; + } + + void Texture::SetWidth(uint32_t inWidth) + { + width = inWidth; + } + + void Texture::SetHeight(uint32_t inHeight) + { + height = inHeight; + } + + void Texture::SetDepthOrArraySize(uint32_t inDepthOrArraySize) + { + depthOrArraySize = inDepthOrArraySize; + } + + void Texture::SetMipLevels(uint8_t inMipLevels) + { + mipLevels = inMipLevels; + } + + void Texture::SetSamples(uint8_t inSamples) + { + samples = inSamples; + } + + void Texture::SetName(const std::string& inName) + { + name = inName; + } + + void Texture::UpdateMips() + { + mipsData.clear(); + mipsData.resize(mipLevels); + + const auto bytesPerPixel = RHI::GetBytesPerPixel(static_cast(format)); + for (auto i = 0; i < mipLevels; i++) { + mipsData[i].resize(width * height * depthOrArraySize * bytesPerPixel); + } + } + + void Texture::UpdateRHI() + { + const auto& renderModule = EngineHolder::Get().GetRenderModule(); + auto* device = renderModule.GetDevice(); + + texture = device->CreateTexture( + RHI::TextureCreateInfo() + .SetDimension(Internal::GetTextureDimension(type)) + .SetWidth(width) + .SetHeight(height) + .SetDepthOrArraySize(depthOrArraySize) + .SetFormat(static_cast(format)) + .SetUsages(RHI::TextureUsageBits::copyDst | RHI::TextureUsageBits::textureBinding) + .SetMipLevels(mipLevels) + .SetSamples(samples) + .SetInitialState(RHI::TextureState::shaderReadOnly) + .SetDebugName(name)); + + textureView = texture->CreateTextureView( + RHI::TextureViewCreateInfo() + .SetType(Internal::IsDepthOrStencilFormat(format) ? RHI::TextureViewType::depthStencil : RHI::TextureViewType::textureBinding) + .SetDimension(static_cast(type)) + .SetAspect(Internal::GetTextureAspect(format)) + .SetMipLevels(0, mipLevels) + .SetArrayLayers(0, type == TextureType::t3D ? 1 : depthOrArraySize)); + + renderModule.GetRenderThread().EmplaceTask([ + device, + texturePtr = texture.Get(), + type = type, + format = format, + width = width, + height = height, + depthOrArraySize = depthOrArraySize, + mipLevels = mipLevels, + aspect = Internal::GetTextureAspect(format), + mipsData = mipsData, + name = name]() -> void { + if (type == TextureType::t3D) { + Internal::Upload3DTexture(*device, *texturePtr, format, width, height, depthOrArraySize, mipLevels, aspect, mipsData, name); + } else { + Internal::UploadTextureOrArray(*device, *texturePtr, format, width, height, depthOrArraySize, mipLevels, aspect, mipsData, name); + } + }); + } +} diff --git a/Engine/Source/Runtime/Src/Component/Primitive.cpp b/Engine/Source/Runtime/Src/Component/Primitive.cpp new file mode 100644 index 000000000..ae54aaabd --- /dev/null +++ b/Engine/Source/Runtime/Src/Component/Primitive.cpp @@ -0,0 +1,9 @@ +// +// Created by johnk on 2025/3/24. +// + +#include + +namespace Runtime { + StaticPrimitive::StaticPrimitive() = default; +} diff --git a/Engine/Source/Runtime/Src/Engine.cpp b/Engine/Source/Runtime/Src/Engine.cpp index 56015ccf6..c5c76013c 100644 --- a/Engine/Source/Runtime/Src/Engine.cpp +++ b/Engine/Source/Runtime/Src/Engine.cpp @@ -132,7 +132,7 @@ namespace Runtime { void EngineHolder::Load(const std::string& inModuleName, const EngineInitParams& inInitParams) { Assert(engine == nullptr); - auto& gameModule = Core::ModuleManager::Get().GetOrLoadTyped(inModuleName); + auto& gameModule = Core::ModuleManager::Get().GetOrLoadTyped(inModuleName); engine = gameModule.CreateEngine(inInitParams); } diff --git a/Engine/Source/Runtime/Src/System/Render.cpp b/Engine/Source/Runtime/Src/System/Render.cpp index 9c1c1ad46..eb3eedd63 100644 --- a/Engine/Source/Runtime/Src/System/Render.cpp +++ b/Engine/Source/Runtime/Src/System/Render.cpp @@ -33,7 +33,7 @@ namespace Runtime { [ fence = lastFrameFence, views = BuildViews(), - scene = registry.GGet().scene, + scene = registry.GGet().scene.Get(), surfaceExtent = Common::UVec2(clientViewport.GetWidth(), clientViewport.GetHeight()), presentInfo = clientViewport.GetNextPresentInfo(), renderModule = &renderModule, @@ -43,8 +43,9 @@ namespace Runtime { fence->Reset(); Render::StandardRenderer::Params rendererParams; + rendererParams.device = renderModule->GetDevice(); rendererParams.scene = scene; - rendererParams.surface = presentInfo.backBuffer; + rendererParams.surface = presentInfo.backTexture; rendererParams.surfaceExtent = surfaceExtent; rendererParams.views = views; rendererParams.waitSemaphore = presentInfo.imageReadySemaphore; diff --git a/Engine/Source/Runtime/Src/System/Scene.cpp b/Engine/Source/Runtime/Src/System/Scene.cpp index d07d29e72..9cab2e9c0 100644 --- a/Engine/Source/Runtime/Src/System/Scene.cpp +++ b/Engine/Source/Runtime/Src/System/Scene.cpp @@ -26,10 +26,7 @@ namespace Runtime { SceneSystem::~SceneSystem() // NOLINT { - auto& sceneHolder = registry.GGet(); - renderModule.GetRenderThread().EmplaceTask([scene = std::exchange(sceneHolder.scene, nullptr)]() -> void { - delete scene; - }); + registry.GRemove(); } void SceneSystem::Tick(float inDeltaTimeSeconds) @@ -43,6 +40,7 @@ namespace Runtime { directionalLightsObserver.Removed().Each([this](Entity e) -> void { QueueRemoveSceneProxy(e); }); pointLightsObserver.Removed().Each([this](Entity e) -> void { QueueRemoveSceneProxy(e); }); spotLightsObserver.Removed().Each([this](Entity e) -> void { QueueRemoveSceneProxy(e); }); + // TODO primitive transformUpdatedObserver.Each([this](Entity e) -> void { if (registry.Has(e) || registry.Has(e) || registry.Has(e)) { diff --git a/Engine/Source/Runtime/Src/Viewport.cpp b/Engine/Source/Runtime/Src/Viewport.cpp index 4fbe26044..386e85208 100644 --- a/Engine/Source/Runtime/Src/Viewport.cpp +++ b/Engine/Source/Runtime/Src/Viewport.cpp @@ -10,7 +10,7 @@ namespace Runtime { Viewport::Viewport() = default; PresentInfo::PresentInfo() - : backBuffer(nullptr) + : backTexture(nullptr) , imageReadySemaphore(nullptr) , renderFinishedSemaphore(nullptr) { diff --git a/Engine/Source/Runtime/Src/World.cpp b/Engine/Source/Runtime/Src/World.cpp index cd7cca59a..d8ef17039 100644 --- a/Engine/Source/Runtime/Src/World.cpp +++ b/Engine/Source/Runtime/Src/World.cpp @@ -78,13 +78,13 @@ namespace Runtime { void World::LoadFrom(AssetPtr inLevel) { Assert(Stopped()); - ecRegistry.Load(inLevel->archive); + ecRegistry.Load(inLevel->GetArchive()); } void World::SaveTo(AssetPtr inLevel) { Assert(Stopped()); - ecRegistry.Save(inLevel->archive); + ecRegistry.Save(inLevel->GetArchive()); } void World::Tick(float inDeltaTimeSeconds) diff --git a/Engine/Source/Runtime/Test/RuntimeTestModule.h b/Engine/Source/Runtime/Test/RuntimeTestModule.h index f47333d26..dbdd6e30b 100644 --- a/Engine/Source/Runtime/Test/RuntimeTestModule.h +++ b/Engine/Source/Runtime/Test/RuntimeTestModule.h @@ -6,7 +6,7 @@ #include -class RuntimeTestModule final : public Runtime::IEngineModule { +class RuntimeTestModule final : public Runtime::EngineModule { public: void OnUnload() override; Core::ModuleType Type() const override; diff --git a/Sample/Base/Application.cpp b/Sample/Base/Application.cpp index 4b426e6ac..f90af8f05 100644 --- a/Sample/Base/Application.cpp +++ b/Sample/Base/Application.cpp @@ -95,6 +95,7 @@ int Application::RunLoop() } OnDestroy(); + glfwDestroyWindow(window); glfwTerminate(); return 0; } From a5e4125ad820da77cd1b665206f294da139dea6e Mon Sep 17 00:00:00 2001 From: Kindem Date: Sat, 29 Mar 2025 00:19:51 +0800 Subject: [PATCH 3/4] feat: misc runtime update --- Engine/Source/Launch/Src/GameApplication.cpp | 2 +- Engine/Source/Launch/Src/GameViewport.cpp | 1 + Engine/Source/Mirror/Include/Mirror/Meta.h | 4 +- Engine/Source/Mirror/Include/Mirror/Mirror.h | 87 ++-- .../Source/Mirror/Include/Mirror/Registry.h | 42 +- Engine/Source/Mirror/Src/Mirror.cpp | 36 +- Engine/Source/Mirror/Test/AnyTest.cpp | 8 +- Engine/Source/Mirror/Test/AnyTest.h | 12 +- Engine/Source/RHI/Include/RHI/RHI.h | 4 + .../Runtime/Include/Runtime/Asset/Asset.h | 115 ++++-- .../Runtime/Include/Runtime/Asset/Material.h | 82 +++- .../Runtime/Include/Runtime/Asset/Mesh.h | 2 +- .../Runtime/Include/Runtime/Asset/Texture.h | 58 ++- .../Include/Runtime/Component/Player.h | 5 +- .../Runtime/Include/Runtime/RenderThreadPtr.h | 8 +- .../Runtime/Include/Runtime/System/Player.h | 10 - .../Runtime/Include/Runtime/System/Render.h | 2 +- Engine/Source/Runtime/Src/Asset/Material.cpp | 164 +++++++- Engine/Source/Runtime/Src/Asset/Texture.cpp | 376 ++++++++++++------ Engine/Source/Runtime/Src/System/Player.cpp | 8 +- Engine/Source/Runtime/Test/AssetTest.cpp | 18 +- Tool/MirrorTool/ExeSrc/Main.cpp | 15 + Tool/MirrorTool/Include/MirrorTool/Parser.h | 1 + Tool/MirrorTool/Src/Generator.cpp | 13 +- Tool/MirrorTool/Src/Parser.cpp | 5 + 25 files changed, 834 insertions(+), 244 deletions(-) diff --git a/Engine/Source/Launch/Src/GameApplication.cpp b/Engine/Source/Launch/Src/GameApplication.cpp index ae1e9ff89..a4aa9aee9 100644 --- a/Engine/Source/Launch/Src/GameApplication.cpp +++ b/Engine/Source/Launch/Src/GameApplication.cpp @@ -43,7 +43,7 @@ namespace Launch { settingRegistry.LoadAllSettings(); const auto& gameSettings = Runtime::SettingsRegistry::Get().GetSettings(); - const auto startupLevel = Runtime::AssetManager::Get().SyncLoad(gameSettings.gameStartupLevel); + const auto startupLevel = Runtime::AssetManager::Get().SyncLoad(gameSettings.gameStartupLevel, Runtime::Level::GetStaticClass()); viewport->GetClient().GetWorld().LoadFrom(startupLevel); } diff --git a/Engine/Source/Launch/Src/GameViewport.cpp b/Engine/Source/Launch/Src/GameViewport.cpp index be530fcd3..5d7ca22eb 100644 --- a/Engine/Source/Launch/Src/GameViewport.cpp +++ b/Engine/Source/Launch/Src/GameViewport.cpp @@ -3,6 +3,7 @@ // #include +#include namespace Launch::Internal { static void* GetGlfwPlatformWindow(GLFWwindow* inWindow) diff --git a/Engine/Source/Mirror/Include/Mirror/Meta.h b/Engine/Source/Mirror/Include/Mirror/Meta.h index 932355632..5ae9ef672 100644 --- a/Engine/Source/Mirror/Include/Mirror/Meta.h +++ b/Engine/Source/Mirror/Include/Mirror/Meta.h @@ -30,11 +30,11 @@ private: \ static Mirror::Internal::ScopedReleaser _mirrorRegistry; \ public: \ static const Mirror::Class& GetStaticClass(); \ - const Mirror::Class& GetClass(); \ + const Mirror::Class& GetClass() const; \ #define EPolyClassBody(className) \ private: \ static Mirror::Internal::ScopedReleaser _mirrorRegistry; \ public: \ static const Mirror::Class& GetStaticClass(); \ - virtual const Mirror::Class& GetClass(); \ + virtual const Mirror::Class& GetClass() const; \ diff --git a/Engine/Source/Mirror/Include/Mirror/Mirror.h b/Engine/Source/Mirror/Include/Mirror/Mirror.h index d07aff2ef..2b5233833 100644 --- a/Engine/Source/Mirror/Include/Mirror/Mirror.h +++ b/Engine/Source/Mirror/Include/Mirror/Mirror.h @@ -72,9 +72,12 @@ namespace Mirror { const TypeInfo* removePointer; }; + class Any; + class Class; + MIRROR_API bool PointerConvertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType); - MIRROR_API bool PolymorphismConvertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType); - MIRROR_API bool Convertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType); + MIRROR_API bool PolymorphismConvertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType, const Class* inSrcDynamicClass); + MIRROR_API bool Convertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType, const Class* inSrcDynamicClass); enum class AnyPolicy : uint8_t { memoryHolder, @@ -83,8 +86,6 @@ namespace Mirror { max }; - class Any; - using TemplateViewId = uint32_t; using TemplateViewRttiPtr = const void*; @@ -105,6 +106,7 @@ namespace Mirror { using JsonDeserializeFunc = void(void*, const rapidjson::Value&); using ToStringFunc = std::string(const void*); using GetTemplateViewRttiFunc = std::pair(); + using GetDynamicClassFunc = const Class*(const void*); template static void Detor(void* inThis) noexcept; template static void CopyConstruct(void* inThis, const void* inOther); @@ -128,6 +130,7 @@ namespace Mirror { template static void JsonDeserialize(void* inThis, const rapidjson::Value& inJsonValue); template static std::string ToString(const void* inThis); template static std::pair GetTemplateViewRtti(); + template static const Class* GetDynamicClass(const void* inThis); DetorFunc* detor; CopyConstructFunc* copyConstruct; @@ -151,6 +154,7 @@ namespace Mirror { JsonDeserializeFunc* jsonDeserialize; ToStringFunc* toString; GetTemplateViewRttiFunc* getTemplateViewRtti; + GetDynamicClassFunc* getDynamicClass; }; template @@ -176,7 +180,8 @@ namespace Mirror { &AnyRtti::JsonSerialize, &AnyRtti::JsonDeserialize, &AnyRtti::ToString, - &AnyRtti::GetTemplateViewRtti + &AnyRtti::GetTemplateViewRtti, + &AnyRtti::GetDynamicClass }; template @@ -245,8 +250,6 @@ namespace Mirror { template T As() const; template T* TryAs(); template T* TryAs() const; - template T PolyAs(); - template T PolyAs() const; template bool CanAsTemplateView() const; TemplateViewRttiPtr GetTemplateViewRtti() const; @@ -280,6 +283,7 @@ namespace Mirror { const TypeInfo* RemovePointerType() const; Mirror::TypeId TypeId(); Mirror::TypeId TypeId() const; + const Class* GetDynamicClass() const; void Reset(); bool Empty() const; size_t Serialize(Common::BinarySerializeStream& inStream) const; @@ -366,6 +370,7 @@ namespace Mirror { Argument& operator=(Any&& inAny); template T As() const; + template T* TryAs() const; template bool CanAsTemplateView() const; TemplateViewRttiPtr GetTemplateViewRtti() const; @@ -378,6 +383,7 @@ namespace Mirror { const TypeInfo* RemoveRefType() const; const TypeInfo* AddPointerType() const; const TypeInfo* RemovePointerType() const; + const Class* GetDynamicClass() const; private: template decltype(auto) Delegate(F&& inFunc) const; @@ -822,12 +828,12 @@ namespace Mirror { const MemberFunction& GetMemberFunction(const Id& inId) const; Any GetDefaultObject() const; bool IsTransient() const; - Any ConstructDyn(const ArgumentList& arguments) const; Any NewDyn(const ArgumentList& arguments) const; Any InplaceNewDyn(void* ptr, const ArgumentList& arguments) const; void DestructDyn(const Argument& argument) const; void DeleteDyn(const Argument& argument) const; + Any Cast(const Argument& objPtrOrRef) const; private: static std::unordered_map typeToIdMap; @@ -837,6 +843,8 @@ namespace Mirror { using BaseClassGetter = std::function; using InplaceGetter = std::function; + using DefaultObjectCreator = std::function; + using Caster = std::function; struct ConstructParams { Id id; @@ -844,7 +852,8 @@ namespace Mirror { size_t memorySize; BaseClassGetter baseClassGetter; InplaceGetter inplaceGetter; - std::function defaultObjectCreator; + Caster caster; + DefaultObjectCreator defaultObjectCreator; std::optional destructorParams; std::optional defaultConstructorParams; std::optional moveConstructorParams; @@ -853,7 +862,7 @@ namespace Mirror { explicit Class(ConstructParams&& params); - void CreateDefaultObject(const std::function& inCreator); + void CreateDefaultObject(const DefaultObjectCreator& inCreator); Destructor& EmplaceDestructor(Destructor::ConstructParams&& inParams); Constructor& EmplaceConstructor(const Id& inId, Constructor::ConstructParams&& inParams); Variable& EmplaceStaticVariable(const Id& inId, Variable::ConstructParams&& inParams); @@ -865,6 +874,7 @@ namespace Mirror { size_t memorySize; BaseClassGetter baseClassGetter; InplaceGetter inplaceGetter; + Caster caster; Any defaultObject; std::optional destructor; std::unordered_map constructors; @@ -2882,8 +2892,25 @@ namespace Mirror { { return { TemplateViewRttiGetter::Id(), - TemplateViewRttiGetter::Get() - }; + TemplateViewRttiGetter::Get()}; + } + + template + const Class* AnyRtti::GetDynamicClass(const void* inThis) + { + if constexpr (std::is_pointer_v) { + if constexpr (MetaClass>>) { + return &(*static_cast(inThis))->GetClass(); + } else { + return nullptr; + } + } else { + if constexpr (MetaClass) { + return &static_cast(inThis)->GetClass(); + } else { + return nullptr; + } + } } template @@ -3030,7 +3057,8 @@ namespace Mirror { Assert(!IsArray()); return Mirror::Convertible( { Type(), RemoveRefType(), RemovePointerType() }, - { GetTypeInfo(), GetTypeInfo>(), GetTypeInfo>() }); + { GetTypeInfo(), GetTypeInfo>(), GetTypeInfo>() }, + rtti->getDynamicClass(Data())); } template @@ -3039,7 +3067,8 @@ namespace Mirror { Assert(!IsArray()); return Mirror::Convertible( { Type(), RemoveRefType(), RemovePointerType() }, - { GetTypeInfo(), GetTypeInfo>(), GetTypeInfo>() }); + { GetTypeInfo(), GetTypeInfo>(), GetTypeInfo>() }, + rtti->getDynamicClass(Data())); } template @@ -3062,7 +3091,8 @@ namespace Mirror { Assert(!IsArray()); const bool convertible = Mirror::Convertible( { AddPointerType(), AddPointerType(), RemoveRefType() }, - { GetTypeInfo(), GetTypeInfo(), GetTypeInfo() }); + { GetTypeInfo(), GetTypeInfo(), GetTypeInfo() }, + rtti->getDynamicClass(Data())); return convertible ? static_cast*>(Data()) : nullptr; } @@ -3072,24 +3102,11 @@ namespace Mirror { Assert(!IsArray()); const bool convertible = Mirror::Convertible( { AddPointerType(), AddPointerType(), RemoveRefType() }, - { GetTypeInfo(), GetTypeInfo(), GetTypeInfo() }); + { GetTypeInfo(), GetTypeInfo(), GetTypeInfo() }, + rtti->getDynamicClass(Data())); return convertible ? static_cast*>(Data()) : nullptr; } - template - T Any::PolyAs() - { - Assert(!IsArray()); - return dynamic_cast(As()); - } - - template - T Any::PolyAs() const - { - Assert(!IsArray()); - return dynamic_cast(As()); - } - template bool Any::CanAsTemplateView() const { @@ -3162,11 +3179,19 @@ namespace Mirror { template T Argument::As() const // NOLINT { - return Delegate([](auto&& value) -> decltype(auto) { + return Delegate([&](auto&& value) -> decltype(auto) { return value.template As(); }); } + template + T* Argument::TryAs() const + { + return Delegate([&](auto&& value) -> decltype(auto) { + return value.template TryAs(); + }); + } + template bool Argument::CanAsTemplateView() const { diff --git a/Engine/Source/Mirror/Include/Mirror/Registry.h b/Engine/Source/Mirror/Include/Mirror/Registry.h index cd29f8573..d37f485c3 100644 --- a/Engine/Source/Mirror/Include/Mirror/Registry.h +++ b/Engine/Source/Mirror/Include/Mirror/Registry.h @@ -55,7 +55,8 @@ namespace Mirror { public: ~ClassRegistry() override; - template ClassRegistry& Constructor(const Id& inId); + template ClassRegistry& Constructor(const Id& inId); + template ClassRegistry& Constructor(const Id& inId); template ClassRegistry& StaticVariable(const Id& inId); template ClassRegistry& StaticFunction(const Id& inId); template ClassRegistry& MemberVariable(const Id& inId); @@ -238,7 +239,14 @@ namespace Mirror { ClassRegistry::~ClassRegistry() = default; template - template + template + ClassRegistry& ClassRegistry::Constructor(const Id& inId) + { + return Constructor(inId); + } + + template + template ClassRegistry& ClassRegistry::Constructor(const Id& inId) { using ArgsTupleType = std::tuple; @@ -256,7 +264,7 @@ namespace Mirror { params.argRemoveRefTypeInfos = { GetTypeInfo>()... }; params.argRemovePointerTypeInfos = { GetTypeInfo>()... }; params.stackConstructor = [](const ArgumentList& args) -> Any { - if constexpr (std::is_copy_constructible_v || std::is_move_constructible_v) { + if constexpr (!std::is_abstract_v && (std::is_copy_constructible_v || std::is_move_constructible_v)) { Assert(argsTupleSize == args.size()); return ForwardAsAny(Internal::InvokeConstructorStack(args, std::make_index_sequence {})); } else { @@ -265,12 +273,22 @@ namespace Mirror { } }; params.heapConstructor = [](const ArgumentList& args) -> Any { - Assert(argsTupleSize == args.size()); - return ForwardAsAny(Internal::InvokeConstructorNew(args, std::make_index_sequence {})); + if constexpr (!std::is_abstract_v) { + Assert(argsTupleSize == args.size()); + return ForwardAsAny(Internal::InvokeConstructorNew(args, std::make_index_sequence {})); + } else { + QuickFail(); + return {}; + } }; params.inplaceConstructor = [](void* ptr, const ArgumentList& args) -> Any { - Assert(argsTupleSize == args.size()); - return ForwardAsAny(std::ref(Internal::InvokeConstructorInplace(ptr, args, std::make_index_sequence {}))); + if constexpr (!std::is_abstract_v) { + Assert(argsTupleSize == args.size()); + return ForwardAsAny(std::ref(Internal::InvokeConstructorInplace(ptr, args, std::make_index_sequence {}))); + } else { + QuickFail(); + return {}; + } }; return MetaDataRegistry::SetContext(&clazz.EmplaceConstructor(inId, std::move(params))); @@ -514,6 +532,16 @@ namespace Mirror { params.inplaceGetter = [](void* ptr) -> Any { return { std::ref(*static_cast(ptr)) }; }; + params.caster = [](const Argument& argument) -> Any { + if (argument.Type()->isPointer) { + return argument.Type()->isConstPointer ? argument.As() : argument.As(); + } + if (argument.IsRef()) { + return std::ref(argument.IsConstRef() ? argument.As() : argument.As()); + } + QuickFail(); + return {}; + }; if constexpr (std::is_default_constructible_v) { params.defaultObjectCreator = []() -> Any { return { C() }; diff --git a/Engine/Source/Mirror/Src/Mirror.cpp b/Engine/Source/Mirror/Src/Mirror.cpp index a0787592d..81bdd89a7 100644 --- a/Engine/Source/Mirror/Src/Mirror.cpp +++ b/Engine/Source/Mirror/Src/Mirror.cpp @@ -27,7 +27,7 @@ namespace Mirror { return !srcRemovePointer->isConst || dstRemovePointer->isConst; } - bool PolymorphismConvertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType) + bool PolymorphismConvertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType, const Class* inSrcDynamicClass) { const auto [srcRaw, srcRemoveRef, srcRemovePointer] = inSrcType; const auto [dstRaw, dstRemoveRef, dstRemovePointer] = inDstType; @@ -53,13 +53,20 @@ namespace Mirror { const auto* srcClass = Class::Find(srcRemoveRefOrPtr->id); // NOLINT const auto* dstClass = Class::Find(dstRemoveRefOrPtr->id); // NOLINT - if (srcClass == nullptr || dstClass == nullptr || !dstClass->IsBaseOf(srcClass)) { + const bool allClassValid = srcClass != nullptr && dstClass != nullptr; + if (!allClassValid) { + return false; + } + + const bool canUpDynamicCast = dstClass->IsBaseOf(srcClass); // NOLINT + const bool canDownDynamicCast = inSrcDynamicClass != nullptr && (inSrcDynamicClass == dstClass || dstClass->IsBaseOf(inSrcDynamicClass)); // NOLINT + if (!canUpDynamicCast && !canDownDynamicCast) { return false; } return !srcRemoveRefOrPtr->isConst || dstRaw->isRValueReference || dstRemoveRefOrPtr->isConst; } - bool Convertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType) + bool Convertible(const TypeInfoCompact& inSrcType, const TypeInfoCompact& inDstType, const Class* inSrcDynamicClass) { const auto [srcRaw, srcRemoveRef, srcRemovePointer] = inSrcType; const auto [dstRaw, dstRemoveRef, dstRemovePointer] = inDstType; @@ -70,7 +77,7 @@ namespace Mirror { } return !srcRemoveRef->isConst || dstRaw->isRValueReference || dstRemoveRef->isConst; } - return PointerConvertible(inSrcType, inDstType) || PolymorphismConvertible(inSrcType, inDstType); + return PointerConvertible(inSrcType, inDstType) || PolymorphismConvertible(inSrcType, inDstType, inSrcDynamicClass); } Any::Any() @@ -586,6 +593,12 @@ namespace Mirror { return Type()->id; } + const Class* Any::GetDynamicClass() const + { + Assert(rtti != nullptr); + return rtti->getDynamicClass(Data()); + } + void Any::Reset() { arrayLength = 0; @@ -836,6 +849,13 @@ namespace Mirror { }); } + const Class* Argument::GetDynamicClass() const + { + return Delegate([](auto&& value) -> decltype(auto) { + return value.GetDynamicClass(); + }); + } + Id Id::null = Id(); Id::Id() @@ -1400,6 +1420,7 @@ namespace Mirror { , memorySize(params.memorySize) , baseClassGetter(std::move(params.baseClassGetter)) , inplaceGetter(std::move(params.inplaceGetter)) + , caster(std::move(params.caster)) { CreateDefaultObject(params.defaultObjectCreator); if (params.destructorParams.has_value()) { @@ -1672,7 +1693,7 @@ namespace Mirror { for (auto i = 0; i < arguments.size(); i++) { const TypeInfoCompact srcType { arguments[i].Type(), arguments[i].RemoveRefType(), arguments[i].RemovePointerType() }; // NOLINT const TypeInfoCompact dstType { argTypeInfos[i], argRemoveRefTypeInfos[i], argRemovePointerTypeInfos[i] }; // NOLINT - if (Convertible(srcType, dstType)) { + if (Convertible(srcType, dstType, arguments[i].GetDynamicClass())) { rate += dstType.raw->isRValueReference ? 2 : 1; continue; } @@ -1720,6 +1741,11 @@ namespace Mirror { GetDestructor().DeleteDyn(argument); } + Any Class::Cast(const Argument& objPtrOrRef) const + { + return caster(objPtrOrRef); + } + const Constructor* Class::FindConstructor(const Id& inId) const { const auto iter = constructors.find(inId); diff --git a/Engine/Source/Mirror/Test/AnyTest.cpp b/Engine/Source/Mirror/Test/AnyTest.cpp index e7cb229c8..7c29dfdad 100644 --- a/Engine/Source/Mirror/Test/AnyTest.cpp +++ b/Engine/Source/Mirror/Test/AnyTest.cpp @@ -662,13 +662,13 @@ TEST(AnyTest, PolyAsTest) const Common::UniquePtr v0 = new AnyDerivedClassTest2(1, 2.0f, "3"); Any a0 = std::ref(*v0); - const auto& r0 = a0.PolyAs(); + const auto& r0 = a0.As(); ASSERT_EQ(r0.a, 1); ASSERT_EQ(r0.b, 2.0f); ASSERT_EQ(r0.c, "3"); Any a1 = v0.Get(); - const auto* p0 = a1.PolyAs(); + const auto* p0 = a1.As(); ASSERT_EQ(p0->a, 1); ASSERT_EQ(p0->b, 2.0f); ASSERT_EQ(p0->c, "3"); @@ -679,13 +679,13 @@ TEST(AnyTest, ConstPolyAsTest) const Common::UniquePtr v0 = new AnyDerivedClassTest2(1, 2.0f, "3"); const Any a0 = std::ref(*v0); - const auto& r0 = a0.PolyAs(); + const auto& r0 = a0.As(); ASSERT_EQ(r0.a, 1); ASSERT_EQ(r0.b, 2.0f); ASSERT_EQ(r0.c, "3"); const Any a1 = v0.Get(); - const auto* p0 = a1.PolyAs(); + const auto* p0 = a1.As(); ASSERT_EQ(p0->a, 1); ASSERT_EQ(p0->b, 2.0f); ASSERT_EQ(p0->c, "3"); diff --git a/Engine/Source/Mirror/Test/AnyTest.h b/Engine/Source/Mirror/Test/AnyTest.h index a91687bec..868bdda93 100644 --- a/Engine/Source/Mirror/Test/AnyTest.h +++ b/Engine/Source/Mirror/Test/AnyTest.h @@ -58,15 +58,19 @@ struct AnyBasicTest { }; struct EClass() AnyBaseClassTest { - EClassBody(AnyBaseClassTest) + EPolyClassBody(AnyBaseClassTest) + + virtual ~AnyBaseClassTest() = default; }; struct EClass() AnyDerivedClassTest : AnyBaseClassTest { - EClassBody(AnyDerivedClassTest) + EPolyClassBody(AnyDerivedClassTest) + + ~AnyDerivedClassTest() override = default; }; struct EClass() AnyBaseClassTest2 { - EClassBody(AnyBaseClassTest2) + EPolyClassBody(AnyBaseClassTest2) AnyBaseClassTest2(int inA, float inB) : a(inA) @@ -81,7 +85,7 @@ struct EClass() AnyBaseClassTest2 { }; struct EClass() AnyDerivedClassTest2 final : AnyBaseClassTest2 { - EClassBody(AnyDerivedClassTest2) + EPolyClassBody(AnyDerivedClassTest2) AnyDerivedClassTest2(int inA, float inB, std::string inC) : AnyBaseClassTest2(inA, inB) diff --git a/Engine/Source/RHI/Include/RHI/RHI.h b/Engine/Source/RHI/Include/RHI/RHI.h index 33eae983e..eb8c080c7 100644 --- a/Engine/Source/RHI/Include/RHI/RHI.h +++ b/Engine/Source/RHI/Include/RHI/RHI.h @@ -24,3 +24,7 @@ #include #include #include + +#if PLATFORM_WINDOWS +#undef CreateSemaphore +#endif diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h b/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h index 0a17d5e3e..416034147 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h @@ -56,8 +56,10 @@ namespace Runtime { const Core::Uri& Uri() const; A* operator->() const noexcept; A& operator*() const noexcept; + explicit operator bool() const; bool operator==(nullptr_t) const noexcept; bool operator!=(nullptr_t) const noexcept; + bool Valid() const; A* Get() const; void Reset(A* pointer = nullptr); auto RefCount() const; @@ -92,13 +94,13 @@ namespace Runtime { class SoftAssetPtr { public: SoftAssetPtr(); - explicit SoftAssetPtr(Core::Uri inUri); + SoftAssetPtr(Core::Uri inUri, const Mirror::Class& inClass); explicit SoftAssetPtr(AssetPtr& inAsset); SoftAssetPtr(const SoftAssetPtr& other); SoftAssetPtr(SoftAssetPtr&& other) noexcept; ~SoftAssetPtr(); - SoftAssetPtr& operator=(Core::Uri inUri); + SoftAssetPtr& operator=(const std::pair& inUriAndClass); SoftAssetPtr& operator=(AssetPtr& inAsset); SoftAssetPtr& operator=(const SoftAssetPtr& other); SoftAssetPtr& operator=(SoftAssetPtr&& other) noexcept; @@ -108,9 +110,11 @@ namespace Runtime { AssetPtr Get() const; void Reset(); const Core::Uri& Uri() const; + const Mirror::Class* Class() const; private: Core::Uri uri; + const Mirror::Class* clazz; AssetPtr asset; }; @@ -122,15 +126,15 @@ namespace Runtime { static AssetManager& Get(); ~AssetManager(); - template A> AssetPtr SyncLoad(const Core::Uri& uri); - template A> void SyncLoadSoft(SoftAssetPtr& softAssetRef); - template A> void AsyncLoad(const Core::Uri& uri, const OnAssetLoaded& onAssetLoaded); - template A> void AsyncLoadSoft(SoftAssetPtr& softAssetRef, const OnSoftAssetLoaded& onSoftAssetLoaded); + template A> AssetPtr SyncLoad(const Core::Uri& uri, const Mirror::Class& clazz); + template A> void SyncLoadSoft(SoftAssetPtr& softAssetRef, const Mirror::Class& clazz); + template A> void AsyncLoad(const Core::Uri& uri, const Mirror::Class& clazz, const OnAssetLoaded& onAssetLoaded); + template A> void AsyncLoadSoft(SoftAssetPtr& softAssetRef, const Mirror::Class& clazz, const OnSoftAssetLoaded& onSoftAssetLoaded); template A> void Save(const AssetPtr& assetRef); template A> void SaveSoft(const SoftAssetPtr& softAssetRef); private: - template A> AssetPtr LoadInternal(const Core::Uri& uri); + template A> AssetPtr LoadInternal(const Core::Uri& uri, const Mirror::Class& clazz); AssetManager(); @@ -147,14 +151,23 @@ namespace Common { static size_t Serialize(BinarySerializeStream& stream, const Runtime::AssetPtr& value) { - return Serializer::Serialize(stream, value.Uri()); + size_t serialized = 0; + serialized += Serializer::Serialize(stream, value.Uri()); + serialized += Serializer::Serialize(stream, &value->GetClass()); + return serialized; } static size_t Deserialize(BinaryDeserializeStream& stream, Runtime::AssetPtr& value) { + size_t deserialized = 0; + Core::Uri uri; - const auto deserialized = Serializer::Deserialize(stream, uri); - value = Runtime::AssetManager::Get().SyncLoad(uri); + deserialized += Serializer::Deserialize(stream, uri); + + const Mirror::Class* clazz; + deserialized += Serializer::Deserialize(stream, clazz); + + value = Runtime::AssetManager::Get().SyncLoad(uri, *clazz); return deserialized; } }; @@ -165,14 +178,23 @@ namespace Common { static size_t Serialize(BinarySerializeStream& stream, const Runtime::SoftAssetPtr& value) { - return Serializer::Serialize(stream, value.Uri()); + size_t serialized = 0; + serialized += Serializer::Serialize(stream, value.Uri()); + serialized += Serializer::Serialize(stream, &value->GetClass()); + return serialized; } static size_t Deserialize(BinaryDeserializeStream& stream, Runtime::SoftAssetPtr& value) { + size_t deserialized = 0; + Core::Uri uri; - const auto deserialized = Serializer::Deserialize(stream, uri); - value = uri; + deserialized += Serializer::Deserialize(stream, uri); + + const Mirror::Class* clazz; + deserialized += Serializer::Deserialize(stream, clazz); + + value = { value, *clazz }; return deserialized; } }; @@ -273,6 +295,12 @@ namespace Runtime { return ptr.operator*(); } + template A> + AssetPtr::operator bool() const + { + return Valid(); + } + template A> bool AssetPtr::operator==(nullptr_t) const noexcept { @@ -285,6 +313,12 @@ namespace Runtime { return ptr != nullptr; } + template A> + bool AssetPtr::Valid() const + { + return ptr != nullptr; + } + template A> A* AssetPtr::Get() const { @@ -391,14 +425,15 @@ namespace Runtime { template A> SoftAssetPtr::SoftAssetPtr() - : uri() + : clazz(nullptr) , asset() { } template A> - SoftAssetPtr::SoftAssetPtr(Core::Uri inUri) + SoftAssetPtr::SoftAssetPtr(Core::Uri inUri, const Mirror::Class& inClass) : uri(std::move(inUri)) + , clazz(&inClass) , asset() { } @@ -406,6 +441,7 @@ namespace Runtime { template A> SoftAssetPtr::SoftAssetPtr(AssetPtr& inAsset) : uri(inAsset.Uri()) + , clazz(&inAsset->GetClass()) , asset(inAsset) { } @@ -413,6 +449,7 @@ namespace Runtime { template A> SoftAssetPtr::SoftAssetPtr(const SoftAssetPtr& other) : uri(other.uri) + , clazz(other.clazz) , asset(other.asset) { } @@ -420,6 +457,7 @@ namespace Runtime { template A> SoftAssetPtr::SoftAssetPtr(SoftAssetPtr&& other) noexcept : uri(std::move(other.uri)) + , clazz(other.clazz) , asset(std::move(other.asset)) { } @@ -428,9 +466,10 @@ namespace Runtime { SoftAssetPtr::~SoftAssetPtr() = default; template A> - SoftAssetPtr& SoftAssetPtr::operator=(Core::Uri inUri) + SoftAssetPtr& SoftAssetPtr::operator=(const std::pair& inUriAndClass) { - uri = std::move(inUri); + uri = inUriAndClass.first; + clazz = &inUriAndClass.second; asset = nullptr; return *this; } @@ -439,6 +478,7 @@ namespace Runtime { SoftAssetPtr& SoftAssetPtr::operator=(AssetPtr& inAsset) { uri = inAsset.Uri(); + clazz = &inAsset->GetClass(); asset = inAsset; return *this; } @@ -447,6 +487,7 @@ namespace Runtime { SoftAssetPtr& SoftAssetPtr::operator=(const SoftAssetPtr& other) { uri = other.uri; + clazz = other.clazz; asset = other.asset; return *this; } @@ -455,6 +496,7 @@ namespace Runtime { SoftAssetPtr& SoftAssetPtr::operator=(SoftAssetPtr&& other) noexcept { uri = std::move(other.uri); + clazz = other.clazz; asset = std::move(other.asset); return *this; } @@ -490,14 +532,20 @@ namespace Runtime { } template A> - AssetPtr AssetManager::SyncLoad(const Core::Uri& uri) + const Mirror::Class* SoftAssetPtr::Class() const + { + return clazz; + } + + template A> + AssetPtr AssetManager::SyncLoad(const Core::Uri& uri, const Mirror::Class& clazz) { auto iter = weakAssetRefs.find(uri); if (iter != weakAssetRefs.end() && !iter->second.Expired()) { return iter->second.Lock().StaticCast(); } - AssetPtr result = LoadInternal(uri); + AssetPtr result = LoadInternal(uri, clazz); AssetPtr tempRef = result.template StaticCast(); if (iter == weakAssetRefs.end()) { weakAssetRefs.emplace(std::make_pair(uri, WeakAssetPtr(tempRef))); @@ -508,13 +556,13 @@ namespace Runtime { } template A> - void AssetManager::SyncLoadSoft(SoftAssetPtr& softAssetRef) + void AssetManager::SyncLoadSoft(SoftAssetPtr& softAssetRef, const Mirror::Class& clazz) { - softAssetRef = SyncLoad(softAssetRef.Uri()); + softAssetRef = SyncLoad(softAssetRef.Uri(), clazz); } template A> - void AssetManager::AsyncLoad(const Core::Uri& uri, const OnAssetLoaded& onAssetLoaded) + void AssetManager::AsyncLoad(const Core::Uri& uri, const Mirror::Class& clazz, const OnAssetLoaded& onAssetLoaded) { threadPool.EmplaceTask([=, this]() -> void { AssetPtr result = nullptr; @@ -527,7 +575,7 @@ namespace Runtime { } if (result == nullptr) { - result = LoadInternal(uri); + result = LoadInternal(uri, clazz); } AssetPtr tempRef = result.template StaticCast(); @@ -546,10 +594,10 @@ namespace Runtime { } template A> - void AssetManager::AsyncLoadSoft(SoftAssetPtr& softAssetRef, const OnSoftAssetLoaded& onSoftAssetLoaded) + void AssetManager::AsyncLoadSoft(SoftAssetPtr& softAssetRef, const Mirror::Class& clazz, const OnSoftAssetLoaded& onSoftAssetLoaded) { - threadPool.EmplaceTask([this, softAssetRef, onSoftAssetLoaded]() -> void { - AsyncLoad(softAssetRef.Uri(), [&](AssetPtr& ref) -> void { + threadPool.EmplaceTask([this, softAssetRef, onSoftAssetLoaded, clazz]() -> void { + AsyncLoad(softAssetRef.Uri(), clazz, [&](AssetPtr& ref) -> void { softAssetRef = ref; onSoftAssetLoaded(); }); @@ -559,14 +607,11 @@ namespace Runtime { template A> void AssetManager::Save(const AssetPtr& assetRef) { - if (assetRef == nullptr) { - return; - } - + Assert(assetRef.Valid()); const Core::AssetUriParser parser(assetRef.Uri()); Common::BinaryFileSerializeStream stream(parser.Parse().Absolute().String()); - Mirror::Any ref = std::ref(*assetRef.Get()); + const Mirror::Any ref = assetRef->GetClass().Cast(Mirror::ForwardAsArg(*assetRef.Get())); ref.Serialize(stream); } @@ -577,15 +622,15 @@ namespace Runtime { } template A> - AssetPtr AssetManager::LoadInternal(const Core::Uri& uri) + AssetPtr AssetManager::LoadInternal(const Core::Uri& uri, const Mirror::Class& clazz) { const Core::AssetUriParser parser(uri); Common::BinaryFileDeserializeStream stream(parser.Parse().Absolute().String()); - AssetPtr result = Common::SharedPtr(new A(uri)); - Mirror::Any ref = std::ref(*result.Get()); - ref.Deserialize(stream); + Mirror::Any ptr = clazz.New(uri); + ptr.Deref().Deserialize(stream); + AssetPtr result = Common::SharedPtr(ptr.As()); result->SetUri(uri); result->PostLoad(); return result; diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Material.h b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h index cbc2283b7..a2bbba924 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Material.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h @@ -4,7 +4,10 @@ #pragma once +#include + #include +#include #include #include @@ -18,25 +21,98 @@ namespace Runtime { max }; - // TODO material parameter + enum class EEnum() MaterialParameterType : uint8_t { + tInt, + tFloat, + tFVec2, + tFVec3, + tFVec4, + tFMat4x4, + max + }; + + class RUNTIME_API EClass() MaterialParameter { + EClassBody(MaterialParameter) + + public: + MaterialParameter(); + + EFunc() MaterialParameterType GetType() const; + EFunc() int32_t GetInt() const; + EFunc() float GetFloat() const; + EFunc() Common::FVec2 GetFVec2() const; + EFunc() Common::FVec3 GetFVec3() const; + EFunc() Common::FVec4 GetFVec4() const; + EFunc() Common::FMat4x4 GetFMat4x4() const; + EFunc() void SetInt(int32_t inValue); + EFunc() void SetFloat(float inValue); + EFunc() void SetFVec2(const Common::FVec2& inValue); + EFunc() void SetFVec3(const Common::FVec3& inValue); + EFunc() void SetFVec4(const Common::FVec4& inValue); + EFunc() void SetFMat4x4(const Common::FMat4x4& inValue); + + private: + std::variant parameter; + }; + + class RUNTIME_API EClass() IMaterial : public Asset { + EPolyClassBody(IMaterial) - class RUNTIME_API EClass() Material : public Asset { + public: + using ParameterMap = std::unordered_map; + + ~IMaterial() override; + + EFunc() virtual MaterialType GetType() const = 0; + EFunc() virtual std::string GetSourceCode() const = 0; + EFunc() virtual void SetParameter(const std::string& inName, const MaterialParameter& inParameter) = 0; + EFunc() virtual ParameterMap& GetParameters() = 0; + EFunc() virtual const ParameterMap& GetParameters() const = 0; + + protected: + explicit IMaterial(Core::Uri inUri); + }; + + class RUNTIME_API EClass() Material final : public IMaterial { EPolyClassBody(Material) public: explicit Material(Core::Uri inUri); ~Material() override; + EFunc() MaterialType GetType() const override; + EFunc() std::string GetSourceCode() const override; + EFunc() void SetParameter(const std::string& inName, const MaterialParameter& inParameter) override; + EFunc() ParameterMap& GetParameters() override; + EFunc() const ParameterMap& GetParameters() const override; + + EFunc() void SetType(MaterialType inType); + EFunc() void SetSourceCode(const std::string& inSourceCode); + private: EProperty() MaterialType type; EProperty() std::string sourceCode; + EProperty() ParameterMap parameters; }; - class RUNTIME_API EClass() MaterialInstance final : public Material { + class RUNTIME_API EClass() MaterialInstance final : public IMaterial { EPolyClassBody(MaterialInstance) public: explicit MaterialInstance(Core::Uri inUri); ~MaterialInstance() override; + + EFunc() MaterialType GetType() const override; + EFunc() std::string GetSourceCode() const override; + EFunc() void SetParameter(const std::string& inName, const MaterialParameter& inParameter) override; + EFunc() ParameterMap& GetParameters() override; + EFunc() const ParameterMap& GetParameters() const override; + + EFunc() AssetPtr GetMaterial() const; + EFunc() void SetMaterial(const AssetPtr& inMaterial); + + private: + EProperty() AssetPtr material; + EProperty() ParameterMap parameters; }; } diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h index 4760624a8..c7a87d467 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h @@ -40,7 +40,7 @@ namespace Runtime { ~StaticMesh() override; private: - EProperty() AssetPtr material; + EProperty() AssetPtr material; EProperty() std::vector lodVec; }; } diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Texture.h b/Engine/Source/Runtime/Include/Runtime/Asset/Texture.h index 6c102ff8c..5b71e8482 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Texture.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Texture.h @@ -78,11 +78,11 @@ namespace Runtime { }; static_assert(static_cast(TextureFormat::max) == static_cast(RHI::PixelFormat::max)); - class RUNTIME_API Texture final : public Asset { + class RUNTIME_API EClass() Texture final : public Asset { EPolyClassBody(Texture) public: - using MipPixels = std::vector; + using Pixels = std::vector; explicit Texture(Core::Uri inUri); ~Texture() override; @@ -97,9 +97,8 @@ namespace Runtime { EFunc() uint8_t GetMipLevels() const; EFunc() uint8_t GetSamples() const; EFunc() const std::string& GetName() const; - EFunc() MipPixels& GetMipPixels(uint8_t inMipLevel); - EFunc() const MipPixels& GetMipPixels(uint8_t inMipLevel) const; - + EFunc() Pixels& GetSubResourcePixels(uint8_t inMipLevel, uint8_t inArrayLayer); + EFunc() const Pixels& GetSubResourcePixels(uint8_t inMipLevel, uint8_t inArrayLayer) const; EFunc() void SetType(TextureType inType); EFunc() void SetFormat(TextureFormat inFormat); EFunc() void SetWidth(uint32_t inWidth); @@ -108,7 +107,8 @@ namespace Runtime { EFunc() void SetMipLevels(uint8_t inMipLevels); EFunc() void SetSamples(uint8_t inSamples); EFunc() void SetName(const std::string& inName); - + EFunc() RHI::Texture* GetRHI() const; + EFunc() RHI::TextureView* GetViewRHI() const; EFunc() void UpdateMips(); EFunc() void UpdateRHI(); @@ -121,8 +121,52 @@ namespace Runtime { EProperty() uint8_t mipLevels; EProperty() uint8_t samples; EProperty() std::string name; - EProperty() std::vector mipsData; + EProperty() std::vector subResourcePixelsData; RenderThreadPtr texture; RenderThreadPtr textureView; }; + + class RUNTIME_API EClass() RenderTarget final : public Asset { + EPolyClassBody(RenderTarget) + + public: + explicit RenderTarget(Core::Uri inUri); + ~RenderTarget() override; + + void PostLoad() override; + + EFunc() TextureType GetType() const; + EFunc() TextureFormat GetFormat() const; + EFunc() uint32_t GetWidth() const; + EFunc() uint32_t GetHeight() const; + EFunc() uint32_t GetDepthOrArraySize() const; + EFunc() uint8_t GetMipLevels() const; + EFunc() uint8_t GetSamples() const; + EFunc() const std::string& GetName() const; + EFunc() void SetType(TextureType inType); + EFunc() void SetFormat(TextureFormat inFormat); + EFunc() void SetWidth(uint32_t inWidth); + EFunc() void SetHeight(uint32_t inHeight); + EFunc() void SetDepthOrArraySize(uint32_t inDepthOrArraySize); + EFunc() void SetMipLevels(uint8_t inMipLevels); + EFunc() void SetSamples(uint8_t inSamples); + EFunc() void SetName(const std::string& inName); + EFunc() RHI::Texture* GetRHI() const; + EFunc() RHI::TextureView* GetRenderTargetViewRHI() const; + EFunc() RHI::TextureView* GetShaderResourceViewRHI() const; + EFunc() void UpdateRHI(); + + private: + EProperty() TextureType type; + EProperty() TextureFormat format; + EProperty() uint32_t width; + EProperty() uint32_t height; + EProperty() uint32_t depthOrArraySize; + EProperty() uint8_t mipLevels; + EProperty() uint8_t samples; + EProperty() std::string name; + RenderThreadPtr texture; + RenderThreadPtr renderTargetView; + RenderThreadPtr shaderResourceView; + }; } diff --git a/Engine/Source/Runtime/Include/Runtime/Component/Player.h b/Engine/Source/Runtime/Include/Runtime/Component/Player.h index dec3b8cb9..eae643485 100644 --- a/Engine/Source/Runtime/Include/Runtime/Component/Player.h +++ b/Engine/Source/Runtime/Include/Runtime/Component/Player.h @@ -8,6 +8,7 @@ #include #include #include +#include namespace Runtime { struct RUNTIME_API EClass(globalComp, transient) PlayersInfo { @@ -24,7 +25,7 @@ namespace Runtime { LocalPlayer(); uint8_t localPlayerIndex; - Render::ViewState* viewState; + RenderThreadPtr viewState; }; #if BUILD_EDITOR @@ -33,7 +34,7 @@ namespace Runtime { EditorPlayer(); - Render::ViewState* viewState; + RenderThreadPtr viewState; }; #endif diff --git a/Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h b/Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h index c80241675..0144a9f42 100644 --- a/Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h +++ b/Engine/Source/Runtime/Include/Runtime/RenderThreadPtr.h @@ -60,9 +60,11 @@ namespace Runtime { template RenderThreadPtr::~RenderThreadPtr() { - EngineHolder::Get().GetRenderModule().GetRenderThread().EmplaceTask([transferPtr = std::move(ptr)]() mutable -> void { - transferPtr.Reset(); - }); + if (ptr.Valid()) { + EngineHolder::Get().GetRenderModule().GetRenderThread().EmplaceTask([transferPtr = std::move(ptr)]() mutable -> void { + transferPtr.Reset(); + }); + } } template diff --git a/Engine/Source/Runtime/Include/Runtime/System/Player.h b/Engine/Source/Runtime/Include/Runtime/System/Player.h index 8cf430c7b..2f0604f91 100644 --- a/Engine/Source/Runtime/Include/Runtime/System/Player.h +++ b/Engine/Source/Runtime/Include/Runtime/System/Player.h @@ -26,7 +26,6 @@ namespace Runtime { private: template Entity CreatePlayer(); template void CreatePlayerSpecialPart(T& inPlayer); - template void FinalizePlayer(Entity inEntity); uint8_t activeLocalPlayerNum; Render::RenderModule& renderModule; @@ -69,13 +68,4 @@ namespace Runtime { { } #endif - - template - void PlayerSystem::FinalizePlayer(Entity inEntity) - { - auto& player = registry.Get(inEntity); - renderModule.GetRenderThread().EmplaceTask([viewState = player.viewState]() -> void { - delete viewState; - }); - } } // namespace Runtime diff --git a/Engine/Source/Runtime/Include/Runtime/System/Render.h b/Engine/Source/Runtime/Include/Runtime/System/Render.h index c1725e860..8b1dfb556 100644 --- a/Engine/Source/Runtime/Include/Runtime/System/Render.h +++ b/Engine/Source/Runtime/Include/Runtime/System/Render.h @@ -52,7 +52,7 @@ namespace Runtime { const auto height = clientViewport.GetHeight(); Render::View view = renderModule.CreateView(); - view.state = player.viewState; + view.state = player.viewState.Get(); view.data.viewport = GetPlayerViewport(width, height, inPlayerNum, inPlayerIndex); view.data.viewMatrix = worldTransform.localToWorld.GetTransformMatrixNoScale().Inverse(); view.data.origin = worldTransform.localToWorld.translation; diff --git a/Engine/Source/Runtime/Src/Asset/Material.cpp b/Engine/Source/Runtime/Src/Asset/Material.cpp index 0739ef7d8..85876cdea 100644 --- a/Engine/Source/Runtime/Src/Asset/Material.cpp +++ b/Engine/Source/Runtime/Src/Asset/Material.cpp @@ -5,18 +5,178 @@ #include namespace Runtime { - Material::Material(Core::Uri inUri) + MaterialParameter::MaterialParameter() = default; + + MaterialParameterType MaterialParameter::GetType() const + { + constexpr MaterialParameterType vec[] = { + MaterialParameterType::max, + MaterialParameterType::tInt, + MaterialParameterType::tFloat, + MaterialParameterType::tFVec2, + MaterialParameterType::tFVec3, + MaterialParameterType::tFVec4, + MaterialParameterType::tFMat4x4 + }; + static_assert(sizeof(vec) / sizeof(MaterialParameterType) == std::variant_size_v); + return vec[parameter.index()]; + } + + int32_t MaterialParameter::GetInt() const + { + Assert(GetType() == MaterialParameterType::tInt); + return std::get(parameter); + } + + float MaterialParameter::GetFloat() const + { + Assert(GetType() == MaterialParameterType::tFloat); + return std::get(parameter); + } + + Common::FVec2 MaterialParameter::GetFVec2() const + { + Assert(GetType() == MaterialParameterType::tFVec2); + return std::get(parameter); + } + + Common::FVec3 MaterialParameter::GetFVec3() const + { + Assert(GetType() == MaterialParameterType::tFVec3); + return std::get(parameter); + } + + Common::FVec4 MaterialParameter::GetFVec4() const + { + Assert(GetType() == MaterialParameterType::tFVec4); + return std::get(parameter); + } + + Common::FMat4x4 MaterialParameter::GetFMat4x4() const + { + Assert(GetType() == MaterialParameterType::tFMat4x4); + return std::get(parameter); + } + + void MaterialParameter::SetInt(int32_t inValue) + { + parameter = inValue; + } + + void MaterialParameter::SetFloat(float inValue) + { + parameter = inValue; + } + + void MaterialParameter::SetFVec2(const Common::FVec2& inValue) + { + parameter = inValue; + } + + void MaterialParameter::SetFVec3(const Common::FVec3& inValue) + { + parameter = inValue; + } + + void MaterialParameter::SetFVec4(const Common::FVec4& inValue) + { + parameter = inValue; + } + + void MaterialParameter::SetFMat4x4(const Common::FMat4x4& inValue) + { + parameter = inValue; + } + + IMaterial::IMaterial(Core::Uri inUri) : Asset(std::move(inUri)) + { + } + + IMaterial::~IMaterial() = default; + + Material::Material(Core::Uri inUri) + : IMaterial(std::move(inUri)) , type(MaterialType::max) { } Material::~Material() = default; + MaterialType Material::GetType() const + { + return type; + } + + std::string Material::GetSourceCode() const + { + return sourceCode; + } + + void Material::SetParameter(const std::string& inName, const MaterialParameter& inParameter) + { + parameters[inName] = inParameter; + } + + void Material::SetType(MaterialType inType) + { + type = inType; + } + + void Material::SetSourceCode(const std::string& inSourceCode) + { + sourceCode = inSourceCode; + } + + IMaterial::ParameterMap& Material::GetParameters() + { + return parameters; + } + + const IMaterial::ParameterMap& Material::GetParameters() const + { + return parameters; + } + MaterialInstance::MaterialInstance(Core::Uri inUri) - : Material(std::move(inUri)) + : IMaterial(std::move(inUri)) { } MaterialInstance::~MaterialInstance() = default; + + MaterialType MaterialInstance::GetType() const + { + return material->GetType(); + } + + std::string MaterialInstance::GetSourceCode() const + { + return material->GetSourceCode(); + } + + void MaterialInstance::SetParameter(const std::string& inName, const MaterialParameter& inParameter) + { + parameters[inName] = inParameter; + } + + IMaterial::ParameterMap& MaterialInstance::GetParameters() + { + return parameters; + } + + const IMaterial::ParameterMap& MaterialInstance::GetParameters() const + { + return parameters; + } + + AssetPtr MaterialInstance::GetMaterial() const + { + return material; + } + + void MaterialInstance::SetMaterial(const AssetPtr& inMaterial) // NOLINT + { + material = inMaterial; + } } diff --git a/Engine/Source/Runtime/Src/Asset/Texture.cpp b/Engine/Source/Runtime/Src/Asset/Texture.cpp index dafab90d9..babd29083 100644 --- a/Engine/Source/Runtime/Src/Asset/Texture.cpp +++ b/Engine/Source/Runtime/Src/Asset/Texture.cpp @@ -47,103 +47,9 @@ namespace Runtime::Internal { return RHI::TextureAspect::color; } - static void Upload3DTexture( - RHI::Device& inDevice, - RHI::Texture& inTexture, - TextureFormat inFormat, - uint32_t inWidth, - uint32_t inHeight, - uint32_t inDepthOrArraySize, - uint8_t inMipLevels, - RHI::TextureAspect inAspect, - const std::vector& inMipsData, - const std::string& inName) - { - std::vector copyFootprints; - copyFootprints.reserve(inMipLevels); - for (auto i = 0; i < inMipLevels; i++) { - copyFootprints.emplace_back(inDevice.GetTextureSubResourceCopyFootprint(inTexture, RHI::TextureSubResourceInfo(i, 0, inAspect))); - } - - size_t totalBytes = 0; - for (const auto& copyFootprint : copyFootprints) { - totalBytes += copyFootprint.totalBytes; - } - - const Common::UniquePtr stagingBuffer = inDevice.CreateBuffer( - RHI::BufferCreateInfo() - .SetSize(totalBytes) - .SetUsages(RHI::BufferUsageBits::copySrc | RHI::BufferUsageBits::mapWrite) - .SetInitialState(RHI::BufferState::staging) - .SetDebugName(std::format("StagingBuffer-{}", inName))); - - size_t dstMipOffset = 0; - auto* dstData = stagingBuffer->Map(RHI::MapMode::write, 0, totalBytes); - for (auto m = 0; m < inMipLevels; m++) { - const auto& srcPixels = inMipsData[m]; - const auto& dstCopyFootprints = copyFootprints[m]; - const auto srcRowPitch = inWidth * RHI::GetBytesPerPixel(static_cast(inFormat)); - const auto srcSlicePitch = inWidth * inHeight * RHI::GetBytesPerPixel(static_cast(inFormat)); - for (auto z = 0; z < inDepthOrArraySize; z++) { - for (auto y = 0; y < inHeight; y++) { - const auto* src = srcPixels.data() + srcSlicePitch * z + srcRowPitch * y; // NOLINT - auto* dst = dstData + dstMipOffset + dstCopyFootprints.slicePitch * z + dstCopyFootprints.rowPitch * y; // NOLINT - memcpy(dst, src, srcRowPitch); - } - } - dstMipOffset += dstCopyFootprints.totalBytes; - } - stagingBuffer->UnMap(); - - const Common::UniquePtr cmdBuffer = inDevice.CreateCommandBuffer(); - const auto recoder = cmdBuffer->Begin(); - { - const auto passRecoder = recoder->BeginCopyPass(); - - dstMipOffset = 0; - for (auto m = 0; m < inMipLevels; m++) { - passRecoder->CopyBufferToTexture( - stagingBuffer.Get(), - &inTexture, - RHI::BufferTextureCopyInfo() - .SetBufferOffset(dstMipOffset) - .SetTextureSubResource(RHI::TextureSubResourceInfo(m, 0, inAspect)) - .SetTextureOrigin({ 0, 0, 0 }) - .SetCopyRegion({ inWidth, inHeight, inDepthOrArraySize })); - dstMipOffset += copyFootprints[m].totalBytes; - } - passRecoder->EndPass(); - } - recoder->End(); - - const Common::UniquePtr fence = inDevice.CreateFence(false); - inDevice.GetQueue(RHI::QueueType::transfer, 0) - ->Submit(cmdBuffer.Get(), RHI::QueueSubmitInfo().SetSignalFence(fence.Get())); - fence->Wait(); - } - - static void UploadTextureOrArray( - RHI::Device& inDevice, - RHI::Texture& inTexture, - TextureFormat inFormat, - uint32_t inWidth, - uint32_t inHeight, - uint32_t inDepthOrArraySize, - uint8_t inMipLevels, - RHI::TextureAspect inAspect, - const std::vector& inMipsData, - const std::string& inName) - { - std::vector copyFootprints; - copyFootprints.reserve(inMipLevels * inDepthOrArraySize); - - for (auto m = 0; m < inMipLevels; m++) { - for (auto a = 0; a < inDepthOrArraySize; a++) { - copyFootprints.emplace_back(inDevice.GetTextureSubResourceCopyFootprint(inTexture, RHI::TextureSubResourceInfo(m, a, inAspect))); - } - } - - // TODO + static uint32_t GetSubResourceIndex(uint8_t inMipLevel, uint8_t inArrayLayer, uint8_t inTotalArrayLayer) + { + return inMipLevel * inTotalArrayLayer + inArrayLayer; // NOLINT } } @@ -207,14 +113,22 @@ namespace Runtime { return name; } - Texture::MipPixels& Texture::GetMipPixels(uint8_t inMipLevel) + Texture::Pixels& Texture::GetSubResourcePixels(uint8_t inMipLevel, uint8_t inArrayLayer) { - return mipsData[inMipLevel]; + if (type == TextureType::t3D) { + Assert(inArrayLayer == 0); + return subResourcePixelsData[Internal::GetSubResourceIndex(inMipLevel, 0, 1)]; + } + return subResourcePixelsData[Internal::GetSubResourceIndex(inMipLevel, inArrayLayer, depthOrArraySize)]; } - const Texture::MipPixels& Texture::GetMipPixels(uint8_t inMipLevel) const + const Texture::Pixels& Texture::GetSubResourcePixels(uint8_t inMipLevel, uint8_t inArrayLayer) const { - return mipsData[inMipLevel]; + if (type == TextureType::t3D) { + Assert(inArrayLayer == 0); + return subResourcePixelsData[Internal::GetSubResourceIndex(inMipLevel, 0, 1)]; + } + return subResourcePixelsData[Internal::GetSubResourceIndex(inMipLevel, inArrayLayer, depthOrArraySize)]; } void Texture::SetType(TextureType inType) @@ -257,14 +171,31 @@ namespace Runtime { name = inName; } - void Texture::UpdateMips() + RHI::Texture* Texture::GetRHI() const { - mipsData.clear(); - mipsData.resize(mipLevels); + return texture.Get(); + } + + RHI::TextureView* Texture::GetViewRHI() const + { + return textureView.Get(); + } + void Texture::UpdateMips() + { + const auto arraySize = type == TextureType::t3D ? 1 : depthOrArraySize; const auto bytesPerPixel = RHI::GetBytesPerPixel(static_cast(format)); - for (auto i = 0; i < mipLevels; i++) { - mipsData[i].resize(width * height * depthOrArraySize * bytesPerPixel); + + subResourcePixelsData.clear(); + subResourcePixelsData.resize(mipLevels * arraySize); + + for (auto m = 0; m < mipLevels; m++) { + const auto mipWidth = std::max(width >> m, 1u); + const auto mipHeight = std::max(height >> m, 1u); + + for (auto a = 0; a < arraySize; a++) { + subResourcePixelsData[Internal::GetSubResourceIndex(m, a, arraySize)].resize(mipWidth * mipHeight * bytesPerPixel); + } } } @@ -304,13 +235,234 @@ namespace Runtime { depthOrArraySize = depthOrArraySize, mipLevels = mipLevels, aspect = Internal::GetTextureAspect(format), - mipsData = mipsData, - name = name]() -> void { - if (type == TextureType::t3D) { - Internal::Upload3DTexture(*device, *texturePtr, format, width, height, depthOrArraySize, mipLevels, aspect, mipsData, name); - } else { - Internal::UploadTextureOrArray(*device, *texturePtr, format, width, height, depthOrArraySize, mipLevels, aspect, mipsData, name); + subResourcePixelsData = subResourcePixelsData, + name = name + ]() -> void { + const auto arraySize = type == TextureType::t3D ? 1 : depthOrArraySize; + const auto depth = type == TextureType::t3D ? depthOrArraySize : 1; + + std::vector copyFootprints; + copyFootprints.reserve(mipLevels * arraySize); + for (auto m = 0; m < mipLevels; m++) { + for (auto a = 0; a < arraySize; a++) { + copyFootprints.emplace_back(device->GetTextureSubResourceCopyFootprint(*texturePtr, RHI::TextureSubResourceInfo(m, a, aspect))); + } } + + size_t totalBytes = 0; + for (const auto& copyFootprint : copyFootprints) { + totalBytes += copyFootprint.totalBytes; + } + + const Common::UniquePtr stagingBuffer = device->CreateBuffer( + RHI::BufferCreateInfo() + .SetSize(totalBytes) + .SetUsages(RHI::BufferUsageBits::copySrc | RHI::BufferUsageBits::mapWrite) + .SetInitialState(RHI::BufferState::staging) + .SetDebugName(std::format("StagingBuffer-{}", name))); + + const auto srcRowPitch = width * RHI::GetBytesPerPixel(static_cast(format)); + const auto srcSlicePitch = width * height * RHI::GetBytesPerPixel(static_cast(format)); + + size_t dstSubResourceOffset = 0; + auto* dstData = static_cast(stagingBuffer->Map(RHI::MapMode::write, 0, totalBytes)); + for (auto m = 0; m < mipLevels; m++) { + for (auto a = 0; a < arraySize; a++) { + const auto subResourceIndex = Internal::GetSubResourceIndex(m, a, arraySize); + const auto& srcPixels = subResourcePixelsData[subResourceIndex]; + const auto& dstCopyFootprint = copyFootprints[subResourceIndex]; + + for (auto z = 0; z < depthOrArraySize; z++) { + for (auto y = 0; y < height; y++) { + const auto* src = srcPixels.data() + srcSlicePitch * z + srcRowPitch * y; + auto* dst = dstData + dstSubResourceOffset + dstCopyFootprint.slicePitch * z + dstCopyFootprint.rowPitch * y; + memcpy(dst, src, srcRowPitch); + } + } + dstSubResourceOffset += dstCopyFootprint.totalBytes; + } + } + stagingBuffer->UnMap(); + + const Common::UniquePtr cmdBuffer = device->CreateCommandBuffer(); + const auto recoder = cmdBuffer->Begin(); + { + const auto passRecoder = recoder->BeginCopyPass(); + { + dstSubResourceOffset = 0; + for (auto m = 0; m < mipLevels; m++) { + for (auto a = 0; a < arraySize; a++) { + const auto subResourceIndex = Internal::GetSubResourceIndex(m, a, arraySize); + passRecoder->CopyBufferToTexture( + stagingBuffer.Get(), + texturePtr, + RHI::BufferTextureCopyInfo() + .SetBufferOffset(dstSubResourceOffset) + .SetTextureSubResource(RHI::TextureSubResourceInfo(m, a, aspect)) + .SetTextureOrigin({ 0, 0, 0 }) + .SetCopyRegion({ width, height, depth })); + dstSubResourceOffset += copyFootprints[subResourceIndex].totalBytes; + } + } + } + passRecoder->EndPass(); + } + recoder->End(); + + const Common::UniquePtr fence = device->CreateFence(false); + device + ->GetQueue(RHI::QueueType::transfer, 0) + ->Submit(cmdBuffer.Get(), RHI::QueueSubmitInfo().SetSignalFence(fence.Get())); + fence->Wait(); }); } + + RenderTarget::RenderTarget(Core::Uri inUri) + : Asset(std::move(inUri)) + , type(TextureType::max) + , format(TextureFormat::max) + , width(1) + , height(1) + , depthOrArraySize(1) + , mipLevels(1) + , samples(1) + { + } + + RenderTarget::~RenderTarget() = default; + + void RenderTarget::PostLoad() + { + UpdateRHI(); + } + + TextureType RenderTarget::GetType() const + { + return type; + } + + TextureFormat RenderTarget::GetFormat() const + { + return format; + } + + uint32_t RenderTarget::GetWidth() const + { + return width; + } + + uint32_t RenderTarget::GetHeight() const + { + return height; + } + + uint32_t RenderTarget::GetDepthOrArraySize() const + { + return depthOrArraySize; + } + + uint8_t RenderTarget::GetMipLevels() const + { + return mipLevels; + } + + uint8_t RenderTarget::GetSamples() const + { + return samples; + } + + const std::string& RenderTarget::GetName() const + { + return name; + } + + void RenderTarget::SetType(TextureType inType) + { + type = inType; + } + + void RenderTarget::SetFormat(TextureFormat inFormat) + { + format = inFormat; + } + + void RenderTarget::SetWidth(uint32_t inWidth) + { + width = inWidth; + } + + void RenderTarget::SetHeight(uint32_t inHeight) + { + height = inHeight; + } + + void RenderTarget::SetDepthOrArraySize(uint32_t inDepthOrArraySize) + { + depthOrArraySize = inDepthOrArraySize; + } + + void RenderTarget::SetMipLevels(uint8_t inMipLevels) + { + mipLevels = inMipLevels; + } + + void RenderTarget::SetSamples(uint8_t inSamples) + { + samples = inSamples; + } + + void RenderTarget::SetName(const std::string& inName) + { + name = inName; + } + + RHI::Texture* RenderTarget::GetRHI() const + { + return texture.Get(); + } + + RHI::TextureView* RenderTarget::GetRenderTargetViewRHI() const + { + return renderTargetView.Get(); + } + + RHI::TextureView* RenderTarget::GetShaderResourceViewRHI() const + { + return shaderResourceView.Get(); + } + + void RenderTarget::UpdateRHI() + { + const auto& renderModule = EngineHolder::Get().GetRenderModule(); + auto* device = renderModule.GetDevice(); + + texture = device->CreateTexture( + RHI::TextureCreateInfo() + .SetDimension(Internal::GetTextureDimension(type)) + .SetWidth(width) + .SetHeight(height) + .SetDepthOrArraySize(depthOrArraySize) + .SetFormat(static_cast(format)) + .SetUsages(RHI::TextureUsageBits::textureBinding | (Internal::IsDepthOrStencilFormat(format) ? RHI::TextureUsageBits::depthStencilAttachment : RHI::TextureUsageBits::renderAttachment)) + .SetMipLevels(mipLevels) + .SetSamples(samples) + .SetInitialState(RHI::TextureState::shaderReadOnly) + .SetDebugName(name)); + + renderTargetView = texture->CreateTextureView( + RHI::TextureViewCreateInfo() + .SetType(Internal::IsDepthOrStencilFormat(format) ? RHI::TextureViewType::depthStencil : RHI::TextureViewType::colorAttachment) + .SetDimension(static_cast(type)) + .SetAspect(Internal::GetTextureAspect(format)) + .SetMipLevels(0, mipLevels) + .SetArrayLayers(0, type == TextureType::t3D ? 1 : depthOrArraySize)); + + shaderResourceView = texture->CreateTextureView( + RHI::TextureViewCreateInfo() + .SetType(Internal::IsDepthOrStencilFormat(format) ? RHI::TextureViewType::depthStencil : RHI::TextureViewType::textureBinding) + .SetDimension(static_cast(type)) + .SetAspect(Internal::GetTextureAspect(format)) + .SetMipLevels(0, mipLevels) + .SetArrayLayers(0, type == TextureType::t3D ? 1 : depthOrArraySize)); + } } diff --git a/Engine/Source/Runtime/Src/System/Player.cpp b/Engine/Source/Runtime/Src/System/Player.cpp index 1c4397590..388c727e8 100644 --- a/Engine/Source/Runtime/Src/System/Player.cpp +++ b/Engine/Source/Runtime/Src/System/Player.cpp @@ -29,11 +29,5 @@ namespace Runtime { } } - PlayerSystem::~PlayerSystem() - { - registry.View().Each([this](Entity e, LocalPlayer& player) -> void { FinalizePlayer(e); }); -#if BUILD_EDITOR - registry.View().Each([this](Entity e, EditorPlayer& player) -> void { FinalizePlayer(e); }); -#endif - } + PlayerSystem::~PlayerSystem() = default; } // namespace Runtime diff --git a/Engine/Source/Runtime/Test/AssetTest.cpp b/Engine/Source/Runtime/Test/AssetTest.cpp index 066421ef5..6700a4112 100644 --- a/Engine/Source/Runtime/Test/AssetTest.cpp +++ b/Engine/Source/Runtime/Test/AssetTest.cpp @@ -47,7 +47,7 @@ TEST(AssetTest, SaveLoadTest) AssetPtr asset = MakeShared(uri, 1, "hello"); AssetManager::Get().Save(asset); - AssetPtr restore = AssetManager::Get().SyncLoad(uri); + AssetPtr restore = AssetManager::Get().SyncLoad(uri, TestAsset::GetStaticClass()); ASSERT_EQ(restore.Uri(), uri); ASSERT_EQ(restore->a, 1); ASSERT_EQ(restore->b, "hello"); @@ -60,9 +60,23 @@ TEST(AssetTest, AsyncLoadTest) AssetPtr asset = MakeShared(uri, 1, "hello"); AssetManager::Get().Save(asset); - AssetManager::Get().AsyncLoad(uri, [&](AssetPtr restore) -> void { + AssetManager::Get().AsyncLoad(uri, TestAsset::GetStaticClass(), [&](AssetPtr restore) -> void { ASSERT_EQ(restore.Uri(), uri); ASSERT_EQ(restore->a, 1); ASSERT_EQ(restore->b, "hello"); }); } + +TEST(AssetTest, PolySaveLoadTest) +{ + static Core::Uri uri("asset://Engine/Test/Generated/Runtime/AssetTest.PolySaveLoadTest"); + + AssetPtr asset = new TestAsset(uri, 1, "hello"); + AssetManager::Get().Save(asset); + + AssetPtr restore = AssetManager::Get().SyncLoad(uri, TestAsset::GetStaticClass()); + AssetPtr result = restore.DynamicCast(); + ASSERT_EQ(result.Uri(), uri); + ASSERT_EQ(result->a, 1); + ASSERT_EQ(result->b, "hello"); +} diff --git a/Tool/MirrorTool/ExeSrc/Main.cpp b/Tool/MirrorTool/ExeSrc/Main.cpp index 16138869f..58cab5adb 100644 --- a/Tool/MirrorTool/ExeSrc/Main.cpp +++ b/Tool/MirrorTool/ExeSrc/Main.cpp @@ -2,6 +2,8 @@ // Created by johnk on 2022/11/20. // +#include + #include #include @@ -9,10 +11,23 @@ #include #include +#define OUTPUT_FULL_CMDLINE 0 + int main(int argc, char* argv[]) // NOLINT { AutoCoutFlush; +#if OUTPUT_FULL_CMDLINE + std::stringstream fullCmdline; + for (auto i = 0; i < argc; i++) { + fullCmdline << argv[i]; + if (i != argc - 1) { + fullCmdline << " "; + } + } + std::cout << fullCmdline.str() << std::endl; +#endif + std::string inputFile; std::string outputFile; std::vector headerDirs; diff --git a/Tool/MirrorTool/Include/MirrorTool/Parser.h b/Tool/MirrorTool/Include/MirrorTool/Parser.h index ca997078c..057b1a83e 100644 --- a/Tool/MirrorTool/Include/MirrorTool/Parser.h +++ b/Tool/MirrorTool/Include/MirrorTool/Parser.h @@ -45,6 +45,7 @@ namespace MirrorTool { struct ClassFunctionInfo : FunctionInfo { FieldAccess fieldAccess; + bool isConst = false; }; struct ClassConstructorInfo : Node { diff --git a/Tool/MirrorTool/Src/Generator.cpp b/Tool/MirrorTool/Src/Generator.cpp index 14a4a803b..b2c12fd6b 100644 --- a/Tool/MirrorTool/Src/Generator.cpp +++ b/Tool/MirrorTool/Src/Generator.cpp @@ -213,8 +213,11 @@ namespace MirrorTool { } stream << GetMetaDataCode<3>(clazz); for (const auto& constructor : clazz.constructors) { - const std::string fieldAccessStr = constructor.fieldAccess != FieldAccess::pub ? std::format(", {}", GetFieldAccessStr(constructor.fieldAccess)) : ""; - stream << Common::newline << Common::tab<3> << std::format(R"(.Constructor<{}{}>("{}"))", constructor.name, fieldAccessStr, constructor.name); + if (constructor.fieldAccess == FieldAccess::pub) { + stream << Common::newline << Common::tab<3> << std::format(R"(.Constructor<{}>("{}"))", constructor.name, constructor.name); + } else { + stream << Common::newline << Common::tab<3> << std::format(R"(.Constructor<{}, {}>("{}"))", GetFieldAccessStr(constructor.fieldAccess), constructor.name, constructor.name); + } stream << GetMetaDataCode<4>(constructor); } for (const auto& staticVariable : clazz.staticVariables) { @@ -258,8 +261,8 @@ namespace MirrorTool { for (const auto& overload : overloads) { const ClassFunctionInfo& function = *overload; const std::string functionName = GetFullName(function); - const std::string shortFunctionNameWithParams = GetOverloadFunctionFullNameWithParams(function, function.name); - const std::string ptrType = GetOverloadFunctionPtrType(function, fullName); + const std::string shortFunctionNameWithParams = GetOverloadFunctionFullNameWithParams(function, function.name) + (overload->isConst ? " const" : ""); + const std::string ptrType = GetOverloadFunctionPtrType(function, fullName) + (overload->isConst ? " const" : ""); const std::string fieldAccessStr = function.fieldAccess != FieldAccess::pub ? std::format(", {}", GetFieldAccessStr(function.fieldAccess)) : ""; stream << Common::newline << Common::tab<3> << std::format(R"(.MemberFunction(&{}){}>("{}"))", ptrType, functionName, fieldAccessStr, shortFunctionNameWithParams); stream << GetMetaDataCode<4>(function); @@ -289,7 +292,7 @@ namespace MirrorTool { stream << Common::tab<1> << std::format("static const Mirror::Class& clazz = Mirror::Class::Get<{}>();", fullName) << Common::newline; stream << Common::tab<1> << "return clazz;" << Common::newline; stream << "}" << Common::newline; - stream << std::format("const Mirror::Class& {}::GetClass()", fullName) << Common::newline; + stream << std::format("const Mirror::Class& {}::GetClass() const", fullName) << Common::newline; stream << "{" << Common::newline; stream << Common::tab<1> << std::format("static const Mirror::Class& clazz = Mirror::Class::Get<{}>();", fullName) << Common::newline; stream << Common::tab<1> << "return clazz;" << Common::newline; diff --git a/Tool/MirrorTool/Src/Parser.cpp b/Tool/MirrorTool/Src/Parser.cpp index 082b5d3dc..d779fd717 100644 --- a/Tool/MirrorTool/Src/Parser.cpp +++ b/Tool/MirrorTool/Src/Parser.cpp @@ -237,17 +237,22 @@ namespace MirrorTool { CXType retType = clang_getCursorResultType(cursor); CXString retTypeSpelling = clang_getTypeSpelling(retType); + const CXString functionPrettyPrinted = clang_getCursorPrettyPrinted(cursor, nullptr); + const std::string functionPrettyPrintedStr = clang_getCString(functionPrettyPrinted); + ClassFunctionInfo functionInfo; functionInfo.outerName = GetOuterName(context.outerName, context.name); functionInfo.name = spellingStr; functionInfo.retType = clang_getCString(retTypeSpelling); functionInfo.fieldAccess = context.lastFieldAccess; + functionInfo.isConst = functionPrettyPrintedStr.find(") const") != std::string::npos; auto& functions = isStatic ? context.staticFunctions : context.functions; functions.emplace_back(std::move(functionInfo)); VisitChildren(ClassFunctionVisitor, ClassFunctionInfo, cursor, functions.back()); ApplyMetaFilter(functions, functionMetaTag); clang_disposeString(retTypeSpelling); + clang_disposeString(functionPrettyPrinted); } else if (kind == CXCursor_Constructor && NeedProcessConstructorCursor(cursor)) { ClassConstructorInfo constructorInfo; constructorInfo.outerName = GetOuterName(context.outerName, context.name); From d150d81efcf0324a43b6595abdb794d9e8993354 Mon Sep 17 00:00:00 2001 From: FlyAndNotDown Date: Sun, 30 Mar 2025 12:07:27 +0800 Subject: [PATCH 4/4] fix: scroll bar style issue on windows --- Editor/Qml/EWidgetSamples.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/Editor/Qml/EWidgetSamples.qml b/Editor/Qml/EWidgetSamples.qml index e39bf4de3..9c161f50f 100644 --- a/Editor/Qml/EWidgetSamples.qml +++ b/Editor/Qml/EWidgetSamples.qml @@ -1,5 +1,6 @@ import QtQuick import QtQuick.Controls +import QtQuick.Controls.Basic import QtQuick.Layouts Rectangle {