Fix 3D swizzled copies & a small bug with DMA clears

This commit is contained in:
TheASVigilante 2023-02-21 15:34:42 +01:00 committed by Billy Laws
parent 70ee36e85c
commit caf1abbe31
2 changed files with 66 additions and 52 deletions

View File

@ -116,8 +116,9 @@ namespace skyline::gpu::texture {
size_t surfaceHeightLines{util::DivideCeil<size_t>(dimensions.height, formatBlockHeight)}; size_t surfaceHeightLines{util::DivideCeil<size_t>(dimensions.height, formatBlockHeight)};
size_t surfaceHeightRobs{surfaceHeightLines / robHeight}; //!< The height of the surface in ROBs excluding padding ROBs size_t surfaceHeightRobs{surfaceHeightLines / robHeight}; //!< The height of the surface in ROBs excluding padding ROBs
size_t blockDepth{std::min<size_t>(dimensions.depth, gobBlockDepth)}; size_t depthMobCount{util::DivideCeil<size_t>(dimensions.depth, gobBlockDepth)}; //!< The depth of the surface in MOBs (Matrix of Blocks)
size_t blockPaddingZ{GobWidth * GobHeight * blockHeight * (gobBlockDepth - blockDepth)}; size_t blockDepth{util::AlignUp(dimensions.depth, gobBlockDepth) - dimensions.depth};
size_t blockPaddingZ{gobBlockDepth != 1 ? GobWidth * GobHeight * blockHeight * blockDepth : 0};
bool hasPaddingBlock{robWidthUnalignedBytes != robWidthBytes}; bool hasPaddingBlock{robWidthUnalignedBytes != robWidthBytes};
size_t blockPaddingOffset{hasPaddingBlock ? (GobWidth - (robWidthBytes - robWidthUnalignedBytes)) : 0}; size_t blockPaddingOffset{hasPaddingBlock ? (GobWidth - (robWidthBytes - robWidthUnalignedBytes)) : 0};
@ -129,9 +130,9 @@ namespace skyline::gpu::texture {
u8 *sector{blockLinear}; u8 *sector{blockLinear};
auto deswizzleRob{[&](u8 *pitchRob, auto isLastRob, size_t blockPaddingY = 0, size_t blockExtentY = 0) { auto deswizzleRob{[&](u8 *pitchRob, auto isLastRob, size_t depthSliceCount, size_t blockPaddingY = 0, size_t blockExtentY = 0) {
auto deswizzleBlock{[&](u8 *pitchBlock, auto copySector) __attribute__((always_inline)) { auto deswizzleBlock{[&](u8 *pitchBlock, auto copySector) __attribute__((always_inline)) {
for (size_t gobZ{}; gobZ < blockDepth; gobZ++) { // Every Block contains `blockDepth` Z-axis GOBs (Slices) for (size_t gobZ{}; gobZ < depthSliceCount; gobZ++) { // Every Block contains `depthSliceCount` slices, excluding padding
u8 *pitchGob{pitchBlock}; u8 *pitchGob{pitchBlock};
for (size_t gobY{}; gobY < blockHeight; gobY++) { // Every Block contains `blockHeight` Y-axis GOBs for (size_t gobY{}; gobY < blockHeight; gobY++) { // Every Block contains `blockHeight` Y-axis GOBs
#pragma clang loop unroll_count(SectorLinesInGob) #pragma clang loop unroll_count(SectorLinesInGob)
@ -158,6 +159,7 @@ namespace skyline::gpu::texture {
pitchBlock += gobZOffset; // Increment the linear block to the next Z-axis GOB pitchBlock += gobZOffset; // Increment the linear block to the next Z-axis GOB
} }
if (depthSliceCount != gobBlockDepth) [[unlikely]]
sector += blockPaddingZ; // Skip over any padding Z-axis GOBs sector += blockPaddingZ; // Skip over any padding Z-axis GOBs
}}; }};
@ -183,16 +185,18 @@ namespace skyline::gpu::texture {
else else
std::memcpy(sector, linearSector + pixelOffset, formatBpb); std::memcpy(sector, linearSector + pixelOffset, formatBpb);
} }
sector += formatBpb;
xT += formatBpb; xT += formatBpb;
} }
sector += SectorWidth;
}); });
}}; }};
for (size_t currMob{}; currMob < depthMobCount; ++currMob, pitch += gobZOffset * gobBlockDepth) {
u8 *pitchRob{pitch}; u8 *pitchRob{pitch};
size_t sliceCount{(currMob + 1) == depthMobCount ? gobBlockDepth - blockDepth : gobBlockDepth};
for (size_t rob{}; rob < surfaceHeightRobs; rob++) { // Every Surface contains `surfaceHeightRobs` ROBs (excl. padding ROB) for (size_t rob{}; rob < surfaceHeightRobs; rob++) { // Every Surface contains `surfaceHeightRobs` ROBs (excl. padding ROB)
deswizzleRob(pitchRob, std::false_type{}); deswizzleRob(pitchRob, std::false_type{}, sliceCount);
pitchRob += robBytes; // Increment the linear ROB to the next ROB pitchRob += robBytes; // Increment the linear ROB to the next ROB
} }
@ -202,9 +206,13 @@ namespace skyline::gpu::texture {
deswizzleRob( deswizzleRob(
pitchRob, pitchRob,
std::true_type{}, std::true_type{},
sliceCount,
(gobBlockHeight - blockHeight) * (GobWidth * GobHeight), // Calculate padding at the end of a block to skip (gobBlockHeight - blockHeight) * (GobWidth * GobHeight), // Calculate padding at the end of a block to skip
util::IsAligned(surfaceHeightLines, GobHeight) ? GobHeight : surfaceHeightLines - util::AlignDown(surfaceHeightLines, GobHeight) // Calculate the line relative to the start of the last GOB that is the cut-off point for the image util::IsAligned(surfaceHeightLines, GobHeight) ? GobHeight : surfaceHeightLines - util::AlignDown(surfaceHeightLines, GobHeight) // Calculate the line relative to the start of the last GOB that is the cut-off point for the image
); );
blockHeight = gobBlockHeight;
}
} }
} }
@ -247,18 +255,23 @@ namespace skyline::gpu::texture {
originY = util::DivideCeil<u32>(originY, static_cast<u32>(formatBlockHeight)); originY = util::DivideCeil<u32>(originY, static_cast<u32>(formatBlockHeight));
size_t alignedDepth{util::AlignUp(blockLinearDimensions.depth, gobBlockDepth)}; size_t depthMobCount{util::DivideCeil<size_t>(blockLinearDimensions.depth, gobBlockDepth)}; //!< The depth of the surface in MOBs (Matrix of Blocks)
size_t lastMobSliceCount{gobBlockDepth - (util::AlignUp(blockLinearDimensions.depth, gobBlockDepth) - blockLinearDimensions.depth)};
size_t pitchBytes{pitchAmount ? pitchAmount : pitchTextureWidthBytes}; size_t pitchBytes{pitchAmount ? pitchAmount : pitchTextureWidthBytes};
size_t robSize{blockLinearTextureWidthAlignedBytes * robHeight * alignedDepth}; size_t robSize{blockLinearTextureWidthAlignedBytes * robHeight * gobBlockDepth};
size_t blockSize{robHeight * GobWidth * alignedDepth}; size_t robPerMob{util::DivideCeil<size_t>(util::DivideCeil<size_t>(blockLinearDimensions.height, formatBlockHeight), robHeight)};
size_t blockSize{robHeight * GobWidth * gobBlockDepth};
u8 *pitchOffset{pitch}; u8 *pitchOffset{pitch};
auto copyTexture{[&]<typename FORMATBPB>() __attribute__((always_inline)) { auto copyTexture{[&]<typename FORMATBPB>() __attribute__((always_inline)) {
for (size_t slice{}; slice < blockLinearDimensions.depth; ++slice, blockLinear += (GobHeight * GobWidth * gobBlockHeight)) { for (size_t currMob{}; currMob < depthMobCount; ++currMob, blockLinear += robSize * robPerMob) {
u64 robOffset{util::AlignDown(originY, robHeight) * blockLinearTextureWidthAlignedBytes * alignedDepth}; size_t sliceCount{(currMob + 1) == depthMobCount ? lastMobSliceCount : gobBlockDepth};
u64 sliceOffset{};
for (size_t slice{}; slice < sliceCount; ++slice, sliceOffset += (GobHeight * GobWidth * gobBlockHeight)) {
u64 robOffset{util::AlignDown(originY, robHeight) * blockLinearTextureWidthAlignedBytes * gobBlockDepth};
for (size_t line{}; line < pitchTextureHeight; ++line, pitchOffset += pitchBytes) { for (size_t line{}; line < pitchTextureHeight; ++line, pitchOffset += pitchBytes) {
// XYZ Offset in entire ROBs // XYZ Offset in entire ROBs
if (line && !((originY + line) & (robHeight - 1))) [[unlikely]] if (line && !((originY + line) & (robHeight - 1))) [[unlikely]]
@ -269,13 +282,13 @@ namespace skyline::gpu::texture {
GobYOffset += (((originY + line) & 0x6) << 5) + (((originY + line) & 0x1) << 4); GobYOffset += (((originY + line) & 0x6) << 5) + (((originY + line) & 0x1) << 4);
u8 *deSwizzledOffset{pitchOffset}; u8 *deSwizzledOffset{pitchOffset};
u8 *swizzledYZOffset{blockLinear + robOffset + GobYOffset}; u8 *swizzledYZOffset{blockLinear + robOffset + GobYOffset + sliceOffset};
u8 *swizzledOffset{}; u8 *swizzledOffset{};
size_t xBytes{originXBytes}; size_t xBytes{originXBytes};
size_t GobXOffset{}; size_t GobXOffset{};
size_t blockOffset{util::AlignDown(xBytes, GobWidth) * robHeight * alignedDepth}; size_t blockOffset{util::AlignDown(xBytes, GobWidth) * robHeight * gobBlockDepth};
for (size_t pixel{}; pixel < pitchTextureWidth; ++pixel, deSwizzledOffset += formatBpb, xBytes += formatBpb) { for (size_t pixel{}; pixel < pitchTextureWidth; ++pixel, deSwizzledOffset += formatBpb, xBytes += formatBpb) {
// XYZ Offset in entire blocks in current ROB // XYZ Offset in entire blocks in current ROB
@ -294,6 +307,7 @@ namespace skyline::gpu::texture {
} }
} }
} }
}
}}; }};
switch (formatBpb) { switch (formatBpb) {

View File

@ -95,8 +95,8 @@ namespace skyline::soc::gm20b::engine {
(registers.remapComponents->dstZ == Registers::RemapComponents::Swizzle::ConstA) && (registers.remapComponents->dstZ == Registers::RemapComponents::Swizzle::ConstA) &&
(registers.remapComponents->dstW == Registers::RemapComponents::Swizzle::ConstA) && (registers.remapComponents->dstW == Registers::RemapComponents::Swizzle::ConstA) &&
(registers.remapComponents->ComponentSize() == 4)) { (registers.remapComponents->ComponentSize() == 4)) {
for (size_t currMapping{dstMappings.size()}; currMapping; --currMapping) for (auto mapping : dstMappings)
interconnect.Clear(dstMappings[currMapping], *registers.remapConstA); interconnect.Clear(mapping, *registers.remapConstA);
} else { } else {
Logger::Warn("Remapped DMA copies are unimplemented!"); Logger::Warn("Remapped DMA copies are unimplemented!");
} }