This commit is contained in:
ouczbs 2024-10-30 21:02:51 +08:00
parent 11590308f9
commit fe8a28c8b0
10 changed files with 62 additions and 72 deletions

View File

@ -1,2 +1 @@
#pragma once #pragma once
EDITOR_API extern int editor_v;

View File

@ -4,14 +4,17 @@
#include "lemon/list_graph.h" #include "lemon/list_graph.h"
#include <functional> #include <functional>
namespace api { namespace api {
struct RenderPassNode;
struct RenderContext; struct RenderContext;
struct ComputePassContext {}; struct ComputePassContext {};
struct RenderPassContext { struct RenderPassContext {
RenderContext* parent; RenderContext* parent;
RenderPassContext(RenderContext* parent) : parent(parent) {}; RenderPassNode* node;
RenderPassContext(RenderContext* parent, RenderPassNode* node) : parent(parent),node(node) {};
RenderContext* operator->() { RenderContext* operator->() {
return parent; return parent;
} }
size_t PassKey();
}; };
struct CopyPassContext {}; struct CopyPassContext {};
@ -88,7 +91,8 @@ namespace api {
}; };
using RenderPassEdgeIterFn = std::function<void(FrameResource*, FrameGraphEdgePtr)>; using RenderPassEdgeIterFn = std::function<void(FrameResource*, FrameGraphEdgePtr)>;
struct RenderPassNode { struct RenderPassNode {
Name name; Name name;
size_t hash;
RenderPassNodeExecuteFn executor; RenderPassNodeExecuteFn executor;
pmr::vector<FrameGraphEdgePtr> inEdges{ FramePool() }; pmr::vector<FrameGraphEdgePtr> inEdges{ FramePool() };
pmr::vector<FrameGraphEdgePtr> outEdges{ FramePool() }; pmr::vector<FrameGraphEdgePtr> outEdges{ FramePool() };
@ -120,4 +124,8 @@ namespace api {
node = new (FramePool()) RenderPassNode(); node = new (FramePool()) RenderPassNode();
node->executor = executor; node->executor = executor;
} }
inline size_t RenderPassContext::PassKey()
{
return node->hash;
}
} }

View File

