ConvectionKernels_UnfinishedEndpoints.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #pragma once
  2. #include "ConvectionKernels_Util.h"
  3. namespace cvtt
  4. {
  5. namespace Internal
  6. {
  7. template<int TVectorSize>
  8. class UnfinishedEndpoints
  9. {
  10. public:
  11. typedef ParallelMath::Float MFloat;
  12. typedef ParallelMath::UInt16 MUInt16;
  13. typedef ParallelMath::UInt15 MUInt15;
  14. typedef ParallelMath::SInt16 MSInt16;
  15. typedef ParallelMath::SInt32 MSInt32;
  16. UnfinishedEndpoints()
  17. {
  18. }
  19. UnfinishedEndpoints(const MFloat *base, const MFloat *offset)
  20. {
  21. for (int ch = 0; ch < TVectorSize; ch++)
  22. m_base[ch] = base[ch];
  23. for (int ch = 0; ch < TVectorSize; ch++)
  24. m_offset[ch] = offset[ch];
  25. }
  26. UnfinishedEndpoints(const UnfinishedEndpoints& other)
  27. {
  28. for (int ch = 0; ch < TVectorSize; ch++)
  29. m_base[ch] = other.m_base[ch];
  30. for (int ch = 0; ch < TVectorSize; ch++)
  31. m_offset[ch] = other.m_offset[ch];
  32. }
  33. void FinishHDRUnsigned(int tweak, int range, MSInt16 *outEP0, MSInt16 *outEP1, ParallelMath::RoundTowardNearestForScope *roundingMode)
  34. {
  35. float tweakFactors[2];
  36. Util::ComputeTweakFactors(tweak, range, tweakFactors);
  37. for (int ch = 0; ch < TVectorSize; ch++)
  38. {
  39. MUInt15 channelEPs[2];
  40. for (int epi = 0; epi < 2; epi++)
  41. {
  42. MFloat f = ParallelMath::Clamp(m_base[ch] + m_offset[ch] * tweakFactors[epi], 0.0f, 31743.0f);
  43. channelEPs[epi] = ParallelMath::RoundAndConvertToU15(f, roundingMode);
  44. }
  45. outEP0[ch] = ParallelMath::LosslessCast<MSInt16>::Cast(channelEPs[0]);
  46. outEP1[ch] = ParallelMath::LosslessCast<MSInt16>::Cast(channelEPs[1]);
  47. }
  48. }
  49. void FinishHDRSigned(int tweak, int range, MSInt16* outEP0, MSInt16* outEP1, ParallelMath::RoundTowardNearestForScope* roundingMode)
  50. {
  51. float tweakFactors[2];
  52. Util::ComputeTweakFactors(tweak, range, tweakFactors);
  53. for (int ch = 0; ch < TVectorSize; ch++)
  54. {
  55. MSInt16 channelEPs[2];
  56. for (int epi = 0; epi < 2; epi++)
  57. {
  58. MFloat f = ParallelMath::Clamp(m_base[ch] + m_offset[ch] * tweakFactors[epi], -31743.0f, 31743.0f);
  59. channelEPs[epi] = ParallelMath::RoundAndConvertToS16(f, roundingMode);
  60. }
  61. outEP0[ch] = channelEPs[0];
  62. outEP1[ch] = channelEPs[1];
  63. }
  64. }
  65. void FinishLDR(int tweak, int range, MUInt15* outEP0, MUInt15* outEP1)
  66. {
  67. ParallelMath::RoundTowardNearestForScope roundingMode;
  68. float tweakFactors[2];
  69. Util::ComputeTweakFactors(tweak, range, tweakFactors);
  70. for (int ch = 0; ch < TVectorSize; ch++)
  71. {
  72. MFloat ep0f = ParallelMath::Clamp(m_base[ch] + m_offset[ch] * tweakFactors[0], 0.0f, 255.0f);
  73. MFloat ep1f = ParallelMath::Clamp(m_base[ch] + m_offset[ch] * tweakFactors[1], 0.0f, 255.0f);
  74. outEP0[ch] = ParallelMath::RoundAndConvertToU15(ep0f, &roundingMode);
  75. outEP1[ch] = ParallelMath::RoundAndConvertToU15(ep1f, &roundingMode);
  76. }
  77. }
  78. template<int TNewVectorSize>
  79. UnfinishedEndpoints<TNewVectorSize> ExpandTo(float filler)
  80. {
  81. MFloat newBase[TNewVectorSize];
  82. MFloat newOffset[TNewVectorSize];
  83. for (int ch = 0; ch < TNewVectorSize && ch < TVectorSize; ch++)
  84. {
  85. newBase[ch] = m_base[ch];
  86. newOffset[ch] = m_offset[ch];
  87. }
  88. MFloat fillerV = ParallelMath::MakeFloat(filler);
  89. for (int ch = TVectorSize; ch < TNewVectorSize; ch++)
  90. {
  91. newBase[ch] = fillerV;
  92. newOffset[ch] = ParallelMath::MakeFloatZero();
  93. }
  94. return UnfinishedEndpoints<TNewVectorSize>(newBase, newOffset);
  95. }
  96. private:
  97. MFloat m_base[TVectorSize];
  98. MFloat m_offset[TVectorSize];
  99. };
  100. }
  101. }