gpu resource reuse
This commit is contained in:
parent
e4975e06c4
commit
38d9b90bf1
@ -607,6 +607,7 @@ ForceInline void LockTicketMutex(TicketMutex *tm)
|
|||||||
|
|
||||||
ForceInline void UnlockTicketMutex(TicketMutex *tm)
|
ForceInline void UnlockTicketMutex(TicketMutex *tm)
|
||||||
{
|
{
|
||||||
|
/* TODO: Atomic set w/ known ticket + 1 */
|
||||||
Atomic64FetchAdd(&tm->serving.v, 1);
|
Atomic64FetchAdd(&tm->serving.v, 1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -39,10 +39,32 @@ GPU_D12_Command *GPU_D12_PushCmd(GPU_D12_CommandList *cl)
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GPU_D12_ReuseHashFromResourceDesc(GPU_ResourceDesc desc)
|
u64 GPU_D12_ReuseHashFromResourceDesc(GPU_ResourceDesc desc, u64 buffer_size)
|
||||||
{
|
{
|
||||||
/* TODO */
|
u64 result = RandU64FromSeeds(desc.kind, desc.flags);
|
||||||
u64 result = 1;
|
switch(desc.kind)
|
||||||
|
{
|
||||||
|
default: break;
|
||||||
|
case GPU_ResourceKind_Texture1D:
|
||||||
|
case GPU_ResourceKind_Texture2D:
|
||||||
|
case GPU_ResourceKind_Texture3D:
|
||||||
|
{
|
||||||
|
result = RandU64FromSeeds(result, desc.texture.format);
|
||||||
|
result = RandU64FromSeeds(result, desc.texture.mip_levels);
|
||||||
|
result = RandU64FromSeeds(result, desc.clear_color.x);
|
||||||
|
result = RandU64FromSeeds(result, desc.clear_color.y);
|
||||||
|
result = RandU64FromSeeds(result, desc.clear_color.z);
|
||||||
|
result = RandU64FromSeeds(result, desc.clear_color.w);
|
||||||
|
result = RandU64FromSeeds(result, desc.texture.size.x);
|
||||||
|
result = RandU64FromSeeds(result, desc.texture.size.y);
|
||||||
|
result = RandU64FromSeeds(result, desc.texture.size.z);
|
||||||
|
} break;
|
||||||
|
case GPU_ResourceKind_Buffer:
|
||||||
|
{
|
||||||
|
result = RandU64FromSeeds(result, desc.buffer.heap_kind);
|
||||||
|
result = RandU64FromSeeds(result, buffer_size);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -919,26 +941,35 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
|
|||||||
buffer_size = MaxU64(AlignU64Pow2(desc.buffer.count * desc.buffer.stride), Kibi(64));
|
buffer_size = MaxU64(AlignU64Pow2(desc.buffer.count * desc.buffer.stride), Kibi(64));
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 reuse_hash = GPU_D12_ReuseHashFromResourceDesc(desc);
|
u64 reuse_hash = GPU_D12_ReuseHashFromResourceDesc(desc, buffer_size);
|
||||||
#if 0
|
|
||||||
/* Grab reusable */
|
/* Grab reusable */
|
||||||
{
|
{
|
||||||
u64 bin_index = hash % countof(g->reuse_bins);
|
u64 bin_index = reuse_hash % countof(g->resource_reuse_bins);
|
||||||
GPU_D12_ReuseBin *bin = &g->reuse_bins[bin_index];
|
GPU_D12_ResourceReuseListBin *bin = &g->resource_reuse_bins[bin_index];
|
||||||
{
|
{
|
||||||
Lock lock = LockE(&bin->mutex);
|
Lock lock = LockE(&bin->mutex);
|
||||||
for (r = bin->first; r; r = r->next_reuse)
|
|
||||||
{
|
{
|
||||||
if (r->reuse_hash == hash)
|
GPU_D12_ResourceReuseList *list = bin->first;
|
||||||
|
for (; list; list = list->next)
|
||||||
{
|
{
|
||||||
DllRemoveNP(bin->first, bin->last, r, next_reuse, prev_reuse);
|
if (list->hash == reuse_hash) break;
|
||||||
break;
|
}
|
||||||
|
if (list)
|
||||||
|
{
|
||||||
|
r = list->first;
|
||||||
|
list->first = r->next_free;
|
||||||
|
if (!list->first)
|
||||||
|
{
|
||||||
|
DllRemove(bin->first, bin->last, list);
|
||||||
|
StackPush(bin->first_free, list);
|
||||||
|
list->prev = 0;
|
||||||
|
}
|
||||||
|
r->next_free = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Unlock(&lock);
|
Unlock(&lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Grab from free list */
|
/* Grab from free list */
|
||||||
if (!r)
|
if (!r)
|
||||||
@ -967,10 +998,9 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
|
|||||||
PushAlign(perm, CachelineSize);
|
PushAlign(perm, CachelineSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->reuse_hash == 0)
|
/* Create d3d resource */
|
||||||
|
if (!r->d3d_resource)
|
||||||
{
|
{
|
||||||
r->reuse_hash = reuse_hash;
|
|
||||||
|
|
||||||
switch (desc.kind)
|
switch (desc.kind)
|
||||||
{
|
{
|
||||||
case GPU_ResourceKind_Sampler: break;
|
case GPU_ResourceKind_Sampler: break;
|
||||||
@ -1044,13 +1074,17 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Create texture srv descriptor */
|
/* Create texture srv descriptor */
|
||||||
if (desc.kind == GPU_ResourceKind_Texture1D
|
if (desc.kind == GPU_ResourceKind_Texture1D
|
||||||
|| desc.kind == GPU_ResourceKind_Texture2D
|
|| desc.kind == GPU_ResourceKind_Texture2D
|
||||||
|| desc.kind == GPU_ResourceKind_Texture3D)
|
|| desc.kind == GPU_ResourceKind_Texture3D)
|
||||||
|
{
|
||||||
|
if (!r->srv_descriptor)
|
||||||
{
|
{
|
||||||
r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
||||||
|
}
|
||||||
ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, 0, r->srv_descriptor->handle);
|
ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, 0, r->srv_descriptor->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1059,6 +1093,10 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
|
|||||||
&& desc.buffer.heap_kind != GPU_HeapKind_Download
|
&& desc.buffer.heap_kind != GPU_HeapKind_Download
|
||||||
&& desc.buffer.count > 0)
|
&& desc.buffer.count > 0)
|
||||||
{
|
{
|
||||||
|
if (!r->srv_descriptor)
|
||||||
|
{
|
||||||
|
r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
||||||
|
}
|
||||||
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI;
|
D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI;
|
||||||
srv_desc.Format = DXGI_FORMAT_UNKNOWN;
|
srv_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||||
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER;
|
||||||
@ -1067,27 +1105,36 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
|
|||||||
srv_desc.Buffer.NumElements = desc.buffer.count;
|
srv_desc.Buffer.NumElements = desc.buffer.count;
|
||||||
srv_desc.Buffer.StructureByteStride = desc.buffer.stride;
|
srv_desc.Buffer.StructureByteStride = desc.buffer.stride;
|
||||||
srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
|
srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE;
|
||||||
r->srv_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
|
||||||
ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, &srv_desc, r->srv_descriptor->handle);
|
ID3D12Device_CreateShaderResourceView(g->device, r->d3d_resource, &srv_desc, r->srv_descriptor->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create uav descriptor */
|
/* Create uav descriptor */
|
||||||
if (desc.flags & GPU_ResourceFlag_Writable)
|
if (desc.flags & GPU_ResourceFlag_Writable)
|
||||||
|
{
|
||||||
|
if (!r->uav_descriptor)
|
||||||
{
|
{
|
||||||
r->uav_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
r->uav_descriptor = GPU_D12_AcquireDescriptor(g->cbv_srv_uav_heap);
|
||||||
|
}
|
||||||
ID3D12Device_CreateUnorderedAccessView(g->device, r->d3d_resource, 0, 0, r->uav_descriptor->handle);
|
ID3D12Device_CreateUnorderedAccessView(g->device, r->d3d_resource, 0, 0, r->uav_descriptor->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create rtv descriptor */
|
/* Create rtv descriptor */
|
||||||
if (desc.flags & GPU_ResourceFlag_Renderable)
|
if (desc.flags & GPU_ResourceFlag_Renderable)
|
||||||
|
{
|
||||||
|
if (!r->rtv_descriptor)
|
||||||
{
|
{
|
||||||
r->rtv_descriptor = GPU_D12_AcquireDescriptor(g->rtv_heap);
|
r->rtv_descriptor = GPU_D12_AcquireDescriptor(g->rtv_heap);
|
||||||
|
}
|
||||||
ID3D12Device_CreateRenderTargetView(g->device, r->d3d_resource, 0, r->rtv_descriptor->handle);
|
ID3D12Device_CreateRenderTargetView(g->device, r->d3d_resource, 0, r->rtv_descriptor->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create sampler descriptor */
|
/* Create sampler descriptor */
|
||||||
if (desc.kind == GPU_ResourceKind_Sampler)
|
if (desc.kind == GPU_ResourceKind_Sampler)
|
||||||
{
|
{
|
||||||
|
if (!r->sampler_descriptor)
|
||||||
|
{
|
||||||
|
r->sampler_descriptor = GPU_D12_AcquireDescriptor(g->sampler_heap);
|
||||||
|
}
|
||||||
D3D12_SAMPLER_DESC d3d_desc = ZI;
|
D3D12_SAMPLER_DESC d3d_desc = ZI;
|
||||||
d3d_desc.Filter = (D3D12_FILTER)desc.sampler.filter;
|
d3d_desc.Filter = (D3D12_FILTER)desc.sampler.filter;
|
||||||
d3d_desc.AddressU = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.x;
|
d3d_desc.AddressU = (D3D12_TEXTURE_ADDRESS_MODE)desc.sampler.x;
|
||||||
@ -1111,12 +1158,11 @@ GPU_Resource *GPU_AcquireResource(GPU_ResourceDesc desc)
|
|||||||
{
|
{
|
||||||
d3d_desc.MaxLOD = D3D12_FLOAT32_MAX;
|
d3d_desc.MaxLOD = D3D12_FLOAT32_MAX;
|
||||||
}
|
}
|
||||||
r->sampler_descriptor = GPU_D12_AcquireDescriptor(g->sampler_heap);
|
|
||||||
ID3D12Device_CreateSampler(g->device, &d3d_desc, r->sampler_descriptor->handle);
|
ID3D12Device_CreateSampler(g->device, &d3d_desc, r->sampler_descriptor->handle);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
r->desc = desc;
|
r->desc = desc;
|
||||||
|
r->buffer_size = buffer_size;
|
||||||
|
|
||||||
return (GPU_Resource *)r;
|
return (GPU_Resource *)r;
|
||||||
}
|
}
|
||||||
@ -1126,7 +1172,66 @@ void GPU_ReleaseResource(GPU_Resource *gpu_resource, GPU_ReleaseFlag flags)
|
|||||||
GPU_D12_SharedState *g = &GPU_D12_shared_state;
|
GPU_D12_SharedState *g = &GPU_D12_shared_state;
|
||||||
GPU_D12_Resource *r = (GPU_D12_Resource *)gpu_resource;
|
GPU_D12_Resource *r = (GPU_D12_Resource *)gpu_resource;
|
||||||
|
|
||||||
/* TODO: Reuse */
|
if (r->srv_descriptor)
|
||||||
|
{
|
||||||
|
GPU_D12_ReleaseDescriptor(r->srv_descriptor);
|
||||||
|
r->srv_descriptor = 0;
|
||||||
|
}
|
||||||
|
if (r->uav_descriptor)
|
||||||
|
{
|
||||||
|
GPU_D12_ReleaseDescriptor(r->uav_descriptor);
|
||||||
|
r->uav_descriptor = 0;
|
||||||
|
}
|
||||||
|
if (r->rtv_descriptor)
|
||||||
|
{
|
||||||
|
GPU_D12_ReleaseDescriptor(r->rtv_descriptor);
|
||||||
|
r->rtv_descriptor = 0;
|
||||||
|
}
|
||||||
|
if (r->sampler_descriptor)
|
||||||
|
{
|
||||||
|
GPU_D12_ReleaseDescriptor(r->sampler_descriptor);
|
||||||
|
r->sampler_descriptor = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
DllPushBack(bin->first, bin->last, list);
|
||||||
|
}
|
||||||
|
StackPushN(list->first, r, next_free);
|
||||||
|
}
|
||||||
|
Unlock(&lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
switch (r->desc.kind)
|
switch (r->desc.kind)
|
||||||
{
|
{
|
||||||
case GPU_ResourceKind_Buffer:
|
case GPU_ResourceKind_Buffer:
|
||||||
@ -1137,28 +1242,12 @@ void GPU_ReleaseResource(GPU_Resource *gpu_resource, GPU_ReleaseFlag flags)
|
|||||||
ID3D12Resource_Release(r->d3d_resource);
|
ID3D12Resource_Release(r->d3d_resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r->srv_descriptor)
|
|
||||||
{
|
|
||||||
GPU_D12_ReleaseDescriptor(r->srv_descriptor);
|
|
||||||
}
|
|
||||||
if (r->uav_descriptor)
|
|
||||||
{
|
|
||||||
GPU_D12_ReleaseDescriptor(r->uav_descriptor);
|
|
||||||
}
|
|
||||||
if (r->rtv_descriptor)
|
|
||||||
{
|
|
||||||
GPU_D12_ReleaseDescriptor(r->rtv_descriptor);
|
|
||||||
}
|
|
||||||
if (r->sampler_descriptor)
|
|
||||||
{
|
|
||||||
GPU_D12_ReleaseDescriptor(r->sampler_descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lock lock = LockE(&g->free_resources_mutex);
|
Lock lock = LockE(&g->free_resources_mutex);
|
||||||
r->next_free = g->first_free_resource;
|
r->next_free = g->first_free_resource;
|
||||||
g->first_free_resource = r;
|
g->first_free_resource = r;
|
||||||
Unlock(&lock);
|
Unlock(&lock);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GPU_GetReadableId(GPU_Resource *resource)
|
u32 GPU_GetReadableId(GPU_Resource *resource)
|
||||||
|
|||||||
@ -90,7 +90,8 @@ Struct(GPU_D12_Resource)
|
|||||||
|
|
||||||
ID3D12Resource *d3d_resource;
|
ID3D12Resource *d3d_resource;
|
||||||
D3D12_RESOURCE_STATES state;
|
D3D12_RESOURCE_STATES state;
|
||||||
u64 reuse_hash;
|
|
||||||
|
u64 buffer_size; /* Actual size of buffer in GPU memory */
|
||||||
|
|
||||||
GPU_D12_Descriptor *srv_descriptor;
|
GPU_D12_Descriptor *srv_descriptor;
|
||||||
GPU_D12_Descriptor *uav_descriptor;
|
GPU_D12_Descriptor *uav_descriptor;
|
||||||
@ -104,6 +105,22 @@ Struct(GPU_D12_Resource)
|
|||||||
D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address;
|
D3D12_GPU_VIRTUAL_ADDRESS buffer_gpu_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Struct(GPU_D12_ResourceReuseList)
|
||||||
|
{
|
||||||
|
u64 hash;
|
||||||
|
GPU_D12_ResourceReuseList *next;
|
||||||
|
GPU_D12_ResourceReuseList *prev;
|
||||||
|
GPU_D12_Resource *first;
|
||||||
|
};
|
||||||
|
|
||||||
|
Struct(GPU_D12_ResourceReuseListBin)
|
||||||
|
{
|
||||||
|
Mutex mutex;
|
||||||
|
GPU_D12_ResourceReuseList *first;
|
||||||
|
GPU_D12_ResourceReuseList *last;
|
||||||
|
GPU_D12_ResourceReuseList *first_free;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Queue types
|
//~ Queue types
|
||||||
|
|
||||||
@ -253,6 +270,8 @@ Struct(GPU_D12_Swapchain)
|
|||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ State types
|
//~ State types
|
||||||
|
|
||||||
|
#define GPU_D12_NumResourceReuseBins 1024
|
||||||
|
|
||||||
Struct(GPU_D12_FiberState)
|
Struct(GPU_D12_FiberState)
|
||||||
{
|
{
|
||||||
GPU_D12_CommandList *first_free_command_list;
|
GPU_D12_CommandList *first_free_command_list;
|
||||||
@ -282,6 +301,7 @@ Struct(GPU_D12_SharedState)
|
|||||||
/* Resources */
|
/* Resources */
|
||||||
Mutex free_resources_mutex;
|
Mutex free_resources_mutex;
|
||||||
GPU_D12_Resource *first_free_resource;
|
GPU_D12_Resource *first_free_resource;
|
||||||
|
GPU_D12_ResourceReuseListBin resource_reuse_bins[GPU_D12_NumResourceReuseBins];
|
||||||
|
|
||||||
/* Swapchains */
|
/* Swapchains */
|
||||||
Mutex free_swapchains_mutex;
|
Mutex free_swapchains_mutex;
|
||||||
@ -299,7 +319,7 @@ Struct(GPU_D12_SharedState)
|
|||||||
GPU_D12_FiberState *GPU_D12_FiberStateFromId(i16 fiber_id);
|
GPU_D12_FiberState *GPU_D12_FiberStateFromId(i16 fiber_id);
|
||||||
DXGI_FORMAT GPU_D12_DxgiFormatFromGpuFormat(GPU_Format format);
|
DXGI_FORMAT GPU_D12_DxgiFormatFromGpuFormat(GPU_Format format);
|
||||||
GPU_D12_Command *GPU_D12_PushCmd(GPU_D12_CommandList *cl);
|
GPU_D12_Command *GPU_D12_PushCmd(GPU_D12_CommandList *cl);
|
||||||
u64 GPU_D12_ReuseHashFromResourceDesc(GPU_ResourceDesc desc);
|
u64 GPU_D12_ReuseHashFromResourceDesc(GPU_ResourceDesc desc, u64 buffer_size);
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
//~ Startup
|
//~ Startup
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user