mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
liverpool: fix dmadata packet handling
This commit is contained in:
parent
3c0c921ef5
commit
ec31340b1a
@ -569,25 +569,39 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
||||
break;
|
||||
}
|
||||
if (dma_data->src_sel == DmaDataSrc::Data && dma_data->dst_sel == DmaDataDst::Gds) {
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Data ({}) -> Gds {:#x}, {} bytes",
|
||||
dma_data->data, dma_data->dst_addr_lo, dma_data->NumBytes());
|
||||
rasterizer->InlineData(dma_data->dst_addr_lo, &dma_data->data, sizeof(u32),
|
||||
true);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Memory &&
|
||||
dma_data->dst_sel == DmaDataDst::Gds) {
|
||||
rasterizer->InlineData(dma_data->dst_addr_lo,
|
||||
dma_data->SrcAddress<const void*>(),
|
||||
dma_data->NumBytes(), true);
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Memory {:#x} -> Gds {:#x}, {} bytes",
|
||||
dma_data->SrcAddress<VAddr>(), dma_data->dst_addr_lo,
|
||||
dma_data->NumBytes());
|
||||
rasterizer->CopyBuffer(dma_data->dst_addr_lo, dma_data->SrcAddress<VAddr>(),
|
||||
dma_data->NumBytes(), true, false);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Data &&
|
||||
dma_data->dst_sel == DmaDataDst::Memory) {
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Data ({}) -> Memory {:#x}, {} bytes",
|
||||
dma_data->data, dma_data->DstAddress<uintptr_t>(),
|
||||
dma_data->NumBytes());
|
||||
rasterizer->InlineData(dma_data->DstAddress<VAddr>(), &dma_data->data,
|
||||
sizeof(u32), false);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Gds &&
|
||||
dma_data->dst_sel == DmaDataDst::Memory) {
|
||||
// LOG_WARNING(Render_Vulkan, "GDS memory read");
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Gds {:#x} -> Memory {:#x}, {} bytes",
|
||||
dma_data->src_addr_lo, dma_data->DstAddress<uintptr_t>(),
|
||||
dma_data->NumBytes());
|
||||
rasterizer->CopyBuffer(dma_data->DstAddress<VAddr>(), dma_data->src_addr_lo,
|
||||
dma_data->NumBytes(), false, true);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Memory &&
|
||||
dma_data->dst_sel == DmaDataDst::Memory) {
|
||||
rasterizer->InlineData(dma_data->DstAddress<VAddr>(),
|
||||
dma_data->SrcAddress<const void*>(),
|
||||
dma_data->NumBytes(), false);
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Memory {:#x} -> Memory {:#x}, {} bytes",
|
||||
dma_data->SrcAddress<uintptr_t>(),
|
||||
dma_data->DstAddress<uintptr_t>(), dma_data->NumBytes());
|
||||
rasterizer->CopyBuffer(dma_data->DstAddress<VAddr>(),
|
||||
dma_data->SrcAddress<VAddr>(), dma_data->NumBytes(),
|
||||
false, false);
|
||||
} else {
|
||||
UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}",
|
||||
u32(dma_data->src_sel.Value()), u32(dma_data->dst_sel.Value()));
|
||||
@ -728,23 +742,37 @@ Liverpool::Task Liverpool::ProcessCompute(std::span<const u32> acb, int vqid) {
|
||||
break;
|
||||
}
|
||||
if (dma_data->src_sel == DmaDataSrc::Data && dma_data->dst_sel == DmaDataDst::Gds) {
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Data ({}) -> Gds {:#x}, {} bytes",
|
||||
dma_data->data, dma_data->dst_addr_lo, dma_data->NumBytes());
|
||||
rasterizer->InlineData(dma_data->dst_addr_lo, &dma_data->data, sizeof(u32), true);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Memory &&
|
||||
dma_data->dst_sel == DmaDataDst::Gds) {
|
||||
rasterizer->InlineData(dma_data->dst_addr_lo, dma_data->SrcAddress<const void*>(),
|
||||
dma_data->NumBytes(), true);
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Memory {:#x} -> Gds {:#x}, {} bytes",
|
||||
dma_data->SrcAddress<VAddr>(), dma_data->dst_addr_lo,
|
||||
dma_data->NumBytes());
|
||||
rasterizer->CopyBuffer(dma_data->dst_addr_lo, dma_data->SrcAddress<VAddr>(),
|
||||
dma_data->NumBytes(), true, false);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Data &&
|
||||
dma_data->dst_sel == DmaDataDst::Memory) {
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Data ({}) -> Memory {:#x}, {} bytes",
|
||||
dma_data->data, dma_data->DstAddress<uintptr_t>(),
|
||||
dma_data->NumBytes());
|
||||
rasterizer->InlineData(dma_data->DstAddress<VAddr>(), &dma_data->data, sizeof(u32),
|
||||
false);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Gds &&
|
||||
dma_data->dst_sel == DmaDataDst::Memory) {
|
||||
// LOG_WARNING(Render_Vulkan, "GDS memory read");
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Gds {:#x} -> Memory {:#x}, {} bytes",
|
||||
dma_data->src_addr_lo, dma_data->DstAddress<uintptr_t>(),
|
||||
dma_data->NumBytes());
|
||||
rasterizer->CopyBuffer(dma_data->DstAddress<VAddr>(), dma_data->src_addr_lo,
|
||||
dma_data->NumBytes(), false, true);
|
||||
} else if (dma_data->src_sel == DmaDataSrc::Memory &&
|
||||
dma_data->dst_sel == DmaDataDst::Memory) {
|
||||
rasterizer->InlineData(dma_data->DstAddress<VAddr>(),
|
||||
dma_data->SrcAddress<const void*>(), dma_data->NumBytes(),
|
||||
false);
|
||||
LOG_CRITICAL(Render_Vulkan, "DmaData Memory {:#x} -> Memory {:#x}, {} bytes",
|
||||
dma_data->SrcAddress<uintptr_t>(), dma_data->DstAddress<uintptr_t>(),
|
||||
dma_data->NumBytes());
|
||||
rasterizer->CopyBuffer(dma_data->DstAddress<VAddr>(), dma_data->SrcAddress<VAddr>(),
|
||||
dma_data->NumBytes(), false, false);
|
||||
} else {
|
||||
UNREACHABLE_MSG("WriteData src_sel = {}, dst_sel = {}",
|
||||
u32(dma_data->src_sel.Value()), u32(dma_data->dst_sel.Value()));
|
||||
|
@ -313,10 +313,10 @@ void BufferCache::InlineData(VAddr address, const void* value, u32 num_bytes, bo
|
||||
return &slot_buffers[buffer_id];
|
||||
}();
|
||||
const vk::BufferMemoryBarrier2 buf_barrier = {
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eTransfer,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eTransferWrite,
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eMemoryRead,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite,
|
||||
.buffer = buffer->Handle(),
|
||||
.offset = buffer->Offset(address),
|
||||
.size = num_bytes,
|
||||
@ -327,6 +327,78 @@ void BufferCache::InlineData(VAddr address, const void* value, u32 num_bytes, bo
|
||||
.pBufferMemoryBarriers = &buf_barrier,
|
||||
});
|
||||
cmdbuf.updateBuffer(buffer->Handle(), buf_barrier.offset, num_bytes, value);
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||
.dependencyFlags = vk::DependencyFlagBits::eByRegion,
|
||||
.bufferMemoryBarrierCount = 1,
|
||||
.pBufferMemoryBarriers = &buf_barrier,
|
||||
});
|
||||
}
|
||||
|
||||
void BufferCache::CopyBuffer(VAddr dst, VAddr src, u32 num_bytes, bool dst_gds, bool src_gds) {
|
||||
if (!dst_gds && !IsRegionRegistered(dst, num_bytes)) {
|
||||
if (src_gds || IsRegionRegistered(src, num_bytes)) {
|
||||
LOG_CRITICAL(Render_Vulkan, "readback is not implemented");
|
||||
return;
|
||||
}
|
||||
memcpy(std::bit_cast<void*>(dst), std::bit_cast<void*>(src), num_bytes);
|
||||
return;
|
||||
}
|
||||
if (!src_gds && !IsRegionRegistered(src, num_bytes)) {
|
||||
InlineData(dst, std::bit_cast<void*>(src), num_bytes, dst_gds);
|
||||
return;
|
||||
}
|
||||
auto& src_buffer = [&] -> const Buffer& {
|
||||
if (src_gds) {
|
||||
return gds_buffer;
|
||||
}
|
||||
const BufferId buffer_id = FindBuffer(src, num_bytes);
|
||||
return slot_buffers[buffer_id];
|
||||
}();
|
||||
auto& dst_buffer = [&] -> const Buffer& {
|
||||
if (dst_gds) {
|
||||
return gds_buffer;
|
||||
}
|
||||
const BufferId buffer_id = FindBuffer(dst, num_bytes);
|
||||
return slot_buffers[buffer_id];
|
||||
}();
|
||||
vk::BufferCopy region{
|
||||
.srcOffset = src_buffer.Offset(src),
|
||||
.dstOffset = dst_buffer.Offset(dst),
|
||||
.size = num_bytes,
|
||||
};
|
||||
const vk::BufferMemoryBarrier2 buf_barriers[2] = {
|
||||
{
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite,
|
||||
.buffer = dst_buffer.Handle(),
|
||||
.offset = dst_buffer.Offset(dst),
|
||||
.size = num_bytes,
|
||||
},
|
||||
{
|
||||
.srcStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.srcAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite,
|
||||
.dstStageMask = vk::PipelineStageFlagBits2::eAllCommands,
|
||||
.dstAccessMask = vk::AccessFlagBits2::eMemoryRead | vk::AccessFlagBits2::eMemoryWrite,
|
||||
.buffer = src_buffer.Handle(),
|
||||
.offset = src_buffer.Offset(src),
|
||||
.size = num_bytes,
|
||||
},
|
||||
};
|
||||
scheduler.EndRendering();
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||
.dependencyFlags = vk::DependencyFlagBits::eByRegion,
|
||||
.bufferMemoryBarrierCount = 2,
|
||||
.pBufferMemoryBarriers = buf_barriers,
|
||||
});
|
||||
cmdbuf.copyBuffer(src_buffer.Handle(), dst_buffer.Handle(), region);
|
||||
cmdbuf.pipelineBarrier2(vk::DependencyInfo{
|
||||
.dependencyFlags = vk::DependencyFlagBits::eByRegion,
|
||||
.bufferMemoryBarrierCount = 2,
|
||||
.pBufferMemoryBarriers = buf_barriers,
|
||||
});
|
||||
}
|
||||
|
||||
std::pair<Buffer*, u32> BufferCache::ObtainHostUBO(std::span<const u32> data) {
|
||||
@ -701,8 +773,22 @@ bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr,
|
||||
scheduler.EndRendering();
|
||||
image.Transit(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlagBits2::eTransferRead, {});
|
||||
const auto cmdbuf = scheduler.CommandBuffer();
|
||||
static constexpr vk::MemoryBarrier READ_BARRIER{
|
||||
.srcAccessMask = vk::AccessFlagBits::eMemoryWrite,
|
||||
.dstAccessMask = vk::AccessFlagBits::eTransferRead | vk::AccessFlagBits::eTransferWrite,
|
||||
};
|
||||
static constexpr vk::MemoryBarrier WRITE_BARRIER{
|
||||
.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
|
||||
.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite,
|
||||
};
|
||||
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
|
||||
vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::DependencyFlagBits::eByRegion, READ_BARRIER, {}, {});
|
||||
cmdbuf.copyImageToBuffer(image.image, vk::ImageLayout::eTransferSrcOptimal, buffer.buffer,
|
||||
copies);
|
||||
cmdbuf.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands,
|
||||
vk::PipelineStageFlagBits::eTransfer,
|
||||
vk::DependencyFlagBits::eByRegion, WRITE_BARRIER, {}, {});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ public:
|
||||
|
||||
/// Writes a value to GPU buffer.
|
||||
void InlineData(VAddr address, const void* value, u32 num_bytes, bool is_gds);
|
||||
void CopyBuffer(VAddr dst, VAddr src, u32 num_bytes, bool dst_gds, bool src_gds);
|
||||
|
||||
[[nodiscard]] std::pair<Buffer*, u32> ObtainHostUBO(std::span<const u32> data);
|
||||
|
||||
|
@ -263,7 +263,6 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3
|
||||
}
|
||||
|
||||
auto state = PrepareRenderState(pipeline->GetMrtMask());
|
||||
|
||||
if (!BindResources(pipeline)) {
|
||||
return;
|
||||
}
|
||||
@ -354,6 +353,9 @@ void Rasterizer::DispatchIndirect(VAddr address, u32 offset, u32 size) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_CRITICAL(Render_Vulkan, "DispatchIndirect addr = {:#x}",
|
||||
std::bit_cast<uintptr_t>(address + offset));
|
||||
|
||||
scheduler.EndRendering();
|
||||
|
||||
const auto [buffer, base] = buffer_cache.ObtainBuffer(address + offset, size, false);
|
||||
@ -840,6 +842,10 @@ void Rasterizer::InlineData(VAddr address, const void* value, u32 num_bytes, boo
|
||||
buffer_cache.InlineData(address, value, num_bytes, is_gds);
|
||||
}
|
||||
|
||||
void Rasterizer::CopyBuffer(VAddr dst, VAddr src, u32 num_bytes, bool dst_gds, bool src_gds) {
|
||||
buffer_cache.CopyBuffer(dst, src, num_bytes, dst_gds, src_gds);
|
||||
}
|
||||
|
||||
u32 Rasterizer::ReadDataFromGds(u32 gds_offset) {
|
||||
auto* gds_buf = buffer_cache.GetGdsBuffer();
|
||||
u32 value;
|
||||
|
@ -53,6 +53,7 @@ public:
|
||||
void ScopedMarkerInsertColor(const std::string_view& str, const u32 color);
|
||||
|
||||
void InlineData(VAddr address, const void* value, u32 num_bytes, bool is_gds);
|
||||
void CopyBuffer(VAddr dst, VAddr src, u32 num_bytes, bool dst_gds, bool src_gds);
|
||||
u32 ReadDataFromGds(u32 gsd_offset);
|
||||
bool InvalidateMemory(VAddr addr, u64 size);
|
||||
bool IsMapped(VAddr addr, u64 size);
|
||||
|
Loading…
Reference in New Issue
Block a user