summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp47
-rw-r--r--src/shader_recompiler/runtime_info.h2
-rw-r--r--src/shader_recompiler/shader_info.h3
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp1
5 files changed, 35 insertions, 19 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index 77efb4f57..b58741d4d 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -137,28 +137,35 @@ bool IsLegacyAttribute(IR::Attribute attribute) {
}
std::map<IR::Attribute, IR::Attribute> GenerateLegacyToGenericMappings(
- const VaryingState& state, std::queue<IR::Attribute> ununsed_generics) {
+ const VaryingState& state, std::queue<IR::Attribute> unused_generics,
+ const std::map<IR::Attribute, IR::Attribute>& previous_stage_mapping) {
std::map<IR::Attribute, IR::Attribute> mapping;
+ auto update_mapping = [&mapping, &unused_generics, previous_stage_mapping](IR::Attribute attr,
+ size_t count) {
+ if (previous_stage_mapping.find(attr) != previous_stage_mapping.end()) {
+ for (size_t i = 0; i < count; ++i) {
+ mapping.insert({attr + i, previous_stage_mapping.at(attr + i)});
+ }
+ } else {
+ for (size_t i = 0; i < count; ++i) {
+ mapping.insert({attr + i, unused_generics.front() + i});
+ }
+ unused_generics.pop();
+ }
+ };
for (size_t index = 0; index < 4; ++index) {
auto attr = IR::Attribute::ColorFrontDiffuseR + index * 4;
if (state.AnyComponent(attr)) {
- for (size_t i = 0; i < 4; ++i) {
- mapping.insert({attr + i, ununsed_generics.front() + i});
- }
- ununsed_generics.pop();
+ update_mapping(attr, 4);
}
}
if (state[IR::Attribute::FogCoordinate]) {
- mapping.insert({IR::Attribute::FogCoordinate, ununsed_generics.front()});
- ununsed_generics.pop();
+ update_mapping(IR::Attribute::FogCoordinate, 1);
}
for (size_t index = 0; index < IR::NUM_FIXEDFNCTEXTURE; ++index) {
auto attr = IR::Attribute::FixedFncTexture0S + index * 4;
if (state.AnyComponent(attr)) {
- for (size_t i = 0; i < 4; ++i) {
- mapping.insert({attr + i, ununsed_generics.front() + i});
- }
- ununsed_generics.pop();
+ update_mapping(attr, 4);
}
}
return mapping;
@@ -265,21 +272,22 @@ IR::Program MergeDualVertexPrograms(IR::Program& vertex_a, IR::Program& vertex_b
void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& runtime_info) {
auto& stores = program.info.stores;
if (stores.Legacy()) {
- std::queue<IR::Attribute> ununsed_output_generics{};
+ std::queue<IR::Attribute> unused_output_generics{};
for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
if (!stores.Generic(index)) {
- ununsed_output_generics.push(IR::Attribute::Generic0X + index * 4);
+ unused_output_generics.push(IR::Attribute::Generic0X + index * 4);
}
}
- auto mappings = GenerateLegacyToGenericMappings(stores, ununsed_output_generics);
+ program.info.legacy_stores_mapping =
+ GenerateLegacyToGenericMappings(stores, unused_output_generics, {});
for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) {
switch (inst.GetOpcode()) {
case IR::Opcode::SetAttribute: {
const auto attr = inst.Arg(0).Attribute();
if (IsLegacyAttribute(attr)) {
- stores.Set(mappings[attr], true);
- inst.SetArg(0, Shader::IR::Value(mappings[attr]));
+ stores.Set(program.info.legacy_stores_mapping[attr], true);
+ inst.SetArg(0, Shader::IR::Value(program.info.legacy_stores_mapping[attr]));
}
break;
}
@@ -292,15 +300,16 @@ void ConvertLegacyToGeneric(IR::Program& program, const Shader::RuntimeInfo& run
auto& loads = program.info.loads;
if (loads.Legacy()) {
- std::queue<IR::Attribute> ununsed_input_generics{};
+ std::queue<IR::Attribute> unused_input_generics{};
for (size_t index = 0; index < IR::NUM_GENERICS; ++index) {
const AttributeType input_type{runtime_info.generic_input_types[index]};
if (!runtime_info.previous_stage_stores.Generic(index) || !loads.Generic(index) ||
input_type == AttributeType::Disabled) {
- ununsed_input_generics.push(IR::Attribute::Generic0X + index * 4);
+ unused_input_generics.push(IR::Attribute::Generic0X + index * 4);
}
}
- auto mappings = GenerateLegacyToGenericMappings(loads, ununsed_input_generics);
+ auto mappings = GenerateLegacyToGenericMappings(
+ loads, unused_input_generics, runtime_info.previous_stage_legacy_stores_mapping);
for (IR::Block* const block : program.post_order_blocks) {
for (IR::Inst& inst : block->Instructions()) {
switch (inst.GetOpcode()) {
diff --git a/src/shader_recompiler/runtime_info.h b/src/shader_recompiler/runtime_info.h
index dcb5ab158..549b81ef7 100644
--- a/src/shader_recompiler/runtime_info.h
+++ b/src/shader_recompiler/runtime_info.h
@@ -4,6 +4,7 @@
#pragma once
#include <array>
+#include <map>
#include <optional>
#include <vector>
@@ -60,6 +61,7 @@ struct TransformFeedbackVarying {
struct RuntimeInfo {
std::array<AttributeType, 32> generic_input_types{};
VaryingState previous_stage_stores;
+ std::map<IR::Attribute, IR::Attribute> previous_stage_legacy_stores_mapping;
bool convert_depth_mode{};
bool force_early_z{};
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index cc596da4f..81097bf1a 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -5,6 +5,7 @@
#include <array>
#include <bitset>
+#include <map>
#include "common/common_types.h"
#include "shader_recompiler/frontend/ir/type.h"
@@ -127,6 +128,8 @@ struct Info {
VaryingState stores;
VaryingState passthrough;
+ std::map<IR::Attribute, IR::Attribute> legacy_stores_mapping;
+
bool loads_indexed_attributes{};
std::array<bool, 8> stores_frag_color{};
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 609f0a772..e94cfdb1a 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -63,6 +63,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(const GraphicsPipelineKey& key,
Shader::RuntimeInfo info;
if (previous_program) {
info.previous_stage_stores = previous_program->info.stores;
+ info.previous_stage_legacy_stores_mapping = previous_program->info.legacy_stores_mapping;
} else {
// Mark all stores as available for vertex shaders
info.previous_stage_stores.mask.set();
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 20f1d6584..13d5a1f67 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -134,6 +134,7 @@ Shader::RuntimeInfo MakeRuntimeInfo(std::span<const Shader::IR::Program> program
Shader::RuntimeInfo info;
if (previous_program) {
info.previous_stage_stores = previous_program->info.stores;
+ info.previous_stage_legacy_stores_mapping = previous_program->info.legacy_stores_mapping;
if (previous_program->is_geometry_passthrough) {
info.previous_stage_stores.mask |= previous_program->info.passthrough.mask;
}