mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 00:35:29 +03:00
Implement simple pipeline transition cache
Avoids the need to hash PipelineState when we can guess the pipeline that will be used next. This could very easily be optimised in the future with generational, usage-based caching if necessary.
This commit is contained in:
parent
302b2fcc3f
commit
388cff3353
@ -505,13 +505,27 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
Pipeline::Pipeline(InterconnectContext &ctx, const PackedPipelineState &packedState, const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries, span<TextureView *> colorAttachments, TextureView *depthAttachment)
|
||||
: shaderStages{MakePipelineShaders(ctx, packedState, shaderBinaries)},
|
||||
descriptorSetLayoutBindings{MakePipelineDescriptorSetLayoutBindings(shaderStages)},
|
||||
compiledPipeline{MakeCompiledPipeline(ctx, packedState, shaderStages, descriptorSetLayoutBindings, colorAttachments, depthAttachment)} {
|
||||
compiledPipeline{MakeCompiledPipeline(ctx, packedState, shaderStages, descriptorSetLayoutBindings, colorAttachments, depthAttachment)},
|
||||
sourcePackedState{packedState} {
|
||||
}
|
||||
|
||||
Pipeline *Pipeline::LookupNext(const PackedPipelineState &packedState) {
|
||||
auto it{std::find_if(transitionCache.begin(), transitionCache.end(), [&packedState](auto pipeline) {
|
||||
if (pipeline && pipeline->sourcePackedState == packedState)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
})};
|
||||
|
||||
if (it != transitionCache.end())
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Pipeline::AddTransition(const PackedPipelineState &packedState, Pipeline *next) {}
|
||||
void Pipeline::AddTransition(Pipeline *next) {
|
||||
transitionCache[transitionCacheNextIdx] = next;
|
||||
transitionCacheNextIdx = (transitionCacheNextIdx + 1) % transitionCache.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,12 +32,17 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
std::vector<vk::DescriptorSetLayoutBinding> descriptorSetLayoutBindings;
|
||||
cache::GraphicsPipelineCache::CompiledPipeline compiledPipeline;
|
||||
|
||||
std::array<Pipeline *, 4> transitionCache{};
|
||||
size_t transitionCacheNextIdx{};
|
||||
|
||||
public:
|
||||
PackedPipelineState sourcePackedState;
|
||||
|
||||
Pipeline(InterconnectContext &ctx, const PackedPipelineState &packedState, const std::array<ShaderBinary, engine::PipelineCount> &shaderBinaries, span<TextureView *> colorAttachments, TextureView *depthAttachment);
|
||||
|
||||
Pipeline *LookupNext(const PackedPipelineState &packedState);
|
||||
|
||||
void AddTransition(const PackedPipelineState &packedState, Pipeline *next);
|
||||
void AddTransition(Pipeline *next);
|
||||
};
|
||||
|
||||
class PipelineManager {
|
||||
|
@ -294,6 +294,15 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
entry->cache.insert({blockMapping.data() + blockOffset, CacheEntry{binary, hash}});
|
||||
}
|
||||
|
||||
// TODO: this needs to be checked every draw irresspective of pipeline dirtiness
|
||||
bool PipelineStageState::Refresh(InterconnectContext &ctx) {
|
||||
std::scoped_lock lock{trapMutex};
|
||||
if (entry && entry->dirty)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
PipelineStageState::~PipelineStageState() {
|
||||
std::scoped_lock lock{trapMutex};
|
||||
//for (const auto &mirror : mirrorMap)
|
||||
@ -504,10 +513,11 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
pipeline = newPipeline;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto newPipeline{pipelineManager.FindOrCreate(ctx, packedState, shaderBinaries, colorAttachments, depthAttachment)};
|
||||
pipeline->AddTransition(packedState, newPipeline);
|
||||
if (pipeline)
|
||||
pipeline->AddTransition(newPipeline);
|
||||
pipeline = newPipeline;
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
void Flush(InterconnectContext &ctx, PackedPipelineState &packedState);
|
||||
};
|
||||
|
||||
class PipelineStageState : dirty::ManualDirty {
|
||||
class PipelineStageState : dirty::RefreshableManualDirty {
|
||||
public:
|
||||
struct EngineRegisters {
|
||||
const engine::Pipeline &pipeline;
|
||||
@ -100,6 +100,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
~PipelineStageState();
|
||||
|
||||
void Flush(InterconnectContext &ctx);
|
||||
|
||||
bool Refresh(InterconnectContext &ctx);
|
||||
};
|
||||
|
||||
class VertexInputState : dirty::ManualDirty {
|
||||
|
Loading…
Reference in New Issue
Block a user