emit_spirv_convert.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  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_instructions.h"
  5. #include "shader_recompiler/backend/spirv/spirv_emit_context.h"
  6. namespace Shader::Backend::SPIRV {
  7. namespace {
  8. Id ExtractU16(EmitContext& ctx, Id value) {
  9. if (ctx.profile.support_int16) {
  10. return ctx.OpUConvert(ctx.U16, value);
  11. } else {
  12. return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u));
  13. }
  14. }
  15. Id ExtractS16(EmitContext& ctx, Id value) {
  16. if (ctx.profile.support_int16) {
  17. return ctx.OpSConvert(ctx.S16, value);
  18. } else {
  19. return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(16u));
  20. }
  21. }
  22. Id ExtractU8(EmitContext& ctx, Id value) {
  23. if (ctx.profile.support_int8) {
  24. return ctx.OpUConvert(ctx.U8, value);
  25. } else {
  26. return ctx.OpBitFieldUExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u));
  27. }
  28. }
  29. Id ExtractS8(EmitContext& ctx, Id value) {
  30. if (ctx.profile.support_int8) {
  31. return ctx.OpSConvert(ctx.S8, value);
  32. } else {
  33. return ctx.OpBitFieldSExtract(ctx.U32[1], value, ctx.u32_zero_value, ctx.Const(8u));
  34. }
  35. }
  36. } // Anonymous namespace
  37. Id EmitConvertS16F16(EmitContext& ctx, Id value) {
  38. if (ctx.profile.support_int16) {
  39. return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value));
  40. } else {
  41. return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value));
  42. }
  43. }
  44. Id EmitConvertS16F32(EmitContext& ctx, Id value) {
  45. if (ctx.profile.support_int16) {
  46. return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value));
  47. } else {
  48. return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value));
  49. }
  50. }
  51. Id EmitConvertS16F64(EmitContext& ctx, Id value) {
  52. if (ctx.profile.support_int16) {
  53. return ctx.OpSConvert(ctx.U32[1], ctx.OpConvertFToS(ctx.U16, value));
  54. } else {
  55. return ExtractS16(ctx, ctx.OpConvertFToS(ctx.U32[1], value));
  56. }
  57. }
  58. Id EmitConvertS32F16(EmitContext& ctx, Id value) {
  59. return ctx.OpConvertFToS(ctx.U32[1], value);
  60. }
  61. Id EmitConvertS32F32(EmitContext& ctx, Id value) {
  62. if (ctx.profile.has_broken_signed_operations) {
  63. return ctx.OpBitcast(ctx.U32[1], ctx.OpConvertFToS(ctx.S32[1], value));
  64. } else {
  65. return ctx.OpConvertFToS(ctx.U32[1], value);
  66. }
  67. }
  68. Id EmitConvertS32F64(EmitContext& ctx, Id value) {
  69. return ctx.OpConvertFToS(ctx.U32[1], value);
  70. }
  71. Id EmitConvertS64F16(EmitContext& ctx, Id value) {
  72. return ctx.OpConvertFToS(ctx.U64, value);
  73. }
  74. Id EmitConvertS64F32(EmitContext& ctx, Id value) {
  75. return ctx.OpConvertFToS(ctx.U64, value);
  76. }
  77. Id EmitConvertS64F64(EmitContext& ctx, Id value) {
  78. return ctx.OpConvertFToS(ctx.U64, value);
  79. }
  80. Id EmitConvertU16F16(EmitContext& ctx, Id value) {
  81. if (ctx.profile.support_int16) {
  82. return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value));
  83. } else {
  84. return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value));
  85. }
  86. }
  87. Id EmitConvertU16F32(EmitContext& ctx, Id value) {
  88. if (ctx.profile.support_int16) {
  89. return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value));
  90. } else {
  91. return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value));
  92. }
  93. }
  94. Id EmitConvertU16F64(EmitContext& ctx, Id value) {
  95. if (ctx.profile.support_int16) {
  96. return ctx.OpUConvert(ctx.U32[1], ctx.OpConvertFToU(ctx.U16, value));
  97. } else {
  98. return ExtractU16(ctx, ctx.OpConvertFToU(ctx.U32[1], value));
  99. }
  100. }
  101. Id EmitConvertU32F16(EmitContext& ctx, Id value) {
  102. return ctx.OpConvertFToU(ctx.U32[1], value);
  103. }
  104. Id EmitConvertU32F32(EmitContext& ctx, Id value) {
  105. return ctx.OpConvertFToU(ctx.U32[1], value);
  106. }
  107. Id EmitConvertU32F64(EmitContext& ctx, Id value) {
  108. return ctx.OpConvertFToU(ctx.U32[1], value);
  109. }
  110. Id EmitConvertU64F16(EmitContext& ctx, Id value) {
  111. return ctx.OpConvertFToU(ctx.U64, value);
  112. }
  113. Id EmitConvertU64F32(EmitContext& ctx, Id value) {
  114. return ctx.OpConvertFToU(ctx.U64, value);
  115. }
  116. Id EmitConvertU64F64(EmitContext& ctx, Id value) {
  117. return ctx.OpConvertFToU(ctx.U64, value);
  118. }
  119. Id EmitConvertU64U32(EmitContext& ctx, Id value) {
  120. return ctx.OpUConvert(ctx.U64, value);
  121. }
  122. Id EmitConvertU32U64(EmitContext& ctx, Id value) {
  123. return ctx.OpUConvert(ctx.U32[1], value);
  124. }
  125. Id EmitConvertF16F32(EmitContext& ctx, Id value) {
  126. return ctx.OpFConvert(ctx.F16[1], value);
  127. }
  128. Id EmitConvertF32F16(EmitContext& ctx, Id value) {
  129. return ctx.OpFConvert(ctx.F32[1], value);
  130. }
  131. Id EmitConvertF32F64(EmitContext& ctx, Id value) {
  132. return ctx.OpFConvert(ctx.F32[1], value);
  133. }
  134. Id EmitConvertF64F32(EmitContext& ctx, Id value) {
  135. return ctx.OpFConvert(ctx.F64[1], value);
  136. }
  137. Id EmitConvertF16S8(EmitContext& ctx, Id value) {
  138. return ctx.OpConvertSToF(ctx.F16[1], ExtractS8(ctx, value));
  139. }
  140. Id EmitConvertF16S16(EmitContext& ctx, Id value) {
  141. return ctx.OpConvertSToF(ctx.F16[1], ExtractS16(ctx, value));
  142. }
  143. Id EmitConvertF16S32(EmitContext& ctx, Id value) {
  144. return ctx.OpConvertSToF(ctx.F16[1], value);
  145. }
  146. Id EmitConvertF16S64(EmitContext& ctx, Id value) {
  147. return ctx.OpConvertSToF(ctx.F16[1], value);
  148. }
  149. Id EmitConvertF16U8(EmitContext& ctx, Id value) {
  150. return ctx.OpConvertUToF(ctx.F16[1], ExtractU8(ctx, value));
  151. }
  152. Id EmitConvertF16U16(EmitContext& ctx, Id value) {
  153. return ctx.OpConvertUToF(ctx.F16[1], ExtractU16(ctx, value));
  154. }
  155. Id EmitConvertF16U32(EmitContext& ctx, Id value) {
  156. return ctx.OpConvertUToF(ctx.F16[1], value);
  157. }
  158. Id EmitConvertF16U64(EmitContext& ctx, Id value) {
  159. return ctx.OpConvertUToF(ctx.F16[1], value);
  160. }
  161. Id EmitConvertF32S8(EmitContext& ctx, Id value) {
  162. return ctx.OpConvertSToF(ctx.F32[1], ExtractS8(ctx, value));
  163. }
  164. Id EmitConvertF32S16(EmitContext& ctx, Id value) {
  165. return ctx.OpConvertSToF(ctx.F32[1], ExtractS16(ctx, value));
  166. }
  167. Id EmitConvertF32S32(EmitContext& ctx, Id value) {
  168. if (ctx.profile.has_broken_signed_operations) {
  169. value = ctx.OpBitcast(ctx.S32[1], value);
  170. }
  171. return ctx.OpConvertSToF(ctx.F32[1], value);
  172. }
  173. Id EmitConvertF32S64(EmitContext& ctx, Id value) {
  174. return ctx.OpConvertSToF(ctx.F32[1], value);
  175. }
  176. Id EmitConvertF32U8(EmitContext& ctx, Id value) {
  177. return ctx.OpConvertUToF(ctx.F32[1], ExtractU8(ctx, value));
  178. }
  179. Id EmitConvertF32U16(EmitContext& ctx, Id value) {
  180. return ctx.OpConvertUToF(ctx.F32[1], ExtractU16(ctx, value));
  181. }
  182. Id EmitConvertF32U32(EmitContext& ctx, Id value) {
  183. return ctx.OpConvertUToF(ctx.F32[1], value);
  184. }
  185. Id EmitConvertF32U64(EmitContext& ctx, Id value) {
  186. return ctx.OpConvertUToF(ctx.F32[1], value);
  187. }
  188. Id EmitConvertF64S8(EmitContext& ctx, Id value) {
  189. return ctx.OpConvertSToF(ctx.F64[1], ExtractS8(ctx, value));
  190. }
  191. Id EmitConvertF64S16(EmitContext& ctx, Id value) {
  192. return ctx.OpConvertSToF(ctx.F64[1], ExtractS16(ctx, value));
  193. }
  194. Id EmitConvertF64S32(EmitContext& ctx, Id value) {
  195. if (ctx.profile.has_broken_signed_operations) {
  196. value = ctx.OpBitcast(ctx.S32[1], value);
  197. }
  198. return ctx.OpConvertSToF(ctx.F64[1], value);
  199. }
  200. Id EmitConvertF64S64(EmitContext& ctx, Id value) {
  201. return ctx.OpConvertSToF(ctx.F64[1], value);
  202. }
  203. Id EmitConvertF64U8(EmitContext& ctx, Id value) {
  204. return ctx.OpConvertUToF(ctx.F64[1], ExtractU8(ctx, value));
  205. }
  206. Id EmitConvertF64U16(EmitContext& ctx, Id value) {
  207. return ctx.OpConvertUToF(ctx.F64[1], ExtractU16(ctx, value));
  208. }
  209. Id EmitConvertF64U32(EmitContext& ctx, Id value) {
  210. return ctx.OpConvertUToF(ctx.F64[1], value);
  211. }
  212. Id EmitConvertF64U64(EmitContext& ctx, Id value) {
  213. return ctx.OpConvertUToF(ctx.F64[1], value);
  214. }
  215. } // namespace Shader::Backend::SPIRV