From 1b4503c571d3b961efe74fa7e35d5fa14941ec09 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Wed, 24 Apr 2019 16:35:54 -0300 Subject: texture_cache: Split texture cache into different files --- src/video_core/texture_cache/surface_params.cpp | 412 ++++++++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 src/video_core/texture_cache/surface_params.cpp (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp new file mode 100644 index 000000000..d1f8c53d5 --- /dev/null +++ b/src/video_core/texture_cache/surface_params.cpp @@ -0,0 +1,412 @@ +// Copyright 2019 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include + +#include "common/cityhash.h" +#include "common/alignment.h" +#include "core/core.h" +#include "video_core/surface.h" +#include "video_core/texture_cache/surface_params.h" +#include "video_core/textures/decoders.h" + +namespace VideoCommon { + +using VideoCore::Surface::ComponentTypeFromDepthFormat; +using VideoCore::Surface::ComponentTypeFromRenderTarget; +using VideoCore::Surface::ComponentTypeFromTexture; +using VideoCore::Surface::PixelFormatFromDepthFormat; +using VideoCore::Surface::PixelFormatFromRenderTargetFormat; +using VideoCore::Surface::PixelFormatFromTextureFormat; +using VideoCore::Surface::SurfaceTarget; +using VideoCore::Surface::SurfaceTargetFromTextureType; + +namespace { +constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { + return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile); +} +} // Anonymous namespace + +SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, + const Tegra::Texture::FullTextureInfo& config) { + SurfaceParams params; + params.is_tiled = config.tic.IsTiled(); + params.srgb_conversion = config.tic.IsSrgbConversionEnabled(); + params.block_width = params.is_tiled ? config.tic.BlockWidth() : 0, + params.block_height = params.is_tiled ? config.tic.BlockHeight() : 0, + params.block_depth = params.is_tiled ? config.tic.BlockDepth() : 0, + params.tile_width_spacing = params.is_tiled ? (1 << config.tic.tile_width_spacing.Value()) : 1; + params.pixel_format = PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value(), + params.srgb_conversion); + params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); + params.type = GetFormatType(params.pixel_format); + params.target = SurfaceTargetFromTextureType(config.tic.texture_type); + params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); + params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); + params.depth = config.tic.Depth(); + if (params.target == SurfaceTarget::TextureCubemap || + params.target == SurfaceTarget::TextureCubeArray) { + params.depth *= 6; + } + params.pitch = params.is_tiled ? 0 : config.tic.Pitch(); + params.unaligned_height = config.tic.Height(); + params.num_levels = config.tic.max_mip_level + 1; + + params.CalculateCachedValues(); + return params; +} + +SurfaceParams SurfaceParams::CreateForDepthBuffer( + Core::System& system, u32 zeta_width, u32 zeta_height, Tegra::DepthFormat format, + u32 block_width, u32 block_height, u32 block_depth, + Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout type) { + SurfaceParams params; + params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; + params.srgb_conversion = false; + params.block_width = 1 << std::min(block_width, 5U); + params.block_height = 1 << std::min(block_height, 5U); + params.block_depth = 1 << std::min(block_depth, 5U); + params.tile_width_spacing = 1; + params.pixel_format = PixelFormatFromDepthFormat(format); + params.component_type = ComponentTypeFromDepthFormat(format); + params.type = GetFormatType(params.pixel_format); + params.width = zeta_width; + params.height = zeta_height; + params.unaligned_height = zeta_height; + params.target = SurfaceTarget::Texture2D; + params.depth = 1; + params.num_levels = 1; + + params.CalculateCachedValues(); + return params; +} + +SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::size_t index) { + const auto& config{system.GPU().Maxwell3D().regs.rt[index]}; + SurfaceParams params; + params.is_tiled = + config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; + params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || + config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; + params.block_width = 1 << config.memory_layout.block_width; + params.block_height = 1 << config.memory_layout.block_height; + params.block_depth = 1 << config.memory_layout.block_depth; + params.tile_width_spacing = 1; + params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); + params.component_type = ComponentTypeFromRenderTarget(config.format); + params.type = GetFormatType(params.pixel_format); + if (params.is_tiled) { + params.width = config.width; + } else { + const u32 bpp = GetFormatBpp(params.pixel_format) / CHAR_BIT; + params.pitch = config.width; + params.width = params.pitch / bpp; + } + params.height = config.height; + params.depth = 1; + params.unaligned_height = config.height; + params.target = SurfaceTarget::Texture2D; + params.num_levels = 1; + + params.CalculateCachedValues(); + return params; +} + +SurfaceParams SurfaceParams::CreateForFermiCopySurface( + const Tegra::Engines::Fermi2D::Regs::Surface& config) { + SurfaceParams params{}; + params.is_tiled = !config.linear; + params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || + config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; + params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0, + params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, + params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0, + params.tile_width_spacing = 1; + params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); + params.component_type = ComponentTypeFromRenderTarget(config.format); + params.type = GetFormatType(params.pixel_format); + params.width = config.width; + params.height = config.height; + params.unaligned_height = config.height; + // TODO(Rodrigo): Try to guess the surface target from depth and layer parameters + params.target = SurfaceTarget::Texture2D; + params.depth = 1; + params.num_levels = 1; + + params.CalculateCachedValues(); + return params; +} + +u32 SurfaceParams::GetMipWidth(u32 level) const { + return std::max(1U, width >> level); +} + +u32 SurfaceParams::GetMipHeight(u32 level) const { + return std::max(1U, height >> level); +} + +u32 SurfaceParams::GetMipDepth(u32 level) const { + return IsLayered() ? depth : std::max(1U, depth >> level); +} + +bool SurfaceParams::IsLayered() const { + switch (target) { + case SurfaceTarget::Texture1DArray: + case SurfaceTarget::Texture2DArray: + case SurfaceTarget::TextureCubemap: + case SurfaceTarget::TextureCubeArray: + return true; + default: + return false; + } +} + +u32 SurfaceParams::GetMipBlockHeight(u32 level) const { + // Auto block resizing algorithm from: + // https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c + if (level == 0) { + return this->block_height; + } + + const u32 height{GetMipHeight(level)}; + const u32 default_block_height{GetDefaultBlockHeight()}; + const u32 blocks_in_y{(height + default_block_height - 1) / default_block_height}; + u32 block_height = 16; + while (block_height > 1 && blocks_in_y <= block_height * 4) { + block_height >>= 1; + } + return block_height; +} + +u32 SurfaceParams::GetMipBlockDepth(u32 level) const { + if (level == 0) { + return this->block_depth; + } + if (IsLayered()) { + return 1; + } + + const u32 depth{GetMipDepth(level)}; + u32 block_depth = 32; + while (block_depth > 1 && depth * 2 <= block_depth) { + block_depth >>= 1; + } + + if (block_depth == 32 && GetMipBlockHeight(level) >= 4) { + return 16; + } + + return block_depth; +} + +std::size_t SurfaceParams::GetGuestMipmapLevelOffset(u32 level) const { + std::size_t offset = 0; + for (u32 i = 0; i < level; i++) { + offset += GetInnerMipmapMemorySize(i, false, false); + } + return offset; +} + +std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const { + std::size_t offset = 0; + for (u32 i = 0; i < level; i++) { + offset += GetInnerMipmapMemorySize(i, true, false) * GetNumLayers(); + } + return offset; +} + +std::size_t SurfaceParams::GetHostMipmapSize(u32 level) const { + return GetInnerMipmapMemorySize(level, true, false) * GetNumLayers(); +} + +std::size_t SurfaceParams::GetGuestLayerSize() const { + return GetLayerSize(false, false); +} + +std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) const { + std::size_t size = 0; + for (u32 level = 0; level < num_levels; ++level) { + size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed); + } + if (is_tiled && (IsLayered() || target == SurfaceTarget::Texture3D)) { + return Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); + } + return size; +} + +std::size_t SurfaceParams::GetHostLayerSize(u32 level) const { + ASSERT(target != SurfaceTarget::Texture3D); + return GetInnerMipmapMemorySize(level, true, false); +} + +u32 SurfaceParams::GetDefaultBlockWidth() const { + return VideoCore::Surface::GetDefaultBlockWidth(pixel_format); +} + +u32 SurfaceParams::GetDefaultBlockHeight() const { + return VideoCore::Surface::GetDefaultBlockHeight(pixel_format); +} + +u32 SurfaceParams::GetBitsPerPixel() const { + return VideoCore::Surface::GetFormatBpp(pixel_format); +} + +u32 SurfaceParams::GetBytesPerPixel() const { + return VideoCore::Surface::GetBytesPerPixel(pixel_format); +} + +bool SurfaceParams::IsFamiliar(const SurfaceParams& view_params) const { + if (std::tie(is_tiled, tile_width_spacing, pixel_format, component_type, type) != + std::tie(view_params.is_tiled, view_params.tile_width_spacing, view_params.pixel_format, + view_params.component_type, view_params.type)) { + return false; + } + + const SurfaceTarget view_target{view_params.target}; + if (view_target == target) { + return true; + } + + switch (target) { + case SurfaceTarget::Texture1D: + case SurfaceTarget::Texture2D: + case SurfaceTarget::Texture3D: + return false; + case SurfaceTarget::Texture1DArray: + return view_target == SurfaceTarget::Texture1D; + case SurfaceTarget::Texture2DArray: + return view_target == SurfaceTarget::Texture2D; + case SurfaceTarget::TextureCubemap: + return view_target == SurfaceTarget::Texture2D || + view_target == SurfaceTarget::Texture2DArray; + case SurfaceTarget::TextureCubeArray: + return view_target == SurfaceTarget::Texture2D || + view_target == SurfaceTarget::Texture2DArray || + view_target == SurfaceTarget::TextureCubemap; + default: + UNIMPLEMENTED_MSG("Unimplemented texture family={}", static_cast(target)); + return false; + } +} + +bool SurfaceParams::IsPixelFormatZeta() const { + return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat && + pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; +} + +void SurfaceParams::CalculateCachedValues() { + switch (target) { + case SurfaceTarget::Texture1D: + case SurfaceTarget::Texture2D: + case SurfaceTarget::Texture3D: + num_layers = 1; + break; + case SurfaceTarget::Texture1DArray: + case SurfaceTarget::Texture2DArray: + case SurfaceTarget::TextureCubemap: + case SurfaceTarget::TextureCubeArray: + num_layers = depth; + break; + default: + UNREACHABLE(); + } + + guest_size_in_bytes = GetInnerMemorySize(false, false, false); + + if (IsPixelFormatASTC(pixel_format)) { + // ASTC is uncompressed in software, in emulated as RGBA8 + host_size_in_bytes = static_cast(width) * static_cast(height) * + static_cast(depth) * 4ULL; + } else { + host_size_in_bytes = GetInnerMemorySize(true, false, false); + } +} + +std::size_t SurfaceParams::GetInnerMipmapMemorySize(u32 level, bool as_host_size, + bool uncompressed) const { + const bool tiled{as_host_size ? false : is_tiled}; + const u32 width{GetMipmapSize(uncompressed, GetMipWidth(level), GetDefaultBlockWidth())}; + const u32 height{GetMipmapSize(uncompressed, GetMipHeight(level), GetDefaultBlockHeight())}; + const u32 depth{target == SurfaceTarget::Texture3D ? GetMipDepth(level) : 1U}; + return Tegra::Texture::CalculateSize(tiled, GetBytesPerPixel(), width, height, depth, + GetMipBlockHeight(level), GetMipBlockDepth(level)); +} + +std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only, + bool uncompressed) const { + return GetLayerSize(as_host_size, uncompressed) * (layer_only ? 1U : num_layers); +} + +std::map> SurfaceParams::CreateViewOffsetMap() const { + std::map> view_offset_map; + switch (target) { + case SurfaceTarget::Texture1D: + case SurfaceTarget::Texture2D: + case SurfaceTarget::Texture3D: { + // TODO(Rodrigo): Add layer iterations for 3D textures + constexpr u32 layer = 0; + for (u32 level = 0; level < num_levels; ++level) { + const std::size_t offset{GetGuestMipmapLevelOffset(level)}; + view_offset_map.insert({offset, {layer, level}}); + } + break; + } + case SurfaceTarget::Texture1DArray: + case SurfaceTarget::Texture2DArray: + case SurfaceTarget::TextureCubemap: + case SurfaceTarget::TextureCubeArray: { + const std::size_t layer_size{GetGuestLayerSize()}; + for (u32 level = 0; level < num_levels; ++level) { + const std::size_t level_offset{GetGuestMipmapLevelOffset(level)}; + for (u32 layer = 0; layer < num_layers; ++layer) { + const auto layer_offset{static_cast(layer_size * layer)}; + const std::size_t offset{level_offset + layer_offset}; + view_offset_map.insert({offset, {layer, level}}); + } + } + break; + } + default: + UNIMPLEMENTED_MSG("Unimplemented surface target {}", static_cast(target)); + } + return view_offset_map; +} + +bool SurfaceParams::IsViewValid(const SurfaceParams& view_params, u32 layer, u32 level) const { + return IsDimensionValid(view_params, level) && IsDepthValid(view_params, level) && + IsInBounds(view_params, layer, level); +} + +bool SurfaceParams::IsDimensionValid(const SurfaceParams& view_params, u32 level) const { + return view_params.width == GetMipWidth(level) && view_params.height == GetMipHeight(level); +} + +bool SurfaceParams::IsDepthValid(const SurfaceParams& view_params, u32 level) const { + if (view_params.target != SurfaceTarget::Texture3D) { + return true; + } + return view_params.depth == GetMipDepth(level); +} + +bool SurfaceParams::IsInBounds(const SurfaceParams& view_params, u32 layer, u32 level) const { + return layer + view_params.num_layers <= num_layers && + level + view_params.num_levels <= num_levels; +} + +std::size_t HasheableSurfaceParams::Hash() const { + return static_cast( + Common::CityHash64(reinterpret_cast(this), sizeof(*this))); +} + +bool HasheableSurfaceParams::operator==(const HasheableSurfaceParams& rhs) const { + return std::tie(is_tiled, block_width, block_height, block_depth, tile_width_spacing, width, + height, depth, pitch, unaligned_height, num_levels, pixel_format, + component_type, type, target) == + std::tie(rhs.is_tiled, rhs.block_width, rhs.block_height, rhs.block_depth, + rhs.tile_width_spacing, rhs.width, rhs.height, rhs.depth, rhs.pitch, + rhs.unaligned_height, rhs.num_levels, rhs.pixel_format, rhs.component_type, + rhs.type, rhs.target); +} + +} // namespace VideoCommon -- cgit v1.2.3 From 3d471e732d688c20aef73a506bdb6126002d3193 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 7 May 2019 10:56:45 -0400 Subject: Correct Surface Base and Views for new Texture Cache --- src/video_core/texture_cache/surface_params.cpp | 210 +++++++++--------------- 1 file changed, 75 insertions(+), 135 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index d1f8c53d5..d9052152c 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -7,6 +7,7 @@ #include "common/cityhash.h" #include "common/alignment.h" #include "core/core.h" +#include "video_core/engines/shader_bytecode.h" #include "video_core/surface.h" #include "video_core/texture_cache/surface_params.h" #include "video_core/textures/decoders.h" @@ -22,6 +23,37 @@ using VideoCore::Surface::PixelFormatFromTextureFormat; using VideoCore::Surface::SurfaceTarget; using VideoCore::Surface::SurfaceTargetFromTextureType; +SurfaceTarget TextureType2SurfaceTarget(Tegra::Shader::TextureType type, bool is_array) { + switch (type) { + case Tegra::Shader::TextureType::Texture1D: { + if (is_array) + return SurfaceTarget::Texture1DArray; + else + return SurfaceTarget::Texture1D; + } + case Tegra::Shader::TextureType::Texture2D: { + if (is_array) + return SurfaceTarget::Texture2DArray; + else + return SurfaceTarget::Texture2D; + } + case Tegra::Shader::TextureType::Texture3D: { + ASSERT(!is_array); + return SurfaceTarget::Texture3D; + } + case Tegra::Shader::TextureType::TextureCube: { + if (is_array) + return SurfaceTarget::TextureCubeArray; + else + return SurfaceTarget::TextureCubemap; + } + default: { + UNREACHABLE(); + return SurfaceTarget::Texture2D; + } + } +} + namespace { constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { return uncompressed ? mip_size : std::max(1U, (mip_size + tile - 1) / tile); @@ -29,7 +61,8 @@ constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { } // Anonymous namespace SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, - const Tegra::Texture::FullTextureInfo& config) { + const Tegra::Texture::FullTextureInfo& config, + const VideoCommon::Shader::Sampler& entry) { SurfaceParams params; params.is_tiled = config.tic.IsTiled(); params.srgb_conversion = config.tic.IsSrgbConversionEnabled(); @@ -41,7 +74,8 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.srgb_conversion); params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); params.type = GetFormatType(params.pixel_format); - params.target = SurfaceTargetFromTextureType(config.tic.texture_type); + // TODO: on 1DBuffer we should use the tic info. + params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray()); params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); params.depth = config.tic.Depth(); @@ -52,8 +86,7 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.pitch = params.is_tiled ? 0 : config.tic.Pitch(); params.unaligned_height = config.tic.Height(); params.num_levels = config.tic.max_mip_level + 1; - - params.CalculateCachedValues(); + params.is_layered = params.IsLayered(); return params; } @@ -77,8 +110,7 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer( params.target = SurfaceTarget::Texture2D; params.depth = 1; params.num_levels = 1; - - params.CalculateCachedValues(); + params.is_layered = false; return params; } @@ -108,8 +140,7 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz params.unaligned_height = config.height; params.target = SurfaceTarget::Texture2D; params.num_levels = 1; - - params.CalculateCachedValues(); + params.is_layered = false; return params; } @@ -128,13 +159,13 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( params.type = GetFormatType(params.pixel_format); params.width = config.width; params.height = config.height; + params.pitch = config.pitch; params.unaligned_height = config.height; // TODO(Rodrigo): Try to guess the surface target from depth and layer parameters params.target = SurfaceTarget::Texture2D; params.depth = 1; params.num_levels = 1; - - params.CalculateCachedValues(); + params.is_layered = params.IsLayered(); return params; } @@ -147,7 +178,7 @@ u32 SurfaceParams::GetMipHeight(u32 level) const { } u32 SurfaceParams::GetMipDepth(u32 level) const { - return IsLayered() ? depth : std::max(1U, depth >> level); + return is_layered ? depth : std::max(1U, depth >> level); } bool SurfaceParams::IsLayered() const { @@ -183,7 +214,7 @@ u32 SurfaceParams::GetMipBlockDepth(u32 level) const { if (level == 0) { return this->block_depth; } - if (IsLayered()) { + if (is_layered) { return 1; } @@ -216,6 +247,10 @@ std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const { return offset; } +std::size_t SurfaceParams::GetGuestMipmapSize(u32 level) const { + return GetInnerMipmapMemorySize(level, false, false); +} + std::size_t SurfaceParams::GetHostMipmapSize(u32 level) const { return GetInnerMipmapMemorySize(level, true, false) * GetNumLayers(); } @@ -229,7 +264,7 @@ std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) co for (u32 level = 0; level < num_levels; ++level) { size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed); } - if (is_tiled && (IsLayered() || target == SurfaceTarget::Texture3D)) { + if (is_tiled && is_layered) { return Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); } return size; @@ -256,150 +291,32 @@ u32 SurfaceParams::GetBytesPerPixel() const { return VideoCore::Surface::GetBytesPerPixel(pixel_format); } -bool SurfaceParams::IsFamiliar(const SurfaceParams& view_params) const { - if (std::tie(is_tiled, tile_width_spacing, pixel_format, component_type, type) != - std::tie(view_params.is_tiled, view_params.tile_width_spacing, view_params.pixel_format, - view_params.component_type, view_params.type)) { - return false; - } - - const SurfaceTarget view_target{view_params.target}; - if (view_target == target) { - return true; - } - - switch (target) { - case SurfaceTarget::Texture1D: - case SurfaceTarget::Texture2D: - case SurfaceTarget::Texture3D: - return false; - case SurfaceTarget::Texture1DArray: - return view_target == SurfaceTarget::Texture1D; - case SurfaceTarget::Texture2DArray: - return view_target == SurfaceTarget::Texture2D; - case SurfaceTarget::TextureCubemap: - return view_target == SurfaceTarget::Texture2D || - view_target == SurfaceTarget::Texture2DArray; - case SurfaceTarget::TextureCubeArray: - return view_target == SurfaceTarget::Texture2D || - view_target == SurfaceTarget::Texture2DArray || - view_target == SurfaceTarget::TextureCubemap; - default: - UNIMPLEMENTED_MSG("Unimplemented texture family={}", static_cast(target)); - return false; - } -} - bool SurfaceParams::IsPixelFormatZeta() const { return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat && pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; } -void SurfaceParams::CalculateCachedValues() { - switch (target) { - case SurfaceTarget::Texture1D: - case SurfaceTarget::Texture2D: - case SurfaceTarget::Texture3D: - num_layers = 1; - break; - case SurfaceTarget::Texture1DArray: - case SurfaceTarget::Texture2DArray: - case SurfaceTarget::TextureCubemap: - case SurfaceTarget::TextureCubeArray: - num_layers = depth; - break; - default: - UNREACHABLE(); - } - - guest_size_in_bytes = GetInnerMemorySize(false, false, false); - - if (IsPixelFormatASTC(pixel_format)) { - // ASTC is uncompressed in software, in emulated as RGBA8 - host_size_in_bytes = static_cast(width) * static_cast(height) * - static_cast(depth) * 4ULL; - } else { - host_size_in_bytes = GetInnerMemorySize(true, false, false); - } -} - std::size_t SurfaceParams::GetInnerMipmapMemorySize(u32 level, bool as_host_size, bool uncompressed) const { const bool tiled{as_host_size ? false : is_tiled}; const u32 width{GetMipmapSize(uncompressed, GetMipWidth(level), GetDefaultBlockWidth())}; const u32 height{GetMipmapSize(uncompressed, GetMipHeight(level), GetDefaultBlockHeight())}; - const u32 depth{target == SurfaceTarget::Texture3D ? GetMipDepth(level) : 1U}; + const u32 depth{is_layered ? 1U : GetMipDepth(level)}; return Tegra::Texture::CalculateSize(tiled, GetBytesPerPixel(), width, height, depth, GetMipBlockHeight(level), GetMipBlockDepth(level)); } std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only, bool uncompressed) const { - return GetLayerSize(as_host_size, uncompressed) * (layer_only ? 1U : num_layers); -} - -std::map> SurfaceParams::CreateViewOffsetMap() const { - std::map> view_offset_map; - switch (target) { - case SurfaceTarget::Texture1D: - case SurfaceTarget::Texture2D: - case SurfaceTarget::Texture3D: { - // TODO(Rodrigo): Add layer iterations for 3D textures - constexpr u32 layer = 0; - for (u32 level = 0; level < num_levels; ++level) { - const std::size_t offset{GetGuestMipmapLevelOffset(level)}; - view_offset_map.insert({offset, {layer, level}}); - } - break; - } - case SurfaceTarget::Texture1DArray: - case SurfaceTarget::Texture2DArray: - case SurfaceTarget::TextureCubemap: - case SurfaceTarget::TextureCubeArray: { - const std::size_t layer_size{GetGuestLayerSize()}; - for (u32 level = 0; level < num_levels; ++level) { - const std::size_t level_offset{GetGuestMipmapLevelOffset(level)}; - for (u32 layer = 0; layer < num_layers; ++layer) { - const auto layer_offset{static_cast(layer_size * layer)}; - const std::size_t offset{level_offset + layer_offset}; - view_offset_map.insert({offset, {layer, level}}); - } - } - break; - } - default: - UNIMPLEMENTED_MSG("Unimplemented surface target {}", static_cast(target)); - } - return view_offset_map; -} - -bool SurfaceParams::IsViewValid(const SurfaceParams& view_params, u32 layer, u32 level) const { - return IsDimensionValid(view_params, level) && IsDepthValid(view_params, level) && - IsInBounds(view_params, layer, level); + return GetLayerSize(as_host_size, uncompressed) * (layer_only ? 1U : depth); } -bool SurfaceParams::IsDimensionValid(const SurfaceParams& view_params, u32 level) const { - return view_params.width == GetMipWidth(level) && view_params.height == GetMipHeight(level); -} - -bool SurfaceParams::IsDepthValid(const SurfaceParams& view_params, u32 level) const { - if (view_params.target != SurfaceTarget::Texture3D) { - return true; - } - return view_params.depth == GetMipDepth(level); -} - -bool SurfaceParams::IsInBounds(const SurfaceParams& view_params, u32 layer, u32 level) const { - return layer + view_params.num_layers <= num_layers && - level + view_params.num_levels <= num_levels; -} - -std::size_t HasheableSurfaceParams::Hash() const { +std::size_t SurfaceParams::Hash() const { return static_cast( Common::CityHash64(reinterpret_cast(this), sizeof(*this))); } -bool HasheableSurfaceParams::operator==(const HasheableSurfaceParams& rhs) const { +bool SurfaceParams::operator==(const SurfaceParams& rhs) const { return std::tie(is_tiled, block_width, block_height, block_depth, tile_width_spacing, width, height, depth, pitch, unaligned_height, num_levels, pixel_format, component_type, type, target) == @@ -409,4 +326,27 @@ bool HasheableSurfaceParams::operator==(const HasheableSurfaceParams& rhs) const rhs.type, rhs.target); } +std::string SurfaceParams::TargetName() const { + switch (target) { + case SurfaceTarget::Texture1D: + return "1D"; + case SurfaceTarget::Texture2D: + return "2D"; + case SurfaceTarget::Texture3D: + return "3D"; + case SurfaceTarget::Texture1DArray: + return "1DArray"; + case SurfaceTarget::Texture2DArray: + return "2DArray"; + case SurfaceTarget::TextureCubemap: + return "Cube"; + case SurfaceTarget::TextureCubeArray: + return "CubeArray"; + default: + LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast(target)); + UNREACHABLE(); + return fmt::format("TUK({})", static_cast(target)); + } +} + } // namespace VideoCommon -- cgit v1.2.3 From b347543e8341ae323ea232d47df2c144fe21c739 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 8 May 2019 18:27:29 -0400 Subject: Reduce amount of size calculations. --- src/video_core/texture_cache/surface_params.cpp | 31 +------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index d9052152c..b537b26e2 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -4,13 +4,12 @@ #include -#include "common/cityhash.h" #include "common/alignment.h" +#include "common/cityhash.h" #include "core/core.h" #include "video_core/engines/shader_bytecode.h" #include "video_core/surface.h" #include "video_core/texture_cache/surface_params.h" -#include "video_core/textures/decoders.h" namespace VideoCommon { @@ -169,18 +168,6 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( return params; } -u32 SurfaceParams::GetMipWidth(u32 level) const { - return std::max(1U, width >> level); -} - -u32 SurfaceParams::GetMipHeight(u32 level) const { - return std::max(1U, height >> level); -} - -u32 SurfaceParams::GetMipDepth(u32 level) const { - return is_layered ? depth : std::max(1U, depth >> level); -} - bool SurfaceParams::IsLayered() const { switch (target) { case SurfaceTarget::Texture1DArray: @@ -275,22 +262,6 @@ std::size_t SurfaceParams::GetHostLayerSize(u32 level) const { return GetInnerMipmapMemorySize(level, true, false); } -u32 SurfaceParams::GetDefaultBlockWidth() const { - return VideoCore::Surface::GetDefaultBlockWidth(pixel_format); -} - -u32 SurfaceParams::GetDefaultBlockHeight() const { - return VideoCore::Surface::GetDefaultBlockHeight(pixel_format); -} - -u32 SurfaceParams::GetBitsPerPixel() const { - return VideoCore::Surface::GetFormatBpp(pixel_format); -} - -u32 SurfaceParams::GetBytesPerPixel() const { - return VideoCore::Surface::GetBytesPerPixel(pixel_format); -} - bool SurfaceParams::IsPixelFormatZeta() const { return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat && pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; -- cgit v1.2.3 From 345e73f2feb0701e3c3099d002a1c21fb524eae4 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 10 May 2019 04:17:48 -0300 Subject: video_core: Use un-shifted block sizes to avoid integer divisions Instead of storing all block width, height and depths in their shifted form: block_width = 1U << block_shift; Store them like they are provided by the emulated hardware (their block_shift form). This way we can avoid doing the costly Common::AlignUp operation to align texture sizes and drop CPU integer divisions with bitwise logic (defined in Common::AlignBits). --- src/video_core/texture_cache/surface_params.cpp | 39 +++++++++++++------------ 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index b537b26e2..3a47f404d 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -96,9 +96,9 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer( SurfaceParams params; params.is_tiled = type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; params.srgb_conversion = false; - params.block_width = 1 << std::min(block_width, 5U); - params.block_height = 1 << std::min(block_height, 5U); - params.block_depth = 1 << std::min(block_depth, 5U); + params.block_width = std::min(block_width, 5U); + params.block_height = std::min(block_height, 5U); + params.block_depth = std::min(block_depth, 5U); params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromDepthFormat(format); params.component_type = ComponentTypeFromDepthFormat(format); @@ -120,9 +120,9 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz config.memory_layout.type == Tegra::Engines::Maxwell3D::Regs::InvMemoryLayout::BlockLinear; params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; - params.block_width = 1 << config.memory_layout.block_width; - params.block_height = 1 << config.memory_layout.block_height; - params.block_depth = 1 << config.memory_layout.block_depth; + params.block_width = config.memory_layout.block_width; + params.block_height = config.memory_layout.block_height; + params.block_depth = config.memory_layout.block_depth; params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); params.component_type = ComponentTypeFromRenderTarget(config.format); @@ -149,9 +149,9 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( params.is_tiled = !config.linear; params.srgb_conversion = config.format == Tegra::RenderTargetFormat::BGRA8_SRGB || config.format == Tegra::RenderTargetFormat::RGBA8_SRGB; - params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 32U) : 0, - params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 32U) : 0, - params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 32U) : 0, + params.block_width = params.is_tiled ? std::min(config.BlockWidth(), 5U) : 0, + params.block_height = params.is_tiled ? std::min(config.BlockHeight(), 5U) : 0, + params.block_depth = params.is_tiled ? std::min(config.BlockDepth(), 5U) : 0, params.tile_width_spacing = 1; params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); params.component_type = ComponentTypeFromRenderTarget(config.format); @@ -190,9 +190,9 @@ u32 SurfaceParams::GetMipBlockHeight(u32 level) const { const u32 height{GetMipHeight(level)}; const u32 default_block_height{GetDefaultBlockHeight()}; const u32 blocks_in_y{(height + default_block_height - 1) / default_block_height}; - u32 block_height = 16; - while (block_height > 1 && blocks_in_y <= block_height * 4) { - block_height >>= 1; + u32 block_height = 4; + while (block_height > 0 && blocks_in_y <= (1U << block_height) * 4) { + --block_height; } return block_height; } @@ -202,17 +202,17 @@ u32 SurfaceParams::GetMipBlockDepth(u32 level) const { return this->block_depth; } if (is_layered) { - return 1; + return 0; } const u32 depth{GetMipDepth(level)}; - u32 block_depth = 32; - while (block_depth > 1 && depth * 2 <= block_depth) { - block_depth >>= 1; + u32 block_depth = 5; + while (block_depth > 0 && depth * 2 <= (1U << block_depth)) { + --block_depth; } - if (block_depth == 32 && GetMipBlockHeight(level) >= 4) { - return 16; + if (block_depth == 5 && GetMipBlockHeight(level) >= 2) { + return 4; } return block_depth; @@ -252,7 +252,8 @@ std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) co size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed); } if (is_tiled && is_layered) { - return Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); + return Common::AlignBits(size, + Tegra::Texture::GetGOBSizeShift() + block_height + block_depth); } return size; } -- cgit v1.2.3 From 94f2be5473182789ec3f6388b43fcd708a505500 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 10 May 2019 22:12:35 -0400 Subject: texture_cache: Optimize GetMipBlockHeight and GetMipBlockDepth --- src/video_core/texture_cache/surface_params.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 3a47f404d..e7e671d8c 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -5,6 +5,7 @@ #include #include "common/alignment.h" +#include "common/bit_util.h" #include "common/cityhash.h" #include "core/core.h" #include "video_core/engines/shader_bytecode.h" @@ -190,11 +191,8 @@ u32 SurfaceParams::GetMipBlockHeight(u32 level) const { const u32 height{GetMipHeight(level)}; const u32 default_block_height{GetDefaultBlockHeight()}; const u32 blocks_in_y{(height + default_block_height - 1) / default_block_height}; - u32 block_height = 4; - while (block_height > 0 && blocks_in_y <= (1U << block_height) * 4) { - --block_height; - } - return block_height; + const u32 block_height = Common::Log2Ceil32(blocks_in_y); + return std::clamp(block_height, 3U, 8U) - 3U; } u32 SurfaceParams::GetMipBlockDepth(u32 level) const { @@ -206,15 +204,10 @@ u32 SurfaceParams::GetMipBlockDepth(u32 level) const { } const u32 depth{GetMipDepth(level)}; - u32 block_depth = 5; - while (block_depth > 0 && depth * 2 <= (1U << block_depth)) { - --block_depth; - } - - if (block_depth == 5 && GetMipBlockHeight(level) >= 2) { - return 4; + const u32 block_depth = Common::Log2Ceil32(depth); + if (block_depth > 4) { + return 5 - (GetMipBlockHeight(level) >= 2); } - return block_depth; } -- cgit v1.2.3 From 2131f715730580dfeb692acdf3ae3e62ffd455c1 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Fri, 10 May 2019 23:02:14 -0300 Subject: surface_params: Optimize CreateForTexture Instead of using Common::AlignUp, use Common::AlignBits to align the texture compression factor. --- src/video_core/texture_cache/surface_params.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index e7e671d8c..6f39f8468 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -76,8 +76,10 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.type = GetFormatType(params.pixel_format); // TODO: on 1DBuffer we should use the tic info. params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray()); - params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); - params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); + params.width = + Common::AlignBits(config.tic.Width(), GetCompressionFactorShift(params.pixel_format)); + params.height = + Common::AlignBits(config.tic.Height(), GetCompressionFactorShift(params.pixel_format)); params.depth = config.tic.Depth(); if (params.target == SurfaceTarget::TextureCubemap || params.target == SurfaceTarget::TextureCubeArray) { -- cgit v1.2.3 From c2ed348bddc1cd1bd97ce789d7855b1571e45ef4 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 12 May 2019 18:31:03 -0300 Subject: surface_params: Ensure pitch is always written to avoid surface leaks --- src/video_core/texture_cache/surface_params.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 6f39f8468..8472b69dc 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -111,6 +111,7 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer( params.unaligned_height = zeta_height; params.target = SurfaceTarget::Texture2D; params.depth = 1; + params.pitch = 0; params.num_levels = 1; params.is_layered = false; return params; @@ -131,6 +132,7 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz params.component_type = ComponentTypeFromRenderTarget(config.format); params.type = GetFormatType(params.pixel_format); if (params.is_tiled) { + params.pitch = 0; params.width = config.width; } else { const u32 bpp = GetFormatBpp(params.pixel_format) / CHAR_BIT; -- cgit v1.2.3 From 7731a0e2d15da04eea746b4b8dd5c6c4b29f9f29 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 12 May 2019 20:33:52 -0400 Subject: texture_cache: General Fixes Fixed ASTC mipmaps loading Fixed alignment on openGL upload/download Fixed Block Height Calculation Removed unalign_height --- src/video_core/texture_cache/surface_params.cpp | 52 ++++++++++++++----------- 1 file changed, 30 insertions(+), 22 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 8472b69dc..d9d157d02 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -76,17 +76,14 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.type = GetFormatType(params.pixel_format); // TODO: on 1DBuffer we should use the tic info. params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray()); - params.width = - Common::AlignBits(config.tic.Width(), GetCompressionFactorShift(params.pixel_format)); - params.height = - Common::AlignBits(config.tic.Height(), GetCompressionFactorShift(params.pixel_format)); + params.width = config.tic.Width(); + params.height = config.tic.Height(); params.depth = config.tic.Depth(); if (params.target == SurfaceTarget::TextureCubemap || params.target == SurfaceTarget::TextureCubeArray) { params.depth *= 6; } params.pitch = params.is_tiled ? 0 : config.tic.Pitch(); - params.unaligned_height = config.tic.Height(); params.num_levels = config.tic.max_mip_level + 1; params.is_layered = params.IsLayered(); return params; @@ -108,7 +105,6 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer( params.type = GetFormatType(params.pixel_format); params.width = zeta_width; params.height = zeta_height; - params.unaligned_height = zeta_height; params.target = SurfaceTarget::Texture2D; params.depth = 1; params.pitch = 0; @@ -141,7 +137,6 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz } params.height = config.height; params.depth = 1; - params.unaligned_height = config.height; params.target = SurfaceTarget::Texture2D; params.num_levels = 1; params.is_layered = false; @@ -164,7 +159,6 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( params.width = config.width; params.height = config.height; params.pitch = config.pitch; - params.unaligned_height = config.height; // TODO(Rodrigo): Try to guess the surface target from depth and layer parameters params.target = SurfaceTarget::Texture2D; params.depth = 1; @@ -185,18 +179,18 @@ bool SurfaceParams::IsLayered() const { } } +// Auto block resizing algorithm from: +// https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c u32 SurfaceParams::GetMipBlockHeight(u32 level) const { - // Auto block resizing algorithm from: - // https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c if (level == 0) { return this->block_height; } - const u32 height{GetMipHeight(level)}; + const u32 height_new{GetMipHeight(level)}; const u32 default_block_height{GetDefaultBlockHeight()}; - const u32 blocks_in_y{(height + default_block_height - 1) / default_block_height}; - const u32 block_height = Common::Log2Ceil32(blocks_in_y); - return std::clamp(block_height, 3U, 8U) - 3U; + const u32 blocks_in_y{(height_new + default_block_height - 1) / default_block_height}; + const u32 block_height_new = Common::Log2Ceil32(blocks_in_y); + return std::clamp(block_height_new, 3U, 7U) - 3U; } u32 SurfaceParams::GetMipBlockDepth(u32 level) const { @@ -207,12 +201,12 @@ u32 SurfaceParams::GetMipBlockDepth(u32 level) const { return 0; } - const u32 depth{GetMipDepth(level)}; - const u32 block_depth = Common::Log2Ceil32(depth); - if (block_depth > 4) { + const u32 depth_new{GetMipDepth(level)}; + const u32 block_depth_new = Common::Log2Ceil32(depth_new); + if (block_depth_new > 4) { return 5 - (GetMipBlockHeight(level) >= 2); } - return block_depth; + return block_depth_new; } std::size_t SurfaceParams::GetGuestMipmapLevelOffset(u32 level) const { @@ -231,6 +225,14 @@ std::size_t SurfaceParams::GetHostMipmapLevelOffset(u32 level) const { return offset; } +std::size_t SurfaceParams::GetConvertedMipmapOffset(u32 level) const { + std::size_t offset = 0; + for (u32 i = 0; i < level; i++) { + offset += GetConvertedMipmapSize(i); + } + return offset; +} + std::size_t SurfaceParams::GetGuestMipmapSize(u32 level) const { return GetInnerMipmapMemorySize(level, false, false); } @@ -239,6 +241,14 @@ std::size_t SurfaceParams::GetHostMipmapSize(u32 level) const { return GetInnerMipmapMemorySize(level, true, false) * GetNumLayers(); } +std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const { + constexpr std::size_t rgb8_bpp = 4ULL; + const std::size_t width_t = GetMipWidth(level); + const std::size_t height_t = GetMipHeight(level); + const std::size_t depth_t = is_layered ? depth : GetMipDepth(level); + return width_t * height_t * depth_t * rgb8_bpp; +} + std::size_t SurfaceParams::GetGuestLayerSize() const { return GetLayerSize(false, false); } @@ -287,12 +297,10 @@ std::size_t SurfaceParams::Hash() const { bool SurfaceParams::operator==(const SurfaceParams& rhs) const { return std::tie(is_tiled, block_width, block_height, block_depth, tile_width_spacing, width, - height, depth, pitch, unaligned_height, num_levels, pixel_format, - component_type, type, target) == + height, depth, pitch, num_levels, pixel_format, component_type, type, target) == std::tie(rhs.is_tiled, rhs.block_width, rhs.block_height, rhs.block_depth, rhs.tile_width_spacing, rhs.width, rhs.height, rhs.depth, rhs.pitch, - rhs.unaligned_height, rhs.num_levels, rhs.pixel_format, rhs.component_type, - rhs.type, rhs.target); + rhs.num_levels, rhs.pixel_format, rhs.component_type, rhs.type, rhs.target); } std::string SurfaceParams::TargetName() const { -- cgit v1.2.3 From 228f516bb4426a41a4d1c1756751557f7a0eecda Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 24 May 2019 15:34:31 -0400 Subject: texture_cache uncompress-compress is untopological. This makes conflicts between non compress and compress textures to be auto recycled. It also limits the amount of mipmaps a texture can have if it goes above it's limit. --- src/video_core/texture_cache/surface_params.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index d9d157d02..77c09264a 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -85,6 +85,7 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, } params.pitch = params.is_tiled ? 0 : config.tic.Pitch(); params.num_levels = config.tic.max_mip_level + 1; + params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap()); params.is_layered = params.IsLayered(); return params; } @@ -109,6 +110,7 @@ SurfaceParams SurfaceParams::CreateForDepthBuffer( params.depth = 1; params.pitch = 0; params.num_levels = 1; + params.emulated_levels = 1; params.is_layered = false; return params; } @@ -139,6 +141,7 @@ SurfaceParams SurfaceParams::CreateForFramebuffer(Core::System& system, std::siz params.depth = 1; params.target = SurfaceTarget::Texture2D; params.num_levels = 1; + params.emulated_levels = 1; params.is_layered = false; return params; } @@ -163,6 +166,7 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( params.target = SurfaceTarget::Texture2D; params.depth = 1; params.num_levels = 1; + params.emulated_levels = 1; params.is_layered = params.IsLayered(); return params; } -- cgit v1.2.3 From 9f755218a1359cbd004e6c287f5fead0897c1d11 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 1 Jun 2019 23:03:22 -0400 Subject: texture_cache: move some large methods to cpp files --- src/video_core/texture_cache/surface_params.cpp | 33 ------------------------- 1 file changed, 33 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 77c09264a..60a7356bb 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -6,7 +6,6 @@ #include "common/alignment.h" #include "common/bit_util.h" -#include "common/cityhash.h" #include "core/core.h" #include "video_core/engines/shader_bytecode.h" #include "video_core/surface.h" @@ -237,14 +236,6 @@ std::size_t SurfaceParams::GetConvertedMipmapOffset(u32 level) const { return offset; } -std::size_t SurfaceParams::GetGuestMipmapSize(u32 level) const { - return GetInnerMipmapMemorySize(level, false, false); -} - -std::size_t SurfaceParams::GetHostMipmapSize(u32 level) const { - return GetInnerMipmapMemorySize(level, true, false) * GetNumLayers(); -} - std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const { constexpr std::size_t rgb8_bpp = 4ULL; const std::size_t width_t = GetMipWidth(level); @@ -253,10 +244,6 @@ std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const { return width_t * height_t * depth_t * rgb8_bpp; } -std::size_t SurfaceParams::GetGuestLayerSize() const { - return GetLayerSize(false, false); -} - std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) const { std::size_t size = 0; for (u32 level = 0; level < num_levels; ++level) { @@ -269,16 +256,6 @@ std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) co return size; } -std::size_t SurfaceParams::GetHostLayerSize(u32 level) const { - ASSERT(target != SurfaceTarget::Texture3D); - return GetInnerMipmapMemorySize(level, true, false); -} - -bool SurfaceParams::IsPixelFormatZeta() const { - return pixel_format >= VideoCore::Surface::PixelFormat::MaxColorFormat && - pixel_format < VideoCore::Surface::PixelFormat::MaxDepthStencilFormat; -} - std::size_t SurfaceParams::GetInnerMipmapMemorySize(u32 level, bool as_host_size, bool uncompressed) const { const bool tiled{as_host_size ? false : is_tiled}; @@ -289,16 +266,6 @@ std::size_t SurfaceParams::GetInnerMipmapMemorySize(u32 level, bool as_host_size GetMipBlockHeight(level), GetMipBlockDepth(level)); } -std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only, - bool uncompressed) const { - return GetLayerSize(as_host_size, uncompressed) * (layer_only ? 1U : depth); -} - -std::size_t SurfaceParams::Hash() const { - return static_cast( - Common::CityHash64(reinterpret_cast(this), sizeof(*this))); -} - bool SurfaceParams::operator==(const SurfaceParams& rhs) const { return std::tie(is_tiled, block_width, block_height, block_depth, tile_width_spacing, width, height, depth, pitch, num_levels, pixel_format, component_type, type, target) == -- cgit v1.2.3 From a56f687793a0a24a368f0dafd5333daf8cbacecf Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 12 Jun 2019 09:32:26 -0400 Subject: texture_cache: correct texture buffer on surface params --- src/video_core/texture_cache/surface_params.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 60a7356bb..f789da2c4 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -74,10 +74,17 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); params.type = GetFormatType(params.pixel_format); // TODO: on 1DBuffer we should use the tic info. - params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray()); - params.width = config.tic.Width(); - params.height = config.tic.Height(); - params.depth = config.tic.Depth(); + if (!config.tic.IsBuffer()) { + params.target = TextureType2SurfaceTarget(entry.GetType(), entry.IsArray()); + params.width = config.tic.Width(); + params.height = config.tic.Height(); + params.depth = config.tic.Depth(); + } else { + params.target = SurfaceTarget::TextureBuffer; + params.width = config.tic.Width(); + params.height = 0; + params.depth = 0; + } if (params.target == SurfaceTarget::TextureCubemap || params.target == SurfaceTarget::TextureCubeArray) { params.depth *= 6; -- cgit v1.2.3 From 198a0395bb1b1d19de12560ac146add0705ed00e Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 15 Jun 2019 11:08:11 -0400 Subject: texture_cache: Corrections to buffers and shadow formats use. --- src/video_core/texture_cache/surface_params.cpp | 44 +++++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index f789da2c4..290ba438d 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -16,11 +16,13 @@ namespace VideoCommon { using VideoCore::Surface::ComponentTypeFromDepthFormat; using VideoCore::Surface::ComponentTypeFromRenderTarget; using VideoCore::Surface::ComponentTypeFromTexture; +using VideoCore::Surface::PixelFormat; using VideoCore::Surface::PixelFormatFromDepthFormat; using VideoCore::Surface::PixelFormatFromRenderTargetFormat; using VideoCore::Surface::PixelFormatFromTextureFormat; using VideoCore::Surface::SurfaceTarget; using VideoCore::Surface::SurfaceTargetFromTextureType; +using VideoCore::Surface::SurfaceType; SurfaceTarget TextureType2SurfaceTarget(Tegra::Shader::TextureType type, bool is_array) { switch (type) { @@ -71,6 +73,24 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.tile_width_spacing = params.is_tiled ? (1 << config.tic.tile_width_spacing.Value()) : 1; params.pixel_format = PixelFormatFromTextureFormat(config.tic.format, config.tic.r_type.Value(), params.srgb_conversion); + params.type = GetFormatType(params.pixel_format); + if (entry.IsShadow() && params.type == SurfaceType::ColorTexture) { + switch (params.pixel_format) { + case PixelFormat::R16F: { + params.pixel_format = PixelFormat::Z16; + break; + } + case PixelFormat::R32F: { + params.pixel_format = PixelFormat::Z32F; + break; + } + default: { + UNIMPLEMENTED_MSG("Unimplemented shadow convert format: {}", + static_cast(params.pixel_format)); + } + } + params.type = GetFormatType(params.pixel_format); + } params.component_type = ComponentTypeFromTexture(config.tic.r_type.Value()); params.type = GetFormatType(params.pixel_format); // TODO: on 1DBuffer we should use the tic info. @@ -79,20 +99,24 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.width = config.tic.Width(); params.height = config.tic.Height(); params.depth = config.tic.Depth(); + params.pitch = params.is_tiled ? 0 : config.tic.Pitch(); + if (params.target == SurfaceTarget::TextureCubemap || + params.target == SurfaceTarget::TextureCubeArray) { + params.depth *= 6; + } + params.num_levels = config.tic.max_mip_level + 1; + params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap()); + params.is_layered = params.IsLayered(); } else { params.target = SurfaceTarget::TextureBuffer; params.width = config.tic.Width(); - params.height = 0; - params.depth = 0; + params.pitch = params.width * params.GetBytesPerPixel(); + params.height = 1; + params.depth = 1; + params.num_levels = 1; + params.emulated_levels = 1; + params.is_layered = false; } - if (params.target == SurfaceTarget::TextureCubemap || - params.target == SurfaceTarget::TextureCubeArray) { - params.depth *= 6; - } - params.pitch = params.is_tiled ? 0 : config.tic.Pitch(); - params.num_levels = config.tic.max_mip_level + 1; - params.emulated_levels = std::min(params.num_levels, params.MaxPossibleMipmap()); - params.is_layered = params.IsLayered(); return params; } -- cgit v1.2.3 From 6acdae0e4c9d0c20f668cd86250b5d5b0dbd70c4 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 17 Jun 2019 19:19:47 -0400 Subject: texture_cache: Correct format R16U as sibling --- src/video_core/texture_cache/surface_params.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 290ba438d..a670fc1a9 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -76,6 +76,7 @@ SurfaceParams SurfaceParams::CreateForTexture(Core::System& system, params.type = GetFormatType(params.pixel_format); if (entry.IsShadow() && params.type == SurfaceType::ColorTexture) { switch (params.pixel_format) { + case PixelFormat::R16U: case PixelFormat::R16F: { params.pixel_format = PixelFormat::Z16; break; -- cgit v1.2.3 From c0abc7124d6ecd17f9da5ee5b3de9cb3dbf3ce1f Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Tue, 25 Jun 2019 18:03:25 -0400 Subject: surface_params: Corrections, asserts and documentation. --- src/video_core/texture_cache/surface_params.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index a670fc1a9..340ed2ca0 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -269,11 +269,11 @@ std::size_t SurfaceParams::GetConvertedMipmapOffset(u32 level) const { } std::size_t SurfaceParams::GetConvertedMipmapSize(u32 level) const { - constexpr std::size_t rgb8_bpp = 4ULL; + constexpr std::size_t rgba8_bpp = 4ULL; const std::size_t width_t = GetMipWidth(level); const std::size_t height_t = GetMipHeight(level); const std::size_t depth_t = is_layered ? depth : GetMipDepth(level); - return width_t * height_t * depth_t * rgb8_bpp; + return width_t * height_t * depth_t * rgba8_bpp; } std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) const { -- cgit v1.2.3 From 30b176f92b67ec7a9b1ce08cf89d50abd125f8a8 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 4 Jul 2019 19:38:19 -0400 Subject: texture_cache: Correct Texture Buffer Uploading --- src/video_core/texture_cache/surface_params.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/video_core/texture_cache/surface_params.cpp') diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 340ed2ca0..9c56e2b4f 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp @@ -310,6 +310,8 @@ std::string SurfaceParams::TargetName() const { switch (target) { case SurfaceTarget::Texture1D: return "1D"; + case SurfaceTarget::TextureBuffer: + return "TexBuffer"; case SurfaceTarget::Texture2D: return "2D"; case SurfaceTarget::Texture3D: -- cgit v1.2.3