implement queue sync
This commit is contained in:
parent
7fecea03f5
commit
7ed6b8a62e
@ -751,386 +751,6 @@ void GPU_D12_CommitRawCommandList(GPU_D12_RawCommandList *cl)
|
||||
// ID3D12CommandQueue_Wait(queue_a->d3d_queue, b_fence, b_target_fence_value);
|
||||
// }
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Resource hooks
|
||||
|
||||
#if 0
|
||||
|
||||
GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
|
||||
{
|
||||
GPU_D12_SharedState *g = &GPU_D12_shared_state;
|
||||
GPU_D12_Resource *r = 0;
|
||||
|
||||
if (desc.kind == GPU_ResourceKind_Unknown)
|
||||
{
|
||||
Panic(Lit("Unknown gpu resource type"));
|
||||
}
|
||||
|
||||
u64 buffer_size = 0;
|
||||
if (desc.kind == GPU_ResourceKind_Buffer)
|
||||
{
|
||||
desc.buffer.stride = MaxU32(desc.buffer.stride, 1);
|
||||
buffer_size = MaxU64(AlignU64ToNextPow2(desc.buffer.count * desc.buffer.stride), Kibi(64));
|
||||
}
|
||||
|
||||
u64 reuse_hash = GPU_D12_ReuseHashFromResourceDesc(desc, buffer_size);
|
||||
/* Grab reusable */
|
||||
{
|
||||
u64 bin_index = reuse_hash % countof(g->resource_reuse_bins);
|
||||
GPU_D12_ResourceReuseListBin *bin = &g->resource_reuse_bins[bin_index];
|
||||
{
|
||||
Lock lock = LockE(&bin->mutex);
|
||||
{
|
||||
GPU_D12_ResourceReuseList *list = bin->first;
|
||||
for (; list; list = list->next)
|
||||
{
|
||||
if (list->hash == reuse_hash) break;
|
||||
}
|
||||
if (list)
|
||||
{
|
||||
r = list->first;
|
||||
list->first = r->next_free;
|
||||
if (!list->first)
|
||||
{
|
||||
DllQueueRemove(bin->first, bin->last, list);
|
||||
SllStackPush(bin->first_free, list);
|
||||
list->prev = 0;
|
||||
}
|
||||
r->next_free = 0;
|
||||
}
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
}
|
||||
|
||||
/* Grab from free list */
|
||||
if (!r)
|
||||
{
|
||||
{
|
||||
Lock lock = LockE(&g->free_resources_mutex);
|
||||
r = g->first_free_resource;
|
||||
if (r)
|
||||
{
|
||||
g->first_free_resource = r->next_free;
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
if (r)
|
||||
{
|
||||
ZeroStruct(r);
|
||||
}
|
||||
}
|
||||
|
||||
/* Push new */
|
||||
if (!r)
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
PushAlign(perm, CachelineSize);
|
||||
r = PushStruct(perm, GPU_D12_Resource);
|
||||
PushAlign(perm, CachelineSize);
|
||||
}
|
||||
|
||||
/* Create d3d resource */
|
||||
if (!r->d3d_resource)
|
||||
{
|
||||
switch (desc.kind)
|
||||
{
|
||||
default: break;
|
||||
|
||||
/* Buffer */
|
||||
case GPU_ResourceKind_Buffer:
|
||||
{
|
||||
D3D12_HEAP_FLAGS heap_flags = 0;
|
||||
if (!(desc.flags & GPU_ResourceFlag_Zeroed))
|
||||
{
|
||||
heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES heap_props = {
|
||||
.Type = desc.buffer.heap_kind == GPU_HeapKind_Upload ? D3D12_HEAP_TYPE_UPLOAD
|
||||
: desc.buffer.heap_kind == GPU_HeapKind_Download ? D3D12_HEAP_TYPE_READBACK
|
||||
: D3D12_HEAP_TYPE_DEFAULT
|
||||
};
|
||||
Assert(!(desc.flags & GPU_ResourceFlag_Rasterizable));
|
||||
D3D12_RESOURCE_DESC d3d_desc = ZI;
|
||||
d3d_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
d3d_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
d3d_desc.Alignment = 0;
|
||||
d3d_desc.Width = buffer_size;
|
||||
d3d_desc.Height = 1;
|
||||
d3d_desc.DepthOrArraySize = 1;
|
||||
d3d_desc.MipLevels = 1;
|
||||
d3d_desc.SampleDesc.Count = 1;
|
||||
d3d_desc.SampleDesc.Quality = 0;
|
||||
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(desc.flags, GPU_ResourceFlag_Writable);
|
||||
r->state = desc.buffer.heap_kind == GPU_HeapKind_Download ? D3D12_RESOURCE_STATE_COPY_DEST : D3D12_RESOURCE_STATE_COMMON;
|
||||
HRESULT hr = ID3D12Device_CreateCommittedResource(g->device, &heap_props, heap_flags, &d3d_desc, r->state, 0, &IID_ID3D12Resource, (void **)&r->d3d_resource);
|
||||
Atomic64FetchAdd(&g->driver_resources_allocated, 1);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
/* TODO: Don't panic */
|
||||
Panic(Lit("Failed to create buffer resource"));
|
||||
}
|
||||
r->buffer_gpu_address = ID3D12Resource_GetGPUVirtualAddress(r->d3d_resource);
|
||||
} break;
|
||||
|
||||
/* Texture */
|
||||
case GPU_ResourceKind_Texture1D:
|
||||
case GPU_ResourceKind_Texture2D:
|
||||
case GPU_ResourceKind_Texture3D:
|
||||
{
|
||||
D3D12_HEAP_FLAGS heap_flags = 0;
|
||||
if (!(desc.flags & GPU_ResourceFlag_Zeroed))
|
||||
{
|
||||
heap_flags |= D3D12_HEAP_FLAG_CREATE_NOT_ZEROED;
|
||||
}
|
||||
|
||||
D3D12_HEAP_PROPERTIES heap_props = { .Type = D3D12_HEAP_TYPE_DEFAULT };
|
||||
D3D12_RESOURCE_DESC d3d_desc = ZI;
|
||||
d3d_desc.Dimension = desc.kind == GPU_ResourceKind_Texture1D ? D3D12_RESOURCE_DIMENSION_TEXTURE1D
|
||||
: desc.kind == GPU_ResourceKind_Texture2D ? D3D12_RESOURCE_DIMENSION_TEXTURE2D
|
||||
: D3D12_RESOURCE_DIMENSION_TEXTURE3D;
|
||||
d3d_desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
|
||||
d3d_desc.Format = GPU_D12_DxgiFormatFromGpuFormat(desc.texture.format);
|
||||
d3d_desc.Alignment = 0;
|
||||
d3d_desc.Width = MaxI32(desc.texture.size.x, 1);
|
||||
d3d_desc.Height = MaxI32(desc.texture.size.y, 1);
|
||||
d3d_desc.DepthOrArraySize = MaxI32(desc.texture.size.z, 1);
|
||||
d3d_desc.MipLevels = (desc.flags & GPU_ResourceFlag_MaxMipLevels) ? 0 : MaxI32(desc.texture.mip_levels, 1);
|
||||
d3d_desc.SampleDesc.Count = 1;
|
||||
d3d_desc.SampleDesc.Quality = 0;
|
||||
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS * AnyBit(desc.flags, GPU_ResourceFlag_Writable);
|
||||
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET * AnyBit(desc.flags, GPU_ResourceFlag_Rasterizable);
|
||||
d3d_desc.Flags |= D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS * (desc.initial_layout == GPU_Layout_Simultaneous);
|
||||
r->state = D3D12_RESOURCE_STATE_COMMON;
|
||||
D3D12_CLEAR_VALUE clear_value = { .Format = d3d_desc.Format, .Color = { 0 } };
|
||||
clear_value.Color[0] = desc.clear_color.x;
|
||||
clear_value.Color[1] = desc.clear_color.y;
|
||||
clear_value.Color[2] = desc.clear_color.z;
|
||||
clear_value.Color[3] = desc.clear_color.w;
|
||||
D3D12_CLEAR_VALUE *clear_value_ptr = d3d_desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET ? &clear_value : 0;
|
||||
HRESULT hr = ID3D12Device_CreateCommittedResource(g->device, &heap_props, heap_flags, &d3d_desc, r->state, clear_value_ptr, &IID_ID3D12Resource, (void **)&r->d3d_resource);
|
||||
Atomic64FetchAdd(&g->driver_resources_allocated, 1);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
/* TODO: Don't panic */
|
||||
Panic(Lit("Failed to create buffer resource"));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
r->srv_descriptor = &GPU_D12_NilDescriptor;
|
||||
r->uav_descriptor = &GPU_D12_NilDescriptor;
|
||||
r->rtv_descriptor = &GPU_D12_NilDescriptor;
|
||||
r->sampler_descriptor = &GPU_D12_NilDescriptor;
|
||||
|
||||
/* Create texture srv descriptor */
|
||||
if (desc.kind == GPU_ResourceKind_Texture1D
|
||||
|| desc.kind == GPU_ResourceKind_Texture2D
|
||||
|| desc.kind == GPU_ResourceKind_Texture3D)
|
||||
{
|
||||
if (!r->srv_descriptor->valid)
|
||||
{
|
||||
r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
||||
}
|
||||
ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, 0, r->srv_descriptor->handle);
|
||||
}
|
||||
|
||||
/* Create buffer srv descriptor */
|
||||
if (desc.kind == GPU_ResourceKind_Buffer
|
||||
&& desc.buffer.heap_kind != GPU_HeapKind_Download
|
||||
&& desc.buffer.count > 0)
|
||||
{
|
||||
if (!r->srv_descriptor->valid)
|
||||
{
|
||||
r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
||||
}
|
||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI;
|
||||
srv_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
||||
srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
|
||||
srv_desc.Buffer.FirstElement = 0;
|
||||
srv_desc.Buffer.NumElements = desc.buffer.count;
|
||||
srv_desc.Buffer.StructureByteStride = desc.buffer.stride;
|
||||
srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
|
||||
ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, &srv_desc, r->srv_descriptor->handle);
|
||||
}
|
||||
|
||||
/* Create uav descriptor */
|
||||
if (desc.flags & GPU_ResourceFlag_Writable)
|
||||
{
|
||||
if (!r->uav_descriptor->valid)
|
||||
{
|
||||
r->uav_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
||||
}
|
||||
ID3D12Device_CreateUnorderedAccessView(g->device, r->d3d_resource, 0, 0, r->uav_descriptor->handle);
|
||||
}
|
||||
|
||||
/* Create rtv descriptor */
|
||||
if (desc.flags & GPU_ResourceFlag_Rasterizable)
|
||||
{
|
||||
if (!r->rtv_descriptor->valid)
|
||||
{
|
||||
r->rtv_descriptor = GPU_D12_AcquireDescriptor(g->rtv_heap);
|
||||
}
|
||||
ID3D12Device_CreateRenderTargetView(g->device, r->d3d_resource, 0, r->rtv_descriptor->handle);
|
||||
}
|
||||
|
||||
/* Create sampler descriptor */
|
||||
if (desc.kind == GPU_ResourceKind_Sampler)
|
||||
{
|
||||
if (!r->sampler_descriptor->valid)
|
||||
{
|
||||
r->sampler_descriptor = GPU_D12_AcquireDescriptor(g->sampler_heap);
|
||||
}
|
||||
D3D12_SAMPLER_DESC d3d_desc = ZI;
|
||||
d3d_desc.Filter = (D3D12_FILTER)desc.sampler.filter;
|
||||
d3d_desc.AddressU = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.x;
|
||||
d3d_desc.AddressV = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.y;
|
||||
d3d_desc.AddressW = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.z;
|
||||
d3d_desc.MipLODBias = desc.sampler.mip_lod_bias;
|
||||
d3d_desc.MaxAnisotropy = MaxU32(desc.sampler.max_anisotropy, 1);
|
||||
d3d_desc.ComparisonFunc = (D3D12_COMPARISON_FUNC)desc.sampler.comparison;
|
||||
d3d_desc.BorderColor[0] = desc.sampler.border_color.x;
|
||||
d3d_desc.BorderColor[1] = desc.sampler.border_color.y;
|
||||
d3d_desc.BorderColor[2] = desc.sampler.border_color.z;
|
||||
d3d_desc.BorderColor[3] = desc.sampler.border_color.w;
|
||||
d3d_desc.MinLOD = desc.sampler.min_lod;
|
||||
d3d_desc.MaxLOD = desc.sampler.max_lod;
|
||||
|
||||
/* Defaults */
|
||||
if (d3d_desc.AddressU == 0) d3d_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
if (d3d_desc.AddressV == 0) d3d_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
if (d3d_desc.AddressW == 0) d3d_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
if (d3d_desc.MaxLOD >= F32Infinity)
|
||||
{
|
||||
d3d_desc.MaxLOD = D3D12_FLOAT32_MAX;
|
||||
}
|
||||
ID3D12Device_CreateSampler(g->device, &d3d_desc, r->sampler_descriptor->handle);
|
||||
}
|
||||
|
||||
r->desc = desc;
|
||||
r->buffer_size = buffer_size;
|
||||
|
||||
return (GPU_Resource *)r;
|
||||
}
|
||||
|
||||
void GPU_ReleaseResource(GPU_Resource *gpu_resource, GPU_ReleaseFlag flags)
|
||||
{
|
||||
GPU_D12_SharedState *g = &GPU_D12_shared_state;
|
||||
GPU_D12_Resource *r = (GPU_D12_Resource *)gpu_resource;
|
||||
|
||||
if (r->srv_descriptor->valid)
|
||||
{
|
||||
GPU_D12_ReleaseDescriptor(r->srv_descriptor);
|
||||
}
|
||||
if (r->uav_descriptor->valid)
|
||||
{
|
||||
GPU_D12_ReleaseDescriptor(r->uav_descriptor);
|
||||
}
|
||||
if (r->rtv_descriptor->valid)
|
||||
{
|
||||
GPU_D12_ReleaseDescriptor(r->rtv_descriptor);
|
||||
}
|
||||
if (r->sampler_descriptor->valid)
|
||||
{
|
||||
GPU_D12_ReleaseDescriptor(r->sampler_descriptor);
|
||||
}
|
||||
|
||||
if (flags & GPU_ReleaseFlag_Reuse)
|
||||
{
|
||||
GPU_ResourceDesc desc = r->desc;
|
||||
u64 buffer_size = r->buffer_size;
|
||||
u64 reuse_hash = GPU_D12_ReuseHashFromResourceDesc(desc, buffer_size);
|
||||
u64 bin_index = reuse_hash % countof(g->resource_reuse_bins);
|
||||
GPU_D12_ResourceReuseListBin *bin = &g->resource_reuse_bins[bin_index];
|
||||
{
|
||||
Lock lock = LockE(&bin->mutex);
|
||||
{
|
||||
GPU_D12_ResourceReuseList *list = bin->first;
|
||||
for (; list; list = list->next)
|
||||
{
|
||||
if (list->hash == reuse_hash) break;
|
||||
}
|
||||
if (!list)
|
||||
{
|
||||
list = bin->first_free;
|
||||
if (list)
|
||||
{
|
||||
bin->first_free = list->next;
|
||||
}
|
||||
else
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
PushAlign(perm, CachelineSize);
|
||||
list = PushStruct(perm, GPU_D12_ResourceReuseList);
|
||||
PushAlign(perm, CachelineSize);
|
||||
}
|
||||
list->hash = reuse_hash;
|
||||
DllQueuePush(bin->first, bin->last, list);
|
||||
}
|
||||
SllStackPushN(list->first, r, next_free);
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (r->desc.kind)
|
||||
{
|
||||
default: break;
|
||||
case GPU_ResourceKind_Buffer:
|
||||
case GPU_ResourceKind_Texture1D:
|
||||
case GPU_ResourceKind_Texture2D:
|
||||
case GPU_ResourceKind_Texture3D:
|
||||
{
|
||||
ID3D12Resource_Release(r->d3d_resource);
|
||||
Atomic64FetchAdd(&g->driver_resources_allocated, -1);
|
||||
} break;
|
||||
}
|
||||
Lock lock = LockE(&g->free_resources_mutex);
|
||||
r->next_free = g->first_free_resource;
|
||||
g->first_free_resource = r;
|
||||
Unlock(&lock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Vec2I32 GPU_GetTextureSize2D(GPU_Resource *gpu_resource)
|
||||
{
|
||||
GPU_D12_Resource *resource = (GPU_D12_Resource *)gpu_resource;
|
||||
return VEC2I32(resource->desc.texture.size.x, resource->desc.texture.size.y);
|
||||
}
|
||||
|
||||
Vec3I32 GPU_GetTextureSize3D(GPU_Resource *gpu_resource)
|
||||
{
|
||||
GPU_D12_Resource *resource = (GPU_D12_Resource *)gpu_resource;
|
||||
return resource->desc.texture.size;
|
||||
}
|
||||
|
||||
u64 GPU_GetFootprintSize(GPU_Resource *gpu_resource)
|
||||
{
|
||||
GPU_D12_SharedState *g = &GPU_D12_shared_state;
|
||||
D3D12_RESOURCE_DESC desc = ZI;
|
||||
D3D12_PLACED_SUBRESOURCE_FOOTPRINT placed_footprint = ZI;
|
||||
ID3D12Resource_GetDesc(((GPU_D12_Resource *)gpu_resource)->d3d_resource, &desc);
|
||||
u64 footprint_size = 0;
|
||||
u64 upload_row_size = 0;
|
||||
u32 upload_num_rows = 0;
|
||||
ID3D12Device_GetCopyableFootprints(g->device, &desc, 0, 1, 0, &placed_footprint, &upload_num_rows, &upload_row_size, &footprint_size);
|
||||
return footprint_size;
|
||||
}
|
||||
|
||||
u64 GPU_GetBufferCount(GPU_Resource *gpu_resource)
|
||||
{
|
||||
GPU_D12_Resource *resource = (GPU_D12_Resource *)gpu_resource;
|
||||
return resource->desc.buffer.count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Arena
|
||||
|
||||
@ -2767,14 +2387,50 @@ void GPU_ProfN(GPU_CommandListHandle cl, String name)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ @hookimpl Synchronization
|
||||
|
||||
void GPU_SyncQueue(GPU_QueueKind completion_queue, GPU_QueueKind waiter_queue)
|
||||
void GPU_SyncQueue(GPU_QueueKind completion_queue_kind, GPU_QueueKind waiter_queue_kind)
|
||||
{
|
||||
/* TODO */
|
||||
if (completion_queue_kind != waiter_queue_kind)
|
||||
{
|
||||
GPU_D12_Queue *completion_queue = GPU_D12_QueueFromKind(completion_queue_kind);
|
||||
GPU_D12_Queue *waiter_queue = GPU_D12_QueueFromKind(waiter_queue_kind);
|
||||
ID3D12Fence *d3d_fence = completion_queue->commit_fence;
|
||||
u64 fence_target = 0;
|
||||
{
|
||||
Lock lock = LockS(&completion_queue->commit_mutex);
|
||||
fence_target = completion_queue->commit_fence_target;
|
||||
Unlock(&lock);
|
||||
}
|
||||
if (ID3D12Fence_GetCompletedValue(d3d_fence) < fence_target)
|
||||
{
|
||||
ID3D12CommandQueue_Wait(waiter_queue->d3d_queue, d3d_fence, fence_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GPU_SyncAllQueues(GPU_QueueKind completion_queue)
|
||||
void GPU_SyncAllQueues(GPU_QueueKind completion_queue_kind)
|
||||
{
|
||||
/* TODO */
|
||||
if (GPU_MultiQueueIsEnabled)
|
||||
{
|
||||
GPU_D12_Queue *completion_queue = GPU_D12_QueueFromKind(completion_queue_kind);
|
||||
ID3D12Fence *d3d_fence = completion_queue->commit_fence;
|
||||
u64 fence_target = 0;
|
||||
{
|
||||
Lock lock = LockS(&completion_queue->commit_mutex);
|
||||
fence_target = completion_queue->commit_fence_target;
|
||||
Unlock(&lock);
|
||||
}
|
||||
if (ID3D12Fence_GetCompletedValue(d3d_fence) < fence_target)
|
||||
{
|
||||
for (GPU_QueueKind waiter_queue_kind = 0; waiter_queue_kind < GPU_NumQueues; ++waiter_queue_kind)
|
||||
{
|
||||
if (waiter_queue_kind != completion_queue_kind)
|
||||
{
|
||||
GPU_D12_Queue *waiter_queue = GPU_D12_QueueFromKind(waiter_queue_kind);
|
||||
ID3D12CommandQueue_Wait(waiter_queue->d3d_queue, d3d_fence, fence_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
Loading…
Reference in New Issue
Block a user