mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-26 12:56:54 +01:00
graphics: split shader translation into explicit opcode dispatchers
This commit is contained in:
@@ -57,46 +57,50 @@ bool Translator::TranslateEmbeddedFetch(const Decoder::Instruction& inst, uint32
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Translator::TranslateAttributeOperation(const Decoder::Instruction& inst, std::string* error) {
|
||||
void Translator::V_INTERP_P1_F32() {}
|
||||
|
||||
void Translator::V_INTERP_P2_F32(const Decoder::Instruction& inst) {
|
||||
const auto value = ir.Emit(IR::ValueOpcode::GetAttribute,
|
||||
{IR::Value(inst.src1.value), IR::Value(inst.src2.value)});
|
||||
WriteOperand(inst.dst, value);
|
||||
}
|
||||
|
||||
bool Translator::V_INTERP_MOV_F32(const Decoder::Instruction& inst, std::string* error) {
|
||||
if (inst.src0.value >= 3u) {
|
||||
return ShaderError::Fail(error,
|
||||
fmt::format("v_interp_mov_f32 mode {} is reserved at pc 0x{:08x}",
|
||||
inst.src0.value, inst.pc));
|
||||
}
|
||||
const auto value = ir.Emit(
|
||||
IR::ValueOpcode::GetInterpolationParameter,
|
||||
{IR::Value(inst.src1.value), IR::Value(inst.src2.value), IR::Value(inst.src0.value)});
|
||||
WriteOperand(inst.dst, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Translator::EXP(const Decoder::Instruction& inst, std::string* error) {
|
||||
uint32_t index = 0;
|
||||
if (ExportTargetKindFromTarget(inst.exp.target, index) == IR::ExportTargetKind::Unknown) {
|
||||
return ShaderError::Fail(error,
|
||||
fmt::format("unsupported EXP target 0x{:02x} at pc 0x{:08x}",
|
||||
inst.exp.target, inst.pc));
|
||||
}
|
||||
std::array<IR::Value, 4> components {IR::Value(0u), IR::Value(0u), IR::Value(0u),
|
||||
IR::Value(0u)};
|
||||
for (uint32_t source = 0; source < std::min(inst.src_count, 4u); source++) {
|
||||
components[source] = ReadRawU32(PlainOperand(SourceAt(inst, source)));
|
||||
}
|
||||
const auto data = ir.Emit(IR::ValueOpcode::CompositeConstructU32x4,
|
||||
{components[0], components[1], components[2], components[3]});
|
||||
ir.Emit(IR::ValueOpcode::SetAttribute, {data, ir.GetExec()}, AddExportInfo(inst));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Translator::EmitInterpolation(const Decoder::Instruction& inst, std::string* error) {
|
||||
switch (inst.opcode) {
|
||||
case Decoder::Opcode::V_INTERP_P1_F32: return true;
|
||||
case Decoder::Opcode::V_INTERP_P2_F32:
|
||||
case Decoder::Opcode::V_INTERP_MOV_F32: {
|
||||
if (inst.opcode == Decoder::Opcode::V_INTERP_MOV_F32 && inst.src0.value >= 3u) {
|
||||
return ShaderError::Fail(
|
||||
error, fmt::format("v_interp_mov_f32 mode {} is reserved at pc 0x{:08x}",
|
||||
inst.src0.value, inst.pc));
|
||||
}
|
||||
const auto interpolation_mode =
|
||||
inst.opcode == Decoder::Opcode::V_INTERP_MOV_F32 ? inst.src0.value : 3u;
|
||||
const auto value =
|
||||
interpolation_mode < 3u
|
||||
? ir.Emit(IR::ValueOpcode::GetInterpolationParameter,
|
||||
{IR::Value(inst.src1.value), IR::Value(inst.src2.value),
|
||||
IR::Value(interpolation_mode)})
|
||||
: ir.Emit(IR::ValueOpcode::GetAttribute,
|
||||
{IR::Value(inst.src1.value), IR::Value(inst.src2.value)});
|
||||
WriteOperand(inst.dst, value);
|
||||
return true;
|
||||
}
|
||||
case Decoder::Opcode::EXP: {
|
||||
uint32_t index = 0;
|
||||
if (ExportTargetKindFromTarget(inst.exp.target, index) ==
|
||||
IR::ExportTargetKind::Unknown) {
|
||||
return ShaderError::Fail(
|
||||
error, fmt::format("unsupported EXP target 0x{:02x} at pc 0x{:08x}",
|
||||
inst.exp.target, inst.pc));
|
||||
}
|
||||
std::array<IR::Value, 4> components {IR::Value(0u), IR::Value(0u), IR::Value(0u),
|
||||
IR::Value(0u)};
|
||||
for (uint32_t source = 0; source < std::min(inst.src_count, 4u); source++) {
|
||||
components[source] = ReadRawU32(PlainOperand(SourceAt(inst, source)));
|
||||
}
|
||||
const auto data = ir.Emit(IR::ValueOpcode::CompositeConstructU32x4,
|
||||
{components[0], components[1], components[2], components[3]});
|
||||
ir.Emit(IR::ValueOpcode::SetAttribute, {data, ir.GetExec()}, AddExportInfo(inst));
|
||||
return true;
|
||||
}
|
||||
case Decoder::Opcode::V_INTERP_P1_F32: V_INTERP_P1_F32(); return true;
|
||||
case Decoder::Opcode::V_INTERP_P2_F32: V_INTERP_P2_F32(inst); return true;
|
||||
case Decoder::Opcode::V_INTERP_MOV_F32: return V_INTERP_MOV_F32(inst, error);
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user