80
80
static const uint FOURCC_ATI1 = MAKEFOURCC('A', 'T', 'I', '1');
81
81
static const uint FOURCC_ATI2 = MAKEFOURCC('A', 'T', 'I', '2');
83
static const uint FOURCC_A2XY = MAKEFOURCC('A', '2', 'X', 'Y');
85
static const uint FOURCC_DX10 = MAKEFOURCC('D', 'X', '1', '0');
83
87
// 32 bit RGB formats.
84
88
static const uint D3DFMT_R8G8B8 = 20;
85
89
static const uint D3DFMT_A8R8G8B8 = 21;
279
283
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4,
287
const char * getDxgiFormatString(DXGI_FORMAT dxgiFormat)
289
#define CASE(format) case DXGI_FORMAT_##format: return #format
294
CASE(R32G32B32A32_TYPELESS);
295
CASE(R32G32B32A32_FLOAT);
296
CASE(R32G32B32A32_UINT);
297
CASE(R32G32B32A32_SINT);
299
CASE(R32G32B32_TYPELESS);
300
CASE(R32G32B32_FLOAT);
301
CASE(R32G32B32_UINT);
302
CASE(R32G32B32_SINT);
304
CASE(R16G16B16A16_TYPELESS);
305
CASE(R16G16B16A16_FLOAT);
306
CASE(R16G16B16A16_UNORM);
307
CASE(R16G16B16A16_UINT);
308
CASE(R16G16B16A16_SNORM);
309
CASE(R16G16B16A16_SINT);
311
CASE(R32G32_TYPELESS);
316
CASE(R32G8X24_TYPELESS);
317
CASE(D32_FLOAT_S8X24_UINT);
318
CASE(R32_FLOAT_X8X24_TYPELESS);
319
CASE(X32_TYPELESS_G8X24_UINT);
321
CASE(R10G10B10A2_TYPELESS);
322
CASE(R10G10B10A2_UNORM);
323
CASE(R10G10B10A2_UINT);
325
CASE(R11G11B10_FLOAT);
327
CASE(R8G8B8A8_TYPELESS);
328
CASE(R8G8B8A8_UNORM);
329
CASE(R8G8B8A8_UNORM_SRGB);
331
CASE(R8G8B8A8_SNORM);
334
CASE(R16G16_TYPELESS);
347
CASE(R24G8_TYPELESS);
348
CASE(D24_UNORM_S8_UINT);
349
CASE(R24_UNORM_X8_TYPELESS);
350
CASE(X24_TYPELESS_G8_UINT);
375
CASE(R9G9B9E5_SHAREDEXP);
377
CASE(R8G8_B8G8_UNORM);
378
CASE(G8R8_G8B8_UNORM);
382
CASE(BC1_UNORM_SRGB);
386
CASE(BC2_UNORM_SRGB);
390
CASE(BC3_UNORM_SRGB);
401
CASE(B5G5R5A1_UNORM);
402
CASE(B8G8R8A8_UNORM);
403
CASE(B8G8R8X8_UNORM);
411
const char * getD3d10ResourceDimensionString(D3D10_RESOURCE_DIMENSION resourceDimension)
413
switch(resourceDimension)
416
case D3D10_RESOURCE_DIMENSION_UNKNOWN: return "UNKNOWN";
417
case D3D10_RESOURCE_DIMENSION_BUFFER: return "BUFFER";
418
case D3D10_RESOURCE_DIMENSION_TEXTURE1D: return "TEXTURE1D";
419
case D3D10_RESOURCE_DIMENSION_TEXTURE2D: return "TEXTURE2D";
420
case D3D10_RESOURCE_DIMENSION_TEXTURE3D: return "TEXTURE3D";
282
424
/*** implementation ***/
284
426
void mem_read(Stream & mem, DDSPixelFormat & pf)
451
593
// set fourcc pixel format.
452
594
this->pf.flags = DDPF_FOURCC;
453
595
this->pf.fourcc = MAKEFOURCC(c0, c1, c2, c3);
454
this->pf.bitcount = 0;
597
if (this->pf.fourcc == FOURCC_ATI2)
599
this->pf.bitcount = FOURCC_A2XY;
603
this->pf.bitcount = 0;
455
606
this->pf.rmask = 0;
456
607
this->pf.gmask = 0;
457
608
this->pf.bmask = 0;
521
673
bool DDSHeader::hasDX10Header() const
523
return this->pf.flags == 0;
675
return this->pf.fourcc == FOURCC_DX10; // @@ This is according to AMD
676
//return this->pf.flags == 0; // @@ This is according to MS
526
679
DirectDrawSurface::DirectDrawSurface(unsigned char *mem, uint size) : stream(mem, size), header()
528
681
mem_read(stream, header);
683
// some ATI2 compressed normal maps do not have their
684
// normal flag set, so force it here (the original nvtt don't do
685
// this, but the decompressor has a -forcenormal flag)
686
if (header.pf.fourcc == FOURCC_ATI2) header.setNormalFlag(true);
531
689
DirectDrawSurface::~DirectDrawSurface()
561
719
bool DirectDrawSurface::isSupported() const
563
if (header.pf.flags & DDPF_FOURCC)
565
if (header.pf.fourcc != FOURCC_DXT1 &&
566
header.pf.fourcc != FOURCC_DXT2 &&
567
header.pf.fourcc != FOURCC_DXT3 &&
568
header.pf.fourcc != FOURCC_DXT4 &&
569
header.pf.fourcc != FOURCC_DXT5 &&
570
header.pf.fourcc != FOURCC_RXGB &&
571
header.pf.fourcc != FOURCC_ATI1 &&
572
header.pf.fourcc != FOURCC_ATI2)
574
// Unknown fourcc code.
578
else if (header.pf.flags & DDPF_RGB)
580
// All RGB formats are supported now.
721
if (header.hasDX10Header())
587
if (isTextureCube() && (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES)
589
// Cubemaps must contain all faces.
595
// @@ 3D textures not supported yet.
726
if (header.pf.flags & DDPF_FOURCC)
728
if (header.pf.fourcc != FOURCC_DXT1 &&
729
header.pf.fourcc != FOURCC_DXT2 &&
730
header.pf.fourcc != FOURCC_DXT3 &&
731
header.pf.fourcc != FOURCC_DXT4 &&
732
header.pf.fourcc != FOURCC_DXT5 &&
733
header.pf.fourcc != FOURCC_RXGB &&
734
header.pf.fourcc != FOURCC_ATI1 &&
735
header.pf.fourcc != FOURCC_ATI2)
737
// Unknown fourcc code.
741
else if (header.pf.flags & DDPF_RGB)
743
// All RGB formats are supported now.
750
if (isTextureCube() && (header.caps.caps2 & DDSCAPS2_CUBEMAP_ALL_FACES) != DDSCAPS2_CUBEMAP_ALL_FACES)
752
// Cubemaps must contain all faces.
758
// @@ 3D textures not supported yet.
808
bool DirectDrawSurface::isTexture1D() const
810
if (header.hasDX10Header())
812
return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE1D;
644
817
bool DirectDrawSurface::isTexture2D() const
646
return !isTexture3D() && !isTextureCube();
819
if (header.hasDX10Header())
821
return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE2D;
825
return !isTexture3D() && !isTextureCube();
649
829
bool DirectDrawSurface::isTexture3D() const
831
if (header.hasDX10Header())
833
return header.header10.resourceDimension == D3D10_RESOURCE_DIMENSION_TEXTURE3D;
651
837
return (header.caps.caps2 & DDSCAPS2_VOLUME) != 0;
654
841
bool DirectDrawSurface::isTextureCube() const
656
843
return (header.caps.caps2 & DDSCAPS2_CUBEMAP) != 0;
846
void DirectDrawSurface::setNormalFlag(bool b)
848
header.setNormalFlag(b);
659
851
void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
661
853
stream.seek(offset(face, mipmap));
712
if (header.pf.amask != 0)
904
// set image format: RGB or ARGB
905
// alpha channel exists if and only if the alpha mask is non-zero
906
if (header.pf.amask == 0)
908
img->setFormat(Image::Format_RGB);
714
912
img->setFormat(Image::Format_ARGB);
736
934
void DirectDrawSurface::readBlockImage(Image * img)
937
// set image format: RGB or ARGB
938
if (header.pf.fourcc == FOURCC_RXGB ||
939
header.pf.fourcc == FOURCC_ATI1 ||
940
header.pf.fourcc == FOURCC_ATI2 ||
941
header.pf.flags & DDPF_NORMAL)
943
img->setFormat(Image::Format_RGB);
947
img->setFormat(Image::Format_ARGB);
738
950
const uint w = img->width();
739
951
const uint h = img->height();
971
1183
if (header.pf.flags & DDPF_ALPHAPREMULT) printf("\t\tDDPF_ALPHAPREMULT\n");
972
1184
if (header.pf.flags & DDPF_NORMAL) printf("\t\tDDPF_NORMAL\n");
974
printf("\tFourCC: '%c%c%c%c'\n", ((header.pf.fourcc >> 0) & 0xFF), ((header.pf.fourcc >> 8) & 0xFF), ((header.pf.fourcc >> 16) & 0xFF), ((header.pf.fourcc >> 24) & 0xFF));
975
printf("\tBit count: %d\n", header.pf.bitcount);
1186
printf("\tFourCC: '%c%c%c%c'\n",
1187
((header.pf.fourcc >> 0) & 0xFF),
1188
((header.pf.fourcc >> 8) & 0xFF),
1189
((header.pf.fourcc >> 16) & 0xFF),
1190
((header.pf.fourcc >> 24) & 0xFF));
1191
if ((header.pf.fourcc & DDPF_FOURCC) && (header.pf.bitcount != 0))
1193
printf("\tSwizzle: '%c%c%c%c'\n",
1194
(header.pf.bitcount >> 0) & 0xFF,
1195
(header.pf.bitcount >> 8) & 0xFF,
1196
(header.pf.bitcount >> 16) & 0xFF,
1197
(header.pf.bitcount >> 24) & 0xFF);
1201
printf("\tBit count: %d\n", header.pf.bitcount);
976
1203
printf("\tRed mask: 0x%.8X\n", header.pf.rmask);
977
1204
printf("\tGreen mask: 0x%.8X\n", header.pf.gmask);
978
1205
printf("\tBlue mask: 0x%.8X\n", header.pf.bmask);
1003
1230
printf("\tCaps 3: 0x%.8X\n", header.caps.caps3);
1004
1231
printf("\tCaps 4: 0x%.8X\n", header.caps.caps4);
1006
if (header.pf.flags == 0)
1233
if (header.hasDX10Header())
1008
1235
printf("DX10 Header:\n");
1009
printf("\tDXGI Format: %u\n", header.header10.dxgiFormat);
1010
printf("\tResource dimension: %u\n", header.header10.resourceDimension);
1236
printf("\tDXGI Format: %u (%s)\n", header.header10.dxgiFormat, getDxgiFormatString((DXGI_FORMAT)header.header10.dxgiFormat));
1237
printf("\tResource dimension: %u (%s)\n", header.header10.resourceDimension, getD3d10ResourceDimensionString((D3D10_RESOURCE_DIMENSION)header.header10.resourceDimension));
1011
1238
printf("\tMisc flag: %u\n", header.header10.miscFlag);
1012
1239
printf("\tArray size: %u\n", header.header10.arraySize);