SetSwapchainPresentMode + other swapchain-y features from FNA3D D3D11
parent
a5284ba0cd
commit
17f9322698
|
@ -389,12 +389,13 @@ typedef struct D3D11SwapchainData
|
|||
{
|
||||
IDXGISwapChain *swapchain;
|
||||
D3D11Texture texture;
|
||||
Refresh_PresentMode presentMode;
|
||||
} D3D11SwapchainData;
|
||||
|
||||
/* FIXME: Why do we have WindowData separate from SwapchainData? */
|
||||
typedef struct D3D11WindowData
|
||||
{
|
||||
void* windowHandle;
|
||||
uint8_t allowTearing;
|
||||
D3D11SwapchainData *swapchainData;
|
||||
} D3D11WindowData;
|
||||
|
||||
|
@ -517,7 +518,8 @@ typedef struct D3D11Renderer
|
|||
void *d3dcompiler_dll;
|
||||
|
||||
uint8_t debugMode;
|
||||
D3D_FEATURE_LEVEL featureLevel; /* FIXME: Do we need this? */
|
||||
BOOL supportsTearing;
|
||||
|
||||
PFN_D3DCOMPILE D3DCompileFunc;
|
||||
|
||||
D3D11WindowData **claimedWindows;
|
||||
|
@ -3296,12 +3298,14 @@ static uint8_t D3D11_INTERNAL_InitializeSwapchainTexture(
|
|||
|
||||
static uint8_t D3D11_INTERNAL_CreateSwapchain(
|
||||
D3D11Renderer *renderer,
|
||||
D3D11WindowData *windowData
|
||||
D3D11WindowData *windowData,
|
||||
Refresh_PresentMode presentMode
|
||||
) {
|
||||
SDL_SysWMinfo info;
|
||||
HWND dxgiHandle;
|
||||
int width, height;
|
||||
DXGI_SWAP_CHAIN_DESC swapchainDesc;
|
||||
IDXGIFactory4 *factory4;
|
||||
IDXGIFactory1 *pParent;
|
||||
IDXGISwapChain *swapchain;
|
||||
D3D11SwapchainData *swapchainData;
|
||||
|
@ -3328,11 +3332,35 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
|
|||
swapchainDesc.SampleDesc.Count = 1;
|
||||
swapchainDesc.SampleDesc.Quality = 0;
|
||||
swapchainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swapchainDesc.BufferCount = 3;
|
||||
swapchainDesc.BufferCount = 2;
|
||||
swapchainDesc.OutputWindow = dxgiHandle;
|
||||
swapchainDesc.Windowed = 1;
|
||||
swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
swapchainDesc.Flags = 0;
|
||||
|
||||
if (renderer->supportsTearing)
|
||||
{
|
||||
swapchainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
}
|
||||
else
|
||||
{
|
||||
swapchainDesc.Flags = 0;
|
||||
|
||||
/* For Windows 10+, use a better form of discard swap behavior */
|
||||
res = IDXGIFactory1_QueryInterface(
|
||||
renderer->factory,
|
||||
&D3D_IID_IDXGIFactory4,
|
||||
&factory4
|
||||
);
|
||||
if (SUCCEEDED(res))
|
||||
{
|
||||
swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||
IDXGIFactory4_Release(factory4);
|
||||
}
|
||||
else
|
||||
{
|
||||
swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create the swapchain! */
|
||||
res = IDXGIFactory1_CreateSwapChain(
|
||||
|
@ -3341,7 +3369,7 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
|
|||
&swapchainDesc,
|
||||
&swapchain
|
||||
);
|
||||
ERROR_CHECK("Could not create swapchain");
|
||||
ERROR_CHECK("Could not create swapchain", 0);
|
||||
|
||||
/*
|
||||
* The swapchain's parent is a separate factory from the factory that
|
||||
|
@ -3385,6 +3413,7 @@ static uint8_t D3D11_INTERNAL_CreateSwapchain(
|
|||
/* Create the swapchain data */
|
||||
swapchainData = (D3D11SwapchainData*) SDL_malloc(sizeof(D3D11SwapchainData));
|
||||
swapchainData->swapchain = swapchain;
|
||||
swapchainData->presentMode = presentMode;
|
||||
|
||||
if (!D3D11_INTERNAL_InitializeSwapchainTexture(
|
||||
renderer,
|
||||
|
@ -3415,11 +3444,11 @@ static uint8_t D3D11_INTERNAL_ResizeSwapchain(
|
|||
/* Resize the swapchain */
|
||||
res = IDXGISwapChain_ResizeBuffers(
|
||||
swapchainData->swapchain,
|
||||
0, /* Keep buffer count the same */
|
||||
0, /* Keep buffer count the same */
|
||||
width,
|
||||
height,
|
||||
DXGI_FORMAT_UNKNOWN, /* Keep the old format */
|
||||
0
|
||||
DXGI_FORMAT_UNKNOWN, /* Keep the old format */
|
||||
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0
|
||||
);
|
||||
ERROR_CHECK_RETURN("Could not resize swapchain buffers", 0);
|
||||
|
||||
|
@ -3470,9 +3499,8 @@ static uint8_t D3D11_ClaimWindow(
|
|||
{
|
||||
windowData = (D3D11WindowData*) SDL_malloc(sizeof(D3D11WindowData));
|
||||
windowData->windowHandle = windowHandle;
|
||||
windowData->allowTearing = presentMode == REFRESH_PRESENTMODE_IMMEDIATE;
|
||||
|
||||
if (D3D11_INTERNAL_CreateSwapchain(renderer, windowData))
|
||||
if (D3D11_INTERNAL_CreateSwapchain(renderer, windowData, presentMode))
|
||||
{
|
||||
SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_DATA, windowData);
|
||||
|
||||
|
@ -3604,7 +3632,9 @@ static void D3D11_SetSwapchainPresentMode(
|
|||
void *windowHandle,
|
||||
Refresh_PresentMode presentMode
|
||||
) {
|
||||
NOT_IMPLEMENTED
|
||||
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle);
|
||||
D3D11SwapchainData *swapchainData = windowData->swapchainData;
|
||||
swapchainData->presentMode = presentMode;
|
||||
}
|
||||
|
||||
/* Submission and Fences */
|
||||
|
@ -3737,7 +3767,7 @@ static void D3D11_Submit(
|
|||
ID3D11CommandList_Release(commandList);
|
||||
|
||||
/* Mark the command buffer as submitted */
|
||||
if (renderer->submittedCommandBufferCount + 1 >= renderer->submittedCommandBufferCapacity)
|
||||
if (renderer->submittedCommandBufferCount >= renderer->submittedCommandBufferCapacity)
|
||||
{
|
||||
renderer->submittedCommandBufferCapacity = renderer->submittedCommandBufferCount + 1;
|
||||
|
||||
|
@ -3753,10 +3783,24 @@ static void D3D11_Submit(
|
|||
/* Present, if applicable */
|
||||
if (d3d11CommandBuffer->swapchainData)
|
||||
{
|
||||
uint32_t syncInterval = 1;
|
||||
if (d3d11CommandBuffer->swapchainData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE)
|
||||
{
|
||||
syncInterval = 0;
|
||||
}
|
||||
|
||||
uint32_t presentFlags = 0;
|
||||
if ( renderer->supportsTearing &&
|
||||
(d3d11CommandBuffer->swapchainData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE ||
|
||||
d3d11CommandBuffer->swapchainData->presentMode == REFRESH_PRESENTMODE_FIFO_RELAXED)
|
||||
) {
|
||||
presentFlags = DXGI_PRESENT_ALLOW_TEARING;
|
||||
}
|
||||
|
||||
IDXGISwapChain_Present(
|
||||
d3d11CommandBuffer->swapchainData->swapchain,
|
||||
1, /* FIXME: Assumes vsync! */
|
||||
0
|
||||
syncInterval,
|
||||
presentFlags
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4040,6 +4084,7 @@ static Refresh_Device* D3D11_CreateDevice(
|
|||
PFN_CREATE_DXGI_FACTORY1 CreateDXGIFactoryFunc;
|
||||
PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc;
|
||||
D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_1 };
|
||||
IDXGIFactory5 *factory5;
|
||||
IDXGIFactory6 *factory6;
|
||||
uint32_t flags;
|
||||
DXGI_ADAPTER_DESC1 adapterDesc;
|
||||
|
@ -4094,7 +4139,28 @@ static Refresh_Device* D3D11_CreateDevice(
|
|||
);
|
||||
ERROR_CHECK_RETURN("Could not create DXGIFactory", NULL);
|
||||
|
||||
/* Get the default adapter */
|
||||
/* Check for explicit tearing support */
|
||||
res = IDXGIFactory1_QueryInterface(
|
||||
renderer->factory,
|
||||
&D3D_IID_IDXGIFactory5,
|
||||
(void**) &factory5
|
||||
);
|
||||
if (SUCCEEDED(res))
|
||||
{
|
||||
res = IDXGIFactory5_CheckFeatureSupport(
|
||||
factory5,
|
||||
DXGI_FEATURE_PRESENT_ALLOW_TEARING,
|
||||
&renderer->supportsTearing,
|
||||
sizeof(renderer->supportsTearing)
|
||||
);
|
||||
if (FAILED(res))
|
||||
{
|
||||
renderer->supportsTearing = FALSE;
|
||||
}
|
||||
IDXGIFactory5_Release(factory5);
|
||||
}
|
||||
|
||||
/* Select the appropriate device for rendering */
|
||||
res = IDXGIAdapter1_QueryInterface(
|
||||
renderer->factory,
|
||||
&D3D_IID_IDXGIFactory6,
|
||||
|
@ -4109,6 +4175,7 @@ static Refresh_Device* D3D11_CreateDevice(
|
|||
&D3D_IID_IDXGIAdapter1,
|
||||
&renderer->adapter
|
||||
);
|
||||
IDXGIFactory6_Release(factory6);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4166,7 +4233,7 @@ tryCreateDevice:
|
|||
SDL_arraysize(levels),
|
||||
D3D11_SDK_VERSION,
|
||||
&d3d11Device,
|
||||
&renderer->featureLevel,
|
||||
NULL,
|
||||
&renderer->immediateContext
|
||||
);
|
||||
if (FAILED(res) && debugMode)
|
||||
|
|
|
@ -30,6 +30,8 @@ typedef HRESULT(WINAPI* PFN_DXGI_GET_DEBUG_INTERFACE)(const GUID* riid, void** p
|
|||
|
||||
/* IIDs (from https://magnumdb.com) */
|
||||
static const IID D3D_IID_IDXGIFactory1 = { 0x770aae78,0xf26f,0x4dba,{0xa8,0x29,0x25,0x3c,0x83,0xd1,0xb3,0x87} };
|
||||
static const IID D3D_IID_IDXGIFactory4 = { 0x1bc6ea02,0xef36,0x464f,{0xbf,0x0c,0x21,0xca,0x39,0xe5,0x16,0x8a} };
|
||||
static const IID D3D_IID_IDXGIFactory5 = { 0x7632e1f5,0xee65,0x4dca,{0x87,0xfd,0x84,0xcd,0x75,0xf8,0x83,0x8d} };
|
||||
static const IID D3D_IID_IDXGIFactory6 = { 0xc1b6694f,0xff09,0x44a9,{0xb0,0x3c,0x77,0x90,0x0a,0x0a,0x1d,0x17} };
|
||||
static const IID D3D_IID_IDXGIAdapter1 = { 0x29038f61,0x3839,0x4626,{0x91,0xfd,0x08,0x68,0x79,0x01,0x1a,0x05} };
|
||||
static const IID D3D_IID_ID3D11Texture2D = { 0x6f15aaf2,0xd208,0x4e89,{0x9a,0xb4,0x48,0x95,0x35,0xd3,0x4f,0x9c} };
|
||||
|
|
Loading…
Reference in New Issue