diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 135 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 40 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 6 |
3 files changed, 109 insertions, 72 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 9c8925383..591ec7998 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -78,6 +78,29 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { | |||
| 78 | } | 78 | } |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const { | ||
| 82 | const u32 compression_factor{GetCompressionFactor(pixel_format)}; | ||
| 83 | const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)}; | ||
| 84 | u32 m_depth = (layer_only ? 1U : depth); | ||
| 85 | u32 m_width = std::max(1U, width / compression_factor); | ||
| 86 | u32 m_height = std::max(1U, height / compression_factor); | ||
| 87 | std::size_t size = Tegra::Texture::CalculateSize(is_tiled, bytes_per_pixel, m_width, m_height, | ||
| 88 | m_depth, block_height, block_depth); | ||
| 89 | u32 m_block_height = block_height; | ||
| 90 | u32 m_block_depth = block_depth; | ||
| 91 | std::size_t block_size_bytes = 512 * block_height * block_depth; // 512 is GOB size | ||
| 92 | for (u32 i = 1; i < max_mip_level; i++) { | ||
| 93 | m_width = std::max(1U, m_width / 2); | ||
| 94 | m_height = std::max(1U, m_height / 2); | ||
| 95 | m_depth = std::max(1U, m_depth / 2); | ||
| 96 | m_block_height = std::max(1U, m_block_height / 2); | ||
| 97 | m_block_depth = std::max(1U, m_block_depth / 2); | ||
| 98 | size += Tegra::Texture::CalculateSize(is_tiled, bytes_per_pixel, m_width, m_height, m_depth, | ||
| 99 | m_block_height, m_block_depth); | ||
| 100 | } | ||
| 101 | return is_tiled ? Common::AlignUp(size, block_size_bytes) : size; | ||
| 102 | } | ||
| 103 | |||
| 81 | /*static*/ SurfaceParams SurfaceParams::CreateForTexture( | 104 | /*static*/ SurfaceParams SurfaceParams::CreateForTexture( |
| 82 | const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) { | 105 | const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) { |
| 83 | SurfaceParams params{}; | 106 | SurfaceParams params{}; |
| @@ -124,6 +147,7 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { | |||
| 124 | break; | 147 | break; |
| 125 | } | 148 | } |
| 126 | 149 | ||
| 150 | params.is_layered = SurfaceTargetIsLayered(params.target); | ||
| 127 | params.max_mip_level = config.tic.max_mip_level + 1; | 151 | params.max_mip_level = config.tic.max_mip_level + 1; |
| 128 | params.rt = {}; | 152 | params.rt = {}; |
| 129 | 153 | ||
| @@ -150,6 +174,7 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { | |||
| 150 | params.target = SurfaceTarget::Texture2D; | 174 | params.target = SurfaceTarget::Texture2D; |
| 151 | params.depth = 1; | 175 | params.depth = 1; |
| 152 | params.max_mip_level = 0; | 176 | params.max_mip_level = 0; |
| 177 | params.is_layered = false; | ||
| 153 | 178 | ||
| 154 | // Render target specific parameters, not used for caching | 179 | // Render target specific parameters, not used for caching |
| 155 | params.rt.index = static_cast<u32>(index); | 180 | params.rt.index = static_cast<u32>(index); |
| @@ -182,6 +207,7 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { | |||
| 182 | params.target = SurfaceTarget::Texture2D; | 207 | params.target = SurfaceTarget::Texture2D; |
| 183 | params.depth = 1; | 208 | params.depth = 1; |
| 184 | params.max_mip_level = 0; | 209 | params.max_mip_level = 0; |
| 210 | params.is_layered = false; | ||
| 185 | params.rt = {}; | 211 | params.rt = {}; |
| 186 | 212 | ||
| 187 | params.InitCacheParameters(zeta_address); | 213 | params.InitCacheParameters(zeta_address); |
| @@ -361,10 +387,11 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d | |||
| 361 | } | 387 | } |
| 362 | } | 388 | } |
| 363 | 389 | ||
| 364 | static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr), | 390 | using GLConversionArray = std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr), |
| 365 | SurfaceParams::MaxPixelFormat> | 391 | SurfaceParams::MaxPixelFormat>; |
| 366 | morton_to_gl_fns = { | 392 | |
| 367 | // clang-format off | 393 | static constexpr GLConversionArray morton_to_gl_fns = { |
| 394 | // clang-format off | ||
| 368 | MortonCopy<true, PixelFormat::ABGR8U>, | 395 | MortonCopy<true, PixelFormat::ABGR8U>, |
| 369 | MortonCopy<true, PixelFormat::ABGR8S>, | 396 | MortonCopy<true, PixelFormat::ABGR8S>, |
| 370 | MortonCopy<true, PixelFormat::ABGR8UI>, | 397 | MortonCopy<true, PixelFormat::ABGR8UI>, |
| @@ -418,13 +445,11 @@ static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, | |||
| 418 | MortonCopy<true, PixelFormat::Z24S8>, | 445 | MortonCopy<true, PixelFormat::Z24S8>, |
| 419 | MortonCopy<true, PixelFormat::S8Z24>, | 446 | MortonCopy<true, PixelFormat::S8Z24>, |
| 420 | MortonCopy<true, PixelFormat::Z32FS8>, | 447 | MortonCopy<true, PixelFormat::Z32FS8>, |
| 421 | // clang-format on | 448 | // clang-format on |
| 422 | }; | 449 | }; |
| 423 | 450 | ||
| 424 | static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr), | 451 | static constexpr GLConversionArray gl_to_morton_fns = { |
| 425 | SurfaceParams::MaxPixelFormat> | 452 | // clang-format off |
| 426 | gl_to_morton_fns = { | ||
| 427 | // clang-format off | ||
| 428 | MortonCopy<false, PixelFormat::ABGR8U>, | 453 | MortonCopy<false, PixelFormat::ABGR8U>, |
| 429 | MortonCopy<false, PixelFormat::ABGR8S>, | 454 | MortonCopy<false, PixelFormat::ABGR8S>, |
| 430 | MortonCopy<false, PixelFormat::ABGR8UI>, | 455 | MortonCopy<false, PixelFormat::ABGR8UI>, |
| @@ -479,9 +504,35 @@ static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, | |||
| 479 | MortonCopy<false, PixelFormat::Z24S8>, | 504 | MortonCopy<false, PixelFormat::Z24S8>, |
| 480 | MortonCopy<false, PixelFormat::S8Z24>, | 505 | MortonCopy<false, PixelFormat::S8Z24>, |
| 481 | MortonCopy<false, PixelFormat::Z32FS8>, | 506 | MortonCopy<false, PixelFormat::Z32FS8>, |
| 482 | // clang-format on | 507 | // clang-format on |
| 483 | }; | 508 | }; |
| 484 | 509 | ||
| 510 | void SwizzleFunc(const GLConversionArray& functions, const SurfaceParams& params, | ||
| 511 | std::vector<u8>& gl_buffer) { | ||
| 512 | u32 depth = params.depth; | ||
| 513 | if (params.target == SurfaceParams::SurfaceTarget::Texture2D) { | ||
| 514 | // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented. | ||
| 515 | depth = 1U; | ||
| 516 | } | ||
| 517 | if (params.is_layered) { | ||
| 518 | u64 offset = 0; | ||
| 519 | u64 offset_gl = 0; | ||
| 520 | u64 layer_size = params.LayerMemorySize(); | ||
| 521 | u64 gl_size = params.LayerSizeGL(); | ||
| 522 | for (u32 i = 0; i < depth; i++) { | ||
| 523 | functions[static_cast<std::size_t>(params.pixel_format)]( | ||
| 524 | params.width, params.block_height, params.height, params.block_depth, 1, | ||
| 525 | gl_buffer.data() + offset_gl, gl_size, params.addr + offset); | ||
| 526 | offset += layer_size; | ||
| 527 | offset_gl += gl_size; | ||
| 528 | } | ||
| 529 | } else { | ||
| 530 | functions[static_cast<std::size_t>(params.pixel_format)]( | ||
| 531 | params.width, params.block_height, params.height, params.block_depth, depth, | ||
| 532 | gl_buffer.data(), gl_buffer.size(), params.addr); | ||
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 485 | static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface, | 536 | static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface, |
| 486 | GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0, | 537 | GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0, |
| 487 | GLenum dst_attachment = 0, std::size_t cubemap_face = 0) { | 538 | GLenum dst_attachment = 0, std::size_t cubemap_face = 0) { |
| @@ -881,21 +932,10 @@ void CachedSurface::LoadGLBuffer() { | |||
| 881 | 932 | ||
| 882 | gl_buffer.resize(params.size_in_bytes_gl); | 933 | gl_buffer.resize(params.size_in_bytes_gl); |
| 883 | if (params.is_tiled) { | 934 | if (params.is_tiled) { |
| 884 | u32 depth = params.depth; | ||
| 885 | u32 block_depth = params.block_depth; | ||
| 886 | |||
| 887 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}", | 935 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}", |
| 888 | params.block_width, static_cast<u32>(params.target)); | 936 | params.block_width, static_cast<u32>(params.target)); |
| 889 | 937 | ||
| 890 | if (params.target == SurfaceParams::SurfaceTarget::Texture2D) { | 938 | SwizzleFunc(morton_to_gl_fns, params, gl_buffer); |
| 891 | // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented. | ||
| 892 | depth = 1U; | ||
| 893 | block_depth = 1U; | ||
| 894 | } | ||
| 895 | |||
| 896 | morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)]( | ||
| 897 | params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(), | ||
| 898 | gl_buffer.size(), params.addr); | ||
| 899 | } else { | 939 | } else { |
| 900 | const auto texture_src_data{Memory::GetPointer(params.addr)}; | 940 | const auto texture_src_data{Memory::GetPointer(params.addr)}; |
| 901 | const auto texture_src_data_end{texture_src_data + params.size_in_bytes_gl}; | 941 | const auto texture_src_data_end{texture_src_data + params.size_in_bytes_gl}; |
| @@ -929,19 +969,10 @@ void CachedSurface::FlushGLBuffer() { | |||
| 929 | const u8* const texture_src_data = Memory::GetPointer(params.addr); | 969 | const u8* const texture_src_data = Memory::GetPointer(params.addr); |
| 930 | ASSERT(texture_src_data); | 970 | ASSERT(texture_src_data); |
| 931 | if (params.is_tiled) { | 971 | if (params.is_tiled) { |
| 932 | u32 depth = params.depth; | ||
| 933 | u32 block_depth = params.block_depth; | ||
| 934 | |||
| 935 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}", | 972 | ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}", |
| 936 | params.block_width, static_cast<u32>(params.target)); | 973 | params.block_width, static_cast<u32>(params.target)); |
| 937 | 974 | ||
| 938 | if (params.target == SurfaceParams::SurfaceTarget::Texture2D) { | 975 | SwizzleFunc(gl_to_morton_fns, params, gl_buffer); |
| 939 | // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented. | ||
| 940 | depth = 1U; | ||
| 941 | } | ||
| 942 | gl_to_morton_fns[static_cast<size_t>(params.pixel_format)]( | ||
| 943 | params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(), | ||
| 944 | gl_buffer.size(), GetAddr()); | ||
| 945 | } else { | 976 | } else { |
| 946 | std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer.data(), GetSizeInBytes()); | 977 | std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer.data(), GetSizeInBytes()); |
| 947 | } | 978 | } |
| @@ -1179,7 +1210,7 @@ void RasterizerCacheOpenGL::AccurateCopySurface(const Surface& src_surface, | |||
| 1179 | const Surface& dst_surface) { | 1210 | const Surface& dst_surface) { |
| 1180 | const auto& src_params{src_surface->GetSurfaceParams()}; | 1211 | const auto& src_params{src_surface->GetSurfaceParams()}; |
| 1181 | const auto& dst_params{dst_surface->GetSurfaceParams()}; | 1212 | const auto& dst_params{dst_surface->GetSurfaceParams()}; |
| 1182 | FlushRegion(src_params.addr, dst_params.size_in_bytes); | 1213 | FlushRegion(src_params.addr, dst_params.MemorySize()); |
| 1183 | LoadSurface(dst_surface); | 1214 | LoadSurface(dst_surface); |
| 1184 | } | 1215 | } |
| 1185 | 1216 | ||
| @@ -1221,44 +1252,10 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, | |||
| 1221 | CopySurface(old_surface, new_surface, copy_pbo.handle); | 1252 | CopySurface(old_surface, new_surface, copy_pbo.handle); |
| 1222 | } | 1253 | } |
| 1223 | break; | 1254 | break; |
| 1255 | case SurfaceParams::SurfaceTarget::TextureCubemap: | ||
| 1224 | case SurfaceParams::SurfaceTarget::Texture3D: | 1256 | case SurfaceParams::SurfaceTarget::Texture3D: |
| 1225 | AccurateCopySurface(old_surface, new_surface); | 1257 | AccurateCopySurface(old_surface, new_surface); |
| 1226 | break; | 1258 | break; |
| 1227 | case SurfaceParams::SurfaceTarget::TextureCubemap: { | ||
| 1228 | if (old_params.rt.array_mode != 1) { | ||
| 1229 | // TODO(bunnei): This is used by Breath of the Wild, I'm not sure how to implement this | ||
| 1230 | // yet (array rendering used as a cubemap texture). | ||
| 1231 | LOG_CRITICAL(HW_GPU, "Unhandled rendertarget array_mode {}", old_params.rt.array_mode); | ||
| 1232 | UNREACHABLE(); | ||
| 1233 | return new_surface; | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | // This seems to be used for render-to-cubemap texture | ||
| 1237 | ASSERT_MSG(old_params.target == SurfaceParams::SurfaceTarget::Texture2D, "Unexpected"); | ||
| 1238 | ASSERT_MSG(old_params.pixel_format == new_params.pixel_format, "Unexpected"); | ||
| 1239 | ASSERT_MSG(old_params.rt.base_layer == 0, "Unimplemented"); | ||
| 1240 | |||
| 1241 | // TODO(bunnei): Verify the below - this stride seems to be in 32-bit words, not pixels. | ||
| 1242 | // Tested with Splatoon 2, Super Mario Odyssey, and Breath of the Wild. | ||
| 1243 | const std::size_t byte_stride{old_params.rt.layer_stride * sizeof(u32)}; | ||
| 1244 | |||
| 1245 | for (std::size_t index = 0; index < new_params.depth; ++index) { | ||
| 1246 | Surface face_surface{TryGetReservedSurface(old_params)}; | ||
| 1247 | ASSERT_MSG(face_surface, "Unexpected"); | ||
| 1248 | |||
| 1249 | if (is_blit) { | ||
| 1250 | BlitSurface(face_surface, new_surface, read_framebuffer.handle, | ||
| 1251 | draw_framebuffer.handle, face_surface->GetSurfaceParams().rt.index, | ||
| 1252 | new_params.rt.index, index); | ||
| 1253 | } else { | ||
| 1254 | CopySurface(face_surface, new_surface, copy_pbo.handle, | ||
| 1255 | face_surface->GetSurfaceParams().rt.index, new_params.rt.index, index); | ||
| 1256 | } | ||
| 1257 | |||
| 1258 | old_params.addr += byte_stride; | ||
| 1259 | } | ||
| 1260 | break; | ||
| 1261 | } | ||
| 1262 | default: | 1259 | default: |
| 1263 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | 1260 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", |
| 1264 | static_cast<u32>(new_params.target)); | 1261 | static_cast<u32>(new_params.target)); |
| @@ -1266,7 +1263,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, | |||
| 1266 | } | 1263 | } |
| 1267 | 1264 | ||
| 1268 | return new_surface; | 1265 | return new_surface; |
| 1269 | } | 1266 | } // namespace OpenGL |
| 1270 | 1267 | ||
| 1271 | Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr addr) const { | 1268 | Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr addr) const { |
| 1272 | return TryGet(addr); | 1269 | return TryGet(addr); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 0dd0d90a3..50a7ab47d 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -168,6 +168,23 @@ struct SurfaceParams { | |||
| 168 | } | 168 | } |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static bool SurfaceTargetIsLayered(SurfaceTarget target) { | ||
| 172 | switch (target) { | ||
| 173 | case SurfaceTarget::Texture1D: | ||
| 174 | case SurfaceTarget::Texture2D: | ||
| 175 | case SurfaceTarget::Texture3D: | ||
| 176 | return false; | ||
| 177 | case SurfaceTarget::Texture1DArray: | ||
| 178 | case SurfaceTarget::Texture2DArray: | ||
| 179 | case SurfaceTarget::TextureCubemap: | ||
| 180 | return true; | ||
| 181 | default: | ||
| 182 | LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target)); | ||
| 183 | UNREACHABLE(); | ||
| 184 | return false; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 171 | /** | 188 | /** |
| 172 | * Gets the compression factor for the specified PixelFormat. This applies to just the | 189 | * Gets the compression factor for the specified PixelFormat. This applies to just the |
| 173 | * "compressed width" and "compressed height", not the overall compression factor of a | 190 | * "compressed width" and "compressed height", not the overall compression factor of a |
| @@ -742,6 +759,25 @@ struct SurfaceParams { | |||
| 742 | return size_in_bytes_gl / 6; | 759 | return size_in_bytes_gl / 6; |
| 743 | } | 760 | } |
| 744 | 761 | ||
| 762 | /// Returns the exact size of memory occupied by the texture in VRAM, including mipmaps. | ||
| 763 | std::size_t MemorySize() const { | ||
| 764 | std::size_t size = InnerMemorySize(is_layered); | ||
| 765 | if (is_layered) | ||
| 766 | return size * depth; | ||
| 767 | return size; | ||
| 768 | } | ||
| 769 | |||
| 770 | /// Returns the exact size of the memory occupied by a layer in a texture in VRAM, including | ||
| 771 | /// mipmaps. | ||
| 772 | std::size_t LayerMemorySize() const { | ||
| 773 | return InnerMemorySize(true); | ||
| 774 | } | ||
| 775 | |||
| 776 | /// Returns the size of a layer of this surface in OpenGL. | ||
| 777 | std::size_t LayerSizeGL() const { | ||
| 778 | return SizeInBytesRaw(true) / depth; | ||
| 779 | } | ||
| 780 | |||
| 745 | /// Creates SurfaceParams from a texture configuration | 781 | /// Creates SurfaceParams from a texture configuration |
| 746 | static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config, | 782 | static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config, |
| 747 | const GLShader::SamplerEntry& entry); | 783 | const GLShader::SamplerEntry& entry); |
| @@ -782,6 +818,7 @@ struct SurfaceParams { | |||
| 782 | u32 unaligned_height; | 818 | u32 unaligned_height; |
| 783 | SurfaceTarget target; | 819 | SurfaceTarget target; |
| 784 | u32 max_mip_level; | 820 | u32 max_mip_level; |
| 821 | bool is_layered; | ||
| 785 | 822 | ||
| 786 | // Parameters used for caching | 823 | // Parameters used for caching |
| 787 | VAddr addr; | 824 | VAddr addr; |
| @@ -797,6 +834,9 @@ struct SurfaceParams { | |||
| 797 | u32 layer_stride; | 834 | u32 layer_stride; |
| 798 | u32 base_layer; | 835 | u32 base_layer; |
| 799 | } rt; | 836 | } rt; |
| 837 | |||
| 838 | private: | ||
| 839 | std::size_t InnerMemorySize(bool layer_only = false) const; | ||
| 800 | }; | 840 | }; |
| 801 | 841 | ||
| 802 | }; // namespace OpenGL | 842 | }; // namespace OpenGL |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index da7989db9..550ca856c 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -319,13 +319,13 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat | |||
| 319 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, | 319 | std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, |
| 320 | u32 block_height, u32 block_depth) { | 320 | u32 block_height, u32 block_depth) { |
| 321 | if (tiled) { | 321 | if (tiled) { |
| 322 | const u32 gobs_in_x = 64 / bytes_per_pixel; | 322 | const u32 gobs_in_x = 64; |
| 323 | const u32 gobs_in_y = 8; | 323 | const u32 gobs_in_y = 8; |
| 324 | const u32 gobs_in_z = 1; | 324 | const u32 gobs_in_z = 1; |
| 325 | const u32 aligned_width = Common::AlignUp(width, gobs_in_x); | 325 | const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gobs_in_x); |
| 326 | const u32 aligned_height = Common::AlignUp(height, gobs_in_y * block_height); | 326 | const u32 aligned_height = Common::AlignUp(height, gobs_in_y * block_height); |
| 327 | const u32 aligned_depth = Common::AlignUp(depth, gobs_in_z * block_depth); | 327 | const u32 aligned_depth = Common::AlignUp(depth, gobs_in_z * block_depth); |
| 328 | return aligned_width * aligned_height * aligned_depth * bytes_per_pixel; | 328 | return aligned_width * aligned_height * aligned_depth; |
| 329 | } else { | 329 | } else { |
| 330 | return width * height * depth * bytes_per_pixel; | 330 | return width * height * depth * bytes_per_pixel; |
| 331 | } | 331 | } |