mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +00:00
buffer_cache: Make ReadMemory thread-safe
This commit is contained in:
parent
bc148d0701
commit
ec6fc48049
@ -73,6 +73,20 @@ Liverpool::~Liverpool() {
|
|||||||
process_thread.join();
|
process_thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Liverpool::ProcessCommands() {
|
||||||
|
// Process incoming commands with high priority
|
||||||
|
while (num_commands) {
|
||||||
|
Common::UniqueFunction<void> callback{};
|
||||||
|
{
|
||||||
|
std::unique_lock lk{submit_mutex};
|
||||||
|
callback = std::move(command_queue.front());
|
||||||
|
command_queue.pop();
|
||||||
|
--num_commands;
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Liverpool::Process(std::stop_token stoken) {
|
void Liverpool::Process(std::stop_token stoken) {
|
||||||
Common::SetCurrentThreadName("shadPS4:GpuCommandProcessor");
|
Common::SetCurrentThreadName("shadPS4:GpuCommandProcessor");
|
||||||
|
|
||||||
@ -91,18 +105,7 @@ void Liverpool::Process(std::stop_token stoken) {
|
|||||||
curr_qid = -1;
|
curr_qid = -1;
|
||||||
|
|
||||||
while (num_submits || num_commands) {
|
while (num_submits || num_commands) {
|
||||||
|
ProcessCommands();
|
||||||
// Process incoming commands with high priority
|
|
||||||
while (num_commands) {
|
|
||||||
Common::UniqueFunction<void> callback{};
|
|
||||||
{
|
|
||||||
std::unique_lock lk{submit_mutex};
|
|
||||||
callback = std::move(command_queue.front());
|
|
||||||
command_queue.pop();
|
|
||||||
--num_commands;
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
curr_qid = (curr_qid + 1) % num_mapped_queues;
|
curr_qid = (curr_qid + 1) % num_mapped_queues;
|
||||||
|
|
||||||
@ -148,6 +151,8 @@ Liverpool::Task Liverpool::ProcessCeUpdate(std::span<const u32> ccb) {
|
|||||||
FIBER_ENTER(ccb_task_name);
|
FIBER_ENTER(ccb_task_name);
|
||||||
|
|
||||||
while (!ccb.empty()) {
|
while (!ccb.empty()) {
|
||||||
|
ProcessCommands();
|
||||||
|
|
||||||
const auto* header = reinterpret_cast<const PM4Header*>(ccb.data());
|
const auto* header = reinterpret_cast<const PM4Header*>(ccb.data());
|
||||||
const u32 type = header->type;
|
const u32 type = header->type;
|
||||||
if (type != 3) {
|
if (type != 3) {
|
||||||
@ -228,6 +233,8 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||||||
const auto* header = reinterpret_cast<const PM4Header*>(dcb.data());
|
const auto* header = reinterpret_cast<const PM4Header*>(dcb.data());
|
||||||
const u32 type = header->type;
|
const u32 type = header->type;
|
||||||
|
|
||||||
|
ProcessCommands();
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Wrong PM4 type {}", type);
|
UNREACHABLE_MSG("Wrong PM4 type {}", type);
|
||||||
@ -815,6 +822,8 @@ Liverpool::Task Liverpool::ProcessCompute(const u32* acb, u32 acb_dwords, u32 vq
|
|||||||
|
|
||||||
auto base_addr = reinterpret_cast<VAddr>(acb);
|
auto base_addr = reinterpret_cast<VAddr>(acb);
|
||||||
while (acb_dwords > 0) {
|
while (acb_dwords > 0) {
|
||||||
|
ProcessCommands();
|
||||||
|
|
||||||
auto* header = reinterpret_cast<const PM4Header*>(acb);
|
auto* header = reinterpret_cast<const PM4Header*>(acb);
|
||||||
u32 next_dw_off = header->type3.NumWords() + 1;
|
u32 next_dw_off = header->type3.NumWords() + 1;
|
||||||
|
|
||||||
|
@ -1587,6 +1587,7 @@ private:
|
|||||||
template <bool is_indirect = false>
|
template <bool is_indirect = false>
|
||||||
Task ProcessCompute(const u32* acb, u32 acb_dwords, u32 vqid);
|
Task ProcessCompute(const u32* acb, u32 acb_dwords, u32 vqid);
|
||||||
|
|
||||||
|
void ProcessCommands();
|
||||||
void Process(std::stop_token stoken);
|
void Process(std::stop_token stoken);
|
||||||
|
|
||||||
struct GpuQueue {
|
struct GpuQueue {
|
||||||
|
@ -140,14 +140,22 @@ void BufferCache::InvalidateMemory(VAddr device_addr, u64 size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BufferCache::ReadMemory(VAddr device_addr, u64 size) {
|
void BufferCache::ReadMemory(VAddr device_addr, u64 size) {
|
||||||
ForEachBufferInRange(device_addr, size, [this, device_addr, size](BufferId buffer_id, Buffer& buffer) {
|
if (!memory_tracker.IsRegionGpuModified(device_addr, size)) {
|
||||||
const VAddr buffer_start = buffer.CpuAddr();
|
return;
|
||||||
const VAddr buffer_end = buffer_start + buffer.SizeBytes();
|
}
|
||||||
const VAddr download_start = std::max(buffer_start, device_addr);
|
std::binary_semaphore sem{0};
|
||||||
const VAddr download_end = std::min(buffer_end, device_addr + size);
|
liverpool->SendCommand([this, &sem, device_addr, size] {
|
||||||
const u64 download_size = download_end - download_start;
|
ForEachBufferInRange(device_addr, size, [this, device_addr, size](BufferId buffer_id, Buffer& buffer) {
|
||||||
DownloadBufferMemory(buffer, download_start, download_size);
|
const VAddr buffer_start = buffer.CpuAddr();
|
||||||
|
const VAddr buffer_end = buffer_start + buffer.SizeBytes();
|
||||||
|
const VAddr download_start = std::max(buffer_start, device_addr);
|
||||||
|
const VAddr download_end = std::min(buffer_end, device_addr + size);
|
||||||
|
const u64 download_size = download_end - download_start;
|
||||||
|
DownloadBufferMemory(buffer, download_start, download_size);
|
||||||
|
});
|
||||||
|
sem.release();
|
||||||
});
|
});
|
||||||
|
sem.acquire();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferCache::DownloadBufferMemory(const Buffer& buffer, VAddr device_addr, u64 size) {
|
void BufferCache::DownloadBufferMemory(const Buffer& buffer, VAddr device_addr, u64 size) {
|
||||||
|
@ -488,7 +488,7 @@ bool Rasterizer::BindResources(const Pipeline* pipeline) {
|
|||||||
uses_dma |= stage->dma_types != Shader::IR::Type::Void;
|
uses_dma |= stage->dma_types != Shader::IR::Type::Void;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uses_dma && !fault_process_pending) {
|
if (uses_dma) {
|
||||||
// We only use fault buffer for DMA right now.
|
// We only use fault buffer for DMA right now.
|
||||||
{
|
{
|
||||||
// TODO: GPU might have written to memory (for example with EVENT_WRITE_EOP)
|
// TODO: GPU might have written to memory (for example with EVENT_WRITE_EOP)
|
||||||
|
Loading…
Reference in New Issue
Block a user