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
EDITOR_API extern int editor_v;

View File

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

View File

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

View File

@ -11,25 +11,6 @@ namespace api {
static RscHandle<Mesh> mesh;
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{};
surface.FromTexture(graph.mSurface);
surface.colorFormat = TinyImageFormat_B8G8R8A8_SRGB;
@ -45,6 +26,25 @@ namespace api {
}
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;
ctx->SetViewport(0.0f, 0.0f,(float)surface.width,(float)surface.height, 0.f, 1.f);
ctx->SetScissor(0, 0, surface.width, surface.height);

View File

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

View File

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

View File

@ -11,20 +11,6 @@
#include "tinyimageformat/tinyimageformat_apis.h"
#include "zlog.h"
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) {
if (k1.pass != k2.pass) 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);
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;
std::map<VkShaderStageFlagBits, VkShaderModule> shaderModules;
auto& device = backend.GetDevice();
@ -108,8 +99,7 @@ namespace vkn {
shaderStageInfo.pName = "main";
shaderStages.push_back(shaderStageInfo);
}
auto it = refl::find_info(shader.Name());
auto meta = it->GetMeta(string_hash("vkMeta"));
auto meta = refl::find_meta(shader.Name(),string_hash("vkMeta"));
// 设置顶点输入格式
VkPipelineVertexInputStateCreateInfo vertexInputInfo = {};
VkVertexInputBindingDescription bindingDescription = {};
@ -185,11 +175,6 @@ namespace vkn {
multisampleInfo.pSampleMask = VK_NULL_HANDLE;
multisampleInfo.alphaToCoverageEnable = 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
VkPipelineColorBlendAttachmentState colorBlendAttachment{};
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;
VkRenderPass pass = GetRenderPass(config);
node->hash = config;
VkRenderPass pass = GetRenderPass(node->hash, config);
frameKey.pass = pass;
auto it = FramebufferCache.find(frameKey);
VkFramebuffer framebuffer = it->second;
@ -414,10 +400,10 @@ namespace vkn {
VulkanContext& ctx = *(VulkanContext*)&context;
vkCmdEndRenderPass(ctx.command);
}
VkRenderPass VulkanAPI::GetRenderPass(RenderPassKey& config) {
auto it = RenderPassCache.find(config);
VkRenderPass VulkanAPI::GetRenderPass(size_t hash, RenderPassKey& config) {
auto it = RenderPassCache.find(hash);
if (it != RenderPassCache.end()) {
return it->second;
return it->second.pass;
}
// Set up some const aliases for terseness.
const VkAttachmentLoadOp kClear = VK_ATTACHMENT_LOAD_OP_CLEAR;
@ -581,9 +567,8 @@ namespace vkn {
};
}
renderPassInfo.attachmentCount = attachmentIndex;
VkRenderPass renderPass;
VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &renderPass);
RenderPassCache.emplace(config, renderPass);
return renderPass;
VkResult error = vkCreateRenderPass(backend.GetDevice().Ptr(), &renderPassInfo, nullptr, &config.pass);
RenderPassCache.emplace(hash, config);
return config.pass;
}
}

View File

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