DXGI_ format name for DXT1 and DXT4 image formats?

Mar 25, 2013 at 3:36 PM
Edited Mar 25, 2013 at 4:36 PM
I'm hoping to use the library to convert data from xml-formatted source data into something I can display. The app is using Qt, so I'll need to make a QPixmap from it.

I'm thinking I can use LoadFromDDSMemory on the raw data, but this needs the file format specified. All I know at the moment is the app is DX9 only and the format name is normally one of DXT1 or DXT4 (depending on purpose). The source data does not have a DX header as far as I can tell.

Can you help point me in the right direction?

Thanks, Ruth


[[Additional Info: I have as source data: width, height, format, pixel data, is byteflipped. raw data arrives in 8-byte chunks which I'm storing in a long* array. Format is source app specific. Code so far:
DirectX::Image img;
img.width = tw;
img.height = th;
img.format = DXGI_xxxx;
img.pixels = (uint8_t *)pixelData;
DirectX::ComputePitch(img.format, tw, th, img.rowPitch, img.slicePitch);
]]
Mar 25, 2013 at 4:36 PM
I found out a bit more : DXGI_FORMAT_BC1_UNORM_SRGB is DXT1 and DXGI_FORMAT_BC2_UNORM_SRGB is DXT3, I think...
Coordinator
Mar 25, 2013 at 6:24 PM
This page lists the mapping between D3D9 and D3D11 texture formats:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb205073(v=vs.85).aspx#mapping_texture_formats
Coordinator
Mar 25, 2013 at 6:44 PM
Edited Mar 25, 2013 at 6:46 PM
Shawn's like is the comprehensive list for porting, and you can find more information specifically on compressed formats here.

DX9-era BC1, BC2, and BC3
FourCC "DXT1" is either BC1_UNORM or BC1_UNORM_SRGB depending on the source data (the format doesn't specify colorspace)

FourCC "DXT2" is BC2_UNORM or BC2_UNORM_SRGB with premultiplied alpha. FourCC "DXT3" is BC2_UNORM or BC2_UNORM_SRGB with straight alpha. Premultiplied alpha is another aspect of the application usage not the format.

FourCC "DXT4" is BC3_UNORM or BC3_UNORM_SRGB with premultiplied alpha. FourCC "DXT5" is BC3_UNORM or BC3_UNORM_SRGB with straight alpha.

DX10-era BC4 & BC5
BC4_UNORM is stored using legacy formats as either FourCC "ATI1" or "BC4U". BC4_SNORM is FourCC "BC4S".

BC5_UNORM is stored using legacy formats as either FourCC "ATI2" or "BC5U". BC5_SNORM is FourCC "BC5S".

DX11-era BC6H & BC7
There are no FourCC legacy formats for DX11 era. They are always written as "DX10" extended headers.
Mar 25, 2013 at 7:21 PM
Edited Mar 25, 2013 at 7:27 PM
Thank you both for your input. I think I found the page Shawn posted between my initial and second post, but it's good to get confirmation.

I am struggling now to convert my data; I have looked through the library and can see all sorts of hopeful functions but all are "static": _CopyImage and _CopyScanline are the ones I would most like to use.

Where I've got to: data comes in as distinct blobs of pixel data with separately-specified metadata, with md and blob for each mip level. I have got to the point that I'm making an Image for each mip level, with a separately-alloc'd long[] buffer for the pixel data. After this, it seemed good to do:
//for(each mip map in source) { read and initialise imgSet[i] }

DirectX::ScratchImage sc;
HRESULT hr = sc.InitializeArrayFromImages(imgSet, numMips, false);

DirectX::ScratchImage decomp;
DirectX::Decompress(sc.GetImages()[0], DXGI_FORMAT_UNKNOWN, decomp);

const DirectX::TexMetadata &tmd = decomp.GetMetadata();
QSize imgSz(tmd.width, tmd.height);
QImage *texImg = new QImage(imgSz, QImage::Format_ARGB32_Premultiplied);
to first:
  • make a single ScratchImage for the mip collection;
  • Decompress the data from the largest mip (pro tem) into a new ScratchImage [using format_unknown: it might be better to use BC3_UNORM ? ]
I was then planning to memcpy scanlines into my QImage, at least that was the plan. However although QImage offers bytesPerLine() and uchar *QImage::scanLine (int i) functions which look useful for this, I can't seem to get access to the corresponding info for the source.

I could go hack the library but that seems bad somehow... Any ideas?

Forgot to ask: Having initialised my ScratchImage from the imSet[] array with it's pointers to heap-based pixel data, who owns that pixel data?
Mar 25, 2013 at 8:24 PM
Edited Mar 25, 2013 at 8:25 PM
Sorry.... link refreshed. :(
Coordinator
Mar 25, 2013 at 11:42 PM
What is your goal here? Are you just trying to load the content to a Direct3D 11 device, or are you trying to convert to a standard DDS file?

ScratchImage's whole point in life is to own memory. After you do the decompress, you can throw out sc and only keep decomp for example.

You really need to specify what format you want decomp to be in because you aren't telling QImage a format.
Mar 26, 2013 at 1:32 AM
My goal is to decompress the image from its almost-dds in memory form (i.e. dds with no header) into something I can display with QImage in my app. That is, neither loading into a Direct3D device nor writing it to (any sort of) file.

Your comment about specifying a format: do you mean don't use FORMAT_UNKNOWN so that it's known to match the QImage format because I'm not telling QImage what format the Decompress wrote the data in? That was the basis of my "better use BC3_UNORM" comment, though BC3 would be a compressed form: B8G8R8A8_UNORM would presumably be the correct one.

Thanks for the confirmation about ScratchImage memory.
Coordinator
Mar 26, 2013 at 9:38 PM
FORMAT_UNKNOWN tells DirectXTex to "Pick something that's a good match for the source BC format". You are actually explicitly requiring it be B8G8R8A8_UNORM or your QImage constructor will get the wrong results.
DirectX::ScratchImage decomp;
DirectX::Decompress(sc.GetImages()[0], DXGI_FORMAT_B8G8R8A8_UNORM, decomp);
Note with the latest release of DirectXTex you'll want that last line to be:
QImage *texImg = new QImage(imgSz, tmd.IsPMAlpha() ? QImage::Format_ARGB32_Premultiplied : QImage:Format_ARGB32 );