emit_spirv_convert.cpp 7.6 KB

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