How to Pass Struct by Value?

Jorn Vernee jorn.vernee at oracle.com
Fri Oct 2 12:19:01 UTC 2020


Hi Michael,

I'm not sure what value you are printing there, since you don't show the 
code.

Presumably the ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart 
will fill in the 'ptr' field of the D3D12_CPU_DESCRIPTOR_HANDLE you pass 
it a pointer to, which is then used by 
ID3D12Device_CreateRenderTargetView. So, you could verify that the 'ptr' 
field is actually being set when calling 
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart.

Jorn

On 02/10/2020 08:12, Michael Ennen wrote:
> One thing I noticed is that when I create pRtvHandle and print it, I 
> get an address like so:
>
> pRtvHandlePtr: MemoryAddress{ base: null offset=0x1c655a6526f }
>
> The ptr struct member also seems to correspond to this number
>
> pRtvHandlePtr: 1951352115823 (converting to hex it is 0x1c655a6526f).
>
> But looking at the DirectX 12 debug errors I see:
>
> [17008] D3D12 ERROR: ID3D12Device::CreateRenderTargetView: Specified 
> CPU descriptor handle ptr=0x000001C6D33B6210 does not refer to a 
> location in a descriptor heap.  [ EXECUTION ERROR #646: 
> INVALID_DESCRIPTOR_HANDLE]
>
> And thus I am not sure where it is getting that address from...maybe 
> it's the address of the pointer itself and not the ptr struct member?
>
> But even so trying to do:
>
> ID3D12Device_CreateRenderTargetView.invokeExact(pDevice.address(), 
> pSurface0.address(), MemoryAddress.NULL, 
> MemoryAddress.ofLong(pRtvHandlePtr));
>
> yields an EXCEPTION_ACCESS_VIOLATION so I don't think that's right, 
> either.
>
> On Wed, Sep 30, 2020 at 12:40 PM Michael Ennen <mike.ennen at gmail.com 
> <mailto:mike.ennen at gmail.com>> wrote:
>
>     Sorry, that should have been:
>
>     var pRtvHandle = D3D12_CPU_DESCRIPTOR_HANDLE.allocate(scope);
>     MethodHandle
>     ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart =
>     getInstance().downcallHandle(
>     getCPUDescriptorHandleForHeapStartAddr,
>     MethodType.methodType(void.class, MemoryAddress.class,
>     MemoryAddress.class),
>     FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));
>     ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart.invokeExact(
>     pHeapDescriptor.address(), pRtvHandle.address());
>     MethodHandle ID3D12Device_CreateRenderTargetView =
>     getInstance().downcallHandle(
>     createRenderTargetViewAddr,
>     MethodType.methodType(void.class, MemoryAddress.class,
>     MemoryAddress.class, MemoryAddress.class, MemorySegment.class),
>     FunctionDescriptor.ofVoid(C_POINTER, C_POINTER, C_POINTER,
>     D3D12_CPU_DESCRIPTOR_HANDLE.$LAYOUT()));
>     ID3D12Device_CreateRenderTargetView.invokeExact(pDevice.address(),
>     pSurface0.address(), MemoryAddress.NULL, pRtvHandle);
>
>     On Wed, Sep 30, 2020 at 12:38 PM Michael Ennen
>     <mike.ennen at gmail.com <mailto:mike.ennen at gmail.com>> wrote:
>
>         I tried using your example and adapting it to the following:
>
>         var pRtvHandle = D3D12_CPU_DESCRIPTOR_HANDLE.allocate(scope);
>         MethodHandle
>         ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart =
>         getInstance().downcallHandle(
>         getCPUDescriptorHandleForHeapStartAddr,
>         MethodType.methodType(void.class, MemoryAddress.class,
>         MemorySegment.class),
>         FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));
>         ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart.invokeExact(
>         pHeapDescriptor.address(), pRtvHandle.address());
>         MethodHandle ID3D12Device_CreateRenderTargetView =
>         getInstance().downcallHandle(
>         createRenderTargetViewAddr,
>         MethodType.methodType(void.class, MemoryAddress.class,
>         MemoryAddress.class, MemoryAddress.class, MemorySegment.class),
>         FunctionDescriptor.ofVoid(C_POINTER, C_POINTER, C_POINTER,
>         D3D12_CPU_DESCRIPTOR_HANDLE.$LAYOUT()));
>         ID3D12Device_CreateRenderTargetView.invokeExact(pDevice.address(),
>         pSurface0.address(), MemoryAddress.NULL, pRtvHandle);
>
>         But no dice.
>
>
>         On Wed, Sep 30, 2020 at 11:46 AM Michael Ennen
>         <mike.ennen at gmail.com <mailto:mike.ennen at gmail.com>> wrote:
>
>             See also:
>
>             https://github.com/wolfgangfengel/graphicsdemoskeleton/blob/ba11402b6027ea14322bc430a23f2aadf3c0b11c/DirectX%2012/01_Skeleton/Window.c#L263
>             <https://urldefense.com/v3/__https://github.com/wolfgangfengel/graphicsdemoskeleton/blob/ba11402b6027ea14322bc430a23f2aadf3c0b11c/DirectX*2012/01_Skeleton/Window.c*L263__;JSM!!GqivPVa7Brio!I6BvzIBgWMA2lOJmtL2_8SkxW-f6kS61xDEp2QD_ymKDSTMczKYyQ9JYmgm4BTXB$>
>
>             On Wed, Sep 30, 2020 at 11:45 AM Michael Ennen
>             <mike.ennen at gmail.com <mailto:mike.ennen at gmail.com>> wrote:
>
>                 Ah yes I should have mentioned that this is actually
>                 an error with the unsupported DirectX 12 C API.
>
>                 See the following:
>
>                             // Even though
>                 GetCPUDescriptorHandleForHeapStart is documented as
>                 taking no arguments (except for the
>                             // this pointer), to use from C code it
>                 needs to take an additional rtvHandle argument, see,
>                 for example:
>                             //
>                 https://joshstaiger.org/notes/C-Language-Problems-in-Direct3D-12-GetCPUDescriptorHandleForHeapStart.html
>                 <https://urldefense.com/v3/__https://joshstaiger.org/notes/C-Language-Problems-in-Direct3D-12-GetCPUDescriptorHandleForHeapStart.html__;!!GqivPVa7Brio!I6BvzIBgWMA2lOJmtL2_8SkxW-f6kS61xDEp2QD_ymKDSTMczKYyQ9JYmgVwkGCK$>
>                             //
>                 https://github.com/curldivergence/dx12bindings/blob/841974943b7fbbd146d5372e9b496a9d72daf771/build.rs#L33
>                 <https://urldefense.com/v3/__https://github.com/curldivergence/dx12bindings/blob/841974943b7fbbd146d5372e9b496a9d72daf771/build.rs*L33__;Iw!!GqivPVa7Brio!I6BvzIBgWMA2lOJmtL2_8SkxW-f6kS61xDEp2QD_ymKDSTMczKYyQ9JYmnHkpAW0$>
>
>                 On Wed, Sep 30, 2020 at 2:55 AM Jorn Vernee
>                 <jorn.vernee at oracle.com
>                 <mailto:jorn.vernee at oracle.com>> wrote:
>
>                     Once again formatting is getting messed up.
>
>                     Uploaded a file here:
>                     http://cr.openjdk.java.net/~jvernee/ec.txt
>
>                     Jorn
>
>                     On 30/09/2020 11:47, Jorn Vernee wrote:
>                     > Hi Micheal,
>                     >
>                     > When I look at the d3d12.h header, I only find
>                     this declaration of
>                     > GetCPUDescriptorHandleForHeapStart:
>                     >
>                     >         D3D12_CPU_DESCRIPTOR_HANDLE (
>                     STDMETHODCALLTYPE
>                     > *GetCPUDescriptorHandleForHeapStart )(
>                     >             ID3D12DescriptorHeap * This);
>                     >
>                     > Which is in ID3D12DescriptorHeapVtbl.
>                     >
>                     > The return type being defined as:
>                     >
>                     > typedef struct D3D12_CPU_DESCRIPTOR_HANDLE
>                     >     {
>                     >     SIZE_T ptr;
>                     >     }     D3D12_CPU_DESCRIPTOR_HANDLE;
>                     >
>                     > I'd expect this to be linked and invoked as:
>                     >
>                     > MemorySegment heapDescriptorVtbl =
>                     >
>                     asSegment(ID3D12DescriptorHeap.lpVtbl$get(pHeapDescriptor),
>
>                     > ID3D12DescriptorHeapVtbl.$LAYOUT()); MemoryAddress
>                     > getCPUDescriptorHandleForHeapStartAddr =
>                     >
>                     ID3D12DescriptorHeapVtbl.GetCPUDescriptorHandleForHeapStart$get(heapDescriptorVtbl);
>
>                     > MethodHandle
>                     ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart
>                     =
>                     >
>                     getInstance().downcallHandle(getCPUDescriptorHandleForHeapStartAddr,
>
>                     > MethodType.methodType(MemorySegment.class,
>                     MemoryAddress.class),
>                     >
>                     FunctionDescriptor.of(D3D12_CPU_DESCRIPTOR_HANDLE.$LAYOUT(),
>
>                     > C_POINTER)); MemorySegment handle = (MemorySegment)
>                     >
>                     ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart.invokeExact(pHeapDescriptor.address());
>
>                     > // ^^^ don't forget to close this after using
>                     >
>                     > The linker will take care of handling all the
>                     ABI details.
>                     >
>                     > HTH,
>                     > Jorn
>                     >
>                     > On 30/09/2020 08:36, Michael Ennen wrote:
>                     >> I am messing around with DirectX 12 more and I
>                     am getting stuck on
>                     >> how to
>                     >> call the "GetCPUDescriptorHandleForHeapStart "
>                     method. It must take a
>                     >> struct by-value and not as a pointer reference.
>                     >>
>                     https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12descriptorheap-getcpudescriptorhandleforheapstart
>                     <https://urldefense.com/v3/__https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12descriptorheap-getcpudescriptorhandleforheapstart__;!!GqivPVa7Brio!I6BvzIBgWMA2lOJmtL2_8SkxW-f6kS61xDEp2QD_ymKDSTMczKYyQ9JYmoVq3N9K$>
>
>                     >>
>                     >>
>                     >> There seems to be a bit of an issue with that
>                     method as I see some
>                     >> Github
>                     >> issues talking about it's weird ABI, but I
>                     don't think I am hitting that
>                     >> issue (see
>                     https://github.com/halide/Halide/issues/5156
>                     <https://urldefense.com/v3/__https://github.com/halide/Halide/issues/5156__;!!GqivPVa7Brio!I6BvzIBgWMA2lOJmtL2_8SkxW-f6kS61xDEp2QD_ymKDSTMczKYyQ9JYmqVYKSkY$>
>                     for example).
>                     >>
>                     >> I have the following:
>                     >>
>                     >> MemorySegment heapDescriptorVtbl =
>                     >>
>                     asSegment(ID3D12DescriptorHeap.lpVtbl$get(pHeapDescriptor),
>                     >> ID3D12DescriptorHeapVtbl.$LAYOUT());
>                     >> MemoryAddress
>                     getCPUDescriptorHandleForHeapStartAddr =
>                     >>
>                     ID3D12DescriptorHeapVtbl.GetCPUDescriptorHandleForHeapStart$get(heapDescriptorVtbl);
>
>                     >>
>                     >> var pRtvHandle =
>                     D3D12_CPU_DESCRIPTOR_HANDLE.allocate(scope);
>                     >> MethodHandle
>                     ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart
>                     =
>                     >>
>                     getInstance().downcallHandle(getCPUDescriptorHandleForHeapStartAddr,
>                     >> MethodType.methodType(void.class,
>                     MemoryAddress.class,
>                     >> MemoryAddress.class),
>                     >> FunctionDescriptor.ofVoid(C_POINTER, C_POINTER));
>                     >>
>                     ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart.invokeExact(
>                     >> pHeapDescriptor.address(), pRtvHandle.address());
>                     >>
>                     >> But it is not right as I am passing in
>                     D3D12_CPU_DESCRIPTOR_HANDLE as a
>                     >> pointer.
>                     >>
>                     >> I tried exploring the Panama API and looking at
>                     tests but just didn't
>                     >> find
>                     >> what I was looking for (how to pass a struct by
>                     value, if that's
>                     >> possible
>                     >> with the ABI semantics).
>                     >>
>                     >> My current work is here:
>                     >>
>                     >> https://github.com/brcolow/java-dx12/
>                     <https://urldefense.com/v3/__https://github.com/brcolow/java-dx12/__;!!GqivPVa7Brio!I6BvzIBgWMA2lOJmtL2_8SkxW-f6kS61xDEp2QD_ymKDSTMczKYyQ9JYmp0p5LUD$>
>                     >>
>                     >> Thanks very much.
>
>
>
>                 -- 
>                 Michael Ennen
>
>
>
>             -- 
>             Michael Ennen
>
>
>
>         -- 
>         Michael Ennen
>
>
>
>     -- 
>     Michael Ennen
>
>
>
> -- 
> Michael Ennen


More information about the panama-dev mailing list