GnmDriver: Clear context support (#567)

* gnmdriver: added support for gpu context reset

* shader_recompiler: minor validation fixes

* shader_recompiler: added `V_CMPX_GT_I32`

* shader_recompiler: fix for crash on inline sampler access

* compilation warnings and dead code elimination

* amdgpu: fix for registers addressing

* libraries: videoout: reduce logging pressure

* shader_recompiler: fix for devergence scope detection
This commit is contained in:
psucien 2024-08-25 22:01:05 +02:00 committed by GitHub
parent c2ddfe51e1
commit b687ae5e34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 147 additions and 50 deletions

View file

@ -179,6 +179,7 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
spv::ExecutionModel execution_model{};
ctx.AddCapability(spv::Capability::Image1D);
ctx.AddCapability(spv::Capability::Sampled1D);
ctx.AddCapability(spv::Capability::ImageQuery);
if (info.uses_fp16) {
ctx.AddCapability(spv::Capability::Float16);
ctx.AddCapability(spv::Capability::Int16);

View file

@ -405,6 +405,10 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) {
image.GetNumberFmt() == AmdGpu::NumberFormat::Float) {
return spv::ImageFormat::Rg16f;
}
if (image.GetDataFmt() == AmdGpu::DataFormat::Format16_16 &&
image.GetNumberFmt() == AmdGpu::NumberFormat::Snorm) {
return spv::ImageFormat::Rg16Snorm;
}
if (image.GetDataFmt() == AmdGpu::DataFormat::Format8_8 &&
image.GetNumberFmt() == AmdGpu::NumberFormat::Unorm) {
return spv::ImageFormat::Rg8;

View file

@ -21,8 +21,13 @@ struct Compare {
}
};
static IR::Condition MakeCondition(Opcode opcode) {
switch (opcode) {
static IR::Condition MakeCondition(const GcnInst& inst) {
if (inst.IsCmpx()) {
ASSERT(inst.opcode == Opcode::V_CMPX_NE_U32);
return IR::Condition::Execnz;
}
switch (inst.opcode) {
case Opcode::S_CBRANCH_SCC0:
return IR::Condition::Scc0;
case Opcode::S_CBRANCH_SCC1:
@ -37,7 +42,6 @@ static IR::Condition MakeCondition(Opcode opcode) {
return IR::Condition::Execnz;
case Opcode::S_AND_SAVEEXEC_B64:
case Opcode::S_ANDN2_B64:
case Opcode::V_CMPX_NE_U32:
return IR::Condition::Execnz;
default:
return IR::Condition::True;
@ -94,7 +98,8 @@ void CFG::EmitDivergenceLabels() {
// While this instruction does not save EXEC it is often used paired
// with SAVEEXEC to mask the threads that didn't pass the condition
// of initial branch.
inst.opcode == Opcode::S_ANDN2_B64 || inst.opcode == Opcode::V_CMPX_NE_U32;
(inst.opcode == Opcode::S_ANDN2_B64 && inst.dst[0].field == OperandField::ExecLo) ||
inst.opcode == Opcode::V_CMPX_NE_U32;
};
const auto is_close_scope = [](const GcnInst& inst) {
// Closing an EXEC scope can be either a branch instruction
@ -104,7 +109,8 @@ void CFG::EmitDivergenceLabels() {
// Sometimes compiler might insert instructions between the SAVEEXEC and the branch.
// Those instructions need to be wrapped in the condition as well so allow branch
// as end scope instruction.
inst.opcode == Opcode::S_CBRANCH_EXECZ || inst.opcode == Opcode::S_ANDN2_B64;
inst.opcode == Opcode::S_CBRANCH_EXECZ ||
(inst.opcode == Opcode::S_ANDN2_B64 && inst.dst[0].field == OperandField::ExecLo);
};
// Since we will be adding new labels, avoid iterating those as well.
@ -171,7 +177,7 @@ void CFG::EmitBlocks() {
block->begin_index = GetIndex(start);
block->end_index = end_index;
block->end_inst = end_inst;
block->cond = MakeCondition(end_inst.opcode);
block->cond = MakeCondition(end_inst);
blocks.insert(*block);
}
}

View file

@ -47,4 +47,18 @@ bool GcnInst::IsConditionalBranch() const {
return false;
}
bool GcnInst::IsCmpx() const {
if ((opcode >= Opcode::V_CMPX_F_F32 && opcode <= Opcode::V_CMPX_T_F32) ||
(opcode >= Opcode::V_CMPX_F_F64 && opcode <= Opcode::V_CMPX_T_F64) ||
(opcode >= Opcode::V_CMPSX_F_F32 && opcode <= Opcode::V_CMPSX_T_F32) ||
(opcode >= Opcode::V_CMPSX_F_F64 && opcode <= Opcode::V_CMPSX_T_F64) ||
(opcode >= Opcode::V_CMPX_F_I32 && opcode <= Opcode::V_CMPX_CLASS_F32) ||
(opcode >= Opcode::V_CMPX_F_I64 && opcode <= Opcode::V_CMPX_CLASS_F64) ||
(opcode >= Opcode::V_CMPX_F_U32 && opcode <= Opcode::V_CMPX_T_U32) ||
(opcode >= Opcode::V_CMPX_F_U64 && opcode <= Opcode::V_CMPX_T_U64)) {
return true;
}
return false;
}
} // namespace Shader::Gcn

View file

@ -203,6 +203,7 @@ struct GcnInst {
bool IsUnconditionalBranch() const;
bool IsConditionalBranch() const;
bool IsFork() const;
bool IsCmpx() const;
};
} // namespace Shader::Gcn

View file

@ -280,6 +280,8 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
return V_CMP_U32(ConditionOp::GT, true, false, inst);
case Opcode::V_CMP_LT_I32:
return V_CMP_U32(ConditionOp::LT, true, false, inst);
case Opcode::V_CMPX_GT_I32:
return V_CMP_U32(ConditionOp::GT, true, true, inst);
case Opcode::V_CMPX_LT_I32:
return V_CMP_U32(ConditionOp::LT, true, true, inst);
case Opcode::V_CMPX_F_U32:

View file

@ -246,10 +246,7 @@ public:
return true;
}
// Samplers with different bindings might still be the same.
const auto old_sharp =
info.ReadUd<AmdGpu::Sampler>(existing.sgpr_base, existing.dword_offset);
const auto new_sharp = info.ReadUd<AmdGpu::Sampler>(desc.sgpr_base, desc.dword_offset);
return old_sharp == new_sharp;
return existing.GetSsharp(info) == desc.GetSsharp(info);
})};
return index;
}