shader: Implement TLD4.PTP

This commit is contained in:
FernandoS27 2021-03-26 16:02:04 +01:00 committed by ameerj
parent 981eb6f43b
commit 742d11c2ad
15 changed files with 111 additions and 28 deletions

View file

@ -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);

View file

@ -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) {

View file

@ -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;

View file

@ -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, )

View file

@ -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();

View file

@ -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;

View file

@ -101,16 +101,18 @@ IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg& reg, TextureType type) {
switch (type) {
case TextureType::_1D:
case TextureType::ARRAY_1D:
return v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4));
return v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true);
case TextureType::_2D:
case TextureType::ARRAY_2D:
return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4)),
v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4)));
return v.ir.CompositeConstruct(
v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true),
v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4), true));
case TextureType::_3D:
case TextureType::ARRAY_3D:
return v.ir.CompositeConstruct(v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4)),
v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4)),
v.ir.BitFieldExtract(value, v.ir.Imm32(8), v.ir.Imm32(4)));
return v.ir.CompositeConstruct(
v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(4), true),
v.ir.BitFieldExtract(value, v.ir.Imm32(4), v.ir.Imm32(4), true),
v.ir.BitFieldExtract(value, v.ir.Imm32(8), v.ir.Imm32(4), true));
case TextureType::CUBE:
case TextureType::ARRAY_CUBE:
throw NotImplementedException("Illegal offset on CUBE sample");

View file

@ -106,17 +106,17 @@ IR::Value MakeOffset(TranslatorVisitor& v, IR::Reg& reg, TextureType type) {
throw NotImplementedException("Invalid texture type {}", type);
}
std::pair<IR::Value, IR::Value> MakeOffsetPTP(TranslatorVisitor& v, IR::Reg& reg) {
IR::Value MakeOffsetPTP(TranslatorVisitor& v, IR::Reg& reg) {
const IR::U32 value1{v.X(reg++)};
const IR::U32 value2{v.X(reg++)};
const auto getVector = ([&v](const IR::U32& value) {
const IR::U32 bitsize = v.ir.Imm32(6);
const auto getVector = ([&v, &bitsize](const IR::U32& value, u32 base) {
return v.ir.CompositeConstruct(
v.ir.BitFieldExtract(value, v.ir.Imm32(0), v.ir.Imm32(6), true),
v.ir.BitFieldExtract(value, v.ir.Imm32(8), v.ir.Imm32(6), true),
v.ir.BitFieldExtract(value, v.ir.Imm32(16), v.ir.Imm32(6), true),
v.ir.BitFieldExtract(value, v.ir.Imm32(24), v.ir.Imm32(6), true));
v.ir.BitFieldExtract(value, v.ir.Imm32(base + 0), bitsize, true),
v.ir.BitFieldExtract(value, v.ir.Imm32(base + 8), bitsize, true));
});
return {getVector(value1), getVector(value2)};
return v.ir.CompositeConstruct(getVector(value1, 0), getVector(value1, 16),
getVector(value2, 0), getVector(value2, 16));
}
void Impl(TranslatorVisitor& v, u64 insn, ComponentType component_type, OffsetType offset_type,
@ -155,7 +155,7 @@ void Impl(TranslatorVisitor& v, u64 insn, ComponentType component_type, OffsetTy
break;
}
case OffsetType::PTP: {
std::tie(offset, offset2) = MakeOffsetPTP(v, meta_reg);
offset2 = MakeOffsetPTP(v, meta_reg);
break;
}
default: