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); 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) { static texture::Format ConvertColorRenderTargetFormat(engine::ColorTarget::Format format) {
#define FORMAT_CASE_BASE(engineFormat, skFormat, warn) \ #define FORMAT_CASE_BASE(engineFormat, skFormat, warn) \
@ -107,8 +107,10 @@ namespace skyline::gpu::interconnect::maxwell3d {
#undef FORMAT_CASE_BASE #undef FORMAT_CASE_BASE
} }
void ColorRenderTargetState::Flush(InterconnectContext &ctx) { void ColorRenderTargetState::Flush(InterconnectContext &ctx, Key &key) {
auto &target{engine->colorTarget}; auto &target{engine->colorTarget};
key.SetCtFormat(index, target.format);
if (target.format == engine::ColorTarget::Format::Disabled) { if (target.format == engine::ColorTarget::Format::Disabled) {
view = {}; view = {};
return; return;
@ -173,7 +175,9 @@ namespace skyline::gpu::interconnect::maxwell3d {
#undef FORMAT_CASE #undef FORMAT_CASE
} }
void DepthRenderTargetState::Flush(InterconnectContext &ctx) { void DepthRenderTargetState::Flush(InterconnectContext &ctx, Key &key) {
key.SetZtFormat(engine->ztFormat);
if (!engine->ztSelect.targetCount) { if (!engine->ztSelect.targetCount) {
view = {}; view = {};
return; return;
@ -824,19 +828,21 @@ namespace skyline::gpu::interconnect::maxwell3d {
PipelineState::PipelineState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine) PipelineState::PipelineState(dirty::Handle dirtyHandle, DirtyManager &manager, const EngineRegisters &engine)
: engine{manager, dirtyHandle, 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}, depthRenderTarget{manager, engine.depthRenderTargetRegisters},
rasterization{manager, engine.rasterizationRegisters}, rasterization{manager, engine.rasterizationRegisters},
depthStencil{manager, engine.depthStencilRegisters}, depthStencil{manager, engine.depthStencilRegisters},
colorBlend{manager, engine.colorBlendRegisters} {} colorBlend{manager, engine.colorBlendRegisters} {}
void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) { void PipelineState::Flush(InterconnectContext &ctx, StateUpdateBuilder &builder) {
Key key;
boost::container::static_vector<TextureView *, engine::ColorTargetCount> colorAttachments; boost::container::static_vector<TextureView *, engine::ColorTargetCount> colorAttachments;
for (auto &colorRenderTarget : colorRenderTargets) 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()); 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)}; auto vertexInputState{directState.vertexInput.Build(ctx, engine->vertexInputRegisters)};
const auto &inputAssemblyState{directState.inputAssembly.Build()}; 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) { 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) { 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" #include "common.h"
namespace skyline::gpu::interconnect::maxwell3d { 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 { class ColorRenderTargetState : dirty::ManualDirty {
public: public:
struct EngineRegisters { struct EngineRegisters {
@ -18,13 +38,14 @@ namespace skyline::gpu::interconnect::maxwell3d {
private: private:
dirty::BoundSubresource<EngineRegisters> engine; dirty::BoundSubresource<EngineRegisters> engine;
size_t index;
public: 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; std::shared_ptr<TextureView> view;
void Flush(InterconnectContext &ctx); void Flush(InterconnectContext &ctx, Key &key);
}; };
class DepthRenderTargetState : dirty::ManualDirty { class DepthRenderTargetState : dirty::ManualDirty {
@ -49,7 +70,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
std::shared_ptr<TextureView> view; std::shared_ptr<TextureView> view;
void Flush(InterconnectContext &ctx); void Flush(InterconnectContext &ctx, Key &key);
}; };
struct VertexInputState { struct VertexInputState {
@ -242,6 +263,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
}; };
private: private:
Key key{};
dirty::BoundSubresource<EngineRegisters> engine; dirty::BoundSubresource<EngineRegisters> engine;
std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets; std::array<dirty::ManualDirtyState<ColorRenderTargetState>, engine::ColorTargetCount> colorRenderTargets;