converter.cpp 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-3.0-or-later
  3. #include <array>
  4. #include <bit>
  5. #include <cmath>
  6. #include <span>
  7. #include <unordered_map>
  8. #include "common/assert.h"
  9. #include "video_core/engines/sw_blitter/converter.h"
  10. #include "video_core/surface.h"
  11. #include "video_core/textures/decoders.h"
  12. #ifdef _MSC_VER
  13. #define FORCE_INLINE __forceinline
  14. #else
  15. #define FORCE_INLINE inline __attribute__((always_inline))
  16. #endif
  17. namespace Tegra::Engines::Blitter {
  18. enum class Swizzle : size_t {
  19. R = 0,
  20. G = 1,
  21. B = 2,
  22. A = 3,
  23. None,
  24. };
  25. enum class ComponentType : u32 {
  26. SNORM = 1,
  27. UNORM = 2,
  28. SINT = 3,
  29. UINT = 4,
  30. SNORM_FORCE_FP16 = 5,
  31. UNORM_FORCE_FP16 = 6,
  32. FLOAT = 7,
  33. SRGB = 8,
  34. };
  35. namespace {
  36. constexpr std::array<f32, 256> SRGB_TO_RGB_LUT = {
  37. 0.000000e+00f, 3.035270e-04f, 6.070540e-04f, 9.105810e-04f, 1.214108e-03f, 1.517635e-03f,
  38. 1.821162e-03f, 2.124689e-03f, 2.428216e-03f, 2.731743e-03f, 3.035270e-03f, 3.346536e-03f,
  39. 3.676507e-03f, 4.024717e-03f, 4.391442e-03f, 4.776953e-03f, 5.181517e-03f, 5.605392e-03f,
  40. 6.048833e-03f, 6.512091e-03f, 6.995410e-03f, 7.499032e-03f, 8.023193e-03f, 8.568126e-03f,
  41. 9.134059e-03f, 9.721218e-03f, 1.032982e-02f, 1.096009e-02f, 1.161224e-02f, 1.228649e-02f,
  42. 1.298303e-02f, 1.370208e-02f, 1.444384e-02f, 1.520851e-02f, 1.599629e-02f, 1.680738e-02f,
  43. 1.764195e-02f, 1.850022e-02f, 1.938236e-02f, 2.028856e-02f, 2.121901e-02f, 2.217389e-02f,
  44. 2.315337e-02f, 2.415763e-02f, 2.518686e-02f, 2.624122e-02f, 2.732089e-02f, 2.842604e-02f,
  45. 2.955684e-02f, 3.071344e-02f, 3.189603e-02f, 3.310477e-02f, 3.433981e-02f, 3.560131e-02f,
  46. 3.688945e-02f, 3.820437e-02f, 3.954624e-02f, 4.091520e-02f, 4.231141e-02f, 4.373503e-02f,
  47. 4.518620e-02f, 4.666509e-02f, 4.817183e-02f, 4.970657e-02f, 5.126946e-02f, 5.286065e-02f,
  48. 5.448028e-02f, 5.612849e-02f, 5.780543e-02f, 5.951124e-02f, 6.124605e-02f, 6.301001e-02f,
  49. 6.480327e-02f, 6.662594e-02f, 6.847817e-02f, 7.036009e-02f, 7.227185e-02f, 7.421357e-02f,
  50. 7.618538e-02f, 7.818742e-02f, 8.021982e-02f, 8.228271e-02f, 8.437621e-02f, 8.650046e-02f,
  51. 8.865558e-02f, 9.084171e-02f, 9.305897e-02f, 9.530747e-02f, 9.758735e-02f, 9.989873e-02f,
  52. 1.022417e-01f, 1.046165e-01f, 1.070231e-01f, 1.094617e-01f, 1.119324e-01f, 1.144354e-01f,
  53. 1.169707e-01f, 1.195384e-01f, 1.221388e-01f, 1.247718e-01f, 1.274377e-01f, 1.301365e-01f,
  54. 1.328683e-01f, 1.356333e-01f, 1.384316e-01f, 1.412633e-01f, 1.441285e-01f, 1.470273e-01f,
  55. 1.499598e-01f, 1.529261e-01f, 1.559265e-01f, 1.589608e-01f, 1.620294e-01f, 1.651322e-01f,
  56. 1.682694e-01f, 1.714411e-01f, 1.746474e-01f, 1.778884e-01f, 1.811642e-01f, 1.844750e-01f,
  57. 1.878208e-01f, 1.912017e-01f, 1.946178e-01f, 1.980693e-01f, 2.015563e-01f, 2.050787e-01f,
  58. 2.086369e-01f, 2.122308e-01f, 2.158605e-01f, 2.195262e-01f, 2.232280e-01f, 2.269659e-01f,
  59. 2.307401e-01f, 2.345506e-01f, 2.383976e-01f, 2.422811e-01f, 2.462013e-01f, 2.501583e-01f,
  60. 2.541521e-01f, 2.581829e-01f, 2.622507e-01f, 2.663556e-01f, 2.704978e-01f, 2.746773e-01f,
  61. 2.788943e-01f, 2.831487e-01f, 2.874408e-01f, 2.917706e-01f, 2.961383e-01f, 3.005438e-01f,
  62. 3.049873e-01f, 3.094689e-01f, 3.139887e-01f, 3.185468e-01f, 3.231432e-01f, 3.277781e-01f,
  63. 3.324515e-01f, 3.371636e-01f, 3.419144e-01f, 3.467041e-01f, 3.515326e-01f, 3.564001e-01f,
  64. 3.613068e-01f, 3.662526e-01f, 3.712377e-01f, 3.762621e-01f, 3.813260e-01f, 3.864294e-01f,
  65. 3.915725e-01f, 3.967552e-01f, 4.019778e-01f, 4.072402e-01f, 4.125426e-01f, 4.178851e-01f,
  66. 4.232677e-01f, 4.286905e-01f, 4.341536e-01f, 4.396572e-01f, 4.452012e-01f, 4.507858e-01f,
  67. 4.564110e-01f, 4.620770e-01f, 4.677838e-01f, 4.735315e-01f, 4.793202e-01f, 4.851499e-01f,
  68. 4.910209e-01f, 4.969330e-01f, 5.028865e-01f, 5.088813e-01f, 5.149177e-01f, 5.209956e-01f,
  69. 5.271151e-01f, 5.332764e-01f, 5.394795e-01f, 5.457245e-01f, 5.520114e-01f, 5.583404e-01f,
  70. 5.647115e-01f, 5.711249e-01f, 5.775805e-01f, 5.840784e-01f, 5.906188e-01f, 5.972018e-01f,
  71. 6.038274e-01f, 6.104956e-01f, 6.172066e-01f, 6.239604e-01f, 6.307572e-01f, 6.375968e-01f,
  72. 6.444797e-01f, 6.514056e-01f, 6.583748e-01f, 6.653873e-01f, 6.724432e-01f, 6.795425e-01f,
  73. 6.866853e-01f, 6.938717e-01f, 7.011019e-01f, 7.083758e-01f, 7.156935e-01f, 7.230551e-01f,
  74. 7.304608e-01f, 7.379104e-01f, 7.454042e-01f, 7.529422e-01f, 7.605245e-01f, 7.681512e-01f,
  75. 7.758222e-01f, 7.835378e-01f, 7.912979e-01f, 7.991027e-01f, 8.069522e-01f, 8.148466e-01f,
  76. 8.227857e-01f, 8.307699e-01f, 8.387990e-01f, 8.468732e-01f, 8.549926e-01f, 8.631572e-01f,
  77. 8.713671e-01f, 8.796224e-01f, 8.879231e-01f, 8.962694e-01f, 9.046612e-01f, 9.130986e-01f,
  78. 9.215819e-01f, 9.301109e-01f, 9.386857e-01f, 9.473065e-01f, 9.559733e-01f, 9.646863e-01f,
  79. 9.734453e-01f, 9.822506e-01f, 9.911021e-01f, 1.000000e+00f};
  80. constexpr std::array<f32, 256> RGB_TO_SRGB_LUT = {
  81. 0.000000e+00f, 4.984009e-02f, 8.494473e-02f, 1.107021e-01f, 1.318038e-01f, 1.500052e-01f,
  82. 1.661857e-01f, 1.808585e-01f, 1.943532e-01f, 2.068957e-01f, 2.186491e-01f, 2.297351e-01f,
  83. 2.402475e-01f, 2.502604e-01f, 2.598334e-01f, 2.690152e-01f, 2.778465e-01f, 2.863614e-01f,
  84. 2.945889e-01f, 3.025538e-01f, 3.102778e-01f, 3.177796e-01f, 3.250757e-01f, 3.321809e-01f,
  85. 3.391081e-01f, 3.458689e-01f, 3.524737e-01f, 3.589320e-01f, 3.652521e-01f, 3.714419e-01f,
  86. 3.775084e-01f, 3.834581e-01f, 3.892968e-01f, 3.950301e-01f, 4.006628e-01f, 4.061998e-01f,
  87. 4.116451e-01f, 4.170030e-01f, 4.222770e-01f, 4.274707e-01f, 4.325873e-01f, 4.376298e-01f,
  88. 4.426010e-01f, 4.475037e-01f, 4.523403e-01f, 4.571131e-01f, 4.618246e-01f, 4.664766e-01f,
  89. 4.710712e-01f, 4.756104e-01f, 4.800958e-01f, 4.845292e-01f, 4.889122e-01f, 4.932462e-01f,
  90. 4.975329e-01f, 5.017734e-01f, 5.059693e-01f, 5.101216e-01f, 5.142317e-01f, 5.183006e-01f,
  91. 5.223295e-01f, 5.263194e-01f, 5.302714e-01f, 5.341862e-01f, 5.380651e-01f, 5.419087e-01f,
  92. 5.457181e-01f, 5.494938e-01f, 5.532369e-01f, 5.569480e-01f, 5.606278e-01f, 5.642771e-01f,
  93. 5.678965e-01f, 5.714868e-01f, 5.750484e-01f, 5.785821e-01f, 5.820884e-01f, 5.855680e-01f,
  94. 5.890211e-01f, 5.924487e-01f, 5.958509e-01f, 5.992285e-01f, 6.025819e-01f, 6.059114e-01f,
  95. 6.092176e-01f, 6.125010e-01f, 6.157619e-01f, 6.190008e-01f, 6.222180e-01f, 6.254140e-01f,
  96. 6.285890e-01f, 6.317436e-01f, 6.348780e-01f, 6.379926e-01f, 6.410878e-01f, 6.441637e-01f,
  97. 6.472208e-01f, 6.502595e-01f, 6.532799e-01f, 6.562824e-01f, 6.592672e-01f, 6.622347e-01f,
  98. 6.651851e-01f, 6.681187e-01f, 6.710356e-01f, 6.739363e-01f, 6.768209e-01f, 6.796897e-01f,
  99. 6.825429e-01f, 6.853807e-01f, 6.882034e-01f, 6.910111e-01f, 6.938041e-01f, 6.965826e-01f,
  100. 6.993468e-01f, 7.020969e-01f, 7.048331e-01f, 7.075556e-01f, 7.102645e-01f, 7.129600e-01f,
  101. 7.156424e-01f, 7.183118e-01f, 7.209683e-01f, 7.236121e-01f, 7.262435e-01f, 7.288625e-01f,
  102. 7.314693e-01f, 7.340640e-01f, 7.366470e-01f, 7.392181e-01f, 7.417776e-01f, 7.443256e-01f,
  103. 7.468624e-01f, 7.493880e-01f, 7.519025e-01f, 7.544061e-01f, 7.568989e-01f, 7.593810e-01f,
  104. 7.618526e-01f, 7.643137e-01f, 7.667645e-01f, 7.692052e-01f, 7.716358e-01f, 7.740564e-01f,
  105. 7.764671e-01f, 7.788681e-01f, 7.812595e-01f, 7.836413e-01f, 7.860138e-01f, 7.883768e-01f,
  106. 7.907307e-01f, 7.930754e-01f, 7.954110e-01f, 7.977377e-01f, 8.000556e-01f, 8.023647e-01f,
  107. 8.046651e-01f, 8.069569e-01f, 8.092403e-01f, 8.115152e-01f, 8.137818e-01f, 8.160402e-01f,
  108. 8.182903e-01f, 8.205324e-01f, 8.227665e-01f, 8.249926e-01f, 8.272109e-01f, 8.294214e-01f,
  109. 8.316242e-01f, 8.338194e-01f, 8.360070e-01f, 8.381871e-01f, 8.403597e-01f, 8.425251e-01f,
  110. 8.446831e-01f, 8.468339e-01f, 8.489776e-01f, 8.511142e-01f, 8.532437e-01f, 8.553662e-01f,
  111. 8.574819e-01f, 8.595907e-01f, 8.616927e-01f, 8.637881e-01f, 8.658767e-01f, 8.679587e-01f,
  112. 8.700342e-01f, 8.721032e-01f, 8.741657e-01f, 8.762218e-01f, 8.782716e-01f, 8.803151e-01f,
  113. 8.823524e-01f, 8.843835e-01f, 8.864085e-01f, 8.884274e-01f, 8.904402e-01f, 8.924471e-01f,
  114. 8.944480e-01f, 8.964431e-01f, 8.984324e-01f, 9.004158e-01f, 9.023935e-01f, 9.043654e-01f,
  115. 9.063318e-01f, 9.082925e-01f, 9.102476e-01f, 9.121972e-01f, 9.141413e-01f, 9.160800e-01f,
  116. 9.180133e-01f, 9.199412e-01f, 9.218637e-01f, 9.237810e-01f, 9.256931e-01f, 9.276000e-01f,
  117. 9.295017e-01f, 9.313982e-01f, 9.332896e-01f, 9.351761e-01f, 9.370575e-01f, 9.389339e-01f,
  118. 9.408054e-01f, 9.426719e-01f, 9.445336e-01f, 9.463905e-01f, 9.482424e-01f, 9.500897e-01f,
  119. 9.519322e-01f, 9.537700e-01f, 9.556032e-01f, 9.574316e-01f, 9.592555e-01f, 9.610748e-01f,
  120. 9.628896e-01f, 9.646998e-01f, 9.665055e-01f, 9.683068e-01f, 9.701037e-01f, 9.718961e-01f,
  121. 9.736842e-01f, 9.754679e-01f, 9.772474e-01f, 9.790225e-01f, 9.807934e-01f, 9.825601e-01f,
  122. 9.843225e-01f, 9.860808e-01f, 9.878350e-01f, 9.895850e-01f, 9.913309e-01f, 9.930727e-01f,
  123. 9.948106e-01f, 9.965444e-01f, 9.982741e-01f, 1.000000e+00f};
  124. } // namespace
  125. struct R32B32G32A32_FLOATTraits {
  126. static constexpr size_t num_components = 4;
  127. static constexpr std::array<ComponentType, num_components> component_types = {
  128. ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT};
  129. static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32};
  130. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  131. Swizzle::A, Swizzle::G, Swizzle::B, Swizzle::R};
  132. };
  133. struct R32G32B32A32_SINTTraits {
  134. static constexpr size_t num_components = 4;
  135. static constexpr std::array<ComponentType, num_components> component_types = {
  136. ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT};
  137. static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32};
  138. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  139. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  140. };
  141. struct R32G32B32A32_UINTTraits {
  142. static constexpr size_t num_components = 4;
  143. static constexpr std::array<ComponentType, num_components> component_types = {
  144. ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT};
  145. static constexpr std::array<size_t, num_components> component_sizes = {32, 32, 32, 32};
  146. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  147. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  148. };
  149. struct R16G16B16A16_UNORMTraits {
  150. static constexpr size_t num_components = 4;
  151. static constexpr std::array<ComponentType, num_components> component_types = {
  152. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  153. static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16};
  154. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  155. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  156. };
  157. struct R16G16B16A16_SNORMTraits {
  158. static constexpr size_t num_components = 4;
  159. static constexpr std::array<ComponentType, num_components> component_types = {
  160. ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM};
  161. static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16};
  162. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  163. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  164. };
  165. struct R16G16B16A16_SINTTraits {
  166. static constexpr size_t num_components = 4;
  167. static constexpr std::array<ComponentType, num_components> component_types = {
  168. ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT};
  169. static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16};
  170. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  171. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  172. };
  173. struct R16G16B16A16_UINTTraits {
  174. static constexpr size_t num_components = 4;
  175. static constexpr std::array<ComponentType, num_components> component_types = {
  176. ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT};
  177. static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16};
  178. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  179. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  180. };
  181. struct R16G16B16A16_FLOATTraits {
  182. static constexpr size_t num_components = 4;
  183. static constexpr std::array<ComponentType, num_components> component_types = {
  184. ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT};
  185. static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16};
  186. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  187. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  188. };
  189. struct R32G32_FLOATTraits {
  190. static constexpr size_t num_components = 2;
  191. static constexpr std::array<ComponentType, num_components> component_types = {
  192. ComponentType::FLOAT, ComponentType::FLOAT};
  193. static constexpr std::array<size_t, num_components> component_sizes = {32, 32};
  194. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  195. Swizzle::R};
  196. };
  197. struct R32G32_SINTTraits {
  198. static constexpr size_t num_components = 2;
  199. static constexpr std::array<ComponentType, num_components> component_types = {
  200. ComponentType::SINT, ComponentType::SINT};
  201. static constexpr std::array<size_t, num_components> component_sizes = {32, 32};
  202. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  203. Swizzle::R};
  204. };
  205. struct R32G32_UINTTraits {
  206. static constexpr size_t num_components = 2;
  207. static constexpr std::array<ComponentType, num_components> component_types = {
  208. ComponentType::UINT, ComponentType::UINT};
  209. static constexpr std::array<size_t, num_components> component_sizes = {32, 32};
  210. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  211. Swizzle::R};
  212. };
  213. struct R16G16B16X16_FLOATTraits {
  214. static constexpr size_t num_components = 4;
  215. static constexpr std::array<ComponentType, num_components> component_types = {
  216. ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT};
  217. static constexpr std::array<size_t, num_components> component_sizes = {16, 16, 16, 16};
  218. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  219. Swizzle::None, Swizzle::B, Swizzle::G, Swizzle::R};
  220. };
  221. struct A8R8G8B8_UNORMTraits {
  222. static constexpr size_t num_components = 4;
  223. static constexpr std::array<ComponentType, num_components> component_types = {
  224. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  225. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  226. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  227. Swizzle::B, Swizzle::G, Swizzle::R, Swizzle::A};
  228. };
  229. struct A8R8G8B8_SRGBTraits {
  230. static constexpr size_t num_components = 4;
  231. static constexpr std::array<ComponentType, num_components> component_types = {
  232. ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB};
  233. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  234. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  235. Swizzle::B, Swizzle::G, Swizzle::R, Swizzle::A};
  236. };
  237. struct A2B10G10R10_UNORMTraits {
  238. static constexpr size_t num_components = 4;
  239. static constexpr std::array<ComponentType, num_components> component_types = {
  240. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  241. static constexpr std::array<size_t, num_components> component_sizes = {10, 10, 10, 2};
  242. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  243. Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A};
  244. };
  245. struct A2B10G10R10_UINTTraits {
  246. static constexpr size_t num_components = 4;
  247. static constexpr std::array<ComponentType, num_components> component_types = {
  248. ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT};
  249. static constexpr std::array<size_t, num_components> component_sizes = {10, 10, 10, 2};
  250. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  251. Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A};
  252. };
  253. struct A8B8G8R8_UNORMTraits {
  254. static constexpr size_t num_components = 4;
  255. static constexpr std::array<ComponentType, num_components> component_types = {
  256. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  257. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  258. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  259. Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A};
  260. };
  261. struct A8B8G8R8_SRGBTraits {
  262. static constexpr size_t num_components = 4;
  263. static constexpr std::array<ComponentType, num_components> component_types = {
  264. ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB};
  265. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  266. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  267. Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A};
  268. };
  269. struct A8B8G8R8_SNORMTraits {
  270. static constexpr size_t num_components = 4;
  271. static constexpr std::array<ComponentType, num_components> component_types = {
  272. ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM, ComponentType::SNORM};
  273. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  274. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  275. Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A};
  276. };
  277. struct A8B8G8R8_SINTTraits {
  278. static constexpr size_t num_components = 4;
  279. static constexpr std::array<ComponentType, num_components> component_types = {
  280. ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT};
  281. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  282. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  283. Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A};
  284. };
  285. struct A8B8G8R8_UINTTraits {
  286. static constexpr size_t num_components = 4;
  287. static constexpr std::array<ComponentType, num_components> component_types = {
  288. ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT};
  289. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  290. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  291. Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A};
  292. };
  293. struct R16G16_UNORMTraits {
  294. static constexpr size_t num_components = 2;
  295. static constexpr std::array<ComponentType, num_components> component_types = {
  296. ComponentType::UNORM, ComponentType::UNORM};
  297. static constexpr std::array<size_t, num_components> component_sizes = {16, 16};
  298. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  299. Swizzle::R};
  300. };
  301. struct R16G16_SNORMTraits {
  302. static constexpr size_t num_components = 2;
  303. static constexpr std::array<ComponentType, num_components> component_types = {
  304. ComponentType::SNORM, ComponentType::SNORM};
  305. static constexpr std::array<size_t, num_components> component_sizes = {16, 16};
  306. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  307. Swizzle::R};
  308. };
  309. struct R16G16_SINTTraits {
  310. static constexpr size_t num_components = 2;
  311. static constexpr std::array<ComponentType, num_components> component_types = {
  312. ComponentType::SINT, ComponentType::SINT};
  313. static constexpr std::array<size_t, num_components> component_sizes = {16, 16};
  314. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  315. Swizzle::R};
  316. };
  317. struct R16G16_UINTTraits {
  318. static constexpr size_t num_components = 2;
  319. static constexpr std::array<ComponentType, num_components> component_types = {
  320. ComponentType::UINT, ComponentType::UINT};
  321. static constexpr std::array<size_t, num_components> component_sizes = {16, 16};
  322. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  323. Swizzle::R};
  324. };
  325. struct R16G16_FLOATTraits {
  326. static constexpr size_t num_components = 2;
  327. static constexpr std::array<ComponentType, num_components> component_types = {
  328. ComponentType::FLOAT, ComponentType::FLOAT};
  329. static constexpr std::array<size_t, num_components> component_sizes = {16, 16};
  330. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  331. Swizzle::R};
  332. };
  333. struct B10G11R11_FLOATTraits {
  334. static constexpr size_t num_components = 3;
  335. static constexpr std::array<ComponentType, num_components> component_types = {
  336. ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT};
  337. static constexpr std::array<size_t, num_components> component_sizes = {11, 11, 10};
  338. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  339. Swizzle::R, Swizzle::G, Swizzle::B};
  340. };
  341. struct R32_SINTTraits {
  342. static constexpr size_t num_components = 1;
  343. static constexpr std::array<ComponentType, num_components> component_types = {
  344. ComponentType::SINT};
  345. static constexpr std::array<size_t, num_components> component_sizes = {32};
  346. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  347. };
  348. struct R32_UINTTraits {
  349. static constexpr size_t num_components = 1;
  350. static constexpr std::array<ComponentType, num_components> component_types = {
  351. ComponentType::UINT};
  352. static constexpr std::array<size_t, num_components> component_sizes = {32};
  353. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  354. };
  355. struct R32_FLOATTraits {
  356. static constexpr size_t num_components = 1;
  357. static constexpr std::array<ComponentType, num_components> component_types = {
  358. ComponentType::FLOAT};
  359. static constexpr std::array<size_t, num_components> component_sizes = {32};
  360. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  361. };
  362. struct R5G6B5_UNORMTraits {
  363. static constexpr size_t num_components = 3;
  364. static constexpr std::array<ComponentType, num_components> component_types = {
  365. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  366. static constexpr std::array<size_t, num_components> component_sizes = {5, 6, 5};
  367. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  368. Swizzle::B, Swizzle::G, Swizzle::R};
  369. };
  370. struct A1R5G5B5_UNORMTraits {
  371. static constexpr size_t num_components = 4;
  372. static constexpr std::array<ComponentType, num_components> component_types = {
  373. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  374. static constexpr std::array<size_t, num_components> component_sizes = {5, 5, 5, 1};
  375. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  376. Swizzle::B, Swizzle::G, Swizzle::R, Swizzle::A};
  377. };
  378. struct R8G8_UNORMTraits {
  379. static constexpr size_t num_components = 2;
  380. static constexpr std::array<ComponentType, num_components> component_types = {
  381. ComponentType::UNORM, ComponentType::UNORM};
  382. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  383. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  384. Swizzle::R};
  385. };
  386. struct R8G8_SNORMTraits {
  387. static constexpr size_t num_components = 2;
  388. static constexpr std::array<ComponentType, num_components> component_types = {
  389. ComponentType::SNORM, ComponentType::SNORM};
  390. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  391. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  392. Swizzle::R};
  393. };
  394. struct R8G8_SINTTraits {
  395. static constexpr size_t num_components = 2;
  396. static constexpr std::array<ComponentType, num_components> component_types = {
  397. ComponentType::SINT, ComponentType::SINT};
  398. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  399. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  400. Swizzle::R};
  401. };
  402. struct R8G8_UINTTraits {
  403. static constexpr size_t num_components = 2;
  404. static constexpr std::array<ComponentType, num_components> component_types = {
  405. ComponentType::UINT, ComponentType::UINT};
  406. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  407. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::G,
  408. Swizzle::R};
  409. };
  410. struct R16_UNORMTraits {
  411. static constexpr size_t num_components = 1;
  412. static constexpr std::array<ComponentType, num_components> component_types = {
  413. ComponentType::UNORM};
  414. static constexpr std::array<size_t, num_components> component_sizes = {16};
  415. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  416. };
  417. struct R16_SNORMTraits {
  418. static constexpr size_t num_components = 1;
  419. static constexpr std::array<ComponentType, num_components> component_types = {
  420. ComponentType::SNORM};
  421. static constexpr std::array<size_t, num_components> component_sizes = {16};
  422. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  423. };
  424. struct R16_SINTTraits {
  425. static constexpr size_t num_components = 1;
  426. static constexpr std::array<ComponentType, num_components> component_types = {
  427. ComponentType::SINT};
  428. static constexpr std::array<size_t, num_components> component_sizes = {16};
  429. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  430. };
  431. struct R16_UINTTraits {
  432. static constexpr size_t num_components = 1;
  433. static constexpr std::array<ComponentType, num_components> component_types = {
  434. ComponentType::UINT};
  435. static constexpr std::array<size_t, num_components> component_sizes = {16};
  436. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  437. };
  438. struct R16_FLOATTraits {
  439. static constexpr size_t num_components = 1;
  440. static constexpr std::array<ComponentType, num_components> component_types = {
  441. ComponentType::FLOAT};
  442. static constexpr std::array<size_t, num_components> component_sizes = {16};
  443. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  444. };
  445. struct R8_UNORMTraits {
  446. static constexpr size_t num_components = 1;
  447. static constexpr std::array<ComponentType, num_components> component_types = {
  448. ComponentType::UNORM};
  449. static constexpr std::array<size_t, num_components> component_sizes = {8};
  450. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  451. };
  452. struct R8_SNORMTraits {
  453. static constexpr size_t num_components = 1;
  454. static constexpr std::array<ComponentType, num_components> component_types = {
  455. ComponentType::SNORM};
  456. static constexpr std::array<size_t, num_components> component_sizes = {8};
  457. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  458. };
  459. struct R8_SINTTraits {
  460. static constexpr size_t num_components = 1;
  461. static constexpr std::array<ComponentType, num_components> component_types = {
  462. ComponentType::SINT};
  463. static constexpr std::array<size_t, num_components> component_sizes = {8};
  464. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  465. };
  466. struct R8_UINTTraits {
  467. static constexpr size_t num_components = 1;
  468. static constexpr std::array<ComponentType, num_components> component_types = {
  469. ComponentType::UINT};
  470. static constexpr std::array<size_t, num_components> component_sizes = {8};
  471. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  472. };
  473. template <class ConverterTraits>
  474. class ConverterImpl : public Converter {
  475. private:
  476. static constexpr size_t num_components = ConverterTraits::num_components;
  477. static constexpr std::array<ComponentType, num_components> component_types =
  478. ConverterTraits::component_types;
  479. static constexpr std::array<size_t, num_components> component_sizes =
  480. ConverterTraits::component_sizes;
  481. static constexpr std::array<Swizzle, num_components> component_swizzle =
  482. ConverterTraits::component_swizzle;
  483. static constexpr size_t CalculateByteSize() {
  484. size_t size = 0;
  485. for (const size_t component_size : component_sizes) {
  486. size += component_size;
  487. }
  488. const size_t power = (sizeof(size_t) * 8) - std::countl_zero(size) - 1ULL;
  489. const size_t base_size = 1ULL << power;
  490. const size_t mask = base_size - 1ULL;
  491. return ((size & mask) != 0 ? base_size << 1ULL : base_size) / 8;
  492. }
  493. static constexpr size_t total_bytes_per_pixel = CalculateByteSize();
  494. static constexpr size_t total_words_per_pixel =
  495. (total_bytes_per_pixel + sizeof(u32) - 1U) / sizeof(u32);
  496. static constexpr size_t components_per_ir_rep = 4;
  497. template <bool get_offsets>
  498. static constexpr std::array<size_t, num_components> GetBoundWordsOffsets() {
  499. std::array<size_t, num_components> result;
  500. result.fill(0);
  501. constexpr size_t total_bits_per_word = sizeof(u32) * 8;
  502. size_t accumulated_size = 0;
  503. size_t count = 0;
  504. for (size_t i = 0; i < num_components; i++) {
  505. if constexpr (get_offsets) {
  506. result[i] = accumulated_size;
  507. } else {
  508. result[i] = count;
  509. }
  510. accumulated_size += component_sizes[i];
  511. if (accumulated_size > total_bits_per_word) {
  512. if constexpr (get_offsets) {
  513. result[i] = 0;
  514. } else {
  515. result[i]++;
  516. }
  517. count++;
  518. accumulated_size = component_sizes[i];
  519. }
  520. }
  521. return result;
  522. }
  523. static constexpr std::array<size_t, num_components> bound_words = GetBoundWordsOffsets<false>();
  524. static constexpr std::array<size_t, num_components> bound_offsets =
  525. GetBoundWordsOffsets<true>();
  526. static constexpr std::array<u32, num_components> GetComponentsMask() {
  527. std::array<u32, num_components> result;
  528. for (size_t i = 0; i < num_components; i++) {
  529. result[i] = (((u32)~0) >> (8 * sizeof(u32) - component_sizes[i])) << bound_offsets[i];
  530. }
  531. return result;
  532. }
  533. static constexpr std::array<u32, num_components> component_mask = GetComponentsMask();
  534. // We are forcing inline so the compiler can SIMD the conversations, since it may do 4 function
  535. // calls, it may fail to detect the benefit of inlining.
  536. template <size_t which_component>
  537. FORCE_INLINE void ConvertToComponent(u32 which_word, f32& out_component) {
  538. const u32 value = (which_word >> bound_offsets[which_component]) &
  539. static_cast<u32>((1ULL << component_sizes[which_component]) - 1ULL);
  540. const auto sign_extend = [](u32 base_value, size_t bits) {
  541. const size_t shift_amount = sizeof(u32) * 8 - bits;
  542. s32 shifted_value = static_cast<s32>(base_value << shift_amount);
  543. return shifted_value >> shift_amount;
  544. };
  545. const auto force_to_fp16 = [](f32 base_value) {
  546. u32 tmp = std::bit_cast<u32>(base_value);
  547. constexpr size_t fp32_mantissa_bits = 23;
  548. constexpr size_t fp16_mantissa_bits = 10;
  549. constexpr size_t mantissa_mask =
  550. ~((1ULL << (fp32_mantissa_bits - fp16_mantissa_bits)) - 1ULL);
  551. tmp = tmp & mantissa_mask;
  552. // TODO: force the exponent within the range of half float. Not needed in UNORM / SNORM
  553. return std::bit_cast<f32>(tmp);
  554. };
  555. const auto from_fp_n = [&sign_extend](u32 base_value, size_t bits, size_t mantissa) {
  556. constexpr size_t fp32_mantissa_bits = 23;
  557. size_t shift_towards = fp32_mantissa_bits - mantissa;
  558. const u32 new_value =
  559. static_cast<u32>(sign_extend(base_value, bits) << shift_towards) & (~(1U << 31));
  560. return std::bit_cast<f32>(new_value);
  561. };
  562. const auto calculate_snorm = [&]() {
  563. return static_cast<f32>(
  564. static_cast<f64>(sign_extend(value, component_sizes[which_component])) /
  565. ((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL));
  566. };
  567. const auto calculate_unorm = [&]() {
  568. return static_cast<f32>(static_cast<f32>(value) /
  569. ((1ULL << (component_sizes[which_component])) - 1ULL));
  570. };
  571. if constexpr (component_types[which_component] == ComponentType::SNORM) {
  572. out_component = calculate_snorm();
  573. } else if constexpr (component_types[which_component] == ComponentType::UNORM) {
  574. out_component = calculate_unorm();
  575. } else if constexpr (component_types[which_component] == ComponentType::SINT) {
  576. out_component = static_cast<f32>(
  577. static_cast<s32>(sign_extend(value, component_sizes[which_component])));
  578. } else if constexpr (component_types[which_component] == ComponentType::UINT) {
  579. out_component = static_cast<f32>(
  580. static_cast<s32>(sign_extend(value, component_sizes[which_component])));
  581. } else if constexpr (component_types[which_component] == ComponentType::SNORM_FORCE_FP16) {
  582. out_component = calculate_snorm();
  583. out_component = force_to_fp16(out_component);
  584. } else if constexpr (component_types[which_component] == ComponentType::UNORM_FORCE_FP16) {
  585. out_component = calculate_unorm();
  586. out_component = force_to_fp16(out_component);
  587. } else if constexpr (component_types[which_component] == ComponentType::FLOAT) {
  588. if constexpr (component_sizes[which_component] == 32) {
  589. out_component = std::bit_cast<f32>(value);
  590. } else if constexpr (component_sizes[which_component] == 16) {
  591. static constexpr u32 sign_mask = 0x8000;
  592. static constexpr u32 mantissa_mask = 0x8000;
  593. out_component = std::bit_cast<f32>(((value & sign_mask) << 16) |
  594. (((value & 0x7c00) + 0x1C000) << 13) |
  595. ((value & mantissa_mask) << 13));
  596. } else {
  597. out_component = from_fp_n(value, component_sizes[which_component],
  598. component_sizes[which_component] - 5);
  599. }
  600. } else if constexpr (component_types[which_component] == ComponentType::SRGB) {
  601. if constexpr (component_swizzle[which_component] == Swizzle::A) {
  602. out_component = calculate_unorm();
  603. } else if constexpr (component_sizes[which_component] == 8) {
  604. out_component = SRGB_TO_RGB_LUT[value];
  605. } else {
  606. out_component = calculate_unorm();
  607. UNIMPLEMENTED_MSG("SRGB Conversion with component sizes of {} is unimplemented",
  608. component_sizes[which_component]);
  609. }
  610. }
  611. }
  612. // We are forcing inline so the compiler can SIMD the conversations, since it may do 4 function
  613. // calls, it may fail to detect the benefit of inlining.
  614. template <size_t which_component>
  615. FORCE_INLINE void ConvertFromComponent(u32& which_word, f32 in_component) {
  616. const auto insert_to_word = [&]<typename T>(T new_word) {
  617. which_word |= (static_cast<u32>(new_word) << bound_offsets[which_component]) &
  618. component_mask[which_component];
  619. };
  620. const auto to_fp_n = [](f32 base_value, size_t bits, size_t mantissa) {
  621. constexpr size_t fp32_mantissa_bits = 23;
  622. u32 tmp_value = std::bit_cast<u32>(std::max(base_value, 0.0f));
  623. size_t shift_towards = fp32_mantissa_bits - mantissa;
  624. return tmp_value >> shift_towards;
  625. };
  626. const auto calculate_unorm = [&]() {
  627. return static_cast<u32>(static_cast<f32>(in_component) *
  628. ((1ULL << (component_sizes[which_component])) - 1ULL));
  629. };
  630. if constexpr (component_types[which_component] == ComponentType::SNORM ||
  631. component_types[which_component] == ComponentType::SNORM_FORCE_FP16) {
  632. s32 tmp_word =
  633. static_cast<s32>(static_cast<f64>(in_component) *
  634. ((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL));
  635. insert_to_word(tmp_word);
  636. } else if constexpr (component_types[which_component] == ComponentType::UNORM ||
  637. component_types[which_component] == ComponentType::UNORM_FORCE_FP16) {
  638. u32 tmp_word = calculate_unorm();
  639. insert_to_word(tmp_word);
  640. } else if constexpr (component_types[which_component] == ComponentType::SINT) {
  641. s32 tmp_word = static_cast<s32>(in_component);
  642. insert_to_word(tmp_word);
  643. } else if constexpr (component_types[which_component] == ComponentType::UINT) {
  644. u32 tmp_word = static_cast<u32>(in_component);
  645. insert_to_word(tmp_word);
  646. } else if constexpr (component_types[which_component] == ComponentType::FLOAT) {
  647. if constexpr (component_sizes[which_component] == 32) {
  648. u32 tmp_word = std::bit_cast<u32>(in_component);
  649. insert_to_word(tmp_word);
  650. } else if constexpr (component_sizes[which_component] == 16) {
  651. static constexpr u32 sign_mask = 0x8000;
  652. static constexpr u32 mantissa_mask = 0x8000;
  653. const u32 tmp_word = std::bit_cast<u32>(in_component);
  654. const u32 half = ((tmp_word >> 16) & sign_mask) |
  655. ((((tmp_word & 0x7f800000) - 0x38000000) >> 13) & 0x7c00) |
  656. ((tmp_word >> 13) & 0x03ff);
  657. insert_to_word(half);
  658. } else {
  659. insert_to_word(to_fp_n(in_component, component_sizes[which_component],
  660. component_sizes[which_component] - 5));
  661. }
  662. } else if constexpr (component_types[which_component] == ComponentType::SRGB) {
  663. if constexpr (component_swizzle[which_component] != Swizzle::A) {
  664. if constexpr (component_sizes[which_component] == 8) {
  665. const u32 index = calculate_unorm();
  666. in_component = RGB_TO_SRGB_LUT[index];
  667. } else {
  668. UNIMPLEMENTED_MSG("SRGB Conversion with component sizes of {} is unimplemented",
  669. component_sizes[which_component]);
  670. }
  671. }
  672. const u32 tmp_word = calculate_unorm();
  673. insert_to_word(tmp_word);
  674. }
  675. }
  676. public:
  677. void ConvertTo(std::span<u8> input, std::span<f32> output) override {
  678. const size_t num_pixels = output.size() / components_per_ir_rep;
  679. for (size_t pixel = 0; pixel < num_pixels; pixel++) {
  680. std::array<u32, total_words_per_pixel> words{};
  681. std::memcpy(words.data(), &input[pixel * total_bytes_per_pixel], total_bytes_per_pixel);
  682. std::span<f32> new_components(&output[pixel * components_per_ir_rep],
  683. components_per_ir_rep);
  684. if constexpr (component_swizzle[0] != Swizzle::None) {
  685. ConvertToComponent<0>(words[bound_words[0]],
  686. new_components[static_cast<size_t>(component_swizzle[0])]);
  687. } else {
  688. new_components[0] = 0.0f;
  689. }
  690. if constexpr (num_components >= 2) {
  691. if constexpr (component_swizzle[1] != Swizzle::None) {
  692. ConvertToComponent<1>(
  693. words[bound_words[1]],
  694. new_components[static_cast<size_t>(component_swizzle[1])]);
  695. } else {
  696. new_components[1] = 0.0f;
  697. }
  698. } else {
  699. new_components[1] = 0.0f;
  700. }
  701. if constexpr (num_components >= 3) {
  702. if constexpr (component_swizzle[2] != Swizzle::None) {
  703. ConvertToComponent<2>(
  704. words[bound_words[2]],
  705. new_components[static_cast<size_t>(component_swizzle[2])]);
  706. } else {
  707. new_components[2] = 0.0f;
  708. }
  709. } else {
  710. new_components[2] = 0.0f;
  711. }
  712. if constexpr (num_components >= 4) {
  713. if constexpr (component_swizzle[3] != Swizzle::None) {
  714. ConvertToComponent<3>(
  715. words[bound_words[3]],
  716. new_components[static_cast<size_t>(component_swizzle[3])]);
  717. } else {
  718. new_components[3] = 0.0f;
  719. }
  720. } else {
  721. new_components[3] = 0.0f;
  722. }
  723. }
  724. }
  725. void ConvertFrom(std::span<f32> input, std::span<u8> output) override {
  726. const size_t num_pixels = output.size() / total_bytes_per_pixel;
  727. for (size_t pixel = 0; pixel < num_pixels; pixel++) {
  728. std::span<f32> old_components(&input[pixel * components_per_ir_rep],
  729. components_per_ir_rep);
  730. std::array<u32, total_words_per_pixel> words{};
  731. if constexpr (component_swizzle[0] != Swizzle::None) {
  732. ConvertFromComponent<0>(words[bound_words[0]],
  733. old_components[static_cast<size_t>(component_swizzle[0])]);
  734. }
  735. if constexpr (num_components >= 2) {
  736. if constexpr (component_swizzle[1] != Swizzle::None) {
  737. ConvertFromComponent<1>(
  738. words[bound_words[1]],
  739. old_components[static_cast<size_t>(component_swizzle[1])]);
  740. }
  741. }
  742. if constexpr (num_components >= 3) {
  743. if constexpr (component_swizzle[2] != Swizzle::None) {
  744. ConvertFromComponent<2>(
  745. words[bound_words[2]],
  746. old_components[static_cast<size_t>(component_swizzle[2])]);
  747. }
  748. }
  749. if constexpr (num_components >= 4) {
  750. if constexpr (component_swizzle[3] != Swizzle::None) {
  751. ConvertFromComponent<3>(
  752. words[bound_words[3]],
  753. old_components[static_cast<size_t>(component_swizzle[3])]);
  754. }
  755. }
  756. std::memcpy(&output[pixel * total_bytes_per_pixel], words.data(),
  757. total_bytes_per_pixel);
  758. }
  759. }
  760. ConverterImpl() = default;
  761. ~ConverterImpl() = default;
  762. };
  763. struct ConverterFactory::ConverterFactoryImpl {
  764. std::unordered_map<RenderTargetFormat, std::unique_ptr<Converter>> converters_cache;
  765. };
  766. ConverterFactory::ConverterFactory() {
  767. impl = std::make_unique<ConverterFactoryImpl>();
  768. }
  769. ConverterFactory::~ConverterFactory() = default;
  770. Converter* ConverterFactory::GetFormatConverter(RenderTargetFormat format) {
  771. auto it = impl->converters_cache.find(format);
  772. if (it == impl->converters_cache.end()) [[unlikely]] {
  773. return BuildConverter(format);
  774. }
  775. return it->second.get();
  776. }
  777. class NullConverter : public Converter {
  778. public:
  779. void ConvertTo([[maybe_unused]] std::span<u8> input, std::span<f32> output) override {
  780. std::fill(output.begin(), output.end(), 0.0f);
  781. }
  782. void ConvertFrom([[maybe_unused]] std::span<f32> input, std::span<u8> output) override {
  783. const u8 fill_value = 0U;
  784. std::fill(output.begin(), output.end(), fill_value);
  785. }
  786. };
  787. Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) {
  788. switch (format) {
  789. case RenderTargetFormat::R32B32G32A32_FLOAT:
  790. return impl->converters_cache
  791. .emplace(format, std::make_unique<ConverterImpl<R32B32G32A32_FLOATTraits>>())
  792. .first->second.get();
  793. break;
  794. case RenderTargetFormat::R32G32B32A32_SINT:
  795. return impl->converters_cache
  796. .emplace(format, std::make_unique<ConverterImpl<R32G32B32A32_SINTTraits>>())
  797. .first->second.get();
  798. break;
  799. case RenderTargetFormat::R32G32B32A32_UINT:
  800. return impl->converters_cache
  801. .emplace(format, std::make_unique<ConverterImpl<R32G32B32A32_UINTTraits>>())
  802. .first->second.get();
  803. break;
  804. case RenderTargetFormat::R16G16B16A16_UNORM:
  805. return impl->converters_cache
  806. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_UNORMTraits>>())
  807. .first->second.get();
  808. break;
  809. case RenderTargetFormat::R16G16B16A16_SNORM:
  810. return impl->converters_cache
  811. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_SNORMTraits>>())
  812. .first->second.get();
  813. break;
  814. case RenderTargetFormat::R16G16B16A16_SINT:
  815. return impl->converters_cache
  816. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_SINTTraits>>())
  817. .first->second.get();
  818. break;
  819. case RenderTargetFormat::R16G16B16A16_UINT:
  820. return impl->converters_cache
  821. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_UINTTraits>>())
  822. .first->second.get();
  823. break;
  824. case RenderTargetFormat::R16G16B16A16_FLOAT:
  825. return impl->converters_cache
  826. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_FLOATTraits>>())
  827. .first->second.get();
  828. break;
  829. case RenderTargetFormat::R32G32_FLOAT:
  830. return impl->converters_cache
  831. .emplace(format, std::make_unique<ConverterImpl<R32G32_FLOATTraits>>())
  832. .first->second.get();
  833. break;
  834. case RenderTargetFormat::R32G32_SINT:
  835. return impl->converters_cache
  836. .emplace(format, std::make_unique<ConverterImpl<R32G32_SINTTraits>>())
  837. .first->second.get();
  838. break;
  839. case RenderTargetFormat::R32G32_UINT:
  840. return impl->converters_cache
  841. .emplace(format, std::make_unique<ConverterImpl<R32G32_UINTTraits>>())
  842. .first->second.get();
  843. break;
  844. case RenderTargetFormat::R16G16B16X16_FLOAT:
  845. return impl->converters_cache
  846. .emplace(format, std::make_unique<ConverterImpl<R16G16B16X16_FLOATTraits>>())
  847. .first->second.get();
  848. break;
  849. case RenderTargetFormat::A8R8G8B8_UNORM:
  850. return impl->converters_cache
  851. .emplace(format, std::make_unique<ConverterImpl<A8R8G8B8_UNORMTraits>>())
  852. .first->second.get();
  853. break;
  854. case RenderTargetFormat::A8R8G8B8_SRGB:
  855. return impl->converters_cache
  856. .emplace(format, std::make_unique<ConverterImpl<A8R8G8B8_SRGBTraits>>())
  857. .first->second.get();
  858. break;
  859. case RenderTargetFormat::A2B10G10R10_UNORM:
  860. return impl->converters_cache
  861. .emplace(format, std::make_unique<ConverterImpl<A2B10G10R10_UNORMTraits>>())
  862. .first->second.get();
  863. break;
  864. case RenderTargetFormat::A2B10G10R10_UINT:
  865. return impl->converters_cache
  866. .emplace(format, std::make_unique<ConverterImpl<A2B10G10R10_UINTTraits>>())
  867. .first->second.get();
  868. break;
  869. case RenderTargetFormat::A8B8G8R8_UNORM:
  870. return impl->converters_cache
  871. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_UNORMTraits>>())
  872. .first->second.get();
  873. break;
  874. case RenderTargetFormat::A8B8G8R8_SRGB:
  875. return impl->converters_cache
  876. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_SRGBTraits>>())
  877. .first->second.get();
  878. break;
  879. case RenderTargetFormat::A8B8G8R8_SNORM:
  880. return impl->converters_cache
  881. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_SNORMTraits>>())
  882. .first->second.get();
  883. break;
  884. case RenderTargetFormat::A8B8G8R8_SINT:
  885. return impl->converters_cache
  886. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_SINTTraits>>())
  887. .first->second.get();
  888. break;
  889. case RenderTargetFormat::A8B8G8R8_UINT:
  890. return impl->converters_cache
  891. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_UINTTraits>>())
  892. .first->second.get();
  893. break;
  894. case RenderTargetFormat::R16G16_UNORM:
  895. return impl->converters_cache
  896. .emplace(format, std::make_unique<ConverterImpl<R16G16_UNORMTraits>>())
  897. .first->second.get();
  898. break;
  899. case RenderTargetFormat::R16G16_SNORM:
  900. return impl->converters_cache
  901. .emplace(format, std::make_unique<ConverterImpl<R16G16_SNORMTraits>>())
  902. .first->second.get();
  903. break;
  904. case RenderTargetFormat::R16G16_SINT:
  905. return impl->converters_cache
  906. .emplace(format, std::make_unique<ConverterImpl<R16G16_SINTTraits>>())
  907. .first->second.get();
  908. break;
  909. case RenderTargetFormat::R16G16_UINT:
  910. return impl->converters_cache
  911. .emplace(format, std::make_unique<ConverterImpl<R16G16_UINTTraits>>())
  912. .first->second.get();
  913. break;
  914. case RenderTargetFormat::R16G16_FLOAT:
  915. return impl->converters_cache
  916. .emplace(format, std::make_unique<ConverterImpl<R16G16_FLOATTraits>>())
  917. .first->second.get();
  918. break;
  919. case RenderTargetFormat::B10G11R11_FLOAT:
  920. return impl->converters_cache
  921. .emplace(format, std::make_unique<ConverterImpl<B10G11R11_FLOATTraits>>())
  922. .first->second.get();
  923. break;
  924. case RenderTargetFormat::R32_SINT:
  925. return impl->converters_cache
  926. .emplace(format, std::make_unique<ConverterImpl<R32_SINTTraits>>())
  927. .first->second.get();
  928. break;
  929. case RenderTargetFormat::R32_UINT:
  930. return impl->converters_cache
  931. .emplace(format, std::make_unique<ConverterImpl<R32_UINTTraits>>())
  932. .first->second.get();
  933. break;
  934. case RenderTargetFormat::R32_FLOAT:
  935. return impl->converters_cache
  936. .emplace(format, std::make_unique<ConverterImpl<R32_FLOATTraits>>())
  937. .first->second.get();
  938. break;
  939. case RenderTargetFormat::R5G6B5_UNORM:
  940. return impl->converters_cache
  941. .emplace(format, std::make_unique<ConverterImpl<R5G6B5_UNORMTraits>>())
  942. .first->second.get();
  943. break;
  944. case RenderTargetFormat::A1R5G5B5_UNORM:
  945. return impl->converters_cache
  946. .emplace(format, std::make_unique<ConverterImpl<A1R5G5B5_UNORMTraits>>())
  947. .first->second.get();
  948. break;
  949. case RenderTargetFormat::R8G8_UNORM:
  950. return impl->converters_cache
  951. .emplace(format, std::make_unique<ConverterImpl<R8G8_UNORMTraits>>())
  952. .first->second.get();
  953. break;
  954. case RenderTargetFormat::R8G8_SNORM:
  955. return impl->converters_cache
  956. .emplace(format, std::make_unique<ConverterImpl<R8G8_SNORMTraits>>())
  957. .first->second.get();
  958. break;
  959. case RenderTargetFormat::R8G8_SINT:
  960. return impl->converters_cache
  961. .emplace(format, std::make_unique<ConverterImpl<R8G8_SINTTraits>>())
  962. .first->second.get();
  963. break;
  964. case RenderTargetFormat::R8G8_UINT:
  965. return impl->converters_cache
  966. .emplace(format, std::make_unique<ConverterImpl<R8G8_UINTTraits>>())
  967. .first->second.get();
  968. break;
  969. case RenderTargetFormat::R16_UNORM:
  970. return impl->converters_cache
  971. .emplace(format, std::make_unique<ConverterImpl<R16_UNORMTraits>>())
  972. .first->second.get();
  973. break;
  974. case RenderTargetFormat::R16_SNORM:
  975. return impl->converters_cache
  976. .emplace(format, std::make_unique<ConverterImpl<R16_SNORMTraits>>())
  977. .first->second.get();
  978. break;
  979. case RenderTargetFormat::R16_SINT:
  980. return impl->converters_cache
  981. .emplace(format, std::make_unique<ConverterImpl<R16_SINTTraits>>())
  982. .first->second.get();
  983. break;
  984. case RenderTargetFormat::R16_UINT:
  985. return impl->converters_cache
  986. .emplace(format, std::make_unique<ConverterImpl<R16_UINTTraits>>())
  987. .first->second.get();
  988. break;
  989. case RenderTargetFormat::R16_FLOAT:
  990. return impl->converters_cache
  991. .emplace(format, std::make_unique<ConverterImpl<R16_FLOATTraits>>())
  992. .first->second.get();
  993. break;
  994. case RenderTargetFormat::R8_UNORM:
  995. return impl->converters_cache
  996. .emplace(format, std::make_unique<ConverterImpl<R8_UNORMTraits>>())
  997. .first->second.get();
  998. break;
  999. case RenderTargetFormat::R8_SNORM:
  1000. return impl->converters_cache
  1001. .emplace(format, std::make_unique<ConverterImpl<R8_SNORMTraits>>())
  1002. .first->second.get();
  1003. break;
  1004. case RenderTargetFormat::R8_SINT:
  1005. return impl->converters_cache
  1006. .emplace(format, std::make_unique<ConverterImpl<R8_SINTTraits>>())
  1007. .first->second.get();
  1008. break;
  1009. case RenderTargetFormat::R8_UINT:
  1010. return impl->converters_cache
  1011. .emplace(format, std::make_unique<ConverterImpl<R8_UINTTraits>>())
  1012. .first->second.get();
  1013. break;
  1014. default: {
  1015. UNIMPLEMENTED_MSG("This format {} converter is not implemented", format);
  1016. return impl->converters_cache.emplace(format, std::make_unique<NullConverter>())
  1017. .first->second.get();
  1018. }
  1019. }
  1020. }
  1021. } // namespace Tegra::Engines::Blitter