From 61779fa072fea906410eca3e29ba54fe1ee347d3 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 17 Jun 2018 23:50:44 -0400 Subject: gl_rasterizer: Implement texture format ASTC_2D_4X4. --- .../renderer_opengl/gl_rasterizer_cache.cpp | 28 +++++++++++++++++++++- .../renderer_opengl/gl_rasterizer_cache.h | 16 +++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl') diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index e61960cc0..b2a61024e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -28,6 +28,7 @@ #include "video_core/engines/maxwell_3d.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_state.h" +#include "video_core/textures/astc.h" #include "video_core/textures/decoders.h" #include "video_core/utils.h" #include "video_core/video_core.h" @@ -55,6 +56,7 @@ static constexpr std::array tex_form {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45 {GL_COMPRESSED_RED_RGTC1, GL_RED, GL_UNSIGNED_INT_8_8_8_8, true}, // DXN1 + {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, false}, // ASTC_2D_4X4 }}; static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { @@ -86,6 +88,23 @@ static u16 GetResolutionScaleFactor() { : Settings::values.resolution_factor); } +static void ConvertASTCToRGBA8(std::vector& data, PixelFormat format, u32 width, u32 height) { + u32 block_width{}; + u32 block_height{}; + + switch (format) { + case PixelFormat::ASTC_2D_4X4: + block_width = 4; + block_height = 4; + break; + default: + NGLOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast(format)); + UNREACHABLE(); + } + + data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height); +} + template void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::GPUVAddr base, Tegra::GPUVAddr start, Tegra::GPUVAddr end) { @@ -97,6 +116,12 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra:: auto data = Tegra::Texture::UnswizzleTexture( *gpu.memory_manager->GpuToCpuAddress(base), SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); + + if (SurfaceParams::IsFormatASTC(format)) { + // ASTC formats are converted to RGBA8 in software, as most PC GPUs do not support this + ConvertASTCToRGBA8(data, format, stride, height); + } + std::memcpy(gl_buffer, data.data(), data.size()); } else { // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check @@ -118,7 +143,7 @@ static constexpr std::array, MortonCopy, MortonCopy, MortonCopy, MortonCopy, MortonCopy, - MortonCopy, + MortonCopy, MortonCopy, }; static constexpr std::array, }; // Allocate an uninitialized texture of appropriate size and format for the surface diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 0f43e863d..9da945e19 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -65,6 +65,7 @@ struct SurfaceParams { DXT23 = 8, DXT45 = 9, DXN1 = 10, // This is also known as BC4 + ASTC_2D_4X4 = 11, Max, Invalid = 255, @@ -111,6 +112,7 @@ struct SurfaceParams { 4, // DXT23 4, // DXT45 4, // DXN1 + 1, // ASTC_2D_4X4 }}; ASSERT(static_cast(format) < compression_factor_table.size()); @@ -136,6 +138,7 @@ struct SurfaceParams { 128, // DXT23 128, // DXT45 64, // DXN1 + 32, // ASTC_2D_4X4 }}; ASSERT(static_cast(format) < bpp_table.size()); @@ -162,6 +165,15 @@ struct SurfaceParams { } } + static bool IsFormatASTC(PixelFormat format) { + switch (format) { + case PixelFormat::ASTC_2D_4X4: + return true; + default: + return false; + } + } + static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { switch (format) { case Tegra::FramebufferConfig::PixelFormat::ABGR8: @@ -197,6 +209,8 @@ struct SurfaceParams { return PixelFormat::DXT45; case Tegra::Texture::TextureFormat::DXN1: return PixelFormat::DXN1; + case Tegra::Texture::TextureFormat::ASTC_2D_4X4: + return PixelFormat::ASTC_2D_4X4; default: NGLOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast(format)); UNREACHABLE(); @@ -228,6 +242,8 @@ struct SurfaceParams { return Tegra::Texture::TextureFormat::DXT45; case PixelFormat::DXN1: return Tegra::Texture::TextureFormat::DXN1; + case PixelFormat::ASTC_2D_4X4: + return Tegra::Texture::TextureFormat::ASTC_2D_4X4; default: UNREACHABLE(); } -- cgit v1.2.3