mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 17:01:49 +01:00
Track VkRenderPass
and Subpass Index for Subpass Function Nodes
We require a handle to the current renderpass and the index of the subpass in certain cases, this is now tracked by the `CommandExecutor` and passed in as a parameter to `NextSubpassFunctionNode` and the newly-introduced `SubpassFunctionNode`.
This commit is contained in:
parent
cb7f68b98d
commit
56b3a01a59
@ -43,7 +43,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandExecutor::AddSubpass(const std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &)> &function, vk::Rect2D renderArea, span<TextureView *> inputAttachments, span<TextureView *> colorAttachments, TextureView *depthStencilAttachment) {
|
void CommandExecutor::AddSubpass(std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)> &&function, vk::Rect2D renderArea, span<TextureView *> inputAttachments, span<TextureView *> colorAttachments, TextureView *depthStencilAttachment) {
|
||||||
for (const auto &attachments : {inputAttachments, colorAttachments})
|
for (const auto &attachments : {inputAttachments, colorAttachments})
|
||||||
for (const auto &attachment : attachments)
|
for (const auto &attachment : attachments)
|
||||||
AttachTexture(attachment->texture);
|
AttachTexture(attachment->texture);
|
||||||
@ -53,9 +53,9 @@ namespace skyline::gpu::interconnect {
|
|||||||
bool newRenderPass{CreateRenderPass(renderArea)};
|
bool newRenderPass{CreateRenderPass(renderArea)};
|
||||||
renderPass->AddSubpass(inputAttachments, colorAttachments, depthStencilAttachment ? &*depthStencilAttachment : nullptr);
|
renderPass->AddSubpass(inputAttachments, colorAttachments, depthStencilAttachment ? &*depthStencilAttachment : nullptr);
|
||||||
if (newRenderPass)
|
if (newRenderPass)
|
||||||
nodes.emplace_back(std::in_place_type_t<node::FunctionNode>(), function);
|
nodes.emplace_back(std::in_place_type_t<node::SubpassFunctionNode>(), std::forward<std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)>>(function));
|
||||||
else
|
else
|
||||||
nodes.emplace_back(std::in_place_type_t<node::NextSubpassFunctionNode>(), function);
|
nodes.emplace_back(std::in_place_type_t<node::NextSubpassFunctionNode>(), std::forward<std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)>>(function));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandExecutor::AddClearColorSubpass(TextureView *attachment, const vk::ClearColorValue &value) {
|
void CommandExecutor::AddClearColorSubpass(TextureView *attachment, const vk::ClearColorValue &value) {
|
||||||
@ -83,7 +83,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
if (newRenderPass)
|
if (newRenderPass)
|
||||||
nodes.emplace_back(std::in_place_type_t<node::FunctionNode>(), function);
|
nodes.emplace_back(std::in_place_type_t<node::SubpassFunctionNode>(), function);
|
||||||
else
|
else
|
||||||
nodes.emplace_back(std::in_place_type_t<node::NextSubpassFunctionNode>(), function);
|
nodes.emplace_back(std::in_place_type_t<node::NextSubpassFunctionNode>(), function);
|
||||||
}
|
}
|
||||||
@ -110,14 +110,24 @@ namespace skyline::gpu::interconnect {
|
|||||||
for (auto buffer : syncBuffers)
|
for (auto buffer : syncBuffers)
|
||||||
buffer->SynchronizeHostWithCycle(cycle);
|
buffer->SynchronizeHostWithCycle(cycle);
|
||||||
|
|
||||||
|
vk::RenderPass lRenderPass;
|
||||||
|
u32 subpassIndex;
|
||||||
|
|
||||||
using namespace node;
|
using namespace node;
|
||||||
for (NodeVariant &node : nodes) {
|
for (NodeVariant &node : nodes) {
|
||||||
#define NODE(name) [&](name& node) { node(commandBuffer, cycle, gpu); }
|
#define NODE(name) [&](name& node) { node(commandBuffer, cycle, gpu); }
|
||||||
std::visit(VariantVisitor{
|
std::visit(VariantVisitor{
|
||||||
NODE(FunctionNode),
|
NODE(FunctionNode),
|
||||||
NODE(RenderPassNode),
|
|
||||||
|
[&](RenderPassNode &node) {
|
||||||
|
lRenderPass = node(commandBuffer, cycle, gpu);
|
||||||
|
subpassIndex = 0;
|
||||||
|
},
|
||||||
|
|
||||||
NODE(NextSubpassNode),
|
NODE(NextSubpassNode),
|
||||||
NODE(NextSubpassFunctionNode),
|
[&](SubpassFunctionNode &node) { node(commandBuffer, cycle, gpu, lRenderPass, subpassIndex); },
|
||||||
|
[&](NextSubpassFunctionNode &node) { node(commandBuffer, cycle, gpu, lRenderPass, ++subpassIndex); },
|
||||||
|
|
||||||
NODE(RenderPassEndNode),
|
NODE(RenderPassEndNode),
|
||||||
}, node);
|
}, node);
|
||||||
#undef NODE
|
#undef NODE
|
||||||
|
@ -49,7 +49,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
* @note Any texture supplied to this **must** be locked by the calling thread, it should also undergo no persistent layout transitions till execution
|
* @note Any texture supplied to this **must** be locked by the calling thread, it should also undergo no persistent layout transitions till execution
|
||||||
* @note All attachments will automatically be attached and aren't required to be attached prior
|
* @note All attachments will automatically be attached and aren't required to be attached prior
|
||||||
*/
|
*/
|
||||||
void AddSubpass(const std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &)> &&function, vk::Rect2D renderArea, span<TextureView *> inputAttachments = {}, span<TextureView *> colorAttachments = {}, TextureView *depthStencilAttachment = {});
|
void AddSubpass(std::function<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)> &&function, vk::Rect2D renderArea, span<TextureView *> inputAttachments = {}, span<TextureView *> colorAttachments = {}, TextureView *depthStencilAttachment = {});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a subpass that clears the entirety of the specified attachment with a value, it may utilize VK_ATTACHMENT_LOAD_OP_CLEAR for a more efficient clear when possible
|
* @brief Adds a subpass that clears the entirety of the specified attachment with a value, it may utilize VK_ATTACHMENT_LOAD_OP_CLEAR for a more efficient clear when possible
|
||||||
|
@ -160,7 +160,7 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPassNode::operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu) {
|
vk::RenderPass RenderPassNode::operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu) {
|
||||||
storage->device = &gpu.vkDevice;
|
storage->device = &gpu.vkDevice;
|
||||||
|
|
||||||
auto preserveAttachmentIt{preserveAttachmentReferences.begin()};
|
auto preserveAttachmentIt{preserveAttachmentReferences.begin()};
|
||||||
@ -220,5 +220,7 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
texture->unlock();
|
texture->unlock();
|
||||||
texture->cycle = cycle;
|
texture->cycle = cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return renderPass;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
struct FunctionNodeBase {
|
struct FunctionNodeBase {
|
||||||
std::function<FunctionSignature> function;
|
std::function<FunctionSignature> function;
|
||||||
|
|
||||||
FunctionNodeBase(std::function<FunctionSignature> function) : function(function) {}
|
FunctionNodeBase(std::function<FunctionSignature> &&function) : function(function) {}
|
||||||
|
|
||||||
template<class... Args>
|
template<class... Args>
|
||||||
void operator()(Args &&... args) {
|
void operator()(Args &&... args) {
|
||||||
@ -86,7 +86,7 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
*/
|
*/
|
||||||
bool ClearColorAttachment(u32 colorAttachment, const vk::ClearColorValue &value);
|
bool ClearColorAttachment(u32 colorAttachment, const vk::ClearColorValue &value);
|
||||||
|
|
||||||
void operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu);
|
vk::RenderPass operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,15 +98,17 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using SubpassFunctionNode = FunctionNodeBase<void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32)>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief A FunctionNode which progresses to the next subpass prior to calling the function
|
* @brief A FunctionNode which progresses to the next subpass prior to calling the function
|
||||||
*/
|
*/
|
||||||
struct NextSubpassFunctionNode : private FunctionNode {
|
struct NextSubpassFunctionNode : private SubpassFunctionNode {
|
||||||
using FunctionNode::FunctionNode;
|
using SubpassFunctionNode::SubpassFunctionNode;
|
||||||
|
|
||||||
void operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu) {
|
void operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu, vk::RenderPass renderPass, u32 subpassIndex) {
|
||||||
commandBuffer.nextSubpass(vk::SubpassContents::eInline);
|
commandBuffer.nextSubpass(vk::SubpassContents::eInline);
|
||||||
FunctionNode::operator()(commandBuffer, cycle, gpu);
|
SubpassFunctionNode::operator()(commandBuffer, cycle, gpu, renderPass, subpassIndex);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,5 +121,5 @@ namespace skyline::gpu::interconnect::node {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using NodeVariant = std::variant<FunctionNode, RenderPassNode, NextSubpassNode, NextSubpassFunctionNode, RenderPassEndNode>; //!< A variant encompassing all command nodes types
|
using NodeVariant = std::variant<FunctionNode, RenderPassNode, NextSubpassNode, SubpassFunctionNode, NextSubpassFunctionNode, RenderPassEndNode>; //!< A variant encompassing all command nodes types
|
||||||
}
|
}
|
||||||
|
@ -361,7 +361,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
if (scissor.extent.width == renderTarget->texture->dimensions.width && scissor.extent.height == renderTarget->texture->dimensions.height && renderTarget->range.baseArrayLayer == 0 && renderTarget->range.layerCount == 1 && clear.layerId == 0) {
|
if (scissor.extent.width == renderTarget->texture->dimensions.width && scissor.extent.height == renderTarget->texture->dimensions.height && renderTarget->range.baseArrayLayer == 0 && renderTarget->range.layerCount == 1 && clear.layerId == 0) {
|
||||||
executor.AddClearColorSubpass(renderTarget, clearColorValue);
|
executor.AddClearColorSubpass(renderTarget, clearColorValue);
|
||||||
} else {
|
} else {
|
||||||
executor.AddSubpass([aspect, clearColorValue = clearColorValue, layerId = clear.layerId, scissor](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &) {
|
executor.AddSubpass([aspect, clearColorValue = clearColorValue, layerId = clear.layerId, scissor](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &, vk::RenderPass, u32) {
|
||||||
commandBuffer.clearAttachments(vk::ClearAttachment{
|
commandBuffer.clearAttachments(vk::ClearAttachment{
|
||||||
.aspectMask = aspect,
|
.aspectMask = aspect,
|
||||||
.colorAttachment = 0,
|
.colorAttachment = 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user