shader_recompiler: Add more instructions
This commit is contained in:
parent
ce31fad222
commit
8850c2f4be
|
@ -54,7 +54,11 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, Id of
|
||||||
Id ms) {
|
Id ms) {
|
||||||
const auto& texture = ctx.images[handle & 0xFFFF];
|
const auto& texture = ctx.images[handle & 0xFFFF];
|
||||||
const Id image = ctx.OpLoad(texture.image_type, texture.id);
|
const Id image = ctx.OpLoad(texture.image_type, texture.id);
|
||||||
|
if (Sirit::ValidId(lod)) {
|
||||||
return ctx.OpImageFetch(ctx.F32[4], image, coords, spv::ImageOperandsMask::Lod, lod);
|
return ctx.OpImageFetch(ctx.F32[4], image, coords, spv::ImageOperandsMask::Lod, lod);
|
||||||
|
} else {
|
||||||
|
return ctx.OpImageFetch(ctx.F32[4], image, coords);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
|
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id lod,
|
||||||
|
|
|
@ -216,6 +216,14 @@ void Translator::S_AND_B32(const GcnInst& inst) {
|
||||||
ir.SetScc(ir.INotEqual(result, ir.Imm32(0)));
|
ir.SetScc(ir.INotEqual(result, ir.Imm32(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Translator::S_OR_B32(const GcnInst& inst) {
|
||||||
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
|
const IR::U32 result{ir.BitwiseOr(src0, src1)};
|
||||||
|
SetDst(inst.dst[0], result);
|
||||||
|
ir.SetScc(ir.INotEqual(result, ir.Imm32(0)));
|
||||||
|
}
|
||||||
|
|
||||||
void Translator::S_LSHR_B32(const GcnInst& inst) {
|
void Translator::S_LSHR_B32(const GcnInst& inst) {
|
||||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
|
@ -285,4 +293,32 @@ void Translator::S_BFM_B32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], ir.ShiftLeftLogical(mask, src1));
|
SetDst(inst.dst[0], ir.ShiftLeftLogical(mask, src1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Translator::S_NOT_B64(const GcnInst& inst) {
|
||||||
|
const auto get_src = [&](const InstOperand& operand) {
|
||||||
|
switch (operand.field) {
|
||||||
|
case OperandField::VccLo:
|
||||||
|
return ir.GetVcc();
|
||||||
|
case OperandField::ExecLo:
|
||||||
|
return ir.GetExec();
|
||||||
|
case OperandField::ScalarGPR:
|
||||||
|
return ir.GetThreadBitScalarReg(IR::ScalarReg(operand.code));
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const IR::U1 src0{get_src(inst.src[0])};
|
||||||
|
const IR::U1 result = ir.LogicalNot(src0);
|
||||||
|
ir.SetScc(result);
|
||||||
|
switch (inst.dst[0].field) {
|
||||||
|
case OperandField::VccLo:
|
||||||
|
ir.SetVcc(result);
|
||||||
|
break;
|
||||||
|
case OperandField::ScalarGPR:
|
||||||
|
ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), result);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Shader::Gcn
|
} // namespace Shader::Gcn
|
||||||
|
|
|
@ -324,7 +324,10 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
translator.IMAGE_STORE(inst);
|
translator.IMAGE_STORE(inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::IMAGE_LOAD_MIP:
|
case Opcode::IMAGE_LOAD_MIP:
|
||||||
translator.IMAGE_LOAD_MIP(inst);
|
translator.IMAGE_LOAD(true, inst);
|
||||||
|
break;
|
||||||
|
case Opcode::IMAGE_LOAD:
|
||||||
|
translator.IMAGE_LOAD(false, inst);
|
||||||
break;
|
break;
|
||||||
case Opcode::V_CMP_GE_I32:
|
case Opcode::V_CMP_GE_I32:
|
||||||
translator.V_CMP_U32(ConditionOp::GE, true, false, inst);
|
translator.V_CMP_U32(ConditionOp::GE, true, false, inst);
|
||||||
|
@ -335,6 +338,9 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
case Opcode::V_CMP_LE_I32:
|
case Opcode::V_CMP_LE_I32:
|
||||||
translator.V_CMP_U32(ConditionOp::LE, true, false, inst);
|
translator.V_CMP_U32(ConditionOp::LE, true, false, inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::V_CMP_NE_I32:
|
||||||
|
translator.V_CMP_U32(ConditionOp::LG, true, false, inst);
|
||||||
|
break;
|
||||||
case Opcode::V_CMP_NE_U32:
|
case Opcode::V_CMP_NE_U32:
|
||||||
translator.V_CMP_U32(ConditionOp::LG, false, false, inst);
|
translator.V_CMP_U32(ConditionOp::LG, false, false, inst);
|
||||||
break;
|
break;
|
||||||
|
@ -386,6 +392,9 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
case Opcode::V_CMP_NLT_F32:
|
case Opcode::V_CMP_NLT_F32:
|
||||||
translator.V_CMP_F32(ConditionOp::GE, false, inst);
|
translator.V_CMP_F32(ConditionOp::GE, false, inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::S_CMP_LT_U32:
|
||||||
|
translator.S_CMP(ConditionOp::LT, false, inst);
|
||||||
|
break;
|
||||||
case Opcode::S_CMP_LG_U32:
|
case Opcode::S_CMP_LG_U32:
|
||||||
translator.S_CMP(ConditionOp::LG, false, inst);
|
translator.S_CMP(ConditionOp::LG, false, inst);
|
||||||
break;
|
break;
|
||||||
|
@ -585,6 +594,9 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
case Opcode::S_AND_B64:
|
case Opcode::S_AND_B64:
|
||||||
translator.S_AND_B64(false, inst);
|
translator.S_AND_B64(false, inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::S_NOT_B64:
|
||||||
|
translator.S_NOT_B64(inst);
|
||||||
|
break;
|
||||||
case Opcode::S_NAND_B64:
|
case Opcode::S_NAND_B64:
|
||||||
translator.S_AND_B64(true, inst);
|
translator.S_AND_B64(true, inst);
|
||||||
break;
|
break;
|
||||||
|
@ -627,6 +639,9 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
case Opcode::S_AND_B32:
|
case Opcode::S_AND_B32:
|
||||||
translator.S_AND_B32(inst);
|
translator.S_AND_B32(inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::S_OR_B32:
|
||||||
|
translator.S_OR_B32(inst);
|
||||||
|
break;
|
||||||
case Opcode::S_LSHR_B32:
|
case Opcode::S_LSHR_B32:
|
||||||
translator.S_LSHR_B32(inst);
|
translator.S_LSHR_B32(inst);
|
||||||
break;
|
break;
|
||||||
|
@ -657,9 +672,21 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
||||||
case Opcode::S_BFM_B32:
|
case Opcode::S_BFM_B32:
|
||||||
translator.S_BFM_B32(inst);
|
translator.S_BFM_B32(inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::V_MIN_U32:
|
||||||
|
translator.V_MIN_U32(inst);
|
||||||
|
break;
|
||||||
|
case Opcode::V_CMP_NE_U64:
|
||||||
|
translator.V_CMP_NE_U64(inst);
|
||||||
|
break;
|
||||||
case Opcode::V_TRUNC_F32:
|
case Opcode::V_TRUNC_F32:
|
||||||
translator.V_TRUNC_F32(inst);
|
translator.V_TRUNC_F32(inst);
|
||||||
break;
|
break;
|
||||||
|
case Opcode::V_CEIL_F32:
|
||||||
|
translator.V_CEIL_F32(inst);
|
||||||
|
break;
|
||||||
|
case Opcode::S_TTRACEDATA:
|
||||||
|
LOG_WARNING(Render_Vulkan, "S_TTRACEDATA instruction!");
|
||||||
|
break;
|
||||||
case Opcode::S_NOP:
|
case Opcode::S_NOP:
|
||||||
case Opcode::S_CBRANCH_EXECZ:
|
case Opcode::S_CBRANCH_EXECZ:
|
||||||
case Opcode::S_CBRANCH_SCC0:
|
case Opcode::S_CBRANCH_SCC0:
|
||||||
|
|
|
@ -45,12 +45,14 @@ public:
|
||||||
void S_AND_B64(bool negate, const GcnInst& inst);
|
void S_AND_B64(bool negate, const GcnInst& inst);
|
||||||
void S_ADD_I32(const GcnInst& inst);
|
void S_ADD_I32(const GcnInst& inst);
|
||||||
void S_AND_B32(const GcnInst& inst);
|
void S_AND_B32(const GcnInst& inst);
|
||||||
|
void S_OR_B32(const GcnInst& inst);
|
||||||
void S_LSHR_B32(const GcnInst& inst);
|
void S_LSHR_B32(const GcnInst& inst);
|
||||||
void S_CSELECT_B32(const GcnInst& inst);
|
void S_CSELECT_B32(const GcnInst& inst);
|
||||||
void S_CSELECT_B64(const GcnInst& inst);
|
void S_CSELECT_B64(const GcnInst& inst);
|
||||||
void S_BFE_U32(const GcnInst& inst);
|
void S_BFE_U32(const GcnInst& inst);
|
||||||
void S_LSHL_B32(const GcnInst& inst);
|
void S_LSHL_B32(const GcnInst& inst);
|
||||||
void S_BFM_B32(const GcnInst& inst);
|
void S_BFM_B32(const GcnInst& inst);
|
||||||
|
void S_NOT_B64(const GcnInst& inst);
|
||||||
|
|
||||||
// Scalar Memory
|
// Scalar Memory
|
||||||
void S_LOAD_DWORD(int num_dwords, const GcnInst& inst);
|
void S_LOAD_DWORD(int num_dwords, const GcnInst& inst);
|
||||||
|
@ -115,6 +117,9 @@ public:
|
||||||
void V_MIN_I32(const GcnInst& inst);
|
void V_MIN_I32(const GcnInst& inst);
|
||||||
void V_MUL_LO_U32(const GcnInst& inst);
|
void V_MUL_LO_U32(const GcnInst& inst);
|
||||||
void V_TRUNC_F32(const GcnInst& inst);
|
void V_TRUNC_F32(const GcnInst& inst);
|
||||||
|
void V_CEIL_F32(const GcnInst& inst);
|
||||||
|
void V_MIN_U32(const GcnInst& inst);
|
||||||
|
void V_CMP_NE_U64(const GcnInst& inst);
|
||||||
|
|
||||||
// Vector Memory
|
// Vector Memory
|
||||||
void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, const GcnInst& inst);
|
void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, const GcnInst& inst);
|
||||||
|
@ -132,7 +137,7 @@ public:
|
||||||
void IMAGE_GET_RESINFO(const GcnInst& inst);
|
void IMAGE_GET_RESINFO(const GcnInst& inst);
|
||||||
void IMAGE_SAMPLE(const GcnInst& inst);
|
void IMAGE_SAMPLE(const GcnInst& inst);
|
||||||
void IMAGE_STORE(const GcnInst& inst);
|
void IMAGE_STORE(const GcnInst& inst);
|
||||||
void IMAGE_LOAD_MIP(const GcnInst& inst);
|
void IMAGE_LOAD(bool has_mip, const GcnInst& inst);
|
||||||
|
|
||||||
// Export
|
// Export
|
||||||
void EXP(const GcnInst& inst);
|
void EXP(const GcnInst& inst);
|
||||||
|
|
|
@ -430,4 +430,44 @@ void Translator::V_TRUNC_F32(const GcnInst& inst) {
|
||||||
SetDst(inst.dst[0], ir.FPTrunc(src0));
|
SetDst(inst.dst[0], ir.FPTrunc(src0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Translator::V_CEIL_F32(const GcnInst& inst) {
|
||||||
|
const IR::F32 src0{GetSrc(inst.src[0], true)};
|
||||||
|
SetDst(inst.dst[0], ir.FPCeil(src0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::V_MIN_U32(const GcnInst& inst) {
|
||||||
|
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||||
|
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||||
|
SetDst(inst.dst[0], ir.IMin(src0, src1, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::V_CMP_NE_U64(const GcnInst& inst) {
|
||||||
|
const auto get_src = [&](const InstOperand& operand) {
|
||||||
|
switch (operand.field) {
|
||||||
|
case OperandField::VccLo:
|
||||||
|
return ir.GetVcc();
|
||||||
|
case OperandField::ExecLo:
|
||||||
|
return ir.GetExec();
|
||||||
|
case OperandField::ScalarGPR:
|
||||||
|
return ir.GetThreadBitScalarReg(IR::ScalarReg(operand.code));
|
||||||
|
case OperandField::ConstZero:
|
||||||
|
return ir.Imm1(false);
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const IR::U1 src0{get_src(inst.src[0])};
|
||||||
|
ASSERT(inst.src[1].field == OperandField::ConstZero); // src0 != 0
|
||||||
|
switch (inst.dst[1].field) {
|
||||||
|
case OperandField::VccLo:
|
||||||
|
ir.SetVcc(src0);
|
||||||
|
break;
|
||||||
|
case OperandField::ScalarGPR:
|
||||||
|
ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[1].code), src0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Shader::Gcn
|
} // namespace Shader::Gcn
|
||||||
|
|
|
@ -31,7 +31,9 @@ void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) {
|
||||||
|
|
||||||
void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
||||||
const auto& mimg = inst.control.mimg;
|
const auto& mimg = inst.control.mimg;
|
||||||
ASSERT(!mimg.da);
|
if (mimg.da) {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Image instruction declares an array");
|
||||||
|
}
|
||||||
|
|
||||||
IR::VectorReg addr_reg{inst.src[0].code};
|
IR::VectorReg addr_reg{inst.src[0].code};
|
||||||
IR::VectorReg dest_reg{inst.dst[0].code};
|
IR::VectorReg dest_reg{inst.dst[0].code};
|
||||||
|
@ -107,7 +109,7 @@ void Translator::IMAGE_SAMPLE(const GcnInst& inst) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::IMAGE_LOAD_MIP(const GcnInst& inst) {
|
void Translator::IMAGE_LOAD(bool has_mip, const GcnInst& inst) {
|
||||||
const auto& mimg = inst.control.mimg;
|
const auto& mimg = inst.control.mimg;
|
||||||
IR::VectorReg addr_reg{inst.src[0].code};
|
IR::VectorReg addr_reg{inst.src[0].code};
|
||||||
IR::VectorReg dest_reg{inst.dst[0].code};
|
IR::VectorReg dest_reg{inst.dst[0].code};
|
||||||
|
@ -119,7 +121,7 @@ void Translator::IMAGE_LOAD_MIP(const GcnInst& inst) {
|
||||||
ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3));
|
ir.GetVectorReg(addr_reg + 2), ir.GetVectorReg(addr_reg + 3));
|
||||||
|
|
||||||
IR::TextureInstInfo info{};
|
IR::TextureInstInfo info{};
|
||||||
info.explicit_lod.Assign(1);
|
info.explicit_lod.Assign(has_mip);
|
||||||
const IR::Value texel = ir.ImageFetch(handle, body, {}, {}, {}, info);
|
const IR::Value texel = ir.ImageFetch(handle, body, {}, {}, {}, info);
|
||||||
|
|
||||||
for (u32 i = 0; i < 4; i++) {
|
for (u32 i = 0; i < 4; i++) {
|
||||||
|
|
|
@ -251,7 +251,8 @@ IR::Value PatchCubeCoord(IR::IREmitter& ir, const IR::Value& s, const IR::Value&
|
||||||
|
|
||||||
void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors) {
|
void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors) {
|
||||||
IR::Inst* producer = inst.Arg(0).InstRecursive();
|
IR::Inst* producer = inst.Arg(0).InstRecursive();
|
||||||
ASSERT(producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2 ||
|
ASSERT(producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2 || // IMAGE_SAMPLE (image+sampler)
|
||||||
|
producer->GetOpcode() == IR::Opcode::ReadConst || // IMAGE_LOAD (image only)
|
||||||
producer->GetOpcode() == IR::Opcode::GetUserData);
|
producer->GetOpcode() == IR::Opcode::GetUserData);
|
||||||
const auto [tsharp_handle, ssharp_handle] = [&] -> std::pair<IR::Inst*, IR::Inst*> {
|
const auto [tsharp_handle, ssharp_handle] = [&] -> std::pair<IR::Inst*, IR::Inst*> {
|
||||||
if (producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2) {
|
if (producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2) {
|
||||||
|
|
Loading…
Reference in New Issue