diff --git a/src/shader_recompiler/frontend/translate/scalar_alu.cpp b/src/shader_recompiler/frontend/translate/scalar_alu.cpp index 1ef0d82d..e731e299 100644 --- a/src/shader_recompiler/frontend/translate/scalar_alu.cpp +++ b/src/shader_recompiler/frontend/translate/scalar_alu.cpp @@ -161,8 +161,9 @@ void Translator::EmitSOPK(const GcnInst& inst) { switch (inst.opcode) { // SOPK case Opcode::S_MOVK_I32: - return S_MOVK(inst); - + return S_MOVK(inst, false); + case Opcode::S_CMOVK_I32: + return S_MOVK(inst, true); case Opcode::S_CMPK_EQ_I32: return S_CMPK(ConditionOp::EQ, true, inst); case Opcode::S_CMPK_LG_I32: @@ -458,13 +459,16 @@ void Translator::S_ABSDIFF_I32(const GcnInst& inst) { // SOPK -void Translator::S_MOVK(const GcnInst& inst) { - const auto simm16 = inst.control.sopk.simm; - if (simm16 & (1 << 15)) { - // TODO: need to verify the case of imm sign extension - UNREACHABLE(); +void Translator::S_MOVK(const GcnInst& inst, bool is_conditional) { + const s16 simm16 = inst.control.sopk.simm; + // do the sign extension + const s32 simm32 = static_cast(simm16); + IR::U32 val = ir.Imm32(simm32); + if (is_conditional) { + // if !SCC its a NOP + val = IR::U32{ir.Select(ir.GetScc(), val, GetSrc(inst.dst[0]))}; } - SetDst(inst.dst[0], ir.Imm32(simm16)); + SetDst(inst.dst[0], val); } void Translator::S_CMPK(ConditionOp cond, bool is_signed, const GcnInst& inst) { diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index 60bad186..8e575fca 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -100,7 +100,7 @@ public: void S_NOT_B32(const GcnInst& inst); // SOPK - void S_MOVK(const GcnInst& inst); + void S_MOVK(const GcnInst& inst, bool is_conditional); void S_CMPK(ConditionOp cond, bool is_signed, const GcnInst& inst); void S_ADDK_I32(const GcnInst& inst); void S_MULK_I32(const GcnInst& inst); diff --git a/src/shader_recompiler/ir/passes/hull_shader_transform.cpp b/src/shader_recompiler/ir/passes/hull_shader_transform.cpp index 5cf02b6d..895c9823 100644 --- a/src/shader_recompiler/ir/passes/hull_shader_transform.cpp +++ b/src/shader_recompiler/ir/passes/hull_shader_transform.cpp @@ -398,8 +398,8 @@ void HullShaderTransform(IR::Program& program, RuntimeInfo& runtime_info) { // communicated to the driver. // The layout seems to be implied by the type of the abstract domain. switch (runtime_info.hs_info.tess_type) { - case AmdGpu::TessellationType::Quad: - ASSERT(gcn_factor_idx < 6); + case AmdGpu::TessellationType::Isoline: + ASSERT(gcn_factor_idx < 2); return IR::PatchFactor(gcn_factor_idx); case AmdGpu::TessellationType::Triangle: ASSERT(gcn_factor_idx < 4); @@ -407,9 +407,11 @@ void HullShaderTransform(IR::Program& program, RuntimeInfo& runtime_info) { return IR::Patch::TessellationLodInteriorU; } return IR::PatchFactor(gcn_factor_idx); + case AmdGpu::TessellationType::Quad: + ASSERT(gcn_factor_idx < 6); + return IR::PatchFactor(gcn_factor_idx); default: - // Point domain types haven't been seen so far - UNREACHABLE_MSG("Unhandled tess type"); + UNREACHABLE(); } };