Xbox GDKX support (#5869)

* Xbox GDK support (14 squashed commits)

* Added basic keyboard testing

* Update readme

* Code review fixes

* Fixed issue where controller add/removal wasn't working (since the device notification events don't work on Xbox, have to use the joystick thread to poll XInput)
This commit is contained in:
chalonverse
2022-07-01 13:59:14 -07:00
committed by GitHub
parent 0025621b80
commit f317d619cc
77 changed files with 2573 additions and 74 deletions

View File

@@ -38,10 +38,17 @@
#include "../SDL_sysrender.h"
#include "../SDL_d3dmath.h"
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
#include "SDL_render_d3d12_xbox.h"
#ifndef D3D12_TEXTURE_DATA_PITCH_ALIGNMENT
#define D3D12_TEXTURE_DATA_PITCH_ALIGNMENT 256
#endif
#else
#include <d3d12.h>
#include <dxgi1_6.h>
#include <dxgidebug.h>
#include <d3d12sdklayers.h>
#endif
#include "SDL_shaders_d3d12.h"
@@ -153,14 +160,18 @@ typedef struct
{
void *hDXGIMod;
void *hD3D12Mod;
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
UINT64 frameToken;
#else
IDXGIFactory6 *dxgiFactory;
IDXGIAdapter4 *dxgiAdapter;
IDXGIDebug *dxgiDebug;
IDXGISwapChain4 *swapChain;
#endif
ID3D12Device1 *d3dDevice;
ID3D12Debug *debugInterface;
IDXGIDebug *dxgiDebug;
ID3D12CommandQueue *commandQueue;
ID3D12GraphicsCommandList2 *commandList;
IDXGISwapChain4 *swapChain;
DXGI_SWAP_EFFECT swapEffect;
/* Descriptor heaps */
@@ -231,7 +242,7 @@ typedef struct
static const GUID SDL_IID_IDXGIFactory6 = { 0xc1b6694f, 0xff09, 0x44a9, { 0xb0, 0x3c, 0x77, 0x90, 0x0a, 0x0a, 0x1d, 0x17 } };
static const GUID SDL_IID_IDXGIAdapter4 = { 0x3c8d99d1, 0x4fbf, 0x4181, { 0xa8, 0x2c, 0xaf, 0x66, 0xbf, 0x7b, 0xd2, 0x4e } };
static const GUID SDL_IID_IDXGIDevice1 = { 0x77db970f, 0x6276, 0x48ba, { 0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c } };
static const GUID SDL_IID_ID3D12Device5 = { 0x8b4f173b, 0x2fea, 0x4b80, { 0x8f, 0x58, 0x43, 0x07, 0x19, 0x1a, 0xb9, 0x5d } };
static const GUID SDL_IID_ID3D12Device1 = { 0x77acce80, 0x638e, 0x4e65, { 0x88, 0x95, 0xc1, 0xf2, 0x33, 0x86, 0x86, 0x3e } };
static const GUID SDL_IID_IDXGISwapChain4 = { 0x3D585D5A, 0xBD4A, 0x489E, { 0xB1, 0xF4, 0x3D, 0xBC, 0xB6, 0x45, 0x2F, 0xFB } };
static const GUID SDL_IID_IDXGIDebug1 = { 0xc5a05f0c, 0x16f2, 0x4adf, { 0x9f, 0x4d, 0xa8, 0xc4, 0xd5, 0x8a, 0xc5, 0x50 } };
static const GUID SDL_IID_IDXGIInfoQueue = { 0xD67441C7,0x672A,0x476f, { 0x9E,0x82,0xCD,0x55,0xB4,0x49,0x49,0xCE } };
@@ -307,8 +318,11 @@ D3D12_ReleaseAll(SDL_Renderer * renderer)
if (data) {
int i;
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
SAFE_RELEASE(data->dxgiFactory);
SAFE_RELEASE(data->dxgiAdapter);
SAFE_RELEASE(data->swapChain);
#endif
SAFE_RELEASE(data->d3dDevice);
SAFE_RELEASE(data->debugInterface);
SAFE_RELEASE(data->commandQueue);
@@ -317,7 +331,6 @@ D3D12_ReleaseAll(SDL_Renderer * renderer)
SAFE_RELEASE(data->textureRTVDescriptorHeap);
SAFE_RELEASE(data->srvDescriptorHeap);
SAFE_RELEASE(data->samplerDescriptorHeap);
SAFE_RELEASE(data->swapChain);
SAFE_RELEASE(data->fence);
for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) {
@@ -345,12 +358,14 @@ D3D12_ReleaseAll(SDL_Renderer * renderer)
data->currentRenderTargetView.ptr = 0;
data->currentSampler.ptr = 0;
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
/* Check for any leaks if in debug mode */
if (data->dxgiDebug) {
DXGI_DEBUG_RLO_FLAGS rloFlags = (DXGI_DEBUG_RLO_FLAGS)(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL);
D3D_CALL(data->dxgiDebug, ReportLiveObjects, SDL_DXGI_DEBUG_ALL, rloFlags);
SAFE_RELEASE(data->dxgiDebug);
}
#endif
/* Unload the D3D libraries. This should be done last, in order
* to prevent IUnknown::Release() calls from crashing.
@@ -700,10 +715,12 @@ D3D12_CreateVertexBuffer(D3D12_RenderData *data, size_t vbidx, size_t size)
static HRESULT
D3D12_CreateDeviceResources(SDL_Renderer* renderer)
{
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
typedef HRESULT(WINAPI* PFN_CREATE_DXGI_FACTORY)(UINT flags, REFIID riid, void** ppFactory);
PFN_CREATE_DXGI_FACTORY CreateDXGIFactoryFunc;
D3D12_RenderData* data = (D3D12_RenderData*)renderer->driverdata;
PFN_D3D12_CREATE_DEVICE D3D12CreateDeviceFunc;
#endif
D3D12_RenderData* data = (D3D12_RenderData*)renderer->driverdata;
ID3D12Device* d3dDevice = NULL;
HRESULT result = S_OK;
UINT creationFlags = 0;
@@ -728,6 +745,10 @@ D3D12_CreateDeviceResources(SDL_Renderer* renderer)
DXGI_FORMAT_R8_UNORM
};
/* See if we need debug interfaces */
createDebug = SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_FALSE);
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
data->hDXGIMod = SDL_LoadObject("dxgi.dll");
if (!data->hDXGIMod) {
result = E_FAIL;
@@ -752,9 +773,6 @@ D3D12_CreateDeviceResources(SDL_Renderer* renderer)
goto done;
}
/* See if we need debug interfaces */
createDebug = SDL_GetHintBoolean(SDL_HINT_RENDER_DIRECT3D11_DEBUG, SDL_FALSE);
if (createDebug) {
PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterfaceFunc;
@@ -766,7 +784,15 @@ D3D12_CreateDeviceResources(SDL_Renderer* renderer)
D3D12GetDebugInterfaceFunc(D3D_GUID(SDL_IID_ID3D12Debug), (void**)&data->debugInterface);
D3D_CALL(data->debugInterface, EnableDebugLayer);
}
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
result = D3D12_XBOX_CreateDevice(&d3dDevice, createDebug);
if (FAILED(result)) {
/* SDL Error is set by D3D12_XBOX_CreateDevice */
goto done;
}
#else
if (createDebug) {
#ifdef __IDXGIInfoQueue_INTERFACE_DEFINED__
IDXGIInfoQueue *dxgiInfoQueue = NULL;
@@ -818,7 +844,7 @@ D3D12_CreateDeviceResources(SDL_Renderer* renderer)
result = D3D12CreateDeviceFunc((IUnknown *)data->dxgiAdapter,
D3D_FEATURE_LEVEL_11_0, /* Request minimum feature level 11.0 for maximum compatibility */
D3D_GUID(SDL_IID_ID3D12Device5),
D3D_GUID(SDL_IID_ID3D12Device1),
(void **)&d3dDevice
);
if (FAILED(result)) {
@@ -848,10 +874,11 @@ D3D12_CreateDeviceResources(SDL_Renderer* renderer)
SAFE_RELEASE(infoQueue);
}
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
result = D3D_CALL(d3dDevice, QueryInterface, D3D_GUID(SDL_IID_ID3D12Device5), (void **)&data->d3dDevice);
result = D3D_CALL(d3dDevice, QueryInterface, D3D_GUID(SDL_IID_ID3D12Device1), (void **)&data->d3dDevice);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device to ID3D12Device5"), result);
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("ID3D12Device to ID3D12Device1"), result);
goto done;
}
@@ -1120,6 +1147,7 @@ D3D12_GetViewportAlignedD3DRect(SDL_Renderer * renderer, const SDL_Rect * sdlRec
return 0;
}
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
static HRESULT
D3D12_CreateSwapChain(SDL_Renderer * renderer, int w, int h)
{
@@ -1187,6 +1215,7 @@ done:
SAFE_RELEASE(swapChain);
return result;
}
#endif
static HRESULT D3D12_UpdateForWindowSizeChange(SDL_Renderer * renderer);
@@ -1246,6 +1275,7 @@ D3D12_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
h = tmp;
}
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
if (data->swapChain) {
/* If the swap chain already exists, resize it. */
result = D3D_CALL(data->swapChain, ResizeBuffers,
@@ -1283,9 +1313,17 @@ D3D12_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
}
}
}
#endif /*!defined(__XBOXONE__) && !defined(__XBOXSERIES__)*/
/* Get each back buffer render target and create render target views */
for (i = 0; i < SDL_D3D12_NUM_BUFFERS; ++i) {
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
result = D3D12_XBOX_CreateBackBufferTarget(data->d3dDevice, renderer->window->w, renderer->window->h, (void **) &data->renderTargets[i]);
if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("D3D12_XBOX_CreateBackBufferTarget"), result);
goto done;
}
#else
result = D3D_CALL(data->swapChain, GetBuffer,
i,
D3D_GUID(SDL_IID_ID3D12Resource),
@@ -1295,6 +1333,7 @@ D3D12_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain4::GetBuffer"), result);
goto done;
}
#endif
SDL_zero(rtvDesc);
rtvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
@@ -1307,7 +1346,11 @@ D3D12_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
}
/* Set back buffer index to current buffer */
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
data->currentBackBufferIndex = 0;
#else
data->currentBackBufferIndex = D3D_CALL(data->swapChain, GetCurrentBackBufferIndex);
#endif
/* Set the swap chain target immediately, so that a target is always set
* even before we get to SetDrawState. Without this it's possible to hit
@@ -1323,6 +1366,10 @@ D3D12_CreateWindowSizeDependentResources(SDL_Renderer * renderer)
data->viewportDirty = SDL_TRUE;
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
D3D12_XBOX_StartFrame(data->d3dDevice, &data->frameToken);
#endif
done:
return result;
}
@@ -2870,8 +2917,10 @@ static void
D3D12_RenderPresent(SDL_Renderer * renderer)
{
D3D12_RenderData *data = (D3D12_RenderData *) renderer->driverdata;
#if !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
UINT syncInterval;
UINT presentFlags;
#endif
HRESULT result;
/* Transition the render target to present state */
@@ -2885,6 +2934,9 @@ D3D12_RenderPresent(SDL_Renderer * renderer)
result = D3D_CALL(data->commandList, Close);
D3D_CALL(data->commandQueue, ExecuteCommandLists, 1, (ID3D12CommandList * const *)&data->commandList);
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
result = D3D12_XBOX_PresentFrame(data->commandQueue, data->frameToken, data->renderTargets[data->currentBackBufferIndex]);
#else
if (renderer->info.flags & SDL_RENDERER_PRESENTVSYNC) {
syncInterval = 1;
presentFlags = 0;
@@ -2897,6 +2949,7 @@ D3D12_RenderPresent(SDL_Renderer * renderer)
* rects to improve efficiency in certain scenarios.
*/
result = D3D_CALL(data->swapChain, Present, syncInterval, presentFlags);
#endif
if (FAILED(result) && result != DXGI_ERROR_WAS_STILL_DRAWING) {
/* If the device was removed either by a disconnect or a driver upgrade, we
@@ -2923,7 +2976,12 @@ D3D12_RenderPresent(SDL_Renderer * renderer)
}
data->fenceValue++;
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
data->currentBackBufferIndex++;
data->currentBackBufferIndex %= SDL_D3D12_NUM_BUFFERS;
#else
data->currentBackBufferIndex = D3D_CALL(data->swapChain, GetCurrentBackBufferIndex);
#endif
/* Reset the command allocator and command list, and transition back to render target */
D3D12_ResetCommandList(data);
@@ -2932,6 +2990,10 @@ D3D12_RenderPresent(SDL_Renderer * renderer)
D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATE_RENDER_TARGET
);
#if defined(__XBOXONE__) || defined(__XBOXSERIES__)
D3D12_XBOX_StartFrame(data->d3dDevice, &data->frameToken);
#endif
}
}

