From b68f71481dcd1303a5ce69f7b4379be2fcdc0062 Mon Sep 17 00:00:00 2001 From: FlyAntNotDown <461425614@qq.com> Date: Sun, 16 Mar 2025 22:19:43 +0800 Subject: [PATCH 1/6] refactor: change macos native surface type from NSWindow* to NSView* to support qt better --- Engine/Source/RHI-Vulkan/Src/Platform/MacosSurface.mm | 4 +--- Engine/Source/RHI/Include/RHI/Surface.h | 2 ++ Sample/Base/Application.cpp | 2 +- ThirdParty/CMakeLists.txt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Engine/Source/RHI-Vulkan/Src/Platform/MacosSurface.mm b/Engine/Source/RHI-Vulkan/Src/Platform/MacosSurface.mm index 65c3a8d8c..0fec94746 100644 --- a/Engine/Source/RHI-Vulkan/Src/Platform/MacosSurface.mm +++ b/Engine/Source/RHI-Vulkan/Src/Platform/MacosSurface.mm @@ -14,11 +14,9 @@ namespace RHI::Vulkan { VkSurfaceKHR CreateNativeSurface(const VkInstance& instance, const SurfaceCreateInfo& createInfo) { - auto nsWin = static_cast(createInfo.window); - NSBundle* bundle = [NSBundle bundleWithPath: @"/System/Library/Frameworks/QuartzCore.framework"]; CALayer* layer = [[bundle classNamed: @"CAMetalLayer"] layer]; - NSView* view = nsWin.contentView; + auto* view = static_cast(createInfo.window); [view setLayer: layer]; [view setWantsLayer: YES]; diff --git a/Engine/Source/RHI/Include/RHI/Surface.h b/Engine/Source/RHI/Include/RHI/Surface.h index 6e34a9c40..f0f7cf82b 100644 --- a/Engine/Source/RHI/Include/RHI/Surface.h +++ b/Engine/Source/RHI/Include/RHI/Surface.h @@ -8,6 +8,8 @@ namespace RHI { struct SurfaceCreateInfo { + // Windows: HWND + // macOS: NSView* void* window; explicit SurfaceCreateInfo(void* inWindow = nullptr); diff --git a/Sample/Base/Application.cpp b/Sample/Base/Application.cpp index c228033ca..4b426e6ac 100644 --- a/Sample/Base/Application.cpp +++ b/Sample/Base/Application.cpp @@ -215,7 +215,7 @@ void* Application::GetPlatformWindow() const #if PLATFORM_WINDOWS return glfwGetWin32Window(window); #elif PLATFORM_MACOS - return glfwGetCocoaWindow(window); + return glfwGetCocoaView(window); #else Unimplement(); return nullptr; diff --git a/ThirdParty/CMakeLists.txt b/ThirdParty/CMakeLists.txt index e9396450e..b53e589c6 100644 --- a/ThirdParty/CMakeLists.txt +++ b/ThirdParty/CMakeLists.txt @@ -125,8 +125,8 @@ Add3rdAliasPackage( Add3rdCMakeProject( NAME glfw PLATFORM All - VERSION 3.3.6 - HASH d3a7807f604b0f92af7606b2018a007892bb8de0db5efb99e26fb1f41b828da4 + VERSION 4.0 + HASH 2483836f085d616acaa48f6dc8efec5239f6a538c3a25d13fdc6a7afb2cce1d4 CMAKE_ARG -DUSE_MSVC_RUNTIME_LIBRARY_DLL=OFF -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF -DGLFW_BUILD_DOCS=OFF INCLUDE $/include LINK $/lib From ce28f54e9ed7588fa69819e816898cc8bcae35c8 Mon Sep 17 00:00:00 2001 From: FlyAntNotDown <461425614@qq.com> Date: Sun, 16 Mar 2025 22:20:00 +0800 Subject: [PATCH 2/6] feat: graphics window basic --- Editor/Include/Editor/Widget/GraphicsWindow.h | 41 +++++++++++ .../Editor/Widget/GraphicsWindowSample.h | 41 +++++++++++ Editor/Src/Main.cpp | 10 ++- Editor/Src/Widget/GraphicsWindow.cpp | 71 +++++++++++++++++++ Editor/Src/Widget/GraphicsWindowSample.cpp | 50 +++++++++++++ 5 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 Editor/Include/Editor/Widget/GraphicsWindow.h create mode 100644 Editor/Include/Editor/Widget/GraphicsWindowSample.h create mode 100644 Editor/Src/Widget/GraphicsWindow.cpp create mode 100644 Editor/Src/Widget/GraphicsWindowSample.cpp diff --git a/Editor/Include/Editor/Widget/GraphicsWindow.h b/Editor/Include/Editor/Widget/GraphicsWindow.h new file mode 100644 index 000000000..7fce51be4 --- /dev/null +++ b/Editor/Include/Editor/Widget/GraphicsWindow.h @@ -0,0 +1,41 @@ +// +// Created by Kindem on 2025/3/16. +// + +#pragma once + +#include + +#include +#include + +namespace Editor { + struct GraphicsWindowDesc { + uint8_t textureNum; + std::vector formatQualifiers; + RHI::PresentMode presentMode; + }; + + class GraphicsWindow : public QWindow { + Q_OBJECT + + public: + explicit GraphicsWindow(const GraphicsWindowDesc& inDesc, QWindow* inParent = nullptr); + ~GraphicsWindow() override; + + uint8_t GetTextureNum() const; + RHI::PixelFormat GetPixelFormat() const; + RHI::Device& GetDevice() const; + RHI::Surface& GetSurface() const; + RHI::SwapChain& GetSwapChain() const; + + // TODO auto resize + + private: + uint8_t textureNum; + RHI::PixelFormat pixelFormat; + RHI::Device* device; + Common::UniquePtr surface; + Common::UniquePtr swapChain; + }; +} diff --git a/Editor/Include/Editor/Widget/GraphicsWindowSample.h b/Editor/Include/Editor/Widget/GraphicsWindowSample.h new file mode 100644 index 000000000..facbb0da2 --- /dev/null +++ b/Editor/Include/Editor/Widget/GraphicsWindowSample.h @@ -0,0 +1,41 @@ +// +// Created by Kindem on 2025/3/16. +// + +#pragma once + +#include +#include + +#include + +namespace Editor { + class GraphicsWindowSample final : public GraphicsWindow { + Q_OBJECT + + public: + explicit GraphicsWindowSample(QWindow* inParent = nullptr); + + private: + static constexpr uint8_t swapChainTextureNum = 2; + static GraphicsWindowDesc GetGraphicsWindowDesc(); + + Common::UniquePtr imageReadySemaphore; + Common::UniquePtr renderFinishedSemaphore; + Common::UniquePtr frameFence; + std::array swapChainTextures; + std::array, 2> swapChainTextureViews; + }; + + class GraphicsWindowSampleWidget final : public QWidget { + Q_OBJECT + + public: + explicit GraphicsWindowSampleWidget(QWidget* inParent = nullptr); + + private: + GraphicsWindowSample* graphicsWindow; + QWidget* graphicsWindowContainer; + QVBoxLayout* mainLayout; + }; +} diff --git a/Editor/Src/Main.cpp b/Editor/Src/Main.cpp index b29755c3c..a1f20a0f3 100644 --- a/Editor/Src/Main.cpp +++ b/Editor/Src/Main.cpp @@ -10,6 +10,12 @@ #include #if BUILD_CONFIG_DEBUG +#include + +static ::Core::CmdlineArgValue caGraphicsWindowSample( + "graphicsSample", "-graphicsSample", false, + "Whether to run graphics sample instead of editor"); + static ::Core::CmdlineArgValue caRunSample( "widgetSamples", "-widgetSamples", false, "Whether to run widget samples instead of editor"); @@ -54,7 +60,9 @@ int main(int argc, char* argv[]) Common::UniquePtr mainWidget; #if BUILD_CONFIG_DEBUG - if (caRunSample.GetValue()) { + if (caGraphicsWindowSample.GetValue()) { + mainWidget = new Editor::GraphicsWindowSampleWidget(); + } else if (caRunSample.GetValue()) { mainWidget = new Editor::WidgetSamples(); } else #endif diff --git a/Editor/Src/Widget/GraphicsWindow.cpp b/Editor/Src/Widget/GraphicsWindow.cpp new file mode 100644 index 000000000..2bf485da7 --- /dev/null +++ b/Editor/Src/Widget/GraphicsWindow.cpp @@ -0,0 +1,71 @@ +// +// Created by Kindem on 2025/3/16. +// + +#include +#include + +namespace Editor { + GraphicsWindow::GraphicsWindow(const GraphicsWindowDesc& inDesc, QWindow* inParent) + : QWindow(inParent) + , textureNum(inDesc.textureNum) + { + const Render::RenderModule& renderModule = Core::ModuleManager::Get().GetTyped("Render"); + device = renderModule.GetDevice(); + Assert(device != nullptr); + + surface = device->CreateSurface( + RHI::SurfaceCreateInfo() + .SetWindow(reinterpret_cast(winId()))); // NOLINT + + pixelFormat = RHI::PixelFormat::max; + for (const auto format : inDesc.formatQualifiers) { + if (device->CheckSwapChainFormatSupport(surface.Get(), format)) { + pixelFormat = format; + break; + } + } + + swapChain = device->CreateSwapChain( + RHI::SwapChainCreateInfo() + .SetPresentQueue(device->GetQueue(RHI::QueueType::graphics, 0)) + .SetSurface(surface.Get()) + .SetTextureNum(inDesc.textureNum) + .SetFormat(pixelFormat) + .SetWidth(width()) + .SetHeight(height()) + .SetPresentMode(inDesc.presentMode)); + } + + GraphicsWindow::~GraphicsWindow() + { + const Common::UniquePtr fence = device->CreateFence(false); + device->GetQueue(RHI::QueueType::graphics, 0)->Flush(fence.Get()); + fence->Wait(); + } + + uint8_t GraphicsWindow::GetTextureNum() const + { + return textureNum; + } + + RHI::PixelFormat GraphicsWindow::GetPixelFormat() const + { + return pixelFormat; + } + + RHI::Device& GraphicsWindow::GetDevice() const + { + return *device; + } + + RHI::Surface& GraphicsWindow::GetSurface() const + { + return *surface; + } + + RHI::SwapChain& GraphicsWindow::GetSwapChain() const + { + return *swapChain; + } +} // namespace Editor diff --git a/Editor/Src/Widget/GraphicsWindowSample.cpp b/Editor/Src/Widget/GraphicsWindowSample.cpp new file mode 100644 index 000000000..0dcde91ca --- /dev/null +++ b/Editor/Src/Widget/GraphicsWindowSample.cpp @@ -0,0 +1,50 @@ +// +// Created by Kindem on 2025/3/16. +// + +#include +#include + +namespace Editor { + GraphicsWindowSample::GraphicsWindowSample(QWindow* inParent) + : GraphicsWindow(GetGraphicsWindowDesc(), inParent) + , imageReadySemaphore(GetDevice().CreateSemaphore()) + , renderFinishedSemaphore(GetDevice().CreateSemaphore()) + , frameFence(GetDevice().CreateFence(true)) + { + for (auto i = 0; i < swapChainTextureNum; i++) { + swapChainTextures[i] = GetSwapChain().GetTexture(i); + swapChainTextureViews[i] = swapChainTextures[i]->CreateTextureView( + RHI::TextureViewCreateInfo() + .SetDimension(RHI::TextureViewDimension::tv2D) + .SetMipLevels(0, 1) + .SetArrayLayers(0, 1) + .SetAspect(RHI::TextureAspect::color) + .SetType(RHI::TextureViewType::colorAttachment)); + } + } + + GraphicsWindowDesc GraphicsWindowSample::GetGraphicsWindowDesc() + { + GraphicsWindowDesc result; + result.textureNum = swapChainTextureNum; + result.formatQualifiers = { RHI::PixelFormat::rgba8Unorm, RHI::PixelFormat::bgra8Unorm }; + result.presentMode = RHI::PresentMode::immediately; + return result; + } + + GraphicsWindowSampleWidget::GraphicsWindowSampleWidget(QWidget* inParent) + : QWidget(inParent) + , graphicsWindow(new GraphicsWindowSample()) + { + graphicsWindowContainer = createWindowContainer(graphicsWindow); + graphicsWindowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + graphicsWindowContainer->show(); + + mainLayout = new QVBoxLayout(); + setLayout(mainLayout); + + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->addWidget(graphicsWindowContainer); + } +} // namespace Editor From 0c50d8ca31d3e58be077c6e3c6be8184864b4a05 Mon Sep 17 00:00:00 2001 From: FlyAntNotDown <461425614@qq.com> Date: Sun, 16 Mar 2025 22:56:01 +0800 Subject: [PATCH 3/6] refactor: update rhi & render sample shaders --- Engine/Shader/{Platform.h => Platform.esh} | 0 Engine/Source/RHI-Vulkan/Src/VmaImport.cpp | 2 +- Sample/CMakeLists.txt | 17 ++++++++--------- .../{Compute.hlsl => Compute.esl} | 2 +- .../RHI-ParallelCompute/ParallelCompute.cpp | 2 +- Sample/RHI-SSAO/SSAOApplication.cpp | 19 ++++++++++--------- .../RHI-SSAO/Shader/{Blur.hlsl => Blur.esl} | 2 +- .../{Composition.hlsl => Composition.esl} | 2 +- .../Shader/{Gbuffer.hlsl => Gbuffer.esl} | 2 +- .../RHI-SSAO/Shader/{SSAO.hlsl => SSAO.esl} | 2 +- Sample/RHI-TexSampling/TexSampling.cpp | 4 ++-- .../{TexSampling.hlsl => TexSampling.esl} | 2 +- Sample/RHI-Triangle/Triangle.cpp | 4 ++-- .../{Triangle.hlsl => Triangle.esl} | 2 +- 14 files changed, 31 insertions(+), 31 deletions(-) rename Engine/Shader/{Platform.h => Platform.esh} (100%) rename Sample/RHI-ParallelCompute/{Compute.hlsl => Compute.esl} (94%) rename Sample/RHI-SSAO/Shader/{Blur.hlsl => Blur.esl} (97%) rename Sample/RHI-SSAO/Shader/{Composition.hlsl => Composition.esl} (98%) rename Sample/RHI-SSAO/Shader/{Gbuffer.hlsl => Gbuffer.esl} (98%) rename Sample/RHI-SSAO/Shader/{SSAO.hlsl => SSAO.esl} (98%) rename Sample/RHI-TexSampling/{TexSampling.hlsl => TexSampling.esl} (96%) rename Sample/RHI-Triangle/{Triangle.hlsl => Triangle.esl} (95%) diff --git a/Engine/Shader/Platform.h b/Engine/Shader/Platform.esh similarity index 100% rename from Engine/Shader/Platform.h rename to Engine/Shader/Platform.esh diff --git a/Engine/Source/RHI-Vulkan/Src/VmaImport.cpp b/Engine/Source/RHI-Vulkan/Src/VmaImport.cpp index cd298aac2..438b034ad 100644 --- a/Engine/Source/RHI-Vulkan/Src/VmaImport.cpp +++ b/Engine/Source/RHI-Vulkan/Src/VmaImport.cpp @@ -3,4 +3,4 @@ // #define VMA_IMPLEMENTATION -#include "vk_mem_alloc.h" +#include diff --git a/Sample/CMakeLists.txt b/Sample/CMakeLists.txt index 0d2461dae..6c1a5f20f 100644 --- a/Sample/CMakeLists.txt +++ b/Sample/CMakeLists.txt @@ -22,8 +22,7 @@ function(AddSample) list(APPEND PATHS ${path}) endforeach() - list(APPEND PATHS "${CMAKE_SOURCE_DIR}/Engine/Shader/Platform.h->../Test/Sample/ShaderInclude/Platform.h") - list(APPEND PATHS "${CMAKE_SOURCE_DIR}/Engine/Shader/Platform.h->../Test/Sample/ShaderInclude/Platform.esh") + list(APPEND PATHS "${CMAKE_SOURCE_DIR}/Engine/Shader/Platform.esh->../Test/Sample/ShaderInclude/Platform.esh") AddExecutable( SAMPLE @@ -56,7 +55,7 @@ AddSample( NAME RHISample-Triangle SRC ${SOURCES} INC RHI-Triangle - SHADER RHI-Triangle/Triangle.hlsl + SHADER RHI-Triangle/Triangle.esl ) file(GLOB SOURCES RHI-TexSampling/*.cpp) @@ -64,7 +63,7 @@ AddSample( NAME RHISample-TexSampling SRC ${SOURCES} INC RHI-TexSampling - SHADER RHI-TexSampling/TexSampling.hlsl + SHADER RHI-TexSampling/TexSampling.esl IMAGE RHI-TexSampling/Awesomeface.png ) @@ -74,10 +73,10 @@ AddSample( SRC ${SOURCES} INC RHI-SSAO SHADER - RHI-SSAO/Shader/Gbuffer.hlsl - RHI-SSAO/Shader/SSAO.hlsl - RHI-SSAO/Shader/Blur.hlsl - RHI-SSAO/Shader/Composition.hlsl + RHI-SSAO/Shader/Gbuffer.esl + RHI-SSAO/Shader/SSAO.esl + RHI-SSAO/Shader/Blur.esl + RHI-SSAO/Shader/Composition.esl MODEL RHI-SSAO/Model/Voyager.gltf ) @@ -86,7 +85,7 @@ file(GLOB SOURCES RHI-ParallelCompute/*.cpp) AddSample( NAME RHISample-ParallelCompute SRC ${SOURCES} - SHADER RHI-ParallelCompute/Compute.hlsl + SHADER RHI-ParallelCompute/Compute.esl ) file(GLOB SOURCES Rendering-Triangle/*.cpp) diff --git a/Sample/RHI-ParallelCompute/Compute.hlsl b/Sample/RHI-ParallelCompute/Compute.esl similarity index 94% rename from Sample/RHI-ParallelCompute/Compute.hlsl rename to Sample/RHI-ParallelCompute/Compute.esl index a4960ab96..3ed3054f1 100644 --- a/Sample/RHI-ParallelCompute/Compute.hlsl +++ b/Sample/RHI-ParallelCompute/Compute.esl @@ -1,4 +1,4 @@ -#include +#include // spir-v treat vec2 and vec4 as built-in type? struct Data { diff --git a/Sample/RHI-ParallelCompute/ParallelCompute.cpp b/Sample/RHI-ParallelCompute/ParallelCompute.cpp index be060f611..8af4ff121 100644 --- a/Sample/RHI-ParallelCompute/ParallelCompute.cpp +++ b/Sample/RHI-ParallelCompute/ParallelCompute.cpp @@ -133,7 +133,7 @@ class ParallelCompute final : public Application { void DealWithPipelineBindingOBjs() { - csOutPut = CompileShader("../Test/Sample/RHI-ParallelCompute/Compute.hlsl", "CSMain", ShaderStageBits::sCompute); + csOutPut = CompileShader("../Test/Sample/RHI-ParallelCompute/Compute.esl", "CSMain", ShaderStageBits::sCompute); auto shaderModuleCreateInfo = ShaderModuleCreateInfo("CSMain", csOutPut.byteCode); csShaderModule = device->CreateShaderModule(shaderModuleCreateInfo); diff --git a/Sample/RHI-SSAO/SSAOApplication.cpp b/Sample/RHI-SSAO/SSAOApplication.cpp index ca8cdc2bc..c8b0f64de 100644 --- a/Sample/RHI-SSAO/SSAOApplication.cpp +++ b/Sample/RHI-SSAO/SSAOApplication.cpp @@ -6,8 +6,9 @@ #include #include +#include + #include -#include "GLTFParser.h" using namespace RHI; @@ -538,14 +539,14 @@ class SSAOApplication final : public Application { void CreateShaderModules() { - CompileShaderAndCreateShaderModule(shaderObjects.gBufferVs, shaderObjects.gBufferVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Gbuffer.hlsl", "VSMain", ShaderStageBits::sVertex); - CompileShaderAndCreateShaderModule(shaderObjects.gBufferPs, shaderObjects.gBufferPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Gbuffer.hlsl", "PSMain", ShaderStageBits::sPixel); - CompileShaderAndCreateShaderModule(shaderObjects.ssaoVs, shaderObjects.ssaoVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/SSAO.hlsl", "VSMain", ShaderStageBits::sVertex); - CompileShaderAndCreateShaderModule(shaderObjects.ssaoPs, shaderObjects.ssaoPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/SSAO.hlsl", "PSMain", ShaderStageBits::sPixel); - CompileShaderAndCreateShaderModule(shaderObjects.ssaoBlurVs, shaderObjects.ssaoBlurVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Blur.hlsl", "VSMain", ShaderStageBits::sVertex); - CompileShaderAndCreateShaderModule(shaderObjects.ssaoBlurPs, shaderObjects.ssaoBlurPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Blur.hlsl", "PSMain", ShaderStageBits::sPixel); - CompileShaderAndCreateShaderModule(shaderObjects.compositionVs, shaderObjects.compositionVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Composition.hlsl", "VSMain", ShaderStageBits::sVertex); - CompileShaderAndCreateShaderModule(shaderObjects.compositionPs, shaderObjects.compositionPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Composition.hlsl", "PSMain", ShaderStageBits::sPixel); + CompileShaderAndCreateShaderModule(shaderObjects.gBufferVs, shaderObjects.gBufferVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Gbuffer.esl", "VSMain", ShaderStageBits::sVertex); + CompileShaderAndCreateShaderModule(shaderObjects.gBufferPs, shaderObjects.gBufferPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Gbuffer.esl", "PSMain", ShaderStageBits::sPixel); + CompileShaderAndCreateShaderModule(shaderObjects.ssaoVs, shaderObjects.ssaoVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/SSAO.esl", "VSMain", ShaderStageBits::sVertex); + CompileShaderAndCreateShaderModule(shaderObjects.ssaoPs, shaderObjects.ssaoPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/SSAO.esl", "PSMain", ShaderStageBits::sPixel); + CompileShaderAndCreateShaderModule(shaderObjects.ssaoBlurVs, shaderObjects.ssaoBlurVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Blur.esl", "VSMain", ShaderStageBits::sVertex); + CompileShaderAndCreateShaderModule(shaderObjects.ssaoBlurPs, shaderObjects.ssaoBlurPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Blur.esl", "PSMain", ShaderStageBits::sPixel); + CompileShaderAndCreateShaderModule(shaderObjects.compositionVs, shaderObjects.compositionVsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Composition.esl", "VSMain", ShaderStageBits::sVertex); + CompileShaderAndCreateShaderModule(shaderObjects.compositionPs, shaderObjects.compositionPsCompileOutput, "../Test/Sample/RHI-SSAO/Shader/Composition.esl", "PSMain", ShaderStageBits::sPixel); } void CreateSampler() diff --git a/Sample/RHI-SSAO/Shader/Blur.hlsl b/Sample/RHI-SSAO/Shader/Blur.esl similarity index 97% rename from Sample/RHI-SSAO/Shader/Blur.hlsl rename to Sample/RHI-SSAO/Shader/Blur.esl index b35fa638c..369e2cf57 100644 --- a/Sample/RHI-SSAO/Shader/Blur.hlsl +++ b/Sample/RHI-SSAO/Shader/Blur.esl @@ -1,4 +1,4 @@ -#include +#include VkBinding(0, 0) Texture2D ssaoTex : register(t0); VkBinding(1, 0) SamplerState ssaoSampler : register(s0); diff --git a/Sample/RHI-SSAO/Shader/Composition.hlsl b/Sample/RHI-SSAO/Shader/Composition.esl similarity index 98% rename from Sample/RHI-SSAO/Shader/Composition.hlsl rename to Sample/RHI-SSAO/Shader/Composition.esl index 47faa373c..3b093ffbe 100644 --- a/Sample/RHI-SSAO/Shader/Composition.hlsl +++ b/Sample/RHI-SSAO/Shader/Composition.esl @@ -1,4 +1,4 @@ -#include +#include VkBinding(0, 0) Texture2D posTex : register(t0); VkBinding(1, 0) Texture2D normalTex : register(t1); diff --git a/Sample/RHI-SSAO/Shader/Gbuffer.hlsl b/Sample/RHI-SSAO/Shader/Gbuffer.esl similarity index 98% rename from Sample/RHI-SSAO/Shader/Gbuffer.hlsl rename to Sample/RHI-SSAO/Shader/Gbuffer.esl index a6e2bfbc0..e60e535c1 100644 --- a/Sample/RHI-SSAO/Shader/Gbuffer.hlsl +++ b/Sample/RHI-SSAO/Shader/Gbuffer.esl @@ -1,4 +1,4 @@ -#include +#include VkBinding(0, 0) cbuffer passParams : register(b0) { diff --git a/Sample/RHI-SSAO/Shader/SSAO.hlsl b/Sample/RHI-SSAO/Shader/SSAO.esl similarity index 98% rename from Sample/RHI-SSAO/Shader/SSAO.hlsl rename to Sample/RHI-SSAO/Shader/SSAO.esl index 50cc38ce2..8fd4ab122 100644 --- a/Sample/RHI-SSAO/Shader/SSAO.hlsl +++ b/Sample/RHI-SSAO/Shader/SSAO.esl @@ -1,4 +1,4 @@ -#include +#include VkBinding(0, 0) Texture2D posDepthTex : register(t0); VkBinding(1, 0) Texture2D normalTex : register(t1); diff --git a/Sample/RHI-TexSampling/TexSampling.cpp b/Sample/RHI-TexSampling/TexSampling.cpp index bcf13dbd9..986c4402c 100644 --- a/Sample/RHI-TexSampling/TexSampling.cpp +++ b/Sample/RHI-TexSampling/TexSampling.cpp @@ -301,10 +301,10 @@ class TexSamplingApplication final : public Application { void CreateShaderModules() { - vsCompileOutput = CompileShader("../Test/Sample/RHI-TexSampling/TexSampling.hlsl", "VSMain", ShaderStageBits::sVertex); + vsCompileOutput = CompileShader("../Test/Sample/RHI-TexSampling/TexSampling.esl", "VSMain", ShaderStageBits::sVertex); vertexShader = device->CreateShaderModule(ShaderModuleCreateInfo("VSMain", vsCompileOutput.byteCode)); - psCompileOutput = CompileShader("../Test/Sample/RHI-TexSampling/TexSampling.hlsl", "PSMain", ShaderStageBits::sPixel); + psCompileOutput = CompileShader("../Test/Sample/RHI-TexSampling/TexSampling.esl", "PSMain", ShaderStageBits::sPixel); pixelShader = device->CreateShaderModule(ShaderModuleCreateInfo("PSMain", psCompileOutput.byteCode)); } diff --git a/Sample/RHI-TexSampling/TexSampling.hlsl b/Sample/RHI-TexSampling/TexSampling.esl similarity index 96% rename from Sample/RHI-TexSampling/TexSampling.hlsl rename to Sample/RHI-TexSampling/TexSampling.esl index fec462c03..92967bf10 100644 --- a/Sample/RHI-TexSampling/TexSampling.hlsl +++ b/Sample/RHI-TexSampling/TexSampling.esl @@ -1,4 +1,4 @@ -#include +#include VkBinding(0, 0) Texture2D colorTex : register(t0); VkBinding(1, 0) SamplerState colorSampler : register(s0); diff --git a/Sample/RHI-Triangle/Triangle.cpp b/Sample/RHI-Triangle/Triangle.cpp index 3385bbd4b..a9619100c 100644 --- a/Sample/RHI-Triangle/Triangle.cpp +++ b/Sample/RHI-Triangle/Triangle.cpp @@ -170,10 +170,10 @@ class TriangleApplication final : public Application { void CreatePipeline() { - vsCompileOutput = CompileShader("../Test/Sample/RHI-Triangle/Triangle.hlsl", "VSMain", RHI::ShaderStageBits::sVertex); + vsCompileOutput = CompileShader("../Test/Sample/RHI-Triangle/Triangle.esl", "VSMain", RHI::ShaderStageBits::sVertex); vertexShader = device->CreateShaderModule(ShaderModuleCreateInfo("VSMain", vsCompileOutput.byteCode)); - psCompileOutput = CompileShader("../Test/Sample/RHI-Triangle/Triangle.hlsl", "PSMain", RHI::ShaderStageBits::sPixel); + psCompileOutput = CompileShader("../Test/Sample/RHI-Triangle/Triangle.esl", "PSMain", RHI::ShaderStageBits::sPixel); pixelShader = device->CreateShaderModule(ShaderModuleCreateInfo("PSMain", psCompileOutput.byteCode)); RasterPipelineCreateInfo createInfo = RasterPipelineCreateInfo(pipelineLayout.Get()) diff --git a/Sample/RHI-Triangle/Triangle.hlsl b/Sample/RHI-Triangle/Triangle.esl similarity index 95% rename from Sample/RHI-Triangle/Triangle.hlsl rename to Sample/RHI-Triangle/Triangle.esl index 6b0162b84..e3832dbd5 100644 --- a/Sample/RHI-Triangle/Triangle.hlsl +++ b/Sample/RHI-Triangle/Triangle.esl @@ -1,4 +1,4 @@ -#include +#include struct FragmentInput { float4 position : SV_POSITION; From bb119af8a818fa5a761dd2aa52641d78a5e82a61 Mon Sep 17 00:00:00 2001 From: John Kindem <461425614@qq.com> Date: Mon, 17 Mar 2025 21:38:00 +0800 Subject: [PATCH 4/6] feat: graphics window sample basics --- Editor/CMakeLists.txt | 22 ++ .../Editor/Widget/GraphicsSampleWidget.h | 50 +++++ Editor/Include/Editor/Widget/GraphicsWidget.h | 55 +++++ Editor/Include/Editor/Widget/GraphicsWindow.h | 41 ---- .../Editor/Widget/GraphicsWindowSample.h | 41 ---- Editor/Shader/GraphicsWindowSample.esl | 34 +++ Editor/Src/Main.cpp | 12 +- Editor/Src/Widget/GraphicsSampleWidget.cpp | 204 ++++++++++++++++++ Editor/Src/Widget/GraphicsWidget.cpp | 142 ++++++++++++ Editor/Src/Widget/GraphicsWindow.cpp | 71 ------ Editor/Src/Widget/GraphicsWindowSample.cpp | 50 ----- Engine/CMakeLists.txt | 13 ++ Engine/Source/Core/Include/Core/Cmdline.h | 16 +- Engine/Source/Core/Src/Cmdline.cpp | 2 +- .../Include/RHI/DirectX12/Device.h | 4 +- .../RHI-DirectX12/Include/RHI/DirectX12/Gpu.h | 5 +- Engine/Source/RHI-DirectX12/Src/Device.cpp | 10 +- .../RHI-Dummy/Include/RHI/Dummy/Device.h | 7 +- .../Source/RHI-Dummy/Include/RHI/Dummy/Gpu.h | 7 +- Engine/Source/RHI-Dummy/Src/Device.cpp | 8 +- Engine/Source/RHI-Dummy/Src/Gpu.cpp | 12 +- Engine/Source/RHI-Dummy/Src/Instance.cpp | 2 +- .../RHI-Vulkan/Include/RHI/Vulkan/Device.h | 4 +- .../RHI-Vulkan/Include/RHI/Vulkan/Gpu.h | 5 +- Engine/Source/RHI-Vulkan/Src/Device.cpp | 10 +- Engine/Source/RHI-Vulkan/Src/Gpu.cpp | 8 +- Engine/Source/RHI-Vulkan/Src/SwapChain.cpp | 7 +- Engine/Source/RHI/Include/RHI/Device.h | 2 + Engine/Source/RHI/Include/RHI/Gpu.h | 2 + 29 files changed, 595 insertions(+), 251 deletions(-) create mode 100644 Editor/Include/Editor/Widget/GraphicsSampleWidget.h create mode 100644 Editor/Include/Editor/Widget/GraphicsWidget.h delete mode 100644 Editor/Include/Editor/Widget/GraphicsWindow.h delete mode 100644 Editor/Include/Editor/Widget/GraphicsWindowSample.h create mode 100644 Editor/Shader/GraphicsWindowSample.esl create mode 100644 Editor/Src/Widget/GraphicsSampleWidget.cpp create mode 100644 Editor/Src/Widget/GraphicsWidget.cpp delete mode 100644 Editor/Src/Widget/GraphicsWindow.cpp delete mode 100644 Editor/Src/Widget/GraphicsWindowSample.cpp diff --git a/Editor/CMakeLists.txt b/Editor/CMakeLists.txt index 2b87c96a0..da68c6a5c 100644 --- a/Editor/CMakeLists.txt +++ b/Editor/CMakeLists.txt @@ -28,6 +28,27 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows") ) endif () +# ---- begin shaders --------------------------------------------------------------------------------- +GetEngineShaderResources( + NAME Editor + OUTPUT EDITOR_RESOURCES +) + +file(GLOB_RECURSE SHADERS Shader/*.es*) +foreach (SHADER ${SHADERS}) + get_filename_component(SHADER_ABSOLUTE ${SHADER} ABSOLUTE) + string(REPLACE ${CMAKE_CURRENT_SOURCE_DIR}/Shader ../Shader/Editor COPY_DST ${SHADER_ABSOLUTE}) + list(APPEND EDITOR_RESOURCES ${SHADER}->${COPY_DST}) +endforeach () + +AddResourcesCopyCommand( + NAME Editor + RES ${EDITOR_RESOURCES} +) +# ---- end shaders ----------------------------------------------------------------------------------- + + +# ---- begin qml ------------------------------------------------------------------------------------- set(EDITOR_QML_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/Qml) set(EDITOR_RESOURCE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/Qml/Resource) get_filename_component(EDITOR_RESOURCE_ROOT_ABSOLUTE ${EDITOR_RESOURCE_ROOT} ABSOLUTE) @@ -62,3 +83,4 @@ qt_add_qml_module( RESOURCES ${RESOURCES} OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Generated/QmlModule ) +# ---- end qml --------------------------------------------------------------------------------------- diff --git a/Editor/Include/Editor/Widget/GraphicsSampleWidget.h b/Editor/Include/Editor/Widget/GraphicsSampleWidget.h new file mode 100644 index 000000000..2a6f53dbe --- /dev/null +++ b/Editor/Include/Editor/Widget/GraphicsSampleWidget.h @@ -0,0 +1,50 @@ +// +// Created by Kindem on 2025/3/16. +// + +#pragma once + +#include +#include + +#include +#include + +namespace Editor { + class GraphicsSampleWidget final : public GraphicsWidget { + Q_OBJECT + + public: + explicit GraphicsSampleWidget(QWidget* inParent = nullptr); + ~GraphicsSampleWidget() override; + + protected: + void resizeEvent(QResizeEvent* event) override; + void OnDrawFrame() override; + + private: + static constexpr uint8_t swapChainTextureNum = 2; + static GraphicsWidgetDesc GetGraphicsWidgetDesc(); + + void FetchSwapChainTextures(); + + Common::UniquePtr imageReadySemaphore; + Common::UniquePtr renderFinishedSemaphore; + Common::UniquePtr frameFence; + std::array swapChainTextures; + std::array, 2> swapChainTextureViews; + Render::ShaderCompileOutput vsCompileOutput; + Render::ShaderCompileOutput psCompileOutput; + Common::UniquePtr vsModule; + Common::UniquePtr psModule; + Common::UniquePtr bindGroupLayout; + Common::UniquePtr pipelineLayout; + Common::UniquePtr pipeline; + Common::UniquePtr vertexBuffer; + Common::UniquePtr vertexBufferView; + Common::UniquePtr uniformBuffer; + Common::UniquePtr uniformBufferView; + Common::UniquePtr bindGroup; + Common::UniquePtr commandBuffer; + }; +} diff --git a/Editor/Include/Editor/Widget/GraphicsWidget.h b/Editor/Include/Editor/Widget/GraphicsWidget.h new file mode 100644 index 000000000..76d516dd2 --- /dev/null +++ b/Editor/Include/Editor/Widget/GraphicsWidget.h @@ -0,0 +1,55 @@ +// +// Created by Kindem on 2025/3/16. +// + +#pragma once + +#include +#include + +#include +#include + +namespace Editor { + struct GraphicsWidgetDesc { + uint8_t textureNum; + std::vector formatQualifiers; + RHI::PresentMode presentMode; + }; + + class GraphicsWidget : public QWidget { + Q_OBJECT + + public: + explicit GraphicsWidget(const GraphicsWidgetDesc& inDesc, QWidget* inParent = nullptr); + ~GraphicsWidget() override; + + uint8_t GetTextureNum() const; + RHI::PixelFormat GetPixelFormat() const; + RHI::PresentMode GetPresentMode() const; + RHI::Device& GetDevice() const; + RHI::Surface& GetSurface() const; + RHI::SwapChain& GetSwapChain() const; + + protected: + QPaintEngine* paintEngine() const override; + void resizeEvent(QResizeEvent* event) override; + + virtual void OnDrawFrame(); + void WaitDeviceIdle() const; + double GetLastTimeSeconds() const; + double GetCurrentTimeSeconds() const; + float GetDeltaTimeSeconds() const; + + uint8_t textureNum; + RHI::PixelFormat pixelFormat; + RHI::PresentMode presentMode; + RHI::Device* device; + Common::UniquePtr surface; + Common::UniquePtr swapChain; + QTimer* timer; + double lastTimeSeconds; + double currentTimeSeconds; + float deltaTimeSeconds; + }; +} diff --git a/Editor/Include/Editor/Widget/GraphicsWindow.h b/Editor/Include/Editor/Widget/GraphicsWindow.h deleted file mode 100644 index 7fce51be4..000000000 --- a/Editor/Include/Editor/Widget/GraphicsWindow.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by Kindem on 2025/3/16. -// - -#pragma once - -#include - -#include -#include - -namespace Editor { - struct GraphicsWindowDesc { - uint8_t textureNum; - std::vector formatQualifiers; - RHI::PresentMode presentMode; - }; - - class GraphicsWindow : public QWindow { - Q_OBJECT - - public: - explicit GraphicsWindow(const GraphicsWindowDesc& inDesc, QWindow* inParent = nullptr); - ~GraphicsWindow() override; - - uint8_t GetTextureNum() const; - RHI::PixelFormat GetPixelFormat() const; - RHI::Device& GetDevice() const; - RHI::Surface& GetSurface() const; - RHI::SwapChain& GetSwapChain() const; - - // TODO auto resize - - private: - uint8_t textureNum; - RHI::PixelFormat pixelFormat; - RHI::Device* device; - Common::UniquePtr surface; - Common::UniquePtr swapChain; - }; -} diff --git a/Editor/Include/Editor/Widget/GraphicsWindowSample.h b/Editor/Include/Editor/Widget/GraphicsWindowSample.h deleted file mode 100644 index facbb0da2..000000000 --- a/Editor/Include/Editor/Widget/GraphicsWindowSample.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Created by Kindem on 2025/3/16. -// - -#pragma once - -#include -#include - -#include - -namespace Editor { - class GraphicsWindowSample final : public GraphicsWindow { - Q_OBJECT - - public: - explicit GraphicsWindowSample(QWindow* inParent = nullptr); - - private: - static constexpr uint8_t swapChainTextureNum = 2; - static GraphicsWindowDesc GetGraphicsWindowDesc(); - - Common::UniquePtr imageReadySemaphore; - Common::UniquePtr renderFinishedSemaphore; - Common::UniquePtr frameFence; - std::array swapChainTextures; - std::array, 2> swapChainTextureViews; - }; - - class GraphicsWindowSampleWidget final : public QWidget { - Q_OBJECT - - public: - explicit GraphicsWindowSampleWidget(QWidget* inParent = nullptr); - - private: - GraphicsWindowSample* graphicsWindow; - QWidget* graphicsWindowContainer; - QVBoxLayout* mainLayout; - }; -} diff --git a/Editor/Shader/GraphicsWindowSample.esl b/Editor/Shader/GraphicsWindowSample.esl new file mode 100644 index 000000000..384503904 --- /dev/null +++ b/Editor/Shader/GraphicsWindowSample.esl @@ -0,0 +1,34 @@ +#include + +struct FragmentInput { + float4 position : SV_POSITION; + float4 color : COLOR; +}; + +#if VERTEX_SHADER +cbuffer vsUniform { + float3 vertexColor; +}; + +FragmentInput VSMain( + uint vertexId : SV_VertexID, + VkLocation(0) float3 position : POSITION) +{ + FragmentInput fragmentInput; + fragmentInput.position = float4(position.xyz, 1.0f); +#if VULKAN + fragmentInput.position.y = - fragmentInput.position.y; +#endif + + fragmentInput.color = float4(0.0f, 0.0f, 0.0f, 1.0f); + fragmentInput.color[vertexId % 3] = vertexColor[vertexId % 3]; + return fragmentInput; +} +#endif + +#if PIXEL_SHADER +float4 PSMain(FragmentInput input) : SV_TARGET +{ + return input.color; +} +#endif diff --git a/Editor/Src/Main.cpp b/Editor/Src/Main.cpp index a1f20a0f3..1629a2eb8 100644 --- a/Editor/Src/Main.cpp +++ b/Editor/Src/Main.cpp @@ -10,22 +10,22 @@ #include #if BUILD_CONFIG_DEBUG -#include +#include -static ::Core::CmdlineArgValue caGraphicsWindowSample( +static Core::CmdlineArgValue caGraphicsWindowSample( "graphicsSample", "-graphicsSample", false, "Whether to run graphics sample instead of editor"); -static ::Core::CmdlineArgValue caRunSample( +static Core::CmdlineArgValue caRunSample( "widgetSamples", "-widgetSamples", false, "Whether to run widget samples instead of editor"); #endif -static ::Core::CmdlineArgValue caRhiType( +static Core::CmdlineArgValue caRhiType( "rhiType", "-rhi", RHI::GetPlatformDefaultRHIAbbrString(), "rhi abbr string, can be 'dx12' or 'vulkan'"); -static ::Core::CmdlineArgValue caProjectRoot( +static Core::CmdlineArgValue caProjectRoot( "projectRoot", "-project", "", "project root path"); @@ -61,7 +61,7 @@ int main(int argc, char* argv[]) Common::UniquePtr mainWidget; #if BUILD_CONFIG_DEBUG if (caGraphicsWindowSample.GetValue()) { - mainWidget = new Editor::GraphicsWindowSampleWidget(); + mainWidget = new Editor::GraphicsSampleWidget(); } else if (caRunSample.GetValue()) { mainWidget = new Editor::WidgetSamples(); } else diff --git a/Editor/Src/Widget/GraphicsSampleWidget.cpp b/Editor/Src/Widget/GraphicsSampleWidget.cpp new file mode 100644 index 000000000..df9d4ec42 --- /dev/null +++ b/Editor/Src/Widget/GraphicsSampleWidget.cpp @@ -0,0 +1,204 @@ +// +// Created by Kindem on 2025/3/16. +// + +#include +#include // NOLINT + +namespace Editor { + struct GraphicsWindowSampleVertex { + Common::FVec3 position; + }; + + struct GraphicsWindowSampleVsUniform { + Common::FVec3 color; + }; + + GraphicsWidgetDesc GraphicsSampleWidget::GetGraphicsWidgetDesc() + { + GraphicsWidgetDesc result; + result.textureNum = swapChainTextureNum; + result.formatQualifiers = {RHI::PixelFormat::rgba8Unorm, RHI::PixelFormat::bgra8Unorm}; + result.presentMode = RHI::PresentMode::immediately; + return result; + } + + GraphicsSampleWidget::GraphicsSampleWidget(QWidget* inParent) + : GraphicsWidget(GetGraphicsWidgetDesc(), inParent) + , imageReadySemaphore(GetDevice().CreateSemaphore()) + , renderFinishedSemaphore(GetDevice().CreateSemaphore()) + , frameFence(GetDevice().CreateFence(true)) + { + setFixedWidth(1024); + setFixedHeight(768); + + FetchSwapChainTextures(); + + Render::ShaderCompileOptions shaderCompileOptions; + shaderCompileOptions.includePaths = {"../Shader/Engine"}; + shaderCompileOptions.byteCodeType = GetDevice().GetGpu().GetInstance().GetRHIType() == RHI::RHIType::directX12 ? Render::ShaderByteCodeType::dxil : Render::ShaderByteCodeType::spirv; + shaderCompileOptions.withDebugInfo = static_cast(BUILD_CONFIG_DEBUG); + + { + Render::ShaderCompileInput shaderCompileInput; + shaderCompileInput.source = Common::FileUtils::ReadTextFile("../Shader/Editor/GraphicsWindowSample.esl"); + shaderCompileInput.stage = RHI::ShaderStageBits::sVertex; + shaderCompileInput.entryPoint = "VSMain"; + vsCompileOutput = Render::ShaderCompiler::Get().Compile(shaderCompileInput, shaderCompileOptions).get(); + } + + { + Render::ShaderCompileInput shaderCompileInput; + shaderCompileInput.source = Common::FileUtils::ReadTextFile("../Shader/Editor/GraphicsWindowSample.esl"); + shaderCompileInput.stage = RHI::ShaderStageBits::sPixel; + shaderCompileInput.entryPoint = "PSMain"; + psCompileOutput = Render::ShaderCompiler::Get().Compile(shaderCompileInput, shaderCompileOptions).get(); + } + + vsModule = GetDevice().CreateShaderModule(RHI::ShaderModuleCreateInfo("VSMain", vsCompileOutput.byteCode)); + psModule = GetDevice().CreateShaderModule(RHI::ShaderModuleCreateInfo("PSMain", psCompileOutput.byteCode)); + + bindGroupLayout = GetDevice().CreateBindGroupLayout( + RHI::BindGroupLayoutCreateInfo(0) + .AddEntry(RHI::BindGroupLayoutEntry(vsCompileOutput.reflectionData.QueryResourceBindingChecked("vsUniform").second, RHI::ShaderStageBits::sVertex))); + + pipelineLayout = GetDevice().CreatePipelineLayout( + RHI::PipelineLayoutCreateInfo() + .AddBindGroupLayout(bindGroupLayout.Get())); + + pipeline = GetDevice().CreateRasterPipeline( + RHI::RasterPipelineCreateInfo(pipelineLayout.Get()) + .SetVertexShader(vsModule.Get()) + .SetPixelShader(psModule.Get()) + .SetVertexState( + RHI::VertexState() + .AddVertexBufferLayout( + RHI::VertexBufferLayout(RHI::VertexStepMode::perVertex, sizeof(GraphicsWindowSampleVertex)) + .AddAttribute(RHI::VertexAttribute(vsCompileOutput.reflectionData.QueryVertexBindingChecked("POSITION"), RHI::VertexFormat::float32X3, 0)))) + .SetFragmentState( + RHI::FragmentState() + .AddColorTarget(RHI::ColorTargetState(swapChainTextures[0]->GetCreateInfo().format, RHI::ColorWriteBits::all))) + .SetPrimitiveState(RHI::PrimitiveState(RHI::PrimitiveTopologyType::triangle, RHI::FillMode::solid, RHI::IndexFormat::uint16, RHI::FrontFace::ccw, RHI::CullMode::none))); + + { + const std::vector vertices = { + {{-.5f, -.5f, 0.f}}, + {{.5f, -.5f, 0.f}}, + {{0.f, .5f, 0.f}}, + }; + const auto bufferSize = vertices.size() * sizeof(GraphicsWindowSampleVertex); + + vertexBuffer = GetDevice().CreateBuffer( + RHI::BufferCreateInfo() + .SetSize(bufferSize) + .SetUsages(RHI::BufferUsageBits::vertex | RHI::BufferUsageBits::mapWrite | RHI::BufferUsageBits::copySrc) + .SetInitialState(RHI::BufferState::staging) + .SetDebugName("vertexBuffer")); + + auto* data = vertexBuffer->Map(RHI::MapMode::write, 0, bufferSize); + memcpy(data, vertices.data(), bufferSize); + vertexBuffer->UnMap(); + + vertexBufferView = vertexBuffer->CreateBufferView( + RHI::BufferViewCreateInfo() + .SetType(RHI::BufferViewType::vertex) + .SetSize(bufferSize) + .SetOffset(0) + .SetExtendVertex(sizeof(GraphicsWindowSampleVertex))); + } + + { + uniformBuffer = GetDevice().CreateBuffer( + RHI::BufferCreateInfo() + .SetSize(sizeof(GraphicsWindowSampleVsUniform)) + .SetUsages(RHI::BufferUsageBits::uniform | RHI::BufferUsageBits::mapWrite | RHI::BufferUsageBits::copySrc) + .SetInitialState(RHI::BufferState::staging) + .SetDebugName("vsUniform")); + + uniformBufferView = uniformBuffer->CreateBufferView( + RHI::BufferViewCreateInfo() + .SetType(RHI::BufferViewType::uniformBinding) + .SetSize(sizeof(GraphicsWindowSampleVsUniform)) + .SetOffset(0)); + } + + bindGroup = GetDevice().CreateBindGroup( + RHI::BindGroupCreateInfo(bindGroupLayout.Get()) + .AddEntry(RHI::BindGroupEntry(vsCompileOutput.reflectionData.QueryResourceBindingChecked("vsUniform").second, uniformBufferView.Get()))); + + commandBuffer = GetDevice().CreateCommandBuffer(); + } + + GraphicsSampleWidget::~GraphicsSampleWidget() + { + WaitDeviceIdle(); + } + + void GraphicsSampleWidget::resizeEvent(QResizeEvent* event) + { + GraphicsWidget::resizeEvent(event); + + FetchSwapChainTextures(); + } + + void GraphicsSampleWidget::FetchSwapChainTextures() + { + for (auto i = 0; i < swapChainTextureNum; i++) { + swapChainTextures[i] = GetSwapChain().GetTexture(i); + swapChainTextureViews[i] = swapChainTextures[i]->CreateTextureView( + RHI::TextureViewCreateInfo() + .SetDimension(RHI::TextureViewDimension::tv2D) + .SetMipLevels(0, 1) + .SetArrayLayers(0, 1) + .SetAspect(RHI::TextureAspect::color) + .SetType(RHI::TextureViewType::colorAttachment)); + } + } + + void GraphicsSampleWidget::OnDrawFrame() + { + GraphicsWidget::OnDrawFrame(); + + frameFence->Wait(); + frameFence->Reset(); + + const double currentTimeSeconds = GetCurrentTimeSeconds(); + const GraphicsWindowSampleVsUniform uniform = {{ + (std::sin(currentTimeSeconds) + 1) / 2, + (std::cos(currentTimeSeconds) + 1) / 2, + std::abs(std::sin(currentTimeSeconds)) + }}; + auto* uniformData = uniformBuffer->Map(RHI::MapMode::write, 0, sizeof(GraphicsWindowSampleVsUniform)); + memcpy(uniformData, &uniform, sizeof(GraphicsWindowSampleVsUniform)); + uniformBuffer->UnMap(); + + const auto backTextureIndex = GetSwapChain().AcquireBackTexture(imageReadySemaphore.Get()); + const Common::UniquePtr commandRecorder = commandBuffer->Begin(); + { + commandRecorder->ResourceBarrier(RHI::Barrier::Transition(swapChainTextures[backTextureIndex], RHI::TextureState::present, RHI::TextureState::renderTarget)); + const Common::UniquePtr rasterRecorder = commandRecorder->BeginRasterPass( + RHI::RasterPassBeginInfo() + .AddColorAttachment(RHI::ColorAttachment(swapChainTextureViews[backTextureIndex].Get(), RHI::LoadOp::clear, RHI::StoreOp::store, Common::LinearColorConsts::black))); + { + rasterRecorder->SetPipeline(pipeline.Get()); + rasterRecorder->SetBindGroup(0, bindGroup.Get()); + rasterRecorder->SetScissor(0, 0, width(), height()); + rasterRecorder->SetViewport(0, 0, static_cast(width()), static_cast(height()), 0, 1); + rasterRecorder->SetPrimitiveTopology(RHI::PrimitiveTopology::triangleList); + rasterRecorder->SetVertexBuffer(0, vertexBufferView.Get()); + rasterRecorder->Draw(3, 1, 0, 0); + } + rasterRecorder->EndPass(); + commandRecorder->ResourceBarrier(RHI::Barrier::Transition(swapChainTextures[backTextureIndex], RHI::TextureState::renderTarget, RHI::TextureState::present)); + } + commandRecorder->End(); + + GetDevice().GetQueue(RHI::QueueType::graphics, 0)->Submit( + commandBuffer.Get(), + RHI::QueueSubmitInfo() + .AddWaitSemaphore(imageReadySemaphore.Get()) + .AddSignalSemaphore(renderFinishedSemaphore.Get()) + .SetSignalFence(frameFence.Get())); + GetSwapChain().Present(renderFinishedSemaphore.Get()); + } +} // namespace Editor diff --git a/Editor/Src/Widget/GraphicsWidget.cpp b/Editor/Src/Widget/GraphicsWidget.cpp new file mode 100644 index 000000000..30347fe08 --- /dev/null +++ b/Editor/Src/Widget/GraphicsWidget.cpp @@ -0,0 +1,142 @@ +// +// Created by Kindem on 2025/3/16. +// + +#include +#include +#include // NOLINT + +namespace Editor { + GraphicsWidget::GraphicsWidget(const GraphicsWidgetDesc& inDesc, QWidget* inParent) + : QWidget(inParent) + , textureNum(inDesc.textureNum) + , presentMode(inDesc.presentMode) + , lastTimeSeconds(Common::TimePoint::Now().ToSeconds()) + , currentTimeSeconds(Common::TimePoint::Now().ToSeconds()) + , deltaTimeSeconds(0.0f) + { + setAttribute(Qt::WA_NativeWindow); + setAttribute(Qt::WA_PaintOnScreen); + setAttribute(Qt::WA_NoSystemBackground); + + const Render::RenderModule& renderModule = Core::ModuleManager::Get().GetTyped("Render"); + device = renderModule.GetDevice(); + Assert(device != nullptr); + + surface = device->CreateSurface( + RHI::SurfaceCreateInfo() + .SetWindow(reinterpret_cast(winId()))); // NOLINT + + pixelFormat = RHI::PixelFormat::max; + for (const auto format : inDesc.formatQualifiers) { + if (device->CheckSwapChainFormatSupport(surface.Get(), format)) { + pixelFormat = format; + break; + } + } + + swapChain = device->CreateSwapChain( + RHI::SwapChainCreateInfo() + .SetPresentQueue(device->GetQueue(RHI::QueueType::graphics, 0)) + .SetSurface(surface.Get()) + .SetTextureNum(inDesc.textureNum) + .SetFormat(pixelFormat) + .SetWidth(width()) + .SetHeight(height()) + .SetPresentMode(inDesc.presentMode)); + + timer = new QTimer(this); + connect(timer, &QTimer::timeout, this, &GraphicsWidget::OnDrawFrame); + timer->start(0); + } + + GraphicsWidget::~GraphicsWidget() + { + disconnect(timer, &QTimer::timeout, this, &GraphicsWidget::OnDrawFrame); + timer->stop(); + + WaitDeviceIdle(); + } + + uint8_t GraphicsWidget::GetTextureNum() const + { + return textureNum; + } + + RHI::PixelFormat GraphicsWidget::GetPixelFormat() const + { + return pixelFormat; + } + + RHI::PresentMode GraphicsWidget::GetPresentMode() const + { + return presentMode; + } + + RHI::Device& GraphicsWidget::GetDevice() const + { + return *device; + } + + RHI::Surface& GraphicsWidget::GetSurface() const + { + return *surface; + } + + RHI::SwapChain& GraphicsWidget::GetSwapChain() const + { + return *swapChain; + } + + QPaintEngine* GraphicsWidget::paintEngine() const + { + return nullptr; + } + + void GraphicsWidget::resizeEvent(QResizeEvent* event) + { + WaitDeviceIdle(); + + const auto newSize = event->size(); + + swapChain.Reset(); + swapChain = device->CreateSwapChain( + RHI::SwapChainCreateInfo() + .SetPresentQueue(device->GetQueue(RHI::QueueType::graphics, 0)) + .SetSurface(surface.Get()) + .SetTextureNum(textureNum) + .SetFormat(pixelFormat) + .SetWidth(newSize.width()) + .SetHeight(newSize.height()) + .SetPresentMode(presentMode)); + } + + void GraphicsWidget::OnDrawFrame() + { + currentTimeSeconds = Common::TimePoint::Now().ToSeconds(); + deltaTimeSeconds = currentTimeSeconds - lastTimeSeconds; + lastTimeSeconds = currentTimeSeconds; + } + + void GraphicsWidget::WaitDeviceIdle() const + { + const Common::UniquePtr fence = device->CreateFence(false); + device->GetQueue(RHI::QueueType::graphics, 0)->Flush(fence.Get()); + fence->Wait(); + } + + double GraphicsWidget::GetLastTimeSeconds() const + { + return currentTimeSeconds; + } + + double GraphicsWidget::GetCurrentTimeSeconds() const + { + return currentTimeSeconds; + } + + float GraphicsWidget::GetDeltaTimeSeconds() const + { + return deltaTimeSeconds; + } +} // namespace Editor diff --git a/Editor/Src/Widget/GraphicsWindow.cpp b/Editor/Src/Widget/GraphicsWindow.cpp deleted file mode 100644 index 2bf485da7..000000000 --- a/Editor/Src/Widget/GraphicsWindow.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// Created by Kindem on 2025/3/16. -// - -#include -#include - -namespace Editor { - GraphicsWindow::GraphicsWindow(const GraphicsWindowDesc& inDesc, QWindow* inParent) - : QWindow(inParent) - , textureNum(inDesc.textureNum) - { - const Render::RenderModule& renderModule = Core::ModuleManager::Get().GetTyped("Render"); - device = renderModule.GetDevice(); - Assert(device != nullptr); - - surface = device->CreateSurface( - RHI::SurfaceCreateInfo() - .SetWindow(reinterpret_cast(winId()))); // NOLINT - - pixelFormat = RHI::PixelFormat::max; - for (const auto format : inDesc.formatQualifiers) { - if (device->CheckSwapChainFormatSupport(surface.Get(), format)) { - pixelFormat = format; - break; - } - } - - swapChain = device->CreateSwapChain( - RHI::SwapChainCreateInfo() - .SetPresentQueue(device->GetQueue(RHI::QueueType::graphics, 0)) - .SetSurface(surface.Get()) - .SetTextureNum(inDesc.textureNum) - .SetFormat(pixelFormat) - .SetWidth(width()) - .SetHeight(height()) - .SetPresentMode(inDesc.presentMode)); - } - - GraphicsWindow::~GraphicsWindow() - { - const Common::UniquePtr fence = device->CreateFence(false); - device->GetQueue(RHI::QueueType::graphics, 0)->Flush(fence.Get()); - fence->Wait(); - } - - uint8_t GraphicsWindow::GetTextureNum() const - { - return textureNum; - } - - RHI::PixelFormat GraphicsWindow::GetPixelFormat() const - { - return pixelFormat; - } - - RHI::Device& GraphicsWindow::GetDevice() const - { - return *device; - } - - RHI::Surface& GraphicsWindow::GetSurface() const - { - return *surface; - } - - RHI::SwapChain& GraphicsWindow::GetSwapChain() const - { - return *swapChain; - } -} // namespace Editor diff --git a/Editor/Src/Widget/GraphicsWindowSample.cpp b/Editor/Src/Widget/GraphicsWindowSample.cpp deleted file mode 100644 index 0dcde91ca..000000000 --- a/Editor/Src/Widget/GraphicsWindowSample.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// Created by Kindem on 2025/3/16. -// - -#include -#include - -namespace Editor { - GraphicsWindowSample::GraphicsWindowSample(QWindow* inParent) - : GraphicsWindow(GetGraphicsWindowDesc(), inParent) - , imageReadySemaphore(GetDevice().CreateSemaphore()) - , renderFinishedSemaphore(GetDevice().CreateSemaphore()) - , frameFence(GetDevice().CreateFence(true)) - { - for (auto i = 0; i < swapChainTextureNum; i++) { - swapChainTextures[i] = GetSwapChain().GetTexture(i); - swapChainTextureViews[i] = swapChainTextures[i]->CreateTextureView( - RHI::TextureViewCreateInfo() - .SetDimension(RHI::TextureViewDimension::tv2D) - .SetMipLevels(0, 1) - .SetArrayLayers(0, 1) - .SetAspect(RHI::TextureAspect::color) - .SetType(RHI::TextureViewType::colorAttachment)); - } - } - - GraphicsWindowDesc GraphicsWindowSample::GetGraphicsWindowDesc() - { - GraphicsWindowDesc result; - result.textureNum = swapChainTextureNum; - result.formatQualifiers = { RHI::PixelFormat::rgba8Unorm, RHI::PixelFormat::bgra8Unorm }; - result.presentMode = RHI::PresentMode::immediately; - return result; - } - - GraphicsWindowSampleWidget::GraphicsWindowSampleWidget(QWidget* inParent) - : QWidget(inParent) - , graphicsWindow(new GraphicsWindowSample()) - { - graphicsWindowContainer = createWindowContainer(graphicsWindow); - graphicsWindowContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - graphicsWindowContainer->show(); - - mainLayout = new QVBoxLayout(); - setLayout(mainLayout); - - mainLayout->setContentsMargins(0, 0, 0, 0); - mainLayout->addWidget(graphicsWindowContainer); - } -} // namespace Editor diff --git a/Engine/CMakeLists.txt b/Engine/CMakeLists.txt index 2aa23fb57..31b147311 100644 --- a/Engine/CMakeLists.txt +++ b/Engine/CMakeLists.txt @@ -1 +1,14 @@ add_subdirectory(Source) + +function(GetEngineShaderResources) + cmake_parse_arguments(PARAMS "" "NAME" "OUTPUT" ${ARGN}) + + file(GLOB_RECURSE ENGINE_SHADERS ${CMAKE_SOURCE_DIR}/Engine/Shader/*.es*) + foreach (SHADER ${ENGINE_SHADERS}) + get_filename_component(SHADER_ABSOLUTE ${SHADER} ABSOLUTE) + string(REPLACE ${CMAKE_SOURCE_DIR}/Engine/Shader ../Shader/Engine COPY_DST ${SHADER_ABSOLUTE}) + list(APPEND RESULT ${SHADER}->${COPY_DST}) + endforeach () + + set(${PARAMS_OUTPUT} ${RESULT} PARENT_SCOPE) +endfunction() diff --git a/Engine/Source/Core/Include/Core/Cmdline.h b/Engine/Source/Core/Include/Core/Cmdline.h index 8d1266891..25a2e6f99 100644 --- a/Engine/Source/Core/Include/Core/Cmdline.h +++ b/Engine/Source/Core/Include/Core/Cmdline.h @@ -18,12 +18,12 @@ namespace Core { virtual ~CmdlineArg(); template - T GetValue(); + T GetValue() const; protected: friend class Cli; - virtual const void* Value() = 0; + virtual const void* Value() const = 0; virtual clipp::group CreateClippParameter() = 0; }; @@ -34,7 +34,7 @@ namespace Core { std::pair Parse(int argc, char* argv[]); CmdlineArg* FindArg(const std::string& name) const; - CmdlineArg& FindArgChecked(const std::string& name) const; + CmdlineArg& GetArg(const std::string& name) const; private: template friend class CmdlineArgValue; @@ -55,7 +55,7 @@ namespace Core { T GetValue() const; protected: - const void* Value() override; + const void* Value() const override; clipp::group CreateClippParameter() override; private: @@ -74,7 +74,7 @@ namespace Core { T GetValue() const; protected: - const void* Value() override; + const void* Value() const override; clipp::group CreateClippParameter() override; private: @@ -87,7 +87,7 @@ namespace Core { namespace Core { template - T CmdlineArg::GetValue() + T CmdlineArg::GetValue() const { return static_cast(Value()); } @@ -113,7 +113,7 @@ namespace Core { } template - const void* CmdlineArgValue::Value() + const void* CmdlineArgValue::Value() const { return &value; } @@ -149,7 +149,7 @@ namespace Core { } template - const void* CmdlineArgRef::Value() + const void* CmdlineArgRef::Value() const { return &valueRef; } diff --git a/Engine/Source/Core/Src/Cmdline.cpp b/Engine/Source/Core/Src/Cmdline.cpp index dc3717cd7..8f698f333 100644 --- a/Engine/Source/Core/Src/Cmdline.cpp +++ b/Engine/Source/Core/Src/Cmdline.cpp @@ -50,7 +50,7 @@ namespace Core { return iter == args.end() ? nullptr : iter->second; } - CmdlineArg& Cli::FindArgChecked(const std::string& name) const + CmdlineArg& Cli::GetArg(const std::string& name) const { auto* result = FindArg(name); Assert(result != nullptr); diff --git a/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Device.h b/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Device.h index 02b06fc87..eaf542f19 100644 --- a/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Device.h +++ b/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Device.h @@ -13,11 +13,11 @@ #include #include #include +#include using Microsoft::WRL::ComPtr; namespace RHI::DirectX12 { - class DX12Gpu; class DX12Queue; class DX12Device; @@ -73,6 +73,7 @@ namespace RHI::DirectX12 { DX12Device(DX12Gpu& inGpu, const DeviceCreateInfo& inCreateInfo); ~DX12Device() override; + DX12Gpu& GetGpu() const override; size_t GetQueueNum(QueueType inType) override; Queue* GetQueue(QueueType inType, size_t inIndex) override; Common::UniquePtr CreateSurface(const SurfaceCreateInfo& inCreateInfo) override; @@ -93,7 +94,6 @@ namespace RHI::DirectX12 { bool CheckSwapChainFormatSupport(Surface* inSurface, PixelFormat inFormat) override; TextureSubResourceCopyFootprint GetTextureSubResourceCopyFootprint(const Texture& texture, const TextureSubResourceInfo& subResourceInfo) override; - DX12Gpu& GetGpu() const; ID3D12Device* GetNative() const; Common::UniquePtr AllocateRtvDescriptor() const; Common::UniquePtr AllocateCbvSrvUavDescriptor() const; diff --git a/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Gpu.h b/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Gpu.h index ff9d4fd5d..7a9a911ae 100644 --- a/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Gpu.h +++ b/Engine/Source/RHI-DirectX12/Include/RHI/DirectX12/Gpu.h @@ -8,12 +8,11 @@ #include #include +#include using Microsoft::WRL::ComPtr; namespace RHI::DirectX12 { - class DX12Instance; - class DX12Gpu final : public Gpu { public: NonCopyable(DX12Gpu) @@ -22,8 +21,8 @@ namespace RHI::DirectX12 { GpuProperty GetProperty() override; Common::UniquePtr RequestDevice(const DeviceCreateInfo& inCreateInfo) override; + DX12Instance& GetInstance() const override; - DX12Instance& GetInstance() const; IDXGIAdapter1* GetNative() const; private: diff --git a/Engine/Source/RHI-DirectX12/Src/Device.cpp b/Engine/Source/RHI-DirectX12/Src/Device.cpp index 953b76715..470badfe7 100644 --- a/Engine/Source/RHI-DirectX12/Src/Device.cpp +++ b/Engine/Source/RHI-DirectX12/Src/Device.cpp @@ -166,6 +166,11 @@ namespace RHI::DirectX12 { return queues.at(inType).size(); } + DX12Gpu& DX12Device::GetGpu() const + { + return gpu; + } + Queue* DX12Device::GetQueue(const QueueType inType, const size_t inIndex) { const auto& queueArray = queues.at(inType); @@ -273,11 +278,6 @@ namespace RHI::DirectX12 { return result; } - DX12Gpu& DX12Device::GetGpu() const - { - return gpu; - } - ID3D12Device* DX12Device::GetNative() const { return nativeDevice.Get(); diff --git a/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Device.h b/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Device.h index 993d78d76..2f9268f42 100644 --- a/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Device.h +++ b/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Device.h @@ -5,6 +5,7 @@ #pragma once #include +#include namespace RHI::Dummy { class DummyQueue; @@ -12,9 +13,10 @@ namespace RHI::Dummy { class DummyDevice final : public Device { public: NonCopyable(DummyDevice) - explicit DummyDevice(const DeviceCreateInfo& createInfo); + explicit DummyDevice(DummyGpu& gpu, const DeviceCreateInfo& createInfo); ~DummyDevice() override; - + + DummyGpu& GetGpu() const override; size_t GetQueueNum(QueueType type) override; Queue* GetQueue(QueueType type, size_t index) override; Common::UniquePtr CreateSurface(const RHI::SurfaceCreateInfo &createInfo) override; @@ -36,6 +38,7 @@ namespace RHI::Dummy { TextureSubResourceCopyFootprint GetTextureSubResourceCopyFootprint(const Texture& texture, const TextureSubResourceInfo& subResourceInfo) override; private: + DummyGpu& gpu; Common::UniquePtr dummyQueue; }; } diff --git a/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Gpu.h b/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Gpu.h index 932e5de14..019122703 100644 --- a/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Gpu.h +++ b/Engine/Source/RHI-Dummy/Include/RHI/Dummy/Gpu.h @@ -5,14 +5,19 @@ #pragma once #include +#include namespace RHI::Dummy { class DummyGpu final : public Gpu { public: NonCopyable(DummyGpu) - DummyGpu(); + explicit DummyGpu(DummyInstance& inInstance); ~DummyGpu() override; GpuProperty GetProperty() override; Common::UniquePtr RequestDevice(const DeviceCreateInfo& createInfo) override; + DummyInstance& GetInstance() const override; + + private: + DummyInstance& instance; }; } diff --git a/Engine/Source/RHI-Dummy/Src/Device.cpp b/Engine/Source/RHI-Dummy/Src/Device.cpp index 6479231e5..c4cbd46d4 100644 --- a/Engine/Source/RHI-Dummy/Src/Device.cpp +++ b/Engine/Source/RHI-Dummy/Src/Device.cpp @@ -19,14 +19,20 @@ #include namespace RHI::Dummy { - DummyDevice::DummyDevice(const DeviceCreateInfo& createInfo) + DummyDevice::DummyDevice(DummyGpu& gpu, const DeviceCreateInfo& createInfo) : Device(createInfo) + , gpu(gpu) , dummyQueue(Common::MakeUnique()) { } DummyDevice::~DummyDevice() = default; + DummyGpu& DummyDevice::GetGpu() const + { + return gpu; + } + size_t DummyDevice::GetQueueNum(const QueueType type) { return type == QueueType::graphics ? 1 : 0; diff --git a/Engine/Source/RHI-Dummy/Src/Gpu.cpp b/Engine/Source/RHI-Dummy/Src/Gpu.cpp index 2d9316678..5409865f7 100644 --- a/Engine/Source/RHI-Dummy/Src/Gpu.cpp +++ b/Engine/Source/RHI-Dummy/Src/Gpu.cpp @@ -6,7 +6,10 @@ #include namespace RHI::Dummy { - DummyGpu::DummyGpu() = default; + DummyGpu::DummyGpu(DummyInstance& inInstance) + : instance(inInstance) + { + } DummyGpu::~DummyGpu() = default; @@ -17,6 +20,11 @@ namespace RHI::Dummy { Common::UniquePtr DummyGpu::RequestDevice(const DeviceCreateInfo& createInfo) { - return { new DummyDevice(createInfo) }; + return { new DummyDevice(*this, createInfo) }; + } + + DummyInstance& DummyGpu::GetInstance() const + { + return instance; } } diff --git a/Engine/Source/RHI-Dummy/Src/Instance.cpp b/Engine/Source/RHI-Dummy/Src/Instance.cpp index a3e021dcc..9ae23ed9f 100644 --- a/Engine/Source/RHI-Dummy/Src/Instance.cpp +++ b/Engine/Source/RHI-Dummy/Src/Instance.cpp @@ -10,7 +10,7 @@ namespace RHI::Dummy { Instance* gInstance = nullptr; DummyInstance::DummyInstance() - : dummyGpu(Common::MakeUnique()) + : dummyGpu(Common::MakeUnique(*this)) { } diff --git a/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Device.h b/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Device.h index aa7578604..7071a00fa 100644 --- a/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Device.h +++ b/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Device.h @@ -12,9 +12,9 @@ #include #include +#include namespace RHI::Vulkan { - class VulkanGpu; class VulkanQueue; class VulkanDevice final : public Device { @@ -23,6 +23,7 @@ namespace RHI::Vulkan { VulkanDevice(VulkanGpu& inGpu, const DeviceCreateInfo& inCreateInfo); ~VulkanDevice() override; + VulkanGpu& GetGpu() const override; size_t GetQueueNum(QueueType inType) override; Queue* GetQueue(QueueType inType, size_t inIndex) override; Common::UniquePtr CreateSurface(const SurfaceCreateInfo& inCreateInfo) override; @@ -45,7 +46,6 @@ namespace RHI::Vulkan { VkDevice GetNative() const; VmaAllocator& GetNativeAllocator(); - VulkanGpu& GetGpu() const; #if BUILD_CONFIG_DEBUG void SetObjectName(VkObjectType inObjectType, uint64_t inObjectHandle, const char* inObjectName) const; diff --git a/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Gpu.h b/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Gpu.h index 55ffe1563..a2c62f3bb 100644 --- a/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Gpu.h +++ b/Engine/Source/RHI-Vulkan/Include/RHI/Vulkan/Gpu.h @@ -7,10 +7,9 @@ #include #include +#include namespace RHI::Vulkan { - class VulkanInstance; - class VulkanGpu final : public Gpu { public: NonCopyable(VulkanGpu) @@ -19,9 +18,9 @@ namespace RHI::Vulkan { GpuProperty GetProperty() override; Common::UniquePtr RequestDevice(const DeviceCreateInfo& inCreateInfo) override; + VulkanInstance& GetInstance() const override; VkPhysicalDevice GetNative() const; - VulkanInstance& GetInstance() const; uint32_t FindMemoryType(uint32_t inFilter, VkMemoryPropertyFlags inPropertyFlag) const; private: diff --git a/Engine/Source/RHI-Vulkan/Src/Device.cpp b/Engine/Source/RHI-Vulkan/Src/Device.cpp index d98ee1177..5b6e0ebc9 100644 --- a/Engine/Source/RHI-Vulkan/Src/Device.cpp +++ b/Engine/Source/RHI-Vulkan/Src/Device.cpp @@ -60,6 +60,11 @@ namespace RHI::Vulkan { vkDestroyDevice(nativeDevice, nullptr); } + VulkanGpu& VulkanDevice::GetGpu() const + { + return gpu; + } + size_t VulkanDevice::GetQueueNum(const QueueType inType) { return queues.at(inType).size(); @@ -186,11 +191,6 @@ namespace RHI::Vulkan { return nativeDevice; } - VulkanGpu& VulkanDevice::GetGpu() const - { - return gpu; - } - std::optional VulkanDevice::FindQueueFamilyIndex(const std::vector& inProperties, std::vector& inUsedQueueFamily, QueueType inQueueType) { for (uint32_t i = 0; i < inProperties.size(); i++) { diff --git a/Engine/Source/RHI-Vulkan/Src/Gpu.cpp b/Engine/Source/RHI-Vulkan/Src/Gpu.cpp index f5647bd82..d155bb699 100644 --- a/Engine/Source/RHI-Vulkan/Src/Gpu.cpp +++ b/Engine/Source/RHI-Vulkan/Src/Gpu.cpp @@ -32,14 +32,14 @@ namespace RHI::Vulkan { return { new VulkanDevice(*this, inCreateInfo) }; } - VkPhysicalDevice VulkanGpu::GetNative() const + VulkanInstance& VulkanGpu::GetInstance() const { - return nativePhysicalDevice; + return instance; } - VulkanInstance& VulkanGpu::GetInstance() const + VkPhysicalDevice VulkanGpu::GetNative() const { - return instance; + return nativePhysicalDevice; } uint32_t VulkanGpu::FindMemoryType(uint32_t inFilter, VkMemoryPropertyFlags inPropertyFlag) const diff --git a/Engine/Source/RHI-Vulkan/Src/SwapChain.cpp b/Engine/Source/RHI-Vulkan/Src/SwapChain.cpp index c3788c514..d32bbdc3d 100644 --- a/Engine/Source/RHI-Vulkan/Src/SwapChain.cpp +++ b/Engine/Source/RHI-Vulkan/Src/SwapChain.cpp @@ -50,7 +50,8 @@ namespace RHI::Vulkan { uint8_t VulkanSwapChain::AcquireBackTexture(Semaphore* inSignalSemaphore) { const auto& vulkanSignalSemaphore = static_cast(*inSignalSemaphore); - Assert(vkAcquireNextImageKHR(device.GetNative(), nativeSwapChain, UINT64_MAX, vulkanSignalSemaphore.GetNative(), VK_NULL_HANDLE, ¤tImage) == VK_SUCCESS); + const auto result = vkAcquireNextImageKHR(device.GetNative(), nativeSwapChain, UINT64_MAX, vulkanSignalSemaphore.GetNative(), VK_NULL_HANDLE, ¤tImage); + Assert(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR); return currentImage; } @@ -66,7 +67,9 @@ namespace RHI::Vulkan { presetInfo.waitSemaphoreCount = waitSemaphores.size(); presetInfo.pWaitSemaphores = waitSemaphores.data(); presetInfo.pImageIndices = ¤tImage; - Assert(vkQueuePresentKHR(nativeQueue, &presetInfo) == VK_SUCCESS); + + const auto result = vkQueuePresentKHR(nativeQueue, &presetInfo); + Assert(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR); } void VulkanSwapChain::CreateNativeSwapChain(const SwapChainCreateInfo& inCreateInfo) diff --git a/Engine/Source/RHI/Include/RHI/Device.h b/Engine/Source/RHI/Include/RHI/Device.h index f1ecce2d9..816a2fea3 100644 --- a/Engine/Source/RHI/Include/RHI/Device.h +++ b/Engine/Source/RHI/Include/RHI/Device.h @@ -8,6 +8,7 @@ #include #include +#include #if PLATFORM_WINDOWS #undef CreateSemaphore @@ -62,6 +63,7 @@ namespace RHI { NonCopyable(Device) virtual ~Device(); + virtual Gpu& GetGpu() const = 0; virtual size_t GetQueueNum(QueueType type) = 0; virtual Queue* GetQueue(QueueType type, size_t index) = 0; virtual Common::UniquePtr CreateSurface(const SurfaceCreateInfo& createInfo) = 0; diff --git a/Engine/Source/RHI/Include/RHI/Gpu.h b/Engine/Source/RHI/Include/RHI/Gpu.h index 91d64ac50..decf5b7da 100644 --- a/Engine/Source/RHI/Include/RHI/Gpu.h +++ b/Engine/Source/RHI/Include/RHI/Gpu.h @@ -11,6 +11,7 @@ namespace RHI { class Device; + class Instance; struct DeviceCreateInfo; struct GpuProperty { @@ -25,6 +26,7 @@ namespace RHI { virtual ~Gpu(); virtual GpuProperty GetProperty() = 0; virtual Common::UniquePtr RequestDevice(const DeviceCreateInfo& createInfo) = 0; + virtual Instance& GetInstance() const = 0; protected: Gpu(); From bb2a0cd4e36463af9b1661e2c9464c79c2de3ea9 Mon Sep 17 00:00:00 2001 From: FlyAntNotDown <461425614@qq.com> Date: Wed, 19 Mar 2025 22:07:21 +0800 Subject: [PATCH 5/6] feat: misc runtime update --- .../Common/Include/Common/Math/Projection.h | 29 +------ Engine/Source/Common/Include/Common/Memory.h | 58 +++++++++++-- Engine/Source/Core/Src/Console.cpp | 2 + .../Launch/Include/Launch/GameViewport.h | 6 +- Engine/Source/Launch/Src/GameViewport.cpp | 4 +- .../Render/Include/Render/RenderModule.h | 6 +- .../Source/Render/Include/Render/Renderer.h | 6 +- Engine/Source/Render/Include/Render/View.h | 12 +-- .../Source/Render/SharedSrc/RenderModule.cpp | 7 +- Engine/Source/Render/Src/Renderer.cpp | 9 ++ Engine/Source/Render/Src/ShaderCompiler.cpp | 2 +- Engine/Source/Render/Src/View.cpp | 2 +- .../Runtime/Include/Runtime/Asset/Asset.h | 29 +++---- .../Runtime/Include/Runtime/Asset/Level.h | 5 +- .../Runtime/Include/Runtime/Asset/Material.h | 41 +++++++++ .../Runtime/Include/Runtime/Asset/Mesh.h | 44 ++++++++++ .../Runtime/Component/{View.h => Camera.h} | 0 .../Include/Runtime/Component/Player.h | 21 ++++- Engine/Source/Runtime/Include/Runtime/ECS.h | 9 +- .../Runtime/Include/Runtime/System/Player.h | 75 +++++++++++++++++ .../Runtime/Include/Runtime/System/Render.h | 43 +++++++++- .../Source/Runtime/Include/Runtime/Viewport.h | 6 +- Engine/Source/Runtime/Src/Asset/Asset.cpp | 2 + Engine/Source/Runtime/Src/Asset/Level.cpp | 2 + Engine/Source/Runtime/Src/Asset/Material.cpp | 17 ++++ Engine/Source/Runtime/Src/Asset/Mesh.cpp | 14 ++++ .../Src/Component/{View.cpp => Camera.cpp} | 2 +- .../Source/Runtime/Src/Component/Player.cpp | 13 ++- Engine/Source/Runtime/Src/ECS.cpp | 7 +- Engine/Source/Runtime/Src/System/Player.cpp | 34 +++++++- Engine/Source/Runtime/Src/System/Render.cpp | 83 ++++++++++++++++++- .../Source/Runtime/Src/SystemGraphPresets.cpp | 6 +- Engine/Source/Runtime/Test/AssetTest.cpp | 4 +- Engine/Source/Runtime/Test/AssetTest.h | 4 +- Tool/MirrorTool/Src/Generator.cpp | 2 +- 35 files changed, 512 insertions(+), 94 deletions(-) create mode 100644 Engine/Source/Runtime/Include/Runtime/Asset/Material.h create mode 100644 Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h rename Engine/Source/Runtime/Include/Runtime/Component/{View.h => Camera.h} (100%) create mode 100644 Engine/Source/Runtime/Src/Asset/Material.cpp create mode 100644 Engine/Source/Runtime/Src/Asset/Mesh.cpp rename Engine/Source/Runtime/Src/Component/{View.cpp => Camera.cpp} (81%) diff --git a/Engine/Source/Common/Include/Common/Math/Projection.h b/Engine/Source/Common/Include/Common/Math/Projection.h index 47f80e98e..1fcc63b0c 100644 --- a/Engine/Source/Common/Include/Common/Math/Projection.h +++ b/Engine/Source/Common/Include/Common/Math/Projection.h @@ -32,8 +32,7 @@ namespace Common { template struct ReversedZOrthogonalProjection : ReversedZOrthogonalProjectionBase { ReversedZOrthogonalProjection(); - ReversedZOrthogonalProjection(T inWidth, T inHeight, T inNearPlane); - ReversedZOrthogonalProjection(T inWidth, T inHeight, T inNearPlane, T inFarPlane); + ReversedZOrthogonalProjection(T inWidth, T inHeight, T inNearPlane, const std::optional& inFarPlane = {}); Mat GetProjectionMatrix() const; bool operator==(const ReversedZOrthogonalProjection& inRhs) const; @@ -42,8 +41,7 @@ namespace Common { template struct ReversedZPerspectiveProjection : ReversedZPerspectiveProjectionBase { ReversedZPerspectiveProjection(); - ReversedZPerspectiveProjection(T inFOV, T inWidth, T inHeight, T inNearPlane); - ReversedZPerspectiveProjection(T inFOV, T inWidth, T inHeight, T inNearPlane, T inFarPlane); + ReversedZPerspectiveProjection(T inFOV, T inWidth, T inHeight, T inNearPlane, const std::optional& inFarPlane); Mat GetProjectionMatrix() const; bool operator==(const ReversedZPerspectiveProjection& inRhs) const; @@ -251,16 +249,7 @@ namespace Common { } template - ReversedZOrthogonalProjection::ReversedZOrthogonalProjection(T inWidth, T inHeight, T inNearPlane) - { - this->width = inWidth; - this->height = inHeight; - this->nearPlane = inNearPlane; - this->farPlane = {}; - } - - template - ReversedZOrthogonalProjection::ReversedZOrthogonalProjection(T inWidth, T inHeight, T inNearPlane, T inFarPlane) + ReversedZOrthogonalProjection::ReversedZOrthogonalProjection(T inWidth, T inHeight, T inNearPlane, const std::optional& inFarPlane) { this->width = inWidth; this->height = inHeight; @@ -317,17 +306,7 @@ namespace Common { } template - ReversedZPerspectiveProjection::ReversedZPerspectiveProjection(T inFOV, T inWidth, T inHeight, T inNearPlane) - { - this->fov = inFOV; - this->width = inWidth; - this->height = inHeight; - this->nearPlane = inNearPlane; - this->farPlane = {}; - } - - template - ReversedZPerspectiveProjection::ReversedZPerspectiveProjection(T inFOV, T inWidth, T inHeight, T inNearPlane, T inFarPlane) + ReversedZPerspectiveProjection::ReversedZPerspectiveProjection(T inFOV, T inWidth, T inHeight, T inNearPlane, const std::optional& inFarPlane) { this->fov = inFOV; this->width = inWidth; diff --git a/Engine/Source/Common/Include/Common/Memory.h b/Engine/Source/Common/Include/Common/Memory.h index db04297f6..858599215 100644 --- a/Engine/Source/Common/Include/Common/Memory.h +++ b/Engine/Source/Common/Include/Common/Memory.h @@ -32,6 +32,7 @@ namespace Common { bool Valid() const; T* Get() const; + T* Release(); void Reset(T* pointer = nullptr); std::unique_ptr& GetStd(); @@ -42,9 +43,11 @@ namespace Common { template class SharedPtr { public: - template SharedPtr(std::shared_ptr& sharedPtr); // NOLINT + template SharedPtr(const std::shared_ptr& sharedPtr); // NOLINT template SharedPtr(std::shared_ptr&& sharedPtr) noexcept; // NOLINT template SharedPtr(std::unique_ptr&& uniquePtr) noexcept; // NOLINT + template SharedPtr(const SharedPtr& sharedPtr); // NOLINT + template SharedPtr(SharedPtr&& sharedPtr) noexcept; // NOLINT template SharedPtr(UniquePtr&& uniquePtr) noexcept; // NOLINT SharedPtr(T* pointer); // NOLINT @@ -53,13 +56,14 @@ namespace Common { SharedPtr(); ~SharedPtr(); - template SharedPtr& operator=(std::shared_ptr& sharedPtr); + template SharedPtr& operator=(const std::shared_ptr& sharedPtr); template SharedPtr& operator=(std::shared_ptr&& sharedPtr); template SharedPtr& operator=(std::unique_ptr&& uniquePtr) noexcept; + template SharedPtr& operator=(const SharedPtr& sharedPtr); + template SharedPtr& operator=(SharedPtr&& sharedPtr) noexcept; template SharedPtr& operator=(UniquePtr&& uniquePtr) noexcept; - SharedPtr& operator=(T* pointer); - SharedPtr& operator=(SharedPtr& other); // NOLINT + SharedPtr& operator=(const SharedPtr& other); // NOLINT SharedPtr& operator=(SharedPtr&& other) noexcept; T* operator->() const noexcept; T& operator*() const noexcept; @@ -189,6 +193,12 @@ namespace Common { return ptr.get(); } + template + T* UniquePtr::Release() + { + return ptr.release(); + } + template bool UniquePtr::Valid() const { @@ -209,7 +219,7 @@ namespace Common { template template - SharedPtr::SharedPtr(std::shared_ptr& sharedPtr) + SharedPtr::SharedPtr(const std::shared_ptr& sharedPtr) : ptr(sharedPtr) { } @@ -228,10 +238,24 @@ namespace Common { { } + template + template + SharedPtr::SharedPtr(const SharedPtr& sharedPtr) + : ptr(sharedPtr.ptr) + { + } + + template + template + SharedPtr::SharedPtr(SharedPtr&& sharedPtr) noexcept + : ptr(std::move(sharedPtr.ptr)) + { + } + template template SharedPtr::SharedPtr(UniquePtr&& uniquePtr) noexcept - : ptr(std::move(uniquePtr.Get())) + : ptr(uniquePtr.Release()) { } @@ -261,7 +285,7 @@ namespace Common { template template - SharedPtr & SharedPtr::operator=(std::shared_ptr & sharedPtr) + SharedPtr & SharedPtr::operator=(const std::shared_ptr & sharedPtr) { ptr = sharedPtr; return *this; @@ -279,7 +303,23 @@ namespace Common { template SharedPtr& SharedPtr::operator=(std::unique_ptr&& uniquePtr) noexcept { - ptr = std::move(uniquePtr); + ptr = uniquePtr.Release(); + return *this; + } + + template + template + SharedPtr& SharedPtr::operator=(const SharedPtr& sharedPtr) + { + ptr = sharedPtr.ptr; + return *this; + } + + template + template + SharedPtr& SharedPtr::operator=(SharedPtr&& sharedPtr) noexcept + { + ptr = std::move(sharedPtr.ptr); return *this; } @@ -299,7 +339,7 @@ namespace Common { } template - SharedPtr & SharedPtr::operator=(SharedPtr& other) + SharedPtr & SharedPtr::operator=(const SharedPtr& other) { ptr = other.ptr; return *this; diff --git a/Engine/Source/Core/Src/Console.cpp b/Engine/Source/Core/Src/Console.cpp index 9112f4e86..0abf12fa1 100644 --- a/Engine/Source/Core/Src/Console.cpp +++ b/Engine/Source/Core/Src/Console.cpp @@ -6,7 +6,9 @@ #include #include +#include #include +#include namespace Core::Internal { static void SetConsoleSettingFromJsonValue(ConsoleSetting& inConsoleSetting, const rapidjson::Value& inJsonValue) diff --git a/Engine/Source/Launch/Include/Launch/GameViewport.h b/Engine/Source/Launch/Include/Launch/GameViewport.h index cc8b471d6..8ab3c92d0 100644 --- a/Engine/Source/Launch/Include/Launch/GameViewport.h +++ b/Engine/Source/Launch/Include/Launch/GameViewport.h @@ -7,15 +7,15 @@ #include namespace Launch { - class GameViewport : public Runtime::Viewport { + class GameViewport final : public Runtime::Viewport { public: GameViewport(); ~GameViewport() override; Runtime::Client& GetClient() override; Runtime::PresentInfo GetNextPresentInfo() override; - size_t GetWidth() override; - size_t GetHeight() override; + size_t GetWidth() const override; + size_t GetHeight() const override; private: // TODO glfw window diff --git a/Engine/Source/Launch/Src/GameViewport.cpp b/Engine/Source/Launch/Src/GameViewport.cpp index 4db293cde..8f2caad5c 100644 --- a/Engine/Source/Launch/Src/GameViewport.cpp +++ b/Engine/Source/Launch/Src/GameViewport.cpp @@ -27,13 +27,13 @@ namespace Launch { return Runtime::PresentInfo(); } - size_t GameViewport::GetWidth() + size_t GameViewport::GetWidth() const { // TODO return 0; } - size_t GameViewport::GetHeight() + size_t GameViewport::GetHeight() const { // TODO return 0; diff --git a/Engine/Source/Render/Include/Render/RenderModule.h b/Engine/Source/Render/Include/Render/RenderModule.h index f46a0ca7c..ec749f147 100644 --- a/Engine/Source/Render/Include/Render/RenderModule.h +++ b/Engine/Source/Render/Include/Render/RenderModule.h @@ -6,10 +6,11 @@ #include #include +#include +#include +#include #include #include -#include -#include namespace Render { struct RenderModuleInitParams { @@ -32,6 +33,7 @@ namespace Render { Scene* NewScene() const; ViewState* NewViewState() const; View CreateView() const; + StandardRenderer CreateStandardRenderer(const StandardRenderer::Params& inParams) const; private: bool initialized; diff --git a/Engine/Source/Render/Include/Render/Renderer.h b/Engine/Source/Render/Include/Render/Renderer.h index 50fd671a3..f40ecfafc 100644 --- a/Engine/Source/Render/Include/Render/Renderer.h +++ b/Engine/Source/Render/Include/Render/Renderer.h @@ -18,8 +18,8 @@ namespace Render { public: struct Params { const Scene* scene; - Common::UVec2 surfaceExtent; const RHI::Texture* surface; + Common::UVec2 surfaceExtent; std::vector views; RHI::Semaphore* waitSemaphore; RHI::Semaphore* signalSemaphore; @@ -34,6 +34,7 @@ namespace Render { protected: const Scene* scene; const RHI::Texture* surface; + Common::UVec2 surfaceExtent; std::vector views; RHI::Semaphore* waitSemaphore; RHI::Semaphore* signalSemaphore; @@ -42,11 +43,14 @@ namespace Render { class StandardRenderer final : public Renderer { public: + using Params = Renderer::Params; + explicit StandardRenderer(const Params& inParams); ~StandardRenderer() override; void Render(float inDeltaTimeSeconds) override; private: + void FinalizeViews() const; }; } diff --git a/Engine/Source/Render/Include/Render/View.h b/Engine/Source/Render/Include/Render/View.h index 0a5efc255..c42c73161 100644 --- a/Engine/Source/Render/Include/Render/View.h +++ b/Engine/Source/Render/Include/Render/View.h @@ -8,18 +8,18 @@ #include namespace Render { - struct ViewRenderData { - ViewRenderData(); + struct ViewData { + ViewData(); Common::FMat4x4 viewMatrix; Common::FMat4x4 projectionMatrix; - Common::FRect viewport; + Common::URect viewport; }; struct ViewState { ViewState(); - ViewRenderData prevViewRenderData; + ViewData prevData; // TODO frame number ... // TODO temporal history ... }; @@ -27,7 +27,7 @@ namespace Render { struct View { View(); - ViewRenderData renderData; - ViewState* viewState; + ViewData data; + ViewState* state; }; } diff --git a/Engine/Source/Render/SharedSrc/RenderModule.cpp b/Engine/Source/Render/SharedSrc/RenderModule.cpp index deb508af4..8cbc54757 100644 --- a/Engine/Source/Render/SharedSrc/RenderModule.cpp +++ b/Engine/Source/Render/SharedSrc/RenderModule.cpp @@ -81,6 +81,11 @@ namespace Render { { return View(); } -} + + StandardRenderer RenderModule::CreateStandardRenderer(const StandardRenderer::Params& inParams) const // NOLINT + { + return StandardRenderer(inParams); + } +} // namespace Render IMPLEMENT_DYNAMIC_MODULE(RENDER_API, Render::RenderModule); diff --git a/Engine/Source/Render/Src/Renderer.cpp b/Engine/Source/Render/Src/Renderer.cpp index 031b20546..22ffa92cd 100644 --- a/Engine/Source/Render/Src/Renderer.cpp +++ b/Engine/Source/Render/Src/Renderer.cpp @@ -8,6 +8,7 @@ namespace Render { Renderer::Renderer(const Params& inParams) : scene(inParams.scene) , surface(inParams.surface) + , surfaceExtent(inParams.surfaceExtent) , views(inParams.views) , waitSemaphore(inParams.waitSemaphore) , signalSemaphore(inParams.signalSemaphore) @@ -27,5 +28,13 @@ namespace Render { void StandardRenderer::Render(float inDeltaTimeSeconds) { // TODO + FinalizeViews(); + } + + void StandardRenderer::FinalizeViews() const + { + for (const auto& view : views) { + view.state->prevData = view.data; + } } } diff --git a/Engine/Source/Render/Src/ShaderCompiler.cpp b/Engine/Source/Render/Src/ShaderCompiler.cpp index f4c2154d8..a3afb8fa6 100644 --- a/Engine/Source/Render/Src/ShaderCompiler.cpp +++ b/Engine/Source/Render/Src/ShaderCompiler.cpp @@ -332,7 +332,7 @@ namespace Render { return instance; } - ShaderCompiler::ShaderCompiler() : threadPool("ShaderCompiler", 16) + ShaderCompiler::ShaderCompiler() : threadPool("ShaderCompiler", 4) { } diff --git a/Engine/Source/Render/Src/View.cpp b/Engine/Source/Render/Src/View.cpp index f533879ff..51f285bcd 100644 --- a/Engine/Source/Render/Src/View.cpp +++ b/Engine/Source/Render/Src/View.cpp @@ -5,7 +5,7 @@ #include namespace Render { - ViewRenderData::ViewRenderData() + ViewData::ViewData() : viewMatrix(Common::FMat4x4Consts::identity) , projectionMatrix(Common::FMat4x4Consts::identity) , viewport() diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h b/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h index d7cf5cfc9..625c068cb 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Asset.h @@ -20,10 +20,11 @@ namespace Runtime { struct RUNTIME_API EClass() Asset { - EClassBody(Asset) + EPolyClassBody(Asset) Asset(); explicit Asset(Core::Uri inUri); + virtual ~Asset(); EProperty() Core::Uri uri; }; @@ -31,18 +32,18 @@ namespace Runtime { template A> class AssetPtr { public: - template A2> AssetPtr(Common::SharedPtr& sharedPtr); // NOLINT + template A2> AssetPtr(const Common::SharedPtr& sharedPtr); // NOLINT template A2> AssetPtr(Common::SharedPtr&& sharedPtr) noexcept; // NOLINT AssetPtr(A* pointer); // NOLINT - AssetPtr(AssetPtr& other); // NOLINT + AssetPtr(const AssetPtr& other); // NOLINT AssetPtr(AssetPtr&& other) noexcept; // NOLINT AssetPtr(); ~AssetPtr(); - template A2> AssetPtr& operator=(Common::SharedPtr& sharedPtr); + template A2> AssetPtr& operator=(const Common::SharedPtr& sharedPtr); template A2> AssetPtr& operator=(Common::SharedPtr&& sharedPtr) noexcept; AssetPtr& operator=(A* pointer); - AssetPtr& operator=(AssetPtr& other); // NOLINT + AssetPtr& operator=(const AssetPtr& other); // NOLINT AssetPtr& operator=(AssetPtr&& other) noexcept; const Core::Uri& Uri() const; @@ -139,14 +140,14 @@ namespace Common { static size_t Serialize(BinarySerializeStream& stream, const Runtime::AssetPtr& value) { - return Serializer::Serialize(stream, value); + return Serializer::Serialize(stream, value.Uri()); } static size_t Deserialize(BinaryDeserializeStream& stream, Runtime::AssetPtr& value) { Core::Uri uri; const auto deserialized = Serializer::Deserialize(stream, uri); - value = Runtime::AssetManager::Get().SyncLoad(uri, uri); + value = Runtime::AssetManager::Get().SyncLoad(uri); return deserialized; } }; @@ -157,7 +158,7 @@ namespace Common { static size_t Serialize(BinarySerializeStream& stream, const Runtime::SoftAssetPtr& value) { - return Serializer::Serialize(stream, value); + return Serializer::Serialize(stream, value.Uri()); } static size_t Deserialize(BinaryDeserializeStream& stream, Runtime::SoftAssetPtr& value) @@ -173,7 +174,7 @@ namespace Common { namespace Runtime { template A> template A2> - AssetPtr::AssetPtr(Common::SharedPtr& sharedPtr) + AssetPtr::AssetPtr(const Common::SharedPtr& sharedPtr) : ptr(sharedPtr) { } @@ -192,7 +193,7 @@ namespace Runtime { } template A> - AssetPtr::AssetPtr(AssetPtr& other) + AssetPtr::AssetPtr(const AssetPtr& other) : ptr(other.ptr) { } @@ -211,7 +212,7 @@ namespace Runtime { template A> template A2> - AssetPtr& AssetPtr::operator=(Common::SharedPtr& sharedPtr) + AssetPtr& AssetPtr::operator=(const Common::SharedPtr& sharedPtr) { ptr = sharedPtr; return *this; @@ -233,7 +234,7 @@ namespace Runtime { } template A> - AssetPtr& AssetPtr::operator=(AssetPtr& other) + AssetPtr& AssetPtr::operator=(const AssetPtr& other) { ptr = other.ptr; return *this; @@ -508,7 +509,7 @@ namespace Runtime { template A> void AssetManager::AsyncLoad(const Core::Uri& uri, const OnAssetLoaded& onAssetLoaded) { - threadPool.EmplaceTask([=]() -> void { + threadPool.EmplaceTask([=, this]() -> void { AssetPtr result = nullptr; { std::unique_lock lock(mutex); @@ -574,7 +575,7 @@ namespace Runtime { const Core::AssetUriParser parser(uri); Common::BinaryFileDeserializeStream stream(parser.Parse().Absolute().String()); - AssetPtr result = Common::SharedPtr(new A()); + AssetPtr result = Common::SharedPtr(new A(uri)); Mirror::Any ref = std::ref(*result.Get()); ref.Deserialize(stream); diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Level.h b/Engine/Source/Runtime/Include/Runtime/Asset/Level.h index 8aafe8b53..3db1f3397 100644 --- a/Engine/Source/Runtime/Include/Runtime/Asset/Level.h +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Level.h @@ -10,10 +10,11 @@ #include namespace Runtime { - struct RUNTIME_API EClass() Level : public Asset { - EClassBody(Level) + struct RUNTIME_API EClass() Level final : Asset { + EPolyClassBody(Level) explicit Level(Core::Uri inUri); + ~Level() override; EProperty() ECArchive archive; }; diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Material.h b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h new file mode 100644 index 000000000..9dd175ad6 --- /dev/null +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Material.h @@ -0,0 +1,41 @@ +// +// Created by johnk on 2025/3/21. +// + +#pragma once + +#include +#include +#include + +namespace Runtime { + enum class EEnum() MaterialType : uint8_t { + surface, + volume, + postProcess, + max + }; + + class RUNTIME_API EClass() MaterialGraph { + EClassBody(MaterialGraph) + + public: + MaterialGraph(); + + private: + // TODO nodes etc. + }; + + struct RUNTIME_API EClass() Material final : Asset { + EPolyClassBody(Material) + + explicit Material(Core::Uri inUri); + ~Material() override; + + MaterialType type; + std::string sourceCode; +#if BUILD_EDITOR + MaterialGraph graph; +#endif + }; +} diff --git a/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h new file mode 100644 index 000000000..d494f825e --- /dev/null +++ b/Engine/Source/Runtime/Include/Runtime/Asset/Mesh.h @@ -0,0 +1,44 @@ +// +// Created by johnk on 2025/3/21. +// + +#pragma once + +#include +#include +#include +#include +#include + +namespace Runtime { + struct RUNTIME_API EClass() StaticMeshVertices { + EClassBody(MeshVerticesData) + + EProperty() uint32_t vertexCount; + EProperty() uint32_t indexCount; + EProperty() std::vector positions; + EProperty() std::vector tangents; + EProperty() std::vector uv0; + // optional + EProperty() std::vector uv1; + EProperty() std::vector colors; + }; + + struct RUNTIME_API EClass() StaticMeshLOD { + EClassBody(MeshLOD) + + EProperty() StaticMeshVertices vertices; + // TODO distance field data ? + // TODO voxel data ? + }; + + struct RUNTIME_API EClass() StaticMesh final : Asset { + EPolyClassBody(StaticMesh) + + explicit StaticMesh(Core::Uri inUri); + ~StaticMesh() override; + + EProperty() AssetPtr material; + EProperty() std::vector lodVec; + }; +} diff --git a/Engine/Source/Runtime/Include/Runtime/Component/View.h b/Engine/Source/Runtime/Include/Runtime/Component/Camera.h similarity index 100% rename from Engine/Source/Runtime/Include/Runtime/Component/View.h rename to Engine/Source/Runtime/Include/Runtime/Component/Camera.h diff --git a/Engine/Source/Runtime/Include/Runtime/Component/Player.h b/Engine/Source/Runtime/Include/Runtime/Component/Player.h index ae70a1fca..dec3b8cb9 100644 --- a/Engine/Source/Runtime/Include/Runtime/Component/Player.h +++ b/Engine/Source/Runtime/Include/Runtime/Component/Player.h @@ -10,23 +10,36 @@ #include namespace Runtime { + struct RUNTIME_API EClass(globalComp, transient) PlayersInfo { + EClassBody(PlayersInfo) + + PlayersInfo(); + + std::vector players; + }; + struct RUNTIME_API EClass(transient) LocalPlayer { EClassBody(Player) LocalPlayer(); - Entity activeCamera; + uint8_t localPlayerIndex; Render::ViewState* viewState; }; #if BUILD_EDITOR - struct RUNTIME_API EClass(transient) EditorVirtualPlayer { + struct RUNTIME_API EClass(transient) EditorPlayer { EClassBody(EditorVirtualPlayer) - EditorVirtualPlayer(); + EditorPlayer(); - Entity activeCamera; Render::ViewState* viewState; }; #endif + + struct RUNTIME_API EClass() PlayerStart { + EClassBody(PlayerStart) + + PlayerStart(); + }; } diff --git a/Engine/Source/Runtime/Include/Runtime/ECS.h b/Engine/Source/Runtime/Include/Runtime/ECS.h index 5d2aea399..776a01469 100644 --- a/Engine/Source/Runtime/Include/Runtime/ECS.h +++ b/Engine/Source/Runtime/Include/Runtime/ECS.h @@ -246,6 +246,7 @@ namespace Runtime { NonMovable(BasicView) template void Each(F&& inFunc) const; + const ResultVector& All() const; size_t Count() const; ConstIter Begin() const; ConstIter End() const; @@ -750,7 +751,7 @@ namespace Runtime { Evaluate(inRegistry); } - template + template template void BasicView, C...>::Each(F&& inFunc) const { @@ -763,6 +764,12 @@ namespace Runtime { } } + template + const typename BasicView, C...>::ResultVector& BasicView, C...>::All() const + { + return result; + } + template size_t BasicView, C...>::Count() const { diff --git a/Engine/Source/Runtime/Include/Runtime/System/Player.h b/Engine/Source/Runtime/Include/Runtime/System/Player.h index 48db565a0..8cf430c7b 100644 --- a/Engine/Source/Runtime/Include/Runtime/System/Player.h +++ b/Engine/Source/Runtime/Include/Runtime/System/Player.h @@ -4,3 +4,78 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include + +namespace Runtime { + class RUNTIME_API EClass() PlayerSystem final : public System { + EClassBody(PlayerSystem) + + public: + NonCopyable(PlayerSystem) + NonMovable(PlayerSystem) + + PlayerSystem(ECRegistry& inRegistry, const SystemSetupContext& inContext); + ~PlayerSystem() override; + + private: + template Entity CreatePlayer(); + template void CreatePlayerSpecialPart(T& inPlayer); + template void FinalizePlayer(Entity inEntity); + + uint8_t activeLocalPlayerNum; + Render::RenderModule& renderModule; + }; +} + +namespace Runtime { + template + Entity PlayerSystem::CreatePlayer() + { + const auto& playerStartQuery = registry.View().All(); + Assert(playerStartQuery.size() == 1); + const auto& [playerStartEntity, playerStart, playerStartTransform] = playerStartQuery[0]; + + const auto playerEntity = registry.Create(); + registry.Emplace(playerEntity); + registry.Emplace(playerEntity, playerStartTransform); + + auto& player = registry.Emplace(playerEntity); + player.viewState = renderModule.NewViewState(); + CreatePlayerSpecialPart(player); + return playerEntity; + } + + template + inline void PlayerSystem::CreatePlayerSpecialPart(T& inPlayer) // NOLINT + { + Unimplement(); + } + + template <> + inline void PlayerSystem::CreatePlayerSpecialPart(LocalPlayer& inPlayer) // NOLINT + { + inPlayer.localPlayerIndex = activeLocalPlayerNum++; + } + +#if BUILD_EDITOR + template <> + inline void PlayerSystem::CreatePlayerSpecialPart(EditorPlayer& inPlayer) // NOLINT + { + } +#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 ee0631088..d55d834b8 100644 --- a/Engine/Source/Runtime/Include/Runtime/System/Render.h +++ b/Engine/Source/Runtime/Include/Runtime/System/Render.h @@ -4,7 +4,14 @@ #pragma once +#include +#include +#include +#include +#include +#include #include +#include #include namespace Runtime { @@ -21,6 +28,40 @@ namespace Runtime { void Tick(float inDeltaTimeSeconds) override; private: - // TODO + static Common::URect GetPlayerViewport(uint32_t inWidth, uint32_t inHeight, uint8_t inPlayerNum, uint8_t inPlayerIndex); + template Render::View BuildViewForPlayer(Entity inEntity, uint8_t inPlayerNum, uint8_t inPlayerIndex) const; + std::vector BuildViews() const; + + Render::RenderModule& renderModule; + PlayType playType; + Client* client; + RHI::Fence* lastFrameFence; }; } + +namespace Runtime { + template + Render::View RenderSystem::BuildViewForPlayer(Entity inEntity, uint8_t inPlayerNum, uint8_t inPlayerIndex) const + { + const auto& player = registry.Get(inEntity); + const auto& camera = registry.Get(inEntity); + const auto& worldTransform = registry.Get(inEntity); + const auto& clientViewport = client->GetViewport(); + + const auto width = clientViewport.GetWidth(); + const auto height = clientViewport.GetHeight(); + + Render::View view = renderModule.CreateView(); + view.state = player.viewState; + view.data.viewport = GetPlayerViewport(width, height, inPlayerNum, inPlayerIndex); + view.data.viewMatrix = worldTransform.localToWorld.GetTransformMatrixNoScale().Inverse(); + 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(); + } else { + const Common::FReversedZOrthoProjection projection(static_cast(width), static_cast(height), camera.nearPlane, camera.farPlane); + view.data.projectionMatrix = projection.GetProjectionMatrix(); + } + return view; + } +} diff --git a/Engine/Source/Runtime/Include/Runtime/Viewport.h b/Engine/Source/Runtime/Include/Runtime/Viewport.h index 82e638ebc..5a828018d 100644 --- a/Engine/Source/Runtime/Include/Runtime/Viewport.h +++ b/Engine/Source/Runtime/Include/Runtime/Viewport.h @@ -24,11 +24,9 @@ namespace Runtime { virtual Client& GetClient() = 0; virtual PresentInfo GetNextPresentInfo() = 0; - virtual size_t GetWidth() = 0; - virtual size_t GetHeight() = 0; - + virtual size_t GetWidth() const = 0; + virtual size_t GetHeight() const = 0; // TODO mouse keyboard inputs etc. - // TODO resolution change etc. protected: Viewport(); diff --git a/Engine/Source/Runtime/Src/Asset/Asset.cpp b/Engine/Source/Runtime/Src/Asset/Asset.cpp index 01fc0c404..0d76ab3a6 100644 --- a/Engine/Source/Runtime/Src/Asset/Asset.cpp +++ b/Engine/Source/Runtime/Src/Asset/Asset.cpp @@ -12,6 +12,8 @@ namespace Runtime { { } + Asset::~Asset() = default; + AssetManager& AssetManager::Get() { static AssetManager instance; diff --git a/Engine/Source/Runtime/Src/Asset/Level.cpp b/Engine/Source/Runtime/Src/Asset/Level.cpp index eca3f9564..44aa90604 100644 --- a/Engine/Source/Runtime/Src/Asset/Level.cpp +++ b/Engine/Source/Runtime/Src/Asset/Level.cpp @@ -9,4 +9,6 @@ namespace Runtime { : Asset(std::move(inUri)) { } + + Level::~Level() = default; } diff --git a/Engine/Source/Runtime/Src/Asset/Material.cpp b/Engine/Source/Runtime/Src/Asset/Material.cpp new file mode 100644 index 000000000..56fb584bb --- /dev/null +++ b/Engine/Source/Runtime/Src/Asset/Material.cpp @@ -0,0 +1,17 @@ +// +// Created by johnk on 2025/3/21. +// + +#include + +namespace Runtime { + MaterialGraph::MaterialGraph() = default; + + Material::Material(Core::Uri inUri) + : Asset(std::move(inUri)) + , type(MaterialType::max) + { + } + + Material::~Material() = default; +} diff --git a/Engine/Source/Runtime/Src/Asset/Mesh.cpp b/Engine/Source/Runtime/Src/Asset/Mesh.cpp new file mode 100644 index 000000000..f2674c9f1 --- /dev/null +++ b/Engine/Source/Runtime/Src/Asset/Mesh.cpp @@ -0,0 +1,14 @@ +// +// Created by johnk on 2025/3/21. +// + +#include + +namespace Runtime { + StaticMesh::StaticMesh(Core::Uri inUri) + : Asset(std::move(inUri)) + { + } + + StaticMesh::~StaticMesh() = default; +} diff --git a/Engine/Source/Runtime/Src/Component/View.cpp b/Engine/Source/Runtime/Src/Component/Camera.cpp similarity index 81% rename from Engine/Source/Runtime/Src/Component/View.cpp rename to Engine/Source/Runtime/Src/Component/Camera.cpp index e241cbc5e..b5165f70a 100644 --- a/Engine/Source/Runtime/Src/Component/View.cpp +++ b/Engine/Source/Runtime/Src/Component/Camera.cpp @@ -2,7 +2,7 @@ // Created by johnk on 2024/10/14. // -#include +#include namespace Runtime { Camera::Camera() diff --git a/Engine/Source/Runtime/Src/Component/Player.cpp b/Engine/Source/Runtime/Src/Component/Player.cpp index f96b01124..adf96d718 100644 --- a/Engine/Source/Runtime/Src/Component/Player.cpp +++ b/Engine/Source/Runtime/Src/Component/Player.cpp @@ -5,15 +5,20 @@ #include namespace Runtime { + PlayersInfo::PlayersInfo() = default; + LocalPlayer::LocalPlayer() - : activeCamera(entityNull) + : localPlayerIndex(0) + , viewState(nullptr) { } #if BUILD_EDITOR - EditorVirtualPlayer::EditorVirtualPlayer() - : activeCamera(entityNull) + EditorPlayer::EditorPlayer() + : viewState(nullptr) { } #endif -} + + PlayerStart::PlayerStart() = default; +} // namespace Runtime diff --git a/Engine/Source/Runtime/Src/ECS.cpp b/Engine/Source/Runtime/Src/ECS.cpp index bfd90bb1f..7335ee8c5 100644 --- a/Engine/Source/Runtime/Src/ECS.cpp +++ b/Engine/Source/Runtime/Src/ECS.cpp @@ -4,6 +4,7 @@ #include +#include #include namespace Runtime { @@ -1247,13 +1248,14 @@ namespace Runtime { void SystemPipeline::ParallelPerformAction(const ActionFunc& inActionFunc) { tf::Taskflow taskFlow; - auto lastBarrier = taskFlow.emplace([]() -> void {}); + auto lastBarrier = taskFlow.emplace([]() -> void { Core::ScopedThreadTag threadTag(Core::ThreadTag::gameWorker); }); for (auto& groupContext : systemGraph) { if (groupContext.strategy == SystemExecuteStrategy::sequential) { tf::Task lastTask = lastBarrier; for (auto& systemContext : groupContext.systems) { auto task = taskFlow.emplace([&]() -> void { + Core::ScopedThreadTag threadTag(Core::ThreadTag::gameWorker); inActionFunc(systemContext); }); task.succeed(lastTask); @@ -1266,12 +1268,13 @@ namespace Runtime { for (auto& systemContext : groupContext.systems) { tasks.emplace_back(taskFlow.emplace([&]() -> void { + Core::ScopedThreadTag threadTag(Core::ThreadTag::gameWorker); inActionFunc(systemContext); })); tasks.back().succeed(lastBarrier); } - auto barrier = taskFlow.emplace([]() -> void {}); + auto barrier = taskFlow.emplace([]() -> void { Core::ScopedThreadTag threadTag(Core::ThreadTag::gameWorker); }); for (const auto& task : tasks) { barrier.succeed(task); } diff --git a/Engine/Source/Runtime/Src/System/Player.cpp b/Engine/Source/Runtime/Src/System/Player.cpp index 0ac67fd29..1c4397590 100644 --- a/Engine/Source/Runtime/Src/System/Player.cpp +++ b/Engine/Source/Runtime/Src/System/Player.cpp @@ -2,8 +2,38 @@ // Created by johnk on 2025/3/13. // -#include +#include +#include +#include +#include namespace Runtime { + PlayerSystem::PlayerSystem(ECRegistry& inRegistry, const SystemSetupContext& inContext) + : System(inRegistry, inContext) + , activeLocalPlayerNum(0) + , renderModule(EngineHolder::Get().GetRenderModule()) + { + auto& playersInfo = registry.GEmplace(); -} +#if BUILD_EDITOR + if (inContext.playType == PlayType::editor) { + playersInfo.players.emplace_back(CreatePlayer()); + } +#endif + if (inContext.playType == PlayType::game) { + const auto& gameSettings = SettingsRegistry::Get().GetSettings(); + playersInfo.players.resize(gameSettings.initialLocalPlayerNum); + for (auto& playerEntity : playersInfo.players) { + playerEntity = CreatePlayer(); + } + } + } + + 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 + } +} // namespace Runtime diff --git a/Engine/Source/Runtime/Src/System/Render.cpp b/Engine/Source/Runtime/Src/System/Render.cpp index 561c76ca2..9c1c1ad46 100644 --- a/Engine/Source/Runtime/Src/System/Render.cpp +++ b/Engine/Source/Runtime/Src/System/Render.cpp @@ -2,18 +2,97 @@ // Created by johnk on 2025/3/4. // +#include +#include +#include +#include #include namespace Runtime { RenderSystem::RenderSystem(ECRegistry& inRegistry, const SystemSetupContext& inContext) : System(inRegistry, inContext) + , renderModule(EngineHolder::Get().GetRenderModule()) + , playType(inContext.playType) + , client(inContext.client) + , lastFrameFence(renderModule.GetDevice()->CreateFence(true).Release()) { } - RenderSystem::~RenderSystem() = default; + RenderSystem::~RenderSystem() // NOLINT + { + renderModule.GetRenderThread().EmplaceTask([fence = lastFrameFence]() -> void { + fence->Wait(); + delete fence; + }); + } void RenderSystem::Tick(float inDeltaTimeSeconds) { - // TODO + auto& clientViewport = client->GetViewport(); + renderModule.GetRenderThread().EmplaceTask( + [ + fence = lastFrameFence, + views = BuildViews(), + scene = registry.GGet().scene, + surfaceExtent = Common::UVec2(clientViewport.GetWidth(), clientViewport.GetHeight()), + presentInfo = clientViewport.GetNextPresentInfo(), + renderModule = &renderModule, + inDeltaTimeSeconds + ]() -> void { + fence->Wait(); + fence->Reset(); + + Render::StandardRenderer::Params rendererParams; + rendererParams.scene = scene; + rendererParams.surface = presentInfo.backBuffer; + rendererParams.surfaceExtent = surfaceExtent; + rendererParams.views = views; + rendererParams.waitSemaphore = presentInfo.imageReadySemaphore; + rendererParams.signalSemaphore = presentInfo.renderFinishedSemaphore; + rendererParams.signalFence = fence; + + auto renderer = renderModule->CreateStandardRenderer(rendererParams); + renderer.Render(inDeltaTimeSeconds); + }); + } + + Common::URect RenderSystem::GetPlayerViewport(uint32_t inWidth, uint32_t inHeight, uint8_t inPlayerNum, uint8_t inPlayerIndex) + { + Assert(inPlayerNum > 0 && inPlayerIndex < inPlayerNum); + if (inPlayerNum == 1) { + return { 0, 0, inWidth, inHeight }; + } + if (inPlayerNum == 2) { + const auto widthPerPlayer = inWidth / 2; + return { widthPerPlayer * inPlayerIndex, 0, widthPerPlayer, inHeight }; + } + if (inPlayerNum <= 4) { + const auto widthPerPlayer = inWidth / 2; + const auto heightPerPlayer = inHeight / 2; + return { widthPerPlayer * (inPlayerIndex % 2), heightPerPlayer * (inPlayerIndex / 2), widthPerPlayer, heightPerPlayer }; + } + Unimplement(); + return {}; + } + + std::vector RenderSystem::BuildViews() const + { + const auto& playersInfo = registry.GGet(); + const auto playerNum = playersInfo.players.size(); + + std::vector result; + result.reserve(playerNum); + + for (auto i = 0; i < playerNum; i++) { + if (registry.Has(i)) { + result.emplace_back(BuildViewForPlayer(playersInfo.players[i], playerNum, i)); + } + #if BUILD_EDITOR + if (registry.Has(i)) { + result.emplace_back(BuildViewForPlayer(playersInfo.players[i], playerNum, i)); + } + #endif + } + return result; } } diff --git a/Engine/Source/Runtime/Src/SystemGraphPresets.cpp b/Engine/Source/Runtime/Src/SystemGraphPresets.cpp index 9085d5cbf..9d5c1c522 100644 --- a/Engine/Source/Runtime/Src/SystemGraphPresets.cpp +++ b/Engine/Source/Runtime/Src/SystemGraphPresets.cpp @@ -2,10 +2,11 @@ // Created by johnk on 2025/3/13. // -#include +#include #include #include #include +#include namespace Runtime { const SystemGraph& SystemGraphPresets::Default3DWorld() @@ -13,6 +14,9 @@ namespace Runtime { static SystemGraph graph = []() -> SystemGraph { SystemGraph systemGraph; + auto& preTransformGroup = systemGraph.AddGroup("PreTransformConcurrent", SystemExecuteStrategy::concurrent); + preTransformGroup.EmplaceSystem(); + auto& transformGroup = systemGraph.AddGroup("Transform", SystemExecuteStrategy::sequential); transformGroup.EmplaceSystem(); diff --git a/Engine/Source/Runtime/Test/AssetTest.cpp b/Engine/Source/Runtime/Test/AssetTest.cpp index 5348e58c2..066421ef5 100644 --- a/Engine/Source/Runtime/Test/AssetTest.cpp +++ b/Engine/Source/Runtime/Test/AssetTest.cpp @@ -8,7 +8,7 @@ TEST(AssetTest, AssetRefTest0) { - AssetPtr a0 = MakeShared(); + AssetPtr a0 = MakeShared(Core::Uri("")); ASSERT_EQ(a0.RefCount(), 1); AssetPtr a1 = a0; @@ -23,7 +23,7 @@ TEST(AssetTest, AssetRefTest0) TEST(AssetTest, AssetRefTest1) { - AssetPtr a0 = MakeShared(); + AssetPtr a0 = MakeShared(Core::Uri("")); AssetPtr a1 = std::move(a0); ASSERT_EQ(a1.RefCount(), 1); diff --git a/Engine/Source/Runtime/Test/AssetTest.h b/Engine/Source/Runtime/Test/AssetTest.h index ac7b267c4..4fe75e6de 100644 --- a/Engine/Source/Runtime/Test/AssetTest.h +++ b/Engine/Source/Runtime/Test/AssetTest.h @@ -12,8 +12,8 @@ using namespace Runtime; struct EClass() TestAsset : public Asset { EClassBody(TestAsset) - TestAsset() - : Asset(Core::Uri("")) + explicit TestAsset(Core::Uri uri) + : Asset(std::move(uri)) , a(0) , b() { diff --git a/Tool/MirrorTool/Src/Generator.cpp b/Tool/MirrorTool/Src/Generator.cpp index 526506a04..14a4a803b 100644 --- a/Tool/MirrorTool/Src/Generator.cpp +++ b/Tool/MirrorTool/Src/Generator.cpp @@ -89,7 +89,7 @@ namespace MirrorTool { std::stringstream stream; stream << Common::newline; - stream << Common::tab<2> << std::format(R"("Mirror::Registry::Get().UnloadEnum("{}");")", fullName) << Common::newline; + stream << Common::tab<2> << std::format(R"(Mirror::Registry::Get().UnloadEnum("{}");)", fullName) << Common::newline; return stream.str(); } From 0916663d8dd38da3c35278df8853e1b923e8adb0 Mon Sep 17 00:00:00 2001 From: FlyAntNotDown <461425614@qq.com> Date: Sat, 22 Mar 2025 10:37:05 +0800 Subject: [PATCH 6/6] refactor: remove timer in graphics widget and change graphics sample widget to multithread --- .../Editor/Widget/GraphicsSampleWidget.h | 9 +- Editor/Include/Editor/Widget/GraphicsWidget.h | 25 +---- Editor/Src/Widget/GraphicsSampleWidget.cpp | 80 ++++++++++----- Editor/Src/Widget/GraphicsWidget.cpp | 98 +------------------ 4 files changed, 66 insertions(+), 146 deletions(-) diff --git a/Editor/Include/Editor/Widget/GraphicsSampleWidget.h b/Editor/Include/Editor/Widget/GraphicsSampleWidget.h index 2a6f53dbe..79920ddd3 100644 --- a/Editor/Include/Editor/Widget/GraphicsSampleWidget.h +++ b/Editor/Include/Editor/Widget/GraphicsSampleWidget.h @@ -20,17 +20,18 @@ namespace Editor { protected: void resizeEvent(QResizeEvent* event) override; - void OnDrawFrame() override; private: static constexpr uint8_t swapChainTextureNum = 2; - static GraphicsWidgetDesc GetGraphicsWidgetDesc(); - void FetchSwapChainTextures(); + void RecreateSwapChain(uint32_t inWidth, uint32_t inHeight); + void DispatchFrame() const; + void DrawFrame() const; Common::UniquePtr imageReadySemaphore; Common::UniquePtr renderFinishedSemaphore; Common::UniquePtr frameFence; + Common::UniquePtr swapChain; std::array swapChainTextures; std::array, 2> swapChainTextureViews; Render::ShaderCompileOutput vsCompileOutput; @@ -46,5 +47,7 @@ namespace Editor { Common::UniquePtr uniformBufferView; Common::UniquePtr bindGroup; Common::UniquePtr commandBuffer; + Common::UniquePtr drawThread; + std::atomic_bool running; }; } diff --git a/Editor/Include/Editor/Widget/GraphicsWidget.h b/Editor/Include/Editor/Widget/GraphicsWidget.h index 76d516dd2..88e707816 100644 --- a/Editor/Include/Editor/Widget/GraphicsWidget.h +++ b/Editor/Include/Editor/Widget/GraphicsWidget.h @@ -11,45 +11,22 @@ #include namespace Editor { - struct GraphicsWidgetDesc { - uint8_t textureNum; - std::vector formatQualifiers; - RHI::PresentMode presentMode; - }; - class GraphicsWidget : public QWidget { Q_OBJECT public: - explicit GraphicsWidget(const GraphicsWidgetDesc& inDesc, QWidget* inParent = nullptr); + explicit GraphicsWidget(QWidget* inParent = nullptr); ~GraphicsWidget() override; - uint8_t GetTextureNum() const; - RHI::PixelFormat GetPixelFormat() const; - RHI::PresentMode GetPresentMode() const; RHI::Device& GetDevice() const; RHI::Surface& GetSurface() const; - RHI::SwapChain& GetSwapChain() const; protected: QPaintEngine* paintEngine() const override; - void resizeEvent(QResizeEvent* event) override; - virtual void OnDrawFrame(); void WaitDeviceIdle() const; - double GetLastTimeSeconds() const; - double GetCurrentTimeSeconds() const; - float GetDeltaTimeSeconds() const; - uint8_t textureNum; - RHI::PixelFormat pixelFormat; - RHI::PresentMode presentMode; RHI::Device* device; Common::UniquePtr surface; - Common::UniquePtr swapChain; - QTimer* timer; - double lastTimeSeconds; - double currentTimeSeconds; - float deltaTimeSeconds; }; } diff --git a/Editor/Src/Widget/GraphicsSampleWidget.cpp b/Editor/Src/Widget/GraphicsSampleWidget.cpp index df9d4ec42..b01cd42b4 100644 --- a/Editor/Src/Widget/GraphicsSampleWidget.cpp +++ b/Editor/Src/Widget/GraphicsSampleWidget.cpp @@ -2,6 +2,7 @@ // Created by Kindem on 2025/3/16. // +#include #include #include // NOLINT @@ -14,30 +15,20 @@ namespace Editor { Common::FVec3 color; }; - GraphicsWidgetDesc GraphicsSampleWidget::GetGraphicsWidgetDesc() - { - GraphicsWidgetDesc result; - result.textureNum = swapChainTextureNum; - result.formatQualifiers = {RHI::PixelFormat::rgba8Unorm, RHI::PixelFormat::bgra8Unorm}; - result.presentMode = RHI::PresentMode::immediately; - return result; - } - GraphicsSampleWidget::GraphicsSampleWidget(QWidget* inParent) - : GraphicsWidget(GetGraphicsWidgetDesc(), inParent) + : GraphicsWidget(inParent) , imageReadySemaphore(GetDevice().CreateSemaphore()) , renderFinishedSemaphore(GetDevice().CreateSemaphore()) , frameFence(GetDevice().CreateFence(true)) + , drawThread(Common::MakeUnique("DrawThread")) { - setFixedWidth(1024); - setFixedHeight(768); - - FetchSwapChainTextures(); + resize(1024, 768); + RecreateSwapChain(width(), height()); Render::ShaderCompileOptions shaderCompileOptions; shaderCompileOptions.includePaths = {"../Shader/Engine"}; shaderCompileOptions.byteCodeType = GetDevice().GetGpu().GetInstance().GetRHIType() == RHI::RHIType::directX12 ? Render::ShaderByteCodeType::dxil : Render::ShaderByteCodeType::spirv; - shaderCompileOptions.withDebugInfo = static_cast(BUILD_CONFIG_DEBUG); + shaderCompileOptions.withDebugInfo = static_cast(BUILD_CONFIG_DEBUG); // NOLINT { Render::ShaderCompileInput shaderCompileInput; @@ -127,10 +118,15 @@ namespace Editor { .AddEntry(RHI::BindGroupEntry(vsCompileOutput.reflectionData.QueryResourceBindingChecked("vsUniform").second, uniformBufferView.Get()))); commandBuffer = GetDevice().CreateCommandBuffer(); + + running = true; + DispatchFrame(); } GraphicsSampleWidget::~GraphicsSampleWidget() { + running = false; + drawThread.Reset(); WaitDeviceIdle(); } @@ -138,13 +134,43 @@ namespace Editor { { GraphicsWidget::resizeEvent(event); - FetchSwapChainTextures(); + drawThread->EmplaceTask([this, size = event->size()]() -> void { + RecreateSwapChain(size.width(), size.height()); + }); } - void GraphicsSampleWidget::FetchSwapChainTextures() + void GraphicsSampleWidget::RecreateSwapChain(uint32_t inWidth, uint32_t inHeight) { + static std::vector formatQualifiers = { + RHI::PixelFormat::rgba8Unorm, + RHI::PixelFormat::bgra8Unorm}; + + if (swapChain != nullptr) { + WaitDeviceIdle(); + 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)); + for (auto i = 0; i < swapChainTextureNum; i++) { - swapChainTextures[i] = GetSwapChain().GetTexture(i); + swapChainTextures[i] = swapChain->GetTexture(i); swapChainTextureViews[i] = swapChainTextures[i]->CreateTextureView( RHI::TextureViewCreateInfo() .SetDimension(RHI::TextureViewDimension::tv2D) @@ -155,14 +181,20 @@ namespace Editor { } } - void GraphicsSampleWidget::OnDrawFrame() + void GraphicsSampleWidget::DispatchFrame() const { - GraphicsWidget::OnDrawFrame(); + if (!running) { + return; + } + drawThread->EmplaceTask([this]() -> void { DrawFrame(); }); + } + void GraphicsSampleWidget::DrawFrame() const + { frameFence->Wait(); frameFence->Reset(); - const double currentTimeSeconds = GetCurrentTimeSeconds(); + const double currentTimeSeconds = Common::TimePoint::Now().ToSeconds(); const GraphicsWindowSampleVsUniform uniform = {{ (std::sin(currentTimeSeconds) + 1) / 2, (std::cos(currentTimeSeconds) + 1) / 2, @@ -172,7 +204,7 @@ namespace Editor { memcpy(uniformData, &uniform, sizeof(GraphicsWindowSampleVsUniform)); uniformBuffer->UnMap(); - const auto backTextureIndex = GetSwapChain().AcquireBackTexture(imageReadySemaphore.Get()); + const auto backTextureIndex = swapChain->AcquireBackTexture(imageReadySemaphore.Get()); const Common::UniquePtr commandRecorder = commandBuffer->Begin(); { commandRecorder->ResourceBarrier(RHI::Barrier::Transition(swapChainTextures[backTextureIndex], RHI::TextureState::present, RHI::TextureState::renderTarget)); @@ -199,6 +231,8 @@ namespace Editor { .AddWaitSemaphore(imageReadySemaphore.Get()) .AddSignalSemaphore(renderFinishedSemaphore.Get()) .SetSignalFence(frameFence.Get())); - GetSwapChain().Present(renderFinishedSemaphore.Get()); + swapChain->Present(renderFinishedSemaphore.Get()); + + DispatchFrame(); } } // namespace Editor diff --git a/Editor/Src/Widget/GraphicsWidget.cpp b/Editor/Src/Widget/GraphicsWidget.cpp index 30347fe08..d9674caea 100644 --- a/Editor/Src/Widget/GraphicsWidget.cpp +++ b/Editor/Src/Widget/GraphicsWidget.cpp @@ -2,18 +2,12 @@ // Created by Kindem on 2025/3/16. // -#include #include #include // NOLINT namespace Editor { - GraphicsWidget::GraphicsWidget(const GraphicsWidgetDesc& inDesc, QWidget* inParent) + GraphicsWidget::GraphicsWidget(QWidget* inParent) : QWidget(inParent) - , textureNum(inDesc.textureNum) - , presentMode(inDesc.presentMode) - , lastTimeSeconds(Common::TimePoint::Now().ToSeconds()) - , currentTimeSeconds(Common::TimePoint::Now().ToSeconds()) - , deltaTimeSeconds(0.0f) { setAttribute(Qt::WA_NativeWindow); setAttribute(Qt::WA_PaintOnScreen); @@ -26,52 +20,9 @@ namespace Editor { surface = device->CreateSurface( RHI::SurfaceCreateInfo() .SetWindow(reinterpret_cast(winId()))); // NOLINT - - pixelFormat = RHI::PixelFormat::max; - for (const auto format : inDesc.formatQualifiers) { - if (device->CheckSwapChainFormatSupport(surface.Get(), format)) { - pixelFormat = format; - break; - } - } - - swapChain = device->CreateSwapChain( - RHI::SwapChainCreateInfo() - .SetPresentQueue(device->GetQueue(RHI::QueueType::graphics, 0)) - .SetSurface(surface.Get()) - .SetTextureNum(inDesc.textureNum) - .SetFormat(pixelFormat) - .SetWidth(width()) - .SetHeight(height()) - .SetPresentMode(inDesc.presentMode)); - - timer = new QTimer(this); - connect(timer, &QTimer::timeout, this, &GraphicsWidget::OnDrawFrame); - timer->start(0); - } - - GraphicsWidget::~GraphicsWidget() - { - disconnect(timer, &QTimer::timeout, this, &GraphicsWidget::OnDrawFrame); - timer->stop(); - - WaitDeviceIdle(); - } - - uint8_t GraphicsWidget::GetTextureNum() const - { - return textureNum; } - RHI::PixelFormat GraphicsWidget::GetPixelFormat() const - { - return pixelFormat; - } - - RHI::PresentMode GraphicsWidget::GetPresentMode() const - { - return presentMode; - } + GraphicsWidget::~GraphicsWidget() = default; RHI::Device& GraphicsWidget::GetDevice() const { @@ -83,60 +34,15 @@ namespace Editor { return *surface; } - RHI::SwapChain& GraphicsWidget::GetSwapChain() const - { - return *swapChain; - } - QPaintEngine* GraphicsWidget::paintEngine() const { return nullptr; } - void GraphicsWidget::resizeEvent(QResizeEvent* event) - { - WaitDeviceIdle(); - - const auto newSize = event->size(); - - swapChain.Reset(); - swapChain = device->CreateSwapChain( - RHI::SwapChainCreateInfo() - .SetPresentQueue(device->GetQueue(RHI::QueueType::graphics, 0)) - .SetSurface(surface.Get()) - .SetTextureNum(textureNum) - .SetFormat(pixelFormat) - .SetWidth(newSize.width()) - .SetHeight(newSize.height()) - .SetPresentMode(presentMode)); - } - - void GraphicsWidget::OnDrawFrame() - { - currentTimeSeconds = Common::TimePoint::Now().ToSeconds(); - deltaTimeSeconds = currentTimeSeconds - lastTimeSeconds; - lastTimeSeconds = currentTimeSeconds; - } - void GraphicsWidget::WaitDeviceIdle() const { const Common::UniquePtr fence = device->CreateFence(false); device->GetQueue(RHI::QueueType::graphics, 0)->Flush(fence.Get()); fence->Wait(); } - - double GraphicsWidget::GetLastTimeSeconds() const - { - return currentTimeSeconds; - } - - double GraphicsWidget::GetCurrentTimeSeconds() const - { - return currentTimeSeconds; - } - - float GraphicsWidget::GetDeltaTimeSeconds() const - { - return deltaTimeSeconds; - } } // namespace Editor