BUG: PVRTexTool, export DDS BGRA 4444 - incorrect color encoding

Steps to reproduce:

  • Create a new texture
  • Use edit individual channels to fill all channels with 0, except red which you fill with 255
  • Encode the current texture using BGRA 4444, DirectX 11 (9_3)
  • Save texture as Direct Draw Surface (*.dds)
  • Inspect the outputed file using your favourite tool
  • Repeat the procedure to test the color mask of the remaining channels



    Results:
  • Notice the DDS_HEADER_DXT10 dxgiFormat specifies DXGI_FORMAT_UNKNOWN
  • Notice the value of the first pixel is: 0x00f0 for red, 0x0f00 (green), 0xf000 (blue), 0x000f (alpha)



    Expected results:
  • The DDS_HEADER_DXT10 dxgiFormat should specify DXGI_FORMAT_B4G4R4A4_UNORM
  • The pixel value for DXGI_FORMAT_B4G4R4A4_UNORM should be: 0x0f00 for red, 0x00f0 (green), 0x000f (blue), 0xf000 (alpha)



    Tested on:

    PVRTexTool 4.04 (SDK build 3.1@2308999)

    Windows 8, (64bit)

Hi Mario,



As per the other bug you reported (http://forum.imgtec.com/discussion/2704/bug-pvrtextool-export-dds-bgra5551-incorrect-color-encoding) I believe the masks should actually be set to all zeroes, which again is true in the next release. However I am missing the DXGI format enumeration, which I have subsequently added to the code, so it should be present in future releases.



Thanks,

Tobias

Hi Tobias - Thank you for your help!



Thank you for adding DXGI_FORMAT_B4G4R4A4_UNORM to the DDS_HEADER_DXT10 output when you save a BGRA 4444, DirectX 11 (9_3). I look forward to testing the new version when it is made available!



As i mentioned in my other bug report it is the image data that is not encoded according to the specifications. On the following webpage you will find a sample implementation of a DDS loader provided by Microsoft that specified the correct color encoding of DXGI_FORMAT_B4G4R4A4_UNORM the same way I list in my expected results: 0x0f00 for red, 0x00f0 (green), 0x000f (blue), 0xf000 (alpha).



Complete code for DDSTextureLoader - Windows app development | Microsoft Learn



Search for the function GetDXGIFormat where you will find the following code snipet:

if (ISBITMASK(0x0f00, 0x00f0, 0x000f, 0xf000))
{
return DXGI_FORMAT_B4G4R4A4_UNORM;
}



You could also try to load up a DDS image exported from PVRTexTool using BGRA 4444, DirectX 11 (9_3) and render it straight without any conversion with Direct3D 11 to view the incorrect color encoding :-)

Ask me any questions if you should have trouble reproducing the bug.

Hi Mario,



Ah ok, I see what you mean. The trouble is that, the order which DX9 described (ARGB) is the order in which PVRTexLib interprets sub-byte data, whereas byte aligned data is in the opposite order. This is the same order adopted by OpenGL. This is largely due to the common access methods to this data (byte aligned data is read as an array, where element[0] would be listed first - R usually). For sub-byte data, elements are instead accessed through bitflags and shift operations, which naturally lends itself to the opposite ordering - a developer expects (0xf000) to refer to the first element, for example. In OpenGL or DX9, these non-aligned channels were described as such, though they disagreed on the order or byte-aligned data. DX11 essentially flipped all of DX9’s enumerations, without changing the underlying data order. This means that sub byte data is described in the opposite way, whereas aligned data matched.



The way I got around this for DX9 was by defining the type differently - RGBA8888 “unsigned byte” was OpenGL order, RGBA888 “unsigned integer” was DX9. Unfortunately I can’t do the same thing with DirectX 11, as there’s no 4 bit type.



So, what I’m going to do for now is simply re-document it - so the correct PVRTexLib format will be “ARGB4444”, and update the mappings appropriately. Later I’ll possibly add interfaces to set DXGI/D3D/OpenGL formats directly in the GUI and CL, as I currently do in the Library - but that’s a rather more major job unfortunately.



Does that sound like a reasonable resolution to this?



Regards,

Tobias

Hi Tobias - thank you for your help.



Are you suggesting to keep the image data encoded as it is today for 16bit texture formats - and just name the formats differently in the tool?



My wish is that PVRTexTool will output DDS image data in native DirectX 11 texture formats so that there is no need to swizzle the color channels during a post-process, loading or runtime. Will you be able to do that for DXGI_FORMAT_B4G4R4A4_UNORM and DXGI_FORMAT_B5G5R5A1_UNORM for the next release of PVRTexTool?



Once again - thank you for you help.

Hi Mario,



No the format will be the correct order for DX, but it won’t be named the same as the DX ordering. In other words, in PVRTexTool lingo it will be “ARGB4444”, but the channel order will match that of DX’s B4G4R4A4 format. I.e. no swizzling required.



Regards,

Tobias