ubugfix
This commit is contained in:
parent
f6e755ea3f
commit
f8913cd7d2
@ -25,7 +25,6 @@ namespace api {
|
||||
class ShaderProgram
|
||||
, class Asset
|
||||
, class Texture
|
||||
, class FrameBuffer
|
||||
>;
|
||||
template<typename Resource>
|
||||
concept is_resource_v = requires { typename Resource::BaseResource; };
|
||||
|
||||
@ -2,4 +2,16 @@
|
||||
#include "render/module.h"
|
||||
namespace api {
|
||||
IMPLEMENT_STATIC_MODULE(RENDER_API, RenderModule, render);
|
||||
void RenderAPI::RenderView(FRenderView& view)
|
||||
{
|
||||
graph.Compile();
|
||||
graph.Execute(view);
|
||||
graph.Clear();
|
||||
}
|
||||
void RenderAPI::Render()
|
||||
{
|
||||
for (auto view : context.views) {
|
||||
RenderView(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,11 @@
|
||||
#include "render/window.h"
|
||||
namespace api {
|
||||
inline Window::Window(CreatePFN func, const Args& args, int width, int height) noexcept : mHeight(height), mWidth(width)
|
||||
inline Window::Window(CreatePFN createPFN, const Args& args, int width, int height) noexcept : mHeight(height), mWidth(width)
|
||||
{
|
||||
uint32_t windowFlags = SDL_WINDOW_SHOWN;
|
||||
uint32_t windowFlags = args.windowFlags | SDL_WINDOW_SHOWN;
|
||||
windowFlags |= args.resizeable ? SDL_WINDOW_RESIZABLE : 0;
|
||||
windowFlags |= args.headless ? SDL_WINDOW_HIDDEN : 0;
|
||||
// Even if we're in headless mode, we still need to create a window, otherwise SDL will not poll events.
|
||||
mPtr = func(args.title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, windowFlags);
|
||||
mPtr = createPFN(args.title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, windowFlags);
|
||||
}
|
||||
}
|
||||
@ -1,17 +0,0 @@
|
||||
#pragma once
|
||||
#include "desc/attachment_desc.h"
|
||||
namespace api {
|
||||
class Attachment;
|
||||
class FrameBuffer : public Resource<FrameBuffer>
|
||||
{
|
||||
public:
|
||||
pmr::vector<Attachment*> mAttachments{};
|
||||
Attachment* mDepthAttach{};
|
||||
Attachment* mStencilAttach{};
|
||||
Vector2 mSize;
|
||||
public:
|
||||
Vector2 Size() const { return mSize; }
|
||||
const Attachment& DepthAttachment()const { return *mDepthAttach; }
|
||||
const Attachment& GetAttachment(size_t index)const { return *mAttachments[index]; }
|
||||
};
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
#include "asset/asset.h"
|
||||
namespace api {
|
||||
class Texture : public Resource<Texture>
|
||||
{
|
||||
public:
|
||||
};
|
||||
}
|
||||
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "type.h"
|
||||
namespace api {
|
||||
struct FRenderView;
|
||||
class FrameGraph
|
||||
{
|
||||
public:
|
||||
@ -18,13 +19,13 @@ namespace api {
|
||||
FrameGraphEdgePtr CreateTexture(const TextureSetupFunction& setup);
|
||||
|
||||
void Compile();
|
||||
void Execute();
|
||||
void Execute(FRenderView& view);
|
||||
void Clear();
|
||||
|
||||
public:
|
||||
void ExecuteRenderPass(RenderPassNode* node);
|
||||
void ExecutePresentPass(RenderPassNode* node);
|
||||
void ExecuteComputePass(RenderPassNode* node);
|
||||
void ExecuteCopyPass(RenderPassNode* node);
|
||||
void ExecuteRenderPass(RenderPassNode* node, FRenderView& view);
|
||||
void ExecutePresentPass(RenderPassNode* node, FRenderView& view);
|
||||
void ExecuteComputePass(RenderPassNode* node, FRenderView& view);
|
||||
void ExecuteCopyPass(RenderPassNode* node, FRenderView& view);
|
||||
};
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "render/asset/framebuffer.h"
|
||||
#include "asset/asset.h"
|
||||
#include "render/type.h"
|
||||
#include "lemon/list_graph.h"
|
||||
#include <functional>
|
||||
namespace api {
|
||||
|
||||
@ -1,7 +1,13 @@
|
||||
#pragma once
|
||||
#include "type.h"
|
||||
namespace api {
|
||||
struct RenderContext;
|
||||
struct FRenderView {
|
||||
RenderContext* context;
|
||||
};
|
||||
struct RenderContext {
|
||||
|
||||
pmr::vector<FRenderView> views;
|
||||
uint32_t frame{ 0 };
|
||||
uint32_t presentFrame{ 0 };
|
||||
};
|
||||
}
|
||||
@ -2,14 +2,15 @@
|
||||
#include "singleton.h"
|
||||
#include "pmr/frame_allocator.h"
|
||||
#include "render_context.h"
|
||||
#include "graph/frame_graph.h"
|
||||
namespace api {
|
||||
class Mesh;
|
||||
class Shader;
|
||||
class Camera;
|
||||
class RenderNode;
|
||||
class RENDER_API RenderAPI : public Singleton<RenderAPI>
|
||||
{
|
||||
public:
|
||||
RenderContext* ctx;
|
||||
FrameGraph graph;
|
||||
RenderAPI() {};
|
||||
virtual ~RenderAPI() {};
|
||||
public:
|
||||
@ -28,5 +29,7 @@ namespace api {
|
||||
|
||||
virtual void BeginFrame() = 0;
|
||||
virtual void EndFrame() = 0;
|
||||
virtual void RenderView(FRenderView& view);
|
||||
void Render();
|
||||
};
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
namespace api {
|
||||
enum class GraphicsAPI
|
||||
{
|
||||
@ -6,4 +7,14 @@ namespace api {
|
||||
Vulkan,
|
||||
D3D12
|
||||
};
|
||||
struct TextureDesc {
|
||||
static TextureDesc Make() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
struct AttachmentDesc {
|
||||
static AttachmentDesc Make() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -11,6 +11,7 @@ namespace api {
|
||||
SDL_Window* mPtr = nullptr;
|
||||
struct Args {
|
||||
const char* title;
|
||||
uint32_t windowFlags = 0;
|
||||
bool resizeable = true;
|
||||
bool headless = false;
|
||||
};
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
#include "render/asset/framebuffer.h"
|
||||
namespace api {
|
||||
|
||||
}
|
||||
4
engine/modules/engine/render/src/asset/texture.cpp
Normal file
4
engine/modules/engine/render/src/asset/texture.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
#include "render/asset/texture.h"
|
||||
namespace api {
|
||||
|
||||
}
|
||||
@ -27,21 +27,21 @@ namespace api {
|
||||
});
|
||||
mNodes.erase(end, mNodes.end());
|
||||
}
|
||||
void FrameGraph::Execute()
|
||||
void FrameGraph::Execute(FRenderView& view)
|
||||
{
|
||||
for (auto node : mNodes) {
|
||||
switch (node.type) {
|
||||
case FrameGraphNodePtr::Render:
|
||||
ExecuteRenderPass(node.node);
|
||||
ExecuteRenderPass(node.node, view);
|
||||
break;
|
||||
case FrameGraphNodePtr::Present:
|
||||
ExecuteComputePass(node.node);
|
||||
ExecuteRenderPass(node.node, view);
|
||||
break;
|
||||
case FrameGraphNodePtr::Compute:
|
||||
ExecuteRenderPass(node.node);
|
||||
ExecuteComputePass(node.node, view);
|
||||
break;
|
||||
case FrameGraphNodePtr::Copy:
|
||||
ExecuteCopyPass(node.node);
|
||||
ExecuteCopyPass(node.node, view);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -51,22 +51,22 @@ namespace api {
|
||||
mGraph.clear();
|
||||
mNodes.clear();
|
||||
}
|
||||
void FrameGraph::ExecuteRenderPass(RenderPassNode* node)
|
||||
void FrameGraph::ExecuteRenderPass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
RenderPassContext context{};
|
||||
std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
|
||||
}
|
||||
void FrameGraph::ExecutePresentPass(RenderPassNode* node)
|
||||
void FrameGraph::ExecutePresentPass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
RenderPassContext context{};
|
||||
std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
|
||||
}
|
||||
void FrameGraph::ExecuteComputePass(RenderPassNode* node)
|
||||
void FrameGraph::ExecuteComputePass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
ComputePassContext context{};
|
||||
std::get<ComputePassExecuteFunction>(node->executor)(*this, context);
|
||||
}
|
||||
void FrameGraph::ExecuteCopyPass(RenderPassNode* node)
|
||||
void FrameGraph::ExecuteCopyPass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
CopyPassContext context{};
|
||||
std::get<CopyPassExecuteFunction>(node->executor)(*this, context);
|
||||
|
||||
@ -14,4 +14,13 @@ namespace vkn {
|
||||
class CommandBuffer;
|
||||
using voidFn = std::function<void()>;
|
||||
using commandFn = std::function<void(CommandBuffer& cmd)>;
|
||||
|
||||
struct MeshVAO
|
||||
{
|
||||
uint32_t indexCount = 0; // 索引数量
|
||||
VkBuffer indexBuffer = VK_NULL_HANDLE;
|
||||
uint32_t vertexCount = 0; // 顶点数量
|
||||
VkBuffer vertexBuffer = VK_NULL_HANDLE;
|
||||
bool inUse = false;
|
||||
};
|
||||
}
|
||||
|
||||
@ -10,6 +10,10 @@ namespace vkn {
|
||||
using api::Guid;
|
||||
using api::Mesh;
|
||||
using api::Shader;
|
||||
class VulkanContext : public api::RenderContext {
|
||||
public:
|
||||
VkSemaphore surfaceSemaphore;
|
||||
};
|
||||
class VULKAN_API VulkanAPI : public api::RenderAPI {
|
||||
private:
|
||||
VulkanWindow& window;
|
||||
|
||||
@ -1,9 +1,14 @@
|
||||
#pragma once
|
||||
#include "type.h"
|
||||
#include "render/window.h"
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
namespace api {
|
||||
class RenderContext;
|
||||
}
|
||||
namespace vkn {
|
||||
class Device;
|
||||
struct VulkanWindowArgs {
|
||||
using RenderContext = api::RenderContext;
|
||||
struct VULKAN_API VulkanWindowArgs {
|
||||
uint32_t frames;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
@ -25,9 +30,10 @@ namespace vkn {
|
||||
pmr::vector<VkSemaphore> mSemaphores{ GlobalPool() };
|
||||
public:
|
||||
VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args);
|
||||
|
||||
void Aquire(RenderContext& ctx);
|
||||
void Present(RenderContext& ctx);
|
||||
};
|
||||
class VulkanWindow : public api::Window {
|
||||
class VULKAN_API VulkanWindow : public api::Window {
|
||||
private:
|
||||
VulkanSwapchain* mSwapchain;
|
||||
public:
|
||||
@ -37,9 +43,12 @@ namespace vkn {
|
||||
void operator delete(void* p) {}
|
||||
public:
|
||||
using api::Window::Window;
|
||||
void CreateRender(VulkanWindowArgs& args);
|
||||
using CreatePFN = decltype(&SDL_Vulkan_CreateSurface);
|
||||
bool CreateRender(CreatePFN createPFN, VulkanWindowArgs& args);
|
||||
static VulkanWindow* Ptr() {
|
||||
return (VulkanWindow*)api::Window::Ptr();
|
||||
}
|
||||
void Aquire(RenderContext& ctx) { mSwapchain->Aquire(ctx); }
|
||||
void Present(RenderContext& ctx) { mSwapchain->Present(ctx); };
|
||||
};
|
||||
}
|
||||
@ -1,14 +1,6 @@
|
||||
#pragma once
|
||||
#include "vkn/type.h"
|
||||
namespace vkn {
|
||||
struct MeshVAO
|
||||
{
|
||||
uint32_t indexCount = 0; // 索引数量
|
||||
VkBuffer indexBuffer = VK_NULL_HANDLE;
|
||||
uint32_t vertexCount = 0; // 顶点数量
|
||||
VkBuffer vertexBuffer = VK_NULL_HANDLE;
|
||||
bool inUse = false;
|
||||
};
|
||||
struct Buffer {
|
||||
VkBuffer* ppBuffer;
|
||||
void* pCpuData;
|
||||
|
||||
@ -48,10 +48,10 @@ namespace vkn {
|
||||
}
|
||||
void VulkanAPI::BeginFrame()
|
||||
{
|
||||
|
||||
window.Aquire(context);
|
||||
}
|
||||
void VulkanAPI::EndFrame()
|
||||
{
|
||||
|
||||
window.Present(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,21 +4,21 @@
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/backend.h"
|
||||
#include "zlog.h"
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
#include <algorithm>
|
||||
namespace vkn {
|
||||
void VulkanWindow::CreateRender(VulkanWindowArgs& args)
|
||||
bool VulkanWindow::CreateRender(CreatePFN createPFN, VulkanWindowArgs& args)
|
||||
{
|
||||
VulkanAPI* api = VulkanAPI::Ptr();
|
||||
Backend& backend = api->GetBackend();
|
||||
VkInstance instance = backend.GetInstance().Ptr();
|
||||
VkSurfaceKHR surface;
|
||||
if (!SDL_Vulkan_CreateSurface(mPtr, instance, &surface)) {
|
||||
zlog::error("SDL_Vulkan_CreateSurface failed! {}", SDL_GetError());
|
||||
if (!createPFN(mPtr, instance, &surface)) {
|
||||
return false;
|
||||
}
|
||||
args.width = mWidth;
|
||||
args.height = mHeight;
|
||||
mSwapchain = new (GlobalPool()) VulkanSwapchain(backend.GetDevice(), surface, args);
|
||||
return true;
|
||||
}
|
||||
VulkanSwapchain::VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args)
|
||||
: mDevice(device)
|
||||
@ -50,9 +50,37 @@ namespace vkn {
|
||||
if (result != VK_SUCCESS) {
|
||||
zlog::error("Failed to create swap chain.");
|
||||
}
|
||||
pmr::vector<VkImage> swapchain_images{FramePool()};
|
||||
|
||||
mFrames = args.frames;
|
||||
pmr::vector<VkImage> swapchain_images{ FramePool() };
|
||||
uint32_t imageCount = 0;
|
||||
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, nullptr);
|
||||
swapchain_images.resize(imageCount);
|
||||
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data());
|
||||
|
||||
}
|
||||
void VulkanSwapchain::Aquire(RenderContext& ctx)
|
||||
{
|
||||
VkFence surfaceFence = mFences[ctx.frame];
|
||||
VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame];
|
||||
if (vkWaitForFences(mDevice.Ptr(), 1, &surfaceFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS)
|
||||
throw std::runtime_error("Failed to wait for fence!");
|
||||
vkAcquireNextImageKHR(mDevice.Ptr(), mPtr, UINT64_MAX, surfaceSemaphore, VK_NULL_HANDLE, &ctx.presentFrame);
|
||||
vkResetFences(mDevice.Ptr(), 1, &surfaceFence);
|
||||
}
|
||||
void VulkanSwapchain::Present(RenderContext& ctx)
|
||||
{
|
||||
VkSwapchainKHR swapChains[] = { mPtr };
|
||||
VkSemaphore waitSemaphores[] = { ctx.surfaceSemaphore };
|
||||
VkPresentInfoKHR presentInfo = {};
|
||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
presentInfo.pWaitSemaphores = waitSemaphores;
|
||||
presentInfo.waitSemaphoreCount = 1;
|
||||
presentInfo.pSwapchains = swapChains;
|
||||
presentInfo.swapchainCount = 1;
|
||||
presentInfo.pImageIndices = &ctx.presentFrame;
|
||||
presentInfo.pResults = VK_NULL_HANDLE;
|
||||
Backend::RenderWorker->Present(presentInfo);
|
||||
ctx.frame = (ctx.frame + 1) % mFrames;
|
||||
}
|
||||
VkExtent2D VulkanWindowArgs::EnableImageExtent2D(VkSurfaceCapabilitiesKHR& capabilities)
|
||||
{
|
||||
|
||||
@ -1,25 +1,33 @@
|
||||
#include "zlog.h"
|
||||
#include "zworld.h"
|
||||
#include "vkn/vulkan_window.h"
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "render/pass/demo_pass.h"
|
||||
#include <iostream>
|
||||
using namespace api;
|
||||
RenderAPI* API;
|
||||
void ZWorldModule::OnLoad(int argc, char** argv)
|
||||
{
|
||||
// 创建窗口
|
||||
new vkn::VulkanWindow(&SDL_CreateWindow, { "zengine" }, 1080, 720);
|
||||
new vkn::VulkanAPI();
|
||||
auto window = new vkn::VulkanWindow(&SDL_CreateWindow, { "zengine" , SDL_WINDOW_VULKAN }, 1080, 720);
|
||||
API = new vkn::VulkanAPI();
|
||||
auto args = vkn::VulkanWindowArgs::Default();
|
||||
args.frames = 3;
|
||||
if (!window->CreateRender(&SDL_Vulkan_CreateSurface, args)) {
|
||||
zlog::errorf("SDL_Vulkan_CreateSurface failed {}", SDL_GetError());
|
||||
}
|
||||
API->context.views.push_back({});
|
||||
}
|
||||
|
||||
void ZWorldModule::OnUnload()
|
||||
{
|
||||
|
||||
API = nullptr;
|
||||
}
|
||||
|
||||
void ZWorldModule::MainLoop()
|
||||
{
|
||||
bool running = true;
|
||||
SDL_Event event_;
|
||||
auto RenderAPI = RenderAPI::Ptr();
|
||||
while (running) {
|
||||
// 处理事件
|
||||
while (SDL_PollEvent(&event_)) {
|
||||
@ -27,7 +35,9 @@ void ZWorldModule::MainLoop()
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
RenderAPI->BeginFrame();
|
||||
RenderAPI->EndFrame();
|
||||
API->graph.AddRenderPass<DemoPass>();
|
||||
API->BeginFrame();
|
||||
API->Render();
|
||||
API->EndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user