diff options
| author | 2018-04-23 23:45:47 -0400 | |
|---|---|---|
| committer | 2018-04-24 22:31:46 -0400 | |
| commit | bc0f1896fc1092bdc66fb66f977163de08672f01 (patch) | |
| tree | 8ad416a2de1336c68edeb3f155964c7649aef106 /src | |
| parent | gl_rasterizer_cache: Update to be based on GPU addresses, not CPU addresses. (diff) | |
| download | yuzu-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.cpp | 37 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 52 |
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 | ||
| 49 | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | 46 | static 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 | ||
| 58 | static const FormatTuple& GetFormatTuple(PixelFormat pixel_format, ComponentType component_type) { | 55 | static 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 | } |