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:
TextureDesc mSurface;
table<Name, TextureDesc> mResourceTable;
table<Name, TextureDesc> mResourceTable;
table<TextureDesc::Key, TextureDesc> mResourcePool;
table<TextureDesc::Key, TextureDesc> mResourceViewPool;
lemon::ListGraph mGraph;
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
public:

View File

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

View File

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

View File

@ -8,6 +8,15 @@ namespace api {
Vulkan,
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 {
static BufferDesc Make() {
return {};
@ -15,6 +24,7 @@ namespace api {
};
using ImagePtr = void*;
struct TextureDesc {
using Key = uint32_t;
ImagePtr image;
static TextureDesc Make() {
return {};
@ -23,6 +33,7 @@ namespace api {
struct AttachmentDesc {
ImagePtr image;
TinyImageFormat colorFormat;
SampleCount sampleCount;
static AttachmentDesc Make() {
return {};
}

View File

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

View File

@ -18,7 +18,6 @@ namespace api {
resource = edge.Make();
resource->source = node;
resource->resource = desc;
edge->image = desc.image;
node->inEdges.push_back(edge);
return *this;
}
@ -41,7 +40,6 @@ namespace api {
resource = edge.Make();
resource->source = node;
resource->resource = desc;
edge->image = desc.image;
node->outEdges.push_back(edge);
return *this;
}
@ -74,7 +72,6 @@ namespace api {
edge.ppImage = &ptr;
edge.targetState = state;
edge->resource = desc;
edge->image = desc.image;
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)
{
AttachmentDesc surface{};
surface.colorFormat = TinyImageFormat_B8G8R8_UNORM;
surface.colorFormat = TinyImageFormat_B8G8R8A8_UNORM;
surface.sampleCount = SAMPLE_COUNT_1;
auto edge = graph.CreateTexture(
[=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) {
builder.Name("import")
.Import(graph.mSurface, surface, ResourceState::PRESENT);
.Import(graph.mSurface.image, surface, ResourceState::PRESENT);
});
builder.Name("MiniPass")
.Write(edge);

View File

@ -4,6 +4,17 @@ namespace meta {
concept is_enum_t = requires { std::is_enum_v<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 {
using underlying = std::underlying_type_t<Enum>;
return Enum(underlying(lhs) & underlying(rhs));

View File

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

View File

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

View File

@ -69,11 +69,16 @@ namespace vkn {
}
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()
{
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) {
VulkanContext& ctx = *(VulkanContext*)&context;
@ -89,7 +94,10 @@ namespace vkn {
auto desc = GetVkTextureTransition(srcStageMask, dstStageMask, barrier);
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)
{
@ -99,6 +107,10 @@ namespace vkn {
if (it->IsAttachment()) {
auto& desc = it->CastTo<api::AttachmentDesc>();
config.colorFormat[i] = (VkFormat)TinyImageFormat_ToVkFormat(desc.colorFormat);
config.samples = (VkSampleCountFlagBits)desc.sampleCount;
TargetBufferFlags flag = TargetBufferFlags(int(TargetBufferFlags::COLOR0) << i);
config.clear |= flag;
i++;
}
}

View File

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

View File

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

View File

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

View File

@ -5,6 +5,14 @@
#include "render/pass/demo_pass.h"
#include <iostream>
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;
void ZWorldModule::OnLoad(int argc, char** argv)
{