diff options
| author | 2018-06-26 15:05:13 -0400 | |
|---|---|---|
| committer | 2018-06-27 00:08:04 -0400 | |
| commit | 8af1ae46aa5a9303b21839b446d2ebf17ee12802 (patch) | |
| tree | 0107f0b2e7442bece9a58992c09fdc6532b98871 | |
| parent | gl_rasterizer_cache: Use SurfaceParams as a key for surface caching. (diff) | |
| download | yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.gz yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.xz yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.zip | |
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 { | |||
| 41 | params.type = GetFormatType(params.pixel_format); | 41 | params.type = GetFormatType(params.pixel_format); |
| 42 | params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); | 42 | params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); |
| 43 | params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); | 43 | params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); |
| 44 | params.unaligned_height = config.tic.Height(); | ||
| 44 | params.size_in_bytes = params.SizeInBytes(); | 45 | params.size_in_bytes = params.SizeInBytes(); |
| 45 | return params; | 46 | return params; |
| 46 | } | 47 | } |
| @@ -57,6 +58,7 @@ struct FormatTuple { | |||
| 57 | params.type = GetFormatType(params.pixel_format); | 58 | params.type = GetFormatType(params.pixel_format); |
| 58 | params.width = config.width; | 59 | params.width = config.width; |
| 59 | params.height = config.height; | 60 | params.height = config.height; |
| 61 | params.unaligned_height = config.height; | ||
| 60 | params.size_in_bytes = params.SizeInBytes(); | 62 | params.size_in_bytes = params.SizeInBytes(); |
| 61 | return params; | 63 | return params; |
| 62 | } | 64 | } |
| @@ -108,20 +110,29 @@ static bool IsPixelFormatASTC(PixelFormat format) { | |||
| 108 | } | 110 | } |
| 109 | } | 111 | } |
| 110 | 112 | ||
| 111 | static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) { | 113 | static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) { |
| 112 | u32 block_width{}; | ||
| 113 | u32 block_height{}; | ||
| 114 | |||
| 115 | switch (format) { | 114 | switch (format) { |
| 116 | case PixelFormat::ASTC_2D_4X4: | 115 | case PixelFormat::ASTC_2D_4X4: |
| 117 | block_width = 4; | 116 | return {4, 4}; |
| 118 | block_height = 4; | ||
| 119 | break; | ||
| 120 | default: | 117 | default: |
| 121 | NGLOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); | 118 | NGLOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format)); |
| 122 | UNREACHABLE(); | 119 | UNREACHABLE(); |
| 123 | } | 120 | } |
| 121 | } | ||
| 124 | 122 | ||
| 123 | MathUtil::Rectangle<u32> SurfaceParams::GetRect() const { | ||
| 124 | u32 actual_height{unaligned_height}; | ||
| 125 | if (IsPixelFormatASTC(pixel_format)) { | ||
| 126 | // ASTC formats must stop at the ATSC block size boundary | ||
| 127 | actual_height = Common::AlignDown(actual_height, GetASTCBlockSize(pixel_format).second); | ||
| 128 | } | ||
| 129 | return {0, actual_height, width, 0}; | ||
| 130 | } | ||
| 131 | |||
| 132 | static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) { | ||
| 133 | u32 block_width{}; | ||
| 134 | u32 block_height{}; | ||
| 135 | std::tie(block_width, block_height) = GetASTCBlockSize(format); | ||
| 125 | data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height); | 136 | data = Tegra::Texture::ASTC::Decompress(data, width, height, block_width, block_height); |
| 126 | } | 137 | } |
| 127 | 138 | ||
| @@ -136,12 +147,6 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u8* gl_buffer, Tegra:: | |||
| 136 | *gpu.memory_manager->GpuToCpuAddress(addr), | 147 | *gpu.memory_manager->GpuToCpuAddress(addr), |
| 137 | SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); | 148 | SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); |
| 138 | 149 | ||
| 139 | if (IsPixelFormatASTC(format)) { | ||
| 140 | // ASTC formats are converted to RGBA8 in software, as most PC GPUs do not support | ||
| 141 | // this | ||
| 142 | ConvertASTCToRGBA8(data, format, stride, height); | ||
| 143 | } | ||
| 144 | |||
| 145 | std::memcpy(gl_buffer, data.data(), data.size()); | 150 | std::memcpy(gl_buffer, data.data(), data.size()); |
| 146 | } else { | 151 | } else { |
| 147 | // TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should | 152 | // 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 | |||
| 212 | 217 | ||
| 213 | CachedSurface::CachedSurface(const SurfaceParams& params) : params(params), gl_buffer_size(0) { | 218 | CachedSurface::CachedSurface(const SurfaceParams& params) : params(params), gl_buffer_size(0) { |
| 214 | texture.Create(); | 219 | texture.Create(); |
| 220 | const auto& rect{params.GetRect()}; | ||
| 215 | AllocateSurfaceTexture(texture.handle, | 221 | AllocateSurfaceTexture(texture.handle, |
| 216 | GetFormatTuple(params.pixel_format, params.component_type), params.width, | 222 | GetFormatTuple(params.pixel_format, params.component_type), |
| 217 | params.height); | 223 | rect.GetWidth(), rect.GetHeight()); |
| 218 | } | 224 | } |
| 219 | 225 | ||
| 220 | MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); | 226 | MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); |
| @@ -225,21 +231,23 @@ void CachedSurface::LoadGLBuffer() { | |||
| 225 | 231 | ||
| 226 | ASSERT(texture_src_data); | 232 | ASSERT(texture_src_data); |
| 227 | 233 | ||
| 228 | if (!gl_buffer) { | 234 | gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); |
| 229 | gl_buffer_size = params.width * params.height * GetGLBytesPerPixel(params.pixel_format); | ||
| 230 | gl_buffer.reset(new u8[gl_buffer_size]); | ||
| 231 | } | ||
| 232 | 235 | ||
| 233 | MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); | 236 | MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); |
| 234 | 237 | ||
| 235 | if (!params.is_tiled) { | 238 | if (!params.is_tiled) { |
| 236 | const u32 bytes_per_pixel{params.GetFormatBpp() >> 3}; | 239 | const u32 bytes_per_pixel{params.GetFormatBpp() >> 3}; |
| 237 | 240 | ||
| 238 | std::memcpy(&gl_buffer[0], texture_src_data, | 241 | std::memcpy(gl_buffer.data(), texture_src_data, |
| 239 | bytes_per_pixel * params.width * params.height); | 242 | bytes_per_pixel * params.width * params.height); |
| 240 | } else { | 243 | } else { |
| 241 | morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( | 244 | morton_to_gl_fns[static_cast<size_t>(params.pixel_format)]( |
| 242 | params.width, params.block_height, params.height, &gl_buffer[0], params.addr); | 245 | params.width, params.block_height, params.height, gl_buffer.data(), params.addr); |
| 246 | } | ||
| 247 | |||
| 248 | if (IsPixelFormatASTC(params.pixel_format)) { | ||
| 249 | // ASTC formats are converted to RGBA8 in software, as most PC GPUs do not support this | ||
| 250 | ConvertASTCToRGBA8(gl_buffer, params.pixel_format, params.width, params.height); | ||
| 243 | } | 251 | } |
| 244 | } | 252 | } |
| 245 | 253 | ||
| @@ -248,16 +256,16 @@ void CachedSurface::FlushGLBuffer() { | |||
| 248 | u8* const dst_buffer = Memory::GetPointer(params.GetCpuAddr()); | 256 | u8* const dst_buffer = Memory::GetPointer(params.GetCpuAddr()); |
| 249 | 257 | ||
| 250 | ASSERT(dst_buffer); | 258 | ASSERT(dst_buffer); |
| 251 | ASSERT(gl_buffer_size == | 259 | ASSERT(gl_buffer.size() == |
| 252 | params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); | 260 | params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); |
| 253 | 261 | ||
| 254 | MICROPROFILE_SCOPE(OpenGL_SurfaceFlush); | 262 | MICROPROFILE_SCOPE(OpenGL_SurfaceFlush); |
| 255 | 263 | ||
| 256 | if (!params.is_tiled) { | 264 | if (!params.is_tiled) { |
| 257 | std::memcpy(dst_buffer, &gl_buffer[0], params.size_in_bytes); | 265 | std::memcpy(dst_buffer, gl_buffer.data(), params.size_in_bytes); |
| 258 | } else { | 266 | } else { |
| 259 | gl_to_morton_fns[static_cast<size_t>(params.pixel_format)]( | 267 | gl_to_morton_fns[static_cast<size_t>(params.pixel_format)]( |
| 260 | params.width, params.block_height, params.height, &gl_buffer[0], params.addr); | 268 | params.width, params.block_height, params.height, gl_buffer.data(), params.addr); |
| 261 | } | 269 | } |
| 262 | } | 270 | } |
| 263 | 271 | ||
| @@ -268,7 +276,7 @@ void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle | |||
| 268 | 276 | ||
| 269 | MICROPROFILE_SCOPE(OpenGL_TextureUL); | 277 | MICROPROFILE_SCOPE(OpenGL_TextureUL); |
| 270 | 278 | ||
| 271 | ASSERT(gl_buffer_size == | 279 | ASSERT(gl_buffer.size() == |
| 272 | params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); | 280 | params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); |
| 273 | 281 | ||
| 274 | const auto& rect{params.GetRect()}; | 282 | const auto& rect{params.GetRect()}; |
| @@ -315,10 +323,7 @@ void CachedSurface::DownloadGLTexture(GLuint read_fb_handle, GLuint draw_fb_hand | |||
| 315 | 323 | ||
| 316 | MICROPROFILE_SCOPE(OpenGL_TextureDL); | 324 | MICROPROFILE_SCOPE(OpenGL_TextureDL); |
| 317 | 325 | ||
| 318 | if (!gl_buffer) { | 326 | gl_buffer.resize(params.width * params.height * GetGLBytesPerPixel(params.pixel_format)); |
| 319 | gl_buffer_size = params.width * params.height * GetGLBytesPerPixel(params.pixel_format); | ||
| 320 | gl_buffer.reset(new u8[gl_buffer_size]); | ||
| 321 | } | ||
| 322 | 327 | ||
| 323 | OpenGLState state = OpenGLState::GetCurState(); | 328 | OpenGLState state = OpenGLState::GetCurState(); |
| 324 | OpenGLState prev_state = state; | 329 | 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 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <map> | 8 | #include <map> |
| 9 | #include <memory> | 9 | #include <memory> |
| 10 | #include <vector> | ||
| 10 | 11 | ||
| 11 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 12 | #include "common/hash.h" | 13 | #include "common/hash.h" |
| @@ -79,7 +80,7 @@ struct SurfaceParams { | |||
| 79 | 4, // DXT23 | 80 | 4, // DXT23 |
| 80 | 4, // DXT45 | 81 | 4, // DXT45 |
| 81 | 4, // DXN1 | 82 | 4, // DXN1 |
| 82 | 1, // ASTC_2D_4X4 | 83 | 4, // ASTC_2D_4X4 |
| 83 | }}; | 84 | }}; |
| 84 | 85 | ||
| 85 | ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); | 86 | ASSERT(static_cast<size_t>(format) < compression_factor_table.size()); |
| @@ -242,9 +243,7 @@ struct SurfaceParams { | |||
| 242 | return SurfaceType::Invalid; | 243 | return SurfaceType::Invalid; |
| 243 | } | 244 | } |
| 244 | 245 | ||
| 245 | MathUtil::Rectangle<u32> GetRect() const { | 246 | MathUtil::Rectangle<u32> GetRect() const; |
| 246 | return {0, height, width, 0}; | ||
| 247 | } | ||
| 248 | 247 | ||
| 249 | size_t SizeInBytes() const { | 248 | size_t SizeInBytes() const { |
| 250 | const u32 compression_factor{GetCompressionFactor(pixel_format)}; | 249 | const u32 compression_factor{GetCompressionFactor(pixel_format)}; |
| @@ -269,6 +268,7 @@ struct SurfaceParams { | |||
| 269 | SurfaceType type; | 268 | SurfaceType type; |
| 270 | u32 width; | 269 | u32 width; |
| 271 | u32 height; | 270 | u32 height; |
| 271 | u32 unaligned_height; | ||
| 272 | size_t size_in_bytes; | 272 | size_t size_in_bytes; |
| 273 | }; | 273 | }; |
| 274 | 274 | ||
| @@ -318,8 +318,7 @@ public: | |||
| 318 | 318 | ||
| 319 | private: | 319 | private: |
| 320 | OGLTexture texture; | 320 | OGLTexture texture; |
| 321 | std::unique_ptr<u8[]> gl_buffer; | 321 | std::vector<u8> gl_buffer; |
| 322 | size_t gl_buffer_size; | ||
| 323 | SurfaceParams params; | 322 | SurfaceParams params; |
| 324 | }; | 323 | }; |
| 325 | 324 | ||