This commit is contained in:
ouczbs 2024-10-12 17:40:59 +08:00
parent 9e9fab97f4
commit c39296d050
16 changed files with 92 additions and 23 deletions

View File

@ -10,7 +10,8 @@ namespace api {
public: public:
TextureDesc mSurface; TextureDesc mSurface;
table<Name, TextureDesc> mResourceTable; table<Name, TextureDesc> mResourceTable;
table<Name, TextureDesc> mResourceTable; table<TextureDesc::Key, TextureDesc> mResourcePool;
table<TextureDesc::Key, TextureDesc> mResourceViewPool;
lemon::ListGraph mGraph; lemon::ListGraph mGraph;
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()}; pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
public: public:

View File

@ -40,7 +40,6 @@ namespace api {
Name name; Name name;
ResourceState sourceState; ResourceState sourceState;
Resource resource; Resource resource;
ImagePtr image;
FrameGraphNodePtr source; FrameGraphNodePtr source;
pmr::vector<FrameGraphNodePtr> targets{ FramePool() }; pmr::vector<FrameGraphNodePtr> targets{ FramePool() };
template<typename T> template<typename T>
@ -72,6 +71,7 @@ namespace api {
FrameResource* operator ->()const { FrameResource* operator ->()const {
return resource; return resource;
} }
void Resolve(FrameGraph* graph);
}; };
using RenderPassEdgeIterFn = std::function<void(FrameResource*, FrameGraphEdgePtr)>; using RenderPassEdgeIterFn = std::function<void(FrameResource*, FrameGraphEdgePtr)>;
struct RenderPassNode { struct RenderPassNode {

View File

@ -7,4 +7,5 @@ namespace api {
static void Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder); static void Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder);
static void Execute(FrameGraph&, RenderPassContext&); static void Execute(FrameGraph&, RenderPassContext&);
}; };
} }

View File

