mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 17:22:00 +01:00
Implement DMA engine Block Linear->Linear copies
This commit is contained in:
parent
3e4e8de1d2
commit
dbbc5704d2
@ -39,6 +39,9 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
if (registers.launchDma->srcMemoryLayout == Registers::LaunchDma::MemoryLayout::Pitch &&
|
if (registers.launchDma->srcMemoryLayout == Registers::LaunchDma::MemoryLayout::Pitch &&
|
||||||
registers.launchDma->dstMemoryLayout == Registers::LaunchDma::MemoryLayout::BlockLinear)
|
registers.launchDma->dstMemoryLayout == Registers::LaunchDma::MemoryLayout::BlockLinear)
|
||||||
CopyPitchToBlockLinear();
|
CopyPitchToBlockLinear();
|
||||||
|
else if (registers.launchDma->srcMemoryLayout == Registers::LaunchDma::MemoryLayout::BlockLinear &&
|
||||||
|
registers.launchDma->dstMemoryLayout == Registers::LaunchDma::MemoryLayout::Pitch)
|
||||||
|
CopyBlockLinearToPitch();
|
||||||
else
|
else
|
||||||
Logger::Warn("Unimplemented multi-line copy type: {} -> {}!",
|
Logger::Warn("Unimplemented multi-line copy type: {} -> {}!",
|
||||||
static_cast<u8>(registers.launchDma->srcMemoryLayout), static_cast<u8>(registers.launchDma->dstMemoryLayout));
|
static_cast<u8>(registers.launchDma->srcMemoryLayout), static_cast<u8>(registers.launchDma->dstMemoryLayout));
|
||||||
@ -72,6 +75,9 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*registers.lineLengthIn != registers.dstSurface->width)
|
||||||
|
Logger::Warn("DMA copy width mismatch: src: {} dst: {}", *registers.lineLengthIn, registers.dstSurface->width);
|
||||||
|
|
||||||
gpu::GuestTexture srcTexture{span<u8>{},
|
gpu::GuestTexture srcTexture{span<u8>{},
|
||||||
gpu::texture::Dimensions{*registers.lineLengthIn, *registers.lineCount, 1},
|
gpu::texture::Dimensions{*registers.lineLengthIn, *registers.lineCount, 1},
|
||||||
gpu::format::GetFormatForBpp(bytesPerPixel),
|
gpu::format::GetFormatForBpp(bytesPerPixel),
|
||||||
@ -85,9 +91,6 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*registers.lineLengthIn != registers.dstSurface->width)
|
|
||||||
Logger::Warn("DMA copy width mismatch: src: {} dst: {}", *registers.lineLengthIn, registers.dstSurface->width);
|
|
||||||
|
|
||||||
// This represents a single layer view into a potentially multi-layer texture
|
// This represents a single layer view into a potentially multi-layer texture
|
||||||
gpu::GuestTexture dstTexture{span<u8>{},
|
gpu::GuestTexture dstTexture{span<u8>{},
|
||||||
gpu::texture::Dimensions{*registers.lineLengthIn, registers.dstSurface->height, 1},
|
gpu::texture::Dimensions{*registers.lineLengthIn, registers.dstSurface->height, 1},
|
||||||
@ -108,6 +111,63 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
gpu::texture::CopyLinearToBlockLinear(dstTexture, srcTexture.mappings.front().data(), dstTexture.mappings.front().data());
|
gpu::texture::CopyLinearToBlockLinear(dstTexture, srcTexture.mappings.front().data(), dstTexture.mappings.front().data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MaxwellDma::CopyBlockLinearToPitch() {
|
||||||
|
if (registers.srcSurface->blockSize.Depth() > 1 || registers.srcSurface->depth > 1) {
|
||||||
|
Logger::Warn("3D DMA engine copies are unimplemented!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registers.srcSurface->blockSize.Width() != 1) {
|
||||||
|
Logger::Warn("DMA engine copies with block widths other than 1 are unimplemented!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 bytesPerPixel{static_cast<u32>(registers.remapComponents->ComponentSize() * registers.remapComponents->NumSrcComponents())};
|
||||||
|
if (bytesPerPixel * *registers.lineLengthIn != *registers.pitchOut) {
|
||||||
|
Logger::Warn("Non-linear DMA destination textures are not implemented!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (registers.srcSurface->origin.x || registers.srcSurface->origin.y) {
|
||||||
|
Logger::Warn("Non-zero origin DMA copies are not implemented!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*registers.lineLengthIn != registers.srcSurface->width)
|
||||||
|
Logger::Warn("DMA copy width mismatch: src: {} dst: {}", *registers.lineLengthIn, registers.dstSurface->width);
|
||||||
|
|
||||||
|
gpu::GuestTexture srcTexture{span<u8>{},
|
||||||
|
gpu::texture::Dimensions{registers.srcSurface->width, registers.srcSurface->height, 1},
|
||||||
|
gpu::format::GetFormatForBpp(bytesPerPixel),
|
||||||
|
gpu::texture::TileConfig{ .mode = gpu::texture::TileMode::Block, .blockHeight = registers.srcSurface->blockSize.Height(), .blockDepth = 1 },
|
||||||
|
gpu::texture::TextureType::e2D};
|
||||||
|
|
||||||
|
if (auto mappings{channelCtx.asCtx->gmmu.TranslateRange(*registers.offsetIn, srcTexture.GetLayerSize())}; mappings.size() == 1) {
|
||||||
|
srcTexture.mappings[0] = mappings[0];
|
||||||
|
} else {
|
||||||
|
Logger::Warn("DMA for split textures is unimplemented!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::GuestTexture dstTexture{span<u8>{},
|
||||||
|
gpu::texture::Dimensions{*registers.lineLengthIn, *registers.lineCount, 1},
|
||||||
|
gpu::format::GetFormatForBpp(bytesPerPixel),
|
||||||
|
gpu::texture::TileConfig{ .mode = gpu::texture::TileMode::Linear },
|
||||||
|
gpu::texture::TextureType::e2D};
|
||||||
|
|
||||||
|
if (auto mappings{channelCtx.asCtx->gmmu.TranslateRange(*registers.offsetOut, dstTexture.GetLayerSize())}; mappings.size() == 1) {
|
||||||
|
dstTexture.mappings[0] = mappings[0];
|
||||||
|
} else {
|
||||||
|
Logger::Warn("DMA for split textures is unimplemented!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::Debug("{}x{}@0x{:X} -> {}x{}@0x{:X}", srcTexture.dimensions.width, srcTexture.dimensions.height, *registers.offsetIn, dstTexture.dimensions.width, dstTexture.dimensions.height, *registers.offsetOut);
|
||||||
|
|
||||||
|
gpu::texture::CopyBlockLinearToLinear(srcTexture, srcTexture.mappings.front().data(), dstTexture.mappings.front().data());
|
||||||
|
}
|
||||||
|
|
||||||
void MaxwellDma::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
void MaxwellDma::CallMethodBatchNonInc(u32 method, span<u32> arguments) {
|
||||||
for (u32 argument : arguments)
|
for (u32 argument : arguments)
|
||||||
HandleMethod(method, argument);
|
HandleMethod(method, argument);
|
||||||
|
@ -24,6 +24,8 @@ namespace skyline::soc::gm20b::engine {
|
|||||||
|
|
||||||
void CopyPitchToBlockLinear();
|
void CopyPitchToBlockLinear();
|
||||||
|
|
||||||
|
void CopyBlockLinearToPitch();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @url https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/dma-copy/clb0b5.h
|
* @url https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/dma-copy/clb0b5.h
|
||||||
|
Loading…
Reference in New Issue
Block a user