texture_mipmap_level.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <optional>
  5. #include "common/bit_field.h"
  6. #include "common/common_types.h"
  7. #include "shader_recompiler/frontend/ir/modifiers.h"
  8. #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
  9. namespace Shader::Maxwell {
  10. namespace {
  11. enum class TextureType : u64 {
  12. _1D,
  13. ARRAY_1D,
  14. _2D,
  15. ARRAY_2D,
  16. _3D,
  17. ARRAY_3D,
  18. CUBE,
  19. ARRAY_CUBE,
  20. };
  21. Shader::TextureType GetType(TextureType type, bool dc) {
  22. switch (type) {
  23. case TextureType::_1D:
  24. return dc ? Shader::TextureType::Shadow1D : Shader::TextureType::Color1D;
  25. case TextureType::ARRAY_1D:
  26. return dc ? Shader::TextureType::ShadowArray1D : Shader::TextureType::ColorArray1D;
  27. case TextureType::_2D:
  28. return dc ? Shader::TextureType::Shadow2D : Shader::TextureType::Color2D;
  29. case TextureType::ARRAY_2D:
  30. return dc ? Shader::TextureType::ShadowArray2D : Shader::TextureType::ColorArray2D;
  31. case TextureType::_3D:
  32. return dc ? Shader::TextureType::Shadow3D : Shader::TextureType::Color3D;
  33. case TextureType::ARRAY_3D:
  34. throw NotImplementedException("3D array texture type");
  35. case TextureType::CUBE:
  36. return dc ? Shader::TextureType::ShadowCube : Shader::TextureType::ColorCube;
  37. case TextureType::ARRAY_CUBE:
  38. return dc ? Shader::TextureType::ShadowArrayCube : Shader::TextureType::ColorArrayCube;
  39. }
  40. throw NotImplementedException("Invalid texture type {}", type);
  41. }
  42. IR::Value MakeCoords(TranslatorVisitor& v, IR::Reg reg, TextureType type) {
  43. const auto read_array{[&]() -> IR::F32 { return v.ir.ConvertUToF(32, 16, v.X(reg)); }};
  44. switch (type) {
  45. case TextureType::_1D:
  46. return v.F(reg);
  47. case TextureType::ARRAY_1D:
  48. return v.ir.CompositeConstruct(v.F(reg + 1), read_array());
  49. case TextureType::_2D:
  50. return v.ir.CompositeConstruct(v.F(reg), v.F(reg + 1));
  51. case TextureType::ARRAY_2D:
  52. return v.ir.CompositeConstruct(v.F(reg + 1), v.F(reg + 2), read_array());
  53. case TextureType::_3D:
  54. return v.ir.CompositeConstruct(v.F(reg), v.F(reg + 1), v.F(reg + 2));
  55. case TextureType::ARRAY_3D:
  56. throw NotImplementedException("3D array texture type");
  57. case TextureType::CUBE:
  58. return v.ir.CompositeConstruct(v.F(reg), v.F(reg + 1), v.F(reg + 2));
  59. case TextureType::ARRAY_CUBE:
  60. return v.ir.CompositeConstruct(v.F(reg + 1), v.F(reg + 2), v.F(reg + 3), read_array());
  61. }
  62. throw NotImplementedException("Invalid texture type {}", type);
  63. }
  64. void Impl(TranslatorVisitor& v, u64 insn, bool is_bindless) {
  65. union {
  66. u64 raw;
  67. BitField<49, 1, u64> nodep;
  68. BitField<35, 1, u64> ndv;
  69. BitField<0, 8, IR::Reg> dest_reg;
  70. BitField<8, 8, IR::Reg> coord_reg;
  71. BitField<20, 8, IR::Reg> meta_reg;
  72. BitField<28, 3, TextureType> type;
  73. BitField<31, 4, u64> mask;
  74. BitField<36, 13, u64> cbuf_offset;
  75. } const tmml{insn};
  76. if ((tmml.mask & 0b1100) != 0) {
  77. throw NotImplementedException("TMML BA results are not implmented");
  78. }
  79. IR::F32 transform_constant{v.ir.Imm32(256.0f)};
  80. const IR::Value coords{MakeCoords(v, tmml.coord_reg, tmml.type)};
  81. IR::U32 handle;
  82. IR::Reg meta_reg{tmml.meta_reg};
  83. if (is_bindless) {
  84. handle = v.X(meta_reg++);
  85. } else {
  86. handle = v.ir.Imm32(static_cast<u32>(tmml.cbuf_offset.Value() * 4));
  87. }
  88. IR::TextureInstInfo info{};
  89. info.type.Assign(GetType(tmml.type, false));
  90. const IR::Value sample{v.ir.ImageQueryLod(handle, coords, info)};
  91. IR::Reg dest_reg{tmml.dest_reg};
  92. for (size_t element = 0; element < 4; ++element) {
  93. if (((tmml.mask >> element) & 1) == 0) {
  94. continue;
  95. }
  96. IR::F32 value{v.ir.CompositeExtract(sample, element)};
  97. if (element < 2) {
  98. value = v.ir.FPMul(value, transform_constant);
  99. }
  100. v.F(dest_reg, value);
  101. ++dest_reg;
  102. }
  103. }
  104. } // Anonymous namespace
  105. void TranslatorVisitor::TMML(u64 insn) {
  106. Impl(*this, insn, false);
  107. }
  108. void TranslatorVisitor::TMML_b(u64 insn) {
  109. Impl(*this, insn, true);
  110. }
  111. } // namespace Shader::Maxwell