mirror of
https://github.com/Takiiiiiiii/strato.git
synced 2025-07-17 08:46:39 +00:00
We want `TextureView`(s) to be disconnected from the backing on the host and instead represent a specific texture on the guest with a backing that can change depending on mapping of new textures which'd invalidate the backing but should now be automatically repointed to an appropriate new backing. This approach also requires locking of the backing to function as it is mutable till it has been locked or the backing has an attached `FenceCycle` that hasn't been signaled which will be added for `CommandExecutor` in a subsequent commit.
124 lines
5.1 KiB
C++
124 lines
5.1 KiB
C++
// SPDX-License-Identifier: MPL-2.0
|
|
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
|
|
|
#pragma once
|
|
|
|
#include <gpu.h>
|
|
|
|
namespace skyline::gpu::interconnect::node {
|
|
/**
|
|
* @brief A generic node for simply executing a function
|
|
*/
|
|
template<typename FunctionSignature = void(vk::raii::CommandBuffer &, const std::shared_ptr<FenceCycle> &, GPU &)>
|
|
struct FunctionNodeBase {
|
|
std::function<FunctionSignature> function;
|
|
|
|
FunctionNodeBase(std::function<FunctionSignature> function) : function(function) {}
|
|
|
|
template<class... Args>
|
|
void operator()(Args &&... args) {
|
|
function(std::forward<Args>(args)...);
|
|
}
|
|
};
|
|
|
|
using FunctionNode = FunctionNodeBase<>;
|
|
|
|
/**
|
|
* @brief Creates and begins a VkRenderPass alongside managing all resources bound to it and to the subpasses inside it
|
|
*/
|
|
struct RenderPassNode {
|
|
private:
|
|
/**
|
|
* @brief Storage for all resources in the VkRenderPass that have their lifetimes bond to the completion fence
|
|
*/
|
|
struct Storage : public FenceCycleDependency {
|
|
vk::raii::Device *device{};
|
|
vk::Framebuffer framebuffer{};
|
|
vk::RenderPass renderPass{};
|
|
std::vector<std::shared_ptr<Texture>> textures;
|
|
|
|
~Storage();
|
|
};
|
|
|
|
std::shared_ptr<Storage> storage;
|
|
|
|
std::vector<vk::ImageView> attachments;
|
|
std::vector<vk::AttachmentDescription> attachmentDescriptions;
|
|
|
|
std::vector<vk::AttachmentReference> attachmentReferences;
|
|
std::vector<std::vector<u32>> preserveAttachmentReferences; //!< Any attachment that must be preserved to be utilized by a future subpass, these are stored per-subpass to ensure contiguity
|
|
|
|
constexpr static uintptr_t NoDepthStencil{std::numeric_limits<uintptr_t>::max()}; //!< A sentinel value to denote the lack of a depth stencil attachment in a VkSubpassDescription
|
|
|
|
/**
|
|
* @brief Rebases a pointer containing an offset relative to the beginning of a container
|
|
*/
|
|
template<typename Container, typename T>
|
|
constexpr T *RebasePointer(const Container &container, const T *offset) {
|
|
return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(container.data()) + reinterpret_cast<uintptr_t>(offset));
|
|
}
|
|
|
|
public:
|
|
std::vector<vk::SubpassDescription> subpassDescriptions;
|
|
std::vector<vk::SubpassDependency> subpassDependencies;
|
|
|
|
vk::Rect2D renderArea;
|
|
std::vector<vk::ClearValue> clearValues;
|
|
|
|
RenderPassNode(vk::Rect2D renderArea) : storage(std::make_shared<Storage>()), renderArea(renderArea) {}
|
|
|
|
/**
|
|
* @note Any preservation of attachments from previous subpasses is automatically handled by this
|
|
* @return The index of the attachment in the render pass which can be utilized with VkAttachmentReference
|
|
*/
|
|
u32 AddAttachment(TextureView *view);
|
|
|
|
/**
|
|
* @brief Creates a subpass with the attachments bound in the specified order
|
|
*/
|
|
void AddSubpass(span<TextureView *> inputAttachments, span<TextureView *> colorAttachments, TextureView *depthStencilAttachment);
|
|
|
|
/**
|
|
* @brief Clears a color attachment in the current subpass with VK_ATTACHMENT_LOAD_OP_LOAD
|
|
* @param colorAttachment The index of the attachment in the attachments bound to the current subpass
|
|
* @return If the attachment could be cleared or not due to conflicts with other operations
|
|
* @note We require a subpass to be attached during this as the clear will not take place unless it's referenced by a subpass
|
|
*/
|
|
bool ClearColorAttachment(u32 colorAttachment, const vk::ClearColorValue &value);
|
|
|
|
void operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu);
|
|
};
|
|
|
|
/**
|
|
* @brief A node which progresses to the next subpass during a render pass
|
|
*/
|
|
struct NextSubpassNode {
|
|
void operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu) {
|
|
commandBuffer.nextSubpass(vk::SubpassContents::eInline);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief A FunctionNode which progresses to the next subpass prior to calling the function
|
|
*/
|
|
struct NextSubpassFunctionNode : private FunctionNode {
|
|
using FunctionNode::FunctionNode;
|
|
|
|
void operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu) {
|
|
commandBuffer.nextSubpass(vk::SubpassContents::eInline);
|
|
FunctionNode::operator()(commandBuffer, cycle, gpu);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @brief Ends a VkRenderPass that would be created prior with RenderPassNode
|
|
*/
|
|
struct RenderPassEndNode {
|
|
void operator()(vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &cycle, GPU &gpu) {
|
|
commandBuffer.endRenderPass();
|
|
}
|
|
};
|
|
|
|
using NodeVariant = std::variant<FunctionNode, RenderPassNode, NextSubpassNode, NextSubpassFunctionNode, RenderPassEndNode>; //!< A variant encompassing all command nodes types
|
|
}
|