aboutsummaryrefslogtreecommitdiff
path: root/include/CudaLibrary.hpp
blob: ac3511385f6b93a2277a4084e09238c42573ac24 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#pragma once

#include <cuda.h>
#include <cudaGL.h>
#include <dlfcn.h>
#include <stdio.h>

typedef CUresult CUDAAPI (*CUINIT)(unsigned int Flags);
typedef CUresult CUDAAPI (*CUDEVICEGETCOUNT)(int *count);
typedef CUresult CUDAAPI (*CUDEVICEGET)(CUdevice *device, int ordinal);
typedef CUresult CUDAAPI (*CUCTXCREATE_V2)(CUcontext *pctx, unsigned int flags, CUdevice dev);
typedef CUresult CUDAAPI (*CUCTXPUSHCURRENT_V2)(CUcontext ctx);
typedef CUresult CUDAAPI (*CUCTXPOPCURRENT_V2)(CUcontext *pctx);
typedef CUresult CUDAAPI (*CUGETERRORSTRING)(CUresult error, const char **pStr);
typedef CUresult CUDAAPI (*CUMEMSETD8_V2)(CUdeviceptr dstDevice, unsigned char uc, size_t N);
typedef CUresult CUDAAPI (*CUMEMCPY2D_V2)(const CUDA_MEMCPY2D *pCopy);

typedef CUresult CUDAAPI (*CUGRAPHICSGLREGISTERIMAGE)(CUgraphicsResource *pCudaResource, GLuint image, GLenum target, unsigned int Flags);
typedef CUresult CUDAAPI (*CUGRAPHICSRESOURCESETMAPFLAGS)(CUgraphicsResource resource, unsigned int flags);
typedef CUresult CUDAAPI (*CUGRAPHICSMAPRESOURCES)(unsigned int count, CUgraphicsResource *resources, CUstream hStream);
typedef CUresult CUDAAPI (*CUGRAPHICSUNREGISTERRESOURCE)(CUgraphicsResource resource);
typedef CUresult CUDAAPI (*CUGRAPHICSSUBRESOURCEGETMAPPEDARRAY)(CUarray *pArray, CUgraphicsResource resource, unsigned int arrayIndex, unsigned int mipLevel);

struct Cuda {
    CUINIT cuInit;
    CUDEVICEGETCOUNT cuDeviceGetCount;
    CUDEVICEGET cuDeviceGet;
    CUCTXCREATE_V2 cuCtxCreate_v2;
    CUCTXPUSHCURRENT_V2 cuCtxPushCurrent_v2;
    CUCTXPOPCURRENT_V2 cuCtxPopCurrent_v2;
    CUGETERRORSTRING cuGetErrorString;
    CUMEMSETD8_V2 cuMemsetD8_v2;
    CUMEMCPY2D_V2 cuMemcpy2D_v2;

    CUGRAPHICSGLREGISTERIMAGE cuGraphicsGLRegisterImage;
    CUGRAPHICSRESOURCESETMAPFLAGS cuGraphicsResourceSetMapFlags;
    CUGRAPHICSMAPRESOURCES cuGraphicsMapResources;
    CUGRAPHICSUNREGISTERRESOURCE cuGraphicsUnregisterResource;
    CUGRAPHICSSUBRESOURCEGETMAPPEDARRAY cuGraphicsSubResourceGetMappedArray;

    ~Cuda() {
        if(library)
            dlclose(library);
    }

    bool load() {
        if(library)
            return true;

        dlerror(); // clear
        void *lib = dlopen("libcuda.so", RTLD_LAZY);
        if(!lib) {
            fprintf(stderr, "Error: failed to load libcuda.so, error: %s\n", dlerror());
            return false;
        }

        cuInit = (CUINIT)load_symbol(lib, "cuInit");
        if(!cuInit)
            goto fail;

        cuDeviceGetCount = (CUDEVICEGETCOUNT)load_symbol(lib, "cuDeviceGetCount");
        if(!cuDeviceGetCount)
            goto fail;

        cuDeviceGet = (CUDEVICEGET)load_symbol(lib, "cuDeviceGet");
        if(!cuDeviceGet)
            goto fail;

        cuCtxCreate_v2 = (CUCTXCREATE_V2)load_symbol(lib, "cuCtxCreate_v2");
        if(!cuCtxCreate_v2)
            goto fail;

        cuCtxPushCurrent_v2 = (CUCTXPUSHCURRENT_V2)load_symbol(lib, "cuCtxPushCurrent_v2");
        if(!cuCtxPushCurrent_v2)
            goto fail;

        cuCtxPopCurrent_v2 = (CUCTXPOPCURRENT_V2)load_symbol(lib, "cuCtxPopCurrent_v2");
        if(!cuCtxPopCurrent_v2)
            goto fail;

        cuGetErrorString = (CUGETERRORSTRING)load_symbol(lib, "cuGetErrorString");
        if(!cuGetErrorString)
            goto fail;

        cuMemsetD8_v2 = (CUMEMSETD8_V2)load_symbol(lib, "cuMemsetD8_v2");
        if(!cuMemsetD8_v2)
            goto fail;

        cuMemcpy2D_v2 = (CUMEMCPY2D_V2)load_symbol(lib, "cuMemcpy2D_v2");
        if(!cuMemcpy2D_v2)
            goto fail;

        cuGraphicsGLRegisterImage = (CUGRAPHICSGLREGISTERIMAGE)load_symbol(lib, "cuGraphicsGLRegisterImage");
        if(!cuGraphicsGLRegisterImage)
            goto fail;

        cuGraphicsResourceSetMapFlags = (CUGRAPHICSRESOURCESETMAPFLAGS)load_symbol(lib, "cuGraphicsResourceSetMapFlags");
        if(!cuGraphicsResourceSetMapFlags)
            goto fail;

        cuGraphicsMapResources = (CUGRAPHICSMAPRESOURCES)load_symbol(lib, "cuGraphicsMapResources");
        if(!cuGraphicsMapResources)
            goto fail;

        cuGraphicsUnregisterResource = (CUGRAPHICSUNREGISTERRESOURCE)load_symbol(lib, "cuGraphicsUnregisterResource");
        if(!cuGraphicsUnregisterResource)
            goto fail;

        cuGraphicsSubResourceGetMappedArray = (CUGRAPHICSSUBRESOURCEGETMAPPEDARRAY)load_symbol(lib, "cuGraphicsSubResourceGetMappedArray");
        if(!cuGraphicsSubResourceGetMappedArray)
            goto fail;

        library = lib;
        return true;

        fail:
        dlclose(lib);
        return false;
    }
private:
    void* load_symbol(void *library, const char *symbol) {
        void *sym = dlsym(library, symbol);
        if(!sym)
            fprintf(stderr, "Error: missing required symbol %s from libcuda.so\n", symbol);
        return sym;
    }
private:
    void *library = nullptr;
};