summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler
diff options
context:
space:
mode:
authorFernando Sahmkow <fsahmkow27@gmail.com>2022-11-09 17:58:10 +0100
committerFernando Sahmkow <fsahmkow27@gmail.com>2023-01-01 22:43:57 +0100
commitaad0cbf024fb8077a9b375a093c60a7e2ab1db3d (patch)
tree8c6a86c92ed8cedbafb5f34dd9f72283eaaf4342 /src/shader_recompiler
parentMacroHLE: Add Index Buffer size estimation. (diff)
downloadyuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar.gz
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar.bz2
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar.lz
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar.xz
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.tar.zst
yuzu-aad0cbf024fb8077a9b375a093c60a7e2ab1db3d.zip
Diffstat (limited to '')
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp8
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp10
-rw-r--r--src/shader_recompiler/environment.h5
-rw-r--r--src/shader_recompiler/frontend/ir/attribute.cpp4
-rw-r--r--src/shader_recompiler/frontend/ir/attribute.h4
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp8
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.h2
-rw-r--r--src/shader_recompiler/frontend/maxwell/translate_program.cpp2
-rw-r--r--src/shader_recompiler/ir_opt/constant_propagation_pass.cpp45
-rw-r--r--src/shader_recompiler/ir_opt/passes.h2
-rw-r--r--src/shader_recompiler/shader_info.h5
-rw-r--r--src/shader_recompiler/varying_state.h2
12 files changed, 91 insertions, 6 deletions
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
index 73b67f0af..e4802bf9e 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp
@@ -339,6 +339,10 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, Id vertex) {
const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_vertex)};
return ctx.OpBitcast(ctx.F32[1], ctx.OpISub(ctx.U32[1], index, base));
}
+ case IR::Attribute::BaseInstance:
+ return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_instance));
+ case IR::Attribute::BaseVertex:
+ return ctx.OpBitcast(ctx.F32[1], ctx.OpLoad(ctx.U32[1], ctx.base_vertex));
case IR::Attribute::FrontFace:
return ctx.OpSelect(ctx.F32[1], ctx.OpLoad(ctx.U1, ctx.front_face),
ctx.OpBitcast(ctx.F32[1], ctx.Const(std::numeric_limits<u32>::max())),
@@ -380,6 +384,10 @@ Id EmitGetAttributeU32(EmitContext& ctx, IR::Attribute attr, Id) {
const Id base{ctx.OpLoad(ctx.U32[1], ctx.base_vertex)};
return ctx.OpISub(ctx.U32[1], index, base);
}
+ case IR::Attribute::BaseInstance:
+ return ctx.OpLoad(ctx.U32[1], ctx.base_instance);
+ case IR::Attribute::BaseVertex:
+ return ctx.OpLoad(ctx.U32[1], ctx.base_vertex);
default:
throw NotImplementedException("Read U32 attribute {}", attr);
}
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
index 41dc6d031..563a5fc49 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
@@ -1379,18 +1379,28 @@ void EmitContext::DefineInputs(const IR::Program& program) {
if (loads[IR::Attribute::InstanceId]) {
if (profile.support_vertex_instance_id) {
instance_id = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceId);
+ if (loads[IR::Attribute::BaseInstance]) {
+ base_instance = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseVertex);
+ }
} else {
instance_index = DefineInput(*this, U32[1], true, spv::BuiltIn::InstanceIndex);
base_instance = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseInstance);
}
+ } else if (loads[IR::Attribute::BaseInstance]) {
+ base_instance = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseInstance);
}
if (loads[IR::Attribute::VertexId]) {
if (profile.support_vertex_instance_id) {
vertex_id = DefineInput(*this, U32[1], true, spv::BuiltIn::VertexId);
+ if (loads[IR::Attribute::BaseVertex]) {
+ base_vertex = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseVertex);
+ }
} else {
vertex_index = DefineInput(*this, U32[1], true, spv::BuiltIn::VertexIndex);
base_vertex = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseVertex);
}
+ } else if (loads[IR::Attribute::BaseVertex]) {
+ base_vertex = DefineInput(*this, U32[1], true, spv::BuiltIn::BaseVertex);
}
if (loads[IR::Attribute::FrontFace]) {
front_face = DefineInput(*this, U1, true, spv::BuiltIn::FrontFacing);
diff --git a/src/shader_recompiler/environment.h b/src/shader_recompiler/environment.h
index 402f2664f..b9b4455f6 100644
--- a/src/shader_recompiler/environment.h
+++ b/src/shader_recompiler/environment.h
@@ -34,6 +34,11 @@ public:
[[nodiscard]] virtual std::array<u32, 3> WorkgroupSize() const = 0;
+ [[nodiscard]] virtual bool HasHLEMacroState() const = 0;
+
+ [[nodiscard]] virtual std::optional<ReplaceConstant> GetReplaceConstBuffer(
+ u32 bank, u32 offset) = 0;
+
virtual void Dump(u64 hash) = 0;
[[nodiscard]] const ProgramHeader& SPH() const noexcept {
diff --git a/src/shader_recompiler/frontend/ir/attribute.cpp b/src/shader_recompiler/frontend/ir/attribute.cpp
index 7d3d882e4..73e189a89 100644
--- a/src/shader_recompiler/frontend/ir/attribute.cpp
+++ b/src/shader_recompiler/frontend/ir/attribute.cpp
@@ -446,6 +446,10 @@ std::string NameOf(Attribute attribute) {
return "ViewportMask";
case Attribute::FrontFace:
return "FrontFace";
+ case Attribute::BaseInstance:
+ return "BaseInstance";
+ case Attribute::BaseVertex:
+ return "BaseVertex";
}
return fmt::format("<reserved attribute {}>", static_cast<int>(attribute));
}
diff --git a/src/shader_recompiler/frontend/ir/attribute.h b/src/shader_recompiler/frontend/ir/attribute.h
index 6ee3947b1..364d8a912 100644
--- a/src/shader_recompiler/frontend/ir/attribute.h
+++ b/src/shader_recompiler/frontend/ir/attribute.h
@@ -219,6 +219,10 @@ enum class Attribute : u64 {
FixedFncTexture9Q = 231,
ViewportMask = 232,
FrontFace = 255,
+
+ // Implementation attributes
+ BaseInstance = 256,
+ BaseVertex = 257,
};
constexpr size_t NUM_GENERICS = 32;
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index 0cdac0eff..eb2e49a68 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -294,6 +294,14 @@ F32 IREmitter::GetAttribute(IR::Attribute attribute, const U32& vertex) {
return Inst<F32>(Opcode::GetAttribute, attribute, vertex);
}
+U32 IREmitter::GetAttributeU32(IR::Attribute attribute) {
+ return GetAttributeU32(attribute, Imm32(0));
+}
+
+U32 IREmitter::GetAttributeU32(IR::Attribute attribute, const U32& vertex) {
+ return Inst<U32>(Opcode::GetAttributeU32, attribute, vertex);
+}
+
void IREmitter::SetAttribute(IR::Attribute attribute, const F32& value, const U32& vertex) {
Inst(Opcode::SetAttribute, attribute, value, vertex);
}
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.h b/src/shader_recompiler/frontend/ir/ir_emitter.h
index 2df992feb..7aaaa4ab0 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.h
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.h
@@ -74,6 +74,8 @@ public:
[[nodiscard]] F32 GetAttribute(IR::Attribute attribute);
[[nodiscard]] F32 GetAttribute(IR::Attribute attribute, const U32& vertex);
+ [[nodiscard]] U32 GetAttributeU32(IR::Attribute attribute);
+ [[nodiscard]] U32 GetAttributeU32(IR::Attribute attribute, const U32& vertex);
void SetAttribute(IR::Attribute attribute, const F32& value, const U32& vertex);
[[nodiscard]] F32 GetAttributeIndexed(const U32& phys_address);
diff --git a/src/shader_recompiler/frontend/maxwell/translate_program.cpp b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
index 3adbd2b16..ac159d24b 100644
--- a/src/shader_recompiler/frontend/maxwell/translate_program.cpp
+++ b/src/shader_recompiler/frontend/maxwell/translate_program.cpp
@@ -219,7 +219,7 @@ IR::Program TranslateProgram(ObjectPool<IR::Inst>& inst_pool, ObjectPool<IR::Blo
}
Optimization::SsaRewritePass(program);
- Optimization::ConstantPropagationPass(program);
+ Optimization::ConstantPropagationPass(env, program);
Optimization::PositionPass(env, program);
diff --git a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
index 826f9a54a..ac10405f3 100644
--- a/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
+++ b/src/shader_recompiler/ir_opt/constant_propagation_pass.cpp
@@ -7,6 +7,7 @@
#include <type_traits>
#include "common/bit_cast.h"
+#include "shader_recompiler/environment.h"
#include "shader_recompiler/exception.h"
#include "shader_recompiler/frontend/ir/ir_emitter.h"
#include "shader_recompiler/frontend/ir/value.h"
@@ -515,6 +516,8 @@ void FoldBitCast(IR::Inst& inst, IR::Opcode reverse) {
case IR::Attribute::PrimitiveId:
case IR::Attribute::InstanceId:
case IR::Attribute::VertexId:
+ case IR::Attribute::BaseVertex:
+ case IR::Attribute::BaseInstance:
break;
default:
return;
@@ -644,7 +647,37 @@ void FoldFSwizzleAdd(IR::Block& block, IR::Inst& inst) {
}
}
-void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
+void FoldConstBuffer(Environment& env, IR::Block& block, IR::Inst& inst) {
+ 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();
+ const auto offset_value = offset.U32();
+ auto replacement = env.GetReplaceConstBuffer(bank_value, offset_value);
+ if (!replacement) {
+ return;
+ }
+ const auto new_attribute = [replacement]() {
+ switch (*replacement) {
+ case ReplaceConstant::BaseInstance:
+ return IR::Attribute::BaseInstance;
+ case ReplaceConstant::BaseVertex:
+ return IR::Attribute::BaseVertex;
+ default:
+ throw NotImplementedException("Not implemented replacement variable {}", *replacement);
+ }
+ }();
+ IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
+ if (inst.GetOpcode() == IR::Opcode::GetCbufU32) {
+ inst.ReplaceUsesWith(ir.GetAttributeU32(new_attribute));
+ } else {
+ inst.ReplaceUsesWith(ir.GetAttribute(new_attribute));
+ }
+}
+
+void ConstantPropagation(Environment& env, IR::Block& block, IR::Inst& inst) {
switch (inst.GetOpcode()) {
case IR::Opcode::GetRegister:
return FoldGetRegister(inst);
@@ -789,18 +822,24 @@ void ConstantPropagation(IR::Block& block, IR::Inst& inst) {
IR::Opcode::CompositeInsertF16x4);
case IR::Opcode::FSwizzleAdd:
return FoldFSwizzleAdd(block, inst);
+ case IR::Opcode::GetCbufF32:
+ case IR::Opcode::GetCbufU32:
+ if (env.HasHLEMacroState()) {
+ return FoldConstBuffer(env, block, inst);
+ }
+ break;
default:
break;
}
}
} // Anonymous namespace
-void ConstantPropagationPass(IR::Program& program) {
+void ConstantPropagationPass(Environment& env, IR::Program& program) {
const auto end{program.post_order_blocks.rend()};
for (auto it = program.post_order_blocks.rbegin(); it != end; ++it) {
IR::Block* const block{*it};
for (IR::Inst& inst : block->Instructions()) {
- ConstantPropagation(*block, inst);
+ ConstantPropagation(env, *block, inst);
}
}
}
diff --git a/src/shader_recompiler/ir_opt/passes.h b/src/shader_recompiler/ir_opt/passes.h
index 11bfe801a..1f8f2ba95 100644
--- a/src/shader_recompiler/ir_opt/passes.h
+++ b/src/shader_recompiler/ir_opt/passes.h
@@ -13,7 +13,7 @@ struct HostTranslateInfo;
namespace Shader::Optimization {
void CollectShaderInfoPass(Environment& env, IR::Program& program);
-void ConstantPropagationPass(IR::Program& program);
+void ConstantPropagationPass(Environment& env, IR::Program& program);
void DeadCodeEliminationPass(IR::Program& program);
void GlobalMemoryToStorageBufferPass(IR::Program& program);
void IdentityRemovalPass(IR::Program& program);
diff --git a/src/shader_recompiler/shader_info.h b/src/shader_recompiler/shader_info.h
index d9c6e92db..ea0f48344 100644
--- a/src/shader_recompiler/shader_info.h
+++ b/src/shader_recompiler/shader_info.h
@@ -16,6 +16,11 @@
namespace Shader {
+enum class ReplaceConstant : u32 {
+ BaseInstance,
+ BaseVertex,
+};
+
enum class TextureType : u32 {
Color1D,
ColorArray1D,
diff --git a/src/shader_recompiler/varying_state.h b/src/shader_recompiler/varying_state.h
index 7b28a285f..18a9aaf50 100644
--- a/src/shader_recompiler/varying_state.h
+++ b/src/shader_recompiler/varying_state.h
@@ -11,7 +11,7 @@
namespace Shader {
struct VaryingState {
- std::bitset<256> mask{};
+ std::bitset<512> mask{};
void Set(IR::Attribute attribute, bool state = true) {
mask[static_cast<size_t>(attribute)] = state;