c1de8b6f
renderer: gate fence re-signal on pre-submit errors only
a73x 2026-04-18 15:16
Commit message
src/renderer.zig
| Old | New | ||
|---|---|---|---|
| @@ -1292,7 +1292,10 @@ pub const Context = struct { | |||
| 1292 | const image_index = try vk_sync.acquireImageBounded(self.vkd, self.device, self.swapchain, self.image_available); | 1292 | const image_index = try vk_sync.acquireImageBounded(self.vkd, self.device, self.swapchain, self.image_available); |
| 1293 | 1293 | ||
| 1294 | try self.vkd.resetFences(self.device, 1, @ptrCast(&self.in_flight_fence)); | 1294 | try self.vkd.resetFences(self.device, 1, @ptrCast(&self.in_flight_fence)); |
| 1295 | errdefer self.resignalFence(self.in_flight_fence); | 1295 | // Re-signal only on errors before queueSubmit; once submit succeeds the |
| 1296 | // GPU will signal the fence on completion and a manual signal would race. | ||
| 1297 | var submit_done = false; | ||
| 1298 | errdefer if (!submit_done) self.resignalFence(self.in_flight_fence); | ||
| 1296 | 1299 | ||
| 1297 | // Record command buffer | 1300 | // Record command buffer |
| 1298 | try self.vkd.resetCommandBuffer(self.command_buffer, .{}); | 1301 | try self.vkd.resetCommandBuffer(self.command_buffer, .{}); |
| @@ -1331,6 +1334,7 @@ pub const Context = struct { | |||
| 1331 | .signal_semaphore_count = 1, | 1334 | .signal_semaphore_count = 1, |
| 1332 | .p_signal_semaphores = @ptrCast(&self.render_finished), | 1335 | .p_signal_semaphores = @ptrCast(&self.render_finished), |
| 1333 | }), self.in_flight_fence); | 1336 | }), self.in_flight_fence); |
| 1337 | submit_done = true; | ||
| 1334 | 1338 | ||
| 1335 | // Present | 1339 | // Present |
| 1336 | const present_result = self.vkd.queuePresentKHR(self.present_queue, &vk.PresentInfoKHR{ | 1340 | const present_result = self.vkd.queuePresentKHR(self.present_queue, &vk.PresentInfoKHR{ |
| @@ -1725,7 +1729,10 @@ pub const Context = struct { | |||
| 1725 | } | 1729 | } |
| 1726 | 1730 | ||
| 1727 | try self.vkd.resetFences(self.device, 1, @ptrCast(&self.in_flight_fence)); | 1731 | try self.vkd.resetFences(self.device, 1, @ptrCast(&self.in_flight_fence)); |
| 1728 | errdefer self.resignalFence(self.in_flight_fence); | 1732 | // Re-signal only on errors before queueSubmit; once submit succeeds the |
| 1733 | // GPU will signal the fence on completion and a manual signal would race. | ||
| 1734 | var submit_done = false; | ||
| 1735 | errdefer if (!submit_done) self.resignalFence(self.in_flight_fence); | ||
| 1729 | 1736 | ||
| 1730 | // Record command buffer | 1737 | // Record command buffer |
| 1731 | try self.vkd.resetCommandBuffer(self.command_buffer, .{}); | 1738 | try self.vkd.resetCommandBuffer(self.command_buffer, .{}); |
| @@ -1774,6 +1781,7 @@ pub const Context = struct { | |||
| 1774 | .signal_semaphore_count = 1, | 1781 | .signal_semaphore_count = 1, |
| 1775 | .p_signal_semaphores = @ptrCast(&self.render_finished), | 1782 | .p_signal_semaphores = @ptrCast(&self.render_finished), |
| 1776 | }), self.in_flight_fence); | 1783 | }), self.in_flight_fence); |
| 1784 | submit_done = true; | ||
| 1777 | if (timing_out) |t| { | 1785 | if (timing_out) |t| { |
| 1778 | t.submit_us = readTimer(&timer); | 1786 | t.submit_us = readTimer(&timer); |
| 1779 | timer.reset(); | 1787 | timer.reset(); |
| @@ -1818,7 +1826,12 @@ pub const Context = struct { | |||
| 1818 | // 2. Reset + begin capture command buffer | 1826 | // 2. Reset + begin capture command buffer |
| 1819 | try vk_sync.waitFenceBounded(self.vkd, self.device, self.capture_fence); | 1827 | try vk_sync.waitFenceBounded(self.vkd, self.device, self.capture_fence); |
| 1820 | try self.vkd.resetFences(self.device, 1, @ptrCast(&self.capture_fence)); | 1828 | try self.vkd.resetFences(self.device, 1, @ptrCast(&self.capture_fence)); |
| 1821 | errdefer self.resignalFence(self.capture_fence); | 1829 | // Re-signal only on errors before queueSubmit; once submit succeeds the |
| 1830 | // GPU will signal the fence on completion and a manual signal would race | ||
| 1831 | // (in particular, the post-submit waitFenceBounded below could time out | ||
| 1832 | // on a driver flake while the GPU work is still legitimately in flight). | ||
| 1833 | var submit_done = false; | ||
| 1834 | errdefer if (!submit_done) self.resignalFence(self.capture_fence); | ||
| 1822 | 1835 | ||
| 1823 | try self.vkd.resetCommandBuffer(self.capture_cmd, .{}); | 1836 | try self.vkd.resetCommandBuffer(self.capture_cmd, .{}); |
| 1824 | try self.vkd.beginCommandBuffer(self.capture_cmd, &vk.CommandBufferBeginInfo{ | 1837 | try self.vkd.beginCommandBuffer(self.capture_cmd, &vk.CommandBufferBeginInfo{ |
| @@ -1934,6 +1947,7 @@ pub const Context = struct { | |||
| 1934 | .command_buffer_count = 1, | 1947 | .command_buffer_count = 1, |
| 1935 | .p_command_buffers = @ptrCast(&self.capture_cmd), | 1948 | .p_command_buffers = @ptrCast(&self.capture_cmd), |
| 1936 | }), self.capture_fence); | 1949 | }), self.capture_fence); |
| 1950 | submit_done = true; | ||
| 1937 | try vk_sync.waitFenceBounded(self.vkd, self.device, self.capture_fence); | 1951 | try vk_sync.waitFenceBounded(self.vkd, self.device, self.capture_fence); |
| 1938 | } | 1952 | } |
| 1939 | 1953 | ||