github.com/racerxdl/gonx@v0.0.0-20210103083128-c5afc43bcbd2/services/gpu/gpu.go (about) 1 package gpu 2 3 import ( 4 "github.com/racerxdl/gonx/nx/nxerrors" 5 "github.com/racerxdl/gonx/services/nv" 6 "unsafe" 7 ) 8 9 const gpuDebug = false 10 11 var ( 12 nvasFd int32 13 nvmapFd int32 14 nvhostCtrlFd int32 15 gpuInitializations = 0 16 ) 17 18 type Fence struct { 19 SyncptId uint32 20 SyncptValue uint32 21 } 22 23 func (g *Fence) Wait(timeout uint32) error { 24 if gpuInitializations <= 0 { 25 return nxerrors.GPUNotInitialized 26 } 27 28 wait := nvhostIocCtrlSyncPtWaitArgs{ 29 syncptId: g.SyncptId, 30 threshold: g.SyncptValue, 31 timeout: timeout, 32 } 33 34 handle, err := nv.Ioctl(nvmapFd, NVHOST_IOC_CTRL_SYNCPT_WAIT, unsafe.Pointer(&wait), unsafe.Sizeof(wait)) 35 if err != nil { 36 return err 37 } 38 39 if handle != 0 { 40 return nxerrors.IPCError{ 41 Message: "error calling NVHOST_IOC_CTRL_SYNCPT_WAIT", 42 Result: uint64(handle), 43 } 44 } 45 46 return nil 47 } 48 49 func Init() (err error) { 50 if gpuDebug { 51 println("GPU::Init()") 52 } 53 gpuInitializations++ 54 if gpuInitializations > 1 { 55 return nil 56 } 57 58 nvInit := false 59 nvmapInit := false 60 nvasInit := false 61 62 defer func() { 63 if err != nil { 64 if nvmapInit { 65 _ = nv.Close(nvmapFd) 66 } 67 if nvasInit { 68 _ = nv.Close(nvasFd) 69 } 70 if nvInit { 71 nv.Finalize() 72 } 73 gpuInitializations-- 74 } 75 }() 76 77 if gpuDebug { 78 println("GPU::Init() - Init NV") 79 } 80 81 err = nv.Init() 82 if err != nil { 83 return err 84 } 85 nvInit = true 86 87 if gpuDebug { 88 println("GPU::Init() - open nvhost-as-gpu") 89 } 90 nvasFd, err = nv.Open("/dev/nvhost-as-gpu") 91 if err != nil { 92 return err 93 } 94 nvasInit = true 95 96 if gpuDebug { 97 println("GPU::Init() - open nvmap") 98 } 99 nvmapFd, err = nv.Open("/dev/nvmap") 100 if err != nil { 101 return err 102 } 103 nvmapInit = true 104 105 if gpuDebug { 106 println("GPU::Init() - open nvhost-ctrl") 107 } 108 nvhostCtrlFd, err = nv.Open("/dev/nvhost-ctrl") 109 110 return err 111 } 112 113 func forceFinalize() { 114 if gpuDebug { 115 println("GPU::ForceFinalize()") 116 } 117 _ = nv.Close(nvhostCtrlFd) 118 _ = nv.Close(nvmapFd) 119 _ = nv.Close(nvasFd) 120 nv.Finalize() 121 gpuInitializations = 0 122 } 123 124 func Finalize() { 125 if gpuDebug { 126 println("GPU::Finalize()") 127 } 128 gpuInitializations-- 129 if gpuInitializations <= 0 { 130 forceFinalize() 131 } 132 }