Introduce a base pipeline cache key starting with RTs

It was determined that a general purpose Vulkan pipeline cache isn't viable for the significant performance reqs of Draw(), by using a Maxwell 3D specific key we can shrink state significantly more than if we used Vulkan structs.
This commit is contained in:
Billy Laws 2022-09-06 18:05:28 +01:00
parent 1e8f7d7fcb
commit ffe24aa075
2 changed files with 40 additions and 11 deletions

View File

@ -18,7 +18,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
manager.Bind(handle, colorTarget);
}
ColorRenderTargetState::ColorRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) : engine{manager, dirtyHandle, engine} {}
ColorRenderTargetState::ColorRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine, size_t index) : engine{manager, dirtyHandle, engine}, index{index} {}
static texture::Format ConvertColorRenderTargetFormat(engine::ColorTarget::Format format) {
#define FORMAT_CASE_BASE(engineFormat, skFormat, warn) \
@ -107,8 +107,10 @@ namespace skyline::gpu::interconnect::maxwell3d {
#undef FORMAT_CASE_BASE
}
void ColorRenderTargetState::Flush(InterconnectContext &ctx) {
void ColorRenderTargetState::Flush(InterconnectContext &ctx, Key &key) {
auto &target{engine->colorTarget};
key.SetCtFormat(index, target.format);
if (target.format == engine::ColorTarget::Format::Disabled) {
view = {};
return;
@ -173,7 +175,9 @@ namespace skyline::gpu::interconnect::maxwell3d {
#undef FORMAT_CASE
}
void DepthRenderTargetState::Flush(InterconnectContext &ctx) {
void DepthRenderTargetState::Flush(InterconnectContext &ctx, Key &key) {
key.SetZtFormat(engine->ztFormat);
if (!engine->ztSelect.targetCount) {
view = {};
return;
@ -824,19 +828,21 @@ namespace skyline::gpu::interconnect::maxwell3d {
PipelineState::PipelineState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine)
: engine{manager, dirtyHandle, engine},
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters)},
colorRenderTargets{util::MergeInto<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount>(manager, engine.colorRenderTargetsRegisters, util::IncrementingT<size_t>{})},
depthRenderTarget{manager, engine.depthRenderTargetRegisters},
rasterization{manager, engine.rasterizationRegisters},
depthStencil{manager, engine.depthStencilRegisters},
colorBlend{manager, engine.colorBlendRegisters} {}
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
Key key;
boost::container::static_vector<TextureView *, engine::ColorTargetCount> colorAttachments;
for (auto &colorRenderTarget : colorRenderTargets)
if (auto view{colorRenderTarget.UpdateGet(ctx).view}; view)
if (auto view{colorRenderTarget.UpdateGet(ctx, key).view}; view)
colorAttachments.push_back(view.get());
TextureView *depthAttachment{depthRenderTarget.UpdateGet(ctx).view.get()};
TextureView *depthAttachment{depthRenderTarget.UpdateGet(ctx, key).view.get()};
auto vertexInputState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
const auto &inputAssemblyState{directState.inputAssembly.Build()};
@ -867,10 +873,10 @@ namespace skyline::gpu::interconnect::maxwell3d {
}
std::shared_ptr<TextureView> PipelineState::GetColorRenderTargetForClear(InterconnectContext &ctx, size_t index) {
return colorRenderTargets[index].UpdateGet(ctx).view;
return colorRenderTargets[index].UpdateGet(ctx, key).view;
}
std::shared_ptr<TextureView> PipelineState::GetDepthRenderTargetForClear(InterconnectContext &ctx) {
return depthRenderTarget.UpdateGet(ctx).view;
return depthRenderTarget.UpdateGet(ctx, key).view;
}
}

View File

@ -8,6 +8,26 @@
#include "common.h"
namespace skyline::gpu::interconnect::maxwell3d {
class Key {
private:
struct {
u8 ztFormat : 5; // ZtFormat - 0xA as u8
};
std::array<u8, engine::ColorTargetCount> ctFormats; //!< ColorTarget::Format as u8
public:
std::array<engine::VertexAttribute, engine::VertexAttributeCount> vertexAttributes;
void SetCtFormat(size_t index, engine::ColorTarget::Format format) {
ctFormats[index] = static_cast<u8>(format);
}
void SetZtFormat(engine::ZtFormat format) {
ztFormat = static_cast<u8>(format) - static_cast<u8>(engine::ZtFormat::ZF32);
}
};
class ColorRenderTargetState : dirty::ManualDirty {
public:
struct EngineRegisters {
@ -18,13 +38,14 @@ namespace skyline::gpu::interconnect::maxwell3d {
private:
dirty::BoundSubresource<EngineRegisters> engine;
size_t index;
public:
ColorRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine);
ColorRenderTargetState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine, size_t index);
std::shared_ptr<TextureView> view;
void Flush(InterconnectContext &ctx);
void Flush(InterconnectContext &ctx, Key &key);
};
class DepthRenderTargetState : dirty::ManualDirty {
@ -49,7 +70,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
std::shared_ptr<TextureView> view;
void Flush(InterconnectContext &ctx);
void Flush(InterconnectContext &ctx, Key &key);
};
struct VertexInputState {
@ -242,6 +263,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
};
private:
Key key{};
dirty::BoundSubresource<EngineRegisters> engine;
std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;