GPU: Add support for the DXT23 and DXT45 compressed texture formats.
This commit is contained in:
		
							parent
							
								
									60e6e8953e
								
							
						
					
					
						commit
						057170928c
					
				@ -49,9 +49,11 @@ struct FormatTuple {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{
 | 
			
		||||
    {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1},                   // ABGR8
 | 
			
		||||
    {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1},                      // B5G6R5
 | 
			
		||||
    {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1
 | 
			
		||||
    {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1},                     // ABGR8
 | 
			
		||||
    {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1},                        // B5G6R5
 | 
			
		||||
    {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16},   // DXT1
 | 
			
		||||
    {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23
 | 
			
		||||
    {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) {
 | 
			
		||||
@ -81,23 +83,6 @@ static u16 GetResolutionScaleFactor() {
 | 
			
		||||
                                : Settings::values.resolution_factor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <bool morton_to_gl, PixelFormat format>
 | 
			
		||||
static void MortonCopyTile(u32 stride, u8* tile_buffer, u8* gl_buffer) {
 | 
			
		||||
    constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8;
 | 
			
		||||
    constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format);
 | 
			
		||||
    for (u32 y = 0; y < 8; ++y) {
 | 
			
		||||
        for (u32 x = 0; x < 8; ++x) {
 | 
			
		||||
            u8* tile_ptr = tile_buffer + VideoCore::MortonInterleave(x, y) * bytes_per_pixel;
 | 
			
		||||
            u8* gl_ptr = gl_buffer + ((7 - y) * stride + x) * gl_bytes_per_pixel;
 | 
			
		||||
            if (morton_to_gl) {
 | 
			
		||||
                std::memcpy(gl_ptr, tile_ptr, bytes_per_pixel);
 | 
			
		||||
            } else {
 | 
			
		||||
                std::memcpy(tile_ptr, gl_ptr, bytes_per_pixel);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <bool morton_to_gl, PixelFormat format>
 | 
			
		||||
void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr base, VAddr start,
 | 
			
		||||
                VAddr end) {
 | 
			
		||||
@ -121,9 +106,9 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, VAddr b
 | 
			
		||||
static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr),
 | 
			
		||||
                            SurfaceParams::MaxPixelFormat>
 | 
			
		||||
    morton_to_gl_fns = {
 | 
			
		||||
        MortonCopy<true, PixelFormat::ABGR8>,
 | 
			
		||||
        MortonCopy<true, PixelFormat::B5G6R5>,
 | 
			
		||||
        MortonCopy<true, PixelFormat::DXT1>,
 | 
			
		||||
        MortonCopy<true, PixelFormat::ABGR8>, MortonCopy<true, PixelFormat::B5G6R5>,
 | 
			
		||||
        MortonCopy<true, PixelFormat::DXT1>,  MortonCopy<true, PixelFormat::DXT23>,
 | 
			
		||||
        MortonCopy<true, PixelFormat::DXT45>,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr),
 | 
			
		||||
@ -131,7 +116,9 @@ static constexpr std::array<void (*)(u32, u32, u32, u8*, VAddr, VAddr, VAddr),
 | 
			
		||||
    gl_to_morton_fns = {
 | 
			
		||||
        MortonCopy<false, PixelFormat::ABGR8>,
 | 
			
		||||
        MortonCopy<false, PixelFormat::B5G6R5>,
 | 
			
		||||
        // TODO(Subv): Swizzling the DXT1 format is not yet supported
 | 
			
		||||
        // TODO(Subv): Swizzling the DXT1/DXT23/DXT45 formats is not yet supported
 | 
			
		||||
        nullptr,
 | 
			
		||||
        nullptr,
 | 
			
		||||
        nullptr,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -55,6 +55,8 @@ struct SurfaceParams {
 | 
			
		||||
        ABGR8 = 0,
 | 
			
		||||
        B5G6R5 = 1,
 | 
			
		||||
        DXT1 = 2,
 | 
			
		||||
        DXT23 = 3,
 | 
			
		||||
        DXT45 = 4,
 | 
			
		||||
 | 
			
		||||
        Max,
 | 
			
		||||
        Invalid = 255,
 | 
			
		||||
@ -84,9 +86,11 @@ struct SurfaceParams {
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
        constexpr std::array<unsigned int, MaxPixelFormat> bpp_table = {
 | 
			
		||||
            32, // ABGR8
 | 
			
		||||
            16, // B5G6R5
 | 
			
		||||
            64, // DXT1
 | 
			
		||||
            32,  // ABGR8
 | 
			
		||||
            16,  // B5G6R5
 | 
			
		||||
            64,  // DXT1
 | 
			
		||||
            128, // DXT23
 | 
			
		||||
            128, // DXT45
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        ASSERT(static_cast<size_t>(format) < bpp_table.size());
 | 
			
		||||
@ -125,6 +129,10 @@ struct SurfaceParams {
 | 
			
		||||
            return PixelFormat::B5G6R5;
 | 
			
		||||
        case Tegra::Texture::TextureFormat::DXT1:
 | 
			
		||||
            return PixelFormat::DXT1;
 | 
			
		||||
        case Tegra::Texture::TextureFormat::DXT23:
 | 
			
		||||
            return PixelFormat::DXT23;
 | 
			
		||||
        case Tegra::Texture::TextureFormat::DXT45:
 | 
			
		||||
            return PixelFormat::DXT45;
 | 
			
		||||
        default:
 | 
			
		||||
            NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
@ -140,6 +148,10 @@ struct SurfaceParams {
 | 
			
		||||
            return Tegra::Texture::TextureFormat::B5G6R5;
 | 
			
		||||
        case PixelFormat::DXT1:
 | 
			
		||||
            return Tegra::Texture::TextureFormat::DXT1;
 | 
			
		||||
        case PixelFormat::DXT23:
 | 
			
		||||
            return Tegra::Texture::TextureFormat::DXT23;
 | 
			
		||||
        case PixelFormat::DXT45:
 | 
			
		||||
            return Tegra::Texture::TextureFormat::DXT45;
 | 
			
		||||
        default:
 | 
			
		||||
            UNREACHABLE();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -48,6 +48,10 @@ u32 BytesPerPixel(TextureFormat format) {
 | 
			
		||||
    case TextureFormat::DXT1:
 | 
			
		||||
        // In this case a 'pixel' actually refers to a 4x4 tile.
 | 
			
		||||
        return 8;
 | 
			
		||||
    case TextureFormat::DXT23:
 | 
			
		||||
    case TextureFormat::DXT45:
 | 
			
		||||
        // In this case a 'pixel' actually refers to a 4x4 tile.
 | 
			
		||||
        return 16;
 | 
			
		||||
    case TextureFormat::A8R8G8B8:
 | 
			
		||||
        return 4;
 | 
			
		||||
    case TextureFormat::B5G6R5:
 | 
			
		||||
@ -67,7 +71,9 @@ std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width,
 | 
			
		||||
 | 
			
		||||
    switch (format) {
 | 
			
		||||
    case TextureFormat::DXT1:
 | 
			
		||||
        // In the DXT1 format, each 4x4 tile is swizzled instead of just individual pixel values.
 | 
			
		||||
    case TextureFormat::DXT23:
 | 
			
		||||
    case TextureFormat::DXT45:
 | 
			
		||||
        // In the DXT formats, each 4x4 tile is swizzled instead of just individual pixel values.
 | 
			
		||||
        CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data,
 | 
			
		||||
                         unswizzled_data.data(), true, block_height);
 | 
			
		||||
        break;
 | 
			
		||||
@ -91,6 +97,8 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
 | 
			
		||||
    // TODO(Subv): Implement.
 | 
			
		||||
    switch (format) {
 | 
			
		||||
    case TextureFormat::DXT1:
 | 
			
		||||
    case TextureFormat::DXT23:
 | 
			
		||||
    case TextureFormat::DXT45:
 | 
			
		||||
    case TextureFormat::A8R8G8B8:
 | 
			
		||||
    case TextureFormat::B5G6R5:
 | 
			
		||||
        // TODO(Subv): For the time being just forward the same data without any decoding.
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user