mirror of
https://git.sr.ht/~eliasnaur/gio
synced 2026-07-07 18:35:34 +00:00
gpu/internal/vulkan,internal/vk: allocate descriptor sets in batches
We know exactly the configuration and number of sets in each pool, so we may as well allocate them al up front. References: https://todo.sr.ht/~eliasnaur/gio/375 Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
@@ -107,8 +107,8 @@ type descPool struct {
|
|||||||
layout vk.PipelineLayout
|
layout vk.PipelineLayout
|
||||||
descLayout vk.DescriptorSetLayout
|
descLayout vk.DescriptorSetLayout
|
||||||
pool vk.DescriptorPool
|
pool vk.DescriptorPool
|
||||||
|
sets []vk.DescriptorSet
|
||||||
size int
|
size int
|
||||||
cap int
|
|
||||||
texBinds []int
|
texBinds []int
|
||||||
imgBinds []int
|
imgBinds []int
|
||||||
bufBinds []int
|
bufBinds []int
|
||||||
@@ -224,7 +224,6 @@ func (b *Backend) resetPipes() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if p.desc.size > 0 {
|
if p.desc.size > 0 {
|
||||||
vk.ResetDescriptorPool(b.dev, p.desc.pool)
|
|
||||||
p.desc.size = 0
|
p.desc.size = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,24 +685,17 @@ func (p *descPool) release(d vk.Device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *descPool) bindDescriptorSet(b *Backend, cmdBuf vk.CommandBuffer, bindPoint vk.PipelineBindPoint, texBinds [texUnits]*Texture, bufBinds [storageUnits]*Buffer) {
|
func (p *descPool) bindDescriptorSet(b *Backend, cmdBuf vk.CommandBuffer, bindPoint vk.PipelineBindPoint, texBinds [texUnits]*Texture, bufBinds [storageUnits]*Buffer) {
|
||||||
realloced := false
|
if p.size == len(p.sets) {
|
||||||
destroyPool := func() {
|
l := p.descLayout
|
||||||
|
if l == 0 {
|
||||||
|
panic("vulkan: descriptor set is dirty, but pipeline has empty layout")
|
||||||
|
}
|
||||||
|
newCap := len(p.sets) * 2
|
||||||
if pool := p.pool; pool != 0 {
|
if pool := p.pool; pool != 0 {
|
||||||
b.deferFunc(func(d vk.Device) {
|
b.deferFunc(func(d vk.Device) {
|
||||||
vk.DestroyDescriptorPool(d, pool)
|
vk.DestroyDescriptorPool(d, pool)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
p.pool = 0
|
|
||||||
p.cap = 0
|
|
||||||
}
|
|
||||||
for {
|
|
||||||
if p.size == p.cap {
|
|
||||||
if realloced {
|
|
||||||
panic("vulkan: vkAllocateDescriptorSet failed on a newly allocated descriptor pool")
|
|
||||||
}
|
|
||||||
newCap := p.cap * 2
|
|
||||||
destroyPool()
|
|
||||||
realloced = true
|
|
||||||
const initialPoolSize = 100
|
const initialPoolSize = 100
|
||||||
if newCap < initialPoolSize {
|
if newCap < initialPoolSize {
|
||||||
newCap = initialPoolSize
|
newCap = initialPoolSize
|
||||||
@@ -720,21 +712,17 @@ func (p *descPool) bindDescriptorSet(b *Backend, cmdBuf vk.CommandBuffer, bindPo
|
|||||||
}
|
}
|
||||||
pool, err := vk.CreateDescriptorPool(b.dev, newCap, poolSizes)
|
pool, err := vk.CreateDescriptorPool(b.dev, newCap, poolSizes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Errorf("vulkan: failed to allocate descriptor pool with %d descriptors", newCap))
|
panic(fmt.Errorf("vulkan: failed to allocate descriptor pool with %d descriptors: %v", newCap, err))
|
||||||
}
|
}
|
||||||
p.pool = pool
|
p.pool = pool
|
||||||
p.cap = newCap
|
sets, err := vk.AllocateDescriptorSets(b.dev, p.pool, l, newCap)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Errorf("vulkan: failed to allocate descriptor with %d sets: %v", newCap, err))
|
||||||
|
}
|
||||||
|
p.sets = sets
|
||||||
p.size = 0
|
p.size = 0
|
||||||
}
|
}
|
||||||
l := p.descLayout
|
descSet := p.sets[p.size]
|
||||||
if l == 0 {
|
|
||||||
panic("vulkan: descriptor set is dirty, but pipeline has empty layout")
|
|
||||||
}
|
|
||||||
descSet, err := vk.AllocateDescriptorSet(b.dev, p.pool, l)
|
|
||||||
if err != nil {
|
|
||||||
destroyPool()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
p.size++
|
p.size++
|
||||||
for _, bind := range p.texBinds {
|
for _, bind := range p.texBinds {
|
||||||
tex := texBinds[bind]
|
tex := texBinds[bind]
|
||||||
@@ -752,8 +740,6 @@ func (p *descPool) bindDescriptorSet(b *Backend, cmdBuf vk.CommandBuffer, bindPo
|
|||||||
vk.UpdateDescriptorSet(b.dev, write)
|
vk.UpdateDescriptorSet(b.dev, write)
|
||||||
}
|
}
|
||||||
vk.CmdBindDescriptorSets(cmdBuf, bindPoint, p.layout, 0, []vk.DescriptorSet{descSet})
|
vk.CmdBindDescriptorSets(cmdBuf, bindPoint, p.layout, 0, []vk.DescriptorSet{descSet})
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Texture) imageBarrier(cmdBuf vk.CommandBuffer, layout vk.ImageLayout, stage vk.PipelineStageFlags, access vk.AccessFlags) {
|
func (t *Texture) imageBarrier(cmdBuf vk.CommandBuffer, layout vk.ImageLayout, stage vk.PipelineStageFlags, access vk.AccessFlags) {
|
||||||
|
|||||||
+11
-7
@@ -1739,18 +1739,22 @@ func UpdateDescriptorSet(d Device, write WriteDescriptorSet) {
|
|||||||
C.vkUpdateDescriptorSets(funcs.vkUpdateDescriptorSets, d, write, 0, nil)
|
C.vkUpdateDescriptorSets(funcs.vkUpdateDescriptorSets, d, write, 0, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func AllocateDescriptorSet(d Device, pool DescriptorPool, layout DescriptorSetLayout) (DescriptorSet, error) {
|
func AllocateDescriptorSets(d Device, pool DescriptorPool, layout DescriptorSetLayout, count int) ([]DescriptorSet, error) {
|
||||||
|
layouts := make([]DescriptorSetLayout, count)
|
||||||
|
for i := range layouts {
|
||||||
|
layouts[i] = layout
|
||||||
|
}
|
||||||
inf := C.VkDescriptorSetAllocateInfo{
|
inf := C.VkDescriptorSetAllocateInfo{
|
||||||
sType: C.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
sType: C.VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
|
||||||
descriptorPool: pool,
|
descriptorPool: pool,
|
||||||
descriptorSetCount: 1,
|
descriptorSetCount: C.uint32_t(count),
|
||||||
pSetLayouts: &layout,
|
pSetLayouts: &layouts[0],
|
||||||
}
|
}
|
||||||
var set C.VkDescriptorSet
|
sets := make([]DescriptorSet, count, count)
|
||||||
if err := vkErr(C.vkAllocateDescriptorSets(funcs.vkAllocateDescriptorSets, d, inf, &set)); err != nil {
|
if err := vkErr(C.vkAllocateDescriptorSets(funcs.vkAllocateDescriptorSets, d, inf, &sets[0])); err != nil {
|
||||||
return nilDescriptorSet, fmt.Errorf("vulkan: vkAllocateDescriptorSets: %w", err)
|
return nil, fmt.Errorf("vulkan: vkAllocateDescriptorSets: %w", err)
|
||||||
}
|
}
|
||||||
return set, nil
|
return sets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateComputePipeline(d Device, mod ShaderModule, layout PipelineLayout) (Pipeline, error) {
|
func CreateComputePipeline(d Device, mod ShaderModule, layout PipelineLayout) (Pipeline, error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user