diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c index 4b03ca6d57..ffb7996e00 100644 --- a/src/render/direct3d12/SDL_render_d3d12.c +++ b/src/render/direct3d12/SDL_render_d3d12.c @@ -52,7 +52,7 @@ #define SDL_COMPOSE_ERROR(str) SDL_STRINGIFY_ARG(__FUNCTION__) ", " str #endif -#ifdef __cplusplus +#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES) #define SAFE_RELEASE(X) \ if (X) { \ (X)->Release(); \ @@ -61,6 +61,8 @@ #define D3D_CALL(THIS, FUNC, ...) (THIS)->FUNC(__VA_ARGS__) #define D3D_CALL_RET(THIS, FUNC, RETVAL, ...) *(RETVAL) = (THIS)->FUNC(__VA_ARGS__) #define D3D_GUID(X) (X) +/* DXGI_PRESENT flags are removed on Xbox */ +#define DXGI_PRESENT_ALLOW_TEARING 0 #else #define SAFE_RELEASE(X) \ if (X) { \ @@ -72,6 +74,53 @@ #define D3D_GUID(X) &(X) #endif +/* + * Older Windows SDK headers declare some d3d12 functions with the wrong function prototype. + * - ID3D12Heap::GetDesc + * - ID3D12Resource::GetDesc + * - ID3D12DescriptorHeap::GetDesc + * (and 9 more) + * */ + +#if !(defined(__MINGW32__) || defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) \ + && (!defined(D3D12_SDK_VERSION) || D3D12_SDK_VERSION < 3) + +#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" { @@ -479,10 +528,10 @@ static D3D12_GPU_DESCRIPTOR_HANDLE D3D12_CPUtoGPUHandle(ID3D12DescriptorHeap *he 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; @@ -513,7 +562,7 @@ static D3D12_CPU_DESCRIPTOR_HANDLE D3D12_GetCurrentRenderTargetView(SDL_Renderer } 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; } @@ -1124,7 +1173,7 @@ static HRESULT D3D12_CreateDeviceResources(SDL_Renderer *renderer) 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; @@ -1453,7 +1502,7 @@ static HRESULT D3D12_CreateWindowSizeDependentResources(SDL_Renderer *renderer) 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); } @@ -1710,7 +1759,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL 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, @@ -1719,7 +1768,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL 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, @@ -1727,7 +1776,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL &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, @@ -1746,7 +1795,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL } nvResourceViewDesc.Texture2D.PlaneSlice = 1; - 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, @@ -1763,7 +1812,7 @@ static int D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL 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, @@ -1827,7 +1876,7 @@ static int D3D12_UpdateTextureInternal(D3D12_RenderData *rendererData, ID3D12Res /* 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; if (textureDesc.Format == DXGI_FORMAT_NV12 || @@ -2083,7 +2132,7 @@ static int D3D12_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, /* 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; @@ -2192,7 +2241,7 @@ static void D3D12_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) 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; @@ -2964,7 +3013,7 @@ static SDL_Surface *D3D12_RenderReadPixels(SDL_Renderer *renderer, const SDL_Rec /* 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;