HexaEngine / Hexa.NET.DirectXTex

A .NET wrapper for the DirectXTex library.
MIT License
2 stars 0 forks source link

Issues on Linux #5

Closed iMrShadow closed 1 month ago

iMrShadow commented 1 month ago

I started testing the project on Linux. Some functions work correct - loading image from bytes, creating a new scratch image and some utility functions. However, the app crashes when Decompress2 and Convert2 are executed. There are possibly other functions that crash as well, but I can't really debug on this machine very effectively (i3-3110M 64-bit, 6GB RAM, Linux Mint 22 fresh installation). The code worked fine on Windows.

When Convert2 is used - the error code shows " Value does not fall within the expected range.".

uint format = (uint)(DirectXTex.IsSRGB(Metadata.Format) ? DXGIFormat.R8G8B8A8_UNORM_SRGB : DXGIFormat.R8G8B8A8_UNORM);

        ScratchImage destImage = DirectXTex.CreateScratchImage();

        HResult result;

        if (DirectXTex.IsCompressed(Metadata.Format))
        {
            result = DirectXTex.Decompress2(Image.GetImages(), Image.GetImageCount(), Image.GetMetadata(), format, destImage); // Immediate crash - no result

            Image.Release();
            Image = destImage;
        }
        else if (Metadata.Format != (uint)DXGIFormat.R8G8B8A8_UNORM_SRGB && Metadata.Format != (uint)DXGIFormat.R8G8B8A8_UNORM)
        {
            result = DirectXTex.Convert2(Image.GetImages(), Image.GetImageCount(), Image.GetMetadata(), format, TexFilterFlags.Default, 0.5f, destImage); // Error code when result.ThrowIf() is used - all values are 0, despite the initial values being different.

            Image.Release();
            Image = destImage;
        }
        else
        {
            result = 0;
            destImage.Release();
        }

I don't know if this is reproducible on other hardware.

Thanks

JunaMeinhold commented 1 month ago

Can confirm, it's a bug... but what exactly no idea

Thread 1 "Example" received signal SIGSEGV, Segmentation fault.
iMrShadow commented 1 month ago

Segfaults, that's super unfortunate. I wonder if there are missing writing permissions or memory allocations problems, no idea how a wrapper can get a segfault... I hope it's not super serious

If you need any assistance with testing let me know.

JunaMeinhold commented 1 month ago

I think i found the issue, a bug in the c translation layer. Before the potential fix image After the potential fix image the error moved which is a good sign

JunaMeinhold commented 1 month ago

This issue could possibly linked to the issue that you experienced before.

To verify that could you maybe try calling GetMetadataFromDDSFile(). If that works then it's this issue

iMrShadow commented 1 month ago

I will, gimme a couple of minutes

iMrShadow commented 1 month ago

Deja Vu, when I execute either LoadFromDDSFile or GetMetadataFromDDSFile() I get a crash again. In VSC I got this output: terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error' what(): filesystem error: Cannot convert character sequence: Invalid or incomplete multibyte or wide character.

If I use the LoadFromDDSMemory and GetMetadataFromDDSMemory - they work. It could potentially be linked to std::filesystem not knowing the platforms. I am not sure how it originally broke on Windows tho (#2)

So potentially there are 2 bugs instead of 1. Let me know if LoadFromDDSFile works for you on Linux

JunaMeinhold commented 1 month ago

Small warning: API changes ahead.

iMrShadow commented 1 month ago

That's fine, just let me know what things will break when they are done

JunaMeinhold commented 1 month ago

image Okay now i can reproduce the file system bug.

JunaMeinhold commented 1 month ago

I found a potential fix/problem DirectXTex uses wchar_t which is on win usually 2 bytes and on linux 4 bytes which could explain the problem here

JunaMeinhold commented 1 month ago

image it seems to work now

JunaMeinhold commented 1 month ago

Just that you know the WIC codecs eg png, jpg, ico, bmp don't work on linux, WIC is a windows component

iMrShadow commented 1 month ago

Yeah, I know. For that reason, I convert to raw pixel data and encode using SkiaSharp. Another alternative would be to implement DirectXTex's SaveAsPng extension (works for all platforms) into the wrapper, but that requires libpng. It could make things "cleaner", but it's not required

Edit: link - https://github.com/microsoft/DirectXTex/wiki/Using-JPEG-PNG-OSS

JunaMeinhold commented 1 month ago

image Okay last small fixes, and i might look into the png, jpeg api and implement that before doing the final release

JunaMeinhold commented 1 month ago

It will take a bit longer, I will add a new dll import technique, which is faster and also backwards compatible with netstandard2.0

JunaMeinhold commented 1 month ago

The new version is now available on nuget. (Hopefully that fixed all the bugs)

iMrShadow commented 1 month ago

I will test it out, thanks

iMrShadow commented 1 month ago

Good news! The functions seem to work - the dds was displayed successfully after some transformations and other utility functions, which is great.

The only thing about the refactoring part is that image.GetMetadata() cannot be directly used in functions, but it's a minor thing.

Once again, thanks a lot!