Skip to content

DDS Variants #10

@walbourn

Description

@walbourn

I've gotten reports for various DDS variants that I support in DirectXTex. You may or may not want to support them for this project:

        // These DXT5 variants have various swizzled channels. They are returned 'as is' to the client as BC3.
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('A', '2', 'D', '5'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('x', 'G', 'B', 'R'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'x', 'B', 'G'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'B', 'x', 'G'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('x', 'R', 'B', 'G'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'G', 'x', 'B'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('x', 'G', 'x', 'R'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G', 'X', 'R', 'B'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('G', 'R', 'X', 'B'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('R', 'X', 'G', 'B'), 0, 0, 0, 0, 0 } },
        { DXGI_FORMAT_BC3_UNORM,          CONV_FLAGS_NONE,      { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, MAKEFOURCC('B', 'R', 'G', 'X'), 0, 0, 0, 0, 0 } },
    DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_A8L8_ALT =
    { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 8, 0x00ff, 0, 0, 0xff00 };

        { DXGI_FORMAT_R8G8_UNORM,         CONV_FLAGS_NONE,      DDSPF_A8L8_ALT }, // D3DFMT_A8L8 (alternative bitcount)
    // NVTT v1 wrote these with RGB instead of LUMINANCE
    DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_L8_NVTT1 =
    { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 8, 0xff, 0, 0, 0 };

    DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_L16_NVTT1 =
    { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0xffff, 0, 0, 0 };

    DDSGLOBALCONST DDS_PIXELFORMAT DDSPF_A8L8_NVTT1 =
    { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00ff, 0, 0, 0xff00 };

        { DXGI_FORMAT_R8_UNORM,           CONV_FLAGS_NONE,      DDSPF_L8_NVTT1 }, // D3DFMT_L8
        { DXGI_FORMAT_R16_UNORM,          CONV_FLAGS_NONE,      DDSPF_L16_NVTT1  }, // D3DFMT_L16
        { DXGI_FORMAT_R8G8_UNORM,         CONV_FLAGS_NONE,      DDSPF_A8L8_NVTT1 }, // D3DFMT_A8L8
                if (flags & DDS_FLAGS_PERMISSIVE)
                {
                    // Allow cases where mipCount was computed incorrectly
                    size_t maxMips = 0;
                    std::ignore = Internal::CalculateMipLevels3D(metadata.width, metadata.height, metadata.depth, maxMips)  / Internal::CalculateMipLevels(metadata.width, metadata.height, maxMips);
                }

                    metadata.mipLevels = std::min(metadata.mipLevels, maxMips);
                }

    if (flags & DDS_FLAGS_PERMISSIVE)
    {
        // For cubemaps, DDS_HEADER_DXT10.arraySize is supposed to be 'number of cubes'.
        // This handles cases where the value is incorrectly written as the original 6*numCubes value.
        if ((mdata.miscFlags & TEX_MISC_TEXTURECUBE)
            && (convFlags & CONV_FLAGS_DX10)
            && (image.GetPixelsSize() > remaining)
            && ((mdata.arraySize % 6) == 0))
        {
            mdata.arraySize = mdata.arraySize / 6;
            hr = image.Initialize(mdata);
            if (FAILED(hr))
                return hr;

            if (image.GetPixelsSize() > remaining)
            {
                image.Release();
                return HRESULT_E_HANDLE_EOF;
            }
        }
    }
        // Verify header to validate DDS file
        if (flags & DDS_FLAGS_PERMISSIVE)
        {
            if (pHeader->size != 24 /* Known variant */
                && pHeader->size != sizeof(DDS_HEADER))
            {
                return HRESULT_E_NOT_SUPPORTED;
            }
        }
        else if (pHeader->size != sizeof(DDS_HEADER))
        {
            return HRESULT_E_NOT_SUPPORTED;
        }

        if (flags & DDS_FLAGS_PERMISSIVE)
        {
            if (pHeader->ddspf.size != 0 /* Known variant */
                && pHeader->ddspf.size != 24 /* Known variant */
                && pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT))
            {
                return HRESULT_E_NOT_SUPPORTED;
            }
        }
        else if (pHeader->ddspf.size != sizeof(DDS_PIXELFORMAT))
        {
            return HRESULT_E_NOT_SUPPORTED;
        }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions