From acc1fd69f1de1f3a534180ce3bbd1e4ae90c8ea5 Mon Sep 17 00:00:00 2001 From: jacob Date: Mon, 23 Jun 2025 14:26:41 -0500 Subject: [PATCH] texture upload test --- src/config.h | 2 +- src/gp.h | 14 +- src/gp_dx12.c | 416 +++++++++++++++++++++++++++++++------------------- 3 files changed, 268 insertions(+), 164 deletions(-) diff --git a/src/config.h b/src/config.h index cf08c73b..3b07856b 100644 --- a/src/config.h +++ b/src/config.h @@ -96,4 +96,4 @@ #define AUDIO_ENABLED 0 #define VSYNC_ENABLED 0 -#define USER_FPS_LIMIT 30 +#define USER_FPS_LIMIT 300 diff --git a/src/gp.h b/src/gp.h index 4600a14c..d9e68178 100644 --- a/src/gp.h +++ b/src/gp.h @@ -58,7 +58,7 @@ void gp_texture_clear(struct gp_handle target_texture, u32 clear_color); struct v2i32 gp_texture_get_size(struct gp_handle texture); /* ========================== * - * Cmd buffer + * Flow * ========================== */ struct gp_indices { @@ -109,14 +109,6 @@ struct gp_cmd_params { }; }; -struct gp_handle gp_flow_alloc(void); - -void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_params params); - -/* ========================== * - * Dispatch - * ========================== */ - struct gp_dispatch_params { struct gp_handle flow; struct gp_handle draw_target; @@ -124,6 +116,10 @@ struct gp_dispatch_params { struct xform draw_target_view; }; +struct gp_handle gp_flow_alloc(void); + +void gp_push_cmd(struct gp_handle gp_flow, struct gp_cmd_params params); + void gp_dispatch(struct gp_dispatch_params params); /* ========================== * diff --git a/src/gp_dx12.c b/src/gp_dx12.c index db50f9c5..9b472e61 100644 --- a/src/gp_dx12.c +++ b/src/gp_dx12.c @@ -89,6 +89,7 @@ struct pipeline_error { }; struct command_queue { + D3D12_COMMAND_LIST_TYPE type; ID3D12CommandQueue *cq; struct arena *arena; struct sys_mutex *mutex; @@ -102,8 +103,8 @@ struct command_queue { struct command_list { struct command_queue *cq; - struct ID3D12GraphicsCommandList *cl; struct ID3D12CommandAllocator *ca; + struct ID3D12GraphicsCommandList *cl; struct command_descriptor_heap *first_command_descriptor_heap; struct command_buffer *first_command_buffer; @@ -1368,71 +1369,6 @@ INTERNAL enum D3D12_RESOURCE_STATES dx12_resource_barrier(ID3D12GraphicsCommandL return old_state; } -struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data) -{ - LOCAL_PERSIST const DXGI_FORMAT formats[] = { - [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = DXGI_FORMAT_R8G8B8A8_UNORM, - [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB - }; - - DXGI_FORMAT dxgi_format = 0; - if (format < (i32)ARRAY_COUNT(formats)) { - dxgi_format = formats[format]; - } - if (format == 0) { - sys_panic(LIT("Tried to create texture with unknown format")); - } - - enum dx12_resource_view_flags view_flags = DX12_RESOURCE_VIEW_FLAG_SRV; - - D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; - heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; - heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - - D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - - D3D12_RESOURCE_DESC desc = ZI; - desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - desc.Format = dxgi_format; - desc.Alignment = 0; - desc.Width = size.x; - desc.Height = size.y; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - if (flags & GP_TEXTURE_FLAG_TARGETABLE) { - desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; - view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV; - } - - D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_COPY_DEST; - - struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags); - r->texture_size = size; - - (UNUSED)initial_data; - - return handle_alloc(DX12_HANDLE_KIND_RESOURCE, r); -} - -void gp_texture_clear(struct gp_handle target_resource, u32 clear_color) -{ - (UNUSED)target_resource; - (UNUSED)clear_color; -} - -struct v2i32 gp_texture_get_size(struct gp_handle resource) -{ - struct v2i32 res = ZI; - struct dx12_resource *dx12_resource = handle_get_data(resource, DX12_HANDLE_KIND_RESOURCE); - if (dx12_resource) { - res = dx12_resource->texture_size; - } - return res; -} - /* ========================== * * Command queue * ========================== */ @@ -1445,8 +1381,8 @@ INTERNAL struct command_queue *command_queue_alloc(enum D3D12_COMMAND_LIST_TYPE cq = arena_push(arena, struct command_queue); cq->arena = arena; } - cq->mutex = sys_mutex_alloc(); + cq->type = type; D3D12_COMMAND_QUEUE_DESC desc = ZI; desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; @@ -1522,12 +1458,12 @@ INTERNAL struct command_list *command_list_open(struct command_queue *cq) cl->cl = old_cl; cl->ca = old_ca; } else { - hr = ID3D12Device_CreateCommandAllocator(G.device, D3D12_COMMAND_LIST_TYPE_DIRECT, &IID_ID3D12CommandAllocator, (void **)&cl->ca); + hr = ID3D12Device_CreateCommandAllocator(G.device, cq->type, &IID_ID3D12CommandAllocator, (void **)&cl->ca); if (FAILED(hr)) { sys_panic(LIT("Failed to create command allocator")); } - hr = ID3D12Device_CreateCommandList(G.device, 0, D3D12_COMMAND_LIST_TYPE_DIRECT, cl->ca, NULL, &IID_ID3D12GraphicsCommandList, (void **)&cl->cl); + hr = ID3D12Device_CreateCommandList(G.device, 0, cq->type, cl->ca, NULL, &IID_ID3D12GraphicsCommandList, (void **)&cl->cl); if (FAILED(hr)) { sys_panic(LIT("Failed to create command list")); } @@ -1553,7 +1489,7 @@ INTERNAL struct command_list *command_list_open(struct command_queue *cq) } /* TODO: Allow multiple command list submissions */ -INTERNAL void command_list_close(struct command_list *cl) +INTERNAL u64 command_list_close(struct command_list *cl) { struct command_queue *cq = cl->cq; @@ -1614,6 +1550,8 @@ INTERNAL void command_list_close(struct command_list *cl) cq->last_submitted_command_list = cl; sys_mutex_unlock(&lock); } + + return target_fence_value; } /* ========================== * @@ -1825,6 +1763,177 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl return cb; } +/* ========================== * + * Texture + * ========================== */ + +struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data) +{ + struct dxgi_format_info { DXGI_FORMAT format; u32 size; }; + LOCAL_PERSIST const struct dxgi_format_info formats[] = { + [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM] = { DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, + [GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB] = { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, 4 } + }; + + DXGI_FORMAT dxgi_format = ZI; + u32 pixel_size = 0; + if (format < (i32)ARRAY_COUNT(formats)) { + dxgi_format = formats[format].format; + pixel_size = formats[format].size; + ASSERT(dxgi_format != 0); + ASSERT(pixel_size != 0); + } + if (format == 0) { + sys_panic(LIT("Tried to create texture with unknown format")); + } + + enum dx12_resource_view_flags view_flags = DX12_RESOURCE_VIEW_FLAG_SRV; + + D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT }; + heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + + D3D12_RESOURCE_DESC desc = ZI; + desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + desc.Format = dxgi_format; + desc.Alignment = 0; + desc.Width = size.x; + desc.Height = size.y; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + if (flags & GP_TEXTURE_FLAG_TARGETABLE) { + desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV; + } + + D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_COPY_DEST; + + struct dx12_resource *r = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags); + r->texture_size = size; + + /* Upload texture */ + if (initial_data) { + u64 upload_size = 0; + u64 upload_row_size = 0; + u32 upload_num_rows = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT footprint = ZI; + ID3D12Device_GetCopyableFootprints(G.device, &desc, 0, 1, 0, &footprint, &upload_num_rows, &upload_row_size, &upload_size); + + /* Create temp upload heap */ + struct dx12_resource *upload = NULL; + { + enum dx12_resource_view_flags upload_view_flags = DX12_RESOURCE_VIEW_FLAG_NONE; + + D3D12_HEAP_PROPERTIES upload_heap_props = { .Type = D3D12_HEAP_TYPE_UPLOAD }; + upload_heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + upload_heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_HEAP_FLAGS upload_heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + + D3D12_RESOURCE_DESC upload_desc = ZI; + upload_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + upload_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + upload_desc.Format = DXGI_FORMAT_UNKNOWN; + upload_desc.Alignment = 0; + upload_desc.Width = upload_size; + upload_desc.Height = 1; + upload_desc.DepthOrArraySize = 1; + upload_desc.MipLevels = 1; + upload_desc.SampleDesc.Count = 1; + upload_desc.SampleDesc.Quality = 0; + D3D12_RESOURCE_STATES upload_initial_state = D3D12_RESOURCE_STATE_GENERIC_READ; + + /* FIXME: Release */ + upload = dx12_resource_alloc(upload_heap_props, upload_heap_flags, upload_desc, upload_initial_state, upload_view_flags); + + /* Copy to upload heap */ +#if 0 + /* FIXME: Copy based on footprint */ + { + D3D12_RANGE read_range = ZI; + void *dst = NULL; + HRESULT hr = ID3D12Resource_Map(upload->resource, 0, &read_range, &dst); + if (FAILED(hr) || !dst) { + /* TODO: Don't panic */ + sys_panic(LIT("Failed to map texture upload resource")); + } + MEMCPY(dst, initial_data, size.x * size.y * pixel_size); + ID3D12Resource_Unmap(upload->resource, 0, NULL); + } +#else + /* FIXME: Copy based on footprint */ + { + D3D12_RANGE read_range = ZI; + void *mapped = NULL; + HRESULT hr = ID3D12Resource_Map(upload->resource, 0, &read_range, &mapped); + if (FAILED(hr) || !mapped) { + /* TODO: Don't panic */ + sys_panic(LIT("Failed to map texture upload resource")); + } + u8 *dst = (u8 *)mapped + footprint.Offset; + u8 *src = initial_data; + for (u32 y = 0; y < upload_num_rows; ++y) { + memcpy(dst + y * footprint.Footprint.RowPitch, src + y * size.x * pixel_size, size.x * pixel_size); + } + ID3D12Resource_Unmap(upload->resource, 0, NULL); + } +#endif + } + + /* Copy from upload heap to texture */ + struct command_queue *cq = G.cq_copy_background; + struct command_list *cl = command_list_open(cq); + { + D3D12_TEXTURE_COPY_LOCATION dst_loc = { + .pResource = r->resource, + .Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, + .SubresourceIndex = 0, + }; + + D3D12_TEXTURE_COPY_LOCATION src_loc = { + .pResource = upload->resource, + .Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT, + .PlacedFootprint = footprint, + }; + + ID3D12GraphicsCommandList_CopyTextureRegion(cl->cl, &dst_loc, 0, 0, 0, &src_loc, NULL); + /* FIXME: Better barrier? */ + //dx12_resource_barrier(cl->cl, r, D3D12_RESOURCE_STATE_ALL_SHADER_RESOURCE); + } + u64 fence_target = command_list_close(cl); + + /* Wait */ + /* TODO: Return async waitable to caller */ + HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); + ID3D12Fence_SetEventOnCompletion(cq->fence, fence_target, event); + WaitForSingleObject(event, INFINITE); + CloseHandle(event); + } + + return handle_alloc(DX12_HANDLE_KIND_RESOURCE, r); +} + +void gp_texture_clear(struct gp_handle target_resource, u32 clear_color) +{ + (UNUSED)target_resource; + (UNUSED)clear_color; +} + +struct v2i32 gp_texture_get_size(struct gp_handle resource) +{ + struct v2i32 res = ZI; + struct dx12_resource *dx12_resource = handle_get_data(resource, DX12_HANDLE_KIND_RESOURCE); + if (dx12_resource) { + res = dx12_resource->texture_size; + } + return res; +} + /* ========================== * * Dispatch * ========================== */ @@ -1842,98 +1951,98 @@ void gp_dispatch(struct gp_dispatch_params params) __prof; struct flow *flow = handle_get_data(params.flow, DX12_HANDLE_KIND_FLOW); - struct dx12_resource *target = handle_get_data(params.draw_target, DX12_HANDLE_KIND_RESOURCE); - - struct command_queue *cq = G.cq_direct; - struct command_list *cl = command_list_open(cq); - - /* Upload dummmy vert & index buffer */ - /* TODO: Make these static */ - /* Dummy vertex buffer */ - LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, STRING(0, 0)); - struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, STRING_FROM_ARRAY(quad_indices)); - D3D12_VERTEX_BUFFER_VIEW dummy_vertex_buffer_view = ZI; - dummy_vertex_buffer_view.BufferLocation = dummy_vertex_buffer->resource->gpu_address; - D3D12_INDEX_BUFFER_VIEW quad_index_buffer_view = ZI; - quad_index_buffer_view.BufferLocation = quad_index_buffer->resource->gpu_address; - quad_index_buffer_view.Format = DXGI_FORMAT_R16_UINT; - quad_index_buffer_view.SizeInBytes = sizeof(quad_indices); - - /* Upload instance buffer */ - struct command_buffer *instance_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_instances_arena)); - - /* Upload descriptor heap */ - struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); - - /* Viewport */ - struct rect viewport = params.draw_target_viewport; - struct D3D12_VIEWPORT d3d12_viewport = ZI; - d3d12_viewport.TopLeftX = viewport.x; - d3d12_viewport.TopLeftY = viewport.y; - d3d12_viewport.Width = viewport.width; - d3d12_viewport.Height = viewport.height; - d3d12_viewport.MinDepth = 0.0f; - d3d12_viewport.MaxDepth = 1.0f; - - /* Scissor */ - D3D12_RECT d3d12_scissor = ZI; - d3d12_scissor.left = viewport.x; - d3d12_scissor.top = viewport.y; - d3d12_scissor.right = viewport.x + viewport.width; - d3d12_scissor.bottom = viewport.y + viewport.height; - - struct mat4x4 vp_matrix = calculate_vp(params.draw_target_view, viewport.width, viewport.height); - - /* Create temporary descriptor heap */ - /* NOTE: This should always occur after buffers are submitted */ /* Material pass */ + struct command_list *cl = command_list_open(G.cq_direct); { - //struct pipeline *pipeline = dx12_get_pipeline(pipeline_scope, LIT("material")); - struct pipeline *pipeline = &G.test_pipeline; - u32 instance_count = instance_buffer->size / sizeof(struct sh_material_instance); + struct dx12_resource *target = handle_get_data(params.draw_target, DX12_HANDLE_KIND_RESOURCE); - /* Bind pipeline */ - ID3D12GraphicsCommandList_SetPipelineState(cl->cl, pipeline->pso); - ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, pipeline->rootsig); + /* Upload dummmy vert & index buffer */ + /* TODO: Make these static */ + /* Dummy vertex buffer */ + LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; + struct command_buffer *dummy_vertex_buffer = command_list_push_buffer(cl, STRING(0, 0)); + struct command_buffer *quad_index_buffer = command_list_push_buffer(cl, STRING_FROM_ARRAY(quad_indices)); + D3D12_VERTEX_BUFFER_VIEW dummy_vertex_buffer_view = ZI; + dummy_vertex_buffer_view.BufferLocation = dummy_vertex_buffer->resource->gpu_address; + D3D12_INDEX_BUFFER_VIEW quad_index_buffer_view = ZI; + quad_index_buffer_view.BufferLocation = quad_index_buffer->resource->gpu_address; + quad_index_buffer_view.Format = DXGI_FORMAT_R16_UINT; + quad_index_buffer_view.SizeInBytes = sizeof(quad_indices); - /* Fill & bind constant buffer */ - struct sh_material_constants constants = ZI; - constants.projection = sh_float4x4_from_mat4x4(vp_matrix); - constants.instance_offset = sh_uint_from_u32(0); - struct command_buffer *constant_buffer = command_list_push_buffer(cl, STRING_FROM_STRUCT(&constants)); - ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(cl->cl, 0, constant_buffer->resource->gpu_address); + /* Upload instance buffer */ + struct command_buffer *instance_buffer = command_list_push_buffer(cl, STRING_FROM_ARENA(flow->material_instances_arena)); - /* Bind instance buffer */ - ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->resource->gpu_address); + /* Upload descriptor heap */ + struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); - /* Bind descriptor heap */ - ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; - ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps); - ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 2, descriptor_heap->gp_handle); + /* Viewport */ + struct rect viewport = params.draw_target_viewport; + struct D3D12_VIEWPORT d3d12_viewport = ZI; + d3d12_viewport.TopLeftX = viewport.x; + d3d12_viewport.TopLeftY = viewport.y; + d3d12_viewport.Width = viewport.width; + d3d12_viewport.Height = viewport.height; + d3d12_viewport.MinDepth = 0.0f; + d3d12_viewport.MaxDepth = 1.0f; - /* Setup Rasterizer State */ - ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &d3d12_viewport); - ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &d3d12_scissor); + /* Scissor */ + D3D12_RECT d3d12_scissor = ZI; + d3d12_scissor.left = viewport.x; + d3d12_scissor.top = viewport.y; + d3d12_scissor.right = viewport.x + viewport.width; + d3d12_scissor.bottom = viewport.y + viewport.height; - /* Transition render target */ - enum D3D12_RESOURCE_STATES old_state = dx12_resource_barrier(cl->cl, target, D3D12_RESOURCE_STATE_RENDER_TARGET); - ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &target->rtv_descriptor->handle, false, NULL); - //f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; - //ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rtvHandle, clearColor, 0, nullptr); + struct mat4x4 vp_matrix = calculate_vp(params.draw_target_view, viewport.width, viewport.height); - /* Draw */ - ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &dummy_vertex_buffer_view); - ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &quad_index_buffer_view); - ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0); + /* Create temporary descriptor heap */ + /* NOTE: This should always occur after buffers are submitted */ - /* Reset render target */ - dx12_resource_barrier(cl->cl, target, old_state); + /* Push commands */ + { + //struct pipeline *pipeline = dx12_get_pipeline(pipeline_scope, LIT("material")); + struct pipeline *pipeline = &G.test_pipeline; + u32 instance_count = instance_buffer->size / sizeof(struct sh_material_instance); + + /* Bind pipeline */ + ID3D12GraphicsCommandList_SetPipelineState(cl->cl, pipeline->pso); + ID3D12GraphicsCommandList_SetGraphicsRootSignature(cl->cl, pipeline->rootsig); + + /* Fill & bind constant buffer */ + struct sh_material_constants constants = ZI; + constants.projection = sh_float4x4_from_mat4x4(vp_matrix); + constants.instance_offset = sh_uint_from_u32(0); + struct command_buffer *constant_buffer = command_list_push_buffer(cl, STRING_FROM_STRUCT(&constants)); + ID3D12GraphicsCommandList_SetGraphicsRootConstantBufferView(cl->cl, 0, constant_buffer->resource->gpu_address); + + /* Bind instance buffer */ + ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->resource->gpu_address); + + /* Bind descriptor heap */ + ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; + ID3D12GraphicsCommandList_SetDescriptorHeaps(cl->cl, ARRAY_COUNT(heaps), heaps); + ID3D12GraphicsCommandList_SetGraphicsRootDescriptorTable(cl->cl, 2, descriptor_heap->gp_handle); + + /* Setup Rasterizer State */ + ID3D12GraphicsCommandList_RSSetViewports(cl->cl, 1, &d3d12_viewport); + ID3D12GraphicsCommandList_RSSetScissorRects(cl->cl, 1, &d3d12_scissor); + + /* Transition render target */ + enum D3D12_RESOURCE_STATES old_state = dx12_resource_barrier(cl->cl, target, D3D12_RESOURCE_STATE_RENDER_TARGET); + ID3D12GraphicsCommandList_OMSetRenderTargets(cl->cl, 1, &target->rtv_descriptor->handle, false, NULL); + //f32 clear_color[] = { 0.0f, 0.0f, 0.0f, 0.0f }; + //ID3D12GraphicsCommandList_ClearRenderTargetView(cl->cl, rtvHandle, clearColor, 0, nullptr); + + /* Draw */ + ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &dummy_vertex_buffer_view); + ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &quad_index_buffer_view); + ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_count, 0, 0, 0); + + /* Reset render target */ + dx12_resource_barrier(cl->cl, target, old_state); + } } - - /* Execute command list */ command_list_close(cl); /* Reset flow */ @@ -2083,10 +2192,8 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src, if (!flow.gen) { flow = gp_flow_alloc(); } -#if 0 struct gp_handle dst_texture_handle = handle_alloc(DX12_HANDLE_KIND_RESOURCE, dst); struct gp_handle src_texture_handle = handle_alloc(DX12_HANDLE_KIND_RESOURCE, src); -#endif /* Draw texture to backbuffer texture */ /* TODO: Specialized blit shader */ @@ -2108,7 +2215,7 @@ INTERNAL void present_blit(struct dx12_resource *dst, struct dx12_resource *src, void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, struct gp_handle texture, struct xform texture_xf, i32 vsync) { - sys_sleep(0.1); + //sys_sleep(0.1); #if 0 /* FIXME: Remove this */ @@ -2128,13 +2235,14 @@ void gp_present(struct sys_window *window, struct v2i32 backbuffer_resolution, s CloseHandle(event); #endif - struct dx12_resource *backbuffer_resource = update_swapchain(window, backbuffer_resolution); struct dx12_resource *texture_resource = handle_get_data(texture, DX12_HANDLE_KIND_RESOURCE); /* Blit */ present_blit(backbuffer_resource, texture_resource, texture_xf); + //sys_sleep(0.1); + /* Present */ HRESULT hr = IDXGISwapChain3_Present(G.swapchain, 0, 0); if (!SUCCEEDED(hr)) {