From f2be1893447bc8ee0eebf23d2efc540d5fdd7fa8 Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 10 Mar 2026 23:50:13 -0500 Subject: [PATCH] working resourceless-gpu api --- src/gpu/gpu_dx12/gpu_dx12_core.c | 151 ++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 24 deletions(-) diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index 18aab93f..667e346e 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -1368,16 +1368,37 @@ void G_D12_ReleaseDescriptor(G_D12_Descriptor *descriptor) - -void G_D12_InitResourceDescriptor(G_D12_Descriptor *descriptor, G_D12_Resource *resource, RngI32 mips) -{ -} - void G_D12_InitRtvDescriptor(G_D12_Descriptor *descriptor, G_D12_Resource *resource, i32 mip) { - // FIXME: Impl + DXGI_FORMAT format = G_D12_DxgiFormatFromGpuFormat(resource->texture_format); + D3D12_RESOURCE_DESC res_d3d_desc = Zi; + { + ID3D12Resource_GetDesc(resource->d3d_resource, &res_d3d_desc); + } + D3D12_RENDER_TARGET_VIEW_DESC rtv_desc = Zi; + { + rtv_desc.Format = res_d3d_desc.Format; + if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) + { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE1D; + rtv_desc.Texture1D.MipSlice = mip; + } + else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) + { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; + rtv_desc.Texture2D.MipSlice = mip; + } + else if (res_d3d_desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + rtv_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D; + rtv_desc.Texture3D.MipSlice = mip; + } + } + ID3D12Device_CreateRenderTargetView(G_D12.device, resource->d3d_resource, &rtv_desc, descriptor->d3d_handle); } + + G_D12_Descriptor *G_D12_DescriptorFromBufferRef(G_BufferRef ref) { G_D12_DescriptorHeap *heap = &G_D12.descriptor_heaps[G_D12_DescriptorHeapKind_CbvSrvUav]; @@ -1856,10 +1877,15 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle srv.Format = DXGI_FORMAT_R32_TYPELESS; srv.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW; srv.Buffer.StructureByteStride = 0; + srv.Buffer.FirstElement = (descriptor->info.buffer_element_offset * descriptor->info.buffer_element_stride) / 4; + srv.Buffer.NumElements = (descriptor->info.buffer_element_count * descriptor->info.buffer_element_stride) / 4; } else if (srv.Buffer.StructureByteStride < 4) { ok = 0; + srv.Buffer.StructureByteStride = 4; + srv.Buffer.FirstElement = 0; + srv.Buffer.NumElements = 1; } if (ok) { @@ -1867,7 +1893,7 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle } else { - ID3D12Device_CreateShaderResourceView(G_D12.device, 0, 0, d3d_handle); + ID3D12Device_CreateShaderResourceView(G_D12.device, 0, &srv, d3d_handle); } } else @@ -1886,10 +1912,15 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle uav.Format = DXGI_FORMAT_R32_TYPELESS; uav.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW; uav.Buffer.StructureByteStride = 0; + uav.Buffer.FirstElement = (descriptor->info.buffer_element_offset * descriptor->info.buffer_element_stride) / 4; + uav.Buffer.NumElements = (descriptor->info.buffer_element_count * descriptor->info.buffer_element_stride) / 4; } else if (uav.Buffer.StructureByteStride < 4) { ok = 0; + uav.Buffer.StructureByteStride = 4; + uav.Buffer.FirstElement = 0; + uav.Buffer.NumElements = 0; } if (ok) { @@ -1897,7 +1928,7 @@ G_BaseDescriptorIndex G_PushMemory(G_CommandListHandle cl_handle, G_ArenaHandle } else { - ID3D12Device_CreateUnorderedAccessView(G_D12.device, 0, 0, 0, d3d_handle); + ID3D12Device_CreateUnorderedAccessView(G_D12.device, 0, 0, &uav, d3d_handle); } } } @@ -3888,7 +3919,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) ////////////////////////////// //- Attach completion info to reset descriptors - for (G_D12_Descriptor *descriptor = cl->reset_descriptors.first; descriptor; descriptor = descriptor->next) + for (G_D12_Descriptor *descriptor = cl->reset_descriptors.first; descriptor;) { G_D12_Descriptor *next = descriptor->next; { @@ -4192,7 +4223,7 @@ void G_CopyTextureToTexture(G_CommandListHandle cl_handle, G_TextureRef dst_ref, D3D12_TEXTURE_COPY_LOCATION src_loc = Zi; D3D12_TEXTURE_COPY_LOCATION dst_loc = Zi; { - src_loc.pResource = dst->d3d_resource; + src_loc.pResource = src->d3d_resource; src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; src_loc.SubresourceIndex = 0; } @@ -4579,6 +4610,7 @@ G_BackbufferHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_For if (!backbuffer->d3d_resource) { ZeroStruct(backbuffer); + backbuffer->swapchain = swapchain; HRESULT hr = IDXGISwapChain3_GetBuffer(swapchain->d3d_swapchain, backbuffer_idx, &IID_ID3D12Resource, (void **)&backbuffer->d3d_resource); if (FAILED(hr)) { @@ -4621,23 +4653,94 @@ void G_CommitBackbuffer(G_BackbufferHandle backbuffer_handle, Vec2I32 dst_offset G_D12_Swapchain *swapchain = backbuffer->swapchain; G_D12_Queue *direct_queue = G_D12_QueueFromKind(G_QueueKind_Direct); - - - - // FIXME: Copy to backbuffer here Vec2I32 src_dims = G_Count2D(src); src_range = IntersectRng2I32(src_range, RNG2I32(VEC2I32(0, 0), src_dims)); + src_range.p1.x = MinI32(src_range.p1.x, src_range.p0.x + (swapchain->resolution.x - dst_offset.x)); + src_range.p1.y = MinI32(src_range.p1.y, src_range.p0.y + (swapchain->resolution.y - dst_offset.y)); - // if (!IsRng2I32Empty(src_range)) - // { - // G_D12_RawCommandList *rcl = G_D12_PrepareRawCommandList(G_QueueKind_Direct); - // ID3D12GraphicsCommandList7 *d3d_cl = rcl->d3d_cl; - // { - // G_D12_InsertEvent(d3d_cl, G_D12_EventKind_Marker, Lit("Copy to backbuffer")); - // ID3D12GraphicsCommandList_CopyTextureRegion(d3d_cl, &dst_loc, dst_offset.x, dst_offset.y, dst_offset.z, &src_loc, src_box_ptr); - // } - // G_D12_CommitRawCommandList(rcl); - // } + if (!IsRng2I32Empty(src_range)) + { + G_D12_Resource *src_resource = G_D12_ResourceFromTextureRef(src); + G_D12_RawCommandList *rcl = G_D12_PrepareRawCommandList(G_QueueKind_Direct); + ID3D12GraphicsCommandList7 *d3d_cl = rcl->d3d_cl; + { + G_D12_InsertEvent(d3d_cl, G_D12_EventKind_Marker, Lit("Copy to backbuffer")); + + + D3D12_BOX src_box = Zi; + { + src_box.left = src_range.p0.x; + src_box.top = src_range.p0.y; + src_box.front = 0; + src_box.right = src_range.p1.x; + src_box.bottom = src_range.p1.y; + src_box.back = 1; + } + + D3D12_TEXTURE_COPY_LOCATION src_loc = Zi; + D3D12_TEXTURE_COPY_LOCATION dst_loc = Zi; + { + src_loc.pResource = src_resource->d3d_resource; + src_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + src_loc.SubresourceIndex = 0; + } + { + dst_loc.pResource = backbuffer->d3d_resource; + dst_loc.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dst_loc.SubresourceIndex = 0; + } + + // Transition backbuffer to copy dest + { + D3D12_TEXTURE_BARRIER barrier = Zi; + { + barrier.SyncBefore = D3D12_BARRIER_SYNC_NONE; + barrier.SyncAfter = D3D12_BARRIER_SYNC_COPY; + barrier.AccessBefore = D3D12_BARRIER_ACCESS_NO_ACCESS; + barrier.AccessAfter = D3D12_BARRIER_ACCESS_COPY_DEST; + barrier.LayoutBefore = D3D12_BARRIER_LAYOUT_PRESENT; + barrier.LayoutAfter = D3D12_BARRIER_LAYOUT_COPY_DEST; + barrier.pResource = backbuffer->d3d_resource; + barrier.Subresources.NumArraySlices = 1; + barrier.Subresources.NumPlanes = 1; + barrier.Subresources.IndexOrFirstMipLevel = 0; + barrier.Subresources.NumMipLevels = 1; + } + D3D12_BARRIER_GROUP barrier_group = Zi; + barrier_group.Type = D3D12_BARRIER_TYPE_TEXTURE; + barrier_group.NumBarriers = 1; + barrier_group.pTextureBarriers = &barrier; + ID3D12GraphicsCommandList7_Barrier(d3d_cl, 1, &barrier_group); + } + + // Copy user texture to backbuffer + ID3D12GraphicsCommandList_CopyTextureRegion(d3d_cl, &dst_loc, dst_offset.x, dst_offset.y, 0, &src_loc, &src_box); + + // Transition backbuffer to presentable + { + D3D12_TEXTURE_BARRIER barrier = Zi; + { + barrier.SyncBefore = D3D12_BARRIER_SYNC_COPY; + barrier.SyncAfter = D3D12_BARRIER_SYNC_NONE; + barrier.AccessBefore = D3D12_BARRIER_ACCESS_COPY_DEST; + barrier.AccessAfter = D3D12_BARRIER_ACCESS_NO_ACCESS; + barrier.LayoutBefore = D3D12_BARRIER_LAYOUT_COPY_DEST; + barrier.LayoutAfter = D3D12_BARRIER_LAYOUT_PRESENT; + barrier.pResource = backbuffer->d3d_resource; + barrier.Subresources.NumArraySlices = 1; + barrier.Subresources.NumPlanes = 1; + barrier.Subresources.IndexOrFirstMipLevel = 0; + barrier.Subresources.NumMipLevels = 1; + } + D3D12_BARRIER_GROUP barrier_group = Zi; + barrier_group.Type = D3D12_BARRIER_TYPE_TEXTURE; + barrier_group.NumBarriers = 1; + barrier_group.pTextureBarriers = &barrier; + ID3D12GraphicsCommandList7_Barrier(d3d_cl, 1, &barrier_group); + } + } + G_D12_CommitRawCommandList(rcl); + }