Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
BC.h
Go to the documentation of this file.
1 //-------------------------------------------------------------------------------------
2 // BC.h
3 //
4 // Block-compression (BC) functionality
5 //
6 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
7 // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
8 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
9 // PARTICULAR PURPOSE.
10 //
11 // Copyright (c) Microsoft Corporation. All rights reserved.
12 //
13 // http://go.microsoft.com/fwlink/?LinkId=248926
14 //-------------------------------------------------------------------------------------
15 
16 #if defined(_MSC_VER) && (_MSC_VER > 1000)
17 #pragma once
18 #endif
19 
20 #include <assert.h>
21 #include <directxmath.h>
22 #include <directxpackedvector.h>
23 
24 namespace DirectX
25 {
26 
27 //-------------------------------------------------------------------------------------
28 // Constants
29 //-------------------------------------------------------------------------------------
30 
31 const uint16_t F16S_MASK = 0x8000; // f16 sign mask
32 const uint16_t F16EM_MASK = 0x7fff; // f16 exp & mantissa mask
33 const uint16_t F16MAX = 0x7bff; // MAXFLT bit pattern for XMHALF
34 
35 #define SIGN_EXTEND(x,nb) ((((x)&(1<<((nb)-1)))?((~0)<<(nb)):0)|(x))
36 
37 // Because these are used in SAL annotations, they need to remain macros rather than const values
38 #define NUM_PIXELS_PER_BLOCK 16
39 #define BC6H_MAX_REGIONS 2
40 #define BC6H_MAX_INDICES 16
41 #define BC7_MAX_REGIONS 3
42 #define BC7_MAX_INDICES 16
43 
44 const size_t BC6H_NUM_CHANNELS = 3;
45 const size_t BC6H_MAX_SHAPES = 32;
46 
47 const size_t BC7_NUM_CHANNELS = 4;
48 const size_t BC7_MAX_SHAPES = 64;
49 
50 const int32_t BC67_WEIGHT_MAX = 64;
51 const uint32_t BC67_WEIGHT_SHIFT = 6;
52 const int32_t BC67_WEIGHT_ROUND = 32;
53 
54 extern const int g_aWeights2[4];
55 extern const int g_aWeights3[8];
56 extern const int g_aWeights4[16];
57 
59 {
61  BC_FLAGS_DITHER_RGB = 0x10000, // Enables dithering for RGB colors for BC1-3
62  BC_FLAGS_DITHER_A = 0x20000, // Enables dithering for Alpha channel for BC1-3
63  BC_FLAGS_UNIFORM = 0x40000, // By default, uses perceptual weighting for BC1-3; this flag makes it a uniform weighting
64 };
65 
66 //-------------------------------------------------------------------------------------
67 // Structures
68 //-------------------------------------------------------------------------------------
69 class HDRColorA;
70 
71 class LDRColorA
72 {
73 public:
74  uint8_t r, g, b, a;
75 
76  LDRColorA() {}
77  LDRColorA(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a) : r(_r), g(_g), b(_b), a(_a) {}
78 
79  const uint8_t& operator [] (_In_range_(0,3) size_t uElement) const
80  {
81  switch(uElement)
82  {
83  case 0: return r;
84  case 1: return g;
85  case 2: return b;
86  case 3: return a;
87  default: assert(false); return r;
88  }
89  }
90 
91  uint8_t& operator [] (_In_range_(0,3) size_t uElement)
92  {
93  switch(uElement)
94  {
95  case 0: return r;
96  case 1: return g;
97  case 2: return b;
98  case 3: return a;
99  default: assert(false); return r;
100  }
101  }
102 
103  LDRColorA operator = (_In_ const HDRColorA& c);
104 
105  static void InterpolateRGB(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ _In_range_(2, 4) size_t wcprec, _Out_ LDRColorA& out)
106  {
107  const int* aWeights = nullptr;
108  switch(wcprec)
109  {
110  case 2: aWeights = g_aWeights2; assert( wc < 4 ); _Analysis_assume_( wc < 4 ); break;
111  case 3: aWeights = g_aWeights3; assert( wc < 8 ); _Analysis_assume_( wc < 8 ); break;
112  case 4: aWeights = g_aWeights4; assert( wc < 16 ); _Analysis_assume_( wc < 16 ); break;
113  default: assert(false); out.r = out.g = out.b = 0; return;
114  }
115  out.r = uint8_t((uint32_t(c0.r) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.r) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
116  out.g = uint8_t((uint32_t(c0.g) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.g) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
117  out.b = uint8_t((uint32_t(c0.b) * uint32_t(BC67_WEIGHT_MAX - aWeights[wc]) + uint32_t(c1.b) * uint32_t(aWeights[wc]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
118  }
119 
120  static void InterpolateA(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wa, _In_range_(2, 4) _In_ size_t waprec, _Out_ LDRColorA& out)
121  {
122  const int* aWeights = nullptr;
123  switch(waprec)
124  {
125  case 2: aWeights = g_aWeights2; assert( wa < 4 ); _Analysis_assume_( wa < 4 ); break;
126  case 3: aWeights = g_aWeights3; assert( wa < 8 ); _Analysis_assume_( wa < 8 ); break;
127  case 4: aWeights = g_aWeights4; assert( wa < 16 ); _Analysis_assume_( wa < 16 ); break;
128  default: assert(false); out.a = 0; return;
129  }
130  out.a = uint8_t((uint32_t(c0.a) * uint32_t(BC67_WEIGHT_MAX - aWeights[wa]) + uint32_t(c1.a) * uint32_t(aWeights[wa]) + BC67_WEIGHT_ROUND) >> BC67_WEIGHT_SHIFT);
131  }
132 
133  static void Interpolate(_In_ const LDRColorA& c0, _In_ const LDRColorA& c1, _In_ size_t wc, _In_ size_t wa, _In_ _In_range_(2, 4) size_t wcprec, _In_ _In_range_(2, 4) size_t waprec, _Out_ LDRColorA& out)
134  {
135  InterpolateRGB(c0, c1, wc, wcprec, out);
136  InterpolateA(c0, c1, wa, waprec, out);
137  }
138 };
139 
140 static_assert( sizeof(LDRColorA) == 4, "Unexpected packing");
141 
143 {
144 public:
145  float r, g, b, a;
146 
147 public:
149  HDRColorA(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) {}
150  HDRColorA(const HDRColorA& c) : r(c.r), g(c.g), b(c.b), a(c.a) {}
152  {
153  r = float(c.r) * (1.0f/255.0f);
154  g = float(c.g) * (1.0f/255.0f);
155  b = float(c.b) * (1.0f/255.0f);
156  a = float(c.a) * (1.0f/255.0f);
157  }
158 
159  // binary operators
160  HDRColorA operator + ( _In_ const HDRColorA& c ) const
161  {
162  return HDRColorA(r + c.r, g + c.g, b + c.b, a + c.a);
163  }
164 
165  HDRColorA operator - ( _In_ const HDRColorA& c ) const
166  {
167  return HDRColorA(r - c.r, g - c.g, b - c.b, a - c.a);
168  }
169 
170  HDRColorA operator * ( _In_ float f ) const
171  {
172  return HDRColorA(r * f, g * f, b * f, a * f);
173  }
174 
175  HDRColorA operator / ( _In_ float f ) const
176  {
177  float fInv = 1.0f / f;
178  return HDRColorA(r * fInv, g * fInv, b * fInv, a * fInv);
179  }
180 
181  float operator * ( _In_ const HDRColorA& c ) const
182  {
183  return r * c.r + g * c.g + b * c.b + a * c.a;
184  }
185 
186  // assignment operators
187  HDRColorA& operator += ( _In_ const HDRColorA& c )
188  {
189  r += c.r;
190  g += c.g;
191  b += c.b;
192  a += c.a;
193  return *this;
194  }
195 
196  HDRColorA& operator -= ( _In_ const HDRColorA& c )
197  {
198  r -= c.r;
199  g -= c.g;
200  b -= c.b;
201  a -= c.a;
202  return *this;
203  }
204 
205  HDRColorA& operator *= ( _In_ float f )
206  {
207  r *= f;
208  g *= f;
209  b *= f;
210  a *= f;
211  return *this;
212  }
213 
214  HDRColorA& operator /= ( _In_ float f )
215  {
216  float fInv = 1.0f / f;
217  r *= fInv;
218  g *= fInv;
219  b *= fInv;
220  a *= fInv;
221  return *this;
222  }
223 
225  {
226  r = (float) c.r;
227  g = (float) c.g;
228  b = (float) c.b;
229  a = (float) c.a;
230  return *this;
231  }
232 
233  HDRColorA& Clamp(_In_ float fMin, _In_ float fMax)
234  {
235  r = std::min<float>(fMax, std::max<float>(fMin, r));
236  g = std::min<float>(fMax, std::max<float>(fMin, g));
237  b = std::min<float>(fMax, std::max<float>(fMin, b));
238  a = std::min<float>(fMax, std::max<float>(fMin, a));
239  return *this;
240  }
241 
243  {
244  return LDRColorA((uint8_t) (r + 0.01f), (uint8_t) (g + 0.01f), (uint8_t) (b + 0.01f), (uint8_t) (a + 0.01f));
245  }
246 };
247 
249 {
250  LDRColorA ret;
251  HDRColorA tmp(c);
252  tmp = tmp.Clamp(0.0f, 1.0f) * 255.0f;
253  ret.r = uint8_t(tmp.r + 0.001f);
254  ret.g = uint8_t(tmp.g + 0.001f);
255  ret.b = uint8_t(tmp.b + 0.001f);
256  ret.a = uint8_t(tmp.a + 0.001f);
257  return ret;
258 }
259 
261 {
264 };
265 
267 {
270 };
271 
272 inline HDRColorA* HDRColorALerp(_Out_ HDRColorA *pOut, _In_ const HDRColorA *pC1, _In_ const HDRColorA *pC2, _In_ float s)
273 {
274  pOut->r = pC1->r + s * (pC2->r - pC1->r);
275  pOut->g = pC1->g + s * (pC2->g - pC1->g);
276  pOut->b = pC1->b + s * (pC2->b - pC1->b);
277  pOut->a = pC1->a + s * (pC2->a - pC1->a);
278  return pOut;
279 }
280 
281 #pragma pack(push,1)
282 // BC1/DXT1 compression (4 bits per texel)
283 struct D3DX_BC1
284 {
285  uint16_t rgb[2]; // 565 colors
286  uint32_t bitmap; // 2bpp rgb bitmap
287 };
288 
289 // BC2/DXT2/3 compression (8 bits per texel)
290 struct D3DX_BC2
291 {
292  uint32_t bitmap[2]; // 4bpp alpha bitmap
293  D3DX_BC1 bc1; // BC1 rgb data
294 };
295 
296 // BC3/DXT4/5 compression (8 bits per texel)
297 struct D3DX_BC3
298 {
299  uint8_t alpha[2]; // alpha values
300  uint8_t bitmap[6]; // 3bpp alpha bitmap
301  D3DX_BC1 bc1; // BC1 rgb data
302 };
303 #pragma pack(pop)
304 
305 class INTColor
306 {
307 public:
308  int r, g, b;
309  int pad;
310 
311 public:
312  INTColor() {}
313  INTColor(int nr, int ng, int nb) {r = nr; g = ng; b = nb;}
314  INTColor(const INTColor& c) {r = c.r; g = c.g; b = c.b;}
315 
316  INTColor operator - ( _In_ const INTColor& c ) const
317  {
318  return INTColor(r - c.r, g - c.g, b - c.b);
319  }
320 
321  INTColor& operator += ( _In_ const INTColor& c )
322  {
323  r += c.r;
324  g += c.g;
325  b += c.b;
326  return *this;
327  }
328 
329  INTColor& operator -= ( _In_ const INTColor& c )
330  {
331  r -= c.r;
332  g -= c.g;
333  b -= c.b;
334  return *this;
335  }
336 
337  INTColor& operator &= ( _In_ const INTColor& c )
338  {
339  r &= c.r;
340  g &= c.g;
341  b &= c.b;
342  return *this;
343  }
344 
345  int& operator [] ( _In_ uint8_t i )
346  {
347  assert(i < sizeof(INTColor) / sizeof(int));
348  _Analysis_assume_(i < sizeof(INTColor) / sizeof(int));
349  return ((int*) this)[i];
350  }
351 
352  void Set(_In_ const HDRColorA& c, _In_ bool bSigned)
353  {
354  PackedVector::XMHALF4 aF16;
355 
356  XMVECTOR v = XMLoadFloat4( (const XMFLOAT4*)& c );
357  XMStoreHalf4( &aF16, v );
358 
359  r = F16ToINT(aF16.x, bSigned);
360  g = F16ToINT(aF16.y, bSigned);
361  b = F16ToINT(aF16.z, bSigned);
362  }
363 
364  INTColor& Clamp(_In_ int iMin, _In_ int iMax)
365  {
366  r = std::min<int>(iMax, std::max<int>(iMin, r));
367  g = std::min<int>(iMax, std::max<int>(iMin, g));
368  b = std::min<int>(iMax, std::max<int>(iMin, b));
369  return *this;
370  }
371 
372  INTColor& SignExtend(_In_ const LDRColorA& Prec)
373  {
374  r = SIGN_EXTEND(r, Prec.r);
375  g = SIGN_EXTEND(g, Prec.g);
376  b = SIGN_EXTEND(b, Prec.b);
377  return *this;
378  }
379 
380  void ToF16(_Out_writes_(3) PackedVector::HALF aF16[3], _In_ bool bSigned) const
381  {
382  aF16[0] = INT2F16(r, bSigned);
383  aF16[1] = INT2F16(g, bSigned);
384  aF16[2] = INT2F16(b, bSigned);
385  }
386 
387 private:
388  static int F16ToINT(_In_ const PackedVector::HALF& f, _In_ bool bSigned)
389  {
390  uint16_t input = *((const uint16_t*) &f);
391  int out, s;
392  if(bSigned)
393  {
394  s = input & F16S_MASK;
395  input &= F16EM_MASK;
396  if(input > F16MAX) out = F16MAX;
397  else out = input;
398  out = s ? -out : out;
399  }
400  else
401  {
402  if(input & F16S_MASK) out = 0;
403  else out = input;
404  }
405  return out;
406  }
407 
408  static PackedVector::HALF INT2F16(_In_ int input, _In_ bool bSigned)
409  {
410  PackedVector::HALF h;
411  uint16_t out;
412  if(bSigned)
413  {
414  int s = 0;
415  if(input < 0)
416  {
417  s = F16S_MASK;
418  input = -input;
419  }
420  out = uint16_t(s | input);
421  }
422  else
423  {
424  assert(input >= 0 && input <= F16MAX);
425  out = (uint16_t) input;
426  }
427 
428  *((uint16_t*) &h) = out;
429  return h;
430  }
431 };
432 
433 static_assert( sizeof(INTColor) == 16, "Unexpected packing");
434 
436 {
439 };
440 
441 template< size_t SizeInBytes >
442 class CBits
443 {
444 public:
445  uint8_t GetBit(_Inout_ size_t& uStartBit) const
446  {
447  assert(uStartBit < 128);
448  _Analysis_assume_(uStartBit < 128);
449  size_t uIndex = uStartBit >> 3;
450  uint8_t ret = (m_uBits[uIndex] >> (uStartBit - (uIndex << 3))) & 0x01;
451  uStartBit++;
452  return ret;
453  }
454 
455  uint8_t GetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits) const
456  {
457  if(uNumBits == 0) return 0;
458  assert(uStartBit + uNumBits <= 128 && uNumBits <= 8);
459  _Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8);
460  uint8_t ret;
461  size_t uIndex = uStartBit >> 3;
462  size_t uBase = uStartBit - (uIndex << 3);
463  if(uBase + uNumBits > 8)
464  {
465  size_t uFirstIndexBits = 8 - uBase;
466  size_t uNextIndexBits = uNumBits - uFirstIndexBits;
467  ret = (m_uBits[uIndex] >> uBase) | ((m_uBits[uIndex+1] & ((1 << uNextIndexBits) - 1)) << uFirstIndexBits);
468  }
469  else
470  {
471  ret = (m_uBits[uIndex] >> uBase) & ((1 << uNumBits) - 1);
472  }
473  assert(ret < (1 << uNumBits));
474  uStartBit += uNumBits;
475  return ret;
476  }
477 
478  void SetBit(_Inout_ size_t& uStartBit, _In_ uint8_t uValue)
479  {
480  assert(uStartBit < 128 && uValue < 2);
481  _Analysis_assume_(uStartBit < 128 && uValue < 2);
482  size_t uIndex = uStartBit >> 3;
483  size_t uBase = uStartBit - (uIndex << 3);
484  m_uBits[uIndex] &= ~(1 << uBase);
485  m_uBits[uIndex] |= uValue << uBase;
486  uStartBit++;
487  }
488 
489  void SetBits(_Inout_ size_t& uStartBit, _In_ size_t uNumBits, _In_ uint8_t uValue)
490  {
491  if(uNumBits == 0)
492  return;
493  assert(uStartBit + uNumBits <= 128 && uNumBits <= 8);
494  _Analysis_assume_(uStartBit + uNumBits <= 128 && uNumBits <= 8);
495  assert(uValue < (1 << uNumBits));
496  size_t uIndex = uStartBit >> 3;
497  size_t uBase = uStartBit - (uIndex << 3);
498  if(uBase + uNumBits > 8)
499  {
500  size_t uFirstIndexBits = 8 - uBase;
501  size_t uNextIndexBits = uNumBits - uFirstIndexBits;
502  m_uBits[uIndex] &= ~(((1 << uFirstIndexBits) - 1) << uBase);
503  m_uBits[uIndex] |= uValue << uBase;
504  m_uBits[uIndex+1] &= ~((1 << uNextIndexBits) - 1);
505  m_uBits[uIndex+1] |= uValue >> uFirstIndexBits;
506  }
507  else
508  {
509  m_uBits[uIndex] &= ~(((1 << uNumBits) - 1) << uBase);
510  m_uBits[uIndex] |= uValue << uBase;
511  }
512  uStartBit += uNumBits;
513  }
514 
515 private:
516  uint8_t m_uBits[ SizeInBytes ];
517 };
518 
519 // BC6H compression (16 bits per texel)
520 class D3DX_BC6H : private CBits< 16 >
521 {
522 public:
523  void Decode(_In_ bool bSigned, _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA* pOut) const;
524  void Encode(_In_ bool bSigned, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
525 
526 private:
527 #pragma warning(push)
528 #pragma warning(disable : 4480)
529  enum EField : uint8_t
530  {
531  NA, // N/A
532  M, // Mode
533  D, // Shape
534  RW,
535  RX,
536  RY,
537  RZ,
538  GW,
539  GX,
540  GY,
541  GZ,
542  BW,
543  BX,
544  BY,
545  BZ,
546  };
547 #pragma warning(pop)
548 
549  struct ModeDescriptor
550  {
551  EField m_eField;
552  uint8_t m_uBit;
553  };
554 
555  struct ModeInfo
556  {
557  uint8_t uMode;
558  uint8_t uPartitions;
559  bool bTransformed;
560  uint8_t uIndexPrec;
561  LDRColorA RGBAPrec[BC6H_MAX_REGIONS][2];
562  };
563 
564 #pragma warning(push)
565 #pragma warning(disable : 4512)
566  struct EncodeParams
567  {
568  float fBestErr;
569  const bool bSigned;
570  uint8_t uMode;
571  uint8_t uShape;
572  const HDRColorA* const aHDRPixels;
574  INTColor aIPixels[NUM_PIXELS_PER_BLOCK];
575 
576  EncodeParams(const HDRColorA* const aOriginal, bool bSignedFormat) :
577  aHDRPixels(aOriginal), fBestErr(FLT_MAX), bSigned(bSignedFormat)
578  {
579  for(size_t i = 0; i < NUM_PIXELS_PER_BLOCK; ++i)
580  {
581  aIPixels[i].Set(aOriginal[i], bSigned);
582  }
583  }
584  };
585 #pragma warning(pop)
586 
587  static int Quantize(_In_ int iValue, _In_ int prec, _In_ bool bSigned);
588  static int Unquantize(_In_ int comp, _In_ uint8_t uBitsPerComp, _In_ bool bSigned);
589  static int FinishUnquantize(_In_ int comp, _In_ bool bSigned);
590 
591  static bool EndPointsFit(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[]);
592 
593  void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ const INTEndPntPair& endPts,
594  _Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]) const;
595  float MapColorsQuantized(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ const INTEndPntPair &endPts) const;
596  float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ uint8_t ch,
597  _In_ const INTEndPntPair& oldEndPts, _Out_ INTEndPntPair& newEndPts, _In_ float fOldErr, _In_ int do_b) const;
598  void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const INTColor aColors[], _In_ size_t np, _In_ float aOrgErr,
599  _In_ const INTEndPntPair &aOrgEndPts, _Out_ INTEndPntPair &aOptEndPts) const;
600  void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const float aOrgErr[],
601  _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aOrgEndPts[],
603  static void SwapIndices(_In_ const EncodeParams* pEP, _Inout_updates_all_(BC6H_MAX_REGIONS) INTEndPntPair aEndPts[],
604  _In_reads_(NUM_PIXELS_PER_BLOCK) size_t aIndices[]);
605  void AssignIndices(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[],
606  _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[],
607  _Out_writes_(BC6H_MAX_REGIONS) float aTotErr[]) const;
608  void QuantizeEndPts(_In_ const EncodeParams* pEP, _Out_writes_(BC6H_MAX_REGIONS) INTEndPntPair* qQntEndPts) const;
609  void EmitBlock(_In_ const EncodeParams* pEP, _In_reads_(BC6H_MAX_REGIONS) const INTEndPntPair aEndPts[],
610  _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndices[]);
611  void Refine(_Inout_ EncodeParams* pEP);
612 
613  static void GeneratePaletteUnquantized(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _Out_writes_(BC6H_MAX_INDICES) INTColor aPalette[]);
614  float MapColors(_In_ const EncodeParams* pEP, _In_ size_t uRegion, _In_ size_t np, _In_reads_(np) const size_t* auIndex) const;
615  float RoughMSE(_Inout_ EncodeParams* pEP) const;
616 
617 private:
618  const static ModeDescriptor ms_aDesc[][82];
619  const static ModeInfo ms_aInfo[];
620  const static int ms_aModeToInfo[];
621 };
622 
623 // BC67 compression (16b bits per texel)
624 class D3DX_BC7 : private CBits< 16 >
625 {
626 public:
628  void Encode(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA* const pIn);
629 
630 private:
631  struct ModeInfo
632  {
633  uint8_t uPartitions;
634  uint8_t uPartitionBits;
635  uint8_t uPBits;
636  uint8_t uRotationBits;
637  uint8_t uIndexModeBits;
638  uint8_t uIndexPrec;
639  uint8_t uIndexPrec2;
640  LDRColorA RGBAPrec;
641  LDRColorA RGBAPrecWithP;
642  };
643 
644 #pragma warning(push)
645 #pragma warning(disable : 4512)
646  struct EncodeParams
647  {
648  uint8_t uMode;
650  LDRColorA aLDRPixels[NUM_PIXELS_PER_BLOCK];
651  const HDRColorA* const aHDRPixels;
652 
653  EncodeParams(const HDRColorA* const aOriginal) : aHDRPixels(aOriginal) {}
654  };
655 #pragma warning(pop)
656 
657  static uint8_t Quantize(_In_ uint8_t comp, _In_ uint8_t uPrec)
658  {
659  assert(0 < uPrec && uPrec <= 8);
660  uint8_t rnd = (uint8_t) std::min<uint16_t>(255, uint16_t(comp) + (1 << (7 - uPrec)));
661  return rnd >> (8 - uPrec);
662  }
663 
664  static LDRColorA Quantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec)
665  {
666  LDRColorA q;
667  q.r = Quantize(c.r, RGBAPrec.r);
668  q.g = Quantize(c.g, RGBAPrec.g);
669  q.b = Quantize(c.b, RGBAPrec.b);
670  if(RGBAPrec.a)
671  q.a = Quantize(c.a, RGBAPrec.a);
672  else
673  q.a = 255;
674  return q;
675  }
676 
677  static uint8_t Unquantize(_In_ uint8_t comp, _In_ size_t uPrec)
678  {
679  assert(0 < uPrec && uPrec <= 8);
680  comp = comp << (8 - uPrec);
681  return comp | (comp >> uPrec);
682  }
683 
684  static LDRColorA Unquantize(_In_ const LDRColorA& c, _In_ const LDRColorA& RGBAPrec)
685  {
686  LDRColorA q;
687  q.r = Unquantize(c.r, RGBAPrec.r);
688  q.g = Unquantize(c.g, RGBAPrec.g);
689  q.b = Unquantize(c.b, RGBAPrec.b);
690  q.a = RGBAPrec.a > 0 ? Unquantize(c.a, RGBAPrec.a) : 255;
691  return q;
692  }
693 
694  void GeneratePaletteQuantized(_In_ const EncodeParams* pEP, _In_ size_t uIndexMode, _In_ const LDREndPntPair& endpts,
695  _Out_writes_(BC7_MAX_INDICES) LDRColorA aPalette[]) const;
696  float PerturbOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode,
697  _In_ size_t ch, _In_ const LDREndPntPair &old_endpts,
698  _Out_ LDREndPntPair &new_endpts, _In_ float old_err, _In_ uint8_t do_b) const;
699  void Exhaustive(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode,
700  _In_ size_t ch, _Inout_ float& fOrgErr, _Inout_ LDREndPntPair& optEndPt) const;
701  void OptimizeOne(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA colors[], _In_ size_t np, _In_ size_t uIndexMode,
702  _In_ float orig_err, _In_ const LDREndPntPair &orig_endpts, _Out_ LDREndPntPair &opt_endpts) const;
703  void OptimizeEndPoints(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode,
704  _In_reads_(BC7_MAX_REGIONS) const float orig_err[],
705  _In_reads_(BC7_MAX_REGIONS) const LDREndPntPair orig_endpts[],
706  _Out_writes_(BC7_MAX_REGIONS) LDREndPntPair opt_endpts[]) const;
707  void AssignIndices(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode,
709  _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices[], _Out_writes_(NUM_PIXELS_PER_BLOCK) size_t aIndices2[],
710  _Out_writes_(BC7_MAX_REGIONS) float afTotErr[]) const;
711  void EmitBlock(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode,
712  _In_reads_(BC7_MAX_REGIONS) const LDREndPntPair aEndPts[],
713  _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex[],
714  _In_reads_(NUM_PIXELS_PER_BLOCK) const size_t aIndex2[]);
715  float Refine(_In_ const EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uRotation, _In_ size_t uIndexMode);
716 
717  float MapColors(_In_ const EncodeParams* pEP, _In_reads_(np) const LDRColorA aColors[], _In_ size_t np, _In_ size_t uIndexMode,
718  _In_ const LDREndPntPair& endPts, _In_ float fMinErr) const;
719  static float RoughMSE(_Inout_ EncodeParams* pEP, _In_ size_t uShape, _In_ size_t uIndexMode);
720 
721 private:
722  const static ModeInfo ms_aInfo[];
723 };
724 
725 //-------------------------------------------------------------------------------------
726 #pragma warning(push)
727 #pragma warning(disable : 4127)
728 template <bool bRange> void OptimizeAlpha(float *pX, float *pY, const float *pPoints, size_t cSteps)
729 {
730  static const float pC6[] = { 5.0f/5.0f, 4.0f/5.0f, 3.0f/5.0f, 2.0f/5.0f, 1.0f/5.0f, 0.0f/5.0f };
731  static const float pD6[] = { 0.0f/5.0f, 1.0f/5.0f, 2.0f/5.0f, 3.0f/5.0f, 4.0f/5.0f, 5.0f/5.0f };
732  static const float pC8[] = { 7.0f/7.0f, 6.0f/7.0f, 5.0f/7.0f, 4.0f/7.0f, 3.0f/7.0f, 2.0f/7.0f, 1.0f/7.0f, 0.0f/7.0f };
733  static const float pD8[] = { 0.0f/7.0f, 1.0f/7.0f, 2.0f/7.0f, 3.0f/7.0f, 4.0f/7.0f, 5.0f/7.0f, 6.0f/7.0f, 7.0f/7.0f };
734 
735  const float *pC = (6 == cSteps) ? pC6 : pC8;
736  const float *pD = (6 == cSteps) ? pD6 : pD8;
737 
738  float MAX_VALUE = 1.0f;
739  float MIN_VALUE;
740  if (bRange)
741  {
742  MIN_VALUE = -1.0f;
743  }
744  else
745  {
746  MIN_VALUE = 0.0f;
747  }
748 
749  // Find Min and Max points, as starting point
750  float fX = MAX_VALUE;
751  float fY = MIN_VALUE;
752 
753  if(8 == cSteps)
754  {
755  for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
756  {
757  if(pPoints[iPoint] < fX)
758  fX = pPoints[iPoint];
759 
760  if(pPoints[iPoint] > fY)
761  fY = pPoints[iPoint];
762  }
763  }
764  else
765  {
766  for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
767  {
768  if(pPoints[iPoint] < fX && pPoints[iPoint] > MIN_VALUE)
769  fX = pPoints[iPoint];
770 
771  if(pPoints[iPoint] > fY && pPoints[iPoint] < MAX_VALUE)
772  fY = pPoints[iPoint];
773  }
774 
775  if (fX == fY)
776  {
777  fY = MAX_VALUE;
778  }
779  }
780 
781  // Use Newton's Method to find local minima of sum-of-squares error.
782  float fSteps = (float) (cSteps - 1);
783 
784  for(size_t iIteration = 0; iIteration < 8; iIteration++)
785  {
786  float fScale;
787 
788  if((fY - fX) < (1.0f / 256.0f))
789  break;
790 
791  fScale = fSteps / (fY - fX);
792 
793  // Calculate new steps
794  float pSteps[8];
795 
796  for(size_t iStep = 0; iStep < cSteps; iStep++)
797  pSteps[iStep] = pC[iStep] * fX + pD[iStep] * fY;
798 
799  if(6 == cSteps)
800  {
801  pSteps[6] = MIN_VALUE;
802  pSteps[7] = MAX_VALUE;
803  }
804 
805  // Evaluate function, and derivatives
806  float dX = 0.0f;
807  float dY = 0.0f;
808  float d2X = 0.0f;
809  float d2Y = 0.0f;
810 
811  for(size_t iPoint = 0; iPoint < NUM_PIXELS_PER_BLOCK; iPoint++)
812  {
813  float fDot = (pPoints[iPoint] - fX) * fScale;
814 
815  size_t iStep;
816 
817  if(fDot <= 0.0f)
818  iStep = ((6 == cSteps) && (pPoints[iPoint] <= fX * 0.5f)) ? 6 : 0;
819  else if(fDot >= fSteps)
820  iStep = ((6 == cSteps) && (pPoints[iPoint] >= (fY + 1.0f) * 0.5f)) ? 7 : (cSteps - 1);
821  else
822  iStep = static_cast<int32_t>(fDot + 0.5f);
823 
824 
825  if(iStep < cSteps)
826  {
827  // D3DX had this computation backwards (pPoints[iPoint] - pSteps[iStep])
828  // this fix improves RMS of the alpha component
829  float fDiff = pSteps[iStep] - pPoints[iPoint];
830 
831  dX += pC[iStep] * fDiff;
832  d2X += pC[iStep] * pC[iStep];
833 
834  dY += pD[iStep] * fDiff;
835  d2Y += pD[iStep] * pD[iStep];
836  }
837  }
838 
839  // Move endpoints
840  if(d2X > 0.0f)
841  fX -= dX / d2X;
842 
843  if(d2Y > 0.0f)
844  fY -= dY / d2Y;
845 
846  if(fX > fY)
847  {
848  float f = fX; fX = fY; fY = f;
849  }
850 
851  if((dX * dX < (1.0f / 64.0f)) && (dY * dY < (1.0f / 64.0f)))
852  break;
853  }
854 
855  *pX = (fX < MIN_VALUE) ? MIN_VALUE : (fX > MAX_VALUE) ? MAX_VALUE : fX;
856  *pY = (fY < MIN_VALUE) ? MIN_VALUE : (fY > MAX_VALUE) ? MAX_VALUE : fY;
857 }
858 #pragma warning(pop)
859 
860 
861 //-------------------------------------------------------------------------------------
862 // Functions
863 //-------------------------------------------------------------------------------------
864 
865 typedef void (*BC_DECODE)(XMVECTOR *pColor, const uint8_t *pBC);
866 typedef void (*BC_ENCODE)(uint8_t *pDXT, const XMVECTOR *pColor, DWORD flags);
867 
868 void D3DXDecodeBC1(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
869 void D3DXDecodeBC2(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
870 void D3DXDecodeBC3(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
871 void D3DXDecodeBC4U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
872 void D3DXDecodeBC4S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC);
873 void D3DXDecodeBC5U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
874 void D3DXDecodeBC5S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
875 void D3DXDecodeBC6HU(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
876 void D3DXDecodeBC6HS(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
877 void D3DXDecodeBC7(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC);
878 
879 void D3DXEncodeBC1(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ float alphaRef, _In_ DWORD flags);
880  // BC1 requires one additional parameter, so it doesn't match signature of BC_ENCODE above
881 
882 void D3DXEncodeBC2(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
883 void D3DXEncodeBC3(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
884 void D3DXEncodeBC4U(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
885 void D3DXEncodeBC4S(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
886 void D3DXEncodeBC5U(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
887 void D3DXEncodeBC5S(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
888 void D3DXEncodeBC6HU(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
889 void D3DXEncodeBC6HS(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
890 void D3DXEncodeBC7(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags);
891 
892 }; // namespace
_Use_decl_annotations_ void D3DXEncodeBC3(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
Definition: BC.cpp:939
INTColor & operator-=(_In_ const INTColor &c)
Definition: BC.h:329
HDRColorA operator+(_In_ const HDRColorA &c) const
Definition: BC.h:160
const size_t BC7_NUM_CHANNELS
Definition: BC.h:47
LDRColorA(uint8_t _r, uint8_t _g, uint8_t _b, uint8_t _a)
Definition: BC.h:77
BC_FLAGS
Definition: BC.h:58
void D3DXEncodeBC5U(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
const uint8_t & operator[](_In_range_(0, 3) size_t uElement) const
Definition: BC.h:79
void D3DXDecodeBC6HS(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC)
const uint16_t F16S_MASK
Definition: BC.h:31
INTColor & Clamp(_In_ int iMin, _In_ int iMax)
Definition: BC.h:364
#define NUM_PIXELS_PER_BLOCK
Definition: BC.h:38
void(* BC_DECODE)(XMVECTOR *pColor, const uint8_t *pBC)
Definition: BC.h:865
INTColor operator-(_In_ const INTColor &c) const
Definition: BC.h:316
LDRColorA A
Definition: BC.h:262
INTColor & operator&=(_In_ const INTColor &c)
Definition: BC.h:337
uint32_t bitmap
Definition: BC.h:286
uint8_t r
Definition: BC.h:74
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
Definition: DirectXTexP.h:170
HDRColorA B
Definition: BC.h:269
INTColor & SignExtend(_In_ const LDRColorA &Prec)
Definition: BC.h:372
_Use_decl_annotations_ void D3DXDecodeBC3(XMVECTOR *pColor, const uint8_t *pBC)
Definition: BC.cpp:897
size_t _In_ DXGI_FORMAT size_t _In_ TEXP_LEGACY_FORMAT _In_ DWORD flags assert(pDestination &&outSize > 0)
void D3DXEncodeBC4U(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
uint8_t a
Definition: BC.h:74
HDRColorA & operator/=(_In_ float f)
Definition: BC.h:214
const size_t BC6H_MAX_SHAPES
Definition: BC.h:45
uint8_t b
Definition: BC.h:74
const int32_t BC67_WEIGHT_MAX
Definition: BC.h:50
HDRColorA(const HDRColorA &c)
Definition: BC.h:150
void D3DXEncodeBC4S(_Out_writes_(8) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
void D3DXDecodeBC4S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC)
void ToF16(_Out_writes_(3) PackedVector::HALF aF16[3], _In_ bool bSigned) const
Definition: BC.h:380
HDRColorA & operator*=(_In_ float f)
Definition: BC.h:205
void D3DXEncodeBC6HU(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
const int g_aWeights3[8]
Definition: BC6HBC7.cpp:36
void D3DXDecodeBC4U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC)
uint8_t GetBits(_Inout_ size_t &uStartBit, _In_ size_t uNumBits) const
Definition: BC.h:455
void D3DXDecodeBC6HU(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC)
LDRColorA B
Definition: BC.h:263
static void InterpolateRGB(_In_ const LDRColorA &c0, _In_ const LDRColorA &c1, _In_ size_t wc, _In_ _In_range_(2, 4) size_t wcprec, _Out_ LDRColorA &out)
Definition: BC.h:105
INTColor(int nr, int ng, int nb)
Definition: BC.h:313
static void Interpolate(_In_ const LDRColorA &c0, _In_ const LDRColorA &c1, _In_ size_t wc, _In_ size_t wa, _In_ _In_range_(2, 4) size_t wcprec, _In_ _In_range_(2, 4) size_t waprec, _Out_ LDRColorA &out)
Definition: BC.h:133
#define BC6H_MAX_INDICES
Definition: BC.h:40
HDRColorA(float _r, float _g, float _b, float _a)
Definition: BC.h:149
INTColor A
Definition: BC.h:437
void Decode(_In_ bool bSigned, _Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA *pOut) const
Definition: BC6HBC7.cpp:1078
uint32_t bitmap[2]
Definition: BC.h:292
#define SIGN_EXTEND(x, nb)
Definition: BC.h:35
const size_t BC6H_NUM_CHANNELS
Definition: BC.h:44
const int32_t BC67_WEIGHT_ROUND
Definition: BC.h:52
static void InterpolateA(_In_ const LDRColorA &c0, _In_ const LDRColorA &c1, _In_ size_t wa, _In_range_(2, 4) _In_ size_t waprec, _Out_ LDRColorA &out)
Definition: BC.h:120
uint16_t rgb[2]
Definition: BC.h:285
INTColor B
Definition: BC.h:438
void D3DXDecodeBC7(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC)
D3DX_BC1 bc1
Definition: BC.h:301
uint8_t g
Definition: BC.h:74
void D3DXEncodeBC6HS(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
void D3DXDecodeBC5U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC)
#define BC7_MAX_INDICES
Definition: BC.h:42
_In_ size_t _In_ DXGI_FORMAT _Inout_updates_all_(count) XMVECTOR *pSource
HDRColorA * HDRColorALerp(_Out_ HDRColorA *pOut, _In_ const HDRColorA *pC1, _In_ const HDRColorA *pC2, _In_ float s)
Definition: BC.h:272
HDRColorA & operator+=(_In_ const HDRColorA &c)
Definition: BC.h:187
_In_ size_t _In_ const TexMetadata _In_ DWORD _Out_writes_(nImages) Image *images
HDRColorA(const LDRColorA &c)
Definition: BC.h:151
void Encode(_In_ bool bSigned, _In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *const pIn)
Definition: BC6HBC7.cpp:1239
INTColor(const INTColor &c)
Definition: BC.h:314
HDRColorA & operator=(_In_ const LDRColorA &c)
Definition: BC.h:224
const uint16_t F16MAX
Definition: BC.h:33
D3DX_BC1 bc1
Definition: BC.h:293
const size_t BC7_MAX_SHAPES
Definition: BC.h:48
function s(a)
uint8_t alpha[2]
Definition: BC.h:299
int & operator[](_In_ uint8_t i)
Definition: BC.h:345
_Use_decl_annotations_ void D3DXEncodeBC1(uint8_t *pBC, const XMVECTOR *pColor, float alphaRef, DWORD flags)
Definition: BC.cpp:729
void Set(_In_ const HDRColorA &c, _In_ bool bSigned)
Definition: BC.h:352
_In_ size_t _In_ DXGI_FORMAT _In_reads_(count) const XMVECTOR *pSource
INTColor & operator+=(_In_ const INTColor &c)
Definition: BC.h:321
LDRColorA ToLDRColorA() const
Definition: BC.h:242
HDRColorA operator-(_In_ const HDRColorA &c) const
Definition: BC.h:165
#define BC6H_MAX_REGIONS
Definition: BC.h:39
HDRColorA A
Definition: BC.h:268
void Encode(_In_reads_(NUM_PIXELS_PER_BLOCK) const HDRColorA *const pIn)
Definition: BC6HBC7.cpp:2147
void SetBit(_Inout_ size_t &uStartBit, _In_ uint8_t uValue)
Definition: BC.h:478
const uint16_t F16EM_MASK
Definition: BC.h:32
void OptimizeAlpha(float *pX, float *pY, const float *pPoints, size_t cSteps)
Definition: BC.h:728
HDRColorA & Clamp(_In_ float fMin, _In_ float fMax)
Definition: BC.h:233
const int g_aWeights2[4]
Definition: BC6HBC7.cpp:35
uint8_t GetBit(_Inout_ size_t &uStartBit) const
Definition: BC.h:445
void SetBits(_Inout_ size_t &uStartBit, _In_ size_t uNumBits, _In_ uint8_t uValue)
Definition: BC.h:489
HDRColorA operator*(_In_ float f) const
Definition: BC.h:170
void D3DXDecodeBC5S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC)
LDRColorA operator=(_In_ const HDRColorA &c)
Definition: BC.h:248
HDRColorA & operator-=(_In_ const HDRColorA &c)
Definition: BC.h:196
const uint32_t BC67_WEIGHT_SHIFT
Definition: BC.h:51
void(* BC_ENCODE)(uint8_t *pDXT, const XMVECTOR *pColor, DWORD flags)
Definition: BC.h:866
_Use_decl_annotations_ void D3DXEncodeBC2(uint8_t *pBC, const XMVECTOR *pColor, DWORD flags)
Definition: BC.cpp:820
void D3DXEncodeBC5S(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
HDRColorA operator/(_In_ float f) const
Definition: BC.h:175
const int g_aWeights4[16]
Definition: BC6HBC7.cpp:37
_Use_decl_annotations_ void D3DXDecodeBC1(XMVECTOR *pColor, const uint8_t *pBC)
Definition: BC.cpp:722
#define BC7_MAX_REGIONS
Definition: BC.h:41
void Decode(_Out_writes_(NUM_PIXELS_PER_BLOCK) HDRColorA *pOut) const
Definition: BC6HBC7.cpp:1938
void D3DXEncodeBC7(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
_Use_decl_annotations_ void D3DXDecodeBC2(XMVECTOR *pColor, const uint8_t *pBC)
Definition: BC.cpp:794
uint8_t bitmap[6]
Definition: BC.h:300