31 #define BLOCK_SIZE (BLOCK_LEN * BLOCK_LEN)
39 #pragma warning(disable : 4201)
44 float R(
size_t uOffset)
const
53 return red_0 / 255.0f;
55 return red_1 / 255.0f;
56 float fred_0 =
red_0 / 255.0f;
57 float fred_1 =
red_1 / 255.0f;
61 return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f;
70 return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f;
76 return (
size_t) ((
data >> (3*uOffset + 16)) & 0x07);
81 data &= ~((uint64_t) 0x07 << (3*uOffset + 16));
82 data |= ((uint64_t) uIndex << (3*uOffset + 16));
100 float R(
size_t uOffset)
const
108 int8_t sred_0 = (
red_0 == -128)? -127 :
red_0;
109 int8_t sred_1 = (
red_1 == -128)? -127 :
red_1;
112 return sred_0 / 127.0f;
114 return sred_1 / 127.0f;
115 float fred_0 = sred_0 / 127.0f;
116 float fred_1 = sred_1 / 127.0f;
120 return (fred_0 * (7-uIndex) + fred_1 * uIndex) / 7.0f;
129 return (fred_0 * (5-uIndex) + fred_1 * uIndex) / 5.0f;
135 return (
size_t) ((
data >> (3*uOffset + 16)) & 0x07);
140 data &= ~((uint64_t) 0x07 << (3*uOffset + 16));
141 data |= ((uint64_t) uIndex << (3*uOffset + 16));
161 static void inline FloatToSNorm( _In_
float fVal, _Out_ int8_t *piSNorm )
163 const uint32_t dwMostNeg = ( 1 << ( 8 *
sizeof( int8_t ) - 1 ) );
174 fVal = fVal * (int8_t) ( dwMostNeg - 1 );
181 *piSNorm = (int8_t) (fVal);
190 float MAX_NORM = 1.0f;
197 float fBlockMax = theTexelsU[0];
198 float fBlockMin = theTexelsU[0];
201 if (theTexelsU[i]<fBlockMin)
203 fBlockMin = theTexelsU[i];
205 else if (theTexelsU[i]>fBlockMax)
207 fBlockMax = theTexelsU[i];
213 bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax );
218 if (!bUsing4BlockCodec)
220 OptimizeAlpha<false>(&fStart, &fEnd, theTexelsU, 8);
222 iStart = (
uint8_t) (fStart * 255.0f);
223 iEnd = (
uint8_t) (fEnd * 255.0f);
226 endpointU_1 = iStart;
230 OptimizeAlpha<false>(&fStart, &fEnd, theTexelsU, 6);
232 iStart = (
uint8_t) (fStart * 255.0f);
233 iEnd = (
uint8_t) (fEnd * 255.0f);
236 endpointU_0 = iStart;
244 float MAX_NORM = 1.0f;
251 float fBlockMax = theTexelsU[0];
252 float fBlockMin = theTexelsU[0];
255 if (theTexelsU[i]<fBlockMin)
257 fBlockMin = theTexelsU[i];
259 else if (theTexelsU[i]>fBlockMax)
261 fBlockMax = theTexelsU[i];
267 bool bUsing4BlockCodec = ( MIN_NORM == fBlockMin || MAX_NORM == fBlockMax );
272 if (!bUsing4BlockCodec)
274 OptimizeAlpha<true>(&fStart, &fEnd, theTexelsU, 8);
280 endpointU_1 = iStart;
284 OptimizeAlpha<true>(&fStart, &fEnd, theTexelsU, 6);
290 endpointU_0 = iStart;
305 _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1, _Out_ int8_t &endpointV_0, _Out_ int8_t &endpointV_1)
318 for (i = 0; i < 8; ++i)
320 rGradient[i] = pBC->DecodeFromIndex(i);
324 size_t uBestIndex = 0;
325 float fBestDelta = 100000;
326 for (
size_t uIndex = 0; uIndex < 8; uIndex++)
328 float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]);
329 if (fCurrentDelta < fBestDelta)
332 fBestDelta = fCurrentDelta;
335 pBC->SetIndex(i, uBestIndex);
343 for (i = 0; i < 8; ++i)
345 rGradient[i] = pBC->DecodeFromIndex(i);
349 size_t uBestIndex = 0;
350 float fBestDelta = 100000;
351 for (
size_t uIndex = 0; uIndex < 8; uIndex++)
353 float fCurrentDelta = fabsf(rGradient[uIndex]-theTexelsU[i]);
354 if (fCurrentDelta < fBestDelta)
357 fBestDelta = fCurrentDelta;
360 pBC->SetIndex(i, uBestIndex);
372 _Use_decl_annotations_
376 static_assert(
sizeof(
BC4_UNORM) == 8,
"BC4_UNORM should be 8 bytes" );
378 auto pBC4 =
reinterpret_cast<const BC4_UNORM*
>(pBC);
382 #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
383 pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f);
387 _Use_decl_annotations_
391 static_assert(
sizeof(
BC4_SNORM) == 8,
"BC4_SNORM should be 8 bytes" );
393 auto pBC4 =
reinterpret_cast<const BC4_SNORM*
>(pBC);
397 #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
398 pColor[i] = XMVectorSet( pBC4->R(i), 0, 0, 1.0f);
402 _Use_decl_annotations_
405 UNREFERENCED_PARAMETER( flags );
408 static_assert(
sizeof(
BC4_UNORM) == 8,
"BC4_UNORM should be 8 bytes" );
411 auto pBC4 =
reinterpret_cast<BC4_UNORM*
>(pBC);
416 theTexelsU[i] = XMVectorGetX( pColor[i] );
423 _Use_decl_annotations_
426 UNREFERENCED_PARAMETER( flags );
429 static_assert(
sizeof(
BC4_SNORM) == 8,
"BC4_SNORM should be 8 bytes" );
432 auto pBC4 =
reinterpret_cast<BC4_SNORM*
>(pBC);
437 theTexelsU[i] = XMVectorGetX( pColor[i] );
448 _Use_decl_annotations_
452 static_assert(
sizeof(
BC4_UNORM) == 8,
"BC4_UNORM should be 8 bytes" );
454 auto pBCR =
reinterpret_cast<const BC4_UNORM*
>(pBC);
459 #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
460 pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f);
464 _Use_decl_annotations_
468 static_assert(
sizeof(
BC4_SNORM) == 8,
"BC4_SNORM should be 8 bytes" );
470 auto pBCR =
reinterpret_cast<const BC4_SNORM*
>(pBC);
475 #pragma prefast(suppress:22103, "writing blocks in two halves confuses tool")
476 pColor[i] = XMVectorSet(pBCR->R(i), pBCG->R(i), 0, 1.0f);
480 _Use_decl_annotations_
483 UNREFERENCED_PARAMETER( flags );
486 static_assert(
sizeof(
BC4_UNORM) == 8,
"BC4_UNORM should be 8 bytes" );
489 auto pBCR =
reinterpret_cast<BC4_UNORM*
>(pBC);
497 XMStoreFloat4A( &clr, pColor[i] );
498 theTexelsU[i] = clr.x;
499 theTexelsV[i] = clr.y;
514 _Use_decl_annotations_
517 UNREFERENCED_PARAMETER( flags );
520 static_assert(
sizeof(
BC4_SNORM) == 8,
"BC4_SNORM should be 8 bytes" );
523 auto pBCR =
reinterpret_cast<BC4_SNORM*
>(pBC);
531 XMStoreFloat4A( &clr, pColor[i] );
532 theTexelsU[i] = clr.x;
533 theTexelsV[i] = clr.y;
float DecodeFromIndex(size_t uIndex) const
size_t GetIndex(size_t uOffset) const
void D3DXEncodeBC5U(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)
#define NUM_PIXELS_PER_BLOCK
_In_ size_t _In_ DXGI_FORMAT _In_ size_t _In_ DXGI_FORMAT _In_ DWORD flags
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)
float R(size_t uOffset) const
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 SetIndex(size_t uOffset, size_t uIndex)
static void FindClosestUNORM(_Inout_ BC4_UNORM *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
void D3DXDecodeBC4U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(8) const uint8_t *pBC)
static void FindEndPointsBC4S(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1)
static void FindEndPointsBC5S(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[], _Out_ int8_t &endpointU_0, _Out_ int8_t &endpointU_1, _Out_ int8_t &endpointV_0, _Out_ int8_t &endpointV_1)
void D3DXDecodeBC5U(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC)
size_t GetIndex(size_t uOffset) const
float DecodeFromIndex(size_t uIndex) const
static void FindEndPointsBC4U(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1)
_In_ size_t _In_ DXGI_FORMAT _In_reads_(count) const XMVECTOR *pSource
static void FloatToSNorm(_In_ float fVal, _Out_ int8_t *piSNorm)
void SetIndex(size_t uOffset, size_t uIndex)
static void FindEndPointsBC5U(_In_reads_(BLOCK_SIZE) const float theTexelsU[], _In_reads_(BLOCK_SIZE) const float theTexelsV[], _Out_ uint8_t &endpointU_0, _Out_ uint8_t &endpointU_1, _Out_ uint8_t &endpointV_0, _Out_ uint8_t &endpointV_1)
float R(size_t uOffset) const
void D3DXDecodeBC5S(_Out_writes_(NUM_PIXELS_PER_BLOCK) XMVECTOR *pColor, _In_reads_(16) const uint8_t *pBC)
static void FindClosestSNORM(_Inout_ BC4_SNORM *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const float theTexelsU[])
void D3DXEncodeBC5S(_Out_writes_(16) uint8_t *pBC, _In_reads_(NUM_PIXELS_PER_BLOCK) const XMVECTOR *pColor, _In_ DWORD flags)