texture_query.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <optional>
  4. #include "common/bit_field.h"
  5. #include "common/common_types.h"
  6. #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
  7. namespace Shader::Maxwell {
  8. namespace {
  9. enum class Mode : u64 {
  10. Dimension = 1,
  11. TextureType = 2,
  12. SamplePos = 5,
  13. };
  14. IR::Value Query(TranslatorVisitor& v, const IR::U32& handle, Mode mode, IR::Reg src_reg, u64 mask) {
  15. switch (mode) {
  16. case Mode::Dimension: {
  17. const bool needs_num_mips{((mask >> 3) & 1) != 0};
  18. const IR::U1 skip_mips{v.ir.Imm1(!needs_num_mips)};
  19. const IR::U32 lod{v.X(src_reg)};
  20. return v.ir.ImageQueryDimension(handle, lod, skip_mips);
  21. }
  22. case Mode::TextureType:
  23. case Mode::SamplePos:
  24. default:
  25. throw NotImplementedException("Mode {}", mode);
  26. }
  27. }
  28. void Impl(TranslatorVisitor& v, u64 insn, std::optional<u32> cbuf_offset) {
  29. union {
  30. u64 raw;
  31. BitField<49, 1, u64> nodep;
  32. BitField<0, 8, IR::Reg> dest_reg;
  33. BitField<8, 8, IR::Reg> src_reg;
  34. BitField<22, 3, Mode> mode;
  35. BitField<31, 4, u64> mask;
  36. } const txq{insn};
  37. IR::Reg src_reg{txq.src_reg};
  38. IR::U32 handle;
  39. if (cbuf_offset) {
  40. handle = v.ir.Imm32(*cbuf_offset);
  41. } else {
  42. handle = v.X(src_reg);
  43. ++src_reg;
  44. }
  45. const IR::Value query{Query(v, handle, txq.mode, src_reg, txq.mask)};
  46. IR::Reg dest_reg{txq.dest_reg};
  47. for (int element = 0; element < 4; ++element) {
  48. if (((txq.mask >> element) & 1) == 0) {
  49. continue;
  50. }
  51. v.X(dest_reg, IR::U32{v.ir.CompositeExtract(query, static_cast<size_t>(element))});
  52. ++dest_reg;
  53. }
  54. }
  55. } // Anonymous namespace
  56. void TranslatorVisitor::TXQ(u64 insn) {
  57. union {
  58. u64 raw;
  59. BitField<36, 13, u64> cbuf_offset;
  60. } const txq{insn};
  61. Impl(*this, insn, static_cast<u32>(txq.cbuf_offset * 4));
  62. }
  63. void TranslatorVisitor::TXQ_b(u64 insn) {
  64. Impl(*this, insn, std::nullopt);
  65. }
  66. } // namespace Shader::Maxwell