2024-03-06 04:58:34 +00:00
|
|
|
|
/* Refresh - XNA-inspired 3D Graphics Library with modern capabilities
|
2023-09-23 01:44:20 +00:00
|
|
|
|
*
|
|
|
|
|
* Copyright (c) 2020 Evan Hemsley
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* Evan "cosmonaut" Hemsley <evan@moonside.games>
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#if REFRESH_DRIVER_D3D11
|
|
|
|
|
|
|
|
|
|
#define D3D11_NO_HELPERS
|
|
|
|
|
#define CINTERFACE
|
|
|
|
|
#define COBJMACROS
|
2024-02-07 14:02:49 +00:00
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
#include <d3d11.h>
|
2023-11-06 01:20:37 +00:00
|
|
|
|
#include <d3d11_1.h>
|
2023-09-23 01:44:20 +00:00
|
|
|
|
#include <dxgi.h>
|
2023-11-06 01:20:37 +00:00
|
|
|
|
#include <dxgi1_6.h>
|
2024-02-07 14:02:49 +00:00
|
|
|
|
#include <dxgidebug.h>
|
2023-09-23 01:44:20 +00:00
|
|
|
|
#include <d3dcompiler.h>
|
|
|
|
|
|
|
|
|
|
#include "Refresh_Driver.h"
|
|
|
|
|
#include "Refresh_Driver_D3D11_cdefines.h"
|
|
|
|
|
|
|
|
|
|
#include <SDL.h>
|
|
|
|
|
#include <SDL_syswm.h>
|
|
|
|
|
|
|
|
|
|
/* Defines */
|
|
|
|
|
|
|
|
|
|
#define D3D11_DLL "d3d11.dll"
|
|
|
|
|
#define DXGI_DLL "dxgi.dll"
|
2024-02-07 14:02:49 +00:00
|
|
|
|
#define DXGIDEBUG_DLL "dxgidebug.dll"
|
2023-09-25 00:25:49 +00:00
|
|
|
|
#define D3D11_CREATE_DEVICE_FUNC "D3D11CreateDevice"
|
|
|
|
|
#define D3DCOMPILE_FUNC "D3DCompile"
|
|
|
|
|
#define CREATE_DXGI_FACTORY1_FUNC "CreateDXGIFactory1"
|
2024-02-07 14:02:49 +00:00
|
|
|
|
#define DXGI_GET_DEBUG_INTERFACE_FUNC "DXGIGetDebugInterface"
|
2023-09-25 02:20:04 +00:00
|
|
|
|
#define WINDOW_DATA "Refresh_D3D11WindowData"
|
2023-11-05 20:17:23 +00:00
|
|
|
|
#define UBO_BUFFER_SIZE 16000 /* 16KB */
|
2023-09-23 01:44:20 +00:00
|
|
|
|
|
|
|
|
|
#define NOT_IMPLEMENTED SDL_assert(0 && "Not implemented!");
|
|
|
|
|
|
|
|
|
|
/* Macros */
|
|
|
|
|
|
|
|
|
|
#define ERROR_CHECK(msg) \
|
|
|
|
|
if (FAILED(res)) \
|
|
|
|
|
{ \
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, msg, res); \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define ERROR_CHECK_RETURN(msg, ret) \
|
|
|
|
|
if (FAILED(res)) \
|
|
|
|
|
{ \
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, msg, res); \
|
|
|
|
|
return ret; \
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 19:27:48 +00:00
|
|
|
|
#define EXPAND_ARRAY_IF_NEEDED(arr, elementType, newCount, capacity, newCapacity) \
|
|
|
|
|
if (newCount >= capacity) \
|
|
|
|
|
{ \
|
|
|
|
|
capacity = newCapacity; \
|
|
|
|
|
arr = (elementType*) SDL_realloc( \
|
|
|
|
|
arr, \
|
|
|
|
|
sizeof(elementType) * capacity \
|
|
|
|
|
); \
|
2023-09-25 02:29:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* D3DCompile signature */
|
|
|
|
|
|
|
|
|
|
typedef HRESULT(WINAPI *PFN_D3DCOMPILE)(
|
|
|
|
|
LPCVOID pSrcData,
|
|
|
|
|
SIZE_T SrcDataSize,
|
|
|
|
|
LPCSTR pSourceName,
|
|
|
|
|
const D3D_SHADER_MACRO* pDefines,
|
|
|
|
|
ID3DInclude* pInclude,
|
|
|
|
|
LPCSTR pEntrypoint,
|
|
|
|
|
LPCSTR pTarget,
|
|
|
|
|
UINT Flags1,
|
|
|
|
|
UINT Flags2,
|
|
|
|
|
ID3DBlob **ppCode,
|
|
|
|
|
ID3DBlob **ppErrorMsgs
|
|
|
|
|
);
|
|
|
|
|
|
2023-09-28 02:12:28 +00:00
|
|
|
|
/* Forward Declarations */
|
|
|
|
|
|
|
|
|
|
static void D3D11_Wait(Refresh_Renderer *driverData);
|
2023-10-12 13:42:32 +00:00
|
|
|
|
static void D3D11_UnclaimWindow(
|
|
|
|
|
Refresh_Renderer * driverData,
|
|
|
|
|
void *windowHandle
|
|
|
|
|
);
|
2023-09-28 02:12:28 +00:00
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Conversions */
|
|
|
|
|
|
2023-09-25 02:20:04 +00:00
|
|
|
|
static DXGI_FORMAT RefreshToD3D11_TextureFormat[] =
|
2023-09-23 01:44:20 +00:00
|
|
|
|
{
|
|
|
|
|
DXGI_FORMAT_R8G8B8A8_UNORM, /* R8G8B8A8 */
|
|
|
|
|
DXGI_FORMAT_B8G8R8A8_UNORM, /* B8G8R8A8 */
|
2023-10-27 04:03:05 +00:00
|
|
|
|
DXGI_FORMAT_B5G6R5_UNORM, /* R5G6B5 */ /* FIXME: Swizzle? */
|
|
|
|
|
DXGI_FORMAT_B5G5R5A1_UNORM, /* A1R5G5B5 */ /* FIXME: Swizzle? */
|
2023-09-23 01:44:20 +00:00
|
|
|
|
DXGI_FORMAT_B4G4R4A4_UNORM, /* B4G4R4A4 */
|
|
|
|
|
DXGI_FORMAT_R10G10B10A2_UNORM, /* A2R10G10B10 */
|
|
|
|
|
DXGI_FORMAT_R16G16_UNORM, /* R16G16 */
|
|
|
|
|
DXGI_FORMAT_R16G16B16A16_UNORM, /* R16G16B16A16 */
|
|
|
|
|
DXGI_FORMAT_R8_UNORM, /* R8 */
|
2023-10-27 04:03:05 +00:00
|
|
|
|
DXGI_FORMAT_BC1_UNORM, /* BC1 */
|
|
|
|
|
DXGI_FORMAT_BC2_UNORM, /* BC2 */
|
|
|
|
|
DXGI_FORMAT_BC3_UNORM, /* BC3 */
|
|
|
|
|
DXGI_FORMAT_BC7_UNORM, /* BC7 */
|
|
|
|
|
DXGI_FORMAT_R8G8_SNORM, /* R8G8_SNORM */
|
|
|
|
|
DXGI_FORMAT_R8G8B8A8_SNORM, /* R8G8B8A8_SNORM */
|
2023-09-23 01:44:20 +00:00
|
|
|
|
DXGI_FORMAT_R16_FLOAT, /* R16_SFLOAT */
|
|
|
|
|
DXGI_FORMAT_R16G16_FLOAT, /* R16G16_SFLOAT */
|
|
|
|
|
DXGI_FORMAT_R16G16B16A16_FLOAT, /* R16G16B16A16_SFLOAT */
|
2023-10-27 04:03:05 +00:00
|
|
|
|
DXGI_FORMAT_R32_FLOAT, /* R32_SFLOAT */
|
|
|
|
|
DXGI_FORMAT_R32G32_FLOAT, /* R32G32_SFLOAT */
|
|
|
|
|
DXGI_FORMAT_R32G32B32A32_FLOAT, /* R32G32B32A32_SFLOAT */
|
|
|
|
|
DXGI_FORMAT_R8_UINT, /* R8_UINT */
|
|
|
|
|
DXGI_FORMAT_R8G8_UINT, /* R8G8_UINT */
|
|
|
|
|
DXGI_FORMAT_R8G8B8A8_UINT, /* R8G8B8A8_UINT */
|
|
|
|
|
DXGI_FORMAT_R16_UINT, /* R16_UINT */
|
|
|
|
|
DXGI_FORMAT_R16G16_UINT, /* R16G16_UINT */
|
|
|
|
|
DXGI_FORMAT_R16G16B16A16_UINT, /* R16G16B16A16_UINT */
|
|
|
|
|
DXGI_FORMAT_D16_UNORM, /* D16_UNORM */
|
|
|
|
|
DXGI_FORMAT_D32_FLOAT, /* D32_SFLOAT */
|
|
|
|
|
DXGI_FORMAT_D24_UNORM_S8_UINT, /* D16_UNORM_S8_UINT */
|
|
|
|
|
DXGI_FORMAT_D32_FLOAT_S8X24_UINT/* D32_SFLOAT_S8_UINT */
|
2023-09-23 01:44:20 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static DXGI_FORMAT RefreshToD3D11_VertexFormat[] =
|
|
|
|
|
{
|
|
|
|
|
DXGI_FORMAT_R32_UINT, /* UINT */
|
|
|
|
|
DXGI_FORMAT_R32_FLOAT, /* FLOAT */
|
|
|
|
|
DXGI_FORMAT_R32G32_FLOAT, /* VECTOR2 */
|
|
|
|
|
DXGI_FORMAT_R32G32B32_FLOAT, /* VECTOR3 */
|
|
|
|
|
DXGI_FORMAT_R32G32B32A32_FLOAT, /* VECTOR4 */
|
|
|
|
|
DXGI_FORMAT_R8G8B8A8_UNORM, /* COLOR */
|
|
|
|
|
DXGI_FORMAT_R8G8B8A8_UINT, /* BYTE4 */
|
|
|
|
|
DXGI_FORMAT_R16G16_SINT, /* SHORT2 */
|
|
|
|
|
DXGI_FORMAT_R16G16B16A16_SINT, /* SHORT4 */
|
|
|
|
|
DXGI_FORMAT_R16G16_SNORM, /* NORMALIZEDSHORT2 */
|
|
|
|
|
DXGI_FORMAT_R16G16B16A16_SNORM, /* NORMALIZEDSHORT4 */
|
|
|
|
|
DXGI_FORMAT_R16G16_FLOAT, /* HALFVECTOR2 */
|
|
|
|
|
DXGI_FORMAT_R16G16B16A16_FLOAT /* HALFVECTOR4 */
|
|
|
|
|
};
|
|
|
|
|
|
2023-10-27 02:25:03 +00:00
|
|
|
|
static uint32_t RefreshToD3D11_SampleCount[] =
|
|
|
|
|
{
|
|
|
|
|
1, /* REFRESH_SAMPLECOUNT_1 */
|
|
|
|
|
2, /* REFRESH_SAMPLECOUNT_2 */
|
|
|
|
|
4, /* REFRESH_SAMPLECOUNT_4 */
|
|
|
|
|
8 /* REFRESH_SAMPLECOUNT_8 */
|
|
|
|
|
};
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static DXGI_FORMAT RefreshToD3D11_IndexType[] =
|
|
|
|
|
{
|
|
|
|
|
DXGI_FORMAT_R16_UINT, /* 16BIT */
|
|
|
|
|
DXGI_FORMAT_R32_UINT /* 32BIT */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_PRIMITIVE_TOPOLOGY RefreshToD3D11_PrimitiveType[] =
|
|
|
|
|
{
|
|
|
|
|
D3D_PRIMITIVE_TOPOLOGY_POINTLIST, /* POINTLIST */
|
|
|
|
|
D3D_PRIMITIVE_TOPOLOGY_LINELIST, /* LINELIST */
|
|
|
|
|
D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, /* LINESTRIP */
|
|
|
|
|
D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, /* TRIANGLELIST */
|
|
|
|
|
D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP /* TRIANGLESTRIP */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_FILL_MODE RefreshToD3D11_PolygonMode[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_FILL_SOLID, /* FILL */
|
|
|
|
|
D3D11_FILL_WIREFRAME, /* LINE */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_CULL_MODE RefreshToD3D11_CullMode[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_CULL_NONE, /* NONE */
|
|
|
|
|
D3D11_CULL_FRONT, /* FRONT */
|
|
|
|
|
D3D11_CULL_BACK /* BACK */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_BLEND RefreshToD3D11_BlendFactor[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_BLEND_ZERO, /* ZERO */
|
|
|
|
|
D3D11_BLEND_ONE, /* ONE */
|
|
|
|
|
D3D11_BLEND_SRC_COLOR, /* SRC_COLOR */
|
|
|
|
|
D3D11_BLEND_INV_SRC_COLOR, /* ONE_MINUS_SRC_COLOR */
|
|
|
|
|
D3D11_BLEND_DEST_COLOR, /* DST_COLOR */
|
|
|
|
|
D3D11_BLEND_INV_DEST_COLOR, /* ONE_MINUS_DST_COLOR */
|
|
|
|
|
D3D11_BLEND_SRC_ALPHA, /* SRC_ALPHA */
|
|
|
|
|
D3D11_BLEND_INV_SRC_ALPHA, /* ONE_MINUS_SRC_ALPHA */
|
|
|
|
|
D3D11_BLEND_DEST_ALPHA, /* DST_ALPHA */
|
|
|
|
|
D3D11_BLEND_INV_DEST_ALPHA, /* ONE_MINUS_DST_ALPHA */
|
|
|
|
|
D3D11_BLEND_BLEND_FACTOR, /* CONSTANT_COLOR */
|
|
|
|
|
D3D11_BLEND_INV_BLEND_FACTOR, /* ONE_MINUS_CONSTANT_COLOR */
|
|
|
|
|
D3D11_BLEND_SRC_ALPHA_SAT, /* SRC_ALPHA_SATURATE */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_BLEND_OP RefreshToD3D11_BlendOp[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_BLEND_OP_ADD, /* ADD */
|
|
|
|
|
D3D11_BLEND_OP_SUBTRACT, /* SUBTRACT */
|
|
|
|
|
D3D11_BLEND_OP_REV_SUBTRACT, /* REVERSE_SUBTRACT */
|
|
|
|
|
D3D11_BLEND_OP_MIN, /* MIN */
|
|
|
|
|
D3D11_BLEND_OP_MAX /* MAX */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_COMPARISON_FUNC RefreshToD3D11_CompareOp[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_COMPARISON_NEVER, /* NEVER */
|
|
|
|
|
D3D11_COMPARISON_LESS, /* LESS */
|
|
|
|
|
D3D11_COMPARISON_EQUAL, /* EQUAL */
|
|
|
|
|
D3D11_COMPARISON_LESS_EQUAL, /* LESS_OR_EQUAL */
|
|
|
|
|
D3D11_COMPARISON_GREATER, /* GREATER */
|
|
|
|
|
D3D11_COMPARISON_NOT_EQUAL, /* NOT_EQUAL */
|
|
|
|
|
D3D11_COMPARISON_GREATER_EQUAL, /* GREATER_OR_EQUAL */
|
|
|
|
|
D3D11_COMPARISON_ALWAYS /* ALWAYS */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_STENCIL_OP RefreshToD3D11_StencilOp[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_STENCIL_OP_KEEP, /* KEEP */
|
|
|
|
|
D3D11_STENCIL_OP_ZERO, /* ZERO */
|
|
|
|
|
D3D11_STENCIL_OP_REPLACE, /* REPLACE */
|
|
|
|
|
D3D11_STENCIL_OP_INCR_SAT, /* INCREMENT_AND_CLAMP */
|
|
|
|
|
D3D11_STENCIL_OP_DECR_SAT, /* DECREMENT_AND_CLAMP */
|
|
|
|
|
D3D11_STENCIL_OP_INVERT, /* INVERT */
|
|
|
|
|
D3D11_STENCIL_OP_INCR, /* INCREMENT_AND_WRAP */
|
|
|
|
|
D3D11_STENCIL_OP_DECR /* DECREMENT_AND_WRAP */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_INPUT_CLASSIFICATION RefreshToD3D11_VertexInputRate[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_INPUT_PER_VERTEX_DATA, /* VERTEX */
|
|
|
|
|
D3D11_INPUT_PER_INSTANCE_DATA /* INSTANCE */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static D3D11_TEXTURE_ADDRESS_MODE RefreshToD3D11_SamplerAddressMode[] =
|
|
|
|
|
{
|
|
|
|
|
D3D11_TEXTURE_ADDRESS_WRAP, /* REPEAT */
|
|
|
|
|
D3D11_TEXTURE_ADDRESS_MIRROR, /* MIRRORED_REPEAT */
|
|
|
|
|
D3D11_TEXTURE_ADDRESS_CLAMP, /* CLAMP_TO_EDGE */
|
|
|
|
|
D3D11_TEXTURE_ADDRESS_BORDER /* CLAMP_TO_BORDER */
|
|
|
|
|
};
|
|
|
|
|
|
2023-10-13 03:11:55 +00:00
|
|
|
|
static void RefreshToD3D11_BorderColor(
|
|
|
|
|
Refresh_SamplerStateCreateInfo *createInfo,
|
|
|
|
|
D3D11_SAMPLER_DESC *desc
|
|
|
|
|
) {
|
|
|
|
|
switch (createInfo->borderColor)
|
|
|
|
|
{
|
|
|
|
|
case REFRESH_BORDERCOLOR_FLOAT_OPAQUE_BLACK:
|
|
|
|
|
case REFRESH_BORDERCOLOR_INT_OPAQUE_BLACK:
|
|
|
|
|
desc->BorderColor[0] = 0.0f;
|
|
|
|
|
desc->BorderColor[1] = 0.0f;
|
|
|
|
|
desc->BorderColor[2] = 0.0f;
|
|
|
|
|
desc->BorderColor[3] = 1.0f;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case REFRESH_BORDERCOLOR_FLOAT_OPAQUE_WHITE:
|
|
|
|
|
case REFRESH_BORDERCOLOR_INT_OPAQUE_WHITE:
|
|
|
|
|
desc->BorderColor[0] = 1.0f;
|
|
|
|
|
desc->BorderColor[1] = 1.0f;
|
|
|
|
|
desc->BorderColor[2] = 1.0f;
|
|
|
|
|
desc->BorderColor[3] = 1.0f;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case REFRESH_BORDERCOLOR_FLOAT_TRANSPARENT_BLACK:
|
|
|
|
|
case REFRESH_BORDERCOLOR_INT_TRANSPARENT_BLACK:
|
|
|
|
|
desc->BorderColor[0] = 0.0f;
|
|
|
|
|
desc->BorderColor[1] = 0.0f;
|
|
|
|
|
desc->BorderColor[2] = 0.0f;
|
|
|
|
|
desc->BorderColor[3] = 0.0f;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 03:07:46 +00:00
|
|
|
|
static D3D11_FILTER RefreshToD3D11_Filter(Refresh_SamplerStateCreateInfo *createInfo)
|
|
|
|
|
{
|
|
|
|
|
if (createInfo->minFilter == REFRESH_FILTER_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
if (createInfo->magFilter == REFRESH_FILTER_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
if (createInfo->mipmapMode == REFRESH_SAMPLERMIPMAPMODE_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (createInfo->mipmapMode == REFRESH_SAMPLERMIPMAPMODE_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (createInfo->magFilter == REFRESH_FILTER_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
if (createInfo->mipmapMode == REFRESH_SAMPLERMIPMAPMODE_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (createInfo->mipmapMode == REFRESH_SAMPLERMIPMAPMODE_LINEAR)
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return D3D11_FILTER_MIN_MAG_MIP_POINT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Structs */
|
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
typedef struct D3D11TextureSubresource
|
2024-02-09 21:28:08 +00:00
|
|
|
|
{
|
2024-03-05 23:45:41 +00:00
|
|
|
|
ID3D11RenderTargetView *colorTargetView; /* NULL if not a color target */
|
|
|
|
|
ID3D11DepthStencilView *depthStencilTargetView; /* NULL if not a depth stencil target */
|
|
|
|
|
ID3D11UnorderedAccessView *uav; /* NULL if not used in compute */
|
|
|
|
|
ID3D11Resource *msaaHandle; /* NULL if not using MSAA */
|
2024-02-09 21:28:08 +00:00
|
|
|
|
uint32_t level;
|
|
|
|
|
uint32_t layer;
|
2024-03-05 20:27:38 +00:00
|
|
|
|
} D3D11TextureSubresource;
|
2024-02-09 21:28:08 +00:00
|
|
|
|
|
2023-09-26 03:10:36 +00:00
|
|
|
|
typedef struct D3D11Texture
|
|
|
|
|
{
|
|
|
|
|
/* D3D Handles */
|
|
|
|
|
ID3D11Resource *handle; /* ID3D11Texture2D* or ID3D11Texture3D* */
|
|
|
|
|
ID3D11ShaderResourceView *shaderView;
|
2024-02-09 21:28:08 +00:00
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
D3D11TextureSubresource *subresources; /* count is layerCount * levelCount */
|
2023-09-26 03:10:36 +00:00
|
|
|
|
|
|
|
|
|
/* Basic Info */
|
2023-10-27 02:25:03 +00:00
|
|
|
|
Refresh_TextureFormat format;
|
|
|
|
|
uint32_t width;
|
|
|
|
|
uint32_t height;
|
|
|
|
|
uint32_t depth;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
uint32_t levelCount;
|
2024-03-05 20:27:38 +00:00
|
|
|
|
uint32_t layerCount;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
uint8_t isCube;
|
2024-02-09 21:28:08 +00:00
|
|
|
|
uint8_t isRenderTarget;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
} D3D11Texture;
|
|
|
|
|
|
2024-02-11 04:18:25 +00:00
|
|
|
|
typedef struct D3D11WindowData
|
2023-09-25 02:20:04 +00:00
|
|
|
|
{
|
2024-02-11 04:18:25 +00:00
|
|
|
|
void* windowHandle;
|
2023-09-25 02:20:04 +00:00
|
|
|
|
IDXGISwapChain *swapchain;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
D3D11Texture texture;
|
2024-02-10 23:07:56 +00:00
|
|
|
|
Refresh_PresentMode presentMode;
|
2023-09-25 02:29:11 +00:00
|
|
|
|
} D3D11WindowData;
|
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
typedef struct D3D11ShaderModule
|
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceChild *shader; /* ID3D11VertexShader, ID3D11PixelShader, ID3D11ComputeShader */
|
|
|
|
|
ID3D10Blob *blob;
|
|
|
|
|
} D3D11ShaderModule;
|
|
|
|
|
|
|
|
|
|
typedef struct D3D11GraphicsPipeline
|
|
|
|
|
{
|
|
|
|
|
float blendConstants[4];
|
|
|
|
|
int32_t numColorAttachments;
|
|
|
|
|
DXGI_FORMAT colorAttachmentFormats[MAX_COLOR_TARGET_BINDINGS];
|
|
|
|
|
ID3D11BlendState *colorAttachmentBlendState;
|
|
|
|
|
|
2023-10-13 02:31:04 +00:00
|
|
|
|
Refresh_MultisampleState multisampleState;
|
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
uint8_t hasDepthStencilAttachment;
|
|
|
|
|
DXGI_FORMAT depthStencilAttachmentFormat;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
ID3D11DepthStencilState *depthStencilState;
|
|
|
|
|
uint32_t stencilRef;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
2023-10-11 02:45:32 +00:00
|
|
|
|
Refresh_PrimitiveType primitiveType;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
ID3D11RasterizerState *rasterizerState;
|
|
|
|
|
|
|
|
|
|
ID3D11VertexShader *vertexShader;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
ID3D11InputLayout *inputLayout;
|
|
|
|
|
uint32_t *vertexStrides;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
uint32_t numVertexSamplers;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
uint32_t vertexUniformBlockSize;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
ID3D11PixelShader *fragmentShader;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
uint32_t numFragmentSamplers;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
uint32_t fragmentUniformBlockSize;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
} D3D11GraphicsPipeline;
|
|
|
|
|
|
2024-02-08 03:03:21 +00:00
|
|
|
|
typedef struct D3D11ComputePipeline
|
|
|
|
|
{
|
|
|
|
|
ID3D11ComputeShader *computeShader;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
uint32_t computeUniformBlockSize;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
uint32_t numTextures;
|
|
|
|
|
uint32_t numBuffers;
|
|
|
|
|
} D3D11ComputePipeline;
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
typedef struct D3D11Buffer
|
|
|
|
|
{
|
|
|
|
|
ID3D11Buffer *handle;
|
2024-02-09 17:04:32 +00:00
|
|
|
|
ID3D11UnorderedAccessView* uav;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
uint32_t size;
|
|
|
|
|
} D3D11Buffer;
|
|
|
|
|
|
2024-03-03 18:58:44 +00:00
|
|
|
|
typedef struct D3D11TransferBuffer
|
|
|
|
|
{
|
2024-03-05 02:01:37 +00:00
|
|
|
|
uint8_t *data;
|
|
|
|
|
uint32_t size;
|
2024-03-03 19:27:48 +00:00
|
|
|
|
SDL_atomic_t referenceCount;
|
2024-03-03 18:58:44 +00:00
|
|
|
|
} D3D11TransferBuffer;
|
|
|
|
|
|
|
|
|
|
typedef struct D3D11TransferBufferContainer
|
|
|
|
|
{
|
|
|
|
|
D3D11TransferBuffer *activeBuffer;
|
|
|
|
|
|
|
|
|
|
/* These are all the buffers that have been used by this container.
|
|
|
|
|
* If the resource is bound and then updated with SafeDiscard, a new resource
|
|
|
|
|
* will be added to this list.
|
|
|
|
|
* These can be reused after they are submitted and command processing is complete.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t bufferCapacity;
|
|
|
|
|
uint32_t bufferCount;
|
|
|
|
|
D3D11TransferBuffer **buffers;
|
|
|
|
|
} D3D11TransferBufferContainer;
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
typedef struct D3D11UniformBuffer
|
|
|
|
|
{
|
|
|
|
|
D3D11Buffer *d3d11Buffer;
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uint32_t offset; /* number of bytes written */
|
|
|
|
|
uint32_t drawOffset; /* parameter for SetConstantBuffers */
|
2024-02-09 17:19:51 +00:00
|
|
|
|
uint8_t hasDiscarded;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
} D3D11UniformBuffer;
|
|
|
|
|
|
2024-02-09 04:53:36 +00:00
|
|
|
|
typedef struct D3D11Fence
|
|
|
|
|
{
|
|
|
|
|
ID3D11Query *handle;
|
|
|
|
|
} D3D11Fence;
|
|
|
|
|
|
2023-10-13 02:31:04 +00:00
|
|
|
|
typedef struct D3D11CommandBuffer
|
|
|
|
|
{
|
2024-02-11 04:18:25 +00:00
|
|
|
|
/* Deferred Context */
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11DeviceContext1 *context;
|
2024-02-11 04:18:25 +00:00
|
|
|
|
|
|
|
|
|
/* Window */
|
|
|
|
|
D3D11WindowData *windowData;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
|
|
|
|
/* Render Pass */
|
|
|
|
|
D3D11GraphicsPipeline *graphicsPipeline;
|
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
/* Render Pass MSAA resolve */
|
|
|
|
|
D3D11Texture *colorTargetResolveTexture[MAX_COLOR_TARGET_BINDINGS];
|
|
|
|
|
uint32_t colorTargetResolveSubresourceIndex[MAX_COLOR_TARGET_BINDINGS];
|
|
|
|
|
ID3D11Resource *colorTargetMsaaHandle[MAX_COLOR_TARGET_BINDINGS];
|
|
|
|
|
|
2024-02-08 03:03:21 +00:00
|
|
|
|
/* Compute Pass */
|
|
|
|
|
D3D11ComputePipeline *computePipeline;
|
|
|
|
|
|
2024-02-11 03:49:19 +00:00
|
|
|
|
/* Fences */
|
2024-02-09 04:53:36 +00:00
|
|
|
|
D3D11Fence *fence;
|
2024-02-09 06:31:54 +00:00
|
|
|
|
uint8_t autoReleaseFence;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Uniforms */
|
|
|
|
|
D3D11UniformBuffer *vertexUniformBuffer;
|
|
|
|
|
D3D11UniformBuffer *fragmentUniformBuffer;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
D3D11UniformBuffer *computeUniformBuffer;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D11UniformBuffer **boundUniformBuffers;
|
|
|
|
|
uint32_t boundUniformBufferCount;
|
|
|
|
|
uint32_t boundUniformBufferCapacity;
|
2024-03-03 19:27:48 +00:00
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
/* Transfer Reference Counting */
|
2024-03-03 19:27:48 +00:00
|
|
|
|
D3D11TransferBuffer **usedTransferBuffers;
|
|
|
|
|
uint32_t usedTransferBufferCount;
|
|
|
|
|
uint32_t usedTransferBufferCapacity;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
} D3D11CommandBuffer;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
2023-10-13 03:07:46 +00:00
|
|
|
|
typedef struct D3D11Sampler
|
|
|
|
|
{
|
|
|
|
|
ID3D11SamplerState *handle;
|
|
|
|
|
} D3D11Sampler;
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
typedef struct D3D11Renderer
|
|
|
|
|
{
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11Device1 *device;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
ID3D11DeviceContext *immediateContext;
|
|
|
|
|
IDXGIFactory1 *factory;
|
2023-09-25 00:25:49 +00:00
|
|
|
|
IDXGIAdapter1 *adapter;
|
2024-02-07 14:02:49 +00:00
|
|
|
|
IDXGIDebug *dxgiDebug;
|
|
|
|
|
IDXGIInfoQueue *dxgiInfoQueue;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
void *d3d11_dll;
|
|
|
|
|
void *dxgi_dll;
|
2024-02-07 14:02:49 +00:00
|
|
|
|
void *dxgidebug_dll;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
void *d3dcompiler_dll;
|
|
|
|
|
|
|
|
|
|
uint8_t debugMode;
|
2024-02-10 23:07:56 +00:00
|
|
|
|
BOOL supportsTearing;
|
2024-02-11 00:00:12 +00:00
|
|
|
|
uint8_t supportsFlipDiscard;
|
2024-02-10 23:07:56 +00:00
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
PFN_D3DCOMPILE D3DCompileFunc;
|
2023-09-25 02:20:04 +00:00
|
|
|
|
|
2023-09-25 02:29:11 +00:00
|
|
|
|
D3D11WindowData **claimedWindows;
|
2023-09-25 02:20:04 +00:00
|
|
|
|
uint32_t claimedWindowCount;
|
|
|
|
|
uint32_t claimedWindowCapacity;
|
2023-09-25 02:29:11 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D11CommandBuffer **availableCommandBuffers;
|
|
|
|
|
uint32_t availableCommandBufferCount;
|
|
|
|
|
uint32_t availableCommandBufferCapacity;
|
2023-10-08 21:05:33 +00:00
|
|
|
|
|
|
|
|
|
D3D11CommandBuffer **submittedCommandBuffers;
|
|
|
|
|
uint32_t submittedCommandBufferCount;
|
|
|
|
|
uint32_t submittedCommandBufferCapacity;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
|
|
|
|
|
D3D11UniformBuffer **availableUniformBuffers;
|
|
|
|
|
uint32_t availableUniformBufferCount;
|
|
|
|
|
uint32_t availableUniformBufferCapacity;
|
|
|
|
|
|
2024-02-09 04:53:36 +00:00
|
|
|
|
D3D11Fence **availableFences;
|
|
|
|
|
uint32_t availableFenceCount;
|
|
|
|
|
uint32_t availableFenceCapacity;
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
SDL_mutex *contextLock;
|
|
|
|
|
SDL_mutex *acquireCommandBufferLock;
|
|
|
|
|
SDL_mutex *uniformBufferLock;
|
2024-02-09 05:59:13 +00:00
|
|
|
|
SDL_mutex *fenceLock;
|
2024-02-11 04:18:25 +00:00
|
|
|
|
SDL_mutex *windowLock;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
} D3D11Renderer;
|
|
|
|
|
|
|
|
|
|
/* Logging */
|
|
|
|
|
|
|
|
|
|
static void D3D11_INTERNAL_LogError(
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11Device1 *device,
|
2023-09-23 01:44:20 +00:00
|
|
|
|
const char *msg,
|
|
|
|
|
HRESULT res
|
|
|
|
|
) {
|
|
|
|
|
#define MAX_ERROR_LEN 1024 /* FIXME: Arbitrary! */
|
|
|
|
|
|
|
|
|
|
/* Buffer for text, ensure space for \0 terminator after buffer */
|
|
|
|
|
char wszMsgBuff[MAX_ERROR_LEN + 1];
|
|
|
|
|
DWORD dwChars; /* Number of chars returned. */
|
|
|
|
|
|
|
|
|
|
if (res == DXGI_ERROR_DEVICE_REMOVED)
|
|
|
|
|
{
|
|
|
|
|
res = ID3D11Device_GetDeviceRemovedReason(device);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Try to get the message from the system errors. */
|
|
|
|
|
dwChars = FormatMessage(
|
|
|
|
|
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
|
|
|
NULL,
|
|
|
|
|
res,
|
|
|
|
|
0,
|
|
|
|
|
wszMsgBuff,
|
|
|
|
|
MAX_ERROR_LEN,
|
|
|
|
|
NULL
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* No message? Screw it, just post the code. */
|
|
|
|
|
if (dwChars == 0)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogError("%s! Error Code: 0x%08X", msg, res);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ensure valid range */
|
|
|
|
|
dwChars = SDL_min(dwChars, MAX_ERROR_LEN);
|
|
|
|
|
|
|
|
|
|
/* Trim whitespace from tail of message */
|
|
|
|
|
while (dwChars > 0)
|
|
|
|
|
{
|
|
|
|
|
if (wszMsgBuff[dwChars - 1] <= ' ')
|
|
|
|
|
{
|
|
|
|
|
dwChars--;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Ensure null-terminated string */
|
|
|
|
|
wszMsgBuff[dwChars] = '\0';
|
|
|
|
|
|
|
|
|
|
Refresh_LogError("%s! Error Code: %s (0x%08X)", msg, wszMsgBuff, res);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Helper Functions */
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
|
|
|
|
static inline uint32_t D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
uint32_t mipLevel,
|
|
|
|
|
uint32_t arraySlice,
|
|
|
|
|
uint32_t numLevels
|
|
|
|
|
) {
|
|
|
|
|
return mipLevel + (arraySlice * numLevels);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
static inline uint32_t D3D11_INTERNAL_NextHighestAlignment(
|
|
|
|
|
uint32_t n,
|
|
|
|
|
uint32_t align
|
|
|
|
|
) {
|
|
|
|
|
return align * ((n + align - 1) / align);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 22:37:08 +00:00
|
|
|
|
static DXGI_FORMAT D3D11_INTERNAL_GetTypelessFormat(
|
|
|
|
|
DXGI_FORMAT typedFormat
|
|
|
|
|
) {
|
|
|
|
|
switch (typedFormat)
|
|
|
|
|
{
|
|
|
|
|
case DXGI_FORMAT_D16_UNORM:
|
|
|
|
|
return DXGI_FORMAT_R16_TYPELESS;
|
|
|
|
|
case DXGI_FORMAT_D32_FLOAT:
|
|
|
|
|
return DXGI_FORMAT_R32_TYPELESS;
|
|
|
|
|
case DXGI_FORMAT_D24_UNORM_S8_UINT:
|
|
|
|
|
return DXGI_FORMAT_R24G8_TYPELESS;
|
|
|
|
|
case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
|
|
|
|
|
return DXGI_FORMAT_R32G8X24_TYPELESS;
|
|
|
|
|
default:
|
|
|
|
|
Refresh_LogError("Cannot get typeless DXGI format of format %d", typedFormat);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static DXGI_FORMAT D3D11_INTERNAL_GetSampleableFormat(
|
|
|
|
|
DXGI_FORMAT format
|
|
|
|
|
) {
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
case DXGI_FORMAT_R16_TYPELESS:
|
|
|
|
|
return DXGI_FORMAT_R16_UNORM;
|
|
|
|
|
case DXGI_FORMAT_R32_TYPELESS:
|
|
|
|
|
return DXGI_FORMAT_R32_FLOAT;
|
2024-02-09 22:39:55 +00:00
|
|
|
|
case DXGI_FORMAT_R24G8_TYPELESS:
|
2024-02-09 22:37:08 +00:00
|
|
|
|
return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
|
|
|
|
|
case DXGI_FORMAT_R32G8X24_TYPELESS:
|
|
|
|
|
return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
|
|
|
|
|
default:
|
|
|
|
|
return format;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Quit */
|
|
|
|
|
|
|
|
|
|
static void D3D11_DestroyDevice(
|
|
|
|
|
Refresh_Device *device
|
|
|
|
|
) {
|
2023-10-12 13:42:32 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) device->driverData;
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Flush any remaining GPU work... */
|
2023-10-12 13:42:32 +00:00
|
|
|
|
D3D11_Wait(device->driverData);
|
|
|
|
|
|
|
|
|
|
/* Release the window data */
|
2023-10-13 02:31:04 +00:00
|
|
|
|
for (int32_t i = renderer->claimedWindowCount - 1; i >= 0; i -= 1)
|
2023-10-12 13:42:32 +00:00
|
|
|
|
{
|
|
|
|
|
D3D11_UnclaimWindow(device->driverData, renderer->claimedWindows[i]->windowHandle);
|
|
|
|
|
}
|
|
|
|
|
SDL_free(renderer->claimedWindows);
|
|
|
|
|
|
|
|
|
|
/* Release command buffer infrastructure */
|
2023-11-05 20:17:23 +00:00
|
|
|
|
for (uint32_t i = 0; i < renderer->availableCommandBufferCount; i += 1)
|
2023-10-12 13:42:32 +00:00
|
|
|
|
{
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D11CommandBuffer *commandBuffer = renderer->availableCommandBuffers[i];
|
2023-10-12 13:42:32 +00:00
|
|
|
|
ID3D11DeviceContext_Release(commandBuffer->context);
|
2024-02-11 03:49:19 +00:00
|
|
|
|
SDL_free(commandBuffer->boundUniformBuffers);
|
2024-03-03 19:27:48 +00:00
|
|
|
|
SDL_free(commandBuffer->usedTransferBuffers);
|
2023-10-12 13:42:32 +00:00
|
|
|
|
SDL_free(commandBuffer);
|
|
|
|
|
}
|
2023-11-05 20:17:23 +00:00
|
|
|
|
SDL_free(renderer->availableCommandBuffers);
|
|
|
|
|
SDL_free(renderer->submittedCommandBuffers);
|
2023-10-12 13:42:32 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Release uniform buffer infrastructure */
|
|
|
|
|
for (uint32_t i = 0; i < renderer->availableUniformBufferCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
D3D11UniformBuffer *uniformBuffer = renderer->availableUniformBuffers[i];
|
|
|
|
|
ID3D11Buffer_Release(uniformBuffer->d3d11Buffer->handle);
|
|
|
|
|
SDL_free(uniformBuffer->d3d11Buffer);
|
|
|
|
|
SDL_free(uniformBuffer);
|
|
|
|
|
}
|
2024-02-07 13:33:23 +00:00
|
|
|
|
SDL_free(renderer->availableUniformBuffers);
|
2023-10-12 13:42:32 +00:00
|
|
|
|
|
2024-02-09 04:53:36 +00:00
|
|
|
|
/* Release fence infrastructure */
|
|
|
|
|
for (uint32_t i = 0; i < renderer->availableFenceCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
D3D11Fence *fence = renderer->availableFences[i];
|
|
|
|
|
ID3D11Query_Release(fence->handle);
|
|
|
|
|
SDL_free(fence);
|
|
|
|
|
}
|
|
|
|
|
SDL_free(renderer->availableFences);
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Release the mutexes */
|
2023-10-12 13:42:32 +00:00
|
|
|
|
SDL_DestroyMutex(renderer->acquireCommandBufferLock);
|
|
|
|
|
SDL_DestroyMutex(renderer->contextLock);
|
2023-11-05 20:17:23 +00:00
|
|
|
|
SDL_DestroyMutex(renderer->uniformBufferLock);
|
2024-02-09 05:59:13 +00:00
|
|
|
|
SDL_DestroyMutex(renderer->fenceLock);
|
2024-02-11 04:18:25 +00:00
|
|
|
|
SDL_DestroyMutex(renderer->windowLock);
|
2023-10-12 13:42:32 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Release the device and associated objects */
|
2023-10-12 13:42:32 +00:00
|
|
|
|
ID3D11DeviceContext_Release(renderer->immediateContext);
|
|
|
|
|
ID3D11Device_Release(renderer->device);
|
|
|
|
|
IDXGIAdapter_Release(renderer->adapter);
|
|
|
|
|
IDXGIFactory_Release(renderer->factory);
|
|
|
|
|
|
2024-02-07 14:02:49 +00:00
|
|
|
|
/* Report leaks and clean up debug objects */
|
|
|
|
|
if (renderer->dxgiDebug)
|
|
|
|
|
{
|
2024-02-07 15:09:01 +00:00
|
|
|
|
IDXGIDebug_ReportLiveObjects(
|
|
|
|
|
renderer->dxgiDebug,
|
|
|
|
|
D3D_IID_DXGI_DEBUG_ALL,
|
|
|
|
|
DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_DETAIL
|
|
|
|
|
);
|
2024-02-07 14:02:49 +00:00
|
|
|
|
IDXGIDebug_Release(renderer->dxgiDebug);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (renderer->dxgiInfoQueue)
|
|
|
|
|
{
|
|
|
|
|
IDXGIInfoQueue_Release(renderer->dxgiInfoQueue);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-07 04:40:16 +00:00
|
|
|
|
/* Release the DLLs */
|
|
|
|
|
SDL_UnloadObject(renderer->d3d11_dll);
|
|
|
|
|
SDL_UnloadObject(renderer->dxgi_dll);
|
2024-02-07 14:02:49 +00:00
|
|
|
|
if (renderer->dxgidebug_dll)
|
|
|
|
|
{
|
|
|
|
|
SDL_UnloadObject(renderer->dxgidebug_dll);
|
|
|
|
|
}
|
2024-02-07 04:40:16 +00:00
|
|
|
|
SDL_UnloadObject(renderer->d3dcompiler_dll);
|
|
|
|
|
|
|
|
|
|
/* Free the primary Refresh structures */
|
2023-10-12 13:42:32 +00:00
|
|
|
|
SDL_free(renderer);
|
|
|
|
|
SDL_free(device);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Drawing */
|
|
|
|
|
|
|
|
|
|
static void D3D11_DrawInstancedPrimitives(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
uint32_t baseVertex,
|
|
|
|
|
uint32_t startIndex,
|
|
|
|
|
uint32_t primitiveCount,
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uint32_t instanceCount
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2023-10-27 02:25:03 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
uint32_t vertexOffsetInConstants = d3d11CommandBuffer->vertexUniformBuffer != NULL ? d3d11CommandBuffer->vertexUniformBuffer->drawOffset / 16 : 0;
|
|
|
|
|
uint32_t fragmentOffsetInConstants = d3d11CommandBuffer->fragmentUniformBuffer != NULL ? d3d11CommandBuffer->fragmentUniformBuffer->drawOffset / 16 : 0;
|
2023-11-06 01:20:37 +00:00
|
|
|
|
uint32_t vertexBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->vertexUniformBlockSize / 16;
|
|
|
|
|
uint32_t fragmentBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->fragmentUniformBlockSize / 16;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
if (d3d11CommandBuffer->vertexUniformBuffer != NULL)
|
|
|
|
|
{
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11DeviceContext1_VSSetConstantBuffers1(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
2023-11-06 01:20:37 +00:00
|
|
|
|
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
&vertexOffsetInConstants,
|
|
|
|
|
&vertexBlockSizeInConstants
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->fragmentUniformBuffer != NULL)
|
|
|
|
|
{
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11DeviceContext1_PSSetConstantBuffers1(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
2023-11-06 01:20:37 +00:00
|
|
|
|
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
&fragmentOffsetInConstants,
|
|
|
|
|
&fragmentBlockSizeInConstants
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-27 02:25:03 +00:00
|
|
|
|
ID3D11DeviceContext_DrawIndexedInstanced(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
PrimitiveVerts(d3d11CommandBuffer->graphicsPipeline->primitiveType, primitiveCount),
|
|
|
|
|
instanceCount,
|
|
|
|
|
startIndex,
|
|
|
|
|
baseVertex,
|
|
|
|
|
0
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_DrawIndexedPrimitives(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
uint32_t baseVertex,
|
|
|
|
|
uint32_t startIndex,
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uint32_t primitiveCount
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2023-10-27 02:25:03 +00:00
|
|
|
|
D3D11_DrawInstancedPrimitives(
|
|
|
|
|
driverData,
|
|
|
|
|
commandBuffer,
|
|
|
|
|
baseVertex,
|
|
|
|
|
startIndex,
|
|
|
|
|
primitiveCount,
|
2024-03-03 07:33:36 +00:00
|
|
|
|
1
|
2023-10-27 02:25:03 +00:00
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_DrawPrimitives(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
uint32_t vertexStart,
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uint32_t primitiveCount
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2023-10-12 13:18:39 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
uint32_t vertexOffsetInConstants = d3d11CommandBuffer->vertexUniformBuffer != NULL ? d3d11CommandBuffer->vertexUniformBuffer->drawOffset / 16 : 0;
|
|
|
|
|
uint32_t fragmentOffsetInConstants = d3d11CommandBuffer->fragmentUniformBuffer != NULL ? d3d11CommandBuffer->fragmentUniformBuffer->drawOffset / 16 : 0;
|
2023-11-06 01:20:37 +00:00
|
|
|
|
uint32_t vertexBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->vertexUniformBlockSize / 16;
|
|
|
|
|
uint32_t fragmentBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->fragmentUniformBlockSize / 16;
|
2023-10-11 02:45:32 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
if (d3d11CommandBuffer->vertexUniformBuffer != NULL)
|
|
|
|
|
{
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11DeviceContext1_VSSetConstantBuffers1(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
2023-11-06 01:20:37 +00:00
|
|
|
|
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
&vertexOffsetInConstants,
|
|
|
|
|
&vertexBlockSizeInConstants
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->fragmentUniformBuffer != NULL)
|
|
|
|
|
{
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11DeviceContext1_PSSetConstantBuffers1(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
2023-11-06 01:20:37 +00:00
|
|
|
|
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
&fragmentOffsetInConstants,
|
|
|
|
|
&fragmentBlockSizeInConstants
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 02:45:32 +00:00
|
|
|
|
ID3D11DeviceContext_Draw(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
PrimitiveVerts(d3d11CommandBuffer->graphicsPipeline->primitiveType, primitiveCount),
|
2023-10-11 02:45:32 +00:00
|
|
|
|
vertexStart
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_DrawPrimitivesIndirect(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
2024-03-03 07:33:36 +00:00
|
|
|
|
Refresh_GpuBuffer *gpuBuffer,
|
2023-09-23 01:44:20 +00:00
|
|
|
|
uint32_t offsetInBytes,
|
|
|
|
|
uint32_t drawCount,
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uint32_t stride
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-02-07 17:53:18 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-03-03 07:33:36 +00:00
|
|
|
|
D3D11Buffer *d3d11Buffer = (D3D11Buffer*) gpuBuffer;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
uint32_t vertexOffsetInConstants = d3d11CommandBuffer->vertexUniformBuffer != NULL ? d3d11CommandBuffer->vertexUniformBuffer->drawOffset / 16 : 0;
|
|
|
|
|
uint32_t fragmentOffsetInConstants = d3d11CommandBuffer->fragmentUniformBuffer != NULL ? d3d11CommandBuffer->fragmentUniformBuffer->drawOffset / 16 : 0;
|
2024-02-07 17:53:18 +00:00
|
|
|
|
uint32_t vertexBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->vertexUniformBlockSize / 16;
|
|
|
|
|
uint32_t fragmentBlockSizeInConstants = d3d11CommandBuffer->graphicsPipeline->fragmentUniformBlockSize / 16;
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->vertexUniformBuffer != NULL)
|
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceContext1_VSSetConstantBuffers1(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
&d3d11CommandBuffer->vertexUniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
&vertexOffsetInConstants,
|
|
|
|
|
&vertexBlockSizeInConstants
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->fragmentUniformBuffer != NULL)
|
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceContext1_PSSetConstantBuffers1(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
&d3d11CommandBuffer->fragmentUniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
&fragmentOffsetInConstants,
|
|
|
|
|
&fragmentBlockSizeInConstants
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* D3D11: "We have multi-draw at home!"
|
|
|
|
|
* Multi-draw at home:
|
|
|
|
|
*/
|
|
|
|
|
for (uint32_t i = 0; i < drawCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceContext_DrawInstancedIndirect(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
d3d11Buffer->handle,
|
|
|
|
|
offsetInBytes + (stride * i)
|
|
|
|
|
);
|
|
|
|
|
}
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_DispatchCompute(
|
2024-03-03 07:33:36 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
uint32_t groupCountX,
|
|
|
|
|
uint32_t groupCountY,
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uint32_t groupCountZ
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-02-08 03:03:21 +00:00
|
|
|
|
D3D11CommandBuffer* d3d11CommandBuffer = (D3D11CommandBuffer*)commandBuffer;
|
2024-03-06 00:31:41 +00:00
|
|
|
|
uint32_t computeOffsetInConstants = d3d11CommandBuffer->computeUniformBuffer != NULL ? d3d11CommandBuffer->computeUniformBuffer->drawOffset / 16 : 0;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
uint32_t computeBlockSizeInConstants = (uint32_t) (d3d11CommandBuffer->computePipeline->computeUniformBlockSize / 16);
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->computeUniformBuffer != NULL)
|
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceContext1_CSSetConstantBuffers1(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
1,
|
|
|
|
|
&d3d11CommandBuffer->computeUniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
&computeOffsetInConstants,
|
|
|
|
|
&computeBlockSizeInConstants
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_Dispatch(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
groupCountX,
|
|
|
|
|
groupCountY,
|
|
|
|
|
groupCountZ
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* State Creation */
|
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
static ID3D11BlendState* D3D11_INTERNAL_FetchBlendState(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
uint32_t numColorAttachments,
|
|
|
|
|
Refresh_ColorAttachmentDescription *colorAttachments
|
|
|
|
|
) {
|
|
|
|
|
ID3D11BlendState *result;
|
|
|
|
|
D3D11_BLEND_DESC blendDesc;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
/* Create a new blend state.
|
|
|
|
|
* The spec says the driver will not create duplicate states, so there's no need to cache.
|
|
|
|
|
*/
|
|
|
|
|
SDL_zero(blendDesc); /* needed for any unused RT entries */
|
|
|
|
|
|
|
|
|
|
blendDesc.AlphaToCoverageEnable = FALSE;
|
|
|
|
|
blendDesc.IndependentBlendEnable = TRUE;
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < numColorAttachments; i += 1)
|
2023-10-11 02:27:36 +00:00
|
|
|
|
{
|
|
|
|
|
blendDesc.RenderTarget[i].BlendEnable = colorAttachments[i].blendState.blendEnable;
|
|
|
|
|
blendDesc.RenderTarget[i].BlendOp = RefreshToD3D11_BlendOp[
|
|
|
|
|
colorAttachments[i].blendState.colorBlendOp
|
|
|
|
|
];
|
|
|
|
|
blendDesc.RenderTarget[i].BlendOpAlpha = RefreshToD3D11_BlendOp[
|
|
|
|
|
colorAttachments[i].blendState.alphaBlendOp
|
|
|
|
|
];
|
|
|
|
|
blendDesc.RenderTarget[i].DestBlend = RefreshToD3D11_BlendFactor[
|
|
|
|
|
colorAttachments[i].blendState.dstColorBlendFactor
|
|
|
|
|
];
|
|
|
|
|
blendDesc.RenderTarget[i].DestBlendAlpha = RefreshToD3D11_BlendFactor[
|
|
|
|
|
colorAttachments[i].blendState.dstAlphaBlendFactor
|
|
|
|
|
];
|
|
|
|
|
blendDesc.RenderTarget[i].RenderTargetWriteMask = colorAttachments[i].blendState.colorWriteMask;
|
|
|
|
|
blendDesc.RenderTarget[i].SrcBlend = RefreshToD3D11_BlendFactor[
|
|
|
|
|
colorAttachments[i].blendState.srcColorBlendFactor
|
|
|
|
|
];
|
|
|
|
|
blendDesc.RenderTarget[i].SrcBlendAlpha = RefreshToD3D11_BlendFactor[
|
|
|
|
|
colorAttachments[i].blendState.srcAlphaBlendFactor
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateBlendState(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&blendDesc,
|
|
|
|
|
&result
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create blend state", NULL);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ID3D11DepthStencilState* D3D11_INTERNAL_FetchDepthStencilState(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
Refresh_DepthStencilState depthStencilState
|
|
|
|
|
) {
|
|
|
|
|
ID3D11DepthStencilState *result;
|
|
|
|
|
D3D11_DEPTH_STENCIL_DESC dsDesc;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
/* Create a new depth-stencil state.
|
|
|
|
|
* The spec says the driver will not create duplicate states, so there's no need to cache.
|
|
|
|
|
*/
|
|
|
|
|
dsDesc.DepthEnable = depthStencilState.depthTestEnable;
|
|
|
|
|
dsDesc.StencilEnable = depthStencilState.stencilTestEnable;
|
2024-02-09 22:03:57 +00:00
|
|
|
|
dsDesc.DepthFunc = RefreshToD3D11_CompareOp[depthStencilState.compareOp];
|
2023-10-11 02:27:36 +00:00
|
|
|
|
dsDesc.DepthWriteMask = (
|
|
|
|
|
depthStencilState.depthWriteEnable ?
|
|
|
|
|
D3D11_DEPTH_WRITE_MASK_ALL :
|
|
|
|
|
D3D11_DEPTH_WRITE_MASK_ZERO
|
|
|
|
|
);
|
|
|
|
|
|
2024-02-09 22:03:57 +00:00
|
|
|
|
dsDesc.BackFace.StencilFunc = RefreshToD3D11_CompareOp[depthStencilState.backStencilState.compareOp];
|
|
|
|
|
dsDesc.BackFace.StencilDepthFailOp = RefreshToD3D11_CompareOp[depthStencilState.backStencilState.depthFailOp];
|
|
|
|
|
dsDesc.BackFace.StencilFailOp = RefreshToD3D11_CompareOp[depthStencilState.backStencilState.failOp];
|
|
|
|
|
dsDesc.BackFace.StencilPassOp = RefreshToD3D11_CompareOp[depthStencilState.backStencilState.passOp];
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
2024-02-09 22:03:57 +00:00
|
|
|
|
dsDesc.FrontFace.StencilFunc = RefreshToD3D11_CompareOp[depthStencilState.frontStencilState.compareOp];
|
|
|
|
|
dsDesc.FrontFace.StencilDepthFailOp = RefreshToD3D11_CompareOp[depthStencilState.frontStencilState.depthFailOp];
|
|
|
|
|
dsDesc.FrontFace.StencilFailOp = RefreshToD3D11_CompareOp[depthStencilState.frontStencilState.failOp];
|
|
|
|
|
dsDesc.FrontFace.StencilPassOp = RefreshToD3D11_CompareOp[depthStencilState.frontStencilState.passOp];
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
2024-03-03 07:02:44 +00:00
|
|
|
|
dsDesc.StencilReadMask = depthStencilState.compareMask;
|
|
|
|
|
dsDesc.StencilWriteMask = depthStencilState.writeMask;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
2024-02-11 05:00:55 +00:00
|
|
|
|
if (depthStencilState.depthBoundsTestEnable)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11 does not support Depth Bounds tests!");
|
|
|
|
|
}
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateDepthStencilState(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&dsDesc,
|
|
|
|
|
&result
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create depth-stencil state", NULL);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ID3D11RasterizerState* D3D11_INTERNAL_FetchRasterizerState(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
Refresh_RasterizerState rasterizerState
|
|
|
|
|
) {
|
|
|
|
|
ID3D11RasterizerState *result;
|
|
|
|
|
D3D11_RASTERIZER_DESC rasterizerDesc;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
/* Create a new rasterizer state.
|
|
|
|
|
* The spec says the driver will not create duplicate states, so there's no need to cache.
|
|
|
|
|
*/
|
|
|
|
|
rasterizerDesc.AntialiasedLineEnable = FALSE;
|
|
|
|
|
rasterizerDesc.CullMode = RefreshToD3D11_CullMode[rasterizerState.cullMode];
|
2024-02-11 05:00:55 +00:00
|
|
|
|
rasterizerDesc.DepthBias = (INT) rasterizerState.depthBiasConstantFactor;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
rasterizerDesc.DepthBiasClamp = rasterizerState.depthBiasClamp;
|
2024-02-11 05:00:55 +00:00
|
|
|
|
rasterizerDesc.DepthClipEnable = TRUE;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
rasterizerDesc.FillMode = (rasterizerState.fillMode == REFRESH_FILLMODE_FILL) ? D3D11_FILL_SOLID : D3D11_FILL_WIREFRAME;
|
|
|
|
|
rasterizerDesc.FrontCounterClockwise = (rasterizerState.frontFace == REFRESH_FRONTFACE_COUNTER_CLOCKWISE);
|
|
|
|
|
rasterizerDesc.MultisampleEnable = TRUE; /* only applies to MSAA render targets */
|
|
|
|
|
rasterizerDesc.ScissorEnable = TRUE;
|
|
|
|
|
rasterizerDesc.SlopeScaledDepthBias = rasterizerState.depthBiasSlopeFactor;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateRasterizerState(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&rasterizerDesc,
|
|
|
|
|
&result
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create rasterizer state", NULL);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint32_t D3D11_INTERNAL_FindIndexOfVertexBinding(
|
|
|
|
|
uint32_t targetBinding,
|
|
|
|
|
const Refresh_VertexBinding *bindings,
|
|
|
|
|
uint32_t numBindings
|
|
|
|
|
) {
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < numBindings; i += 1)
|
2023-10-11 02:27:36 +00:00
|
|
|
|
{
|
|
|
|
|
if (bindings[i].binding == targetBinding)
|
|
|
|
|
{
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Refresh_LogError("Could not find vertex binding %d!", targetBinding);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static ID3D11InputLayout* D3D11_INTERNAL_FetchInputLayout(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
Refresh_VertexInputState inputState,
|
|
|
|
|
void *shaderBytes,
|
|
|
|
|
size_t shaderByteLength
|
|
|
|
|
) {
|
|
|
|
|
ID3D11InputLayout *result = NULL;
|
|
|
|
|
D3D11_INPUT_ELEMENT_DESC *elementDescs;
|
2024-02-09 05:47:25 +00:00
|
|
|
|
uint32_t bindingIndex;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2024-02-07 03:48:16 +00:00
|
|
|
|
/* Don't bother creating/fetching an input layout if there are no attributes. */
|
|
|
|
|
if (inputState.vertexAttributeCount == 0)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
/* Allocate an array of vertex elements */
|
|
|
|
|
elementDescs = SDL_stack_alloc(
|
|
|
|
|
D3D11_INPUT_ELEMENT_DESC,
|
|
|
|
|
inputState.vertexAttributeCount
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* Create the array of input elements */
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < inputState.vertexAttributeCount; i += 1)
|
2023-10-11 02:27:36 +00:00
|
|
|
|
{
|
|
|
|
|
elementDescs[i].AlignedByteOffset = inputState.vertexAttributes[i].offset;
|
|
|
|
|
elementDescs[i].Format = RefreshToD3D11_VertexFormat[
|
|
|
|
|
inputState.vertexAttributes[i].format
|
|
|
|
|
];
|
|
|
|
|
elementDescs[i].InputSlot = inputState.vertexAttributes[i].binding;
|
|
|
|
|
|
|
|
|
|
bindingIndex = D3D11_INTERNAL_FindIndexOfVertexBinding(
|
|
|
|
|
elementDescs[i].InputSlot,
|
|
|
|
|
inputState.vertexBindings,
|
|
|
|
|
inputState.vertexBindingCount
|
|
|
|
|
);
|
|
|
|
|
elementDescs[i].InputSlotClass = RefreshToD3D11_VertexInputRate[
|
|
|
|
|
inputState.vertexBindings[bindingIndex].inputRate
|
|
|
|
|
];
|
|
|
|
|
/* The spec requires this to be 0 for per-vertex data */
|
|
|
|
|
elementDescs[i].InstanceDataStepRate = (
|
|
|
|
|
elementDescs[i].InputSlotClass == D3D11_INPUT_PER_INSTANCE_DATA ? 1 : 0
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
elementDescs[i].SemanticIndex = inputState.vertexAttributes[i].location;
|
|
|
|
|
elementDescs[i].SemanticName = "TEXCOORD";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateInputLayout(
|
|
|
|
|
renderer->device,
|
|
|
|
|
elementDescs,
|
|
|
|
|
inputState.vertexAttributeCount,
|
|
|
|
|
shaderBytes,
|
|
|
|
|
shaderByteLength,
|
|
|
|
|
&result
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogError("Could not create input layout! Error: %X", res);
|
|
|
|
|
SDL_stack_free(elementDescs);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* FIXME:
|
|
|
|
|
* These are not cached by the driver! Should we cache them, or allow duplicates?
|
|
|
|
|
* If we have one input layout per graphics pipeline maybe that wouldn't be so bad...?
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
SDL_stack_free(elementDescs);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2023-09-23 01:44:20 +00:00
|
|
|
|
|
2024-02-09 21:28:08 +00:00
|
|
|
|
/* Pipeline Creation */
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static Refresh_ComputePipeline* D3D11_CreateComputePipeline(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_ComputeShaderInfo *computeShaderInfo
|
|
|
|
|
) {
|
2024-02-09 08:02:41 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-02-11 05:00:55 +00:00
|
|
|
|
D3D11ShaderModule *shaderModule = (D3D11ShaderModule*) computeShaderInfo->shaderModule;
|
2024-02-09 08:02:41 +00:00
|
|
|
|
|
2024-02-11 06:07:01 +00:00
|
|
|
|
D3D11ComputePipeline *pipeline = SDL_malloc(sizeof(D3D11ComputePipeline));
|
2024-02-11 05:00:55 +00:00
|
|
|
|
pipeline->numTextures = computeShaderInfo->imageBindingCount;
|
|
|
|
|
pipeline->numBuffers = computeShaderInfo->bufferBindingCount;
|
2024-02-09 08:02:41 +00:00
|
|
|
|
pipeline->computeShader = (ID3D11ComputeShader*) shaderModule->shader;
|
2024-02-09 08:17:08 +00:00
|
|
|
|
pipeline->computeUniformBlockSize = D3D11_INTERNAL_NextHighestAlignment(
|
2024-03-05 23:45:41 +00:00
|
|
|
|
computeShaderInfo->uniformBufferSize,
|
2024-02-09 08:17:08 +00:00
|
|
|
|
256
|
|
|
|
|
);
|
2024-02-09 08:02:41 +00:00
|
|
|
|
|
2024-02-08 03:03:21 +00:00
|
|
|
|
return (Refresh_ComputePipeline*) pipeline;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Refresh_GraphicsPipeline* D3D11_CreateGraphicsPipeline(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_GraphicsPipelineCreateInfo *pipelineCreateInfo
|
|
|
|
|
) {
|
2023-10-11 02:27:36 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11ShaderModule *vertShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->vertexShaderInfo.shaderModule;
|
|
|
|
|
D3D11ShaderModule *fragShaderModule = (D3D11ShaderModule*) pipelineCreateInfo->fragmentShaderInfo.shaderModule;
|
|
|
|
|
|
2024-02-11 06:07:01 +00:00
|
|
|
|
D3D11GraphicsPipeline *pipeline = SDL_malloc(sizeof(D3D11GraphicsPipeline));
|
2024-02-11 05:00:55 +00:00
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Blend */
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->colorAttachmentBlendState = D3D11_INTERNAL_FetchBlendState(
|
|
|
|
|
renderer,
|
|
|
|
|
pipelineCreateInfo->attachmentInfo.colorAttachmentCount,
|
|
|
|
|
pipelineCreateInfo->attachmentInfo.colorAttachmentDescriptions
|
|
|
|
|
);
|
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
pipeline->numColorAttachments = pipelineCreateInfo->attachmentInfo.colorAttachmentCount;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
for (int32_t i = 0; i < pipeline->numColorAttachments; i += 1)
|
2023-10-11 02:27:36 +00:00
|
|
|
|
{
|
|
|
|
|
pipeline->colorAttachmentFormats[i] = RefreshToD3D11_TextureFormat[
|
|
|
|
|
pipelineCreateInfo->attachmentInfo.colorAttachmentDescriptions[i].format
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pipeline->blendConstants[0] = pipelineCreateInfo->blendConstants[0];
|
|
|
|
|
pipeline->blendConstants[1] = pipelineCreateInfo->blendConstants[1];
|
|
|
|
|
pipeline->blendConstants[2] = pipelineCreateInfo->blendConstants[2];
|
|
|
|
|
pipeline->blendConstants[3] = pipelineCreateInfo->blendConstants[3];
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Multisample */
|
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
pipeline->multisampleState = pipelineCreateInfo->multisampleState;
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Depth-Stencil */
|
2023-10-11 02:45:32 +00:00
|
|
|
|
|
|
|
|
|
pipeline->depthStencilState = D3D11_INTERNAL_FetchDepthStencilState(
|
2023-10-11 02:27:36 +00:00
|
|
|
|
renderer,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipelineCreateInfo->depthStencilState
|
2023-10-11 02:27:36 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
pipeline->hasDepthStencilAttachment = pipelineCreateInfo->attachmentInfo.hasDepthStencilAttachment;
|
|
|
|
|
pipeline->depthStencilAttachmentFormat = RefreshToD3D11_TextureFormat[
|
|
|
|
|
pipelineCreateInfo->attachmentInfo.depthStencilFormat
|
|
|
|
|
];
|
2024-03-03 07:02:44 +00:00
|
|
|
|
pipeline->stencilRef = pipelineCreateInfo->depthStencilState.reference;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
|
|
|
|
/* Rasterizer */
|
|
|
|
|
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->primitiveType = pipelineCreateInfo->primitiveType;
|
2023-10-11 02:27:36 +00:00
|
|
|
|
pipeline->rasterizerState = D3D11_INTERNAL_FetchRasterizerState(
|
|
|
|
|
renderer,
|
|
|
|
|
pipelineCreateInfo->rasterizerState
|
|
|
|
|
);
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Vertex Shader */
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
|
|
|
|
pipeline->vertexShader = (ID3D11VertexShader*) vertShaderModule->shader;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
pipeline->numVertexSamplers = pipelineCreateInfo->vertexShaderInfo.samplerBindingCount;
|
2023-11-06 01:20:37 +00:00
|
|
|
|
pipeline->vertexUniformBlockSize = D3D11_INTERNAL_NextHighestAlignment(
|
|
|
|
|
(uint32_t) pipelineCreateInfo->vertexShaderInfo.uniformBufferSize,
|
|
|
|
|
256
|
|
|
|
|
);
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
|
|
|
|
/* Input Layout */
|
|
|
|
|
|
|
|
|
|
pipeline->inputLayout = D3D11_INTERNAL_FetchInputLayout(
|
|
|
|
|
renderer,
|
|
|
|
|
pipelineCreateInfo->vertexInputState,
|
|
|
|
|
ID3D10Blob_GetBufferPointer(vertShaderModule->blob),
|
|
|
|
|
ID3D10Blob_GetBufferSize(vertShaderModule->blob)
|
|
|
|
|
);
|
|
|
|
|
|
2023-10-13 02:31:04 +00:00
|
|
|
|
if (pipelineCreateInfo->vertexInputState.vertexBindingCount > 0)
|
|
|
|
|
{
|
|
|
|
|
pipeline->vertexStrides = SDL_malloc(
|
|
|
|
|
sizeof(uint32_t) *
|
|
|
|
|
pipelineCreateInfo->vertexInputState.vertexBindingCount
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pipelineCreateInfo->vertexInputState.vertexBindingCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
pipeline->vertexStrides[i] = pipelineCreateInfo->vertexInputState.vertexBindings[i].stride;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pipeline->vertexStrides = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 02:27:36 +00:00
|
|
|
|
/* Fragment Shader */
|
|
|
|
|
|
|
|
|
|
pipeline->fragmentShader = (ID3D11PixelShader*) fragShaderModule->shader;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
pipeline->numFragmentSamplers = pipelineCreateInfo->fragmentShaderInfo.samplerBindingCount;
|
2023-11-06 01:20:37 +00:00
|
|
|
|
pipeline->fragmentUniformBlockSize = D3D11_INTERNAL_NextHighestAlignment(
|
2024-02-07 15:35:03 +00:00
|
|
|
|
(uint32_t) pipelineCreateInfo->fragmentShaderInfo.uniformBufferSize,
|
2023-11-06 01:20:37 +00:00
|
|
|
|
256
|
|
|
|
|
);
|
2023-10-11 02:27:36 +00:00
|
|
|
|
|
|
|
|
|
return (Refresh_GraphicsPipeline*) pipeline;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 21:28:08 +00:00
|
|
|
|
/* Resource Creation */
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static Refresh_Sampler* D3D11_CreateSampler(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_SamplerStateCreateInfo *samplerStateCreateInfo
|
|
|
|
|
) {
|
2023-10-13 03:07:46 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11_SAMPLER_DESC samplerDesc;
|
2023-10-27 01:37:27 +00:00
|
|
|
|
ID3D11SamplerState *samplerStateHandle;
|
2023-10-13 03:07:46 +00:00
|
|
|
|
D3D11Sampler *d3d11Sampler;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
samplerDesc.AddressU = RefreshToD3D11_SamplerAddressMode[samplerStateCreateInfo->addressModeU];
|
|
|
|
|
samplerDesc.AddressV = RefreshToD3D11_SamplerAddressMode[samplerStateCreateInfo->addressModeV];
|
|
|
|
|
samplerDesc.AddressW = RefreshToD3D11_SamplerAddressMode[samplerStateCreateInfo->addressModeW];
|
|
|
|
|
|
2023-10-13 03:11:55 +00:00
|
|
|
|
RefreshToD3D11_BorderColor(
|
|
|
|
|
samplerStateCreateInfo,
|
|
|
|
|
&samplerDesc
|
|
|
|
|
);
|
2023-10-13 03:07:46 +00:00
|
|
|
|
|
|
|
|
|
samplerDesc.ComparisonFunc = (
|
|
|
|
|
samplerStateCreateInfo->compareEnable ?
|
|
|
|
|
RefreshToD3D11_CompareOp[samplerStateCreateInfo->compareOp] :
|
|
|
|
|
RefreshToD3D11_CompareOp[REFRESH_COMPAREOP_ALWAYS]
|
|
|
|
|
);
|
|
|
|
|
samplerDesc.MaxAnisotropy = (
|
|
|
|
|
samplerStateCreateInfo->anisotropyEnable ?
|
|
|
|
|
(UINT) samplerStateCreateInfo->maxAnisotropy :
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
samplerDesc.Filter = RefreshToD3D11_Filter(samplerStateCreateInfo);
|
|
|
|
|
samplerDesc.MaxLOD = samplerStateCreateInfo->maxLod;
|
|
|
|
|
samplerDesc.MinLOD = samplerStateCreateInfo->minLod;
|
|
|
|
|
samplerDesc.MipLODBias = samplerStateCreateInfo->mipLodBias;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateSamplerState(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&samplerDesc,
|
2023-10-27 01:37:27 +00:00
|
|
|
|
&samplerStateHandle
|
2023-10-13 03:07:46 +00:00
|
|
|
|
);
|
2023-10-27 01:37:27 +00:00
|
|
|
|
ERROR_CHECK_RETURN("Could not create sampler state", NULL);
|
2023-10-13 03:07:46 +00:00
|
|
|
|
|
|
|
|
|
d3d11Sampler = (D3D11Sampler*) SDL_malloc(sizeof(D3D11Sampler));
|
2023-10-27 01:37:27 +00:00
|
|
|
|
d3d11Sampler->handle = samplerStateHandle;
|
2023-10-13 03:07:46 +00:00
|
|
|
|
|
|
|
|
|
return (Refresh_Sampler*) d3d11Sampler;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Refresh_ShaderModule* D3D11_CreateShaderModule(
|
|
|
|
|
Refresh_Renderer *driverData,
|
2024-02-11 06:07:01 +00:00
|
|
|
|
Refresh_Driver_ShaderModuleCreateInfo *shaderModuleCreateInfo
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2023-10-11 02:32:12 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-02-11 06:07:01 +00:00
|
|
|
|
D3D11ShaderModule* shaderModule;
|
|
|
|
|
Refresh_Driver_ShaderType shaderType = shaderModuleCreateInfo->type;
|
|
|
|
|
const char *profileNames[] = { "vs_5_0", "ps_5_0", "cs_5_0" };
|
|
|
|
|
ID3D10Blob *blob, *errorBlob;
|
|
|
|
|
ID3D11DeviceChild *shader = NULL;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
/* Compile HLSL to DXBC */
|
|
|
|
|
res = renderer->D3DCompileFunc(
|
|
|
|
|
shaderModuleCreateInfo->byteCode,
|
|
|
|
|
shaderModuleCreateInfo->codeSize,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
"main", /* API FIXME: Intentionally ignoring entryPointName because it MUST be "main" anyway */
|
|
|
|
|
profileNames[shaderType],
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
&blob,
|
|
|
|
|
&errorBlob
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogError(
|
|
|
|
|
"D3DCompile Error (%s): %s",
|
|
|
|
|
profileNames[shaderType],
|
|
|
|
|
ID3D10Blob_GetBufferPointer(errorBlob)
|
|
|
|
|
);
|
|
|
|
|
ID3D10Blob_Release(errorBlob);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Actually create the shader */
|
|
|
|
|
if (shaderType == REFRESH_DRIVER_SHADERTYPE_VERTEX)
|
|
|
|
|
{
|
|
|
|
|
res = ID3D11Device_CreateVertexShader(
|
|
|
|
|
renderer->device,
|
|
|
|
|
ID3D10Blob_GetBufferPointer(blob),
|
|
|
|
|
ID3D10Blob_GetBufferSize(blob),
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11VertexShader**) &shader
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Could not compile vertex shader", res);
|
|
|
|
|
ID3D10Blob_Release(blob);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (shaderType == REFRESH_DRIVER_SHADERTYPE_FRAGMENT)
|
|
|
|
|
{
|
|
|
|
|
res = ID3D11Device_CreatePixelShader(
|
|
|
|
|
renderer->device,
|
|
|
|
|
ID3D10Blob_GetBufferPointer(blob),
|
|
|
|
|
ID3D10Blob_GetBufferSize(blob),
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11PixelShader**) &shader
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Could not compile pixel shader", res);
|
|
|
|
|
ID3D10Blob_Release(blob);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (shaderType == REFRESH_DRIVER_SHADERTYPE_COMPUTE)
|
|
|
|
|
{
|
|
|
|
|
res = ID3D11Device_CreateComputeShader(
|
|
|
|
|
renderer->device,
|
|
|
|
|
ID3D10Blob_GetBufferPointer(blob),
|
|
|
|
|
ID3D10Blob_GetBufferSize(blob),
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11ComputeShader**) &shader
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Could not compile compute shader", res);
|
|
|
|
|
ID3D10Blob_Release(blob);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-10-11 02:32:12 +00:00
|
|
|
|
|
2024-02-11 06:07:01 +00:00
|
|
|
|
/* Allocate and set up the shader module */
|
|
|
|
|
shaderModule = (D3D11ShaderModule*) SDL_malloc(sizeof(D3D11ShaderModule));
|
|
|
|
|
shaderModule->shader = shader;
|
|
|
|
|
shaderModule->blob = blob;
|
2023-10-11 02:32:12 +00:00
|
|
|
|
|
|
|
|
|
return (Refresh_ShaderModule*) shaderModule;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Refresh_Texture* D3D11_CreateTexture(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_TextureCreateInfo *textureCreateInfo
|
|
|
|
|
) {
|
2023-10-27 02:25:03 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-02-10 05:56:36 +00:00
|
|
|
|
uint8_t isColorTarget, isDepthStencil, isSampler, isCompute, isMultisample;
|
2024-02-09 18:09:29 +00:00
|
|
|
|
DXGI_FORMAT format;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
ID3D11Resource *textureHandle;
|
2024-02-10 05:56:36 +00:00
|
|
|
|
ID3D11Resource *msaaHandle = NULL;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
ID3D11ShaderResourceView *srv = NULL;
|
|
|
|
|
D3D11Texture *d3d11Texture;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2024-02-09 21:28:08 +00:00
|
|
|
|
isColorTarget = textureCreateInfo->usageFlags & REFRESH_TEXTUREUSAGE_COLOR_TARGET_BIT;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
isDepthStencil = textureCreateInfo->usageFlags & REFRESH_TEXTUREUSAGE_DEPTH_STENCIL_TARGET_BIT;
|
|
|
|
|
isSampler = textureCreateInfo->usageFlags & REFRESH_TEXTUREUSAGE_SAMPLER_BIT;
|
|
|
|
|
isCompute = textureCreateInfo->usageFlags & REFRESH_TEXTUREUSAGE_COMPUTE_BIT;
|
2024-02-10 05:56:36 +00:00
|
|
|
|
isMultisample = textureCreateInfo->sampleCount > 1;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
2024-02-09 18:09:29 +00:00
|
|
|
|
format = RefreshToD3D11_TextureFormat[textureCreateInfo->format];
|
2024-02-09 22:37:08 +00:00
|
|
|
|
if (isDepthStencil)
|
|
|
|
|
{
|
|
|
|
|
format = D3D11_INTERNAL_GetTypelessFormat(format);
|
|
|
|
|
}
|
2024-02-09 18:09:29 +00:00
|
|
|
|
|
2023-10-27 02:25:03 +00:00
|
|
|
|
if (textureCreateInfo->depth <= 1)
|
|
|
|
|
{
|
|
|
|
|
D3D11_TEXTURE2D_DESC desc2D;
|
|
|
|
|
|
|
|
|
|
desc2D.BindFlags = 0;
|
|
|
|
|
if (isSampler)
|
|
|
|
|
{
|
|
|
|
|
desc2D.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
if (isCompute)
|
|
|
|
|
{
|
|
|
|
|
desc2D.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
|
|
|
|
}
|
2024-02-09 21:28:08 +00:00
|
|
|
|
if (isColorTarget)
|
2023-10-27 02:25:03 +00:00
|
|
|
|
{
|
|
|
|
|
desc2D.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
|
|
|
|
}
|
|
|
|
|
if (isDepthStencil)
|
|
|
|
|
{
|
|
|
|
|
desc2D.BindFlags |= D3D11_BIND_DEPTH_STENCIL;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-10 05:56:36 +00:00
|
|
|
|
desc2D.Width = textureCreateInfo->width;
|
|
|
|
|
desc2D.Height = textureCreateInfo->height;
|
2024-03-05 20:27:38 +00:00
|
|
|
|
desc2D.ArraySize = textureCreateInfo->isCube ? 6 : textureCreateInfo->layerCount;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
desc2D.CPUAccessFlags = 0;
|
2024-02-09 18:09:29 +00:00
|
|
|
|
desc2D.Format = format;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
desc2D.MipLevels = textureCreateInfo->levelCount;
|
2024-02-09 22:03:57 +00:00
|
|
|
|
desc2D.MiscFlags = textureCreateInfo->isCube ? D3D11_RESOURCE_MISC_TEXTURECUBE : 0;
|
2024-02-10 05:56:36 +00:00
|
|
|
|
desc2D.SampleDesc.Count = 1;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
desc2D.SampleDesc.Quality = 0;
|
|
|
|
|
desc2D.Usage = D3D11_USAGE_DEFAULT;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateTexture2D(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&desc2D,
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11Texture2D**) &textureHandle
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create Texture2D", NULL);
|
|
|
|
|
|
|
|
|
|
/* Create the SRV, if applicable */
|
|
|
|
|
if (isSampler)
|
|
|
|
|
{
|
|
|
|
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
2024-02-09 22:37:08 +00:00
|
|
|
|
srvDesc.Format = D3D11_INTERNAL_GetSampleableFormat(format);
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
|
|
|
|
if (textureCreateInfo->isCube)
|
|
|
|
|
{
|
|
|
|
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
|
|
|
|
|
srvDesc.TextureCube.MipLevels = desc2D.MipLevels;
|
|
|
|
|
srvDesc.TextureCube.MostDetailedMip = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
|
|
|
srvDesc.Texture2D.MipLevels = desc2D.MipLevels;
|
|
|
|
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateShaderResourceView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
textureHandle,
|
|
|
|
|
&srvDesc,
|
|
|
|
|
&srv
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
ID3D11Resource_Release(textureHandle);
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Could not create SRV for 2D texture", res);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
D3D11_TEXTURE3D_DESC desc3D;
|
|
|
|
|
|
|
|
|
|
desc3D.BindFlags = 0;
|
|
|
|
|
if (isSampler)
|
|
|
|
|
{
|
|
|
|
|
desc3D.BindFlags |= D3D11_BIND_SHADER_RESOURCE;
|
|
|
|
|
}
|
|
|
|
|
if (isCompute)
|
|
|
|
|
{
|
|
|
|
|
desc3D.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
|
|
|
|
}
|
2024-02-09 21:28:08 +00:00
|
|
|
|
if (isColorTarget)
|
2024-02-09 18:09:29 +00:00
|
|
|
|
{
|
|
|
|
|
desc3D.BindFlags |= D3D11_BIND_RENDER_TARGET;
|
|
|
|
|
}
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
2024-02-10 05:56:36 +00:00
|
|
|
|
desc3D.Width = textureCreateInfo->width;
|
|
|
|
|
desc3D.Height = textureCreateInfo->height;
|
|
|
|
|
desc3D.Depth = textureCreateInfo->depth;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
desc3D.CPUAccessFlags = 0;
|
2024-02-09 18:09:29 +00:00
|
|
|
|
desc3D.Format = format;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
desc3D.MipLevels = textureCreateInfo->levelCount;
|
|
|
|
|
desc3D.MiscFlags = 0;
|
|
|
|
|
desc3D.Usage = D3D11_USAGE_DEFAULT;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateTexture3D(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&desc3D,
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11Texture3D**) &textureHandle
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create Texture3D", NULL);
|
|
|
|
|
|
|
|
|
|
/* Create the SRV, if applicable */
|
|
|
|
|
if (isSampler)
|
|
|
|
|
{
|
|
|
|
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
2024-02-09 18:09:29 +00:00
|
|
|
|
srvDesc.Format = format;
|
2024-03-05 20:27:38 +00:00
|
|
|
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
srvDesc.Texture3D.MipLevels = desc3D.MipLevels;
|
|
|
|
|
srvDesc.Texture3D.MostDetailedMip = 0;
|
|
|
|
|
|
2024-02-07 16:08:23 +00:00
|
|
|
|
res = ID3D11Device_CreateShaderResourceView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
textureHandle,
|
|
|
|
|
&srvDesc,
|
|
|
|
|
&srv
|
|
|
|
|
);
|
2023-10-27 02:25:03 +00:00
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
ID3D11Resource_Release(textureHandle);
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Could not create SRV for 3D texture", res);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
d3d11Texture = (D3D11Texture*) SDL_malloc(sizeof(D3D11Texture));
|
|
|
|
|
d3d11Texture->handle = textureHandle;
|
|
|
|
|
d3d11Texture->format = textureCreateInfo->format;
|
|
|
|
|
d3d11Texture->width = textureCreateInfo->width;
|
|
|
|
|
d3d11Texture->height = textureCreateInfo->height;
|
|
|
|
|
d3d11Texture->depth = textureCreateInfo->depth;
|
|
|
|
|
d3d11Texture->levelCount = textureCreateInfo->levelCount;
|
2024-03-05 20:27:38 +00:00
|
|
|
|
d3d11Texture->layerCount = textureCreateInfo->layerCount;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
d3d11Texture->isCube = textureCreateInfo->isCube;
|
2024-02-09 21:28:08 +00:00
|
|
|
|
d3d11Texture->isRenderTarget = isColorTarget | isDepthStencil;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
d3d11Texture->shaderView = srv;
|
2024-02-09 21:28:08 +00:00
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
d3d11Texture->subresources = SDL_malloc(
|
|
|
|
|
d3d11Texture->levelCount * d3d11Texture->layerCount * sizeof(D3D11TextureSubresource)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
for (uint32_t layerIndex = 0; layerIndex < d3d11Texture->layerCount; layerIndex += 1)
|
2024-02-09 21:28:08 +00:00
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
for (uint32_t levelIndex = 0; levelIndex < d3d11Texture->levelCount; levelIndex += 1)
|
|
|
|
|
{
|
|
|
|
|
uint32_t subresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
levelIndex,
|
|
|
|
|
layerIndex,
|
|
|
|
|
d3d11Texture->levelCount
|
|
|
|
|
);
|
|
|
|
|
|
2024-03-05 23:45:41 +00:00
|
|
|
|
d3d11Texture->subresources[subresourceIndex].colorTargetView = NULL;
|
|
|
|
|
d3d11Texture->subresources[subresourceIndex].depthStencilTargetView = NULL;
|
|
|
|
|
d3d11Texture->subresources[subresourceIndex].uav = NULL;
|
|
|
|
|
d3d11Texture->subresources[subresourceIndex].msaaHandle = NULL;
|
2024-03-05 20:27:38 +00:00
|
|
|
|
d3d11Texture->subresources[subresourceIndex].layer = layerIndex;
|
|
|
|
|
d3d11Texture->subresources[subresourceIndex].level = levelIndex;
|
|
|
|
|
|
|
|
|
|
if (isMultisample)
|
|
|
|
|
{
|
|
|
|
|
D3D11_TEXTURE2D_DESC desc2D;
|
|
|
|
|
|
|
|
|
|
desc2D.MiscFlags = 0;
|
|
|
|
|
desc2D.MipLevels = 1;
|
|
|
|
|
desc2D.ArraySize = 1;
|
|
|
|
|
desc2D.SampleDesc.Count = RefreshToD3D11_SampleCount[textureCreateInfo->sampleCount];
|
|
|
|
|
desc2D.SampleDesc.Quality = D3D11_STANDARD_MULTISAMPLE_PATTERN;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateTexture2D(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&desc2D,
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11Texture2D**) &d3d11Texture->subresources[subresourceIndex].msaaHandle
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create MSAA texture!", NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d3d11Texture->isRenderTarget)
|
|
|
|
|
{
|
|
|
|
|
if (isDepthStencil)
|
|
|
|
|
{
|
|
|
|
|
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
|
|
|
|
|
|
2024-03-05 23:45:41 +00:00
|
|
|
|
dsvDesc.Format = RefreshToD3D11_TextureFormat[d3d11Texture->format];
|
2024-03-05 20:27:38 +00:00
|
|
|
|
dsvDesc.Flags = 0;
|
|
|
|
|
|
|
|
|
|
if (isMultisample)
|
|
|
|
|
{
|
|
|
|
|
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
|
|
|
|
|
dsvDesc.Texture2D.MipSlice = levelIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateDepthStencilView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
isMultisample ? d3d11Texture->subresources[subresourceIndex].msaaHandle : d3d11Texture->handle,
|
|
|
|
|
&dsvDesc,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
&d3d11Texture->subresources[subresourceIndex].depthStencilTargetView
|
2024-03-05 20:27:38 +00:00
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create DSV!", NULL);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
|
|
|
|
|
|
2024-03-06 00:18:31 +00:00
|
|
|
|
rtvDesc.Format = RefreshToD3D11_TextureFormat[d3d11Texture->format];
|
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
if (d3d11Texture->layerCount > 1)
|
|
|
|
|
{
|
|
|
|
|
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
|
|
|
|
|
rtvDesc.Texture2DArray.MipSlice = levelIndex;
|
|
|
|
|
rtvDesc.Texture2DArray.FirstArraySlice = layerIndex;
|
|
|
|
|
rtvDesc.Texture2DArray.ArraySize = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (d3d11Texture->depth > 1)
|
|
|
|
|
{
|
|
|
|
|
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
|
|
|
|
|
rtvDesc.Texture3D.MipSlice = levelIndex;
|
|
|
|
|
rtvDesc.Texture3D.FirstWSlice = 0;
|
|
|
|
|
rtvDesc.Texture3D.WSize = d3d11Texture->depth;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
|
|
|
|
rtvDesc.Texture2D.MipSlice = levelIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateRenderTargetView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
d3d11Texture->handle,
|
|
|
|
|
&rtvDesc,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
&d3d11Texture->subresources[subresourceIndex].colorTargetView
|
2024-03-05 20:27:38 +00:00
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create RTV!", NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isCompute)
|
|
|
|
|
{
|
|
|
|
|
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
|
|
|
|
|
uavDesc.Format = format;
|
|
|
|
|
|
|
|
|
|
if (d3d11Texture->layerCount > 1)
|
|
|
|
|
{
|
|
|
|
|
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
|
|
|
|
|
uavDesc.Texture2DArray.MipSlice = levelIndex;
|
|
|
|
|
uavDesc.Texture2DArray.FirstArraySlice = layerIndex;
|
|
|
|
|
uavDesc.Texture2DArray.ArraySize = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (d3d11Texture->depth > 1)
|
|
|
|
|
{
|
|
|
|
|
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
|
|
|
|
|
uavDesc.Texture3D.MipSlice = levelIndex;
|
|
|
|
|
uavDesc.Texture3D.FirstWSlice = 0;
|
|
|
|
|
uavDesc.Texture3D.WSize = d3d11Texture->layerCount;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
|
|
|
|
uavDesc.Texture2D.MipSlice = levelIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateUnorderedAccessView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
d3d11Texture->handle,
|
|
|
|
|
&uavDesc,
|
|
|
|
|
&d3d11Texture->subresources[subresourceIndex].uav
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create UAV!", NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-09 21:28:08 +00:00
|
|
|
|
}
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
|
|
|
|
return (Refresh_Texture*) d3d11Texture;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 18:58:44 +00:00
|
|
|
|
static Refresh_GpuBuffer* D3D11_CreateGpuBuffer(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_BufferUsageFlags usageFlags,
|
|
|
|
|
uint32_t sizeInBytes
|
|
|
|
|
) {
|
2023-10-13 02:31:04 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11_BUFFER_DESC bufferDesc;
|
|
|
|
|
ID3D11Buffer *bufferHandle;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
ID3D11UnorderedAccessView *uav = NULL;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
D3D11Buffer *d3d11Buffer;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2024-02-09 17:04:32 +00:00
|
|
|
|
bufferDesc.BindFlags = 0;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
if (usageFlags & REFRESH_BUFFERUSAGE_VERTEX_BIT)
|
|
|
|
|
{
|
2024-02-09 17:04:32 +00:00
|
|
|
|
bufferDesc.BindFlags |= D3D11_BIND_VERTEX_BUFFER;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
}
|
|
|
|
|
if (usageFlags & REFRESH_BUFFERUSAGE_INDEX_BIT)
|
|
|
|
|
{
|
2024-02-09 17:04:32 +00:00
|
|
|
|
bufferDesc.BindFlags |= D3D11_BIND_INDEX_BUFFER;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
}
|
2024-02-07 17:53:18 +00:00
|
|
|
|
if ((usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT) || (usageFlags & REFRESH_BUFFERUSAGE_INDIRECT_BIT))
|
2023-10-13 02:31:04 +00:00
|
|
|
|
{
|
2024-02-09 17:04:32 +00:00
|
|
|
|
bufferDesc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bufferDesc.ByteWidth = sizeInBytes;
|
2024-02-09 17:04:32 +00:00
|
|
|
|
bufferDesc.Usage = D3D11_USAGE_DEFAULT;
|
|
|
|
|
bufferDesc.CPUAccessFlags = 0;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
bufferDesc.StructureByteStride = 0;
|
|
|
|
|
|
2024-02-11 06:36:41 +00:00
|
|
|
|
bufferDesc.MiscFlags = 0;
|
|
|
|
|
if (usageFlags & REFRESH_BUFFERUSAGE_INDIRECT_BIT)
|
|
|
|
|
{
|
|
|
|
|
bufferDesc.MiscFlags |= D3D11_RESOURCE_MISC_DRAWINDIRECT_ARGS;
|
|
|
|
|
}
|
|
|
|
|
if (usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT)
|
|
|
|
|
{
|
|
|
|
|
bufferDesc.MiscFlags |= D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS;
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:31:04 +00:00
|
|
|
|
res = ID3D11Device_CreateBuffer(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&bufferDesc,
|
|
|
|
|
NULL,
|
|
|
|
|
&bufferHandle
|
|
|
|
|
);
|
2023-10-27 01:37:27 +00:00
|
|
|
|
ERROR_CHECK_RETURN("Could not create buffer", NULL);
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
2024-02-08 03:03:21 +00:00
|
|
|
|
/* Create a UAV for the buffer */
|
|
|
|
|
if (usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT)
|
|
|
|
|
{
|
|
|
|
|
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
|
2024-02-11 06:36:41 +00:00
|
|
|
|
uavDesc.Format = DXGI_FORMAT_R32_TYPELESS;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
|
|
|
|
uavDesc.Buffer.FirstElement = 0;
|
2024-02-11 06:36:41 +00:00
|
|
|
|
uavDesc.Buffer.Flags = D3D11_BUFFER_UAV_FLAG_RAW;
|
|
|
|
|
uavDesc.Buffer.NumElements = sizeInBytes / sizeof(uint32_t);
|
2024-02-08 03:03:21 +00:00
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateUnorderedAccessView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
(ID3D11Resource*) bufferHandle,
|
|
|
|
|
&uavDesc,
|
|
|
|
|
&uav
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
ID3D11Buffer_Release(bufferHandle);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create UAV for buffer!", NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:31:04 +00:00
|
|
|
|
d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer));
|
|
|
|
|
d3d11Buffer->handle = bufferHandle;
|
|
|
|
|
d3d11Buffer->size = sizeInBytes;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
d3d11Buffer->uav = uav;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
2024-03-03 18:58:44 +00:00
|
|
|
|
return (Refresh_GpuBuffer*) d3d11Buffer;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 19:27:48 +00:00
|
|
|
|
static void D3D11_INTERNAL_TrackTransferBuffer(
|
|
|
|
|
D3D11CommandBuffer *commandBuffer,
|
|
|
|
|
D3D11TransferBuffer *buffer
|
|
|
|
|
) {
|
|
|
|
|
EXPAND_ARRAY_IF_NEEDED(
|
|
|
|
|
commandBuffer->usedTransferBuffers,
|
|
|
|
|
D3D11TransferBuffer*,
|
|
|
|
|
commandBuffer->usedTransferBufferCount + 1,
|
|
|
|
|
commandBuffer->usedTransferBufferCapacity,
|
|
|
|
|
commandBuffer->boundUniformBufferCapacity * 2
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
SDL_AtomicIncRef(&buffer->referenceCount);
|
|
|
|
|
|
|
|
|
|
commandBuffer->usedTransferBuffers[
|
|
|
|
|
commandBuffer->usedTransferBufferCount
|
|
|
|
|
] = buffer;
|
|
|
|
|
commandBuffer->usedTransferBufferCount += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static D3D11TransferBuffer* D3D11_INTERNAL_CreateTransferBuffer(
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11Renderer *renderer,
|
2024-03-03 18:58:44 +00:00
|
|
|
|
uint32_t sizeInBytes
|
|
|
|
|
) {
|
2024-03-05 22:55:53 +00:00
|
|
|
|
D3D11TransferBuffer *transferBuffer = (D3D11TransferBuffer*) SDL_malloc(sizeof(D3D11TransferBuffer));
|
2024-03-04 19:29:23 +00:00
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
transferBuffer->data = (uint8_t*) SDL_malloc(sizeInBytes);
|
|
|
|
|
transferBuffer->size = sizeInBytes;
|
2024-03-03 19:27:48 +00:00
|
|
|
|
SDL_AtomicSet(&transferBuffer->referenceCount, 0);
|
|
|
|
|
|
|
|
|
|
return transferBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This actually returns a container handle so we can rotate buffers on Discard. */
|
|
|
|
|
static Refresh_TransferBuffer* D3D11_CreateTransferBuffer(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
uint32_t sizeInBytes
|
|
|
|
|
) {
|
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) SDL_malloc(sizeof(D3D11TransferBufferContainer));
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11TransferBuffer *transferBuffer = D3D11_INTERNAL_CreateTransferBuffer(renderer, sizeInBytes);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
|
2024-03-03 18:58:44 +00:00
|
|
|
|
container->activeBuffer = transferBuffer;
|
|
|
|
|
container->bufferCapacity = 1;
|
|
|
|
|
container->bufferCount = 1;
|
|
|
|
|
container->buffers = SDL_malloc(
|
2024-03-06 06:41:07 +00:00
|
|
|
|
container->bufferCapacity * sizeof(D3D11TransferBuffer*)
|
2024-03-03 18:58:44 +00:00
|
|
|
|
);
|
|
|
|
|
container->buffers[0] = transferBuffer;
|
|
|
|
|
|
|
|
|
|
return (Refresh_TransferBuffer*) container;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 19:27:48 +00:00
|
|
|
|
/* TransferBuffer Data */
|
|
|
|
|
|
|
|
|
|
static void D3D11_INTERNAL_DiscardActiveTransferBuffer(
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11Renderer *renderer,
|
2024-03-03 19:27:48 +00:00
|
|
|
|
D3D11TransferBufferContainer *container
|
|
|
|
|
) {
|
|
|
|
|
for (uint32_t i = 0; i < container->bufferCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
if (SDL_AtomicGet(&container->buffers[i]->referenceCount) == 0)
|
|
|
|
|
{
|
|
|
|
|
container->activeBuffer = container->buffers[i];
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
container->activeBuffer = D3D11_INTERNAL_CreateTransferBuffer(
|
2024-03-04 19:29:23 +00:00
|
|
|
|
renderer,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
container->activeBuffer->size
|
2024-03-03 19:27:48 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
EXPAND_ARRAY_IF_NEEDED(
|
|
|
|
|
container->buffers,
|
|
|
|
|
D3D11TransferBuffer*,
|
|
|
|
|
container->bufferCount + 1,
|
|
|
|
|
container->bufferCapacity,
|
|
|
|
|
container->bufferCapacity * 2
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
container->buffers[
|
|
|
|
|
container->bufferCapacity
|
|
|
|
|
] = container->activeBuffer;
|
|
|
|
|
container->bufferCount += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_SetTransferData(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
void* data,
|
|
|
|
|
Refresh_TransferBuffer *transferBuffer,
|
|
|
|
|
Refresh_BufferCopy *copyParams,
|
|
|
|
|
Refresh_TransferOptions transferOption
|
|
|
|
|
) {
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-03-03 19:27:48 +00:00
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) transferBuffer;
|
|
|
|
|
D3D11TransferBuffer *buffer = container->activeBuffer;
|
|
|
|
|
|
2024-03-04 19:29:23 +00:00
|
|
|
|
/* Rotate the transfer buffer if necessary */
|
2024-03-03 19:27:48 +00:00
|
|
|
|
if (
|
|
|
|
|
transferOption == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
|
|
|
|
|
SDL_AtomicGet(&container->activeBuffer->referenceCount) > 0
|
|
|
|
|
) {
|
|
|
|
|
D3D11_INTERNAL_DiscardActiveTransferBuffer(
|
2024-03-04 19:29:23 +00:00
|
|
|
|
renderer,
|
2024-03-03 19:27:48 +00:00
|
|
|
|
container
|
|
|
|
|
);
|
2024-03-04 19:29:23 +00:00
|
|
|
|
buffer = container->activeBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 19:27:48 +00:00
|
|
|
|
SDL_memcpy(
|
2024-03-05 02:01:37 +00:00
|
|
|
|
(uint8_t*) buffer->data + copyParams->dstOffset,
|
2024-03-03 19:27:48 +00:00
|
|
|
|
((uint8_t*) data) + copyParams->srcOffset,
|
|
|
|
|
copyParams->size
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_GetTransferData(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_TransferBuffer *transferBuffer,
|
|
|
|
|
void* data,
|
|
|
|
|
Refresh_BufferCopy *copyParams
|
|
|
|
|
) {
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-03-03 19:27:48 +00:00
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) transferBuffer;
|
|
|
|
|
D3D11TransferBuffer *buffer = container->activeBuffer;
|
|
|
|
|
|
|
|
|
|
SDL_memcpy(
|
|
|
|
|
((uint8_t*) data) + copyParams->dstOffset,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
(uint8_t*) buffer->data + copyParams->srcOffset,
|
2024-03-03 19:27:48 +00:00
|
|
|
|
copyParams->size
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 18:58:44 +00:00
|
|
|
|
/* Copy Pass */
|
|
|
|
|
|
|
|
|
|
static void D3D11_BeginCopyPass(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
|
|
|
|
/* no-op */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_UploadToTexture(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
2024-03-03 18:58:44 +00:00
|
|
|
|
Refresh_TransferBuffer *transferBuffer,
|
|
|
|
|
Refresh_TextureRegion *textureRegion,
|
|
|
|
|
Refresh_BufferImageCopy *copyParams,
|
|
|
|
|
Refresh_WriteOptions writeOption
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-03-03 18:58:44 +00:00
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) transferBuffer;
|
|
|
|
|
D3D11TransferBuffer *d3d11TransferBuffer = container->activeBuffer;
|
|
|
|
|
D3D11Texture *d3d11Texture = (D3D11Texture*) textureRegion->textureSlice.texture;
|
2024-03-06 00:06:39 +00:00
|
|
|
|
uint32_t bufferStride = copyParams->bufferStride;
|
|
|
|
|
uint32_t bufferImageHeight = copyParams->bufferImageHeight;
|
2024-03-03 18:58:44 +00:00
|
|
|
|
int32_t w = textureRegion->w;
|
|
|
|
|
int32_t h = textureRegion->h;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
|
|
|
|
int32_t blockSize = Texture_GetBlockSize(d3d11Texture->format);
|
|
|
|
|
if (blockSize > 1)
|
|
|
|
|
{
|
|
|
|
|
w = (w + blockSize - 1) & ~(blockSize - 1);
|
|
|
|
|
h = (h + blockSize - 1) & ~(blockSize - 1);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 00:06:39 +00:00
|
|
|
|
if (bufferStride == 0)
|
|
|
|
|
{
|
|
|
|
|
bufferStride = BytesPerRow(w, d3d11Texture->format);
|
|
|
|
|
}
|
|
|
|
|
if (bufferImageHeight == 0)
|
|
|
|
|
{
|
|
|
|
|
bufferImageHeight = h;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11_BOX dstBox;
|
|
|
|
|
dstBox.left = textureRegion->x;
|
|
|
|
|
dstBox.top = textureRegion->y;
|
2024-03-06 01:54:50 +00:00
|
|
|
|
dstBox.front = textureRegion->z;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
dstBox.right = textureRegion->x + w;
|
|
|
|
|
dstBox.bottom = textureRegion->y + h;
|
2024-03-06 01:54:50 +00:00
|
|
|
|
dstBox.back = textureRegion->z + 1;
|
2024-03-04 19:29:23 +00:00
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
ID3D11DeviceContext1_UpdateSubresource1(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
d3d11Texture->handle,
|
|
|
|
|
D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
textureRegion->textureSlice.mipLevel,
|
|
|
|
|
textureRegion->textureSlice.layer,
|
|
|
|
|
1
|
|
|
|
|
),
|
|
|
|
|
&dstBox,
|
|
|
|
|
(uint8_t*) d3d11TransferBuffer->data + copyParams->bufferOffset,
|
2024-03-06 00:06:39 +00:00
|
|
|
|
bufferStride,
|
|
|
|
|
bufferStride * bufferImageHeight,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD ? D3D11_COPY_DISCARD : 0
|
|
|
|
|
);
|
2024-03-04 19:29:23 +00:00
|
|
|
|
|
|
|
|
|
D3D11_INTERNAL_TrackTransferBuffer(d3d11CommandBuffer, d3d11TransferBuffer);
|
|
|
|
|
}
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
2024-03-04 19:29:23 +00:00
|
|
|
|
static void D3D11_UploadToBuffer(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_TransferBuffer *transferBuffer,
|
|
|
|
|
Refresh_GpuBuffer *gpuBuffer,
|
|
|
|
|
Refresh_BufferCopy *copyParams,
|
|
|
|
|
Refresh_WriteOptions writeOption
|
|
|
|
|
) {
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) transferBuffer;
|
|
|
|
|
D3D11TransferBuffer *d3d11TransferBuffer = container->activeBuffer;
|
|
|
|
|
D3D11Buffer *d3d11Buffer = (D3D11Buffer*) gpuBuffer;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
D3D11_BOX dstBox = { copyParams->dstOffset, 0, 0, copyParams->dstOffset + copyParams->size, 1, 1 };
|
2024-03-04 19:29:23 +00:00
|
|
|
|
|
2024-03-05 23:45:41 +00:00
|
|
|
|
ID3D11DeviceContext1_UpdateSubresource1(
|
2023-10-27 02:25:03 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
(ID3D11Resource*) d3d11Buffer->handle,
|
2024-03-04 19:29:23 +00:00
|
|
|
|
0,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
&dstBox,
|
|
|
|
|
d3d11TransferBuffer->data + copyParams->srcOffset,
|
2024-03-04 19:29:23 +00:00
|
|
|
|
0,
|
|
|
|
|
0,
|
2024-03-03 18:58:44 +00:00
|
|
|
|
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD ? D3D11_COPY_DISCARD : 0
|
2023-10-27 02:25:03 +00:00
|
|
|
|
);
|
2024-03-03 19:27:48 +00:00
|
|
|
|
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11_INTERNAL_TrackTransferBuffer(d3d11CommandBuffer, d3d11TransferBuffer);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-04 19:29:23 +00:00
|
|
|
|
static void D3D11_DownloadFromTexture(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
2024-03-04 19:29:23 +00:00
|
|
|
|
Refresh_TextureRegion *textureRegion,
|
2024-03-03 18:58:44 +00:00
|
|
|
|
Refresh_TransferBuffer *transferBuffer,
|
2024-03-04 19:29:23 +00:00
|
|
|
|
Refresh_BufferImageCopy *copyParams,
|
|
|
|
|
Refresh_TransferOptions transferOption
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-03-04 19:29:23 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-03-03 18:58:44 +00:00
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) transferBuffer;
|
|
|
|
|
D3D11TransferBuffer *d3d11TransferBuffer = container->activeBuffer;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11Texture *d3d11Texture = (D3D11Texture*) textureRegion->textureSlice.texture;
|
|
|
|
|
D3D11_TEXTURE2D_DESC stagingDesc;
|
|
|
|
|
ID3D11Resource *stagingTexture;
|
|
|
|
|
uint32_t subresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
textureRegion->textureSlice.mipLevel,
|
|
|
|
|
textureRegion->textureSlice.layer,
|
|
|
|
|
d3d11Texture->levelCount
|
|
|
|
|
);
|
|
|
|
|
int32_t formatSize = Texture_GetFormatSize(d3d11Texture->format);
|
2024-03-06 06:24:33 +00:00
|
|
|
|
uint32_t bufferStride = copyParams->bufferStride == 0 ? (textureRegion->w * formatSize) : copyParams->bufferStride;
|
|
|
|
|
uint32_t bufferImageHeight = copyParams->bufferImageHeight == 0 ? (textureRegion->h * formatSize) : copyParams->bufferImageHeight;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11_BOX srcBox = {textureRegion->x, textureRegion->y, textureRegion->z, textureRegion->x + textureRegion->w, textureRegion->y + textureRegion->h, 1};
|
|
|
|
|
D3D11_MAPPED_SUBRESOURCE subresource;
|
|
|
|
|
HRESULT res;
|
2024-02-09 23:52:47 +00:00
|
|
|
|
|
2024-03-04 19:29:23 +00:00
|
|
|
|
/* Rotate the transfer buffer if necessary */
|
|
|
|
|
if (
|
|
|
|
|
transferOption == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
|
|
|
|
|
SDL_AtomicGet(&container->activeBuffer->referenceCount) > 0
|
|
|
|
|
) {
|
|
|
|
|
D3D11_INTERNAL_DiscardActiveTransferBuffer(
|
|
|
|
|
renderer,
|
|
|
|
|
container
|
|
|
|
|
);
|
|
|
|
|
d3d11TransferBuffer = container->activeBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
stagingDesc.Width = textureRegion->w;
|
|
|
|
|
stagingDesc.Height = textureRegion->h;
|
|
|
|
|
stagingDesc.MipLevels = 1;
|
|
|
|
|
stagingDesc.ArraySize = 1;
|
|
|
|
|
stagingDesc.Format = RefreshToD3D11_TextureFormat[d3d11Texture->format];
|
|
|
|
|
stagingDesc.SampleDesc.Count = 1;
|
|
|
|
|
stagingDesc.SampleDesc.Quality = 0;
|
|
|
|
|
stagingDesc.Usage = D3D11_USAGE_STAGING;
|
|
|
|
|
stagingDesc.BindFlags = 0;
|
|
|
|
|
stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
|
|
|
|
stagingDesc.MiscFlags = 0;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateTexture2D(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&stagingDesc,
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11Texture2D**) &stagingTexture
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Staging texture creation failed",)
|
|
|
|
|
|
2024-03-06 01:30:20 +00:00
|
|
|
|
/* Readback is only possible on CPU timeline in D3D11 */
|
|
|
|
|
SDL_LockMutex(renderer->contextLock);
|
|
|
|
|
ID3D11DeviceContext_CopySubresourceRegion(
|
|
|
|
|
renderer->immediateContext,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
stagingTexture,
|
2024-02-09 23:52:47 +00:00
|
|
|
|
0,
|
2024-03-06 06:24:33 +00:00
|
|
|
|
0,
|
2024-03-04 19:29:23 +00:00
|
|
|
|
0,
|
|
|
|
|
0,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
d3d11Texture->handle,
|
|
|
|
|
subresourceIndex,
|
2024-03-06 01:30:20 +00:00
|
|
|
|
&srcBox
|
2024-02-09 23:52:47 +00:00
|
|
|
|
);
|
2024-03-03 19:27:48 +00:00
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
/* Read from the staging texture */
|
2024-03-06 01:30:20 +00:00
|
|
|
|
res = ID3D11DeviceContext_Map(
|
|
|
|
|
renderer->immediateContext,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
stagingTexture,
|
2024-03-06 06:24:33 +00:00
|
|
|
|
0,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11_MAP_READ,
|
|
|
|
|
0,
|
|
|
|
|
&subresource
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not map texture for reading",)
|
2024-02-09 05:47:25 +00:00
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
uint8_t* dataPtr = (uint8_t*) d3d11TransferBuffer->data + copyParams->bufferOffset;
|
2024-03-06 04:58:34 +00:00
|
|
|
|
|
2024-03-06 06:48:04 +00:00
|
|
|
|
/* TODO: figure out 3D copy */
|
2024-03-06 06:24:33 +00:00
|
|
|
|
for (uint32_t row = textureRegion->y; row < textureRegion->h; row += 1)
|
2024-03-05 02:01:37 +00:00
|
|
|
|
{
|
|
|
|
|
SDL_memcpy(
|
|
|
|
|
dataPtr,
|
2024-03-06 06:24:33 +00:00
|
|
|
|
(uint8_t*) subresource.pData + (row * subresource.RowPitch) + (textureRegion->x * formatSize),
|
|
|
|
|
bufferStride
|
2024-03-05 02:01:37 +00:00
|
|
|
|
);
|
2024-03-06 06:24:33 +00:00
|
|
|
|
dataPtr += bufferStride;
|
2024-03-06 04:58:34 +00:00
|
|
|
|
}
|
2024-02-09 17:19:51 +00:00
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
ID3D11DeviceContext1_Unmap(
|
2024-03-06 01:30:20 +00:00
|
|
|
|
renderer->immediateContext,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
stagingTexture,
|
|
|
|
|
0
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
2024-03-06 01:30:20 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->contextLock);
|
2024-03-05 02:01:37 +00:00
|
|
|
|
|
2024-03-06 01:30:20 +00:00
|
|
|
|
/* Clean up the staging texture */
|
2024-03-05 02:01:37 +00:00
|
|
|
|
ID3D11Texture2D_Release(stagingTexture);
|
2023-11-05 20:17:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
static void D3D11_DownloadFromBuffer(
|
2024-02-09 05:47:25 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
Refresh_GpuBuffer *gpuBuffer,
|
|
|
|
|
Refresh_TransferBuffer *transferBuffer,
|
|
|
|
|
Refresh_BufferCopy *copyParams,
|
|
|
|
|
Refresh_TransferOptions transferOption
|
2023-11-05 20:17:23 +00:00
|
|
|
|
) {
|
2024-02-09 06:57:26 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) transferBuffer;
|
|
|
|
|
D3D11TransferBuffer *d3d11TransferBuffer = container->activeBuffer;
|
|
|
|
|
D3D11Buffer *d3d11Buffer = (D3D11Buffer*) gpuBuffer;
|
|
|
|
|
D3D11_BOX srcBox = { copyParams->srcOffset, 0, 0, copyParams->size, 1, 1 };
|
2024-02-09 06:57:26 +00:00
|
|
|
|
ID3D11Resource *stagingBuffer;
|
|
|
|
|
D3D11_MAPPED_SUBRESOURCE mappedSubresource;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11_BUFFER_DESC stagingBufferDesc;
|
2024-02-09 06:57:26 +00:00
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
/* Rotate the transfer buffer if necessary */
|
|
|
|
|
if (
|
|
|
|
|
transferOption == REFRESH_TRANSFEROPTIONS_SAFEDISCARD &&
|
|
|
|
|
SDL_AtomicGet(&container->activeBuffer->referenceCount) > 0
|
|
|
|
|
) {
|
|
|
|
|
D3D11_INTERNAL_DiscardActiveTransferBuffer(
|
|
|
|
|
renderer,
|
|
|
|
|
container
|
|
|
|
|
);
|
|
|
|
|
d3d11TransferBuffer = container->activeBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 06:57:26 +00:00
|
|
|
|
/* Create staging buffer */
|
2024-03-05 02:01:37 +00:00
|
|
|
|
stagingBufferDesc.ByteWidth = copyParams->size;
|
2024-02-09 06:57:26 +00:00
|
|
|
|
stagingBufferDesc.Usage = D3D11_USAGE_STAGING;
|
|
|
|
|
stagingBufferDesc.BindFlags = 0;
|
|
|
|
|
stagingBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
|
|
|
|
stagingBufferDesc.MiscFlags = 0;
|
|
|
|
|
stagingBufferDesc.StructureByteStride = 0;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateBuffer(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&stagingBufferDesc,
|
|
|
|
|
NULL,
|
|
|
|
|
(ID3D11Buffer**) &stagingBuffer
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create staging buffer for readback", );
|
|
|
|
|
|
2024-03-06 01:30:20 +00:00
|
|
|
|
/* Readback is only possible on CPU timeline in D3D11 */
|
|
|
|
|
SDL_LockMutex(renderer->contextLock);
|
|
|
|
|
ID3D11DeviceContext_CopySubresourceRegion(
|
|
|
|
|
renderer->immediateContext,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
(ID3D11Resource*) stagingBuffer,
|
2024-02-09 06:57:26 +00:00
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
(ID3D11Resource*) d3d11Buffer->handle,
|
2024-02-09 06:57:26 +00:00
|
|
|
|
0,
|
2024-03-06 01:30:20 +00:00
|
|
|
|
&srcBox
|
2024-02-09 06:57:26 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* Read from the staging buffer */
|
2024-03-06 01:30:20 +00:00
|
|
|
|
res = ID3D11DeviceContext_Map(
|
|
|
|
|
renderer->immediateContext,
|
2024-02-09 06:57:26 +00:00
|
|
|
|
stagingBuffer,
|
|
|
|
|
0,
|
|
|
|
|
D3D11_MAP_READ,
|
|
|
|
|
0,
|
|
|
|
|
&mappedSubresource
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
D3D11_INTERNAL_LogError(
|
|
|
|
|
renderer->device,
|
|
|
|
|
"Failed to map staging buffer for read!",
|
|
|
|
|
res
|
|
|
|
|
);
|
|
|
|
|
ID3D11Buffer_Release(stagingBuffer);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
SDL_memcpy(
|
|
|
|
|
d3d11TransferBuffer->data + copyParams->dstOffset,
|
|
|
|
|
mappedSubresource.pData,
|
|
|
|
|
copyParams->size
|
|
|
|
|
);
|
2024-02-09 06:57:26 +00:00
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
ID3D11DeviceContext1_Unmap(
|
2024-03-06 01:30:20 +00:00
|
|
|
|
renderer->immediateContext,
|
2024-02-09 06:57:26 +00:00
|
|
|
|
stagingBuffer,
|
|
|
|
|
0
|
|
|
|
|
);
|
2024-03-06 01:30:20 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->contextLock);
|
2024-02-09 06:57:26 +00:00
|
|
|
|
|
|
|
|
|
/* Clean up the staging buffer */
|
2024-03-05 02:01:37 +00:00
|
|
|
|
ID3D11Buffer_Release(stagingBuffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_CopyTextureToTexture(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_TextureRegion *source,
|
|
|
|
|
Refresh_TextureRegion *destination,
|
|
|
|
|
Refresh_WriteOptions writeOption
|
|
|
|
|
) {
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-03-05 22:55:53 +00:00
|
|
|
|
D3D11Texture *srcTexture = (D3D11Texture*) source->textureSlice.texture;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
uint32_t srcSubresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
source->textureSlice.mipLevel,
|
|
|
|
|
source->textureSlice.layer,
|
|
|
|
|
srcTexture->levelCount
|
|
|
|
|
);
|
2024-03-05 22:55:53 +00:00
|
|
|
|
D3D11Texture *dstTexture = (D3D11Texture*) destination->textureSlice.texture;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
uint32_t dstSubresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
destination->textureSlice.mipLevel,
|
|
|
|
|
destination->textureSlice.layer,
|
|
|
|
|
dstTexture->levelCount
|
|
|
|
|
);
|
2024-03-06 04:58:34 +00:00
|
|
|
|
D3D11_BOX srcBox = { source->x, source->y, source->z, source->x + source->w, source->y + source->h, 1 };
|
2024-03-05 02:01:37 +00:00
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext1_CopySubresourceRegion1(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
dstTexture->handle,
|
|
|
|
|
dstSubresourceIndex,
|
|
|
|
|
destination->x,
|
|
|
|
|
destination->y,
|
|
|
|
|
destination->z,
|
|
|
|
|
srcTexture->handle,
|
|
|
|
|
srcSubresourceIndex,
|
|
|
|
|
&srcBox,
|
|
|
|
|
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD ? D3D11_COPY_DISCARD : 0
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_CopyBufferToBuffer(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_GpuBuffer *source,
|
|
|
|
|
Refresh_GpuBuffer *destination,
|
|
|
|
|
Refresh_BufferCopy *copyParams,
|
|
|
|
|
Refresh_WriteOptions writeOption
|
|
|
|
|
) {
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11Buffer *srcBuffer = (D3D11Buffer*) source;
|
|
|
|
|
D3D11Buffer *dstBuffer = (D3D11Buffer*) destination;
|
|
|
|
|
D3D11_BOX srcBox = { copyParams->srcOffset, 0, 0, copyParams->srcOffset + copyParams->size, 1, 1 };
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext1_CopySubresourceRegion1(
|
|
|
|
|
d3d11CommandBuffer->context,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
(ID3D11Resource*) dstBuffer->handle,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
0,
|
|
|
|
|
copyParams->dstOffset,
|
|
|
|
|
0,
|
|
|
|
|
0,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
(ID3D11Resource*) srcBuffer->handle,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
0,
|
|
|
|
|
&srcBox,
|
|
|
|
|
writeOption == REFRESH_WRITEOPTIONS_SAFEDISCARD ? D3D11_COPY_DISCARD : 0
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 22:55:53 +00:00
|
|
|
|
static void D3D11_GenerateMipmaps(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_Texture *texture
|
|
|
|
|
) {
|
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11Texture *d3d11Texture = (D3D11Texture*) texture;
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext1_GenerateMips(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
d3d11Texture->shaderView
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
static void D3D11_EndCopyPass(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
|
|
|
|
/* no-op */
|
2023-11-05 20:17:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Uniforms */
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
static uint8_t D3D11_INTERNAL_CreateUniformBuffer(
|
|
|
|
|
D3D11Renderer *renderer
|
|
|
|
|
) {
|
|
|
|
|
D3D11_BUFFER_DESC bufferDesc;
|
2024-02-07 13:34:07 +00:00
|
|
|
|
ID3D11Buffer *bufferHandle;
|
|
|
|
|
D3D11UniformBuffer *uniformBuffer;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
bufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
|
|
|
|
bufferDesc.ByteWidth = UBO_BUFFER_SIZE;
|
|
|
|
|
bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
|
|
|
|
bufferDesc.MiscFlags = 0;
|
|
|
|
|
bufferDesc.StructureByteStride = 0;
|
|
|
|
|
bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
|
|
|
|
|
|
2024-02-07 13:34:07 +00:00
|
|
|
|
res = ID3D11Device_CreateBuffer(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->device,
|
|
|
|
|
&bufferDesc,
|
|
|
|
|
NULL,
|
|
|
|
|
&bufferHandle
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Failed to create uniform buffer", 0);
|
|
|
|
|
|
2024-02-07 13:34:07 +00:00
|
|
|
|
uniformBuffer = SDL_malloc(sizeof(D3D11UniformBuffer));
|
2023-11-05 20:17:23 +00:00
|
|
|
|
uniformBuffer->offset = 0;
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uniformBuffer->drawOffset = 0;
|
2024-02-09 17:19:51 +00:00
|
|
|
|
uniformBuffer->hasDiscarded = 0;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
uniformBuffer->d3d11Buffer = SDL_malloc(sizeof(D3D11Buffer));
|
|
|
|
|
uniformBuffer->d3d11Buffer->handle = bufferHandle;
|
|
|
|
|
uniformBuffer->d3d11Buffer->size = UBO_BUFFER_SIZE;
|
2024-02-09 05:47:25 +00:00
|
|
|
|
uniformBuffer->d3d11Buffer->uav = NULL;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
|
|
|
|
|
/* Add it to the available pool */
|
|
|
|
|
if (renderer->availableUniformBufferCount >= renderer->availableUniformBufferCapacity)
|
|
|
|
|
{
|
|
|
|
|
renderer->availableUniformBufferCapacity *= 2;
|
|
|
|
|
|
|
|
|
|
renderer->availableUniformBuffers = SDL_realloc(
|
|
|
|
|
renderer->availableUniformBuffers,
|
|
|
|
|
sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderer->availableUniformBuffers[renderer->availableUniformBufferCount] = uniformBuffer;
|
|
|
|
|
renderer->availableUniformBufferCount += 1;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
static uint8_t D3D11_INTERNAL_AcquireUniformBuffer(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D11Renderer *renderer,
|
2024-02-09 05:47:25 +00:00
|
|
|
|
D3D11CommandBuffer *commandBuffer,
|
|
|
|
|
D3D11UniformBuffer **uniformBufferToBind,
|
2023-11-05 20:17:23 +00:00
|
|
|
|
uint64_t blockSize
|
|
|
|
|
) {
|
2024-02-07 13:34:07 +00:00
|
|
|
|
D3D11UniformBuffer *uniformBuffer;
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Acquire a uniform buffer from the pool */
|
2023-11-05 20:17:23 +00:00
|
|
|
|
SDL_LockMutex(renderer->uniformBufferLock);
|
|
|
|
|
|
|
|
|
|
if (renderer->availableUniformBufferCount == 0)
|
|
|
|
|
{
|
|
|
|
|
if (!D3D11_INTERNAL_CreateUniformBuffer(renderer))
|
|
|
|
|
{
|
|
|
|
|
SDL_UnlockMutex(renderer->uniformBufferLock);
|
|
|
|
|
Refresh_LogError("Failed to create uniform buffer!");
|
2024-02-09 05:47:25 +00:00
|
|
|
|
return 0;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-07 13:34:07 +00:00
|
|
|
|
uniformBuffer = renderer->availableUniformBuffers[renderer->availableUniformBufferCount - 1];
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->availableUniformBufferCount -= 1;
|
|
|
|
|
|
|
|
|
|
SDL_UnlockMutex(renderer->uniformBufferLock);
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Reset the uniform buffer */
|
2024-02-09 17:19:51 +00:00
|
|
|
|
uniformBuffer->hasDiscarded = 0;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
uniformBuffer->offset = 0;
|
2024-03-03 07:33:36 +00:00
|
|
|
|
uniformBuffer->drawOffset = 0;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Bind the uniform buffer to the command buffer */
|
|
|
|
|
if (commandBuffer->boundUniformBufferCount >= commandBuffer->boundUniformBufferCapacity)
|
|
|
|
|
{
|
|
|
|
|
commandBuffer->boundUniformBufferCapacity *= 2;
|
|
|
|
|
commandBuffer->boundUniformBuffers = SDL_realloc(
|
|
|
|
|
commandBuffer->boundUniformBuffers,
|
|
|
|
|
sizeof(D3D11UniformBuffer*) * commandBuffer->boundUniformBufferCapacity
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
commandBuffer->boundUniformBuffers[commandBuffer->boundUniformBufferCount] = uniformBuffer;
|
|
|
|
|
commandBuffer->boundUniformBufferCount += 1;
|
|
|
|
|
|
|
|
|
|
*uniformBufferToBind = uniformBuffer;
|
|
|
|
|
|
|
|
|
|
return 1;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 17:19:51 +00:00
|
|
|
|
static void D3D11_INTERNAL_SetUniformBufferData(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
D3D11CommandBuffer *commandBuffer,
|
|
|
|
|
D3D11UniformBuffer *uniformBuffer,
|
|
|
|
|
void* data,
|
|
|
|
|
uint32_t dataLength
|
|
|
|
|
) {
|
|
|
|
|
D3D11_MAPPED_SUBRESOURCE subres;
|
|
|
|
|
|
|
|
|
|
HRESULT res = ID3D11DeviceContext_Map(
|
|
|
|
|
commandBuffer->context,
|
|
|
|
|
(ID3D11Resource*) uniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
0,
|
|
|
|
|
uniformBuffer->hasDiscarded ? D3D11_MAP_WRITE_NO_OVERWRITE : D3D11_MAP_WRITE_DISCARD,
|
|
|
|
|
0,
|
|
|
|
|
&subres
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not map buffer for writing!", );
|
|
|
|
|
|
|
|
|
|
SDL_memcpy(
|
|
|
|
|
(uint8_t*) subres.pData + uniformBuffer->offset,
|
|
|
|
|
data,
|
|
|
|
|
dataLength
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_Unmap(
|
|
|
|
|
commandBuffer->context,
|
|
|
|
|
(ID3D11Resource*) uniformBuffer->d3d11Buffer->handle,
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
uniformBuffer->hasDiscarded = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 07:33:36 +00:00
|
|
|
|
static void D3D11_PushVertexShaderUniforms(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
void *data,
|
|
|
|
|
uint32_t dataLengthInBytes
|
|
|
|
|
) {
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11GraphicsPipeline *graphicsPipeline = d3d11CommandBuffer->graphicsPipeline;
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->vertexUniformBuffer->offset + graphicsPipeline->vertexUniformBlockSize >= UBO_BUFFER_SIZE)
|
|
|
|
|
{
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Out of space! Get a new uniform buffer. */
|
|
|
|
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer,
|
2024-02-09 05:47:25 +00:00
|
|
|
|
d3d11CommandBuffer,
|
|
|
|
|
&d3d11CommandBuffer->vertexUniformBuffer,
|
2023-11-05 20:17:23 +00:00
|
|
|
|
graphicsPipeline->vertexUniformBlockSize
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 07:33:36 +00:00
|
|
|
|
d3d11CommandBuffer->vertexUniformBuffer->drawOffset = d3d11CommandBuffer->vertexUniformBuffer->offset;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
|
2024-02-09 17:19:51 +00:00
|
|
|
|
D3D11_INTERNAL_SetUniformBufferData(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer,
|
|
|
|
|
d3d11CommandBuffer,
|
2024-02-09 17:19:51 +00:00
|
|
|
|
d3d11CommandBuffer->vertexUniformBuffer,
|
2023-11-05 20:17:23 +00:00
|
|
|
|
data,
|
2024-02-09 17:19:51 +00:00
|
|
|
|
dataLengthInBytes
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
d3d11CommandBuffer->vertexUniformBuffer->offset += graphicsPipeline->vertexUniformBlockSize;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 07:33:36 +00:00
|
|
|
|
static void D3D11_PushFragmentShaderUniforms(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
void *data,
|
|
|
|
|
uint32_t dataLengthInBytes
|
|
|
|
|
) {
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11GraphicsPipeline *graphicsPipeline = d3d11CommandBuffer->graphicsPipeline;
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->fragmentUniformBuffer->offset + graphicsPipeline->fragmentUniformBlockSize >= UBO_BUFFER_SIZE)
|
|
|
|
|
{
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Out of space! Get a new uniform buffer. */
|
|
|
|
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer,
|
2024-02-09 05:47:25 +00:00
|
|
|
|
d3d11CommandBuffer,
|
|
|
|
|
&d3d11CommandBuffer->fragmentUniformBuffer,
|
2023-11-05 20:17:23 +00:00
|
|
|
|
graphicsPipeline->fragmentUniformBlockSize
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 07:33:36 +00:00
|
|
|
|
d3d11CommandBuffer->fragmentUniformBuffer->drawOffset = d3d11CommandBuffer->fragmentUniformBuffer->offset;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
|
2024-02-09 17:19:51 +00:00
|
|
|
|
D3D11_INTERNAL_SetUniformBufferData(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer,
|
|
|
|
|
d3d11CommandBuffer,
|
2024-02-09 17:19:51 +00:00
|
|
|
|
d3d11CommandBuffer->fragmentUniformBuffer,
|
2023-11-05 20:17:23 +00:00
|
|
|
|
data,
|
2024-02-09 17:19:51 +00:00
|
|
|
|
dataLengthInBytes
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
d3d11CommandBuffer->fragmentUniformBuffer->offset += graphicsPipeline->fragmentUniformBlockSize;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 23:45:41 +00:00
|
|
|
|
static void D3D11_PushComputeShaderUniforms(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
void *data,
|
|
|
|
|
uint32_t dataLengthInBytes
|
|
|
|
|
) {
|
2024-02-09 08:17:08 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11ComputePipeline *computePipeline = d3d11CommandBuffer->computePipeline;
|
|
|
|
|
|
|
|
|
|
if (d3d11CommandBuffer->computeUniformBuffer->offset + computePipeline->computeUniformBlockSize >= UBO_BUFFER_SIZE)
|
|
|
|
|
{
|
|
|
|
|
/* Out of space! Get a new uniform buffer. */
|
|
|
|
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
|
|
|
|
renderer,
|
|
|
|
|
d3d11CommandBuffer,
|
|
|
|
|
&d3d11CommandBuffer->computeUniformBuffer,
|
|
|
|
|
computePipeline->computeUniformBlockSize
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 07:33:36 +00:00
|
|
|
|
d3d11CommandBuffer->computeUniformBuffer->drawOffset = d3d11CommandBuffer->computeUniformBuffer->offset;
|
2024-02-09 08:17:08 +00:00
|
|
|
|
|
2024-02-09 17:19:51 +00:00
|
|
|
|
D3D11_INTERNAL_SetUniformBufferData(
|
2024-02-09 08:17:08 +00:00
|
|
|
|
renderer,
|
|
|
|
|
d3d11CommandBuffer,
|
2024-02-09 17:19:51 +00:00
|
|
|
|
d3d11CommandBuffer->computeUniformBuffer,
|
2024-02-09 08:17:08 +00:00
|
|
|
|
data,
|
2024-02-09 17:19:51 +00:00
|
|
|
|
dataLengthInBytes
|
2024-02-09 08:17:08 +00:00
|
|
|
|
);
|
|
|
|
|
|
2024-02-11 04:21:01 +00:00
|
|
|
|
d3d11CommandBuffer->computeUniformBuffer->offset +=
|
2024-03-05 23:45:41 +00:00
|
|
|
|
(uint32_t) computePipeline->computeUniformBlockSize;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:47:25 +00:00
|
|
|
|
/* Samplers */
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static void D3D11_BindVertexSamplers(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
Refresh_TextureSamplerBinding *pBindings
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-02-07 16:18:49 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
ID3D11ShaderResourceView* srvs[MAX_VERTEXTEXTURE_SAMPLERS];
|
|
|
|
|
ID3D11SamplerState* d3d11Samplers[MAX_VERTEXTEXTURE_SAMPLERS];
|
|
|
|
|
|
|
|
|
|
int32_t numVertexSamplers = d3d11CommandBuffer->graphicsPipeline->numVertexSamplers;
|
|
|
|
|
|
|
|
|
|
for (int32_t i = 0; i < numVertexSamplers; i += 1)
|
|
|
|
|
{
|
2024-03-05 23:45:41 +00:00
|
|
|
|
srvs[i] = ((D3D11Texture*) pBindings[i].texture)->shaderView;
|
|
|
|
|
d3d11Samplers[i] = ((D3D11Sampler*) pBindings[i].sampler)->handle;
|
2024-02-07 16:18:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_VSSetShaderResources(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
numVertexSamplers,
|
|
|
|
|
srvs
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_VSSetSamplers(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
numVertexSamplers,
|
|
|
|
|
d3d11Samplers
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_BindFragmentSamplers(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
2024-03-05 23:45:41 +00:00
|
|
|
|
Refresh_TextureSamplerBinding *pBindings
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2023-10-27 02:25:03 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
ID3D11ShaderResourceView* srvs[MAX_TEXTURE_SAMPLERS];
|
|
|
|
|
ID3D11SamplerState* d3d11Samplers[MAX_TEXTURE_SAMPLERS];
|
|
|
|
|
|
|
|
|
|
int32_t numFragmentSamplers = d3d11CommandBuffer->graphicsPipeline->numFragmentSamplers;
|
|
|
|
|
|
|
|
|
|
for (int32_t i = 0; i < numFragmentSamplers; i += 1)
|
|
|
|
|
{
|
2024-03-05 23:45:41 +00:00
|
|
|
|
srvs[i] = ((D3D11Texture*) pBindings[i].texture)->shaderView;
|
|
|
|
|
d3d11Samplers[i] = ((D3D11Sampler*) pBindings[i].sampler)->handle;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_PSSetShaderResources(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
numFragmentSamplers,
|
|
|
|
|
srvs
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_PSSetSamplers(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
numFragmentSamplers,
|
|
|
|
|
d3d11Samplers
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Disposal */
|
|
|
|
|
|
|
|
|
|
static void D3D11_QueueDestroyTexture(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_Texture *texture
|
|
|
|
|
) {
|
2023-10-27 02:25:03 +00:00
|
|
|
|
D3D11Texture *d3d11Texture = (D3D11Texture*) texture;
|
2024-02-07 14:02:49 +00:00
|
|
|
|
|
|
|
|
|
if (d3d11Texture->shaderView)
|
|
|
|
|
{
|
|
|
|
|
ID3D11ShaderResourceView_Release(d3d11Texture->shaderView);
|
|
|
|
|
}
|
2024-03-05 20:27:38 +00:00
|
|
|
|
|
|
|
|
|
for (uint32_t layerIndex = 0; layerIndex < d3d11Texture->layerCount; layerIndex += 1)
|
2024-02-09 18:09:29 +00:00
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
for (uint32_t levelIndex = 0; levelIndex < d3d11Texture->levelCount; levelIndex += 1)
|
2024-02-09 21:28:08 +00:00
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
uint32_t subresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
levelIndex,
|
|
|
|
|
layerIndex,
|
|
|
|
|
d3d11Texture->levelCount
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (d3d11Texture->subresources[subresourceIndex].msaaHandle != NULL)
|
|
|
|
|
{
|
|
|
|
|
ID3D11Resource_Release(d3d11Texture->subresources[subresourceIndex].msaaHandle);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 23:45:41 +00:00
|
|
|
|
if (d3d11Texture->subresources[subresourceIndex].colorTargetView != NULL)
|
|
|
|
|
{
|
|
|
|
|
ID3D11RenderTargetView_Release(d3d11Texture->subresources[subresourceIndex].colorTargetView);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d3d11Texture->subresources[subresourceIndex].depthStencilTargetView != NULL)
|
2024-03-05 20:27:38 +00:00
|
|
|
|
{
|
2024-03-05 23:45:41 +00:00
|
|
|
|
ID3D11DepthStencilView_Release(d3d11Texture->subresources[subresourceIndex].depthStencilTargetView);
|
2024-03-05 20:27:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d3d11Texture->subresources[subresourceIndex].uav != NULL)
|
|
|
|
|
{
|
|
|
|
|
ID3D11UnorderedAccessView_Release(d3d11Texture->subresources[subresourceIndex].uav);
|
|
|
|
|
}
|
2024-02-09 21:28:08 +00:00
|
|
|
|
}
|
2024-02-10 05:56:36 +00:00
|
|
|
|
}
|
2024-03-05 20:27:38 +00:00
|
|
|
|
SDL_free(d3d11Texture->subresources);
|
2024-02-07 14:02:49 +00:00
|
|
|
|
|
2023-10-27 02:25:03 +00:00
|
|
|
|
ID3D11Resource_Release(d3d11Texture->handle);
|
2024-02-07 14:02:49 +00:00
|
|
|
|
|
2023-10-27 02:25:03 +00:00
|
|
|
|
SDL_free(d3d11Texture);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_QueueDestroySampler(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_Sampler *sampler
|
|
|
|
|
) {
|
2023-10-13 03:12:55 +00:00
|
|
|
|
D3D11Sampler *d3d11Sampler = (D3D11Sampler*) sampler;
|
|
|
|
|
ID3D11SamplerState_Release(d3d11Sampler->handle);
|
|
|
|
|
SDL_free(d3d11Sampler);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
static void D3D11_QueueDestroyGpuBuffer(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
Refresh_GpuBuffer *gpuBuffer
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11Buffer *d3d11Buffer = (D3D11Buffer*) gpuBuffer;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
|
|
|
|
|
if (d3d11Buffer->uav)
|
|
|
|
|
{
|
2024-02-09 08:02:41 +00:00
|
|
|
|
ID3D11UnorderedAccessView_Release(d3d11Buffer->uav);
|
2024-02-08 03:03:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-13 02:31:04 +00:00
|
|
|
|
ID3D11Buffer_Release(d3d11Buffer->handle);
|
2024-02-08 03:03:21 +00:00
|
|
|
|
|
2023-10-13 02:31:04 +00:00
|
|
|
|
SDL_free(d3d11Buffer);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 22:55:53 +00:00
|
|
|
|
static void D3D11_QueueDestroyTransferBuffer(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_TransferBuffer *transferBuffer
|
|
|
|
|
) {
|
|
|
|
|
D3D11TransferBufferContainer *container = (D3D11TransferBufferContainer*) transferBuffer;
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < container->bufferCount; i += 1)
|
|
|
|
|
{
|
2024-03-06 06:41:07 +00:00
|
|
|
|
SDL_free(container->buffers[i]->data);
|
2024-03-05 22:55:53 +00:00
|
|
|
|
SDL_free(container->buffers[i]);
|
|
|
|
|
}
|
|
|
|
|
SDL_free(container->buffers);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static void D3D11_QueueDestroyShaderModule(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_ShaderModule *shaderModule
|
|
|
|
|
) {
|
2023-10-11 02:45:32 +00:00
|
|
|
|
D3D11ShaderModule *d3dShaderModule = (D3D11ShaderModule*) shaderModule;
|
2023-10-12 13:42:32 +00:00
|
|
|
|
|
|
|
|
|
if (d3dShaderModule->shader)
|
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceChild_Release(d3dShaderModule->shader);
|
|
|
|
|
}
|
|
|
|
|
if (d3dShaderModule->blob)
|
|
|
|
|
{
|
|
|
|
|
ID3D10Blob_Release(d3dShaderModule->blob);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 02:45:32 +00:00
|
|
|
|
SDL_free(d3dShaderModule);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_QueueDestroyComputePipeline(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_ComputePipeline *computePipeline
|
|
|
|
|
) {
|
2024-02-09 06:35:19 +00:00
|
|
|
|
D3D11ComputePipeline *d3d11ComputePipeline = (D3D11ComputePipeline*) computePipeline;
|
|
|
|
|
SDL_free(d3d11ComputePipeline);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_QueueDestroyGraphicsPipeline(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_GraphicsPipeline *graphicsPipeline
|
|
|
|
|
) {
|
2023-10-11 02:45:32 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2024-02-09 06:35:19 +00:00
|
|
|
|
D3D11GraphicsPipeline *d3d11GraphicsPipeline = (D3D11GraphicsPipeline*) graphicsPipeline;
|
2023-10-11 02:45:32 +00:00
|
|
|
|
|
2024-02-09 06:35:19 +00:00
|
|
|
|
ID3D11BlendState_Release(d3d11GraphicsPipeline->colorAttachmentBlendState);
|
|
|
|
|
ID3D11DepthStencilState_Release(d3d11GraphicsPipeline->depthStencilState);
|
|
|
|
|
ID3D11RasterizerState_Release(d3d11GraphicsPipeline->rasterizerState);
|
2023-10-11 02:45:32 +00:00
|
|
|
|
|
2024-02-09 06:35:19 +00:00
|
|
|
|
if (d3d11GraphicsPipeline->inputLayout)
|
2024-02-07 03:48:16 +00:00
|
|
|
|
{
|
2024-02-09 06:35:19 +00:00
|
|
|
|
ID3D11InputLayout_Release(d3d11GraphicsPipeline->inputLayout);
|
2024-02-07 03:48:16 +00:00
|
|
|
|
}
|
2024-02-09 06:35:19 +00:00
|
|
|
|
if (d3d11GraphicsPipeline->vertexStrides)
|
2023-10-13 02:31:04 +00:00
|
|
|
|
{
|
2024-02-09 06:35:19 +00:00
|
|
|
|
SDL_free(d3d11GraphicsPipeline->vertexStrides);
|
2023-10-13 02:31:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 06:35:19 +00:00
|
|
|
|
SDL_free(d3d11GraphicsPipeline);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Graphics State */
|
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
static void D3D11_INTERNAL_AllocateCommandBuffers(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
uint32_t allocateCount
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2023-10-08 21:05:33 +00:00
|
|
|
|
D3D11CommandBuffer *commandBuffer;
|
2023-09-25 02:29:11 +00:00
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->availableCommandBufferCapacity += allocateCount;
|
2023-09-25 02:29:11 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->availableCommandBuffers = SDL_realloc(
|
|
|
|
|
renderer->availableCommandBuffers,
|
|
|
|
|
sizeof(D3D11CommandBuffer*) * renderer->availableCommandBufferCapacity
|
2023-10-08 21:05:33 +00:00
|
|
|
|
);
|
2023-09-25 02:29:11 +00:00
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
for (uint32_t i = 0; i < allocateCount; i += 1)
|
2023-09-25 02:29:11 +00:00
|
|
|
|
{
|
2023-10-08 21:05:33 +00:00
|
|
|
|
commandBuffer = SDL_malloc(sizeof(D3D11CommandBuffer));
|
2023-09-25 02:29:11 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Deferred Device Context */
|
2023-11-06 01:20:37 +00:00
|
|
|
|
res = ID3D11Device1_CreateDeferredContext1(
|
2023-09-25 02:29:11 +00:00
|
|
|
|
renderer->device,
|
|
|
|
|
0,
|
2023-10-08 21:05:33 +00:00
|
|
|
|
&commandBuffer->context
|
2023-09-25 02:29:11 +00:00
|
|
|
|
);
|
2023-10-27 01:37:27 +00:00
|
|
|
|
ERROR_CHECK("Could not create deferred context");
|
2023-10-08 21:05:33 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Bound Uniform Buffers */
|
|
|
|
|
commandBuffer->boundUniformBufferCapacity = 16;
|
|
|
|
|
commandBuffer->boundUniformBufferCount = 0;
|
|
|
|
|
commandBuffer->boundUniformBuffers = SDL_malloc(
|
|
|
|
|
commandBuffer->boundUniformBufferCapacity * sizeof(D3D11UniformBuffer*)
|
|
|
|
|
);
|
|
|
|
|
|
2024-03-03 19:27:48 +00:00
|
|
|
|
/* Reference Counting */
|
|
|
|
|
commandBuffer->usedTransferBufferCapacity = 4;
|
|
|
|
|
commandBuffer->usedTransferBufferCount = 0;
|
|
|
|
|
commandBuffer->usedTransferBuffers = SDL_malloc(
|
|
|
|
|
commandBuffer->usedTransferBufferCapacity * sizeof(D3D11TransferBuffer*)
|
|
|
|
|
);
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
|
|
|
|
|
renderer->availableCommandBufferCount += 1;
|
2023-09-25 02:29:11 +00:00
|
|
|
|
}
|
2023-10-08 21:05:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static D3D11CommandBuffer* D3D11_INTERNAL_GetInactiveCommandBufferFromPool(
|
|
|
|
|
D3D11Renderer *renderer
|
|
|
|
|
) {
|
|
|
|
|
D3D11CommandBuffer *commandBuffer;
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
if (renderer->availableCommandBufferCount == 0)
|
2023-10-08 21:05:33 +00:00
|
|
|
|
{
|
|
|
|
|
D3D11_INTERNAL_AllocateCommandBuffers(
|
|
|
|
|
renderer,
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->availableCommandBufferCapacity
|
2023-10-08 21:05:33 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
commandBuffer = renderer->availableCommandBuffers[renderer->availableCommandBufferCount - 1];
|
|
|
|
|
renderer->availableCommandBufferCount -= 1;
|
2023-10-08 21:05:33 +00:00
|
|
|
|
|
|
|
|
|
return commandBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
static uint8_t D3D11_INTERNAL_CreateFence(
|
|
|
|
|
D3D11Renderer *renderer
|
2024-02-09 04:53:36 +00:00
|
|
|
|
) {
|
|
|
|
|
D3D11_QUERY_DESC queryDesc;
|
2024-02-09 05:59:13 +00:00
|
|
|
|
ID3D11Query *queryHandle;
|
|
|
|
|
D3D11Fence* fence;
|
2024-02-09 04:53:36 +00:00
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
queryDesc.Query = D3D11_QUERY_EVENT;
|
|
|
|
|
queryDesc.MiscFlags = 0;
|
|
|
|
|
res = ID3D11Device_CreateQuery(
|
|
|
|
|
renderer->device,
|
|
|
|
|
&queryDesc,
|
|
|
|
|
&queryHandle
|
2024-02-09 04:53:36 +00:00
|
|
|
|
);
|
2024-02-09 05:59:13 +00:00
|
|
|
|
ERROR_CHECK_RETURN("Could not create query", 0);
|
2024-02-09 04:53:36 +00:00
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
fence = SDL_malloc(sizeof(D3D11Fence));
|
|
|
|
|
fence->handle = queryHandle;
|
|
|
|
|
|
|
|
|
|
/* Add it to the available pool */
|
|
|
|
|
if (renderer->availableFenceCount >= renderer->availableFenceCapacity)
|
2024-02-09 04:53:36 +00:00
|
|
|
|
{
|
2024-02-09 05:59:13 +00:00
|
|
|
|
renderer->availableFenceCapacity *= 2;
|
2024-02-09 04:53:36 +00:00
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
renderer->availableFences = SDL_realloc(
|
|
|
|
|
renderer->availableFences,
|
|
|
|
|
sizeof(D3D11Fence*) * renderer->availableFenceCapacity
|
2024-02-09 04:53:36 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
2024-02-09 05:59:13 +00:00
|
|
|
|
|
|
|
|
|
renderer->availableFences[renderer->availableFenceCount] = fence;
|
|
|
|
|
renderer->availableFenceCount += 1;
|
|
|
|
|
|
|
|
|
|
return 1;
|
2024-02-09 04:53:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
static uint8_t D3D11_INTERNAL_AcquireFence(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
D3D11CommandBuffer *commandBuffer
|
2024-02-09 04:53:36 +00:00
|
|
|
|
) {
|
|
|
|
|
D3D11Fence *fence;
|
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
/* Acquire a fence from the pool */
|
|
|
|
|
SDL_LockMutex(renderer->fenceLock);
|
2024-02-09 04:53:36 +00:00
|
|
|
|
|
|
|
|
|
if (renderer->availableFenceCount == 0)
|
|
|
|
|
{
|
2024-02-09 05:59:13 +00:00
|
|
|
|
if (!D3D11_INTERNAL_CreateFence(renderer))
|
|
|
|
|
{
|
|
|
|
|
SDL_UnlockMutex(renderer->fenceLock);
|
|
|
|
|
Refresh_LogError("Failed to create fence!");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2024-02-09 04:53:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fence = renderer->availableFences[renderer->availableFenceCount - 1];
|
|
|
|
|
renderer->availableFenceCount -= 1;
|
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->fenceLock);
|
2024-02-09 04:53:36 +00:00
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
/* Associate the fence with the command buffer */
|
|
|
|
|
commandBuffer->fence = fence;
|
|
|
|
|
|
|
|
|
|
return 1;
|
2024-02-09 04:53:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
|
|
|
|
|
Refresh_Renderer *driverData
|
|
|
|
|
) {
|
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *commandBuffer;
|
|
|
|
|
|
|
|
|
|
SDL_LockMutex(renderer->acquireCommandBufferLock);
|
2023-09-25 02:29:11 +00:00
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
commandBuffer = D3D11_INTERNAL_GetInactiveCommandBufferFromPool(renderer);
|
2024-02-11 04:18:25 +00:00
|
|
|
|
commandBuffer->windowData = NULL;
|
2023-10-11 02:45:32 +00:00
|
|
|
|
commandBuffer->graphicsPipeline = NULL;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
commandBuffer->computePipeline = NULL;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
commandBuffer->vertexUniformBuffer = NULL;
|
2023-11-06 01:20:37 +00:00
|
|
|
|
commandBuffer->fragmentUniformBuffer = NULL;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
commandBuffer->computeUniformBuffer = NULL;
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
|
2023-09-25 02:29:11 +00:00
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
commandBuffer->colorTargetResolveTexture[i] = NULL;
|
|
|
|
|
commandBuffer->colorTargetResolveSubresourceIndex[i] = 0;
|
|
|
|
|
commandBuffer->colorTargetMsaaHandle[i] = NULL;
|
2023-09-25 02:29:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 05:59:13 +00:00
|
|
|
|
D3D11_INTERNAL_AcquireFence(renderer, commandBuffer);
|
2024-02-09 06:31:54 +00:00
|
|
|
|
commandBuffer->autoReleaseFence = 1;
|
2024-02-09 04:53:36 +00:00
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
|
2023-09-25 02:29:11 +00:00
|
|
|
|
|
|
|
|
|
return (Refresh_CommandBuffer*) commandBuffer;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_BeginRenderPass(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_ColorAttachmentInfo *colorAttachmentInfos,
|
|
|
|
|
uint32_t colorAttachmentCount,
|
|
|
|
|
Refresh_DepthStencilAttachmentInfo *depthStencilAttachmentInfo
|
|
|
|
|
) {
|
2023-09-28 02:01:45 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-02-10 05:56:36 +00:00
|
|
|
|
ID3D11RenderTargetView* rtvs[MAX_COLOR_TARGET_BINDINGS];
|
|
|
|
|
ID3D11DepthStencilView *dsv = NULL;
|
2024-02-09 22:37:08 +00:00
|
|
|
|
uint32_t vpWidth = UINT_MAX;
|
|
|
|
|
uint32_t vpHeight = UINT_MAX;
|
2023-09-28 02:01:45 +00:00
|
|
|
|
D3D11_VIEWPORT viewport;
|
|
|
|
|
D3D11_RECT scissorRect;
|
|
|
|
|
|
2024-02-10 05:56:36 +00:00
|
|
|
|
/* Clear the bound targets for the current command buffer */
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
|
2023-09-28 02:01:45 +00:00
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
d3d11CommandBuffer->colorTargetResolveTexture[i] = NULL;
|
|
|
|
|
d3d11CommandBuffer->colorTargetResolveSubresourceIndex[i] = 0;
|
|
|
|
|
d3d11CommandBuffer->colorTargetMsaaHandle[i] = NULL;
|
2023-09-28 02:01:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-10 05:56:36 +00:00
|
|
|
|
/* Set up the new color target bindings */
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < colorAttachmentCount; i += 1)
|
2023-09-28 02:01:45 +00:00
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
D3D11Texture *texture = (D3D11Texture*) colorAttachmentInfos[i].textureSlice.texture;
|
2024-02-10 05:56:36 +00:00
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
uint32_t subresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
colorAttachmentInfos[i].textureSlice.mipLevel,
|
|
|
|
|
colorAttachmentInfos[i].textureSlice.layer,
|
|
|
|
|
texture->levelCount
|
2024-02-09 21:28:08 +00:00
|
|
|
|
);
|
2024-03-05 23:45:41 +00:00
|
|
|
|
rtvs[i] = texture->subresources[subresourceIndex].colorTargetView;
|
2024-03-05 20:27:38 +00:00
|
|
|
|
|
|
|
|
|
if (texture->subresources[subresourceIndex].msaaHandle != NULL)
|
|
|
|
|
{
|
|
|
|
|
d3d11CommandBuffer->colorTargetResolveTexture[i] = texture;
|
|
|
|
|
d3d11CommandBuffer->colorTargetResolveSubresourceIndex[i] = subresourceIndex;
|
|
|
|
|
d3d11CommandBuffer->colorTargetMsaaHandle[i] = texture->subresources[subresourceIndex].msaaHandle;
|
|
|
|
|
}
|
2023-09-28 02:01:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the DSV for the depth stencil attachment, if applicable */
|
|
|
|
|
if (depthStencilAttachmentInfo != NULL)
|
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
D3D11Texture *texture = (D3D11Texture*) depthStencilAttachmentInfo->textureSlice.texture;
|
2024-02-10 05:56:36 +00:00
|
|
|
|
|
2024-03-05 20:27:38 +00:00
|
|
|
|
uint32_t subresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
depthStencilAttachmentInfo->textureSlice.mipLevel,
|
|
|
|
|
depthStencilAttachmentInfo->textureSlice.layer,
|
|
|
|
|
texture->levelCount
|
2024-02-09 22:03:57 +00:00
|
|
|
|
);
|
2024-03-05 20:27:38 +00:00
|
|
|
|
|
2024-03-05 23:45:41 +00:00
|
|
|
|
dsv = texture->subresources[subresourceIndex].depthStencilTargetView;
|
2023-09-28 02:01:45 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Actually set the RTs */
|
|
|
|
|
ID3D11DeviceContext_OMSetRenderTargets(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
colorAttachmentCount,
|
2024-02-10 05:56:36 +00:00
|
|
|
|
rtvs,
|
|
|
|
|
dsv
|
2023-09-28 02:01:45 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* Perform load ops on the RTs */
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < colorAttachmentCount; i += 1)
|
2023-09-28 02:01:45 +00:00
|
|
|
|
{
|
|
|
|
|
if (colorAttachmentInfos[i].loadOp == REFRESH_LOADOP_CLEAR)
|
|
|
|
|
{
|
2024-02-10 05:56:36 +00:00
|
|
|
|
float clearColors[] =
|
|
|
|
|
{
|
|
|
|
|
colorAttachmentInfos[i].clearColor.x,
|
|
|
|
|
colorAttachmentInfos[i].clearColor.y,
|
|
|
|
|
colorAttachmentInfos[i].clearColor.z,
|
|
|
|
|
colorAttachmentInfos[i].clearColor.w
|
|
|
|
|
};
|
2023-09-28 02:01:45 +00:00
|
|
|
|
ID3D11DeviceContext_ClearRenderTargetView(
|
|
|
|
|
d3d11CommandBuffer->context,
|
2024-02-10 05:56:36 +00:00
|
|
|
|
rtvs[i],
|
2023-09-28 02:01:45 +00:00
|
|
|
|
clearColors
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-10 05:56:36 +00:00
|
|
|
|
if (depthStencilAttachmentInfo != NULL)
|
2023-09-28 02:01:45 +00:00
|
|
|
|
{
|
2024-02-10 05:56:36 +00:00
|
|
|
|
D3D11_CLEAR_FLAG dsClearFlags = 0;
|
2023-09-28 02:01:45 +00:00
|
|
|
|
if (depthStencilAttachmentInfo->loadOp == REFRESH_LOADOP_CLEAR)
|
|
|
|
|
{
|
|
|
|
|
dsClearFlags |= D3D11_CLEAR_DEPTH;
|
|
|
|
|
}
|
|
|
|
|
if (depthStencilAttachmentInfo->stencilLoadOp == REFRESH_LOADOP_CLEAR)
|
|
|
|
|
{
|
|
|
|
|
dsClearFlags |= D3D11_CLEAR_STENCIL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dsClearFlags != 0)
|
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceContext_ClearDepthStencilView(
|
|
|
|
|
d3d11CommandBuffer->context,
|
2024-02-10 05:56:36 +00:00
|
|
|
|
dsv,
|
2023-09-28 02:01:45 +00:00
|
|
|
|
dsClearFlags,
|
|
|
|
|
depthStencilAttachmentInfo->depthStencilClearValue.depth,
|
|
|
|
|
(uint8_t) depthStencilAttachmentInfo->depthStencilClearValue.stencil
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 22:37:08 +00:00
|
|
|
|
/* The viewport cannot be larger than the smallest attachment. */
|
|
|
|
|
for (uint32_t i = 0; i < colorAttachmentCount; i += 1)
|
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
D3D11Texture *texture = (D3D11Texture*) colorAttachmentInfos[i].textureSlice.texture;
|
|
|
|
|
uint32_t w = texture->width >> colorAttachmentInfos[i].textureSlice.mipLevel;
|
|
|
|
|
uint32_t h = texture->height >> colorAttachmentInfos[i].textureSlice.mipLevel;
|
2024-02-09 22:37:08 +00:00
|
|
|
|
|
|
|
|
|
if (w < vpWidth)
|
|
|
|
|
{
|
|
|
|
|
vpWidth = w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (h < vpHeight)
|
|
|
|
|
{
|
|
|
|
|
vpHeight = h;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (depthStencilAttachmentInfo != NULL)
|
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
D3D11Texture *texture = (D3D11Texture*) depthStencilAttachmentInfo->textureSlice.texture;
|
|
|
|
|
uint32_t w = texture->width >> depthStencilAttachmentInfo->textureSlice.mipLevel;
|
|
|
|
|
uint32_t h = texture->height >> depthStencilAttachmentInfo->textureSlice.mipLevel;
|
2024-02-09 22:37:08 +00:00
|
|
|
|
|
|
|
|
|
if (w < vpWidth)
|
|
|
|
|
{
|
|
|
|
|
vpWidth = w;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (h < vpHeight)
|
|
|
|
|
{
|
|
|
|
|
vpHeight = h;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-28 02:01:45 +00:00
|
|
|
|
/* Set default viewport and scissor state */
|
|
|
|
|
viewport.TopLeftX = 0;
|
|
|
|
|
viewport.TopLeftY = 0;
|
2024-02-09 22:37:08 +00:00
|
|
|
|
viewport.Width = (FLOAT) vpWidth;
|
|
|
|
|
viewport.Height = (FLOAT) vpHeight;
|
2023-09-28 02:01:45 +00:00
|
|
|
|
viewport.MinDepth = 0;
|
|
|
|
|
viewport.MaxDepth = 1;
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_RSSetViewports(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
1,
|
|
|
|
|
&viewport
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
scissorRect.left = 0;
|
|
|
|
|
scissorRect.right = (LONG) viewport.Width;
|
|
|
|
|
scissorRect.top = 0;
|
|
|
|
|
scissorRect.bottom = (LONG) viewport.Height;
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_RSSetScissorRects(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
1,
|
|
|
|
|
&scissorRect
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_EndRenderPass(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
|
|
|
|
|
d3d11CommandBuffer->vertexUniformBuffer = NULL;
|
|
|
|
|
d3d11CommandBuffer->fragmentUniformBuffer = NULL;
|
2024-02-09 05:47:25 +00:00
|
|
|
|
d3d11CommandBuffer->computeUniformBuffer = NULL;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
|
2024-02-10 05:56:36 +00:00
|
|
|
|
/* Resolve MSAA color render targets */
|
|
|
|
|
for (uint32_t i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
|
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
if (d3d11CommandBuffer->colorTargetMsaaHandle[i] != NULL)
|
2024-02-10 05:56:36 +00:00
|
|
|
|
{
|
|
|
|
|
ID3D11DeviceContext_ResolveSubresource(
|
|
|
|
|
d3d11CommandBuffer->context,
|
2024-03-05 20:27:38 +00:00
|
|
|
|
d3d11CommandBuffer->colorTargetResolveTexture[i]->handle,
|
|
|
|
|
d3d11CommandBuffer->colorTargetResolveSubresourceIndex[i],
|
|
|
|
|
d3d11CommandBuffer->colorTargetMsaaHandle[i],
|
2024-02-10 05:56:36 +00:00
|
|
|
|
0,
|
2024-03-05 20:27:38 +00:00
|
|
|
|
RefreshToD3D11_TextureFormat[d3d11CommandBuffer->colorTargetResolveTexture[i]->format]
|
2024-02-10 05:56:36 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_BindGraphicsPipeline(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_GraphicsPipeline *graphicsPipeline
|
|
|
|
|
) {
|
2023-10-11 02:45:32 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2023-10-12 13:18:39 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2023-10-11 02:45:32 +00:00
|
|
|
|
D3D11GraphicsPipeline *pipeline = (D3D11GraphicsPipeline*) graphicsPipeline;
|
|
|
|
|
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->graphicsPipeline = pipeline;
|
2023-10-11 02:45:32 +00:00
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
if (pipeline->vertexUniformBlockSize == 0)
|
|
|
|
|
{
|
|
|
|
|
d3d11CommandBuffer->vertexUniformBuffer = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-09 05:47:25 +00:00
|
|
|
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer,
|
|
|
|
|
d3d11CommandBuffer,
|
2024-02-09 05:47:25 +00:00
|
|
|
|
&d3d11CommandBuffer->vertexUniformBuffer,
|
|
|
|
|
pipeline->vertexUniformBlockSize
|
2023-11-05 20:17:23 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pipeline->fragmentUniformBlockSize == 0)
|
|
|
|
|
{
|
|
|
|
|
d3d11CommandBuffer->fragmentUniformBuffer = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-09 05:47:25 +00:00
|
|
|
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer,
|
2024-02-09 05:47:25 +00:00
|
|
|
|
d3d11CommandBuffer,
|
|
|
|
|
&d3d11CommandBuffer->fragmentUniformBuffer,
|
2023-11-05 20:17:23 +00:00
|
|
|
|
pipeline->fragmentUniformBlockSize
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-11 02:45:32 +00:00
|
|
|
|
ID3D11DeviceContext_OMSetBlendState(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->colorAttachmentBlendState,
|
|
|
|
|
pipeline->blendConstants,
|
|
|
|
|
pipeline->multisampleState.sampleMask
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_OMSetDepthStencilState(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->depthStencilState,
|
|
|
|
|
pipeline->stencilRef
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_IASetPrimitiveTopology(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
RefreshToD3D11_PrimitiveType[pipeline->primitiveType]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_IASetInputLayout(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->inputLayout
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_RSSetState(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->rasterizerState
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_VSSetShader(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->vertexShader,
|
|
|
|
|
NULL,
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_PSSetShader(
|
2023-10-12 13:18:39 +00:00
|
|
|
|
d3d11CommandBuffer->context,
|
2023-10-11 02:45:32 +00:00
|
|
|
|
pipeline->fragmentShader,
|
|
|
|
|
NULL,
|
|
|
|
|
0
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_SetViewport(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_Viewport *viewport
|
|
|
|
|
) {
|
2023-10-12 13:18:53 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11_VIEWPORT vp =
|
|
|
|
|
{
|
|
|
|
|
viewport->x,
|
|
|
|
|
viewport->y,
|
|
|
|
|
viewport->w,
|
|
|
|
|
viewport->h,
|
|
|
|
|
viewport->minDepth,
|
|
|
|
|
viewport->maxDepth
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_RSSetViewports(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
1,
|
|
|
|
|
&vp
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_SetScissor(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_Rect *scissor
|
|
|
|
|
) {
|
2023-10-13 02:31:04 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2023-10-12 13:18:53 +00:00
|
|
|
|
D3D11_RECT rect =
|
|
|
|
|
{
|
|
|
|
|
scissor->x,
|
|
|
|
|
scissor->y,
|
|
|
|
|
scissor->x + scissor->w,
|
|
|
|
|
scissor->y + scissor->h
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_RSSetScissorRects(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
1,
|
|
|
|
|
&rect
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_BindVertexBuffers(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
uint32_t firstBinding,
|
|
|
|
|
uint32_t bindingCount,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
Refresh_BufferBinding *pBindings
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2023-10-13 02:31:04 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
ID3D11Buffer *bufferHandles[MAX_BUFFER_BINDINGS];
|
2024-03-05 02:01:37 +00:00
|
|
|
|
UINT bufferOffsets[MAX_BUFFER_BINDINGS];
|
2023-10-13 02:31:04 +00:00
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < bindingCount; i += 1)
|
|
|
|
|
{
|
2024-03-05 02:01:37 +00:00
|
|
|
|
bufferHandles[i] = ((D3D11Buffer*) pBindings[i].gpuBuffer)->handle;
|
|
|
|
|
bufferOffsets[i] = pBindings[i].offset;
|
2023-10-13 02:31:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_IASetVertexBuffers(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
firstBinding,
|
|
|
|
|
bindingCount,
|
|
|
|
|
bufferHandles,
|
|
|
|
|
&d3d11CommandBuffer->graphicsPipeline->vertexStrides[firstBinding],
|
2024-03-05 02:01:37 +00:00
|
|
|
|
bufferOffsets
|
2023-10-13 02:31:04 +00:00
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_BindIndexBuffer(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
Refresh_BufferBinding *pBinding,
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_IndexElementSize indexElementSize
|
|
|
|
|
) {
|
2023-10-27 02:25:03 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-03-05 02:01:37 +00:00
|
|
|
|
D3D11Buffer *d3d11Buffer = (D3D11Buffer*) pBinding->gpuBuffer;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_IASetIndexBuffer(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
d3d11Buffer->handle,
|
|
|
|
|
RefreshToD3D11_IndexType[indexElementSize],
|
2024-03-05 02:01:37 +00:00
|
|
|
|
(UINT) pBinding->offset
|
2023-10-27 02:25:03 +00:00
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Compute State */
|
|
|
|
|
|
2024-03-05 22:55:53 +00:00
|
|
|
|
static void D3D11_BeginComputePass(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
|
|
|
|
/* no-op */
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static void D3D11_BindComputePipeline(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
Refresh_ComputePipeline *computePipeline
|
|
|
|
|
) {
|
2024-02-08 03:03:21 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11ComputePipeline *pipeline = (D3D11ComputePipeline*) computePipeline;
|
|
|
|
|
|
|
|
|
|
d3d11CommandBuffer->computePipeline = pipeline;
|
|
|
|
|
|
|
|
|
|
if (pipeline->computeUniformBlockSize == 0)
|
|
|
|
|
{
|
|
|
|
|
d3d11CommandBuffer->computeUniformBuffer = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-09 05:47:25 +00:00
|
|
|
|
D3D11_INTERNAL_AcquireUniformBuffer(
|
2024-02-08 03:03:21 +00:00
|
|
|
|
renderer,
|
2024-02-09 05:47:25 +00:00
|
|
|
|
d3d11CommandBuffer,
|
|
|
|
|
&d3d11CommandBuffer->computeUniformBuffer,
|
2024-02-08 03:03:21 +00:00
|
|
|
|
pipeline->computeUniformBlockSize
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_CSSetShader(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
pipeline->computeShader,
|
|
|
|
|
NULL,
|
|
|
|
|
0
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
/* D3D11 can't discard when setting a UAV, so just ignore writeOption */
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static void D3D11_BindComputeBuffers(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
Refresh_ComputeBufferBinding *pBindings
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-02-08 03:03:21 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-02-11 03:49:19 +00:00
|
|
|
|
ID3D11UnorderedAccessView* uavs[MAX_BUFFER_BINDINGS];
|
2024-02-08 03:03:21 +00:00
|
|
|
|
|
|
|
|
|
int32_t numBuffers = d3d11CommandBuffer->computePipeline->numBuffers;
|
|
|
|
|
|
|
|
|
|
for (int32_t i = 0; i < numBuffers; i += 1)
|
|
|
|
|
{
|
2024-03-05 02:01:37 +00:00
|
|
|
|
uavs[i] = ((D3D11Buffer*) pBindings[i].gpuBuffer)->uav;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_CSSetUnorderedAccessViews(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
numBuffers,
|
|
|
|
|
uavs,
|
|
|
|
|
NULL
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 02:01:37 +00:00
|
|
|
|
/* D3D11 can't discard when setting a UAV, so just ignore writeOption */
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static void D3D11_BindComputeTextures(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
2024-03-05 02:01:37 +00:00
|
|
|
|
Refresh_ComputeTextureBinding *pBindings
|
2023-09-23 01:44:20 +00:00
|
|
|
|
) {
|
2024-02-08 03:03:21 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2024-02-11 03:49:19 +00:00
|
|
|
|
ID3D11UnorderedAccessView *uavs[MAX_TEXTURE_SAMPLERS];
|
2024-02-08 03:03:21 +00:00
|
|
|
|
|
|
|
|
|
int32_t numTextures = d3d11CommandBuffer->computePipeline->numTextures;
|
|
|
|
|
|
|
|
|
|
for (int32_t i = 0; i < numTextures; i += 1)
|
|
|
|
|
{
|
2024-03-05 20:27:38 +00:00
|
|
|
|
D3D11Texture *texture = ((D3D11Texture*) pBindings[i].textureSlice.texture);
|
|
|
|
|
uint32_t subresourceIndex = D3D11_INTERNAL_CalcSubresource(
|
|
|
|
|
pBindings[i].textureSlice.mipLevel,
|
|
|
|
|
pBindings[i].textureSlice.layer,
|
|
|
|
|
texture->levelCount
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
uavs[i] = texture->subresources[subresourceIndex].uav;
|
2024-02-08 03:03:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ID3D11DeviceContext_CSSetUnorderedAccessViews(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
numTextures,
|
|
|
|
|
uavs,
|
|
|
|
|
NULL
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 22:55:53 +00:00
|
|
|
|
static void D3D11_EndComputePass(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
|
|
|
|
/* no-op */
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Window and Swapchain Management */
|
|
|
|
|
|
2023-09-25 02:29:11 +00:00
|
|
|
|
static D3D11WindowData* D3D11_INTERNAL_FetchWindowData(
|
2023-09-25 02:20:04 +00:00
|
|
|
|
void *windowHandle
|
|
|
|
|
) {
|
2023-09-25 02:29:11 +00:00
|
|
|
|
return (D3D11WindowData*) SDL_GetWindowData(windowHandle, WINDOW_DATA);
|
2023-09-25 02:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 03:10:36 +00:00
|
|
|
|
static uint8_t D3D11_INTERNAL_InitializeSwapchainTexture(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
IDXGISwapChain *swapchain,
|
|
|
|
|
D3D11Texture *pTexture
|
|
|
|
|
) {
|
|
|
|
|
ID3D11Texture2D *swapchainTexture;
|
2024-03-06 04:58:34 +00:00
|
|
|
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
|
2024-03-05 22:55:53 +00:00
|
|
|
|
D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
D3D11_TEXTURE2D_DESC textureDesc;
|
2024-03-06 04:58:34 +00:00
|
|
|
|
ID3D11ShaderResourceView *srv;
|
2024-02-09 21:28:08 +00:00
|
|
|
|
ID3D11RenderTargetView *rtv;
|
2024-03-05 22:55:53 +00:00
|
|
|
|
ID3D11UnorderedAccessView *uav;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
/* Clear all the texture data */
|
|
|
|
|
SDL_zerop(pTexture);
|
|
|
|
|
|
|
|
|
|
/* Grab the buffer from the swapchain */
|
|
|
|
|
res = IDXGISwapChain_GetBuffer(
|
|
|
|
|
swapchain,
|
|
|
|
|
0,
|
|
|
|
|
&D3D_IID_ID3D11Texture2D,
|
|
|
|
|
(void**) &swapchainTexture
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not get buffer from swapchain!", 0);
|
|
|
|
|
|
2024-03-06 04:58:34 +00:00
|
|
|
|
/* Create the SRV for the swapchain */
|
|
|
|
|
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
|
|
|
|
srvDesc.Texture2D.MipLevels = 1;
|
|
|
|
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateShaderResourceView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
(ID3D11Resource *)swapchainTexture,
|
|
|
|
|
&srvDesc,
|
|
|
|
|
&srv
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
ID3D11Texture2D_Release(swapchainTexture);
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Swapchain SRV creation failed", res);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 03:10:36 +00:00
|
|
|
|
/* Create the RTV for the swapchain */
|
|
|
|
|
rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
|
|
|
rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
|
|
|
|
|
rtvDesc.Texture2D.MipSlice = 0;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateRenderTargetView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
(ID3D11Resource*) swapchainTexture,
|
|
|
|
|
&rtvDesc,
|
2024-02-09 21:28:08 +00:00
|
|
|
|
&rtv
|
2023-09-26 03:10:36 +00:00
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
2024-03-06 04:58:34 +00:00
|
|
|
|
ID3D11ShaderResourceView_Release(srv);
|
2023-09-26 03:10:36 +00:00
|
|
|
|
ID3D11Texture2D_Release(swapchainTexture);
|
2023-10-27 01:37:27 +00:00
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Swapchain RTV creation failed", res);
|
2023-09-26 03:10:36 +00:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-05 23:45:41 +00:00
|
|
|
|
uavDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
2024-03-05 22:55:53 +00:00
|
|
|
|
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
|
|
|
|
|
uavDesc.Texture2D.MipSlice = 0;
|
|
|
|
|
|
|
|
|
|
res = ID3D11Device_CreateUnorderedAccessView(
|
|
|
|
|
renderer->device,
|
|
|
|
|
(ID3D11Resource *)swapchainTexture,
|
|
|
|
|
&uavDesc,
|
|
|
|
|
&uav
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
2024-03-06 04:58:34 +00:00
|
|
|
|
ID3D11ShaderResourceView_Release(srv);
|
2024-03-05 22:55:53 +00:00
|
|
|
|
ID3D11RenderTargetView_Release(rtv);
|
|
|
|
|
ID3D11Texture2D_Release(swapchainTexture);
|
|
|
|
|
D3D11_INTERNAL_LogError(renderer->device, "Swapchain UAV creation failed", res);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 21:28:08 +00:00
|
|
|
|
/* Fill out the texture struct */
|
2024-03-06 04:58:34 +00:00
|
|
|
|
pTexture->handle = NULL; /* This will be set in AcquireSwapchainTexture. */
|
|
|
|
|
pTexture->shaderView = srv;
|
2024-03-05 22:55:53 +00:00
|
|
|
|
pTexture->subresources = SDL_malloc(sizeof(D3D11TextureSubresource));
|
2024-03-05 23:45:41 +00:00
|
|
|
|
pTexture->subresources[0].colorTargetView = rtv;
|
2024-03-05 22:55:53 +00:00
|
|
|
|
pTexture->subresources[0].uav = uav;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
pTexture->subresources[0].depthStencilTargetView = NULL;
|
2024-03-05 22:55:53 +00:00
|
|
|
|
pTexture->subresources[0].msaaHandle = NULL;
|
|
|
|
|
pTexture->subresources[0].layer = 0;
|
|
|
|
|
pTexture->subresources[0].level = 0;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
|
|
|
|
|
ID3D11Texture2D_GetDesc(swapchainTexture, &textureDesc);
|
|
|
|
|
pTexture->levelCount = textureDesc.MipLevels;
|
2023-10-27 02:25:03 +00:00
|
|
|
|
pTexture->width = textureDesc.Width;
|
|
|
|
|
pTexture->height = textureDesc.Height;
|
2024-02-09 21:28:08 +00:00
|
|
|
|
pTexture->depth = 1;
|
|
|
|
|
pTexture->isCube = 0;
|
|
|
|
|
pTexture->isRenderTarget = 1;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
|
ID3D11Texture2D_Release(swapchainTexture);
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-25 02:20:04 +00:00
|
|
|
|
static uint8_t D3D11_INTERNAL_CreateSwapchain(
|
|
|
|
|
D3D11Renderer *renderer,
|
2024-02-10 23:07:56 +00:00
|
|
|
|
D3D11WindowData *windowData,
|
|
|
|
|
Refresh_PresentMode presentMode
|
2023-09-25 02:20:04 +00:00
|
|
|
|
) {
|
|
|
|
|
SDL_SysWMinfo info;
|
|
|
|
|
HWND dxgiHandle;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
int width, height;
|
2023-09-25 02:20:04 +00:00
|
|
|
|
DXGI_SWAP_CHAIN_DESC swapchainDesc;
|
|
|
|
|
IDXGIFactory1 *pParent;
|
|
|
|
|
IDXGISwapChain *swapchain;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
/* Get the DXGI handle */
|
|
|
|
|
SDL_VERSION(&info.version);
|
|
|
|
|
SDL_GetWindowWMInfo((SDL_Window*) windowData->windowHandle, &info);
|
|
|
|
|
dxgiHandle = info.info.win.window;
|
|
|
|
|
|
2023-09-26 03:10:36 +00:00
|
|
|
|
/* Get the window size */
|
|
|
|
|
SDL_GetWindowSize((SDL_Window*) windowData->windowHandle, &width, &height);
|
|
|
|
|
|
2023-09-25 02:20:04 +00:00
|
|
|
|
/* Initialize the swapchain buffer descriptor */
|
2023-09-26 02:24:01 +00:00
|
|
|
|
swapchainDesc.BufferDesc.Width = 0;
|
|
|
|
|
swapchainDesc.BufferDesc.Height = 0;
|
|
|
|
|
swapchainDesc.BufferDesc.RefreshRate.Numerator = 0;
|
|
|
|
|
swapchainDesc.BufferDesc.RefreshRate.Denominator = 0;
|
2024-03-05 23:45:41 +00:00
|
|
|
|
/* TODO: support different swapchain formats? */
|
2023-09-26 02:24:01 +00:00
|
|
|
|
swapchainDesc.BufferDesc.Format = RefreshToD3D11_TextureFormat[REFRESH_TEXTUREFORMAT_R8G8B8A8];
|
|
|
|
|
swapchainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
|
|
|
|
swapchainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
|
|
|
|
|
|
|
|
|
/* Initialize the rest of the swapchain descriptor */
|
2023-09-25 02:20:04 +00:00
|
|
|
|
swapchainDesc.SampleDesc.Count = 1;
|
|
|
|
|
swapchainDesc.SampleDesc.Quality = 0;
|
2024-03-06 04:58:34 +00:00
|
|
|
|
swapchainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_UNORDERED_ACCESS | DXGI_USAGE_SHADER_INPUT;
|
2024-02-10 23:07:56 +00:00
|
|
|
|
swapchainDesc.BufferCount = 2;
|
2023-09-25 02:20:04 +00:00
|
|
|
|
swapchainDesc.OutputWindow = dxgiHandle;
|
|
|
|
|
swapchainDesc.Windowed = 1;
|
2024-02-10 23:07:56 +00:00
|
|
|
|
|
|
|
|
|
if (renderer->supportsTearing)
|
|
|
|
|
{
|
|
|
|
|
swapchainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
2024-02-11 00:00:12 +00:00
|
|
|
|
/* We know this is supported because tearing support implies DXGI 1.5+ */
|
2024-02-10 23:07:56 +00:00
|
|
|
|
swapchainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
swapchainDesc.Flags = 0;
|
2024-02-11 00:00:12 +00:00
|
|
|
|
swapchainDesc.SwapEffect = (
|
|
|
|
|
renderer->supportsFlipDiscard ?
|
|
|
|
|
DXGI_SWAP_EFFECT_FLIP_DISCARD :
|
|
|
|
|
DXGI_SWAP_EFFECT_DISCARD
|
2024-02-10 23:07:56 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
2023-09-25 02:20:04 +00:00
|
|
|
|
|
|
|
|
|
/* Create the swapchain! */
|
|
|
|
|
res = IDXGIFactory1_CreateSwapChain(
|
|
|
|
|
(IDXGIFactory1*) renderer->factory,
|
|
|
|
|
(IUnknown*) renderer->device,
|
|
|
|
|
&swapchainDesc,
|
|
|
|
|
&swapchain
|
|
|
|
|
);
|
2024-02-11 00:00:12 +00:00
|
|
|
|
ERROR_CHECK_RETURN("Could not create swapchain", 0);
|
2023-09-25 02:20:04 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The swapchain's parent is a separate factory from the factory that
|
|
|
|
|
* we used to create the swapchain, and only that parent can be used to
|
|
|
|
|
* set the window association. Trying to set an association on our factory
|
|
|
|
|
* will silently fail and doesn't even verify arguments or return errors.
|
|
|
|
|
* See https://gamedev.net/forums/topic/634235-dxgidisabling-altenter/4999955/
|
|
|
|
|
*/
|
|
|
|
|
res = IDXGISwapChain_GetParent(
|
|
|
|
|
swapchain,
|
|
|
|
|
&D3D_IID_IDXGIFactory1,
|
2024-02-07 13:33:23 +00:00
|
|
|
|
(void**) &pParent
|
2023-09-25 02:20:04 +00:00
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn(
|
|
|
|
|
"Could not get swapchain parent! Error Code: %08X",
|
|
|
|
|
res
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Disable DXGI window crap */
|
|
|
|
|
res = IDXGIFactory1_MakeWindowAssociation(
|
|
|
|
|
pParent,
|
|
|
|
|
dxgiHandle,
|
|
|
|
|
DXGI_MWA_NO_WINDOW_CHANGES
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn(
|
|
|
|
|
"MakeWindowAssociation failed! Error Code: %08X",
|
|
|
|
|
res
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-02-07 13:33:23 +00:00
|
|
|
|
|
|
|
|
|
/* We're done with the parent now */
|
|
|
|
|
IDXGIFactory1_Release(pParent);
|
2023-09-25 02:20:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-11 04:18:25 +00:00
|
|
|
|
/* Initialize the swapchain data */
|
|
|
|
|
windowData->swapchain = swapchain;
|
|
|
|
|
windowData->presentMode = presentMode;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
|
|
|
|
|
if (!D3D11_INTERNAL_InitializeSwapchainTexture(
|
|
|
|
|
renderer,
|
|
|
|
|
swapchain,
|
2024-02-11 04:18:25 +00:00
|
|
|
|
&windowData->texture
|
2023-09-26 03:10:36 +00:00
|
|
|
|
)) {
|
|
|
|
|
IDXGISwapChain_Release(swapchain);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-25 02:20:04 +00:00
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 03:10:36 +00:00
|
|
|
|
static uint8_t D3D11_INTERNAL_ResizeSwapchain(
|
|
|
|
|
D3D11Renderer *renderer,
|
2024-02-11 04:18:25 +00:00
|
|
|
|
D3D11WindowData *windowData,
|
2023-09-26 03:10:36 +00:00
|
|
|
|
int32_t width,
|
|
|
|
|
int32_t height
|
|
|
|
|
) {
|
2024-03-05 22:55:53 +00:00
|
|
|
|
/* Release the old views */
|
2024-03-06 06:45:47 +00:00
|
|
|
|
ID3D11ShaderResourceView_Release(windowData->texture.shaderView);
|
2024-03-05 23:45:41 +00:00
|
|
|
|
ID3D11RenderTargetView_Release(windowData->texture.subresources[0].colorTargetView);
|
2024-03-05 22:55:53 +00:00
|
|
|
|
ID3D11UnorderedAccessView_Release(windowData->texture.subresources[0].uav);
|
|
|
|
|
SDL_free(windowData->texture.subresources);
|
2023-09-26 03:10:36 +00:00
|
|
|
|
|
|
|
|
|
/* Resize the swapchain */
|
2024-02-11 04:18:25 +00:00
|
|
|
|
HRESULT res = IDXGISwapChain_ResizeBuffers(
|
|
|
|
|
windowData->swapchain,
|
2024-02-10 23:07:56 +00:00
|
|
|
|
0, /* Keep buffer count the same */
|
2023-09-26 03:10:36 +00:00
|
|
|
|
width,
|
|
|
|
|
height,
|
2024-02-10 23:07:56 +00:00
|
|
|
|
DXGI_FORMAT_UNKNOWN, /* Keep the old format */
|
|
|
|
|
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0
|
2023-09-26 03:10:36 +00:00
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not resize swapchain buffers", 0);
|
|
|
|
|
|
|
|
|
|
/* Create the Refresh-side texture for the swapchain */
|
|
|
|
|
return D3D11_INTERNAL_InitializeSwapchainTexture(
|
|
|
|
|
renderer,
|
2024-02-11 04:18:25 +00:00
|
|
|
|
windowData->swapchain,
|
|
|
|
|
&windowData->texture
|
2023-09-26 03:10:36 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static uint8_t D3D11_ClaimWindow(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
void *windowHandle,
|
|
|
|
|
Refresh_PresentMode presentMode
|
|
|
|
|
) {
|
2023-09-25 02:20:04 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2023-09-25 02:29:11 +00:00
|
|
|
|
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle);
|
2023-09-25 02:20:04 +00:00
|
|
|
|
|
|
|
|
|
if (windowData == NULL)
|
|
|
|
|
{
|
2023-09-25 02:29:11 +00:00
|
|
|
|
windowData = (D3D11WindowData*) SDL_malloc(sizeof(D3D11WindowData));
|
2023-09-25 02:20:04 +00:00
|
|
|
|
windowData->windowHandle = windowHandle;
|
|
|
|
|
|
2024-02-10 23:07:56 +00:00
|
|
|
|
if (D3D11_INTERNAL_CreateSwapchain(renderer, windowData, presentMode))
|
2023-09-25 02:20:04 +00:00
|
|
|
|
{
|
|
|
|
|
SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_DATA, windowData);
|
|
|
|
|
|
2024-02-11 04:18:25 +00:00
|
|
|
|
SDL_LockMutex(renderer->windowLock);
|
|
|
|
|
|
2023-09-25 02:20:04 +00:00
|
|
|
|
if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity)
|
|
|
|
|
{
|
|
|
|
|
renderer->claimedWindowCapacity *= 2;
|
|
|
|
|
renderer->claimedWindows = SDL_realloc(
|
|
|
|
|
renderer->claimedWindows,
|
2023-09-25 02:29:11 +00:00
|
|
|
|
renderer->claimedWindowCapacity * sizeof(D3D11WindowData*)
|
2023-09-25 02:20:04 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
renderer->claimedWindows[renderer->claimedWindowCount] = windowData;
|
|
|
|
|
renderer->claimedWindowCount += 1;
|
|
|
|
|
|
2024-02-11 04:18:25 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->windowLock);
|
|
|
|
|
|
2023-09-25 02:20:04 +00:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogError("Could not create swapchain, failed to claim window!");
|
|
|
|
|
SDL_free(windowData);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("Window already claimed!");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-28 02:12:28 +00:00
|
|
|
|
static void D3D11_UnclaimWindow(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
void *windowHandle
|
|
|
|
|
) {
|
2023-09-28 02:12:28 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle);
|
|
|
|
|
|
|
|
|
|
if (windowData == NULL)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-11 04:18:25 +00:00
|
|
|
|
D3D11_Wait(driverData);
|
|
|
|
|
|
2024-03-06 04:58:34 +00:00
|
|
|
|
ID3D11ShaderResourceView_Release(windowData->texture.shaderView);
|
2024-03-05 23:45:41 +00:00
|
|
|
|
ID3D11RenderTargetView_Release(windowData->texture.subresources[0].colorTargetView);
|
2024-03-05 22:55:53 +00:00
|
|
|
|
ID3D11UnorderedAccessView_Release(windowData->texture.subresources[0].uav);
|
|
|
|
|
SDL_free(windowData->texture.subresources);
|
2024-02-11 04:18:25 +00:00
|
|
|
|
IDXGISwapChain_Release(windowData->swapchain);
|
2023-09-28 02:12:28 +00:00
|
|
|
|
|
2024-02-11 04:18:25 +00:00
|
|
|
|
SDL_LockMutex(renderer->windowLock);
|
2024-02-09 05:47:25 +00:00
|
|
|
|
for (uint32_t i = 0; i < renderer->claimedWindowCount; i += 1)
|
2023-09-28 02:12:28 +00:00
|
|
|
|
{
|
|
|
|
|
if (renderer->claimedWindows[i]->windowHandle == windowHandle)
|
|
|
|
|
{
|
|
|
|
|
renderer->claimedWindows[i] = renderer->claimedWindows[renderer->claimedWindowCount - 1];
|
|
|
|
|
renderer->claimedWindowCount -= 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-11 04:18:25 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->windowLock);
|
2023-09-28 02:12:28 +00:00
|
|
|
|
|
|
|
|
|
SDL_free(windowData);
|
|
|
|
|
SDL_SetWindowData((SDL_Window*) windowHandle, WINDOW_DATA, NULL);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Refresh_Texture* D3D11_AcquireSwapchainTexture(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer,
|
|
|
|
|
void *windowHandle,
|
|
|
|
|
uint32_t *pWidth,
|
|
|
|
|
uint32_t *pHeight
|
|
|
|
|
) {
|
2023-09-26 03:10:36 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
2023-10-12 13:18:39 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
2023-09-30 01:52:14 +00:00
|
|
|
|
D3D11WindowData *windowData;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
DXGI_SWAP_CHAIN_DESC swapchainDesc;
|
|
|
|
|
int w, h;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2023-09-30 01:52:14 +00:00
|
|
|
|
windowData = D3D11_INTERNAL_FetchWindowData(windowHandle);
|
|
|
|
|
if (windowData == NULL)
|
|
|
|
|
{
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-26 03:10:36 +00:00
|
|
|
|
/* Check for window size changes and resize the swapchain if needed. */
|
2024-02-11 04:18:25 +00:00
|
|
|
|
IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc);
|
2023-09-26 03:10:36 +00:00
|
|
|
|
SDL_GetWindowSize((SDL_Window*) windowHandle, &w, &h);
|
|
|
|
|
|
|
|
|
|
if (w != swapchainDesc.BufferDesc.Width || h != swapchainDesc.BufferDesc.Height)
|
|
|
|
|
{
|
|
|
|
|
res = D3D11_INTERNAL_ResizeSwapchain(
|
|
|
|
|
renderer,
|
2024-02-11 04:18:25 +00:00
|
|
|
|
windowData,
|
2023-09-26 03:10:36 +00:00
|
|
|
|
w,
|
|
|
|
|
h
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not resize swapchain", NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-06 04:58:34 +00:00
|
|
|
|
/* Set the handle on the windowData texture data. */
|
|
|
|
|
res = IDXGISwapChain_GetBuffer(
|
|
|
|
|
windowData->swapchain,
|
|
|
|
|
0,
|
|
|
|
|
&D3D_IID_ID3D11Texture2D,
|
|
|
|
|
(void**) &windowData->texture.handle
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not acquire swapchain!", NULL);
|
|
|
|
|
|
2023-09-26 03:10:36 +00:00
|
|
|
|
/* Let the command buffer know it's associated with this swapchain. */
|
2024-02-11 04:18:25 +00:00
|
|
|
|
d3d11CommandBuffer->windowData = windowData;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
|
|
|
|
|
/* Send the dimensions to the out parameters. */
|
2024-02-11 04:18:25 +00:00
|
|
|
|
*pWidth = windowData->texture.width;
|
|
|
|
|
*pHeight = windowData->texture.height;
|
2023-09-26 03:10:36 +00:00
|
|
|
|
|
|
|
|
|
/* Return the swapchain texture */
|
2024-02-11 04:18:25 +00:00
|
|
|
|
return (Refresh_Texture*) &windowData->texture;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Refresh_TextureFormat D3D11_GetSwapchainFormat(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
void *windowHandle
|
|
|
|
|
) {
|
|
|
|
|
return REFRESH_TEXTUREFORMAT_R8G8B8A8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_SetSwapchainPresentMode(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
void *windowHandle,
|
|
|
|
|
Refresh_PresentMode presentMode
|
|
|
|
|
) {
|
2024-02-10 23:07:56 +00:00
|
|
|
|
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(windowHandle);
|
2024-02-11 04:18:25 +00:00
|
|
|
|
windowData->presentMode = presentMode;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Submission and Fences */
|
|
|
|
|
|
2024-02-09 06:31:54 +00:00
|
|
|
|
static void D3D11_INTERNAL_ReleaseFenceToPool(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
D3D11Fence *fence
|
|
|
|
|
) {
|
|
|
|
|
SDL_LockMutex(renderer->fenceLock);
|
|
|
|
|
|
|
|
|
|
if (renderer->availableFenceCount == renderer->availableFenceCapacity)
|
|
|
|
|
{
|
|
|
|
|
renderer->availableFenceCapacity *= 2;
|
|
|
|
|
renderer->availableFences = SDL_realloc(
|
|
|
|
|
renderer->availableFences,
|
|
|
|
|
renderer->availableFenceCapacity * sizeof(D3D11Fence*)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
renderer->availableFences[renderer->availableFenceCount] = fence;
|
|
|
|
|
renderer->availableFenceCount += 1;
|
|
|
|
|
|
|
|
|
|
SDL_UnlockMutex(renderer->fenceLock);
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
static void D3D11_INTERNAL_CleanCommandBuffer(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
D3D11CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Bound uniform buffers are now available */
|
|
|
|
|
SDL_LockMutex(renderer->uniformBufferLock);
|
|
|
|
|
for (uint32_t i = 0; i < commandBuffer->boundUniformBufferCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
if (renderer->availableUniformBufferCount == renderer->availableUniformBufferCapacity)
|
|
|
|
|
{
|
|
|
|
|
renderer->availableUniformBufferCapacity *= 2;
|
|
|
|
|
renderer->availableUniformBuffers = SDL_realloc(
|
|
|
|
|
renderer->availableUniformBuffers,
|
|
|
|
|
renderer->availableUniformBufferCapacity * sizeof(D3D11UniformBuffer*)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderer->availableUniformBuffers[renderer->availableUniformBufferCount] = commandBuffer->boundUniformBuffers[i];
|
|
|
|
|
renderer->availableUniformBufferCount += 1;
|
|
|
|
|
}
|
|
|
|
|
SDL_UnlockMutex(renderer->uniformBufferLock);
|
|
|
|
|
|
|
|
|
|
commandBuffer->boundUniformBufferCount = 0;
|
|
|
|
|
|
2024-03-03 19:27:48 +00:00
|
|
|
|
/* Reference Counting */
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < commandBuffer->usedTransferBufferCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
SDL_AtomicDecRef(&commandBuffer->usedTransferBuffers[i]->referenceCount);
|
|
|
|
|
}
|
|
|
|
|
commandBuffer->usedTransferBufferCount = 0;
|
|
|
|
|
|
2024-02-09 06:31:54 +00:00
|
|
|
|
/* The fence is now available (unless SubmitAndAcquireFence was called) */
|
|
|
|
|
if (commandBuffer->autoReleaseFence)
|
2024-02-09 04:53:36 +00:00
|
|
|
|
{
|
2024-02-09 06:31:54 +00:00
|
|
|
|
D3D11_INTERNAL_ReleaseFenceToPool(renderer, commandBuffer->fence);
|
2024-02-09 04:53:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Return command buffer to pool */
|
2023-10-08 21:05:33 +00:00
|
|
|
|
SDL_LockMutex(renderer->acquireCommandBufferLock);
|
2023-11-05 20:17:23 +00:00
|
|
|
|
if (renderer->availableCommandBufferCount == renderer->availableCommandBufferCapacity)
|
2023-10-08 21:05:33 +00:00
|
|
|
|
{
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->availableCommandBufferCapacity += 1;
|
|
|
|
|
renderer->availableCommandBuffers = SDL_realloc(
|
|
|
|
|
renderer->availableCommandBuffers,
|
|
|
|
|
renderer->availableCommandBufferCapacity * sizeof(D3D11CommandBuffer*)
|
2023-10-08 21:05:33 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
|
|
|
|
|
renderer->availableCommandBufferCount += 1;
|
2023-10-08 21:05:33 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
|
|
|
|
|
|
|
|
|
|
/* Remove this command buffer from the submitted list */
|
2023-11-05 20:17:23 +00:00
|
|
|
|
for (uint32_t i = 0; i < renderer->submittedCommandBufferCount; i += 1)
|
2023-10-08 21:05:33 +00:00
|
|
|
|
{
|
|
|
|
|
if (renderer->submittedCommandBuffers[i] == commandBuffer)
|
|
|
|
|
{
|
|
|
|
|
renderer->submittedCommandBuffers[i] = renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount - 1];
|
|
|
|
|
renderer->submittedCommandBufferCount -= 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-09 06:31:54 +00:00
|
|
|
|
static void D3D11_INTERNAL_WaitForFence(
|
|
|
|
|
D3D11Renderer *renderer,
|
|
|
|
|
D3D11Fence *fence
|
|
|
|
|
) {
|
|
|
|
|
BOOL queryData;
|
2024-02-11 03:49:19 +00:00
|
|
|
|
HRESULT res;
|
2024-02-09 06:31:54 +00:00
|
|
|
|
|
2024-02-11 03:49:19 +00:00
|
|
|
|
SDL_LockMutex(renderer->contextLock);
|
|
|
|
|
|
2024-02-11 06:40:48 +00:00
|
|
|
|
do
|
2024-02-11 03:49:19 +00:00
|
|
|
|
{
|
2024-02-11 06:40:48 +00:00
|
|
|
|
res = ID3D11DeviceContext_GetData(
|
|
|
|
|
renderer->immediateContext,
|
|
|
|
|
(ID3D11Asynchronous*)fence->handle,
|
|
|
|
|
&queryData,
|
|
|
|
|
sizeof(queryData),
|
|
|
|
|
0
|
|
|
|
|
);
|
2024-02-09 06:31:54 +00:00
|
|
|
|
}
|
2024-02-11 06:40:48 +00:00
|
|
|
|
while (res != S_OK); /* Spin until we get a result back... */
|
2024-02-11 03:49:19 +00:00
|
|
|
|
|
|
|
|
|
SDL_UnlockMutex(renderer->contextLock);
|
2024-02-09 06:31:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static void D3D11_Submit(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
2023-09-28 02:01:45 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
ID3D11CommandList *commandList;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
SDL_LockMutex(renderer->contextLock);
|
|
|
|
|
|
2023-10-08 21:16:11 +00:00
|
|
|
|
/* Notify the command buffer completion query that we have completed recording */
|
|
|
|
|
ID3D11DeviceContext_End(
|
|
|
|
|
renderer->immediateContext,
|
2024-02-09 04:53:36 +00:00
|
|
|
|
(ID3D11Asynchronous*) d3d11CommandBuffer->fence->handle
|
2023-10-08 21:16:11 +00:00
|
|
|
|
);
|
|
|
|
|
|
2023-09-28 02:01:45 +00:00
|
|
|
|
/* Serialize the commands into the command list */
|
|
|
|
|
res = ID3D11DeviceContext_FinishCommandList(
|
|
|
|
|
d3d11CommandBuffer->context,
|
|
|
|
|
0,
|
|
|
|
|
&commandList
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK("Could not finish command list recording!");
|
|
|
|
|
|
|
|
|
|
/* Submit the command list to the immediate context */
|
|
|
|
|
ID3D11DeviceContext_ExecuteCommandList(
|
|
|
|
|
renderer->immediateContext,
|
|
|
|
|
commandList,
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
ID3D11CommandList_Release(commandList);
|
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
/* Mark the command buffer as submitted */
|
2024-02-10 23:07:56 +00:00
|
|
|
|
if (renderer->submittedCommandBufferCount >= renderer->submittedCommandBufferCapacity)
|
2023-10-08 21:05:33 +00:00
|
|
|
|
{
|
|
|
|
|
renderer->submittedCommandBufferCapacity = renderer->submittedCommandBufferCount + 1;
|
|
|
|
|
|
|
|
|
|
renderer->submittedCommandBuffers = SDL_realloc(
|
|
|
|
|
renderer->submittedCommandBuffers,
|
|
|
|
|
sizeof(D3D11CommandBuffer*) * renderer->submittedCommandBufferCapacity
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount] = d3d11CommandBuffer;
|
|
|
|
|
renderer->submittedCommandBufferCount += 1;
|
|
|
|
|
|
2023-09-28 02:01:45 +00:00
|
|
|
|
/* Present, if applicable */
|
2024-02-11 04:18:25 +00:00
|
|
|
|
if (d3d11CommandBuffer->windowData)
|
2023-09-28 02:01:45 +00:00
|
|
|
|
{
|
2024-02-11 00:00:12 +00:00
|
|
|
|
/* FIXME: Is there some way to emulate FIFO_RELAXED? */
|
|
|
|
|
|
2024-02-10 23:07:56 +00:00
|
|
|
|
uint32_t syncInterval = 1;
|
2024-02-11 04:18:25 +00:00
|
|
|
|
if ( d3d11CommandBuffer->windowData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE ||
|
|
|
|
|
(renderer->supportsFlipDiscard && d3d11CommandBuffer->windowData->presentMode == REFRESH_PRESENTMODE_MAILBOX)
|
2024-02-11 00:00:12 +00:00
|
|
|
|
) {
|
2024-02-10 23:07:56 +00:00
|
|
|
|
syncInterval = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint32_t presentFlags = 0;
|
2024-02-11 04:18:25 +00:00
|
|
|
|
if ( renderer->supportsTearing &&
|
|
|
|
|
d3d11CommandBuffer->windowData->presentMode == REFRESH_PRESENTMODE_IMMEDIATE )
|
2024-02-11 00:00:12 +00:00
|
|
|
|
{
|
2024-02-10 23:07:56 +00:00
|
|
|
|
presentFlags = DXGI_PRESENT_ALLOW_TEARING;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-28 02:01:45 +00:00
|
|
|
|
IDXGISwapChain_Present(
|
2024-02-11 04:18:25 +00:00
|
|
|
|
d3d11CommandBuffer->windowData->swapchain,
|
2024-02-10 23:07:56 +00:00
|
|
|
|
syncInterval,
|
|
|
|
|
presentFlags
|
2023-09-28 02:01:45 +00:00
|
|
|
|
);
|
2024-03-06 04:58:34 +00:00
|
|
|
|
|
|
|
|
|
ID3D11Texture2D_Release(d3d11CommandBuffer->windowData->texture.handle);
|
2023-09-28 02:01:45 +00:00
|
|
|
|
}
|
2023-10-08 21:05:33 +00:00
|
|
|
|
|
2023-10-27 02:39:15 +00:00
|
|
|
|
/* Check if we can perform any cleanups */
|
|
|
|
|
for (int32_t i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1)
|
|
|
|
|
{
|
|
|
|
|
BOOL queryData;
|
|
|
|
|
res = ID3D11DeviceContext_GetData(
|
|
|
|
|
renderer->immediateContext,
|
2024-02-09 04:53:36 +00:00
|
|
|
|
(ID3D11Asynchronous*) renderer->submittedCommandBuffers[i]->fence->handle,
|
2023-10-27 02:39:15 +00:00
|
|
|
|
&queryData,
|
|
|
|
|
sizeof(queryData),
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
if (res == S_OK)
|
|
|
|
|
{
|
|
|
|
|
D3D11_INTERNAL_CleanCommandBuffer(
|
|
|
|
|
renderer,
|
|
|
|
|
renderer->submittedCommandBuffers[i]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-08 21:05:33 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->contextLock);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Refresh_Fence* D3D11_SubmitAndAcquireFence(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_CommandBuffer *commandBuffer
|
|
|
|
|
) {
|
2024-02-09 06:31:54 +00:00
|
|
|
|
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
|
|
|
|
|
D3D11Fence *fence = d3d11CommandBuffer->fence;
|
|
|
|
|
|
|
|
|
|
d3d11CommandBuffer->autoReleaseFence = 0;
|
|
|
|
|
D3D11_Submit(driverData, commandBuffer);
|
|
|
|
|
|
|
|
|
|
return (Refresh_Fence*) fence;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_Wait(
|
|
|
|
|
Refresh_Renderer *driverData
|
|
|
|
|
) {
|
2023-10-08 21:05:33 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11CommandBuffer *commandBuffer;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Wait for all submitted command buffers to complete.
|
|
|
|
|
* Sort of equivalent to vkDeviceWaitIdle.
|
|
|
|
|
*/
|
|
|
|
|
for (uint32_t i = 0; i < renderer->submittedCommandBufferCount; i += 1)
|
|
|
|
|
{
|
2024-02-09 06:31:54 +00:00
|
|
|
|
D3D11_INTERNAL_WaitForFence(
|
|
|
|
|
renderer,
|
|
|
|
|
renderer->submittedCommandBuffers[i]->fence
|
|
|
|
|
);
|
2023-10-08 21:05:33 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-11 03:49:19 +00:00
|
|
|
|
SDL_LockMutex(renderer->contextLock); /* This effectively acts as a lock around submittedCommandBuffers */
|
2023-10-08 21:05:33 +00:00
|
|
|
|
|
|
|
|
|
for (int32_t i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1)
|
|
|
|
|
{
|
|
|
|
|
commandBuffer = renderer->submittedCommandBuffers[i];
|
|
|
|
|
D3D11_INTERNAL_CleanCommandBuffer(renderer, commandBuffer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_UnlockMutex(renderer->contextLock);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_WaitForFences(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
uint8_t waitAll,
|
|
|
|
|
uint32_t fenceCount,
|
|
|
|
|
Refresh_Fence **pFences
|
|
|
|
|
) {
|
2024-02-09 06:31:54 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11Fence *fence;
|
|
|
|
|
BOOL queryData;
|
|
|
|
|
HRESULT res = S_FALSE;
|
|
|
|
|
|
|
|
|
|
if (waitAll)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
fence = (D3D11Fence*) pFences[i];
|
|
|
|
|
D3D11_INTERNAL_WaitForFence(renderer, fence);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-02-11 03:49:19 +00:00
|
|
|
|
SDL_LockMutex(renderer->contextLock);
|
|
|
|
|
|
2024-02-09 06:31:54 +00:00
|
|
|
|
while (res != S_OK)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; i += 1)
|
|
|
|
|
{
|
|
|
|
|
fence = (D3D11Fence*) pFences[i];
|
|
|
|
|
res = ID3D11DeviceContext_GetData(
|
|
|
|
|
renderer->immediateContext,
|
|
|
|
|
(ID3D11Asynchronous*) fence->handle,
|
|
|
|
|
&queryData,
|
|
|
|
|
sizeof(queryData),
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
if (res == S_OK)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-11 03:49:19 +00:00
|
|
|
|
|
|
|
|
|
SDL_UnlockMutex(renderer->contextLock);
|
2024-02-09 06:31:54 +00:00
|
|
|
|
}
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int D3D11_QueryFence(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_Fence *fence
|
|
|
|
|
) {
|
2024-02-09 06:31:54 +00:00
|
|
|
|
D3D11Renderer *renderer = (D3D11Renderer*) driverData;
|
|
|
|
|
D3D11Fence *d3d11Fence = (D3D11Fence*) fence;
|
|
|
|
|
BOOL queryData;
|
2024-02-11 03:49:19 +00:00
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
SDL_LockMutex(renderer->contextLock);
|
2024-02-09 06:31:54 +00:00
|
|
|
|
|
2024-02-11 03:49:19 +00:00
|
|
|
|
res = ID3D11DeviceContext_GetData(
|
2024-02-09 06:31:54 +00:00
|
|
|
|
renderer->immediateContext,
|
|
|
|
|
(ID3D11Asynchronous*) d3d11Fence->handle,
|
|
|
|
|
&queryData,
|
|
|
|
|
sizeof(queryData),
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
|
2024-02-11 03:49:19 +00:00
|
|
|
|
SDL_UnlockMutex(renderer->contextLock);
|
|
|
|
|
|
2024-02-09 06:31:54 +00:00
|
|
|
|
return res == S_OK;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void D3D11_ReleaseFence(
|
|
|
|
|
Refresh_Renderer *driverData,
|
|
|
|
|
Refresh_Fence *fence
|
|
|
|
|
) {
|
2024-02-09 06:31:54 +00:00
|
|
|
|
D3D11_INTERNAL_ReleaseFenceToPool(
|
|
|
|
|
(D3D11Renderer*) driverData,
|
|
|
|
|
(D3D11Fence*) fence
|
|
|
|
|
);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Device Creation */
|
|
|
|
|
|
|
|
|
|
static uint8_t D3D11_PrepareDriver(
|
|
|
|
|
uint32_t *flags
|
|
|
|
|
) {
|
2023-09-25 00:25:49 +00:00
|
|
|
|
void *d3d11_dll, *d3dcompiler_dll, *dxgi_dll;
|
|
|
|
|
PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc;
|
2024-02-07 15:09:30 +00:00
|
|
|
|
D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_1 };
|
2023-09-25 00:25:49 +00:00
|
|
|
|
PFN_D3DCOMPILE D3DCompileFunc;
|
|
|
|
|
PFN_CREATE_DXGI_FACTORY1 CreateDXGIFactoryFunc;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
/* Can we load D3D11? */
|
|
|
|
|
|
|
|
|
|
d3d11_dll = SDL_LoadObject(D3D11_DLL);
|
|
|
|
|
if (d3d11_dll == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11: Could not find " D3D11_DLL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
D3D11CreateDeviceFunc = (PFN_D3D11_CREATE_DEVICE) SDL_LoadFunction(
|
|
|
|
|
d3d11_dll,
|
|
|
|
|
D3D11_CREATE_DEVICE_FUNC
|
|
|
|
|
);
|
|
|
|
|
if (D3D11CreateDeviceFunc == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11: Could not find function " D3D11_CREATE_DEVICE_FUNC " in " D3D11_DLL);
|
|
|
|
|
SDL_UnloadObject(d3d11_dll);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Can we create a device? */
|
|
|
|
|
|
|
|
|
|
res = D3D11CreateDeviceFunc(
|
|
|
|
|
NULL,
|
|
|
|
|
D3D_DRIVER_TYPE_HARDWARE,
|
|
|
|
|
NULL,
|
|
|
|
|
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
|
|
|
|
|
levels,
|
|
|
|
|
SDL_arraysize(levels),
|
|
|
|
|
D3D11_SDK_VERSION,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL,
|
|
|
|
|
NULL
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
SDL_UnloadObject(d3d11_dll);
|
|
|
|
|
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11: Could not create D3D11Device with feature level 11_0");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Can we load D3DCompiler? */
|
|
|
|
|
|
|
|
|
|
d3dcompiler_dll = SDL_LoadObject(D3DCOMPILER_DLL);
|
|
|
|
|
if (d3dcompiler_dll == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11: Could not find " D3DCOMPILER_DLL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
D3DCompileFunc = (PFN_D3DCOMPILE) SDL_LoadFunction(
|
|
|
|
|
d3dcompiler_dll,
|
|
|
|
|
D3DCOMPILE_FUNC
|
|
|
|
|
);
|
|
|
|
|
SDL_UnloadObject(d3dcompiler_dll); /* We're not going to call this function, so we can just unload now. */
|
|
|
|
|
if (D3DCompileFunc == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11: Could not find function " D3DCOMPILE_FUNC " in " D3DCOMPILER_DLL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Can we load DXGI? */
|
|
|
|
|
|
|
|
|
|
dxgi_dll = SDL_LoadObject(DXGI_DLL);
|
|
|
|
|
if (dxgi_dll == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11: Could not find " DXGI_DLL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY1) SDL_LoadFunction(
|
|
|
|
|
dxgi_dll,
|
|
|
|
|
CREATE_DXGI_FACTORY1_FUNC
|
|
|
|
|
);
|
|
|
|
|
SDL_UnloadObject(dxgi_dll); /* We're not going to call this function, so we can just unload now. */
|
|
|
|
|
if (CreateDXGIFactoryFunc == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("D3D11: Could not find function " CREATE_DXGI_FACTORY1_FUNC " in " DXGI_DLL);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* No window flags required */
|
|
|
|
|
SDL_SetHint(SDL_HINT_VIDEO_EXTERNAL_CONTEXT, "1");
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-07 14:02:49 +00:00
|
|
|
|
static void D3D11_INTERNAL_TryInitializeDXGIDebug(D3D11Renderer *renderer)
|
|
|
|
|
{
|
|
|
|
|
PFN_DXGI_GET_DEBUG_INTERFACE DXGIGetDebugInterfaceFunc;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
|
|
|
|
|
renderer->dxgidebug_dll = SDL_LoadObject(DXGIDEBUG_DLL);
|
|
|
|
|
if (renderer->dxgidebug_dll == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("Could not find " DXGIDEBUG_DLL);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DXGIGetDebugInterfaceFunc = SDL_LoadFunction(
|
|
|
|
|
renderer->dxgidebug_dll,
|
|
|
|
|
DXGI_GET_DEBUG_INTERFACE_FUNC
|
|
|
|
|
);
|
|
|
|
|
if (DXGIGetDebugInterfaceFunc == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("Could not load function: " DXGI_GET_DEBUG_INTERFACE_FUNC);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIDebug, &renderer->dxgiDebug);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("Could not get IDXGIDebug interface");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res = DXGIGetDebugInterfaceFunc(&D3D_IID_IDXGIInfoQueue, &renderer->dxgiInfoQueue);
|
|
|
|
|
if (FAILED(res))
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogWarn("Could not get IDXGIInfoQueue interface");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
static Refresh_Device* D3D11_CreateDevice(
|
|
|
|
|
uint8_t debugMode
|
|
|
|
|
) {
|
|
|
|
|
D3D11Renderer *renderer;
|
2023-09-25 00:25:49 +00:00
|
|
|
|
PFN_CREATE_DXGI_FACTORY1 CreateDXGIFactoryFunc;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
PFN_D3D11_CREATE_DEVICE D3D11CreateDeviceFunc;
|
2023-11-05 20:17:23 +00:00
|
|
|
|
D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_11_1 };
|
2024-02-11 00:00:12 +00:00
|
|
|
|
IDXGIFactory4 *factory4;
|
2024-02-10 23:07:56 +00:00
|
|
|
|
IDXGIFactory5 *factory5;
|
2023-09-25 00:25:49 +00:00
|
|
|
|
IDXGIFactory6 *factory6;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
uint32_t flags;
|
|
|
|
|
DXGI_ADAPTER_DESC1 adapterDesc;
|
|
|
|
|
HRESULT res;
|
|
|
|
|
Refresh_Device* result;
|
|
|
|
|
|
|
|
|
|
/* Allocate and zero out the renderer */
|
|
|
|
|
renderer = (D3D11Renderer*) SDL_calloc(1, sizeof(D3D11Renderer));
|
|
|
|
|
|
|
|
|
|
/* Load the D3DCompiler library */
|
|
|
|
|
renderer->d3dcompiler_dll = SDL_LoadObject(D3DCOMPILER_DLL);
|
|
|
|
|
if (renderer->d3dcompiler_dll == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogError("Could not find " D3DCOMPILER_DLL);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Load the D3DCompile function pointer */
|
|
|
|
|
renderer->D3DCompileFunc = (PFN_D3DCOMPILE) SDL_LoadFunction(
|
|
|
|
|
renderer->d3dcompiler_dll,
|
2023-09-25 00:25:49 +00:00
|
|
|
|
D3DCOMPILE_FUNC
|
2023-09-23 01:44:20 +00:00
|
|
|
|
);
|
|
|
|
|
if (renderer->D3DCompileFunc == NULL)
|
|
|
|
|
{
|
2023-09-25 00:25:49 +00:00
|
|
|
|
Refresh_LogError("Could not load function: " D3DCOMPILE_FUNC);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Load the DXGI library */
|
|
|
|
|
renderer->dxgi_dll = SDL_LoadObject(DXGI_DLL);
|
|
|
|
|
if (renderer->dxgi_dll == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogError("Could not find " DXGI_DLL);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-25 00:25:49 +00:00
|
|
|
|
/* Load the CreateDXGIFactory1 function */
|
|
|
|
|
CreateDXGIFactoryFunc = (PFN_CREATE_DXGI_FACTORY1) SDL_LoadFunction(
|
2023-09-23 01:44:20 +00:00
|
|
|
|
renderer->dxgi_dll,
|
2023-09-25 00:25:49 +00:00
|
|
|
|
CREATE_DXGI_FACTORY1_FUNC
|
2023-09-23 01:44:20 +00:00
|
|
|
|
);
|
|
|
|
|
if (CreateDXGIFactoryFunc == NULL)
|
|
|
|
|
{
|
2023-09-25 00:25:49 +00:00
|
|
|
|
Refresh_LogError("Could not load function: " CREATE_DXGI_FACTORY1_FUNC);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create the DXGI factory */
|
|
|
|
|
res = CreateDXGIFactoryFunc(
|
|
|
|
|
&D3D_IID_IDXGIFactory1,
|
|
|
|
|
&renderer->factory
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create DXGIFactory", NULL);
|
|
|
|
|
|
2024-02-11 00:00:12 +00:00
|
|
|
|
/* Check for flip-model discard support (supported on Windows 10+) */
|
|
|
|
|
res = IDXGIFactory1_QueryInterface(
|
|
|
|
|
renderer->factory,
|
|
|
|
|
&D3D_IID_IDXGIFactory4,
|
|
|
|
|
&factory4
|
|
|
|
|
);
|
|
|
|
|
if (SUCCEEDED(res))
|
|
|
|
|
{
|
|
|
|
|
renderer->supportsFlipDiscard = 1;
|
|
|
|
|
IDXGIFactory4_Release(factory4);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-10 23:07:56 +00:00
|
|
|
|
/* 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 */
|
2023-09-23 01:44:20 +00:00
|
|
|
|
res = IDXGIAdapter1_QueryInterface(
|
|
|
|
|
renderer->factory,
|
|
|
|
|
&D3D_IID_IDXGIFactory6,
|
|
|
|
|
(void**) &factory6
|
|
|
|
|
);
|
|
|
|
|
if (SUCCEEDED(res))
|
|
|
|
|
{
|
|
|
|
|
IDXGIFactory6_EnumAdapterByGpuPreference(
|
2023-09-25 00:25:49 +00:00
|
|
|
|
factory6,
|
2023-09-23 01:44:20 +00:00
|
|
|
|
0,
|
|
|
|
|
DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
|
|
|
|
|
&D3D_IID_IDXGIAdapter1,
|
|
|
|
|
&renderer->adapter
|
|
|
|
|
);
|
2024-02-10 23:07:56 +00:00
|
|
|
|
IDXGIFactory6_Release(factory6);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
IDXGIFactory1_EnumAdapters1(
|
|
|
|
|
renderer->factory,
|
|
|
|
|
0,
|
|
|
|
|
&renderer->adapter
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get information about the selected adapter. Used for logging info. */
|
|
|
|
|
IDXGIAdapter1_GetDesc1(renderer->adapter, &adapterDesc);
|
|
|
|
|
|
2024-02-07 14:02:49 +00:00
|
|
|
|
/* Initialize the DXGI debug layer, if applicable */
|
|
|
|
|
if (debugMode)
|
|
|
|
|
{
|
|
|
|
|
D3D11_INTERNAL_TryInitializeDXGIDebug(renderer);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Load the D3D library */
|
|
|
|
|
renderer->d3d11_dll = SDL_LoadObject(D3D11_DLL);
|
|
|
|
|
if (renderer->d3d11_dll == NULL)
|
|
|
|
|
{
|
|
|
|
|
Refresh_LogError("Could not find " D3D11_DLL);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Load the CreateDevice function */
|
|
|
|
|
D3D11CreateDeviceFunc = (PFN_D3D11_CREATE_DEVICE) SDL_LoadFunction(
|
|
|
|
|
renderer->d3d11_dll,
|
2023-09-25 00:25:49 +00:00
|
|
|
|
D3D11_CREATE_DEVICE_FUNC
|
2023-09-23 01:44:20 +00:00
|
|
|
|
);
|
|
|
|
|
if (D3D11CreateDeviceFunc == NULL)
|
|
|
|
|
{
|
2023-09-25 00:25:49 +00:00
|
|
|
|
Refresh_LogError("Could not load function: " D3D11_CREATE_DEVICE_FUNC);
|
2023-09-23 01:44:20 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set up device flags */
|
|
|
|
|
flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
|
|
|
|
if (debugMode)
|
|
|
|
|
{
|
|
|
|
|
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create the device */
|
2023-11-06 01:20:37 +00:00
|
|
|
|
ID3D11Device *d3d11Device;
|
2023-09-23 01:44:20 +00:00
|
|
|
|
tryCreateDevice:
|
|
|
|
|
res = D3D11CreateDeviceFunc(
|
2023-09-25 00:25:49 +00:00
|
|
|
|
(IDXGIAdapter*) renderer->adapter,
|
2023-09-23 01:44:20 +00:00
|
|
|
|
D3D_DRIVER_TYPE_UNKNOWN, /* Must be UNKNOWN if adapter is non-null according to spec */
|
|
|
|
|
NULL,
|
|
|
|
|
flags,
|
|
|
|
|
levels,
|
|
|
|
|
SDL_arraysize(levels),
|
|
|
|
|
D3D11_SDK_VERSION,
|
2023-11-06 01:20:37 +00:00
|
|
|
|
&d3d11Device,
|
2024-02-10 23:07:56 +00:00
|
|
|
|
NULL,
|
2023-09-23 01:44:20 +00:00
|
|
|
|
&renderer->immediateContext
|
|
|
|
|
);
|
|
|
|
|
if (FAILED(res) && debugMode)
|
|
|
|
|
{
|
|
|
|
|
/* If device creation failed, and we're in debug mode, remove the debug flag and try again. */
|
|
|
|
|
Refresh_LogWarn("Creating device in debug mode failed with error %08X. Trying non-debug.", res);
|
|
|
|
|
flags &= ~D3D11_CREATE_DEVICE_DEBUG;
|
|
|
|
|
debugMode = 0;
|
|
|
|
|
goto tryCreateDevice;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ERROR_CHECK_RETURN("Could not create D3D11 device", NULL);
|
|
|
|
|
|
2023-11-06 01:20:37 +00:00
|
|
|
|
/* The actual device we want is the ID3D11Device1 interface... */
|
|
|
|
|
res = ID3D11Device_QueryInterface(
|
|
|
|
|
d3d11Device,
|
|
|
|
|
&D3D_IID_ID3D11Device1,
|
|
|
|
|
&renderer->device
|
|
|
|
|
);
|
|
|
|
|
ERROR_CHECK_RETURN("Could not get ID3D11Device1 interface", NULL);
|
|
|
|
|
|
2024-02-07 15:09:30 +00:00
|
|
|
|
/* Release the old device interface, we don't need it anymore */
|
|
|
|
|
ID3D11Device_Release(d3d11Device);
|
|
|
|
|
|
2024-02-07 15:09:01 +00:00
|
|
|
|
/* Set up the info queue */
|
|
|
|
|
if (renderer->dxgiInfoQueue)
|
|
|
|
|
{
|
|
|
|
|
DXGI_INFO_QUEUE_MESSAGE_SEVERITY sevList[] =
|
|
|
|
|
{
|
|
|
|
|
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION,
|
|
|
|
|
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR,
|
|
|
|
|
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_WARNING,
|
|
|
|
|
// DXGI_INFO_QUEUE_MESSAGE_SEVERITY_INFO, /* This can be a bit much, so toggle as needed for debugging. */
|
|
|
|
|
DXGI_INFO_QUEUE_MESSAGE_SEVERITY_MESSAGE
|
|
|
|
|
};
|
|
|
|
|
DXGI_INFO_QUEUE_FILTER filter = { 0 };
|
|
|
|
|
filter.AllowList.NumSeverities = SDL_arraysize(sevList);
|
|
|
|
|
filter.AllowList.pSeverityList = sevList;
|
|
|
|
|
|
|
|
|
|
IDXGIInfoQueue_PushStorageFilter(
|
|
|
|
|
renderer->dxgiInfoQueue,
|
|
|
|
|
D3D_IID_DXGI_DEBUG_ALL,
|
|
|
|
|
&filter
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Print driver info */
|
|
|
|
|
Refresh_LogInfo("Refresh Driver: D3D11");
|
|
|
|
|
Refresh_LogInfo("D3D11 Adapter: %S", adapterDesc.Description);
|
|
|
|
|
|
2023-09-25 02:29:11 +00:00
|
|
|
|
/* Create mutexes */
|
2024-02-11 03:49:19 +00:00
|
|
|
|
renderer->contextLock = SDL_CreateMutex();
|
2023-10-08 21:05:33 +00:00
|
|
|
|
renderer->acquireCommandBufferLock = SDL_CreateMutex();
|
2023-11-05 20:17:23 +00:00
|
|
|
|
renderer->uniformBufferLock = SDL_CreateMutex();
|
2024-02-09 05:59:13 +00:00
|
|
|
|
renderer->fenceLock = SDL_CreateMutex();
|
2024-02-11 04:18:25 +00:00
|
|
|
|
renderer->windowLock = SDL_CreateMutex();
|
2023-09-25 02:29:11 +00:00
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Initialize miscellaneous renderer members */
|
|
|
|
|
renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG);
|
|
|
|
|
|
2024-02-09 04:53:36 +00:00
|
|
|
|
/* Create command buffer pool */
|
2023-10-08 21:16:11 +00:00
|
|
|
|
D3D11_INTERNAL_AllocateCommandBuffers(renderer, 2);
|
|
|
|
|
|
2023-11-05 20:17:23 +00:00
|
|
|
|
/* Create uniform buffer pool */
|
|
|
|
|
renderer->availableUniformBufferCapacity = 2;
|
2024-02-11 04:18:25 +00:00
|
|
|
|
renderer->availableUniformBuffers = SDL_malloc(
|
|
|
|
|
sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity
|
|
|
|
|
);
|
2023-11-05 20:17:23 +00:00
|
|
|
|
|
2024-02-09 04:53:36 +00:00
|
|
|
|
/* Create fence pool */
|
2024-02-09 05:59:13 +00:00
|
|
|
|
renderer->availableFenceCapacity = 2;
|
2024-02-11 04:18:25 +00:00
|
|
|
|
renderer->availableFences = SDL_malloc(
|
|
|
|
|
sizeof(D3D11Fence*) * renderer->availableFenceCapacity
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
/* Create claimed window list */
|
|
|
|
|
renderer->claimedWindowCapacity = 1;
|
|
|
|
|
renderer->claimedWindows = SDL_malloc(
|
|
|
|
|
sizeof(D3D11WindowData*) * renderer->claimedWindowCapacity
|
|
|
|
|
);
|
2024-02-09 04:53:36 +00:00
|
|
|
|
|
2023-09-23 01:44:20 +00:00
|
|
|
|
/* Create the Refresh Device */
|
|
|
|
|
result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device));
|
|
|
|
|
ASSIGN_DRIVER(D3D11)
|
|
|
|
|
result->driverData = (Refresh_Renderer*) renderer;
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Refresh_Driver D3D11Driver = {
|
|
|
|
|
"D3D11",
|
|
|
|
|
D3D11_PrepareDriver,
|
|
|
|
|
D3D11_CreateDevice
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif //REFRESH_DRIVER_D3D11
|