Harbor

Changelog a58b553aa0e4

pin gpu d3d12 resource sync

@sky · 1 month ago · parent ca7b6a35153c
0 added 4 modified 0 deleted
gpu/backend/d3d12/d3d12_backend.odin modified

Diff hidden because this file has more than 800 lines.

gpu/backend/d3d12/d3d12_frame.odin +15 -20 modified
13 unchanged lines hidden
14 14 if g_d3d == nil {return}
15 15
16 16 wait_gpu_idle()
17 + drain_deferred_releases_now_d3d12()
17 18
18 19 // Destroy all active samplers
19 20 for &entry in g_d3d.samplers {
18 unchanged lines hidden
38 39 }
39 40
40 41 // Destroy shaders
41 - for &entry in g_d3d.shaders {
42 - if entry.active {
43 - delete(entry.bytecode)
44 - entry.active = false
45 - }
42 + for i in 0 ..< MAX_SHADERS {
43 + if g_d3d.shaders[i].active do destroy_shader_d3d12(bk.Shader_Handle(i))
46 44 }
47 45
48 46 // Destroy pipelines
49 - for &entry in g_d3d.pipelines {
50 - if entry.active {
51 - if entry.pso != nil {entry.pso->Release()}
52 - entry.active = false
53 - }
47 + for i in 0 ..< MAX_PIPELINES {
48 + if g_d3d.pipelines[i].active do destroy_graphics_pipeline_d3d12(bk.Pipeline_Handle(i))
54 49 }
55 50
56 51 // Destroy textures
57 - for &entry in g_d3d.textures {
58 - if entry.active {
59 - if entry.resource != nil {entry.resource->Release()}
60 - entry.active = false
61 - }
52 + for i in 0 ..< MAX_TEXTURES {
53 + if g_d3d.textures[i].active do destroy_texture_d3d12(bk.Texture_Handle(i))
62 54 }
63 55
64 56 // Destroy buffers
65 - for &entry in g_d3d.buffers {
66 - if entry.active {
67 - if entry.resource != nil {entry.resource->Release()}
68 - entry.active = false
69 - }
57 + for i in 0 ..< MAX_BUFFERS {
58 + if g_d3d.buffers[i].active do destroy_buffer_d3d12(bk.Buffer_Handle(i))
70 59 }
71 60
61 + drain_deferred_releases_now_d3d12()
62 +
72 63 // Destroy core objects
73 64 if g_d3d.graphics_root_sig != nil {g_d3d.graphics_root_sig->Release()}
74 65 if g_d3d.compute_root_sig != nil {g_d3d.compute_root_sig->Release()}
26 unchanged lines hidden
101 92 if g_d3d.command_queue != nil {g_d3d.command_queue->Release()}
102 93 if g_d3d.device != nil {g_d3d.device->Release()}
103 94
95 + delete(g_d3d.deferred_releases)
104 96 free(g_d3d)
105 97 g_d3d = nil
106 98 bk.backend_initialized = false
1 unchanged lines hidden
108 100
109 101 wait_idle_d3d12 :: proc() {
110 102 wait_gpu_idle()
103 + drain_deferred_releases_now_d3d12()
111 104 }
112 105
113 106 // --- Frame lifecycle ---
11 unchanged lines hidden
125 118 win32.WaitForSingleObject(g_d3d.fence_event, win32.INFINITE)
126 119 }
127 120 }
121 + drain_deferred_releases_now_d3d12()
128 122
129 123 // Reset allocator and command list
130 124 fr.command_allocator->Reset()
47 unchanged lines hidden
178 172 fr.fence_value = g_d3d.fence_value
179 173 g_d3d.command_queue->Signal(g_d3d.fence, g_d3d.fence_value)
180 174 g_d3d.fence_value += 1
175 + drain_deferred_releases_now_d3d12()
181 176
182 177 g_d3d.frame_active = false
183 178 g_d3d.render_pass_active = false
209 unchanged lines hidden
gpu/backend/d3d12/d3d12_ops.odin modified

Diff hidden because this file has more than 800 lines.

gpu/docs/gpu_intent_api.md +10 -0 modified
43 unchanged lines hidden
44 44
45 45 Rule: if visibility requires meaning, host handles it. If visibility only requires geometry/render state, `gpu` may handle it.
46 46
47 + ## Resource lifetime and synchronization
48 +
49 + Backends must preserve GPU object lifetime until every command list that references the object has completed. Destroying a buffer, texture, shader, pipeline, framebuffer attachment, or temporary upload allocation while frames are in flight retires the backend object behind the completed fence that covers the already-recorded work. `wait_idle` drains all retired objects.
50 +
51 + CPU mapping is only valid for host-visible buffers. GPU-local/default buffers are not mappable through `map_buffer` or `get_buffer_mapped`; backends must report that explicitly and return `nil`. Host-visible upload buffers may stay persistently mapped when the backend memory model allows it.
52 +
53 + `compute_barrier` means storage/UAV visibility between backend dispatch/draw work in one frame. It is not a render-target transition substitute. Backends that lack a complete storage descriptor path must report that separately through capabilities or diagnostics instead of pretending the barrier enables unsupported binding.
54 +
55 + D3D12 runtime fence behavior cannot be executed by Linux CI. D3D12 lifetime and transition work is accepted by static backend checks, pure fence-order tests where available, and explicit Windows runtime verification debt.
56 +
47 57 ## Public frame shape
48 58
49 59 Target API shape:
184 unchanged lines hidden