GPU: Allow using a configurable block height when unswizzling textures.

This commit is contained in:
Subv 2018-04-15 19:53:15 -05:00
parent db5f2bfa7e
commit 6b63aaa5b4
4 changed files with 23 additions and 7 deletions

View File

@ -1041,9 +1041,18 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
params.height = config.tic.Height(); params.height = config.tic.Height();
params.is_tiled = config.tic.IsTiled(); params.is_tiled = config.tic.IsTiled();
params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format);
if (config.tic.IsTiled()) {
params.block_height = config.tic.BlockHeight();
} else {
// Use the texture-provided stride value if the texture isn't tiled.
params.stride = params.PixelsInBytes(config.tic.Pitch());
}
params.UpdateParams(); params.UpdateParams();
if (config.tic.Width() % 8 != 0 || config.tic.Height() % 8 != 0) { if (config.tic.Width() % 8 != 0 || config.tic.Height() % 8 != 0 ||
params.stride != params.width) {
Surface src_surface; Surface src_surface;
MathUtil::Rectangle<u32> rect; MathUtil::Rectangle<u32> rect;
std::tie(src_surface, rect) = GetSurfaceSubRect(params, ScaleMatch::Ignore, true); std::tie(src_surface, rect) = GetSurfaceSubRect(params, ScaleMatch::Ignore, true);

View File

@ -56,23 +56,22 @@ u32 BytesPerPixel(TextureFormat format) {
} }
} }
std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height) { std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
u32 block_height) {
u8* data = Memory::GetPointer(address); u8* data = Memory::GetPointer(address);
u32 bytes_per_pixel = BytesPerPixel(format); u32 bytes_per_pixel = BytesPerPixel(format);
static constexpr u32 DefaultBlockHeight = 16;
std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); std::vector<u8> unswizzled_data(width * height * bytes_per_pixel);
switch (format) { switch (format) {
case TextureFormat::DXT1: case TextureFormat::DXT1:
// In the DXT1 format, each 4x4 tile is swizzled instead of just individual pixel values. // In the DXT1 format, each 4x4 tile is swizzled instead of just individual pixel values.
CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, DefaultBlockHeight); unswizzled_data.data(), true, block_height);
break; break;
case TextureFormat::A8R8G8B8: case TextureFormat::A8R8G8B8:
CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data,
unswizzled_data.data(), true, DefaultBlockHeight); unswizzled_data.data(), true, block_height);
break; break;
default: default:
UNIMPLEMENTED_MSG("Format not implemented"); UNIMPLEMENTED_MSG("Format not implemented");

View File

@ -14,7 +14,8 @@ namespace Texture {
/** /**
* Unswizzles a swizzled texture without changing its format. * Unswizzles a swizzled texture without changing its format.
*/ */
std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height); std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height,
u32 block_height = TICEntry::DefaultBlockHeight);
/** /**
* Decodes an unswizzled texture into a A8R8G8B8 texture. * Decodes an unswizzled texture into a A8R8G8B8 texture.

View File

@ -105,6 +105,13 @@ struct TICEntry {
return height_minus_1 + 1; return height_minus_1 + 1;
} }
u32 BlockHeight() const {
ASSERT(header_version == TICHeaderVersion::BlockLinear ||
header_version == TICHeaderVersion::BlockLinearColorKey);
// The block height is stored in log2 format.
return 1 << block_height;
}
bool IsTiled() const { bool IsTiled() const {
return header_version == TICHeaderVersion::BlockLinear || return header_version == TICHeaderVersion::BlockLinear ||
header_version == TICHeaderVersion::BlockLinearColorKey; header_version == TICHeaderVersion::BlockLinearColorKey;