Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
266 views
in Technique[技术] by (71.8m points)

c# - Direct2D (SharpDX) block compressed bitmaps not compressed in memory

I have a few (8-10) large texture atlases (around 8192x8192 saved as BC1 DDS) but they are rather small disk space wise, only 32MiB.

The problem is, that when I load those files using WIC, they lose their block compression and take up to 256MiB of RAM, which shouldn't happen according to the sources

Here is my C# SharpDX code which loads the file:

public Bitmap LoadBitmap(string path) {
    Bitmap m;

    using (BitmapDecoder d = new BitmapDecoder(imagingFactory, $"plugins/HDPatch/{path}", Guid.Empty, SharpDX.IO.NativeFileAccess.Read, DecodeOptions.CacheOnDemand)) {
        DdsDecoder decoder = d.QueryInterface<DdsDecoder>();
        decoder.GetFrame(0, 0, 0, out BitmapFrameDecode frame);
        m = SharpDX.Direct2D1.Bitmap.FromWicBitmap(_target, frame);//_target.CreateBitmap(converter, new BitmapProperties());
        decoder.Dispose();
        frame.Dispose();
    }

    return m;
}

Do I need to change something, or should I use a different method of loading them than WIC?

I looked at the DdsFrameDecode.CopyBlocks (+ ID2D1Bitmap::CopyFromMemory) method but I do not know how that works.. (What exactly is my stride and where do I get that information from)

EDIT:

So the BitmapFrameDecode gives me a PixelFormat of 32bppPBGRA

If I query a DDSFrameDecode from that BitmapFrameDecode, I get a format of BC1_UNorm from the DdsFrameDecode. The DdsDecoder also reports a texture with DdsAlphaModePremultiplied, and a DxgiFormat of BC1_UNorm.

But when I force the pixel format of BC1_UNorm in the BitmapProperties I get the D2D DEBUG ERROR: "The pixel format passed to this API is not compatible with the pixel format of the IWICBitmapSource"

EDIT2: I figured out how to use CopyBlocks

    SharpDX.DataStream stream = new 
    SharpDX.DataStream(test2.FormatInfo.BytesPerBlock * test2.SizeInBlocks.Width * test2.SizeInBlocks.Height, true, true);
    test2.CopyBlocks(null, test2.FormatInfo.BytesPerBlock * test2.SizeInBlocks.Width, stream);
    m = new Bitmap(_target, new SharpDX.Size2(decoder.Parameters.Width, decoder.Parameters.Height), stream, test2.FormatInfo.BytesPerBlock * test2.FormatInfo.BlockWidth, new BitmapProperties(new PixelFormat(SharpDX.DXGI.Format.BC1_UNorm, AlphaMode.Premultiplied)));

But the problem still exists. It can successfully create the Bitmap but it still consumes to much memory (250MiB+ instead of the actual block compressed size of 32MiB)

Does it maybe have to do with the render target of? I use a software B8G8R8A8_UNorm DeviceContext render target

EDIT3:

Example project: https://drive.google.com/file/d/1hCgQnEV9xcTevgdswAiPJNREk1oDgqDC/view?usp=sharing

question from:https://stackoverflow.com/questions/65905637/direct2d-sharpdx-block-compressed-bitmaps-not-compressed-in-memory

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...