shader: expose graphics compute queue fields to GETREG

This commit is contained in:
nmzik
2026-10-09 16:22:28 +02:00
parent 1818aae562
commit bb5edbd490
13 changed files with 102 additions and 17 deletions
@@ -534,7 +534,8 @@ void PrepareCallTarget(ShaderSource& source, const CompileOptions& options) {
if (inserted) {
Block translated;
Frontend::Translator translator(query, &translated, 1u,
(options.input_info.compute->float_mode & 0x10u) == 0u);
(options.input_info.compute->float_mode & 0x10u) == 0u,
!options.input_info.compute->async_compute);
translator.TranslateInstruction(source.decoded.instructions[index]);
for (const auto& inst: translated) {
uint32_t destination = UINT32_MAX;
@@ -89,7 +89,7 @@ constexpr OpcodeMap SOPK_OPCODE_LIST[] = {
{0x08u, Opcode::S_CMP_LE_I32}, {0x09u, Opcode::S_CMP_EQ_U32}, {0x0au, Opcode::S_CMP_LG_U32},
{0x0bu, Opcode::S_CMP_GT_U32}, {0x0cu, Opcode::S_CMP_GE_U32}, {0x0du, Opcode::S_CMP_LT_U32},
{0x0eu, Opcode::S_CMP_LE_U32}, {0x0fu, Opcode::S_ADD_I32}, {0x10u, Opcode::S_MULK_I32},
{0x13u, Opcode::S_SETREG_B32}, {0x17u, Opcode::S_WAITCNT_VSCNT}, {0x18u, Opcode::S_WAITCNT},
{0x12u, Opcode::S_GETREG_B32}, {0x13u, Opcode::S_SETREG_B32}, {0x17u, Opcode::S_WAITCNT_VSCNT}, {0x18u, Opcode::S_WAITCNT},
{0x19u, Opcode::S_WAITCNT}, {0x1au, Opcode::S_WAITCNT},
{0x1bu, Opcode::S_SUBVECTOR_LOOP_BEGIN}, {0x1cu, Opcode::S_SUBVECTOR_LOOP_END},
};
@@ -207,7 +207,7 @@ void DecodeSopk(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t word = code[word_index];
const uint32_t opcode = (word >> 23u) & 0x1fu;
const uint32_t sdst = (word >> 16u) & 0x7fu;
const auto imm = opcode >= 0x09u && opcode <= 0x0eu
const auto imm = (opcode >= 0x09u && opcode <= 0x0eu) || opcode == 0x12u
? static_cast<int32_t>(word & 0xffffu)
: static_cast<int32_t>(static_cast<int16_t>(word & 0xffffu));
@@ -227,6 +227,7 @@ void DecodeSopk(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
}
switch (inst.opcode) {
case Opcode::S_GETREG_B32:
case Opcode::S_MOVK_I32: DecodeScalarDestination(sdst, pc, inst.dst); return;
case Opcode::S_SUBVECTOR_LOOP_BEGIN:
case Opcode::S_SUBVECTOR_LOOP_END:
@@ -679,6 +679,7 @@ enum class Opcode {
S_CBRANCH_CDBGSYS,
S_CBRANCH_CDBGSYS_OR_USER,
S_SENDMSG,
S_GETREG_B32,
S_SETREG_B32,
S_SLEEP,
S_TRAP,
@@ -18,6 +18,13 @@ void Translator::EmitScalar(const Decoder::Instruction& inst) {
case O::S_CSELECT_B32: S_CSELECT_B32(inst); return;
case O::S_CSELECT_B64: ScalarSelect64(inst, inst.src1); return;
case O::S_CMOV_B64: ScalarSelect64(inst, inst.dst); return;
case O::S_GETREG_B32:
if (!graphics_compute || (inst.src0.value != 0x1818u && inst.src0.value != 0x0a18u))
EXIT("unsupported S_GETREG_B32 at pc 0x%08x: selector=0x%04x graphics_compute=%u",
inst.pc, inst.src0.value, static_cast<unsigned>(graphics_compute));
// HW_ID2 identifies graphics compute as QUEUE=6, ME=0.
WriteOperand(inst.dst, IR::Value(inst.src0.value == 0x1818u ? 6u : 0u));
return;
case O::S_SETREG_B32: EmitControlNop(); return;
case O::S_WAITCNT_VSCNT: S_WAITCNT_VSCNT(inst); return;
case O::S_WAITCNT: return;
@@ -1356,7 +1356,8 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
(options.input_info.compute->float_mode & 0x10u) == 0;
for (const auto& cfg_block: cfg.blocks) {
auto* block = blocks_by_id.at(cfg_block.id);
Translator translator(result, block, vector_limit, flush_f32_inputs);
Translator translator(result, block, vector_limit, flush_f32_inputs,
options.stage == ShaderType::Compute && !options.input_info.compute->async_compute);
for (uint32_t index = cfg_block.inst_begin; index < cfg_block.inst_end; index++) {
const auto& instruction = decoded.instructions[index];
if (IsCodeTableLoad(cfg, instruction.pc)) {
@@ -10,9 +10,9 @@ namespace Libs::Graphics::ShaderRecompiler::Frontend {
class Translator {
public:
Translator(IR::Program& program, IR::Block* block, uint32_t vector_limit,
bool flush_f32_inputs)
bool flush_f32_inputs, bool graphics_compute)
: program(program), ir(block), current_vector_limit(vector_limit),
flush_f32_inputs(flush_f32_inputs) {}
flush_f32_inputs(flush_f32_inputs), graphics_compute(graphics_compute) {}
void TranslateInstruction(const Decoder::Instruction& inst);
void TranslateEmbeddedFetch(const Decoder::Instruction& inst, uint32_t attribute,
@@ -264,6 +264,7 @@ private:
uint32_t current_pc = 0;
uint32_t current_vector_limit = 1;
bool flush_f32_inputs;
bool graphics_compute;
};
} // namespace Libs::Graphics::ShaderRecompiler::Frontend
+4 -1
View File
@@ -574,10 +574,12 @@ static void ShaderGetStaticInputInfoPS(
static void ShaderGetStaticInputInfoCS(const HW::ComputeShaderInfo& regs,
const HW::ShaderRegisters& /*sh*/,
const ShaderMappedData& data, ShaderComputeInputInfo& info) {
const bool async_compute = info.async_compute;
const bool dispatch_thread_dimensions = info.dispatch_thread_dimensions;
const auto host_subgroup_size = info.host_subgroup_size;
const auto workgroup_counts = std::to_array(info.workgroup_counts);
info = {};
info.async_compute = async_compute;
info.dispatch_thread_dimensions = dispatch_thread_dimensions;
info.host_subgroup_size = host_subgroup_size;
std::ranges::copy(workgroup_counts, info.workgroup_counts);
@@ -693,7 +695,8 @@ void BuildStageStaticKey(const ShaderComputeInputInfo& info, std::vector<uint32_
key.push_back(info.thread_ids_num);
key.push_back(info.lds_size_dwords);
key.push_back(info.scratch_size_dwords);
key.push_back(static_cast<uint32_t>(info.dispatch_thread_dimensions));
key.push_back(static_cast<uint32_t>(info.dispatch_thread_dimensions) |
(static_cast<uint32_t>(info.async_compute) << 1u));
for (int i = 0; i < 3; i++) {
key.push_back(info.threads_num[i]);
key.push_back(static_cast<uint32_t>(info.group_id[i]));
+1
View File
@@ -146,6 +146,7 @@ struct ShaderVertexInputInfo {
};
struct ShaderComputeInputInfo: ShaderWorkgroupInputInfo {
bool async_compute = false;
uint8_t float_mode = 0xc0;
uint32_t dispatch_threads_num[3] = {0, 0, 0};
uint32_t workgroup_counts[3] = {0, 0, 0};