diff --git a/src/common/config.cpp b/src/common/config.cpp index 4a806b2e..afabba03 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -18,6 +18,7 @@ std::string logType = "sync"; bool isDebugDump = false; bool isLibc = true; bool isShowSplash = false; +bool isNullGpu = false; bool isLleLibc() { return isLibc; @@ -54,6 +55,10 @@ bool showSplash() { return isShowSplash; } +bool nullGpu() { + return isNullGpu; +} + void load(const std::filesystem::path& path) { // If the configuration file does not exist, create it and return std::error_code error; @@ -90,6 +95,7 @@ void load(const std::filesystem::path& path) { screenWidth = toml::find_or(gpu, "screenWidth", screenWidth); screenHeight = toml::find_or(gpu, "screenHeight", screenHeight); gpuId = toml::find_or(gpu, "gpuId", 0); + isNullGpu = toml::find_or(gpu, "nullGpu", false); } } if (data.contains("Debug")) { @@ -135,6 +141,7 @@ void save(const std::filesystem::path& path) { data["GPU"]["gpuId"] = gpuId; data["GPU"]["screenWidth"] = screenWidth; data["GPU"]["screenHeight"] = screenHeight; + data["GPU"]["nullGpu"] = isNullGpu; data["Debug"]["DebugDump"] = isDebugDump; data["LLE"]["libc"] = isLibc; diff --git a/src/common/config.h b/src/common/config.h index 7a8c3358..803e9409 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -21,5 +21,6 @@ s32 getGpuId(); bool debugDump(); bool isLleLibc(); bool showSplash(); +bool nullGpu(); }; // namespace Config diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index b1181647..a3cf2a98 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -1429,9 +1429,12 @@ s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[ for (auto cbpair = 0u; cbpair < count; ++cbpair) { const auto* ccb = ccb_gpu_addrs ? ccb_gpu_addrs[cbpair] : nullptr; - const auto ccb_size = ccb_sizes_in_bytes ? ccb_sizes_in_bytes[cbpair] : 0; + const auto ccb_size_in_bytes = ccb_sizes_in_bytes ? ccb_sizes_in_bytes[cbpair] : 0; - liverpool->SubmitGfx({dcb_gpu_addrs[cbpair], dcb_sizes_in_bytes[cbpair]}, {ccb, ccb_size}); + const auto dcb_size_dw = dcb_sizes_in_bytes[cbpair] >> 2; + const auto ccb_size_dw = ccb_size_in_bytes >> 2; + + liverpool->SubmitGfx({dcb_gpu_addrs[cbpair], dcb_size_dw}, {ccb, ccb_size_dw}); } return ORBIS_OK; diff --git a/src/core/platform.h b/src/core/platform.h index 60baee6e..c8cc2a4f 100644 --- a/src/core/platform.h +++ b/src/core/platform.h @@ -26,7 +26,6 @@ enum class InterruptId : u32 { Compute6RelMem = 6u, GfxEop = 7u, GfxFlip = 8u, - MaxValue }; using IrqHandler = std::function; @@ -81,7 +80,7 @@ private: std::queue one_time_subscribers{}; std::mutex m_lock{}; }; - std::array irq_contexts{}; + std::array()> irq_contexts{}; }; using IrqC = Common::Singleton; diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 89c54831..09c1cb66 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -34,10 +34,15 @@ void Liverpool::Process(std::stop_token stoken) { gfx_ring.pop(); } - ASSERT_MSG(dcb.size() != 0, "Empty command list received"); - ProcessCmdList(dcb.data(), dcb.size()); + ASSERT_MSG(!dcb.empty(), "Empty command list received"); + ProcessCmdList(dcb.data(), dcb.size_bytes()); - cv_complete.notify_all(); + { + std::unique_lock lock{m_ring_access}; + if (gfx_ring.empty()) { + cv_complete.notify_all(); + } + } } } @@ -108,7 +113,9 @@ void Liverpool::ProcessCmdList(const u32* cmdbuf, u32 size_in_bytes) { regs.index_base_address.base_addr_hi.Assign(draw_index->index_base_hi); regs.num_indices = draw_index->index_count; regs.draw_initiator = draw_index->draw_initiator; - rasterizer->DrawIndex(); + if (rasterizer) { + rasterizer->DrawIndex(); + } break; } case PM4ItOpcode::DrawIndexAuto: { diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index 78526569..f0a27bb1 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -644,7 +644,7 @@ private: void ProcessCmdList(const u32* cmdbuf, u32 size_in_bytes); void Process(std::stop_token stoken); - Vulkan::Rasterizer* rasterizer; + Vulkan::Rasterizer* rasterizer{}; std::jthread process_thread{}; std::queue> gfx_ring{}; std::condition_variable_any cv_submit{}; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index f9c8a9a8..5f5d3d4e 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/config.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" @@ -19,7 +20,9 @@ Rasterizer::Rasterizer(const Instance& instance_, Scheduler& scheduler_, : instance{instance_}, scheduler{scheduler_}, texture_cache{texture_cache_}, liverpool{liverpool_}, pipeline_cache{instance, scheduler, liverpool}, vertex_index_buffer{instance, scheduler, VertexIndexFlags, 64_MB} { - liverpool->BindRasterizer(this); + if (!Config::nullGpu()) { + liverpool->BindRasterizer(this); + } } Rasterizer::~Rasterizer() = default;