diff --git a/engine/src/engine/app.cpp b/engine/src/engine/app.cpp index 6f701ae..34cff57 100644 --- a/engine/src/engine/app.cpp +++ b/engine/src/engine/app.cpp @@ -11,8 +11,8 @@ namespace engineapi { const char* name = "zengine"; new AssetManager(); _RenderAPI = RenderAPI::MakeInstance(); - _RenderAPI->SetUpRenderPasses(); _Window = Window::MakeInstance(3, 640, 720, name); + _RenderAPI->OnInit(); auto scene_manager = new SceneManager(); scene_manager->LoadScene(path); } diff --git a/engine/src/engine/render/asset/material.cpp b/engine/src/engine/render/asset/material.cpp index 2c03d26..7995aa7 100644 --- a/engine/src/engine/render/asset/material.cpp +++ b/engine/src/engine/render/asset/material.cpp @@ -9,8 +9,4 @@ namespace engineapi { Material::~Material() { } - void Material::Use() - { - RenderAPI::GetSingletonPtr()->UseMaterial(mId); - } } diff --git a/engine/src/engine/render/asset/material.h b/engine/src/engine/render/asset/material.h index e056be0..c028a88 100644 --- a/engine/src/engine/render/asset/material.h +++ b/engine/src/engine/render/asset/material.h @@ -10,8 +10,5 @@ namespace engineapi { Material(string name, uint32_t flags); ~Material(); - - void Use(); - }; }; \ No newline at end of file diff --git a/engine/src/engine/render/asset/mesh.h b/engine/src/engine/render/asset/mesh.h index 0a1eee2..1a51fa1 100644 --- a/engine/src/engine/render/asset/mesh.h +++ b/engine/src/engine/render/asset/mesh.h @@ -4,7 +4,6 @@ namespace engineapi { class Texture; class Material; class Mesh : public Asset { - friend class RenderVulkanAPI; protected: uint32_t VAO = 0; vector mVertices; @@ -12,5 +11,16 @@ namespace engineapi { public: Mesh(string name, uint32_t flags, vector& vertices, vector& indices); void BeginLoad()override; + + public: + uint32_t& GetVAO() { + return VAO; + } + vector& GetVertices() { + return mVertices; + } + vector& GetIndices() { + return mIndices; + } }; }; \ No newline at end of file diff --git a/engine/src/engine/render/asset/shader.cpp b/engine/src/engine/render/asset/shader.cpp index 1512f7d..e6da9f7 100644 --- a/engine/src/engine/render/asset/shader.cpp +++ b/engine/src/engine/render/asset/shader.cpp @@ -13,8 +13,4 @@ namespace engineapi { { } - void Shader::Use() - { - RenderAPI::GetSingletonPtr()->UseShader(mId); - } } diff --git a/engine/src/engine/render/asset/shader.h b/engine/src/engine/render/asset/shader.h index f02d428..fa008b3 100644 --- a/engine/src/engine/render/asset/shader.h +++ b/engine/src/engine/render/asset/shader.h @@ -9,6 +9,5 @@ namespace engineapi { Shader(string name, uint32_t flags); ~Shader(); void BeginLoad()override; - void Use(); }; }; \ No newline at end of file diff --git a/engine/src/engine/render/node/rendernode.cpp b/engine/src/engine/render/node/rendernode.cpp new file mode 100644 index 0000000..3591a22 --- /dev/null +++ b/engine/src/engine/render/node/rendernode.cpp @@ -0,0 +1,9 @@ +#include "rendernode.h" +#include "../renderapi.h" +namespace engineapi { + RenderNode::RenderNode(RenderType type) + : mType(type) + { + mContext = RenderAPI::GetSingletonPtr()->GetContext(); + } +} \ No newline at end of file diff --git a/engine/src/engine/render/node/rendernode.h b/engine/src/engine/render/node/rendernode.h new file mode 100644 index 0000000..f263eca --- /dev/null +++ b/engine/src/engine/render/node/rendernode.h @@ -0,0 +1,32 @@ +#pragma once +#include "../asset/material.h" +#include "../asset/mesh.h" +#include "../asset/texture.h" +#include "../render_context.h" +namespace engineapi { + enum RenderType + { + RENDER_SHADOW_GENERATION, + RENDER_FORWARD_RENDERING, + RENDER_RAY_TRACING, + RENDER_AFTER_EFFECT_RENDERING, + RENDER_UI_RENDERING, + RENDER_COUNT + }; + class Camera; + class RenderNode + { + protected: + RenderType mType; + RenderContext* mContext; + public: + RenderNode(RenderType type); + ~RenderNode() {}; + + virtual void Render(Camera& camera) = 0; + public: + RenderType GetType() { + return mType; + } + }; +}; \ No newline at end of file diff --git a/engine/src/engine/render/pass/renderpass_forward.cpp b/engine/src/engine/render/node/rendernode_forward.cpp similarity index 69% rename from engine/src/engine/render/pass/renderpass_forward.cpp rename to engine/src/engine/render/node/rendernode_forward.cpp index a76bee7..9888096 100644 --- a/engine/src/engine/render/pass/renderpass_forward.cpp +++ b/engine/src/engine/render/node/rendernode_forward.cpp @@ -1,32 +1,23 @@ -#include "renderpass_forward.h" +#include "rendernode_forward.h" #include "../renderapi.h" #include "../window.h" #include "object/camera/camera.h" #include "../asset/model.h" #include "asset/asset_manager.h" namespace engineapi { - RenderPassForwardRendering::RenderPassForwardRendering() + RenderNodeForwardRendering::RenderNodeForwardRendering() + :RenderNode(RENDER_FORWARD_RENDERING) { - mID = 0; mSky = AssetManager::GetSingletonPtr()->LoadAsset("assets/models/SkyBoxMesh.ply", Asset::ASSET_SHARED_FLAG | Asset::ASSET_ASYNC_FLAG); //skyBoxMaterial = new Material(new Shader(Resources::GetAssetFullPath("Shaders/SkyBox.zxshader", true), FrameBufferType::Normal)); - skyBoxRenderState = new RenderStateSetting(); - skyBoxRenderState->depthTest = false; - skyBoxRenderState->depthWrite = false; - - opaqueRenderState = new RenderStateSetting(); - - transparentRenderState = new RenderStateSetting(); - transparentRenderState->depthWrite = false; - //drawCommandID = RenderAPI::GetSingletonPtr()->AllocateDrawCommand(CommandType::ForwardRendering); } - RenderPassForwardRendering::~RenderPassForwardRendering() + RenderNodeForwardRendering::~RenderNodeForwardRendering() { } - void RenderPassForwardRendering::Render(Camera& camera) + void RenderNodeForwardRendering::Render(Camera& camera) { auto renderAPI = RenderAPI::GetSingletonPtr(); auto window = Window::GetSingletonPtr(); @@ -36,9 +27,10 @@ namespace engineapi { //FBOManager::GetInstance()->SwitchFBO("Forward"); // ViewPort设置为窗口大小 renderAPI->SetViewPort(width, height); - + mContext->UsePass(mType); + mContext->UseContext(); } - void RenderPassForwardRendering::RenderSkyBox(Camera& camera) + void RenderNodeForwardRendering::RenderSkyBox(Camera& camera) { // 先转3x3再回4x4,把相机位移信息去除 Matrix4 mat_V = Matrix4(Matrix3(camera.GetViewMatrix())); @@ -52,7 +44,7 @@ namespace engineapi { //RenderAPI::GetInstance()->Draw(skyBox->VAO); } - void RenderPassForwardRendering::RenderBatches(const map>& batchs) + void RenderNodeForwardRendering::RenderBatches(const map>& batchs) { } diff --git a/engine/src/engine/render/pass/renderpass_forward.h b/engine/src/engine/render/node/rendernode_forward.h similarity index 50% rename from engine/src/engine/render/pass/renderpass_forward.h rename to engine/src/engine/render/node/rendernode_forward.h index 831a263..07cc329 100644 --- a/engine/src/engine/render/pass/renderpass_forward.h +++ b/engine/src/engine/render/node/rendernode_forward.h @@ -1,23 +1,19 @@ #pragma once -#include "renderpass.h" +#include "rendernode.h" #include "object/render/mesh_render.h" namespace engineapi { class Camera; class Model; - class RenderPassForwardRendering : public RenderPass + class RenderNodeForwardRendering : public RenderNode { public: - RenderPassForwardRendering(); - ~RenderPassForwardRendering(); + RenderNodeForwardRendering(); + ~RenderNodeForwardRendering(); virtual void Render(Camera& camera); private: - uint32_t mID; Model* mSky; - RenderStateSetting* skyBoxRenderState; - RenderStateSetting* opaqueRenderState; - RenderStateSetting* transparentRenderState; void RenderSkyBox(Camera& camera); void RenderBatches(const map>& batchs); diff --git a/engine/src/engine/render/pass/renderpass.h b/engine/src/engine/render/pass/renderpass.h deleted file mode 100644 index dff6f45..0000000 --- a/engine/src/engine/render/pass/renderpass.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once -#include "../asset/material.h" -#include "../asset/mesh.h" -#include "../asset/texture.h" -namespace engineapi { - enum RenderPassType - { - ZX_RENDER_PASS_SHADOW_GENERATION, - ZX_RENDER_PASS_FORWARD_RENDERING, - ZX_RENDER_PASS_RAY_TRACING, - ZX_RENDER_PASS_AFTER_EFFECT_RENDERING, - ZX_RENDER_PASS_UI_RENDERING, - ZX_RENDER_PASS_COUNT - }; - class Camera; - class RenderPass - { - protected: - RenderPassType mType; - public: - RenderPass(RenderPassType type) : mType(type){}; - ~RenderPass() {}; - - virtual void Render(Camera& camera) = 0; - public: - RenderPassType GetType() { - return mType; - } - }; - class RenderStateSetting - { - public: - bool depthTest = true; - bool depthWrite = true; - BlendFactor srcFactor = BlendFactor::SRC_ALPHA; - BlendFactor dstFactor = BlendFactor::ONE_MINUS_SRC_ALPHA; - Vector4 clearColor = Vector4(); - float clearDepth = 1.0f; - uint32_t clearStencil = 0; - bool faceCull = true; - FaceCullOption faceCullOption = FaceCullOption::Back; - }; -}; \ No newline at end of file diff --git a/engine/src/engine/render/render_context.h b/engine/src/engine/render/render_context.h index 8657518..c370b00 100644 --- a/engine/src/engine/render/render_context.h +++ b/engine/src/engine/render/render_context.h @@ -3,10 +3,21 @@ #include "asset/asset_render.h" namespace engineapi { - struct RenderContext { - uint32_t MaterialId; - uint32_t PassId; - uint32_t ShaderId; + class RenderContext { + public: + uint32_t MaterialId{ 0 }; + uint32_t PassId{ 0 }; + uint32_t ShaderId{ 0 }; + public: virtual void UseContext(){}; + virtual void UseMaterial(uint32_t ID) { + MaterialId = ID; + }; + virtual void UseShader(uint32_t ID) { + ShaderId = ID; + }; + virtual void UsePass(uint32_t ID) { + PassId = ID; + }; }; } \ No newline at end of file diff --git a/engine/src/engine/render/renderapi.cpp b/engine/src/engine/render/renderapi.cpp index 7b1e25d..970569a 100644 --- a/engine/src/engine/render/renderapi.cpp +++ b/engine/src/engine/render/renderapi.cpp @@ -1,6 +1,6 @@ #include "renderapi.h" -#include "pass/renderpass.h" -#include "pass/renderpass_forward.h" +#include "node/rendernode.h" +#include "node/rendernode_forward.h" #ifdef VULKAN_API #include "vulkanapi/vulkanapi.h" #endif // VULKAN_API @@ -9,32 +9,32 @@ namespace engineapi { { } - void RenderAPI::SetUpRenderPasses() + void RenderAPI::OnInit() { - mAllPasses.resize(ZX_RENDER_PASS_COUNT); - - //mAllPasses[ZX_RENDER_PASS_SHADOW_GENERATION] = new RenderPassShadowGeneration(); - mAllPasses[ZX_RENDER_PASS_FORWARD_RENDERING] = new RenderPassForwardRendering(); - //mAllPasses[ZX_RENDER_PASS_RAY_TRACING] = new RenderPassRayTracing(); - //mAllPasses[ZX_RENDER_PASS_AFTER_EFFECT_RENDERING] = new RenderPassAfterEffectRendering(); - //mAllPasses[ZX_RENDER_PASS_UI_RENDERING] = new RenderPassUIRendering(); - - mCurPasses.clear(); + InitRenderNode(); + InitRenderPass(); + } + void RenderAPI::InitRenderNode() + { + mAllNodes.clear(); + mAllNodes.resize(RENDER_COUNT); + mAllNodes[RENDER_FORWARD_RENDERING] = new RenderNodeForwardRendering(); + //mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_SHADOW_GENERATION]); - mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_FORWARD_RENDERING]); + mCurNodes.push_back(mAllNodes[RENDER_FORWARD_RENDERING]); //mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_AFTER_EFFECT_RENDERING]); //mCurPasses.push_back(mAllPasses[ZX_RENDER_PASS_UI_RENDERING]); } void RenderAPI::Render(Camera& camera) { - for (auto pass : mCurPasses) { - pass->Render(camera); + for (auto node : mCurNodes) { + node->Render(camera); } } RenderAPI* RenderAPI::MakeInstance() { #ifdef VULKAN_API - return new RenderVulkanAPI(); + return new vulkanapi::RenderVulkanAPI(); #endif } } \ No newline at end of file diff --git a/engine/src/engine/render/renderapi.h b/engine/src/engine/render/renderapi.h index 3d85acc..1518fb3 100644 --- a/engine/src/engine/render/renderapi.h +++ b/engine/src/engine/render/renderapi.h @@ -5,20 +5,23 @@ namespace engineapi { class Mesh; class Camera; - class RenderPass; + class RenderNode; class RenderAPI : public Singleton { protected: + uint32_t mFrame; ViewPortInfo mViewPortInfo; - RenderContext* mContext; - vector mCurPasses; - vector mAllPasses; + vector mCurNodes; + vector mAllNodes; public: RenderAPI(); virtual ~RenderAPI() {}; public: - virtual void SetUpRenderPasses(); + virtual RenderContext* GetContext() = 0; + public: + virtual void OnInit(); + virtual void InitRenderNode(); virtual void InitRenderPass() = 0; public: virtual void SetViewPort(uint32_t width, uint32_t height, uint32_t xOffset = 0, uint32_t yOffset = 0) = 0; @@ -29,16 +32,6 @@ namespace engineapi virtual void DrawStaticMesh(Mesh* mesh) = 0; virtual void SwitchContext() = 0; - - virtual void UseMaterial(uint32_t ID) { - mContext->MaterialId = ID; - }; - virtual void UseShader(uint32_t ID) { - mContext->PassId = ID; - }; - virtual void UsePass(uint32_t ID) { - mContext->ShaderId = ID; - }; public: static RenderAPI* MakeInstance(); }; diff --git a/engine/src/engine/render/window.cpp b/engine/src/engine/render/window.cpp index 83ded77..66c5095 100644 --- a/engine/src/engine/render/window.cpp +++ b/engine/src/engine/render/window.cpp @@ -7,7 +7,7 @@ namespace engineapi { Window* Window::MakeInstance(int frames, uint32_t width, uint32_t height, const char* title) { #ifdef VULKAN_API - return new vulkanapi::Window(frames, width, height, title); + return new vulkanapi::VulkanWindow(frames, width, height, title); #endif } Window::WindowClass::WindowClass() noexcept diff --git a/engine/src/engine/vulkanapi/backend.cpp b/engine/src/engine/vulkanapi/backend.cpp index 203ffd5..0a62a3b 100644 --- a/engine/src/engine/vulkanapi/backend.cpp +++ b/engine/src/engine/vulkanapi/backend.cpp @@ -6,6 +6,7 @@ namespace vulkanapi { CommandWorker* Backend::TransferWorker = nullptr; CommandWorker* Backend::RenderWorker = nullptr; + CommandWorker* Backend::PresentWorker = nullptr; Backend::Backend(const string appName) { auto instanceCreator = InstanceCreator(); @@ -26,6 +27,7 @@ namespace vulkanapi { Backend::TransferWorker = GetWorker(Queue::TransferQueue); Backend::RenderWorker = GetWorker(Queue::RenderQueue); + Backend::PresentWorker = GetWorker(Queue::PresentQueue); } Backend::~Backend() { diff --git a/engine/src/engine/vulkanapi/backend.h b/engine/src/engine/vulkanapi/backend.h index 09fe1f7..56b3f37 100644 --- a/engine/src/engine/vulkanapi/backend.h +++ b/engine/src/engine/vulkanapi/backend.h @@ -27,5 +27,6 @@ namespace vulkanapi { public: static CommandWorker* TransferWorker; static CommandWorker* RenderWorker; + static CommandWorker* PresentWorker; }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/pass/forwardpass.cpp b/engine/src/engine/vulkanapi/pass/forwardpass.cpp index bc74db5..be81fe6 100644 --- a/engine/src/engine/vulkanapi/pass/forwardpass.cpp +++ b/engine/src/engine/vulkanapi/pass/forwardpass.cpp @@ -1,12 +1,30 @@ #include "forwardpass.h" #include "../wrapper/renderpass.h" #include "../wrapper/image.h" +#include "../wrapper/framebuffer.h" +#include "target.h" namespace vulkanapi { void ForwardPass::Record() { } - ForwardPass* ForwardPass::MakePass(Device& device, GeometryBuffer& gBuffer) + void ForwardPass::InitTarget(Device& device, GeometryBuffer& gBuffer, RenderTarget* target) + { + mTarget = target; + target->frames.reserve(target->size); + for (int i = 0; i < target->size; i++) { + auto outputView = gBuffer.positions[i]->View(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_VIEW_TYPE_2D); + auto normalView = gBuffer.normals[i]->View(VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_VIEW_TYPE_2D); + vector surfaces = { outputView, normalView }; + target->frames.emplace_back(device, target, this, surfaces); + } + mClearValues.resize(2); + mClearValues[0].color = { { 0, 0, 0, 0 } }; + mClearValues[1].depthStencil = { 1, 0 }; + mPassBeginInfo.pClearValues = mClearValues.data(); + mPassBeginInfo.clearValueCount = 2; + } + ForwardPass* ForwardPass::MakePass(Device& device, GeometryBuffer& gBuffer, RenderTarget* target) { VkAttachmentDescription positionAttachment{}; positionAttachment.samples = VK_SAMPLE_COUNT_1_BIT; @@ -40,6 +58,9 @@ namespace vulkanapi { vector attachments = { positionAttachment , normalAttachment }; vector subpasses = { subpass }; vector dependencies; - return new ForwardPass(device, "forward", attachments, subpasses, dependencies); + + auto forwad = new ForwardPass(device, "forward", attachments, subpasses, dependencies); + forwad->InitTarget(device, gBuffer, target); + return forwad; } } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/pass/forwardpass.h b/engine/src/engine/vulkanapi/pass/forwardpass.h index 394e5f6..afb5cf2 100644 --- a/engine/src/engine/vulkanapi/pass/forwardpass.h +++ b/engine/src/engine/vulkanapi/pass/forwardpass.h @@ -2,13 +2,15 @@ #include "../wrapper/renderpass.h" #include "gbuffer.h" namespace vulkanapi { - //class MaterialCache; + class RenderTarget; class ForwardPass : public RenderPass { - //MaterialCache mMaterials; + protected: + vector mClearValues; public: using RenderPass::RenderPass; void Record(); + void InitTarget(Device& device, GeometryBuffer& gBuffer, RenderTarget* target); public: - static ForwardPass* MakePass(Device& device, GeometryBuffer& gBuffer); + static ForwardPass* MakePass(Device& device, GeometryBuffer& gBuffer, RenderTarget* target); }; } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/pass/gbuffer.cpp b/engine/src/engine/vulkanapi/pass/gbuffer.cpp index 482e831..dcd50e1 100644 --- a/engine/src/engine/vulkanapi/pass/gbuffer.cpp +++ b/engine/src/engine/vulkanapi/pass/gbuffer.cpp @@ -9,11 +9,15 @@ namespace vulkanapi { VkFormat normalFmt = VK_FORMAT_R8G8B8A8_UNORM; VkFormat diffuseFmt = VK_FORMAT_R8G8B8A8_UNORM; - int usage = 1; + int usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; + auto positionArgs = Image::Make2DArgs(width, height, positionFmt, VK_SAMPLE_COUNT_1_BIT, usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE); + auto normalArgs = Image::Make2DArgs(width, height, positionFmt, VK_SAMPLE_COUNT_1_BIT, usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE); + auto diffuseArgs = Image::Make2DArgs(width, height, positionFmt, VK_SAMPLE_COUNT_1_BIT, usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE); for (int i = 0; i < frames; i++) { - positions.push_back(new Image(device, "position", width , height, diffuseFmt, usage)); - normals.push_back(new Image(device, "normal", width, height, diffuseFmt, usage)); - diffuses.push_back(new Image(device, "diffuse", width, height, diffuseFmt, usage)); + string si = to_string(i); + positions.push_back(new Image(device, "position" + si, positionArgs)); + normals.push_back(new Image(device, "normal" + si, normalArgs)); + diffuses.push_back(new Image(device, "diffuse" + si, diffuseArgs)); } } GeometryBuffer::~GeometryBuffer() diff --git a/engine/src/engine/vulkanapi/pass/target.cpp b/engine/src/engine/vulkanapi/pass/target.cpp index e69de29..4b49253 100644 --- a/engine/src/engine/vulkanapi/pass/target.cpp +++ b/engine/src/engine/vulkanapi/pass/target.cpp @@ -0,0 +1,25 @@ +#include "target.h" +#include "../window.h" +namespace vulkanapi { + void RenderTarget::InitSurface(Device& device, string name) + { + + } + RenderTarget* RenderTarget::MakeOutputTarget() + { + auto window = VulkanWindow::GetSingletonPtr(); + vector& surfaces = window->GetSurface(); + uint32_t width, height; + window->GetSize(width, height); + return new RenderTarget(width, height, surfaces); + } + RenderTarget* RenderTarget::MakeDepthTarget() + { + return nullptr; + } + RenderTarget* RenderTarget::MakeColorTarget() + { + return nullptr; + } +} + diff --git a/engine/src/engine/vulkanapi/pass/target.h b/engine/src/engine/vulkanapi/pass/target.h index 3deda21..ee45fbf 100644 --- a/engine/src/engine/vulkanapi/pass/target.h +++ b/engine/src/engine/vulkanapi/pass/target.h @@ -1,10 +1,25 @@ #pragma once #include "../vulkan.h" +#include "../wrapper/framebuffer.h" namespace vulkanapi { class Image; class Device; class RenderTarget { public: - + uint32_t width; + uint32_t height; + uint32_t size; + vector frames; + vector surfaces; + public: + RenderTarget(uint32_t width, uint32_t height, uint32_t size) + :width(width), height(height), size(size) {}; + RenderTarget(uint32_t width, uint32_t height, vector& surfaces) + :width(width), height(height), size(surfaces.size()), surfaces(surfaces){}; + void InitSurface(Device& device, string name); + public: + static RenderTarget* MakeOutputTarget(); + static RenderTarget* MakeDepthTarget(); + static RenderTarget* MakeColorTarget(); }; } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/thread/worker.cpp b/engine/src/engine/vulkanapi/thread/worker.cpp index 731f70e..e7eb3ac 100644 --- a/engine/src/engine/vulkanapi/thread/worker.cpp +++ b/engine/src/engine/vulkanapi/thread/worker.cpp @@ -52,4 +52,9 @@ namespace vulkanapi { cmd.WaitFofFence(mDevice.Ptr()); mCommandPool.Push(cmd); } + bool CommandWorker::Present(VkPresentInfoKHR& presentInfo) + { + VkResult result = vkQueuePresentKHR(mQueue.Ptr(), &presentInfo); + return result == VK_SUCCESS; + } } diff --git a/engine/src/engine/vulkanapi/thread/worker.h b/engine/src/engine/vulkanapi/thread/worker.h index 289fa98..e285c93 100644 --- a/engine/src/engine/vulkanapi/thread/worker.h +++ b/engine/src/engine/vulkanapi/thread/worker.h @@ -25,5 +25,6 @@ namespace vulkanapi { Buffer(mImmediateExeCmd, fn , callback); } void Draw(commandFn fn); + bool Present(VkPresentInfoKHR& presentInfo); }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/vulkan.h b/engine/src/engine/vulkanapi/vulkan.h index 0aa444a..d9c7f38 100644 --- a/engine/src/engine/vulkanapi/vulkan.h +++ b/engine/src/engine/vulkanapi/vulkan.h @@ -10,6 +10,7 @@ namespace vulkanapi { #define Z_USE_GRAPHIC_DEBUG class CommandBuffer; using std::string; +using std::to_string; using std::vector; using std::map; using voidFn = std::function; diff --git a/engine/src/engine/vulkanapi/vulkan_context.cpp b/engine/src/engine/vulkanapi/vulkan_context.cpp index 0960179..c297c8c 100644 --- a/engine/src/engine/vulkanapi/vulkan_context.cpp +++ b/engine/src/engine/vulkanapi/vulkan_context.cpp @@ -1,9 +1,8 @@ #include "vulkan_context.h" #include "vulkanapi.h" -namespace engineapi { +namespace vulkanapi { void VulkanContext::UseContext() { - Pass = API->VkPasses[PassId]; - + Pass = API.PassList[PassId]; } } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/vulkan_context.h b/engine/src/engine/vulkanapi/vulkan_context.h index af97074..e8396ac 100644 --- a/engine/src/engine/vulkanapi/vulkan_context.h +++ b/engine/src/engine/vulkanapi/vulkan_context.h @@ -1,11 +1,15 @@ #pragma once #include "render/render_context.h" -#include "vulkanapi.h" -namespace engineapi { - struct VulkanContext : public RenderContext { - RenderVulkanAPI* API; - vulkanapi::RenderPass* Pass; +#include "wrapper/renderpass.h" +namespace vulkanapi { + class RenderVulkanAPI; + class VulkanContext : public engineapi::RenderContext { + public: + RenderVulkanAPI& API; + RenderPass* Pass{ nullptr }; + public: + VulkanContext(RenderVulkanAPI& API):API(API){}; virtual void UseContext()override; }; } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/vulkanapi.cpp b/engine/src/engine/vulkanapi/vulkanapi.cpp index 457f576..bbaa3fa 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.cpp +++ b/engine/src/engine/vulkanapi/vulkanapi.cpp @@ -1,17 +1,20 @@ -#include "vulkanapi.h" + #include "vulkanapi.h" #include "wrapper/queue.h" #include "wrapper/buffer.h" #include "wrapper/commandbuffer.h" #include "thread/worker.h" #include "render/asset/mesh.h" #include "object/camera/camera.h" -#include "render/pass/renderpass.h" +#include "render/node/rendernode.h" #include "pass/forwardpass.h" -namespace engineapi { +#include "pass/target.h" +#include "wrapper/swapchain.h" +#include "window.h" +namespace vulkanapi { RenderVulkanAPI::RenderVulkanAPI() :backend("vulkan") + ,context(*this) { - mContext = &context; Buffer::MakeVmaAllocator(backend); } RenderVulkanAPI::~RenderVulkanAPI() @@ -24,12 +27,17 @@ namespace engineapi { } void RenderVulkanAPI::InitRenderPass() { - VkPasses.resize(RenderPassType::ZX_RENDER_PASS_COUNT); + swapchain = VulkanWindow::GetSingletonPtr()->GetSwapchain(); + RenderTarget* output = RenderTarget::MakeOutputTarget(); + TargetList.reserve(RENDER_COUNT); + TargetList.push_back(output); + PassList.resize(RENDER_COUNT); auto gbuffer = GeometryBuffer(backend.GetDevice(), 3, 640, 720); - for (auto pass : mAllPasses) { - auto type = pass->GetType(); - if (type == RenderPassType::ZX_RENDER_PASS_FORWARD_RENDERING) { - VkPasses[type] = ForwardPass::MakePass(backend.GetDevice(), gbuffer); + for (auto node : mAllNodes) { + if (!node)continue; + auto type = node->GetType(); + if (type == RENDER_FORWARD_RENDERING) { + PassList[type] = ForwardPass::MakePass(backend.GetDevice(), gbuffer, output); } } } @@ -42,26 +50,28 @@ namespace engineapi { } void RenderVulkanAPI::BeginFrame() { - + mFrame = swapchain->Aquire(); } void RenderVulkanAPI::EndFrame() { - + swapchain->Present(mFrame); } void RenderVulkanAPI::SetStaticMesh(Mesh* mesh) { - auto meshBuffer = GetNextVAO(mesh->VAO); - meshBuffer->indexCount = mesh->mIndices.size(); - meshBuffer->vertexCount = mesh->mVertices.size(); + auto Indices = mesh->GetIndices(); + auto Vertices = mesh->GetVertices(); + auto meshBuffer = GetNextVAO(mesh->GetVAO()); + meshBuffer->indexCount = Indices.size(); + meshBuffer->vertexCount = Vertices.size(); // ----------------------------------------------- Vertex Buffer ----------------------------------------------- - VkDeviceSize vertexBufferSize = sizeof(Vertex) * mesh->mVertices.size(); + VkDeviceSize vertexBufferSize = sizeof(Vertex) * Vertices.size(); VmaAllocationCreateInfo vertexVmaStagingInfo = {}; VmaAllocation vertexVmaStagingAlloc; VkBuffer vertexStagingBuffer = Buffer::CreateStageBuffer(vertexVmaStagingInfo, vertexVmaStagingAlloc, vertexBufferSize); // 拷贝数据到StagingBuffer - Buffer::CopyData(vertexVmaStagingAlloc, mesh->mVertices.data(), vertexBufferSize); + Buffer::CopyData(vertexVmaStagingAlloc, Vertices.data(), vertexBufferSize); VkBufferUsageFlags vertexFlags = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;//加入光线追踪 VmaAllocationCreateInfo vertexVmaCreateInfo = {}; @@ -69,12 +79,12 @@ namespace engineapi { meshBuffer->vertexBuffer = Buffer::CreateBuffer(vertexCreateInfo, vertexVmaCreateInfo, meshBuffer->vertexBufferAlloc); // ----------------------------------------------- Index Buffer ----------------------------------------------- - VkDeviceSize indexBufferSize = sizeof(uint32_t) * mesh->mIndices.size(); + VkDeviceSize indexBufferSize = sizeof(uint32_t) * Indices.size(); VmaAllocationCreateInfo indexVmaStagingInfo = {}; VmaAllocation indexVmaStagingAlloc; VkBuffer indexStagingBuffer = Buffer::CreateStageBuffer(indexVmaStagingInfo, indexVmaStagingAlloc, vertexBufferSize); // 拷贝数据到StagingBuffer - Buffer::CopyData(indexVmaStagingAlloc, mesh->mIndices.data(), indexBufferSize); + Buffer::CopyData(indexVmaStagingAlloc, Indices.data(), indexBufferSize); VmaAllocationCreateInfo indexVmaCreateInfo = {}; VkBufferCreateInfo indexCreateInfo = Buffer::MakeDeviceInfo(indexVmaCreateInfo, indexBufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); @@ -99,19 +109,18 @@ namespace engineapi { } void RenderVulkanAPI::DrawStaticMesh(Mesh* mesh) { - - } - void RenderVulkanAPI::DrawStaticMesh(Mesh* mesh) - { - auto vulkanVAO = VAOList[mesh->VAO]; + auto vulkanVAO = VAOList[mesh->GetVAO()]; + context.Pass->SetViewPort(mViewPortInfo.width, mViewPortInfo.height, mViewPortInfo.xOffset, mViewPortInfo.yOffset); Backend::RenderWorker->Draw([=](CommandBuffer& cmd) { VkCommandBuffer ptr = cmd.Ptr(); - context.Pass->BeginPass(cmd); + context.Pass->BeginPass(cmd, mFrame); VkBuffer vertexBuffers[] = { vulkanVAO->vertexBuffer }; VkDeviceSize offsets[] = { 0 }; vkCmdBindVertexBuffers(ptr, 0, 1, vertexBuffers, offsets); vkCmdBindIndexBuffer(ptr, vulkanVAO->indexBuffer, 0, VK_INDEX_TYPE_UINT32); - vkCmdDrawIndexed(ptr, vulkanVAO->indexCount, 1, 0, 0, 0); + vkCmdBindPipeline(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline); + vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipelineLayout, 0, 1, &materialData->descriptorSets[currentFrame], 0, VK_NULL_HANDLE); + vkCmdDrawIndexed(ptr, vulkanVAO->indexCount, 1, 0, 0, 0); context.Pass->EndPass(cmd); }); } diff --git a/engine/src/engine/vulkanapi/vulkanapi.h b/engine/src/engine/vulkanapi/vulkanapi.h index 7e1b8ef..3c651ac 100644 --- a/engine/src/engine/vulkanapi/vulkanapi.h +++ b/engine/src/engine/vulkanapi/vulkanapi.h @@ -2,21 +2,29 @@ #include "backend.h" #include "wrapper/renderpass.h" #include "render/renderapi.h" -#include "vulkan_context.h" #include "vulkan_struct.h" -using namespace vulkanapi; -namespace engineapi +#include "vulkan_context.h" +using namespace engineapi; +namespace vulkanapi { + class RenderTarget; + class Swapchain; class RenderVulkanAPI : public RenderAPI { public: Backend backend; VulkanContext context; + Swapchain* swapchain; + vector TargetList; vector VAOList; - vector VkPasses; + vector PassList; public: RenderVulkanAPI(); virtual ~RenderVulkanAPI()override; + public: + virtual RenderContext* GetContext() override { + return &context; + }; public: virtual void SwitchContext()override; public: diff --git a/engine/src/engine/vulkanapi/window.cpp b/engine/src/engine/vulkanapi/window.cpp index 572941e..6a921ee 100644 --- a/engine/src/engine/vulkanapi/window.cpp +++ b/engine/src/engine/vulkanapi/window.cpp @@ -2,13 +2,11 @@ #include "backend.h" #include "wrapper/instance.h" #include "wrapper/device.h" -#include "wrapper/swapchain.h" #include "wrapper/swapchain_creator.h" #include "vulkanapi.h" #include "zlog.h" -using engineapi::RenderVulkanAPI; namespace vulkanapi { - Window::Window(int frames, uint32_t width, uint32_t height, const char* title) + VulkanWindow::VulkanWindow(int frames, uint32_t width, uint32_t height, const char* title) :engineapi::Window(width, height , title) , mSurfaceKHR(nullptr) , mSwapchain(nullptr) diff --git a/engine/src/engine/vulkanapi/window.h b/engine/src/engine/vulkanapi/window.h index f2313da..3935ca6 100644 --- a/engine/src/engine/vulkanapi/window.h +++ b/engine/src/engine/vulkanapi/window.h @@ -1,13 +1,25 @@ #pragma once #include "render/window.h" +#include "wrapper/swapchain.h" #include "vulkan.h" namespace vulkanapi { - class Swapchain; - class Window : public engineapi::Window { + class Image; + class VulkanWindow : public engineapi::Window { protected: VkSurfaceKHR mSurfaceKHR; Swapchain* mSwapchain; public: - Window(int frames, uint32_t width, uint32_t height, const char* title); + VulkanWindow(int frames, uint32_t width, uint32_t height, const char* title); + + vector& GetSurface() { + return mSwapchain->GetSurface(); + } + Swapchain* GetSwapchain() { + return mSwapchain; + } + public: + static VulkanWindow* GetSingletonPtr() { + return (VulkanWindow*)engineapi::Window::GetSingletonPtr(); + } }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/buffer.cpp b/engine/src/engine/vulkanapi/wrapper/buffer.cpp index f49faf7..7e620d6 100644 --- a/engine/src/engine/vulkanapi/wrapper/buffer.cpp +++ b/engine/src/engine/vulkanapi/wrapper/buffer.cpp @@ -69,4 +69,10 @@ namespace vulkanapi { // 销毁StagingBuffer vmaDestroyBuffer(vmaAllocator, buffer, bufferAlloc); } + void Buffer::CreateImage(VkImageCreateInfo& imageInfo, VkImage& ptr, VmaAllocation& allocation, VmaMemoryUsage usage) + { + VmaAllocationCreateInfo allocationInfo = {}; + allocationInfo.usage = usage; + vmaCreateImage(vmaAllocator, &imageInfo, &allocationInfo, &ptr, &allocation, nullptr); + } } diff --git a/engine/src/engine/vulkanapi/wrapper/buffer.h b/engine/src/engine/vulkanapi/wrapper/buffer.h index 06ec432..20463d4 100644 --- a/engine/src/engine/vulkanapi/wrapper/buffer.h +++ b/engine/src/engine/vulkanapi/wrapper/buffer.h @@ -16,5 +16,6 @@ namespace vulkanapi { static VkBuffer CreateStageBuffer(VmaAllocationCreateInfo& allocationCreateInfo, VmaAllocation& allocation, VkDeviceSize vertexBufferSize); static void CopyData(VmaAllocation& allocation,void* data, VkDeviceSize size); static void DestroyBuffer(VkBuffer buffer, VmaAllocation bufferAlloc); + static void CreateImage(VkImageCreateInfo& imageInfo, VkImage& ptr, VmaAllocation& allocation, VmaMemoryUsage usage); }; } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/device.cpp b/engine/src/engine/vulkanapi/wrapper/device.cpp index 8560f4e..a7b0379 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.cpp +++ b/engine/src/engine/vulkanapi/wrapper/device.cpp @@ -70,5 +70,12 @@ namespace vulkanapi { VkResult result = vkCreateFence(mPtr, &fenceInfo, nullptr, &fence); return result == VK_SUCCESS; } + bool Device::CreateSemaphore(VkSemaphore& semaphore) + { + VkSemaphoreCreateInfo semaphoreInfo = {}; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + VkResult result = vkCreateSemaphore(mPtr, &semaphoreInfo, nullptr, &semaphore); + return result == VK_SUCCESS; + } } diff --git a/engine/src/engine/vulkanapi/wrapper/device.h b/engine/src/engine/vulkanapi/wrapper/device.h index f928765..7f73132 100644 --- a/engine/src/engine/vulkanapi/wrapper/device.h +++ b/engine/src/engine/vulkanapi/wrapper/device.h @@ -23,5 +23,6 @@ namespace vulkanapi { Queue* GetQueue(const string& name); bool CreateFence(VkFence& fence); + bool CreateSemaphore(VkSemaphore& semaphore); }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/framebuffer.cpp b/engine/src/engine/vulkanapi/wrapper/framebuffer.cpp new file mode 100644 index 0000000..d73827f --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/framebuffer.cpp @@ -0,0 +1,22 @@ +#include "framebuffer.h" +#include "device.h" +#include "renderpass.h" +#include "image.h" +#include "../pass/target.h" +namespace vulkanapi { + FrameBuffer::FrameBuffer(Device& device, RenderTarget* target, RenderPass* pass, vector& surfaces) + : mSurfaces(surfaces) + { + uint32_t size = mSurfaces.size(); + VkFramebufferCreateInfo framebufferInfo{}; + framebufferInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + // 指定可以兼容的render pass(这个frame buffer和指定的render pass的attachment的数量和类型需要一致) + framebufferInfo.renderPass = pass->Ptr(); + framebufferInfo.attachmentCount = size; + framebufferInfo.pAttachments = mSurfaces.data(); + framebufferInfo.width = target->width; + framebufferInfo.height = target->height; + framebufferInfo.layers = 1; + vkCreateFramebuffer(device.Ptr(), &framebufferInfo, nullptr, &mPtr); + } +} diff --git a/engine/src/engine/vulkanapi/wrapper/framebuffer.h b/engine/src/engine/vulkanapi/wrapper/framebuffer.h new file mode 100644 index 0000000..3e6e183 --- /dev/null +++ b/engine/src/engine/vulkanapi/wrapper/framebuffer.h @@ -0,0 +1,19 @@ +#pragma once +#include "../vulkan.h" +namespace vulkanapi { + class Device; + class RenderPass; + class RenderTarget; + class Image; + class FrameBuffer { + protected: + VkFramebuffer mPtr; + vector mSurfaces; + public: + FrameBuffer(Device& device, RenderTarget* target,RenderPass* pass, vector& surfaces); + + VkFramebuffer& Ptr() { + return mPtr; + } + }; +} \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/image.cpp b/engine/src/engine/vulkanapi/wrapper/image.cpp index 142737b..0c70d91 100644 --- a/engine/src/engine/vulkanapi/wrapper/image.cpp +++ b/engine/src/engine/vulkanapi/wrapper/image.cpp @@ -1,28 +1,87 @@ #include "image.h" +#include "device.h" +#include "buffer.h" namespace vulkanapi { - Image::Image(const Device& device, const char* name, int width, int height, VkFormat format, VkImageUsageFlags usage) - :Image(device, Args{ - 1, - "", - width,height, - 1,1,1, - format,usage, - 1,1,1,1 }) - { - - } - Image::Image(const Device& device, const Args& args) + Image::Image(Device& device, string name, const Args& args) : mArgs(args) + , mName(name) , mDevice(device) , mPtr(nullptr) { + VkImageCreateInfo imageInfo{}; + imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; + imageInfo.imageType = mArgs.Type; + imageInfo.extent.width = mArgs.Width; + imageInfo.extent.height = mArgs.Height; + // 纹理第三个维度的像素数量,如果不是3D纹理应该都是1 + imageInfo.extent.depth = 1; + imageInfo.mipLevels = mArgs.Levels; + imageInfo.arrayLayers = mArgs.Layers; + imageInfo.format = mArgs.Format; + // VK_IMAGE_TILING_LINEAR: texel以行为主序排列为数组 + // VK_IMAGE_TILING_OPTIMAL: texel按照Vulkan的具体实现来定义的一种顺序排列,以实现最佳访问 + // 这个和layout不一样,一旦设置之后是固定的不能改,如果CPU需要读取这个数据,就设置为VK_IMAGE_TILING_LINEAR + // 如果只是GPU使用,就设置为VK_IMAGE_TILING_OPTIMAL性能更好 + imageInfo.tiling = mArgs.Tiling; + // 这里只能填VK_IMAGE_LAYOUT_UNDEFINED或者VK_IMAGE_LAYOUT_PREINITIALIZED + // VK_IMAGE_LAYOUT_UNDEFINED意味着第一次transition数据的时候数据会被丢弃 + // VK_IMAGE_LAYOUT_PREINITIALIZED是第一次transition数据的时候数据会被保留 + // 不是很懂这个什么意思,如果是一个用来从CPU写入数据,然后transfer到其它VkImage的stagingImage,就要用VK_IMAGE_LAYOUT_PREINITIALIZED + imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; + imageInfo.usage = mArgs.Usage; + imageInfo.sharingMode = mArgs.Sharing; + imageInfo.samples = mArgs.Samples; + // 这个只影响当作attachments使用的VkImage(自己创建的frame buffer才支持这个,交换链用的那个默认buffer不支持) + imageInfo.samples = VK_SAMPLE_COUNT_1_BIT; + Buffer::CreateImage(imageInfo, mPtr, mAllocation, mArgs.Memory); } - Image::Image(const Device& device, VkImage ptr, const Args& args) + Image::Image(Device& device, string name, VkImage ptr, const Args& args) : mArgs(args) + , mName(name) , mDevice(device) , mPtr(ptr) { } + VkImageView Image::View(VkFormat format, VkImageAspectFlags aspectFlags, VkImageViewType viewType) + { + VkImageViewCreateInfo createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + createInfo.image = mPtr; + createInfo.viewType = viewType; + createInfo.format = format; + + // components字段允许调整颜色通道的最终的映射逻辑 + // 比如,我们可以将所有颜色通道映射为红色通道,以实现单色纹理,我们也可以将通道映射具体的常量数值0和1 + // 这里用默认的 + createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; + createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; + + // subresourceRangle字段用于描述图像的使用目标是什么,以及可以被访问的有效区域 + // 这个图像用作填充color还是depth stencil等 + createInfo.subresourceRange.aspectMask = aspectFlags; + // 默认处理所有Mipmap + createInfo.subresourceRange.baseMipLevel = 0; + createInfo.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS; + // 默认处理所有Layers + createInfo.subresourceRange.baseArrayLayer = 0; + createInfo.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS; + + VkImageView imageView; + vkCreateImageView(mDevice.Ptr(), &createInfo, nullptr, &imageView); + return imageView; + } + Image::Args Image::Make2DArgs(uint32_t width, uint32_t height, VkFormat format, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VmaMemoryUsage memory) + { + return Args{ + VK_IMAGE_TYPE_2D, + width,height, + 1,1,1, + format,usage, + VK_IMAGE_TILING_LINEAR,VK_SHARING_MODE_EXCLUSIVE, + samples,1,memory }; + } } diff --git a/engine/src/engine/vulkanapi/wrapper/image.h b/engine/src/engine/vulkanapi/wrapper/image.h index a3c9636..3149156 100644 --- a/engine/src/engine/vulkanapi/wrapper/image.h +++ b/engine/src/engine/vulkanapi/wrapper/image.h @@ -1,35 +1,47 @@ #pragma once #include "../vulkan.h" +#include "vk_mem_alloc.h" namespace vulkanapi { class Device; class Image { public: struct Args { - int Type; - const char* Key; - int Width; - int Height; - int Depth; - int Layers; - int Levels; + VkImageType Type; + uint32_t Width; + uint32_t Height; + uint32_t Depth; + uint32_t Layers; + uint32_t Levels; VkFormat Format; VkImageUsageFlags Usage; - int Tiling; - int Sharing; + VkImageTiling Tiling; + VkSharingMode Sharing; + VkSampleCountFlagBits Samples; int Layout; - int Memory; + VmaMemoryUsage Memory; }; protected: + string mName; VkImage mPtr; Args mArgs; - const Device& mDevice; + VmaAllocation mAllocation{nullptr}; + Device& mDevice; public: - Image(const Device& device, const char* name, int width, int height, VkFormat format, VkImageUsageFlags usage); - Image(const Device& device, const Args& args); - Image(const Device& device, VkImage ptr, const Args& args); + Image(Device& device, string name, const Args& args); + Image(Device& device, string name, VkImage ptr, const Args& args); VkFormat Format() { return mArgs.Format; }; - }; + VkImage& Ptr() { + return mPtr; + } + VkImageView View(VkImageAspectFlags aspectFlags, VkImageViewType viewType) { + return View(mArgs.Format, aspectFlags, viewType); + }; + VkImageView View(VkFormat format, VkImageAspectFlags aspectFlags, VkImageViewType viewType); + + public: + static Args Make2DArgs(uint32_t width, uint32_t height, VkFormat format, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VmaMemoryUsage memory); + }; } \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/renderpass.cpp b/engine/src/engine/vulkanapi/wrapper/renderpass.cpp index 64b09c4..983c749 100644 --- a/engine/src/engine/vulkanapi/wrapper/renderpass.cpp +++ b/engine/src/engine/vulkanapi/wrapper/renderpass.cpp @@ -1,11 +1,14 @@ #include "renderpass.h" #include "device.h" #include "commandbuffer.h" +#include "../pass/target.h" +#include "framebuffer.h" namespace vulkanapi { RenderPass::RenderPass(Device& device, const char* name, vector& attachments, vector& subpasses, vector& dependencies) + :mAttachments(attachments) { //pAttachments VkRenderPassCreateInfo create_info{ @@ -24,8 +27,9 @@ namespace vulkanapi { mPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; mPassBeginInfo.renderPass = mPtr; } - void RenderPass::BeginPass(CommandBuffer& cmd) + void RenderPass::BeginPass(CommandBuffer& cmd,int frame) { + mPassBeginInfo.framebuffer = mTarget->frames.at(frame).Ptr(); vkCmdBeginRenderPass(cmd.Ptr(), &mPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); } void RenderPass::EndPass(CommandBuffer& cmd) diff --git a/engine/src/engine/vulkanapi/wrapper/renderpass.h b/engine/src/engine/vulkanapi/wrapper/renderpass.h index 5e73d37..ccd8212 100644 --- a/engine/src/engine/vulkanapi/wrapper/renderpass.h +++ b/engine/src/engine/vulkanapi/wrapper/renderpass.h @@ -5,21 +5,24 @@ namespace vulkanapi { class Device; class CommandBuffer; + class RenderTarget; class RenderPass { protected: VkRenderPass mPtr; + RenderTarget* mTarget; VkRenderPassBeginInfo mPassBeginInfo{}; - + vector mAttachments; public: RenderPass(Device& device, const char* name, vector& attachments, vector& subpasses, vector& dependencies); - + VkRenderPass& Ptr() { + return mPtr; + } public: - void BeginPass(CommandBuffer& cmd); + void BeginPass(CommandBuffer& cmd, int frame); void EndPass(CommandBuffer& cmd); - public: void SetViewPort(uint32_t width, uint32_t height, int32_t xoffset, int32_t yoffset); }; diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain.cpp b/engine/src/engine/vulkanapi/wrapper/swapchain.cpp index c45c4c9..224e02d 100644 --- a/engine/src/engine/vulkanapi/wrapper/swapchain.cpp +++ b/engine/src/engine/vulkanapi/wrapper/swapchain.cpp @@ -2,10 +2,13 @@ #include "swapchain_creator.h" #include "device.h" #include "image.h" +#include "../backend.h" +#include "../thread/worker.h" #include "zlog.h" namespace vulkanapi { Swapchain::Swapchain(SwapchainCreator& Creator) : mPtr(nullptr) + , mDevice(Creator.device) { VkSurfaceCapabilitiesKHR capabilities{}; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Creator.device.GetPhysical(), Creator.presentation_surface, &capabilities); @@ -36,15 +39,31 @@ namespace vulkanapi { } vector swapchain_images; Creator.CreateSwapchainImages(mPtr, swapchain_images); - uint32_t image_count = swapchain_images.size(); - for (auto img : swapchain_images) { - mImages.push_back(new Image(Creator.device, img, Image::Args{ - 1, - "", - (int)Creator.width, (int)Creator.height, - 1, 1, 1, - Creator.imageFormat, Creator.imageUsage, - 1, 1, 1, 1})); + auto args = Image::Make2DArgs(Creator.width, Creator.height, Creator.imageFormat, VK_SAMPLE_COUNT_8_BIT, Creator.imageUsage, VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE); + args.Sharing = VK_SHARING_MODE_CONCURRENT; + for (int i = 0; i < Creator.frames;i++) { + mSurfaces.push_back(new Image(Creator.device,"swapchain" + to_string(i), swapchain_images[i], args)); } + Creator.device.CreateSemaphore(mSemaphore); + } + uint32_t Swapchain::Aquire() + { + uint32_t curPresentImageIdx; + VkResult result = vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, mSemaphore, VK_NULL_HANDLE, &curPresentImageIdx); + return curPresentImageIdx; + } + void Swapchain::Present(uint32_t frame) + { + VkSwapchainKHR swapChains[] = { mPtr }; + VkSemaphore waitSemaphores[] = { mSemaphore }; + VkPresentInfoKHR presentInfo = {}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + presentInfo.pWaitSemaphores = waitSemaphores; + presentInfo.waitSemaphoreCount = 1; + presentInfo.pSwapchains = swapChains; + presentInfo.swapchainCount = 1; + presentInfo.pImageIndices = &frame; + presentInfo.pResults = VK_NULL_HANDLE; + Backend::PresentWorker->Present(presentInfo); } } diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain.h b/engine/src/engine/vulkanapi/wrapper/swapchain.h index fd7670f..7654879 100644 --- a/engine/src/engine/vulkanapi/wrapper/swapchain.h +++ b/engine/src/engine/vulkanapi/wrapper/swapchain.h @@ -4,12 +4,20 @@ namespace vulkanapi { class Image; class SwapchainCreator; + class Device; class Swapchain { friend class SwapchainCreator; protected: VkSwapchainKHR mPtr; - vector mImages; + Device& mDevice; + vector mSurfaces; + VkSemaphore mSemaphore; public: Swapchain(SwapchainCreator& Creator); + uint32_t Aquire(); + void Present(uint32_t frame); + vector& GetSurface(){ + return mSurfaces; + } }; }; \ No newline at end of file diff --git a/engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp b/engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp index e835e9e..aad55b6 100644 --- a/engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp +++ b/engine/src/engine/vulkanapi/wrapper/swapchain_creator.cpp @@ -9,10 +9,10 @@ namespace vulkanapi { , frames(frames) , width(width) , height(height) - , imageFormat(VkFormat::VK_FORMAT_B8G8R8A8_SRGB) - , imageColorSpace(VkColorSpaceKHR::VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) - , presentMode(VkPresentModeKHR::VK_PRESENT_MODE_MAILBOX_KHR) - , imageUsage(VkImageUsageFlagBits::VK_IMAGE_USAGE_TRANSFER_DST_BIT) + , imageFormat(VK_FORMAT_B8G8R8A8_SRGB) + , imageColorSpace(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + , presentMode(VK_PRESENT_MODE_MAILBOX_KHR) + , imageUsage(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT) , maxFrameInFlightCount(2) {