简体   繁体   中英

How can I use compressed DDS format textures with mip mapping?

Until now, I was setting my D3D11_TEXTURE2D_DESC::MipLevels to 1, but in order to improve performance and quality of terrain textures, I've tried to swap it to textures with mipmaps. So this is the code I'm using to create a texture with mipmaps:

 D3D11_TEXTURE2D_DESC t2d;
ZeroMemory(&t2d, sizeof(D3D11_TEXTURE2D_DESC));

UINT BindFlags = (D3D11_BIND_SHADER_RESOURCE | (m_Header.dwMipMapCount ? D3D11_BIND_RENDER_TARGET : 0)); // if the texture has mipmaps then bind it to render target.

t2d.Format = GetDXGIFormat(m_Header.ddspf); // BC2_UNORM
t2d.Width = m_Header.dwWidth;
t2d.Height = m_Header.dwHeight;
t2d.MipLevels = !m_Header.dwMipMapCount ? 1 : 0; // if the texture has mip maps then set it to 0 in order to use them all.
t2d.ArraySize = 1;
t2d.SampleDesc.Count = 1;
t2d.Usage = D3D11_USAGE_DEFAULT;
t2d.BindFlags = BindFlags;
if(!t2d.MipLevels) // only set if the texture has mip maps.
    t2d.MiscFlags = D3D11_RESOURCE_MISC_GENERATE_MIPS;

D3D11_SUBRESOURCE_DATA sd;
ZeroMemory(&sd, sizeof(D3D11_SUBRESOURCE_DATA));

sd.pSysMem = m_DDSData;

switch (t2d.Format) {
case DXGI_FORMAT_BC1_UNORM:
    sd.SysMemPitch = 8 * (m_Header.dwWidth / 4);
    break;
case DXGI_FORMAT_BC2_UNORM:
case DXGI_FORMAT_BC3_UNORM:
    sd.SysMemPitch = 16 * (m_Header.dwWidth / 4);
    break;
case DXGI_FORMAT_R8G8B8A8_UNORM:
case DXGI_FORMAT_B8G8R8A8_UNORM:
    sd.SysMemPitch = m_Header.dwWidth * 4;
    break;
default:
    return Log("Unsupported texture format.");
}

hr = pDevice->CreateTexture2D(&t2d, &sd, &m_pTexture2D);
if (FAILED(hr))
    return Log("Failed to create texture.");

When my code runs and finds a texture with mip maps it ends up failling, and this is the error message I get on debug:

D3D11 ERROR: ID3D11Device::CreateTexture2D: The format (0x4a, BC2_UNORM) cannot be bound as a RenderTarget, or cast to a format that could be bound as a RenderTarget. Therefore this format does not support D3D11_BIND_RENDER_TARGET. [ STATE_CREATION ERROR #92: CREATETEXTURE2D_UNSUPPORTEDFORMAT]

But if it finds a texture with no mip maps, or even a texture with mip maps but I set the mip maps on the texture desciption to 1, I get no error message. As in the error message says, I'm not being able to bind the texture to the render target, but if I try to use D3D11_RESOURCE_MISC_GENERATE_MIPS I get an error message saying the texture needs to be bound to D3D11_BIND_RENDER_TARGET .

Automatic generation of mipmaps does not support Block Compressed formats. You can confirm this using CheckFormatSupport .

bool autogen = false;
UINT fmtSupport = 0;
hr = d3dDevice->CheckFormatSupport(format, &fmtSupport);
if (SUCCEEDED(hr) && (fmtSupport & D3D11_FORMAT_SUPPORT_MIP_AUTOGEN))
{
    // 10level9 feature levels do not support auto-gen mipgen for volume textures
    if ((resDim != D3D11_RESOURCE_DIMENSION_TEXTURE3D)
        || (d3dDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0))
    {
        autogen = true;
    }
}

Generally you are expected to compress your textures offline and generate mipmaps as part of that processing. These can be stored in DDS files and then loaded complete with mips at runtime.

See DirectXTex for a C++ library that supports mipmap generation, Block Compression, and a DDS codec. It includes the DDSTextureLoader module as well which is a light-weight DDS file loader.

For very large data sets, there have been alternative schemes used where the high-resolution image is compressed using some lossy format (like JPEG) which is loaded at runtime, then a software or GPU-based box filter generates the mips. Then all levels of that texture are compressed using a Fast Block Compression scheme. It doesn't have the same quality as offline compression, but for some scenarios it's worth the trade-off.

Remember that Block Compression formats have a fixed 2:1 or 4:1 compression ratio, but the advantage is that you never have to decompress them as the hardware can use it directly to render.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM