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

92 lines
2.1 KiB
Go

package cache
import (
"zworld/engine/renderapi/buffer"
"zworld/engine/renderapi/command"
"zworld/engine/renderapi/device"
"zworld/engine/renderapi/vertex"
"github.com/vkngwrapper/core/v2/core1_0"
)
type MeshCache T[vertex.Mesh, Mesh]
type meshes struct {
device device.T
worker command.Worker
}
func NewMeshCache(device device.T, worker command.Worker) MeshCache {
return New[vertex.Mesh, Mesh](&meshes{
device: device,
worker: worker,
})
}
func (m *meshes) Instantiate(mesh vertex.Mesh, callback func(Mesh)) {
var cached *vkMesh
var vtxStage, idxStage buffer.T
var idxType core1_0.IndexType
switch mesh.IndexSize() {
case 2:
idxType = core1_0.IndexTypeUInt16
case 4:
idxType = core1_0.IndexTypeUInt32
default:
panic("illegal index type")
}
cached = &vkMesh{
key: mesh.Key(),
elements: mesh.IndexCount(),
idxType: idxType,
}
if cached.elements == 0 {
// special case for empty meshes
callback(cached)
return
}
m.worker.Queue(func(cmd command.Buffer) {
vtxSize := mesh.VertexSize() * mesh.VertexCount()
vtxStage = buffer.NewShared(m.device, "staging:vertex", vtxSize)
idxSize := mesh.IndexSize() * mesh.IndexCount()
idxStage = buffer.NewShared(m.device, "staging:index", idxSize)
vtxStage.Write(0, mesh.VertexData())
vtxStage.Flush()
idxStage.Write(0, mesh.IndexData())
idxStage.Flush()
// allocate buffers
cached.vertices = buffer.NewRemote(m.device, mesh.Key()+":vertex", vtxSize, core1_0.BufferUsageVertexBuffer)
cached.indices = buffer.NewRemote(m.device, mesh.Key()+":index", idxSize, core1_0.BufferUsageIndexBuffer)
cmd.CmdCopyBuffer(vtxStage, cached.vertices, core1_0.BufferCopy{
Size: vtxSize,
})
cmd.CmdCopyBuffer(idxStage, cached.indices, core1_0.BufferCopy{
Size: idxSize,
})
})
m.worker.Submit(command.SubmitInfo{
Marker: "MeshCache",
Callback: func() {
vtxStage.Destroy()
idxStage.Destroy()
callback(cached)
},
})
}
func (m *meshes) Delete(mesh Mesh) {
mesh.Destroy()
}
func (m *meshes) Destroy() {}
func (m *meshes) Name() string { return "MeshCache" }
func (m *meshes) String() string { return "MeshCache" }