How to turn mipmap data into a bitmap?

0

I have a .DDS texture file with a format of DXGI_FORMAT_BC3_UNORM that contains 10 mipmaps which I have linked here:

https://1drv.ms/u/s!AiGFMy6hVmtN1Ba3UZsc8682VcEO

I would like to display each individual mipmap of this texture to my XAML app's UI, so I need to convert them to bitmaps.

I am getting the data for each mipmap from the 5th parameter of the DirectX::LoadDDSTextureFromMemory function from DirectXTK12 helper library which returns a std::vector<D3D12_SUBRESOURCE_DATA> filled with the data for all 10 mipmaps.

I am able to turn the highest quality mipmap 0 into a bitmap by using the following code:

std::vector<unsigned char> bytes = get_data_from_dds_file(L"WoodCrate01.dds");

std::vector<D3D12_SUBRESOURCE_DATA> subresources;
winrt::check_hresult(
    DirectX::LoadDDSTextureFromMemory(
        g_device,
        &bytes.front(),
        file_size,
        gpu_tex_resource.put(),
        subresources
    )
);

auto current_index = 0;

auto current_slice_pitch = subresources[current_index].SlicePitch;

std::vector<unsigned char> current_subresource_data;
current_subresource_data.resize(current_slice_pitch);
memcpy(&current_subresource_data[0], subresources[current_index].pData, current_slice_pitch);

Windows::Storage::Streams::InMemoryRandomAccessStream random_stream;
Windows::Storage::Streams::DataWriter writer(random_stream);

writer.WriteBytes(current_subresource_data);
co_await writer.StoreAsync();

auto decoder = co_await Windows::Graphics::Imaging::BitmapDecoder::CreateAsync(random_stream);
// Subresources at index higher than 0 crash at this point with the error: 0x88982F50 : 'The component cannot be found.'.

// The subresource at index 0 doesn't crash at the previous line, so I turn it into a SoftwareBitmap so that I can show it in XAML.
auto new_software_bitmap = co_await decoder.GetSoftwareBitmapAsync();

new_software_bitmap = Windows::Graphics::Imaging::SoftwareBitmap::Convert(
    new_software_bitmap,
    Windows::Graphics::Imaging::BitmapPixelFormat::Bgra8,
    Windows::Graphics::Imaging::BitmapAlphaMode::Premultiplied);

Windows::UI::Xaml::Media::Imaging::SoftwareBitmapSource new_bitmap_source;
co_await new_bitmap_source.SetBitmapAsync(new_software_bitmap);
[...]

The problem starts when I try to change the current_index to 1 or higher. I get an error 0x88982F50 : 'The component cannot be found.' at the line where I try to create the BitmapDecoder.

bitmap
directx
directx-12
dds-format
asked on Stack Overflow Mar 5, 2019 by mbl • edited Mar 5, 2019 by mbl

1 Answer

0

Are you sure that the source image has mipmaps in it? The API you are calling doesn't automatically generate mipmaps:

"These functions create the texture resource and return the initialization data in ddsData which is pointed into by the vector of subresources. They don't support mipmaps generation, but do support reserving space for mipmaps."

Look at the contents of the returned subresources to see what is in there.

answered on Stack Overflow Mar 7, 2019 by cmaughan

User contributions licensed under CC BY-SA 3.0