wip(render3d): one frame recording while one draws on Vulkan (double-buffered ring and pools), R3D_VK_LABELS, grass measuring switches (R3D_NOGRASS, R3D_BLADES, R3D_GRASS_S0/D0)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
4e2087d6eb
commit
f815f3e3cf
8 changed files with 100 additions and 19 deletions
|
|
@ -650,7 +650,8 @@ function gvk_frame_init(render3d_st: mut Render3dState) -> bool {
|
|||
if (counts & VK_SAMPLE_COUNT_2_BIT) != 0 { render3d_st.gvk_msaa_max = 2 }
|
||||
if (counts & VK_SAMPLE_COUNT_4_BIT) != 0 { render3d_st.gvk_msaa_max = 4 }
|
||||
render3d_st.gvk_ring_buf = gvk_buf_new(render3d_st)
|
||||
if not gvk_buf_reserve(render3d_st, render3d_st.gvk_ring_buf, GVK_RING_BYTES) { return false }
|
||||
# one half per frame slot: the cached sets bind this one buffer, and each draw's offset says the half
|
||||
if not gvk_buf_reserve(render3d_st, render3d_st.gvk_ring_buf, GVK_RING_BYTES * 2) { return false }
|
||||
let sizes = bytes(VkDescriptorPoolSize_sizeof * 3)
|
||||
Vk.put_i32(sizes, VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||
Vk.put_i32(sizes, VkDescriptorPoolSize_descriptorCount, 32768)
|
||||
|
|
@ -665,9 +666,13 @@ function gvk_frame_init(render3d_st: mut Render3dState) -> bool {
|
|||
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_poolSizeCount, 3)
|
||||
Vk.put_ptr(dpci, VkDescriptorPoolCreateInfo_pPoolSizes, sizes)
|
||||
let out = bytes(8)
|
||||
let r = Vk.create_descriptor_pool(render3d_st.gvk_dev, dpci, null, out)
|
||||
if r != VK_SUCCESS { return gvk_fail(render3d_st, "vkCreateDescriptorPool", r) }
|
||||
render3d_st.gvk_dpool = gvk_handle(out)
|
||||
render3d_st.gvk_dpools = new []long
|
||||
for k in 0 .. 2 {
|
||||
let r = Vk.create_descriptor_pool(render3d_st.gvk_dev, dpci, null, out)
|
||||
if r != VK_SUCCESS { return gvk_fail(render3d_st, "vkCreateDescriptorPool", r) }
|
||||
push(render3d_st.gvk_dpools, gvk_handle(out))
|
||||
}
|
||||
render3d_st.gvk_dpool = render3d_st.gvk_dpools[0]
|
||||
if not gvk_kpool_make(render3d_st) { return false }
|
||||
render3d_st.gvk_white = gvk_tex_new(render3d_st)
|
||||
let px = bytes(4)
|
||||
|
|
@ -676,14 +681,17 @@ function gvk_frame_init(render3d_st: mut Render3dState) -> bool {
|
|||
}
|
||||
|
||||
function gvk_frame_reset(render3d_st: mut Render3dState) -> void {
|
||||
render3d_st.gvk_ring_off = 0
|
||||
let slot = render3d_st.gvk_frame_no & 1
|
||||
render3d_st.gvk_ring_off = slot * GVK_RING_BYTES
|
||||
render3d_st.gvk_ring_end = (slot + 1) * GVK_RING_BYTES
|
||||
render3d_st.gvk_dpool = render3d_st.gvk_dpools[slot]
|
||||
Vk.reset_descriptor_pool(render3d_st.gvk_dev, render3d_st.gvk_dpool, 0)
|
||||
}
|
||||
|
||||
# a block into the ring; its offset, or -1 when the frame has used the whole ring
|
||||
function gvk_ring_put(render3d_st: mut Render3dState, blk: pointer, n: int) -> int {
|
||||
let at = (render3d_st.gvk_ring_off + render3d_st.gvk_ring_align - 1) / render3d_st.gvk_ring_align * render3d_st.gvk_ring_align
|
||||
if at + n > GVK_RING_BYTES { return -1 }
|
||||
if at + n > render3d_st.gvk_ring_end { return -1 }
|
||||
mem_copy(mem_off(render3d_st.gvk_buf_map[render3d_st.gvk_ring_buf], at), blk, n)
|
||||
render3d_st.gvk_ring_off = at + n
|
||||
return at
|
||||
|
|
@ -954,7 +962,8 @@ function gvk_screen_make(render3d_st: mut Render3dState, w: int, h: int) -> bool
|
|||
|
||||
function gvk_frame_cb(render3d_st: mut Render3dState) -> pointer {
|
||||
if render3d_st.gvk_cb == null {
|
||||
gvk_frame_wait(render3d_st)
|
||||
# the frame in flight uses the other half of the ring and the other pool, unless it has this slot
|
||||
if render3d_st.gvk_frame_pending and (render3d_st.gvk_frame_pending_no & 1) == (render3d_st.gvk_frame_no & 1) { gvk_frame_wait(render3d_st) }
|
||||
gvk_frame_reset(render3d_st)
|
||||
render3d_st.gvk_cb = gvk_once_begin(render3d_st)
|
||||
}
|
||||
|
|
@ -1270,6 +1279,7 @@ function gvk_flush(render3d_st: mut Render3dState) -> void {
|
|||
if render3d_st.gvk_cb == null { return }
|
||||
render3d_st.gvk_n_flush += 1
|
||||
gvk_pass_end(render3d_st)
|
||||
gvk_labels_close(render3d_st)
|
||||
gvk_once_end(render3d_st, render3d_st.gvk_cb)
|
||||
render3d_st.gvk_cb = null
|
||||
render3d_st.gvk_frame_no += 1
|
||||
|
|
@ -1290,6 +1300,7 @@ function gvk_present(render3d_st: mut Render3dState) -> void {
|
|||
}
|
||||
if render3d_st.gvk_cb == null { return }
|
||||
gvk_pass_end(render3d_st)
|
||||
gvk_labels_close(render3d_st)
|
||||
gvk_once_end(render3d_st, render3d_st.gvk_cb)
|
||||
render3d_st.gvk_cb = null
|
||||
render3d_st.gvk_frame_no += 1
|
||||
|
|
@ -1669,6 +1680,7 @@ function gvk_swap_make(render3d_st: mut Render3dState, w: int, h: int) -> bool {
|
|||
function gvk_present_window(render3d_st: mut Render3dState) -> void {
|
||||
let cb = gvk_frame_cb(render3d_st)
|
||||
gvk_pass_end(render3d_st)
|
||||
gvk_labels_close(render3d_st)
|
||||
# a covered window is not drawn to: its layer would hold the frame for a drawable the compositor
|
||||
# hands back once a second. The frame still runs, paced at about 60 Hz, so the game keeps time.
|
||||
if win_visible() == 0 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue