mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-22 19:29:20 +01:00
Abstract out pipeline-compile-time GPU state accesses
Introduces the base abstractions that will be used for pipeline caching, with a 'PipelineStateBundle' that can be (de)serialised to/from disk and an abstract accessor class to allow switching between creating disk-cached pipelines and fresh ones.
This commit is contained in:
parent
2e96248fb6
commit
e849264028
@ -190,6 +190,7 @@ add_library(skyline SHARED
|
||||
${source_DIR}/skyline/gpu/interconnect/inline2memory.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/maxwell_3d/active_state.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/maxwell_3d/pipeline_state.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/maxwell_3d/graphics_pipeline_state_accessor.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/maxwell_3d/packed_pipeline_state.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/maxwell_3d/constant_buffers.cpp
|
||||
@ -205,6 +206,7 @@ add_library(skyline SHARED
|
||||
${source_DIR}/skyline/gpu/interconnect/common/samplers.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/common/textures.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/common/shader_cache.cpp
|
||||
${source_DIR}/skyline/gpu/interconnect/common/pipeline_state_bundle.cpp
|
||||
${source_DIR}/skyline/gpu/shaders/helper_shaders.cpp
|
||||
${source_DIR}/skyline/soc/smmu.cpp
|
||||
${source_DIR}/skyline/soc/host1x/syncpoint.cpp
|
||||
|
@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shader_compiler/shader_info.h>
|
||||
#include "common.h"
|
||||
#include "textures.h"
|
||||
|
||||
namespace skyline::gpu::interconnect {
|
||||
/**
|
||||
* @brief Provides an abstract interface for accessing pipeline state at creation time
|
||||
*/
|
||||
class PipelineStateAccessor {
|
||||
public:
|
||||
/**
|
||||
* @return The texture type for the TIC entry at the given index
|
||||
*/
|
||||
virtual Shader::TextureType GetTextureType(u32 index) const = 0;
|
||||
|
||||
/**
|
||||
* @return The value of the constant buffer at the given index, offset and stage
|
||||
*/
|
||||
virtual u32 GetConstantBufferValue(u32 shaderStage, u32 index, u32 offset) const = 0;
|
||||
|
||||
/**
|
||||
* @return The raw binary for the given pipeline stage
|
||||
*/
|
||||
virtual ShaderBinary GetShaderBinary(u32 pipelineStage) const = 0;
|
||||
|
||||
/**
|
||||
* @brief Marks that all Get* operations on the pipeline state has finished and the pipeline is build
|
||||
*/
|
||||
virtual void MarkComplete() const = 0;
|
||||
|
||||
virtual ~PipelineStateAccessor() = default;
|
||||
};
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include <range/v3/algorithm.hpp>
|
||||
#include "pipeline_state_bundle.h"
|
||||
|
||||
namespace skyline::gpu::interconnect {
|
||||
void PipelineStateBundle::PipelineStage::Reset() {
|
||||
binary.clear();
|
||||
binaryBaseOffset = 0;
|
||||
}
|
||||
|
||||
PipelineStateBundle::PipelineStateBundle() {}
|
||||
|
||||
void PipelineStateBundle::Reset(span<const u8> newKey) {
|
||||
ranges::for_each(pipelineStages, [](auto &stage) { stage.Reset(); });
|
||||
key.resize(newKey.size());
|
||||
span(key).copy_from(newKey);
|
||||
textureTypes.clear();
|
||||
constantBufferValues.clear();
|
||||
}
|
||||
|
||||
void PipelineStateBundle::SetShaderBinary(u32 pipelineStage, ShaderBinary bin) {
|
||||
if (pipelineStages.size() <= pipelineStage)
|
||||
pipelineStages.resize(pipelineStage + 1);
|
||||
auto &stageInfo{pipelineStages[pipelineStage]};
|
||||
stageInfo.binary.resize(bin.binary.size());
|
||||
span(stageInfo.binary).copy_from(bin.binary);
|
||||
stageInfo.binaryBaseOffset = bin.baseOffset;
|
||||
}
|
||||
|
||||
void PipelineStateBundle::AddTextureType(u32 index, Shader::TextureType type) {
|
||||
textureTypes.emplace_back(index, type);
|
||||
}
|
||||
|
||||
void PipelineStateBundle::AddConstantBufferValue(u32 shaderStage, u32 index, u32 offset, u32 value) {
|
||||
constantBufferValues.push_back({shaderStage, index, offset, value});
|
||||
}
|
||||
|
||||
span<u8> PipelineStateBundle::GetKey() {
|
||||
return span(key);
|
||||
}
|
||||
|
||||
ShaderBinary PipelineStateBundle::GetShaderBinary(u32 pipelineStage) {
|
||||
auto &stageInfo{pipelineStages[pipelineStage]};
|
||||
return {stageInfo.binary, stageInfo.binaryBaseOffset};
|
||||
}
|
||||
|
||||
Shader::TextureType PipelineStateBundle::LookupTextureType(u32 offset) {
|
||||
auto it{ranges::find_if(textureTypes, [offset](auto &pair) { return pair.first == offset; })};
|
||||
if (it == textureTypes.end())
|
||||
throw exception("Failed to find texture type for offset: 0x{:X}", offset);
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
u32 PipelineStateBundle::LookupConstantBufferValue(u32 shaderStage, u32 index, u32 offset) {
|
||||
auto it{ranges::find_if(constantBufferValues, [index, offset, shaderStage](auto &val) { return val.index == index && val.offset == offset && val.shaderStage == shaderStage; })};
|
||||
if (it == constantBufferValues.end())
|
||||
throw exception("Failed to find constant buffer value for offset: 0x{:X}", offset);
|
||||
|
||||
return it->value;
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shader_compiler/shader_info.h>
|
||||
#include "common.h"
|
||||
|
||||
namespace skyline::gpu::interconnect {
|
||||
/**
|
||||
* @brief Stores both key and non-key state for a pipeline that is otherwise only accessible at creation time
|
||||
*/
|
||||
class PipelineStateBundle {
|
||||
private:
|
||||
std::vector<u8> key; //!< Byte array containing the pipeline key, this is interpreted by the the user and two different keys might refer to the same pipeline
|
||||
|
||||
/**
|
||||
* @brief Holds the raw binary and associated info for a pipeline stage
|
||||
*/
|
||||
struct PipelineStage {
|
||||
std::vector<u8> binary;
|
||||
u32 binaryBaseOffset;
|
||||
|
||||
void Reset();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Holds a value of a constant buffer read from memory at pipeline creation time
|
||||
*/
|
||||
struct ConstantBufferValue {
|
||||
u32 shaderStage;
|
||||
u32 index;
|
||||
u32 offset;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
boost::container::small_vector<ConstantBufferValue, 4> constantBufferValues;
|
||||
boost::container::small_vector<std::pair<u32, Shader::TextureType>, 4> textureTypes;
|
||||
|
||||
std::vector<PipelineStage> pipelineStages{};
|
||||
|
||||
public:
|
||||
PipelineStateBundle();
|
||||
|
||||
/**
|
||||
* @brief Resets the bundle's state using the given key so it can be reused for a new pipeline
|
||||
*/
|
||||
void Reset(span<const u8> newKey);
|
||||
|
||||
template<typename T> requires std::is_trivially_copyable_v<T>
|
||||
void Reset(const T &value) {
|
||||
Reset(span<const u8>(reinterpret_cast<const u8 *>(&value), sizeof(T)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the binary for a given pipeline stage
|
||||
*/
|
||||
void SetShaderBinary(u32 pipelineStage, ShaderBinary bin);
|
||||
|
||||
/**
|
||||
* @brief Adds a texture type value for a given offset to the bundle
|
||||
*/
|
||||
void AddTextureType(u32 index, Shader::TextureType type);
|
||||
|
||||
/**
|
||||
* @brief Adds a constant buffer value for a given offset and shader stage to the bundle
|
||||
*/
|
||||
void AddConstantBufferValue(u32 shaderStage, u32 index, u32 offset, u32 value);
|
||||
|
||||
/**
|
||||
* @brief Returns the raw key data for the pipeline
|
||||
*/
|
||||
span<u8> GetKey();
|
||||
|
||||
template<typename T> requires std::is_trivially_copyable_v<T>
|
||||
const T &GetKey() {
|
||||
return *reinterpret_cast<const T *>(key.data());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the binary for a given pipeline stage
|
||||
*/
|
||||
ShaderBinary GetShaderBinary(u32 pipelineStage);
|
||||
|
||||
/**
|
||||
* @brief Returns the texture type for a given offset
|
||||
*/
|
||||
Shader::TextureType LookupTextureType(u32 offset);
|
||||
|
||||
/**
|
||||
* @brief Returns the constant buffer value for a given offset and shader stage
|
||||
*/
|
||||
u32 LookupConstantBufferValue(u32 shaderStage, u32 index, u32 offset);
|
||||
};
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include "graphics_pipeline_state_accessor.h"
|
||||
|
||||
namespace skyline::gpu::interconnect::maxwell3d {
|
||||
RuntimeGraphicsPipelineStateAccessor::RuntimeGraphicsPipelineStateAccessor(PipelineStateBundle &bundle,
|
||||
InterconnectContext &ctx,
|
||||
Textures &textures, ConstantBufferSet &constantBuffers,
|
||||
const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries)
|
||||
: bundle{bundle}, ctx{ctx}, textures{textures}, constantBuffers{constantBuffers}, shaderBinaries{shaderBinaries} {}
|
||||
|
||||
|
||||
Shader::TextureType RuntimeGraphicsPipelineStateAccessor::GetTextureType(u32 index) const {
|
||||
Shader::TextureType type{textures.GetTextureType(ctx, index)};
|
||||
bundle.AddTextureType(index, type);
|
||||
return type;
|
||||
}
|
||||
|
||||
u32 RuntimeGraphicsPipelineStateAccessor::GetConstantBufferValue(u32 shaderStage, u32 index, u32 offset) const {
|
||||
u32 value{constantBuffers[shaderStage][index].Read<u32>(ctx.executor, offset)};
|
||||
bundle.AddConstantBufferValue(shaderStage, index, offset, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
ShaderBinary RuntimeGraphicsPipelineStateAccessor::GetShaderBinary(u32 pipelineStage) const {
|
||||
ShaderBinary binary{shaderBinaries[pipelineStage]};
|
||||
bundle.SetShaderBinary(pipelineStage, binary);
|
||||
return binary;
|
||||
}
|
||||
|
||||
void RuntimeGraphicsPipelineStateAccessor::MarkComplete() const {}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gpu/interconnect/common/pipeline_state_accessor.h>
|
||||
#include <gpu/interconnect/common/pipeline_state_bundle.h>
|
||||
#include <gpu/interconnect/common/textures.h>
|
||||
#include "constant_buffers.h"
|
||||
|
||||
|
||||
namespace skyline::gpu::interconnect::maxwell3d {
|
||||
/**
|
||||
* @brief Implements the PipelineStateAccessor interface for pipelines created at emulator runtime
|
||||
*/
|
||||
class RuntimeGraphicsPipelineStateAccessor : public PipelineStateAccessor {
|
||||
private:
|
||||
PipelineStateBundle &bundle;
|
||||
InterconnectContext &ctx;
|
||||
Textures &textures;
|
||||
ConstantBufferSet &constantBuffers;
|
||||
std::array<ShaderBinary, engine::PipelineCount> shaderBinaries;
|
||||
|
||||
public:
|
||||
RuntimeGraphicsPipelineStateAccessor(PipelineStateBundle &bundle,
|
||||
InterconnectContext &ctx,
|
||||
Textures &textures, ConstantBufferSet &constantBuffers,
|
||||
const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries);
|
||||
|
||||
Shader::TextureType GetTextureType(u32 index) const override;
|
||||
|
||||
u32 GetConstantBufferValue(u32 shaderStage, u32 index, u32 offset) const override;
|
||||
|
||||
ShaderBinary GetShaderBinary(u32 pipelineStage) const override;
|
||||
|
||||
void MarkComplete() const override;
|
||||
};
|
||||
}
|
@ -173,35 +173,36 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
return info;
|
||||
}
|
||||
|
||||
static std::array<Pipeline::ShaderStage, engine::ShaderStageCount> MakePipelineShaders(InterconnectContext &ctx, Textures &textures, ConstantBufferSet &constantBuffers, const PackedPipelineState &packedState, const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries) {
|
||||
static std::array<Pipeline::ShaderStage, engine::ShaderStageCount> MakePipelineShaders(InterconnectContext &ctx, const PipelineStateAccessor &accessor, const PackedPipelineState &packedState) {
|
||||
ctx.gpu.shader.ResetPools();
|
||||
|
||||
using PipelineStage = engine::Pipeline::Shader::Type;
|
||||
auto pipelineStage{[](size_t i) { return static_cast<PipelineStage>(i); }};
|
||||
auto pipelineStage{[](u32 i) { return static_cast<PipelineStage>(i); }};
|
||||
auto stageIdx{[](PipelineStage stage) { return static_cast<u8>(stage); }};
|
||||
|
||||
std::array<Shader::IR::Program, engine::PipelineCount> programs;
|
||||
bool ignoreVertexCullBeforeFetch{};
|
||||
|
||||
for (size_t i{}; i < engine::PipelineCount; i++) {
|
||||
for (u32 i{}; i < engine::PipelineCount; i++) {
|
||||
if (!packedState.shaderHashes[i])
|
||||
continue;
|
||||
|
||||
auto binary{accessor.GetShaderBinary(i)};
|
||||
auto program{ctx.gpu.shader.ParseGraphicsShader(
|
||||
packedState.postVtgShaderAttributeSkipMask,
|
||||
ConvertCompilerShaderStage(static_cast<PipelineStage>(i)),
|
||||
shaderBinaries[i].binary, shaderBinaries[i].baseOffset,
|
||||
binary.binary, binary.baseOffset,
|
||||
packedState.bindlessTextureConstantBufferSlotSelect,
|
||||
packedState.viewportTransformEnable,
|
||||
[&](u32 index, u32 offset) {
|
||||
size_t shaderStage{i > 0 ? (i - 1) : 0};
|
||||
return constantBuffers[shaderStage][index].Read<int>(ctx.executor, offset);
|
||||
u32 shaderStage{i > 0 ? (i - 1) : 0};
|
||||
return accessor.GetConstantBufferValue(shaderStage, index, offset);
|
||||
}, [&](u32 index) {
|
||||
return textures.GetTextureType(ctx, BindlessHandle{ .raw = index }.textureIndex);
|
||||
return accessor.GetTextureType(BindlessHandle{ .raw = index }.textureIndex);
|
||||
})};
|
||||
if (i == stageIdx(PipelineStage::Vertex) && packedState.shaderHashes[stageIdx(PipelineStage::VertexCullBeforeFetch)]) {
|
||||
ignoreVertexCullBeforeFetch = true;
|
||||
programs[i] = ctx.gpu.shader.CombineVertexShaders(programs[stageIdx(PipelineStage::VertexCullBeforeFetch)], program, shaderBinaries[i].binary);
|
||||
programs[i] = ctx.gpu.shader.CombineVertexShaders(programs[stageIdx(PipelineStage::VertexCullBeforeFetch)], program, binary.binary);
|
||||
} else {
|
||||
programs[i] = program;
|
||||
}
|
||||
@ -213,7 +214,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
std::array<Pipeline::ShaderStage, engine::ShaderStageCount> shaderStages{};
|
||||
|
||||
for (size_t i{stageIdx(ignoreVertexCullBeforeFetch ? PipelineStage::Vertex : PipelineStage::VertexCullBeforeFetch)}; i < engine::PipelineCount; i++) {
|
||||
for (u32 i{stageIdx(ignoreVertexCullBeforeFetch ? PipelineStage::Vertex : PipelineStage::VertexCullBeforeFetch)}; i < engine::PipelineCount; i++) {
|
||||
if (!packedState.shaderHashes[i])
|
||||
continue;
|
||||
|
||||
@ -424,8 +425,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
static cache::GraphicsPipelineCache::CompiledPipeline MakeCompiledPipeline(InterconnectContext &ctx,
|
||||
const PackedPipelineState &packedState,
|
||||
const std::array<Pipeline::ShaderStage, engine::ShaderStageCount> &shaderStages,
|
||||
span<vk::DescriptorSetLayoutBinding> layoutBindings,
|
||||
span<TextureView *> colorAttachments, TextureView *depthAttachment) {
|
||||
span<vk::DescriptorSetLayoutBinding> layoutBindings) {
|
||||
boost::container::static_vector<vk::PipelineShaderStageCreateInfo, engine::ShaderStageCount> shaderStageInfos;
|
||||
for (const auto &stage : shaderStages)
|
||||
if (stage.module)
|
||||
@ -526,8 +526,13 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
std::tie(depthStencilState.front, depthStencilState.back) = packedState.GetStencilOpsState();
|
||||
|
||||
boost::container::static_vector<vk::PipelineColorBlendAttachmentState, engine::ColorTargetCount> attachmentBlendStates;
|
||||
for (u32 i{}; i < colorAttachments.size(); i++)
|
||||
boost::container::static_vector<vk::Format, engine::ColorTargetCount> colorAttachmentFormats;
|
||||
|
||||
for (u32 i{}; i < packedState.GetColorRenderTargetCount(); i++) {
|
||||
attachmentBlendStates.push_back(packedState.GetAttachmentBlendState(i));
|
||||
texture::Format format{packedState.GetColorRenderTargetFormat(i)};
|
||||
colorAttachmentFormats.push_back(format ? format->vkFormat : vk::Format::eUndefined);
|
||||
}
|
||||
|
||||
vk::PipelineColorBlendStateCreateInfo colorBlendState{
|
||||
.logicOpEnable = packedState.logicOpEnable,
|
||||
@ -536,7 +541,11 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
.pAttachments = attachmentBlendStates.data()
|
||||
};
|
||||
|
||||
constexpr std::array<vk::DynamicState, 10> dynamicStates{
|
||||
|
||||
static constexpr u32 BaseDynamicStateCount{9};
|
||||
static constexpr u32 ExtendedDynamicStateCount{BaseDynamicStateCount + 1};
|
||||
|
||||
constexpr std::array<vk::DynamicState, ExtendedDynamicStateCount> dynamicStates{
|
||||
vk::DynamicState::eViewport,
|
||||
vk::DynamicState::eScissor,
|
||||
vk::DynamicState::eLineWidth,
|
||||
@ -550,9 +559,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
vk::DynamicState::eVertexInputBindingStrideEXT
|
||||
};
|
||||
|
||||
static constexpr u32 BaseDynamicStateCount{9};
|
||||
static constexpr u32 ExtendedDynamicStateCount{BaseDynamicStateCount + 1};
|
||||
|
||||
vk::PipelineDynamicStateCreateInfo dynamicState{
|
||||
.dynamicStateCount = ctx.gpu.traits.supportsExtendedDynamicState ? ExtendedDynamicStateCount : BaseDynamicStateCount,
|
||||
.pDynamicStates = dynamicStates.data()
|
||||
@ -569,6 +575,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
.pScissors = emptyScissors.data(),
|
||||
};
|
||||
|
||||
texture::Format depthStencilFormat{packedState.GetDepthRenderTargetFormat()};
|
||||
|
||||
return ctx.gpu.graphicsPipelineCache.GetCompiledPipeline(cache::GraphicsPipelineCache::PipelineState{
|
||||
.shaderStages = shaderStageInfos,
|
||||
.vertexState = vertexInputState,
|
||||
@ -580,15 +588,16 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
.depthStencilState = depthStencilState,
|
||||
.colorBlendState = colorBlendState,
|
||||
.dynamicState = dynamicState,
|
||||
.colorAttachments = colorAttachments,
|
||||
.depthStencilAttachment = depthAttachment,
|
||||
.colorFormats = colorAttachmentFormats,
|
||||
.depthStencilFormat = depthStencilFormat ? depthStencilFormat->vkFormat : vk::Format::eUndefined,
|
||||
.sampleCount = vk::SampleCountFlagBits::e1, //TODO: fix after MSAA support
|
||||
}, layoutBindings);
|
||||
}
|
||||
|
||||
Pipeline::Pipeline(InterconnectContext &ctx, Textures &textures, ConstantBufferSet &constantBuffers, const PackedPipelineState &packedState, const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries, span<TextureView *> colorAttachments, TextureView *depthAttachment)
|
||||
: shaderStages{MakePipelineShaders(ctx, textures, constantBuffers, packedState, shaderBinaries)},
|
||||
Pipeline::Pipeline(InterconnectContext &ctx, const PipelineStateAccessor &accessor, const PackedPipelineState &packedState)
|
||||
: shaderStages{MakePipelineShaders(ctx, accessor, packedState)},
|
||||
descriptorInfo{MakePipelineDescriptorInfo(shaderStages, ctx.gpu.traits.quirks.needsIndividualTextureBindingWrites)},
|
||||
compiledPipeline{MakeCompiledPipeline(ctx, packedState, shaderStages, descriptorInfo.descriptorSetLayoutBindings, colorAttachments, depthAttachment)},
|
||||
compiledPipeline{MakeCompiledPipeline(ctx, packedState, shaderStages, descriptorInfo.descriptorSetLayoutBindings)},
|
||||
sourcePackedState{packedState} {
|
||||
storageBufferViews.resize(descriptorInfo.totalStorageBufferCount);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "common.h"
|
||||
#include "packed_pipeline_state.h"
|
||||
#include "constant_buffers.h"
|
||||
#include "graphics_pipeline_state_accessor.h"
|
||||
|
||||
namespace skyline::gpu {
|
||||
class TextureView;
|
||||
@ -100,7 +101,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
PackedPipelineState sourcePackedState;
|
||||
|
||||
Pipeline(InterconnectContext &ctx, Textures &textures, ConstantBufferSet &constantBuffers, const PackedPipelineState &packedState, const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries, span<TextureView *> colorAttachments, TextureView *depthAttachment);
|
||||
Pipeline(InterconnectContext &ctx, const PipelineStateAccessor &accessor, const PackedPipelineState &packedState);
|
||||
|
||||
Pipeline *LookupNext(const PackedPipelineState &packedState);
|
||||
|
||||
@ -123,17 +124,23 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
DescriptorUpdateInfo *SyncDescriptorsQuickBind(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, Samplers &samplers, Textures &textures, ConstantBuffers::QuickBind quickBind, span<TextureView *> sampledImages);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Manages the caching and creation of pipelines
|
||||
*/
|
||||
class PipelineManager {
|
||||
private:
|
||||
PipelineStateBundle bundle;
|
||||
tsl::robin_map<PackedPipelineState, std::unique_ptr<Pipeline>, PackedPipelineStateHash> map;
|
||||
|
||||
public:
|
||||
Pipeline *FindOrCreate(InterconnectContext &ctx, Textures &textures, ConstantBufferSet &constantBuffers, const PackedPipelineState &packedState, const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries, span<TextureView *> colorAttachments, TextureView *depthAttachment) {
|
||||
Pipeline *FindOrCreate(InterconnectContext &ctx, Textures &textures, ConstantBufferSet &constantBuffers, const PackedPipelineState &packedState, const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries) {
|
||||
auto it{map.find(packedState)};
|
||||
if (it != map.end())
|
||||
return it->second.get();
|
||||
|
||||
return map.emplace(packedState, std::make_unique<Pipeline>(ctx, textures, constantBuffers, packedState, shaderBinaries, colorAttachments, depthAttachment)).first->second.get();
|
||||
bundle.Reset(packedState);
|
||||
auto accessor{RuntimeGraphicsPipelineStateAccessor{bundle, ctx, textures, constantBuffers, shaderBinaries}};
|
||||
return map.emplace(packedState, std::make_unique<Pipeline>(ctx, accessor, packedState)).first->second.get();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
}
|
||||
|
||||
auto newPipeline{pipelineManager.FindOrCreate(ctx, textures, constantBuffers, packedState, shaderBinaries, colorAttachments, depthAttachment)};
|
||||
auto newPipeline{pipelineManager.FindOrCreate(ctx, textures, constantBuffers, packedState, shaderBinaries)};
|
||||
if (pipeline)
|
||||
pipeline->AddTransition(newPipeline);
|
||||
pipeline = newPipeline;
|
||||
|
@ -136,6 +136,7 @@ namespace skyline::gpu {
|
||||
.scissorCount = 1
|
||||
};
|
||||
|
||||
std::array<vk::Format, 1> colorFormats{colorAttachment ? colorAttachment->format->vkFormat : vk::Format::eUndefined};
|
||||
return gpu.graphicsPipelineCache.GetCompiledPipeline(cache::GraphicsPipelineCache::PipelineState{
|
||||
.shaderStages = shaderStages,
|
||||
.vertexState = vertexState,
|
||||
@ -147,8 +148,8 @@ namespace skyline::gpu {
|
||||
.depthStencilState = depthStencilState,
|
||||
.colorBlendState = blendState,
|
||||
.dynamicState = {},
|
||||
.colorAttachments = span<TextureView *>{colorAttachment},
|
||||
.depthStencilAttachment = depthStencilAttachment,
|
||||
.colorFormats = colorFormats,
|
||||
.depthStencilFormat = depthStencilAttachment ? depthStencilAttachment->format->vkFormat : vk::Format::eUndefined,
|
||||
}, layoutBindings, pushConstantRanges, true);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user