mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-26 12:56:54 +01:00
fix graphical bug (PPSA17221)
This commit is contained in:
@@ -65,10 +65,23 @@ constexpr uint32_t GcrKnownMask = GcrGl2MetadataInvalidate | GcrGl0V
|
|||||||
GcrGl2Writeback | GcrOrder012 | GcrOrder210;
|
GcrGl2Writeback | GcrOrder012 | GcrOrder210;
|
||||||
constexpr uint32_t RegisterSelectorMask = 0x70000000u;
|
constexpr uint32_t RegisterSelectorMask = 0x70000000u;
|
||||||
|
|
||||||
uint32_t NormalizeRegisterOffset(uint32_t raw_offset) {
|
constexpr uint32_t NormalizeRegisterOffset(uint32_t raw_offset) {
|
||||||
return (raw_offset & ~RegisterSelectorMask);
|
return raw_offset & ~RegisterSelectorMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Indirect Cx descriptors retain their selector. Selector 1 offsets 0..31 address the
|
||||||
|
// SPI_PS_INPUT_CNTL register bank; ordinary context-register offsets remain unchanged.
|
||||||
|
constexpr uint32_t DecodeIndirectCxRegisterOffset(uint32_t raw_offset) {
|
||||||
|
const auto offset = NormalizeRegisterOffset(raw_offset);
|
||||||
|
return (raw_offset & RegisterSelectorMask) == Pm4::CX_PS_SHADER_USAGE_BASE && offset < 32u
|
||||||
|
? Pm4::SPI_PS_INPUT_CNTL_0 + offset
|
||||||
|
: offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(DecodeIndirectCxRegisterOffset(Pm4::CX_PS_SHADER_USAGE_BASE + 2u) ==
|
||||||
|
Pm4::SPI_PS_INPUT_CNTL_0 + 2u);
|
||||||
|
static_assert(DecodeIndirectCxRegisterOffset(Pm4::DB_Z_INFO) == Pm4::DB_Z_INFO);
|
||||||
|
|
||||||
bool ReleaseMemGcrNeedsBarrier(uint32_t eop_event_type, uint32_t gcr_cntl) {
|
bool ReleaseMemGcrNeedsBarrier(uint32_t eop_event_type, uint32_t gcr_cntl) {
|
||||||
return eop_event_type != 0x28u ||
|
return eop_event_type != 0x28u ||
|
||||||
(gcr_cntl & (GcrGl2MetadataInvalidate | GcrGl0VectorInvalidate | GcrGl1Invalidate |
|
(gcr_cntl & (GcrGl2MetadataInvalidate | GcrGl0VectorInvalidate | GcrGl1Invalidate |
|
||||||
@@ -2321,14 +2334,18 @@ KYTY_CP_OP_PARSER(CpOpIndirectCxRegs) {
|
|||||||
EXIT("indirect CX registers have null address, num_regs = %" PRIu32 "\n", indirect_num_dw);
|
EXIT("indirect CX registers have null address, num_regs = %" PRIu32 "\n", indirect_num_dw);
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < indirect_num_dw; i++, indirect_buffer += 2) {
|
for (uint32_t i = 0; i < indirect_num_dw; i++, indirect_buffer += 2) {
|
||||||
auto cmd_offset = indirect_buffer[0];
|
// Keep the encoded offset for packet control values, and use the decoded offset only
|
||||||
auto value = indirect_buffer[1];
|
// for register dispatch.
|
||||||
|
auto raw_cmd_offset = indirect_buffer[0];
|
||||||
|
auto cmd_offset = DecodeIndirectCxRegisterOffset(raw_cmd_offset);
|
||||||
|
auto value = indirect_buffer[1];
|
||||||
|
|
||||||
if (HwCtxTrySetFakeRegister(cmd_offset, value)) {
|
if (HwCtxTrySetFakeRegister(cmd_offset, value)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd_offset == 0xffffffffu) {
|
// The sentinel is an encoded descriptor value and must be checked before normalization.
|
||||||
|
if (raw_cmd_offset == 0xffffffffu) {
|
||||||
static bool logged = false;
|
static bool logged = false;
|
||||||
if (!logged) {
|
if (!logged) {
|
||||||
LOGF("\t temporary: skipping indirect CX sentinel pair offset = 0xffffffff, value "
|
LOGF("\t temporary: skipping indirect CX sentinel pair offset = 0xffffffff, value "
|
||||||
|
|||||||
@@ -385,6 +385,9 @@ constexpr uint32_t SPI_SHADER_POS_FORMAT = 0x1C3;
|
|||||||
constexpr uint32_t SPI_SHADER_Z_FORMAT = 0x1C4;
|
constexpr uint32_t SPI_SHADER_Z_FORMAT = 0x1C4;
|
||||||
constexpr uint32_t SPI_SHADER_COL_FORMAT = 0x1C5;
|
constexpr uint32_t SPI_SHADER_COL_FORMAT = 0x1C5;
|
||||||
|
|
||||||
|
// Indirect Cx descriptor selector for the 32-entry PS input-control register bank.
|
||||||
|
constexpr uint32_t CX_PS_SHADER_USAGE_BASE = 0x10000000u;
|
||||||
|
|
||||||
constexpr uint32_t CB_BLEND0_CONTROL = 0x1E0;
|
constexpr uint32_t CB_BLEND0_CONTROL = 0x1E0;
|
||||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_SRCBLEND_SHIFT = 0;
|
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_SRCBLEND_SHIFT = 0;
|
||||||
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_SRCBLEND_MASK = 0x1F;
|
constexpr uint32_t CB_BLEND0_CONTROL_COLOR_SRCBLEND_MASK = 0x1F;
|
||||||
|
|||||||
@@ -798,7 +798,9 @@ static void ShaderGetStaticInputInfoPS(
|
|||||||
|
|
||||||
ps_info = {};
|
ps_info = {};
|
||||||
|
|
||||||
ps_info.input_num = sh.ps_in_control;
|
// SPI_PS_IN_CONTROL.NUM_INTERP occupies bits 5:0. Keep the remaining control
|
||||||
|
// flags in the hardware state and extract only the input count here.
|
||||||
|
ps_info.input_num = sh.ps_in_control & 0x3fu;
|
||||||
ps_info.ps_system_input_base = ShaderCalcPsSystemInputBase(sh);
|
ps_info.ps_system_input_base = ShaderCalcPsSystemInputBase(sh);
|
||||||
const uint32_t active_inputs = sh.ps_input_ena & sh.ps_input_addr;
|
const uint32_t active_inputs = sh.ps_input_ena & sh.ps_input_addr;
|
||||||
ps_info.ps_pos_x = (active_inputs & 0x00000100u) != 0;
|
ps_info.ps_pos_x = (active_inputs & 0x00000100u) != 0;
|
||||||
|
|||||||
+3
-3
@@ -1217,9 +1217,9 @@ static const ShaderSemantic* find_interpolant_output_semantic(const Shader* gs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void set_interpolant_register(ShaderRegister* regs, uint32_t index, uint32_t value) {
|
static void set_interpolant_register(ShaderRegister* regs, uint32_t index, uint32_t value) {
|
||||||
// The native implementation writes a descriptor offset (0x10000000 + index). Kyty stores
|
// Interpolant mappings contain encoded Cx descriptors. Indirect PM4 ingestion resolves
|
||||||
// decoded PM4 register offsets here because direct/custom indirect paths consume them.
|
// this selector and slot to the physical SPI_PS_INPUT_CNTL register.
|
||||||
regs[index].offset = Pm4::SPI_PS_INPUT_CNTL_0 + index;
|
regs[index].offset = Pm4::CX_PS_SHADER_USAGE_BASE + index;
|
||||||
regs[index].value = value;
|
regs[index].value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user