Error Running jextract on d3d12.h
Michael Ennen
mike.ennen at gmail.com
Mon Sep 14 17:39:22 UTC 2020
Ahhh, this makes so much more sense now.
Thank you both tremendously.
On Mon, Sep 14, 2020 at 6:39 AM Jorn Vernee <jorn.vernee at oracle.com> wrote:
> Ok, it looks like the formatting got messed up in the email, so I've
> uploaded the example here as well:
>
> http://cr.openjdk.java.net/~jvernee/d3d12_example/Main.java
>
> Jorn
>
> On 14/09/2020 15:28, Jorn Vernee wrote:
> > I've tried it out on my machine as well (I'm also on Windows). Here is
> > a little bit more complete example that prints out the adapter
> > description
> >
> > If you have extracted the shared/dxgi.h and the shared/guiddef.h
> > headers as well, you can do something like this:
> >
> >
> > import jdk.incubator.foreign.FunctionDescriptor;
> > import jdk.incubator.foreign.MemoryAccess;
> > import jdk.incubator.foreign.MemoryAddress;
> > import jdk.incubator.foreign.MemoryLayout;
> > import jdk.incubator.foreign.MemorySegment;
> > import jdk.incubator.foreign.NativeScope;
> > import org.jextract.dxgi_h;
> > import org.jextract.guiddef_h;
> >
> > import java.lang.invoke.MethodHandle;
> > import java.lang.invoke.MethodType;
> > import java.nio.charset.StandardCharsets;
> >
> > import static jdk.incubator.foreign.CSupport.*;
> > import static org.jextract.dxgi_h.*;
> >
> > public class Main {
> >
> > public static void main(String[] args)throws Throwable {
> > try (NativeScope scope =NativeScope.unboundedScope()) {
> > // IDXGIFactory1** dxgiFactory;
> > var ppDxgiFactory =IDXGIFactory1.allocatePointer(scope);
> > // HRESULT = CreateDXGIFactory1(_uuid(dxgiFactory),
> > &dxgiFactory))
> > checkResult(dxgi_h.CreateDXGIFactory1(IID_IDXGIFactory1,ppDxgiFactory));
> > // IDXGIFactory1* MemorySegment pDxgiFactory
> >
> =asSegment(MemoryAccess.getAddress(ppDxgiFactory),IDXGIFactory1.$LAYOUT());
> >
> > // (This)->lpVtbl MemorySegment vtbl
> >
> =asSegment(IDXGIFactory1.lpVtbl$get(pDxgiFactory),IDXGIFactory1Vtbl.$LAYOUT());
> > // lpVtbl->EnumAdapters1 MemoryAddress addrEnumAdapters
> > =IDXGIFactory1Vtbl.EnumAdapters1$get(vtbl);
> >
> > // link the pointer MethodHandle MH_EnumAdapters1
> > =getSystemLinker().downcallHandle(
> > addrEnumAdapters,
> >
> MethodType.methodType(int.class,MemoryAddress.class,int.class,MemoryAddress.class),
> > FunctionDescriptor.of(C_INT,C_POINTER,C_INT,C_POINTER));
> >
> > /* [annotation][out] _COM_Outptr_ IDXGIAdapter1** */
> > MemorySegment ppOut =IDXGIAdapter1.allocatePointer(scope);
> >
> checkResult((int)MH_EnumAdapters1.invokeExact(pDxgiFactory.address(),0,ppOut.address()));//
>
> > IDXGIAdapter1* MemorySegment pAdapter
> > =asSegment(MemoryAccess.getAddress(ppOut),IDXGIAdapter1.$LAYOUT());
> >
> > // (This)->lpVtbl MemorySegment vtbl2
> >
> =asSegment(IDXGIAdapter1.lpVtbl$get(pAdapter),IDXGIAdapter1Vtbl.$LAYOUT());
> > // lpVtbl->EnumAdapters1 //
> > HRESULT(*)(IDXGIAdapter1*,DXGI_ADAPTER_DESC1*) MemoryAddress
> > addrGetDesc1 =IDXGIAdapter1Vtbl.GetDesc1$get(vtbl2);
> >
> > // link the pointer MethodHandle MH_GetDesc1
> > =getSystemLinker().downcallHandle(
> > addrGetDesc1,
> > MethodType.methodType(int.class,MemoryAddress.class,MemoryAddress.class),
> > FunctionDescriptor.of(C_INT,C_POINTER,C_POINTER));
> >
> > /* DXGI_ADAPTER_DESC1* */ MemorySegment pDesc
> > =DXGI_ADAPTER_DESC1.allocate(scope);
> >
> checkResult((int)MH_GetDesc1.invokeExact(pAdapter.address(),pDesc.address()));
> >
> > // print description MemorySegment descStr
> > =DXGI_ADAPTER_DESC1.Description$slice(pDesc);
> > String str =new
> > String(descStr.toByteArray(),StandardCharsets.UTF_16LE);
> > System.out.println(str);
> > }
> > }
> >
> > public static MemorySegment asSegment(MemoryAddress
> > addr,MemoryLayout layout) {
> > return MemorySegment.ofNativeRestricted(addr,
> > layout.byteSize(),Thread.currentThread(),null,null);
> > }
> >
> > static final MemorySegment IID_IDXGIFactory1 =GUID(
> > (int)0x770aae78,
> > (short)0xf26f,
> > (short)0x4dba,
> > new byte[]{(byte)0xa8,0x29,0x25,0x3c, (byte)0x83,
> > (byte)0xd1, (byte)0xb3, (byte)0x87});
> >
> > static final MemorySegment GUID(int Data1,short Data2,short
> > Data3,byte[] Data4) {
> > MemorySegment ms
> > =MemorySegment.allocateNative(guiddef_h.GUID.$LAYOUT());
> > guiddef_h.GUID.Data1$set(ms, Data1);
> > guiddef_h.GUID.Data2$set(ms, Data2);
> > guiddef_h.GUID.Data3$set(ms, Data3);
> > guiddef_h.GUID.Data4$slice(ms).copyFrom(MemorySegment.ofArray(Data4));
> > return ms;
> > }
> >
> > private static final int S_OK =0x00000000;
> >
> > private static void checkResult(int result) {
> > switch (result) {
> > case S_OK -> {}
> > default ->throw new IllegalStateException("Unknown result:
> > " +String.format("%X8", result));
> > }
> > }
> > }
> >
> >
> > Which on my machine prints: NVIDIA GeForce GTX 1050 Ti
> >
> > HTH,
> > Jorn
> >
> > On 14/09/2020 12:52, Maurizio Cimadamore wrote:
> >> I think there's something off in here:
> >>
> >>> MemorySegment segment =
> >>>
> MemorySegment.allocateNative(dxgi_h.IDXGIFactory1Vtbl.$LAYOUT().byteSize());
>
> >>>
> >>> MemoryAddress address = segment.address().addOffset(64);
> >> I see a couple of issues:
> >>
> >> 1) how do you determine that the offset of the function address you
> >> want to obtain is 64 byte from the start? Didn't jextract give you a
> >> getter for that?
> >>
> >> 2) Even assuming 64 byte is the correct offset, note that the segment
> >> will be initialized to all zeros - I presume this vtable must be
> >> filled in somehow, or perhaps obtained from a global variable?
> >>
> >> From your earlier email I see this:
> >>
> >>> interface IDXGIFactory
> >>> {
> >>> CONST_VTBL struct IDXGIFactoryVtbl *lpVtbl;
> >>> };
> >> So... perhaps once yo create a IDXGIFactory, you can just grab the
> >> pointer to the vtable by accessing its `lpVtbl` field - no need to
> >> allocate a new segment (the library has done the allocation for you).
> >>
> >> If I'm correct, this can be achieved with something like (not sure if
> >> the names are going to be 100% correct since I don't have a
> >> jextracted version of the API with me - so beware, I have NOT tested
> >> this :-) ):
> >>
> >> var dxgiFactoryPtr =
> >> MemoryAccess.getAddress(MemorySegment.ofNativeRestricted(),
> >> dxgiFactory);
> >> var lpVtbl =
> >> MemoryAccess.getAddress(MemorySegment.ofNativeRestricted(),
> >> dxgiFactoryPtr);
> >> var vtable = RuntimeHelper.ofArrayRestricted(lpVtbl,
> >> IDXGIFactory1Vtbl.$LAYOUT(), 1); //1
> >> var address = IDXGIFactory1Vtbl$EnumAdapters$get(vtable);
> >>
> >>
> >> And this should give the address pointer you are looking for. We need
> >> to smooth the edges especially around (1) - e.g. to turn a random
> >> native pointer into a struct with given layout (jextract should
> >> generate a static helper for that, see [1]) - but with the code above
> >> you should be able to get there, I hope.
> >>
> >> P.S.
> >> In these situations, my suggestion is, especially when attacking a
> >> native library for the first time, to always try the library directly
> >> using C and see what happens, to understand exactly what kind of
> >> pattern/idiom the library requires. I did that many times and
> >> realized my assumptions on how library worked were wrong; other users
> >> have posted similar instances in this mailing list. Once you get
> >> things working in C, porting the code in Java using the Panama API is
> >> typically a trivial matter.
> >>
> >> Maurizio
> >>
> >> [1] - https://bugs.openjdk.java.net/browse/JDK-8253102
> >>
> >>
> >> On 13/09/2020 02:37, Michael Ennen wrote:
> >>> Well, progress of a kind? This crashes the VM instead of not
> >>> compiling or
> >>> throwing an exception:
> >>>
> >>> // IDXGIFactory1** dxgiFactory;
> >>> var dxgiFactory = scope.allocate(C_POINTER);
> >>> // HRESULT = CreateDXGIFactory1(_uuid(dxgiFactory), &dxgiFactory))
> >>> int hresult = dxgi_h.CreateDXGIFactory1(GUID(IID.IID_IDXGIFactory1),
> >>> dxgiFactory);
> >>> System.out.println("hresult: " + hresult);
> >>> var dxgiAdapter = scope.allocate(C_POINTER);
> >>> System.out.println("IDXGIFactory1Vtbl byte size: " +
> >>> dxgi_h.IDXGIFactory1Vtbl.$LAYOUT().byteSize()); //112
> >>> MemorySegment segment =
> >>>
> MemorySegment.allocateNative(dxgi_h.IDXGIFactory1Vtbl.$LAYOUT().byteSize());
>
> >>>
> >>> MemoryAddress address = segment.address().addOffset(64);
> >>> FunctionDescriptor functionDescriptor = FunctionDescriptor.of(C_INT,
> >>> C_INT,
> >>> C_POINTER);
> >>> MethodType methodType = MethodType.methodType(int.class, int.class,
> >>> MemoryAddress.class);
> >>> MethodHandle methodHandle = getSystemLinker().downcallHandle(address,
> >>> methodType, functionDescriptor);
> >>> try {
> >>> methodHandle.invokeWithArguments(0, dxgiAdapter.address());
> >>> } catch (Throwable throwable) {
> >>> throwable.printStackTrace();
> >>> }
> >>>
> >>> On Sat, Sep 12, 2020 at 6:34 PM Michael Ennen <mike.ennen at gmail.com>
> >>> wrote:
> >>>
> >>>> I think I see why. It's because I am passing in a MemorySegment,
> >>>> which is
> >>>> the dxgiAdapter which I initialize thusly:
> >>>>
> >>>> var dxgiAdapter = scope.allocate(C_POINTER);
> >>>>
> >>>> I guess I need to make it a MemoryAddress instead.
> >>>>
> >>>> On Sat, Sep 12, 2020 at 2:25 PM Michael Ennen <mike.ennen at gmail.com>
> >>>> wrote:
> >>>>
> >>>>> Thanks so much Ty. That's super helpful. I think I was able to
> >>>>> make quite
> >>>>> a bit of progress:
> >>>>>
> >>>>> var dxgiAdapter = scope.allocate(C_POINTER);
> >>>>> System.out.println("IDXGIFactory1Vtbl byte size: " +
> >>>>> dxgi_h.IDXGIFactory1Vtbl.$LAYOUT().byteSize());
> >>>>> MemorySegment segment =
> >>>>>
> MemorySegment.allocateNative(dxgi_h.IDXGIFactory1Vtbl.$LAYOUT().byteSize());
>
> >>>>>
> >>>>> MemoryAddress address = segment.address().addOffset(64);
> >>>>> FunctionDescriptor functionDescriptor = FunctionDescriptor.of(C_INT,
> >>>>> C_INT, C_POINTER);
> >>>>> MethodType methodType = MethodType.methodType(int.class, int.class,
> >>>>> MemoryAddress.class);
> >>>>> MethodHandle methodHandle = getSystemLinker().downcallHandle(address,
> >>>>> methodType, functionDescriptor);
> >>>>> try {
> >>>>> methodHandle.invokeWithArguments(0, dxgiAdapter);
> >>>>> } catch (Throwable throwable) {
> >>>>> throwable.printStackTrace();
> >>>>> }
> >>>>>
> >>>>> Note that the EnumAdapters1 function signature is actually:
> >>>>>
> >>>>> HRESULT EnumAdapters1(
> >>>>> UINT Adapter,
> >>>>> IDXGIAdapter1 **ppAdapter
> >>>>> );
> >>>>>
> >>>>>
> >>>>> So that's why I went with:
> >>>>>
> >>>>> FunctionDescriptor functionDescriptor = FunctionDescriptor.of(C_INT,
> >>>>> C_INT, C_POINTER);
> >>>>>
> >>>>> and then
> >>>>>
> >>>>> methodHandle.invokeWithArguments(0, dxgiAdapter);
> >>>>>
> >>>>> I did some fancy stuff as per your suggestion which I feel should be
> >>>>> getting the address of the EumAdapters1 function
> >>>>> pointer (basically start at the base address of the struct and
> >>>>> then move
> >>>>> 64 bytes past, which should be the 8th function
> >>>>> pointer which in this case is EnumAdapters1).
> >>>>>
> >>>>> I do get the following exception on invoking the method handle,
> >>>>> though:
> >>>>>
> >>>>> hresult: 0
> >>>>> factory: MemorySegment{ id=0x3898fd8a limit: 8 }
> >>>>> IDXGIFactory1Vtbl byte size: 112
> >>>>> java.lang.ClassCastException: Cannot cast
> >>>>> jdk.internal.foreign.NativeMemorySegmentImpl to
> >>>>> jdk.incubator.foreign.MemoryAddress
> >>>>> at java.base/java.lang.Class.cast(Class.java:3816)
> >>>>> at
> >>>>>
> java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:733)
>
> >>>>>
> >>>>> at com.dx12.DX12.main(DX12.java:91)
> >>>>> at
> >>>>>
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
> >>>>>
> >>>>> Method)
> >>>>> at
> >>>>>
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
>
> >>>>>
> >>>>> at
> >>>>>
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>
> >>>>>
> >>>>> at
> >>>>> java.base/java.lang.reflect.Method.invoke(Method.java:564)
> >>>>> at
> >>>>> jdk.compiler/com.sun.tools.javac.launcher.Main.execute(Main.java:415)
> >>>>> at
> >>>>> jdk.compiler/com.sun.tools.javac.launcher.Main.run(Main.java:192)
> >>>>> at
> >>>>> jdk.compiler/com.sun.tools.javac.launcher.Main.main(Main.java:132)
> >>>>> vh: VarHandle[varType=jdk.incubator.foreign.MemoryAddress,
> >>>>> coord=[interface jdk.incubator.foreign.MemorySegment]]
> >>>>>
> >>>>> Any more assistance would be greatly appreciate but undeserved :).
> >>>>>
> >>>>>
> >>>>> On Sat, Sep 12, 2020 at 1:41 AM Ty Young <youngty1997 at gmail.com>
> >>>>> wrote:
> >>>>>
> >>>>>> Not a JDK developer, but if you want to do this by hand(aka no
> >>>>>> jextract), I had to do this for NVAPI which obfuscates function
> >>>>>> pointers
> >>>>>> using keys, e.g.:
> >>>>>>
> >>>>>>
> >>>>>> nvapi_h.nvapi_QueryInterface(0x0150e828);
> >>>>>>
> >>>>>>
> >>>>>> where "0x0150e828" is the "NvAPI_Initialize" function key as per the
> >>>>>> Open Source headers Nvidia released sometime ago.
> >>>>>>
> >>>>>>
> >>>>>> The only difference is that, since the function pointer is in a
> >>>>>> struct,
> >>>>>> you need to get the segment in the struct containing the function
> >>>>>> pointer(see "slice" MemorySegment method) and actually read from it
> >>>>>> using a VarHandle. You then take that MemoryAddress, with a
> >>>>>> FunctionDescriptor and MethodType, and create a MethodHandle. For
> >>>>>> reference, this my working code("NativeFunction" and
> >>>>>> "NativeTypes" do
> >>>>>> not exist in Panama, those are mine but they dont matter) for the
> >>>>>> NvAPI_Initalize API:
> >>>>>>
> >>>>>>
> >>>>>> public class NvAPI_Initialize implements NativeFunction
> >>>>>> {
> >>>>>> private final MemoryAddress address;
> >>>>>> private final FunctionDescriptor descriptor;
> >>>>>> private final MethodType type;
> >>>>>>
> >>>>>> private final MethodHandle handle;
> >>>>>>
> >>>>>> public NvAPI_Initialize() throws NoSuchMethodException,
> >>>>>> Throwable
> >>>>>> {
> >>>>>> this.address = nvapi_h.nvapi_QueryInterface(0x0150e828);
> >>>>>>
> >>>>>> this.descriptor = FunctionDescriptor.of(NativeTypes.INT);
> >>>>>>
> >>>>>> this.type = MethodType.methodType(int.class);
> >>>>>>
> >>>>>> this.handle =
> >>>>>> CSupport.getSystemLinker().downcallHandle(this.address, this.type,
> >>>>>> this.descriptor);
> >>>>>> }
> >>>>>>
> >>>>>> // etc
> >>>>>>
> >>>>>> }
> >>>>>>
> >>>>>>
> >>>>>> It looks like in your case the FunctionDescriptor would be:
> >>>>>>
> >>>>>>
> >>>>>> this.descriptor = FunctionDescriptor.of(CSupport.C_POINTER,
> >>>>>> CSupport.C_INT, CSupport.C_POINTER);
> >>>>>>
> >>>>>>
> >>>>>> for MethodType:
> >>>>>>
> >>>>>>
> >>>>>> MethodType.methodType(MemoryAddress.class, int.class,
> >>>>>> MemoryAddress.class);
> >>>>>>
> >>>>>>
> >>>>>> where the first argument takes in a IDXGIFactory, the second an
> >>>>>> unsigned
> >>>>>> int, and the third a pointer to what looks like an opaque device
> >>>>>> that
> >>>>>> you pass to other functions.
> >>>>>>
> >>>>>>
> >>>>>> If you haven't already, it might help to make bindings with a
> >>>>>> smaller,
> >>>>>> less complicated library just to get a feel with how things work
> >>>>>> under
> >>>>>> the hood.
> >>>>>>
> >>>>>>
> >>>>>> Hope this helps.
> >>>>>>
> >>>>>>
> >>>>>> On 9/12/20 2:23 AM, Michael Ennen wrote:
> >>>>>>> Looking into this a bit further I think I chose a really bad
> >>>>>>> library to
> >>>>>>> start with as the function I need to call, EnumAdapters, is inside
> >>>>>>> some type of "VTbl" struct that is trying to emulate a C++ class
> >>>>>>> with
> >>>>>>> virtual functions. What jextract is returning is most likely
> >>>>>>> *correct*
> >>>>>>> but in this case so complicated because of how it is laid out in
> >>>>>>> C. It
> >>>>>> is
> >>>>>>> not clear at all how to grab the EnumAdapters function from
> >>>>>>> this mess, and it is probably above my head.
> >>>>>>>
> >>>>>>> EXTERN_C const IID IID_IDXGIFactory;
> >>>>>>>
> >>>>>>> #if defined(__cplusplus) && !defined(CINTERFACE)
> >>>>>>>
> >>>>>>> MIDL_INTERFACE("7b7166ec-21c7-44ae-b21a-c9ae321ae369")
> >>>>>>> IDXGIFactory : public IDXGIObject
> >>>>>>> {
> >>>>>>> public:
> >>>>>>> virtual HRESULT STDMETHODCALLTYPE EnumAdapters(
> >>>>>>> /* [in] */ UINT Adapter,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _COM_Outptr_ IDXGIAdapter **ppAdapter) = 0;
> >>>>>>>
> >>>>>>> virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(
> >>>>>>> HWND WindowHandle,
> >>>>>>> UINT Flags) = 0;
> >>>>>>>
> >>>>>>> virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation(
> >>>>>>> /* [annotation][out] */
> >>>>>>> _Out_ HWND *pWindowHandle) = 0;
> >>>>>>>
> >>>>>>> virtual HRESULT STDMETHODCALLTYPE CreateSwapChain(
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ IUnknown *pDevice,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ DXGI_SWAP_CHAIN_DESC *pDesc,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _COM_Outptr_ IDXGISwapChain **ppSwapChain) = 0;
> >>>>>>>
> >>>>>>> virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter(
> >>>>>>> /* [in] */ HMODULE Module,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _COM_Outptr_ IDXGIAdapter **ppAdapter) = 0;
> >>>>>>>
> >>>>>>> };
> >>>>>>>
> >>>>>>>
> >>>>>>> #else /* C style interface */
> >>>>>>>
> >>>>>>> typedef struct IDXGIFactoryVtbl
> >>>>>>> {
> >>>>>>> BEGIN_INTERFACE
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [in] */ REFIID riid,
> >>>>>>> /* [annotation][iid_is][out] */
> >>>>>>> _COM_Outptr_ void **ppvObject);
> >>>>>>>
> >>>>>>> ULONG ( STDMETHODCALLTYPE *AddRef )(
> >>>>>>> IDXGIFactory * This);
> >>>>>>>
> >>>>>>> ULONG ( STDMETHODCALLTYPE *Release )(
> >>>>>>> IDXGIFactory * This);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *SetPrivateData )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ REFGUID Name,
> >>>>>>> /* [in] */ UINT DataSize,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_reads_bytes_(DataSize) const void *pData);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *SetPrivateDataInterface )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ REFGUID Name,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_opt_ const IUnknown *pUnknown);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *GetPrivateData )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ REFGUID Name,
> >>>>>>> /* [annotation][out][in] */
> >>>>>>> _Inout_ UINT *pDataSize,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _Out_writes_bytes_(*pDataSize) void *pData);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *GetParent )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ REFIID riid,
> >>>>>>> /* [annotation][retval][out] */
> >>>>>>> _COM_Outptr_ void **ppParent);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *EnumAdapters )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [in] */ UINT Adapter,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _COM_Outptr_ IDXGIAdapter **ppAdapter);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *MakeWindowAssociation )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> HWND WindowHandle,
> >>>>>>> UINT Flags);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *GetWindowAssociation )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _Out_ HWND *pWindowHandle);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *CreateSwapChain )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ IUnknown *pDevice,
> >>>>>>> /* [annotation][in] */
> >>>>>>> _In_ DXGI_SWAP_CHAIN_DESC *pDesc,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _COM_Outptr_ IDXGISwapChain **ppSwapChain);
> >>>>>>>
> >>>>>>> HRESULT ( STDMETHODCALLTYPE *CreateSoftwareAdapter )(
> >>>>>>> IDXGIFactory * This,
> >>>>>>> /* [in] */ HMODULE Module,
> >>>>>>> /* [annotation][out] */
> >>>>>>> _COM_Outptr_ IDXGIAdapter **ppAdapter);
> >>>>>>>
> >>>>>>> END_INTERFACE
> >>>>>>> } IDXGIFactoryVtbl;
> >>>>>>>
> >>>>>>> interface IDXGIFactory
> >>>>>>> {
> >>>>>>> CONST_VTBL struct IDXGIFactoryVtbl *lpVtbl;
> >>>>>>> };
> >>>>>>>
> >>>>>>>
> >>>>>
> >>>>> --
> >>>>> Michael Ennen
> >>>>>
> >>>>
> >>>> --
> >>>> Michael Ennen
> >>>>
> >>>
>
--
Michael Ennen
More information about the panama-dev
mailing list