blue window
This commit is contained in:
1 parent
2881b2c9d5
commit
5fa75c116e
5 files changed
+300
-62
No files matched your search
@@ -14,6 +14,17 @@ union Vector2f
|
|||||||
float32 v[2];
|
float32 v[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef union Vector2i Vector2i;
|
||||||
|
union Vector2i
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
int32 x;
|
||||||
|
int32 y;
|
||||||
|
};
|
||||||
|
int32 v[2];
|
||||||
|
};
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// Rect Types
|
// Rect Types
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,15 @@ internal void ja_frame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// render frame
|
||||||
|
r_begin_frame();
|
||||||
|
for (JA_WindowState* w = ja_state->first_window_state; w != &ja_nil_window_state; w = w->order_next)
|
||||||
|
{
|
||||||
|
r_window_begin_frame(w->plat_handle, w->render_handle);
|
||||||
|
r_window_end_frame(w->plat_handle, w->render_handle);
|
||||||
|
}
|
||||||
|
r_end_frame();
|
||||||
|
|
||||||
// show window after first frame
|
// show window after first frame
|
||||||
if (ja_state->frame_depth == 1)
|
if (ja_state->frame_depth == 1)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,20 @@ internal R_Handle r_d3d12_handle_from_window(R_D3D12_Window* window)
|
|||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Wait Function
|
||||||
|
|
||||||
|
internal void r_d3d12_wait()
|
||||||
|
{
|
||||||
|
r_d3d12_state->fence_value += 1;
|
||||||
|
ID3D12CommandQueue_Signal(r_d3d12_state->direct_command_queue, r_d3d12_state->fence, r_d3d12_state->fence_value);
|
||||||
|
if (ID3D12Fence_GetCompletedValue(r_d3d12_state->fence) < r_d3d12_state->fence_value)
|
||||||
|
{
|
||||||
|
ID3D12Fence_SetEventOnCompletion(r_d3d12_state->fence, r_d3d12_state->fence_value, r_d3d12_state->fence_event);
|
||||||
|
WaitForSingleObject(r_d3d12_state->fence_event, INFINITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
// top level layer initialization
|
// top level layer initialization
|
||||||
|
|
||||||
@@ -37,6 +51,13 @@ void r_init()
|
|||||||
|
|
||||||
UINT dxgi_flags = 0;
|
UINT dxgi_flags = 0;
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
|
ID3D12Debug1* debug_controller = 0;
|
||||||
|
if (SUCCEEDED(D3D12GetDebugInterface(&IID_ID3D12Debug1, (void**)&debug_controller)))
|
||||||
|
{
|
||||||
|
ID3D12Debug1_EnableDebugLayer(debug_controller);
|
||||||
|
ID3D12Debug1_SetEnableGPUBasedValidation(debug_controller, TRUE);
|
||||||
|
ID3D12Debug1_Release(debug_controller);
|
||||||
|
}
|
||||||
dxgi_flags |= DXGI_CREATE_FACTORY_DEBUG;
|
dxgi_flags |= DXGI_CREATE_FACTORY_DEBUG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -49,38 +70,6 @@ void r_init()
|
|||||||
abort_self(1);
|
abort_self(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
error = D3D12CreateDevice(0, feature_level, &IID_ID3D12Device4, (void**)&r_d3d12_state->device);
|
|
||||||
if (FAILED(error))
|
|
||||||
{
|
|
||||||
IDXGIAdapter1* warp_adapter = 0;
|
|
||||||
error = IDXGIFactory4_EnumWarpAdapter(r_d3d12_state->dxgi_factory, &IID_IDXGIFactory1, (void**)&warp_adapter);
|
|
||||||
if (SUCCEEDED(error))
|
|
||||||
{
|
|
||||||
error = D3D12CreateDevice((IUnknown*)warp_adapter, feature_level, &IID_ID3D12Device4, (void**)&r_d3d12_state->device);
|
|
||||||
}
|
|
||||||
IDXGIAdapter1_Release(warp_adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(error))
|
|
||||||
{
|
|
||||||
char buffer[256] = { 0 };
|
|
||||||
juliet_snprintf(buffer, sizeof(buffer), "D3D12 device factory creation failure (%lx). Process is terminating", error);
|
|
||||||
sh_message(1, str8_literal("Fatal Error"), str8_cstring(buffer));
|
|
||||||
abort_self(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// break on error
|
|
||||||
#if BUILD_DEBUG
|
|
||||||
ID3D12InfoQueue* info = 0;
|
|
||||||
error = ID3D12Device4_QueryInterface(r_d3d12_state->device, &IID_ID3D12InfoQueue, (void**)info);
|
|
||||||
if (SUCCEEDED(error))
|
|
||||||
{
|
|
||||||
error = ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
|
||||||
error = ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
|
|
||||||
ID3D12InfoQueue_Release(info);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// dxgi setup (device and adapter)
|
// dxgi setup (device and adapter)
|
||||||
IDXGIFactory6* factory6 = 0;
|
IDXGIFactory6* factory6 = 0;
|
||||||
error = IDXGIFactory4_QueryInterface(r_d3d12_state->dxgi_factory, &IID_IDXGIFactory6, (void**)&factory6);
|
error = IDXGIFactory4_QueryInterface(r_d3d12_state->dxgi_factory, &IID_IDXGIFactory6, (void**)&factory6);
|
||||||
@@ -97,6 +86,41 @@ void r_init()
|
|||||||
error = IDXGIFactory4_EnumAdapters1(r_d3d12_state->dxgi_factory, 0, &r_d3d12_state->dxgi_adapter);
|
error = IDXGIFactory4_EnumAdapters1(r_d3d12_state->dxgi_factory, 0, &r_d3d12_state->dxgi_adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error = D3D12CreateDevice((IUnknown*)r_d3d12_state->dxgi_adapter, feature_level, &IID_ID3D12Device4,
|
||||||
|
(void**)&r_d3d12_state->device);
|
||||||
|
|
||||||
|
// Try warp as hardware is no available
|
||||||
|
if (FAILED(error))
|
||||||
|
{
|
||||||
|
IDXGIAdapter1_Release(r_d3d12_state->dxgi_adapter);
|
||||||
|
error = IDXGIFactory4_EnumWarpAdapter(r_d3d12_state->dxgi_factory, &IID_IDXGIAdapter, (void**)&r_d3d12_state->dxgi_adapter);
|
||||||
|
if (SUCCEEDED(error))
|
||||||
|
{
|
||||||
|
error = D3D12CreateDevice((IUnknown*)r_d3d12_state->dxgi_adapter, feature_level, &IID_ID3D12Device4,
|
||||||
|
(void**)&r_d3d12_state->device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(error))
|
||||||
|
{
|
||||||
|
char buffer[256] = { 0 };
|
||||||
|
juliet_snprintf(buffer, sizeof(buffer), "D3D12 device factory creation failure (%lx). Process is terminating", error);
|
||||||
|
sh_message(1, str8_literal("Fatal Error"), str8_cstring(buffer));
|
||||||
|
abort_self(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// break on error
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
ID3D12InfoQueue* info = 0;
|
||||||
|
error = ID3D12Device4_QueryInterface(r_d3d12_state->device, &IID_ID3D12InfoQueue, (void**)&info);
|
||||||
|
if (SUCCEEDED(error))
|
||||||
|
{
|
||||||
|
error = ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_CORRUPTION, TRUE);
|
||||||
|
error = ID3D12InfoQueue_SetBreakOnSeverity(info, D3D12_MESSAGE_SEVERITY_ERROR, TRUE);
|
||||||
|
ID3D12InfoQueue_Release(info);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Create basic graphics queue
|
// Create basic graphics queue
|
||||||
D3D12_COMMAND_QUEUE_DESC queue_desc = { 0 };
|
D3D12_COMMAND_QUEUE_DESC queue_desc = { 0 };
|
||||||
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||||
@@ -110,10 +134,39 @@ void r_init()
|
|||||||
sh_message(1, str8_literal("Fatal Error"), str8_cstring(buffer));
|
sh_message(1, str8_literal("Fatal Error"), str8_cstring(buffer));
|
||||||
abort_self(1);
|
abort_self(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create command allocator and command list
|
||||||
|
for EachIndex(i, 2)
|
||||||
|
{
|
||||||
|
ID3D12Device4_CreateCommandAllocator(r_d3d12_state->device, D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
&IID_ID3D12CommandAllocator, (void**)&r_d3d12_state->command_allocators[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ID3D12Device4_CreateCommandList1(r_d3d12_state->device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_LIST_FLAG_NONE,
|
||||||
|
&IID_ID3D12GraphicsCommandList, (void**)&r_d3d12_state->command_list);
|
||||||
|
|
||||||
|
ID3D12Device4_CreateFence(r_d3d12_state->device, 0, D3D12_FENCE_FLAG_NONE, &IID_ID3D12Fence, (void**)&r_d3d12_state->fence);
|
||||||
|
r_d3d12_state->fence_event = CreateEventW(0, FALSE, FALSE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void r_shutdown()
|
void r_shutdown()
|
||||||
{
|
{
|
||||||
|
MutexScopeW(r_d3d12_state->device_rw_mutex)
|
||||||
|
{
|
||||||
|
r_d3d12_wait();
|
||||||
|
|
||||||
|
CloseHandle(r_d3d12_state->fence_event);
|
||||||
|
ID3D12Fence_Release(r_d3d12_state->fence);
|
||||||
|
for EachIndex(i,2)
|
||||||
|
{
|
||||||
|
ID3D12CommandAllocator_Release(r_d3d12_state->command_allocators[i]);
|
||||||
|
}
|
||||||
|
ID3D12CommandList_Release(r_d3d12_state->command_list);
|
||||||
|
ID3D12CommandQueue_Release(r_d3d12_state->direct_command_queue);
|
||||||
|
ID3D12Device4_Release(r_d3d12_state->device);
|
||||||
|
IDXGIAdapter1_Release(r_d3d12_state->dxgi_adapter);
|
||||||
|
IDXGIFactory4_Release(r_d3d12_state->dxgi_factory);
|
||||||
|
}
|
||||||
rw_mutex_release(r_d3d12_state->device_rw_mutex);
|
rw_mutex_release(r_d3d12_state->device_rw_mutex);
|
||||||
arena_release(r_d3d12_state->arena);
|
arena_release(r_d3d12_state->arena);
|
||||||
}
|
}
|
||||||
@@ -145,31 +198,31 @@ R_Handle r_window_equip(WM_Window handle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create swapchain
|
// Create swapchain
|
||||||
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = { 0 };
|
DXGI_SWAP_CHAIN_DESC1 swapchain_desc = { 0 };
|
||||||
swap_chain_desc.Width = 0; // Use all window width
|
swapchain_desc.Width = 0; // Use all window width
|
||||||
swap_chain_desc.Height = 0; // Use all window height
|
swapchain_desc.Height = 0; // Use all window height
|
||||||
swap_chain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
swapchain_desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
swap_chain_desc.Stereo = 0;
|
swapchain_desc.Stereo = 0;
|
||||||
swap_chain_desc.SampleDesc.Count = 1;
|
swapchain_desc.SampleDesc.Count = 1;
|
||||||
swap_chain_desc.SampleDesc.Quality = 0;
|
swapchain_desc.SampleDesc.Quality = 0;
|
||||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
swapchain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
swap_chain_desc.BufferCount = 2; // Double buffering
|
swapchain_desc.BufferCount = 2; // Double buffering
|
||||||
swap_chain_desc.Scaling = DXGI_SCALING_NONE;
|
swapchain_desc.Scaling = DXGI_SCALING_NONE;
|
||||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
swapchain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
||||||
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
swapchain_desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||||
swap_chain_desc.Flags = 0;
|
swapchain_desc.Flags = 0;
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swap_chain_fullscreen_desc = { 0 };
|
DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapchain_fullscreen_desc = { 0 };
|
||||||
swap_chain_fullscreen_desc.RefreshRate.Numerator = 0;
|
swapchain_fullscreen_desc.RefreshRate.Numerator = 0;
|
||||||
swap_chain_fullscreen_desc.RefreshRate.Denominator = 0;
|
swapchain_fullscreen_desc.RefreshRate.Denominator = 0;
|
||||||
swap_chain_fullscreen_desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
swapchain_fullscreen_desc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||||
swap_chain_fullscreen_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
swapchain_fullscreen_desc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||||
swap_chain_fullscreen_desc.Windowed = TRUE;
|
swapchain_fullscreen_desc.Windowed = TRUE;
|
||||||
|
|
||||||
IDXGISwapChain1* swap_chain1 = 0;
|
IDXGISwapChain1* swapchain1 = 0;
|
||||||
HRESULT error =
|
HRESULT error = IDXGIFactory4_CreateSwapChainForHwnd(r_d3d12_state->dxgi_factory,
|
||||||
IDXGIFactory4_CreateSwapChainForHwnd(r_d3d12_state->dxgi_factory, (IUnknown*)r_d3d12_state->direct_command_queue,
|
(IUnknown*)r_d3d12_state->direct_command_queue, hwnd,
|
||||||
hwnd, &swap_chain_desc, &swap_chain_fullscreen_desc, 0, &swap_chain1);
|
&swapchain_desc, &swapchain_fullscreen_desc, 0, &swapchain1);
|
||||||
if (FAILED(error))
|
if (FAILED(error))
|
||||||
{
|
{
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
@@ -178,11 +231,38 @@ R_Handle r_window_equip(WM_Window handle)
|
|||||||
abort_self(1);
|
abort_self(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
IDXGISwapChain1_QueryInterface(swap_chain1, &IID_IDXGISwapChain3, (void**)&window->swap_chain);
|
IDXGISwapChain1_QueryInterface(swapchain1, &IID_IDXGISwapChain3, (void**)&window->swapchain);
|
||||||
IDXGISwapChain1_Release(swap_chain1);
|
IDXGISwapChain1_Release(swapchain1);
|
||||||
|
|
||||||
IDXGIFactory4_MakeWindowAssociation(r_d3d12_state->dxgi_factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
IDXGIFactory4_MakeWindowAssociation(r_d3d12_state->dxgi_factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
|
||||||
|
// Create framebuffer and rtv for swapchain
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc = { 0 };
|
||||||
|
rtv_heap_desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
||||||
|
rtv_heap_desc.NumDescriptors = 2;
|
||||||
|
rtv_heap_desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
||||||
|
|
||||||
|
ID3D12Device4_CreateDescriptorHeap(r_d3d12_state->device, &rtv_heap_desc, &IID_ID3D12DescriptorHeap,
|
||||||
|
(void**)&window->rtv_heap);
|
||||||
|
|
||||||
|
UINT rtv_stride = ID3D12Device4_GetDescriptorHandleIncrementSize(r_d3d12_state->device, D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = { 0 };
|
||||||
|
ID3D12DescriptorHeap_GetCPUDescriptorHandleForHeapStart(window->rtv_heap, &rtv_handle);
|
||||||
|
|
||||||
|
for (UINT i = 0; i < 2; ++i)
|
||||||
|
{
|
||||||
|
window->rtv_handles[i] = rtv_handle;
|
||||||
|
IDXGISwapChain3_GetBuffer(window->swapchain, i, &IID_ID3D12Resource, (void**)&window->framebuffer[i]);
|
||||||
|
ID3D12Device4_CreateRenderTargetView(r_d3d12_state->device, window->framebuffer[i], 0, window->rtv_handles[i]);
|
||||||
|
rtv_handle.ptr += rtv_stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save resolution in case of resize
|
||||||
|
Rect2f client_rect = wm_client_rect_from_window(handle);
|
||||||
|
Vector2i resolution = { (int32)(client_rect.x1 - client_rect.x0), (int32)(client_rect.y1 - client_rect.y0) };
|
||||||
|
window->last_resolution = resolution;
|
||||||
|
|
||||||
result = r_d3d12_handle_from_window(window);
|
result = r_d3d12_handle_from_window(window);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -192,11 +272,121 @@ void r_window_unequip(WM_Window handle, R_Handle handle_equip)
|
|||||||
{
|
{
|
||||||
MutexScopeW(r_d3d12_state->device_rw_mutex)
|
MutexScopeW(r_d3d12_state->device_rw_mutex)
|
||||||
{
|
{
|
||||||
|
r_d3d12_wait();
|
||||||
|
|
||||||
R_D3D12_Window* window = r_d3d12_window_from_handle(handle_equip);
|
R_D3D12_Window* window = r_d3d12_window_from_handle(handle_equip);
|
||||||
if (window != 0)
|
if (window != 0 && window != &r_d3d12_nil_window)
|
||||||
{
|
{
|
||||||
IDXGISwapChain1_Release(window->swap_chain);
|
for EachIndex(i, 2)
|
||||||
|
{
|
||||||
|
ID3D12Resource_Release(window->framebuffer[i]);
|
||||||
|
}
|
||||||
|
ID3D12DescriptorHeap_Release(window->rtv_heap);
|
||||||
|
IDXGISwapChain1_Release(window->swapchain);
|
||||||
SLL_stack_push(r_d3d12_state->first_free_window, window);
|
SLL_stack_push(r_d3d12_state->first_free_window, window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// frame markers
|
||||||
|
|
||||||
|
void r_begin_frame()
|
||||||
|
{
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
void r_end_frame()
|
||||||
|
{
|
||||||
|
// pouet
|
||||||
|
}
|
||||||
|
|
||||||
|
void r_window_begin_frame(WM_Window window, R_Handle window_equip)
|
||||||
|
{
|
||||||
|
MutexScopeW(r_d3d12_state->device_rw_mutex)
|
||||||
|
{
|
||||||
|
R_D3D12_Window* r_window = r_d3d12_window_from_handle(window_equip);
|
||||||
|
|
||||||
|
// Get resolution
|
||||||
|
Rect2f client_rect = wm_client_rect_from_window(window);
|
||||||
|
Vector2i resolution = { (int32)(client_rect.x1 - client_rect.x0), (int32)(client_rect.y1 - client_rect.y0) };
|
||||||
|
|
||||||
|
// change resolution
|
||||||
|
if (resolution.x > 0 && resolution.y > 0 &&
|
||||||
|
(r_window->last_resolution.x != resolution.x || r_window->last_resolution.y != resolution.y))
|
||||||
|
{
|
||||||
|
r_window->last_resolution = resolution;
|
||||||
|
|
||||||
|
// resize swap chain
|
||||||
|
r_d3d12_wait();
|
||||||
|
|
||||||
|
for EachIndex(i,2)
|
||||||
|
{
|
||||||
|
if (r_window->framebuffer[i] != 0)
|
||||||
|
{
|
||||||
|
ID3D12Resource_Release(r_window->framebuffer[i]);
|
||||||
|
r_window->framebuffer[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IDXGISwapChain3_ResizeBuffers(r_window->swapchain, 0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
|
||||||
|
|
||||||
|
for EachIndex(i,2)
|
||||||
|
{
|
||||||
|
IDXGISwapChain3_GetBuffer(r_window->swapchain, i, &IID_ID3D12Resource, (void**)&r_window->framebuffer[i]);
|
||||||
|
ID3D12Device4_CreateRenderTargetView(r_d3d12_state->device, r_window->framebuffer[i], 0, r_window->rtv_handles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open the command list for that window that frame
|
||||||
|
// TODO : multiple command list as we have multiple windows
|
||||||
|
r_window->framebuffer_idx = IDXGISwapChain3_GetCurrentBackBufferIndex(r_window->swapchain);
|
||||||
|
ID3D12CommandAllocator* allocator = r_d3d12_state->command_allocators[r_window->framebuffer_idx];
|
||||||
|
ID3D12GraphicsCommandList* cmd_list = r_d3d12_state->command_list;
|
||||||
|
|
||||||
|
ID3D12CommandAllocator_Reset(allocator);
|
||||||
|
ID3D12GraphicsCommandList1_Reset(cmd_list, allocator, 0);
|
||||||
|
|
||||||
|
// Barrier to transition from Present (end of frame) to render target
|
||||||
|
D3D12_RESOURCE_BARRIER barrier = { 0 };
|
||||||
|
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
barrier.Transition.pResource = r_window->framebuffer[r_window->framebuffer_idx];
|
||||||
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
||||||
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||||
|
ID3D12GraphicsCommandList_ResourceBarrier(cmd_list, 1, &barrier);
|
||||||
|
|
||||||
|
// HARDCODED
|
||||||
|
// BLUE
|
||||||
|
float32 background[4] = { 0.1f, 0.2f, 0.8f, 1.0f };
|
||||||
|
ID3D12GraphicsCommandList_ClearRenderTargetView(cmd_list, r_window->rtv_handles[r_window->framebuffer_idx],
|
||||||
|
background, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void r_window_end_frame(WM_Window window, R_Handle window_equip)
|
||||||
|
{
|
||||||
|
MutexScopeW(r_d3d12_state->device_rw_mutex)
|
||||||
|
{
|
||||||
|
R_D3D12_Window* r_window = r_d3d12_window_from_handle(window_equip);
|
||||||
|
|
||||||
|
ID3D12GraphicsCommandList* cmd_list = r_d3d12_state->command_list;
|
||||||
|
|
||||||
|
// Transition from render target to present
|
||||||
|
D3D12_RESOURCE_BARRIER barrier = { 0 };
|
||||||
|
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
||||||
|
barrier.Transition.pResource = r_window->framebuffer[r_window->framebuffer_idx];
|
||||||
|
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
||||||
|
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||||
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||||
|
ID3D12GraphicsCommandList_ResourceBarrier(cmd_list, 1, &barrier);
|
||||||
|
|
||||||
|
// Close command list and push it onto the command queue
|
||||||
|
ID3D12GraphicsCommandList_Close(cmd_list);
|
||||||
|
ID3D12CommandQueue_ExecuteCommandLists(r_d3d12_state->direct_command_queue, 1, (ID3D12CommandList**)&cmd_list);
|
||||||
|
|
||||||
|
IDXGISwapChain3_Present(r_window->swapchain, 1, 0);
|
||||||
|
|
||||||
|
// Fence until gpu finishes work
|
||||||
|
r_d3d12_wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,8 +17,17 @@
|
|||||||
typedef struct R_D3D12_Window R_D3D12_Window;
|
typedef struct R_D3D12_Window R_D3D12_Window;
|
||||||
struct R_D3D12_Window
|
struct R_D3D12_Window
|
||||||
{
|
{
|
||||||
R_D3D12_Window* next;
|
R_D3D12_Window* next;
|
||||||
IDXGISwapChain3* swap_chain;
|
|
||||||
|
// SwapChain and framebuffer
|
||||||
|
IDXGISwapChain3* swapchain;
|
||||||
|
ID3D12Resource* framebuffer[2];
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handles[2];
|
||||||
|
ID3D12DescriptorHeap* rtv_heap;
|
||||||
|
uint8 framebuffer_idx;
|
||||||
|
|
||||||
|
// last state
|
||||||
|
Vector2i last_resolution;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct R_D3D12_State R_D3D12_State;
|
typedef struct R_D3D12_State R_D3D12_State;
|
||||||
@@ -35,7 +44,14 @@ struct R_D3D12_State
|
|||||||
IDXGIAdapter1* dxgi_adapter;
|
IDXGIAdapter1* dxgi_adapter;
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
ID3D12CommandQueue* direct_command_queue;
|
ID3D12CommandQueue* direct_command_queue;
|
||||||
|
ID3D12CommandAllocator* command_allocators[2];
|
||||||
|
ID3D12GraphicsCommandList* command_list;
|
||||||
|
|
||||||
|
// Fence
|
||||||
|
ID3D12Fence* fence;
|
||||||
|
uint64 fence_value;
|
||||||
|
HANDLE fence_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
@@ -49,3 +65,8 @@ global read_only R_D3D12_Window r_d3d12_nil_window = { &r_d3d12_nil_window };
|
|||||||
|
|
||||||
internal R_D3D12_Window* r_d3d12_window_from_handle(R_Handle handle);
|
internal R_D3D12_Window* r_d3d12_window_from_handle(R_Handle handle);
|
||||||
internal R_Handle r_d3d12_handle_from_window(R_D3D12_Window* window);
|
internal R_Handle r_d3d12_handle_from_window(R_D3D12_Window* window);
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Wait Function
|
||||||
|
|
||||||
|
internal void r_d3d12_wait();
|
||||||
@@ -21,3 +21,10 @@ void r_shutdown();
|
|||||||
|
|
||||||
R_Handle r_window_equip(WM_Window window);
|
R_Handle r_window_equip(WM_Window window);
|
||||||
void r_window_unequip(WM_Window window, R_Handle window_equip);
|
void r_window_unequip(WM_Window window, R_Handle window_equip);
|
||||||
|
|
||||||
|
// frame markers
|
||||||
|
|
||||||
|
void r_begin_frame();
|
||||||
|
void r_end_frame();
|
||||||
|
void r_window_begin_frame(WM_Window window, R_Handle window_equip);
|
||||||
|
void r_window_end_frame(WM_Window window, R_Handle window_equip);
|
||||||
Reference in new issue
Block a user