diff options
| author | bunnei <bunneidev@gmail.com> | 2018-06-26 15:05:13 -0400 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2018-06-27 00:08:04 -0400 | 
| commit | 8af1ae46aa5a9303b21839b446d2ebf17ee12802 (patch) | |
| tree | 0107f0b2e7442bece9a58992c09fdc6532b98871 | |
| parent | c7c379bd1986830c9fc370ce581710d1098c975c (diff) | |
gl_rasterizer_cache: Various fixes for ASTC handling.
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 63 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 11 | 
2 files changed, 39 insertions, 35 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 59f1a89c9..bd35bdb02 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -41,6 +41,7 @@ struct FormatTuple {      params.type = GetFormatType(params.pixel_format);      params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format));      params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); +    params.unaligned_height = config.tic.Height();      params.size_in_bytes = params.SizeInBytes();      return params;  } @@ -57,6 +58,7 @@ struct FormatTuple {      params.type = GetFormatType(params.pixel_format);      params.width = config.width;      params.height = config.height; +    params.unaligned_height = config.height;      params.size_in_bytes = params.SizeInBytes();      return params;  } @@ -108,20 +110,29 @@ static bool IsPixelFormatASTC(PixelFormat format) {      }  } -static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) { -    u32 block_width{}; -    u32 block_height{}; - +static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {      switch (format) {      case PixelFormat::ASTC_2D_4X4: -        block_width = 4; -        block_height = 4; -        break; +        return {4, 4};      default:          NGLOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));          UNREACHABLE();      } +} +MathUtil::Rectangle<u32> SurfaceParams::GetRect() const { +    u32 actual_height{unaligned_height}; +    if (IsPixelFormatASTC(pixel_format)) { +        // ASTC formats must stop at the ATSC block size boundary +        actual_height = Common::AlignDown(actual_height, GetASTCBlockSize(pixel_format).second); +    } +    return {0, actual_height, width, 0}; +} + +static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) { +    u32 block_width{}; +    u32 block_height{}; +    std::tie(block_width, block_height) = GetASTCBlockSize(format);      data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height);  } @@ -136,12 +147,6 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra::              *gpu.memory_manager->GpuToCpuAddress(addr),              SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); -        if (IsPixelFormatASTC(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 @@ -212,9 +217,10 @@ static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tup  CachedSurface::CachedSurface(const SurfaceParams& params) : params(params), gl_buffer_size(0) {      texture.Create(); +    const auto& rect{params.GetRect()};      AllocateSurfaceTexture(texture.handle, -                           GetFormatTuple(params.pixel_format, params.component_type), params.width, -                           params.height); +                           GetFormatTuple(params.pixel_format, params.component_type), +                           rect.GetWidth(), rect.GetHeight());  }  MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); @@ -225,21 +231,23 @@ void CachedSurface::LoadGLBuffer() {      ASSERT(texture_src_data); -    if (!gl_buffer) { -        gl_buffer_size = params.width * params.height * GetGLBytesPerPixel(params.pixel_format); -        gl_buffer.reset(new u8[gl_buffer_size]); -    } +    gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format));      MICROPROFILE_SCOPE(OpenGL_SurfaceLoad);      if (!params.is_tiled) {          const u32 bytes_per_pixel{params.GetFormatBpp() >> 3}; -        std::memcpy(&gl_buffer[0], texture_src_data, +        std::memcpy(gl_buffer.data(), texture_src_data,                      bytes_per_pixel * params.width * params.height);      } else {          morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( -            params.width, params.block_height, params.height, &gl_buffer[0], params.addr); +            params.width, params.block_height, params.height, gl_buffer.data(), params.addr); +    } + +    if (IsPixelFormatASTC(params.pixel_format)) { +        // ASTC formats are converted to RGBA8 in software, as most PC GPUs do not support this +        ConvertASTCToRGBA8(gl_buffer, params.pixel_format, params.width, params.height);      }  } @@ -248,16 +256,16 @@ void CachedSurface::FlushGLBuffer() {      u8* const dst_buffer = Memory::GetPointer(params.GetCpuAddr());      ASSERT(dst_buffer); -    ASSERT(gl_buffer_size == +    ASSERT(gl_buffer.size() ==             params.width * params.height * GetGLBytesPerPixel(params.pixel_format));      MICROPROFILE_SCOPE(OpenGL_SurfaceFlush);      if (!params.is_tiled) { -        std::memcpy(dst_buffer, &gl_buffer[0], params.size_in_bytes); +        std::memcpy(dst_buffer, gl_buffer.data(), params.size_in_bytes);      } else {          gl_to_morton_fns[static_cast<size_t>(params.pixel_format)]( -            params.width, params.block_height, params.height, &gl_buffer[0], params.addr); +            params.width, params.block_height, params.height, gl_buffer.data(), params.addr);      }  } @@ -268,7 +276,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle      MICROPROFILE_SCOPE(OpenGL_TextureUL); -    ASSERT(gl_buffer_size == +    ASSERT(gl_buffer.size() ==             params.width * params.height * GetGLBytesPerPixel(params.pixel_format));      const auto& rect{params.GetRect()}; @@ -315,10 +323,7 @@ void CachedSurface::DownloadGLTexture(GLuint read_fb_handle, GLuint draw_fb_hand      MICROPROFILE_SCOPE(OpenGL_TextureDL); -    if (!gl_buffer) { -        gl_buffer_size = params.width * params.height * GetGLBytesPerPixel(params.pixel_format); -        gl_buffer.reset(new u8[gl_buffer_size]); -    } +    gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format));      OpenGLState state = OpenGLState::GetCurState();      OpenGLState prev_state = state; diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index bf36f6c24..84bdec652 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -7,6 +7,7 @@  #include <array>  #include <map>  #include <memory> +#include <vector>  #include "common/common_types.h"  #include "common/hash.h" @@ -79,7 +80,7 @@ struct SurfaceParams {              4, // DXT23              4, // DXT45              4, // DXN1 -            1, // ASTC_2D_4X4 +            4, // ASTC_2D_4X4          }};          ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); @@ -242,9 +243,7 @@ struct SurfaceParams {          return SurfaceType::Invalid;      } -    MathUtil::Rectangle<u32> GetRect() const { -        return {0, height, width, 0}; -    } +    MathUtil::Rectangle<u32> GetRect() const;      size_t SizeInBytes() const {          const u32 compression_factor{GetCompressionFactor(pixel_format)}; @@ -269,6 +268,7 @@ struct SurfaceParams {      SurfaceType type;      u32 width;      u32 height; +    u32 unaligned_height;      size_t size_in_bytes;  }; @@ -318,8 +318,7 @@ public:  private:      OGLTexture texture; -    std::unique_ptr<u8[]> gl_buffer; -    size_t gl_buffer_size; +    std::vector<u8> gl_buffer;      SurfaceParams params;  };  | 