View File

@@ -0,0 +1,27 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && (defined(__XBOXONE__) || defined(__XBOXSERIES__))
#include "SDL_render_d3d12_xbox.h"
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."
#endif

View File

@@ -0,0 +1,22 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."

View File

@@ -20,11 +20,10 @@
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED
#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && !defined(__XBOXONE__) && !defined(__XBOXSERIES__)
#include "SDL_stdinc.h"
#define COBJMACROS
#include "../../core/windows/SDL_windows.h"
#include <d3d12.h>
@@ -59,11 +58,6 @@
xxd --include <FILE>
*/
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
#define D3D12_USE_SHADER_MODEL_4_0_level_9_3
#else
#define D3D12_USE_SHADER_MODEL_4_0_level_9_1
#endif
/* The color-only-rendering pixel shader:
@@ -6962,6 +6956,6 @@ void D3D12_GetRootSignatureData(D3D12_RootSignature rootSig, D3D12_SHADER_BYTECO
outBytecode->BytecodeLength = D3D12_rootsigs[rootSig].rs_shader_size;
}
#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED */
#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && !defined(__XBOXONE__) && !defined(__XBOXSERIES__) */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXONE__)
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."
#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXONE__) */
/* vi: set ts=4 sw=4 expandtab: */

View File

@@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"
#if SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXSERIES__)
#error "This is a placeholder Xbox file, as the real one is under NDA. See README-gdk.md for more info."
#endif /* SDL_VIDEO_RENDER_D3D12 && !SDL_RENDER_DISABLED && defined(__XBOXSERIES__) */
/* vi: set ts=4 sw=4 expandtab: */