simple clear color from d3d12, but with debug layer errors and warnings
This commit is contained in:
parent
d73c450d21
commit
f488b22239
11
anton_render.raddb_proj
Normal file
11
anton_render.raddb_proj
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// raddbg 0.9.17 project file
|
||||||
|
|
||||||
|
recent_file: path: "src/render/d3d12/render_d3d12.c"
|
||||||
|
recent_file: path: "src/os/win32/os_gfx_win32.c"
|
||||||
|
recent_file: path: "src/main.c"
|
||||||
|
target:
|
||||||
|
{
|
||||||
|
executable: "build/program.exe"
|
||||||
|
working_directory: build
|
||||||
|
enabled: 1
|
||||||
|
}
|
||||||
@ -38,7 +38,7 @@ entry_point()
|
|||||||
r_init();
|
r_init();
|
||||||
//test_arena(arena);
|
//test_arena(arena);
|
||||||
|
|
||||||
r_trigger_debug_message();
|
//r_trigger_debug_message();
|
||||||
//r_log_debug_messages();
|
//r_log_debug_messages();
|
||||||
|
|
||||||
// Main program loop
|
// Main program loop
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
//~
|
//~
|
||||||
|
|
||||||
#define D3D12_ERROR(msg, ...) LOG("D3D12 ERROR (anton): "); LOG(msg, __VA_ARGS__); Trap();
|
#define D3D12_ERROR(msg, ...) LOG("D3D12 ERROR (anton): "); LOG(msg, __VA_ARGS__); Trap();
|
||||||
#define D3D12_CHECK(hr) if(FAILED((hr))) { Trap(); }
|
#define D3D12_CHECK(hr, msg) if(FAILED((hr))) { D3D12_ERROR(msg, __VA_ARGS__) }
|
||||||
|
|
||||||
#define D3D12_RELEASE(res) if( (res) && (res)->lpVtbl) { (res)->lpVtbl->Release((res)); (res) = 0; }
|
#define D3D12_RELEASE(res) if( (res) && (res)->lpVtbl) { (res)->lpVtbl->Release((res)); (res) = 0; }
|
||||||
|
|
||||||
@ -18,16 +18,18 @@ global R_D3D12_State *r_d3d12_state = 0;
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
//~
|
//~
|
||||||
|
|
||||||
|
|
||||||
// D3D12 initialisiation
|
|
||||||
internal void
|
internal void
|
||||||
r_init()
|
r_init()
|
||||||
{
|
{
|
||||||
Arena *arena = arena_alloc();
|
Arena *arena = arena_alloc();
|
||||||
r_d3d12_state = push_array(arena, R_D3D12_State, 1);
|
r_d3d12_state = push_array(arena, R_D3D12_State, 1);
|
||||||
r_d3d12_state->arena = arena;
|
r_d3d12_state->arena = arena;
|
||||||
|
r_d3d12_state->window_handle = g_win32_window_handle;
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Debug interface
|
||||||
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void**)&r_d3d12_state->debug);
|
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void**)&r_d3d12_state->debug);
|
||||||
if(SUCCEEDED(hr) && r_d3d12_state->debug )
|
if(SUCCEEDED(hr) && r_d3d12_state->debug )
|
||||||
{
|
{
|
||||||
@ -37,41 +39,195 @@ r_init()
|
|||||||
{
|
{
|
||||||
D3D12_ERROR("Failed to create D3D12 Debug interface \n");
|
D3D12_ERROR("Failed to create D3D12 Debug interface \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Create device
|
||||||
hr = D3D12CreateDevice(0,
|
hr = D3D12CreateDevice(0,
|
||||||
D3D_FEATURE_LEVEL_11_0,
|
D3D_FEATURE_LEVEL_11_0,
|
||||||
&IID_ID3D12Device,
|
&IID_ID3D12Device,
|
||||||
(void **)&r_d3d12_state->device);
|
(void **)&r_d3d12_state->device);
|
||||||
if(FAILED(hr))
|
D3D12_CHECK(hr, "Failed to create device\n");
|
||||||
{
|
|
||||||
D3D12_ERROR("Failed to create device \n");
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Create command queue
|
||||||
|
D3D12_COMMAND_QUEUE_DESC queue_desc = {
|
||||||
|
.Type = D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL,
|
||||||
|
.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE,
|
||||||
|
.NodeMask = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
ID3D12CommandQueue *command_queue;
|
||||||
|
hr = r_d3d12_state->device->lpVtbl->CreateCommandQueue(r_d3d12_state->device,
|
||||||
|
&queue_desc,
|
||||||
|
&IID_ID3D12CommandQueue,
|
||||||
|
(void**)&command_queue);
|
||||||
|
|
||||||
|
D3D12_CHECK(hr, "Failed to create command queue\n");
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Create DXGI factory
|
||||||
|
IDXGIFactory4 *factory;
|
||||||
|
hr = CreateDXGIFactory1(&IID_IDXGIFactory4, (void**)&factory);
|
||||||
|
D3D12_CHECK(hr, "Failed to create factory\n");
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Create Swapchain
|
||||||
|
|
||||||
|
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {
|
||||||
|
.Width = WINDOW_WIDTH_PX,
|
||||||
|
.Height = WINDOW_HEIGHT_PX,
|
||||||
|
.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
.Stereo = FALSE,
|
||||||
|
.SampleDesc = {1, 0},
|
||||||
|
.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT,
|
||||||
|
.BufferCount = 2,
|
||||||
|
.Scaling = DXGI_SCALING_STRETCH,
|
||||||
|
.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD,
|
||||||
|
.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED,
|
||||||
|
.Flags = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// We create a temporary SwapChain1 that is then upgraded to a SwapChain3.
|
||||||
|
IDXGISwapChain1* temp_swap_chain;
|
||||||
|
hr = factory->lpVtbl->CreateSwapChainForHwnd(factory,
|
||||||
|
(IUnknown*)command_queue,
|
||||||
|
r_d3d12_state->window_handle,
|
||||||
|
&swap_chain_desc,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&temp_swap_chain);
|
||||||
|
D3D12_CHECK(hr, "Failed to create temp swap chain \n");
|
||||||
|
|
||||||
|
hr = temp_swap_chain->lpVtbl->QueryInterface(temp_swap_chain,
|
||||||
|
&IID_IDXGISwapChain3,
|
||||||
|
(void**)&r_d3d12_state->swapchain);
|
||||||
|
D3D12_CHECK(hr, "Failed to upgrade to swapchain3\n");
|
||||||
|
temp_swap_chain->lpVtbl->Release(temp_swap_chain);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Create Render target view (RTV) descriptor heap
|
||||||
|
D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc = {
|
||||||
|
.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV,
|
||||||
|
.NumDescriptors = 2,
|
||||||
|
.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE,
|
||||||
|
.NodeMask = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ID3D12DescriptorHeap *rtv_heap;
|
||||||
|
hr = r_d3d12_state->device->lpVtbl->
|
||||||
|
CreateDescriptorHeap(r_d3d12_state->device,
|
||||||
|
&rtv_heap_desc,
|
||||||
|
&IID_ID3D12DescriptorHeap,
|
||||||
|
(void**)&rtv_heap);
|
||||||
|
D3D12_CHECK(hr, "Failed to create descriptor heap\n");
|
||||||
|
|
||||||
|
U32 rtv_descriptor_size = r_d3d12_state->device->lpVtbl->
|
||||||
|
GetDescriptorHandleIncrementSize(r_d3d12_state->device,
|
||||||
|
D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Create render target views
|
||||||
|
ID3D12Resource* render_targets[2];
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
|
||||||
|
// TODO(anton): This is probably not correct D3D12 API, but I might have an old SDK.
|
||||||
|
rtv_heap->lpVtbl->GetCPUDescriptorHandleForHeapStart(rtv_heap, &rtv_handle);
|
||||||
|
|
||||||
|
for (U32 i = 0; i < 2; ++i) {
|
||||||
|
r_d3d12_state->swapchain->lpVtbl->GetBuffer(r_d3d12_state->swapchain,
|
||||||
|
i,
|
||||||
|
&IID_ID3D12Resource,
|
||||||
|
(void**)&render_targets[i]);
|
||||||
|
r_d3d12_state->device->lpVtbl->
|
||||||
|
CreateRenderTargetView(r_d3d12_state->device,
|
||||||
|
render_targets[i],
|
||||||
|
0,
|
||||||
|
rtv_handle);
|
||||||
|
|
||||||
|
rtv_handle.ptr += rtv_descriptor_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Command allocator and command list
|
||||||
|
ID3D12CommandAllocator* cmd_allocator;
|
||||||
|
r_d3d12_state->device->lpVtbl->CreateCommandAllocator(r_d3d12_state->device,
|
||||||
|
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
&IID_ID3D12CommandAllocator,
|
||||||
|
(void**)&cmd_allocator);
|
||||||
|
|
||||||
|
ID3D12GraphicsCommandList* cmd_list;
|
||||||
|
r_d3d12_state->device->lpVtbl->CreateCommandList(r_d3d12_state->device,
|
||||||
|
0,
|
||||||
|
D3D12_COMMAND_LIST_TYPE_DIRECT,
|
||||||
|
cmd_allocator,
|
||||||
|
0,
|
||||||
|
&IID_ID3D12GraphicsCommandList,
|
||||||
|
(void**)&cmd_list);
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Fence and event
|
||||||
|
|
||||||
|
ID3D12Fence *fence;
|
||||||
|
U64 fence_value = 0;
|
||||||
|
hr = r_d3d12_state->device->lpVtbl->CreateFence(r_d3d12_state->device,
|
||||||
|
0,
|
||||||
|
D3D12_FENCE_FLAG_NONE,
|
||||||
|
&IID_ID3D12Fence,
|
||||||
|
(void**)&fence);
|
||||||
|
HANDLE fence_event = CreateEvent(0, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
// Record commands to clear screen
|
||||||
|
U32 frameIndex = r_d3d12_state->swapchain->lpVtbl->GetCurrentBackBufferIndex(r_d3d12_state->swapchain);
|
||||||
|
|
||||||
|
cmd_allocator->lpVtbl->Reset(cmd_allocator);
|
||||||
|
cmd_list->lpVtbl->Reset(cmd_list, cmd_allocator, 0);
|
||||||
|
|
||||||
|
D3D12_RESOURCE_BARRIER barrier = {
|
||||||
|
.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
|
||||||
|
.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE,
|
||||||
|
.Transition = {
|
||||||
|
.pResource = render_targets[frameIndex],
|
||||||
|
.StateBefore = D3D12_RESOURCE_STATE_PRESENT,
|
||||||
|
.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET,
|
||||||
|
.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
cmd_list->lpVtbl->ResourceBarrier(cmd_list, 1, &barrier);
|
||||||
|
|
||||||
|
D3D12_CPU_DESCRIPTOR_HANDLE currentRTV;
|
||||||
|
// TODO(anton): Probably wrong API due to old SDK...
|
||||||
|
rtv_heap->lpVtbl->GetCPUDescriptorHandleForHeapStart(rtv_heap, ¤tRTV);
|
||||||
|
currentRTV.ptr += frameIndex * rtv_descriptor_size;
|
||||||
|
|
||||||
|
F32 clearColor[4] = {0.1f, 0.2f, 0.3f, 1.0f};
|
||||||
|
cmd_list->lpVtbl->ClearRenderTargetView(cmd_list, currentRTV, clearColor, 0, 0);
|
||||||
|
|
||||||
|
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
||||||
|
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
||||||
|
cmd_list->lpVtbl->ResourceBarrier(cmd_list, 1, &barrier);
|
||||||
|
|
||||||
|
cmd_list->lpVtbl->Close(cmd_list);
|
||||||
|
|
||||||
|
// Execute and present
|
||||||
|
ID3D12CommandList* lists[] = { (ID3D12CommandList*)cmd_list };
|
||||||
|
command_queue->lpVtbl->ExecuteCommandLists(command_queue, 1, lists);
|
||||||
|
|
||||||
|
r_d3d12_state->swapchain->lpVtbl->Present(r_d3d12_state->swapchain, 1, 0);
|
||||||
|
|
||||||
|
// Wait for GPU
|
||||||
|
fence_value++;
|
||||||
|
command_queue->lpVtbl->Signal(command_queue, fence, fence_value);
|
||||||
|
if (fence->lpVtbl->GetCompletedValue(fence) < fence_value) {
|
||||||
|
fence->lpVtbl->SetEventOnCompletion(fence, fence_value, fence_event);
|
||||||
|
WaitForSingleObject(fence_event, INFINITE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//internal void
|
|
||||||
//r_log_debug_messages()
|
|
||||||
//{
|
|
||||||
// if(r_d3d12_state->info_queue)
|
|
||||||
// {
|
|
||||||
// UINT64 numMessages = r_d3d12_state->info_queue->lpVtbl->GetNumStoredMessages(r_d3d12_state->info_queue);
|
|
||||||
// for (UINT64 i = 0; i < numMessages; i++) {
|
|
||||||
// SIZE_T messageLength = 0;
|
|
||||||
// r_d3d12_state->info_queue->lpVtbl->GetMessage(r_d3d12_state->info_queue, i, NULL, &messageLength);
|
|
||||||
//
|
|
||||||
// D3D12_MESSAGE* message = (D3D12_MESSAGE*)malloc(messageLength);
|
|
||||||
// if (message) {
|
|
||||||
// r_d3d12_state->info_queue->lpVtbl->GetMessage(r_d3d12_state->info_queue, i, message, &messageLength);
|
|
||||||
// LOG("DX12 Debug: %s\n", message->pDescription);
|
|
||||||
// free(message);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// r_d3d12_state->info_queue->lpVtbl->ClearStoredMessages(r_d3d12_state->info_queue);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
r_trigger_debug_message()
|
r_trigger_debug_message()
|
||||||
{
|
{
|
||||||
@ -114,79 +270,8 @@ r_cleanup()
|
|||||||
|
|
||||||
D3D12_RELEASE(r_d3d12_state->device);
|
D3D12_RELEASE(r_d3d12_state->device);
|
||||||
D3D12_RELEASE(r_d3d12_state->debug);
|
D3D12_RELEASE(r_d3d12_state->debug);
|
||||||
|
D3D12_RELEASE(r_d3d12_state->swapchain);
|
||||||
|
|
||||||
|
|
||||||
arena_release(r_d3d12_state->arena);
|
arena_release(r_d3d12_state->arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
//internal LRESULT
|
|
||||||
//r_d3d12_create_swapchain(IDXGIFactory4 *factory)
|
|
||||||
//{
|
|
||||||
// LRESULT result = 0;
|
|
||||||
// HRESULT hr = 0;
|
|
||||||
//
|
|
||||||
// // Log window state
|
|
||||||
// RECT clientRect;
|
|
||||||
// GetClientRect(g_win32_window_handle, &clientRect);
|
|
||||||
// LOG("Swap chain creation - Window state: HWND %p, Visible %d, Client area %ldx%ld\n",
|
|
||||||
// g_win32_window_handle,
|
|
||||||
// IsWindowVisible(g_win32_window_handle),
|
|
||||||
// clientRect.right - clientRect.left,
|
|
||||||
// clientRect.bottom - clientRect.top);
|
|
||||||
//
|
|
||||||
// if (!IsWindowVisible(g_win32_window_handle)) {
|
|
||||||
// LOG("WARNING: Window not visible, attempting to show\n");
|
|
||||||
// ShowWindow(g_win32_window_handle, SW_SHOW);
|
|
||||||
// UpdateWindow(g_win32_window_handle);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (clientRect.right - clientRect.left == 0 || clientRect.bottom - clientRect.top == 0) {
|
|
||||||
// LOG("ERROR: Window has zero client area\n");
|
|
||||||
// result = 0;
|
|
||||||
// Trap();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// DXGI_SWAP_CHAIN_DESC1 swapDesc = {0};
|
|
||||||
// swapDesc.Width = WINDOW_WIDTH_PX;
|
|
||||||
// swapDesc.Height = WINDOW_HEIGHT_PX;
|
|
||||||
// swapDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
// swapDesc.SampleDesc.Count = 1;
|
|
||||||
// swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
// swapDesc.BufferCount = 2;
|
|
||||||
// swapDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
|
||||||
// swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
|
||||||
//
|
|
||||||
// LOG("Creating swap chain on service thread: %dx%d\n", swapDesc.Width, swapDesc.Height);
|
|
||||||
// IDXGISwapChain1* swapChain = 0;
|
|
||||||
// hr = factory->lpVtbl->CreateSwapChainForHwnd(
|
|
||||||
// factory,
|
|
||||||
// (IUnknown*)r_d3d12_state->device,
|
|
||||||
// g_win32_window_handle,
|
|
||||||
// &swapDesc,
|
|
||||||
// 0, 0,
|
|
||||||
// &swapChain
|
|
||||||
// );
|
|
||||||
// if (FAILED(hr)) {
|
|
||||||
// LOG("Failed to create swap chain in service thread: HRESULT 0x%X\n", hr);
|
|
||||||
// r_log_debug_messages();
|
|
||||||
// result = 0;
|
|
||||||
// } else {
|
|
||||||
// hr = swapChain->lpVtbl->QueryInterface(
|
|
||||||
// swapChain,
|
|
||||||
// &IID_IDXGISwapChain3,
|
|
||||||
// (void**)&r_d3d12_state->swapchain
|
|
||||||
// );
|
|
||||||
// swapChain->lpVtbl->Release(swapChain);
|
|
||||||
// if (FAILED(hr)) {
|
|
||||||
// LOG("Failed to query swap chain: HRESULT 0x%X\n", hr);
|
|
||||||
// r_log_debug_messages();
|
|
||||||
// Trap();
|
|
||||||
// result = 0;
|
|
||||||
// } else {
|
|
||||||
// result = 1;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return result;
|
|
||||||
//}
|
|
||||||
Loading…
Reference in New Issue
Block a user