Add support for split mappings to I2M uploads

Used by Super Mario Sunshine and other Vulkan games.
This commit is contained in:
Billy Laws 2022-10-30 16:21:13 +00:00
parent db5e208379
commit b04d18eba5
2 changed files with 16 additions and 9 deletions

View File

@ -15,24 +15,19 @@ namespace skyline::gpu::interconnect {
channelCtx{channelCtx},
executor{channelCtx.executor} {}
void Inline2Memory::Upload(IOVA dst, span<u32> src) {
auto dstMappings{channelCtx.asCtx->gmmu.TranslateRange(dst, src.size_bytes())};
if (dstMappings.size() > 1)
Logger::Warn("Split mapping are unsupported for DMA copies");
auto dstBuf{gpu.buffer.FindOrCreate(dstMappings.front(), executor.tag, [this](std::shared_ptr<Buffer> buffer, ContextLock<Buffer> &&lock) {
void Inline2Memory::UploadSingleMapping(span<u8> dst, span<u8> src) {
auto dstBuf{gpu.buffer.FindOrCreate(dst, executor.tag, [this](std::shared_ptr<Buffer> buffer, ContextLock<Buffer> &&lock) {
executor.AttachLockedBuffer(buffer, std::move(lock));
})};
ContextLock dstBufLock{executor.tag, dstBuf};
dstBuf.Write(src.cast<u8>(), 0, [&]() {
dstBuf.Write(src, 0, [&]() {
executor.AttachLockedBufferView(dstBuf, std::move(dstBufLock));
// This will prevent any CPU accesses to backing for the duration of the usage
dstBuf.GetBuffer()->BlockAllCpuBackingWrites();
auto srcGpuAllocation{gpu.megaBufferAllocator.Push(executor.cycle, src.cast<u8>())};
auto srcGpuAllocation{gpu.megaBufferAllocator.Push(executor.cycle, src)};
executor.AddOutsideRpCommand([srcGpuAllocation, dstBuf, src](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &) {
vk::BufferCopy copyRegion{
.size = src.size_bytes(),
@ -47,4 +42,14 @@ namespace skyline::gpu::interconnect {
});
});
}
void Inline2Memory::Upload(IOVA dst, span<u32> src) {
auto dstMappings{channelCtx.asCtx->gmmu.TranslateRange(dst, src.size_bytes())};
size_t offset{};
for (auto mapping : dstMappings) {
UploadSingleMapping(mapping, src.cast<u8>().subspan(offset, mapping.size()));
offset += mapping.size();
}
}
}

View File

@ -28,6 +28,8 @@ namespace skyline::gpu::interconnect {
soc::gm20b::ChannelContext &channelCtx;
gpu::interconnect::CommandExecutor &executor;
void UploadSingleMapping(span<u8> dst, span<u8> src);
public:
Inline2Memory(GPU &gpu, soc::gm20b::ChannelContext &channelCtx);