opcode_selector.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. // Copyright (c) 2024 Google LLC
  2. //
  3. // This file is licensed under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. #ifndef _HLSL_VK_KHR_OPCODE_SELECTOR_H_
  7. #define _HLSL_VK_KHR_OPCODE_SELECTOR_H_
  8. #define DECLARE_UNARY_OP(name, opcode) \
  9. template <typename ResultType> \
  10. [[vk::ext_instruction(opcode)]] ResultType __builtin_spv_##name( \
  11. ResultType a)
  12. DECLARE_UNARY_OP(CopyObject, 83);
  13. DECLARE_UNARY_OP(SNegate, 126);
  14. DECLARE_UNARY_OP(FNegate, 127);
  15. #define DECLARE_CONVERSION_OP(name, opcode) \
  16. template <typename ResultType, typename OperandType> \
  17. [[vk::ext_instruction(opcode)]] ResultType __builtin_spv_##name( \
  18. OperandType a)
  19. DECLARE_CONVERSION_OP(ConvertFtoU, 109);
  20. DECLARE_CONVERSION_OP(ConvertFtoS, 110);
  21. DECLARE_CONVERSION_OP(ConvertSToF, 111);
  22. DECLARE_CONVERSION_OP(ConvertUToF, 112);
  23. DECLARE_CONVERSION_OP(UConvert, 113);
  24. DECLARE_CONVERSION_OP(SConvert, 114);
  25. DECLARE_CONVERSION_OP(FConvert, 115);
  26. DECLARE_CONVERSION_OP(Bitcast, 124);
  27. #undef DECLARY_UNARY_OP
  28. #define DECLARE_BINOP(name, opcode) \
  29. template <typename ResultType> \
  30. [[vk::ext_instruction(opcode)]] ResultType __builtin_spv_##name( \
  31. ResultType a, ResultType b)
  32. DECLARE_BINOP(IAdd, 128);
  33. DECLARE_BINOP(FAdd, 129);
  34. DECLARE_BINOP(ISub, 130);
  35. DECLARE_BINOP(FSub, 131);
  36. DECLARE_BINOP(IMul, 132);
  37. DECLARE_BINOP(FMul, 133);
  38. DECLARE_BINOP(UDiv, 134);
  39. DECLARE_BINOP(SDiv, 135);
  40. DECLARE_BINOP(FDiv, 136);
  41. #undef DECLARE_BINOP
  42. namespace vk {
  43. namespace util {
  44. template <class ComponentType> class ArithmeticSelector;
  45. #define ARITHMETIC_SELECTOR(BaseType, OpNegate, OpAdd, OpSub, OpMul, OpDiv, \
  46. SIGNED_INTEGER_TYPE) \
  47. template <> class ArithmeticSelector<BaseType> { \
  48. template <class T> static T Negate(T a) { return OpNegate(a); } \
  49. template <class T> static T Add(T a, T b) { return OpAdd(a, b); } \
  50. template <class T> static T Sub(T a, T b) { return OpSub(a, b); } \
  51. template <class T> static T Mul(T a, T b) { return OpMul(a, b); } \
  52. template <class T> static T Div(T a, T b) { return OpDiv(a, b); } \
  53. };
  54. ARITHMETIC_SELECTOR(half, __builtin_spv_FNegate, __builtin_spv_FAdd,
  55. __builtin_spv_FSub, __builtin_spv_FMul, __builtin_spv_FDiv,
  56. false);
  57. ARITHMETIC_SELECTOR(float, __builtin_spv_FNegate, __builtin_spv_FAdd,
  58. __builtin_spv_FSub, __builtin_spv_FMul, __builtin_spv_FDiv,
  59. false);
  60. ARITHMETIC_SELECTOR(double, __builtin_spv_FNegate, __builtin_spv_FAdd,
  61. __builtin_spv_FSub, __builtin_spv_FMul, __builtin_spv_FDiv,
  62. false);
  63. #if __HLSL_ENABLE_16_BIT
  64. ARITHMETIC_SELECTOR(int16_t, __builtin_spv_SNegate, __builtin_spv_IAdd,
  65. __builtin_spv_ISub, __builtin_spv_IMul, __builtin_spv_SDiv,
  66. true);
  67. ARITHMETIC_SELECTOR(uint16_t, __builtin_spv_SNegate, __builtin_spv_IAdd,
  68. __builtin_spv_ISub, __builtin_spv_IMul, __builtin_spv_UDiv,
  69. false);
  70. #endif // __HLSL_ENABLE_16_BIT
  71. ARITHMETIC_SELECTOR(int32_t, __builtin_spv_SNegate, __builtin_spv_IAdd,
  72. __builtin_spv_ISub, __builtin_spv_IMul, __builtin_spv_SDiv,
  73. true);
  74. ARITHMETIC_SELECTOR(int64_t, __builtin_spv_SNegate, __builtin_spv_IAdd,
  75. __builtin_spv_ISub, __builtin_spv_IMul, __builtin_spv_SDiv,
  76. true);
  77. ARITHMETIC_SELECTOR(uint32_t, __builtin_spv_SNegate, __builtin_spv_IAdd,
  78. __builtin_spv_ISub, __builtin_spv_IMul, __builtin_spv_UDiv,
  79. false);
  80. ARITHMETIC_SELECTOR(uint64_t, __builtin_spv_SNegate, __builtin_spv_IAdd,
  81. __builtin_spv_ISub, __builtin_spv_IMul, __builtin_spv_UDiv,
  82. false);
  83. // The conversion selector is will be used to convert one type to another
  84. // using the SPIR-V conversion instructions. See
  85. // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_conversion_instructions.
  86. // SourceType and TargetType must be integer or floating point scalar type.
  87. // ConversionSelector::Convert converts an object of type S to an object of type
  88. // T. S must be SourceType, a vector of SourceType, or a cooperative matrix of
  89. // SourceType. T must be TargetType, a vector of TargetType, or a cooperative
  90. // matrix of TargetType. T must have the same number of components as S. T is a
  91. // cooperative matrix if and only if S is a cooperative matrix.
  92. template <class SourceType, class TargetType> class ConversionSelector;
  93. #define CONVERSION_SELECTOR(SourceType, TargetType, OpConvert) \
  94. template <> class ConversionSelector<SourceType, TargetType> { \
  95. template <class T, class S> static T Convert(S a) { \
  96. return OpConvert<T>(a); \
  97. } \
  98. };
  99. #if __HLSL_ENABLE_16_BIT
  100. CONVERSION_SELECTOR(uint16_t, uint16_t, __builtin_spv_CopyObject);
  101. CONVERSION_SELECTOR(uint16_t, int16_t, __builtin_spv_Bitcast);
  102. CONVERSION_SELECTOR(uint16_t, uint32_t, __builtin_spv_UConvert);
  103. CONVERSION_SELECTOR(uint16_t, int32_t, __builtin_spv_SConvert);
  104. CONVERSION_SELECTOR(uint16_t, uint64_t, __builtin_spv_UConvert);
  105. CONVERSION_SELECTOR(uint16_t, int64_t, __builtin_spv_SConvert);
  106. CONVERSION_SELECTOR(uint16_t, half, __builtin_spv_ConvertUToF);
  107. CONVERSION_SELECTOR(uint16_t, float, __builtin_spv_ConvertUToF);
  108. CONVERSION_SELECTOR(uint16_t, double, __builtin_spv_ConvertUToF);
  109. CONVERSION_SELECTOR(int16_t, uint16_t, __builtin_spv_Bitcast);
  110. CONVERSION_SELECTOR(int16_t, int16_t, __builtin_spv_CopyObject);
  111. CONVERSION_SELECTOR(int16_t, uint32_t, __builtin_spv_UConvert);
  112. CONVERSION_SELECTOR(int16_t, int32_t, __builtin_spv_SConvert);
  113. CONVERSION_SELECTOR(int16_t, uint64_t, __builtin_spv_UConvert);
  114. CONVERSION_SELECTOR(int16_t, int64_t, __builtin_spv_SConvert);
  115. CONVERSION_SELECTOR(int16_t, half, __builtin_spv_ConvertSToF);
  116. CONVERSION_SELECTOR(int16_t, float, __builtin_spv_ConvertSToF);
  117. CONVERSION_SELECTOR(int16_t, double, __builtin_spv_ConvertSToF);
  118. CONVERSION_SELECTOR(uint32_t, uint16_t, __builtin_spv_UConvert);
  119. CONVERSION_SELECTOR(uint32_t, int16_t, __builtin_spv_SConvert);
  120. CONVERSION_SELECTOR(int32_t, uint16_t, __builtin_spv_UConvert);
  121. CONVERSION_SELECTOR(int32_t, int16_t, __builtin_spv_SConvert);
  122. CONVERSION_SELECTOR(uint64_t, uint16_t, __builtin_spv_UConvert);
  123. CONVERSION_SELECTOR(uint64_t, int16_t, __builtin_spv_SConvert);
  124. CONVERSION_SELECTOR(int64_t, uint16_t, __builtin_spv_UConvert);
  125. CONVERSION_SELECTOR(int64_t, int16_t, __builtin_spv_SConvert);
  126. CONVERSION_SELECTOR(half, uint16_t, __builtin_spv_ConvertFtoU);
  127. CONVERSION_SELECTOR(half, int16_t, __builtin_spv_ConvertFtoS);
  128. CONVERSION_SELECTOR(float, uint16_t, __builtin_spv_ConvertFtoU);
  129. CONVERSION_SELECTOR(float, int16_t, __builtin_spv_ConvertFtoS);
  130. CONVERSION_SELECTOR(double, uint16_t, __builtin_spv_ConvertFtoU);
  131. CONVERSION_SELECTOR(double, int16_t, __builtin_spv_ConvertFtoS);
  132. #endif
  133. CONVERSION_SELECTOR(uint32_t, uint32_t, __builtin_spv_CopyObject);
  134. CONVERSION_SELECTOR(uint32_t, int32_t, __builtin_spv_Bitcast);
  135. CONVERSION_SELECTOR(uint32_t, uint64_t, __builtin_spv_UConvert);
  136. CONVERSION_SELECTOR(uint32_t, int64_t, __builtin_spv_SConvert);
  137. CONVERSION_SELECTOR(uint32_t, half, __builtin_spv_ConvertUToF);
  138. CONVERSION_SELECTOR(uint32_t, float, __builtin_spv_ConvertUToF);
  139. CONVERSION_SELECTOR(uint32_t, double, __builtin_spv_ConvertUToF);
  140. CONVERSION_SELECTOR(int32_t, uint32_t, __builtin_spv_Bitcast);
  141. CONVERSION_SELECTOR(int32_t, int32_t, __builtin_spv_CopyObject);
  142. CONVERSION_SELECTOR(int32_t, uint64_t, __builtin_spv_UConvert);
  143. CONVERSION_SELECTOR(int32_t, int64_t, __builtin_spv_SConvert);
  144. CONVERSION_SELECTOR(int32_t, half, __builtin_spv_ConvertSToF);
  145. CONVERSION_SELECTOR(int32_t, float, __builtin_spv_ConvertSToF);
  146. CONVERSION_SELECTOR(int32_t, double, __builtin_spv_ConvertSToF);
  147. CONVERSION_SELECTOR(uint64_t, uint32_t, __builtin_spv_UConvert);
  148. CONVERSION_SELECTOR(uint64_t, int32_t, __builtin_spv_SConvert);
  149. CONVERSION_SELECTOR(uint64_t, uint64_t, __builtin_spv_Bitcast);
  150. CONVERSION_SELECTOR(uint64_t, int64_t, __builtin_spv_CopyObject);
  151. CONVERSION_SELECTOR(uint64_t, half, __builtin_spv_ConvertUToF);
  152. CONVERSION_SELECTOR(uint64_t, float, __builtin_spv_ConvertUToF);
  153. CONVERSION_SELECTOR(uint64_t, double, __builtin_spv_ConvertUToF);
  154. CONVERSION_SELECTOR(int64_t, uint32_t, __builtin_spv_UConvert);
  155. CONVERSION_SELECTOR(int64_t, int32_t, __builtin_spv_SConvert);
  156. CONVERSION_SELECTOR(int64_t, uint64_t, __builtin_spv_Bitcast);
  157. CONVERSION_SELECTOR(int64_t, int64_t, __builtin_spv_CopyObject);
  158. CONVERSION_SELECTOR(int64_t, half, __builtin_spv_ConvertSToF);
  159. CONVERSION_SELECTOR(int64_t, float, __builtin_spv_ConvertSToF);
  160. CONVERSION_SELECTOR(int64_t, double, __builtin_spv_ConvertSToF);
  161. CONVERSION_SELECTOR(half, uint32_t, __builtin_spv_ConvertFtoU);
  162. CONVERSION_SELECTOR(half, int32_t, __builtin_spv_ConvertFtoS);
  163. CONVERSION_SELECTOR(half, uint64_t, __builtin_spv_ConvertFtoU);
  164. CONVERSION_SELECTOR(half, int64_t, __builtin_spv_ConvertFtoS);
  165. CONVERSION_SELECTOR(half, half, __builtin_spv_CopyObject);
  166. #if __HLSL_ENABLE_16_BIT
  167. CONVERSION_SELECTOR(half, float, __builtin_spv_FConvert);
  168. #else
  169. CONVERSION_SELECTOR(half, float, __builtin_spv_CopyObject);
  170. #endif
  171. CONVERSION_SELECTOR(half, double, __builtin_spv_FConvert);
  172. CONVERSION_SELECTOR(float, uint32_t, __builtin_spv_ConvertFtoU);
  173. CONVERSION_SELECTOR(float, int32_t, __builtin_spv_ConvertFtoS);
  174. CONVERSION_SELECTOR(float, uint64_t, __builtin_spv_ConvertFtoU);
  175. CONVERSION_SELECTOR(float, int64_t, __builtin_spv_ConvertFtoS);
  176. #if __HLSL_ENABLE_16_BIT
  177. CONVERSION_SELECTOR(float, half, __builtin_spv_FConvert);
  178. #else
  179. CONVERSION_SELECTOR(float, half, __builtin_spv_CopyObject);
  180. #endif
  181. CONVERSION_SELECTOR(float, float, __builtin_spv_CopyObject);
  182. CONVERSION_SELECTOR(float, double, __builtin_spv_FConvert);
  183. CONVERSION_SELECTOR(double, uint32_t, __builtin_spv_ConvertFtoU);
  184. CONVERSION_SELECTOR(double, int32_t, __builtin_spv_ConvertFtoS);
  185. CONVERSION_SELECTOR(double, uint64_t, __builtin_spv_ConvertFtoU);
  186. CONVERSION_SELECTOR(double, int64_t, __builtin_spv_ConvertFtoS);
  187. CONVERSION_SELECTOR(double, half, __builtin_spv_FConvert);
  188. CONVERSION_SELECTOR(double, float, __builtin_spv_FConvert);
  189. CONVERSION_SELECTOR(double, double, __builtin_spv_CopyObject);
  190. }; // namespace util
  191. } // namespace vk
  192. #endif // _HLSL_VK_KHR_OPCODE_SELECTOR_H_