diff --git a/res/sh/material.hlsl b/res/sh/material.hlsl index 6ede562f..ffee626f 100644 --- a/res/sh/material.hlsl +++ b/res/sh/material.hlsl @@ -7,7 +7,7 @@ #define ROOTSIG \ "CBV(b0), " \ "SRV(t0), " \ - "DescriptorTable(SRV(t1, numDescriptors = unbounded)), " \ + "DescriptorTable(SRV(t1, numDescriptors = unbounded, flags = DESCRIPTORS_VOLATILE)), " \ "StaticSampler(s0, " \ "filter = FILTER_MIN_MAG_MIP_POINT, " \ "addressU = TEXTURE_ADDRESS_CLAMP, " \ diff --git a/src/common.h b/src/common.h index b702881a..bc3be8f9 100644 --- a/src/common.h +++ b/src/common.h @@ -496,9 +496,7 @@ struct sprite_tag { ( \ /* Must be array */ \ ASSERT(IS_ARRAY(a)), \ - /* Must be array of bytes */ \ - ASSERT(sizeof((a)[0]) == sizeof(u8)), \ - ((struct string) { .len = ARRAY_COUNT(a), .text = (u8 *)(a) }) \ + ((struct string) { .len = sizeof(a), .text = (u8 *)(a) }) \ ) /* ========================== * diff --git a/src/gp_dx12.c b/src/gp_dx12.c index 5b9c8336..2ab3088e 100644 --- a/src/gp_dx12.c +++ b/src/gp_dx12.c @@ -128,9 +128,8 @@ struct command_descriptor_heap { struct command_buffer { struct command_buffer_group *group; - struct dx12_resource *staging_resource; - struct dx12_resource *gpu_resource; - u64 count; + struct dx12_resource *resource; + u64 size; struct command_buffer *next_in_command_list; @@ -274,12 +273,6 @@ GLOBAL struct { u32 swapchain_frame_index; IDXGISwapChain3 *swapchain; struct dx12_resource *swapchain_resources[DX12_SWAPCHAIN_BUFFER_COUNT]; - - /* Dummy vertex buffer */ - struct dx12_resource *dummy_vertex_buffer; - struct dx12_resource *dummy_index_buffer; - D3D12_VERTEX_BUFFER_VIEW dummy_vertex_buffer_view; - D3D12_INDEX_BUFFER_VIEW quad_index_buffer_view; } G = ZI, DEBUG_ALIAS(G, G_gp_dx12); /* ========================== * @@ -325,66 +318,7 @@ struct gp_startup_receipt gp_startup(struct work_startup_receipt *work_sr, struc dx12_init_pipelines(); /* Init dummy buffers */ -#if 0 - { - 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 - }; - - 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.Alignment = 0; - desc.Width = size.x; - desc.Height = size.y; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.SampleDesc.Count = 1; - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - 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); - - //G.dummy_vertex_buffer = dx12_resource_alloc( - - - - - - /* Dummy vertex buffer */ - u8 dummy_data[16] = ZI; - D3D11_BUFFER_DESC vdesc = ZI; - vdesc.Usage = D3D11_USAGE_IMMUTABLE; - vdesc.ByteWidth = sizeof(dummy_data); - vdesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - D3D11_SUBRESOURCE_DATA dummy_data_subres = ZI; - dummy_data_subres.pSysMem = dummy_data; - G.dummy_vertex_buffer = dx11_buffer_alloc(vdesc, &dummy_data_subres); - - /* Quad index buffer */ - LOCAL_PERSIST u16 quad_indices[6] = { 0, 1, 2, 0, 2, 3 }; - D3D11_BUFFER_DESC idesc = ZI; - idesc.Usage = D3D11_USAGE_IMMUTABLE; - idesc.ByteWidth = sizeof(quad_indices); - idesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - D3D11_SUBRESOURCE_DATA idata = ZI; - idata.pSysMem = quad_indices; - G.quad_index_buffer = dx11_buffer_alloc(idesc, &idata); - } -#endif + /* TODO */ /* Register callbacks */ @@ -1475,14 +1409,14 @@ struct gp_handle gp_texture_alloc(enum gp_texture_format format, u32 flags, stru 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.Format = dxgi_format; desc.SampleDesc.Count = 1; - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; if (flags & GP_TEXTURE_FLAG_TARGETABLE) { desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; view_flags |= DX12_RESOURCE_VIEW_FLAG_RTV; @@ -1811,8 +1745,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl /* Allocate buffer */ struct command_buffer_group *cb_group = NULL; struct command_buffer *cb = NULL; - struct dx12_resource *old_staging_resource = NULL; - struct dx12_resource *old_gpu_resource = NULL; + struct dx12_resource *resource = NULL; { struct sys_lock lock = sys_mutex_lock_e(G.command_buffers_mutex); @@ -1837,8 +1770,7 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl } if (cb) { /* Remove from submitted list */ - old_staging_resource = cb->staging_resource; - old_gpu_resource = cb->gpu_resource; + resource = cb->resource; struct command_buffer *prev = cb->prev_submitted; struct command_buffer *next = cb->next_submitted; if (prev) { @@ -1859,59 +1791,47 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl } MEMZERO_STRUCT(cb); cb->group = cb_group; + cb->size = data.len; - if (old_staging_resource) { - cb->staging_resource = old_staging_resource; - cb->gpu_resource = old_gpu_resource; + if (resource) { + cb->resource = resource; } else { - /* Create staging resource */ - { -#if 0 - 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 - }; + enum dx12_resource_view_flags view_flags = DX12_RESOURCE_VIEW_FLAG_NONE; - 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")); - } + D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_UPLOAD }; + heap_props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heap_props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; - enum dx12_resource_view_flags view_flags = DX12_RESOURCE_VIEW_FLAG_NONE; + D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; - 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_RESOURCE_DESC desc = ZI; + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.Alignment = 0; + desc.Width = size; + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.SampleDesc.Count = 1; - D3D12_HEAP_FLAGS heap_flags = D3D12_HEAP_FLAG_CREATE_NOT_ZEROED; + D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_GENERIC_READ; - D3D12_RESOURCE_DESC desc = ZI; - desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; - desc.Alignment = 0; - desc.Width = size.x; - desc.Height = size.y; - desc.DepthOrArraySize = 1; - desc.MipLevels = 1; - desc.Format = dxgi_format; - desc.SampleDesc.Count = 1; - desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; - - D3D12_RESOURCE_STATES initial_state = D3D12_RESOURCE_STATE_GENERIC_READ; - - - cb->staging_resource = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags); -#endif - } - /* Create gpu resource */ + cb->resource = dx12_resource_alloc(heap_props, heap_flags, desc, initial_state, view_flags); } - - /* Copy & submit data */ - /* FIXME */ - (UNUSED)data; + /* Copy data to resource */ + { + D3D12_RANGE read_range = ZI; + void *dst = NULL; + HRESULT hr = ID3D12Resource_Map(cb->resource->resource, 0, &read_range, &dst); + if (FAILED(hr) || !dst) { + /* TODO: Don't panic */ + sys_panic(LIT("Failed to map command buffer resource")); + } + MEMCPY(dst, data.text, data.len); + ID3D12Resource_Unmap(cb->resource->resource, 0, NULL); + } /* Insert into command list */ cb->next_in_command_list = cl->first_command_buffer; @@ -1924,6 +1844,14 @@ INTERNAL struct command_buffer *command_list_push_buffer(struct command_list *cl * Dispatch * ========================== */ + /* Calculate the view projection matrix */ +INLINE struct mat4x4 calculate_vp(struct xform view, f32 viewport_width, f32 viewport_height) +{ + struct mat4x4 projection = mat4x4_from_ortho(0.0, viewport_width, viewport_height, 0.0, -1.0, 1.0); + struct mat4x4 view4x4 = mat4x4_from_xform(view); + return mat4x4_mul(projection, view4x4); +} + void gp_dispatch(struct gp_dispatch_params params) { __prof; @@ -1934,7 +1862,25 @@ void gp_dispatch(struct gp_dispatch_params params) 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(plan->material_instances_arena)); + arena_reset(plan->material_instances_arena); + + /* Upload descriptor heap */ struct command_descriptor_heap *descriptor_heap = command_list_push_descriptor_heap(cl, G.cbv_srv_uav_heap); /* Viewport */ @@ -1954,29 +1900,30 @@ void gp_dispatch(struct gp_dispatch_params params) 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 */ - //if (plan->material_instances->count > 0) { - if ((false)) { + { //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); - /* Bind constant buffer */ -#if 0 - struct dx12_buffer *constant_buffer = plan->constant_buffer; - if (!constant_buffer) { - constant_buffer = dx12_buffer_alloc(); - } -#endif + /* 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->gp_handle); + ID3D12GraphicsCommandList_SetGraphicsRootShaderResourceView(cl->cl, 1, instance_buffer->resource->gpu_address); /* Bind descriptor heap */ ID3D12DescriptorHeap *heaps[] = { descriptor_heap->heap }; @@ -1995,9 +1942,9 @@ void gp_dispatch(struct gp_dispatch_params params) /* Draw */ ID3D12GraphicsCommandList_IASetPrimitiveTopology(cl->cl, D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - ID3D12GraphicsCommandList_IASetVertexBuffers(cl->cl, 0, 1, &G.dummy_vertex_buffer_view); - ID3D12GraphicsCommandList_IASetIndexBuffer(cl->cl, &G.quad_index_buffer_view); - ID3D12GraphicsCommandList_DrawIndexedInstanced(cl->cl, 6, instance_buffer->count, 0, 0, 0); + 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);