summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/frontend/ir
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/frontend/ir')
-rw-r--r--src/shader_recompiler/frontend/ir/ir_emitter.cpp14
-rw-r--r--src/shader_recompiler/frontend/ir/microinstruction.h6
-rw-r--r--src/shader_recompiler/frontend/ir/modifiers.h5
-rw-r--r--src/shader_recompiler/frontend/ir/opcodes.inc1
-rw-r--r--src/shader_recompiler/frontend/ir/value.cpp14
-rw-r--r--src/shader_recompiler/frontend/ir/value.h1
6 files changed, 36 insertions, 5 deletions
diff --git a/src/shader_recompiler/frontend/ir/ir_emitter.cpp b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
index b365a8a6e..f49c30484 100644
--- a/src/shader_recompiler/frontend/ir/ir_emitter.cpp
+++ b/src/shader_recompiler/frontend/ir/ir_emitter.cpp
@@ -398,15 +398,16 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2) {
if (e1.Type() != e2.Type()) {
throw InvalidArgument("Mismatching types {} and {}", e1.Type(), e2.Type());
}
+ CompositeDecoration decor{};
switch (e1.Type()) {
case Type::U32:
- return Inst(Opcode::CompositeConstructU32x2, e1, e2);
+ return Inst(Opcode::CompositeConstructU32x2, Flags{decor}, e1, e2);
case Type::F16:
- return Inst(Opcode::CompositeConstructF16x2, e1, e2);
+ return Inst(Opcode::CompositeConstructF16x2, Flags{decor}, e1, e2);
case Type::F32:
- return Inst(Opcode::CompositeConstructF32x2, e1, e2);
+ return Inst(Opcode::CompositeConstructF32x2, Flags{decor}, e1, e2);
case Type::F64:
- return Inst(Opcode::CompositeConstructF64x2, e1, e2);
+ return Inst(Opcode::CompositeConstructF64x2, Flags{decor}, e1, e2);
default:
ThrowInvalidType(e1.Type());
}
@@ -436,6 +437,7 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Valu
throw InvalidArgument("Mismatching types {}, {}, {}, and {}", e1.Type(), e2.Type(),
e3.Type(), e4.Type());
}
+ CompositeDecoration decor{};
switch (e1.Type()) {
case Type::U32:
return Inst(Opcode::CompositeConstructU32x4, e1, e2, e3, e4);
@@ -445,6 +447,8 @@ Value IREmitter::CompositeConstruct(const Value& e1, const Value& e2, const Valu
return Inst(Opcode::CompositeConstructF32x4, e1, e2, e3, e4);
case Type::F64:
return Inst(Opcode::CompositeConstructF64x4, e1, e2, e3, e4);
+ case Type::U32x2:
+ return Inst(Opcode::CompositeConstructArrayU32x2, Flags{decor}, e1, e2, e3, e4);
default:
ThrowInvalidType(e1.Type());
}
@@ -1481,7 +1485,7 @@ Value IREmitter::ImageGather(const Value& handle, const Value& coords, const Val
}
Value IREmitter::ImageGatherDref(const Value& handle, const Value& coords, const Value& offset,
- const Value& offset2, const F32& dref, TextureInstInfo info) {
+ const Value& offset2, const F32& dref, TextureInstInfo info) {
const Opcode op{handle.IsImmediate() ? Opcode::BoundImageGatherDref
: Opcode::BindlessImageGatherDref};
return Inst(op, Flags{info}, handle, coords, offset, offset2, dref);
diff --git a/src/shader_recompiler/frontend/ir/microinstruction.h b/src/shader_recompiler/frontend/ir/microinstruction.h
index 770bbd550..77296cfa4 100644
--- a/src/shader_recompiler/frontend/ir/microinstruction.h
+++ b/src/shader_recompiler/frontend/ir/microinstruction.h
@@ -99,6 +99,12 @@ public:
return ret;
}
+ template <typename FlagsType>
+ requires(sizeof(FlagsType) <= sizeof(u32) && std::is_trivially_copyable_v<FlagsType>)
+ [[nodiscard]] void SetFlags(FlagsType& new_val) noexcept {
+ std::memcpy(&flags, &new_val, sizeof(new_val));
+ }
+
/// Intrusively store the host definition of this instruction.
template <typename DefinitionType>
void SetDefinition(DefinitionType def) {
diff --git a/src/shader_recompiler/frontend/ir/modifiers.h b/src/shader_recompiler/frontend/ir/modifiers.h
index 4f09a4b39..20fb14fea 100644
--- a/src/shader_recompiler/frontend/ir/modifiers.h
+++ b/src/shader_recompiler/frontend/ir/modifiers.h
@@ -32,6 +32,11 @@ struct FpControl {
};
static_assert(sizeof(FpControl) <= sizeof(u32));
+struct CompositeDecoration {
+ bool is_constant{false};
+};
+static_assert(sizeof(CompositeDecoration) <= sizeof(u32));
+
union TextureInstInfo {
u32 raw;
BitField<0, 8, TextureType> type;
diff --git a/src/shader_recompiler/frontend/ir/opcodes.inc b/src/shader_recompiler/frontend/ir/opcodes.inc
index 60a0bc980..0dc0aabdf 100644
--- a/src/shader_recompiler/frontend/ir/opcodes.inc
+++ b/src/shader_recompiler/frontend/ir/opcodes.inc
@@ -126,6 +126,7 @@ OPCODE(CompositeExtractF64x4, F64, F64x
OPCODE(CompositeInsertF64x2, F64x2, F64x2, F64, U32, )
OPCODE(CompositeInsertF64x3, F64x3, F64x3, F64, U32, )
OPCODE(CompositeInsertF64x4, F64x4, F64x4, F64, U32, )
+OPCODE(CompositeConstructArrayU32x2, Opaque, U32x2, U32x2, U32x2, U32x2, )
// Select operations
OPCODE(SelectU1, U1, U1, U1, U1, )
diff --git a/src/shader_recompiler/frontend/ir/value.cpp b/src/shader_recompiler/frontend/ir/value.cpp
index e8e4662e7..7671fc3d8 100644
--- a/src/shader_recompiler/frontend/ir/value.cpp
+++ b/src/shader_recompiler/frontend/ir/value.cpp
@@ -44,6 +44,20 @@ bool Value::IsEmpty() const noexcept {
return type == Type::Void;
}
+bool Value::IsConstantContainer() const {
+ if (IsImmediate()) {
+ return true;
+ }
+ ValidateAccess(Type::Opaque);
+ auto num_args = inst->NumArgs();
+ for (size_t i = 0; i < num_args; i++) {
+ if (!inst->Arg(i).IsConstantContainer()) {
+ return false;
+ }
+ }
+ return true;
+}
+
bool Value::IsImmediate() const noexcept {
if (IsIdentity()) {
return inst->Arg(0).IsImmediate();
diff --git a/src/shader_recompiler/frontend/ir/value.h b/src/shader_recompiler/frontend/ir/value.h
index b27601e70..5d6e74c14 100644
--- a/src/shader_recompiler/frontend/ir/value.h
+++ b/src/shader_recompiler/frontend/ir/value.h
@@ -38,6 +38,7 @@ public:
[[nodiscard]] bool IsImmediate() const noexcept;
[[nodiscard]] bool IsLabel() const noexcept;
[[nodiscard]] IR::Type Type() const noexcept;
+ [[nodiscard]] bool IsConstantContainer() const;
[[nodiscard]] IR::Inst* Inst() const;
[[nodiscard]] IR::Block* Label() const;