Decoration.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. //===--- Decoration.cpp - SPIR-V Decoration implementation-----------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "clang/SPIRV/Decoration.h"
  10. #include "clang/SPIRV/SPIRVContext.h"
  11. #include "clang/SPIRV/String.h"
  12. #include "llvm/llvm_assert/assert.h"
  13. namespace clang {
  14. namespace spirv {
  15. const Decoration *Decoration::getUniqueDecoration(SPIRVContext &context,
  16. const Decoration &d) {
  17. return context.registerDecoration(d);
  18. }
  19. const Decoration *Decoration::getRelaxedPrecision(SPIRVContext &context) {
  20. Decoration d = Decoration(spv::Decoration::RelaxedPrecision);
  21. return getUniqueDecoration(context, d);
  22. }
  23. const Decoration *Decoration::getSpecId(SPIRVContext &context, uint32_t id) {
  24. Decoration d = Decoration(spv::Decoration::SpecId, {id});
  25. return getUniqueDecoration(context, d);
  26. }
  27. const Decoration *Decoration::getBlock(SPIRVContext &context) {
  28. Decoration d = Decoration(spv::Decoration::Block);
  29. return getUniqueDecoration(context, d);
  30. }
  31. const Decoration *Decoration::getBufferBlock(SPIRVContext &context) {
  32. Decoration d = Decoration(spv::Decoration::BufferBlock);
  33. return getUniqueDecoration(context, d);
  34. }
  35. const Decoration *Decoration::getRowMajor(SPIRVContext &context,
  36. uint32_t member_idx) {
  37. Decoration d = Decoration(spv::Decoration::RowMajor);
  38. d.setMemberIndex(member_idx);
  39. return getUniqueDecoration(context, d);
  40. }
  41. const Decoration *Decoration::getColMajor(SPIRVContext &context,
  42. uint32_t member_idx) {
  43. Decoration d = Decoration(spv::Decoration::ColMajor);
  44. d.setMemberIndex(member_idx);
  45. return getUniqueDecoration(context, d);
  46. }
  47. const Decoration *Decoration::getArrayStride(SPIRVContext &context,
  48. uint32_t stride) {
  49. Decoration d = Decoration(spv::Decoration::ArrayStride, {stride});
  50. return getUniqueDecoration(context, d);
  51. }
  52. const Decoration *Decoration::getMatrixStride(SPIRVContext &context,
  53. uint32_t stride,
  54. uint32_t member_idx) {
  55. Decoration d = Decoration(spv::Decoration::MatrixStride, {stride});
  56. d.setMemberIndex(member_idx);
  57. return getUniqueDecoration(context, d);
  58. }
  59. const Decoration *Decoration::getGLSLShared(SPIRVContext &context) {
  60. Decoration d = Decoration(spv::Decoration::GLSLShared);
  61. return getUniqueDecoration(context, d);
  62. }
  63. const Decoration *Decoration::getGLSLPacked(SPIRVContext &context) {
  64. Decoration d = Decoration(spv::Decoration::GLSLPacked);
  65. return getUniqueDecoration(context, d);
  66. }
  67. const Decoration *Decoration::getCPacked(SPIRVContext &context) {
  68. Decoration d = Decoration(spv::Decoration::CPacked);
  69. return getUniqueDecoration(context, d);
  70. }
  71. const Decoration *Decoration::getBuiltIn(SPIRVContext &context,
  72. spv::BuiltIn builtin,
  73. llvm::Optional<uint32_t> member_idx) {
  74. Decoration d =
  75. Decoration(spv::Decoration::BuiltIn, {static_cast<uint32_t>(builtin)});
  76. d.setMemberIndex(member_idx);
  77. return getUniqueDecoration(context, d);
  78. }
  79. const Decoration *
  80. Decoration::getNoPerspective(SPIRVContext &context,
  81. llvm::Optional<uint32_t> member_idx) {
  82. Decoration d = Decoration(spv::Decoration::NoPerspective);
  83. d.setMemberIndex(member_idx);
  84. return getUniqueDecoration(context, d);
  85. }
  86. const Decoration *Decoration::getFlat(SPIRVContext &context,
  87. llvm::Optional<uint32_t> member_idx) {
  88. Decoration d = Decoration(spv::Decoration::Flat);
  89. d.setMemberIndex(member_idx);
  90. return getUniqueDecoration(context, d);
  91. }
  92. const Decoration *Decoration::getPatch(SPIRVContext &context,
  93. llvm::Optional<uint32_t> member_idx) {
  94. Decoration d = Decoration(spv::Decoration::Patch);
  95. d.setMemberIndex(member_idx);
  96. return getUniqueDecoration(context, d);
  97. }
  98. const Decoration *Decoration::getCentroid(SPIRVContext &context,
  99. llvm::Optional<uint32_t> member_idx) {
  100. Decoration d = Decoration(spv::Decoration::Centroid);
  101. d.setMemberIndex(member_idx);
  102. return getUniqueDecoration(context, d);
  103. }
  104. const Decoration *Decoration::getSample(SPIRVContext &context,
  105. llvm::Optional<uint32_t> member_idx) {
  106. Decoration d = Decoration(spv::Decoration::Sample);
  107. d.setMemberIndex(member_idx);
  108. return getUniqueDecoration(context, d);
  109. }
  110. const Decoration *Decoration::getInvariant(SPIRVContext &context) {
  111. Decoration d = Decoration(spv::Decoration::Invariant);
  112. return getUniqueDecoration(context, d);
  113. }
  114. const Decoration *Decoration::getRestrict(SPIRVContext &context) {
  115. Decoration d = Decoration(spv::Decoration::Restrict);
  116. return getUniqueDecoration(context, d);
  117. }
  118. const Decoration *Decoration::getAliased(SPIRVContext &context) {
  119. Decoration d = Decoration(spv::Decoration::Aliased);
  120. return getUniqueDecoration(context, d);
  121. }
  122. const Decoration *Decoration::getVolatile(SPIRVContext &context,
  123. llvm::Optional<uint32_t> member_idx) {
  124. Decoration d = Decoration(spv::Decoration::Volatile);
  125. d.setMemberIndex(member_idx);
  126. return getUniqueDecoration(context, d);
  127. }
  128. const Decoration *Decoration::getConstant(SPIRVContext &context) {
  129. Decoration d = Decoration(spv::Decoration::Constant);
  130. return getUniqueDecoration(context, d);
  131. }
  132. const Decoration *Decoration::getCoherent(SPIRVContext &context,
  133. llvm::Optional<uint32_t> member_idx) {
  134. Decoration d = Decoration(spv::Decoration::Coherent);
  135. d.setMemberIndex(member_idx);
  136. return getUniqueDecoration(context, d);
  137. }
  138. const Decoration *
  139. Decoration::getNonWritable(SPIRVContext &context,
  140. llvm::Optional<uint32_t> member_idx) {
  141. Decoration d = Decoration(spv::Decoration::NonWritable);
  142. d.setMemberIndex(member_idx);
  143. return getUniqueDecoration(context, d);
  144. }
  145. const Decoration *
  146. Decoration::getNonReadable(SPIRVContext &context,
  147. llvm::Optional<uint32_t> member_idx) {
  148. Decoration d = Decoration(spv::Decoration::NonReadable);
  149. d.setMemberIndex(member_idx);
  150. return getUniqueDecoration(context, d);
  151. }
  152. const Decoration *Decoration::getUniform(SPIRVContext &context,
  153. llvm::Optional<uint32_t> member_idx) {
  154. Decoration d = Decoration(spv::Decoration::Uniform);
  155. d.setMemberIndex(member_idx);
  156. return getUniqueDecoration(context, d);
  157. }
  158. const Decoration *Decoration::getSaturatedConversion(SPIRVContext &context) {
  159. Decoration d = Decoration(spv::Decoration::SaturatedConversion);
  160. return getUniqueDecoration(context, d);
  161. }
  162. const Decoration *Decoration::getStream(SPIRVContext &context,
  163. uint32_t stream_number,
  164. llvm::Optional<uint32_t> member_idx) {
  165. Decoration d = Decoration(spv::Decoration::Stream, {stream_number});
  166. d.setMemberIndex(member_idx);
  167. return getUniqueDecoration(context, d);
  168. }
  169. const Decoration *Decoration::getLocation(SPIRVContext &context,
  170. uint32_t location,
  171. llvm::Optional<uint32_t> member_idx) {
  172. Decoration d = Decoration(spv::Decoration::Location, {location});
  173. d.setMemberIndex(member_idx);
  174. return getUniqueDecoration(context, d);
  175. }
  176. const Decoration *
  177. Decoration::getComponent(SPIRVContext &context, uint32_t component,
  178. llvm::Optional<uint32_t> member_idx) {
  179. Decoration d = Decoration(spv::Decoration::Component, {component});
  180. d.setMemberIndex(member_idx);
  181. return getUniqueDecoration(context, d);
  182. }
  183. const Decoration *Decoration::getIndex(SPIRVContext &context, uint32_t index) {
  184. Decoration d = Decoration(spv::Decoration::Index, {index});
  185. return getUniqueDecoration(context, d);
  186. }
  187. const Decoration *Decoration::getBinding(SPIRVContext &context,
  188. uint32_t binding_point) {
  189. Decoration d = Decoration(spv::Decoration::Binding, {binding_point});
  190. return getUniqueDecoration(context, d);
  191. }
  192. const Decoration *Decoration::getDescriptorSet(SPIRVContext &context,
  193. uint32_t set) {
  194. Decoration d = Decoration(spv::Decoration::DescriptorSet, {set});
  195. return getUniqueDecoration(context, d);
  196. }
  197. const Decoration *Decoration::getOffset(SPIRVContext &context,
  198. uint32_t byte_offset,
  199. uint32_t member_idx) {
  200. Decoration d = Decoration(spv::Decoration::Offset, {byte_offset});
  201. d.setMemberIndex(member_idx);
  202. return getUniqueDecoration(context, d);
  203. }
  204. const Decoration *
  205. Decoration::getXfbBuffer(SPIRVContext &context, uint32_t xfb_buf,
  206. llvm::Optional<uint32_t> member_idx) {
  207. Decoration d = Decoration(spv::Decoration::XfbBuffer, {xfb_buf});
  208. d.setMemberIndex(member_idx);
  209. return getUniqueDecoration(context, d);
  210. }
  211. const Decoration *
  212. Decoration::getXfbStride(SPIRVContext &context, uint32_t xfb_stride,
  213. llvm::Optional<uint32_t> member_idx) {
  214. Decoration d = Decoration(spv::Decoration::XfbStride, {xfb_stride});
  215. d.setMemberIndex(member_idx);
  216. return getUniqueDecoration(context, d);
  217. }
  218. const Decoration *
  219. Decoration::getFuncParamAttr(SPIRVContext &context,
  220. spv::FunctionParameterAttribute attr) {
  221. Decoration d =
  222. Decoration(spv::Decoration::FuncParamAttr, {static_cast<uint32_t>(attr)});
  223. return getUniqueDecoration(context, d);
  224. }
  225. const Decoration *Decoration::getFPRoundingMode(SPIRVContext &context,
  226. spv::FPRoundingMode mode) {
  227. Decoration d = Decoration(spv::Decoration::FPRoundingMode,
  228. {static_cast<uint32_t>(mode)});
  229. return getUniqueDecoration(context, d);
  230. }
  231. const Decoration *Decoration::getFPFastMathMode(SPIRVContext &context,
  232. spv::FPFastMathModeShift mode) {
  233. Decoration d = Decoration(spv::Decoration::FPFastMathMode,
  234. {static_cast<uint32_t>(mode)});
  235. return getUniqueDecoration(context, d);
  236. }
  237. const Decoration *
  238. Decoration::getLinkageAttributes(SPIRVContext &context, std::string name,
  239. spv::LinkageType linkage_type) {
  240. llvm::SmallVector<uint32_t, 2> args;
  241. const auto &vec = string::encodeSPIRVString(name);
  242. args.insert(args.end(), vec.begin(), vec.end());
  243. args.push_back(static_cast<uint32_t>(linkage_type));
  244. Decoration d = Decoration(spv::Decoration::LinkageAttributes, args);
  245. return getUniqueDecoration(context, d);
  246. }
  247. const Decoration *Decoration::getNoContraction(SPIRVContext &context) {
  248. Decoration d = Decoration(spv::Decoration::NoContraction);
  249. return getUniqueDecoration(context, d);
  250. }
  251. const Decoration *Decoration::getInputAttachmentIndex(SPIRVContext &context,
  252. uint32_t index) {
  253. Decoration d = Decoration(spv::Decoration::InputAttachmentIndex, {index});
  254. return getUniqueDecoration(context, d);
  255. }
  256. const Decoration *Decoration::getAlignment(SPIRVContext &context,
  257. uint32_t alignment) {
  258. Decoration d = Decoration(spv::Decoration::Alignment, {alignment});
  259. return getUniqueDecoration(context, d);
  260. }
  261. const Decoration *Decoration::getOverrideCoverageNV(SPIRVContext &context) {
  262. Decoration d = Decoration(spv::Decoration::OverrideCoverageNV);
  263. return getUniqueDecoration(context, d);
  264. }
  265. const Decoration *Decoration::getPassthroughNV(SPIRVContext &context) {
  266. Decoration d = Decoration(spv::Decoration::PassthroughNV);
  267. return getUniqueDecoration(context, d);
  268. }
  269. const Decoration *Decoration::getViewportRelativeNV(SPIRVContext &context) {
  270. Decoration d = Decoration(spv::Decoration::ViewportRelativeNV);
  271. return getUniqueDecoration(context, d);
  272. }
  273. const Decoration *
  274. Decoration::getSecondaryViewportRelativeNV(SPIRVContext &context,
  275. uint32_t offset) {
  276. Decoration d = Decoration(spv::Decoration::SecondaryViewportRelativeNV);
  277. return getUniqueDecoration(context, d);
  278. }
  279. const Decoration *Decoration::getHlslCounterBufferGOOGLE(SPIRVContext &context,
  280. uint32_t id) {
  281. Decoration d = Decoration(spv::Decoration::HlslCounterBufferGOOGLE, {id});
  282. return getUniqueDecoration(context, d);
  283. }
  284. const Decoration *
  285. Decoration::getHlslSemanticGOOGLE(SPIRVContext &context,
  286. llvm::StringRef semantic,
  287. llvm ::Optional<uint32_t> member_idx) {
  288. Decoration d = Decoration(spv::Decoration::HlslSemanticGOOGLE,
  289. string::encodeSPIRVString(semantic));
  290. d.setMemberIndex(member_idx);
  291. return getUniqueDecoration(context, d);
  292. }
  293. std::vector<uint32_t> Decoration::withTargetId(uint32_t targetId) const {
  294. std::vector<uint32_t> words;
  295. // TODO: we are essentially duplicate the work InstBuilder is responsible for.
  296. // Should figure out a way to unify them.
  297. words.reserve(3 + args.size() + (memberIndex.hasValue() ? 1 : 0));
  298. words.push_back(static_cast<uint32_t>(getDecorateOpcode(id, memberIndex)));
  299. words.push_back(targetId);
  300. if (memberIndex.hasValue())
  301. words.push_back(*memberIndex);
  302. words.push_back(static_cast<uint32_t>(id));
  303. words.insert(words.end(), args.begin(), args.end());
  304. words.front() |= static_cast<uint32_t>(words.size()) << 16;
  305. return words;
  306. }
  307. spv::Op
  308. Decoration::getDecorateOpcode(spv::Decoration decoration,
  309. const llvm::Optional<uint32_t> &memberIndex) {
  310. if (decoration == spv::Decoration::HlslCounterBufferGOOGLE)
  311. return spv::Op::OpDecorateId;
  312. if (decoration == spv::Decoration::HlslSemanticGOOGLE)
  313. return memberIndex.hasValue() ? spv::Op::OpMemberDecorateStringGOOGLE
  314. : spv::Op::OpDecorateStringGOOGLE;
  315. return memberIndex.hasValue() ? spv::Op::OpMemberDecorate
  316. : spv::Op::OpDecorate;
  317. }
  318. } // end namespace spirv
  319. } // end namespace clang