mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	Merge pull request #1524 from FernandoS27/layers-fix
rasterizer: Fix Layered Textures Loading and Cubemaps
This commit is contained in:
		
						commit
						f7a173de6c
					
				@ -78,6 +78,29 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::size_t SurfaceParams::InnerMemorySize(bool layer_only) const {
 | 
				
			||||||
 | 
					    const u32 compression_factor{GetCompressionFactor(pixel_format)};
 | 
				
			||||||
 | 
					    const u32 bytes_per_pixel{GetBytesPerPixel(pixel_format)};
 | 
				
			||||||
 | 
					    u32 m_depth = (layer_only ? 1U : depth);
 | 
				
			||||||
 | 
					    u32 m_width = std::max(1U, width / compression_factor);
 | 
				
			||||||
 | 
					    u32 m_height = std::max(1U, height / compression_factor);
 | 
				
			||||||
 | 
					    std::size_t size = Tegra::Texture::CalculateSize(is_tiled, bytes_per_pixel, m_width, m_height,
 | 
				
			||||||
 | 
					                                                     m_depth, block_height, block_depth);
 | 
				
			||||||
 | 
					    u32 m_block_height = block_height;
 | 
				
			||||||
 | 
					    u32 m_block_depth = block_depth;
 | 
				
			||||||
 | 
					    std::size_t block_size_bytes = 512 * block_height * block_depth; // 512 is GOB size
 | 
				
			||||||
 | 
					    for (u32 i = 1; i < max_mip_level; i++) {
 | 
				
			||||||
 | 
					        m_width = std::max(1U, m_width / 2);
 | 
				
			||||||
 | 
					        m_height = std::max(1U, m_height / 2);
 | 
				
			||||||
 | 
					        m_depth = std::max(1U, m_depth / 2);
 | 
				
			||||||
 | 
					        m_block_height = std::max(1U, m_block_height / 2);
 | 
				
			||||||
 | 
					        m_block_depth = std::max(1U, m_block_depth / 2);
 | 
				
			||||||
 | 
					        size += Tegra::Texture::CalculateSize(is_tiled, bytes_per_pixel, m_width, m_height, m_depth,
 | 
				
			||||||
 | 
					                                              m_block_height, m_block_depth);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return is_tiled ? Common::AlignUp(size, block_size_bytes) : size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*static*/ SurfaceParams SurfaceParams::CreateForTexture(
 | 
					/*static*/ SurfaceParams SurfaceParams::CreateForTexture(
 | 
				
			||||||
    const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) {
 | 
					    const Tegra::Texture::FullTextureInfo& config, const GLShader::SamplerEntry& entry) {
 | 
				
			||||||
    SurfaceParams params{};
 | 
					    SurfaceParams params{};
 | 
				
			||||||
@ -124,6 +147,7 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    params.is_layered = SurfaceTargetIsLayered(params.target);
 | 
				
			||||||
    params.max_mip_level = config.tic.max_mip_level + 1;
 | 
					    params.max_mip_level = config.tic.max_mip_level + 1;
 | 
				
			||||||
    params.rt = {};
 | 
					    params.rt = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -150,6 +174,7 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {
 | 
				
			|||||||
    params.target = SurfaceTarget::Texture2D;
 | 
					    params.target = SurfaceTarget::Texture2D;
 | 
				
			||||||
    params.depth = 1;
 | 
					    params.depth = 1;
 | 
				
			||||||
    params.max_mip_level = 0;
 | 
					    params.max_mip_level = 0;
 | 
				
			||||||
 | 
					    params.is_layered = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Render target specific parameters, not used for caching
 | 
					    // Render target specific parameters, not used for caching
 | 
				
			||||||
    params.rt.index = static_cast<u32>(index);
 | 
					    params.rt.index = static_cast<u32>(index);
 | 
				
			||||||
@ -182,6 +207,7 @@ void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {
 | 
				
			|||||||
    params.target = SurfaceTarget::Texture2D;
 | 
					    params.target = SurfaceTarget::Texture2D;
 | 
				
			||||||
    params.depth = 1;
 | 
					    params.depth = 1;
 | 
				
			||||||
    params.max_mip_level = 0;
 | 
					    params.max_mip_level = 0;
 | 
				
			||||||
 | 
					    params.is_layered = false;
 | 
				
			||||||
    params.rt = {};
 | 
					    params.rt = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    params.InitCacheParameters(zeta_address);
 | 
					    params.InitCacheParameters(zeta_address);
 | 
				
			||||||
@ -361,10 +387,11 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr),
 | 
					using GLConversionArray = std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr),
 | 
				
			||||||
                            SurfaceParams::MaxPixelFormat>
 | 
					                                     SurfaceParams::MaxPixelFormat>;
 | 
				
			||||||
    morton_to_gl_fns = {
 | 
					
 | 
				
			||||||
        // clang-format off
 | 
					static constexpr GLConversionArray morton_to_gl_fns = {
 | 
				
			||||||
 | 
					    // clang-format off
 | 
				
			||||||
        MortonCopy<true, PixelFormat::ABGR8U>,
 | 
					        MortonCopy<true, PixelFormat::ABGR8U>,
 | 
				
			||||||
        MortonCopy<true, PixelFormat::ABGR8S>,
 | 
					        MortonCopy<true, PixelFormat::ABGR8S>,
 | 
				
			||||||
        MortonCopy<true, PixelFormat::ABGR8UI>,
 | 
					        MortonCopy<true, PixelFormat::ABGR8UI>,
 | 
				
			||||||
@ -418,13 +445,11 @@ static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t,
 | 
				
			|||||||
        MortonCopy<true, PixelFormat::Z24S8>,
 | 
					        MortonCopy<true, PixelFormat::Z24S8>,
 | 
				
			||||||
        MortonCopy<true, PixelFormat::S8Z24>,
 | 
					        MortonCopy<true, PixelFormat::S8Z24>,
 | 
				
			||||||
        MortonCopy<true, PixelFormat::Z32FS8>,
 | 
					        MortonCopy<true, PixelFormat::Z32FS8>,
 | 
				
			||||||
        // clang-format on
 | 
					    // clang-format on
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr),
 | 
					static constexpr GLConversionArray gl_to_morton_fns = {
 | 
				
			||||||
                            SurfaceParams::MaxPixelFormat>
 | 
					    // clang-format off
 | 
				
			||||||
    gl_to_morton_fns = {
 | 
					 | 
				
			||||||
        // clang-format off
 | 
					 | 
				
			||||||
        MortonCopy<false, PixelFormat::ABGR8U>,
 | 
					        MortonCopy<false, PixelFormat::ABGR8U>,
 | 
				
			||||||
        MortonCopy<false, PixelFormat::ABGR8S>,
 | 
					        MortonCopy<false, PixelFormat::ABGR8S>,
 | 
				
			||||||
        MortonCopy<false, PixelFormat::ABGR8UI>,
 | 
					        MortonCopy<false, PixelFormat::ABGR8UI>,
 | 
				
			||||||
@ -479,9 +504,35 @@ static constexpr std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t,
 | 
				
			|||||||
        MortonCopy<false, PixelFormat::Z24S8>,
 | 
					        MortonCopy<false, PixelFormat::Z24S8>,
 | 
				
			||||||
        MortonCopy<false, PixelFormat::S8Z24>,
 | 
					        MortonCopy<false, PixelFormat::S8Z24>,
 | 
				
			||||||
        MortonCopy<false, PixelFormat::Z32FS8>,
 | 
					        MortonCopy<false, PixelFormat::Z32FS8>,
 | 
				
			||||||
        // clang-format on
 | 
					    // clang-format on
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SwizzleFunc(const GLConversionArray& functions, const SurfaceParams& params,
 | 
				
			||||||
 | 
					                 std::vector<u8>& gl_buffer) {
 | 
				
			||||||
 | 
					    u32 depth = params.depth;
 | 
				
			||||||
 | 
					    if (params.target == SurfaceParams::SurfaceTarget::Texture2D) {
 | 
				
			||||||
 | 
					        // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented.
 | 
				
			||||||
 | 
					        depth = 1U;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (params.is_layered) {
 | 
				
			||||||
 | 
					        u64 offset = 0;
 | 
				
			||||||
 | 
					        u64 offset_gl = 0;
 | 
				
			||||||
 | 
					        u64 layer_size = params.LayerMemorySize();
 | 
				
			||||||
 | 
					        u64 gl_size = params.LayerSizeGL();
 | 
				
			||||||
 | 
					        for (u32 i = 0; i < depth; i++) {
 | 
				
			||||||
 | 
					            functions[static_cast<std::size_t>(params.pixel_format)](
 | 
				
			||||||
 | 
					                params.width, params.block_height, params.height, params.block_depth, 1,
 | 
				
			||||||
 | 
					                gl_buffer.data() + offset_gl, gl_size, params.addr + offset);
 | 
				
			||||||
 | 
					            offset += layer_size;
 | 
				
			||||||
 | 
					            offset_gl += gl_size;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        functions[static_cast<std::size_t>(params.pixel_format)](
 | 
				
			||||||
 | 
					            params.width, params.block_height, params.height, params.block_depth, depth,
 | 
				
			||||||
 | 
					            gl_buffer.data(), gl_buffer.size(), params.addr);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
 | 
					static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
 | 
				
			||||||
                        GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0,
 | 
					                        GLuint read_fb_handle, GLuint draw_fb_handle, GLenum src_attachment = 0,
 | 
				
			||||||
                        GLenum dst_attachment = 0, std::size_t cubemap_face = 0) {
 | 
					                        GLenum dst_attachment = 0, std::size_t cubemap_face = 0) {
 | 
				
			||||||
@ -881,21 +932,10 @@ void CachedSurface::LoadGLBuffer() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    gl_buffer.resize(params.size_in_bytes_gl);
 | 
					    gl_buffer.resize(params.size_in_bytes_gl);
 | 
				
			||||||
    if (params.is_tiled) {
 | 
					    if (params.is_tiled) {
 | 
				
			||||||
        u32 depth = params.depth;
 | 
					 | 
				
			||||||
        u32 block_depth = params.block_depth;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}",
 | 
					        ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}",
 | 
				
			||||||
                   params.block_width, static_cast<u32>(params.target));
 | 
					                   params.block_width, static_cast<u32>(params.target));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (params.target == SurfaceParams::SurfaceTarget::Texture2D) {
 | 
					        SwizzleFunc(morton_to_gl_fns, params, gl_buffer);
 | 
				
			||||||
            // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented.
 | 
					 | 
				
			||||||
            depth = 1U;
 | 
					 | 
				
			||||||
            block_depth = 1U;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        morton_to_gl_fns[static_cast<std::size_t>(params.pixel_format)](
 | 
					 | 
				
			||||||
            params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(),
 | 
					 | 
				
			||||||
            gl_buffer.size(), params.addr);
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        const auto texture_src_data{Memory::GetPointer(params.addr)};
 | 
					        const auto texture_src_data{Memory::GetPointer(params.addr)};
 | 
				
			||||||
        const auto texture_src_data_end{texture_src_data + params.size_in_bytes_gl};
 | 
					        const auto texture_src_data_end{texture_src_data + params.size_in_bytes_gl};
 | 
				
			||||||
@ -929,19 +969,10 @@ void CachedSurface::FlushGLBuffer() {
 | 
				
			|||||||
    const u8* const texture_src_data = Memory::GetPointer(params.addr);
 | 
					    const u8* const texture_src_data = Memory::GetPointer(params.addr);
 | 
				
			||||||
    ASSERT(texture_src_data);
 | 
					    ASSERT(texture_src_data);
 | 
				
			||||||
    if (params.is_tiled) {
 | 
					    if (params.is_tiled) {
 | 
				
			||||||
        u32 depth = params.depth;
 | 
					 | 
				
			||||||
        u32 block_depth = params.block_depth;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}",
 | 
					        ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture type {}",
 | 
				
			||||||
                   params.block_width, static_cast<u32>(params.target));
 | 
					                   params.block_width, static_cast<u32>(params.target));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (params.target == SurfaceParams::SurfaceTarget::Texture2D) {
 | 
					        SwizzleFunc(gl_to_morton_fns, params, gl_buffer);
 | 
				
			||||||
            // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented.
 | 
					 | 
				
			||||||
            depth = 1U;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        gl_to_morton_fns[static_cast<size_t>(params.pixel_format)](
 | 
					 | 
				
			||||||
            params.width, params.block_height, params.height, block_depth, depth, gl_buffer.data(),
 | 
					 | 
				
			||||||
            gl_buffer.size(), GetAddr());
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer.data(), GetSizeInBytes());
 | 
					        std::memcpy(Memory::GetPointer(GetAddr()), gl_buffer.data(), GetSizeInBytes());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1179,7 +1210,7 @@ void RasterizerCacheOpenGL::AccurateCopySurface(const Surface& src_surface,
 | 
				
			|||||||
                                                const Surface& dst_surface) {
 | 
					                                                const Surface& dst_surface) {
 | 
				
			||||||
    const auto& src_params{src_surface->GetSurfaceParams()};
 | 
					    const auto& src_params{src_surface->GetSurfaceParams()};
 | 
				
			||||||
    const auto& dst_params{dst_surface->GetSurfaceParams()};
 | 
					    const auto& dst_params{dst_surface->GetSurfaceParams()};
 | 
				
			||||||
    FlushRegion(src_params.addr, dst_params.size_in_bytes);
 | 
					    FlushRegion(src_params.addr, dst_params.MemorySize());
 | 
				
			||||||
    LoadSurface(dst_surface);
 | 
					    LoadSurface(dst_surface);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1221,44 +1252,10 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
 | 
				
			|||||||
            CopySurface(old_surface, new_surface, copy_pbo.handle);
 | 
					            CopySurface(old_surface, new_surface, copy_pbo.handle);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 | 
					    case SurfaceParams::SurfaceTarget::TextureCubemap:
 | 
				
			||||||
    case SurfaceParams::SurfaceTarget::Texture3D:
 | 
					    case SurfaceParams::SurfaceTarget::Texture3D:
 | 
				
			||||||
        AccurateCopySurface(old_surface, new_surface);
 | 
					        AccurateCopySurface(old_surface, new_surface);
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
    case SurfaceParams::SurfaceTarget::TextureCubemap: {
 | 
					 | 
				
			||||||
        if (old_params.rt.array_mode != 1) {
 | 
					 | 
				
			||||||
            // TODO(bunnei): This is used by Breath of the Wild, I'm not sure how to implement this
 | 
					 | 
				
			||||||
            // yet (array rendering used as a cubemap texture).
 | 
					 | 
				
			||||||
            LOG_CRITICAL(HW_GPU, "Unhandled rendertarget array_mode {}", old_params.rt.array_mode);
 | 
					 | 
				
			||||||
            UNREACHABLE();
 | 
					 | 
				
			||||||
            return new_surface;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // This seems to be used for render-to-cubemap texture
 | 
					 | 
				
			||||||
        ASSERT_MSG(old_params.target == SurfaceParams::SurfaceTarget::Texture2D, "Unexpected");
 | 
					 | 
				
			||||||
        ASSERT_MSG(old_params.pixel_format == new_params.pixel_format, "Unexpected");
 | 
					 | 
				
			||||||
        ASSERT_MSG(old_params.rt.base_layer == 0, "Unimplemented");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // TODO(bunnei): Verify the below - this stride seems to be in 32-bit words, not pixels.
 | 
					 | 
				
			||||||
        // Tested with Splatoon 2, Super Mario Odyssey, and Breath of the Wild.
 | 
					 | 
				
			||||||
        const std::size_t byte_stride{old_params.rt.layer_stride * sizeof(u32)};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (std::size_t index = 0; index < new_params.depth; ++index) {
 | 
					 | 
				
			||||||
            Surface face_surface{TryGetReservedSurface(old_params)};
 | 
					 | 
				
			||||||
            ASSERT_MSG(face_surface, "Unexpected");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (is_blit) {
 | 
					 | 
				
			||||||
                BlitSurface(face_surface, new_surface, read_framebuffer.handle,
 | 
					 | 
				
			||||||
                            draw_framebuffer.handle, face_surface->GetSurfaceParams().rt.index,
 | 
					 | 
				
			||||||
                            new_params.rt.index, index);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                CopySurface(face_surface, new_surface, copy_pbo.handle,
 | 
					 | 
				
			||||||
                            face_surface->GetSurfaceParams().rt.index, new_params.rt.index, index);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            old_params.addr += byte_stride;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
 | 
					        LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",
 | 
				
			||||||
                     static_cast<u32>(new_params.target));
 | 
					                     static_cast<u32>(new_params.target));
 | 
				
			||||||
@ -1266,7 +1263,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return new_surface;
 | 
					    return new_surface;
 | 
				
			||||||
}
 | 
					} // namespace OpenGL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr addr) const {
 | 
					Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr addr) const {
 | 
				
			||||||
    return TryGet(addr);
 | 
					    return TryGet(addr);
 | 
				
			||||||
 | 
				
			|||||||
@ -168,6 +168,23 @@ struct SurfaceParams {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static bool SurfaceTargetIsLayered(SurfaceTarget target) {
 | 
				
			||||||
 | 
					        switch (target) {
 | 
				
			||||||
 | 
					        case SurfaceTarget::Texture1D:
 | 
				
			||||||
 | 
					        case SurfaceTarget::Texture2D:
 | 
				
			||||||
 | 
					        case SurfaceTarget::Texture3D:
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        case SurfaceTarget::Texture1DArray:
 | 
				
			||||||
 | 
					        case SurfaceTarget::Texture2DArray:
 | 
				
			||||||
 | 
					        case SurfaceTarget::TextureCubemap:
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
 | 
				
			||||||
 | 
					            UNREACHABLE();
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Gets the compression factor for the specified PixelFormat. This applies to just the
 | 
					     * Gets the compression factor for the specified PixelFormat. This applies to just the
 | 
				
			||||||
     * "compressed width" and "compressed height", not the overall compression factor of a
 | 
					     * "compressed width" and "compressed height", not the overall compression factor of a
 | 
				
			||||||
@ -742,6 +759,25 @@ struct SurfaceParams {
 | 
				
			|||||||
        return size_in_bytes_gl / 6;
 | 
					        return size_in_bytes_gl / 6;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Returns the exact size of memory occupied by the texture in VRAM, including mipmaps.
 | 
				
			||||||
 | 
					    std::size_t MemorySize() const {
 | 
				
			||||||
 | 
					        std::size_t size = InnerMemorySize(is_layered);
 | 
				
			||||||
 | 
					        if (is_layered)
 | 
				
			||||||
 | 
					            return size * depth;
 | 
				
			||||||
 | 
					        return size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Returns the exact size of the memory occupied by a layer in a texture in VRAM, including
 | 
				
			||||||
 | 
					    /// mipmaps.
 | 
				
			||||||
 | 
					    std::size_t LayerMemorySize() const {
 | 
				
			||||||
 | 
					        return InnerMemorySize(true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Returns the size of a layer of this surface in OpenGL.
 | 
				
			||||||
 | 
					    std::size_t LayerSizeGL() const {
 | 
				
			||||||
 | 
					        return SizeInBytesRaw(true) / depth;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Creates SurfaceParams from a texture configuration
 | 
					    /// Creates SurfaceParams from a texture configuration
 | 
				
			||||||
    static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config,
 | 
					    static SurfaceParams CreateForTexture(const Tegra::Texture::FullTextureInfo& config,
 | 
				
			||||||
                                          const GLShader::SamplerEntry& entry);
 | 
					                                          const GLShader::SamplerEntry& entry);
 | 
				
			||||||
@ -782,6 +818,7 @@ struct SurfaceParams {
 | 
				
			|||||||
    u32 unaligned_height;
 | 
					    u32 unaligned_height;
 | 
				
			||||||
    SurfaceTarget target;
 | 
					    SurfaceTarget target;
 | 
				
			||||||
    u32 max_mip_level;
 | 
					    u32 max_mip_level;
 | 
				
			||||||
 | 
					    bool is_layered;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Parameters used for caching
 | 
					    // Parameters used for caching
 | 
				
			||||||
    VAddr addr;
 | 
					    VAddr addr;
 | 
				
			||||||
@ -797,6 +834,9 @@ struct SurfaceParams {
 | 
				
			|||||||
        u32 layer_stride;
 | 
					        u32 layer_stride;
 | 
				
			||||||
        u32 base_layer;
 | 
					        u32 base_layer;
 | 
				
			||||||
    } rt;
 | 
					    } rt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::size_t InnerMemorySize(bool layer_only = false) const;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}; // namespace OpenGL
 | 
					}; // namespace OpenGL
 | 
				
			||||||
 | 
				
			|||||||
@ -319,13 +319,13 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
 | 
				
			|||||||
std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
 | 
					std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
 | 
				
			||||||
                          u32 block_height, u32 block_depth) {
 | 
					                          u32 block_height, u32 block_depth) {
 | 
				
			||||||
    if (tiled) {
 | 
					    if (tiled) {
 | 
				
			||||||
        const u32 gobs_in_x = 64 / bytes_per_pixel;
 | 
					        const u32 gobs_in_x = 64;
 | 
				
			||||||
        const u32 gobs_in_y = 8;
 | 
					        const u32 gobs_in_y = 8;
 | 
				
			||||||
        const u32 gobs_in_z = 1;
 | 
					        const u32 gobs_in_z = 1;
 | 
				
			||||||
        const u32 aligned_width = Common::AlignUp(width, gobs_in_x);
 | 
					        const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gobs_in_x);
 | 
				
			||||||
        const u32 aligned_height = Common::AlignUp(height, gobs_in_y * block_height);
 | 
					        const u32 aligned_height = Common::AlignUp(height, gobs_in_y * block_height);
 | 
				
			||||||
        const u32 aligned_depth = Common::AlignUp(depth, gobs_in_z * block_depth);
 | 
					        const u32 aligned_depth = Common::AlignUp(depth, gobs_in_z * block_depth);
 | 
				
			||||||
        return aligned_width * aligned_height * aligned_depth * bytes_per_pixel;
 | 
					        return aligned_width * aligned_height * aligned_depth;
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        return width * height * depth * bytes_per_pixel;
 | 
					        return width * height * depth * bytes_per_pixel;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user