From e08627884ed59ebbac09a1182428718ed0ec1cbe Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Fri, 9 Jan 2015 04:39:49 +0100
Subject: nvcuda: Implement new functions added in CUDA 6.5.

---
 dlls/nvcuda/nvcuda.c    | 113 ++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/nvcuda/nvcuda.spec |  11 +++++
 include/cuda.h          |   1 +
 3 files changed, 125 insertions(+)

diff --git a/dlls/nvcuda/nvcuda.c b/dlls/nvcuda/nvcuda.c
index 3ef7c35..3118c49 100644
--- a/dlls/nvcuda/nvcuda.c
+++ b/dlls/nvcuda/nvcuda.c
@@ -293,6 +293,20 @@ static CUresult (*pcuTexRefSetMipmapLevelBias)(CUtexref hTexRef, float bias);
 static CUresult (*pcuTexRefSetMipmapLevelClamp)(CUtexref hTexRef, float minMipmapLevelClamp, float maxMipmapLevelClamp);
 static CUresult (*pcuTexRefSetMipmappedArray)(CUtexref hTexRef, CUmipmappedArray hMipmappedArray, unsigned int Flags);
 
+/* CUDA 6.5 */
+static CUresult (*pcuGLGetDevices_v2)(unsigned int *pCudaDeviceCount, CUdevice *pCudaDevices,
+                                      unsigned int cudaDeviceCount, CUGLDeviceList deviceList);
+static CUresult (*pcuGraphicsResourceSetMapFlags_v2)(CUgraphicsResource resource, unsigned int flags);
+static CUresult (*pcuLinkAddData_v2)(CUlinkState state, CUjitInputType type, void *data, size_t size, const char *name,
+                                     unsigned int numOptions, CUjit_option *options, void **optionValues);
+static CUresult (*pcuLinkCreate_v2)(unsigned int numOptions, CUjit_option *options, void **optionValues, CUlinkState *stateOut);
+static CUresult (*pcuMemHostRegister_v2)(void *p, size_t bytesize, unsigned int Flags);
+static CUresult (*pcuOccupancyMaxActiveBlocksPerMultiprocessor)(int *numBlocks, CUfunction func, int blockSize, size_t dynamicSMemSize);
+/*
+static CUresult (*pcuOccupancyMaxPotentialBlockSize)(int *minGridSize, int *blockSize, CUfunction func,
+                                                     void *blockSizeToDynamicSMemSize, size_t dynamicSMemSize, int blockSizeLimit);
+*/
+
 static void *cuda_handle = NULL;
 
 static BOOL load_functions(void)
@@ -306,6 +320,7 @@ static BOOL load_functions(void)
     }
 
     #define LOAD_FUNCPTR(f) if((p##f = dlsym(cuda_handle, #f)) == NULL){FIXME("Can't find symbol %s\n", #f); return FALSE;}
+    #define TRY_LOAD_FUNCPTR(f) p##f = dlsym(cuda_handle, #f)
 
     LOAD_FUNCPTR(cuArray3DCreate);
     LOAD_FUNCPTR(cuArray3DCreate_v2);
@@ -554,7 +569,18 @@ static BOOL load_functions(void)
     LOAD_FUNCPTR(cuTexRefSetMipmapLevelClamp);
     LOAD_FUNCPTR(cuTexRefSetMipmappedArray);
 
+    /* CUDA 6.5 */
+    TRY_LOAD_FUNCPTR(cuGLGetDevices_v2);
+    TRY_LOAD_FUNCPTR(cuGraphicsResourceSetMapFlags_v2);
+    TRY_LOAD_FUNCPTR(cuLinkAddData_v2);
+    TRY_LOAD_FUNCPTR(cuLinkCreate_v2);
+    TRY_LOAD_FUNCPTR(cuMemHostRegister_v2);
+    TRY_LOAD_FUNCPTR(cuOccupancyMaxActiveBlocksPerMultiprocessor);
+    /* TRY_LOAD_FUNCPTR(cuOccupancyMaxPotentialBlockSize); */
+
+
     #undef LOAD_FUNCPTR
+    #undef TRY_LOAD_FUNCPTR
 
     return TRUE;
 }
@@ -2101,6 +2127,93 @@ CUresult WINAPI wine_cuTexRefSetMipmappedArray(CUtexref hTexRef, CUmipmappedArra
     return pcuTexRefSetMipmappedArray(hTexRef, hMipmappedArray, Flags);
 }
 
