update
This commit is contained in:
parent
3ab7bb46f6
commit
d814786d26
@ -10,6 +10,7 @@ namespace api {
|
||||
}
|
||||
void RenderAPI::Render()
|
||||
{
|
||||
graph.mSurface = context.surface;
|
||||
for (auto view : context.views) {
|
||||
RenderView(view);
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "math/vector2.h"
|
||||
#include "render_enum.h"
|
||||
namespace api {
|
||||
/*
|
||||
class Texture;
|
||||
struct Attachment
|
||||
{
|
||||
@ -43,5 +44,5 @@ namespace api {
|
||||
static AttachmentDesc Make() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
};*/
|
||||
}
|
||||
@ -1,9 +1,13 @@
|
||||
#pragma once
|
||||
#include "asset/asset.h"
|
||||
#include "render/type.h"
|
||||
namespace api {
|
||||
class Texture : public Resource<Texture>
|
||||
{
|
||||
public:
|
||||
void* mPtr;
|
||||
TextureDesc mDesc;
|
||||
void* mPtr;
|
||||
public:
|
||||
Texture(TextureDesc& desc);
|
||||
};
|
||||
}
|
||||
@ -8,8 +8,8 @@ namespace api {
|
||||
class TextureBuilder;
|
||||
class RenderPassBuilder;
|
||||
public:
|
||||
RscHandle<Texture> mSurface;
|
||||
table<Name, RscHandle<Texture>> mResourceTable;
|
||||
TextureDesc mSurface;
|
||||
table<Name, TextureDesc> mResourceTable;
|
||||
lemon::ListGraph mGraph;
|
||||
pmr::vector<FrameGraphNodePtr> mNodes{FramePool()};
|
||||
public:
|
||||
@ -23,7 +23,7 @@ namespace api {
|
||||
void Compile();
|
||||
void Execute(FRenderView& view);
|
||||
void Clear();
|
||||
RscHandle<Texture> Resource(Name name) {
|
||||
TextureDesc Resource(Name name) {
|
||||
auto it = mResourceTable.find(name);
|
||||
if (it == mResourceTable.end()) {
|
||||
return {};
|
||||
@ -36,6 +36,6 @@ namespace api {
|
||||
void ExecuteComputePass(RenderPassNode* node, FRenderView& view);
|
||||
void ExecuteCopyPass(RenderPassNode* node, FRenderView& view);
|
||||
|
||||
void ExecuteResourceBarriers(RenderPassNode* node, RenderPassEdgeIterFn fn);
|
||||
void ExecuteResourceBarriers(RenderPassNode* node);
|
||||
};
|
||||
}
|
||||
@ -10,9 +10,9 @@ namespace api {
|
||||
: graph(*graph) , node(node) {};
|
||||
FrameGraph::RenderPassBuilder& Name(pmr::Name name);
|
||||
FrameGraph::RenderPassBuilder& Pass(RenderPass* pass);
|
||||
FrameGraph::RenderPassBuilder& Read(TextureDesc desc);
|
||||
FrameGraph::RenderPassBuilder& Write(TextureDesc desc);
|
||||
FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc);
|
||||
FrameGraph::RenderPassBuilder& Read(TextureDesc desc, ResourceState state);
|
||||
FrameGraph::RenderPassBuilder& Write(BufferDesc desc, ResourceState state);
|
||||
FrameGraph::RenderPassBuilder& Attach(AttachmentDesc desc, ResourceState state);
|
||||
FrameGraph::RenderPassBuilder& Read(const FrameGraphEdgePtr& edge);
|
||||
};
|
||||
struct FrameGraph::TextureBuilder {
|
||||
|
||||
@ -7,7 +7,8 @@ namespace api {
|
||||
};
|
||||
struct RenderContext {
|
||||
pmr::vector<FRenderView> views;
|
||||
uint32_t frame{ 0 };
|
||||
uint32_t presentFrame{ 0 };
|
||||
TextureDesc surface;
|
||||
uint32_t frame{ 0 };
|
||||
uint32_t presentFrame{ 0 };
|
||||
};
|
||||
}
|
||||
@ -13,12 +13,15 @@ namespace api {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
using ImagePtr = void*;
|
||||
struct TextureDesc {
|
||||
ImagePtr image;
|
||||
static TextureDesc Make() {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
struct AttachmentDesc {
|
||||
ImagePtr image;
|
||||
TinyImageFormat colorFormat;
|
||||
static AttachmentDesc Make() {
|
||||
return {};
|
||||
@ -69,7 +72,7 @@ namespace api {
|
||||
};
|
||||
struct TextureBarrier
|
||||
{
|
||||
//Texture* pTexture;
|
||||
TextureDesc mTexture;
|
||||
ResourceState mSrcState;
|
||||
ResourceState mDstState;
|
||||
uint8_t mBeginOnly : 1;
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
#include "render/asset/texture.h"
|
||||
namespace api {
|
||||
Texture::Texture(TextureDesc& desc)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -27,7 +27,7 @@ namespace api {
|
||||
}
|
||||
return !degree;
|
||||
});
|
||||
mNodes.erase(end, mNodes.end());
|
||||
//mNodes.erase(end, mNodes.end());
|
||||
}
|
||||
void FrameGraph::Execute(FRenderView& view)
|
||||
{
|
||||
@ -55,6 +55,7 @@ namespace api {
|
||||
}
|
||||
void FrameGraph::ExecuteRenderPass(RenderPassNode* node, FRenderView& view)
|
||||
{
|
||||
ExecuteResourceBarriers(node);
|
||||
RenderAPI::Ptr()->BeginRenderPass(node);
|
||||
RenderPassContext context{};
|
||||
std::get<RenderPassExecuteFunction>(node->executor)(*this, context);
|
||||
@ -75,7 +76,7 @@ namespace api {
|
||||
CopyPassContext context{};
|
||||
std::get<CopyPassExecuteFunction>(node->executor)(*this, context);
|
||||
}
|
||||
void FrameGraph::ExecuteResourceBarriers(RenderPassNode* node, RenderPassEdgeIterFn fn)
|
||||
void FrameGraph::ExecuteResourceBarriers(RenderPassNode* node)
|
||||
{
|
||||
pmr::vector<BufferBarrier> bufferBarrier{FramePool()};
|
||||
pmr::vector<TextureBarrier> textureBarrier{ FramePool() };
|
||||
@ -104,7 +105,7 @@ namespace api {
|
||||
desc.pBufferBarriers = bufferBarrier.data();
|
||||
desc.textureBarriersCount = textureBarrier.size();
|
||||
desc.pTextureBarriers = textureBarrier.data();
|
||||
|
||||
RenderAPI::Ptr()->ExecuteResourceBarriers(desc);
|
||||
}
|
||||
void RenderPassNode::ForeachEdge(RenderPassEdgeIterFn fn) {
|
||||
for (auto& edge : inEdges) {
|
||||
|
||||
@ -11,10 +11,10 @@ namespace api {
|
||||
node->pass = pass;
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(TextureDesc desc)
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Read(TextureDesc desc, ResourceState state)
|
||||
{
|
||||
FrameGraphEdgePtr edge{};
|
||||
edge.targetState = state;
|
||||
resource = edge.Make();
|
||||
resource->source = node;
|
||||
resource->resource = desc;
|
||||
@ -22,9 +22,10 @@ namespace api {
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Write(TextureDesc desc)
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Write(BufferDesc desc, ResourceState state)
|
||||
{
|
||||
FrameGraphEdgePtr edge{};
|
||||
edge.targetState = state;
|
||||
resource = edge.Make();
|
||||
resource->source = node;
|
||||
resource->resource = desc;
|
||||
@ -32,11 +33,14 @@ namespace api {
|
||||
return *this;
|
||||
}
|
||||
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Attach(AttachmentDesc desc)
|
||||
FrameGraph::RenderPassBuilder& FrameGraph::RenderPassBuilder::Attach(AttachmentDesc desc, ResourceState state)
|
||||
{
|
||||
if (resource) {
|
||||
resource->resource = desc;
|
||||
}
|
||||
FrameGraphEdgePtr edge{};
|
||||
edge.targetState = state;
|
||||
resource = edge.Make();
|
||||
resource->source = node;
|
||||
resource->resource = desc;
|
||||
node->outEdges.push_back(edge);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@ -3,26 +3,11 @@
|
||||
namespace api {
|
||||
void DemoPass::Setup(FrameGraph& graph, FrameGraph::RenderPassBuilder& builder)
|
||||
{
|
||||
auto edge = graph.CreateTexture(
|
||||
[=](FrameGraph& graph, FrameGraph::TextureBuilder& builder) {
|
||||
builder.Name("import")
|
||||
.Import(graph.Resource("demo_input"));
|
||||
});
|
||||
builder.Name("DemoPass")
|
||||
.Read(TextureDesc::Make())
|
||||
.Read(edge)
|
||||
.Write(TextureDesc::Make())
|
||||
.Attach(AttachmentDesc::Make());
|
||||
auto parent_node = builder.node;
|
||||
graph.AddRenderPass(
|
||||
[=](FrameGraph& graph, FrameGraph::RenderPassBuilder& builder) {
|
||||
builder.Name("DemoPassSub")
|
||||
.Read(edge)
|
||||
.Read(parent_node->GetOutput(0));
|
||||
},
|
||||
[](FrameGraph& graph, RenderPassContext& context) {
|
||||
|
||||
});
|
||||
AttachmentDesc surface{};
|
||||
surface.image = graph.mSurface.image;
|
||||
surface.colorFormat = TinyImageFormat_B8G8R8_UNORM;
|
||||
builder.Name("MiniPass")
|
||||
.Attach(surface, ResourceState::PRESENT);
|
||||
}
|
||||
void DemoPass::Execute(FrameGraph&, RenderPassContext&)
|
||||
{
|
||||
|
||||
@ -27,5 +27,8 @@ namespace vkn {
|
||||
Queue& GetQueue() {
|
||||
return mQueue;
|
||||
}
|
||||
VkCommandBuffer AllocateBuffer(VkCommandBufferLevel level) {
|
||||
return mCommandPool.AllocateBuffer(level);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -16,6 +16,7 @@ namespace vkn {
|
||||
struct VulkanContext : public api::RenderContext {
|
||||
VkSemaphore surfaceSemaphore;
|
||||
VkSemaphore presentSemaphore;
|
||||
VkCommandBuffer command;
|
||||
};
|
||||
class VULKAN_API VulkanAPI : public api::RenderAPI {
|
||||
private:
|
||||
|
||||
@ -1,4 +1,15 @@
|
||||
#include "type.h"
|
||||
namespace vkn {
|
||||
|
||||
using api::ResourceState;
|
||||
using api::TextureBarrier;
|
||||
struct VkTextureTransitionDesc {
|
||||
VkAccessFlags srcAccessMask;
|
||||
VkAccessFlags dstAccessMask;
|
||||
VkPipelineStageFlags srcStage;
|
||||
VkPipelineStageFlags dstStage;
|
||||
VkImageLayout mSrcState;
|
||||
VkImageLayout mDstState;
|
||||
};
|
||||
VkImageLayout GetVkLayout(ResourceState layout);
|
||||
VkImageMemoryBarrier GetVkTextureTransition(VkPipelineStageFlags& mSrcStage, VkPipelineStageFlags mDstStage, const TextureBarrier& barrier);
|
||||
}
|
||||
@ -5,6 +5,7 @@
|
||||
namespace vkn {
|
||||
class Device;
|
||||
struct VulkanContext;
|
||||
using api::TextureDesc;
|
||||
struct VULKAN_API VulkanWindowArgs {
|
||||
uint32_t frames;
|
||||
uint32_t width;
|
||||
@ -22,7 +23,8 @@ namespace vkn {
|
||||
Device& mDevice;
|
||||
VkSwapchainKHR mPtr;
|
||||
int mFrames;
|
||||
//pmr::vector<Image*> mSurfaces{GlobalPool()};
|
||||
pmr::vector<TextureDesc> mSurfaces{GlobalPool()};
|
||||
pmr::vector<VkCommandBuffer> mCommands{ GlobalPool() };
|
||||
pmr::vector<VkFence> mFences{ GlobalPool() };
|
||||
pmr::vector<VkSemaphore> mSemaphores{ GlobalPool() };
|
||||
public:
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/vulkan_window.h"
|
||||
#include "vkn/vulkan_api_help.h"
|
||||
#include "vkn/wrapper/buffer.h"
|
||||
#include "vkn/wrapper/device.h"
|
||||
#include "vkn/thread/buffer_worker.h"
|
||||
@ -7,6 +8,7 @@
|
||||
#include "render/asset/mesh.h"
|
||||
#include "meta/enum.h"
|
||||
#include "tinyimageformat/tinyimageformat_apis.h"
|
||||
|
||||
namespace vkn {
|
||||
inline bool operator==(const RenderPassKey& k1, const RenderPassKey& k2) {
|
||||
if (k1.initialColorLayoutMask != k2.initialColorLayoutMask) return false;
|
||||
@ -74,16 +76,20 @@ namespace vkn {
|
||||
window.Present(*(VulkanContext*)&context);
|
||||
}
|
||||
void VulkanAPI::ExecuteResourceBarriers(const ResourceBarrierDesc& desc) {
|
||||
VkCommandBuffer cmd;
|
||||
VulkanContext& ctx = *(VulkanContext*)&context;
|
||||
pmr::vector<VkBufferMemoryBarrier> bufferBarriers{ FramePool() };
|
||||
bufferBarriers.reserve(desc.bufferBarriersCount);
|
||||
pmr::vector<VkImageMemoryBarrier> imageBarriers{ FramePool() };
|
||||
imageBarriers.reserve(desc.textureBarriersCount);
|
||||
using api::ResourceState;
|
||||
VkPipelineStageFlags srcStageMask, dstStageMask;
|
||||
for (uint32_t i = 0; i < desc.textureBarriersCount; i++)
|
||||
{
|
||||
auto& barrier = desc.pTextureBarriers[i];
|
||||
auto desc = GetVkTextureTransition(srcStageMask, dstStageMask, barrier);
|
||||
imageBarriers.push_back(desc);
|
||||
}
|
||||
vkCmdPipelineBarrier(ctx.command, srcStageMask, dstStageMask, 0, 0,NULL, 0, NULL, imageBarriers.size(), imageBarriers.data());
|
||||
}
|
||||
void VulkanAPI::BeginRenderPass(RenderPassNode* node)
|
||||
{
|
||||
|
||||
@ -1,10 +1,35 @@
|
||||
#include <tuple>
|
||||
#include "vkn/vulkan_api_help.h"
|
||||
namespace vkn {
|
||||
using api::ResourceState;
|
||||
inline std::tuple<VkAccessFlags, VkAccessFlags, VkPipelineStageFlags, VkPipelineStageFlags,
|
||||
VkImageLayout, VkImageLayout>
|
||||
getVkTransition(const api::TextureBarrier& barrier) {
|
||||
VkImageLayout GetVkLayout(ResourceState layout) {
|
||||
switch (layout) {
|
||||
case ResourceState::UNDEFINED:
|
||||
return VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
case ResourceState::READ_WRITE:
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case ResourceState::READ_ONLY:
|
||||
return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
case ResourceState::TRANSFER_SRC:
|
||||
return VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
|
||||
case ResourceState::TRANSFER_DST:
|
||||
return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
case ResourceState::DEPTH_ATTACHMENT:
|
||||
return VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||
case ResourceState::DEPTH_SAMPLER:
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case ResourceState::PRESENT:
|
||||
return VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||
// Filament sometimes samples from one miplevel while writing to another level in the
|
||||
// same texture (e.g. bloom does this). Moreover we'd like to avoid lots of expensive
|
||||
// layout transitions. So, keep it simple and use GENERAL for all color-attachable
|
||||
// textures.
|
||||
case ResourceState::COLOR_ATTACHMENT:
|
||||
return VK_IMAGE_LAYOUT_GENERAL;
|
||||
case ResourceState::COLOR_ATTACHMENT_RESOLVE:
|
||||
return VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
}
|
||||
}
|
||||
VkImageMemoryBarrier GetVkTextureTransition(VkPipelineStageFlags& mSrcStage, VkPipelineStageFlags mDstStage, const TextureBarrier& barrier) {
|
||||
VkAccessFlags srcAccessMask, dstAccessMask;
|
||||
VkPipelineStageFlags srcStage, dstStage;
|
||||
|
||||
@ -96,8 +121,18 @@ namespace vkn {
|
||||
dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
return std::make_tuple(srcAccessMask, dstAccessMask, srcStage, dstStage,
|
||||
getVkLayout(transition.oldLayout), getVkLayout(transition.newLayout));
|
||||
mSrcStage |= srcStage;
|
||||
mDstStage |= dstStage;
|
||||
return VkImageMemoryBarrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
|
||||
.srcAccessMask = srcAccessMask,
|
||||
.dstAccessMask = dstAccessMask,
|
||||
.oldLayout = GetVkLayout(barrier.mSrcState),
|
||||
.newLayout = GetVkLayout(barrier.mDstState),
|
||||
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
|
||||
.image = (VkImage)barrier.mTexture.image,
|
||||
//.subresourceRange = transition.subresources,
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@
|
||||
#include "vkn/vulkan_api.h"
|
||||
#include "vkn/backend.h"
|
||||
#include "vkn/thread/command_worker.h"
|
||||
#include "render/asset/texture.h"
|
||||
#include "asset/resource_system.h"
|
||||
#include "zlog.h"
|
||||
#include <algorithm>
|
||||
namespace vkn {
|
||||
@ -58,11 +60,16 @@ namespace vkn {
|
||||
swapchain_images.resize(imageCount);
|
||||
vkGetSwapchainImagesKHR(device.Ptr(), mPtr, &imageCount, swapchain_images.data());
|
||||
mFences.reserve(mFrames);
|
||||
mSurfaces.reserve(mFrames);
|
||||
mCommands.reserve(mFrames);
|
||||
mSemaphores.reserve(mFrames + mFrames);
|
||||
for (int i = 0; i < mFrames; i++) {
|
||||
//mSurfaces.push_back(new Image(Creator.device, "swapchain" + to_string(i), swapchain_images[i], args));
|
||||
api::TextureDesc desc;
|
||||
desc.image = swapchain_images[i];
|
||||
mSurfaces.push_back(desc);
|
||||
mSemaphores.push_back(mDevice.CreateSemaphore());
|
||||
mSemaphores.push_back(mDevice.CreateSemaphore());
|
||||
mCommands.push_back(Backend::RenderWorker->AllocateBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY));
|
||||
mFences.push_back(mDevice.CreateFence(VK_FENCE_CREATE_SIGNALED_BIT));
|
||||
}
|
||||
}
|
||||
@ -70,6 +77,8 @@ namespace vkn {
|
||||
{
|
||||
VkFence surfaceFence = mFences[ctx.frame];
|
||||
VkSemaphore surfaceSemaphore = mSemaphores[ctx.frame];
|
||||
ctx.surface = mSurfaces[ctx.frame];
|
||||
ctx.command = mCommands[ctx.frame];
|
||||
ctx.surfaceSemaphore = surfaceSemaphore;
|
||||
ctx.presentSemaphore = mSemaphores[ctx.frame + mFrames];
|
||||
if (vkWaitForFences(mDevice.Ptr(), 1, &surfaceFence, VK_TRUE, UINT64_MAX) != VK_SUCCESS)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user