emit_spirv_image_atomic.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright 2021 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "shader_recompiler/backend/spirv/emit_spirv.h"
  5. #include "shader_recompiler/backend/spirv/emit_spirv_instructions.h"
  6. #include "shader_recompiler/frontend/ir/modifiers.h"
  7. namespace Shader::Backend::SPIRV {
  8. namespace {
  9. Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
  10. if (!index.IsImmediate()) {
  11. throw NotImplementedException("Indirect image indexing");
  12. }
  13. if (info.type == TextureType::Buffer) {
  14. const ImageBufferDefinition def{ctx.image_buffers.at(index.U32())};
  15. return def.id;
  16. } else {
  17. const ImageDefinition def{ctx.images.at(index.U32())};
  18. return def.id;
  19. }
  20. }
  21. std::pair<Id, Id> AtomicArgs(EmitContext& ctx) {
  22. const Id scope{ctx.Const(static_cast<u32>(spv::Scope::Device))};
  23. const Id semantics{ctx.u32_zero_value};
  24. return {scope, semantics};
  25. }
  26. Id ImageAtomicU32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords, Id value,
  27. Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id, Id)) {
  28. const auto info{inst->Flags<IR::TextureInstInfo>()};
  29. const Id image{Image(ctx, index, info)};
  30. const Id pointer{ctx.OpImageTexelPointer(ctx.image_u32, image, coords, ctx.Const(0U))};
  31. const auto [scope, semantics]{AtomicArgs(ctx)};
  32. return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value);
  33. }
  34. } // Anonymous namespace
  35. Id EmitImageAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  36. Id value) {
  37. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicIAdd);
  38. }
  39. Id EmitImageAtomicSMin32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  40. Id value) {
  41. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicSMin);
  42. }
  43. Id EmitImageAtomicUMin32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  44. Id value) {
  45. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicUMin);
  46. }
  47. Id EmitImageAtomicSMax32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  48. Id value) {
  49. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicSMax);
  50. }
  51. Id EmitImageAtomicUMax32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  52. Id value) {
  53. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicUMax);
  54. }
  55. Id EmitImageAtomicInc32(EmitContext&, IR::Inst*, const IR::Value&, Id, Id) {
  56. // TODO: This is not yet implemented
  57. throw NotImplementedException("SPIR-V Instruction");
  58. }
  59. Id EmitImageAtomicDec32(EmitContext&, IR::Inst*, const IR::Value&, Id, Id) {
  60. // TODO: This is not yet implemented
  61. throw NotImplementedException("SPIR-V Instruction");
  62. }
  63. Id EmitImageAtomicAnd32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  64. Id value) {
  65. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicAnd);
  66. }
  67. Id EmitImageAtomicOr32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  68. Id value) {
  69. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicOr);
  70. }
  71. Id EmitImageAtomicXor32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  72. Id value) {
  73. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicXor);
  74. }
  75. Id EmitImageAtomicExchange32(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, Id coords,
  76. Id value) {
  77. return ImageAtomicU32(ctx, inst, index, coords, value, &Sirit::Module::OpAtomicExchange);
  78. }
  79. Id EmitBindlessImageAtomicIAdd32(EmitContext&) {
  80. throw NotImplementedException("SPIR-V Instruction");
  81. }
  82. Id EmitBindlessImageAtomicSMin32(EmitContext&) {
  83. throw NotImplementedException("SPIR-V Instruction");
  84. }
  85. Id EmitBindlessImageAtomicUMin32(EmitContext&) {
  86. throw NotImplementedException("SPIR-V Instruction");
  87. }
  88. Id EmitBindlessImageAtomicSMax32(EmitContext&) {
  89. throw NotImplementedException("SPIR-V Instruction");
  90. }
  91. Id EmitBindlessImageAtomicUMax32(EmitContext&) {
  92. throw NotImplementedException("SPIR-V Instruction");
  93. }
  94. Id EmitBindlessImageAtomicInc32(EmitContext&) {
  95. throw NotImplementedException("SPIR-V Instruction");
  96. }
  97. Id EmitBindlessImageAtomicDec32(EmitContext&) {
  98. throw NotImplementedException("SPIR-V Instruction");
  99. }
  100. Id EmitBindlessImageAtomicAnd32(EmitContext&) {
  101. throw NotImplementedException("SPIR-V Instruction");
  102. }
  103. Id EmitBindlessImageAtomicOr32(EmitContext&) {
  104. throw NotImplementedException("SPIR-V Instruction");
  105. }
  106. Id EmitBindlessImageAtomicXor32(EmitContext&) {
  107. throw NotImplementedException("SPIR-V Instruction");
  108. }
  109. Id EmitBindlessImageAtomicExchange32(EmitContext&) {
  110. throw NotImplementedException("SPIR-V Instruction");
  111. }
  112. Id EmitBoundImageAtomicIAdd32(EmitContext&) {
  113. throw NotImplementedException("SPIR-V Instruction");
  114. }
  115. Id EmitBoundImageAtomicSMin32(EmitContext&) {
  116. throw NotImplementedException("SPIR-V Instruction");
  117. }
  118. Id EmitBoundImageAtomicUMin32(EmitContext&) {
  119. throw NotImplementedException("SPIR-V Instruction");
  120. }
  121. Id EmitBoundImageAtomicSMax32(EmitContext&) {
  122. throw NotImplementedException("SPIR-V Instruction");
  123. }
  124. Id EmitBoundImageAtomicUMax32(EmitContext&) {
  125. throw NotImplementedException("SPIR-V Instruction");
  126. }
  127. Id EmitBoundImageAtomicInc32(EmitContext&) {
  128. throw NotImplementedException("SPIR-V Instruction");
  129. }
  130. Id EmitBoundImageAtomicDec32(EmitContext&) {
  131. throw NotImplementedException("SPIR-V Instruction");
  132. }
  133. Id EmitBoundImageAtomicAnd32(EmitContext&) {
  134. throw NotImplementedException("SPIR-V Instruction");
  135. }
  136. Id EmitBoundImageAtomicOr32(EmitContext&) {
  137. throw NotImplementedException("SPIR-V Instruction");
  138. }
  139. Id EmitBoundImageAtomicXor32(EmitContext&) {
  140. throw NotImplementedException("SPIR-V Instruction");
  141. }
  142. Id EmitBoundImageAtomicExchange32(EmitContext&) {
  143. throw NotImplementedException("SPIR-V Instruction");
  144. }
  145. } // namespace Shader::Backend::SPIRV