command buffer mapping

This commit is contained in:
jacob 2025-06-19 15:58:20 -05:00
parent 4313b1c768
commit 8ff4ec4a12
3 changed files with 81 additions and 136 deletions

View File

@ -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, " \

View File

@ -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) }) \
)
/* ========================== *

View File

@ -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);