@ -27,7 +27,7 @@ namespace api {
virtual void SetStaticMesh(Mesh& mesh) = 0; virtual void SetStaticMesh(Mesh& mesh) = 0;
virtual void DrawStaticMesh(Mesh& mesh) = 0; virtual void DrawStaticMesh(Mesh& mesh) = 0;
virtual void LoadShader(Shader& shader) = 0; virtual void LoadShader(Shader& shader, size_t passKey) = 0;
virtual ImagePtr CreateTexture(TextureDesc desc) = 0; virtual ImagePtr CreateTexture(TextureDesc desc) = 0;
virtual ImageViewPtr CreateTextureView(TextureViewDesc desc) = 0; virtual ImageViewPtr CreateTextureView(TextureViewDesc desc) = 0;

View File

@ -88,7 +88,7 @@ namespace api {
{ {
ExecuteResourceBarriers(node); ExecuteResourceBarriers(node);
RenderAPI::Ptr()->BeginRenderPass(node); RenderAPI::Ptr()->BeginRenderPass(node);
RenderPassContext context{view.context}; RenderPassContext context{view.context, node};
std::get<RenderPassExecuteFunction>(node->executor)(*this, context); std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
RenderAPI::Ptr()->EndRenderPass(node); RenderAPI::Ptr()->EndRenderPass(node);
} }

View File

@ -11,25 +11,6 @@ namespace api {
static RscHandle<Mesh> mesh; static RscHandle<Mesh> mesh;
bool DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) bool DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
{ {
if (!shader) {
shader = ResourceSystem::Ptr()->LoadEmplaceResource<Shader>();
shader->Name("api::PosVertex");
auto vert = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.vert");
auto frag = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.frag");
shader->SetVertHandle(vert);
shader->SetFragHandle(frag);
RenderAPI::Ptr()->LoadShader(*shader);
vector<PosVertex> vertices = {
{.Position = { 0.0f, -0.5f, 0.f}}, // 底部顶点,红色
{.Position = { 0.5f, 0.5f, 0.f}}, // 右上顶点,绿色
{.Position = {-0.5f, 0.5f, 0.f}} // 左上顶点,蓝色
};
vector<uint32_t> indices = {0, 1, 2};
mesh = ResourceSystem::Ptr()->LoadEmplaceResource<Mesh>(vertices, indices);
material = ResourceSystem::Ptr()->LoadEmplaceResource<Material>(shader);
mesh->SetMaterial(material);
RenderAPI::Ptr()->SetStaticMesh(*mesh);
}
AttachmentDesc surface{}; AttachmentDesc surface{};
surface.FromTexture(graph.mSurface); surface.FromTexture(graph.mSurface);
surface.colorFormat = TinyImageFormat_B8G8R8A8_SRGB; surface.colorFormat = TinyImageFormat_B8G8R8A8_SRGB;
@ -45,6 +26,25 @@ namespace api {
} }
void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx) void DemoPass::Execute(FrameGraph& graph, RenderPassContext& ctx)
{ {
if (!shader) {
shader = ResourceSystem::Ptr()->LoadEmplaceResource<Shader>();
shader->Name("api::PosVertex");
auto vert = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.vert");
auto frag = ResourceSystem::Ptr()->Load<ShaderProgram>("/engine/assets/shader/simple.frag");
shader->SetVertHandle(vert);
shader->SetFragHandle(frag);
RenderAPI::Ptr()->LoadShader(*shader, ctx.PassKey());
vector<PosVertex> vertices = {
{.Position = { 0.0f, -0.5f, 0.f}}, // 底部顶点,红色
{.Position = { 0.5f, 0.5f, 0.f}}, // 右上顶点,绿色
{.Position = {-0.5f, 0.5f, 0.f}} // 左上顶点,蓝色
};
vector<uint32_t> indices = { 0, 1, 2 };
mesh = ResourceSystem::Ptr()->LoadEmplaceResource<Mesh>(vertices, indices);
material = ResourceSystem::Ptr()->LoadEmplaceResource<Material>(shader);
mesh->SetMaterial(material);
RenderAPI::Ptr()->SetStaticMesh(*mesh);
}
auto& surface = graph.mSurface; auto& surface = graph.mSurface;
ctx->SetViewport(0.0f, 0.0f,(float)surface.width,(float)surface.height, 0.f, 1.f); ctx->SetViewport(0.0f, 0.0f,(float)surface.width,(float)surface.height, 0.f, 1.f);
ctx->SetScissor(0, 0, surface.width, surface.height); ctx->SetScissor(0, 0, surface.width, surface.height);

View File

@ -341,4 +341,11 @@ namespace refl {
} }
meta_info<T>(); meta_info<T>();
} }
inline const UClass* find_meta(Name name, size_t hash) {
auto it = find_info(name);
if (it) {
return it->GetMeta(hash);
}
return nullptr;
}
} }

View File

