summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler')
-rw-r--r--src/shader_recompiler/environment.h5
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp30
2 files changed, 34 insertions, 1 deletions
diff --git a/src/shader_recompiler/environment.h b/src/shader_recompiler/environment.h
index 8fc359126..26e8307c1 100644
--- a/src/shader_recompiler/environment.h
+++ b/src/shader_recompiler/environment.h
@@ -57,11 +57,16 @@ public:
return start_address;
}
+ [[nodiscard]] bool IsPropietaryDriver() const noexcept {
+ return is_propietary_driver;
+ }
+
protected:
ProgramHeader sph{};
std::array<u32, 8> gp_passthrough_mask{};
Stage stage{};
u32 start_address{};
+ bool is_propietary_driver{};
};
} // namespace Shader
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index ac10405f3..5275b2c8b 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -677,6 +677,30 @@ void FoldConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst) {
}
}
+void FoldDriverConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst, u32 which_bank,
+ u32 offset_start = 0, u32 offset_end = std::numeric_limits<u16>::max()) {
+ const IR::Value bank{inst.Arg(0)};
+ const IR::Value offset{inst.Arg(1)};
+ if (!bank.IsImmediate() || !offset.IsImmediate()) {
+ return;
+ }
+ const auto bank_value = bank.U32();
+ if (bank_value != which_bank) {
+ return;
+ }
+ const auto offset_value = offset.U32();
+ if (offset_value < offset_start || offset_value >= offset_end) {
+ return;
+ }
+ IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
+ if (inst.GetOpcode() == IR::Opcode::GetCbufU32) {
+ inst.ReplaceUsesWith(IR::Value{env.ReadCbufValue(bank_value, offset_value)});
+ } else {
+ inst.ReplaceUsesWith(
+ IR::Value{Common::BitCast<f32>(env.ReadCbufValue(bank_value, offset_value))});
+ }
+}
+
void ConstantPropagation(Environment& env, IR::Block& block, IR::Inst& inst) {
switch (inst.GetOpcode()) {
case IR::Opcode::GetRegister:
@@ -825,13 +849,17 @@ void ConstantPropagation(Environment& env, IR::Block& block, IR::Inst& inst) {
case IR::Opcode::GetCbufF32:
case IR::Opcode::GetCbufU32:
if (env.HasHLEMacroState()) {
- return FoldConstBuffer(env, block, inst);
+ FoldConstBuffer(env, block, inst);
+ }
+ if (env.IsPropietaryDriver()) {
+ FoldDriverConstBuffer(env, block, inst, 1);
}
break;
default:
break;
}
}
+
} // Anonymous namespace
void ConstantPropagationPass(Environment& env, IR::Program& program) {