mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-21 23:39:55 +00:00
[TEST] Prune on passthrough stores
This commit is contained in:
@@ -391,6 +391,52 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b
|
||||
return result;
|
||||
}
|
||||
|
||||
void PrunePassthroughStores(IR::Program& program, const VaryingState& previous_stage_stores) {
|
||||
if (program.stage != Stage::Geometry || program.is_geometry_passthrough) {
|
||||
return;
|
||||
}
|
||||
VaryingState pruned;
|
||||
for (size_t index = 0; index < program.info.passthrough.mask.size(); ++index) {
|
||||
if (!program.info.passthrough.mask[index] || previous_stage_stores.mask[index]) {
|
||||
continue;
|
||||
}
|
||||
const IR::Attribute attr{static_cast<IR::Attribute>(index)};
|
||||
if (attr >= IR::Attribute::PositionX && attr <= IR::Attribute::PositionW) {
|
||||
continue;
|
||||
}
|
||||
pruned.mask[index] = true;
|
||||
}
|
||||
if (pruned.mask.none()) {
|
||||
return;
|
||||
}
|
||||
const auto erase_matching{[&pruned](IR::Block* block, IR::Opcode opcode, bool skip_used) {
|
||||
auto it{block->begin()};
|
||||
while (it != block->end()) {
|
||||
IR::Inst& inst{*it};
|
||||
if (inst.GetOpcode() != opcode ||
|
||||
!pruned.mask[static_cast<size_t>(inst.Arg(0).Attribute())]) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
if (skip_used && inst.HasUses()) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
inst.Invalidate();
|
||||
it = block->Instructions().erase(it);
|
||||
}
|
||||
}};
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
erase_matching(block, IR::Opcode::SetAttribute, false);
|
||||
}
|
||||
for (IR::Block* const block : program.post_order_blocks) {
|
||||
erase_matching(block, IR::Opcode::GetAttribute, true);
|
||||
}
|
||||
program.info.stores.mask &= ~pruned.mask;
|
||||
program.info.loads.mask &= ~pruned.mask;
|
||||
program.info.passthrough.mask &= ~pruned.mask;
|
||||
}
|
||||
|
||||
void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& runtime_info) {
|
||||
auto& stores = program.info.stores;
|
||||
if (stores.Legacy()) {
|
||||
|
||||
@@ -29,6 +29,8 @@ namespace Shader::Maxwell {
|
||||
|
||||
void ConvertLegacyToGeneric(IR::Program& program, const RuntimeInfo& runtime_info);
|
||||
|
||||
void PrunePassthroughStores(IR::Program& program, const VaryingState& previous_stage_stores);
|
||||
|
||||
// Maxwell v1 and older Nvidia cards don't support setting gl_Layer from non-geometry stages.
|
||||
// This creates a workaround by setting the layer as a generic output and creating a
|
||||
// passthrough geometry shader that reads the generic and sets the layer.
|
||||
|
||||
@@ -45,6 +45,7 @@ using Shader::Backend::SPIRV::EmitSPIRV;
|
||||
using Shader::Maxwell::ConvertLegacyToGeneric;
|
||||
using Shader::Maxwell::GenerateGeometryPassthrough;
|
||||
using Shader::Maxwell::MergeDualVertexPrograms;
|
||||
using Shader::Maxwell::PrunePassthroughStores;
|
||||
using Shader::Maxwell::TranslateProgram;
|
||||
using VideoCommon::ComputeEnvironment;
|
||||
using VideoCommon::FileEnvironment;
|
||||
@@ -54,7 +55,7 @@ using VideoCommon::LoadPipelines;
|
||||
using VideoCommon::SerializePipeline;
|
||||
using Context = ShaderContext::Context;
|
||||
|
||||
constexpr u32 CACHE_VERSION = 17;
|
||||
constexpr u32 CACHE_VERSION = 18;
|
||||
|
||||
template <typename Container>
|
||||
auto MakeSpan(Container& container) {
|
||||
@@ -537,6 +538,9 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
|
||||
const size_t stage_index{index - 1};
|
||||
infos[stage_index] = &program.info;
|
||||
|
||||
if (previous_program) {
|
||||
PrunePassthroughStores(program, previous_program->info.stores);
|
||||
}
|
||||
const auto runtime_info = MakeRuntimeInfo(key, program, previous_program, glasm_use_storage_buffers, use_glasm);
|
||||
switch (::Settings::values.renderer_backend.GetValue()) {
|
||||
case Settings::RendererBackend::OpenGL_GLSL:
|
||||
|
||||
@@ -56,13 +56,14 @@ using Shader::Backend::SPIRV::EmitSPIRV;
|
||||
using Shader::Maxwell::ConvertLegacyToGeneric;
|
||||
using Shader::Maxwell::GenerateGeometryPassthrough;
|
||||
using Shader::Maxwell::MergeDualVertexPrograms;
|
||||
using Shader::Maxwell::PrunePassthroughStores;
|
||||
using Shader::Maxwell::TranslateProgram;
|
||||
using VideoCommon::ComputeEnvironment;
|
||||
using VideoCommon::FileEnvironment;
|
||||
using VideoCommon::GenericEnvironment;
|
||||
using VideoCommon::GraphicsEnvironment;
|
||||
|
||||
constexpr u32 CACHE_VERSION = 20;
|
||||
constexpr u32 CACHE_VERSION = 21;
|
||||
constexpr size_t VULKAN_CACHE_FLUSH_PIPELINES = 128;
|
||||
constexpr size_t VULKAN_CACHE_FLUSH_MIN_SECONDS = 30;
|
||||
constexpr std::array<char, 8> VULKAN_CACHE_MAGIC_NUMBER{'y', 'u', 'z', 'u', 'v', 'k', 'c', 'h'};
|
||||
@@ -838,6 +839,9 @@ std::unique_ptr<GraphicsPipeline> PipelineCache::CreateGraphicsPipeline(
|
||||
const size_t stage_index{index - 1};
|
||||
infos[stage_index] = &program.info;
|
||||
|
||||
if (previous_stage) {
|
||||
PrunePassthroughStores(program, previous_stage->info.stores);
|
||||
}
|
||||
const auto runtime_info{MakeRuntimeInfo(programs, key, program, previous_stage, device)};
|
||||
ConvertLegacyToGeneric(program, runtime_info);
|
||||
const std::vector<u32> code{EmitSPIRV(profile, runtime_info, program, binding)};
|
||||
|
||||
Reference in New Issue
Block a user