@ -38,6 +38,7 @@ namespace vkn {
bool inUse = false; bool inUse = false;
}; };
struct RenderPassKey { struct RenderPassKey {
VkRenderPass pass;
VkFormat colorFormat[8]; VkFormat colorFormat[8];
VkFormat depthFormat; VkFormat depthFormat;
VkSampleCountFlagBits samples; VkSampleCountFlagBits samples;
@ -47,6 +48,9 @@ namespace vkn {
uint8_t subpassMask;// 1 byte uint8_t subpassMask;// 1 byte
uint8_t initialColorLayoutMask;// 1 byte uint8_t initialColorLayoutMask;// 1 byte
uint8_t needsResolveMask; // 1 byte uint8_t needsResolveMask; // 1 byte
operator size_t() {
return meta::MurmurHashFn(this);
}
}; };
struct FramebufferKey { struct FramebufferKey {
VkRenderPass pass; VkRenderPass pass;
@ -100,14 +104,6 @@ namespace vkn {
}; };
} }
namespace std { namespace std {
template<>
struct hash<vkn::RenderPassKey>
{
size_t operator()(const vkn::RenderPassKey& key) const noexcept
{
return meta::MurmurHashFn(key);
}
};
template<> template<>
struct hash<vkn::FramebufferKey> struct hash<vkn::FramebufferKey>
{ {

View File

@ -3,10 +3,7 @@
#include "asset/res/guid.h" #include "asset/res/guid.h"
#include "backend.h" #include "backend.h"
namespace vkn { namespace vkn {
class Backend;
class VulkanWindow; class VulkanWindow;
struct MeshVAO;
struct RenderPassKey;
using api::Guid; using api::Guid;
using api::Mesh; using api::Mesh;
using api::Shader; using api::Shader;
@ -17,7 +14,7 @@ namespace vkn {
Backend backend; Backend backend;
table<Guid, MeshVAO> MeshTable; table<Guid, MeshVAO> MeshTable;
table<Guid, VulkanPipeline> PipelineTable; table<Guid, VulkanPipeline> PipelineTable;
table<RenderPassKey, VkRenderPass> RenderPassCache; table<size_t, RenderPassKey> RenderPassCache;
table<FramebufferKey, VkFramebuffer> FramebufferCache; table<FramebufferKey, VkFramebuffer> FramebufferCache;
public: public:
VulkanAPI(); VulkanAPI();
@ -27,7 +24,7 @@ namespace vkn {
void SetStaticMesh(Mesh& mesh)override; void SetStaticMesh(Mesh& mesh)override;
void DrawStaticMesh(Mesh& mesh)override; void DrawStaticMesh(Mesh& mesh)override;
void LoadShader(Shader& shader)override; void LoadShader(Shader& shader, size_t passKey)override;
ImagePtr CreateTexture(TextureDesc desc)override; ImagePtr CreateTexture(TextureDesc desc)override;
ImageViewPtr CreateTextureView(TextureViewDesc desc)override; ImageViewPtr CreateTextureView(TextureViewDesc desc)override;
@ -38,8 +35,7 @@ namespace vkn {
void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override; void ExecuteResourceBarriers(const ResourceBarrierDesc& desc) override;
VkPipeline GetPipeline() { return nullptr; }; VkPipeline GetPipeline() { return nullptr; };
VkRenderPass GetRenderPass(RenderPassKey& config); VkRenderPass GetRenderPass(size_t hash, RenderPassKey& config);
Backend& GetBackend() { Backend& GetBackend() {
return backend; return backend;
} }

View File

@ -11,20 +11,6 @@
#include "tinyimageformat/tinyimageformat_apis.h" #include "tinyimageformat/tinyimageformat_apis.h"
#include "zlog.h" #include "zlog.h"
namespace vkn { namespace vkn {
inline bool operator==(const RenderPassKey& k1, const RenderPassKey& k2) {
if (k1.initialColorLayoutMask != k2.initialColorLayoutMask) return false;
for (int i = 0; i < MAX_SUPPORTED_RENDER_TARGET_COUNT; i++) {
if (k1.colorFormat[i] != k2.colorFormat[i]) return false;
}
if (k1.depthFormat != k2.depthFormat) return false;
if (k1.clear != k2.clear) return false;
if (k1.discardStart != k2.discardStart) return false;
if (k1.discardEnd != k2.discardEnd) return false;
if (k1.samples != k2.samples) return false;
if (k1.needsResolveMask != k2.needsResolveMask) return false;
if (k1.subpassMask != k2.subpassMask) return false;
return true;
}
inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) { inline bool operator==(const FramebufferKey& k1, const FramebufferKey& k2) {
if (k1.pass != k2.pass) return false; if (k1.pass != k2.pass) return false;
if (k1.attachmentCount != k2.attachmentCount) return false; if (k1.attachmentCount != k2.attachmentCount) return false;
@ -90,8 +76,13 @@ namespace vkn {
vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, 1, &pipeline.descriptorSet, 0, VK_NULL_HANDLE); vkCmdBindDescriptorSets(ptr, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipelineLayout, 0, 1, &pipeline.descriptorSet, 0, VK_NULL_HANDLE);
vkCmdDrawIndexed(ptr, vulkanVAO.indexCount, 1, 0, 0, 0); vkCmdDrawIndexed(ptr, vulkanVAO.indexCount, 1, 0, 0, 0);
} }
void VulkanAPI::LoadShader(Shader& shader) void VulkanAPI::LoadShader(Shader& shader, size_t passKey)
{ {
auto itPass = RenderPassCache.find(passKey);
if (itPass == RenderPassCache.end()) {
return;
}
VkRenderPass renderpass = itPass->second.pass;
pmr::vector<VkPipelineShaderStageCreateInfo> shaderStages; pmr::vector<VkPipelineShaderStageCreateInfo> shaderStages;
std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules; std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules;
auto& device = backend.GetDevice(); auto& device = backend.GetDevice();
@ -108,8 +99,7 @@ namespace vkn {
shaderStageInfo.pName = "main"; shaderStageInfo.pName = "main";
shaderStages.push_back(shaderStageInfo); shaderStages.push_back(shaderStageInfo);
} }
auto it = refl::find_info(shader.Name()); auto meta = refl::find_meta(shader.Name(),string_hash("vkMeta"));
auto meta = it->GetMeta(string_hash("vkMeta"));
// 设置顶点输入格式 // 设置顶点输入格式
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {}; VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
VkVertexInputBindingDescription bindingDescription = {}; VkVertexInputBindingDescription bindingDescription = {};
@ -185,11 +175,6 @@ namespace vkn {
multisampleInfo.pSampleMask = VK_NULL_HANDLE; multisampleInfo.pSampleMask = VK_NULL_HANDLE;
multisampleInfo.alphaToCoverageEnable = VK_FALSE; multisampleInfo.alphaToCoverageEnable = VK_FALSE;
multisampleInfo.alphaToOneEnable = VK_FALSE; multisampleInfo.alphaToOneEnable = VK_FALSE;
RenderPassKey config{};
config.colorFormat[0] = VK_FORMAT_B8G8R8A8_SRGB;
config.samples = vkApiGetSmpleCountFlag(api::SAMPLE_COUNT_1);
VkRenderPass renderpass = GetRenderPass(config);
// Color Blend // Color Blend
VkPipelineColorBlendAttachmentState colorBlendAttachment{}; VkPipelineColorBlendAttachmentState colorBlendAttachment{};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
@ -376,7 +361,8 @@ namespace vkn {
} }
} }
frameKey.attachmentCount = i; frameKey.attachmentCount = i;
VkRenderPass pass = GetRenderPass(config); node->hash = config;
VkRenderPass pass = GetRenderPass(node->hash, config);
frameKey.pass = pass; frameKey.pass = pass;
auto it = FramebufferCache.find(frameKey); auto it = FramebufferCache.find(frameKey);
VkFramebuffer framebuffer = it->second; VkFramebuffer framebuffer = it->second;
@ -414,10 +400,10 @@ namespace vkn {
VulkanContext& ctx = *(VulkanContext*)&context; VulkanContext& ctx = *(VulkanContext*)&context;
vkCmdEndRenderPass(ctx.command); vkCmdEndRenderPass(ctx.command);
} }
VkRenderPass VulkanAPI::GetRenderPass(RenderPassKey& config) { VkRenderPass VulkanAPI::GetRenderPass(size_t hash, RenderPassKey& config) {
auto it = RenderPassCache.find(config); auto it = RenderPassCache.find(hash);
if (it != RenderPassCache.end()) { if (it != RenderPassCache.end()) {
return it->second; return it->second.pass;
} }
// Set up some const aliases for terseness. // Set up some const aliases for terseness.
const VkAttachmentLoadOp kClear = VK_ATTACHMENT_LOAD_OP_CLEAR; const VkAttachmentLoadOp kClear = VK_ATTACHMENT_LOAD_OP_CLEAR;
@ -581,9 +567,8 @@ namespace vkn {
}; };
} }
renderPassInfo.attachmentCount = attachmentIndex; renderPassInfo.attachmentCount = attachmentIndex;
VkRenderPass renderPass; VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &config.pass);
VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &renderPass); RenderPassCache.emplace(hash, config);
RenderPassCache.emplace(config, renderPass); return config.pass;
return renderPass;
} }
} }

View File

@ -1,2 +1 @@
#include "api.h" #include "api.h"
int editor_v;