@ -8,6 +8,15 @@ namespace api {
Vulkan, Vulkan,
D3D12 D3D12
}; };
enum SampleCount
{
SAMPLE_COUNT_1 = 1,
SAMPLE_COUNT_2 = 2,
SAMPLE_COUNT_4 = 4,
SAMPLE_COUNT_8 = 8,
SAMPLE_COUNT_16 = 16,
SAMPLE_COUNT_COUNT = 5,
};
struct BufferDesc { struct BufferDesc {
static BufferDesc Make() { static BufferDesc Make() {
return {}; return {};
@ -15,6 +24,7 @@ namespace api {
}; };
using ImagePtr = void*; using ImagePtr = void*;
struct TextureDesc { struct TextureDesc {
using Key = uint32_t;
ImagePtr image; ImagePtr image;
static TextureDesc Make() { static TextureDesc Make() {
return {}; return {};
@ -23,6 +33,7 @@ namespace api {
struct AttachmentDesc { struct AttachmentDesc {
ImagePtr image; ImagePtr image;
TinyImageFormat colorFormat; TinyImageFormat colorFormat;
SampleCount sampleCount;
static AttachmentDesc Make() { static AttachmentDesc Make() {
return {}; return {};
} }

View File

@ -80,17 +80,8 @@ namespace api {
{ {
pmr::vector<BufferBarrier> bufferBarrier{FramePool()}; pmr::vector<BufferBarrier> bufferBarrier{FramePool()};
pmr::vector<TextureBarrier> textureBarrier{ FramePool() }; pmr::vector<TextureBarrier> textureBarrier{ FramePool() };
node->ForeachEdge([&](FrameResource* resource, FrameGraphEdgePtr edge) { node->ForeachEdge([&, this](FrameResource* resource, FrameGraphEdgePtr edge) {
if (edge) { edge.Resolve(this);
if (!edge->image) {
if (edge.ppImage) {
edge->image = *edge.ppImage;
}
else {
edge->image = Resource("");
}
}
}
if (!edge || edge.targetState == resource->sourceState) { if (!edge || edge.targetState == resource->sourceState) {
return; return;
} }

View File

@ -18,7 +18,6 @@ namespace api {
resource = edge.Make(); resource = edge.Make();
resource->source = node; resource->source = node;
resource->resource = desc; resource->resource = desc;
edge->image = desc.image;
node->inEdges.push_back(edge); node->inEdges.push_back(edge);
return *this; return *this;
} }
@ -41,7 +40,6 @@ namespace api {
resource = edge.Make(); resource = edge.Make();
resource->source = node; resource->source = node;
resource->resource = desc; resource->resource = desc;
edge->image = desc.image;
node->outEdges.push_back(edge); node->outEdges.push_back(edge);
return *this; return *this;
} }
@ -74,7 +72,6 @@ namespace api {
edge.ppImage = &ptr; edge.ppImage = &ptr;
edge.targetState = state; edge.targetState = state;
edge->resource = desc; edge->resource = desc;
edge->image = desc.image;
return *this; return *this;
} }
} }

View File

@ -0,0 +1,24 @@
#include "render/graph/type.h"
namespace api {
void FrameGraphEdgePtr::Resolve(FrameGraph* graph)
{
if (!resource) {
Make();
}
ImagePtr* imageptr;
if (resource->IsAttachment()) {
AttachmentDesc& desc = resource->CastTo<AttachmentDesc>();
imageptr = &desc.image;
}
else if (resource->IsTexture()) {
TextureDesc& desc = resource->CastTo<TextureDesc>();
imageptr = &desc.image;
}
if (*imageptr) {
return;
}
if (ppImage) {
*imageptr = *ppImage;
}
}
}

View File

@ -4,11 +4,12 @@ namespace api {
void DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) void DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
{ {
AttachmentDesc surface{}; AttachmentDesc surface{};
surface.colorFormat = TinyImageFormat_B8G8R8_UNORM; surface.colorFormat = TinyImageFormat_B8G8R8A8_UNORM;
surface.sampleCount = SAMPLE_COUNT_1;
auto edge = graph.CreateTexture( auto edge = graph.CreateTexture(
[=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) { [=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) {
builder.Name("import") builder.Name("import")
.Import(graph.mSurface, surface, ResourceState::PRESENT); .Import(graph.mSurface.image, surface, ResourceState::PRESENT);
}); });
builder.Name("MiniPass") builder.Name("MiniPass")
.Write(edge); .Write(edge);

View File

@ -4,6 +4,17 @@ namespace meta {
concept is_enum_t = requires { std::is_enum_v<Enum>; }; concept is_enum_t = requires { std::is_enum_v<Enum>; };
} }
template<meta::is_enum_t Enum> template<meta::is_enum_t Enum>
inline constexpr Enum operator|=(Enum& lhs, Enum rhs) noexcept {
using underlying = std::underlying_type_t<Enum>;
lhs = Enum(underlying(lhs) | underlying(rhs));
return lhs;
}
template<meta::is_enum_t Enum>
inline constexpr Enum operator|(Enum lhs, Enum rhs) noexcept {
using underlying = std::underlying_type_t<Enum>;
return Enum(underlying(lhs) | underlying(rhs));
}
template<meta::is_enum_t Enum>
inline constexpr Enum operator&(Enum lhs, Enum rhs) noexcept { inline constexpr Enum operator&(Enum lhs, Enum rhs) noexcept {
using underlying = std::underlying_type_t<Enum>; using underlying = std::underlying_type_t<Enum>;
return Enum(underlying(lhs) & underlying(rhs)); return Enum(underlying(lhs) & underlying(rhs));

View File

@ -2,6 +2,7 @@
#include "type.h" #include "type.h"
#include "asset/res/guid.h" #include "asset/res/guid.h"
#include "render/renderapi.h" #include "render/renderapi.h"
#include "wrapper/commandbuffer.h"
#include "backend.h" #include "backend.h"
namespace vkn { namespace vkn {
class Backend; class Backend;
@ -14,9 +15,10 @@ namespace vkn {
using api::RenderPassNode; using api::RenderPassNode;
using api::ResourceBarrierDesc; using api::ResourceBarrierDesc;
struct VulkanContext : public api::RenderContext { struct VulkanContext : public api::RenderContext {
VkFence surfaceFence;;
VkSemaphore surfaceSemaphore; VkSemaphore surfaceSemaphore;
VkSemaphore presentSemaphore; VkSemaphore presentSemaphore;
VkCommandBuffer command; CommandBuffer command;
}; };
class VULKAN_API VulkanAPI : public api::RenderAPI { class VULKAN_API VulkanAPI : public api::RenderAPI {
private: private:

View File

@ -5,6 +5,7 @@ namespace vkn {
protected: protected:
VkCommandBuffer mPtr; VkCommandBuffer mPtr;
public: public:
CommandBuffer() : mPtr(nullptr) {};
CommandBuffer(VkCommandBuffer ptr) : mPtr(ptr) {}; CommandBuffer(VkCommandBuffer ptr) : mPtr(ptr) {};
VkCommandBuffer& Ptr() { VkCommandBuffer& Ptr() {
return mPtr; return mPtr;

View File

@ -69,11 +69,16 @@ namespace vkn {
} }
void VulkanAPI::BeginFrame() void VulkanAPI::BeginFrame()
{ {
window.Aquire(*(VulkanContext*)&context); VulkanContext& ctx = *(VulkanContext*)&context;
window.Aquire(ctx);
ctx.command.BeginRecord(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
} }
void VulkanAPI::EndFrame() void VulkanAPI::EndFrame()
{ {
window.Present(*(VulkanContext*)&context); VulkanContext& ctx = *(VulkanContext*)&context;
ctx.command.EndRecord();
ctx.command.Submit(Backend::RenderWorker->GetQueue().Ptr(), ctx.surfaceFence);
window.Present(ctx);
} }
void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) { void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) {
VulkanContext& ctx = *(VulkanContext*)&context; VulkanContext& ctx = *(VulkanContext*)&context;
@ -89,7 +94,10 @@ namespace vkn {
auto desc = GetVkTextureTransition(srcStageMask, dstStageMask, barrier); auto desc = GetVkTextureTransition(srcStageMask, dstStageMask, barrier);
imageBarriers.push_back(desc); imageBarriers.push_back(desc);
} }
vkCmdPipelineBarrier(ctx.command, srcStageMask, dstStageMask, 0, 0,NULL, 0, NULL, imageBarriers.size(), imageBarriers.data()); if (dstStageMask == 0) {
dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
}
vkCmdPipelineBarrier(ctx.command.Ptr(), srcStageMask, dstStageMask, 0, 0, NULL, 0, NULL, imageBarriers.size(), imageBarriers.data());
} }
void VulkanAPI::BeginRenderPass(RenderPassNode* node) void VulkanAPI::BeginRenderPass(RenderPassNode* node)
{ {
@ -99,6 +107,10 @@ namespace vkn {
if (it->IsAttachment()) { if (it->IsAttachment()) {
auto& desc = it->CastTo<api::AttachmentDesc>(); auto& desc = it->CastTo<api::AttachmentDesc>();
config.colorFormat[i] = (VkFormat)TinyImageFormat_ToVkFormat(desc.colorFormat); config.colorFormat[i] = (VkFormat)TinyImageFormat_ToVkFormat(desc.colorFormat);
config.samples = (VkSampleCountFlagBits)desc.sampleCount;
TargetBufferFlags flag = TargetBufferFlags(int(TargetBufferFlags::COLOR0) << i);
config.clear |= flag;
i++; i++;
} }
} }

View File

@ -123,6 +123,13 @@ namespace vkn {
} }
mSrcStage |= srcStage; mSrcStage |= srcStage;
mDstStage |= dstStage; mDstStage |= dstStage;
VkImageSubresourceRange subresources{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
};
return VkImageMemoryBarrier{ return VkImageMemoryBarrier{
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.srcAccessMask = srcAccessMask, .srcAccessMask = srcAccessMask,
@ -132,7 +139,7 @@ namespace vkn {
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = (VkImage)barrier.mTexture.image, .image = (VkImage)barrier.mTexture.image,
//.subresourceRange = transition.subresources, .subresourceRange = subresources
}; };
} }
} }

View File

@ -79,6 +79,7 @@ namespace vkn {
VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame]; VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame];
ctx.surface = mSurfaces[ctx.frame]; ctx.surface = mSurfaces[ctx.frame];
ctx.command = mCommands[ctx.frame]; ctx.command = mCommands[ctx.frame];
ctx.surfaceFence = surfaceFence;
ctx.surfaceSemaphore = surfaceSemaphore; ctx.surfaceSemaphore = surfaceSemaphore;
ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames]; ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames];
if (vkWaitForFences(mDevice.Ptr(), 1, &surfaceFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS) if (vkWaitForFences(mDevice.Ptr(), 1, &surfaceFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS)

View File

@ -24,6 +24,7 @@ namespace vkn {
void DeviceCreator::AddWindowExtension() void DeviceCreator::AddWindowExtension()
{ {
AddExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME); AddExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
//AddExtension(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME);
#ifdef Z_RENDER_DEBUG #ifdef Z_RENDER_DEBUG
AddLayer("VK_LAYER_KHRONOS_validation"); AddLayer("VK_LAYER_KHRONOS_validation");
AddLayer("VK_LAYER_RENDERDOC_Capture"); AddLayer("VK_LAYER_RENDERDOC_Capture");

View File

@ -5,6 +5,14 @@
#include "render/pass/demo_pass.h" #include "render/pass/demo_pass.h"
#include <iostream> #include <iostream>
using namespace api; using namespace api;
FrameGraphNodePtr FrameGraph::AddRenderPass(const RenderPassSetupFunction& setup, const RenderPassNodeExecuteFn& executor)
{
FrameGraphNodePtr node_ptr{ mGraph.addNode(), executor };
RenderPassBuilder builder{ this, node_ptr };
setup(*this, builder);
mNodes.push_back(node_ptr);
return node_ptr;
}
RenderAPI* API; RenderAPI* API;
void ZWorldModule::OnLoad(int argc, char** argv) void ZWorldModule::OnLoad(int argc, char** argv)
{ {