update
This commit is contained in:
parent
f8913cd7d2
commit
d154ac2251
@ -8,6 +8,8 @@ namespace api {
|
||||
class TextureBuilder;
|
||||
class RenderPassBuilder;
|
||||
public:
|
||||
RscHandle<Texture> mSurface;
|
||||
table<Name, RscHandle<Texture>> mResourceTable;
|
||||
lemon::ListGraph mGraph;
|
||||
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
|
||||
public:
|
||||
@ -21,7 +23,13 @@ namespace api {
|
||||
void Compile();
|
||||
void Execute(FRenderView& view);
|
||||
void Clear();
|
||||
|
||||
RscHandle<Texture> Resource(Name name) {
|
||||
auto it = mResourceTable.find(name);
|
||||
if (it == mResourceTable.end()) {
|
||||
return {};
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
public:
|
||||
void ExecuteRenderPass(RenderPassNode* node, FRenderView& view);
|
||||
void ExecutePresentPass(RenderPassNode* node, FRenderView& view);
|
||||
|
||||
@ -41,8 +41,8 @@ namespace api {
|
||||
};
|
||||
struct FrameResource {
|
||||
using Resource = std::variant<FrameTextureResource, void*>;
|
||||
Name name;
|
||||
Resource resource;
|
||||
Name name;
|
||||
Resource resource;
|
||||
FrameGraphNodePtr source;
|
||||
pmr::vector<FrameGraphNodePtr> targets{ FramePool() };
|
||||
template<typename T>
|
||||
|
||||
@ -9,10 +9,10 @@ namespace api {
|
||||
class RENDER_API RenderAPI : public Singleton<RenderAPI>
|
||||
{
|
||||
public:
|
||||
RenderContext* ctx;
|
||||
RenderContext& context;
|
||||
FrameGraph graph;
|
||||
RenderAPI() {};
|
||||
virtual ~RenderAPI() {};
|
||||
RenderAPI(RenderContext* ctx) : context(*ctx){};
|
||||
virtual ~RenderAPI() { delete &context; };
|
||||
public:
|
||||
void* operator new(size_t size) {
|
||||
return ::operator new(size, GlobalPool());
|
||||
|
||||
@ -17,4 +17,28 @@ namespace api {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
enum class RenderLayout : uint8_t {
|
||||
// The initial layout after the creation of the VkImage. We use this to denote the state before
|
||||
// any transition.
|
||||
UNDEFINED,
|
||||
// Fragment/vertex shader accessible layout for reading and writing.
|
||||
READ_WRITE,
|
||||
// Fragment/vertex shader accessible layout for reading only.
|
||||
READ_ONLY,
|
||||
// For the source of a copy operation.
|
||||
TRANSFER_SRC,
|
||||
// For the destination of a copy operation.
|
||||
TRANSFER_DST,
|
||||
// For using a depth texture as an attachment.
|
||||
DEPTH_ATTACHMENT,
|
||||
// For using a depth texture both as an attachment and as a sampler.
|
||||
DEPTH_SAMPLER,
|
||||
// For swapchain images that will be presented.
|
||||
PRESENT,
|
||||
// For color attachments, but also used when the image is a sampler.
|
||||
// TODO: explore separate layout policies for attachment+sampling and just attachment.
|
||||
COLOR_ATTACHMENT,
|
||||
// For color attachment MSAA resolves.
|
||||
COLOR_ATTACHMENT_RESOLVE,
|
||||
};
|
||||
}
|
||||
@ -6,7 +6,7 @@ namespace api {
|
||||
auto edge = graph.CreateTexture(
|
||||
[=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) {
|
||||
builder.Name("import")
|
||||
.Import({});
|
||||
.Import(graph.Resource("demo_input"));
|
||||
});
|
||||
builder.Name("DemoPass")
|
||||
.Read(TextureDesc::Make())
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <functional>
|
||||
#define VK_NO_PROTOTYPES
|
||||
#include "volk/volk.h"
|
||||
#include <render/type.h>
|
||||
#define Z_RENDER_DEBUG 1
|
||||
namespace vkn {
|
||||
using pmr::Name;
|
||||
@ -14,7 +15,7 @@ namespace vkn {
|
||||
class CommandBuffer;
|
||||
using voidFn = std::function<void()>;
|
||||
using commandFn = std::function<void(CommandBuffer& cmd)>;
|
||||
|
||||
static constexpr uint8_t MAX_SUPPORTED_RENDER_TARGET_COUNT = 8u;
|
||||
struct MeshVAO
|
||||
{
|
||||
uint32_t indexCount = 0; // 索引数量
|
||||
@ -23,4 +24,48 @@ namespace vkn {
|
||||
VkBuffer vertexBuffer = VK_NULL_HANDLE;
|
||||
bool inUse = false;
|
||||
};
|
||||
enum class TargetBufferFlags : uint32_t {
|
||||
NONE = 0x0u, //!< No buffer selected.
|
||||
COLOR0 = 0x00000001u, //!< Color buffer selected.
|
||||
COLOR1 = 0x00000002u, //!< Color buffer selected.
|
||||
COLOR2 = 0x00000004u, //!< Color buffer selected.
|
||||
COLOR3 = 0x00000008u, //!< Color buffer selected.
|
||||
COLOR4 = 0x00000010u, //!< Color buffer selected.
|
||||
COLOR5 = 0x00000020u, //!< Color buffer selected.
|
||||
COLOR6 = 0x00000040u, //!< Color buffer selected.
|
||||
COLOR7 = 0x00000080u, //!< Color buffer selected.
|
||||
|
||||
COLOR = COLOR0, //!< \deprecated
|
||||
COLOR_ALL = COLOR0 | COLOR1 | COLOR2 | COLOR3 | COLOR4 | COLOR5 | COLOR6 | COLOR7,
|
||||
DEPTH = 0x10000000u, //!< Depth buffer selected.
|
||||
STENCIL = 0x20000000u, //!< Stencil buffer selected.
|
||||
DEPTH_AND_STENCIL = DEPTH | STENCIL, //!< depth and stencil buffer selected.
|
||||
ALL = COLOR_ALL | DEPTH | STENCIL //!< Color, depth and stencil buffer selected.
|
||||
};
|
||||
|
||||
struct alignas(8) RenderPassKey {
|
||||
// For each target, we need to know three image layouts: the layout BEFORE the pass, the
|
||||
// layout DURING the pass, and the layout AFTER the pass. Here are the rules:
|
||||
// - For depth, we explicitly specify all three layouts.
|
||||
// - Color targets have their initial image layout specified with a bitmask.
|
||||
// - For each color target, the pre-existing layout is either UNDEFINED (0) or GENERAL (1).
|
||||
// - The render pass and final images layout for color buffers is always
|
||||
// VulkanLayout::COLOR_ATTACHMENT.
|
||||
uint8_t initialColorLayoutMask;
|
||||
|
||||
// Note that if VulkanLayout grows beyond 16, we'd need to up this.
|
||||
api::RenderLayout initialDepthLayout : 8;
|
||||
uint8_t padding0;
|
||||
uint8_t padding1;
|
||||
|
||||
VkFormat colorFormat[MAX_SUPPORTED_RENDER_TARGET_COUNT]; // 32 bytes
|
||||
VkFormat depthFormat; // 4 bytes
|
||||
TargetBufferFlags clear; // 4 bytes
|
||||
TargetBufferFlags discardStart; // 4 bytes
|
||||
TargetBufferFlags discardEnd; // 4 bytes
|
||||
uint8_t samples; // 1 byte
|
||||
uint8_t needsResolveMask; // 1 byte
|
||||
uint8_t subpassMask; // 1 byte
|
||||
uint8_t viewCount; // 1 byte
|
||||
};
|
||||
}
|
||||
|
||||
@ -10,8 +10,7 @@ namespace vkn {
|
||||
using api::Guid;
|
||||
using api::Mesh;
|
||||
using api::Shader;
|
||||
class VulkanContext : public api::RenderContext {
|
||||
public:
|
||||
struct VulkanContext : public api::RenderContext {
|
||||
VkSemaphore surfaceSemaphore;
|
||||
};
|
||||
class VULKAN_API VulkanAPI : public api::RenderAPI {
|
||||
@ -19,6 +18,8 @@ namespace vkn {
|
||||
VulkanWindow& window;
|
||||
Backend backend;
|
||||
table<Guid, MeshVAO> MeshTable;
|
||||
table<Guid, VkRenderPass> RenderPassCache;
|
||||
|
||||
public:
|
||||
VulkanAPI();
|
||||
|
||||
@ -33,6 +34,8 @@ namespace vkn {
|
||||
void BeginFrame()override;
|
||||
void EndFrame()override;
|
||||
|
||||
VkRenderPass GetRenderPass(RenderPassKey config);
|
||||
|
||||
Backend& GetBackend() {
|
||||
return backend;
|
||||
}
|
||||
|
||||
@ -2,12 +2,9 @@
|
||||
#include "type.h"
|
||||
#include "render/window.h"
|
||||
#include <SDL2/SDL_vulkan.h>
|
||||
namespace api {
|
||||
class RenderContext;
|
||||
}
|
||||
namespace vkn {
|
||||
class Device;
|
||||
using RenderContext = api::RenderContext;
|
||||
struct VulkanContext;
|
||||
struct VULKAN_API VulkanWindowArgs {
|
||||
uint32_t frames;
|
||||
uint32_t width;
|
||||
@ -30,8 +27,8 @@ namespace vkn {
|
||||
pmr::vector<VkSemaphore> mSemaphores{ GlobalPool() };
|
||||
public:
|
||||
VulkanSwapchain(Device& device, VkSurfaceKHR surface, VulkanWindowArgs& args);
|
||||
void Aquire(RenderContext& ctx);
|
||||
void Present(RenderContext& ctx);
|
||||
void Aquire(VulkanContext& ctx);
|
||||
void Present(VulkanContext& ctx);
|
||||
};
|
||||
class VULKAN_API VulkanWindow : public api::Window {
|
||||
private:
|
||||
@ -48,7 +45,7 @@ namespace vkn {
|
||||
static VulkanWindow* Ptr() {
|
||||
return (VulkanWindow*)api::Window::Ptr();
|
||||
}
|
||||
void Aquire(RenderContext& ctx) { mSwapchain->Aquire(ctx); }
|
||||
void Present(RenderContext& ctx) { mSwapchain->Present(ctx); };
|
||||
void Aquire(VulkanContext& ctx) { mSwapchain->Aquire(ctx); };
|
||||
void Present(VulkanContext& ctx) { mSwapchain->Present(ctx); };
|
||||
};
|
||||
}
|
||||
@ -20,7 +20,5 @@ namespace vkn {
|
||||
public:
|
||||
static const Name TransferQueue;
|
||||
static const Name RenderQueue;
|
||||
static const Name ComputeQueue;
|
||||
static const Name PresentQueue;
|
||||
};
|
||||
}
|
||||
@ -23,15 +23,12 @@ namespace vkn {
|
||||
|
||||
DeviceCreator deviceCreator = DeviceCreator{ *mInstance };
|
||||
deviceCreator.AddWindowExtension();
|
||||
deviceCreator.AddQueue(Queue::TransferQueue,VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||
deviceCreator.AddQueue(Queue::TransferQueue,VkQueueFlagBits::VK_QUEUE_TRANSFER_BIT, 1.0);
|
||||
deviceCreator.AddQueue(Queue::RenderQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||
deviceCreator.AddQueue(Queue::ComputeQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||
deviceCreator.AddQueue(Queue::PresentQueue, VkQueueFlagBits::VK_QUEUE_GRAPHICS_BIT, 1.0);
|
||||
mDevice = new (GlobalPool()) Device(deviceCreator);
|
||||
|
||||
Backend::TransferWorker = InitWorker<BufferWorker>(Queue::TransferQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
Backend::RenderWorker = InitWorker<CommandWorker>(Queue::RenderQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
Backend::PresentWorker = InitWorker<CommandWorker>(Queue::ComputeQueue, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
|
||||
Backend::TransferWorker->InitVmaAllocator(mInstance->Ptr());
|
||||
}
|
||||
Backend::~Backend()
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/vulkan_window.h"
|
||||
#include "vkn/wrapper/buffer.h"
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "vkn/thread/buffer_worker.h"
|
||||
#include "vkn/thread/command_worker.h"
|
||||
#include "render/asset/mesh.h"
|
||||
namespace vkn {
|
||||
VulkanAPI::VulkanAPI() : window(*VulkanWindow::Ptr()), backend(VulkanEngineName)
|
||||
VulkanAPI::VulkanAPI() : RenderAPI(new VulkanContext())
|
||||
, window(*VulkanWindow::Ptr())
|
||||
, backend(VulkanEngineName)
|
||||
{
|
||||
|
||||
}
|
||||
@ -48,10 +51,24 @@ namespace vkn {
|
||||
}
|
||||
void VulkanAPI::BeginFrame()
|
||||
{
|
||||
window.Aquire(context);
|
||||
window.Aquire(*(VulkanContext*)&context);
|
||||
}
|
||||
void VulkanAPI::EndFrame()
|
||||
{
|
||||
window.Present(context);
|
||||
window.Present(*(VulkanContext*)&context);
|
||||
}
|
||||
VkRenderPass VulkanAPI::GetRenderPass(RenderPassKey config) {
|
||||
// Finally, create the VkRenderPass.
|
||||
VkRenderPassCreateInfo renderPassInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
|
||||
.attachmentCount = 0u,
|
||||
.pAttachments = attachments,
|
||||
.subpassCount = hasSubpasses ? 2u : 1u,
|
||||
.pSubpasses = subpasses,
|
||||
.dependencyCount = hasSubpasses ? 1u : 0u,
|
||||
.pDependencies = dependencies
|
||||
};
|
||||
VkRenderPass renderPass;
|
||||
VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &renderPass);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "vkn/wrapper/instance.h"
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/backend.h"
|
||||
#include "vkn/thread/command_worker.h"
|
||||
#include "zlog.h"
|
||||
#include <algorithm>
|
||||
namespace vkn {
|
||||
@ -56,18 +57,23 @@ namespace vkn {
|
||||
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, nullptr);
|
||||
swapchain_images.resize(imageCount);
|
||||
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data());
|
||||
|
||||
for (int i = 0; i < mFrames; i++) {
|
||||
//mSurfaces.push_back(new Image(Creator.device, "swapchain" + to_string(i), swapchain_images[i], args));
|
||||
mSemaphores.push_back(mDevice.CreateSemaphore());
|
||||
mFences.push_back(mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT));
|
||||
}
|
||||
}
|
||||
void VulkanSwapchain::Aquire(RenderContext& ctx)
|
||||
void VulkanSwapchain::Aquire(VulkanContext& ctx)
|
||||
{
|
||||
VkFence surfaceFence = mFences[ctx.frame];
|
||||
VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame];
|
||||
ctx.surfaceSemaphore = surfaceSemaphore;
|
||||
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)
|
||||
void VulkanSwapchain::Present(VulkanContext& ctx)
|
||||
{
|
||||
VkSwapchainKHR swapChains[] = { mPtr };
|
||||
VkSemaphore waitSemaphores[] = { ctx.surfaceSemaphore };
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
namespace vkn {
|
||||
const Name Queue::TransferQueue = "transfer";
|
||||
const Name Queue::RenderQueue = "render" ;
|
||||
const Name Queue::ComputeQueue = "computer";
|
||||
const Name Queue::PresentQueue = "present" ;
|
||||
Queue::Queue(Name name, uint32_t queueFamilyIndex, VkQueue queue)
|
||||
: mName(name)
|
||||
{
|
||||
|
||||
@ -5,12 +5,11 @@
|
||||
#include "render/pass/demo_pass.h"
|
||||
#include <iostream>
|
||||
using namespace api;
|
||||
RenderAPI* API;
|
||||
void ZWorldModule::OnLoad(int argc, char** argv)
|
||||
{
|
||||
// 创建窗口
|
||||
auto window = new vkn::VulkanWindow(&SDL_CreateWindow, { "zengine" , SDL_WINDOW_VULKAN }, 1080, 720);
|
||||
API = new vkn::VulkanAPI();
|
||||
RenderAPI* API = new vkn::VulkanAPI();
|
||||
auto args = vkn::VulkanWindowArgs::Default();
|
||||
args.frames = 3;
|
||||
if (!window->CreateRender(&SDL_Vulkan_CreateSurface, args)) {
|
||||
@ -21,11 +20,11 @@ void ZWorldModule::OnLoad(int argc, char** argv)
|
||||
|
||||
void ZWorldModule::OnUnload()
|
||||
{
|
||||
API = nullptr;
|
||||
}
|
||||
|
||||
void ZWorldModule::MainLoop()
|
||||
{
|
||||
RenderAPI* API = RenderAPI::Ptr();
|
||||
bool running = true;
|
||||
SDL_Event event_;
|
||||
while (running) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user