mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-08-18 22:42:23 +00:00
agc: new abi
This commit is contained in:
@@ -4441,6 +4441,11 @@ void GraphicsInitJmpTablesUcIndirect() {
|
||||
r.vertex_group_size = KYTY_PM4_GET(value, GE_CNTL, VERT_GRP_SIZE);
|
||||
cp.GetUcfg().SetGeControl(r);
|
||||
};
|
||||
g_hw_uc_indirect_func[Pm4::GE_PC_ALLOC] = [](KYTY_HW_UC_INDIRECT_ARGS) {
|
||||
(void)cp;
|
||||
(void)cmd_offset;
|
||||
(void)value;
|
||||
};
|
||||
|
||||
g_hw_uc_indirect_func[Pm4::GE_USER_VGPR_EN] = [](KYTY_HW_UC_INDIRECT_ARGS) {
|
||||
HW::GeUserVgprEn r;
|
||||
|
||||
@@ -1047,6 +1047,7 @@ constexpr uint32_t GE_USER_VGPR1 = 0x25C;
|
||||
constexpr uint32_t GE_USER_VGPR2 = 0x25D;
|
||||
constexpr uint32_t GE_USER_VGPR3 = 0x25E;
|
||||
constexpr uint32_t GE_STEREO_CNTL = 0x25F;
|
||||
constexpr uint32_t GE_PC_ALLOC = 0x260;
|
||||
|
||||
constexpr uint32_t GE_USER_VGPR_EN = 0x262;
|
||||
constexpr uint32_t GE_USER_VGPR_EN_EN_USER_VGPR1_SHIFT = 0;
|
||||
|
||||
+91
-1
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
@@ -1180,6 +1181,95 @@ int KYTY_SYSV_ABI GraphicsUpdatePrimState(ShaderRegister* cx_regs, ShaderRegiste
|
||||
return OK;
|
||||
}
|
||||
|
||||
struct GsOccupancyLimits {
|
||||
uint32_t vertex;
|
||||
uint32_t export_count;
|
||||
};
|
||||
|
||||
static GsOccupancyLimits get_gs_occupancy_limits(const Shader* gs, uint32_t vertex_capacity,
|
||||
uint32_t export_capacity) {
|
||||
const auto* onchip =
|
||||
find_shader_register(gs->cx_registers, gs->num_cx_registers, Pm4::VGT_GS_ONCHIP_CNTL);
|
||||
const auto* subgroup =
|
||||
find_shader_register(gs->cx_registers, gs->num_cx_registers, Pm4::GE_NGG_SUBGRP_CNTL);
|
||||
const auto* vs_out =
|
||||
find_shader_register(gs->cx_registers, gs->num_cx_registers, Pm4::SPI_VS_OUT_CONFIG);
|
||||
const auto* cl_out =
|
||||
find_shader_register(gs->cx_registers, gs->num_cx_registers, Pm4::PA_CL_VS_OUT_CNTL);
|
||||
const auto* max_output = find_shader_register(gs->cx_registers, gs->num_cx_registers,
|
||||
Pm4::GE_MAX_OUTPUT_PER_SUBGROUP);
|
||||
|
||||
const uint32_t output_words = ((max_output->value & 0x3ffu) + 31u) >> 5u;
|
||||
const uint32_t subgroup_work =
|
||||
((((onchip->value >> 11u) & 0x7ffu) * (subgroup->value & 0x1ffu)) + 31u) >> 5u;
|
||||
uint32_t waves = std::max(subgroup_work, output_words);
|
||||
if ((gs->specials->vgt_shader_stages_en.value & 0x00400000u) == 0) {
|
||||
waves >>= 1u;
|
||||
}
|
||||
waves = std::max(waves, 1u);
|
||||
|
||||
const uint32_t exports = 1u + ((cl_out->value >> 21u) & 1u) + ((cl_out->value >> 22u) & 1u) +
|
||||
((cl_out->value >> 23u) & 1u);
|
||||
const uint32_t export_limit = (export_capacity / exports) * 4u;
|
||||
const uint32_t vertex_limit = (vs_out->value & 0x80u) != 0
|
||||
? 2048u
|
||||
: vertex_capacity / (((vs_out->value >> 2u) & 0xfu) + 1u);
|
||||
|
||||
return {waves * (vertex_limit / output_words), waves * (export_limit / output_words)};
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsGetGsOversubscription(ShaderRegister* regs, const Shader* gs,
|
||||
uint32_t budget, float factor) {
|
||||
PRINT_NAME();
|
||||
|
||||
constexpr uint32_t FULL_PC_OVERSUBSCRIPTION = 0x7ffu;
|
||||
constexpr uint32_t FULL_SH_OVERSUBSCRIPTION = 0x007f0000u;
|
||||
|
||||
regs[0] = {Pm4::GE_PC_ALLOC, 0u};
|
||||
regs[1] = {Pm4::SPI_SHADER_PGM_RSRC4_GS, 0u};
|
||||
|
||||
if (budget == 0u) {
|
||||
return OK;
|
||||
}
|
||||
if (budget == UINT32_MAX) {
|
||||
regs[0].value |= FULL_PC_OVERSUBSCRIPTION;
|
||||
regs[1].value |= FULL_SH_OVERSUBSCRIPTION;
|
||||
return OK;
|
||||
}
|
||||
|
||||
const auto base = get_gs_occupancy_limits(gs, 1024u, 128u);
|
||||
const auto expanded = get_gs_occupancy_limits(gs, 2048u, 382u);
|
||||
const auto base_min = std::min(base.vertex, base.export_count);
|
||||
const auto limit_shift =
|
||||
(gs->specials->vgt_shader_stages_en.value & 0x00400000u) != 0 ? 5u : 6u;
|
||||
const auto expanded_limit =
|
||||
std::min({expanded.vertex, expanded.export_count, budget >> limit_shift, 1024u});
|
||||
const auto headroom = expanded_limit > base_min ? expanded_limit - base_min : 0u;
|
||||
const auto target = static_cast<uint32_t>(
|
||||
std::fma(factor, static_cast<float>(headroom), static_cast<float>(base_min)));
|
||||
|
||||
if (target <= base_min) {
|
||||
return OK;
|
||||
}
|
||||
if (target < base.export_count) {
|
||||
const auto range = std::max(expanded.vertex - base.vertex, 1u);
|
||||
auto value = static_cast<uint32_t>(
|
||||
std::min((static_cast<uint64_t>(target - base.vertex) << 10u) / range, 1024ull));
|
||||
value = std::max(value, 1u);
|
||||
regs[0].value = (regs[0].value & ~FULL_PC_OVERSUBSCRIPTION) |
|
||||
(((value << 1u) - 1u) & FULL_PC_OVERSUBSCRIPTION);
|
||||
regs[1].value |= FULL_SH_OVERSUBSCRIPTION;
|
||||
} else {
|
||||
const auto range = std::max(expanded.export_count - base.export_count, 1u);
|
||||
const auto value = static_cast<uint32_t>(
|
||||
std::min((static_cast<uint64_t>(target - base.export_count) * 127u) / range, 127ull));
|
||||
regs[0].value |= FULL_PC_OVERSUBSCRIPTION;
|
||||
regs[1].value = (regs[1].value & ~FULL_SH_OVERSUBSCRIPTION) | (value << 16u);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static uint32_t shader_semantic_word(const ShaderSemantic& semantic) {
|
||||
return ((semantic.semantic & 0xffu) << 0u) | ((semantic.hardware_mapping & 0xffu) << 8u) |
|
||||
((semantic.size_in_elements & 0xfu) << 16u) | ((semantic.is_f16 & 0x3u) << 20u) |
|
||||
@@ -1466,7 +1556,7 @@ uint32_t* KYTY_SYSV_ABI GraphicsDcbContextStateOp(CommandBuffer* buf, uint32_t o
|
||||
|
||||
buf->DbgDump();
|
||||
|
||||
uint32_t* first = nullptr;
|
||||
uint32_t* first = nullptr;
|
||||
const auto append = [&](uint32_t segment_size_dw) {
|
||||
auto* segment = buf->AllocateDW(segment_size_dw);
|
||||
if (segment == nullptr) {
|
||||
|
||||
@@ -56,6 +56,8 @@ int KYTY_SYSV_ABI GraphicsCreatePrimState(ShaderRegister* cx_regs, ShaderRegis
|
||||
const Shader* hs, const Shader* gs, uint32_t prim_type);
|
||||
int KYTY_SYSV_ABI GraphicsUpdatePrimState(ShaderRegister* cx_regs, ShaderRegister* uc_regs,
|
||||
uint32_t prim_type);
|
||||
int KYTY_SYSV_ABI GraphicsGetGsOversubscription(ShaderRegister* regs, const Shader* gs,
|
||||
uint32_t budget, float factor);
|
||||
int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const Shader* gs,
|
||||
const Shader* ps);
|
||||
int KYTY_SYSV_ABI GraphicsGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type);
|
||||
|
||||
@@ -171,6 +171,7 @@ LIB_DEFINE(InitGraphicsDriver_1) {
|
||||
LIB_FUNC("vRoArM9zaIk", Gen5::GraphicsSetUcRegIndirectPatchAddRegisters);
|
||||
LIB_FUNC("D9sr1xGUriE", Gen5::GraphicsCreatePrimState);
|
||||
LIB_FUNC("Y3ymLfZ1384", Gen5::GraphicsUpdatePrimState);
|
||||
LIB_FUNC("NKIzURsgV7I", Gen5::GraphicsGetGsOversubscription);
|
||||
LIB_FUNC("HV4j+E0MBHE", Gen5::GraphicsCreateInterpolantMapping);
|
||||
LIB_FUNC("V++UgBtQhn0", Gen5::GraphicsGetDataPacketPayloadAddress);
|
||||
LIB_FUNC("s+VGAMDQ0AQ", Gen5::GraphicsGetDataPacketPayloadRange);
|
||||
|
||||
Reference in New Issue
Block a user