mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 00:12:40 +00:00
1 parent
62a92abc66
commit
da6cee924b
10 files changed
+195
-282
No files matched your search
@@ -639,8 +639,6 @@ struct Instruction {
|
||||
bool slc = false;
|
||||
bool idxen = false;
|
||||
bool offen = false;
|
||||
// V_CMPX writes the comparison result to its normal scalar destination and EXEC.
|
||||
bool compare_exec = false;
|
||||
int32_t branch_offset = 0;
|
||||
uint32_t branch_target = 0;
|
||||
struct {
|
||||
|
||||
@@ -1103,8 +1103,9 @@ bool DecodeVopcSdwa(uint32_t pc, std::span<const uint32_t> code, uint32_t word_i
|
||||
!DecodeScalarSource(vsrc1 + (fields.s1 == 0u ? 256u : 0u), pc, &inst->src1, error)) {
|
||||
return false;
|
||||
}
|
||||
inst->compare_exec = IsVopcCompareExec(inst->opcode);
|
||||
if (fields.sd == 0u) {
|
||||
if (IsVopcCompareExec(inst->opcode)) {
|
||||
inst->dst.kind = OperandKind::ExecLo;
|
||||
} else if (fields.sd == 0u) {
|
||||
inst->dst.kind = OperandKind::VccLo;
|
||||
} else if (!DecodeScalarDestination(fields.sdst, pc, &inst->dst, error)) {
|
||||
return false;
|
||||
@@ -1141,8 +1142,7 @@ bool DecodeVopcDpp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_in
|
||||
!DecodeVectorGpr(vsrc1, &inst->src1, error)) {
|
||||
return false;
|
||||
}
|
||||
inst->dst.kind = OperandKind::VccLo;
|
||||
inst->compare_exec = IsVopcCompareExec(inst->opcode);
|
||||
inst->dst.kind = IsVopcCompareExec(inst->opcode) ? OperandKind::ExecLo : OperandKind::VccLo;
|
||||
inst->src0.negate = ((modifier >> 20u) & 0x1u) != 0u;
|
||||
inst->src0.absolute = ((modifier >> 21u) & 0x1u) != 0u;
|
||||
inst->src0.dpp = true;
|
||||
@@ -1532,8 +1532,7 @@ bool DecodeVopc(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
||||
inst->family = Family::VOPC;
|
||||
inst->opcode_id = opcode;
|
||||
inst->opcode = Lookup(VOPC_OPS, static_cast<uint32_t>(std::size(VOPC_OPS)), opcode);
|
||||
inst->dst.kind = OperandKind::VccLo;
|
||||
inst->compare_exec = IsVopcCompareExec(inst->opcode);
|
||||
inst->dst.kind = IsVopcCompareExec(inst->opcode) ? OperandKind::ExecLo : OperandKind::VccLo;
|
||||
SetRawWords(inst, code, word_index, 1);
|
||||
|
||||
switch (src0) {
|
||||
@@ -1619,8 +1618,9 @@ bool DecodeVop3(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
||||
return true;
|
||||
}
|
||||
bool dst_ok = true;
|
||||
inst->compare_exec = compare_exec;
|
||||
if (scalar_dst) {
|
||||
if (compare_exec) {
|
||||
inst->dst.kind = OperandKind::ExecLo;
|
||||
} else if (scalar_dst) {
|
||||
// VOP3A uses VDST for VOPC and the scalar-destination lane-read opcodes.
|
||||
dst_ok = DecodeScalarDestination(vdst, pc, &inst->dst, error);
|
||||
} else {
|
||||
|
||||
@@ -1165,22 +1165,6 @@ bool LowerImplemented(const Decoder::Instruction& decoded, BasicBlock* block, st
|
||||
}
|
||||
|
||||
block->instructions.push_back(inst);
|
||||
if (decoded.compare_exec) {
|
||||
// V_CMPX has two architectural destinations. Keep the comparison's normal VCC/SDST
|
||||
// result, then mirror the complete lane mask to EXEC. A mask is always a 64-bit scalar pair, including wave32 shaders.
|
||||
for (uint32_t i = 0; i < 2u; i++) {
|
||||
Instruction move;
|
||||
move.pc = decoded.pc;
|
||||
move.op = Opcode::MoveU32;
|
||||
move.src_count = 1;
|
||||
move.src[0] = inst.dst;
|
||||
move.src[0].reg.index += i;
|
||||
move.dst.kind = OperandKind::Register;
|
||||
move.dst.reg.file = RegisterFile::Exec;
|
||||
move.dst.reg.index = i;
|
||||
block->instructions.push_back(move);
|
||||
}
|
||||
}
|
||||
return AppendScalarResultSccNonZero(decoded, block, error);
|
||||
}
|
||||
|
||||
|
||||
@@ -94,12 +94,8 @@ uint32_t VertexParameterComponentCount(const EmitterState& state, const InputBin
|
||||
input.location < ShaderVertexInputInfo::RES_MAX &&
|
||||
input.location < static_cast<uint32_t>(state.vertex_input_info->resources_num) &&
|
||||
state.vertex_input_info->resources_dst[input.location].registers_num > 0) {
|
||||
const auto& descriptor = state.vertex_input_info->resources[input.location];
|
||||
const auto dst_count = static_cast<uint32_t>(
|
||||
count = static_cast<uint32_t>(
|
||||
state.vertex_input_info->resources_dst[input.location].registers_num);
|
||||
// Keep the SPIR-V interface and native VkFormat width identical. A destination
|
||||
// selector may request a raw component beyond the written VGPR count (W -> X).
|
||||
count = VertexRawComponentCount(descriptor.DstSelXYZW(), dst_count);
|
||||
}
|
||||
return std::clamp(count, 1u, 4u);
|
||||
}
|
||||
|
||||
@@ -450,25 +450,7 @@ uint32_t EmitVertexParameterComponentU32(EmitterState* state, const InputBinding
|
||||
uint32_t component) {
|
||||
const auto count = VertexParameterComponentCount(*state, input);
|
||||
const auto kind = VertexParameterScalarKind(*state, input.location);
|
||||
uint32_t source_component = component;
|
||||
if (input.location < ShaderVertexInputInfo::RES_MAX &&
|
||||
input.location < static_cast<uint32_t>(state->vertex_input_info->resources_num)) {
|
||||
const auto& descriptor = state->vertex_input_info->resources[input.location];
|
||||
const auto selection =
|
||||
DecodeVertexDstSelector(GetDstSel(descriptor.DstSelXYZW(), component & 3u));
|
||||
if (selection.kind == VertexDstSelectKind::Zero) {
|
||||
return ConstantU32(state, 0u);
|
||||
}
|
||||
if (selection.kind == VertexDstSelectKind::One) {
|
||||
return ConstantU32(state,
|
||||
kind == VertexInputScalarKind::Float ? 0x3f800000u : 1u);
|
||||
}
|
||||
if (selection.kind == VertexDstSelectKind::Reserved) {
|
||||
EXIT("reserved vertex destination selector\n");
|
||||
}
|
||||
source_component = selection.source_component;
|
||||
}
|
||||
if (source_component >= count) {
|
||||
if (component >= count) {
|
||||
return VertexInputDefaultComponentU32(state, kind, component);
|
||||
}
|
||||
|
||||
@@ -480,7 +462,7 @@ uint32_t EmitVertexParameterComponentU32(EmitterState* state, const InputBinding
|
||||
const auto pointer_type = VertexParameterScalarPointerType(*state, kind);
|
||||
const auto pointer = state->builder.AllocateId();
|
||||
state->builder.AddFunction({OpAccessChain, pointer_type, pointer, input.variable_id,
|
||||
ConstantU32(state, source_component)});
|
||||
ConstantU32(state, component)});
|
||||
state->builder.AddFunction({OpLoad, scalar_type, raw, pointer});
|
||||
}
|
||||
|
||||
|
||||
@@ -64,41 +64,6 @@ inline uint8_t GetDstSel(uint32_t swizzle, uint32_t channel) {
|
||||
return (swizzle >> (channel * 3u)) & 0x7u;
|
||||
}
|
||||
|
||||
enum class VertexDstSelectKind : uint8_t { Zero, One, Component, Reserved };
|
||||
|
||||
struct VertexDstSelection {
|
||||
VertexDstSelectKind kind = VertexDstSelectKind::Reserved;
|
||||
uint8_t source_component = 0;
|
||||
};
|
||||
|
||||
constexpr VertexDstSelection DecodeVertexDstSelector(uint8_t selector) {
|
||||
if (selector == 0u) {
|
||||
return {VertexDstSelectKind::Zero, 0};
|
||||
}
|
||||
if (selector == 1u) {
|
||||
return {VertexDstSelectKind::One, 0};
|
||||
}
|
||||
if (selector >= 4u && selector <= 7u) {
|
||||
return {VertexDstSelectKind::Component, static_cast<uint8_t>(selector - 4u)};
|
||||
}
|
||||
return {VertexDstSelectKind::Reserved, 0};
|
||||
}
|
||||
|
||||
constexpr uint32_t VertexRawComponentCount(uint32_t swizzle, uint32_t destination_components) {
|
||||
const auto dst_count = destination_components < 1u
|
||||
? 1u
|
||||
: (destination_components > 4u ? 4u : destination_components);
|
||||
auto count = dst_count;
|
||||
for (uint32_t component = 0; component < dst_count; component++) {
|
||||
const auto selection = DecodeVertexDstSelector(GetDstSel(swizzle, component));
|
||||
if (selection.kind == VertexDstSelectKind::Component) {
|
||||
const auto source_count = static_cast<uint32_t>(selection.source_component) + 1u;
|
||||
count = count > source_count ? count : source_count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
struct ShaderVertexInputInfo {
|
||||
static constexpr int RES_MAX = 32;
|
||||
|
||||
@@ -131,26 +96,26 @@ struct ShaderComputeInputInfo {
|
||||
};
|
||||
|
||||
struct ShaderPixelInputInfo {
|
||||
uint32_t interpolator_settings[32] = {0};
|
||||
uint32_t input_num = 0;
|
||||
uint32_t ps_system_input_base = 0;
|
||||
uint8_t target_output_mode[8] = {};
|
||||
std::array<Prospero::ColorComponentMapping, 8> target_export_mapping = {};
|
||||
uint32_t mrt_output_mask = 0;
|
||||
uint32_t descriptor_set = 0;
|
||||
bool ps_pos_x = false;
|
||||
bool ps_pos_y = false;
|
||||
bool ps_pos_xy = false;
|
||||
bool ps_pos_z = false;
|
||||
bool ps_pos_w = false;
|
||||
bool ps_front_face = false;
|
||||
bool ps_no_perspective = false;
|
||||
bool ps_pixel_kill_enable = false;
|
||||
bool ps_depth_export_enable = false;
|
||||
bool ps_sample_mask_export_enable = false;
|
||||
bool ps_early_z = false;
|
||||
bool ps_execute_on_noop = false;
|
||||
ShaderStageRuntime stage;
|
||||
uint32_t interpolator_settings[32] = {0};
|
||||
uint32_t input_num = 0;
|
||||
uint32_t ps_system_input_base = 0;
|
||||
uint8_t target_output_mode[8] = {};
|
||||
std::array<Prospero::ColorComponentMapping, 8> target_export_mapping = {};
|
||||
uint32_t mrt_output_mask = 0;
|
||||
uint32_t descriptor_set = 0;
|
||||
bool ps_pos_x = false;
|
||||
bool ps_pos_y = false;
|
||||
bool ps_pos_xy = false;
|
||||
bool ps_pos_z = false;
|
||||
bool ps_pos_w = false;
|
||||
bool ps_front_face = false;
|
||||
bool ps_no_perspective = false;
|
||||
bool ps_pixel_kill_enable = false;
|
||||
bool ps_depth_export_enable = false;
|
||||
bool ps_sample_mask_export_enable = false;
|
||||
bool ps_early_z = false;
|
||||
bool ps_execute_on_noop = false;
|
||||
ShaderStageRuntime stage;
|
||||
|
||||
bool HasPositionInput() const { return ps_pos_x || ps_pos_y || ps_pos_z || ps_pos_w; }
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user