HexaEngine / Hexa.NET.DirectXTex

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

Update DirectXTex #1

Closed iMrShadow closed 1 month ago

iMrShadow commented 1 month ago

Hello!

I am using your wrapper and so far it has been a pleasure to work with! However, it's using an older version of DirectXTex (pre-June 2023), which does not support DXGI_FORMAT_A4B4G4R4_UNORM, which was added in this update.

It would be nice to have this feature, since apparently it has a usage

Thanks!

JunaMeinhold commented 1 month ago

Hello,

I will update it today (to June 2024), but there will be a few breaking changes, I overhauled the generator, and the package id will change from HexaEngine.DirectXTex => Hexa.NET.DirectXTex,

JunaMeinhold commented 1 month ago

Done. I leave this issue open so you can report if everything works, I don't have time to fully test it, but at least all unit tests passed.

iMrShadow commented 1 month ago

I removed the older Nuget package and installed the new one. For some reason I can't use the new library despite having it installed. Even Visual Studio and VSC can't auto-find the structs.

Hexa.NET.DirectXTex could not be found

This is how the package reference looks like in the project, which I found odd:

<PackageReference Include="Hexa.NET.DirectXTex" Version="1.0.0">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
JunaMeinhold commented 1 month ago

the namespace changed too (using Hexa.NET.DirectXTex;) and the package is listed https://www.nuget.org/packages/Hexa.NET.DirectXTex/

iMrShadow commented 1 month ago

I found the issue. I removed

<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

These lines were added when I installed the package via Nuget. After removing the namespace is recognised

JunaMeinhold commented 1 month ago

image I noticed there is a issue with the code gen i will fix that soon (Wrapu should be WrapU, etc)

iMrShadow commented 1 month ago

Interesting: I am not sure if it's from DirectXTex or from the wrapper, but the loader crashes on some DDS files, and it's inconsistent. Examples.zip

The crash message is Exception has occurred: CLR/System.AccessViolationException An unhandled exception of type 'System.AccessViolationException' occurred in Hexa.NET.DirectXTex.dll: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'

JunaMeinhold commented 1 month ago

idk, the wrapper is very very thin, and only forwards calls to the actual implementation

JunaMeinhold commented 1 month ago

both files work on my machine, strange. It might be something on your side.

iMrShadow commented 1 month ago

Yeah, the root of the problem has been found. It's interesting why it didn't happen in earlier versions...Hmm

It was a memory leak, because I load the image twice, but I was releasing the memory in only 1 segment (i need to change this behaviour).

JunaMeinhold commented 1 month ago

I usually do something like this to prevent issues and memory leaks image

iMrShadow commented 1 month ago

Update: Actually, I pin-pointed the issue. For some reason it works perfectly fine with LoadFromDDSMemory, but with LoadFromDDSFile sometimes it crashes (and it always crashes with those images I sent). I have no idea why that happens, it's very odd. I also tested these files with your Example project - it also crashes there. (Edit: The above segment also doesn't work - it throws an exception).

It might have to do something with this segment but i am not exactly sure...

JunaMeinhold commented 1 month ago

no issues image

iMrShadow commented 1 month ago

What...(i dont have the file opened anywhere) image

JunaMeinhold commented 1 month ago

Okay that only happens when a heap corruption occurs

iMrShadow commented 1 month ago

I am gonna restart the PC, this is very weird

iMrShadow commented 1 month ago

Same thing. Can it be the Visual Studio setup, despite not changing anything from this project? image

JunaMeinhold commented 1 month ago

please enable this image image

JunaMeinhold commented 1 month ago

and verify that image is not null after creation image

iMrShadow commented 1 month ago

Native debugging is enabled. And the image is not null image

JunaMeinhold commented 1 month ago

which OS do you have?

iMrShadow commented 1 month ago

Windows 10, a slightly older feature update, but i doubt it's from there

Also, could the problem be from here? image

JunaMeinhold commented 1 month ago

no, this code is exactly the same as in my ImGui wrapper and I (and other people) never had issues with that. it's simple string marshalling but with stackalloc if the string is short enough to fit in.

JunaMeinhold commented 1 month ago

I'm on win11, give me a minute i will try it on my win 10 laptop

