d3d12: older Windows SDK headers contain wrong function prototypes
Declare correct function pointers ourselves.
Backport of:
- 98fcf112e74dfd6b99a755c957195671e642b57d
- 89a4d9ae67e82913af71a93611f396530a05f61d
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d2c65c1..063deb0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1811,14 +1811,7 @@
check_include_file(d3d9.h HAVE_D3D_H)
check_include_file(d3d11_1.h HAVE_D3D11_H)
- check_c_source_compiles("
- #include <winsdkver.h>
- #include <sdkddkver.h>
- #include <d3d12.h>
- ID3D12Device1 *device;
- #if WDK_NTDDI_VERSION > 0x0A000008
- int main(int argc, char **argv) { return 0; }
- #endif" HAVE_D3D12_H)
+ check_include_file(d3d12.h HAVE_D3D12_H)
check_include_file(ddraw.h HAVE_DDRAW_H)
check_include_file(dsound.h HAVE_DSOUND_H)
check_include_file(dinput.h HAVE_DINPUT_H)
diff --git a/configure b/configure
index c3a2509..f9994b8 100755
--- a/configure
+++ b/configure
@@ -27513,36 +27513,12 @@
have_d3d11=yes
fi
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for d3d12 Windows SDK version" >&5
-printf %s "checking for d3d12 Windows SDK version... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-#include <winsdkver.h>
-#include <sdkddkver.h>
-#include <d3d12.h>
-ID3D12Device1 *device;
-#if WDK_NTDDI_VERSION <= 0x0A000008
-asdf
-#endif
-
-int
-main (void)
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"
+ ac_fn_c_check_header_compile "$LINENO" "d3d12.h" "ac_cv_header_d3d12_h" "$ac_includes_default"
+if test "x$ac_cv_header_d3d12_h" = xyes
then :
have_d3d12=yes
-else $as_nop
- have_d3d12=no
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_d3d12" >&5
-printf "%s\n" "$have_d3d12" >&6; }
+
ac_fn_c_check_header_compile "$LINENO" "ddraw.h" "ac_cv_header_ddraw_h" "$ac_includes_default"
if test "x$ac_cv_header_ddraw_h" = xyes
then :
diff --git a/configure.ac b/configure.ac
index 2477191..982ba2a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3343,17 +3343,7 @@
if test x$enable_directx = xyes; then
AC_CHECK_HEADER(d3d9.h, have_d3d=yes)
AC_CHECK_HEADER(d3d11_1.h, have_d3d11=yes)
- AC_MSG_CHECKING(for d3d12 Windows SDK version)
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <winsdkver.h>
-#include <sdkddkver.h>
-#include <d3d12.h>
-ID3D12Device1 *device;
-#if WDK_NTDDI_VERSION <= 0x0A000008
-asdf
-#endif
- ]])], [have_d3d12=yes],[have_d3d12=no])
- AC_MSG_RESULT($have_d3d12)
+ AC_CHECK_HEADER(d3d12.h, have_d3d12=yes)
AC_CHECK_HEADER(ddraw.h, have_ddraw=yes)
AC_CHECK_HEADER(dsound.h, have_dsound=yes)
AC_CHECK_HEADER(dinput.h, have_dinput=yes)
diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c
index 9b097f0..8a607bf 100644
--- a/src/render/direct3d12/SDL_render_d3d12.c
+++ b/src/render/direct3d12/SDL_render_d3d12.c
@@ -48,6 +48,7 @@
#include <dxgi1_6.h>
#include <dxgidebug.h>
#include <d3d12sdklayers.h>
+#include <sdkddkver.h>
#endif
#include "SDL_shaders_d3d12.h"
@@ -83,6 +84,54 @@
#define D3D_GUID(X) &(X)
#endif
+/*
+ * Older MS Windows SDK headers declare some d3d12 functions with the wrong function prototype.
+ * - ID3D12Heap::GetDesc
+ * - ID3D12Resource::GetDesc
+ * - ID3D12DescriptorHeap::GetDesc
+ * (and 9 more)+
+ * This is fixed in SDKs since WDK_NTDDI_VERSION >= NTDDI_WIN10_FE (0x0A00000A)
+ */
+
+#if !(defined(__MINGW32__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)) \
+ && (WDK_NTDDI_VERSION < 0x0A00000A)
+
+#define D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(THIS, ...) do { \
+ void (STDMETHODCALLTYPE * func)(ID3D12DescriptorHeap * This, D3D12_CPU_DESCRIPTOR_HANDLE * Handle) = \
+ (void*)(THIS)->lpVtbl->GetCPUDescriptorHandleForHeapStart; \
+ func((THIS), ##__VA_ARGS__); \
+ } while (0)
+
+#define D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(THIS, ...) do { \
+ void (STDMETHODCALLTYPE * func)(ID3D12DescriptorHeap * This, D3D12_GPU_DESCRIPTOR_HANDLE * Handle) = \
+ (void*)(THIS)->lpVtbl->GetGPUDescriptorHandleForHeapStart; \
+ func((THIS), ##__VA_ARGS__); \
+ } while (0)
+
+#define D3D_CALL_RET_ID3D12Resource_GetDesc(THIS, ...) do { \
+ void (STDMETHODCALLTYPE * func)(ID3D12Resource * This, D3D12_RESOURCE_DESC * Desc) = \
+ (void*)(THIS)->lpVtbl->GetDesc; \
+ func((THIS), ##__VA_ARGS__); \
+ } while (0)
+
+#else
+
+/*
+ * MinGW has correct function prototypes in the vtables, but defines wrong functions
+ * Xbox just needs these macros defined as used below (because CINTERFACE doesn't exist)
+ */
+
+#define D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(THIS, ...) \
+ D3D_CALL_RET(THIS, GetCPUDescriptorHandleForHeapStart, ##__VA_ARGS__);
+
+#define D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(THIS, ...) \
+ D3D_CALL_RET(THIS, GetGPUDescriptorHandleForHeapStart, ##__VA_ARGS__);
+
+#define D3D_CALL_RET_ID3D12Resource_GetDesc(THIS, ...) \
+ D3D_CALL_RET(THIS, GetDesc, ##__VA_ARGS__);
+
+#endif
+
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
@@ -398,10 +447,10 @@
SIZE_T offset;
/* Calculate the correct offset into the heap */
- D3D_CALL_RET(heap, GetCPUDescriptorHandleForHeapStart, &CPUHeapStart);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(heap, &CPUHeapStart);
offset = CPUHandle.ptr - CPUHeapStart.ptr;
- D3D_CALL_RET(heap, GetGPUDescriptorHandleForHeapStart, &GPUHandle);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetGPUDescriptorHandleForHeapStart(heap, &GPUHandle);
GPUHandle.ptr += offset;
return GPUHandle;
@@ -432,7 +481,7 @@
}
SDL_zero(rtvDescriptor);
- D3D_CALL_RET(data->rtvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &rtvDescriptor);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->rtvDescriptorHeap, &rtvDescriptor);
rtvDescriptor.ptr += data->currentBackBufferIndex * data->rtvDescriptorSize;
return rtvDescriptor;
}
@@ -1052,7 +1101,7 @@
samplerDesc.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
samplerDesc.MinLOD = 0.0f;
samplerDesc.MaxLOD = D3D12_FLOAT32_MAX;
- D3D_CALL_RET(data->samplerDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &data->nearestPixelSampler);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->samplerDescriptorHeap, &data->nearestPixelSampler);
D3D_CALL(data->d3dDevice, CreateSampler, &samplerDesc, data->nearestPixelSampler);
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
@@ -1341,7 +1390,7 @@
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
SDL_zero(rtvDescriptor);
- D3D_CALL_RET(data->rtvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &rtvDescriptor);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(data->rtvDescriptorHeap, &rtvDescriptor);
rtvDescriptor.ptr += i * data->rtvDescriptorSize;
D3D_CALL(data->d3dDevice, CreateRenderTargetView, data->renderTargets[i], &rtvDesc, rtvDescriptor);
}
@@ -1555,7 +1604,7 @@
resourceViewDesc.Texture2D.MipLevels = textureDesc.MipLevels;
textureData->mainSRVIndex = D3D12_GetAvailableSRVIndex(renderer);
- D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceView);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceView);
textureData->mainTextureResourceView.ptr += textureData->mainSRVIndex * rendererData->srvDescriptorSize;
D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView,
@@ -1564,7 +1613,7 @@
textureData->mainTextureResourceView);
#if SDL_HAVE_YUV
if (textureData->yuv) {
- D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceViewU);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewU);
textureData->mainSRVIndexU = D3D12_GetAvailableSRVIndex(renderer);
textureData->mainTextureResourceViewU.ptr += textureData->mainSRVIndexU * rendererData->srvDescriptorSize;
D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView,
@@ -1572,7 +1621,7 @@
&resourceViewDesc,
textureData->mainTextureResourceViewU);
- D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceViewV);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewV);
textureData->mainSRVIndexV = D3D12_GetAvailableSRVIndex(renderer);
textureData->mainTextureResourceViewV.ptr += textureData->mainSRVIndexV * rendererData->srvDescriptorSize;
D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView,
@@ -1586,7 +1635,7 @@
nvResourceViewDesc.Format = DXGI_FORMAT_R8G8_UNORM;
- D3D_CALL_RET(rendererData->srvDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureResourceViewNV);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->srvDescriptorHeap, &textureData->mainTextureResourceViewNV);
textureData->mainSRVIndexNV = D3D12_GetAvailableSRVIndex(renderer);
textureData->mainTextureResourceViewNV.ptr += textureData->mainSRVIndexNV * rendererData->srvDescriptorSize;
D3D_CALL(rendererData->d3dDevice, CreateShaderResourceView,
@@ -1603,7 +1652,7 @@
renderTargetViewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;
- D3D_CALL_RET(rendererData->textureRTVDescriptorHeap, GetCPUDescriptorHandleForHeapStart, &textureData->mainTextureRenderTargetView);
+ D3D_CALL_RET_ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(rendererData->textureRTVDescriptorHeap, &textureData->mainTextureRenderTargetView);
textureData->mainTextureRenderTargetView.ptr += textureData->mainSRVIndex * rendererData->rtvDescriptorSize;
D3D_CALL(rendererData->d3dDevice, CreateRenderTargetView,
@@ -1668,7 +1717,7 @@
/* Create an upload buffer, which will be used to write to the main texture. */
SDL_zero(textureDesc);
- D3D_CALL_RET(texture, GetDesc, &textureDesc);
+ D3D_CALL_RET_ID3D12Resource_GetDesc(texture, &textureDesc);
textureDesc.Width = w;
textureDesc.Height = h;
@@ -1924,7 +1973,7 @@
/* Create an upload buffer, which will be used to write to the main texture. */
SDL_zero(textureDesc);
- D3D_CALL_RET(textureData->mainTexture, GetDesc, &textureDesc);
+ D3D_CALL_RET_ID3D12Resource_GetDesc(textureData->mainTexture, &textureDesc);
textureDesc.Width = rect->w;
textureDesc.Height = rect->h;
@@ -2033,7 +2082,7 @@
D3D_CALL(textureData->stagingBuffer, Unmap, 0, NULL);
SDL_zero(textureDesc);
- D3D_CALL_RET(textureData->mainTexture, GetDesc, &textureDesc);
+ D3D_CALL_RET_ID3D12Resource_GetDesc(textureData->mainTexture, &textureDesc);
textureDesc.Width = textureData->lockedRect.w;
textureDesc.Height = textureData->lockedRect.h;
@@ -2744,7 +2793,7 @@
/* Create a staging texture to copy the screen's data to: */
SDL_zero(textureDesc);
- D3D_CALL_RET(backBuffer, GetDesc, &textureDesc);
+ D3D_CALL_RET_ID3D12Resource_GetDesc(backBuffer, &textureDesc);
textureDesc.Width = rect->w;
textureDesc.Height = rect->h;