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  }