116 lines
2.5 KiB
Go
116 lines
2.5 KiB
Go
package descriptor
|
|
|
|
import (
|
|
"log"
|
|
|
|
"zworld/engine/renderapi/device"
|
|
|
|
"github.com/vkngwrapper/core/v2/common"
|
|
"github.com/vkngwrapper/core/v2/core1_0"
|
|
"github.com/vkngwrapper/core/v2/driver"
|
|
"github.com/vkngwrapper/extensions/v2/ext_descriptor_indexing"
|
|
)
|
|
|
|
type Pool interface {
|
|
device.Resource[core1_0.DescriptorPool]
|
|
|
|
Allocate(layouts SetLayout) Set
|
|
Recreate()
|
|
}
|
|
|
|
type pool struct {
|
|
ptr core1_0.DescriptorPool
|
|
device device.T
|
|
sizes []core1_0.DescriptorPoolSize
|
|
maxSets int
|
|
|
|
allocatedSets int
|
|
allocatedCounts map[core1_0.DescriptorType]int
|
|
}
|
|
|
|
func NewPool(device device.T, sets int, sizes []core1_0.DescriptorPoolSize) Pool {
|
|
p := &pool{
|
|
device: device,
|
|
ptr: nil,
|
|
sizes: sizes,
|
|
maxSets: sets,
|
|
allocatedCounts: make(map[core1_0.DescriptorType]int),
|
|
}
|
|
p.Recreate()
|
|
return p
|
|
}
|
|
|
|
func (p *pool) Ptr() core1_0.DescriptorPool {
|
|
return p.ptr
|
|
}
|
|
|
|
func (p *pool) Recreate() {
|
|
p.Destroy()
|
|
|
|
info := core1_0.DescriptorPoolCreateInfo{
|
|
Flags: ext_descriptor_indexing.DescriptorPoolCreateUpdateAfterBind,
|
|
PoolSizes: p.sizes,
|
|
MaxSets: p.maxSets,
|
|
}
|
|
ptr, result, err := p.device.Ptr().CreateDescriptorPool(nil, info)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if result != core1_0.VKSuccess {
|
|
panic("failed to create descriptor pooll")
|
|
}
|
|
p.ptr = ptr
|
|
}
|
|
|
|
func (p *pool) Destroy() {
|
|
if p.ptr == nil {
|
|
return
|
|
}
|
|
p.ptr.Destroy(nil)
|
|
p.ptr = nil
|
|
}
|
|
|
|
func (p *pool) Allocate(layout SetLayout) Set {
|
|
info := core1_0.DescriptorSetAllocateInfo{
|
|
DescriptorPool: p.ptr,
|
|
SetLayouts: []core1_0.DescriptorSetLayout{layout.Ptr()},
|
|
}
|
|
|
|
if layout.VariableCount() > 0 {
|
|
variableInfo := ext_descriptor_indexing.DescriptorSetVariableDescriptorCountAllocateInfo{
|
|
DescriptorCounts: []int{layout.VariableCount()},
|
|
}
|
|
info.NextOptions = common.NextOptions{Next: variableInfo}
|
|
}
|
|
|
|
ptr, r, err := p.device.Ptr().AllocateDescriptorSets(info)
|
|
if err != nil {
|
|
log.Println("allocated sets:", p.allocatedSets, "/", p.maxSets)
|
|
log.Println("allocated counts:", p.allocatedCounts)
|
|
panic(err)
|
|
}
|
|
if r != core1_0.VKSuccess {
|
|
if r == core1_0.VKErrorOutOfDeviceMemory {
|
|
panic("failed to allocate descriptor set: out of pool memory")
|
|
}
|
|
panic("failed to allocate descriptor set")
|
|
}
|
|
|
|
p.device.SetDebugObjectName(
|
|
driver.VulkanHandle(ptr[0].Handle()),
|
|
core1_0.ObjectTypeDescriptorSet,
|
|
layout.Name())
|
|
|
|
p.allocatedSets++
|
|
for kind, count := range layout.Counts() {
|
|
current, _ := p.allocatedCounts[kind]
|
|
p.allocatedCounts[kind] = current + count
|
|
}
|
|
|
|
return &set{
|
|
device: p.device,
|
|
ptr: ptr[0],
|
|
layout: layout,
|
|
}
|
|
}
|