converter.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  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::R, Swizzle::B, Swizzle::G, Swizzle::A};
  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::R, Swizzle::G, Swizzle::B, Swizzle::A};
  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::R, Swizzle::G, Swizzle::B, Swizzle::A};
  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::R, Swizzle::G, Swizzle::B, Swizzle::A};
  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::R, Swizzle::G, Swizzle::B, Swizzle::A};
  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::R, Swizzle::G, Swizzle::B, Swizzle::A};
  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::R, Swizzle::G, Swizzle::B, Swizzle::A};
  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::R, Swizzle::G, Swizzle::B, Swizzle::A};
  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::R,
  195. Swizzle::G};
  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::R,
  203. Swizzle::G};
  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::R,
  211. Swizzle::G};
  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::R, Swizzle::G, Swizzle::B, Swizzle::None};
  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::A, Swizzle::R, Swizzle::G, Swizzle::B};
  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::A, Swizzle::R, Swizzle::G, Swizzle::B};
  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 = {2, 10, 10, 10};
  242. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  243. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  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 = {2, 10, 10, 10};
  250. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  251. Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R};
  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::A, Swizzle::B, Swizzle::G, Swizzle::R};
  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::A, Swizzle::B, Swizzle::G, Swizzle::R};
  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::A, Swizzle::B, Swizzle::G, Swizzle::R};
  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::A, Swizzle::B, Swizzle::G, Swizzle::R};
  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::A, Swizzle::B, Swizzle::G, Swizzle::R};
  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::R,
  299. Swizzle::G};
  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::R,
  307. Swizzle::G};
  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::R,
  315. Swizzle::G};
  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::R,
  323. Swizzle::G};
  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::R,
  331. Swizzle::G};
  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 = {10, 11, 11};
  338. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  339. Swizzle::B, Swizzle::G, Swizzle::R};
  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 X8R8G8B8_UNORMTraits {
  363. static constexpr size_t num_components = 4;
  364. static constexpr std::array<ComponentType, num_components> component_types = {
  365. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  366. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  367. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  368. Swizzle::None, Swizzle::R, Swizzle::G, Swizzle::B};
  369. };
  370. struct X8R8G8B8_SRGBTraits {
  371. static constexpr size_t num_components = 4;
  372. static constexpr std::array<ComponentType, num_components> component_types = {
  373. ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB};
  374. static constexpr std::array<size_t, num_components> component_sizes = {8, 8, 8, 8};
  375. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  376. Swizzle::None, Swizzle::R, Swizzle::G, Swizzle::B};
  377. };
  378. struct R5G6B5_UNORMTraits {
  379. static constexpr size_t num_components = 3;
  380. static constexpr std::array<ComponentType, num_components> component_types = {
  381. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  382. static constexpr std::array<size_t, num_components> component_sizes = {5, 6, 5};
  383. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  384. Swizzle::R, Swizzle::G, Swizzle::B};
  385. };
  386. struct A1R5G5B5_UNORMTraits {
  387. static constexpr size_t num_components = 4;
  388. static constexpr std::array<ComponentType, num_components> component_types = {
  389. ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM};
  390. static constexpr std::array<size_t, num_components> component_sizes = {1, 5, 5, 5};
  391. static constexpr std::array<Swizzle, num_components> component_swizzle = {
  392. Swizzle::A, Swizzle::R, Swizzle::G, Swizzle::B};
  393. };
  394. struct R8G8_UNORMTraits {
  395. static constexpr size_t num_components = 2;
  396. static constexpr std::array<ComponentType, num_components> component_types = {
  397. ComponentType::UNORM, ComponentType::UNORM};
  398. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  399. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R,
  400. Swizzle::G};
  401. };
  402. struct R8G8_SNORMTraits {
  403. static constexpr size_t num_components = 2;
  404. static constexpr std::array<ComponentType, num_components> component_types = {
  405. ComponentType::SNORM, ComponentType::SNORM};
  406. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  407. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R,
  408. Swizzle::G};
  409. };
  410. struct R8G8_SINTTraits {
  411. static constexpr size_t num_components = 2;
  412. static constexpr std::array<ComponentType, num_components> component_types = {
  413. ComponentType::SINT, ComponentType::SINT};
  414. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  415. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R,
  416. Swizzle::G};
  417. };
  418. struct R8G8_UINTTraits {
  419. static constexpr size_t num_components = 2;
  420. static constexpr std::array<ComponentType, num_components> component_types = {
  421. ComponentType::UINT, ComponentType::UINT};
  422. static constexpr std::array<size_t, num_components> component_sizes = {8, 8};
  423. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R,
  424. Swizzle::G};
  425. };
  426. struct R16_UNORMTraits {
  427. static constexpr size_t num_components = 1;
  428. static constexpr std::array<ComponentType, num_components> component_types = {
  429. ComponentType::UNORM};
  430. static constexpr std::array<size_t, num_components> component_sizes = {16};
  431. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  432. };
  433. struct R16_SNORMTraits {
  434. static constexpr size_t num_components = 1;
  435. static constexpr std::array<ComponentType, num_components> component_types = {
  436. ComponentType::SNORM};
  437. static constexpr std::array<size_t, num_components> component_sizes = {16};
  438. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  439. };
  440. struct R16_SINTTraits {
  441. static constexpr size_t num_components = 1;
  442. static constexpr std::array<ComponentType, num_components> component_types = {
  443. ComponentType::SINT};
  444. static constexpr std::array<size_t, num_components> component_sizes = {16};
  445. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  446. };
  447. struct R16_UINTTraits {
  448. static constexpr size_t num_components = 1;
  449. static constexpr std::array<ComponentType, num_components> component_types = {
  450. ComponentType::UINT};
  451. static constexpr std::array<size_t, num_components> component_sizes = {16};
  452. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  453. };
  454. struct R16_FLOATTraits {
  455. static constexpr size_t num_components = 1;
  456. static constexpr std::array<ComponentType, num_components> component_types = {
  457. ComponentType::FLOAT};
  458. static constexpr std::array<size_t, num_components> component_sizes = {16};
  459. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  460. };
  461. struct R8_UNORMTraits {
  462. static constexpr size_t num_components = 1;
  463. static constexpr std::array<ComponentType, num_components> component_types = {
  464. ComponentType::UNORM};
  465. static constexpr std::array<size_t, num_components> component_sizes = {8};
  466. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  467. };
  468. struct R8_SNORMTraits {
  469. static constexpr size_t num_components = 1;
  470. static constexpr std::array<ComponentType, num_components> component_types = {
  471. ComponentType::SNORM};
  472. static constexpr std::array<size_t, num_components> component_sizes = {8};
  473. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  474. };
  475. struct R8_SINTTraits {
  476. static constexpr size_t num_components = 1;
  477. static constexpr std::array<ComponentType, num_components> component_types = {
  478. ComponentType::SINT};
  479. static constexpr std::array<size_t, num_components> component_sizes = {8};
  480. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  481. };
  482. struct R8_UINTTraits {
  483. static constexpr size_t num_components = 1;
  484. static constexpr std::array<ComponentType, num_components> component_types = {
  485. ComponentType::UINT};
  486. static constexpr std::array<size_t, num_components> component_sizes = {8};
  487. static constexpr std::array<Swizzle, num_components> component_swizzle = {Swizzle::R};
  488. };
  489. template <class ConverterTraits>
  490. class ConverterImpl : public Converter {
  491. private:
  492. static constexpr size_t num_components = ConverterTraits::num_components;
  493. static constexpr std::array<ComponentType, num_components> component_types =
  494. ConverterTraits::component_types;
  495. static constexpr std::array<size_t, num_components> component_sizes =
  496. ConverterTraits::component_sizes;
  497. static constexpr std::array<Swizzle, num_components> component_swizzle =
  498. ConverterTraits::component_swizzle;
  499. static constexpr size_t CalculateByteSize() {
  500. size_t size = 0;
  501. for (const size_t component_size : component_sizes) {
  502. size += component_size;
  503. }
  504. const size_t power = (sizeof(size_t) * 8) - std::countl_zero(size) - 1ULL;
  505. const size_t base_size = 1ULL << power;
  506. const size_t mask = base_size - 1ULL;
  507. return ((size & mask) != 0 ? base_size << 1ULL : base_size) / 8;
  508. }
  509. static constexpr size_t total_bytes_per_pixel = CalculateByteSize();
  510. static constexpr size_t total_words_per_pixel =
  511. (total_bytes_per_pixel + sizeof(u32) - 1U) / sizeof(u32);
  512. static constexpr size_t components_per_ir_rep = 4;
  513. template <bool get_offsets>
  514. static constexpr std::array<size_t, num_components> GetBoundWordsOffsets() {
  515. std::array<size_t, num_components> result;
  516. result.fill(0);
  517. constexpr size_t total_bits_per_word = sizeof(u32) * 8;
  518. size_t accumulated_size = 0;
  519. size_t count = 0;
  520. for (size_t i = 0; i < num_components; i++) {
  521. if constexpr (get_offsets) {
  522. result[i] = accumulated_size;
  523. } else {
  524. result[i] = count;
  525. }
  526. accumulated_size += component_sizes[i];
  527. if (accumulated_size > total_bits_per_word) {
  528. if constexpr (get_offsets) {
  529. result[i] = 0;
  530. } else {
  531. result[i]++;
  532. }
  533. count++;
  534. accumulated_size = component_sizes[i];
  535. }
  536. }
  537. return result;
  538. }
  539. static constexpr std::array<size_t, num_components> bound_words = GetBoundWordsOffsets<false>();
  540. static constexpr std::array<size_t, num_components> bound_offsets =
  541. GetBoundWordsOffsets<true>();
  542. static constexpr std::array<u32, num_components> GetComponentsMask() {
  543. std::array<u32, num_components> result;
  544. for (size_t i = 0; i < num_components; i++) {
  545. result[i] = (((u32)~0) >> (8 * sizeof(u32) - component_sizes[i])) << bound_offsets[i];
  546. }
  547. return result;
  548. }
  549. static constexpr std::array<u32, num_components> component_mask = GetComponentsMask();
  550. // We are forcing inline so the compiler can SIMD the conversations, since it may do 4 function
  551. // calls, it may fail to detect the benefit of inlining.
  552. template <size_t which_component>
  553. FORCE_INLINE void ConvertToComponent(u32 which_word, f32& out_component) {
  554. const u32 value = (which_word >> bound_offsets[which_component]) &
  555. static_cast<u32>((1ULL << component_sizes[which_component]) - 1ULL);
  556. const auto sign_extend = [](u32 base_value, size_t bits) {
  557. const size_t shift_amount = sizeof(u32) * 8 - bits;
  558. s32 shifted_value = static_cast<s32>(base_value << shift_amount);
  559. return shifted_value >> shift_amount;
  560. };
  561. const auto force_to_fp16 = [](f32 base_value) {
  562. u32 tmp = std::bit_cast<u32>(base_value);
  563. constexpr size_t fp32_mantissa_bits = 23;
  564. constexpr size_t fp16_mantissa_bits = 10;
  565. constexpr size_t mantissa_mask =
  566. ~((1ULL << (fp32_mantissa_bits - fp16_mantissa_bits)) - 1ULL);
  567. tmp = tmp & static_cast<u32>(mantissa_mask);
  568. // TODO: force the exponent within the range of half float. Not needed in UNORM / SNORM
  569. return std::bit_cast<f32>(tmp);
  570. };
  571. const auto from_fp_n = [&sign_extend](u32 base_value, size_t bits, size_t mantissa) {
  572. constexpr size_t fp32_mantissa_bits = 23;
  573. size_t shift_towards = fp32_mantissa_bits - mantissa;
  574. const u32 new_value =
  575. static_cast<u32>(sign_extend(base_value, bits) << shift_towards) & (~(1U << 31));
  576. return std::bit_cast<f32>(new_value);
  577. };
  578. const auto calculate_snorm = [&]() {
  579. return static_cast<f32>(
  580. static_cast<f32>(sign_extend(value, component_sizes[which_component])) /
  581. static_cast<f32>((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL));
  582. };
  583. const auto calculate_unorm = [&]() {
  584. return static_cast<f32>(
  585. static_cast<f32>(value) /
  586. static_cast<f32>((1ULL << (component_sizes[which_component])) - 1ULL));
  587. };
  588. if constexpr (component_types[which_component] == ComponentType::SNORM) {
  589. out_component = calculate_snorm();
  590. } else if constexpr (component_types[which_component] == ComponentType::UNORM) {
  591. out_component = calculate_unorm();
  592. } else if constexpr (component_types[which_component] == ComponentType::SINT) {
  593. out_component = static_cast<f32>(
  594. static_cast<s32>(sign_extend(value, component_sizes[which_component])));
  595. } else if constexpr (component_types[which_component] == ComponentType::UINT) {
  596. out_component = static_cast<f32>(
  597. static_cast<s32>(sign_extend(value, component_sizes[which_component])));
  598. } else if constexpr (component_types[which_component] == ComponentType::SNORM_FORCE_FP16) {
  599. out_component = calculate_snorm();
  600. out_component = force_to_fp16(out_component);
  601. } else if constexpr (component_types[which_component] == ComponentType::UNORM_FORCE_FP16) {
  602. out_component = calculate_unorm();
  603. out_component = force_to_fp16(out_component);
  604. } else if constexpr (component_types[which_component] == ComponentType::FLOAT) {
  605. if constexpr (component_sizes[which_component] == 32) {
  606. out_component = std::bit_cast<f32>(value);
  607. } else if constexpr (component_sizes[which_component] == 16) {
  608. static constexpr u32 sign_mask = 0x8000;
  609. static constexpr u32 mantissa_mask = 0x8000;
  610. out_component = std::bit_cast<f32>(((value & sign_mask) << 16) |
  611. (((value & 0x7c00) + 0x1C000) << 13) |
  612. ((value & mantissa_mask) << 13));
  613. } else {
  614. out_component = from_fp_n(value, component_sizes[which_component],
  615. component_sizes[which_component] - 5);
  616. }
  617. } else if constexpr (component_types[which_component] == ComponentType::SRGB) {
  618. if constexpr (component_swizzle[which_component] == Swizzle::A) {
  619. out_component = calculate_unorm();
  620. } else if constexpr (component_sizes[which_component] == 8) {
  621. out_component = SRGB_TO_RGB_LUT[value];
  622. } else {
  623. out_component = calculate_unorm();
  624. UNIMPLEMENTED_MSG("SRGB Conversion with component sizes of {} is unimplemented",
  625. component_sizes[which_component]);
  626. }
  627. }
  628. }
  629. // We are forcing inline so the compiler can SIMD the conversations, since it may do 4 function
  630. // calls, it may fail to detect the benefit of inlining.
  631. template <size_t which_component>
  632. FORCE_INLINE void ConvertFromComponent(u32& which_word, f32 in_component) {
  633. const auto insert_to_word = [&]<typename T>(T new_word) {
  634. which_word |= (static_cast<u32>(new_word) << bound_offsets[which_component]) &
  635. component_mask[which_component];
  636. };
  637. const auto to_fp_n = [](f32 base_value, size_t bits, size_t mantissa) {
  638. constexpr size_t fp32_mantissa_bits = 23;
  639. u32 tmp_value = std::bit_cast<u32>(std::max(base_value, 0.0f));
  640. size_t shift_towards = fp32_mantissa_bits - mantissa;
  641. return tmp_value >> shift_towards;
  642. };
  643. const auto calculate_unorm = [&]() {
  644. return static_cast<u32>(
  645. static_cast<f32>(in_component) *
  646. static_cast<f32>((1ULL << (component_sizes[which_component])) - 1ULL));
  647. };
  648. if constexpr (component_types[which_component] == ComponentType::SNORM ||
  649. component_types[which_component] == ComponentType::SNORM_FORCE_FP16) {
  650. s32 tmp_word = static_cast<s32>(
  651. static_cast<f32>(in_component) *
  652. static_cast<f32>((1ULL << (component_sizes[which_component] - 1ULL)) - 1ULL));
  653. insert_to_word(tmp_word);
  654. } else if constexpr (component_types[which_component] == ComponentType::UNORM ||
  655. component_types[which_component] == ComponentType::UNORM_FORCE_FP16) {
  656. u32 tmp_word = calculate_unorm();
  657. insert_to_word(tmp_word);
  658. } else if constexpr (component_types[which_component] == ComponentType::SINT) {
  659. s32 tmp_word = static_cast<s32>(in_component);
  660. insert_to_word(tmp_word);
  661. } else if constexpr (component_types[which_component] == ComponentType::UINT) {
  662. u32 tmp_word = static_cast<u32>(in_component);
  663. insert_to_word(tmp_word);
  664. } else if constexpr (component_types[which_component] == ComponentType::FLOAT) {
  665. if constexpr (component_sizes[which_component] == 32) {
  666. u32 tmp_word = std::bit_cast<u32>(in_component);
  667. insert_to_word(tmp_word);
  668. } else if constexpr (component_sizes[which_component] == 16) {
  669. static constexpr u32 sign_mask = 0x8000;
  670. static constexpr u32 mantissa_mask = 0x03ff;
  671. static constexpr u32 exponent_mask = 0x7c00;
  672. const u32 tmp_word = std::bit_cast<u32>(in_component);
  673. const u32 half = ((tmp_word >> 16) & sign_mask) |
  674. ((((tmp_word & 0x7f800000) - 0x38000000) >> 13) & exponent_mask) |
  675. ((tmp_word >> 13) & mantissa_mask);
  676. insert_to_word(half);
  677. } else {
  678. insert_to_word(to_fp_n(in_component, component_sizes[which_component],
  679. component_sizes[which_component] - 5));
  680. }
  681. } else if constexpr (component_types[which_component] == ComponentType::SRGB) {
  682. if constexpr (component_swizzle[which_component] != Swizzle::A) {
  683. if constexpr (component_sizes[which_component] == 8) {
  684. const u32 index = calculate_unorm();
  685. in_component = RGB_TO_SRGB_LUT[index];
  686. } else {
  687. UNIMPLEMENTED_MSG("SRGB Conversion with component sizes of {} is unimplemented",
  688. component_sizes[which_component]);
  689. }
  690. }
  691. const u32 tmp_word = calculate_unorm();
  692. insert_to_word(tmp_word);
  693. }
  694. }
  695. public:
  696. void ConvertTo(std::span<const u8> input, std::span<f32> output) override {
  697. const size_t num_pixels = output.size() / components_per_ir_rep;
  698. for (size_t pixel = 0; pixel < num_pixels; pixel++) {
  699. std::array<u32, total_words_per_pixel> words{};
  700. std::memcpy(words.data(), &input[pixel * total_bytes_per_pixel], total_bytes_per_pixel);
  701. std::span<f32> new_components(&output[pixel * components_per_ir_rep],
  702. components_per_ir_rep);
  703. if constexpr (component_swizzle[0] != Swizzle::None) {
  704. ConvertToComponent<0>(words[bound_words[0]],
  705. new_components[static_cast<size_t>(component_swizzle[0])]);
  706. } else {
  707. new_components[0] = 0.0f;
  708. }
  709. if constexpr (num_components >= 2) {
  710. if constexpr (component_swizzle[1] != Swizzle::None) {
  711. ConvertToComponent<1>(
  712. words[bound_words[1]],
  713. new_components[static_cast<size_t>(component_swizzle[1])]);
  714. } else {
  715. new_components[1] = 0.0f;
  716. }
  717. } else {
  718. new_components[1] = 0.0f;
  719. }
  720. if constexpr (num_components >= 3) {
  721. if constexpr (component_swizzle[2] != Swizzle::None) {
  722. ConvertToComponent<2>(
  723. words[bound_words[2]],
  724. new_components[static_cast<size_t>(component_swizzle[2])]);
  725. } else {
  726. new_components[2] = 0.0f;
  727. }
  728. } else {
  729. new_components[2] = 0.0f;
  730. }
  731. if constexpr (num_components >= 4) {
  732. if constexpr (component_swizzle[3] != Swizzle::None) {
  733. ConvertToComponent<3>(
  734. words[bound_words[3]],
  735. new_components[static_cast<size_t>(component_swizzle[3])]);
  736. } else {
  737. new_components[3] = 0.0f;
  738. }
  739. } else {
  740. new_components[3] = 0.0f;
  741. }
  742. }
  743. }
  744. void ConvertFrom(std::span<const f32> input, std::span<u8> output) override {
  745. const size_t num_pixels = output.size() / total_bytes_per_pixel;
  746. for (size_t pixel = 0; pixel < num_pixels; pixel++) {
  747. std::span<const f32> old_components(&input[pixel * components_per_ir_rep],
  748. components_per_ir_rep);
  749. std::array<u32, total_words_per_pixel> words{};
  750. if constexpr (component_swizzle[0] != Swizzle::None) {
  751. ConvertFromComponent<0>(words[bound_words[0]],
  752. old_components[static_cast<size_t>(component_swizzle[0])]);
  753. }
  754. if constexpr (num_components >= 2) {
  755. if constexpr (component_swizzle[1] != Swizzle::None) {
  756. ConvertFromComponent<1>(
  757. words[bound_words[1]],
  758. old_components[static_cast<size_t>(component_swizzle[1])]);
  759. }
  760. }
  761. if constexpr (num_components >= 3) {
  762. if constexpr (component_swizzle[2] != Swizzle::None) {
  763. ConvertFromComponent<2>(
  764. words[bound_words[2]],
  765. old_components[static_cast<size_t>(component_swizzle[2])]);
  766. }
  767. }
  768. if constexpr (num_components >= 4) {
  769. if constexpr (component_swizzle[3] != Swizzle::None) {
  770. ConvertFromComponent<3>(
  771. words[bound_words[3]],
  772. old_components[static_cast<size_t>(component_swizzle[3])]);
  773. }
  774. }
  775. std::memcpy(&output[pixel * total_bytes_per_pixel], words.data(),
  776. total_bytes_per_pixel);
  777. }
  778. }
  779. ConverterImpl() = default;
  780. ~ConverterImpl() override = default;
  781. };
  782. struct ConverterFactory::ConverterFactoryImpl {
  783. std::unordered_map<RenderTargetFormat, std::unique_ptr<Converter>> converters_cache;
  784. };
  785. ConverterFactory::ConverterFactory() {
  786. impl = std::make_unique<ConverterFactoryImpl>();
  787. }
  788. ConverterFactory::~ConverterFactory() = default;
  789. Converter* ConverterFactory::GetFormatConverter(RenderTargetFormat format) {
  790. auto it = impl->converters_cache.find(format);
  791. if (it == impl->converters_cache.end()) [[unlikely]] {
  792. return BuildConverter(format);
  793. }
  794. return it->second.get();
  795. }
  796. class NullConverter : public Converter {
  797. public:
  798. void ConvertTo([[maybe_unused]] std::span<const u8> input, std::span<f32> output) override {
  799. std::fill(output.begin(), output.end(), 0.0f);
  800. }
  801. void ConvertFrom([[maybe_unused]] std::span<const f32> input, std::span<u8> output) override {
  802. const u8 fill_value = 0U;
  803. std::fill(output.begin(), output.end(), fill_value);
  804. }
  805. NullConverter() = default;
  806. ~NullConverter() = default;
  807. };
  808. Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) {
  809. switch (format) {
  810. case RenderTargetFormat::R32B32G32A32_FLOAT:
  811. return impl->converters_cache
  812. .emplace(format, std::make_unique<ConverterImpl<R32B32G32A32_FLOATTraits>>())
  813. .first->second.get();
  814. break;
  815. case RenderTargetFormat::R32G32B32A32_SINT:
  816. return impl->converters_cache
  817. .emplace(format, std::make_unique<ConverterImpl<R32G32B32A32_SINTTraits>>())
  818. .first->second.get();
  819. break;
  820. case RenderTargetFormat::R32G32B32A32_UINT:
  821. return impl->converters_cache
  822. .emplace(format, std::make_unique<ConverterImpl<R32G32B32A32_UINTTraits>>())
  823. .first->second.get();
  824. break;
  825. case RenderTargetFormat::R16G16B16A16_UNORM:
  826. return impl->converters_cache
  827. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_UNORMTraits>>())
  828. .first->second.get();
  829. break;
  830. case RenderTargetFormat::R16G16B16A16_SNORM:
  831. return impl->converters_cache
  832. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_SNORMTraits>>())
  833. .first->second.get();
  834. break;
  835. case RenderTargetFormat::R16G16B16A16_SINT:
  836. return impl->converters_cache
  837. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_SINTTraits>>())
  838. .first->second.get();
  839. break;
  840. case RenderTargetFormat::R16G16B16A16_UINT:
  841. return impl->converters_cache
  842. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_UINTTraits>>())
  843. .first->second.get();
  844. break;
  845. case RenderTargetFormat::R16G16B16A16_FLOAT:
  846. return impl->converters_cache
  847. .emplace(format, std::make_unique<ConverterImpl<R16G16B16A16_FLOATTraits>>())
  848. .first->second.get();
  849. break;
  850. case RenderTargetFormat::R32G32_FLOAT:
  851. return impl->converters_cache
  852. .emplace(format, std::make_unique<ConverterImpl<R32G32_FLOATTraits>>())
  853. .first->second.get();
  854. break;
  855. case RenderTargetFormat::R32G32_SINT:
  856. return impl->converters_cache
  857. .emplace(format, std::make_unique<ConverterImpl<R32G32_SINTTraits>>())
  858. .first->second.get();
  859. break;
  860. case RenderTargetFormat::R32G32_UINT:
  861. return impl->converters_cache
  862. .emplace(format, std::make_unique<ConverterImpl<R32G32_UINTTraits>>())
  863. .first->second.get();
  864. break;
  865. case RenderTargetFormat::R16G16B16X16_FLOAT:
  866. return impl->converters_cache
  867. .emplace(format, std::make_unique<ConverterImpl<R16G16B16X16_FLOATTraits>>())
  868. .first->second.get();
  869. break;
  870. case RenderTargetFormat::A8R8G8B8_UNORM:
  871. return impl->converters_cache
  872. .emplace(format, std::make_unique<ConverterImpl<A8R8G8B8_UNORMTraits>>())
  873. .first->second.get();
  874. break;
  875. case RenderTargetFormat::A8R8G8B8_SRGB:
  876. return impl->converters_cache
  877. .emplace(format, std::make_unique<ConverterImpl<A8R8G8B8_SRGBTraits>>())
  878. .first->second.get();
  879. break;
  880. case RenderTargetFormat::A2B10G10R10_UNORM:
  881. return impl->converters_cache
  882. .emplace(format, std::make_unique<ConverterImpl<A2B10G10R10_UNORMTraits>>())
  883. .first->second.get();
  884. break;
  885. case RenderTargetFormat::A2B10G10R10_UINT:
  886. return impl->converters_cache
  887. .emplace(format, std::make_unique<ConverterImpl<A2B10G10R10_UINTTraits>>())
  888. .first->second.get();
  889. break;
  890. case RenderTargetFormat::A8B8G8R8_UNORM:
  891. return impl->converters_cache
  892. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_UNORMTraits>>())
  893. .first->second.get();
  894. break;
  895. case RenderTargetFormat::A8B8G8R8_SRGB:
  896. return impl->converters_cache
  897. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_SRGBTraits>>())
  898. .first->second.get();
  899. break;
  900. case RenderTargetFormat::A8B8G8R8_SNORM:
  901. return impl->converters_cache
  902. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_SNORMTraits>>())
  903. .first->second.get();
  904. break;
  905. case RenderTargetFormat::A8B8G8R8_SINT:
  906. return impl->converters_cache
  907. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_SINTTraits>>())
  908. .first->second.get();
  909. break;
  910. case RenderTargetFormat::A8B8G8R8_UINT:
  911. return impl->converters_cache
  912. .emplace(format, std::make_unique<ConverterImpl<A8B8G8R8_UINTTraits>>())
  913. .first->second.get();
  914. break;
  915. case RenderTargetFormat::R16G16_UNORM:
  916. return impl->converters_cache
  917. .emplace(format, std::make_unique<ConverterImpl<R16G16_UNORMTraits>>())
  918. .first->second.get();
  919. break;
  920. case RenderTargetFormat::R16G16_SNORM:
  921. return impl->converters_cache
  922. .emplace(format, std::make_unique<ConverterImpl<R16G16_SNORMTraits>>())
  923. .first->second.get();
  924. break;
  925. case RenderTargetFormat::R16G16_SINT:
  926. return impl->converters_cache
  927. .emplace(format, std::make_unique<ConverterImpl<R16G16_SINTTraits>>())
  928. .first->second.get();
  929. break;
  930. case RenderTargetFormat::R16G16_UINT:
  931. return impl->converters_cache
  932. .emplace(format, std::make_unique<ConverterImpl<R16G16_UINTTraits>>())
  933. .first->second.get();
  934. break;
  935. case RenderTargetFormat::R16G16_FLOAT:
  936. return impl->converters_cache
  937. .emplace(format, std::make_unique<ConverterImpl<R16G16_FLOATTraits>>())
  938. .first->second.get();
  939. break;
  940. case RenderTargetFormat::B10G11R11_FLOAT:
  941. return impl->converters_cache
  942. .emplace(format, std::make_unique<ConverterImpl<B10G11R11_FLOATTraits>>())
  943. .first->second.get();
  944. break;
  945. case RenderTargetFormat::R32_SINT:
  946. return impl->converters_cache
  947. .emplace(format, std::make_unique<ConverterImpl<R32_SINTTraits>>())
  948. .first->second.get();
  949. break;
  950. case RenderTargetFormat::R32_UINT:
  951. return impl->converters_cache
  952. .emplace(format, std::make_unique<ConverterImpl<R32_UINTTraits>>())
  953. .first->second.get();
  954. break;
  955. case RenderTargetFormat::R32_FLOAT:
  956. return impl->converters_cache
  957. .emplace(format, std::make_unique<ConverterImpl<R32_FLOATTraits>>())
  958. .first->second.get();
  959. break;
  960. case RenderTargetFormat::X8R8G8B8_UNORM:
  961. return impl->converters_cache
  962. .emplace(format, std::make_unique<ConverterImpl<X8R8G8B8_UNORMTraits>>())
  963. .first->second.get();
  964. break;
  965. case RenderTargetFormat::X8R8G8B8_SRGB:
  966. return impl->converters_cache
  967. .emplace(format, std::make_unique<ConverterImpl<X8R8G8B8_SRGBTraits>>())
  968. .first->second.get();
  969. break;
  970. case RenderTargetFormat::R5G6B5_UNORM:
  971. return impl->converters_cache
  972. .emplace(format, std::make_unique<ConverterImpl<R5G6B5_UNORMTraits>>())
  973. .first->second.get();
  974. break;
  975. case RenderTargetFormat::A1R5G5B5_UNORM:
  976. return impl->converters_cache
  977. .emplace(format, std::make_unique<ConverterImpl<A1R5G5B5_UNORMTraits>>())
  978. .first->second.get();
  979. break;
  980. case RenderTargetFormat::R8G8_UNORM:
  981. return impl->converters_cache
  982. .emplace(format, std::make_unique<ConverterImpl<R8G8_UNORMTraits>>())
  983. .first->second.get();
  984. break;
  985. case RenderTargetFormat::R8G8_SNORM:
  986. return impl->converters_cache
  987. .emplace(format, std::make_unique<ConverterImpl<R8G8_SNORMTraits>>())
  988. .first->second.get();
  989. break;
  990. case RenderTargetFormat::R8G8_SINT:
  991. return impl->converters_cache
  992. .emplace(format, std::make_unique<ConverterImpl<R8G8_SINTTraits>>())
  993. .first->second.get();
  994. break;
  995. case RenderTargetFormat::R8G8_UINT:
  996. return impl->converters_cache
  997. .emplace(format, std::make_unique<ConverterImpl<R8G8_UINTTraits>>())
  998. .first->second.get();
  999. break;
  1000. case RenderTargetFormat::R16_UNORM:
  1001. return impl->converters_cache
  1002. .emplace(format, std::make_unique<ConverterImpl<R16_UNORMTraits>>())
  1003. .first->second.get();
  1004. break;
  1005. case RenderTargetFormat::R16_SNORM:
  1006. return impl->converters_cache
  1007. .emplace(format, std::make_unique<ConverterImpl<R16_SNORMTraits>>())
  1008. .first->second.get();
  1009. break;
  1010. case RenderTargetFormat::R16_SINT:
  1011. return impl->converters_cache
  1012. .emplace(format, std::make_unique<ConverterImpl<R16_SINTTraits>>())
  1013. .first->second.get();
  1014. break;
  1015. case RenderTargetFormat::R16_UINT:
  1016. return impl->converters_cache
  1017. .emplace(format, std::make_unique<ConverterImpl<R16_UINTTraits>>())
  1018. .first->second.get();
  1019. break;
  1020. case RenderTargetFormat::R16_FLOAT:
  1021. return impl->converters_cache
  1022. .emplace(format, std::make_unique<ConverterImpl<R16_FLOATTraits>>())
  1023. .first->second.get();
  1024. break;
  1025. case RenderTargetFormat::R8_UNORM:
  1026. return impl->converters_cache
  1027. .emplace(format, std::make_unique<ConverterImpl<R8_UNORMTraits>>())
  1028. .first->second.get();
  1029. break;
  1030. case RenderTargetFormat::R8_SNORM:
  1031. return impl->converters_cache
  1032. .emplace(format, std::make_unique<ConverterImpl<R8_SNORMTraits>>())
  1033. .first->second.get();
  1034. break;
  1035. case RenderTargetFormat::R8_SINT:
  1036. return impl->converters_cache
  1037. .emplace(format, std::make_unique<ConverterImpl<R8_SINTTraits>>())
  1038. .first->second.get();
  1039. break;
  1040. case RenderTargetFormat::R8_UINT:
  1041. return impl->converters_cache
  1042. .emplace(format, std::make_unique<ConverterImpl<R8_UINTTraits>>())
  1043. .first->second.get();
  1044. break;
  1045. default: {
  1046. UNIMPLEMENTED_MSG("This format {} converter is not implemented", format);
  1047. return impl->converters_cache.emplace(format, std::make_unique<NullConverter>())
  1048. .first->second.get();
  1049. }
  1050. }
  1051. }
  1052. } // namespace Tegra::Engines::Blitter