mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-21 11:26:56 +02:00
Clamp compute LDS to the device limit and ignore unopenable gamepads
This commit is contained in:
@@ -658,6 +658,19 @@ ShaderProgram PipelineCache::GetComputeProgram(const HW::ComputeShaderInfo& regs
|
|||||||
ShaderComputeInputInfo& input_info) {
|
ShaderComputeInputInfo& input_info) {
|
||||||
input_info.host_subgroup_size = m_graphics.SupportsComputeWave64() ? 64u : 32u;
|
input_info.host_subgroup_size = m_graphics.SupportsComputeWave64() ? 64u : 32u;
|
||||||
const auto params = PrepareProgram(regs, sh, input_info);
|
const auto params = PrepareProgram(regs, sh, input_info);
|
||||||
|
// Use one effective size for the cache key, LDS declaration, and access bounds.
|
||||||
|
const auto max_lds_dwords =
|
||||||
|
m_graphics.GetPhysicalDeviceProperties().limits.maxComputeSharedMemorySize / 4u;
|
||||||
|
if (input_info.lds_size_dwords > max_lds_dwords) {
|
||||||
|
static std::atomic_bool warned = false;
|
||||||
|
if (!warned.exchange(true, std::memory_order_relaxed)) {
|
||||||
|
PipelineCacheLog("GPU warning: game compute shader requests {} bytes of LDS, but "
|
||||||
|
"the Vulkan device limit is {} bytes. Clamping LDS; rendering may "
|
||||||
|
"be incorrect.",
|
||||||
|
input_info.lds_size_dwords * 4u, max_lds_dwords * 4u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input_info.lds_size_dwords = std::min(input_info.lds_size_dwords, max_lds_dwords);
|
||||||
uint32_t push_data_cursor = 0;
|
uint32_t push_data_cursor = 0;
|
||||||
return m_program_cache->Get(params, input_info, push_data_cursor);
|
return m_program_cache->Get(params, input_info, push_data_cursor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -306,14 +306,20 @@ static void GameEventController([[maybe_unused]] const EventController& f) {
|
|||||||
|
|
||||||
if (f.added) {
|
if (f.added) {
|
||||||
auto* pad = SDL_OpenGamepad(f.id);
|
auto* pad = SDL_OpenGamepad(f.id);
|
||||||
EXIT_NOT_IMPLEMENTED(pad == nullptr);
|
if (pad == nullptr) {
|
||||||
|
LOGF("Controller: ignoring gamepad %d that could not be opened: %s\n", f.id,
|
||||||
|
SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
int id = SDL_GetJoystickID(SDL_GetGamepadJoystick(pad));
|
int id = SDL_GetJoystickID(SDL_GetGamepadJoystick(pad));
|
||||||
Controller::Connect(id);
|
Controller::Connect(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.removed) {
|
if (f.removed) {
|
||||||
Controller::Disconnect(f.id);
|
if (auto* pad = SDL_GetGamepadFromID(f.id); pad != nullptr) {
|
||||||
SDL_CloseGamepad(SDL_GetGamepadFromID(f.id));
|
Controller::Disconnect(f.id);
|
||||||
|
SDL_CloseGamepad(pad);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f.down || f.up) {
|
if (f.down || f.up) {
|
||||||
|
|||||||
@@ -31769,6 +31769,54 @@ std::vector<GraphicsCase> MakeGraphicsCases() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckComputeLdsLimit(VulkanHarness &vulkan) {
|
||||||
|
constexpr const char *name = "ComputeLdsLimit";
|
||||||
|
std::vector<u32> code;
|
||||||
|
AppendVMovU32(&code, 1, 7);
|
||||||
|
code.push_back(EncodeDs0(0x0d)); // ds_write_b32 v0, v1
|
||||||
|
code.push_back(EncodeDs1(0, 1, 0));
|
||||||
|
AppendEnd(&code);
|
||||||
|
ShaderMapUserData(reinterpret_cast<uint64_t>(code.data()),
|
||||||
|
{.type = Prospero::ShaderBinaryType::kCs,
|
||||||
|
.code_size_bytes = static_cast<u32>(code.size() * sizeof(u32))});
|
||||||
|
|
||||||
|
GraphicContext graphics;
|
||||||
|
graphics.device = vulkan.Device();
|
||||||
|
graphics.physical_device_properties =
|
||||||
|
vulkan.RuntimeContext().GetPhysicalDeviceProperties();
|
||||||
|
auto &limit = graphics.physical_device_properties.limits.maxComputeSharedMemorySize;
|
||||||
|
// Reproduce a 48-KiB host, or a smaller host limit when the test device requires it.
|
||||||
|
limit = std::min(limit, 48u * 1024u) & ~511u;
|
||||||
|
const auto limit_units = static_cast<uint16_t>(limit / 512u);
|
||||||
|
HW::ComputeShaderInfo regs{};
|
||||||
|
regs.cs_regs.data_addr = reinterpret_cast<uint64_t>(code.data());
|
||||||
|
regs.cs_regs.num_thread_x = 1;
|
||||||
|
regs.cs_regs.num_thread_y = 1;
|
||||||
|
regs.cs_regs.num_thread_z = 1;
|
||||||
|
regs.cs_regs.wave_size = 32;
|
||||||
|
PipelineCache cache(graphics);
|
||||||
|
ShaderProgram at_limit;
|
||||||
|
for (const auto units : {static_cast<uint16_t>(limit_units - 1u), limit_units,
|
||||||
|
uint16_t{112}, uint16_t{128}}) {
|
||||||
|
regs.cs_regs.lds_size = units;
|
||||||
|
ShaderComputeInputInfo input{};
|
||||||
|
const auto program = cache.GetComputeProgram(regs, {}, input);
|
||||||
|
const auto expected = units < limit_units ? units * 128u : limit / 4u;
|
||||||
|
Require(name, "device allocation", input.lds_size_dwords == expected,
|
||||||
|
"compute LDS allocation did not respect the device limit");
|
||||||
|
Require(name, "pipeline creation",
|
||||||
|
cache.GetComputePipeline(input, program).pipeline != nullptr,
|
||||||
|
"clamped LDS shader did not create a Vulkan compute pipeline");
|
||||||
|
if (units == limit_units) {
|
||||||
|
at_limit = program;
|
||||||
|
} else if (units > limit_units) {
|
||||||
|
Require(name, "effective-size cache reuse", program.id == at_limit.id,
|
||||||
|
"equivalent clamped LDS allocations compiled separate shaders");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::printf("[gpu] %-32s ok\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
void CheckPs5GameExampleImageClearRuntimeShape() {
|
void CheckPs5GameExampleImageClearRuntimeShape() {
|
||||||
const auto MakeCode = [] {
|
const auto MakeCode = [] {
|
||||||
std::vector<u32> code;
|
std::vector<u32> code;
|
||||||
@@ -36397,6 +36445,14 @@ int main(int argc, char **argv) {
|
|||||||
std::setvbuf(stdout, nullptr, _IONBF, 0);
|
std::setvbuf(stdout, nullptr, _IONBF, 0);
|
||||||
EnsureConfigInitialized();
|
EnsureConfigInitialized();
|
||||||
CheckLeastRecentlyUsedCacheOrdering();
|
CheckLeastRecentlyUsedCacheOrdering();
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--lds-limit-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
CheckComputeLdsLimit(vulkan);
|
||||||
|
RunCase(&vulkan, DsWideLdsPartialBounds());
|
||||||
|
RunCase(&vulkan, DsAtomic64Bounds(false));
|
||||||
|
RunCase(&vulkan, DsAtomic64Bounds(true));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--new-opcodes-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--new-opcodes-only") == 0) {
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
RunCase(&vulkan, VectorCompareInteger64Edges());
|
RunCase(&vulkan, VectorCompareInteger64Edges());
|
||||||
@@ -37130,6 +37186,7 @@ int main(int argc, char **argv) {
|
|||||||
vulkan.CheckStreamBufferRing();
|
vulkan.CheckStreamBufferRing();
|
||||||
vulkan.CheckGpuTilerCpuParity();
|
vulkan.CheckGpuTilerCpuParity();
|
||||||
vulkan.CheckNativeIndirectDispatch();
|
vulkan.CheckNativeIndirectDispatch();
|
||||||
|
CheckComputeLdsLimit(vulkan);
|
||||||
vulkan.CheckUnifiedTextureCacheFlow();
|
vulkan.CheckUnifiedTextureCacheFlow();
|
||||||
vulkan.CheckUnifiedImageViewCache();
|
vulkan.CheckUnifiedImageViewCache();
|
||||||
vulkan.CheckPackedTextureComponents();
|
vulkan.CheckPackedTextureComponents();
|
||||||
|
|||||||
Reference in New Issue
Block a user