How to Pass Struct by Value?

Michael Ennen mike.ennen at gmail.com
Wed Sep 30 19:40:41 UTC 2020


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> 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>
> wrote:
>
>> See also:
>>
>>
>> https://github.com/wolfgangfengel/graphicsdemoskeleton/blob/ba11402b6027ea14322bc430a23f2aadf3c0b11c/DirectX%2012/01_Skeleton/Window.c#L263
>>
>> On Wed, Sep 30, 2020 at 11:45 AM Michael Ennen <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://github.com/curldivergence/dx12bindings/blob/841974943b7fbbd146d5372e9b496a9d72daf771/build.rs#L33
>>>
>>> On Wed, Sep 30, 2020 at 2:55 AM Jorn Vernee <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
>>>> >>
>>>> >>
>>>> >> 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 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/
>>>> >>
>>>> >> Thanks very much.
>>>>
>>>
>>>
>>> --
>>> Michael Ennen
>>>
>>
>>
>> --
>> Michael Ennen
>>
>
>
> --
> Michael Ennen
>


-- 
Michael Ennen


More information about the panama-dev mailing list