[GPU] Fix scalar c[#+aL], shader docs/refactoring

This commit is contained in:
Triang3l
2022-04-13 23:08:19 +03:00
parent 1f324bebcd
commit fea430f1f9
6 changed files with 395 additions and 201 deletions

View File

@@ -247,22 +247,18 @@ void Shader::GatherExecInformation(
if (sequence & 0b10) {
ucode_disasm_buffer.Append(" serialize\n ");
}
const uint32_t* op_ptr = ucode_data_.data() + instr_offset * 3;
if (sequence & 0b01) {
auto fetch_opcode = FetchOpcode(ucode_data_[instr_offset * 3] & 0x1F);
if (fetch_opcode == FetchOpcode::kVertexFetch) {
auto& op = *reinterpret_cast<const VertexFetchInstruction*>(
ucode_data_.data() + instr_offset * 3);
GatherVertexFetchInformation(op, previous_vfetch_full,
auto& op = *reinterpret_cast<const FetchInstruction*>(op_ptr);
if (op.opcode() == FetchOpcode::kVertexFetch) {
GatherVertexFetchInformation(op.vertex_fetch(), previous_vfetch_full,
ucode_disasm_buffer);
} else {
auto& op = *reinterpret_cast<const TextureFetchInstruction*>(
ucode_data_.data() + instr_offset * 3);
GatherTextureFetchInformation(op, unique_texture_bindings,
ucode_disasm_buffer);
GatherTextureFetchInformation(
op.texture_fetch(), unique_texture_bindings, ucode_disasm_buffer);
}
} else {
auto& op = *reinterpret_cast<const AluInstruction*>(ucode_data_.data() +
instr_offset * 3);
auto& op = *reinterpret_cast<const AluInstruction*>(op_ptr);
GatherAluInstructionInformation(op, memexport_alloc_current_count,
memexport_eA_written,
ucode_disasm_buffer);
@@ -420,7 +416,7 @@ void Shader::GatherOperandInformation(const InstructionOperand& operand) {
switch (operand.storage_source) {
case InstructionStorageSource::kRegister:
if (operand.storage_addressing_mode ==
InstructionStorageAddressingMode::kStatic) {
InstructionStorageAddressingMode::kAbsolute) {
register_static_address_bound_ =
std::max(register_static_address_bound_,
operand.storage_index + uint32_t(1));
@@ -430,7 +426,7 @@ void Shader::GatherOperandInformation(const InstructionOperand& operand) {
break;
case InstructionStorageSource::kConstantFloat:
if (operand.storage_addressing_mode ==
InstructionStorageAddressingMode::kStatic) {
InstructionStorageAddressingMode::kAbsolute) {
// Store used float constants before translating so the
// translator can use tightly packed indices if not dynamically
// indexed.
@@ -457,7 +453,7 @@ void Shader::GatherFetchResultInformation(const InstructionResult& result) {
// operand.
assert_true(result.storage_target == InstructionStorageTarget::kRegister);
if (result.storage_addressing_mode ==
InstructionStorageAddressingMode::kStatic) {
InstructionStorageAddressingMode::kAbsolute) {
register_static_address_bound_ = std::max(
register_static_address_bound_, result.storage_index + uint32_t(1));
} else {
@@ -473,7 +469,7 @@ void Shader::GatherAluResultInformation(
switch (result.storage_target) {
case InstructionStorageTarget::kRegister:
if (result.storage_addressing_mode ==
InstructionStorageAddressingMode::kStatic) {
InstructionStorageAddressingMode::kAbsolute) {
register_static_address_bound_ = std::max(
register_static_address_bound_, result.storage_index + uint32_t(1));
} else {
@@ -789,28 +785,24 @@ void ShaderTranslator::TranslateExecInstructions(
for (uint32_t instr_offset = instr.instruction_address;
instr_offset < instr.instruction_address + instr.instruction_count;
++instr_offset, sequence >>= 2) {
const uint32_t* op_ptr = ucode_dwords + instr_offset * 3;
if (sequence & 0b01) {
auto fetch_opcode =
static_cast<FetchOpcode>(ucode_dwords[instr_offset * 3] & 0x1F);
if (fetch_opcode == FetchOpcode::kVertexFetch) {
auto& op = *reinterpret_cast<const VertexFetchInstruction*>(
ucode_dwords + instr_offset * 3);
auto& op = *reinterpret_cast<const FetchInstruction*>(op_ptr);
if (op.opcode() == FetchOpcode::kVertexFetch) {
const VertexFetchInstruction& vfetch_op = op.vertex_fetch();
ParsedVertexFetchInstruction vfetch_instr;
if (ParseVertexFetchInstruction(op, previous_vfetch_full_,
if (ParseVertexFetchInstruction(vfetch_op, previous_vfetch_full_,
vfetch_instr)) {
previous_vfetch_full_ = op;
previous_vfetch_full_ = vfetch_op;
}
ProcessVertexFetchInstruction(vfetch_instr);
} else {
auto& op = *reinterpret_cast<const TextureFetchInstruction*>(
ucode_dwords + instr_offset * 3);
ParsedTextureFetchInstruction tfetch_instr;
ParseTextureFetchInstruction(op, tfetch_instr);
ParseTextureFetchInstruction(op.texture_fetch(), tfetch_instr);
ProcessTextureFetchInstruction(tfetch_instr);
}
} else {
auto& op = *reinterpret_cast<const AluInstruction*>(ucode_dwords +
instr_offset * 3);
auto& op = *reinterpret_cast<const AluInstruction*>(op_ptr);
ParsedAluInstruction alu_instr;
ParseAluInstruction(op, current_shader().type(), alu_instr);
ProcessAluInstruction(alu_instr);
@@ -826,25 +818,40 @@ static void ParseFetchInstructionResult(uint32_t dest, uint32_t swizzle,
result.storage_index = dest;
result.is_clamped = false;
result.storage_addressing_mode =
is_relative ? InstructionStorageAddressingMode::kAddressRelative
: InstructionStorageAddressingMode::kStatic;
is_relative ? InstructionStorageAddressingMode::kLoopRelative
: InstructionStorageAddressingMode::kAbsolute;
result.original_write_mask = 0b1111;
for (int i = 0; i < 4; ++i) {
switch (swizzle & 0x7) {
case 4:
case 6:
result.components[i] = SwizzleSource::k0;
SwizzleSource component_source = SwizzleSource::k0;
ucode::FetchDestinationSwizzle component_swizzle =
ucode::GetFetchDestinationComponentSwizzle(swizzle, i);
switch (component_swizzle) {
case ucode::FetchDestinationSwizzle::kX:
component_source = SwizzleSource::kX;
break;
case 5:
result.components[i] = SwizzleSource::k1;
case ucode::FetchDestinationSwizzle::kY:
component_source = SwizzleSource::kY;
break;
case 7:
result.original_write_mask &= ~uint32_t(1 << i);
case ucode::FetchDestinationSwizzle::kZ:
component_source = SwizzleSource::kZ;
break;
case ucode::FetchDestinationSwizzle::kW:
component_source = SwizzleSource::kW;
break;
case ucode::FetchDestinationSwizzle::k1:
component_source = SwizzleSource::k1;
break;
case ucode::FetchDestinationSwizzle::kKeep:
result.original_write_mask &= ~(UINT32_C(1) << i);
break;
default:
result.components[i] = GetSwizzleFromComponentIndex(swizzle & 0x3);
// ucode::FetchDestinationSwizzle::k0 or the invalid swizzle 6.
// TODO(Triang3l): Find the correct handling of the invalid swizzle 6.
assert_true(component_swizzle == ucode::FetchDestinationSwizzle::k0);
component_source = SwizzleSource::k0;
break;
}
swizzle >>= 3;
result.components[i] = component_source;
}
}
@@ -867,8 +874,8 @@ bool ParseVertexFetchInstruction(const VertexFetchInstruction& op,
src_op.storage_index = full_op.src();
src_op.storage_addressing_mode =
full_op.is_src_relative()
? InstructionStorageAddressingMode::kAddressRelative
: InstructionStorageAddressingMode::kStatic;
? InstructionStorageAddressingMode::kLoopRelative
: InstructionStorageAddressingMode::kAbsolute;
src_op.is_negated = false;
src_op.is_absolute_value = false;
src_op.component_count = 1;
@@ -962,8 +969,8 @@ void ParseTextureFetchInstruction(const TextureFetchInstruction& op,
src_op.storage_source = InstructionStorageSource::kRegister;
src_op.storage_index = op.src();
src_op.storage_addressing_mode =
op.is_src_relative() ? InstructionStorageAddressingMode::kAddressRelative
: InstructionStorageAddressingMode::kStatic;
op.is_src_relative() ? InstructionStorageAddressingMode::kLoopRelative
: InstructionStorageAddressingMode::kAbsolute;
src_op.is_negated = false;
src_op.is_absolute_value = false;
src_op.component_count =
@@ -1144,91 +1151,51 @@ static const AluOpcodeInfo alu_scalar_opcode_infos[0x40] = {
static void ParseAluInstructionOperand(const AluInstruction& op, uint32_t i,
uint32_t swizzle_component_count,
InstructionOperand& out_op) {
int const_slot = 0;
switch (i) {
case 2:
const_slot = op.src_is_temp(1) ? 0 : 1;
break;
case 3:
const_slot = op.src_is_temp(1) && op.src_is_temp(2) ? 0 : 1;
break;
}
out_op.is_negated = op.src_negate(i);
uint32_t reg = op.src_reg(i);
if (op.src_is_temp(i)) {
out_op.storage_source = InstructionStorageSource::kRegister;
out_op.storage_index = reg & 0x1F;
out_op.is_absolute_value = (reg & 0x80) == 0x80;
out_op.storage_index = AluInstruction::src_temp_reg(reg);
out_op.is_absolute_value = AluInstruction::is_src_temp_value_absolute(reg);
out_op.storage_addressing_mode =
(reg & 0x40) ? InstructionStorageAddressingMode::kAddressRelative
: InstructionStorageAddressingMode::kStatic;
AluInstruction::is_src_temp_relative(reg)
? InstructionStorageAddressingMode::kLoopRelative
: InstructionStorageAddressingMode::kAbsolute;
} else {
out_op.storage_source = InstructionStorageSource::kConstantFloat;
out_op.storage_index = reg;
if ((const_slot == 0 && op.is_const_0_addressed()) ||
(const_slot == 1 && op.is_const_1_addressed())) {
if (op.is_address_relative()) {
if (op.src_const_is_addressed(i)) {
if (op.is_const_address_register_relative()) {
out_op.storage_addressing_mode =
InstructionStorageAddressingMode::kAddressAbsolute;
InstructionStorageAddressingMode::kAddressRegisterRelative;
} else {
out_op.storage_addressing_mode =
InstructionStorageAddressingMode::kAddressRelative;
InstructionStorageAddressingMode::kLoopRelative;
}
} else {
out_op.storage_addressing_mode =
InstructionStorageAddressingMode::kStatic;
InstructionStorageAddressingMode::kAbsolute;
}
out_op.is_absolute_value = op.abs_constants();
}
out_op.component_count = swizzle_component_count;
uint32_t swizzle = op.src_swizzle(i);
if (swizzle_component_count == 1) {
uint32_t a = ((swizzle >> 6) + 3) & 0x3;
out_op.components[0] = GetSwizzleFromComponentIndex(a);
// Scalar `a` (W).
out_op.components[0] = GetSwizzledAluSourceComponent(swizzle, 3);
} else if (swizzle_component_count == 2) {
uint32_t a = ((swizzle >> 6) + 3) & 0x3;
uint32_t b = ((swizzle >> 0) + 0) & 0x3;
out_op.components[0] = GetSwizzleFromComponentIndex(a);
out_op.components[1] = GetSwizzleFromComponentIndex(b);
// Scalar left-hand `a` (W) and right-hand `b` (X).
out_op.components[0] = GetSwizzledAluSourceComponent(swizzle, 3);
out_op.components[1] = GetSwizzledAluSourceComponent(swizzle, 0);
} else if (swizzle_component_count == 3) {
assert_always();
} else if (swizzle_component_count == 4) {
for (uint32_t j = 0; j < swizzle_component_count; ++j, swizzle >>= 2) {
out_op.components[j] = GetSwizzleFromComponentIndex((swizzle + j) & 0x3);
for (uint32_t j = 0; j < swizzle_component_count; ++j) {
out_op.components[j] = GetSwizzledAluSourceComponent(swizzle, j);
}
}
}
static void ParseAluInstructionOperandSpecial(
const AluInstruction& op, InstructionStorageSource storage_source,
uint32_t reg, bool negate, int const_slot, uint32_t component_index,
InstructionOperand& out_op) {
out_op.is_negated = negate;
out_op.is_absolute_value = op.abs_constants();
out_op.storage_source = storage_source;
if (storage_source == InstructionStorageSource::kRegister) {
out_op.storage_index = reg & 0x7F;
out_op.storage_addressing_mode = InstructionStorageAddressingMode::kStatic;
} else {
out_op.storage_index = reg;
if ((const_slot == 0 && op.is_const_0_addressed()) ||
(const_slot == 1 && op.is_const_1_addressed())) {
if (op.is_address_relative()) {
out_op.storage_addressing_mode =
InstructionStorageAddressingMode::kAddressAbsolute;
} else {
out_op.storage_addressing_mode =
InstructionStorageAddressingMode::kAddressRelative;
}
} else {
out_op.storage_addressing_mode =
InstructionStorageAddressingMode::kStatic;
}
}
out_op.component_count = 1;
out_op.components[0] = GetSwizzleFromComponentIndex(component_index);
}
bool ParsedAluInstruction::IsVectorOpDefaultNop() const {
if (vector_opcode != ucode::AluVectorOpcode::kMax ||
vector_and_constant_result.original_write_mask ||
@@ -1237,14 +1204,14 @@ bool ParsedAluInstruction::IsVectorOpDefaultNop() const {
InstructionStorageSource::kRegister ||
vector_operands[0].storage_index != 0 ||
vector_operands[0].storage_addressing_mode !=
InstructionStorageAddressingMode::kStatic ||
InstructionStorageAddressingMode::kAbsolute ||
vector_operands[0].is_negated || vector_operands[0].is_absolute_value ||
!vector_operands[0].IsStandardSwizzle() ||
vector_operands[1].storage_source !=
InstructionStorageSource::kRegister ||
vector_operands[1].storage_index != 0 ||
vector_operands[1].storage_addressing_mode !=
InstructionStorageAddressingMode::kStatic ||
InstructionStorageAddressingMode::kAbsolute ||
vector_operands[1].is_negated || vector_operands[1].is_absolute_value ||
!vector_operands[1].IsStandardSwizzle()) {
return false;
@@ -1253,7 +1220,7 @@ bool ParsedAluInstruction::IsVectorOpDefaultNop() const {
InstructionStorageTarget::kRegister) {
if (vector_and_constant_result.storage_index != 0 ||
vector_and_constant_result.storage_addressing_mode !=
InstructionStorageAddressingMode::kStatic) {
InstructionStorageAddressingMode::kAbsolute) {
return false;
}
} else {
@@ -1330,14 +1297,14 @@ void ParseAluInstruction(const AluInstruction& op,
instr.vector_and_constant_result.storage_target = storage_target;
instr.vector_and_constant_result.storage_addressing_mode =
InstructionStorageAddressingMode::kStatic;
InstructionStorageAddressingMode::kAbsolute;
if (is_export) {
instr.vector_and_constant_result.storage_index = storage_index_export;
} else {
instr.vector_and_constant_result.storage_index = op.vector_dest();
if (op.is_vector_dest_relative()) {
instr.vector_and_constant_result.storage_addressing_mode =
InstructionStorageAddressingMode::kAddressRelative;
InstructionStorageAddressingMode::kLoopRelative;
}
}
instr.vector_and_constant_result.is_clamped = op.vector_clamp();
@@ -1372,14 +1339,14 @@ void ParseAluInstruction(const AluInstruction& op,
instr.scalar_result.storage_target = storage_target;
instr.scalar_result.storage_addressing_mode =
InstructionStorageAddressingMode::kStatic;
InstructionStorageAddressingMode::kAbsolute;
if (is_export) {
instr.scalar_result.storage_index = storage_index_export;
} else {
instr.scalar_result.storage_index = op.scalar_dest();
if (op.is_scalar_dest_relative()) {
instr.scalar_result.storage_addressing_mode =
InstructionStorageAddressingMode::kAddressRelative;
InstructionStorageAddressingMode::kLoopRelative;
}
}
instr.scalar_result.is_clamped = op.scalar_clamp();
@@ -1395,20 +1362,42 @@ void ParseAluInstruction(const AluInstruction& op,
scalar_opcode_info.src_swizzle_component_count,
instr.scalar_operands[0]);
} else {
// Constant and temporary register.
bool src3_negate = op.src_negate(3);
uint32_t src3_swizzle = op.src_swizzle(3);
uint32_t component_a = ((src3_swizzle >> 6) + 3) & 0x3;
uint32_t component_b = ((src3_swizzle >> 0) + 0) & 0x3;
uint32_t reg2 = (src3_swizzle & 0x3C) | (op.src_is_temp(3) << 1) |
(static_cast<int>(op.scalar_opcode()) & 1);
int const_slot = (op.src_is_temp(1) || op.src_is_temp(2)) ? 1 : 0;
ParseAluInstructionOperandSpecial(
op, InstructionStorageSource::kConstantFloat, op.src_reg(3),
op.src_negate(3), 0, component_a, instr.scalar_operands[0]);
// Left-hand constant operand (`a` - W swizzle).
InstructionOperand& const_op = instr.scalar_operands[0];
const_op.is_negated = src3_negate;
const_op.is_absolute_value = op.abs_constants();
const_op.storage_source = InstructionStorageSource::kConstantFloat;
const_op.storage_index = op.src_reg(3);
if (op.src_const_is_addressed(3)) {
if (op.is_const_address_register_relative()) {
const_op.storage_addressing_mode =
InstructionStorageAddressingMode::kAddressRegisterRelative;
} else {
const_op.storage_addressing_mode =
InstructionStorageAddressingMode::kLoopRelative;
}
} else {
const_op.storage_addressing_mode =
InstructionStorageAddressingMode::kAbsolute;
}
const_op.component_count = 1;
const_op.components[0] = GetSwizzledAluSourceComponent(src3_swizzle, 3);
ParseAluInstructionOperandSpecial(op, InstructionStorageSource::kRegister,
reg2, op.src_negate(3), const_slot,
component_b, instr.scalar_operands[1]);
// Right-hand temporary register operand (`b` - X swizzle).
InstructionOperand& temp_op = instr.scalar_operands[1];
temp_op.is_negated = src3_negate;
temp_op.is_absolute_value = op.abs_constants();
temp_op.storage_source = InstructionStorageSource::kRegister;
temp_op.storage_index = op.scalar_const_op_src_temp_reg();
temp_op.storage_addressing_mode =
InstructionStorageAddressingMode::kAbsolute;
temp_op.component_count = 1;
temp_op.components[0] = GetSwizzledAluSourceComponent(src3_swizzle, 0);
}
}
}
@@ -1421,7 +1410,7 @@ bool ParsedAluInstruction::IsScalarOpDefaultNop() const {
if (scalar_result.storage_target == InstructionStorageTarget::kRegister) {
if (scalar_result.storage_index != 0 ||
scalar_result.storage_addressing_mode !=
InstructionStorageAddressingMode::kStatic) {
InstructionStorageAddressingMode::kAbsolute) {
return false;
}
}
@@ -1446,7 +1435,7 @@ uint32_t ParsedAluInstruction::GetMemExportStreamConstant() const {
vector_operands[2].storage_source ==
InstructionStorageSource::kConstantFloat &&
vector_operands[2].storage_addressing_mode ==
InstructionStorageAddressingMode::kStatic &&
InstructionStorageAddressingMode::kAbsolute &&
vector_operands[2].IsStandardSwizzle() &&
!vector_operands[2].is_negated && !vector_operands[2].is_absolute_value) {
return vector_operands[2].storage_index;