Add support for 1D remapped buffer clears

This commit is contained in:
TheASVigilante 2023-02-19 15:19:02 +01:00 committed by Billy Laws
parent 4c3fed6cd0
commit 70ee36e85c
3 changed files with 40 additions and 0 deletions

View File

@ -52,4 +52,32 @@ namespace skyline::gpu::interconnect {
});
});
}
void MaxwellDma::Clear(span<u8> mapping, u32 value) {
if (!util::IsAligned(mapping.size(), 4))
throw exception("Cleared buffer's size is not aligned to 4 bytes!");
auto clearBuf{gpu.buffer.FindOrCreate(mapping, executor.tag, [this](std::shared_ptr<Buffer> buffer, ContextLock<Buffer> &&lock) {
executor.AttachLockedBuffer(buffer, std::move(lock));
})};
executor.AttachBuffer(clearBuf);
clearBuf.GetBuffer()->BlockSequencedCpuBackingWrites();
clearBuf.GetBuffer()->MarkGpuDirty();
executor.AddOutsideRpCommand([clearBuf, value](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &gpu) {
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer, {}, vk::MemoryBarrier{
.srcAccessMask = vk::AccessFlagBits::eMemoryRead,
.dstAccessMask = vk::AccessFlagBits::eTransferRead | vk::AccessFlagBits::eTransferWrite
}, {}, {});
auto clearBufBinding{clearBuf.GetBinding(gpu)};
commandBuffer.fillBuffer(clearBufBinding.buffer, clearBufBinding.offset, clearBufBinding.size, value);
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eTransfer, vk::PipelineStageFlagBits::eAllCommands, {}, vk::MemoryBarrier{
.srcAccessMask = vk::AccessFlagBits::eTransferWrite,
.dstAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eMemoryWrite,
}, {}, {});
});
}
}

View File

@ -30,5 +30,7 @@ namespace skyline::gpu::interconnect {
MaxwellDma(GPU &gpu, soc::gm20b::ChannelContext &channelCtx);
void Copy(span<u8> dstMapping, span<u8> srcMapping);
void Clear(span<u8> mapping, u32 value);
};
}

View File

@ -89,7 +89,17 @@ namespace skyline::soc::gm20b::engine {
auto dstMappings{channelCtx.asCtx->gmmu.TranslateRange(*registers.offsetOut, *registers.lineLengthIn * dstBpp)};
if (registers.launchDma->remapEnable) [[unlikely]] {
// Remapped buffer clears
if ((registers.remapComponents->dstX == Registers::RemapComponents::Swizzle::ConstA) &&
(registers.remapComponents->dstY == Registers::RemapComponents::Swizzle::ConstA) &&
(registers.remapComponents->dstZ == Registers::RemapComponents::Swizzle::ConstA) &&
(registers.remapComponents->dstW == Registers::RemapComponents::Swizzle::ConstA) &&
(registers.remapComponents->ComponentSize() == 4)) {
for (size_t currMapping{dstMappings.size()}; currMapping; --currMapping)
interconnect.Clear(dstMappings[currMapping], *registers.remapConstA);
} else {
Logger::Warn("Remapped DMA copies are unimplemented!");
}
} else {
if (srcMappings.size() != 1 || dstMappings.size() != 1) [[unlikely]]
channelCtx.asCtx->gmmu.Copy(u64{*registers.offsetOut}, u64{*registers.offsetIn}, *registers.lineLengthIn);