accelerated_swizzle.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <array>
  4. #include <bit>
  5. #include "common/alignment.h"
  6. #include "common/common_types.h"
  7. #include "common/div_ceil.h"
  8. #include "video_core/surface.h"
  9. #include "video_core/texture_cache/accelerated_swizzle.h"
  10. #include "video_core/texture_cache/util.h"
  11. #include "video_core/textures/decoders.h"
  12. namespace VideoCommon::Accelerated {
  13. using Tegra::Texture::GOB_SIZE_SHIFT;
  14. using Tegra::Texture::GOB_SIZE_X;
  15. using Tegra::Texture::GOB_SIZE_X_SHIFT;
  16. using Tegra::Texture::GOB_SIZE_Y_SHIFT;
  17. using VideoCore::Surface::BytesPerBlock;
  18. BlockLinearSwizzle2DParams MakeBlockLinearSwizzle2DParams(const SwizzleParameters& swizzle,
  19. const ImageInfo& info) {
  20. const Extent3D block = swizzle.block;
  21. const Extent3D num_tiles = swizzle.num_tiles;
  22. const u32 bytes_per_block = BytesPerBlock(info.format);
  23. const u32 stride_alignment = CalculateLevelStrideAlignment(info, swizzle.level);
  24. const u32 stride = Common::AlignUpLog2(num_tiles.width, stride_alignment) * bytes_per_block;
  25. const u32 gobs_in_x = Common::DivCeilLog2(stride, GOB_SIZE_X_SHIFT);
  26. return BlockLinearSwizzle2DParams{
  27. .origin{0, 0, 0},
  28. .destination{0, 0, 0},
  29. .bytes_per_block_log2 = static_cast<u32>(std::countr_zero(bytes_per_block)),
  30. .layer_stride = info.layer_stride,
  31. .block_size = gobs_in_x << (GOB_SIZE_SHIFT + block.height + block.depth),
  32. .x_shift = GOB_SIZE_SHIFT + block.height + block.depth,
  33. .block_height = block.height,
  34. .block_height_mask = (1U << block.height) - 1,
  35. };
  36. }
  37. BlockLinearSwizzle3DParams MakeBlockLinearSwizzle3DParams(const SwizzleParameters& swizzle,
  38. const ImageInfo& info) {
  39. const Extent3D block = swizzle.block;
  40. const Extent3D num_tiles = swizzle.num_tiles;
  41. const u32 bytes_per_block = BytesPerBlock(info.format);
  42. const u32 stride_alignment = CalculateLevelStrideAlignment(info, swizzle.level);
  43. const u32 stride = Common::AlignUpLog2(num_tiles.width, stride_alignment) * bytes_per_block;
  44. const u32 gobs_in_x = (stride + GOB_SIZE_X - 1) >> GOB_SIZE_X_SHIFT;
  45. const u32 block_size = gobs_in_x << (GOB_SIZE_SHIFT + block.height + block.depth);
  46. const u32 slice_size =
  47. Common::DivCeilLog2(num_tiles.height, block.height + GOB_SIZE_Y_SHIFT) * block_size;
  48. return BlockLinearSwizzle3DParams{
  49. .origin{0, 0, 0},
  50. .destination{0, 0, 0},
  51. .bytes_per_block_log2 = static_cast<u32>(std::countr_zero(bytes_per_block)),
  52. .slice_size = slice_size,
  53. .block_size = block_size,
  54. .x_shift = GOB_SIZE_SHIFT + block.height + block.depth,
  55. .block_height = block.height,
  56. .block_height_mask = (1U << block.height) - 1,
  57. .block_depth = block.depth,
  58. .block_depth_mask = (1U << block.depth) - 1,
  59. };
  60. }
  61. } // namespace VideoCommon::Accelerated