summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2018-06-26 15:05:13 -0400
committerGravatar bunnei2018-06-27 00:08:04 -0400
commit8af1ae46aa5a9303b21839b446d2ebf17ee12802 (patch)
tree0107f0b2e7442bece9a58992c09fdc6532b98871
parentgl_rasterizer_cache: Use SurfaceParams as a key for surface caching. (diff)
downloadyuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.gz
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.tar.xz
yuzu-8af1ae46aa5a9303b21839b446d2ebf17ee12802.zip
gl_rasterizer_cache: Various fixes for ASTC handling.
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp63
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h11
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
111static void ConvertASTCToRGBA8(std::vector<u8>& data, PixelFormat format, u32 width, u32 height) { 113static 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
123MathUtil::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
132static 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
213CachedSurface::CachedSurface(const SurfaceParams& params) : params(params), gl_buffer_size(0) { 218CachedSurface::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
220MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 64, 192)); 226MICROPROFILE_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
319private: 319private:
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