accelerated_swizzle.cpp 3.0 KB

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