From 53565c99291e2de15b21ce17073ecbc537b0107d Mon Sep 17 00:00:00 2001 From: Jesse Natalie Date: Sat, 2 Jul 2022 07:34:07 -0700 Subject: [PATCH] dzn: Add ABI helpers for D3D12 functions returning structs The currently available D3D12 API headers have incorrect C function prototypes for these functions when compiling for non-Windows platforms. Future changes here will move these helpers into the DirectX-Headers project, but: * The process of getting a fix into the headers is still ongoing * I'd prefer to avoid taking an immediate dependency on just-published headers again So, for now add some helpers to work around this problem in Dozen Acked-by: Boris Brezillon Reviewed-by: Bill Kristiansen Part-of: --- src/microsoft/vulkan/dzn_abi_helper.h | 98 +++++++++++++++++++++++ src/microsoft/vulkan/dzn_cmd_buffer.c | 3 +- src/microsoft/vulkan/dzn_descriptor_set.c | 6 +- src/microsoft/vulkan/dzn_device.c | 3 +- src/microsoft/vulkan/dzn_image.c | 3 +- src/microsoft/vulkan/dzn_private.h | 1 + 6 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 src/microsoft/vulkan/dzn_abi_helper.h diff --git a/src/microsoft/vulkan/dzn_abi_helper.h b/src/microsoft/vulkan/dzn_abi_helper.h new file mode 100644 index 00000000000..dad871cd69c --- /dev/null +++ b/src/microsoft/vulkan/dzn_abi_helper.h @@ -0,0 +1,98 @@ +/* + * Copyright © Microsoft Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* The purpose of this file is to abstract the differences between the Windows + * C ABI for D3D12 and the Linux ABI. Essentially, for class methods that return + * structures, the MSVC C++ ABI specifies that they are always called with the return + * structure allocated by the caller, and passed as a hidden second parameter, + * after "this". But the C compiler doesn't apply that automatically to the C + * equivalent definition of the method, and so that ABI needs to be explicitly + * embedded in the C function signature. For Linux, no such ABI difference between + * C and C++ exists, and so C callers should use the same signature as C++. + */ + +#ifndef DZN_ABI_HELPER_H +#define DZN_ABI_HELPER_H + +static inline D3D12_HEAP_PROPERTIES +dzn_ID3D12Device2_GetCustomHeapProperties(ID3D12Device2 *dev, UINT node_mask, D3D12_HEAP_TYPE type) +{ + D3D12_HEAP_PROPERTIES ret; +#ifdef _WIN32 + ID3D12Device2_GetCustomHeapProperties(dev, &ret, node_mask, type); +#else + ret = ((D3D12_HEAP_PROPERTIES (STDMETHODCALLTYPE *)(ID3D12Device2 *, UINT, D3D12_HEAP_TYPE))dev->lpVtbl->GetCustomHeapProperties)(dev, node_mask, type); +#endif + return ret; +} + +static inline D3D12_RESOURCE_ALLOCATION_INFO +dzn_ID3D12Device2_GetResourceAllocationInfo(ID3D12Device2 *dev, UINT visible_mask, UINT num_resource_descs, const D3D12_RESOURCE_DESC *resource_descs) +{ + D3D12_RESOURCE_ALLOCATION_INFO ret; +#ifdef _WIN32 + ID3D12Device2_GetResourceAllocationInfo(dev, &ret, visible_mask, num_resource_descs, resource_descs); +#else + ret = ((D3D12_RESOURCE_ALLOCATION_INFO (STDMETHODCALLTYPE *)(ID3D12Device2 *, UINT, UINT, const D3D12_RESOURCE_DESC *)) + dev->lpVtbl->GetResourceAllocationInfo)(dev, visible_mask, num_resource_descs, resource_descs); +#endif + return ret; +} + +static inline D3D12_RESOURCE_DESC +dzn_ID3D12Resource_GetDesc(ID3D12Resource *res) +{ + D3D12_RESOURCE_DESC ret; +#ifdef _WIN32 + ID3D12Resource_GetDesc(res, &ret); +#else + ret = ((D3D12_RESOURCE_DESC (STDMETHODCALLTYPE *)(ID3D12Resource *))res->lpVtbl->GetDesc)(res); +#endif + return ret; +} + +static inline D3D12_CPU_DESCRIPTOR_HANDLE +dzn_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(ID3D12DescriptorHeap *heap) +{ + D3D12_CPU_DESCRIPTOR_HANDLE ret; +#ifdef _WIN32 + ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap, &ret); +#else + ret = ((D3D12_CPU_DESCRIPTOR_HANDLE (STDMETHODCALLTYPE *)(ID3D12DescriptorHeap *))heap->lpVtbl->GetCPUDescriptorHandleForHeapStart)(heap); +#endif + return ret; +} + +static inline D3D12_GPU_DESCRIPTOR_HANDLE +dzn_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(ID3D12DescriptorHeap *heap) +{ + D3D12_GPU_DESCRIPTOR_HANDLE ret; +#ifdef _WIN32 + ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap, &ret); +#else + ret = ((D3D12_GPU_DESCRIPTOR_HANDLE (STDMETHODCALLTYPE *)(ID3D12DescriptorHeap *))heap->lpVtbl->GetGPUDescriptorHandleForHeapStart)(heap); +#endif + return ret; +} + +#endif /*DZN_ABI_HELPER_H*/ diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c index 123d643105a..a2ca319d413 100644 --- a/src/microsoft/vulkan/dzn_cmd_buffer.c +++ b/src/microsoft/vulkan/dzn_cmd_buffer.c @@ -95,8 +95,7 @@ dzn_cmd_buffer_queue_transition_barriers(struct dzn_cmd_buffer *cmdbuf, struct D3D12_RESOURCE_BARRIER *barriers = he ? he->data : NULL; if (!barriers) { - D3D12_RESOURCE_DESC desc; - ID3D12Resource_GetDesc(res, &desc); + D3D12_RESOURCE_DESC desc = dzn_ID3D12Resource_GetDesc(res); D3D12_FEATURE_DATA_FORMAT_INFO fmt_info = { desc.Format, 0 }; ID3D12Device_CheckFeatureSupport(device->dev, D3D12_FEATURE_FORMAT_INFO, &fmt_info, sizeof(fmt_info)); uint32_t barrier_count = diff --git a/src/microsoft/vulkan/dzn_descriptor_set.c b/src/microsoft/vulkan/dzn_descriptor_set.c index 685d74704d9..fe7b7b212c4 100644 --- a/src/microsoft/vulkan/dzn_descriptor_set.c +++ b/src/microsoft/vulkan/dzn_descriptor_set.c @@ -825,12 +825,10 @@ dzn_descriptor_heap_init(struct dzn_descriptor_heap *heap, VK_ERROR_OUT_OF_DEVICE_MEMORY : VK_ERROR_OUT_OF_HOST_MEMORY); } - D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle; - ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap->heap, &cpu_handle); + D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle = dzn_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap->heap); heap->cpu_base = cpu_handle.ptr; if (shader_visible) { - D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle; - ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap->heap, &gpu_handle); + D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle = dzn_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap->heap); heap->gpu_base = gpu_handle.ptr; } diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c index 2bce231969b..c26dbac99e7 100644 --- a/src/microsoft/vulkan/dzn_device.c +++ b/src/microsoft/vulkan/dzn_device.c @@ -1864,8 +1864,7 @@ static VkResult dzn_device_query_init(struct dzn_device *device) { /* FIXME: create the resource in the default heap */ - D3D12_HEAP_PROPERTIES hprops; - ID3D12Device1_GetCustomHeapProperties(device->dev, &hprops, 0, D3D12_HEAP_TYPE_UPLOAD); + D3D12_HEAP_PROPERTIES hprops = dzn_ID3D12Device2_GetCustomHeapProperties(device->dev, 0, D3D12_HEAP_TYPE_UPLOAD); D3D12_RESOURCE_DESC rdesc = { .Dimension = D3D12_RESOURCE_DIMENSION_BUFFER, .Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, diff --git a/src/microsoft/vulkan/dzn_image.c b/src/microsoft/vulkan/dzn_image.c index c14b6fb791f..9a369789ce5 100644 --- a/src/microsoft/vulkan/dzn_image.c +++ b/src/microsoft/vulkan/dzn_image.c @@ -759,8 +759,7 @@ dzn_GetImageMemoryRequirements2(VkDevice _device, } } - D3D12_RESOURCE_ALLOCATION_INFO info; - ID3D12Device1_GetResourceAllocationInfo(device->dev, &info, 0, 1, &image->desc); + D3D12_RESOURCE_ALLOCATION_INFO info = dzn_ID3D12Device2_GetResourceAllocationInfo(device->dev, 0, 1, &image->desc); pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) { .size = info.SizeInBytes, diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 66f65e35bf4..9e9ee55d897 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -63,6 +63,7 @@ #include #include "spirv_to_dxil.h" +#include "dzn_abi_helper.h" #define DZN_SWAP(t, a, b) \ do { \