From bab21e8cb3df9c06e3c0a37a8fc68fed676f5d6e Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 11 Apr 2019 17:14:55 -0300 Subject: gl_texture_cache: Initial implementation --- src/video_core/textures/decoders.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/video_core/textures') diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 217805386..664ed4b56 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -359,7 +359,8 @@ std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x); const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height); const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth); - return aligned_width * aligned_height * aligned_depth; + const u32 size = aligned_width * aligned_height * aligned_depth; + return size; } else { return width * height * depth * bytes_per_pixel; } -- cgit v1.2.3 From fb94871791f78703737125cd2e5a13db8b7d1059 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 14 Apr 2019 01:44:16 -0300 Subject: gl_texture_cache: Add fast copy path --- .../renderer_opengl/gl_texture_cache.cpp | 51 ++++++++++++++++++++-- src/video_core/renderer_opengl/gl_texture_cache.h | 9 ++++ src/video_core/texture_cache.cpp | 4 +- src/video_core/textures/decoders.cpp | 3 +- 4 files changed, 60 insertions(+), 7 deletions(-) (limited to 'src/video_core/textures') diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 3a456995e..00f9ab92f 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -177,9 +177,9 @@ void ApplyTextureDefaults(const SurfaceParams& params, GLuint texture) { } } -OGLTexture CreateTexture(const SurfaceParams& params, GLenum internal_format) { +OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum internal_format) { OGLTexture texture; - texture.Create(GetTextureTarget(params)); + texture.Create(target); switch (params.GetTarget()) { case SurfaceTarget::Texture1D: @@ -241,7 +241,8 @@ CachedSurface::CachedSurface(const SurfaceParams& params) format = tuple.format; type = tuple.type; is_compressed = tuple.compressed; - texture = CreateTexture(params, internal_format); + target = GetTextureTarget(params); + texture = CreateTexture(params, target, internal_format); staging_buffer.resize(params.GetHostSizeInBytes()); } @@ -504,9 +505,53 @@ TextureCacheOpenGL::~TextureCacheOpenGL() = default; CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView( VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents, const std::vector& overlaps) { + if (overlaps.size() > 1) { + return nullptr; + } + + const auto& old_surface{overlaps[0]}; + const auto& old_params{old_surface->GetSurfaceParams()}; + const auto& new_params{params}; + + if (old_params.GetTarget() == new_params.GetTarget() && + old_params.GetDepth() == new_params.GetDepth() && old_params.GetDepth() == 1 && + old_params.GetNumLevels() == new_params.GetNumLevels() && + old_params.GetPixelFormat() == new_params.GetPixelFormat()) { + return SurfaceCopy(cpu_addr, host_ptr, new_params, old_surface, old_params); + } + return nullptr; } +CachedSurfaceView* TextureCacheOpenGL::SurfaceCopy(VAddr cpu_addr, u8* host_ptr, + const SurfaceParams& new_params, + CachedSurface* old_surface, + const SurfaceParams& old_params) { + CachedSurface* const new_surface{GetUncachedSurface(new_params)}; + Register(new_surface, cpu_addr, host_ptr); + + const u32 min_width{ + std::max(old_params.GetDefaultBlockWidth(), new_params.GetDefaultBlockWidth())}; + const u32 min_height{ + std::max(old_params.GetDefaultBlockHeight(), new_params.GetDefaultBlockHeight())}; + for (u32 level = 0; level < old_params.GetNumLevels(); ++level) { + const u32 width{std::min(old_params.GetMipWidth(level), new_params.GetMipWidth(level))}; + const u32 height{std::min(old_params.GetMipHeight(level), new_params.GetMipHeight(level))}; + if (width < min_width || height < min_height) { + // Avoid copies that are too small to be handled in OpenGL + break; + } + glCopyImageSubData(old_surface->GetTexture(), old_surface->GetTarget(), level, 0, 0, 0, + new_surface->GetTexture(), new_surface->GetTarget(), level, 0, 0, 0, + width, height, 1); + } + + new_surface->MarkAsModified(true); + + // TODO(Rodrigo): Add an entry to directly get the superview + return new_surface->GetView(cpu_addr, new_params); +} + std::unique_ptr TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { return std::make_unique(params); } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index f0a524882..b18b32d99 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -38,6 +38,10 @@ public: void LoadBuffer(); + GLenum GetTarget() const { + return target; + } + GLuint GetTexture() const { return texture.handle; } @@ -56,6 +60,7 @@ private: GLenum format{}; GLenum type{}; bool is_compressed{}; + GLenum target{}; OGLTexture texture; @@ -126,6 +131,10 @@ protected: const std::vector& overlaps); std::unique_ptr CreateSurface(const SurfaceParams& params); + +private: + CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params, + CachedSurface* old_surface, const SurfaceParams& old_params); }; } // namespace OpenGL diff --git a/src/video_core/texture_cache.cpp b/src/video_core/texture_cache.cpp index c42365a82..1cfb9962f 100644 --- a/src/video_core/texture_cache.cpp +++ b/src/video_core/texture_cache.cpp @@ -160,7 +160,7 @@ 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 block_height; + return this->block_height; } const u32 height{GetMipHeight(level)}; const u32 default_block_height{GetDefaultBlockHeight()}; @@ -316,7 +316,7 @@ std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed); } if (is_tiled && !as_host_size) { - size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); + //size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); } return size; } diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 664ed4b56..217805386 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -359,8 +359,7 @@ std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x); const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height); const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth); - const u32 size = aligned_width * aligned_height * aligned_depth; - return size; + return aligned_width * aligned_height * aligned_depth; } else { return width * height * depth * bytes_per_pixel; } -- 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/common/alignment.h | 5 +++ src/video_core/engines/fermi_2d.h | 9 ++-- src/video_core/engines/maxwell_dma.h | 4 +- src/video_core/texture_cache/surface_base.cpp | 3 +- src/video_core/texture_cache/surface_params.cpp | 39 +++++++++--------- src/video_core/texture_cache/surface_params.h | 7 ++-- src/video_core/texture_cache/texture_cache.h | 3 ++ src/video_core/textures/decoders.cpp | 55 ++++++++++++++++--------- src/video_core/textures/decoders.h | 4 +- src/video_core/textures/texture.h | 9 ++-- 10 files changed, 78 insertions(+), 60 deletions(-) (limited to 'src/video_core/textures') diff --git a/src/common/alignment.h b/src/common/alignment.h index d94a2291f..3379a6967 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -19,6 +19,11 @@ constexpr T AlignDown(T value, std::size_t size) { return static_cast(value - value % size); } +template +constexpr T AlignBits(T value, T align) { + return (value + ((1 << align) - 1)) >> align << align; +} + template constexpr bool Is4KBAligned(T value) { static_assert(std::is_unsigned_v, "T must be an unsigned value."); diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 45f59a4d9..3d28afa91 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -63,18 +63,15 @@ public: } u32 BlockWidth() const { - // The block width is stored in log2 format. - return 1 << block_width; + return block_width; } u32 BlockHeight() const { - // The block height is stored in log2 format. - return 1 << block_height; + return block_height; } u32 BlockDepth() const { - // The block depth is stored in log2 format. - return 1 << block_depth; + return block_depth; } }; static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size"); diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index e5942f671..522fa97dc 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h @@ -59,11 +59,11 @@ public: }; u32 BlockHeight() const { - return 1 << block_height; + return block_height; } u32 BlockDepth() const { - return 1 << block_depth; + return block_depth; } }; diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp index 36ca72b4a..510d1aef5 100644 --- a/src/video_core/texture_cache/surface_base.cpp +++ b/src/video_core/texture_cache/surface_base.cpp @@ -22,7 +22,6 @@ SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) : params{params}, mipmap_sizes(params.num_levels), mipmap_offsets(params.num_levels), gpu_addr{gpu_addr}, host_memory_size{ params.GetHostSizeInBytes()} { - std::size_t offset = 0; for (u32 level = 0; level < params.num_levels; ++level) { const std::size_t mipmap_size{params.GetGuestMipmapSize(level)}; @@ -75,7 +74,7 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager, return; } if (params.is_tiled) { - ASSERT_MSG(params.block_width == 1, "Block width is defined as {} on texture target {}", + ASSERT_MSG(params.block_width == 0, "Block width is defined as {} on texture target {}", params.block_width, static_cast(params.target)); for (u32 level = 0; level < params.num_levels; ++level) { const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)}; 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; } diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h index e0ec1be0e..7c48782c7 100644 --- a/src/video_core/texture_cache/surface_params.h +++ b/src/video_core/texture_cache/surface_params.h @@ -54,12 +54,12 @@ public: constexpr std::size_t rgb8_bpp = 4ULL; // ASTC is uncompressed in software, in emulated as RGBA8 host_size_in_bytes = 0; - for (std::size_t level = 0; level < num_levels; level++) { + for (u32 level = 0; level < num_levels; ++level) { const std::size_t width = Common::AlignUp(GetMipWidth(level), GetDefaultBlockWidth()); const std::size_t height = Common::AlignUp(GetMipHeight(level), GetDefaultBlockHeight()); - const std::size_t depth = is_layered ? depth : GetMipDepth(level); + const std::size_t depth = is_layered ? this->depth : GetMipDepth(level); host_size_in_bytes += width * height * depth * rgb8_bpp; } } else { @@ -96,7 +96,8 @@ public: // Helper used for out of class size calculations static std::size_t AlignLayered(const std::size_t out_size, const u32 block_height, const u32 block_depth) { - return Common::AlignUp(out_size, Tegra::Texture::GetGOBSize() * block_height * block_depth); + return Common::AlignBits(out_size, + Tegra::Texture::GetGOBSizeShift() + block_height + block_depth); } /// Returns the offset in bytes in guest memory of a given mipmap level. diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 1c2b63dae..f35d0c88f 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -81,6 +81,9 @@ public: if (!gpu_addr) { return {}; } + if (gpu_addr == 0x1b7ec0000) { + // __debugbreak(); + } const auto params{SurfaceParams::CreateForTexture(system, config, entry)}; return GetSurface(gpu_addr, params, true).second; } diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 217805386..f45fd175a 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -36,10 +36,16 @@ struct alignas(64) SwizzleTable { std::array, N> values{}; }; -constexpr u32 gob_size_x = 64; -constexpr u32 gob_size_y = 8; -constexpr u32 gob_size_z = 1; -constexpr u32 gob_size = gob_size_x * gob_size_y * gob_size_z; +constexpr u32 gob_size_x_shift = 6; +constexpr u32 gob_size_y_shift = 3; +constexpr u32 gob_size_z_shift = 0; +constexpr u32 gob_size_shift = gob_size_x_shift + gob_size_y_shift + gob_size_z_shift; + +constexpr u32 gob_size_x = 1U << gob_size_x_shift; +constexpr u32 gob_size_y = 1U << gob_size_y_shift; +constexpr u32 gob_size_z = 1U << gob_size_z_shift; +constexpr u32 gob_size = 1U << gob_size_shift; + constexpr u32 fast_swizzle_align = 16; constexpr auto legacy_swizzle_table = SwizzleTable(); @@ -171,14 +177,16 @@ void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel, u32 out_bytes_per_pixel, u8* const swizzled_data, u8* const unswizzled_data, bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing) { + const u32 block_height_size{1U << block_height}; + const u32 block_depth_size{1U << block_depth}; if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % fast_swizzle_align == 0) { SwizzledData(swizzled_data, unswizzled_data, unswizzle, width, height, depth, - bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth, - width_spacing); + bytes_per_pixel, out_bytes_per_pixel, block_height_size, + block_depth_size, width_spacing); } else { SwizzledData(swizzled_data, unswizzled_data, unswizzle, width, height, depth, - bytes_per_pixel, out_bytes_per_pixel, block_height, block_depth, - width_spacing); + bytes_per_pixel, out_bytes_per_pixel, block_height_size, + block_depth_size, width_spacing); } } @@ -249,16 +257,18 @@ std::vector UnswizzleTexture(u8* address, u32 tile_size_x, u32 tile_size_y, void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height) { + const u32 block_height_size{1U << block_height}; const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) / gob_size_x}; for (u32 line = 0; line < subrect_height; ++line) { const u32 gob_address_y = - (line / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs + - ((line % (gob_size_y * block_height)) / gob_size_y) * gob_size; + (line / (gob_size_y * block_height_size)) * gob_size * block_height_size * + image_width_in_gobs + + ((line % (gob_size_y * block_height_size)) / gob_size_y) * gob_size; const auto& table = legacy_swizzle_table[line % gob_size_y]; for (u32 x = 0; x < subrect_width; ++x) { const u32 gob_address = - gob_address_y + (x * bytes_per_pixel / gob_size_x) * gob_size * block_height; + gob_address_y + (x * bytes_per_pixel / gob_size_x) * gob_size * block_height_size; const u32 swizzled_offset = gob_address + table[(x * bytes_per_pixel) % gob_size_x]; u8* source_line = unswizzled_data + line * source_pitch + x * bytes_per_pixel; u8* dest_addr = swizzled_data + swizzled_offset; @@ -271,14 +281,17 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height, u32 offset_x, u32 offset_y) { + const u32 block_height_size{1U << block_height}; for (u32 line = 0; line < subrect_height; ++line) { const u32 y2 = line + offset_y; - const u32 gob_address_y = (y2 / (gob_size_y * block_height)) * gob_size * block_height + - ((y2 % (gob_size_y * block_height)) / gob_size_y) * gob_size; + const u32 gob_address_y = + (y2 / (gob_size_y * block_height_size)) * gob_size * block_height_size + + ((y2 % (gob_size_y * block_height_size)) / gob_size_y) * gob_size; const auto& table = legacy_swizzle_table[y2 % gob_size_y]; for (u32 x = 0; x < subrect_width; ++x) { const u32 x2 = (x + offset_x) * bytes_per_pixel; - const u32 gob_address = gob_address_y + (x2 / gob_size_x) * gob_size * block_height; + const u32 gob_address = + gob_address_y + (x2 / gob_size_x) * gob_size * block_height_size; const u32 swizzled_offset = gob_address + table[x2 % gob_size_x]; u8* dest_line = unswizzled_data + line * dest_pitch + x * bytes_per_pixel; u8* source_addr = swizzled_data + swizzled_offset; @@ -291,16 +304,18 @@ void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y, const u32 block_height, const std::size_t copy_size, const u8* source_data, u8* swizzle_data) { + const u32 block_height_size{1U << block_height}; const u32 image_width_in_gobs{(width + gob_size_x - 1) / gob_size_x}; std::size_t count = 0; for (std::size_t y = dst_y; y < height && count < copy_size; ++y) { const std::size_t gob_address_y = - (y / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs + - ((y % (gob_size_y * block_height)) / gob_size_y) * gob_size; + (y / (gob_size_y * block_height_size)) * gob_size * block_height_size * + image_width_in_gobs + + ((y % (gob_size_y * block_height_size)) / gob_size_y) * gob_size; const auto& table = legacy_swizzle_table[y % gob_size_y]; for (std::size_t x = dst_x; x < width && count < copy_size; ++x) { const std::size_t gob_address = - gob_address_y + (x / gob_size_x) * gob_size * block_height; + gob_address_y + (x / gob_size_x) * gob_size * block_height_size; const std::size_t swizzled_offset = gob_address + table[x % gob_size_x]; const u8* source_line = source_data + count; u8* dest_addr = swizzle_data + swizzled_offset; @@ -356,9 +371,9 @@ std::vector DecodeTexture(const std::vector& texture_data, TextureFormat std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, u32 block_height, u32 block_depth) { if (tiled) { - const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x); - const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height); - const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth); + const u32 aligned_width = Common::AlignBits(width * bytes_per_pixel, gob_size_x_shift); + const u32 aligned_height = Common::AlignBits(height, gob_size_y_shift + block_height); + const u32 aligned_depth = Common::AlignBits(depth, gob_size_z_shift + block_depth); return aligned_width * aligned_height * aligned_depth; } else { return width * height * depth * bytes_per_pixel; diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index e072d8401..eaec9b5a5 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h @@ -12,8 +12,8 @@ namespace Tegra::Texture { // GOBSize constant. Calculated by 64 bytes in x multiplied by 8 y coords, represents // an small rect of (64/bytes_per_pixel)X8. -inline std::size_t GetGOBSize() { - return 512; +inline std::size_t GetGOBSizeShift() { + return 9; } /// Unswizzles a swizzled texture without changing its format. diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index 219bfd559..f22b4e7c7 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -219,20 +219,17 @@ struct TICEntry { u32 BlockWidth() const { ASSERT(IsTiled()); - // The block height is stored in log2 format. - return 1 << block_width; + return block_width; } u32 BlockHeight() const { ASSERT(IsTiled()); - // The block height is stored in log2 format. - return 1 << block_height; + return block_height; } u32 BlockDepth() const { ASSERT(IsTiled()); - // The block height is stored in log2 format. - return 1 << block_depth; + return block_depth; } bool IsTiled() const { -- 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 --- .../renderer_opengl/gl_texture_cache.cpp | 11 ++- src/video_core/surface.h | 84 +++++++++++++++++++++- src/video_core/texture_cache/surface_base.cpp | 18 ++++- src/video_core/texture_cache/surface_base.h | 4 ++ src/video_core/texture_cache/surface_params.cpp | 52 ++++++++------ src/video_core/texture_cache/surface_params.h | 27 ++++--- src/video_core/textures/convert.cpp | 14 ++-- src/video_core/textures/convert.h | 7 +- 8 files changed, 170 insertions(+), 47 deletions(-) (limited to 'src/video_core/textures') diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index a55097e5f..197c9f02c 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -23,6 +23,7 @@ using VideoCore::MortonSwizzleMode; using VideoCore::Surface::ComponentType; using VideoCore::Surface::PixelFormat; +using VideoCore::Surface::SurfaceCompression; using VideoCore::Surface::SurfaceTarget; using VideoCore::Surface::SurfaceType; @@ -242,10 +243,10 @@ void CachedSurface::DownloadTexture(std::vector& staging_buffer) { MICROPROFILE_SCOPE(OpenGL_Texture_Download); // TODO(Rodrigo): Optimize alignment - glPixelStorei(GL_PACK_ALIGNMENT, 1); SCOPE_EXIT({ glPixelStorei(GL_PACK_ROW_LENGTH, 0); }); for (u32 level = 0; level < params.num_levels; ++level) { + glPixelStorei(GL_PACK_ALIGNMENT, std::min(8U, params.GetRowAlignment(level))); glPixelStorei(GL_PACK_ROW_LENGTH, static_cast(params.GetMipWidth(level))); const std::size_t mip_offset = params.GetHostMipmapLevelOffset(level); if (is_compressed) { @@ -270,10 +271,14 @@ void CachedSurface::UploadTexture(std::vector& staging_buffer) { void CachedSurface::UploadTextureMipmap(u32 level, std::vector& staging_buffer) { // TODO(Rodrigo): Optimize alignment - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, std::min(8U, params.GetRowAlignment(level))); glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast(params.GetMipWidth(level))); - const std::size_t mip_offset = params.GetHostMipmapLevelOffset(level); + auto compression_type = params.GetCompressionType(); + + const std::size_t mip_offset = compression_type == SurfaceCompression::Converted + ? params.GetConvertedMipmapOffset(level) + : params.GetHostMipmapLevelOffset(level); u8* buffer{staging_buffer.data() + mip_offset}; if (is_compressed) { const auto image_size{static_cast(params.GetHostMipmapSize(level))}; diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 8e98033f3..5d49214e5 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -197,7 +197,7 @@ inline constexpr std::array compression_factor_shift_table */ inline constexpr u32 GetCompressionFactorShift(PixelFormat format) { DEBUG_ASSERT(format != PixelFormat::Invalid); - DEBUG_ASSERT(static_cast(format) < compression_factor_table.size()); + DEBUG_ASSERT(static_cast(format) < compression_factor_shift_table.size()); return compression_factor_shift_table[static_cast(format)]; } @@ -438,6 +438,88 @@ static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) { return GetFormatBpp(pixel_format) / CHAR_BIT; } +enum class SurfaceCompression : u8 { + None = 0, + Compressed = 1, + Converted = 2, + Rearranged = 3, +}; + +inline constexpr std::array compression_type_table = {{ + SurfaceCompression::None, // ABGR8U + SurfaceCompression::None, // ABGR8S + SurfaceCompression::None, // ABGR8UI + SurfaceCompression::None, // B5G6R5U + SurfaceCompression::None, // A2B10G10R10U + SurfaceCompression::None, // A1B5G5R5U + SurfaceCompression::None, // R8U + SurfaceCompression::None, // R8UI + SurfaceCompression::None, // RGBA16F + SurfaceCompression::None, // RGBA16U + SurfaceCompression::None, // RGBA16UI + SurfaceCompression::None, // R11FG11FB10F + SurfaceCompression::None, // RGBA32UI + SurfaceCompression::Compressed, // DXT1 + SurfaceCompression::Compressed, // DXT23 + SurfaceCompression::Compressed, // DXT45 + SurfaceCompression::Compressed, // DXN1 + SurfaceCompression::Compressed, // DXN2UNORM + SurfaceCompression::Compressed, // DXN2SNORM + SurfaceCompression::Compressed, // BC7U + SurfaceCompression::Compressed, // BC6H_UF16 + SurfaceCompression::Compressed, // BC6H_SF16 + SurfaceCompression::Converted, // ASTC_2D_4X4 + SurfaceCompression::None, // BGRA8 + SurfaceCompression::None, // RGBA32F + SurfaceCompression::None, // RG32F + SurfaceCompression::None, // R32F + SurfaceCompression::None, // R16F + SurfaceCompression::None, // R16U + SurfaceCompression::None, // R16S + SurfaceCompression::None, // R16UI + SurfaceCompression::None, // R16I + SurfaceCompression::None, // RG16 + SurfaceCompression::None, // RG16F + SurfaceCompression::None, // RG16UI + SurfaceCompression::None, // RG16I + SurfaceCompression::None, // RG16S + SurfaceCompression::None, // RGB32F + SurfaceCompression::None, // RGBA8_SRGB + SurfaceCompression::None, // RG8U + SurfaceCompression::None, // RG8S + SurfaceCompression::None, // RG32UI + SurfaceCompression::None, // R32UI + SurfaceCompression::Converted, // ASTC_2D_8X8 + SurfaceCompression::Converted, // ASTC_2D_8X5 + SurfaceCompression::Converted, // ASTC_2D_5X4 + SurfaceCompression::None, // BGRA8_SRGB + SurfaceCompression::Compressed, // DXT1_SRGB + SurfaceCompression::Compressed, // DXT23_SRGB + SurfaceCompression::Compressed, // DXT45_SRGB + SurfaceCompression::Compressed, // BC7U_SRGB + SurfaceCompression::Converted, // ASTC_2D_4X4_SRGB + SurfaceCompression::Converted, // ASTC_2D_8X8_SRGB + SurfaceCompression::Converted, // ASTC_2D_8X5_SRGB + SurfaceCompression::Converted, // ASTC_2D_5X4_SRGB + SurfaceCompression::Converted, // ASTC_2D_5X5 + SurfaceCompression::Converted, // ASTC_2D_5X5_SRGB + SurfaceCompression::Converted, // ASTC_2D_10X8 + SurfaceCompression::Converted, // ASTC_2D_10X8_SRGB + SurfaceCompression::None, // Z32F + SurfaceCompression::None, // Z16 + SurfaceCompression::None, // Z24S8 + SurfaceCompression::Rearranged, // S8Z24 + SurfaceCompression::None, // Z32FS8 +}}; + +static constexpr SurfaceCompression GetFormatCompressionType(PixelFormat format) { + if (format == PixelFormat::Invalid) + return SurfaceCompression::None; + + ASSERT(static_cast(format) < compression_type_table.size()); + return compression_type_table[static_cast(format)]; +} + SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type); bool SurfaceTargetIsLayered(SurfaceTarget target); diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp index 510d1aef5..ceff51043 100644 --- a/src/video_core/texture_cache/surface_base.cpp +++ b/src/video_core/texture_cache/surface_base.cpp @@ -17,6 +17,7 @@ MICROPROFILE_DEFINE(GPU_Flush_Texture, "GPU", "Texture Flush", MP_RGB(128, 192, using Tegra::Texture::ConvertFromGuestToHost; using VideoCore::MortonSwizzleMode; +using VideoCore::Surface::SurfaceCompression; SurfaceBaseImpl::SurfaceBaseImpl(GPUVAddr gpu_addr, const SurfaceParams& params) : params{params}, mipmap_sizes(params.num_levels), @@ -102,9 +103,20 @@ void SurfaceBaseImpl::LoadBuffer(Tegra::MemoryManager& memory_manager, } } - for (u32 level = 0; level < params.num_levels; ++level) { - const std::size_t host_offset{params.GetHostMipmapLevelOffset(level)}; - ConvertFromGuestToHost(staging_buffer.data() + host_offset, params.pixel_format, + auto compression_type = params.GetCompressionType(); + if (compression_type == SurfaceCompression::None || + compression_type == SurfaceCompression::Compressed) + return; + + for (u32 level_up = params.num_levels; level_up > 0; --level_up) { + const u32 level = level_up - 1; + const std::size_t in_host_offset{params.GetHostMipmapLevelOffset(level)}; + const std::size_t out_host_offset = compression_type == SurfaceCompression::Rearranged + ? in_host_offset + : params.GetConvertedMipmapOffset(level); + u8* in_buffer = staging_buffer.data() + in_host_offset; + u8* out_buffer = staging_buffer.data() + out_host_offset; + ConvertFromGuestToHost(in_buffer, out_buffer, params.pixel_format, params.GetMipWidth(level), params.GetMipHeight(level), params.GetMipDepth(level), true, true); } diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h index 78db2d665..cb7f22706 100644 --- a/src/video_core/texture_cache/surface_base.h +++ b/src/video_core/texture_cache/surface_base.h @@ -93,6 +93,10 @@ public: return mipmap_sizes[level]; } + bool IsLinear() const { + return !params.is_tiled; + } + bool MatchFormat(VideoCore::Surface::PixelFormat pixel_format) const { return params.pixel_format == pixel_format; } 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 { diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h index 7c48782c7..b3082173f 100644 --- a/src/video_core/texture_cache/surface_params.h +++ b/src/video_core/texture_cache/surface_params.h @@ -7,6 +7,7 @@ #include #include "common/alignment.h" +#include "common/bit_util.h" #include "common/common_types.h" #include "video_core/engines/fermi_2d.h" #include "video_core/engines/maxwell_3d.h" @@ -16,6 +17,8 @@ namespace VideoCommon { +using VideoCore::Surface::SurfaceCompression; + class SurfaceParams { public: /// Creates SurfaceCachedParams from a texture configuration. @@ -50,17 +53,12 @@ public: std::size_t GetHostSizeInBytes() const { std::size_t host_size_in_bytes; - if (IsPixelFormatASTC(pixel_format)) { + if (GetCompressionType() == SurfaceCompression::Converted) { constexpr std::size_t rgb8_bpp = 4ULL; // ASTC is uncompressed in software, in emulated as RGBA8 host_size_in_bytes = 0; for (u32 level = 0; level < num_levels; ++level) { - const std::size_t width = - Common::AlignUp(GetMipWidth(level), GetDefaultBlockWidth()); - const std::size_t height = - Common::AlignUp(GetMipHeight(level), GetDefaultBlockHeight()); - const std::size_t depth = is_layered ? this->depth : GetMipDepth(level); - host_size_in_bytes += width * height * depth * rgb8_bpp; + host_size_in_bytes += GetConvertedMipmapSize(level); } } else { host_size_in_bytes = GetInnerMemorySize(true, false, false); @@ -93,6 +91,12 @@ public: /// Returns the block depth of a given mipmap level. u32 GetMipBlockDepth(u32 level) const; + u32 GetRowAlignment(u32 level) const { + const u32 bpp = + GetCompressionType() == SurfaceCompression::Converted ? 4 : GetBytesPerPixel(); + return 1U << Common::CountTrailingZeroes32(GetMipWidth(level) * bpp); + } + // Helper used for out of class size calculations static std::size_t AlignLayered(const std::size_t out_size, const u32 block_height, const u32 block_depth) { @@ -106,12 +110,16 @@ public: /// Returns the offset in bytes in host memory (linear) of a given mipmap level. std::size_t GetHostMipmapLevelOffset(u32 level) const; + std::size_t GetConvertedMipmapOffset(u32 level) const; + /// Returns the size in bytes in guest memory of a given mipmap level. std::size_t GetGuestMipmapSize(u32 level) const; /// Returns the size in bytes in host memory (linear) of a given mipmap level. std::size_t GetHostMipmapSize(u32 level) const; + std::size_t GetConvertedMipmapSize(u32 level) const; + /// Returns the size of a layer in bytes in guest memory. std::size_t GetGuestLayerSize() const; @@ -141,6 +149,10 @@ public: /// Returns true if the pixel format is a depth and/or stencil format. bool IsPixelFormatZeta() const; + SurfaceCompression GetCompressionType() const { + return VideoCore::Surface::GetFormatCompressionType(pixel_format); + } + std::string TargetName() const; bool is_tiled; @@ -154,7 +166,6 @@ public: u32 height; u32 depth; u32 pitch; - u32 unaligned_height; u32 num_levels; VideoCore::Surface::PixelFormat pixel_format; VideoCore::Surface::ComponentType component_type; diff --git a/src/video_core/textures/convert.cpp b/src/video_core/textures/convert.cpp index 82050bd51..f3efa7eb0 100644 --- a/src/video_core/textures/convert.cpp +++ b/src/video_core/textures/convert.cpp @@ -62,19 +62,19 @@ static void ConvertZ24S8ToS8Z24(u8* data, u32 width, u32 height) { SwapS8Z24ToZ24S8(data, width, height); } -void ConvertFromGuestToHost(u8* data, PixelFormat pixel_format, u32 width, u32 height, u32 depth, - bool convert_astc, bool convert_s8z24) { +void ConvertFromGuestToHost(u8* in_data, u8* out_data, PixelFormat pixel_format, u32 width, + u32 height, u32 depth, bool convert_astc, bool convert_s8z24) { if (convert_astc && IsPixelFormatASTC(pixel_format)) { // Convert ASTC pixel formats to RGBA8, as most desktop GPUs do not support ASTC. u32 block_width{}; u32 block_height{}; std::tie(block_width, block_height) = GetASTCBlockSize(pixel_format); - const std::vector rgba8_data = - Tegra::Texture::ASTC::Decompress(data, width, height, depth, block_width, block_height); - std::copy(rgba8_data.begin(), rgba8_data.end(), data); + const std::vector rgba8_data = Tegra::Texture::ASTC::Decompress( + in_data, width, height, depth, block_width, block_height); + std::copy(rgba8_data.begin(), rgba8_data.end(), out_data); } else if (convert_s8z24 && pixel_format == PixelFormat::S8Z24) { - Tegra::Texture::ConvertS8Z24ToZ24S8(data, width, height); + Tegra::Texture::ConvertS8Z24ToZ24S8(in_data, width, height); } } @@ -90,4 +90,4 @@ void ConvertFromHostToGuest(u8* data, PixelFormat pixel_format, u32 width, u32 h } } -} // namespace Tegra::Texture \ No newline at end of file +} // namespace Tegra::Texture diff --git a/src/video_core/textures/convert.h b/src/video_core/textures/convert.h index 12542e71c..d5d6c77bb 100644 --- a/src/video_core/textures/convert.h +++ b/src/video_core/textures/convert.h @@ -12,10 +12,11 @@ enum class PixelFormat; namespace Tegra::Texture { -void ConvertFromGuestToHost(u8* data, VideoCore::Surface::PixelFormat pixel_format, u32 width, - u32 height, u32 depth, bool convert_astc, bool convert_s8z24); +void ConvertFromGuestToHost(u8* in_data, u8* out_data, VideoCore::Surface::PixelFormat pixel_format, + u32 width, u32 height, u32 depth, bool convert_astc, + bool convert_s8z24); void ConvertFromHostToGuest(u8* data, VideoCore::Surface::PixelFormat pixel_format, u32 width, u32 height, u32 depth, bool convert_astc, bool convert_s8z24); -} // namespace Tegra::Texture \ No newline at end of file +} // namespace Tegra::Texture -- cgit v1.2.3 From b8c75a845b1784045a10fa8b5f1f57f2ec53eeca Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 28 Apr 2019 01:01:22 -0300 Subject: maxwell_3d: Partially implement texture buffers as 1D textures --- src/video_core/engines/maxwell_3d.cpp | 12 ++++-------- src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 2 +- src/video_core/surface.cpp | 2 ++ src/video_core/textures/texture.h | 18 +++++++++++++++++- 4 files changed, 24 insertions(+), 10 deletions(-) (limited to 'src/video_core/textures') diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 08d553696..8755b8af4 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp @@ -430,14 +430,10 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { Texture::TICEntry tic_entry; memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); - ASSERT_MSG(tic_entry.header_version == Texture::TICHeaderVersion::BlockLinear || - tic_entry.header_version == Texture::TICHeaderVersion::Pitch, - "TIC versions other than BlockLinear or Pitch are unimplemented"); - - const auto r_type = tic_entry.r_type.Value(); - const auto g_type = tic_entry.g_type.Value(); - const auto b_type = tic_entry.b_type.Value(); - const auto a_type = tic_entry.a_type.Value(); + const auto r_type{tic_entry.r_type.Value()}; + const auto g_type{tic_entry.g_type.Value()}; + const auto b_type{tic_entry.b_type.Value()}; + const auto a_type{tic_entry.a_type.Value()}; // TODO(Subv): Different data types for separate components are not supported DEBUG_ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index a7681902e..543b36271 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -140,7 +140,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only, params.width = Common::AlignUp(config.tic.Width(), GetCompressionFactor(params.pixel_format)); params.height = Common::AlignUp(config.tic.Height(), GetCompressionFactor(params.pixel_format)); - if (!params.is_tiled) { + if (config.tic.IsLineal()) { params.pitch = config.tic.Pitch(); } params.unaligned_height = config.tic.Height(); diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 6384fa8d2..56c43af17 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -12,6 +12,8 @@ SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_t switch (texture_type) { case Tegra::Texture::TextureType::Texture1D: return SurfaceTarget::Texture1D; + case Tegra::Texture::TextureType::Texture1DBuffer: + return SurfaceTarget::Texture1D; // Fixme case Tegra::Texture::TextureType::Texture2D: case Tegra::Texture::TextureType::Texture2DNoMipmap: return SurfaceTarget::Texture2D; diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index f22b4e7c7..ddeed73d0 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -172,12 +172,16 @@ struct TICEntry { BitField<26, 1, u32> use_header_opt_control; BitField<27, 1, u32> depth_texture; BitField<28, 4, u32> max_mip_level; + + BitField<0, 16, u32> buffer_high_width_minus_one; }; union { BitField<0, 16, u32> width_minus_1; BitField<22, 1, u32> srgb_conversion; BitField<23, 4, TextureType> texture_type; BitField<29, 3, u32> border_size; + + BitField<0, 16, u32> buffer_low_width_minus_one; }; union { BitField<0, 16, u32> height_minus_1; @@ -206,7 +210,10 @@ struct TICEntry { } u32 Width() const { - return width_minus_1 + 1; + if (header_version != TICHeaderVersion::OneDBuffer) { + return width_minus_1 + 1; + } + return (buffer_high_width_minus_one << 16) | buffer_low_width_minus_one; } u32 Height() const { @@ -237,6 +244,15 @@ struct TICEntry { header_version == TICHeaderVersion::BlockLinearColorKey; } + bool IsLineal() const { + return header_version == TICHeaderVersion::Pitch || + header_version == TICHeaderVersion::PitchColorKey; + } + + bool IsBuffer() const { + return header_version == TICHeaderVersion::OneDBuffer; + } + bool IsSrgbConversionEnabled() const { return srgb_conversion != 0; } -- cgit v1.2.3 From 7232a1ed16e46715c29d781fb143bdf799090bec Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 13 Jun 2019 16:41:16 -0400 Subject: decoders: correct block calculation --- src/video_core/engines/engine_upload.cpp | 2 +- src/video_core/engines/engine_upload.h | 6 ++--- src/video_core/engines/fermi_2d.h | 6 ++--- src/video_core/engines/maxwell_dma.cpp | 2 +- src/video_core/engines/maxwell_dma.h | 4 ++-- src/video_core/texture_cache/texture_cache.h | 16 +++++++++++++ src/video_core/textures/decoders.cpp | 34 ++++++++++++---------------- 7 files changed, 41 insertions(+), 29 deletions(-) (limited to 'src/video_core/textures') diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp index c776b9a56..d44ad0cd8 100644 --- a/src/video_core/engines/engine_upload.cpp +++ b/src/video_core/engines/engine_upload.cpp @@ -39,7 +39,7 @@ void State::ProcessData(const u32 data, const bool is_last_call) { UNIMPLEMENTED_IF(regs.dest.BlockWidth() != 0); UNIMPLEMENTED_IF(regs.dest.BlockDepth() != 0); const std::size_t dst_size = Tegra::Texture::CalculateSize( - true, 1, regs.dest.width, regs.dest.height, 1, regs.dest.BlockHeight(), 1); + true, 1, regs.dest.width, regs.dest.height, 1, regs.dest.BlockHeight(), 0); tmp_buffer.resize(dst_size); memory_manager.ReadBlock(address, tmp_buffer.data(), dst_size); Tegra::Texture::SwizzleKepler(regs.dest.width, regs.dest.height, regs.dest.x, regs.dest.y, diff --git a/src/video_core/engines/engine_upload.h b/src/video_core/engines/engine_upload.h index cb294aec3..462da419e 100644 --- a/src/video_core/engines/engine_upload.h +++ b/src/video_core/engines/engine_upload.h @@ -39,15 +39,15 @@ struct Registers { } u32 BlockWidth() const { - return block_width; + return block_width.Value(); } u32 BlockHeight() const { - return block_height; + return block_height.Value(); } u32 BlockDepth() const { - return block_depth; + return block_depth.Value(); } } dest; }; diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h index 0a4c7c5ad..05421d185 100644 --- a/src/video_core/engines/fermi_2d.h +++ b/src/video_core/engines/fermi_2d.h @@ -84,15 +84,15 @@ public: } u32 BlockWidth() const { - return block_width; + return block_width.Value(); } u32 BlockHeight() const { - return block_height; + return block_height.Value(); } u32 BlockDepth() const { - return block_depth; + return block_depth.Value(); } }; static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size"); diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index afb9578d0..3a5dfef0c 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -111,7 +111,7 @@ void MaxwellDMA::HandleCopy() { memory_manager.WriteBlock(dest, write_buffer.data(), dst_size); } else { - ASSERT(regs.dst_params.BlockDepth() == 0); + ASSERT(regs.dst_params.BlockDepth() == 1); const u32 src_bytes_per_pixel = regs.src_pitch / regs.x_count; diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h index 522fa97dc..17b015ca7 100644 --- a/src/video_core/engines/maxwell_dma.h +++ b/src/video_core/engines/maxwell_dma.h @@ -59,11 +59,11 @@ public: }; u32 BlockHeight() const { - return block_height; + return block_height.Value(); } u32 BlockDepth() const { - return block_depth; + return block_depth.Value(); } }; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 201c4d42e..7a9b4c27d 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -335,6 +335,9 @@ private: if (untopological == MatchTopologyResult::CompressUnmatch) { return RecycleStrategy::Flush; } + if (untopological == MatchTopologyResult::FullMatch && !params.is_tiled) { + return RecycleStrategy::Flush; + } return RecycleStrategy::Ignore; } @@ -372,6 +375,11 @@ private: } return InitializeSurface(gpu_addr, params, preserve_contents); } + case RecycleStrategy::BufferCopy: { + auto new_surface = GetUncachedSurface(gpu_addr, params); + BufferCopy(overlaps[0], new_surface); + return {new_surface, new_surface->GetMainView()}; + } default: { UNIMPLEMENTED_MSG("Unimplemented Texture Cache Recycling Strategy!"); return InitializeSurface(gpu_addr, params, do_load); @@ -520,6 +528,10 @@ private: const auto host_ptr{memory_manager->GetPointer(gpu_addr)}; const auto cache_addr{ToCacheAddr(host_ptr)}; + if (gpu_addr == 0x00000001682F0000ULL) { + LOG_CRITICAL(HW_GPU, "Here's the texture!"); + } + // Step 0: guarantee a valid surface if (!cache_addr) { // Return a null surface if it's invalid @@ -566,6 +578,10 @@ private: return InitializeSurface(gpu_addr, params, preserve_contents); } + if (!params.is_tiled) { + return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, + MatchTopologyResult::FullMatch); + } // Step 3 // Now we need to figure the relationship between the texture and its overlaps // we do a topological test to ensure we can find some relationship. If it fails diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index f45fd175a..9a2f4198a 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -256,19 +256,18 @@ std::vector UnswizzleTexture(u8* address, u32 tile_size_x, u32 tile_size_y, } void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, - u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height) { - const u32 block_height_size{1U << block_height}; + u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height_bit) { + const u32 block_height = 1U << block_height_bit; const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) / gob_size_x}; for (u32 line = 0; line < subrect_height; ++line) { const u32 gob_address_y = - (line / (gob_size_y * block_height_size)) * gob_size * block_height_size * - image_width_in_gobs + - ((line % (gob_size_y * block_height_size)) / gob_size_y) * gob_size; + (line / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs + + ((line % (gob_size_y * block_height)) / gob_size_y) * gob_size; const auto& table = legacy_swizzle_table[line % gob_size_y]; for (u32 x = 0; x < subrect_width; ++x) { const u32 gob_address = - gob_address_y + (x * bytes_per_pixel / gob_size_x) * gob_size * block_height_size; + gob_address_y + (x * bytes_per_pixel / gob_size_x) * gob_size * block_height; const u32 swizzled_offset = gob_address + table[(x * bytes_per_pixel) % gob_size_x]; u8* source_line = unswizzled_data + line * source_pitch + x * bytes_per_pixel; u8* dest_addr = swizzled_data + swizzled_offset; @@ -279,19 +278,17 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 } void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, - u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height, + u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height_bit, u32 offset_x, u32 offset_y) { - const u32 block_height_size{1U << block_height}; + const u32 block_height = 1U << block_height_bit; for (u32 line = 0; line < subrect_height; ++line) { const u32 y2 = line + offset_y; - const u32 gob_address_y = - (y2 / (gob_size_y * block_height_size)) * gob_size * block_height_size + - ((y2 % (gob_size_y * block_height_size)) / gob_size_y) * gob_size; + const u32 gob_address_y = (y2 / (gob_size_y * block_height)) * gob_size * block_height + + ((y2 % (gob_size_y * block_height)) / gob_size_y) * gob_size; const auto& table = legacy_swizzle_table[y2 % gob_size_y]; for (u32 x = 0; x < subrect_width; ++x) { const u32 x2 = (x + offset_x) * bytes_per_pixel; - const u32 gob_address = - gob_address_y + (x2 / gob_size_x) * gob_size * block_height_size; + const u32 gob_address = gob_address_y + (x2 / gob_size_x) * gob_size * block_height; const u32 swizzled_offset = gob_address + table[x2 % gob_size_x]; u8* dest_line = unswizzled_data + line * dest_pitch + x * bytes_per_pixel; u8* source_addr = swizzled_data + swizzled_offset; @@ -302,20 +299,19 @@ void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 } void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y, - const u32 block_height, const std::size_t copy_size, const u8* source_data, + const u32 block_height_bit, const std::size_t copy_size, const u8* source_data, u8* swizzle_data) { - const u32 block_height_size{1U << block_height}; + const u32 block_height = 1U << block_height_bit; const u32 image_width_in_gobs{(width + gob_size_x - 1) / gob_size_x}; std::size_t count = 0; for (std::size_t y = dst_y; y < height && count < copy_size; ++y) { const std::size_t gob_address_y = - (y / (gob_size_y * block_height_size)) * gob_size * block_height_size * - image_width_in_gobs + - ((y % (gob_size_y * block_height_size)) / gob_size_y) * gob_size; + (y / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs + + ((y % (gob_size_y * block_height)) / gob_size_y) * gob_size; const auto& table = legacy_swizzle_table[y % gob_size_y]; for (std::size_t x = dst_x; x < width && count < copy_size; ++x) { const std::size_t gob_address = - gob_address_y + (x / gob_size_x) * gob_size * block_height_size; + gob_address_y + (x / gob_size_x) * gob_size * block_height; const std::size_t swizzled_offset = gob_address + table[x % gob_size_x]; const u8* source_line = source_data + count; u8* dest_addr = swizzle_data + swizzled_offset; -- cgit v1.2.3 From 082740d34db0996a0af73d7680c57e1abb31c712 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 14 Jun 2019 16:40:04 -0400 Subject: surface: Correct format S8Z24 --- src/video_core/engines/maxwell_dma.cpp | 2 +- src/video_core/surface.cpp | 4 ++-- src/video_core/texture_cache/texture_cache.h | 4 ---- src/video_core/textures/texture.h | 4 ++-- 4 files changed, 5 insertions(+), 9 deletions(-) (limited to 'src/video_core/textures') diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index 3a5dfef0c..afb9578d0 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -111,7 +111,7 @@ void MaxwellDMA::HandleCopy() { memory_manager.WriteBlock(dest, write_buffer.data(), dst_size); } else { - ASSERT(regs.dst_params.BlockDepth() == 1); + ASSERT(regs.dst_params.BlockDepth() == 0); const u32 src_bytes_per_pixel = regs.src_pitch / regs.x_count; diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 52a79e4a7..c50f6354d 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -308,8 +308,8 @@ PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, return PixelFormat::Z32F; case Tegra::Texture::TextureFormat::Z16: return PixelFormat::Z16; - case Tegra::Texture::TextureFormat::Z24S8: - return PixelFormat::Z24S8; + case Tegra::Texture::TextureFormat::S8Z24: + return PixelFormat::S8Z24; case Tegra::Texture::TextureFormat::ZF32_X24S8: return PixelFormat::Z32FS8; case Tegra::Texture::TextureFormat::DXT1: diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 8213f434d..a9e61cba1 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -534,10 +534,6 @@ private: const auto host_ptr{memory_manager->GetPointer(gpu_addr)}; const auto cache_addr{ToCacheAddr(host_ptr)}; - if (gpu_addr == 0x00000001682F0000ULL) { - LOG_CRITICAL(HW_GPU, "Here's the texture!"); - } - // Step 0: guarantee a valid surface if (!cache_addr) { // Return a null surface if it's invalid diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index ddeed73d0..e3be018b9 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h @@ -52,9 +52,9 @@ enum class TextureFormat : u32 { DXT45 = 0x26, DXN1 = 0x27, DXN2 = 0x28, - Z24S8 = 0x29, + S8Z24 = 0x29, X8Z24 = 0x2a, - S8Z24 = 0x2b, + Z24S8 = 0x2b, X4V4Z24__COV4R4V = 0x2c, X4V4Z24__COV8R8V = 0x2d, V8Z24__COV4R12V = 0x2e, -- cgit v1.2.3 From d1812316e1b0f03af2ba10d4fe04be728e72725c Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 20 Jun 2019 21:22:20 -0400 Subject: texture_cache: Style and Corrections --- src/video_core/renderer_opengl/gl_shader_cache.cpp | 2 +- src/video_core/shader/node.h | 3 +- src/video_core/surface.h | 128 ++++++++++----------- src/video_core/texture_cache/surface_base.cpp | 2 +- src/video_core/texture_cache/surface_base.h | 3 +- src/video_core/texture_cache/texture_cache.h | 1 + src/video_core/textures/decoders.cpp | 7 +- 7 files changed, 75 insertions(+), 71 deletions(-) (limited to 'src/video_core/textures') diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index 02e217b8c..718703091 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -104,7 +104,7 @@ constexpr std::tuple GetPrimitiveDescription(GLen std::size_t CalculateProgramSize(const GLShader::ProgramCode& program) { constexpr std::size_t start_offset = 10; constexpr u64 key = 0xE2400FFFFF07000FULL; - constexpr u64 mask =0xFFFFFFFFFF7FFFFFULL; + constexpr u64 mask = 0xFFFFFFFFFF7FFFFFULL; std::size_t offset = start_offset; std::size_t size = start_offset * sizeof(u64); while (offset < program.size()) { diff --git a/src/video_core/shader/node.h b/src/video_core/shader/node.h index 2bf535928..0ac83fcf0 100644 --- a/src/video_core/shader/node.h +++ b/src/video_core/shader/node.h @@ -339,7 +339,8 @@ struct MetaImage { }; /// Parameters that modify an operation but are not part of any particular operand -using Meta = std::variant; +using Meta = + std::variant; /// Holds any kind of operation that can be done in the IR class OperationNode final { diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 959504cd3..ee9f00fa6 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -447,70 +447,70 @@ enum class SurfaceCompression : u8 { }; inline constexpr std::array compression_type_table = {{ - SurfaceCompression::None, // ABGR8U - SurfaceCompression::None, // ABGR8S - SurfaceCompression::None, // ABGR8UI - SurfaceCompression::None, // B5G6R5U - SurfaceCompression::None, // A2B10G10R10U - SurfaceCompression::None, // A1B5G5R5U - SurfaceCompression::None, // R8U - SurfaceCompression::None, // R8UI - SurfaceCompression::None, // RGBA16F - SurfaceCompression::None, // RGBA16U - SurfaceCompression::None, // RGBA16UI - SurfaceCompression::None, // R11FG11FB10F - SurfaceCompression::None, // RGBA32UI - SurfaceCompression::Compressed, // DXT1 - SurfaceCompression::Compressed, // DXT23 - SurfaceCompression::Compressed, // DXT45 - SurfaceCompression::Compressed, // DXN1 - SurfaceCompression::Compressed, // DXN2UNORM - SurfaceCompression::Compressed, // DXN2SNORM - SurfaceCompression::Compressed, // BC7U - SurfaceCompression::Compressed, // BC6H_UF16 - SurfaceCompression::Compressed, // BC6H_SF16 - SurfaceCompression::Converted, // ASTC_2D_4X4 - SurfaceCompression::None, // BGRA8 - SurfaceCompression::None, // RGBA32F - SurfaceCompression::None, // RG32F - SurfaceCompression::None, // R32F - SurfaceCompression::None, // R16F - SurfaceCompression::None, // R16U - SurfaceCompression::None, // R16S - SurfaceCompression::None, // R16UI - SurfaceCompression::None, // R16I - SurfaceCompression::None, // RG16 - SurfaceCompression::None, // RG16F - SurfaceCompression::None, // RG16UI - SurfaceCompression::None, // RG16I - SurfaceCompression::None, // RG16S - SurfaceCompression::None, // RGB32F - SurfaceCompression::None, // RGBA8_SRGB - SurfaceCompression::None, // RG8U - SurfaceCompression::None, // RG8S - SurfaceCompression::None, // RG32UI - SurfaceCompression::None, // R32UI - SurfaceCompression::Converted, // ASTC_2D_8X8 - SurfaceCompression::Converted, // ASTC_2D_8X5 - SurfaceCompression::Converted, // ASTC_2D_5X4 - SurfaceCompression::None, // BGRA8_SRGB - SurfaceCompression::Compressed, // DXT1_SRGB - SurfaceCompression::Compressed, // DXT23_SRGB - SurfaceCompression::Compressed, // DXT45_SRGB - SurfaceCompression::Compressed, // BC7U_SRGB - SurfaceCompression::Converted, // ASTC_2D_4X4_SRGB - SurfaceCompression::Converted, // ASTC_2D_8X8_SRGB - SurfaceCompression::Converted, // ASTC_2D_8X5_SRGB - SurfaceCompression::Converted, // ASTC_2D_5X4_SRGB - SurfaceCompression::Converted, // ASTC_2D_5X5 - SurfaceCompression::Converted, // ASTC_2D_5X5_SRGB - SurfaceCompression::Converted, // ASTC_2D_10X8 - SurfaceCompression::Converted, // ASTC_2D_10X8_SRGB - SurfaceCompression::None, // Z32F - SurfaceCompression::None, // Z16 - SurfaceCompression::None, // Z24S8 - SurfaceCompression::Rearranged, // S8Z24 - SurfaceCompression::None, // Z32FS8 + SurfaceCompression::None, // ABGR8U + SurfaceCompression::None, // ABGR8S + SurfaceCompression::None, // ABGR8UI + SurfaceCompression::None, // B5G6R5U + SurfaceCompression::None, // A2B10G10R10U + SurfaceCompression::None, // A1B5G5R5U + SurfaceCompression::None, // R8U + SurfaceCompression::None, // R8UI + SurfaceCompression::None, // RGBA16F + SurfaceCompression::None, // RGBA16U + SurfaceCompression::None, // RGBA16UI + SurfaceCompression::None, // R11FG11FB10F + SurfaceCompression::None, // RGBA32UI + SurfaceCompression::Compressed, // DXT1 + SurfaceCompression::Compressed, // DXT23 + SurfaceCompression::Compressed, // DXT45 + SurfaceCompression::Compressed, // DXN1 + SurfaceCompression::Compressed, // DXN2UNORM + SurfaceCompression::Compressed, // DXN2SNORM + SurfaceCompression::Compressed, // BC7U + SurfaceCompression::Compressed, // BC6H_UF16 + SurfaceCompression::Compressed, // BC6H_SF16 + SurfaceCompression::Converted, // ASTC_2D_4X4 + SurfaceCompression::None, // BGRA8 + SurfaceCompression::None, // RGBA32F + SurfaceCompression::None, // RG32F + SurfaceCompression::None, // R32F + SurfaceCompression::None, // R16F + SurfaceCompression::None, // R16U + SurfaceCompression::None, // R16S + SurfaceCompression::None, // R16UI + SurfaceCompression::None, // R16I + SurfaceCompression::None, // RG16 + SurfaceCompression::None, // RG16F + SurfaceCompression::None, // RG16UI + SurfaceCompression::None, // RG16I + SurfaceCompression::None, // RG16S + SurfaceCompression::None, // RGB32F + SurfaceCompression::None, // RGBA8_SRGB + SurfaceCompression::None, // RG8U + SurfaceCompression::None, // RG8S + SurfaceCompression::None, // RG32UI + SurfaceCompression::None, // R32UI + SurfaceCompression::Converted, // ASTC_2D_8X8 + SurfaceCompression::Converted, // ASTC_2D_8X5 + SurfaceCompression::Converted, // ASTC_2D_5X4 + SurfaceCompression::None, // BGRA8_SRGB + SurfaceCompression::Compressed, // DXT1_SRGB + SurfaceCompression::Compressed, // DXT23_SRGB + SurfaceCompression::Compressed, // DXT45_SRGB + SurfaceCompression::Compressed, // BC7U_SRGB + SurfaceCompression::Converted, // ASTC_2D_4X4_SRGB + SurfaceCompression::Converted, // ASTC_2D_8X8_SRGB + SurfaceCompression::Converted, // ASTC_2D_8X5_SRGB + SurfaceCompression::Converted, // ASTC_2D_5X4_SRGB + SurfaceCompression::Converted, // ASTC_2D_5X5 + SurfaceCompression::Converted, // ASTC_2D_5X5_SRGB + SurfaceCompression::Converted, // ASTC_2D_10X8 + SurfaceCompression::Converted, // ASTC_2D_10X8_SRGB + SurfaceCompression::None, // Z32F + SurfaceCompression::None, // Z16 + SurfaceCompression::None, // Z24S8 + SurfaceCompression::Rearranged, // S8Z24 + SurfaceCompression::None, // Z32FS8 }}; static constexpr SurfaceCompression GetFormatCompressionType(PixelFormat format) { diff --git a/src/video_core/texture_cache/surface_base.cpp b/src/video_core/texture_cache/surface_base.cpp index 97bf9ad7a..051014c6a 100644 --- a/src/video_core/texture_cache/surface_base.cpp +++ b/src/video_core/texture_cache/surface_base.cpp @@ -101,7 +101,7 @@ MatchStructureResult SurfaceBaseImpl::MatchesStructure(const SurfaceParams& rhs) std::optional> SurfaceBaseImpl::GetLayerMipmap( const GPUVAddr candidate_gpu_addr) const { if (gpu_addr == candidate_gpu_addr) { - return {{0,0}}; + return {{0, 0}}; } if (candidate_gpu_addr < gpu_addr) { return {}; diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h index 662221adc..252b18538 100644 --- a/src/video_core/texture_cache/surface_base.h +++ b/src/video_core/texture_cache/surface_base.h @@ -254,7 +254,8 @@ public: } return {}; } else { - return GetView(ViewParams(view_params.target, layer, 1, mipmap, end_mipmap - mipmap + 1)); + return GetView( + ViewParams(view_params.target, layer, 1, mipmap, end_mipmap - mipmap + 1)); } } diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index d86ddeb76..b720856f2 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -18,6 +18,7 @@ #include "common/common_types.h" #include "common/math_util.h" #include "core/memory.h" +#include "core/settings.h" #include "video_core/engines/fermi_2d.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/gpu.h" diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 9a2f4198a..7e8295944 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp @@ -256,7 +256,8 @@ std::vector UnswizzleTexture(u8* address, u32 tile_size_x, u32 tile_size_y, } void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, - u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height_bit) { + u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, + u32 block_height_bit) { const u32 block_height = 1U << block_height_bit; const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) / gob_size_x}; @@ -278,8 +279,8 @@ void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 } void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, - u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height_bit, - u32 offset_x, u32 offset_y) { + u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, + u32 block_height_bit, u32 offset_x, u32 offset_y) { const u32 block_height = 1U << block_height_bit; for (u32 line = 0; line < subrect_height; ++line) { const u32 y2 = line + offset_y; -- cgit v1.2.3