| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include <fmt/format.h>
- #include "common/assert.h"
- #include "video_core/surface.h"
- #include "video_core/texture_cache/format_lookup_table.h"
- #include "video_core/texture_cache/image_info.h"
- #include "video_core/texture_cache/samples_helper.h"
- #include "video_core/texture_cache/types.h"
- #include "video_core/texture_cache/util.h"
- #include "video_core/textures/texture.h"
- namespace VideoCommon {
- using Tegra::Engines::Maxwell3D;
- using Tegra::Texture::TextureType;
- using Tegra::Texture::TICEntry;
- using VideoCore::Surface::PixelFormat;
- using VideoCore::Surface::SurfaceType;
- ImageInfo::ImageInfo(const TICEntry& config) noexcept {
- format = PixelFormatFromTextureInfo(config.format, config.r_type, config.g_type, config.b_type,
- config.a_type, config.srgb_conversion);
- num_samples = NumSamples(config.msaa_mode);
- resources.levels = config.max_mip_level + 1;
- if (config.IsPitchLinear()) {
- pitch = config.Pitch();
- } else if (config.IsBlockLinear()) {
- block = Extent3D{
- .width = config.block_width,
- .height = config.block_height,
- .depth = config.block_depth,
- };
- }
- rescaleable = false;
- tile_width_spacing = config.tile_width_spacing;
- if (config.texture_type != TextureType::Texture2D &&
- config.texture_type != TextureType::Texture2DNoMipmap) {
- ASSERT(!config.IsPitchLinear());
- }
- switch (config.texture_type) {
- case TextureType::Texture1D:
- ASSERT(config.BaseLayer() == 0);
- type = ImageType::e1D;
- size.width = config.Width();
- resources.layers = 1;
- break;
- case TextureType::Texture1DArray:
- UNIMPLEMENTED_IF(config.BaseLayer() != 0);
- type = ImageType::e1D;
- size.width = config.Width();
- resources.layers = config.Depth();
- break;
- case TextureType::Texture2D:
- case TextureType::Texture2DNoMipmap:
- ASSERT(config.Depth() == 1);
- type = config.IsPitchLinear() ? ImageType::Linear : ImageType::e2D;
- rescaleable = !config.IsPitchLinear();
- size.width = config.Width();
- size.height = config.Height();
- resources.layers = config.BaseLayer() + 1;
- break;
- case TextureType::Texture2DArray:
- type = ImageType::e2D;
- rescaleable = true;
- size.width = config.Width();
- size.height = config.Height();
- resources.layers = config.BaseLayer() + config.Depth();
- break;
- case TextureType::TextureCubemap:
- ASSERT(config.Depth() == 1);
- type = ImageType::e2D;
- size.width = config.Width();
- size.height = config.Height();
- resources.layers = config.BaseLayer() + 6;
- break;
- case TextureType::TextureCubeArray:
- UNIMPLEMENTED_IF(config.load_store_hint != 0);
- type = ImageType::e2D;
- size.width = config.Width();
- size.height = config.Height();
- resources.layers = config.BaseLayer() + config.Depth() * 6;
- break;
- case TextureType::Texture3D:
- ASSERT(config.BaseLayer() == 0);
- type = ImageType::e3D;
- size.width = config.Width();
- size.height = config.Height();
- size.depth = config.Depth();
- resources.layers = 1;
- break;
- case TextureType::Texture1DBuffer:
- type = ImageType::Buffer;
- size.width = config.Width();
- resources.layers = 1;
- break;
- default:
- ASSERT_MSG(false, "Invalid texture_type={}", static_cast<int>(config.texture_type.Value()));
- break;
- }
- if (type != ImageType::Linear) {
- // FIXME: Call this without passing *this
- layer_stride = CalculateLayerStride(*this);
- maybe_unaligned_layer_stride = CalculateLayerSize(*this);
- rescaleable &= (block.depth == 0) && resources.levels == 1;
- rescaleable &= size.height > 256 || GetFormatType(format) != SurfaceType::ColorTexture;
- downscaleable = size.height > 512;
- }
- }
- ImageInfo::ImageInfo(const Maxwell3D::Regs& regs, size_t index) noexcept {
- const auto& rt = regs.rt[index];
- format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(rt.format);
- rescaleable = false;
- if (rt.tile_mode.is_pitch_linear) {
- ASSERT(rt.tile_mode.dim_control ==
- Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray);
- type = ImageType::Linear;
- pitch = rt.width;
- size = Extent3D{
- .width = pitch / BytesPerBlock(format),
- .height = rt.height,
- .depth = 1,
- };
- return;
- }
- size.width = rt.width;
- size.height = rt.height;
- layer_stride = rt.array_pitch * 4;
- maybe_unaligned_layer_stride = layer_stride;
- num_samples = NumSamples(regs.anti_alias_samples_mode);
- block = Extent3D{
- .width = rt.tile_mode.block_width,
- .height = rt.tile_mode.block_height,
- .depth = rt.tile_mode.block_depth,
- };
- if (rt.tile_mode.dim_control ==
- Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) {
- type = ImageType::e3D;
- size.depth = rt.depth;
- } else {
- rescaleable = block.depth == 0;
- rescaleable &= size.height > 256;
- downscaleable = size.height > 512;
- type = ImageType::e2D;
- resources.layers = rt.depth;
- }
- }
- ImageInfo::ImageInfo(const Tegra::Engines::Maxwell3D::Regs& regs) noexcept {
- format = VideoCore::Surface::PixelFormatFromDepthFormat(regs.zeta.format);
- size.width = regs.zeta_size.width;
- size.height = regs.zeta_size.height;
- rescaleable = false;
- resources.levels = 1;
- layer_stride = regs.zeta.array_pitch * 4;
- maybe_unaligned_layer_stride = layer_stride;
- num_samples = NumSamples(regs.anti_alias_samples_mode);
- block = Extent3D{
- .width = regs.zeta.tile_mode.block_width,
- .height = regs.zeta.tile_mode.block_height,
- .depth = regs.zeta.tile_mode.block_depth,
- };
- if (regs.zeta.tile_mode.is_pitch_linear) {
- ASSERT(regs.zeta.tile_mode.dim_control ==
- Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesArray);
- type = ImageType::Linear;
- pitch = size.width * BytesPerBlock(format);
- } else if (regs.zeta.tile_mode.dim_control ==
- Maxwell3D::Regs::TileMode::DimensionControl::DepthDefinesDepth) {
- ASSERT(regs.zeta.tile_mode.is_pitch_linear == 0);
- ASSERT(regs.zeta_size.dim_control ==
- Maxwell3D::Regs::ZetaSize::DimensionControl::ArraySizeOne);
- type = ImageType::e3D;
- size.depth = regs.zeta_size.depth;
- } else {
- ASSERT(regs.zeta_size.dim_control ==
- Maxwell3D::Regs::ZetaSize::DimensionControl::DepthDefinesArray);
- rescaleable = block.depth == 0;
- downscaleable = size.height > 512;
- type = ImageType::e2D;
- resources.layers = regs.zeta_size.depth;
- }
- }
- ImageInfo::ImageInfo(const Tegra::Engines::Fermi2D::Surface& config) noexcept {
- UNIMPLEMENTED_IF_MSG(config.layer != 0, "Surface layer is not zero");
- format = VideoCore::Surface::PixelFormatFromRenderTargetFormat(config.format);
- rescaleable = false;
- if (config.linear == Tegra::Engines::Fermi2D::MemoryLayout::Pitch) {
- type = ImageType::Linear;
- size = Extent3D{
- .width = config.pitch / VideoCore::Surface::BytesPerBlock(format),
- .height = config.height,
- .depth = 1,
- };
- pitch = config.pitch;
- } else {
- type = config.block_depth > 0 ? ImageType::e3D : ImageType::e2D;
- block = Extent3D{
- .width = config.block_width,
- .height = config.block_height,
- .depth = config.block_depth,
- };
- // 3D blits with more than once slice are not implemented for now
- // Render to individual slices
- size = Extent3D{
- .width = config.width,
- .height = config.height,
- .depth = 1,
- };
- rescaleable = block.depth == 0;
- rescaleable &= size.height > 256;
- downscaleable = size.height > 512;
- }
- }
- } // namespace VideoCommon
|