summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2018-04-23 23:45:47 -0400
committerGravatar bunnei2018-04-24 22:31:46 -0400
commitbc0f1896fc1092bdc66fb66f977163de08672f01 (patch)
tree8ad416a2de1336c68edeb3f155964c7649aef106 /src
parentgl_rasterizer_cache: Update to be based on GPU addresses, not CPU addresses. (diff)
downloadyuzu-bc0f1896fc1092bdc66fb66f977163de08672f01.tar.gz
yuzu-bc0f1896fc1092bdc66fb66f977163de08672f01.tar.xz
yuzu-bc0f1896fc1092bdc66fb66f977163de08672f01.zip
gl_rasterizer_cache: Handle compressed texture sizes.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp37
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h52
2 files changed, 65 insertions, 24 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index d139d51e9..e1ad00feb 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -41,18 +41,15 @@ struct FormatTuple {
41 GLenum format; 41 GLenum format;
42 GLenum type; 42 GLenum type;
43 bool compressed; 43 bool compressed;
44 // How many pixels in the original texture are equivalent to one pixel in the compressed
45 // texture.
46 u32 compression_factor;
47}; 44};
48 45
49static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ 46static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{
50 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false, 1}, // ABGR8 47 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, false}, // ABGR8
51 {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false, 1}, // B5G6R5 48 {GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, false}, // B5G6R5
52 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false, 1}, // A2B10G10R10 49 {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, false}, // A2B10G10R10
53 {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1 50 {GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT1
54 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT23 51 {GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT23
55 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT45 52 {GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, true}, // DXT45
56}}; 53}};
57 54
58static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { 55static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) {
@@ -476,7 +473,7 @@ void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr loa
476 return; 473 return;
477 474
478 if (gl_buffer == nullptr) { 475 if (gl_buffer == nullptr) {
479 gl_buffer_size = width * height * GetGLBytesPerPixel(pixel_format); 476 gl_buffer_size = GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format);
480 gl_buffer.reset(new u8[gl_buffer_size]); 477 gl_buffer.reset(new u8[gl_buffer_size]);
481 } 478 }
482 479
@@ -491,8 +488,9 @@ void CachedSurface::LoadGLBuffer(Tegra::GPUVAddr load_start, Tegra::GPUVAddr loa
491 std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset, 488 std::memcpy(&gl_buffer[start_offset], texture_src_data + start_offset,
492 bytes_per_pixel * width * height); 489 bytes_per_pixel * width * height);
493 } else { 490 } else {
494 morton_to_gl_fns[static_cast<size_t>(pixel_format)]( 491 morton_to_gl_fns[static_cast<size_t>(pixel_format)](GetActualWidth(), block_height,
495 stride, block_height, height, &gl_buffer[0], addr, load_start, load_end); 492 GetActualHeight(), &gl_buffer[0], addr,
493 load_start, load_end);
496 } 494 }
497} 495}
498 496
@@ -548,7 +546,8 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint
548 546
549 MICROPROFILE_SCOPE(OpenGL_TextureUL); 547 MICROPROFILE_SCOPE(OpenGL_TextureUL);
550 548
551 ASSERT(gl_buffer_size == width * height * GetGLBytesPerPixel(pixel_format)); 549 ASSERT(gl_buffer_size ==
550 GetActualWidth() * GetActualHeight() * GetGLBytesPerPixel(pixel_format));
552 551
553 // Load data from memory to the surface 552 // Load data from memory to the surface
554 GLint x0 = static_cast<GLint>(rect.left); 553 GLint x0 = static_cast<GLint>(rect.left);
@@ -583,11 +582,9 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint
583 glActiveTexture(GL_TEXTURE0); 582 glActiveTexture(GL_TEXTURE0);
584 if (tuple.compressed) { 583 if (tuple.compressed) {
585 glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format, 584 glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format,
586 static_cast<GLsizei>(rect.GetWidth()), 585 static_cast<GLsizei>(rect.GetWidth() * GetCompresssionFactor()),
587 static_cast<GLsizei>(rect.GetHeight()), 0, 586 static_cast<GLsizei>(rect.GetHeight() * GetCompresssionFactor()), 0,
588 rect.GetWidth() * rect.GetHeight() * 587 size, &gl_buffer[buffer_offset]);
589 GetGLBytesPerPixel(pixel_format) / tuple.compression_factor,
590 &gl_buffer[buffer_offset]);
591 } else { 588 } else {
592 glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()), 589 glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
593 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, 590 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
@@ -1041,10 +1038,10 @@ Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextu
1041 1038
1042 SurfaceParams params; 1039 SurfaceParams params;
1043 params.addr = config.tic.Address(); 1040 params.addr = config.tic.Address();
1044 params.width = config.tic.Width();
1045 params.height = config.tic.Height();
1046 params.is_tiled = config.tic.IsTiled(); 1041 params.is_tiled = config.tic.IsTiled();
1047 params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format); 1042 params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format);
1043 params.width = config.tic.Width() / params.GetCompresssionFactor();
1044 params.height = config.tic.Height() / params.GetCompresssionFactor();
1048 1045
1049 // TODO(Subv): Different types per component are not supported. 1046 // TODO(Subv): Different types per component are not supported.
1050 ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() && 1047 ASSERT(config.tic.r_type.Value() == config.tic.g_type.Value() &&
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index 5f77f4e61..08858bab4 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -84,23 +84,49 @@ struct SurfaceParams {
84 Invalid = 4, 84 Invalid = 4,
85 }; 85 };
86 86
87 static constexpr unsigned int GetFormatBpp(PixelFormat format) { 87 /**
88 * Gets the compression factor for the specified PixelFormat. This applies to just the
89 * "compressed width" and "compressed height", not the overall compression factor of a
90 * compressed image. This is used for maintaining proper surface sizes for compressed texture
91 * formats.
92 */
93 static constexpr u32 GetCompresssionFactor(PixelFormat format) {
88 if (format == PixelFormat::Invalid) 94 if (format == PixelFormat::Invalid)
89 return 0; 95 return 0;
90 96
91 constexpr std::array<unsigned int, MaxPixelFormat> bpp_table = { 97 constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{
98 1, // ABGR8
99 1, // B5G6R5
100 1, // A2B10G10R10
101 4, // DXT1
102 4, // DXT23
103 4, // DXT45
104 }};
105
106 ASSERT(static_cast<size_t>(format) < compression_factor_table.size());
107 return compression_factor_table[static_cast<size_t>(format)];
108 }
109 u32 GetCompresssionFactor() const {
110 return GetCompresssionFactor(pixel_format);
111 }
112
113 static constexpr u32 GetFormatBpp(PixelFormat format) {
114 if (format == PixelFormat::Invalid)
115 return 0;
116
117 constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
92 32, // ABGR8 118 32, // ABGR8
93 16, // B5G6R5 119 16, // B5G6R5
94 32, // A2B10G10R10 120 32, // A2B10G10R10
95 64, // DXT1 121 64, // DXT1
96 128, // DXT23 122 128, // DXT23
97 128, // DXT45 123 128, // DXT45
98 }; 124 }};
99 125
100 ASSERT(static_cast<size_t>(format) < bpp_table.size()); 126 ASSERT(static_cast<size_t>(format) < bpp_table.size());
101 return bpp_table[static_cast<size_t>(format)]; 127 return bpp_table[static_cast<size_t>(format)];
102 } 128 }
103 unsigned int GetFormatBpp() const { 129 u32 GetFormatBpp() const {
104 return GetFormatBpp(pixel_format); 130 return GetFormatBpp(pixel_format);
105 } 131 }
106 132
@@ -255,6 +281,24 @@ struct SurfaceParams {
255 // Returns the region of the biggest valid rectange within interval 281 // Returns the region of the biggest valid rectange within interval
256 SurfaceInterval GetCopyableInterval(const Surface& src_surface) const; 282 SurfaceInterval GetCopyableInterval(const Surface& src_surface) const;
257 283
284 /**
285 * Gets the actual width (in pixels) of the surface. This is provided because `width` is used
286 * for tracking the surface region in memory, which may be compressed for certain formats. In
287 * this scenario, `width` is actually the compressed width.
288 */
289 u32 GetActualWidth() const {
290 return width * GetCompresssionFactor();
291 }
292
293 /**
294 * Gets the actual height (in pixels) of the surface. This is provided because `height` is used
295 * for tracking the surface region in memory, which may be compressed for certain formats. In
296 * this scenario, `height` is actually the compressed height.
297 */
298 u32 GetActualHeight() const {
299 return height * GetCompresssionFactor();
300 }
301
258 u32 GetScaledWidth() const { 302 u32 GetScaledWidth() const {
259 return width * res_scale; 303 return width * res_scale;
260 } 304 }