more dx12 initialization
This commit is contained in:
parent
50ca2387fa
commit
4fb1e0231b
413
src/gpu_dx12.c
413
src/gpu_dx12.c
@ -72,10 +72,17 @@ GLOBAL struct {
|
|||||||
/* Device */
|
/* Device */
|
||||||
ID3D12Device *device;
|
ID3D12Device *device;
|
||||||
|
|
||||||
|
/* Desc sizes */
|
||||||
|
u32 desc_size_rtv;
|
||||||
|
|
||||||
/* Swapchain */
|
/* Swapchain */
|
||||||
u32 swapchain_frame_index;
|
u32 swapchain_frame_index;
|
||||||
ID3D12CommandQueue *swapchain_cq;
|
ID3D12CommandQueue *swapchain_cq;
|
||||||
|
ID3D12CommandAllocator *swapchain_ca;
|
||||||
IDXGISwapChain3 *swapchain;
|
IDXGISwapChain3 *swapchain;
|
||||||
|
ID3D12DescriptorHeap *swapchain_rtv_heap;
|
||||||
|
ID3D12Resource *swapchain_rtvs[DX12_SWAPCHAIN_BUFFER_COUNT];
|
||||||
|
|
||||||
} G = ZI, DEBUG_ALIAS(G, G_gpu_dx12);
|
} G = ZI, DEBUG_ALIAS(G, G_gpu_dx12);
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
@ -84,188 +91,239 @@ GLOBAL struct {
|
|||||||
|
|
||||||
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown);
|
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown);
|
||||||
|
|
||||||
|
INTERNAL void dx12_init(struct sys_window *window)
|
||||||
|
{
|
||||||
|
__prof;
|
||||||
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
|
HRESULT hr = 0;
|
||||||
|
|
||||||
|
/* Enable debug layer */
|
||||||
|
u32 dxgi_factory_flags = 0;
|
||||||
|
#if DX12_DEBUG
|
||||||
|
{
|
||||||
|
ID3D12Debug *debug_controller0 = NULL;
|
||||||
|
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create ID3D12Debug0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12Debug1 *debug_controller1 = NULL;
|
||||||
|
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create ID3D12Debug1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12Debug_EnableDebugLayer(debug_controller0);
|
||||||
|
|
||||||
|
/* FIXME: Enable this */
|
||||||
|
//ID3D12Debug1_SetEnableGPUBasedValidation(debug_controller1, true);
|
||||||
|
|
||||||
|
ID3D12Debug_Release(debug_controller1);
|
||||||
|
ID3D12Debug_Release(debug_controller0);
|
||||||
|
dxgi_factory_flags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Create factory */
|
||||||
|
IDXGIFactory6 *factory = NULL;
|
||||||
|
hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&factory);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to initialize DXGI factory"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create device */
|
||||||
|
ID3D12Device *device = NULL;
|
||||||
|
{
|
||||||
|
struct string error = LIT("Could not initialize GPU device.");
|
||||||
|
struct string first_gpu_name = ZI;
|
||||||
|
u32 adapter_index = 0;
|
||||||
|
while (true) {
|
||||||
|
IDXGIAdapter1 *adapter = NULL;
|
||||||
|
hr = IDXGIFactory6_EnumAdapterByGpuPreference(factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter1, (void **)&adapter);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
DXGI_ADAPTER_DESC1 desc;
|
||||||
|
IDXGIAdapter1_GetDesc1(adapter, &desc);
|
||||||
|
if (!(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) {
|
||||||
|
if (first_gpu_name.len == 0) {
|
||||||
|
first_gpu_name = string_from_wstr_no_limit(scratch.arena, desc.Description);
|
||||||
|
}
|
||||||
|
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device);
|
||||||
|
if (SUCCEEDED(hr)) {
|
||||||
|
D3D12_FEATURE_DATA_D3D12_OPTIONS7 features = ZI;
|
||||||
|
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS7, &features, sizeof(features));
|
||||||
|
if (SUCCEEDED(hr) && features.MeshShaderTier >= D3D12_MESH_SHADER_TIER_1) {
|
||||||
|
IDXGIAdapter1_Release(adapter);
|
||||||
|
adapter = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ID3D12Device_Release(device);
|
||||||
|
IDXGIAdapter1_Release(adapter);
|
||||||
|
adapter = NULL;
|
||||||
|
device = NULL;
|
||||||
|
++adapter_index;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* TODO: Fall back to compute shaders if mesh shaders aren't supported */
|
||||||
|
if (!device) {
|
||||||
|
if (first_gpu_name.len > 0) {
|
||||||
|
struct string fmt = LIT("Device '%F' does not support DirectX 12_2. Ensure that your drivers are up to date.\n\n"
|
||||||
|
"Note that older GPUs such as those up to and including the GTX 1000 series, the RX 5000 series, and the Intel Xe-LP series do not support DirectX 12_2 features.");
|
||||||
|
error = string_format(scratch.arena, fmt, FMT_STR(first_gpu_name));
|
||||||
|
}
|
||||||
|
sys_panic(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get desc sizes */
|
||||||
|
u32 desc_size_rtv = ID3D12Device_GetDescriptorHandleIncrementSize(device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
|
||||||
|
#if DX12_DEBUG
|
||||||
|
/* Enable D3D12 Debug break */
|
||||||
|
{
|
||||||
|
ID3D12InfoQueue *info = NULL;
|
||||||
|
hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to query ID3D12Device interface"));
|
||||||
|
}
|
||||||
|
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
||||||
|
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
|
||||||
|
ID3D12InfoQueue_Release(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable DXGI Debug break */
|
||||||
|
{
|
||||||
|
IDXGIInfoQueue *dxgi_info = NULL;
|
||||||
|
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to get DXGI debug interface"));
|
||||||
|
}
|
||||||
|
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
||||||
|
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
|
||||||
|
IDXGIInfoQueue_Release(dxgi_info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Create direct command queue */
|
||||||
|
ID3D12CommandQueue *swapchain_cq = NULL;
|
||||||
|
{
|
||||||
|
D3D12_COMMAND_QUEUE_DESC desc = ZI;
|
||||||
|
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||||
|
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||||
|
|
||||||
|
hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&swapchain_cq);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create swapchain command queue"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create direct command allocator */
|
||||||
|
ID3D12CommandAllocator *swapchain_ca = NULL;
|
||||||
|
{
|
||||||
|
hr = ID3D12Device_CreateCommandAllocator(device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&swapchain_ca);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create swapchain command allocator"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create swapchain */
|
||||||
|
IDXGISwapChain3 *swapchain = NULL;
|
||||||
|
u32 swapchain_frame_index = 0;
|
||||||
|
{
|
||||||
|
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 desc = {
|
||||||
|
.Format = DX12_SWAPCHAIN_FORMAT,
|
||||||
|
.SampleDesc = { 1, 0 },
|
||||||
|
.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||||
|
.BufferCount = DX12_SWAPCHAIN_BUFFER_COUNT,
|
||||||
|
.Scaling = DXGI_SCALING_NONE,
|
||||||
|
.Flags = DX12_SWAPCHAIN_FLAGS,
|
||||||
|
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
|
||||||
|
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create swapchain1 */
|
||||||
|
IDXGISwapChain1 *swapchain1 = NULL;
|
||||||
|
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)swapchain_cq, hwnd, &desc, NULL, NULL, &swapchain1);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create IDXGISwapChain1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Upgrade to swapchain3 */
|
||||||
|
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create IDXGISwapChain3"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable Alt+Enter changing monitor resolution to match window size */
|
||||||
|
IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
|
||||||
|
/* Get initial frame index */
|
||||||
|
swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain);
|
||||||
|
|
||||||
|
IDXGISwapChain1_Release(swapchain1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create swapchain RTV heap */
|
||||||
|
ID3D12DescriptorHeap *swapchain_rtv_heap = NULL;
|
||||||
|
{
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC desc = ZI;
|
||||||
|
desc.NumDescriptors = DX12_SWAPCHAIN_BUFFER_COUNT;
|
||||||
|
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||||
|
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
|
|
||||||
|
hr = ID3D12Device_CreateDescriptorHeap(device, &desc, &IID_ID3D12DescriptorHeap, (void **)&swapchain_rtv_heap);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create swapchain RTV heap"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create swacphain RTVs */
|
||||||
|
ID3D12Resource *swapchain_rtvs[DX12_SWAPCHAIN_BUFFER_COUNT] = ZI;
|
||||||
|
{
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = ZI;
|
||||||
|
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(swapchain_rtv_heap, &rtv_handle);
|
||||||
|
for (u32 i = 0; i < DX12_SWAPCHAIN_BUFFER_COUNT; ++i) {
|
||||||
|
hr = IDXGISwapChain3_GetBuffer(swapchain, i, &IID_ID3D12Resource, (void **)&swapchain_rtvs[i]);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
sys_panic(LIT("Failed to create swapchain RTV"));
|
||||||
|
}
|
||||||
|
ID3D12Device_CreateRenderTargetView(device, swapchain_rtvs[i], NULL, rtv_handle);
|
||||||
|
|
||||||
|
rtv_handle.ptr += desc_size_rtv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create command allocator */
|
||||||
|
|
||||||
|
G.device = device;
|
||||||
|
G.desc_size_rtv = desc_size_rtv;
|
||||||
|
G.swapchain_frame_index = swapchain_frame_index;
|
||||||
|
G.swapchain_cq = swapchain_cq;
|
||||||
|
G.swapchain_ca = swapchain_ca;
|
||||||
|
G.swapchain = swapchain;
|
||||||
|
G.swapchain_rtv_heap = swapchain_rtv_heap;
|
||||||
|
MEMCPY(&G.swapchain_rtvs, swapchain_rtvs, sizeof(G.swapchain_rtvs));
|
||||||
|
|
||||||
|
IDXGIFactory6_Release(factory);
|
||||||
|
scratch_end(scratch);
|
||||||
|
}
|
||||||
|
|
||||||
struct gpu_startup_receipt gpu_startup(struct sys_window *window)
|
struct gpu_startup_receipt gpu_startup(struct sys_window *window)
|
||||||
{
|
{
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
/* Initialize handles pool */
|
/* Initialize handles pool */
|
||||||
G.handle_entries_mutex = sys_mutex_alloc();
|
G.handle_entries_mutex = sys_mutex_alloc();
|
||||||
G.handle_entries_arena = arena_alloc(GIGABYTE(64));
|
G.handle_entries_arena = arena_alloc(GIGABYTE(64));
|
||||||
|
|
||||||
/* Initialize dx12 */
|
/* Initialize dx12 */
|
||||||
{
|
dx12_init(window);
|
||||||
/* Enable debug layer */
|
|
||||||
u32 dxgi_factory_flags = 0;
|
|
||||||
#if DX12_DEBUG
|
|
||||||
{
|
|
||||||
ID3D12Debug *debug_controller0 = NULL;
|
|
||||||
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to create ID3D12Debug0"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D12Debug1 *debug_controller1 = NULL;
|
|
||||||
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to create ID3D12Debug1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D12Debug_EnableDebugLayer(debug_controller0);
|
|
||||||
|
|
||||||
/* FIXME: Enable this */
|
|
||||||
//ID3D12Debug1_SetEnableGPUBasedValidation(debug_controller1, true);
|
|
||||||
|
|
||||||
ID3D12Debug_Release(debug_controller1);
|
|
||||||
ID3D12Debug_Release(debug_controller0);
|
|
||||||
dxgi_factory_flags |= DXGI_CREATE_FACTORY_DEBUG;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Create factory */
|
|
||||||
IDXGIFactory6 *factory = NULL;
|
|
||||||
hr = CreateDXGIFactory2(dxgi_factory_flags, &IID_IDXGIFactory6, (void **)&factory);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to initialize DXGI factory"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create device */
|
|
||||||
ID3D12Device *device = NULL;
|
|
||||||
{
|
|
||||||
struct string error = LIT("Could not initialize GPU device.");
|
|
||||||
struct string first_gpu_name = ZI;
|
|
||||||
u32 adapter_index = 0;
|
|
||||||
while (true) {
|
|
||||||
IDXGIAdapter1 *adapter = NULL;
|
|
||||||
hr = IDXGIFactory6_EnumAdapterByGpuPreference(factory, adapter_index, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, &IID_IDXGIAdapter1, (void **)&adapter);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
DXGI_ADAPTER_DESC1 desc;
|
|
||||||
IDXGIAdapter1_GetDesc1(adapter, &desc);
|
|
||||||
if (!(desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)) {
|
|
||||||
if (first_gpu_name.len == 0) {
|
|
||||||
first_gpu_name = string_from_wstr_no_limit(scratch.arena, desc.Description);
|
|
||||||
}
|
|
||||||
/* Using feature level 12_0 instead of 12_2 because mesh feature check happens separately
|
|
||||||
* (because 1600 series cards support mesh shaders but not the rest of 12_2) */
|
|
||||||
hr = D3D12CreateDevice((IUnknown *)adapter, D3D_FEATURE_LEVEL_12_0, &IID_ID3D12Device, (void **)&device);
|
|
||||||
if (SUCCEEDED(hr)) {
|
|
||||||
D3D12_FEATURE_DATA_D3D12_OPTIONS7 features = ZI;
|
|
||||||
hr = ID3D12Device_CheckFeatureSupport(device, D3D12_FEATURE_D3D12_OPTIONS7, &features, sizeof(features));
|
|
||||||
if (SUCCEEDED(hr) && features.MeshShaderTier >= D3D12_MESH_SHADER_TIER_1) {
|
|
||||||
IDXGIAdapter1_Release(adapter);
|
|
||||||
adapter = NULL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ID3D12Device_Release(device);
|
|
||||||
IDXGIAdapter1_Release(adapter);
|
|
||||||
adapter = NULL;
|
|
||||||
device = NULL;
|
|
||||||
++adapter_index;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* TODO: Fall back to compute shaders if mesh shaders aren't supported */
|
|
||||||
if (!device) {
|
|
||||||
if (first_gpu_name.len > 0) {
|
|
||||||
struct string fmt = LIT("Device '%F' does not support DirectX 12_2. Ensure that your drivers are up to date.\n\n"
|
|
||||||
"Note that older GPUs such as those up to and including the GTX 1000 series, the RX 5000 series, and the Intel Xe-LP series do not support DirectX 12_2 features.");
|
|
||||||
error = string_format(scratch.arena, fmt, FMT_STR(first_gpu_name));
|
|
||||||
}
|
|
||||||
sys_panic(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DX12_DEBUG
|
|
||||||
/* Enable D3D12 Debug break */
|
|
||||||
{
|
|
||||||
ID3D12InfoQueue *info = NULL;
|
|
||||||
hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to query ID3D12Device interface"));
|
|
||||||
}
|
|
||||||
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
|
||||||
ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
|
|
||||||
ID3D12InfoQueue_Release(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Enable DXGI Debug break */
|
|
||||||
{
|
|
||||||
IDXGIInfoQueue *dxgi_info = NULL;
|
|
||||||
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to get DXGI debug interface"));
|
|
||||||
}
|
|
||||||
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
|
||||||
IDXGIInfoQueue_SetBreakOnSeverity(dxgi_info, DXGI_DEBUG_ALL, DXGI_INFO_QUEUE_MESSAGE_SEVERITY_ERROR, TRUE);
|
|
||||||
IDXGIInfoQueue_Release(dxgi_info);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Create direct command queue */
|
|
||||||
ID3D12CommandQueue *swapchain_cq = NULL;
|
|
||||||
{
|
|
||||||
D3D12_COMMAND_QUEUE_DESC desc = ZI;
|
|
||||||
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
|
||||||
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
|
||||||
|
|
||||||
hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&swapchain_cq);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to create swapchain command queue"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create swapchain */
|
|
||||||
IDXGISwapChain3 *swapchain = NULL;
|
|
||||||
u32 swapchain_frame_index = 0;
|
|
||||||
{
|
|
||||||
HWND hwnd = (HWND)sys_window_get_internal_handle(window);
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 desc = {
|
|
||||||
.Format = DX12_SWAPCHAIN_FORMAT,
|
|
||||||
.SampleDesc = { 1, 0 },
|
|
||||||
.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
|
||||||
.BufferCount = 3,
|
|
||||||
.Scaling = DXGI_SCALING_NONE,
|
|
||||||
.Flags = DX12_SWAPCHAIN_FLAGS,
|
|
||||||
.AlphaMode = DXGI_ALPHA_MODE_IGNORE,
|
|
||||||
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Create swapchain1 */
|
|
||||||
IDXGISwapChain1 *swapchain1 = NULL;
|
|
||||||
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)swapchain_cq, hwnd, &desc, NULL, NULL, &swapchain1);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to create IDXGISwapChain1"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Upgrade to swapchain3 */
|
|
||||||
hr = IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void **)&swapchain);
|
|
||||||
if (!SUCCEEDED(hr)) {
|
|
||||||
sys_panic(LIT("Failed to create IDXGISwapChain3"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable Alt+Enter changing monitor resolution to match window size */
|
|
||||||
IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
|
||||||
|
|
||||||
/* Get initial frame index */
|
|
||||||
swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain);
|
|
||||||
|
|
||||||
IDXGISwapChain1_Release(swapchain1);
|
|
||||||
}
|
|
||||||
|
|
||||||
G.device = device;
|
|
||||||
G.swapchain_frame_index = swapchain_frame_index;
|
|
||||||
G.swapchain_cq = swapchain_cq;
|
|
||||||
G.swapchain = swapchain;
|
|
||||||
|
|
||||||
IDXGIFactory6_Release(factory);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Register callbacks */
|
||||||
app_register_exit_callback(gpu_shutdown);
|
app_register_exit_callback(gpu_shutdown);
|
||||||
|
|
||||||
scratch_end(scratch);
|
|
||||||
struct gpu_startup_receipt res = ZI;
|
struct gpu_startup_receipt res = ZI;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -274,11 +332,14 @@ INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown)
|
|||||||
{
|
{
|
||||||
#if DX12_DEBUG
|
#if DX12_DEBUG
|
||||||
/* Release objects to make live object reporting less noisy */
|
/* Release objects to make live object reporting less noisy */
|
||||||
{
|
for (u64 i = 0; i < ARRAY_COUNT(G.swapchain_rtvs); ++i) {
|
||||||
ID3D12Device_Release(G.device);
|
ID3D12Resource_Release(G.swapchain_rtvs[i]);
|
||||||
ID3D12CommandQueue_Release(G.swapchain_cq);
|
|
||||||
IDXGISwapChain3_Release(G.swapchain);
|
|
||||||
}
|
}
|
||||||
|
ID3D12DescriptorHeap_Release(G.swapchain_rtv_heap);
|
||||||
|
ID3D12CommandQueue_Release(G.swapchain_ca);
|
||||||
|
ID3D12CommandQueue_Release(G.swapchain_cq);
|
||||||
|
IDXGISwapChain3_Release(G.swapchain);
|
||||||
|
ID3D12Device_Release(G.device);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user