132 lines
2.8 KiB
Go
132 lines
2.8 KiB
Go
package vulkan
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"zworld/engine/renderapi/cache"
|
|
"zworld/engine/renderapi/command"
|
|
"zworld/engine/renderapi/descriptor"
|
|
"zworld/engine/renderapi/device"
|
|
"zworld/engine/renderapi/vulkan/instance"
|
|
|
|
"github.com/vkngwrapper/core/v2/core1_0"
|
|
)
|
|
|
|
type App interface {
|
|
Instance() instance.T
|
|
Device() device.T
|
|
Destroy()
|
|
|
|
Worker(int) command.Worker
|
|
Transferer() command.Worker
|
|
Flush()
|
|
|
|
Pool() descriptor.Pool
|
|
Meshes() cache.MeshCache
|
|
Textures() cache.TextureCache
|
|
Shaders() cache.ShaderCache
|
|
}
|
|
|
|
type backend struct {
|
|
appName string
|
|
instance instance.T
|
|
device device.T
|
|
|
|
transfer command.Worker
|
|
workers []command.Worker
|
|
|
|
pool descriptor.Pool
|
|
meshes cache.MeshCache
|
|
textures cache.TextureCache
|
|
shaders cache.ShaderCache
|
|
}
|
|
|
|
func New(appName string, deviceIndex int) App {
|
|
instance := instance.New(appName)
|
|
device, err := device.New(instance, instance.EnumeratePhysicalDevices()[0])
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// transfer worker
|
|
transfer := command.NewWorker(device, "xfer", core1_0.QueueTransfer|core1_0.QueueGraphics, 1)
|
|
|
|
// per frame graphics workers
|
|
workerCount := 1 // frames
|
|
workers := make([]command.Worker, workerCount)
|
|
for i := range workers {
|
|
workers[i] = command.NewWorker(device, fmt.Sprintf("frame%d", i), core1_0.QueueGraphics, 0)
|
|
}
|
|
|
|
// init caches
|
|
meshes := cache.NewMeshCache(device, transfer)
|
|
textures := cache.NewTextureCache(device, transfer)
|
|
shaders := cache.NewShaderCache(device)
|
|
|
|
pool := descriptor.NewPool(device, 1000, DefaultDescriptorPools)
|
|
|
|
return &backend{
|
|
appName: appName,
|
|
|
|
device: device,
|
|
instance: instance,
|
|
transfer: transfer,
|
|
workers: workers,
|
|
meshes: meshes,
|
|
textures: textures,
|
|
shaders: shaders,
|
|
pool: pool,
|
|
}
|
|
}
|
|
|
|
func (b *backend) Instance() instance.T { return b.instance }
|
|
func (b *backend) Device() device.T { return b.device }
|
|
|
|
func (b *backend) Pool() descriptor.Pool { return b.pool }
|
|
func (b *backend) Meshes() cache.MeshCache { return b.meshes }
|
|
func (b *backend) Textures() cache.TextureCache { return b.textures }
|
|
func (b *backend) Shaders() cache.ShaderCache { return b.shaders }
|
|
|
|
func (b *backend) Transferer() command.Worker {
|
|
return b.transfer
|
|
}
|
|
|
|
func (b *backend) Worker(frame int) command.Worker {
|
|
return b.workers[frame%len(b.workers)]
|
|
}
|
|
|
|
func (b *backend) Flush() {
|
|
// wait for all workers
|
|
for _, w := range b.workers {
|
|
w.Flush()
|
|
}
|
|
b.device.WaitIdle()
|
|
}
|
|
|
|
func (b *backend) Destroy() {
|
|
// flush any pending work
|
|
b.Flush()
|
|
|
|
// clean up caches
|
|
b.pool.Destroy()
|
|
b.meshes.Destroy()
|
|
b.textures.Destroy()
|
|
b.shaders.Destroy()
|
|
|
|
// destroy workers
|
|
b.transfer.Destroy()
|
|
for _, w := range b.workers {
|
|
w.Destroy()
|
|
}
|
|
b.workers = nil
|
|
|
|
if b.device != nil {
|
|
b.device.Destroy()
|
|
b.device = nil
|
|
}
|
|
if b.instance != nil {
|
|
b.instance.Destroy()
|
|
b.instance = nil
|
|
}
|
|
}
|