Merge branch 'master' of https://github.com/xenia-project/xenia into canary_experimental

This commit is contained in:
Gliniak
2023-09-01 18:20:29 +02:00
24 changed files with 1771 additions and 1184 deletions

View File

@@ -913,6 +913,8 @@ enum class OperandModifier : uint32_t {
struct Dest : OperandAddress {
// Ignored for 0-component and 1-component operand types.
// For 4-component operand types, if the write mask is 0, it's treated as
// 0-component.
uint32_t write_mask_;
// Input destinations (v*) are for use only in declarations. Vector input
@@ -1028,12 +1030,16 @@ struct Dest : OperandAddress {
void Write(std::vector<uint32_t>& code, bool in_dcl = false) const {
uint32_t operand_token = GetOperandTokenTypeAndIndex();
OperandDimension dimension = GetDimension(in_dcl);
operand_token |= uint32_t(dimension);
if (dimension == OperandDimension::kVector) {
assert_true(write_mask_ > 0b0000 && write_mask_ <= 0b1111);
operand_token |=
(uint32_t(ComponentSelection::kMask) << 2) | (write_mask_ << 4);
if (write_mask_) {
assert_true(write_mask_ <= 0b1111);
operand_token |=
(uint32_t(ComponentSelection::kMask) << 2) | (write_mask_ << 4);
} else {
dimension = OperandDimension::kNoData;
}
}
operand_token |= uint32_t(dimension);
code.push_back(operand_token);
OperandAddress::Write(code);
}
@@ -1508,6 +1514,8 @@ enum class Opcode : uint32_t {
kStoreUAVTyped = 164,
kLdRaw = 165,
kStoreRaw = 166,
kAtomicAnd = 169,
kAtomicOr = 170,
kEvalSampleIndex = 204,
kEvalCentroid = 205,
};
@@ -2396,6 +2404,14 @@ class Assembler {
++stat_.instruction_count;
++stat_.c_texture_store_instructions;
}
void OpAtomicAnd(const Dest& dest, const Src& address,
uint32_t address_components, const Src& value) {
EmitAtomicOp(Opcode::kAtomicAnd, dest, address, address_components, value);
}
void OpAtomicOr(const Dest& dest, const Src& address,
uint32_t address_components, const Src& value) {
EmitAtomicOp(Opcode::kAtomicOr, dest, address, address_components, value);
}
void OpEvalSampleIndex(const Dest& dest, const Src& value,
const Src& sample_index) {
uint32_t dest_write_mask = dest.GetMask();
@@ -2522,6 +2538,22 @@ class Assembler {
src1.Write(code_, true, 0b0000);
++stat_.instruction_count;
}
void EmitAtomicOp(Opcode opcode, const Dest& dest, const Src& address,
uint32_t address_components, const Src& value) {
// Atomic operations require a 0-component memory destination.
assert_zero(dest.GetMask());
uint32_t address_mask = (1 << address_components) - 1;
uint32_t operands_length = dest.GetLength() +
address.GetLength(address_mask) +
value.GetLength(0b0001);
code_.reserve(code_.size() + 1 + operands_length);
code_.push_back(OpcodeToken(opcode, operands_length));
dest.Write(code_);
address.Write(code_, true, address_mask);
value.Write(code_, true, 0b0001);
++stat_.instruction_count;
++stat_.c_interlocked_instructions;
}
std::vector<uint32_t>& code_;
Statistics& stat_;