Merge commit '8030cfd' into lang/foundations
This commit is contained in:
commit
5297996640
4 changed files with 41 additions and 13 deletions
7
changes/render3d-small-window.md
Normal file
7
changes/render3d-small-window.md
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
bump: patch
|
||||||
|
type: feature
|
||||||
|
**`r3d_small`: a renderer sized for a small UI window.** Set before `r3d_open`, it gives the frame's
|
||||||
|
uniform ring 2 x 4 MB (was 2 x 64), memory blocks of 8 MB with anything over 4 MB on its own (was 64 and
|
||||||
|
16) and descriptor pools an eighth of a world's. Maroon Lake's launcher window, which draws a picture and
|
||||||
|
text and never becomes the game, went from 817 MB to 446 MB with it and its own trims; the rest is the
|
||||||
|
font atlas, the backdrop, Metal's command-buffer storage while it draws, and the program's states.
|
||||||
|
|
@ -587,6 +587,7 @@ export state Render3dState {
|
||||||
r3d_time: float = 0.0
|
r3d_time: float = 0.0
|
||||||
r3d_ready: bool = false
|
r3d_ready: bool = false
|
||||||
r3d_plate: bool = false
|
r3d_plate: bool = false
|
||||||
|
r3d_small: bool = false # set before r3d_open: a small UI window (a launcher) - the ring, the memory blocks and the descriptor pools sized for it
|
||||||
r3d_sky_path: string = null
|
r3d_sky_path: string = null
|
||||||
r3d_debug: bool = false
|
r3d_debug: bool = false
|
||||||
r3d_debug_shadow: bool = false
|
r3d_debug_shadow: bool = false
|
||||||
|
|
|
||||||
|
|
@ -340,6 +340,16 @@ function gvk_alloc(render3d_st: mut Render3dState, req: bytes, want: int) -> lon
|
||||||
const GVK_BLOCK_DEVICE: int = 67108864
|
const GVK_BLOCK_DEVICE: int = 67108864
|
||||||
const GVK_BLOCK_HOST: int = 67108864
|
const GVK_BLOCK_HOST: int = 67108864
|
||||||
const GVK_OWN_OVER: int = 16777216
|
const GVK_OWN_OVER: int = 16777216
|
||||||
|
# a small window's (r3d_small): a UI's few sheets, not a world's hundreds of textures
|
||||||
|
const GVK_BLOCK_SMALL: int = 8388608
|
||||||
|
function gvk_block_bytes(render3d_st: Render3dState) -> int {
|
||||||
|
if render3d_st.r3d_small { return GVK_BLOCK_SMALL }
|
||||||
|
return GVK_BLOCK_DEVICE
|
||||||
|
}
|
||||||
|
function gvk_own_over(render3d_st: Render3dState) -> int {
|
||||||
|
if render3d_st.r3d_small { return GVK_BLOCK_SMALL / 2 }
|
||||||
|
return GVK_OWN_OVER
|
||||||
|
}
|
||||||
|
|
||||||
@alloc_ok("made once per resource and kept for its life (a texture, program, sampler, view, layout or memory block is created when first asked for)")
|
@alloc_ok("made once per resource and kept for its life (a texture, program, sampler, view, layout or memory block is created when first asked for)")
|
||||||
function gvk_mem_init(render3d_st: mut Render3dState) -> void {
|
function gvk_mem_init(render3d_st: mut Render3dState) -> void {
|
||||||
|
|
@ -414,7 +424,7 @@ function gvk_mem_new(render3d_st: mut Render3dState, req: bytes, want: int, imag
|
||||||
}
|
}
|
||||||
let mp = render3d_st.gvk_map_slot
|
let mp = render3d_st.gvk_map_slot
|
||||||
mp[0] = null
|
mp[0] = null
|
||||||
if size <= GVK_OWN_OVER {
|
if size <= gvk_own_over(render3d_st) {
|
||||||
var kind = t * 2
|
var kind = t * 2
|
||||||
if image { kind += 1 }
|
if image { kind += 1 }
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -434,8 +444,8 @@ function gvk_mem_new(render3d_st: mut Render3dState, req: bytes, want: int, imag
|
||||||
i += 1
|
i += 1
|
||||||
}
|
}
|
||||||
if blk < 0 {
|
if blk < 0 {
|
||||||
var bsize = GVK_BLOCK_DEVICE
|
var bsize = gvk_block_bytes(render3d_st)
|
||||||
if host { bsize = GVK_BLOCK_HOST }
|
if host and not render3d_st.r3d_small { bsize = GVK_BLOCK_HOST }
|
||||||
let mem = gvk_mem_raw(render3d_st, t, bsize, host, mp)
|
let mem = gvk_mem_raw(render3d_st, t, bsize, host, mp)
|
||||||
if mem != 0 {
|
if mem != 0 {
|
||||||
# into the record of a block given back, when there is one: a buffer made again every few
|
# into the record of a block given back, when there is one: a buffer made again every few
|
||||||
|
|
|
||||||
|
|
@ -716,6 +716,11 @@ function gvk_bind_texture(render3d_st: mut Render3dState, p: int, name: string,
|
||||||
# its descriptor set comes from a pool that is reset with the frame. Both are rewound at
|
# its descriptor set comes from a pool that is reset with the frame. Both are rewound at
|
||||||
# gvk_frame_reset.
|
# gvk_frame_reset.
|
||||||
const GVK_RING_BYTES: int = 64 * 1024 * 1024
|
const GVK_RING_BYTES: int = 64 * 1024 * 1024
|
||||||
|
const GVK_RING_SMALL: int = 4 * 1024 * 1024 # a UI's frame: a few hundred small blocks
|
||||||
|
function gvk_ring_bytes(render3d_st: Render3dState) -> int {
|
||||||
|
if render3d_st.r3d_small { return GVK_RING_SMALL }
|
||||||
|
return GVK_RING_BYTES
|
||||||
|
}
|
||||||
|
|
||||||
@alloc_ok("start-up: the device, its tables, the programs, the passes and the world's first textures are made once, before play")
|
@alloc_ok("start-up: the device, its tables, the programs, the passes and the world's first textures are made once, before play")
|
||||||
function gvk_frame_init(render3d_st: mut Render3dState) -> bool {
|
function gvk_frame_init(render3d_st: mut Render3dState) -> bool {
|
||||||
|
|
@ -732,18 +737,18 @@ function gvk_frame_init(render3d_st: mut Render3dState) -> bool {
|
||||||
if (counts & VK_SAMPLE_COUNT_4_BIT) != 0 { render3d_st.gvk_msaa_max = 4 }
|
if (counts & VK_SAMPLE_COUNT_4_BIT) != 0 { render3d_st.gvk_msaa_max = 4 }
|
||||||
render3d_st.gvk_ring_buf = gvk_buf_new(render3d_st)
|
render3d_st.gvk_ring_buf = gvk_buf_new(render3d_st)
|
||||||
# one half per frame slot: the cached sets bind this one buffer, and each draw's offset says the half
|
# 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 }
|
if not gvk_buf_reserve(render3d_st, render3d_st.gvk_ring_buf, gvk_ring_bytes(render3d_st) * 2) { return false }
|
||||||
let sizes = bytes(VkDescriptorPoolSize_sizeof * 3)
|
let sizes = bytes(VkDescriptorPoolSize_sizeof * 3)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_descriptorCount, 32768)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_descriptorCount, gvk_pool_n(render3d_st, 32768))
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_descriptorCount, 131072)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_descriptorCount, gvk_pool_n(render3d_st, 131072))
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof * 2 + VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof * 2 + VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof * 2 + VkDescriptorPoolSize_descriptorCount, 16384)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof * 2 + VkDescriptorPoolSize_descriptorCount, gvk_pool_n(render3d_st, 16384))
|
||||||
let dpci = bytes(VkDescriptorPoolCreateInfo_sizeof)
|
let dpci = bytes(VkDescriptorPoolCreateInfo_sizeof)
|
||||||
Vk.zero(dpci, VkDescriptorPoolCreateInfo_sizeof)
|
Vk.zero(dpci, VkDescriptorPoolCreateInfo_sizeof)
|
||||||
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_sType, VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
|
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_sType, VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
|
||||||
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_maxSets, 16384)
|
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_maxSets, gvk_pool_n(render3d_st, 16384))
|
||||||
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_poolSizeCount, 3)
|
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_poolSizeCount, 3)
|
||||||
Vk.put_ptr(dpci, VkDescriptorPoolCreateInfo_pPoolSizes, sizes)
|
Vk.put_ptr(dpci, VkDescriptorPoolCreateInfo_pPoolSizes, sizes)
|
||||||
let out = bytes(8)
|
let out = bytes(8)
|
||||||
|
|
@ -770,8 +775,8 @@ function gvk_frame_reset(render3d_st: mut Render3dState) -> void {
|
||||||
# draw still in use makes its set again the first time it is drawn
|
# draw still in use makes its set again the first time it is drawn
|
||||||
if render3d_st.gvk_sc_dead >= GVK_SC_DEAD_MAX { gvk_kpool_reset(render3d_st) }
|
if render3d_st.gvk_sc_dead >= GVK_SC_DEAD_MAX { gvk_kpool_reset(render3d_st) }
|
||||||
let slot = render3d_st.gvk_frame_no & 1
|
let slot = render3d_st.gvk_frame_no & 1
|
||||||
render3d_st.gvk_ring_off = slot * GVK_RING_BYTES
|
render3d_st.gvk_ring_off = slot * gvk_ring_bytes(render3d_st)
|
||||||
render3d_st.gvk_ring_end = (slot + 1) * GVK_RING_BYTES
|
render3d_st.gvk_ring_end = (slot + 1) * gvk_ring_bytes(render3d_st)
|
||||||
render3d_st.gvk_dpool = render3d_st.gvk_dpools[slot]
|
render3d_st.gvk_dpool = render3d_st.gvk_dpools[slot]
|
||||||
Vk.reset_descriptor_pool(render3d_st.gvk_dev, render3d_st.gvk_dpool, 0)
|
Vk.reset_descriptor_pool(render3d_st.gvk_dev, render3d_st.gvk_dpool, 0)
|
||||||
}
|
}
|
||||||
|
|
@ -795,18 +800,23 @@ function gvk_ring_put(render3d_st: mut Render3dState, blk: pointer, n: int) -> i
|
||||||
# sampler, so a set is never matched against a texture it no longer describes.
|
# sampler, so a set is never matched against a texture it no longer describes.
|
||||||
const GVK_KPOOL_SETS: int = 8192
|
const GVK_KPOOL_SETS: int = 8192
|
||||||
const GVK_SC_DEAD_MAX: int = 256 # textures released before the kept sets start over
|
const GVK_SC_DEAD_MAX: int = 256 # textures released before the kept sets start over
|
||||||
|
# a descriptor pool's counts: a small window's (r3d_small) an eighth of a world's
|
||||||
|
function gvk_pool_n(render3d_st: Render3dState, n: int) -> int {
|
||||||
|
if render3d_st.r3d_small { return n / 8 }
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
@alloc_ok("start-up: the device, its tables, the programs, the passes and the world's first textures are made once, before play")
|
@alloc_ok("start-up: the device, its tables, the programs, the passes and the world's first textures are made once, before play")
|
||||||
function gvk_kpool_make(render3d_st: mut Render3dState) -> bool {
|
function gvk_kpool_make(render3d_st: mut Render3dState) -> bool {
|
||||||
let sizes = bytes(VkDescriptorPoolSize_sizeof * 2)
|
let sizes = bytes(VkDescriptorPoolSize_sizeof * 2)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_descriptorCount, GVK_KPOOL_SETS * 2)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_descriptorCount, gvk_pool_n(render3d_st, GVK_KPOOL_SETS) * 2)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_type, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
|
||||||
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_descriptorCount, GVK_KPOOL_SETS * 8)
|
Vk.put_i32(sizes, VkDescriptorPoolSize_sizeof + VkDescriptorPoolSize_descriptorCount, gvk_pool_n(render3d_st, GVK_KPOOL_SETS) * 8)
|
||||||
let dpci = bytes(VkDescriptorPoolCreateInfo_sizeof)
|
let dpci = bytes(VkDescriptorPoolCreateInfo_sizeof)
|
||||||
Vk.zero(dpci, VkDescriptorPoolCreateInfo_sizeof)
|
Vk.zero(dpci, VkDescriptorPoolCreateInfo_sizeof)
|
||||||
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_sType, VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
|
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_sType, VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO)
|
||||||
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_maxSets, GVK_KPOOL_SETS)
|
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_maxSets, gvk_pool_n(render3d_st, GVK_KPOOL_SETS))
|
||||||
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_poolSizeCount, 2)
|
Vk.put_i32(dpci, VkDescriptorPoolCreateInfo_poolSizeCount, 2)
|
||||||
Vk.put_ptr(dpci, VkDescriptorPoolCreateInfo_pPoolSizes, sizes)
|
Vk.put_ptr(dpci, VkDescriptorPoolCreateInfo_pPoolSizes, sizes)
|
||||||
let out = bytes(8)
|
let out = bytes(8)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue