mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 16:35:29 +03:00
Handle Y-axis GOB non-alignment for swizzling
Certain textures may be unaligned with a GOB's height of 8 lines, we already handle the case of being unaligned with a GOB's width of 64-bytes. This case occurs on titles such as SMO when going in-game.
This commit is contained in:
parent
c910e29168
commit
e027555796
@ -47,7 +47,7 @@ namespace skyline::gpu::texture {
|
|||||||
|
|
||||||
u8 *sector{blockLinear};
|
u8 *sector{blockLinear};
|
||||||
|
|
||||||
auto deswizzleRob{[&](u8 *linearRob, u32 paddingY) {
|
auto deswizzleRob{[&](u8 *linearRob, auto isLastRob, u32 blockPaddingY = 0, u32 blockExtentY = 0) {
|
||||||
auto deswizzleBlock{[&](u8 *linearBlock, auto copySector) __attribute__((always_inline)) {
|
auto deswizzleBlock{[&](u8 *linearBlock, auto copySector) __attribute__((always_inline)) {
|
||||||
for (u32 gobY{}; gobY < blockHeight; gobY++) { // Every Block contains `blockHeight` Y-axis GOBs
|
for (u32 gobY{}; gobY < blockHeight; gobY++) { // Every Block contains `blockHeight` Y-axis GOBs
|
||||||
#pragma clang loop unroll_count(32)
|
#pragma clang loop unroll_count(32)
|
||||||
@ -55,7 +55,14 @@ namespace skyline::gpu::texture {
|
|||||||
u32 xT{((index << 3) & 0b10000) | ((index << 1) & 0b100000)}; // Morton-Swizzle on the X-axis
|
u32 xT{((index << 3) & 0b10000) | ((index << 1) & 0b100000)}; // Morton-Swizzle on the X-axis
|
||||||
u32 yT{((index >> 1) & 0b110) | (index & 0b1)}; // Morton-Swizzle on the Y-axis
|
u32 yT{((index >> 1) & 0b110) | (index & 0b1)}; // Morton-Swizzle on the Y-axis
|
||||||
|
|
||||||
copySector(linearBlock + (yT * robWidthUnalignedBytes) + xT, xT);
|
if constexpr (!isLastRob) {
|
||||||
|
copySector(linearBlock + (yT * robWidthUnalignedBytes) + xT, xT);
|
||||||
|
} else {
|
||||||
|
if (gobY != blockHeight - 1 || yT < blockExtentY)
|
||||||
|
copySector(linearBlock + (yT * robWidthUnalignedBytes) + xT, xT);
|
||||||
|
else
|
||||||
|
sector += SectorWidth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
linearBlock += gobYOffset; // Increment the linear GOB to the next Y-axis GOB
|
linearBlock += gobYOffset; // Increment the linear GOB to the next Y-axis GOB
|
||||||
@ -63,12 +70,13 @@ namespace skyline::gpu::texture {
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
for (u32 block{}; block < robWidthBlocks; block++) { // Every ROB contains `surfaceWidthBlocks` blocks (excl. padding block)
|
for (u32 block{}; block < robWidthBlocks; block++) { // Every ROB contains `surfaceWidthBlocks` blocks (excl. padding block)
|
||||||
deswizzleBlock(linearRob, [&](u8 *linearSector, u32 xT) __attribute__((always_inline)) {
|
deswizzleBlock(linearRob, [&](u8 *linearSector, u32) __attribute__((always_inline)) {
|
||||||
copyFunction(linearSector, sector, SectorWidth);
|
copyFunction(linearSector, sector, SectorWidth);
|
||||||
sector += SectorWidth; // `sectorWidth` bytes are of sequential image data
|
sector += SectorWidth; // `sectorWidth` bytes are of sequential image data
|
||||||
});
|
});
|
||||||
|
|
||||||
sector += paddingY; // Skip over any padding at the end of this block
|
if constexpr (isLastRob)
|
||||||
|
sector += blockPaddingY; // Skip over any padding at the end of this block
|
||||||
linearRob += GobWidth; // Increment the linear block to the next block (As Block Width = 1 GOB Width)
|
linearRob += GobWidth; // Increment the linear block to the next block (As Block Width = 1 GOB Width)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,13 +94,14 @@ namespace skyline::gpu::texture {
|
|||||||
|
|
||||||
u8 *linearRob{linear};
|
u8 *linearRob{linear};
|
||||||
for (u32 rob{}; rob < surfaceHeightRobs; rob++) { // Every Surface contains `surfaceHeightRobs` ROBs (excl. padding ROB)
|
for (u32 rob{}; rob < surfaceHeightRobs; rob++) { // Every Surface contains `surfaceHeightRobs` ROBs (excl. padding ROB)
|
||||||
deswizzleRob(linearRob, 0);
|
deswizzleRob(linearRob, std::false_type{});
|
||||||
linearRob += robBytes; // Increment the linear block to the next ROB
|
linearRob += robBytes; // Increment the linear block to the next ROB
|
||||||
}
|
}
|
||||||
|
|
||||||
if (surfaceHeightLines % robHeight != 0) {
|
if (surfaceHeightLines % robHeight != 0) {
|
||||||
blockHeight = (util::AlignUp(surfaceHeightLines, GobHeight) - (surfaceHeightRobs * robHeight)) / GobHeight; // Calculate the amount of Y GOBs which aren't padding
|
blockHeight = (util::AlignUp(surfaceHeightLines, GobHeight) - (surfaceHeightRobs * robHeight)) / GobHeight; // Calculate the amount of Y GOBs which aren't padding
|
||||||
deswizzleRob(linearRob, (guest.tileConfig.blockHeight - blockHeight) * (SectorWidth * SectorWidth * SectorHeight));
|
u32 surfaceHeightLinesCeil{util::DivideCeil(guest.dimensions.height, u32{guest.format->blockHeight})};
|
||||||
|
deswizzleRob(linearRob, std::true_type{}, (guest.tileConfig.blockHeight - blockHeight) * (SectorWidth * SectorWidth * SectorHeight), surfaceHeightLinesCeil - util::AlignDown(surfaceHeightLinesCeil, GobHeight));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user