92 lines
		
	
	
		
			2.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			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" }
							 |