iMrShadow commented 1 month ago

That is super interesting. It should not be a hardware problem, I have R5 2600 CPU. I frankly have no idea what's happening. LoadFromDDSMemory works as expected (i first read all bytes from the file).

This code works correctly.

unsafe public static ImageProperties GetDDSProperties(string ddsFilePath, DDSFlags flags = DDSFlags.None)
    {
        ScratchImage image = GetDDSImage(ByteFunctions.LoadTexture(ddsFilePath), flags);
...
    }
unsafe public static ScratchImage GetDDSImage(byte[] array, DDSFlags flags = DDSFlags.None)
    {
        GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
        try
        {
            ScratchImage image = DirectXTex.CreateScratchImage();
            TexMetadata metadata;

            // Obtain a pointer to the data
            IntPtr ptr = handle.AddrOfPinnedObject();
            DirectXTex.LoadFromDDSMemory((void*)ptr, (nuint)array.Length, flags, &metadata, image);
            return image;
        }
        finally
        {
            // Release the handle to allow the garbage collector to reclaim the memory
            handle.Free();
        }
    }
JunaMeinhold commented 1 month ago

very strange on my old win 10 machine everything works just fine, and i freshly downloaded it. (Microsoft Windows 10.0.19045.3031, from May 23, 2023)

iMrShadow commented 1 month ago

Great...I am out of ideas. It could very well be my OS version (19042.1526). At least there is a workaround for now. Thank you very much for the help!

One final debugging option is to commit my changes to my project and see if it works for someone else

JunaMeinhold commented 1 month ago

maybe try these in an admin console: sfc /scannow (https://support.microsoft.com/en-us/topic/use-the-system-file-checker-tool-to-repair-missing-or-corrupted-system-files-79aa86cb-ca52-166a-92a3-966e85d4094e) Dism /Online /Cleanup-Image /ScanHealth Dism /Online /Cleanup-Image /RestoreHealth (https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/what-is-dism?view=windows-11)

iMrShadow commented 1 month ago

sfc scanned some corrupt files and fixed them. I'll restart again

Update: No effect. Apparently the "corrupt files" were the windows start up sound (I used a custom Windows 95 start up sound)

JunaMeinhold commented 1 month ago

Okay I'll make a vm ready and make tests again. (with your exact version)

iMrShadow commented 1 month ago

Thanks, I don't think there was need to.

I commited all of my updates. Here's a link to the project that uses your wrapper.

Update: To use it - just put the dds files i sent you in a different folder. Using my app, open the folder containing them and just click on them in the gridview.

JunaMeinhold commented 1 month ago

It works... I also have a older win version installed so it can't be that one image image

JunaMeinhold commented 1 month ago

another question what is your .net 8 version? image

iMrShadow commented 1 month ago

It's bizarre that it works for you.

My .NET Version is 8.0.202

JunaMeinhold commented 1 month ago

try updating it with the visual studio installer or manually

JunaMeinhold commented 1 month ago

(it could be because I disabled runtime marshalling and your version has a bug with that feature)

iMrShadow commented 1 month ago

Give me a couple of minutes, I am updating Visual Studio too

iMrShadow commented 1 month ago

I upgraded to the latest version - no success. It could be the runtime marshalling thing you mentioned

JunaMeinhold commented 1 month ago

image image

JunaMeinhold commented 1 month ago

And for maximum compatibility set this option in the generator settings and run the generator

image

iMrShadow commented 1 month ago

I checked the assembly info, i edited the json and ran the Generator, it's not from them either...hmm. Super strange stuff

If you want - I can close this issue now. This seems like a very strange bug which probably only affects me, and there's a workaround too

JunaMeinhold commented 1 month ago

Weirdest bug I ever had in my 5 years of programming. The only thing we could do is compare asm code from the disassembly but that's way to deep. If you have any other problems I'm always happy to help. (you can close the issue)

iMrShadow commented 1 month ago

The only thing that comes to my mind is the C/C++ compiler I am using, but as you said - at this point it's too deep.

Thank you very much for the help! I appreciate the time you spent trying to figure out what was wrong. If I somehow manage to fix it, I will let you know

I am closing the issue