Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hi, is NV_DX_interop2 missing for WGL.Extensions? #2149

Open
jcyuan opened this issue Apr 21, 2024 · 16 comments
Open

Hi, is NV_DX_interop2 missing for WGL.Extensions? #2149

jcyuan opened this issue Apr 21, 2024 · 16 comments
Labels
area-OpenGL enhancement New feature or request help wanted Extra attention is needed

Comments

@jcyuan
Copy link

jcyuan commented Apr 21, 2024

I found Silk.NET.WGL.Extensions.NV.NVDXInterop only, but there is no extension for NV_DX_interop2.
or maybe there is, but i missed it?
by the way, what does those Overloads mean? for example NVDXInteropOverloads, is this actually the NV_DX_interop2?
thank you so much.

@jcyuan jcyuan added the enhancement New feature or request label Apr 21, 2024
@Perksey
Copy link
Member

Perksey commented Apr 21, 2024

NV_DX_interop2 does not add any new functions therefore it does not have a class generated. For more info see the specification: https://registry.khronos.org/OpenGL/extensions/NV/WGL_NV_DX_interop2.txt

@Perksey Perksey closed this as completed Apr 21, 2024
@jcyuan
Copy link
Author

jcyuan commented Apr 21, 2024

NV_DX_interop2 does not add any new functions therefore it does not have a class generated. For more info see the specification: https://registry.khronos.org/OpenGL/extensions/NV/WGL_NV_DX_interop2.txt

thanks for reply, yeah i know that, actually it was the usage confused me, so how can i use NV_DX_interop2 with Silk.WGL? i assume that the Overloads will be auto used for those changes in NV_DX_interop2?

@Perksey
Copy link
Member

Perksey commented Apr 21, 2024

Yes that's correct.

@jcyuan
Copy link
Author

jcyuan commented Apr 21, 2024

Yes that's correct.

Hi sir, sorry for bothering again,

i just found 2 problems:

1, this method is not implemented in WGL.cs:
image
so, if (wgl.TryGetExtension<NVDXInterop>(out var ext)) will fail.

2, NV_DX_interop does not exist in the extension string list. but i can still use wglGetProcAddress("wglDXOpenDeviceNV") to use those methods, not sure why, it's strange to me...

if i try to use the ext with a 'normal' way just like other extensions:
image
by this test code:

var wgl = WGL.GetApi();
var ext = new NVDXInterop(wgl.Context);
ext.DxopenDevice(out IntPtr device);
 ext.DxcloseDevice(device);

it will fail....

and if i just use it by using DllImport even it does not exist in the extension string list:
image
it just works....

@Perksey
Copy link
Member

Perksey commented Apr 21, 2024

oops

@Perksey
Copy link
Member

Perksey commented Apr 21, 2024

This will now be fixed as part of #2115 (the next update), and the fix is contained in commit dfb4225. If you would like to work around this in your own code, feel free to use this commit as inspiration.

@jcyuan
Copy link
Author

jcyuan commented Apr 22, 2024

This will now be fixed as part of #2115 (the next update), and the fix is contained in commit dfb4225. If you would like to work around this in your own code, feel free to use this commit as inspiration.

👏thanks so much.

@jcyuan
Copy link
Author

jcyuan commented May 1, 2024

hi @Perksey

i had applied your changes into my logic (as the official release is not ready yet),
i found that i can create NVDXInterop extension in my 'primary' context, once i try to create with any context created later (shared with the primary context), the creating will fail.

ex info: i manage all the created DCs in a single thread.

maybe i should wait for new official release?

@Perksey
Copy link
Member

Perksey commented May 1, 2024

2.21 should have fixed this.

@jcyuan
Copy link
Author

jcyuan commented May 1, 2024

so fast! thanks so much @Perksey
but just had a try and it didn't work, here is the code:

[MethodImpl(MethodImplOptions.AggressiveInlining)]
    [SupportedOSPlatform("windows")]
    private INativeContext CreateNativeContext()
    {
        return WGL.CreateDefaultContext(["Opengl32"]);
    }

// ------

 var nativeContext = CreateNativeContext();
        
        using (MakeCurrent())
        {
            _gl = GL.GetApi(nativeContext);
            _wgl= WGL.GetApi();   // new WGL(nativeContext) not work too.
        }

// test
var test = _wgl.TryGetExtension(out NVDXInterop ext);

it throws exception:
image

@Perksey
Copy link
Member

Perksey commented May 1, 2024

Please ensure that you're using WGL.GetApi. Please note that the snippet you gave is using GL.GetApi incorrectly - this will only work for OpenGL 1.1 - you need to use a native context that uses wgl.GetProcAddress for the others.

I'm not sure why this isn't working, I'll reopen this issue until a community member can investigate further.

@Perksey Perksey reopened this May 1, 2024
@Perksey Perksey added help wanted Extra attention is needed area-OpenGL labels May 1, 2024
@jcyuan
Copy link
Author

jcyuan commented May 1, 2024

thanks for your suggestion,
i have changed my code like this:

    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    private static IntPtr GetProcAddress(string proc)
    {
        var p = NativeMethods.wglGetProcAddress(proc);
        return p != IntPtr.Zero ? p : NativeMethods.GetProcAddress(OpenGl32Handle, proc);
    }

        using (MakeCurrent())
        {
            _gl = GL.GetApi(GetProcAddress);
            _wgl = WGL.GetApi();  // way auto create `MultiNativeContext`
        }

i think for _gl it's fine now, but for _wgl, still the same exception.

@jcyuan
Copy link
Author

jcyuan commented May 1, 2024

update:

i tried to create WGL with new WGL(new LamdaNativeContext(GetProcAddress)); (the GetProcAddress is the same one the _gl uses.

now it has exception, the _extensions is null:
image

so i think

private static IntPtr GetProcAddress(string proc)
    {
        var p = NativeMethods.wglGetProcAddress(proc);
        return p != IntPtr.Zero ? p : NativeMethods.GetProcAddress(OpenGl32Handle, proc);
    }

this should be the right way. @Perksey

@jcyuan
Copy link
Author

jcyuan commented May 2, 2024

update:

still failed, even the getProcAddress works for NVDXInterop extension to get those APIs, but those API call only works with the primary context, not sure why...

works fine now, i have manually written a binding for NVDXInterop because it only has a few APIs, and it works with all context now.
hope Silk could fix these problems soon, and thanks so much for official team for your efforts. ❤

@Perksey
Copy link
Member

Perksey commented May 2, 2024

Awesome stuff @jcyuan. I had hoped that this is what the LambdaNativeContext is essentially doing, but it looks like for some reason it's not rolling over to the default context.

The null thing is a big oops, feel free to use unsafe accessors to rectify that:

[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_extensions")]
extern static ref ConcurrentDictionary<nint, HashSet<string>>? Exts(WGL wgl);

Exts(wgl) = new();

@qian-o
Copy link

qian-o commented May 7, 2024

This is a way I tried, I hope it can help you.

Use TryGetProcAddress instead of GetProcAddress in the GetProcAddress function of MultiNativeContext.

public nint GetProcAddress(string proc, int? slot = null)
{
    INativeContext[] contexts = Contexts;
    for (int i = 0; i < contexts.Length; i++)
    {
        if (contexts[i]?.TryGetProcAddress(proc, out IntPtr intPtr, slot) ?? false)
        {
            return intPtr;
        }
    }

    return 0;
}

Initialize and assign _extensions in WGL.

This can effectively solve the extension problem of WGL.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-OpenGL enhancement New feature or request help wanted Extra attention is needed
Projects
Status: Todo
Development

No branches or pull requests

3 participants