zworld/engine/renderapi/buffer/buffer.go
2024-01-14 22:56:06 +08:00

126 lines
2.6 KiB
Go

package buffer
import (
"zworld/engine/renderapi/device"
"github.com/vkngwrapper/core/v2/core1_0"
"github.com/vkngwrapper/core/v2/driver"
)
type T interface {
device.Resource[core1_0.Buffer]
// Size returns the total allocation size of the buffer in bytes
Size() int
// Read directly from the buffer at the given offset
Read(offset int, data any) int
// Write directly to the buffer at the given offset
Write(offset int, data any) int
Flush()
// Memory returns a handle to the underlying memory block
Memory() device.Memory
}
type Args struct {
Key string
Size int
Usage core1_0.BufferUsageFlags
Memory core1_0.MemoryPropertyFlags
}
type buffer struct {
ptr core1_0.Buffer
device device.T
memory device.Memory
size int
}
func New(device device.T, args Args) T {
if args.Size == 0 {
panic("buffer size cant be 0")
}
queueIdx := device.GetQueueFamilyIndex(core1_0.QueueGraphics)
ptr, _, err := device.Ptr().CreateBuffer(nil, core1_0.BufferCreateInfo{
Flags: 0,
Size: args.Size,
Usage: args.Usage,
SharingMode: core1_0.SharingModeExclusive,
QueueFamilyIndices: []int{queueIdx},
})
if err != nil {
panic(err)
}
if args.Key != "" {
device.SetDebugObjectName(driver.VulkanHandle(ptr.Handle()),
core1_0.ObjectTypeBuffer, args.Key)
}
memreq := ptr.MemoryRequirements()
mem := device.Allocate(args.Key, *memreq, args.Memory)
ptr.BindBufferMemory(mem.Ptr(), 0)
return &buffer{
ptr: ptr,
device: device,
memory: mem,
size: int(memreq.Size),
}
}
func NewShared(device device.T, key string, size int) T {
return New(device, Args{
Key: key,
Size: size,
Usage: core1_0.BufferUsageTransferSrc | core1_0.BufferUsageTransferDst,
Memory: core1_0.MemoryPropertyHostVisible | core1_0.MemoryPropertyHostCoherent,
})
}
func NewRemote(device device.T, key string, size int, flags core1_0.BufferUsageFlags) T {
return New(device, Args{
Key: key,
Size: size,
Usage: core1_0.BufferUsageTransferDst | flags,
Memory: core1_0.MemoryPropertyDeviceLocal,
})
}
func (b *buffer) Ptr() core1_0.Buffer {
return b.ptr
}
func (b *buffer) Size() int {
return b.size
}
func (b *buffer) Memory() device.Memory {
return b.memory
}
func (b *buffer) Destroy() {
b.ptr.Destroy(nil)
b.memory.Destroy()
b.ptr = nil
b.memory = nil
b.device = nil
}
func (b *buffer) Write(offset int, data any) int {
return b.memory.Write(offset, data)
}
func (b *buffer) Read(offset int, data any) int {
return b.memory.Read(offset, data)
}
func (b *buffer) Flush() {
b.memory.Flush()
}