+/*
+ * Additions in CUDA 6.5
+ */
+
+CUresult WINAPI wine_cuGLGetDevices_v2(unsigned int *pCudaDeviceCount, CUdevice *pCudaDevices,
+                                       unsigned int cudaDeviceCount, CUGLDeviceList deviceList)
+{
+    TRACE("(%p, %p, %u, %d)\n", pCudaDeviceCount, pCudaDevices, cudaDeviceCount, deviceList);
+    if (!pcuGLGetDevices_v2)
+    {
+        FIXME("not supported\n");
+        return CUDA_ERROR_NOT_SUPPORTED;
+    }
+    return pcuGLGetDevices_v2(pCudaDeviceCount, pCudaDevices, cudaDeviceCount, deviceList);
+}
+
+CUresult WINAPI wine_cuGraphicsResourceSetMapFlags_v2(CUgraphicsResource resource, unsigned int flags)
+{
+    TRACE("(%p, %u)\n", resource, flags);
+    if (!pcuGraphicsResourceSetMapFlags_v2)
+    {
+        FIXME("not supported\n");
+        return CUDA_ERROR_NOT_SUPPORTED;
+    }
+    return pcuGraphicsResourceSetMapFlags_v2(resource, flags);
+}
+
+CUresult WINAPI wine_cuLinkAddData_v2(CUlinkState state, CUjitInputType type, void *data, size_t size, const char *name,
+                                      unsigned int numOptions, CUjit_option *options, void **optionValues)
+{
+    TRACE("(%p, %d, %p, %lu, %s, %u, %p, %p)\n", state, type, data, (SIZE_T)size, name, numOptions, options, optionValues);
+    if (!pcuLinkAddData_v2)
+    {
+        FIXME("not supported\n");
+        return CUDA_ERROR_NOT_SUPPORTED;
+    }
+    return pcuLinkAddData_v2(state, type, data, size, name, numOptions, options, optionValues);
+}
+
+CUresult WINAPI wine_cuLinkCreate_v2(unsigned int numOptions, CUjit_option *options,
+                                     void **optionValues, CUlinkState *stateOut)
+{
+    TRACE("(%u, %p, %p, %p)\n", numOptions, options, optionValues, stateOut);
+    if (!pcuLinkCreate_v2)
+    {
+        FIXME("not supported\n");
+        return CUDA_ERROR_NOT_SUPPORTED;
+    }
+    return pcuLinkCreate_v2(numOptions, options, optionValues, stateOut);
+}
+
+CUresult WINAPI wine_cuMemHostRegister_v2(void *p, size_t bytesize, unsigned int Flags)
+{
+    TRACE("(%p, %lu, %u)\n", p, (SIZE_T)bytesize, Flags);
+    if (!pcuMemHostRegister_v2)
+    {
+        FIXME("not supported\n");
+        return CUDA_ERROR_NOT_SUPPORTED;
+    }
+    return pcuMemHostRegister_v2(p, bytesize, Flags);
+}
+
+CUresult WINAPI wine_cuOccupancyMaxActiveBlocksPerMultiprocessor(int *numBlocks, CUfunction func, int blockSize, size_t dynamicSMemSize)
+{
+    TRACE("(%p, %p, %d, %lu)\n", numBlocks, func, blockSize, (SIZE_T)dynamicSMemSize);
+    if (!pcuOccupancyMaxActiveBlocksPerMultiprocessor)
+    {
+        FIXME("not supported\n");
+        return CUDA_ERROR_NOT_SUPPORTED;
+    }
+    return pcuOccupancyMaxActiveBlocksPerMultiprocessor(numBlocks, func, blockSize, dynamicSMemSize);
+}
+
+/*
+CUresult WINAPI wine_cuOccupancyMaxPotentialBlockSize(int *minGridSize, int *blockSize, CUfunction func,
+                                                      void *blockSizeToDynamicSMemSize, size_t dynamicSMemSize, int blockSizeLimit)
+{
+    TRACE("(%p, %p, %p, %p, %lu, %d)\n", minGridSize, blockSize, func, blockSizeToDynamicSMemSize, (SIZE_T)dynamicSMemSize, blockSizeLimit);
+    if (!pcuOccupancyMaxPotentialBlockSize)
+    {
+        FIXME("not supported\n");
+        return CUDA_ERROR_NOT_SUPPORTED;
+    }
+    return pcuOccupancyMaxPotentialBlockSize(minGridSize, blockSize, func, blockSizeToDynamicSMemSize, dynamicSMemSize, blockSizeLimit);
+}
+*/
+
 BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
 {
     TRACE("(%p, %u, %p)\n", instance, reason, reserved);
diff --git a/dlls/nvcuda/nvcuda.spec b/dlls/nvcuda/nvcuda.spec
index 621b8d5..c23faa4 100644
--- a/dlls/nvcuda/nvcuda.spec
+++ b/dlls/nvcuda/nvcuda.spec
@@ -306,3 +306,14 @@
 @ stdcall cuTexRefSetMipmapLevelClamp(ptr float float) wine_cuTexRefSetMipmapLevelClamp
 @ stdcall cuTexRefSetMipmappedArray(ptr ptr long) wine_cuTexRefSetMipmappedArray
 @ stub cuWGLGetDevice
+
+# CUDA 6.5
+@ stdcall cuGLGetDevices_v2(ptr ptr long long) wine_cuGLGetDevices_v2
+@ stdcall cuGraphicsResourceSetMapFlags_v2(ptr long) wine_cuGraphicsResourceSetMapFlags_v2
+@ stdcall cuLinkAddData_v2(ptr long ptr long str long ptr ptr) wine_cuLinkAddData_v2
+@ stub cuLinkAddFile_v2
+@ stdcall cuLinkCreate_v2(long ptr ptr ptr) wine_cuLinkCreate_v2
+@ stdcall cuMemHostRegister_v2(ptr long long) wine_cuMemHostRegister_v2
+@ stdcall cuOccupancyMaxActiveBlocksPerMultiprocessor(ptr ptr long long) wine_cuOccupancyMaxActiveBlocksPerMultiprocessor
+@ stub cuOccupancyMaxPotentialBlockSize
+#@ stdcall cuOccupancyMaxPotentialBlockSize(ptr ptr ptr ptr long long) wine_cuOccupancyMaxPotentialBlockSize
diff --git a/include/cuda.h b/include/cuda.h
index 1f20f5b..0f7b11d 100644
--- a/include/cuda.h
+++ b/include/cuda.h
@@ -22,6 +22,7 @@
 #define CUDA_SUCCESS                0
 #define CUDA_ERROR_INVALID_VALUE    1
 #define CUDA_ERROR_OUT_OF_MEMORY    2
+#define CUDA_ERROR_NOT_SUPPORTED    801
 #define CUDA_ERROR_UNKNOWN          999
 
 #define CU_IPC_HANDLE_SIZE          64
-- 
2.2.1

