mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 10:56:58 +02:00
shader: expose graphics compute queue fields to GETREG
This commit is contained in:
@@ -1003,7 +1003,7 @@ void CommandProcessor::DispatchDirect(uint32_t thread_group_x, uint32_t thread_g
|
||||
}
|
||||
|
||||
m_renderer.GetRenderExecutor().DispatchDirect(m_submit_id, CurrentBuffer(), thread_group_x,
|
||||
thread_group_y, thread_group_z, mode);
|
||||
thread_group_y, thread_group_z, mode, IsAsyncComputeQueue());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1015,7 +1015,8 @@ void CommandProcessor::DispatchIndirect(uint64_t args_addr, uint32_t mode) {
|
||||
return;
|
||||
}
|
||||
m_sh_ctx.SetCsWaveSize(Pm4::ComputeWaveSize(mode));
|
||||
m_renderer.GetRenderExecutor().DispatchIndirect(m_submit_id, CurrentBuffer(), args_addr, mode);
|
||||
m_renderer.GetRenderExecutor().DispatchIndirect(m_submit_id, CurrentBuffer(), args_addr, mode,
|
||||
IsAsyncComputeQueue());
|
||||
}
|
||||
|
||||
void CommandProcessor::DrawIndexAuto(DrawAutoArgs args) {
|
||||
|
||||
@@ -156,9 +156,9 @@ public:
|
||||
KYTY_CLASS_NO_COPY(RenderExecutor);
|
||||
|
||||
void DispatchDirect(uint64_t submit_id, CommandBuffer& buffer, uint32_t thread_group_x,
|
||||
uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode);
|
||||
uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode, bool async_compute);
|
||||
void DispatchIndirect(uint64_t submit_id, CommandBuffer& buffer, uint64_t args_addr,
|
||||
uint32_t mode);
|
||||
uint32_t mode, bool async_compute);
|
||||
|
||||
void PrepareBindings(const ShaderStageRuntime& runtime, PreparedBindings& prepared);
|
||||
void FindBuffers(std::span<PreparedBindings* const> stages);
|
||||
|
||||
@@ -226,7 +226,7 @@ static void BindSharedMemory(RenderContext& context, ShaderComputeInputInfo& inp
|
||||
|
||||
void RenderExecutor::DispatchDirect(uint64_t submit_id, CommandBuffer& buffer,
|
||||
uint32_t thread_group_x, uint32_t thread_group_y,
|
||||
uint32_t thread_group_z, uint32_t mode) {
|
||||
uint32_t thread_group_z, uint32_t mode, bool async_compute) {
|
||||
EXIT_IF(buffer.IsInvalid());
|
||||
m_context.GetCommandScheduler().PopPendingOperations();
|
||||
auto& ctx = buffer.GetRegisters();
|
||||
@@ -281,6 +281,7 @@ void RenderExecutor::DispatchDirect(uint64_t submit_id, CommandBuffer& buffer,
|
||||
const auto& sh_regs = ctx.GetShaderRegisters();
|
||||
|
||||
ShaderComputeInputInfo input_info {};
|
||||
input_info.async_compute = async_compute;
|
||||
const bool use_thread_dimensions = (mode & DISPATCH_INITIATOR_USE_THREAD_DIMENSIONS) != 0;
|
||||
input_info.dispatch_thread_dimensions = use_thread_dimensions;
|
||||
input_info.workgroup_counts[0] = thread_group_x;
|
||||
@@ -437,7 +438,7 @@ void RenderExecutor::DispatchDirect(uint64_t submit_id, CommandBuffer& buffer,
|
||||
}
|
||||
|
||||
void RenderExecutor::DispatchIndirect(uint64_t submit_id, CommandBuffer& buffer,
|
||||
uint64_t args_addr, uint32_t mode) {
|
||||
uint64_t args_addr, uint32_t mode, bool async_compute) {
|
||||
EXIT_IF(buffer.IsInvalid() || args_addr == 0 || (args_addr & 3u) != 0 ||
|
||||
(mode & Pm4::COMPUTE_DISPATCH_INITIATOR_USE_THREAD_DIMENSIONS) != 0);
|
||||
m_context.GetCommandScheduler().PopPendingOperations();
|
||||
@@ -450,6 +451,7 @@ void RenderExecutor::DispatchIndirect(uint64_t submit_id, CommandBuffer& buffer,
|
||||
return;
|
||||
}
|
||||
ShaderComputeInputInfo input_info {};
|
||||
input_info.async_compute = async_compute;
|
||||
const auto compute_program = m_context.GetPipelineCache().GetComputeProgram(
|
||||
cs_regs, buffer.GetRegisters().GetShaderRegisters(), input_info);
|
||||
buffer.EndRendering();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]));
|
||||
|
||||
@@ -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};
|
||||
|
||||
Reference in New Issue
Block a user