From 34fd73ac28b5acdbf014a1bc4edc84d4f44cc2a0 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 5 Mar 2026 08:02:55 -0600 Subject: [PATCH] backfill tracked mip usage in next batch --- src/gpu/gpu_dx12/gpu_dx12_core.c | 160 ++++++++++++++++--------------- src/gpu/gpu_dx12/gpu_dx12_core.h | 1 + 2 files changed, 83 insertions(+), 78 deletions(-) diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.c b/src/gpu/gpu_dx12/gpu_dx12_core.c index d02a0a41..79ff85fd 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.c +++ b/src/gpu/gpu_dx12/gpu_dx12_core.c @@ -2082,43 +2082,99 @@ void G_D12_UpdateTrackedUsage(Arena *arena, G_D12_CmdBatch *batch, G_D12_Resourc b32 should_track = !AnyBit(resource->d3d_desc.Flags, D3D12_RESOURCE_FLAG_ALLOW_SIMULTANEOUS_ACCESS); if (should_track) { - u64 hash = MixU64(resource->uid); - - if (!batch->tracked_resource_bins) + G_D12_CmdBatch *prev_batch = batch->prev; + G_D12_TrackedResourceNode *trn = 0; + G_D12_TrackedResourceNode *prev_trn = 0; { - batch->tracked_resource_bins = PushStructs(arena, G_D12_TrackedResourceBin, G_D12_TrackedResourceBinsCount); - } - - G_D12_TrackedResourceBin *bin = &batch->tracked_resource_bins[hash % G_D12_TrackedResourceBinsCount]; - G_D12_TrackedResourceNode *trn = bin->first; - for (; trn; trn = trn->next_in_bin) - { - if (trn->hash == hash) + u64 hash = MixU64(resource->uid); + // Fetch/create tracked resource in current batch { - break; + if (!batch->tracked_resource_bins) + { + batch->tracked_resource_bins = PushStructs(arena, G_D12_TrackedResourceBin, G_D12_TrackedResourceBinsCount); + } + G_D12_TrackedResourceBin *bin = &batch->tracked_resource_bins[hash % G_D12_TrackedResourceBinsCount]; + G_D12_TrackedResourceNode *tmp = bin->first; + for (; tmp; tmp = tmp->next_in_bin) + { + if (tmp->hash == hash) + { + break; + } + } + if (!tmp) + { + tmp = PushStruct(arena, G_D12_TrackedResourceNode); + tmp->resource = resource; + tmp->hash = hash; + SllQueuePush(batch->first_tracked_resource, batch->last_tracked_resource, tmp); + SllStackPushN(bin->first, tmp, next_in_bin); + } + trn = tmp; + } + // Fetch/create tracked resource in previous batch + if (prev_batch) + { + if (!prev_batch->tracked_resource_bins) + { + prev_batch->tracked_resource_bins = PushStructs(arena, G_D12_TrackedResourceBin, G_D12_TrackedResourceBinsCount); + } + G_D12_TrackedResourceBin *bin = &prev_batch->tracked_resource_bins[hash % G_D12_TrackedResourceBinsCount]; + G_D12_TrackedResourceNode *tmp = bin->first; + for (; tmp; tmp = tmp->next_in_bin) + { + if (tmp->hash == hash) + { + break; + } + } + if (!tmp) + { + tmp = PushStruct(arena, G_D12_TrackedResourceNode); + tmp->resource = resource; + tmp->hash = hash; + SllQueuePush(prev_batch->first_tracked_resource, prev_batch->last_tracked_resource, tmp); + SllStackPushN(bin->first, tmp, next_in_bin); + } + prev_trn = tmp; } - } - - if (!trn) - { - trn = PushStruct(arena, G_D12_TrackedResourceNode); - trn->resource = resource; - trn->hash = hash; - SllQueuePush(batch->first_tracked_resource, batch->last_tracked_resource, trn); - SllStackPushN(bin->first, trn, next_in_bin); } for (i32 mip_idx = mips.min; mip_idx <= mips.max; ++mip_idx) { G_D12_TrackedMip *mip = &trn->mips[mip_idx]; + G_D12_TrackedMip *prev_mip = 0; + if (prev_trn) + { + prev_mip = &prev_trn->mips[mip_idx]; + } + if (usage_kind > mip->usage) { mip->usage = usage_kind; } + if (usage_kind == G_D12_TrackedUsageKind_MakeExclusive) { mip->prev_usage = G_D12_TrackedUsageKind_MakeCommon; } + else + { + if (usage_kind == G_D12_TrackedUsageKind_MakeCommon) + { + mip->next_usage = G_D12_TrackedUsageKind_MakeCommon; + } + if (prev_mip) + { + mip->prev_usage = prev_mip->usage; + } + } + + if (prev_mip) + { + prev_mip->usage = mip->prev_usage; + prev_mip->next_usage = mip->usage; + } } } } @@ -2264,19 +2320,13 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) if (batch->contains_hazard) { ++batches_count; - SllQueuePush(first_batch, last_batch, batch); + DllQueuePush(first_batch, last_batch, batch); batch = PushStruct(scratch.arena, G_D12_CmdBatch); } G_D12_Resource *resource = cmd->barrier.resource; if (resource) { - // ++batch->transitions_count; - // G_D12_TransitionNode *tn = PushStruct(scratch.arena, G_D12_TransitionNode); - // SllQueuePush(batch->first_transition, batch->last_transition, tn); - // tn->resource = resource; - // tn->mips = RNGI32(0, resource->texture_mips - 1); - if (cmd->barrier.to_exclusive) { G_D12_UpdateTrackedUsage(scratch.arena, batch, resource, RNGI32(0, resource->texture_mips - 1), G_D12_TrackedUsageKind_MakeExclusive); @@ -2302,14 +2352,14 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { // Submit open batch ++batches_count; - SllQueuePush(first_batch, last_batch, batch); + DllQueuePush(first_batch, last_batch, batch); if (batch->first_tracked_resource) { // Final empty batch to implicitly decay tracked resources batch = PushStruct(scratch.arena, G_D12_CmdBatch); ++batches_count; - SllQueuePush(first_batch, last_batch, batch); + DllQueuePush(first_batch, last_batch, batch); } } } @@ -2327,56 +2377,10 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) { G_D12_Resource *resource = trn->resource; - // Fetch next & prev resources - G_D12_TrackedResourceNode *next_trn = 0; - G_D12_TrackedResourceNode *prev_trn = 0; - { - u64 hash = MixU64(resource->uid); - if (prev_batch && prev_batch->tracked_resource_bins) - { - G_D12_TrackedResourceBin *bin = &prev_batch->tracked_resource_bins[hash % G_D12_TrackedResourceBinsCount]; - for (; prev_trn; prev_trn = prev_trn->next_in_bin) - { - if (prev_trn->hash == hash) - { - break; - } - } - } - if (next_batch && next_batch->tracked_resource_bins) - { - G_D12_TrackedResourceBin *bin = &next_batch->tracked_resource_bins[hash % G_D12_TrackedResourceBinsCount]; - for (; next_trn; next_trn = next_trn->next_in_bin) - { - if (next_trn->hash == hash) - { - break; - } - } - } - } - for (i32 mip_idx = 0; mip_idx < resource->texture_mips; ++mip_idx) { G_D12_TrackedMip *mip = &trn->mips[mip_idx]; - if (mip->prev_usage == G_D12_TrackedUsageKind_Untracked && prev_trn) - { - G_D12_TrackedMip *prev_mip = &prev_trn->mips[mip_idx]; - mip->prev_usage = prev_mip->usage; - } - - G_D12_TrackedUsageKind next_usage = G_D12_TrackedUsageKind_Untracked; - if (mip->usage == G_D12_TrackedUsageKind_MakeCommon) - { - next_usage = G_D12_TrackedUsageKind_MakeCommon; - } - else if (next_trn) - { - G_D12_TrackedMip *next_mip = &next_trn->mips[mip_idx]; - next_usage = next_mip->usage; - } - // Push promotion transition if (mip->usage != mip->prev_usage) { @@ -2391,7 +2395,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) } // Push decay transition to next batch - if (next_batch && mip->usage != next_usage) + if (next_batch && mip->usage != mip->next_usage) { ++next_batch->transitions_count; G_D12_TransitionNode *tn = PushStruct(scratch.arena, G_D12_TransitionNode); @@ -2399,7 +2403,7 @@ i64 G_CommitCommandList(G_CommandListHandle cl_handle) tn->resource = resource; tn->old = mip->usage; - tn->new = next_usage; + tn->new = mip->next_usage; tn->mips = RNGI32(mip_idx, mip_idx); } } diff --git a/src/gpu/gpu_dx12/gpu_dx12_core.h b/src/gpu/gpu_dx12/gpu_dx12_core.h index b58471bc..fcee93b2 100644 --- a/src/gpu/gpu_dx12/gpu_dx12_core.h +++ b/src/gpu/gpu_dx12/gpu_dx12_core.h @@ -432,6 +432,7 @@ Struct(G_D12_TrackedMip) { G_D12_TrackedUsageKind prev_usage; G_D12_TrackedUsageKind usage; + G_D12_TrackedUsageKind next_usage; }; Struct(G_D12_TrackedResourceNode)