summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2018-04-15 22:13:08 +0800
committerruki <[email protected]>2018-04-15 22:13:31 +0800
commit60c09804728f333500a353610b100a3b59632646 (patch)
treeed78422564655949f62f22d917ed70da3d083acb
parent6c4f65481bb0df23d34d9e0815ca642804dbb412 (diff)
add cuda test
-rw-r--r--tests/projects/cuda_console/inc/cuda_drvapi_dynlink.c551
-rw-r--r--tests/projects/cuda_console/inc/drvapi_error_string.h463
-rw-r--r--tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink.h25
-rw-r--r--tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_cuda.h1702
-rw-r--r--tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_d3d.h110
-rw-r--r--tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_gl.h58
-rw-r--r--tests/projects/cuda_console/inc/dynlink_d3d10.h303
-rw-r--r--tests/projects/cuda_console/inc/dynlink_d3d11.h174
-rw-r--r--tests/projects/cuda_console/inc/exception.h151
-rw-r--r--tests/projects/cuda_console/inc/helper_cuda.h1356
-rw-r--r--tests/projects/cuda_console/inc/helper_cuda_drvapi.h572
-rw-r--r--tests/projects/cuda_console/inc/helper_cuda_gl.h183
-rw-r--r--tests/projects/cuda_console/inc/helper_cusolver.h172
-rw-r--r--tests/projects/cuda_console/inc/helper_functions.h42
-rw-r--r--tests/projects/cuda_console/inc/helper_gl.h191
-rw-r--r--tests/projects/cuda_console/inc/helper_image.h1110
-rw-r--r--tests/projects/cuda_console/inc/helper_math.h1453
-rw-r--r--tests/projects/cuda_console/inc/helper_string.h527
-rw-r--r--tests/projects/cuda_console/inc/helper_timer.h499
-rw-r--r--tests/projects/cuda_console/inc/multithreading.h60
-rw-r--r--tests/projects/cuda_console/inc/nvMath.h95
-rw-r--r--tests/projects/cuda_console/inc/nvMatrix.h524
-rw-r--r--tests/projects/cuda_console/inc/nvQuaternion.h514
-rw-r--r--tests/projects/cuda_console/inc/nvShaderUtils.h255
-rw-r--r--tests/projects/cuda_console/inc/nvVector.h1058
-rw-r--r--tests/projects/cuda_console/inc/nvrtc_helper.h134
-rw-r--r--tests/projects/cuda_console/inc/param.h310
-rw-r--r--tests/projects/cuda_console/inc/paramgl.h308
-rw-r--r--tests/projects/cuda_console/inc/rendercheck_d3d10.h37
-rw-r--r--tests/projects/cuda_console/inc/rendercheck_d3d11.h37
-rw-r--r--tests/projects/cuda_console/inc/rendercheck_d3d9.h36
-rw-r--r--tests/projects/cuda_console/inc/rendercheck_gl.h1473
-rw-r--r--tests/projects/cuda_console/inc/rendercheck_gles.h1419
-rw-r--r--tests/projects/cuda_console/inc/timer.h64
-rw-r--r--tests/projects/cuda_console/src/main.cu61
-rw-r--r--tests/projects/cuda_console/xmake.lua23
36 files changed, 16050 insertions, 0 deletions
diff --git a/tests/projects/cuda_console/inc/cuda_drvapi_dynlink.c b/tests/projects/cuda_console/inc/cuda_drvapi_dynlink.c
new file mode 100644
index 000000000..bd7f69d3d
--- /dev/null
+++ b/tests/projects/cuda_console/inc/cuda_drvapi_dynlink.c
@@ -0,0 +1,551 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+// With these flags defined, this source file will dynamically
+// load the corresponding functions. Disabled by default.
+//#define CUDA_INIT_D3D9
+//#define CUDA_INIT_D3D10
+//#define CUDA_INIT_D3D11
+//#define CUDA_INIT_OPENGL
+
+#include <stdio.h>
+#include "cuda_drvapi_dynlink.h"
+
+tcuInit *_cuInit;
+tcuDriverGetVersion *cuDriverGetVersion;
+tcuDeviceGet *cuDeviceGet;
+tcuDeviceGetCount *cuDeviceGetCount;
+tcuDeviceGetName *cuDeviceGetName;
+tcuDeviceComputeCapability *cuDeviceComputeCapability;
+tcuDeviceTotalMem *cuDeviceTotalMem;
+tcuDeviceGetProperties *cuDeviceGetProperties;
+tcuDeviceGetAttribute *cuDeviceGetAttribute;
+tcuCtxCreate *cuCtxCreate;
+tcuCtxDestroy *cuCtxDestroy;
+tcuCtxAttach *cuCtxAttach;
+tcuCtxDetach *cuCtxDetach;
+tcuCtxPushCurrent *cuCtxPushCurrent;
+tcuCtxPopCurrent *cuCtxPopCurrent;
+tcuCtxGetCurrent *cuCtxGetCurrent;
+tcuCtxSetCurrent *cuCtxSetCurrent;
+tcuCtxGetDevice *cuCtxGetDevice;
+tcuCtxSynchronize *cuCtxSynchronize;
+tcuModuleLoad *cuModuleLoad;
+tcuModuleLoadData *cuModuleLoadData;
+tcuModuleLoadDataEx *cuModuleLoadDataEx;
+tcuModuleLoadFatBinary *cuModuleLoadFatBinary;
+tcuModuleUnload *cuModuleUnload;
+tcuModuleGetFunction *cuModuleGetFunction;
+tcuModuleGetGlobal *cuModuleGetGlobal;
+tcuModuleGetTexRef *cuModuleGetTexRef;
+tcuModuleGetSurfRef *cuModuleGetSurfRef;
+tcuMemGetInfo *cuMemGetInfo;
+tcuMemAlloc *cuMemAlloc;
+tcuMemAllocPitch *cuMemAllocPitch;
+tcuMemFree *cuMemFree;
+tcuMemGetAddressRange *cuMemGetAddressRange;
+tcuMemAllocHost *cuMemAllocHost;
+tcuMemFreeHost *cuMemFreeHost;
+tcuMemHostAlloc *cuMemHostAlloc;
+tcuMemHostGetDevicePointer *cuMemHostGetDevicePointer;
+tcuMemHostRegister *cuMemHostRegister;
+tcuMemHostUnregister *cuMemHostUnregister;
+tcuMemcpyHtoD *cuMemcpyHtoD;
+tcuMemcpyDtoH *cuMemcpyDtoH;
+tcuMemcpyDtoD *cuMemcpyDtoD;
+tcuMemcpyDtoA *cuMemcpyDtoA;
+tcuMemcpyAtoD *cuMemcpyAtoD;
+tcuMemcpyHtoA *cuMemcpyHtoA;
+tcuMemcpyAtoH *cuMemcpyAtoH;
+tcuMemcpyAtoA *cuMemcpyAtoA;
+tcuMemcpy2D *cuMemcpy2D;
+tcuMemcpy2DUnaligned *cuMemcpy2DUnaligned;
+tcuMemcpy3D *cuMemcpy3D;
+tcuMemcpyHtoDAsync *cuMemcpyHtoDAsync;
+tcuMemcpyDtoHAsync *cuMemcpyDtoHAsync;
+tcuMemcpyDtoDAsync *cuMemcpyDtoDAsync;
+tcuMemcpyHtoAAsync *cuMemcpyHtoAAsync;
+tcuMemcpyAtoHAsync *cuMemcpyAtoHAsync;
+tcuMemcpy2DAsync *cuMemcpy2DAsync;
+tcuMemcpy3DAsync *cuMemcpy3DAsync;
+tcuMemcpy *cuMemcpy;
+tcuMemcpyPeer *cuMemcpyPeer;
+tcuMemsetD8 *cuMemsetD8;
+tcuMemsetD16 *cuMemsetD16;
+tcuMemsetD32 *cuMemsetD32;
+tcuMemsetD2D8 *cuMemsetD2D8;
+tcuMemsetD2D16 *cuMemsetD2D16;
+tcuMemsetD2D32 *cuMemsetD2D32;
+tcuFuncSetBlockShape *cuFuncSetBlockShape;
+tcuFuncSetSharedSize *cuFuncSetSharedSize;
+tcuFuncGetAttribute *cuFuncGetAttribute;
+tcuFuncSetCacheConfig *cuFuncSetCacheConfig;
+tcuLaunchKernel *cuLaunchKernel;
+tcuArrayCreate *cuArrayCreate;
+tcuArrayGetDescriptor *cuArrayGetDescriptor;
+tcuArrayDestroy *cuArrayDestroy;
+tcuArray3DCreate *cuArray3DCreate;
+tcuArray3DGetDescriptor *cuArray3DGetDescriptor;
+tcuTexRefCreate *cuTexRefCreate;
+tcuTexRefDestroy *cuTexRefDestroy;
+tcuTexRefSetArray *cuTexRefSetArray;
+tcuTexRefSetAddress *cuTexRefSetAddress;
+tcuTexRefSetAddress2D *cuTexRefSetAddress2D;
+tcuTexRefSetFormat *cuTexRefSetFormat;
+tcuTexRefSetAddressMode *cuTexRefSetAddressMode;
+tcuTexRefSetFilterMode *cuTexRefSetFilterMode;
+tcuTexRefSetFlags *cuTexRefSetFlags;
+tcuTexRefGetAddress *cuTexRefGetAddress;
+tcuTexRefGetArray *cuTexRefGetArray;
+tcuTexRefGetAddressMode *cuTexRefGetAddressMode;
+tcuTexRefGetFilterMode *cuTexRefGetFilterMode;
+tcuTexRefGetFormat *cuTexRefGetFormat;
+tcuTexRefGetFlags *cuTexRefGetFlags;
+tcuSurfRefSetArray *cuSurfRefSetArray;
+tcuSurfRefGetArray *cuSurfRefGetArray;
+tcuParamSetSize *cuParamSetSize;
+tcuParamSeti *cuParamSeti;
+tcuParamSetf *cuParamSetf;
+tcuParamSetv *cuParamSetv;
+tcuParamSetTexRef *cuParamSetTexRef;
+tcuLaunch *cuLaunch;
+tcuLaunchGrid *cuLaunchGrid;
+tcuLaunchGridAsync *cuLaunchGridAsync;
+tcuEventCreate *cuEventCreate;
+tcuEventRecord *cuEventRecord;
+tcuEventQuery *cuEventQuery;
+tcuEventSynchronize *cuEventSynchronize;
+tcuEventDestroy *cuEventDestroy;
+tcuEventElapsedTime *cuEventElapsedTime;
+tcuStreamCreate *cuStreamCreate;
+tcuStreamQuery *cuStreamQuery;
+tcuStreamSynchronize *cuStreamSynchronize;
+tcuStreamDestroy *cuStreamDestroy;
+tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource;
+tcuGraphicsSubResourceGetMappedArray *cuGraphicsSubResourceGetMappedArray;
+tcuGraphicsResourceGetMappedPointer *cuGraphicsResourceGetMappedPointer;
+tcuGraphicsResourceSetMapFlags *cuGraphicsResourceSetMapFlags;
+tcuGraphicsMapResources *cuGraphicsMapResources;
+tcuGraphicsUnmapResources *cuGraphicsUnmapResources;
+tcuGetExportTable *cuGetExportTable;
+tcuCtxSetLimit *cuCtxSetLimit;
+tcuCtxGetLimit *cuCtxGetLimit;
+tcuMemHostGetFlags *cuMemHostGetFlags;
+
+#ifdef CUDA_INIT_D3D9
+// D3D9/CUDA interop (CUDA 1.x compatible API). These functions
+// are deprecated; please use the ones below
+tcuD3D9Begin *cuD3D9Begin;
+tcuD3D9End *cuD3DEnd;
+tcuD3D9RegisterVertexBuffer *cuD3D9RegisterVertexBuffer;
+tcuD3D9MapVertexBuffer *cuD3D9MapVertexBuffer;
+tcuD3D9UnmapVertexBuffer *cuD3D9UnmapVertexBuffer;
+tcuD3D9UnregisterVertexBuffer *cuD3D9UnregisterVertexBuffer;
+
+// D3D9/CUDA interop (CUDA 2.x compatible)
+tcuD3D9GetDirect3DDevice *cuD3D9GetDirect3DDevice;
+tcuD3D9RegisterResource *cuD3D9RegisterResource;
+tcuD3D9UnregisterResource *cuD3D9UnregisterResource;
+tcuD3D9MapResources *cuD3D9MapResources;
+tcuD3D9UnmapResources *cuD3D9UnmapResources;
+tcuD3D9ResourceSetMapFlags *cuD3D9ResourceSetMapFlags;
+tcuD3D9ResourceGetSurfaceDimensions *cuD3D9ResourceGetSurfaceDimensions;
+tcuD3D9ResourceGetMappedArray *cuD3D9ResourceGetMappedArray;
+tcuD3D9ResourceGetMappedPointer *cuD3D9ResourceGetMappedPointer;
+tcuD3D9ResourceGetMappedSize *cuD3D9ResourceGetMappedSize;
+tcuD3D9ResourceGetMappedPitch *cuD3D9ResourceGetMappedPitch;
+
+// D3D9/CUDA interop (CUDA 2.0+)
+tcuD3D9GetDevice *cuD3D9GetDevice;
+tcuD3D9CtxCreate *cuD3D9CtxCreate;
+tcuGraphicsD3D9RegisterResource *cuGraphicsD3D9RegisterResource;
+#endif
+
+#ifdef CUDA_INIT_D3D10
+// D3D10/CUDA interop (CUDA 3.0+)
+tcuD3D10GetDevice *cuD3D10GetDevice;
+tcuD3D10CtxCreate *cuD3D10CtxCreate;
+tcuGraphicsD3D10RegisterResource *cuGraphicsD3D10RegisterResource;
+#endif
+
+
+#ifdef CUDA_INIT_D3D11
+// D3D11/CUDA interop (CUDA 3.0+)
+tcuD3D11GetDevice *cuD3D11GetDevice;
+tcuD3D11CtxCreate *cuD3D11CtxCreate;
+tcuGraphicsD3D11RegisterResource *cuGraphicsD3D11RegisterResource;
+#endif
+
+// GL/CUDA interop
+#ifdef CUDA_INIT_OPENGL
+tcuGLCtxCreate *cuGLCtxCreate;
+tcuGraphicsGLRegisterBuffer *cuGraphicsGLRegisterBuffer;
+tcuGraphicsGLRegisterImage *cuGraphicsGLRegisterImage;
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+tcuWGLGetDevice *cuWGLGetDevice;
+#endif
+#endif
+
+#define STRINGIFY(X) #X
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#include <Windows.h>
+
+#ifdef UNICODE
+static LPCWSTR __CudaLibName = L"nvcuda.dll";
+#else
+static LPCSTR __CudaLibName = "nvcuda.dll";
+#endif
+
+typedef HMODULE CUDADRIVER;
+
+static CUresult LOAD_LIBRARY(CUDADRIVER *pInstance)
+{
+ *pInstance = LoadLibrary(__CudaLibName);
+
+ if (*pInstance == NULL)
+ {
+ printf("LoadLibrary \"%s\" failed!\n", __CudaLibName);
+ return CUDA_ERROR_UNKNOWN;
+ }
+
+ return CUDA_SUCCESS;
+}
+
+#define GET_PROC_EX(name, alias, required) \
+ alias = (t##name *)GetProcAddress(CudaDrvLib, #name); \
+ if (alias == NULL && required) { \
+ printf("Failed to find required function \"%s\" in %s\n", \
+ #name, __CudaLibName); \
+ return CUDA_ERROR_UNKNOWN; \
+ }
+
+#define GET_PROC_EX_V2(name, alias, required) \
+ alias = (t##name *)GetProcAddress(CudaDrvLib, STRINGIFY(name##_v2));\
+ if (alias == NULL && required) { \
+ printf("Failed to find required function \"%s\" in %s\n", \
+ STRINGIFY(name##_v2), __CudaLibName); \
+ return CUDA_ERROR_UNKNOWN; \
+ }
+
+#elif defined(__unix__) || defined(__APPLE__) || defined(__MACOSX)
+
+#include <dlfcn.h>
+
+#if defined(__APPLE__) || defined(__MACOSX)
+static char __CudaLibName[] = "/usr/local/cuda/lib/libcuda.dylib";
+#else
+static char __CudaLibName[] = "libcuda.so";
+#endif
+
+typedef void *CUDADRIVER;
+
+static CUresult LOAD_LIBRARY(CUDADRIVER *pInstance)
+{
+ *pInstance = dlopen(__CudaLibName, RTLD_NOW);
+
+ if (*pInstance == NULL)
+ {
+ printf("dlopen \"%s\" failed!\n", __CudaLibName);
+ return CUDA_ERROR_UNKNOWN;
+ }
+
+ return CUDA_SUCCESS;
+}
+
+#define GET_PROC_EX(name, alias, required) \
+ alias = (t##name *)dlsym(CudaDrvLib, #name); \
+ if (alias == NULL && required) { \
+ printf("Failed to find required function \"%s\" in %s\n", \
+ #name, __CudaLibName); \
+ return CUDA_ERROR_UNKNOWN; \
+ }
+
+#define GET_PROC_EX_V2(name, alias, required) \
+ alias = (t##name *)dlsym(CudaDrvLib, STRINGIFY(name##_v2)); \
+ if (alias == NULL && required) { \
+ printf("Failed to find required function \"%s\" in %s\n", \
+ STRINGIFY(name##_v2), __CudaLibName); \
+ return CUDA_ERROR_UNKNOWN; \
+ }
+
+#else
+#error unsupported platform
+#endif
+
+#define CHECKED_CALL(call) \
+ do { \
+ CUresult result = (call); \
+ if (CUDA_SUCCESS != result) { \
+ return result; \
+ } \
+ } while(0)
+
+#define GET_PROC_REQUIRED(name) GET_PROC_EX(name,name,1)
+#define GET_PROC_OPTIONAL(name) GET_PROC_EX(name,name,0)
+#define GET_PROC(name) GET_PROC_REQUIRED(name)
+#define GET_PROC_V2(name) GET_PROC_EX_V2(name,name,1)
+
+CUresult CUDAAPI cuInit(unsigned int Flags, int cudaVersion)
+{
+ CUDADRIVER CudaDrvLib;
+ int driverVer = 1000;
+
+ CHECKED_CALL(LOAD_LIBRARY(&CudaDrvLib));
+
+ // cuInit is required; alias it to _cuInit
+ GET_PROC_EX(cuInit, _cuInit, 1);
+ CHECKED_CALL(_cuInit(Flags));
+
+ // available since 2.2. if not present, version 1.0 is assumed
+ GET_PROC_OPTIONAL(cuDriverGetVersion);
+
+ if (cuDriverGetVersion)
+ {
+ CHECKED_CALL(cuDriverGetVersion(&driverVer));
+ }
+
+ // fetch all function pointers
+ GET_PROC(cuDeviceGet);
+ GET_PROC(cuDeviceGetCount);
+ GET_PROC(cuDeviceGetName);
+ GET_PROC(cuDeviceComputeCapability);
+ GET_PROC(cuDeviceGetProperties);
+ GET_PROC(cuDeviceGetAttribute);
+ GET_PROC(cuCtxDestroy);
+ GET_PROC(cuCtxAttach);
+ GET_PROC(cuCtxDetach);
+ GET_PROC(cuCtxPushCurrent);
+ GET_PROC(cuCtxPopCurrent);
+ GET_PROC(cuCtxGetDevice);
+ GET_PROC(cuCtxSynchronize);
+ GET_PROC(cuModuleLoad);
+ GET_PROC(cuModuleLoadData);
+ GET_PROC(cuModuleUnload);
+ GET_PROC(cuModuleGetFunction);
+ GET_PROC(cuModuleGetTexRef);
+ GET_PROC(cuMemFreeHost);
+ GET_PROC(cuMemHostAlloc);
+ GET_PROC(cuFuncSetBlockShape);
+ GET_PROC(cuFuncSetSharedSize);
+ GET_PROC(cuFuncGetAttribute);
+ GET_PROC(cuArrayDestroy);
+ GET_PROC(cuTexRefCreate);
+ GET_PROC(cuTexRefDestroy);
+ GET_PROC(cuTexRefSetArray);
+ GET_PROC(cuTexRefSetFormat);
+ GET_PROC(cuTexRefSetAddressMode);
+ GET_PROC(cuTexRefSetFilterMode);
+ GET_PROC(cuTexRefSetFlags);
+ GET_PROC(cuTexRefGetArray);
+ GET_PROC(cuTexRefGetAddressMode);
+ GET_PROC(cuTexRefGetFilterMode);
+ GET_PROC(cuTexRefGetFormat);
+ GET_PROC(cuTexRefGetFlags);
+ GET_PROC(cuParamSetSize);
+ GET_PROC(cuParamSeti);
+ GET_PROC(cuParamSetf);
+ GET_PROC(cuParamSetv);
+ GET_PROC(cuParamSetTexRef);
+ GET_PROC(cuLaunch);
+ GET_PROC(cuLaunchGrid);
+ GET_PROC(cuLaunchGridAsync);
+ GET_PROC(cuEventCreate);
+ GET_PROC(cuEventRecord);
+ GET_PROC(cuEventQuery);
+ GET_PROC(cuEventSynchronize);
+ GET_PROC(cuEventDestroy);
+ GET_PROC(cuEventElapsedTime);
+ GET_PROC(cuStreamCreate);
+ GET_PROC(cuStreamQuery);
+ GET_PROC(cuStreamSynchronize);
+ GET_PROC(cuStreamDestroy);
+
+ // These could be _v2 interfaces
+ if (cudaVersion >= 4000 && __CUDA_API_VERSION >= 4000)
+ {
+ GET_PROC_V2(cuCtxDestroy);
+ GET_PROC_V2(cuCtxPopCurrent);
+ GET_PROC_V2(cuCtxPushCurrent);
+ GET_PROC_V2(cuStreamDestroy);
+ GET_PROC_V2(cuEventDestroy);
+ }
+
+ if (cudaVersion >= 3020 && __CUDA_API_VERSION >= 3020)
+ {
+ GET_PROC_V2(cuDeviceTotalMem);
+ GET_PROC_V2(cuCtxCreate);
+ GET_PROC_V2(cuModuleGetGlobal);
+ GET_PROC_V2(cuMemGetInfo);
+ GET_PROC_V2(cuMemAlloc);
+ GET_PROC_V2(cuMemAllocPitch);
+ GET_PROC_V2(cuMemFree);
+ GET_PROC_V2(cuMemGetAddressRange);
+ GET_PROC_V2(cuMemAllocHost);
+ GET_PROC_V2(cuMemHostGetDevicePointer);
+ GET_PROC_V2(cuMemcpyHtoD);
+ GET_PROC_V2(cuMemcpyDtoH);
+ GET_PROC_V2(cuMemcpyDtoD);
+ GET_PROC_V2(cuMemcpyDtoA);
+ GET_PROC_V2(cuMemcpyAtoD);
+ GET_PROC_V2(cuMemcpyHtoA);
+ GET_PROC_V2(cuMemcpyAtoH);
+ GET_PROC_V2(cuMemcpyAtoA);
+ GET_PROC_V2(cuMemcpy2D);
+ GET_PROC_V2(cuMemcpy2DUnaligned);
+ GET_PROC_V2(cuMemcpy3D);
+ GET_PROC_V2(cuMemcpyHtoDAsync);
+ GET_PROC_V2(cuMemcpyDtoHAsync);
+ GET_PROC_V2(cuMemcpyHtoAAsync);
+ GET_PROC_V2(cuMemcpyAtoHAsync);
+ GET_PROC_V2(cuMemcpy2DAsync);
+ GET_PROC_V2(cuMemcpy3DAsync);
+ GET_PROC_V2(cuMemsetD8);
+ GET_PROC_V2(cuMemsetD16);
+ GET_PROC_V2(cuMemsetD32);
+ GET_PROC_V2(cuMemsetD2D8);
+ GET_PROC_V2(cuMemsetD2D16);
+ GET_PROC_V2(cuMemsetD2D32);
+ GET_PROC_V2(cuArrayCreate);
+ GET_PROC_V2(cuArrayGetDescriptor);
+ GET_PROC_V2(cuArray3DCreate);
+ GET_PROC_V2(cuArray3DGetDescriptor);
+ GET_PROC_V2(cuTexRefSetAddress);
+ GET_PROC_V2(cuTexRefSetAddress2D);
+ GET_PROC_V2(cuTexRefGetAddress);
+ }
+ else
+ {
+ GET_PROC(cuDeviceTotalMem);
+ GET_PROC(cuCtxCreate);
+ GET_PROC(cuModuleGetGlobal);
+ GET_PROC(cuMemGetInfo);
+ GET_PROC(cuMemAlloc);
+ GET_PROC(cuMemAllocPitch);
+ GET_PROC(cuMemFree);
+ GET_PROC(cuMemGetAddressRange);
+ GET_PROC(cuMemAllocHost);
+ GET_PROC(cuMemHostGetDevicePointer);
+ GET_PROC(cuMemcpyHtoD);
+ GET_PROC(cuMemcpyDtoH);
+ GET_PROC(cuMemcpyDtoD);
+ GET_PROC(cuMemcpyDtoA);
+ GET_PROC(cuMemcpyAtoD);
+ GET_PROC(cuMemcpyHtoA);
+ GET_PROC(cuMemcpyAtoH);
+ GET_PROC(cuMemcpyAtoA);
+ GET_PROC(cuMemcpy2D);
+ GET_PROC(cuMemcpy2DUnaligned);
+ GET_PROC(cuMemcpy3D);
+ GET_PROC(cuMemcpyHtoDAsync);
+ GET_PROC(cuMemcpyDtoHAsync);
+ GET_PROC(cuMemcpyHtoAAsync);
+ GET_PROC(cuMemcpyAtoHAsync);
+ GET_PROC(cuMemcpy2DAsync);
+ GET_PROC(cuMemcpy3DAsync);
+ GET_PROC(cuMemsetD8);
+ GET_PROC(cuMemsetD16);
+ GET_PROC(cuMemsetD32);
+ GET_PROC(cuMemsetD2D8);
+ GET_PROC(cuMemsetD2D16);
+ GET_PROC(cuMemsetD2D32);
+ GET_PROC(cuArrayCreate);
+ GET_PROC(cuArrayGetDescriptor);
+ GET_PROC(cuArray3DCreate);
+ GET_PROC(cuArray3DGetDescriptor);
+ GET_PROC(cuTexRefSetAddress);
+ GET_PROC(cuTexRefSetAddress2D);
+ GET_PROC(cuTexRefGetAddress);
+ }
+
+ // The following functions are specific to CUDA versions
+ if (driverVer >= 2010)
+ {
+ GET_PROC(cuModuleLoadDataEx);
+ GET_PROC(cuModuleLoadFatBinary);
+#ifdef CUDA_INIT_OPENGL
+ GET_PROC(cuGLCtxCreate);
+ GET_PROC(cuGraphicsGLRegisterBuffer);
+ GET_PROC(cuGraphicsGLRegisterImage);
+# ifdef WIN32
+ GET_PROC(cuWGLGetDevice);
+# endif
+#endif
+#ifdef CUDA_INIT_D3D9
+ GET_PROC(cuD3D9GetDevice);
+ GET_PROC(cuD3D9CtxCreate);
+ GET_PROC(cuGraphicsD3D9RegisterResource);
+#endif
+ }
+
+ if (driverVer >= 2030)
+ {
+ GET_PROC(cuMemHostGetFlags);
+#ifdef CUDA_INIT_D3D10
+ GET_PROC(cuD3D10GetDevice);
+ GET_PROC(cuD3D10CtxCreate);
+ GET_PROC(cuGraphicsD3D10RegisterResource);
+#endif
+#ifdef CUDA_INIT_OPENGL
+ GET_PROC(cuGraphicsGLRegisterBuffer);
+ GET_PROC(cuGraphicsGLRegisterImage);
+#endif
+ }
+
+ if (driverVer >= 3000)
+ {
+ GET_PROC(cuMemcpyDtoDAsync);
+ GET_PROC(cuFuncSetCacheConfig);
+#ifdef CUDA_INIT_D3D11
+ GET_PROC(cuD3D11GetDevice);
+ GET_PROC(cuD3D11CtxCreate);
+ GET_PROC(cuGraphicsD3D11RegisterResource);
+#endif
+ GET_PROC(cuGraphicsUnregisterResource);
+ GET_PROC(cuGraphicsSubResourceGetMappedArray);
+
+ if (cudaVersion >= 3020 && __CUDA_API_VERSION >= 3020)
+ {
+ GET_PROC_V2(cuGraphicsResourceGetMappedPointer);
+ }
+ else
+ {
+ GET_PROC(cuGraphicsResourceGetMappedPointer);
+ }
+
+ GET_PROC(cuGraphicsResourceSetMapFlags);
+ GET_PROC(cuGraphicsMapResources);
+ GET_PROC(cuGraphicsUnmapResources);
+ GET_PROC(cuGetExportTable);
+ }
+
+ if (driverVer >= 3010)
+ {
+ GET_PROC(cuModuleGetSurfRef);
+ GET_PROC(cuSurfRefSetArray);
+ GET_PROC(cuSurfRefGetArray);
+ GET_PROC(cuCtxSetLimit);
+ GET_PROC(cuCtxGetLimit);
+ }
+
+ if (driverVer >= 4000)
+ {
+ GET_PROC(cuCtxSetCurrent);
+ GET_PROC(cuCtxGetCurrent);
+ GET_PROC(cuMemHostRegister);
+ GET_PROC(cuMemHostUnregister);
+ GET_PROC(cuMemcpy);
+ GET_PROC(cuMemcpyPeer);
+ GET_PROC(cuLaunchKernel);
+ }
+
+ return CUDA_SUCCESS;
+}
diff --git a/tests/projects/cuda_console/inc/drvapi_error_string.h b/tests/projects/cuda_console/inc/drvapi_error_string.h
new file mode 100644
index 000000000..f29d10d70
--- /dev/null
+++ b/tests/projects/cuda_console/inc/drvapi_error_string.h
@@ -0,0 +1,463 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef _DRVAPI_ERROR_STRING_H_
+#define _DRVAPI_ERROR_STRING_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef __cuda_cuda_h__ // check to see if CUDA_H is included above
+
+// Error Code string definitions here
+typedef struct
+{
+ char const *error_string;
+ int error_id;
+} s_CudaErrorStr;
+
+/**
+ * Error codes
+ */
+static s_CudaErrorStr sCudaDrvErrorString[] =
+{
+ /**
+ * The API call returned with no errors. In the case of query calls, this
+ * can also mean that the operation being queried is complete (see
+ * ::cuEventQuery() and ::cuStreamQuery()).
+ */
+ { "CUDA_SUCCESS", 0 },
+
+ /**
+ * This indicates that one or more of the parameters passed to the API call
+ * is not within an acceptable range of values.
+ */
+ { "CUDA_ERROR_INVALID_VALUE", 1 },
+
+ /**
+ * The API call failed because it was unable to allocate enough memory to
+ * perform the requested operation.
+ */
+ { "CUDA_ERROR_OUT_OF_MEMORY", 2 },
+
+ /**
+ * This indicates that the CUDA driver has not been initialized with
+ * ::cuInit() or that initialization has failed.
+ */
+ { "CUDA_ERROR_NOT_INITIALIZED", 3 },
+
+ /**
+ * This indicates that the CUDA driver is in the process of shutting down.
+ */
+ { "CUDA_ERROR_DEINITIALIZED", 4 },
+
+ /**
+ * This indicates profiling APIs are called while application is running
+ * in visual profiler mode.
+ */
+ { "CUDA_ERROR_PROFILER_DISABLED", 5 },
+ /**
+ * This indicates profiling has not been initialized for this context.
+ * Call cuProfilerInitialize() to resolve this.
+ */
+ { "CUDA_ERROR_PROFILER_NOT_INITIALIZED", 6 },
+ /**
+ * This indicates profiler has already been started and probably
+ * cuProfilerStart() is incorrectly called.
+ */
+ { "CUDA_ERROR_PROFILER_ALREADY_STARTED", 7 },
+ /**
+ * This indicates profiler has already been stopped and probably
+ * cuProfilerStop() is incorrectly called.
+ */
+ { "CUDA_ERROR_PROFILER_ALREADY_STOPPED", 8 },
+ /**
+ * This indicates that no CUDA-capable devices were detected by the installed
+ * CUDA driver.
+ */
+ { "CUDA_ERROR_NO_DEVICE (no CUDA-capable devices were detected)", 100 },
+
+ /**
+ * This indicates that the device ordinal supplied by the user does not
+ * correspond to a valid CUDA device.
+ */
+ { "CUDA_ERROR_INVALID_DEVICE (device specified is not a valid CUDA device)", 101 },
+
+
+ /**
+ * This indicates that the device kernel image is invalid. This can also
+ * indicate an invalid CUDA module.
+ */
+ { "CUDA_ERROR_INVALID_IMAGE", 200 },
+
+ /**
+ * This most frequently indicates that there is no context bound to the
+ * current thread. This can also be returned if the context passed to an
+ * API call is not a valid handle (such as a context that has had
+ * ::cuCtxDestroy() invoked on it). This can also be returned if a user
+ * mixes different API versions (i.e. 3010 context with 3020 API calls).
+ * See ::cuCtxGetApiVersion() for more details.
+ */
+ { "CUDA_ERROR_INVALID_CONTEXT", 201 },
+
+ /**
+ * This indicated that the context being supplied as a parameter to the
+ * API call was already the active context.
+ * \deprecated
+ * This error return is deprecated as of CUDA 3.2. It is no longer an
+ * error to attempt to push the active context via ::cuCtxPushCurrent().
+ */
+ { "CUDA_ERROR_CONTEXT_ALREADY_CURRENT", 202 },
+
+ /**
+ * This indicates that a map or register operation has failed.
+ */
+ { "CUDA_ERROR_MAP_FAILED", 205 },
+
+ /**
+ * This indicates that an unmap or unregister operation has failed.
+ */
+ { "CUDA_ERROR_UNMAP_FAILED", 206 },
+
+ /**
+ * This indicates that the specified array is currently mapped and thus
+ * cannot be destroyed.
+ */
+ { "CUDA_ERROR_ARRAY_IS_MAPPED", 207 },
+
+ /**
+ * This indicates that the resource is already mapped.
+ */
+ { "CUDA_ERROR_ALREADY_MAPPED", 208 },
+
+ /**
+ * This indicates that there is no kernel image available that is suitable
+ * for the device. This can occur when a user specifies code generation
+ * options for a particular CUDA source file that do not include the
+ * corresponding device configuration.
+ */
+ { "CUDA_ERROR_NO_BINARY_FOR_GPU", 209 },
+
+ /**
+ * This indicates that a resource has already been acquired.
+ */
+ { "CUDA_ERROR_ALREADY_ACQUIRED", 210 },
+
+ /**
+ * This indicates that a resource is not mapped.
+ */
+ { "CUDA_ERROR_NOT_MAPPED", 211 },
+
+ /**
+ * This indicates that a mapped resource is not available for access as an
+ * array.
+ */
+ { "CUDA_ERROR_NOT_MAPPED_AS_ARRAY", 212 },
+
+ /**
+ * This indicates that a mapped resource is not available for access as a
+ * pointer.
+ */
+ { "CUDA_ERROR_NOT_MAPPED_AS_POINTER", 213 },
+
+ /**
+ * This indicates that an uncorrectable ECC error was detected during
+ * execution.
+ */
+ { "CUDA_ERROR_ECC_UNCORRECTABLE", 214 },
+
+ /**
+ * This indicates that the ::CUlimit passed to the API call is not
+ * supported by the active device.
+ */
+ { "CUDA_ERROR_UNSUPPORTED_LIMIT", 215 },
+
+ /**
+ * This indicates that the ::CUcontext passed to the API call can
+ * only be bound to a single CPU thread at a time but is already
+ * bound to a CPU thread.
+ */
+ { "CUDA_ERROR_CONTEXT_ALREADY_IN_USE", 216 },
+
+ /**
+ * This indicates that peer access is not supported across the given
+ * devices.
+ */
+ { "CUDA_ERROR_PEER_ACCESS_UNSUPPORTED", 217 },
+
+ /**
+ * This indicates that a PTX JIT compilation failed.
+ */
+ { "CUDA_ERROR_INVALID_PTX", 218 },
+
+ /**
+ * This indicates an error with OpenGL or DirectX context.
+ */
+ { "CUDA_ERROR_INVALID_GRAPHICS_CONTEXT", 219 },
+
+ /**
+ * This indicates that an uncorrectable NVLink error was detected during the
+ * execution.
+ */
+ { "CUDA_ERROR_NVLINK_UNCORRECTABLE", 220 },
+
+ /**
+ * This indicates that the PTX JIT compiler library was not found.
+ */
+ { "CUDA_ERROR_JIT_COMPILER_NOT_FOUND", 221 },
+
+ /**
+ * This indicates that the device kernel source is invalid.
+ */
+ { "CUDA_ERROR_INVALID_SOURCE", 300 },
+
+ /**
+ * This indicates that the file specified was not found.
+ */
+ { "CUDA_ERROR_FILE_NOT_FOUND", 301 },
+
+ /**
+ * This indicates that a link to a shared object failed to resolve.
+ */
+ { "CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND", 302 },
+
+ /**
+ * This indicates that initialization of a shared object failed.
+ */
+ { "CUDA_ERROR_SHARED_OBJECT_INIT_FAILED", 303 },
+
+ /**
+ * This indicates that an OS call failed.
+ */
+ { "CUDA_ERROR_OPERATING_SYSTEM", 304 },
+
+
+ /**
+ * This indicates that a resource handle passed to the API call was not
+ * valid. Resource handles are opaque types like ::CUstream and ::CUevent.
+ */
+ { "CUDA_ERROR_INVALID_HANDLE", 400 },
+
+
+ /**
+ * This indicates that a named symbol was not found. Examples of symbols
+ * are global/constant variable names, texture names }, and surface names.
+ */
+ { "CUDA_ERROR_NOT_FOUND", 500 },
+
+
+ /**
+ * This indicates that asynchronous operations issued previously have not
+ * completed yet. This result is not actually an error, but must be indicated
+ * differently than ::CUDA_SUCCESS (which indicates completion). Calls that
+ * may return this value include ::cuEventQuery() and ::cuStreamQuery().
+ */
+ { "CUDA_ERROR_NOT_READY", 600 },
+
+
+ /**
+ * While executing a kernel, the device encountered a
+ * load or store instruction on an invalid memory address.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ { "CUDA_ERROR_ILLEGAL_ADDRESS", 700 },
+
+ /**
+ * This indicates that a launch did not occur because it did not have
+ * appropriate resources. This error usually indicates that the user has
+ * attempted to pass too many arguments to the device kernel, or the
+ * kernel launch specifies too many threads for the kernel's register
+ * count. Passing arguments of the wrong size (i.e. a 64-bit pointer
+ * when a 32-bit int is expected) is equivalent to passing too many
+ * arguments and can also result in this error.
+ */
+ { "CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES", 701 },
+
+ /**
+ * This indicates that the device kernel took too long to execute. This can
+ * only occur if timeouts are enabled - see the device attribute
+ * ::CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT for more information. The
+ * context cannot be used (and must be destroyed similar to
+ * ::CUDA_ERROR_LAUNCH_FAILED). All existing device memory allocations from
+ * this context are invalid and must be reconstructed if the program is to
+ * continue using CUDA.
+ */
+ { "CUDA_ERROR_LAUNCH_TIMEOUT", 702 },
+
+ /**
+ * This error indicates a kernel launch that uses an incompatible texturing
+ * mode.
+ */
+ { "CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING", 703 },
+
+ /**
+ * This error indicates that a call to ::cuCtxEnablePeerAccess() is
+ * trying to re-enable peer access to a context which has already
+ * had peer access to it enabled.
+ */
+ { "CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED", 704 },
+
+ /**
+ * This error indicates that ::cuCtxDisablePeerAccess() is
+ * trying to disable peer access which has not been enabled yet
+ * via ::cuCtxEnablePeerAccess().
+ */
+ { "CUDA_ERROR_PEER_ACCESS_NOT_ENABLED", 705 },
+
+ /**
+ * This error indicates that the primary context for the specified device
+ * has already been initialized.
+ */
+ { "CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE", 708 },
+
+ /**
+ * This error indicates that the context current to the calling thread
+ * has been destroyed using ::cuCtxDestroy }, or is a primary context which
+ * has not yet been initialized.
+ */
+ { "CUDA_ERROR_CONTEXT_IS_DESTROYED", 709 },
+
+ /**
+ * A device-side assert triggered during kernel execution. The context
+ * cannot be used anymore, and must be destroyed. All existing device
+ * memory allocations from this context are invalid and must be
+ * reconstructed if the program is to continue using CUDA.
+ */
+ { "CUDA_ERROR_ASSERT", 710 },
+
+ /**
+ * This error indicates that the hardware resources required to enable
+ * peer access have been exhausted for one or more of the devices
+ * passed to ::cuCtxEnablePeerAccess().
+ */
+ { "CUDA_ERROR_TOO_MANY_PEERS", 711 },
+
+ /**
+ * This error indicates that the memory range passed to ::cuMemHostRegister()
+ * has already been registered.
+ */
+ { "CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED", 712 },
+
+ /**
+ * This error indicates that the pointer passed to ::cuMemHostUnregister()
+ * does not correspond to any currently registered memory region.
+ */
+ { "CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED", 713 },
+
+ /**
+ * While executing a kernel, the device encountered a stack error.
+ * This can be due to stack corruption or exceeding the stack size limit.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ { "CUDA_ERROR_HARDWARE_STACK_ERROR", 714 },
+
+ /**
+ * While executing a kernel, the device encountered an illegal instruction.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ { "CUDA_ERROR_ILLEGAL_INSTRUCTION", 715 },
+
+ /**
+ * While executing a kernel, the device encountered a load or store instruction
+ * on a memory address which is not aligned.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ { "CUDA_ERROR_MISALIGNED_ADDRESS", 716 },
+
+ /**
+ * While executing a kernel, the device encountered an instruction
+ * which can only operate on memory locations in certain address spaces
+ * (global, shared, or local), but was supplied a memory address not
+ * belonging to an allowed address space.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ { "CUDA_ERROR_INVALID_ADDRESS_SPACE", 717 },
+
+ /**
+ * While executing a kernel, the device program counter wrapped its address space.
+ * This leaves the process in an inconsistent state and any further CUDA work
+ * will return the same error. To continue using CUDA, the process must be terminated
+ * and relaunched.
+ */
+ { "CUDA_ERROR_INVALID_PC", 718 },
+
+ /**
+ * An exception occurred on the device while executing a kernel. Common
+ * causes include dereferencing an invalid device pointer and accessing
+ * out of bounds shared memory. The context cannot be used }, so it must
+ * be destroyed (and a new one should be created). All existing device
+ * memory allocations from this context are invalid and must be
+ * reconstructed if the program is to continue using CUDA.
+ */
+ { "CUDA_ERROR_LAUNCH_FAILED", 719 },
+
+ /**
+ * This error indicates that the number of blocks launched per grid for a kernel that was
+ * launched via either ::cuLaunchCooperativeKernel or ::cuLaunchCooperativeKernelMultiDevice
+ * exceeds the maximum number of blocks as allowed by ::cuOccupancyMaxActiveBlocksPerMultiprocessor
+ * or ::cuOccupancyMaxActiveBlocksPerMultiprocessorWithFlags times the number of multiprocessors
+ * as specified by the device attribute ::CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT.
+ */
+ { "CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE", 720 },
+
+
+ /**
+ * This error indicates that the attempted operation is not permitted.
+ */
+ { "CUDA_ERROR_NOT_PERMITTED", 800 },
+
+ /**
+ * This error indicates that the attempted operation is not supported
+ * on the current system or device.
+ */
+ { "CUDA_ERROR_NOT_SUPPORTED", 801 },
+
+
+ /**
+ * This indicates that an unknown internal error has occurred.
+ */
+ { "CUDA_ERROR_UNKNOWN", 999 },
+ { NULL, -1 }
+};
+
+// This is just a linear search through the array, since the error_id's are not
+// always ocurring consecutively
+inline const char *getCudaDrvErrorString(CUresult error_id)
+{
+ int index = 0;
+
+ while (sCudaDrvErrorString[index].error_id != error_id &&
+ sCudaDrvErrorString[index].error_id != -1)
+ {
+ index++;
+ }
+
+ if (sCudaDrvErrorString[index].error_id == error_id)
+ return (const char *)sCudaDrvErrorString[index].error_string;
+ else
+ return (const char *)"CUDA_ERROR not found!";
+}
+
+#endif // __cuda_cuda_h__
+
+
+#endif
diff --git a/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink.h b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink.h
new file mode 100644
index 000000000..f4549d0fc
--- /dev/null
+++ b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink.h
@@ -0,0 +1,25 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef __cuda_drvapi_dynlink_h__
+#define __cuda_drvapi_dynlink_h__
+
+#include "cuda_drvapi_dynlink_cuda.h"
+
+#if defined(CUDA_INIT_D3D9)||defined(CUDA_INIT_D3D10)||defined(CUDA_INIT_D3D11)
+#include "cuda_drvapi_dynlink_d3d.h"
+#endif
+
+#ifdef CUDA_INIT_OPENGL
+#include "cuda_drvapi_dynlink_gl.h"
+#endif
+
+#endif //__cuda_drvapi_dynlink_h__
diff --git a/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_cuda.h b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_cuda.h
new file mode 100644
index 000000000..602f61efc
--- /dev/null
+++ b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_cuda.h
@@ -0,0 +1,1702 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef __cuda_drvapi_dynlink_cuda_h__
+#define __cuda_drvapi_dynlink_cuda_h__
+
+#include <stdlib.h>
+
+/**
+ * CUDA API versioning support
+ */
+#define __CUDA_API_VERSION 4000
+
+/**
+ * \defgroup CUDA_DRIVER CUDA Driver API
+ *
+ * This section describes the low-level CUDA driver application programming
+ * interface.
+ *
+ * @{
+ */
+
+/**
+ * \defgroup CUDA_TYPES Data types used by CUDA driver
+ * @{
+ */
+
+/**
+ * CUDA API version number
+ */
+#define CUDA_VERSION 3020 /* 3.2 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * CUDA device pointer
+ */
+#if __CUDA_API_VERSION >= 3020
+
+#if defined(_WIN64) || defined(__LP64__)
+typedef unsigned long long CUdeviceptr;
+#else
+typedef unsigned int CUdeviceptr;
+#endif
+
+#endif /* __CUDA_API_VERSION >= 3020 */
+
+typedef int CUdevice; /**< CUDA device */
+typedef struct CUctx_st *CUcontext; /**< CUDA context */
+typedef struct CUmod_st *CUmodule; /**< CUDA module */
+typedef struct CUfunc_st *CUfunction; /**< CUDA function */
+typedef struct CUarray_st *CUarray; /**< CUDA array */
+typedef struct CUtexref_st *CUtexref; /**< CUDA texture reference */
+typedef struct CUsurfref_st *CUsurfref; /**< CUDA surface reference */
+typedef struct CUevent_st *CUevent; /**< CUDA event */
+typedef struct CUstream_st *CUstream; /**< CUDA stream */
+typedef struct CUgraphicsResource_st *CUgraphicsResource; /**< CUDA graphics interop resource */
+
+typedef struct CUuuid_st /**< CUDA definition of UUID */
+{
+ char bytes[16];
+} CUuuid;
+
+/**
+ * Context creation flags
+ */
+typedef enum CUctx_flags_enum
+{
+ CU_CTX_SCHED_AUTO = 0x00, /**< Automatic scheduling */
+ CU_CTX_SCHED_SPIN = 0x01, /**< Set spin as default scheduling */
+ CU_CTX_SCHED_YIELD = 0x02, /**< Set yield as default scheduling */
+ CU_CTX_SCHED_BLOCKING_SYNC = 0x04, /**< Set blocking synchronization as default scheduling */
+ CU_CTX_BLOCKING_SYNC = 0x04, /**< Set blocking synchronization as default scheduling \deprecated */
+ CU_CTX_MAP_HOST = 0x08, /**< Support mapped pinned allocations */
+ CU_CTX_LMEM_RESIZE_TO_MAX = 0x10, /**< Keep local memory allocation after launch */
+#if __CUDA_API_VERSION < 4000
+ CU_CTX_SCHED_MASK = 0x03,
+ CU_CTX_FLAGS_MASK = 0x1f
+#else
+ CU_CTX_SCHED_MASK = 0x07,
+ CU_CTX_PRIMARY = 0x20, /**< Initialize and return the primary context */
+ CU_CTX_FLAGS_MASK = 0x3f
+#endif
+} CUctx_flags;
+
+/**
+ * Event creation flags
+ */
+typedef enum CUevent_flags_enum
+{
+ CU_EVENT_DEFAULT = 0, /**< Default event flag */
+ CU_EVENT_BLOCKING_SYNC = 1, /**< Event uses blocking synchronization */
+ CU_EVENT_DISABLE_TIMING = 2 /**< Event will not record timing data */
+} CUevent_flags;
+
+/**
+ * Array formats
+ */
+typedef enum CUarray_format_enum
+{
+ CU_AD_FORMAT_UNSIGNED_INT8 = 0x01, /**< Unsigned 8-bit integers */
+ CU_AD_FORMAT_UNSIGNED_INT16 = 0x02, /**< Unsigned 16-bit integers */
+ CU_AD_FORMAT_UNSIGNED_INT32 = 0x03, /**< Unsigned 32-bit integers */
+ CU_AD_FORMAT_SIGNED_INT8 = 0x08, /**< Signed 8-bit integers */
+ CU_AD_FORMAT_SIGNED_INT16 = 0x09, /**< Signed 16-bit integers */
+ CU_AD_FORMAT_SIGNED_INT32 = 0x0a, /**< Signed 32-bit integers */
+ CU_AD_FORMAT_HALF = 0x10, /**< 16-bit floating point */
+ CU_AD_FORMAT_FLOAT = 0x20 /**< 32-bit floating point */
+} CUarray_format;
+
+/**
+ * Texture reference addressing modes
+ */
+typedef enum CUaddress_mode_enum
+{
+ CU_TR_ADDRESS_MODE_WRAP = 0, /**< Wrapping address mode */
+ CU_TR_ADDRESS_MODE_CLAMP = 1, /**< Clamp to edge address mode */
+ CU_TR_ADDRESS_MODE_MIRROR = 2, /**< Mirror address mode */
+ CU_TR_ADDRESS_MODE_BORDER = 3 /**< Border address mode */
+} CUaddress_mode;
+
+/**
+ * Texture reference filtering modes
+ */
+typedef enum CUfilter_mode_enum
+{
+ CU_TR_FILTER_MODE_POINT = 0, /**< Point filter mode */
+ CU_TR_FILTER_MODE_LINEAR = 1 /**< Linear filter mode */
+} CUfilter_mode;
+
+/**
+ * Device properties
+ */
+typedef enum CUdevice_attribute_enum
+{
+ CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 1, /**< Maximum number of threads per block */
+ CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_X = 2, /**< Maximum block dimension X */
+ CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Y = 3, /**< Maximum block dimension Y */
+ CU_DEVICE_ATTRIBUTE_MAX_BLOCK_DIM_Z = 4, /**< Maximum block dimension Z */
+ CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_X = 5, /**< Maximum grid dimension X */
+ CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Y = 6, /**< Maximum grid dimension Y */
+ CU_DEVICE_ATTRIBUTE_MAX_GRID_DIM_Z = 7, /**< Maximum grid dimension Z */
+ CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK = 8, /**< Maximum shared memory available per block in bytes */
+ CU_DEVICE_ATTRIBUTE_SHARED_MEMORY_PER_BLOCK = 8, /**< Deprecated, use CU_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK */
+ CU_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY = 9, /**< Memory available on device for __constant__ variables in a CUDA C kernel in bytes */
+ CU_DEVICE_ATTRIBUTE_WARP_SIZE = 10, /**< Warp size in threads */
+ CU_DEVICE_ATTRIBUTE_MAX_PITCH = 11, /**< Maximum pitch in bytes allowed by memory copies */
+ CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK = 12, /**< Maximum number of 32-bit registers available per block */
+ CU_DEVICE_ATTRIBUTE_REGISTERS_PER_BLOCK = 12, /**< Deprecated, use CU_DEVICE_ATTRIBUTE_MAX_REGISTERS_PER_BLOCK */
+ CU_DEVICE_ATTRIBUTE_CLOCK_RATE = 13, /**< Peak clock frequency in kilohertz */
+ CU_DEVICE_ATTRIBUTE_TEXTURE_ALIGNMENT = 14, /**< Alignment requirement for textures */
+ CU_DEVICE_ATTRIBUTE_GPU_OVERLAP = 15, /**< Device can possibly copy memory and execute a kernel concurrently */
+ CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT = 16, /**< Number of multiprocessors on device */
+ CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT = 17, /**< Specifies whether there is a run time limit on kernels */
+ CU_DEVICE_ATTRIBUTE_INTEGRATED = 18, /**< Device is integrated with host memory */
+ CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY = 19, /**< Device can map host memory into CUDA address space */
+ CU_DEVICE_ATTRIBUTE_COMPUTE_MODE = 20, /**< Compute mode (See ::CUcomputemode for details) */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_WIDTH = 21, /**< Maximum 1D texture width */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_WIDTH = 22, /**< Maximum 2D texture width */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_HEIGHT = 23, /**< Maximum 2D texture height */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_WIDTH = 24, /**< Maximum 3D texture width */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_HEIGHT = 25, /**< Maximum 3D texture height */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE3D_DEPTH = 26, /**< Maximum 3D texture depth */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_WIDTH = 27, /**< Maximum texture array width */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_HEIGHT = 28, /**< Maximum texture array height */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE2D_ARRAY_NUMSLICES = 29, /**< Maximum slices in a texture array */
+ CU_DEVICE_ATTRIBUTE_SURFACE_ALIGNMENT = 30, /**< Alignment requirement for surfaces */
+ CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS = 31, /**< Device can possibly execute multiple kernels concurrently */
+ CU_DEVICE_ATTRIBUTE_ECC_ENABLED = 32, /**< Device has ECC support enabled */
+ CU_DEVICE_ATTRIBUTE_PCI_BUS_ID = 33, /**< PCI bus ID of the device */
+ CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID = 34, /**< PCI device ID of the device */
+ CU_DEVICE_ATTRIBUTE_TCC_DRIVER = 35 /**< Device is using TCC driver model */
+
+#if __CUDA_API_VERSION >= 4000
+ ,
+ CU_DEVICE_ATTRIBUTE_MEMORY_CLOCK_RATE = 36, /**< Peak memory clock frequency in kilohertz */
+ CU_DEVICE_ATTRIBUTE_GLOBAL_MEMORY_BUS_WIDTH = 37, /**< Global memory bus width in bits */
+ CU_DEVICE_ATTRIBUTE_L2_CACHE_SIZE = 38, /**< Size of L2 cache in bytes */
+ CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_MULTIPROCESSOR = 39, /**< Maximum resident threads per multiprocessor */
+ CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT = 40, /**< Number of asynchronous engines */
+ CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING = 41, /**< Device uses shares a unified address space with the host */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_WIDTH = 42, /**< Maximum 1D layered texture width */
+ CU_DEVICE_ATTRIBUTE_MAXIMUM_TEXTURE1D_LAYERED_LAYERS = 43 /**< Maximum layers in a 1D layered texture */
+#endif
+} CUdevice_attribute;
+
+/**
+ * Legacy device properties
+ */
+typedef struct CUdevprop_st
+{
+ int maxThreadsPerBlock; /**< Maximum number of threads per block */
+ int maxThreadsDim[3]; /**< Maximum size of each dimension of a block */
+ int maxGridSize[3]; /**< Maximum size of each dimension of a grid */
+ int sharedMemPerBlock; /**< Shared memory available per block in bytes */
+ int totalConstantMemory; /**< Constant memory available on device in bytes */
+ int SIMDWidth; /**< Warp size in threads */
+ int memPitch; /**< Maximum pitch in bytes allowed by memory copies */
+ int regsPerBlock; /**< 32-bit registers available per block */
+ int clockRate; /**< Clock frequency in kilohertz */
+ int textureAlign; /**< Alignment requirement for textures */
+} CUdevprop;
+
+/**
+ * Function properties
+ */
+typedef enum CUfunction_attribute_enum
+{
+ /**
+ * The maximum number of threads per block, beyond which a launch of the
+ * function would fail. This number depends on both the function and the
+ * device on which the function is currently loaded.
+ */
+ CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK = 0,
+
+ /**
+ * The size in bytes of statically-allocated shared memory required by
+ * this function. This does not include dynamically-allocated shared
+ * memory requested by the user at runtime.
+ */
+ CU_FUNC_ATTRIBUTE_SHARED_SIZE_BYTES = 1,
+
+ /**
+ * The size in bytes of user-allocated constant memory required by this
+ * function.
+ */
+ CU_FUNC_ATTRIBUTE_CONST_SIZE_BYTES = 2,
+
+ /**
+ * The size in bytes of local memory used by each thread of this function.
+ */
+ CU_FUNC_ATTRIBUTE_LOCAL_SIZE_BYTES = 3,
+
+ /**
+ * The number of registers used by each thread of this function.
+ */
+ CU_FUNC_ATTRIBUTE_NUM_REGS = 4,
+
+ /**
+ * The PTX virtual architecture version for which the function was
+ * compiled. This value is the major PTX version * 10 + the minor PTX
+ * version, so a PTX version 1.3 function would return the value 13.
+ * Note that this may return the undefined value of 0 for cubins
+ * compiled prior to CUDA 3.0.
+ */
+ CU_FUNC_ATTRIBUTE_PTX_VERSION = 5,
+
+ /**
+ * The binary architecture version for which the function was compiled.
+ * This value is the major binary version * 10 + the minor binary version,
+ * so a binary version 1.3 function would return the value 13. Note that
+ * this will return a value of 10 for legacy cubins that do not have a
+ * properly-encoded binary architecture version.
+ */
+ CU_FUNC_ATTRIBUTE_BINARY_VERSION = 6,
+
+ CU_FUNC_ATTRIBUTE_MAX
+} CUfunction_attribute;
+
+/**
+ * Function cache configurations
+ */
+typedef enum CUfunc_cache_enum
+{
+ CU_FUNC_CACHE_PREFER_NONE = 0x00, /**< no preference for shared memory or L1 (default) */
+ CU_FUNC_CACHE_PREFER_SHARED = 0x01, /**< prefer larger shared memory and smaller L1 cache */
+ CU_FUNC_CACHE_PREFER_L1 = 0x02 /**< prefer larger L1 cache and smaller shared memory */
+} CUfunc_cache;
+
+/**
+ * Memory types
+ */
+typedef enum CUmemorytype_enum
+{
+ CU_MEMORYTYPE_HOST = 0x01, /**< Host memory */
+ CU_MEMORYTYPE_DEVICE = 0x02, /**< Device memory */
+ CU_MEMORYTYPE_ARRAY = 0x03 /**< Array memory */
+#if __CUDA_API_VERSION >= 4000
+ ,
+ CU_MEMORYTYPE_UNIFIED = 0x04 /**< Unified device or host memory */
+#endif
+} CUmemorytype;
+
+/**
+ * Compute Modes
+ */
+typedef enum CUcomputemode_enum
+{
+ CU_COMPUTEMODE_DEFAULT = 0, /**< Default compute mode (Multiple contexts allowed per device) */
+ CU_COMPUTEMODE_EXCLUSIVE = 1, /**< Compute-exclusive-thread mode (Only one context used by a single thread can be present on this device at a time) */
+ CU_COMPUTEMODE_PROHIBITED = 2 /**< Compute-prohibited mode (No contexts can be created on this device at this time) */
+#if __CUDA_API_VERSION >= 4000
+ ,
+ CU_COMPUTEMODE_EXCLUSIVE_PROCESS = 3 /**< Compute-exclusive-process mode (Only one context used by a single process can be present on this device at a time) */
+#endif
+} CUcomputemode;
+
+/**
+ * Online compiler options
+ */
+typedef enum CUjit_option_enum
+{
+ /**
+ * Max number of registers that a thread may use.\n
+ * Option type: unsigned int
+ */
+ CU_JIT_MAX_REGISTERS = 0,
+
+ /**
+ * IN: Specifies minimum number of threads per block to target compilation
+ * for\n
+ * OUT: Returns the number of threads the compiler actually targeted.
+ * This restricts the resource utilization fo the compiler (e.g. max
+ * registers) such that a block with the given number of threads should be
+ * able to launch based on register limitations. Note, this option does not
+ * currently take into account any other resource limitations, such as
+ * shared memory utilization.\n
+ * Option type: unsigned int
+ */
+ CU_JIT_THREADS_PER_BLOCK,
+
+ /**
+ * Returns a float value in the option of the wall clock time, in
+ * milliseconds, spent creating the cubin\n
+ * Option type: float
+ */
+ CU_JIT_WALL_TIME,
+
+ /**
+ * Pointer to a buffer in which to print any log messsages from PTXAS
+ * that are informational in nature (the buffer size is specified via
+ * option ::CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES) \n
+ * Option type: char*
+ */
+ CU_JIT_INFO_LOG_BUFFER,
+
+ /**
+ * IN: Log buffer size in bytes. Log messages will be capped at this size
+ * (including null terminator)\n
+ * OUT: Amount of log buffer filled with messages\n
+ * Option type: unsigned int
+ */
+ CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES,
+
+ /**
+ * Pointer to a buffer in which to print any log messages from PTXAS that
+ * reflect errors (the buffer size is specified via option
+ * ::CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES)\n
+ * Option type: char*
+ */
+ CU_JIT_ERROR_LOG_BUFFER,
+
+ /**
+ * IN: Log buffer size in bytes. Log messages will be capped at this size
+ * (including null terminator)\n
+ * OUT: Amount of log buffer filled with messages\n
+ * Option type: unsigned int
+ */
+ CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES,
+
+ /**
+ * Level of optimizations to apply to generated code (0 - 4), with 4
+ * being the default and highest level of optimizations.\n
+ * Option type: unsigned int
+ */
+ CU_JIT_OPTIMIZATION_LEVEL,
+
+ /**
+ * No option value required. Determines the target based on the current
+ * attached context (default)\n
+ * Option type: No option value needed
+ */
+ CU_JIT_TARGET_FROM_CUCONTEXT,
+
+ /**
+ * Target is chosen based on supplied ::CUjit_target_enum.\n
+ * Option type: unsigned int for enumerated type ::CUjit_target_enum
+ */
+ CU_JIT_TARGET,
+
+ /**
+ * Specifies choice of fallback strategy if matching cubin is not found.
+ * Choice is based on supplied ::CUjit_fallback_enum.\n
+ * Option type: unsigned int for enumerated type ::CUjit_fallback_enum
+ */
+ CU_JIT_FALLBACK_STRATEGY
+
+} CUjit_option;
+
+/**
+ * Online compilation targets
+ */
+typedef enum CUjit_target_enum
+{
+ CU_TARGET_COMPUTE_10 = 0, /**< Compute device class 1.0 */
+ CU_TARGET_COMPUTE_11, /**< Compute device class 1.1 */
+ CU_TARGET_COMPUTE_12, /**< Compute device class 1.2 */
+ CU_TARGET_COMPUTE_13, /**< Compute device class 1.3 */
+ CU_TARGET_COMPUTE_20, /**< Compute device class 2.0 */
+ CU_TARGET_COMPUTE_21 /**< Compute device class 2.1 */
+} CUjit_target;
+
+/**
+ * Cubin matching fallback strategies
+ */
+typedef enum CUjit_fallback_enum
+{
+ CU_PREFER_PTX = 0, /**< Prefer to compile ptx */
+
+ CU_PREFER_BINARY /**< Prefer to fall back to compatible binary code */
+
+} CUjit_fallback;
+
+/**
+ * Flags to register a graphics resource
+ */
+typedef enum CUgraphicsRegisterFlags_enum
+{
+ CU_GRAPHICS_REGISTER_FLAGS_NONE = 0x00,
+ CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY = 0x01,
+ CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD = 0x02,
+ CU_GRAPHICS_REGISTER_FLAGS_SURFACE_LDST = 0x04
+} CUgraphicsRegisterFlags;
+
+/**
+ * Flags for mapping and unmapping interop resources
+ */
+typedef enum CUgraphicsMapResourceFlags_enum
+{
+ CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE = 0x00,
+ CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY = 0x01,
+ CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD = 0x02
+} CUgraphicsMapResourceFlags;
+
+/**
+ * Array indices for cube faces
+ */
+typedef enum CUarray_cubemap_face_enum
+{
+ CU_CUBEMAP_FACE_POSITIVE_X = 0x00, /**< Positive X face of cubemap */
+ CU_CUBEMAP_FACE_NEGATIVE_X = 0x01, /**< Negative X face of cubemap */
+ CU_CUBEMAP_FACE_POSITIVE_Y = 0x02, /**< Positive Y face of cubemap */
+ CU_CUBEMAP_FACE_NEGATIVE_Y = 0x03, /**< Negative Y face of cubemap */
+ CU_CUBEMAP_FACE_POSITIVE_Z = 0x04, /**< Positive Z face of cubemap */
+ CU_CUBEMAP_FACE_NEGATIVE_Z = 0x05 /**< Negative Z face of cubemap */
+} CUarray_cubemap_face;
+
+/**
+ * Limits
+ */
+typedef enum CUlimit_enum
+{
+ CU_LIMIT_STACK_SIZE = 0x00, /**< GPU thread stack size */
+ CU_LIMIT_PRINTF_FIFO_SIZE = 0x01, /**< GPU printf FIFO size */
+ CU_LIMIT_MALLOC_HEAP_SIZE = 0x02 /**< GPU malloc heap size */
+} CUlimit;
+
+/**
+ * Error codes
+ */
+typedef enum cudaError_enum
+{
+ /**
+ * The API call returned with no errors. In the case of query calls, this
+ * can also mean that the operation being queried is complete (see
+ * ::cuEventQuery() and ::cuStreamQuery()).
+ */
+ CUDA_SUCCESS = 0,
+
+ /**
+ * This indicates that one or more of the parameters passed to the API call
+ * is not within an acceptable range of values.
+ */
+ CUDA_ERROR_INVALID_VALUE = 1,
+
+ /**
+ * The API call failed because it was unable to allocate enough memory to
+ * perform the requested operation.
+ */
+ CUDA_ERROR_OUT_OF_MEMORY = 2,
+
+ /**
+ * This indicates that the CUDA driver has not been initialized with
+ * ::cuInit() or that initialization has failed.
+ */
+ CUDA_ERROR_NOT_INITIALIZED = 3,
+
+ /**
+ * This indicates that the CUDA driver is in the process of shutting down.
+ */
+ CUDA_ERROR_DEINITIALIZED = 4,
+
+ /**
+ * This indicates profiling APIs are called while application is running
+ * in visual profiler mode.
+ */
+ CUDA_ERROR_PROFILER_DISABLED = 5,
+ /**
+ * This indicates profiling has not been initialized for this context.
+ * Call cuProfilerInitialize() to resolve this.
+ */
+ CUDA_ERROR_PROFILER_NOT_INITIALIZED = 6,
+ /**
+ * This indicates profiler has already been started and probably
+ * cuProfilerStart() is incorrectly called.
+ */
+ CUDA_ERROR_PROFILER_ALREADY_STARTED = 7,
+ /**
+ * This indicates profiler has already been stopped and probably
+ * cuProfilerStop() is incorrectly called.
+ */
+ CUDA_ERROR_PROFILER_ALREADY_STOPPED = 8,
+ /**
+ * This indicates that no CUDA-capable devices were detected by the installed
+ * CUDA driver.
+ */
+ CUDA_ERROR_NO_DEVICE = 100,
+
+ /**
+ * This indicates that the device ordinal supplied by the user does not
+ * correspond to a valid CUDA device.
+ */
+ CUDA_ERROR_INVALID_DEVICE = 101,
+
+
+ /**
+ * This indicates that the device kernel image is invalid. This can also
+ * indicate an invalid CUDA module.
+ */
+ CUDA_ERROR_INVALID_IMAGE = 200,
+
+ /**
+ * This most frequently indicates that there is no context bound to the
+ * current thread. This can also be returned if the context passed to an
+ * API call is not a valid handle (such as a context that has had
+ * ::cuCtxDestroy() invoked on it). This can also be returned if a user
+ * mixes different API versions (i.e. 3010 context with 3020 API calls).
+ * See ::cuCtxGetApiVersion() for more details.
+ */
+ CUDA_ERROR_INVALID_CONTEXT = 201,
+
+ /**
+ * This indicated that the context being supplied as a parameter to the
+ * API call was already the active context.
+ * \deprecated
+ * This error return is deprecated as of CUDA 3.2. It is no longer an
+ * error to attempt to push the active context via ::cuCtxPushCurrent().
+ */
+ CUDA_ERROR_CONTEXT_ALREADY_CURRENT = 202,
+
+ /**
+ * This indicates that a map or register operation has failed.
+ */
+ CUDA_ERROR_MAP_FAILED = 205,
+
+ /**
+ * This indicates that an unmap or unregister operation has failed.
+ */
+ CUDA_ERROR_UNMAP_FAILED = 206,
+
+ /**
+ * This indicates that the specified array is currently mapped and thus
+ * cannot be destroyed.
+ */
+ CUDA_ERROR_ARRAY_IS_MAPPED = 207,
+
+ /**
+ * This indicates that the resource is already mapped.
+ */
+ CUDA_ERROR_ALREADY_MAPPED = 208,
+
+ /**
+ * This indicates that there is no kernel image available that is suitable
+ * for the device. This can occur when a user specifies code generation
+ * options for a particular CUDA source file that do not include the
+ * corresponding device configuration.
+ */
+ CUDA_ERROR_NO_BINARY_FOR_GPU = 209,
+
+ /**
+ * This indicates that a resource has already been acquired.
+ */
+ CUDA_ERROR_ALREADY_ACQUIRED = 210,
+
+ /**
+ * This indicates that a resource is not mapped.
+ */
+ CUDA_ERROR_NOT_MAPPED = 211,
+
+ /**
+ * This indicates that a mapped resource is not available for access as an
+ * array.
+ */
+ CUDA_ERROR_NOT_MAPPED_AS_ARRAY = 212,
+
+ /**
+ * This indicates that a mapped resource is not available for access as a
+ * pointer.
+ */
+ CUDA_ERROR_NOT_MAPPED_AS_POINTER = 213,
+
+ /**
+ * This indicates that an uncorrectable ECC error was detected during
+ * execution.
+ */
+ CUDA_ERROR_ECC_UNCORRECTABLE = 214,
+
+ /**
+ * This indicates that the ::CUlimit passed to the API call is not
+ * supported by the active device.
+ */
+ CUDA_ERROR_UNSUPPORTED_LIMIT = 215,
+
+ /**
+ * This indicates that the ::CUcontext passed to the API call can
+ * only be bound to a single CPU thread at a time but is already
+ * bound to a CPU thread.
+ */
+ CUDA_ERROR_CONTEXT_ALREADY_IN_USE = 216,
+
+ /**
+ * This indicates that the device kernel source is invalid.
+ */
+ CUDA_ERROR_INVALID_SOURCE = 300,
+
+ /**
+ * This indicates that the file specified was not found.
+ */
+ CUDA_ERROR_FILE_NOT_FOUND = 301,
+
+ /**
+ * This indicates that a link to a shared object failed to resolve.
+ */
+ CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302,
+
+ /**
+ * This indicates that initialization of a shared object failed.
+ */
+ CUDA_ERROR_SHARED_OBJECT_INIT_FAILED = 303,
+
+ /**
+ * This indicates that an OS call failed.
+ */
+ CUDA_ERROR_OPERATING_SYSTEM = 304,
+
+
+ /**
+ * This indicates that a resource handle passed to the API call was not
+ * valid. Resource handles are opaque types like ::CUstream and ::CUevent.
+ */
+ CUDA_ERROR_INVALID_HANDLE = 400,
+
+
+ /**
+ * This indicates that a named symbol was not found. Examples of symbols
+ * are global/constant variable names, texture names, and surface names.
+ */
+ CUDA_ERROR_NOT_FOUND = 500,
+
+
+ /**
+ * This indicates that asynchronous operations issued previously have not
+ * completed yet. This result is not actually an error, but must be indicated
+ * differently than ::CUDA_SUCCESS (which indicates completion). Calls that
+ * may return this value include ::cuEventQuery() and ::cuStreamQuery().
+ */
+ CUDA_ERROR_NOT_READY = 600,
+
+
+ /**
+ * An exception occurred on the device while executing a kernel. Common
+ * causes include dereferencing an invalid device pointer and accessing
+ * out of bounds shared memory. The context cannot be used, so it must
+ * be destroyed (and a new one should be created). All existing device
+ * memory allocations from this context are invalid and must be
+ * reconstructed if the program is to continue using CUDA.
+ */
+ CUDA_ERROR_LAUNCH_FAILED = 700,
+
+ /**
+ * This indicates that a launch did not occur because it did not have
+ * appropriate resources. This error usually indicates that the user has
+ * attempted to pass too many arguments to the device kernel, or the
+ * kernel launch specifies too many threads for the kernel's register
+ * count. Passing arguments of the wrong size (i.e. a 64-bit pointer
+ * when a 32-bit int is expected) is equivalent to passing too many
+ * arguments and can also result in this error.
+ */
+ CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES = 701,
+
+ /**
+ * This indicates that the device kernel took too long to execute. This can
+ * only occur if timeouts are enabled - see the device attribute
+ * ::CU_DEVICE_ATTRIBUTE_KERNEL_EXEC_TIMEOUT for more information. The
+ * context cannot be used (and must be destroyed similar to
+ * ::CUDA_ERROR_LAUNCH_FAILED). All existing device memory allocations from
+ * this context are invalid and must be reconstructed if the program is to
+ * continue using CUDA.
+ */
+ CUDA_ERROR_LAUNCH_TIMEOUT = 702,
+
+ /**
+ * This error indicates a kernel launch that uses an incompatible texturing
+ * mode.
+ */
+ CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING = 703,
+
+ /**
+ * This error indicates that a call to ::cuCtxEnablePeerAccess() is
+ * trying to re-enable peer access to a context which has already
+ * had peer access to it enabled.
+ */
+ CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED = 704,
+
+ /**
+ * This error indicates that a call to ::cuMemPeerRegister is trying to
+ * register memory from a context which has not had peer access
+ * enabled yet via ::cuCtxEnablePeerAccess(), or that
+ * ::cuCtxDisablePeerAccess() is trying to disable peer access
+ * which has not been enabled yet.
+ */
+ CUDA_ERROR_PEER_ACCESS_NOT_ENABLED = 705,
+
+ /**
+ * This error indicates that a call to ::cuMemPeerRegister is trying to
+ * register already-registered memory.
+ */
+ CUDA_ERROR_PEER_MEMORY_ALREADY_REGISTERED = 706,
+
+ /**
+ * This error indicates that a call to ::cuMemPeerUnregister is trying to
+ * unregister memory that has not been registered.
+ */
+ CUDA_ERROR_PEER_MEMORY_NOT_REGISTERED = 707,
+
+ /**
+ * This error indicates that ::cuCtxCreate was called with the flag
+ * ::CU_CTX_PRIMARY on a device which already has initialized its
+ * primary context.
+ */
+ CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE = 708,
+
+ /**
+ * This error indicates that the context current to the calling thread
+ * has been destroyed using ::cuCtxDestroy, or is a primary context which
+ * has not yet been initialized.
+ */
+ CUDA_ERROR_CONTEXT_IS_DESTROYED = 709,
+
+ /**
+ * This indicates that an unknown internal error has occurred.
+ */
+ CUDA_ERROR_UNKNOWN = 999
+} CUresult;
+
+#if __CUDA_API_VERSION >= 4000
+/**
+ * If set, host memory is portable between CUDA contexts.
+ * Flag for ::cuMemHostAlloc()
+ */
+#define CU_MEMHOSTALLOC_PORTABLE 0x01
+
+/**
+ * If set, host memory is mapped into CUDA address space and
+ * ::cuMemHostGetDevicePointer() may be called on the host pointer.
+ * Flag for ::cuMemHostAlloc()
+ */
+#define CU_MEMHOSTALLOC_DEVICEMAP 0x02
+
+/**
+ * If set, host memory is allocated as write-combined - fast to write,
+ * faster to DMA, slow to read except via SSE4 streaming load instruction
+ * (MOVNTDQA).
+ * Flag for ::cuMemHostAlloc()
+ */
+#define CU_MEMHOSTALLOC_WRITECOMBINED 0x04
+
+/**
+ * If set, host memory is portable between CUDA contexts.
+ * Flag for ::cuMemHostRegister()
+ */
+#define CU_MEMHOSTREGISTER_PORTABLE 0x01
+
+/**
+ * If set, host memory is mapped into CUDA address space and
+ * ::cuMemHostGetDevicePointer() may be called on the host pointer.
+ * Flag for ::cuMemHostRegister()
+ */
+#define CU_MEMHOSTREGISTER_DEVICEMAP 0x02
+
+/**
+ * If set, peer memory is mapped into CUDA address space and
+ * ::cuMemPeerGetDevicePointer() may be called on the host pointer.
+ * Flag for ::cuMemPeerRegister()
+ */
+#define CU_MEMPEERREGISTER_DEVICEMAP 0x02
+#endif
+
+#if __CUDA_API_VERSION >= 3020
+
+/**
+ * 2D memory copy parameters
+ */
+typedef struct CUDA_MEMCPY2D_st
+{
+ size_t srcXInBytes; /**< Source X in bytes */
+ size_t srcY; /**< Source Y */
+
+ CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */
+ const void *srcHost; /**< Source host pointer */
+ CUdeviceptr srcDevice; /**< Source device pointer */
+ CUarray srcArray; /**< Source array reference */
+ size_t srcPitch; /**< Source pitch (ignored when src is array) */
+
+ size_t dstXInBytes; /**< Destination X in bytes */
+ size_t dstY; /**< Destination Y */
+
+ CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */
+ void *dstHost; /**< Destination host pointer */
+ CUdeviceptr dstDevice; /**< Destination device pointer */
+ CUarray dstArray; /**< Destination array reference */
+ size_t dstPitch; /**< Destination pitch (ignored when dst is array) */
+
+ size_t WidthInBytes; /**< Width of 2D memory copy in bytes */
+ size_t Height; /**< Height of 2D memory copy */
+} CUDA_MEMCPY2D;
+
+/**
+ * 3D memory copy parameters
+ */
+typedef struct CUDA_MEMCPY3D_st
+{
+ size_t srcXInBytes; /**< Source X in bytes */
+ size_t srcY; /**< Source Y */
+ size_t srcZ; /**< Source Z */
+ size_t srcLOD; /**< Source LOD */
+ CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */
+ const void *srcHost; /**< Source host pointer */
+ CUdeviceptr srcDevice; /**< Source device pointer */
+ CUarray srcArray; /**< Source array reference */
+ void *reserved0; /**< Must be NULL */
+ size_t srcPitch; /**< Source pitch (ignored when src is array) */
+ size_t srcHeight; /**< Source height (ignored when src is array; may be 0 if Depth==1) */
+
+ size_t dstXInBytes; /**< Destination X in bytes */
+ size_t dstY; /**< Destination Y */
+ size_t dstZ; /**< Destination Z */
+ size_t dstLOD; /**< Destination LOD */
+ CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */
+ void *dstHost; /**< Destination host pointer */
+ CUdeviceptr dstDevice; /**< Destination device pointer */
+ CUarray dstArray; /**< Destination array reference */
+ void *reserved1; /**< Must be NULL */
+ size_t dstPitch; /**< Destination pitch (ignored when dst is array) */
+ size_t dstHeight; /**< Destination height (ignored when dst is array; may be 0 if Depth==1) */
+
+ size_t WidthInBytes; /**< Width of 3D memory copy in bytes */
+ size_t Height; /**< Height of 3D memory copy */
+ size_t Depth; /**< Depth of 3D memory copy */
+} CUDA_MEMCPY3D;
+
+/**
+ * 3D memory cross-context copy parameters
+ */
+typedef struct CUDA_MEMCPY3D_PEER_st
+{
+ size_t srcXInBytes; /**< Source X in bytes */
+ size_t srcY; /**< Source Y */
+ size_t srcZ; /**< Source Z */
+ size_t srcLOD; /**< Source LOD */
+ CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */
+ const void *srcHost; /**< Source host pointer */
+ CUdeviceptr srcDevice; /**< Source device pointer */
+ CUarray srcArray; /**< Source array reference */
+ CUcontext srcContext; /**< Source context (ignored with srcMemoryType is ::CU_MEMORYTYPE_ARRAY) */
+ size_t srcPitch; /**< Source pitch (ignored when src is array) */
+ size_t srcHeight; /**< Source height (ignored when src is array; may be 0 if Depth==1) */
+
+ size_t dstXInBytes; /**< Destination X in bytes */
+ size_t dstY; /**< Destination Y */
+ size_t dstZ; /**< Destination Z */
+ size_t dstLOD; /**< Destination LOD */
+ CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */
+ void *dstHost; /**< Destination host pointer */
+ CUdeviceptr dstDevice; /**< Destination device pointer */
+ CUarray dstArray; /**< Destination array reference */
+ CUcontext dstContext; /**< Destination context (ignored with dstMemoryType is ::CU_MEMORYTYPE_ARRAY) */
+ size_t dstPitch; /**< Destination pitch (ignored when dst is array) */
+ size_t dstHeight; /**< Destination height (ignored when dst is array; may be 0 if Depth==1) */
+
+ size_t WidthInBytes; /**< Width of 3D memory copy in bytes */
+ size_t Height; /**< Height of 3D memory copy */
+ size_t Depth; /**< Depth of 3D memory copy */
+} CUDA_MEMCPY3D_PEER;
+
+/**
+ * Array descriptor
+ */
+typedef struct CUDA_ARRAY_DESCRIPTOR_st
+{
+ size_t Width; /**< Width of array */
+ size_t Height; /**< Height of array */
+
+ CUarray_format Format; /**< Array format */
+ unsigned int NumChannels; /**< Channels per array element */
+} CUDA_ARRAY_DESCRIPTOR;
+
+/**
+ * 3D array descriptor
+ */
+typedef struct CUDA_ARRAY3D_DESCRIPTOR_st
+{
+ size_t Width; /**< Width of 3D array */
+ size_t Height; /**< Height of 3D array */
+ size_t Depth; /**< Depth of 3D array */
+
+ CUarray_format Format; /**< Array format */
+ unsigned int NumChannels; /**< Channels per array element */
+ unsigned int Flags; /**< Flags */
+} CUDA_ARRAY3D_DESCRIPTOR;
+
+#endif /* __CUDA_API_VERSION >= 3020 */
+
+/**
+ * If set, the CUDA array is a collection of layers, where each layer is either a 1D
+ * or a 2D array and the Depth member of CUDA_ARRAY3D_DESCRIPTOR specifies the number
+ * of layers, not the depth of a 3D array.
+ */
+#define CUDA_ARRAY3D_LAYERED 0x01
+
+/**
+ * Deprecated, use CUDA_ARRAY3D_LAYERED
+ */
+#define CUDA_ARRAY3D_2DARRAY 0x01
+
+/**
+ * This flag must be set in order to bind a surface reference
+ * to the CUDA array
+ */
+#define CUDA_ARRAY3D_SURFACE_LDST 0x02
+
+/**
+ * Override the texref format with a format inferred from the array.
+ * Flag for ::cuTexRefSetArray()
+ */
+#define CU_TRSA_OVERRIDE_FORMAT 0x01
+
+/**
+ * Read the texture as integers rather than promoting the values to floats
+ * in the range [0,1].
+ * Flag for ::cuTexRefSetFlags()
+ */
+#define CU_TRSF_READ_AS_INTEGER 0x01
+
+/**
+ * Use normalized texture coordinates in the range [0,1) instead of [0,dim).
+ * Flag for ::cuTexRefSetFlags()
+ */
+#define CU_TRSF_NORMALIZED_COORDINATES 0x02
+
+/**
+ * Perform sRGB->linear conversion during texture read.
+ * Flag for ::cuTexRefSetFlags()
+ */
+#define CU_TRSF_SRGB 0x10
+
+/**
+ * End of array terminator for the \p extra parameter to
+ * ::cuLaunchKernel
+ */
+#define CU_LAUNCH_PARAM_END ((void*)0x00)
+
+/**
+ * Indicator that the next value in the \p extra parameter to
+ * ::cuLaunchKernel will be a pointer to a buffer containing all kernel
+ * parameters used for launching kernel \p f. This buffer needs to
+ * honor all alignment/padding requirements of the individual parameters.
+ * If ::CU_LAUNCH_PARAM_BUFFER_SIZE is not also specified in the
+ * \p extra array, then ::CU_LAUNCH_PARAM_BUFFER_POINTER will have no
+ * effect.
+ */
+#define CU_LAUNCH_PARAM_BUFFER_POINTER ((void*)0x01)
+
+/**
+ * Indicator that the next value in the \p extra parameter to
+ * ::cuLaunchKernel will be a pointer to a size_t which contains the
+ * size of the buffer specified with ::CU_LAUNCH_PARAM_BUFFER_POINTER.
+ * It is required that ::CU_LAUNCH_PARAM_BUFFER_POINTER also be specified
+ * in the \p extra array if the value associated with
+ * ::CU_LAUNCH_PARAM_BUFFER_SIZE is not zero.
+ */
+#define CU_LAUNCH_PARAM_BUFFER_SIZE ((void*)0x02)
+
+/**
+ * For texture references loaded into the module, use default texunit from
+ * texture reference.
+ */
+#define CU_PARAM_TR_DEFAULT -1
+
+/**
+ * CUDA API made obselete at API version 3020
+ */
+#if defined(__CUDA_API_VERSION_INTERNAL)
+#define CUdeviceptr CUdeviceptr_v1
+#define CUDA_MEMCPY2D_st CUDA_MEMCPY2D_v1_st
+#define CUDA_MEMCPY2D CUDA_MEMCPY2D_v1
+#define CUDA_MEMCPY3D_st CUDA_MEMCPY3D_v1_st
+#define CUDA_MEMCPY3D CUDA_MEMCPY3D_v1
+#define CUDA_ARRAY_DESCRIPTOR_st CUDA_ARRAY_DESCRIPTOR_v1_st
+#define CUDA_ARRAY_DESCRIPTOR CUDA_ARRAY_DESCRIPTOR_v1
+#define CUDA_ARRAY3D_DESCRIPTOR_st CUDA_ARRAY3D_DESCRIPTOR_v1_st
+#define CUDA_ARRAY3D_DESCRIPTOR CUDA_ARRAY3D_DESCRIPTOR_v1
+#endif /* CUDA_FORCE_LEGACY32_INTERNAL */
+
+#if defined(__CUDA_API_VERSION_INTERNAL) || __CUDA_API_VERSION < 3020
+
+typedef unsigned int CUdeviceptr;
+
+typedef struct CUDA_MEMCPY2D_st
+{
+ unsigned int srcXInBytes; /**< Source X in bytes */
+ unsigned int srcY; /**< Source Y */
+ CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */
+ const void *srcHost; /**< Source host pointer */
+ CUdeviceptr srcDevice; /**< Source device pointer */
+ CUarray srcArray; /**< Source array reference */
+ unsigned int srcPitch; /**< Source pitch (ignored when src is array) */
+
+ unsigned int dstXInBytes; /**< Destination X in bytes */
+ unsigned int dstY; /**< Destination Y */
+ CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */
+ void *dstHost; /**< Destination host pointer */
+ CUdeviceptr dstDevice; /**< Destination device pointer */
+ CUarray dstArray; /**< Destination array reference */
+ unsigned int dstPitch; /**< Destination pitch (ignored when dst is array) */
+
+ unsigned int WidthInBytes; /**< Width of 2D memory copy in bytes */
+ unsigned int Height; /**< Height of 2D memory copy */
+} CUDA_MEMCPY2D;
+
+typedef struct CUDA_MEMCPY3D_st
+{
+ unsigned int srcXInBytes; /**< Source X in bytes */
+ unsigned int srcY; /**< Source Y */
+ unsigned int srcZ; /**< Source Z */
+ unsigned int srcLOD; /**< Source LOD */
+ CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */
+ const void *srcHost; /**< Source host pointer */
+ CUdeviceptr srcDevice; /**< Source device pointer */
+ CUarray srcArray; /**< Source array reference */
+ void *reserved0; /**< Must be NULL */
+ unsigned int srcPitch; /**< Source pitch (ignored when src is array) */
+ unsigned int srcHeight; /**< Source height (ignored when src is array; may be 0 if Depth==1) */
+
+ unsigned int dstXInBytes; /**< Destination X in bytes */
+ unsigned int dstY; /**< Destination Y */
+ unsigned int dstZ; /**< Destination Z */
+ unsigned int dstLOD; /**< Destination LOD */
+ CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */
+ void *dstHost; /**< Destination host pointer */
+ CUdeviceptr dstDevice; /**< Destination device pointer */
+ CUarray dstArray; /**< Destination array reference */
+ void *reserved1; /**< Must be NULL */
+ unsigned int dstPitch; /**< Destination pitch (ignored when dst is array) */
+ unsigned int dstHeight; /**< Destination height (ignored when dst is array; may be 0 if Depth==1) */
+
+ unsigned int WidthInBytes; /**< Width of 3D memory copy in bytes */
+ unsigned int Height; /**< Height of 3D memory copy */
+ unsigned int Depth; /**< Depth of 3D memory copy */
+} CUDA_MEMCPY3D;
+
+typedef struct CUDA_ARRAY_DESCRIPTOR_st
+{
+ unsigned int Width; /**< Width of array */
+ unsigned int Height; /**< Height of array */
+
+ CUarray_format Format; /**< Array format */
+ unsigned int NumChannels; /**< Channels per array element */
+} CUDA_ARRAY_DESCRIPTOR;
+
+typedef struct CUDA_ARRAY3D_DESCRIPTOR_st
+{
+ unsigned int Width; /**< Width of 3D array */
+ unsigned int Height; /**< Height of 3D array */
+ unsigned int Depth; /**< Depth of 3D array */
+
+ CUarray_format Format; /**< Array format */
+ unsigned int NumChannels; /**< Channels per array element */
+ unsigned int Flags; /**< Flags */
+} CUDA_ARRAY3D_DESCRIPTOR;
+
+#endif /* (__CUDA_API_VERSION_INTERNAL) || __CUDA_API_VERSION < 3020 */
+
+/*
+ * If set, the CUDA array contains an array of 2D slices
+ * and the Depth member of CUDA_ARRAY3D_DESCRIPTOR specifies
+ * the number of slices, not the depth of a 3D array.
+ */
+#define CUDA_ARRAY3D_2DARRAY 0x01
+
+/**
+ * This flag must be set in order to bind a surface reference
+ * to the CUDA array
+ */
+#define CUDA_ARRAY3D_SURFACE_LDST 0x02
+
+/**
+ * Override the texref format with a format inferred from the array.
+ * Flag for ::cuTexRefSetArray()
+ */
+#define CU_TRSA_OVERRIDE_FORMAT 0x01
+
+/**
+ * Read the texture as integers rather than promoting the values to floats
+ * in the range [0,1].
+ * Flag for ::cuTexRefSetFlags()
+ */
+#define CU_TRSF_READ_AS_INTEGER 0x01
+
+/**
+ * Use normalized texture coordinates in the range [0,1) instead of [0,dim).
+ * Flag for ::cuTexRefSetFlags()
+ */
+#define CU_TRSF_NORMALIZED_COORDINATES 0x02
+
+/**
+ * Perform sRGB->linear conversion during texture read.
+ * Flag for ::cuTexRefSetFlags()
+ */
+#define CU_TRSF_SRGB 0x10
+
+/**
+ * For texture references loaded into the module, use default texunit from
+ * texture reference.
+ */
+#define CU_PARAM_TR_DEFAULT -1
+
+/** @} */ /* END CUDA_TYPES */
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#define CUDAAPI __stdcall
+#else
+#define CUDAAPI
+#endif
+
+/**
+ * \defgroup CUDA_INITIALIZE Initialization
+ *
+ * This section describes the initialization functions of the low-level CUDA
+ * driver application programming interface.
+ *
+ * @{
+ */
+
+/*********************************
+ ** Initialization
+ *********************************/
+typedef CUresult CUDAAPI tcuInit(unsigned int Flags);
+
+/*********************************
+ ** Driver Version Query
+ *********************************/
+typedef CUresult CUDAAPI tcuDriverGetVersion(int *driverVersion);
+
+/************************************
+ **
+ ** Device management
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuDeviceGet(CUdevice *device, int ordinal);
+typedef CUresult CUDAAPI tcuDeviceGetCount(int *count);
+typedef CUresult CUDAAPI tcuDeviceGetName(char *name, int len, CUdevice dev);
+typedef CUresult CUDAAPI tcuDeviceComputeCapability(int *major, int *minor, CUdevice dev);
+#if __CUDA_API_VERSION >= 3020
+typedef CUresult CUDAAPI tcuDeviceTotalMem(size_t *bytes, CUdevice dev);
+#else
+typedef CUresult CUDAAPI tcuDeviceTotalMem(unsigned int *bytes, CUdevice dev);
+#endif
+
+typedef CUresult CUDAAPI tcuDeviceGetProperties(CUdevprop *prop, CUdevice dev);
+typedef CUresult CUDAAPI tcuDeviceGetAttribute(int *pi, CUdevice_attribute attrib, CUdevice dev);
+
+/************************************
+ **
+ ** Context management
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev);
+typedef CUresult CUDAAPI tcuCtxDestroy(CUcontext ctx);
+typedef CUresult CUDAAPI tcuCtxAttach(CUcontext *pctx, unsigned int flags);
+typedef CUresult CUDAAPI tcuCtxDetach(CUcontext ctx);
+typedef CUresult CUDAAPI tcuCtxPushCurrent(CUcontext ctx);
+typedef CUresult CUDAAPI tcuCtxPopCurrent(CUcontext *pctx);
+
+typedef CUresult CUDAAPI tcuCtxSetCurrent(CUcontext ctx);
+typedef CUresult CUDAAPI tcuCtxGetCurrent(CUcontext *pctx);
+
+typedef CUresult CUDAAPI tcuCtxGetDevice(CUdevice *device);
+typedef CUresult CUDAAPI tcuCtxSynchronize(void);
+
+
+/************************************
+ **
+ ** Module management
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuModuleLoad(CUmodule *module, const char *fname);
+typedef CUresult CUDAAPI tcuModuleLoadData(CUmodule *module, const void *image);
+typedef CUresult CUDAAPI tcuModuleLoadDataEx(CUmodule *module, const void *image, unsigned int numOptions, CUjit_option *options, void **optionValues);
+typedef CUresult CUDAAPI tcuModuleLoadFatBinary(CUmodule *module, const void *fatCubin);
+typedef CUresult CUDAAPI tcuModuleUnload(CUmodule hmod);
+typedef CUresult CUDAAPI tcuModuleGetFunction(CUfunction *hfunc, CUmodule hmod, const char *name);
+
+#if __CUDA_API_VERSION >= 3020
+typedef CUresult CUDAAPI tcuModuleGetGlobal(CUdeviceptr *dptr, size_t *bytes, CUmodule hmod, const char *name);
+#else
+typedef CUresult CUDAAPI tcuModuleGetGlobal(CUdeviceptr *dptr, unsigned int *bytes, CUmodule hmod, const char *name);
+#endif
+
+typedef CUresult CUDAAPI tcuModuleGetTexRef(CUtexref *pTexRef, CUmodule hmod, const char *name);
+typedef CUresult CUDAAPI tcuModuleGetSurfRef(CUsurfref *pSurfRef, CUmodule hmod, const char *name);
+
+/************************************
+ **
+ ** Memory management
+ **
+ ***********************************/
+#if __CUDA_API_VERSION >= 3020
+typedef CUresult CUDAAPI tcuMemGetInfo(size_t *free, size_t *total);
+typedef CUresult CUDAAPI tcuMemAlloc(CUdeviceptr *dptr, size_t bytesize);
+typedef CUresult CUDAAPI tcuMemGetAddressRange(CUdeviceptr *pbase, size_t *psize, CUdeviceptr dptr);
+typedef CUresult CUDAAPI tcuMemAllocPitch(CUdeviceptr *dptr,
+ size_t *pPitch,
+ size_t WidthInBytes,
+ size_t Height,
+ // size of biggest r/w to be performed by kernels on this memory
+ // 4, 8 or 16 bytes
+ unsigned int ElementSizeBytes
+ );
+#else
+typedef CUresult CUDAAPI tcuMemGetInfo(unsigned int *free, unsigned int *total);
+typedef CUresult CUDAAPI tcuMemAlloc(CUdeviceptr *dptr, unsigned int bytesize);
+typedef CUresult CUDAAPI tcuMemGetAddressRange(CUdeviceptr *pbase, unsigned int *psize, CUdeviceptr dptr);
+typedef CUresult CUDAAPI tcuMemAllocPitch(CUdeviceptr *dptr,
+ unsigned int *pPitch,
+ unsigned int WidthInBytes,
+ unsigned int Height,
+ // size of biggest r/w to be performed by kernels on this memory
+ // 4, 8 or 16 bytes
+ unsigned int ElementSizeBytes
+ );
+#endif
+
+typedef CUresult CUDAAPI tcuMemFree(CUdeviceptr dptr);
+
+#if __CUDA_API_VERSION >= 3020
+typedef CUresult CUDAAPI tcuMemAllocHost(void **pp, size_t bytesize);
+#else
+typedef CUresult CUDAAPI tcuMemAllocHost(void **pp, unsigned int bytesize);
+#endif
+
+typedef CUresult CUDAAPI tcuMemFreeHost(void *p);
+typedef CUresult CUDAAPI tcuMemHostAlloc(void **pp, size_t bytesize, unsigned int Flags);
+
+typedef CUresult CUDAAPI tcuMemHostGetDevicePointer(CUdeviceptr *pdptr, void *p, unsigned int Flags);
+typedef CUresult CUDAAPI tcuMemHostGetFlags(unsigned int *pFlags, void *p);
+
+typedef CUresult CUDAAPI tcuMemHostRegister(void *p, size_t bytesize, unsigned int Flags);
+typedef CUresult CUDAAPI tcuMemHostUnregister(void *p);;
+typedef CUresult CUDAAPI tcuMemcpy(CUdeviceptr dst, CUdeviceptr src, size_t ByteCount);
+typedef CUresult CUDAAPI tcuMemcpyPeer(CUdeviceptr dstDevice, CUcontext dstContext, CUdeviceptr srcDevice, CUcontext srcContext, size_t ByteCount);
+
+/************************************
+ **
+ ** Synchronous Memcpy
+ **
+ ** Intra-device memcpy's done with these functions may execute in parallel with the CPU,
+ ** but if host memory is involved, they wait until the copy is done before returning.
+ **
+ ***********************************/
+
+// 1D functions
+#if __CUDA_API_VERSION >= 3020
+// system <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount);
+typedef CUresult CUDAAPI tcuMemcpyDtoH(void *dstHost, CUdeviceptr srcDevice, size_t ByteCount);
+
+// device <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, size_t ByteCount);
+
+// device <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyDtoA(CUarray dstArray, size_t dstOffset, CUdeviceptr srcDevice, size_t ByteCount);
+typedef CUresult CUDAAPI tcuMemcpyAtoD(CUdeviceptr dstDevice, CUarray srcArray, size_t srcOffset, size_t ByteCount);
+
+// system <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyHtoA(CUarray dstArray, size_t dstOffset, const void *srcHost, size_t ByteCount);
+typedef CUresult CUDAAPI tcuMemcpyAtoH(void *dstHost, CUarray srcArray, size_t srcOffset, size_t ByteCount);
+
+// array <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyAtoA(CUarray dstArray, size_t dstOffset, CUarray srcArray, size_t srcOffset, size_t ByteCount);
+#else
+// system <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, unsigned int ByteCount);
+typedef CUresult CUDAAPI tcuMemcpyDtoH(void *dstHost, CUdeviceptr srcDevice, unsigned int ByteCount);
+
+// device <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, unsigned int ByteCount);
+
+// device <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyDtoA(CUarray dstArray, unsigned int dstOffset, CUdeviceptr srcDevice, unsigned int ByteCount);
+typedef CUresult CUDAAPI tcuMemcpyAtoD(CUdeviceptr dstDevice, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount);
+
+// system <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyHtoA(CUarray dstArray, unsigned int dstOffset, const void *srcHost, unsigned int ByteCount);
+typedef CUresult CUDAAPI tcuMemcpyAtoH(void *dstHost, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount);
+
+// array <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyAtoA(CUarray dstArray, unsigned int dstOffset, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount);
+#endif
+
+// 2D memcpy
+
+typedef CUresult CUDAAPI tcuMemcpy2D(const CUDA_MEMCPY2D *pCopy);
+typedef CUresult CUDAAPI tcuMemcpy2DUnaligned(const CUDA_MEMCPY2D *pCopy);
+
+// 3D memcpy
+
+typedef CUresult CUDAAPI tcuMemcpy3D(const CUDA_MEMCPY3D *pCopy);
+
+/************************************
+ **
+ ** Asynchronous Memcpy
+ **
+ ** Any host memory involved must be DMA'able (e.g., allocated with cuMemAllocHost).
+ ** memcpy's done with these functions execute in parallel with the CPU and, if
+ ** the hardware is available, may execute in parallel with the GPU.
+ ** Asynchronous memcpy must be accompanied by appropriate stream synchronization.
+ **
+ ***********************************/
+
+// 1D functions
+#if __CUDA_API_VERSION >= 3020
+// system <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyHtoDAsync(CUdeviceptr dstDevice,
+ const void *srcHost, size_t ByteCount, CUstream hStream);
+typedef CUresult CUDAAPI tcuMemcpyDtoHAsync(void *dstHost,
+ CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream);
+
+// device <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyDtoDAsync(CUdeviceptr dstDevice,
+ CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream);
+
+// system <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyHtoAAsync(CUarray dstArray, size_t dstOffset,
+ const void *srcHost, size_t ByteCount, CUstream hStream);
+typedef CUresult CUDAAPI tcuMemcpyAtoHAsync(void *dstHost, CUarray srcArray, size_t srcOffset,
+ size_t ByteCount, CUstream hStream);
+
+#else
+// system <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyHtoDAsync(CUdeviceptr dstDevice,
+ const void *srcHost, unsigned int ByteCount, CUstream hStream);
+typedef CUresult CUDAAPI tcuMemcpyDtoHAsync(void *dstHost,
+ CUdeviceptr srcDevice, unsigned int ByteCount, CUstream hStream);
+
+// device <-> device memory
+typedef CUresult CUDAAPI tcuMemcpyDtoDAsync(CUdeviceptr dstDevice,
+ CUdeviceptr srcDevice, unsigned int ByteCount, CUstream hStream);
+
+// system <-> array memory
+typedef CUresult CUDAAPI tcuMemcpyHtoAAsync(CUarray dstArray, unsigned int dstOffset,
+ const void *srcHost, unsigned int ByteCount, CUstream hStream);
+typedef CUresult CUDAAPI tcuMemcpyAtoHAsync(void *dstHost, CUarray srcArray, unsigned int srcOffset,
+ unsigned int ByteCount, CUstream hStream);
+#endif
+
+// 2D memcpy
+typedef CUresult CUDAAPI tcuMemcpy2DAsync(const CUDA_MEMCPY2D *pCopy, CUstream hStream);
+
+// 3D memcpy
+typedef CUresult CUDAAPI tcuMemcpy3DAsync(const CUDA_MEMCPY3D *pCopy, CUstream hStream);
+
+/************************************
+ **
+ ** Memset
+ **
+ ***********************************/
+typedef CUresult CUDAAPI tcuMemsetD8(CUdeviceptr dstDevice, unsigned char uc, unsigned int N);
+typedef CUresult CUDAAPI tcuMemsetD16(CUdeviceptr dstDevice, unsigned short us, unsigned int N);
+typedef CUresult CUDAAPI tcuMemsetD32(CUdeviceptr dstDevice, unsigned int ui, unsigned int N);
+
+#if __CUDA_API_VERSION >= 3020
+typedef CUresult CUDAAPI tcuMemsetD2D8(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned char uc, size_t Width, size_t Height);
+typedef CUresult CUDAAPI tcuMemsetD2D16(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned short us, size_t Width, size_t Height);
+typedef CUresult CUDAAPI tcuMemsetD2D32(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int ui, size_t Width, size_t Height);
+#else
+typedef CUresult CUDAAPI tcuMemsetD2D8(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned char uc, unsigned int Width, unsigned int Height);
+typedef CUresult CUDAAPI tcuMemsetD2D16(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned short us, unsigned int Width, unsigned int Height);
+typedef CUresult CUDAAPI tcuMemsetD2D32(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int ui, unsigned int Width, unsigned int Height);
+#endif
+
+/************************************
+ **
+ ** Function management
+ **
+ ***********************************/
+
+
+typedef CUresult CUDAAPI tcuFuncSetBlockShape(CUfunction hfunc, int x, int y, int z);
+typedef CUresult CUDAAPI tcuFuncSetSharedSize(CUfunction hfunc, unsigned int bytes);
+typedef CUresult CUDAAPI tcuFuncGetAttribute(int *pi, CUfunction_attribute attrib, CUfunction hfunc);
+typedef CUresult CUDAAPI tcuFuncSetCacheConfig(CUfunction hfunc, CUfunc_cache config);
+typedef CUresult CUDAAPI tcuLaunchKernel(CUfunction f,
+ unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ,
+ unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ,
+ unsigned int sharedMemBytes,
+ CUstream hStream, void **kernelParams, void **extra);
+
+/************************************
+ **
+ ** Array management
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuArrayCreate(CUarray *pHandle, const CUDA_ARRAY_DESCRIPTOR *pAllocateArray);
+typedef CUresult CUDAAPI tcuArrayGetDescriptor(CUDA_ARRAY_DESCRIPTOR *pArrayDescriptor, CUarray hArray);
+typedef CUresult CUDAAPI tcuArrayDestroy(CUarray hArray);
+
+typedef CUresult CUDAAPI tcuArray3DCreate(CUarray *pHandle, const CUDA_ARRAY3D_DESCRIPTOR *pAllocateArray);
+typedef CUresult CUDAAPI tcuArray3DGetDescriptor(CUDA_ARRAY3D_DESCRIPTOR *pArrayDescriptor, CUarray hArray);
+
+
+/************************************
+ **
+ ** Texture reference management
+ **
+ ***********************************/
+typedef CUresult CUDAAPI tcuTexRefCreate(CUtexref *pTexRef);
+typedef CUresult CUDAAPI tcuTexRefDestroy(CUtexref hTexRef);
+
+typedef CUresult CUDAAPI tcuTexRefSetArray(CUtexref hTexRef, CUarray hArray, unsigned int Flags);
+
+#if __CUDA_API_VERSION >= 3020
+typedef CUresult CUDAAPI tcuTexRefSetAddress(size_t *ByteOffset, CUtexref hTexRef, CUdeviceptr dptr, size_t bytes);
+typedef CUresult CUDAAPI tcuTexRefSetAddress2D(CUtexref hTexRef, const CUDA_ARRAY_DESCRIPTOR *desc, CUdeviceptr dptr, size_t Pitch);
+#else
+typedef CUresult CUDAAPI tcuTexRefSetAddress(unsigned int *ByteOffset, CUtexref hTexRef, CUdeviceptr dptr, unsigned int bytes);
+typedef CUresult CUDAAPI tcuTexRefSetAddress2D(CUtexref hTexRef, const CUDA_ARRAY_DESCRIPTOR *desc, CUdeviceptr dptr, unsigned int Pitch);
+#endif
+
+typedef CUresult CUDAAPI tcuTexRefSetFormat(CUtexref hTexRef, CUarray_format fmt, int NumPackedComponents);
+typedef CUresult CUDAAPI tcuTexRefSetAddressMode(CUtexref hTexRef, int dim, CUaddress_mode am);
+typedef CUresult CUDAAPI tcuTexRefSetFilterMode(CUtexref hTexRef, CUfilter_mode fm);
+typedef CUresult CUDAAPI tcuTexRefSetFlags(CUtexref hTexRef, unsigned int Flags);
+
+typedef CUresult CUDAAPI tcuTexRefGetAddress(CUdeviceptr *pdptr, CUtexref hTexRef);
+typedef CUresult CUDAAPI tcuTexRefGetArray(CUarray *phArray, CUtexref hTexRef);
+typedef CUresult CUDAAPI tcuTexRefGetAddressMode(CUaddress_mode *pam, CUtexref hTexRef, int dim);
+typedef CUresult CUDAAPI tcuTexRefGetFilterMode(CUfilter_mode *pfm, CUtexref hTexRef);
+typedef CUresult CUDAAPI tcuTexRefGetFormat(CUarray_format *pFormat, int *pNumChannels, CUtexref hTexRef);
+typedef CUresult CUDAAPI tcuTexRefGetFlags(unsigned int *pFlags, CUtexref hTexRef);
+
+/************************************
+ **
+ ** Surface reference management
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuSurfRefSetArray(CUsurfref hSurfRef, CUarray hArray, unsigned int Flags);
+typedef CUresult CUDAAPI tcuSurfRefGetArray(CUarray *phArray, CUsurfref hSurfRef);
+
+/************************************
+ **
+ ** Parameter management
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuParamSetSize(CUfunction hfunc, unsigned int numbytes);
+typedef CUresult CUDAAPI tcuParamSeti(CUfunction hfunc, int offset, unsigned int value);
+typedef CUresult CUDAAPI tcuParamSetf(CUfunction hfunc, int offset, float value);
+typedef CUresult CUDAAPI tcuParamSetv(CUfunction hfunc, int offset, void *ptr, unsigned int numbytes);
+typedef CUresult CUDAAPI tcuParamSetTexRef(CUfunction hfunc, int texunit, CUtexref hTexRef);
+
+
+/************************************
+ **
+ ** Launch functions
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuLaunch(CUfunction f);
+typedef CUresult CUDAAPI tcuLaunchGrid(CUfunction f, int grid_width, int grid_height);
+typedef CUresult CUDAAPI tcuLaunchGridAsync(CUfunction f, int grid_width, int grid_height, CUstream hStream);
+
+/************************************
+ **
+ ** Events
+ **
+ ***********************************/
+typedef CUresult CUDAAPI tcuEventCreate(CUevent *phEvent, unsigned int Flags);
+typedef CUresult CUDAAPI tcuEventRecord(CUevent hEvent, CUstream hStream);
+typedef CUresult CUDAAPI tcuEventQuery(CUevent hEvent);
+typedef CUresult CUDAAPI tcuEventSynchronize(CUevent hEvent);
+typedef CUresult CUDAAPI tcuEventDestroy(CUevent hEvent);
+typedef CUresult CUDAAPI tcuEventElapsedTime(float *pMilliseconds, CUevent hStart, CUevent hEnd);
+
+/************************************
+ **
+ ** Streams
+ **
+ ***********************************/
+typedef CUresult CUDAAPI tcuStreamCreate(CUstream *phStream, unsigned int Flags);
+typedef CUresult CUDAAPI tcuStreamQuery(CUstream hStream);
+typedef CUresult CUDAAPI tcuStreamSynchronize(CUstream hStream);
+typedef CUresult CUDAAPI tcuStreamDestroy(CUstream hStream);
+
+/************************************
+ **
+ ** Graphics interop
+ **
+ ***********************************/
+typedef CUresult CUDAAPI tcuGraphicsUnregisterResource(CUgraphicsResource resource);
+typedef CUresult CUDAAPI tcuGraphicsSubResourceGetMappedArray(CUarray *pArray, CUgraphicsResource resource, unsigned int arrayIndex, unsigned int mipLevel);
+
+#if __CUDA_API_VERSION >= 3020
+typedef CUresult CUDAAPI tcuGraphicsResourceGetMappedPointer(CUdeviceptr *pDevPtr, size_t *pSize, CUgraphicsResource resource);
+#else
+typedef CUresult CUDAAPI tcuGraphicsResourceGetMappedPointer(CUdeviceptr *pDevPtr, unsigned int *pSize, CUgraphicsResource resource);
+#endif
+
+typedef CUresult CUDAAPI tcuGraphicsResourceSetMapFlags(CUgraphicsResource resource, unsigned int flags);
+typedef CUresult CUDAAPI tcuGraphicsMapResources(unsigned int count, CUgraphicsResource *resources, CUstream hStream);
+typedef CUresult CUDAAPI tcuGraphicsUnmapResources(unsigned int count, CUgraphicsResource *resources, CUstream hStream);
+
+/************************************
+ **
+ ** Export tables
+ **
+ ***********************************/
+typedef CUresult CUDAAPI tcuGetExportTable(const void **ppExportTable, const CUuuid *pExportTableId);
+
+/************************************
+ **
+ ** Limits
+ **
+ ***********************************/
+
+typedef CUresult CUDAAPI tcuCtxSetLimit(CUlimit limit, size_t value);
+typedef CUresult CUDAAPI tcuCtxGetLimit(size_t *pvalue, CUlimit limit);
+
+
+/************************************
+ ************************************/
+
+extern CUresult CUDAAPI cuInit(unsigned int, int cudaVersion);
+
+extern tcuDriverGetVersion *cuDriverGetVersion;
+extern tcuDeviceGet *cuDeviceGet;
+extern tcuDeviceGetCount *cuDeviceGetCount;
+extern tcuDeviceGetName *cuDeviceGetName;
+extern tcuDeviceComputeCapability *cuDeviceComputeCapability;
+extern tcuDeviceGetProperties *cuDeviceGetProperties;
+extern tcuDeviceGetAttribute *cuDeviceGetAttribute;
+extern tcuCtxDestroy *cuCtxDestroy;
+extern tcuCtxAttach *cuCtxAttach;
+extern tcuCtxDetach *cuCtxDetach;
+extern tcuCtxPushCurrent *cuCtxPushCurrent;
+extern tcuCtxPopCurrent *cuCtxPopCurrent;
+
+extern tcuCtxSetCurrent *cuCtxSetCurrent;
+extern tcuCtxGetCurrent *cuCtxGetCurrent;
+
+extern tcuCtxGetDevice *cuCtxGetDevice;
+extern tcuCtxSynchronize *cuCtxSynchronize;
+extern tcuModuleLoad *cuModuleLoad;
+extern tcuModuleLoadData *cuModuleLoadData;
+extern tcuModuleLoadDataEx *cuModuleLoadDataEx;
+extern tcuModuleLoadFatBinary *cuModuleLoadFatBinary;
+extern tcuModuleUnload *cuModuleUnload;
+extern tcuModuleGetFunction *cuModuleGetFunction;
+extern tcuModuleGetTexRef *cuModuleGetTexRef;
+extern tcuModuleGetSurfRef *cuModuleGetSurfRef;
+extern tcuMemFreeHost *cuMemFreeHost;
+extern tcuMemHostAlloc *cuMemHostAlloc;
+extern tcuMemHostGetFlags *cuMemHostGetFlags;
+
+extern tcuMemHostRegister *cuMemHostRegister;
+extern tcuMemHostUnregister *cuMemHostUnregister;
+extern tcuMemcpy *cuMemcpy;
+extern tcuMemcpyPeer *cuMemcpyPeer;
+
+extern tcuDeviceTotalMem *cuDeviceTotalMem;
+extern tcuCtxCreate *cuCtxCreate;
+extern tcuModuleGetGlobal *cuModuleGetGlobal;
+extern tcuMemGetInfo *cuMemGetInfo;
+extern tcuMemAlloc *cuMemAlloc;
+extern tcuMemAllocPitch *cuMemAllocPitch;
+extern tcuMemFree *cuMemFree;
+extern tcuMemGetAddressRange *cuMemGetAddressRange;
+extern tcuMemAllocHost *cuMemAllocHost;
+extern tcuMemHostGetDevicePointer *cuMemHostGetDevicePointer;
+extern tcuFuncSetBlockShape *cuFuncSetBlockShape;
+extern tcuFuncSetSharedSize *cuFuncSetSharedSize;
+extern tcuFuncGetAttribute *cuFuncGetAttribute;
+extern tcuFuncSetCacheConfig *cuFuncSetCacheConfig;
+extern tcuLaunchKernel *cuLaunchKernel;
+extern tcuArrayDestroy *cuArrayDestroy;
+extern tcuTexRefCreate *cuTexRefCreate;
+extern tcuTexRefDestroy *cuTexRefDestroy;
+extern tcuTexRefSetArray *cuTexRefSetArray;
+extern tcuTexRefSetFormat *cuTexRefSetFormat;
+extern tcuTexRefSetAddressMode *cuTexRefSetAddressMode;
+extern tcuTexRefSetFilterMode *cuTexRefSetFilterMode;
+extern tcuTexRefSetFlags *cuTexRefSetFlags;
+extern tcuTexRefGetArray *cuTexRefGetArray;
+extern tcuTexRefGetAddressMode *cuTexRefGetAddressMode;
+extern tcuTexRefGetFilterMode *cuTexRefGetFilterMode;
+extern tcuTexRefGetFormat *cuTexRefGetFormat;
+extern tcuTexRefGetFlags *cuTexRefGetFlags;
+extern tcuSurfRefSetArray *cuSurfRefSetArray;
+extern tcuSurfRefGetArray *cuSurfRefGetArray;
+extern tcuParamSetSize *cuParamSetSize;
+extern tcuParamSeti *cuParamSeti;
+extern tcuParamSetf *cuParamSetf;
+extern tcuParamSetv *cuParamSetv;
+extern tcuParamSetTexRef *cuParamSetTexRef;
+extern tcuLaunch *cuLaunch;
+extern tcuLaunchGrid *cuLaunchGrid;
+extern tcuLaunchGridAsync *cuLaunchGridAsync;
+extern tcuEventCreate *cuEventCreate;
+extern tcuEventRecord *cuEventRecord;
+extern tcuEventQuery *cuEventQuery;
+extern tcuEventSynchronize *cuEventSynchronize;
+extern tcuEventDestroy *cuEventDestroy;
+extern tcuEventElapsedTime *cuEventElapsedTime;
+extern tcuStreamCreate *cuStreamCreate;
+extern tcuStreamQuery *cuStreamQuery;
+extern tcuStreamSynchronize *cuStreamSynchronize;
+extern tcuStreamDestroy *cuStreamDestroy;
+extern tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource;
+extern tcuGraphicsSubResourceGetMappedArray *cuGraphicsSubResourceGetMappedArray;
+extern tcuGraphicsResourceSetMapFlags *cuGraphicsResourceSetMapFlags;
+extern tcuGraphicsMapResources *cuGraphicsMapResources;
+extern tcuGraphicsUnmapResources *cuGraphicsUnmapResources;
+extern tcuGetExportTable *cuGetExportTable;
+extern tcuCtxSetLimit *cuCtxSetLimit;
+extern tcuCtxGetLimit *cuCtxGetLimit;
+
+// These functions could be using the CUDA 3.2 interface (_v2)
+extern tcuMemcpyHtoD *cuMemcpyHtoD;
+extern tcuMemcpyDtoH *cuMemcpyDtoH;
+extern tcuMemcpyDtoD *cuMemcpyDtoD;
+extern tcuMemcpyDtoA *cuMemcpyDtoA;
+extern tcuMemcpyAtoD *cuMemcpyAtoD;
+extern tcuMemcpyHtoA *cuMemcpyHtoA;
+extern tcuMemcpyAtoH *cuMemcpyAtoH;
+extern tcuMemcpyAtoA *cuMemcpyAtoA;
+extern tcuMemcpy2D *cuMemcpy2D;
+extern tcuMemcpy2DUnaligned *cuMemcpy2DUnaligned;
+extern tcuMemcpy3D *cuMemcpy3D;
+extern tcuMemcpyHtoDAsync *cuMemcpyHtoDAsync;
+extern tcuMemcpyDtoHAsync *cuMemcpyDtoHAsync;
+extern tcuMemcpyDtoDAsync *cuMemcpyDtoDAsync;
+extern tcuMemcpyHtoAAsync *cuMemcpyHtoAAsync;
+extern tcuMemcpyAtoHAsync *cuMemcpyAtoHAsync;
+extern tcuMemcpy2DAsync *cuMemcpy2DAsync;
+extern tcuMemcpy3DAsync *cuMemcpy3DAsync;
+extern tcuMemsetD8 *cuMemsetD8;
+extern tcuMemsetD16 *cuMemsetD16;
+extern tcuMemsetD32 *cuMemsetD32;
+extern tcuMemsetD2D8 *cuMemsetD2D8;
+extern tcuMemsetD2D16 *cuMemsetD2D16;
+extern tcuMemsetD2D32 *cuMemsetD2D32;
+extern tcuArrayCreate *cuArrayCreate;
+extern tcuArrayGetDescriptor *cuArrayGetDescriptor;
+extern tcuArray3DCreate *cuArray3DCreate;
+extern tcuArray3DGetDescriptor *cuArray3DGetDescriptor;
+extern tcuTexRefSetAddress *cuTexRefSetAddress;
+extern tcuTexRefSetAddress2D *cuTexRefSetAddress2D;
+extern tcuTexRefGetAddress *cuTexRefGetAddress;
+extern tcuGraphicsResourceGetMappedPointer *cuGraphicsResourceGetMappedPointer;
+
+#ifdef __cplusplus
+}
+#endif
+
+//#undef __CUDA_API_VERSION
+
+#endif //__cuda_drvapi_dynlink_cuda_h__
diff --git a/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_d3d.h b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_d3d.h
new file mode 100644
index 000000000..f533c517e
--- /dev/null
+++ b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_d3d.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef __cuda_drvapi_dynlink_d3d_h__
+#define __cuda_drvapi_dynlink_d3d_h__
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#pragma warning(disable: 4312)
+
+#if defined (CUDA_INIT_D3D9) || defined(CUDA_INIT_D3D10) || defined(CUDA_INIT_D3D11)
+#include <Windows.h>
+#include <mmsystem.h>
+#endif
+
+#ifdef CUDA_INIT_D3D9
+#include <d3dx9.h>
+#pragma warning( disable : 4996 ) // disable deprecated warning
+#include <strsafe.h>
+#pragma warning( default : 4996 )
+
+/**
+ * CUDA 2.x compatibility - Flags to register a D3D9 graphics resource
+ */
+typedef enum CUd3d9register_flags_enum
+{
+ CU_D3D9_REGISTER_FLAGS_NONE = 0x00,
+ CU_D3D9_REGISTER_FLAGS_ARRAY = 0x01,
+} CUd3d9register_flags;
+
+/**
+ * CUDA 2.x compatibility - Flags for D3D9 mapping and unmapping interop resources
+ */
+typedef enum CUd3d9map_flags_enum
+{
+ CU_D3D9_MAPRESOURCE_FLAGS_NONE = 0x00,
+ CU_D3D9_MAPRESOURCE_FLAGS_READONLY = 0x01,
+ CU_D3D9_MAPRESOURCE_FLAGS_WRITEDISCARD = 0x02,
+} CUd3d9map_flags;
+
+// D3D9/CUDA interop (CUDA 1.x compatible API). These functions are deprecated, please use the ones below
+typedef CUresult CUDAAPI tcuD3D9Begin(IDirect3DDevice9 *pDevice);
+typedef CUresult CUDAAPI tcuD3D9End(void);
+typedef CUresult CUDAAPI tcuD3D9RegisterVertexBuffer(IDirect3DVertexBuffer9 *pVB);
+typedef CUresult CUDAAPI tcuD3D9MapVertexBuffer(CUdeviceptr *pDevPtr, unsigned int *pSize, IDirect3DVertexBuffer9 *pVB);
+typedef CUresult CUDAAPI tcuD3D9UnmapVertexBuffer(IDirect3DVertexBuffer9 *pVB);
+typedef CUresult CUDAAPI tcuD3D9UnregisterVertexBuffer(IDirect3DVertexBuffer9 *pVB);
+
+// D3D9/CUDA interop (CUDA 2.x compatible)
+typedef CUresult CUDAAPI tcuD3D9GetDirect3DDevice(IDirect3DDevice9 **ppD3DDevice);
+typedef CUresult CUDAAPI tcuD3D9RegisterResource(IDirect3DResource9 *pResource, unsigned int Flags);
+typedef CUresult CUDAAPI tcuD3D9UnregisterResource(IDirect3DResource9 *pResource);
+
+typedef CUresult CUDAAPI tcuD3D9MapResources(unsigned int count, IDirect3DResource9 **ppResource);
+typedef CUresult CUDAAPI tcuD3D9UnmapResources(unsigned int count, IDirect3DResource9 **ppResource);
+typedef CUresult CUDAAPI tcuD3D9ResourceSetMapFlags(IDirect3DResource9 *pResource, unsigned int Flags);
+
+typedef CUresult CUDAAPI tcuD3D9ResourceGetSurfaceDimensions(unsigned int *pWidth, unsigned int *pHeight, unsigned int *pDepth, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level);
+typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedArray(CUarray *pArray, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level);
+typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedPointer(CUdeviceptr *pDevPtr, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level);
+typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedSize(unsigned int *pSize, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level);
+typedef CUresult CUDAAPI tcuD3D9ResourceGetMappedPitch(unsigned int *pPitch, unsigned int *pPitchSlice, IDirect3DResource9 *pResource, unsigned int Face, unsigned int Level);
+
+// D3D9/CUDA interop (CUDA 2.0+)
+typedef CUresult CUDAAPI tcuD3D9GetDevice(CUdevice *pCudaDevice, const char *pszAdapterName);
+typedef CUresult CUDAAPI tcuD3D9CtxCreate(CUcontext *pCtx, CUdevice *pCudaDevice, unsigned int Flags, IDirect3DDevice9 *pD3DDevice);
+typedef CUresult CUDAAPI tcuGraphicsD3D9RegisterResource(CUgraphicsResource *pCudaResource, IDirect3DResource9 *pD3DResource, unsigned int Flags);
+#endif
+
+#ifdef CUDA_INIT_D3D10
+#include <dxgi.h>
+#include <d3d10_1.h>
+#include <d3d10.h>
+#include <d3dx10.h>
+
+#pragma warning( disable : 4996 ) // disable deprecated warning
+#include <strsafe.h>
+#pragma warning( default : 4996 )
+
+// D3D11/CUDA interop (CUDA 3.0)
+typedef CUresult CUDAAPI tcuD3D10GetDevice(CUdevice *pCudaDevice, IDXGIAdapter *pAdapter);
+typedef CUresult CUDAAPI tcuD3D10CtxCreate(CUcontext *pCtx, CUdevice *pCudaDevice, unsigned int Flags, ID3D10Device *pD3DDevice);
+typedef CUresult CUDAAPI tcuGraphicsD3D10RegisterResource(CUgraphicsResource *pCudaResource, ID3D10Resource *pD3DResource, unsigned int Flags);
+#endif // CUDA_INIT_D3D10
+
+#ifdef CUDA_INIT_D3D11
+#include <dxgi.h>
+#include <d3d11.h>
+#include <d3dx11.h>
+
+#pragma warning( disable : 4996 ) // disable deprecated warning
+#include <strsafe.h>
+#pragma warning( default : 4996 )
+
+// D3D11/CUDA interop (CUDA 3.0)
+typedef CUresult CUDAAPI tcuD3D11GetDevice(CUdevice *pCudaDevice, IDXGIAdapter *pAdapter);
+typedef CUresult CUDAAPI tcuD3D11CtxCreate(CUcontext *pCtx, CUdevice *pCudaDevice, unsigned int Flags, ID3D11Device *pD3DDevice);
+typedef CUresult CUDAAPI tcuGraphicsD3D11RegisterResource(CUgraphicsResource *pCudaResource, ID3D11Resource *pD3DResource, unsigned int Flags);
+#endif // CUDA_INIT_D3D11
+
+#endif // WIN32
+
+#endif // __cuda_drvapi_dynlink_cuda_d3d_h__
diff --git a/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_gl.h b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_gl.h
new file mode 100644
index 000000000..6b711c2bd
--- /dev/null
+++ b/tests/projects/cuda_console/inc/dynlink/cuda_drvapi_dynlink_gl.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef __cuda_drvapi_dynlink_cuda_gl_h__
+#define __cuda_drvapi_dynlink_cuda_gl_h__
+
+#ifdef CUDA_INIT_OPENGL
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+# define WINDOWS_LEAN_AND_MEAN
+# define NOMINMAX
+# include <windows.h>
+#endif
+
+// includes, system
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+// includes, GL
+#include <GL/glew.h>
+
+#if defined (__APPLE__) || defined(MACOSX)
+#include <GLUT/glut.h>
+#else
+#include <GL/freeglut.h>
+#endif
+
+/************************************
+ **
+ ** OpenGL Graphics/Interop
+ **
+ ***********************************/
+
+// OpenGL/CUDA interop (CUDA 2.0+)
+typedef CUresult CUDAAPI tcuGLCtxCreate(CUcontext *pCtx, unsigned int Flags, CUdevice device);
+typedef CUresult CUDAAPI tcuGraphicsGLRegisterBuffer(CUgraphicsResource *pCudaResource, GLuint buffer, unsigned int Flags);
+typedef CUresult CUDAAPI tcuGraphicsGLRegisterImage(CUgraphicsResource *pCudaResource, GLuint image, GLenum target, unsigned int Flags);
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#include <GL/wglext.h>
+// WIN32
+typedef CUresult CUDAAPI tcuWGLGetDevice(CUdevice *pDevice, HGPUNV hGpu);
+#endif
+
+#endif // CUDA_INIT_OPENGL
+
+#endif // __cuda_drvapi_dynlink_cuda_gl_h__
+
diff --git a/tests/projects/cuda_console/inc/dynlink_d3d10.h b/tests/projects/cuda_console/inc/dynlink_d3d10.h
new file mode 100644
index 000000000..83adb5d9c
--- /dev/null
+++ b/tests/projects/cuda_console/inc/dynlink_d3d10.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+//--------------------------------------------------------------------------------------
+// File: dynlink_d3d10.h
+//
+// Shortcut macros and functions for using DX objects
+//
+// Copyright (c) Microsoft Corporation. All rights reserved
+//--------------------------------------------------------------------------------------
+
+#ifndef _DYNLINK_D3D10_H_
+#define _DYNLINK_D3D10_H_
+
+// Standard Windows includes
+#include <windows.h>
+#include <initguid.h>
+#include <assert.h>
+#include <wchar.h>
+#include <mmsystem.h>
+#include <commctrl.h> // for InitCommonControls()
+#include <shellapi.h> // for ExtractIcon()
+#include <new.h> // for placement new
+#include <shlobj.h>
+#include <math.h>
+#include <limits.h>
+#include <stdio.h>
+
+// CRT's memory leak detection
+#if defined(DEBUG) || defined(_DEBUG)
+#include <crtdbg.h>
+#endif
+
+// Direct3D9 includes
+#include <d3d9.h>
+#include <d3dx9.h>
+
+// Direct3D10 includes
+#include <dxgi.h>
+#include <d3d10_1.h>
+#include <d3d10.h>
+#include <d3dx10.h>
+
+// XInput includes
+#include <xinput.h>
+
+// HRESULT translation for Direct3D10 and other APIs
+#include <dxerr.h>
+
+// strsafe.h deprecates old unsecure string functions. If you
+// really do not want to it to (not recommended), then uncomment the next line
+//#define STRSAFE_NO_DEPRECATE
+
+#ifndef STRSAFE_NO_DEPRECATE
+#pragma deprecated("strncpy")
+#pragma deprecated("wcsncpy")
+#pragma deprecated("_tcsncpy")
+#pragma deprecated("wcsncat")
+#pragma deprecated("strncat")
+#pragma deprecated("_tcsncat")
+#endif
+
+#pragma warning( disable : 4996 ) // disable deprecated warning
+#include <strsafe.h>
+#pragma warning( default : 4996 )
+
+//--------------------------------------------------------------------------------------
+// Structs
+//--------------------------------------------------------------------------------------
+struct DXUTD3D9DeviceSettings
+{
+ UINT AdapterOrdinal;
+ D3DDEVTYPE DeviceType;
+ D3DFORMAT AdapterFormat;
+ DWORD BehaviorFlags;
+ D3DPRESENT_PARAMETERS pp;
+};
+
+struct DXUTD3D10DeviceSettings
+{
+ UINT AdapterOrdinal;
+ D3D10_DRIVER_TYPE DriverType;
+ UINT Output;
+ DXGI_SWAP_CHAIN_DESC sd;
+ UINT32 CreateFlags;
+ UINT32 SyncInterval;
+ DWORD PresentFlags;
+ bool AutoCreateDepthStencil; // DXUT will create the a depth stencil resource and view if true
+ DXGI_FORMAT AutoDepthStencilFormat;
+};
+
+enum DXUTDeviceVersion { DXUT_D3D9_DEVICE, DXUT_D3D10_DEVICE };
+struct DXUTDeviceSettings
+{
+ DXUTDeviceVersion ver;
+ union
+ {
+ DXUTD3D9DeviceSettings d3d9; // only valid if ver == DXUT_D3D9_DEVICE
+ DXUTD3D10DeviceSettings d3d10; // only valid if ver == DXUT_D3D10_DEVICE
+ };
+};
+
+
+//--------------------------------------------------------------------------------------
+// Error codes
+//--------------------------------------------------------------------------------------
+#define DXUTERR_NODIRECT3D MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0901)
+#define DXUTERR_NOCOMPATIBLEDEVICES MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0902)
+#define DXUTERR_MEDIANOTFOUND MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0903)
+#define DXUTERR_NONZEROREFCOUNT MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0904)
+#define DXUTERR_CREATINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0905)
+#define DXUTERR_RESETTINGDEVICE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0906)
+#define DXUTERR_CREATINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0907)
+#define DXUTERR_RESETTINGDEVICEOBJECTS MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x0908)
+#define DXUTERR_DEVICEREMOVED MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x090A)
+
+
+typedef HRESULT(WINAPI *LPCREATEDXGIFACTORY)(REFIID, void **);
+typedef HRESULT(WINAPI *LPD3D10CREATEDEVICE)(IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, UINT, UINT32,
+ ID3D10Device **);
+typedef HRESULT(WINAPI *LPD3D10CREATEDEVICE1)(IDXGIAdapter *, D3D10_DRIVER_TYPE, HMODULE, UINT,
+ D3D10_FEATURE_LEVEL1, UINT, ID3D10Device1 **);
+typedef HRESULT(WINAPI *LPD3D10CREATESTATEBLOCK)(ID3D10Device *pDevice, D3D10_STATE_BLOCK_MASK *pStateBlockMask,
+ ID3D10StateBlock **ppStateBlock);
+typedef HRESULT(WINAPI *LPD3D10STATEBLOCKMASKUNION)(D3D10_STATE_BLOCK_MASK *pA, D3D10_STATE_BLOCK_MASK *pB,
+ D3D10_STATE_BLOCK_MASK *pResult);
+typedef HRESULT(WINAPI *LPD3D10STATEBLOCKMASKINTERSECT)(D3D10_STATE_BLOCK_MASK *pA, D3D10_STATE_BLOCK_MASK *pB,
+ D3D10_STATE_BLOCK_MASK *pResult);
+typedef HRESULT(WINAPI *LPD3D10STATEBLOCKMASKDIFFERENCE)(D3D10_STATE_BLOCK_MASK *pA, D3D10_STATE_BLOCK_MASK *pB,
+ D3D10_STATE_BLOCK_MASK *pResult);
+typedef HRESULT(WINAPI *LPD3D10STATEBLOCKMASKENABLECAPTURE)(D3D10_STATE_BLOCK_MASK *pMask,
+ D3D10_DEVICE_STATE_TYPES StateType, UINT RangeStart,
+ UINT RangeLength);
+typedef HRESULT(WINAPI *LPD3D10STATEBLOCKMASKDISABLECAPTURE)(D3D10_STATE_BLOCK_MASK *pMask,
+ D3D10_DEVICE_STATE_TYPES StateType, UINT RangeStart,
+ UINT RangeLength);
+typedef HRESULT(WINAPI *LPD3D10STATEBLOCKMASKENABLEALL)(D3D10_STATE_BLOCK_MASK *pMask);
+typedef HRESULT(WINAPI *LPD3D10STATEBLOCKMASKDISABLEALL)(D3D10_STATE_BLOCK_MASK *pMask);
+typedef BOOL (WINAPI *LPD3D10STATEBLOCKMASKGETSETTING)(D3D10_STATE_BLOCK_MASK *pMask,
+ D3D10_DEVICE_STATE_TYPES StateType, UINT Entry);
+
+typedef HRESULT(WINAPI *LPD3D10COMPILEEFFECTFROMMEMORY)(void *pData, SIZE_T DataLength, LPCSTR pSrcFileName,
+ CONST D3D10_SHADER_MACRO *pDefines,
+ ID3D10Include *pInclude, UINT HLSLFlags, UINT FXFlags,
+ ID3D10Blob **ppCompiledEffect, ID3D10Blob **ppErrors);
+typedef HRESULT(WINAPI *LPD3D10CREATEEFFECTFROMMEMORY)(void *pData, SIZE_T DataLength, UINT FXFlags,
+ ID3D10Device *pDevice,
+ ID3D10EffectPool *pEffectPool,
+ ID3D10Effect **ppEffect);
+typedef HRESULT(WINAPI *LPD3D10CREATEEFFECTPOOLFROMMEMORY)(void *pData, SIZE_T DataLength, UINT FXFlags,
+ ID3D10Device *pDevice, ID3D10EffectPool **ppEffectPool);
+
+typedef HRESULT(WINAPI *LPD3D10CREATEDEVICEANDSWAPCHAIN)(IDXGIAdapter *pAdapter,
+ D3D10_DRIVER_TYPE DriverType,
+ HMODULE Software,
+ UINT Flags,
+ UINT SDKVersion,
+ DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
+ IDXGISwapChain **ppSwapChain,
+ ID3D10Device **ppDevice);
+
+typedef HRESULT(WINAPI *LPD3D10CREATEDEVICEANDSWAPCHAIN1)(IDXGIAdapter *pAdapter,
+ D3D10_DRIVER_TYPE DriverType,
+ HMODULE Software,
+ UINT Flags,
+ D3D10_FEATURE_LEVEL1 HardwareLevel,
+ UINT SDKVersion,
+ DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,
+ IDXGISwapChain **ppSwapChain,
+ ID3D10Device1 **ppDevice);
+
+// Build a perspective projection matrix. (left-handed)
+typedef D3DXMATRIX *(WINAPI *LPD3DXMATRIXPERSPECTIVEFOVLH)(D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf);
+
+// Build a lookat matrix. (left-handed)
+typedef D3DXMATRIX *(WINAPI *LPD3DXMATRIXLOOKATLH)(D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, CONST D3DXVECTOR3 *pUp);
+
+// Module and function pointers
+static HMODULE g_hModDXGI = NULL;
+static HMODULE g_hModD3DX10 = NULL;
+static HMODULE g_hModD3D10 = NULL;
+static HMODULE g_hModD3D101 = NULL;
+static LPCREATEDXGIFACTORY sFnPtr_CreateDXGIFactory = NULL;
+static LPD3D10CREATESTATEBLOCK sFnPtr_D3D10CreateStateBlock = NULL;
+static LPD3D10CREATEDEVICE sFnPtr_D3D10CreateDevice = NULL;
+static LPD3D10CREATEDEVICE1 sFnPtr_D3D10CreateDevice1 = NULL;
+static LPD3D10STATEBLOCKMASKUNION sFnPtr_D3D10StateBlockMaskUnion = NULL;
+static LPD3D10STATEBLOCKMASKINTERSECT sFnPtr_D3D10StateBlockMaskIntersect = NULL;
+static LPD3D10STATEBLOCKMASKDIFFERENCE sFnPtr_D3D10StateBlockMaskDifference = NULL;
+static LPD3D10STATEBLOCKMASKENABLECAPTURE sFnPtr_D3D10StateBlockMaskEnableCapture = NULL;
+static LPD3D10STATEBLOCKMASKDISABLECAPTURE sFnPtr_D3D10StateBlockMaskDisableCapture = NULL;
+static LPD3D10STATEBLOCKMASKENABLEALL sFnPtr_D3D10StateBlockMaskEnableAll = NULL;
+static LPD3D10STATEBLOCKMASKDISABLEALL sFnPtr_D3D10StateBlockMaskDisableAll = NULL;
+static LPD3D10STATEBLOCKMASKGETSETTING sFnPtr_D3D10StateBlockMaskGetSetting = NULL;
+static LPD3D10COMPILEEFFECTFROMMEMORY sFnPtr_D3D10CompileEffectFromMemory = NULL;
+static LPD3D10CREATEEFFECTFROMMEMORY sFnPtr_D3D10CreateEffectFromMemory = NULL;
+static LPD3D10CREATEEFFECTPOOLFROMMEMORY sFnPtr_D3D10CreateEffectPoolFromMemory = NULL;
+static LPD3D10CREATEDEVICEANDSWAPCHAIN sFnPtr_D3D10CreateDeviceAndSwapChain = NULL;
+static LPD3D10CREATEDEVICEANDSWAPCHAIN1 sFnPtr_D3D10CreateDeviceAndSwapChain1 = NULL;
+static LPD3DXMATRIXPERSPECTIVEFOVLH sFnPtr_D3DXMatrixPerspectiveFovLH = NULL;
+static LPD3DXMATRIXLOOKATLH sFnPtr_D3DXMatrixLookAtLH = NULL;
+
+// unload the D3D10 DLLs
+static bool dynlinkUnloadD3D10API(void)
+{
+ if (g_hModD3D10)
+ {
+ FreeLibrary(g_hModD3D10);
+ g_hModD3D10 = NULL;
+ }
+
+ if (g_hModD3DX10)
+ {
+ FreeLibrary(g_hModD3DX10);
+ g_hModD3DX10 = NULL;
+ }
+
+ if (g_hModDXGI)
+ {
+ FreeLibrary(g_hModDXGI);
+ g_hModDXGI = NULL;
+ }
+
+ if (g_hModD3D101)
+ {
+ FreeLibrary(g_hModD3D101);
+ g_hModD3D101 = NULL;
+ }
+
+ return true;
+}
+
+// Dynamically load the D3D10 DLLs loaded and map the function pointers
+static bool dynlinkLoadD3D10API(void)
+{
+ // First check to see if the D3D10 Library is present.
+ // if it succeeds, then we can call GetProcAddress to grab all of the DX10 functions
+ g_hModD3D10 = LoadLibrary("d3d10.dll");
+
+ if (g_hModD3D10 != NULL)
+ {
+ sFnPtr_D3D10CreateStateBlock = (LPD3D10CREATESTATEBLOCK) GetProcAddress(g_hModD3D10, "D3D10CreateStateBlock");
+ sFnPtr_D3D10CreateDevice = (LPD3D10CREATEDEVICE) GetProcAddress(g_hModD3D10, "D3D10CreateDevice");
+
+ sFnPtr_D3D10StateBlockMaskUnion = (LPD3D10STATEBLOCKMASKUNION) GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskUnion");
+ sFnPtr_D3D10StateBlockMaskIntersect = (LPD3D10STATEBLOCKMASKINTERSECT) GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskIntersect");
+ sFnPtr_D3D10StateBlockMaskDifference = (LPD3D10STATEBLOCKMASKDIFFERENCE) GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskDifference");
+ sFnPtr_D3D10StateBlockMaskEnableCapture = (LPD3D10STATEBLOCKMASKENABLECAPTURE) GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskEnableCapture");
+ sFnPtr_D3D10StateBlockMaskDisableCapture = (LPD3D10STATEBLOCKMASKDISABLECAPTURE)GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskDisableCapture");
+
+ sFnPtr_D3D10StateBlockMaskEnableAll = (LPD3D10STATEBLOCKMASKENABLEALL) GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskEnableAll");
+ sFnPtr_D3D10StateBlockMaskDisableAll = (LPD3D10STATEBLOCKMASKDISABLEALL) GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskDisableAll");
+ sFnPtr_D3D10StateBlockMaskGetSetting = (LPD3D10STATEBLOCKMASKGETSETTING) GetProcAddress(g_hModD3D10, "D3D10StateBlockMaskGetSetting");
+
+ sFnPtr_D3D10CompileEffectFromMemory = (LPD3D10COMPILEEFFECTFROMMEMORY) GetProcAddress(g_hModD3D10, "D3D10CompileEffectFromMemory");
+ sFnPtr_D3D10CreateEffectFromMemory = (LPD3D10CREATEEFFECTFROMMEMORY) GetProcAddress(g_hModD3D10, "D3D10CreateEffectFromMemory");
+ sFnPtr_D3D10CreateEffectPoolFromMemory = (LPD3D10CREATEEFFECTPOOLFROMMEMORY) GetProcAddress(g_hModD3D10, "D3D10CreateEffectPoolFromMemory");
+
+ sFnPtr_D3D10CreateDeviceAndSwapChain = (LPD3D10CREATEDEVICEANDSWAPCHAIN) GetProcAddress(g_hModD3D10, "D3D10CreateDeviceAndSwapChain");
+ }
+
+ g_hModD3DX10 = LoadLibrary("d3dx10.dll");
+
+ if (g_hModD3DX10)
+ {
+ sFnPtr_D3DXMatrixPerspectiveFovLH = (LPD3DXMATRIXPERSPECTIVEFOVLH) GetProcAddress(g_hModD3DX10, "D3DXMatrixPerspectiveFovLH");
+ sFnPtr_D3DXMatrixLookAtLH = (LPD3DXMATRIXLOOKATLH) GetProcAddress(g_hModD3DX10, "D3DXMatrixLookAtLH");
+ }
+
+ g_hModDXGI = LoadLibrary("dxgi.dll");
+
+ if (g_hModDXGI)
+ {
+ sFnPtr_CreateDXGIFactory = (LPCREATEDXGIFACTORY) GetProcAddress(g_hModDXGI , "CreateDXGIFactory");
+ }
+
+ // This may fail if this machine isn't Windows Vista SP1 or later
+ g_hModD3D101 = LoadLibrary("d3d10_1.dll");
+
+ if (g_hModD3D101 != NULL)
+ {
+ sFnPtr_D3D10CreateDevice1 = (LPD3D10CREATEDEVICE1) GetProcAddress(g_hModD3D101, "D3D10CreateDevice1");
+ sFnPtr_D3D10CreateDeviceAndSwapChain1 = (LPD3D10CREATEDEVICEANDSWAPCHAIN1) GetProcAddress(g_hModD3D101, "D3D10CreateDeviceAndSwapChain1");
+ }
+
+ if (g_hModD3D10 == NULL || g_hModD3DX10 == NULL || g_hModDXGI == NULL || g_hModD3D101 == NULL)
+ {
+ dynlinkUnloadD3D10API();
+ return false;
+ }
+
+ return true;
+}
+
+#endif
diff --git a/tests/projects/cuda_console/inc/dynlink_d3d11.h b/tests/projects/cuda_console/inc/dynlink_d3d11.h
new file mode 100644
index 000000000..cf1b4654a
--- /dev/null
+++ b/tests/projects/cuda_console/inc/dynlink_d3d11.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+//--------------------------------------------------------------------------------------
+// File: dynlink_d3d11.h
+//
+// Shortcut macros and functions for using DX objects
+//
+// Copyright (c) Microsoft Corporation. All rights reserved
+//--------------------------------------------------------------------------------------
+
+#ifndef _DYNLINK_D3D11_H_
+#define _DYNLINK_D3D11_H_
+
+// Standard Windows includes
+#include <windows.h>
+#include <initguid.h>
+#include <assert.h>
+#include <wchar.h>
+#include <mmsystem.h>
+#include <commctrl.h> // for InitCommonControls()
+#include <shellapi.h> // for ExtractIcon()
+#include <new.h> // for placement new
+#include <shlobj.h>
+#include <math.h>
+#include <limits.h>
+#include <stdio.h>
+
+// CRT's memory leak detection
+#if defined(DEBUG) || defined(_DEBUG)
+#include <crtdbg.h>
+#endif
+
+// Direct3D9 includes
+//#include <d3d9.h>
+//#include <d3dx9.h>
+
+// Direct3D10 includes
+#include <dxgi.h>
+#include <d3d11.h>
+#include <d3dx11.h>
+// #include <..\Samples\C++\Effects11\Inc\d3dx11effect.h>
+
+// XInput includes
+#include <xinput.h>
+
+// HRESULT translation for Direct3D10 and other APIs
+#include <dxerr.h>
+
+// strsafe.h deprecates old unsecure string functions. If you
+// really do not want to it to (not recommended), then uncomment the next line
+//#define STRSAFE_NO_DEPRECATE
+
+#ifndef STRSAFE_NO_DEPRECATE
+#pragma deprecated("strncpy")
+#pragma deprecated("wcsncpy")
+#pragma deprecated("_tcsncpy")
+#pragma deprecated("wcsncat")
+#pragma deprecated("strncat")
+#pragma deprecated("_tcsncat")
+#endif
+
+#pragma warning( disable : 4996 ) // disable deprecated warning
+#include <strsafe.h>
+#pragma warning( default : 4996 )
+
+typedef HRESULT(WINAPI *LPCREATEDXGIFACTORY)(REFIID, void **);
+typedef HRESULT(WINAPI *LPD3D11CREATEDEVICEANDSWAPCHAIN)(__in_opt IDXGIAdapter *pAdapter, D3D_DRIVER_TYPE DriverType, HMODULE Software, UINT Flags, __in_ecount_opt(FeatureLevels) CONST D3D_FEATURE_LEVEL *pFeatureLevels, UINT FeatureLevels, UINT SDKVersion, __in_opt CONST DXGI_SWAP_CHAIN_DESC *pSwapChainDesc, __out_opt IDXGISwapChain **ppSwapChain, __out_opt ID3D11Device **ppDevice, __out_opt D3D_FEATURE_LEVEL *pFeatureLevel, __out_opt ID3D11DeviceContext **ppImmediateContext);
+typedef HRESULT(WINAPI *LPD3D11CREATEDEVICE)(IDXGIAdapter *, D3D_DRIVER_TYPE, HMODULE, UINT32, D3D_FEATURE_LEVEL *, UINT, UINT32, ID3D11Device **, D3D_FEATURE_LEVEL *, ID3D11DeviceContext **);
+typedef void (WINAPI *LPD3DX11COMPILEFROMMEMORY)(LPCSTR pSrcData, SIZE_T SrcDataLen, LPCSTR pFileName, CONST D3D10_SHADER_MACRO *pDefines, LPD3D10INCLUDE pInclude,
+ LPCSTR pFunctionName, LPCSTR pProfile, UINT Flags1, UINT Flags2, ID3DX11ThreadPump *pPump, ID3D10Blob **ppShader, ID3D10Blob **ppErrorMsgs, HRESULT *pHResult);
+
+static HMODULE s_hModDXGI = NULL;
+static LPCREATEDXGIFACTORY sFnPtr_CreateDXGIFactory = NULL;
+static HMODULE s_hModD3D11 = NULL;
+static HMODULE s_hModD3DX11 = NULL;
+static LPD3D11CREATEDEVICE sFnPtr_D3D11CreateDevice = NULL;
+static LPD3D11CREATEDEVICEANDSWAPCHAIN sFnPtr_D3D11CreateDeviceAndSwapChain = NULL;
+static LPD3DX11COMPILEFROMMEMORY sFnPtr_D3DX11CompileFromMemory = NULL;
+
+// unload the D3D10 DLLs
+static bool dynlinkUnloadD3D11API(void)
+{
+ if (s_hModDXGI)
+ {
+ FreeLibrary(s_hModDXGI);
+ s_hModDXGI = NULL;
+ }
+
+ if (s_hModD3D11)
+ {
+ FreeLibrary(s_hModD3D11);
+ s_hModD3D11 = NULL;
+ }
+
+ if (s_hModD3DX11)
+ {
+ FreeLibrary(s_hModD3DX11);
+ s_hModD3DX11 = NULL;
+ }
+
+ return true;
+}
+
+// Dynamically load the D3D11 DLLs loaded and map the function pointers
+static bool dynlinkLoadD3D11API(void)
+{
+ // If both modules are non-NULL, this function has already been called. Note
+ // that this doesn't guarantee that all ProcAddresses were found.
+ if (s_hModD3D11 != NULL && s_hModD3DX11 != NULL && s_hModDXGI != NULL)
+ {
+ return true;
+ }
+
+#if 1
+ // This may fail if Direct3D 11 isn't installed
+ s_hModD3D11 = LoadLibrary("d3d11.dll");
+
+ if (s_hModD3D11 != NULL)
+ {
+ sFnPtr_D3D11CreateDevice = (LPD3D11CREATEDEVICE)GetProcAddress(s_hModD3D11, "D3D11CreateDevice");
+ sFnPtr_D3D11CreateDeviceAndSwapChain = (LPD3D11CREATEDEVICEANDSWAPCHAIN)GetProcAddress(s_hModD3D11, "D3D11CreateDeviceAndSwapChain");
+ }
+
+ // first try to load D3DX11CompileFromMemory from DirectX 2010 June
+ s_hModD3DX11 = LoadLibrary("D3DX11d_43.dll");
+
+ if (s_hModD3DX11 != NULL)
+ {
+ sFnPtr_D3DX11CompileFromMemory = (LPD3DX11COMPILEFROMMEMORY) GetProcAddress(s_hModD3DX11, "D3DX11CompileFromMemory");
+ }
+ else // if absent try to take it from DirectX 2010 Feb
+ {
+ s_hModD3DX11 = LoadLibrary("D3DX11d_42.dll");
+
+ if (s_hModD3DX11 != NULL)
+ {
+ sFnPtr_D3DX11CompileFromMemory = (LPD3DX11COMPILEFROMMEMORY) GetProcAddress(s_hModD3DX11, "D3DX11CompileFromMemory");
+ }
+ }
+
+ if (!sFnPtr_CreateDXGIFactory)
+ {
+ s_hModDXGI = LoadLibrary("dxgi.dll");
+
+ if (s_hModDXGI)
+ {
+ sFnPtr_CreateDXGIFactory = (LPCREATEDXGIFACTORY)GetProcAddress(s_hModDXGI, "CreateDXGIFactory1");
+ }
+
+ return (s_hModDXGI != NULL) && (s_hModD3D11 != NULL);
+ }
+
+ return (s_hModD3D11 != NULL);
+#else
+ sFnPtr_D3D11CreateDevice = (LPD3D11CREATEDEVICE)D3D11CreateDeviceAndSwapChain;
+ sFnPtr_D3D11CreateDeviceAndSwapChain = (LPD3D11CREATEDEVICEANDSWAPCHAIN)D3D11CreateDeviceAndSwapChain;
+ //sFnPtr_D3DX11CreateEffectFromMemory = ( LPD3DX11CREATEEFFECTFROMMEMORY )D3DX11CreateEffectFromMemory;
+ sFnPtr_D3DX11CompileFromMemory = (LPD3DX11COMPILEFROMMEMORY)D3DX11CompileFromMemory;
+ sFnPtr_CreateDXGIFactory = (LPCREATEDXGIFACTORY)CreateDXGIFactory;
+ return true;
+#endif
+ return true;
+}
+
+#endif
diff --git a/tests/projects/cuda_console/inc/exception.h b/tests/projects/cuda_console/inc/exception.h
new file mode 100644
index 000000000..adda4bce6
--- /dev/null
+++ b/tests/projects/cuda_console/inc/exception.h
@@ -0,0 +1,151 @@
+/*
+* Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+*
+* Please refer to the NVIDIA end user license agreement (EULA) associated
+* with this source code for terms and conditions that govern your use of
+* this software. Any use, reproduction, disclosure, or distribution of
+* this software and related documentation outside the terms of the EULA
+* is strictly prohibited.
+*
+*/
+
+/* CUda UTility Library */
+#ifndef _EXCEPTION_H_
+#define _EXCEPTION_H_
+
+// includes, system
+#include <exception>
+#include <stdexcept>
+#include <iostream>
+#include <stdlib.h>
+
+//! Exception wrapper.
+//! @param Std_Exception Exception out of namespace std for easy typing.
+template<class Std_Exception>
+class Exception : public Std_Exception
+{
+ public:
+
+ //! @brief Static construction interface
+ //! @return Alwayss throws ( Located_Exception<Exception>)
+ //! @param file file in which the Exception occurs
+ //! @param line line in which the Exception occurs
+ //! @param detailed details on the code fragment causing the Exception
+ static void throw_it(const char *file,
+ const int line,
+ const char *detailed = "-");
+
+ //! Static construction interface
+ //! @return Alwayss throws ( Located_Exception<Exception>)
+ //! @param file file in which the Exception occurs
+ //! @param line line in which the Exception occurs
+ //! @param detailed details on the code fragment causing the Exception
+ static void throw_it(const char *file,
+ const int line,
+ const std::string &detailed);
+
+ //! Destructor
+ virtual ~Exception() throw();
+
+ private:
+
+ //! Constructor, default (private)
+ Exception();
+
+ //! Constructor, standard
+ //! @param str string returned by what()
+ Exception(const std::string &str);
+
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//! Exception handler function for arbitrary exceptions
+//! @param ex exception to handle
+////////////////////////////////////////////////////////////////////////////////
+template<class Exception_Typ>
+inline void
+handleException(const Exception_Typ &ex)
+{
+ std::cerr << ex.what() << std::endl;
+
+ exit(EXIT_FAILURE);
+}
+
+//! Convenience macros
+
+//! Exception caused by dynamic program behavior, e.g. file does not exist
+#define RUNTIME_EXCEPTION( msg) \
+ Exception<std::runtime_error>::throw_it( __FILE__, __LINE__, msg)
+
+//! Logic exception in program, e.g. an assert failed
+#define LOGIC_EXCEPTION( msg) \
+ Exception<std::logic_error>::throw_it( __FILE__, __LINE__, msg)
+
+//! Out of range exception
+#define RANGE_EXCEPTION( msg) \
+ Exception<std::range_error>::throw_it( __FILE__, __LINE__, msg)
+
+////////////////////////////////////////////////////////////////////////////////
+//! Implementation
+
+// includes, system
+#include <sstream>
+
+////////////////////////////////////////////////////////////////////////////////
+//! Static construction interface.
+//! @param Exception causing code fragment (file and line) and detailed infos.
+////////////////////////////////////////////////////////////////////////////////
+/*static*/ template<class Std_Exception>
+void
+Exception<Std_Exception>::
+throw_it(const char *file, const int line, const char *detailed)
+{
+ std::stringstream s;
+
+ // Quiet heavy-weight but exceptions are not for
+ // performance / release versions
+ s << "Exception in file '" << file << "' in line " << line << "\n"
+ << "Detailed description: " << detailed << "\n";
+
+ throw Exception(s.str());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Static construction interface.
+//! @param Exception causing code fragment (file and line) and detailed infos.
+////////////////////////////////////////////////////////////////////////////////
+/*static*/ template<class Std_Exception>
+void
+Exception<Std_Exception>::
+throw_it(const char *file, const int line, const std::string &msg)
+{
+ throw_it(file, line, msg.c_str());
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Constructor, default (private).
+////////////////////////////////////////////////////////////////////////////////
+template<class Std_Exception>
+Exception<Std_Exception>::Exception() :
+ Std_Exception("Unknown Exception.\n")
+{ }
+
+////////////////////////////////////////////////////////////////////////////////
+//! Constructor, standard (private).
+//! String returned by what().
+////////////////////////////////////////////////////////////////////////////////
+template<class Std_Exception>
+Exception<Std_Exception>::Exception(const std::string &s) :
+ Std_Exception(s)
+{ }
+
+////////////////////////////////////////////////////////////////////////////////
+//! Destructor
+////////////////////////////////////////////////////////////////////////////////
+template<class Std_Exception>
+Exception<Std_Exception>::~Exception() throw() { }
+
+// functions, exported
+
+#endif // #ifndef _EXCEPTION_H_
+
diff --git a/tests/projects/cuda_console/inc/helper_cuda.h b/tests/projects/cuda_console/inc/helper_cuda.h
new file mode 100644
index 000000000..75e3eb242
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_cuda.h
@@ -0,0 +1,1356 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+////////////////////////////////////////////////////////////////////////////////
+// These are CUDA Helper functions for initialization and error checking
+
+#ifndef HELPER_CUDA_H
+#define HELPER_CUDA_H
+
+#pragma once
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <helper_string.h>
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+// Note, it is required that your SDK sample to include the proper header files, please
+// refer the CUDA examples for examples of the needed CUDA headers, which may change depending
+// on which CUDA functions are used.
+
+// CUDA Runtime error messages
+#ifdef __DRIVER_TYPES_H__
+static const char *_cudaGetErrorEnum(cudaError_t error)
+{
+ switch (error)
+ {
+ case cudaSuccess:
+ return "cudaSuccess";
+
+ case cudaErrorMissingConfiguration:
+ return "cudaErrorMissingConfiguration";
+
+ case cudaErrorMemoryAllocation:
+ return "cudaErrorMemoryAllocation";
+
+ case cudaErrorInitializationError:
+ return "cudaErrorInitializationError";
+
+ case cudaErrorLaunchFailure:
+ return "cudaErrorLaunchFailure";
+
+ case cudaErrorPriorLaunchFailure:
+ return "cudaErrorPriorLaunchFailure";
+
+ case cudaErrorLaunchTimeout:
+ return "cudaErrorLaunchTimeout";
+
+ case cudaErrorLaunchOutOfResources:
+ return "cudaErrorLaunchOutOfResources";
+
+ case cudaErrorInvalidDeviceFunction:
+ return "cudaErrorInvalidDeviceFunction";
+
+ case cudaErrorInvalidConfiguration:
+ return "cudaErrorInvalidConfiguration";
+
+ case cudaErrorInvalidDevice:
+ return "cudaErrorInvalidDevice";
+
+ case cudaErrorInvalidValue:
+ return "cudaErrorInvalidValue";
+
+ case cudaErrorInvalidPitchValue:
+ return "cudaErrorInvalidPitchValue";
+
+ case cudaErrorInvalidSymbol:
+ return "cudaErrorInvalidSymbol";
+
+ case cudaErrorMapBufferObjectFailed:
+ return "cudaErrorMapBufferObjectFailed";
+
+ case cudaErrorUnmapBufferObjectFailed:
+ return "cudaErrorUnmapBufferObjectFailed";
+
+ case cudaErrorInvalidHostPointer:
+ return "cudaErrorInvalidHostPointer";
+
+ case cudaErrorInvalidDevicePointer:
+ return "cudaErrorInvalidDevicePointer";
+
+ case cudaErrorInvalidTexture:
+ return "cudaErrorInvalidTexture";
+
+ case cudaErrorInvalidTextureBinding:
+ return "cudaErrorInvalidTextureBinding";
+
+ case cudaErrorInvalidChannelDescriptor:
+ return "cudaErrorInvalidChannelDescriptor";
+
+ case cudaErrorInvalidMemcpyDirection:
+ return "cudaErrorInvalidMemcpyDirection";
+
+ case cudaErrorAddressOfConstant:
+ return "cudaErrorAddressOfConstant";
+
+ case cudaErrorTextureFetchFailed:
+ return "cudaErrorTextureFetchFailed";
+
+ case cudaErrorTextureNotBound:
+ return "cudaErrorTextureNotBound";
+
+ case cudaErrorSynchronizationError:
+ return "cudaErrorSynchronizationError";
+
+ case cudaErrorInvalidFilterSetting:
+ return "cudaErrorInvalidFilterSetting";
+
+ case cudaErrorInvalidNormSetting:
+ return "cudaErrorInvalidNormSetting";
+
+ case cudaErrorMixedDeviceExecution:
+ return "cudaErrorMixedDeviceExecution";
+
+ case cudaErrorCudartUnloading:
+ return "cudaErrorCudartUnloading";
+
+ case cudaErrorUnknown:
+ return "cudaErrorUnknown";
+
+ case cudaErrorNotYetImplemented:
+ return "cudaErrorNotYetImplemented";
+
+ case cudaErrorMemoryValueTooLarge:
+ return "cudaErrorMemoryValueTooLarge";
+
+ case cudaErrorInvalidResourceHandle:
+ return "cudaErrorInvalidResourceHandle";
+
+ case cudaErrorNotReady:
+ return "cudaErrorNotReady";
+
+ case cudaErrorInsufficientDriver:
+ return "cudaErrorInsufficientDriver";
+
+ case cudaErrorSetOnActiveProcess:
+ return "cudaErrorSetOnActiveProcess";
+
+ case cudaErrorInvalidSurface:
+ return "cudaErrorInvalidSurface";
+
+ case cudaErrorNoDevice:
+ return "cudaErrorNoDevice";
+
+ case cudaErrorECCUncorrectable:
+ return "cudaErrorECCUncorrectable";
+
+ case cudaErrorSharedObjectSymbolNotFound:
+ return "cudaErrorSharedObjectSymbolNotFound";
+
+ case cudaErrorSharedObjectInitFailed:
+ return "cudaErrorSharedObjectInitFailed";
+
+ case cudaErrorUnsupportedLimit:
+ return "cudaErrorUnsupportedLimit";
+
+ case cudaErrorDuplicateVariableName:
+ return "cudaErrorDuplicateVariableName";
+
+ case cudaErrorDuplicateTextureName:
+ return "cudaErrorDuplicateTextureName";
+
+ case cudaErrorDuplicateSurfaceName:
+ return "cudaErrorDuplicateSurfaceName";
+
+ case cudaErrorDevicesUnavailable:
+ return "cudaErrorDevicesUnavailable";
+
+ case cudaErrorInvalidKernelImage:
+ return "cudaErrorInvalidKernelImage";
+
+ case cudaErrorNoKernelImageForDevice:
+ return "cudaErrorNoKernelImageForDevice";
+
+ case cudaErrorIncompatibleDriverContext:
+ return "cudaErrorIncompatibleDriverContext";
+
+ case cudaErrorPeerAccessAlreadyEnabled:
+ return "cudaErrorPeerAccessAlreadyEnabled";
+
+ case cudaErrorPeerAccessNotEnabled:
+ return "cudaErrorPeerAccessNotEnabled";
+
+ case cudaErrorDeviceAlreadyInUse:
+ return "cudaErrorDeviceAlreadyInUse";
+
+ case cudaErrorProfilerDisabled:
+ return "cudaErrorProfilerDisabled";
+
+ case cudaErrorProfilerNotInitialized:
+ return "cudaErrorProfilerNotInitialized";
+
+ case cudaErrorProfilerAlreadyStarted:
+ return "cudaErrorProfilerAlreadyStarted";
+
+ case cudaErrorProfilerAlreadyStopped:
+ return "cudaErrorProfilerAlreadyStopped";
+
+ /* Since CUDA 4.0*/
+ case cudaErrorAssert:
+ return "cudaErrorAssert";
+
+ case cudaErrorTooManyPeers:
+ return "cudaErrorTooManyPeers";
+
+ case cudaErrorHostMemoryAlreadyRegistered:
+ return "cudaErrorHostMemoryAlreadyRegistered";
+
+ case cudaErrorHostMemoryNotRegistered:
+ return "cudaErrorHostMemoryNotRegistered";
+
+ /* Since CUDA 5.0 */
+ case cudaErrorOperatingSystem:
+ return "cudaErrorOperatingSystem";
+
+ case cudaErrorPeerAccessUnsupported:
+ return "cudaErrorPeerAccessUnsupported";
+
+ case cudaErrorLaunchMaxDepthExceeded:
+ return "cudaErrorLaunchMaxDepthExceeded";
+
+ case cudaErrorLaunchFileScopedTex:
+ return "cudaErrorLaunchFileScopedTex";
+
+ case cudaErrorLaunchFileScopedSurf:
+ return "cudaErrorLaunchFileScopedSurf";
+
+ case cudaErrorSyncDepthExceeded:
+ return "cudaErrorSyncDepthExceeded";
+
+ case cudaErrorLaunchPendingCountExceeded:
+ return "cudaErrorLaunchPendingCountExceeded";
+
+ case cudaErrorNotPermitted:
+ return "cudaErrorNotPermitted";
+
+ case cudaErrorNotSupported:
+ return "cudaErrorNotSupported";
+
+ /* Since CUDA 6.0 */
+ case cudaErrorHardwareStackError:
+ return "cudaErrorHardwareStackError";
+
+ case cudaErrorIllegalInstruction:
+ return "cudaErrorIllegalInstruction";
+
+ case cudaErrorMisalignedAddress:
+ return "cudaErrorMisalignedAddress";
+
+ case cudaErrorInvalidAddressSpace:
+ return "cudaErrorInvalidAddressSpace";
+
+ case cudaErrorInvalidPc:
+ return "cudaErrorInvalidPc";
+
+ case cudaErrorIllegalAddress:
+ return "cudaErrorIllegalAddress";
+
+ /* Since CUDA 6.5*/
+ case cudaErrorInvalidPtx:
+ return "cudaErrorInvalidPtx";
+
+ case cudaErrorInvalidGraphicsContext:
+ return "cudaErrorInvalidGraphicsContext";
+
+ case cudaErrorStartupFailure:
+ return "cudaErrorStartupFailure";
+
+ case cudaErrorApiFailureBase:
+ return "cudaErrorApiFailureBase";
+
+ /* Since CUDA 8.0*/
+ case cudaErrorNvlinkUncorrectable :
+ return "cudaErrorNvlinkUncorrectable";
+
+ /* Since CUDA 8.5*/
+ case cudaErrorJitCompilerNotFound :
+ return "cudaErrorJitCompilerNotFound";
+
+ /* Since CUDA 9.0*/
+ case cudaErrorCooperativeLaunchTooLarge :
+ return "cudaErrorCooperativeLaunchTooLarge";
+
+ }
+
+ return "<unknown>";
+}
+#endif
+
+#ifdef __cuda_cuda_h__
+// CUDA Driver API errors
+static const char *_cudaGetErrorEnum(CUresult error)
+{
+ switch (error)
+ {
+ case CUDA_SUCCESS:
+ return "CUDA_SUCCESS";
+
+ case CUDA_ERROR_INVALID_VALUE:
+ return "CUDA_ERROR_INVALID_VALUE";
+
+ case CUDA_ERROR_OUT_OF_MEMORY:
+ return "CUDA_ERROR_OUT_OF_MEMORY";
+
+ case CUDA_ERROR_NOT_INITIALIZED:
+ return "CUDA_ERROR_NOT_INITIALIZED";
+
+ case CUDA_ERROR_DEINITIALIZED:
+ return "CUDA_ERROR_DEINITIALIZED";
+
+ case CUDA_ERROR_PROFILER_DISABLED:
+ return "CUDA_ERROR_PROFILER_DISABLED";
+
+ case CUDA_ERROR_PROFILER_NOT_INITIALIZED:
+ return "CUDA_ERROR_PROFILER_NOT_INITIALIZED";
+
+ case CUDA_ERROR_PROFILER_ALREADY_STARTED:
+ return "CUDA_ERROR_PROFILER_ALREADY_STARTED";
+
+ case CUDA_ERROR_PROFILER_ALREADY_STOPPED:
+ return "CUDA_ERROR_PROFILER_ALREADY_STOPPED";
+
+ case CUDA_ERROR_NO_DEVICE:
+ return "CUDA_ERROR_NO_DEVICE";
+
+ case CUDA_ERROR_INVALID_DEVICE:
+ return "CUDA_ERROR_INVALID_DEVICE";
+
+ case CUDA_ERROR_INVALID_IMAGE:
+ return "CUDA_ERROR_INVALID_IMAGE";
+
+ case CUDA_ERROR_INVALID_CONTEXT:
+ return "CUDA_ERROR_INVALID_CONTEXT";
+
+ case CUDA_ERROR_CONTEXT_ALREADY_CURRENT:
+ return "CUDA_ERROR_CONTEXT_ALREADY_CURRENT";
+
+ case CUDA_ERROR_MAP_FAILED:
+ return "CUDA_ERROR_MAP_FAILED";
+
+ case CUDA_ERROR_UNMAP_FAILED:
+ return "CUDA_ERROR_UNMAP_FAILED";
+
+ case CUDA_ERROR_ARRAY_IS_MAPPED:
+ return "CUDA_ERROR_ARRAY_IS_MAPPED";
+
+ case CUDA_ERROR_ALREADY_MAPPED:
+ return "CUDA_ERROR_ALREADY_MAPPED";
+
+ case CUDA_ERROR_NO_BINARY_FOR_GPU:
+ return "CUDA_ERROR_NO_BINARY_FOR_GPU";
+
+ case CUDA_ERROR_ALREADY_ACQUIRED:
+ return "CUDA_ERROR_ALREADY_ACQUIRED";
+
+ case CUDA_ERROR_NOT_MAPPED:
+ return "CUDA_ERROR_NOT_MAPPED";
+
+ case CUDA_ERROR_NOT_MAPPED_AS_ARRAY:
+ return "CUDA_ERROR_NOT_MAPPED_AS_ARRAY";
+
+ case CUDA_ERROR_NOT_MAPPED_AS_POINTER:
+ return "CUDA_ERROR_NOT_MAPPED_AS_POINTER";
+
+ case CUDA_ERROR_ECC_UNCORRECTABLE:
+ return "CUDA_ERROR_ECC_UNCORRECTABLE";
+
+ case CUDA_ERROR_UNSUPPORTED_LIMIT:
+ return "CUDA_ERROR_UNSUPPORTED_LIMIT";
+
+ case CUDA_ERROR_CONTEXT_ALREADY_IN_USE:
+ return "CUDA_ERROR_CONTEXT_ALREADY_IN_USE";
+
+ case CUDA_ERROR_PEER_ACCESS_UNSUPPORTED:
+ return "CUDA_ERROR_PEER_ACCESS_UNSUPPORTED";
+
+ case CUDA_ERROR_INVALID_PTX:
+ return "CUDA_ERROR_INVALID_PTX";
+
+ case CUDA_ERROR_INVALID_GRAPHICS_CONTEXT:
+ return "CUDA_ERROR_INVALID_GRAPHICS_CONTEXT";
+
+ case CUDA_ERROR_NVLINK_UNCORRECTABLE:
+ return "CUDA_ERROR_NVLINK_UNCORRECTABLE";
+
+ case CUDA_ERROR_JIT_COMPILER_NOT_FOUND:
+ return "CUDA_ERROR_JIT_COMPILER_NOT_FOUND";
+
+ case CUDA_ERROR_INVALID_SOURCE:
+ return "CUDA_ERROR_INVALID_SOURCE";
+
+ case CUDA_ERROR_FILE_NOT_FOUND:
+ return "CUDA_ERROR_FILE_NOT_FOUND";
+
+ case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND:
+ return "CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND";
+
+ case CUDA_ERROR_SHARED_OBJECT_INIT_FAILED:
+ return "CUDA_ERROR_SHARED_OBJECT_INIT_FAILED";
+
+ case CUDA_ERROR_OPERATING_SYSTEM:
+ return "CUDA_ERROR_OPERATING_SYSTEM";
+
+ case CUDA_ERROR_INVALID_HANDLE:
+ return "CUDA_ERROR_INVALID_HANDLE";
+
+ case CUDA_ERROR_NOT_FOUND:
+ return "CUDA_ERROR_NOT_FOUND";
+
+ case CUDA_ERROR_NOT_READY:
+ return "CUDA_ERROR_NOT_READY";
+
+ case CUDA_ERROR_ILLEGAL_ADDRESS:
+ return "CUDA_ERROR_ILLEGAL_ADDRESS";
+
+ case CUDA_ERROR_LAUNCH_FAILED:
+ return "CUDA_ERROR_LAUNCH_FAILED";
+
+ case CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES:
+ return "CUDA_ERROR_LAUNCH_OUT_OF_RESOURCES";
+
+ case CUDA_ERROR_LAUNCH_TIMEOUT:
+ return "CUDA_ERROR_LAUNCH_TIMEOUT";
+
+ case CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING:
+ return "CUDA_ERROR_LAUNCH_INCOMPATIBLE_TEXTURING";
+
+ case CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED:
+ return "CUDA_ERROR_PEER_ACCESS_ALREADY_ENABLED";
+
+ case CUDA_ERROR_PEER_ACCESS_NOT_ENABLED:
+ return "CUDA_ERROR_PEER_ACCESS_NOT_ENABLED";
+
+ case CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE:
+ return "CUDA_ERROR_PRIMARY_CONTEXT_ACTIVE";
+
+ case CUDA_ERROR_CONTEXT_IS_DESTROYED:
+ return "CUDA_ERROR_CONTEXT_IS_DESTROYED";
+
+ case CUDA_ERROR_ASSERT:
+ return "CUDA_ERROR_ASSERT";
+
+ case CUDA_ERROR_TOO_MANY_PEERS:
+ return "CUDA_ERROR_TOO_MANY_PEERS";
+
+ case CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED:
+ return "CUDA_ERROR_HOST_MEMORY_ALREADY_REGISTERED";
+
+ case CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED:
+ return "CUDA_ERROR_HOST_MEMORY_NOT_REGISTERED";
+
+ case CUDA_ERROR_HARDWARE_STACK_ERROR:
+ return "CUDA_ERROR_HARDWARE_STACK_ERROR";
+
+ case CUDA_ERROR_ILLEGAL_INSTRUCTION:
+ return "CUDA_ERROR_ILLEGAL_INSTRUCTION";
+
+ case CUDA_ERROR_MISALIGNED_ADDRESS:
+ return "CUDA_ERROR_MISALIGNED_ADDRESS";
+
+ case CUDA_ERROR_INVALID_ADDRESS_SPACE:
+ return "CUDA_ERROR_INVALID_ADDRESS_SPACE";
+
+ case CUDA_ERROR_INVALID_PC:
+ return "CUDA_ERROR_INVALID_PC";
+
+ case CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE:
+ return "CUDA_ERROR_COOPERATIVE_LAUNCH_TOO_LARGE";
+
+ case CUDA_ERROR_NOT_PERMITTED:
+ return "CUDA_ERROR_NOT_PERMITTED";
+
+ case CUDA_ERROR_NOT_SUPPORTED:
+ return "CUDA_ERROR_NOT_SUPPORTED";
+
+ case CUDA_ERROR_UNKNOWN:
+ return "CUDA_ERROR_UNKNOWN";
+ }
+
+ return "<unknown>";
+}
+#endif
+
+#ifdef CUBLAS_API_H_
+// cuBLAS API errors
+static const char *_cudaGetErrorEnum(cublasStatus_t error)
+{
+ switch (error)
+ {
+ case CUBLAS_STATUS_SUCCESS:
+ return "CUBLAS_STATUS_SUCCESS";
+
+ case CUBLAS_STATUS_NOT_INITIALIZED:
+ return "CUBLAS_STATUS_NOT_INITIALIZED";
+
+ case CUBLAS_STATUS_ALLOC_FAILED:
+ return "CUBLAS_STATUS_ALLOC_FAILED";
+
+ case CUBLAS_STATUS_INVALID_VALUE:
+ return "CUBLAS_STATUS_INVALID_VALUE";
+
+ case CUBLAS_STATUS_ARCH_MISMATCH:
+ return "CUBLAS_STATUS_ARCH_MISMATCH";
+
+ case CUBLAS_STATUS_MAPPING_ERROR:
+ return "CUBLAS_STATUS_MAPPING_ERROR";
+
+ case CUBLAS_STATUS_EXECUTION_FAILED:
+ return "CUBLAS_STATUS_EXECUTION_FAILED";
+
+ case CUBLAS_STATUS_INTERNAL_ERROR:
+ return "CUBLAS_STATUS_INTERNAL_ERROR";
+
+ case CUBLAS_STATUS_NOT_SUPPORTED:
+ return "CUBLAS_STATUS_NOT_SUPPORTED";
+
+ case CUBLAS_STATUS_LICENSE_ERROR:
+ return "CUBLAS_STATUS_LICENSE_ERROR";
+ }
+
+ return "<unknown>";
+}
+#endif
+
+#ifdef _CUFFT_H_
+// cuFFT API errors
+static const char *_cudaGetErrorEnum(cufftResult error)
+{
+ switch (error)
+ {
+ case CUFFT_SUCCESS:
+ return "CUFFT_SUCCESS";
+
+ case CUFFT_INVALID_PLAN:
+ return "CUFFT_INVALID_PLAN";
+
+ case CUFFT_ALLOC_FAILED:
+ return "CUFFT_ALLOC_FAILED";
+
+ case CUFFT_INVALID_TYPE:
+ return "CUFFT_INVALID_TYPE";
+
+ case CUFFT_INVALID_VALUE:
+ return "CUFFT_INVALID_VALUE";
+
+ case CUFFT_INTERNAL_ERROR:
+ return "CUFFT_INTERNAL_ERROR";
+
+ case CUFFT_EXEC_FAILED:
+ return "CUFFT_EXEC_FAILED";
+
+ case CUFFT_SETUP_FAILED:
+ return "CUFFT_SETUP_FAILED";
+
+ case CUFFT_INVALID_SIZE:
+ return "CUFFT_INVALID_SIZE";
+
+ case CUFFT_UNALIGNED_DATA:
+ return "CUFFT_UNALIGNED_DATA";
+
+ case CUFFT_INCOMPLETE_PARAMETER_LIST:
+ return "CUFFT_INCOMPLETE_PARAMETER_LIST";
+
+ case CUFFT_INVALID_DEVICE:
+ return "CUFFT_INVALID_DEVICE";
+
+ case CUFFT_PARSE_ERROR:
+ return "CUFFT_PARSE_ERROR";
+
+ case CUFFT_NO_WORKSPACE:
+ return "CUFFT_NO_WORKSPACE";
+
+ case CUFFT_NOT_IMPLEMENTED:
+ return "CUFFT_NOT_IMPLEMENTED";
+
+ case CUFFT_LICENSE_ERROR:
+ return "CUFFT_LICENSE_ERROR";
+
+ case CUFFT_NOT_SUPPORTED:
+ return "CUFFT_NOT_SUPPORTED";
+ }
+
+ return "<unknown>";
+}
+#endif
+
+
+#ifdef CUSPARSEAPI
+// cuSPARSE API errors
+static const char *_cudaGetErrorEnum(cusparseStatus_t error)
+{
+ switch (error)
+ {
+ case CUSPARSE_STATUS_SUCCESS:
+ return "CUSPARSE_STATUS_SUCCESS";
+
+ case CUSPARSE_STATUS_NOT_INITIALIZED:
+ return "CUSPARSE_STATUS_NOT_INITIALIZED";
+
+ case CUSPARSE_STATUS_ALLOC_FAILED:
+ return "CUSPARSE_STATUS_ALLOC_FAILED";
+
+ case CUSPARSE_STATUS_INVALID_VALUE:
+ return "CUSPARSE_STATUS_INVALID_VALUE";
+
+ case CUSPARSE_STATUS_ARCH_MISMATCH:
+ return "CUSPARSE_STATUS_ARCH_MISMATCH";
+
+ case CUSPARSE_STATUS_MAPPING_ERROR:
+ return "CUSPARSE_STATUS_MAPPING_ERROR";
+
+ case CUSPARSE_STATUS_EXECUTION_FAILED:
+ return "CUSPARSE_STATUS_EXECUTION_FAILED";
+
+ case CUSPARSE_STATUS_INTERNAL_ERROR:
+ return "CUSPARSE_STATUS_INTERNAL_ERROR";
+
+ case CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
+ return "CUSPARSE_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
+ }
+
+ return "<unknown>";
+}
+#endif
+
+#ifdef CUSOLVER_COMMON_H_
+//cuSOLVER API errors
+static const char *_cudaGetErrorEnum(cusolverStatus_t error)
+{
+ switch(error)
+ {
+ case CUSOLVER_STATUS_SUCCESS:
+ return "CUSOLVER_STATUS_SUCCESS";
+ case CUSOLVER_STATUS_NOT_INITIALIZED:
+ return "CUSOLVER_STATUS_NOT_INITIALIZED";
+ case CUSOLVER_STATUS_ALLOC_FAILED:
+ return "CUSOLVER_STATUS_ALLOC_FAILED";
+ case CUSOLVER_STATUS_INVALID_VALUE:
+ return "CUSOLVER_STATUS_INVALID_VALUE";
+ case CUSOLVER_STATUS_ARCH_MISMATCH:
+ return "CUSOLVER_STATUS_ARCH_MISMATCH";
+ case CUSOLVER_STATUS_MAPPING_ERROR:
+ return "CUSOLVER_STATUS_MAPPING_ERROR";
+ case CUSOLVER_STATUS_EXECUTION_FAILED:
+ return "CUSOLVER_STATUS_EXECUTION_FAILED";
+ case CUSOLVER_STATUS_INTERNAL_ERROR:
+ return "CUSOLVER_STATUS_INTERNAL_ERROR";
+ case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
+ return "CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED";
+ case CUSOLVER_STATUS_NOT_SUPPORTED :
+ return "CUSOLVER_STATUS_NOT_SUPPORTED ";
+ case CUSOLVER_STATUS_ZERO_PIVOT:
+ return "CUSOLVER_STATUS_ZERO_PIVOT";
+ case CUSOLVER_STATUS_INVALID_LICENSE:
+ return "CUSOLVER_STATUS_INVALID_LICENSE";
+ }
+
+ return "<unknown>";
+
+}
+#endif
+
+#ifdef CURAND_H_
+// cuRAND API errors
+static const char *_cudaGetErrorEnum(curandStatus_t error)
+{
+ switch (error)
+ {
+ case CURAND_STATUS_SUCCESS:
+ return "CURAND_STATUS_SUCCESS";
+
+ case CURAND_STATUS_VERSION_MISMATCH:
+ return "CURAND_STATUS_VERSION_MISMATCH";
+
+ case CURAND_STATUS_NOT_INITIALIZED:
+ return "CURAND_STATUS_NOT_INITIALIZED";
+
+ case CURAND_STATUS_ALLOCATION_FAILED:
+ return "CURAND_STATUS_ALLOCATION_FAILED";
+
+ case CURAND_STATUS_TYPE_ERROR:
+ return "CURAND_STATUS_TYPE_ERROR";
+
+ case CURAND_STATUS_OUT_OF_RANGE:
+ return "CURAND_STATUS_OUT_OF_RANGE";
+
+ case CURAND_STATUS_LENGTH_NOT_MULTIPLE:
+ return "CURAND_STATUS_LENGTH_NOT_MULTIPLE";
+
+ case CURAND_STATUS_DOUBLE_PRECISION_REQUIRED:
+ return "CURAND_STATUS_DOUBLE_PRECISION_REQUIRED";
+
+ case CURAND_STATUS_LAUNCH_FAILURE:
+ return "CURAND_STATUS_LAUNCH_FAILURE";
+
+ case CURAND_STATUS_PREEXISTING_FAILURE:
+ return "CURAND_STATUS_PREEXISTING_FAILURE";
+
+ case CURAND_STATUS_INITIALIZATION_FAILED:
+ return "CURAND_STATUS_INITIALIZATION_FAILED";
+
+ case CURAND_STATUS_ARCH_MISMATCH:
+ return "CURAND_STATUS_ARCH_MISMATCH";
+
+ case CURAND_STATUS_INTERNAL_ERROR:
+ return "CURAND_STATUS_INTERNAL_ERROR";
+ }
+
+ return "<unknown>";
+}
+#endif
+
+#ifdef NV_NPPIDEFS_H
+// NPP API errors
+static const char *_cudaGetErrorEnum(NppStatus error)
+{
+ switch (error)
+ {
+ case NPP_NOT_SUPPORTED_MODE_ERROR:
+ return "NPP_NOT_SUPPORTED_MODE_ERROR";
+
+ case NPP_ROUND_MODE_NOT_SUPPORTED_ERROR:
+ return "NPP_ROUND_MODE_NOT_SUPPORTED_ERROR";
+
+ case NPP_RESIZE_NO_OPERATION_ERROR:
+ return "NPP_RESIZE_NO_OPERATION_ERROR";
+
+ case NPP_NOT_SUFFICIENT_COMPUTE_CAPABILITY:
+ return "NPP_NOT_SUFFICIENT_COMPUTE_CAPABILITY";
+
+#if ((NPP_VERSION_MAJOR << 12) + (NPP_VERSION_MINOR << 4)) <= 0x5000
+
+ case NPP_BAD_ARG_ERROR:
+ return "NPP_BAD_ARGUMENT_ERROR";
+
+ case NPP_COEFF_ERROR:
+ return "NPP_COEFFICIENT_ERROR";
+
+ case NPP_RECT_ERROR:
+ return "NPP_RECTANGLE_ERROR";
+
+ case NPP_QUAD_ERROR:
+ return "NPP_QUADRANGLE_ERROR";
+
+ case NPP_MEM_ALLOC_ERR:
+ return "NPP_MEMORY_ALLOCATION_ERROR";
+
+ case NPP_HISTO_NUMBER_OF_LEVELS_ERROR:
+ return "NPP_HISTOGRAM_NUMBER_OF_LEVELS_ERROR";
+
+ case NPP_INVALID_INPUT:
+ return "NPP_INVALID_INPUT";
+
+ case NPP_POINTER_ERROR:
+ return "NPP_POINTER_ERROR";
+
+ case NPP_WARNING:
+ return "NPP_WARNING";
+
+ case NPP_ODD_ROI_WARNING:
+ return "NPP_ODD_ROI_WARNING";
+#else
+
+ // These are for CUDA 5.5 or higher
+ case NPP_BAD_ARGUMENT_ERROR:
+ return "NPP_BAD_ARGUMENT_ERROR";
+
+ case NPP_COEFFICIENT_ERROR:
+ return "NPP_COEFFICIENT_ERROR";
+
+ case NPP_RECTANGLE_ERROR:
+ return "NPP_RECTANGLE_ERROR";
+
+ case NPP_QUADRANGLE_ERROR:
+ return "NPP_QUADRANGLE_ERROR";
+
+ case NPP_MEMORY_ALLOCATION_ERR:
+ return "NPP_MEMORY_ALLOCATION_ERROR";
+
+ case NPP_HISTOGRAM_NUMBER_OF_LEVELS_ERROR:
+ return "NPP_HISTOGRAM_NUMBER_OF_LEVELS_ERROR";
+
+ case NPP_INVALID_HOST_POINTER_ERROR:
+ return "NPP_INVALID_HOST_POINTER_ERROR";
+
+ case NPP_INVALID_DEVICE_POINTER_ERROR:
+ return "NPP_INVALID_DEVICE_POINTER_ERROR";
+#endif
+
+ case NPP_LUT_NUMBER_OF_LEVELS_ERROR:
+ return "NPP_LUT_NUMBER_OF_LEVELS_ERROR";
+
+ case NPP_TEXTURE_BIND_ERROR:
+ return "NPP_TEXTURE_BIND_ERROR";
+
+ case NPP_WRONG_INTERSECTION_ROI_ERROR:
+ return "NPP_WRONG_INTERSECTION_ROI_ERROR";
+
+ case NPP_NOT_EVEN_STEP_ERROR:
+ return "NPP_NOT_EVEN_STEP_ERROR";
+
+ case NPP_INTERPOLATION_ERROR:
+ return "NPP_INTERPOLATION_ERROR";
+
+ case NPP_RESIZE_FACTOR_ERROR:
+ return "NPP_RESIZE_FACTOR_ERROR";
+
+ case NPP_HAAR_CLASSIFIER_PIXEL_MATCH_ERROR:
+ return "NPP_HAAR_CLASSIFIER_PIXEL_MATCH_ERROR";
+
+
+#if ((NPP_VERSION_MAJOR << 12) + (NPP_VERSION_MINOR << 4)) <= 0x5000
+
+ case NPP_MEMFREE_ERR:
+ return "NPP_MEMFREE_ERR";
+
+ case NPP_MEMSET_ERR:
+ return "NPP_MEMSET_ERR";
+
+ case NPP_MEMCPY_ERR:
+ return "NPP_MEMCPY_ERROR";
+
+ case NPP_MIRROR_FLIP_ERR:
+ return "NPP_MIRROR_FLIP_ERR";
+#else
+
+ case NPP_MEMFREE_ERROR:
+ return "NPP_MEMFREE_ERROR";
+
+ case NPP_MEMSET_ERROR:
+ return "NPP_MEMSET_ERROR";
+
+ case NPP_MEMCPY_ERROR:
+ return "NPP_MEMCPY_ERROR";
+
+ case NPP_MIRROR_FLIP_ERROR:
+ return "NPP_MIRROR_FLIP_ERROR";
+#endif
+
+ case NPP_ALIGNMENT_ERROR:
+ return "NPP_ALIGNMENT_ERROR";
+
+ case NPP_STEP_ERROR:
+ return "NPP_STEP_ERROR";
+
+ case NPP_SIZE_ERROR:
+ return "NPP_SIZE_ERROR";
+
+ case NPP_NULL_POINTER_ERROR:
+ return "NPP_NULL_POINTER_ERROR";
+
+ case NPP_CUDA_KERNEL_EXECUTION_ERROR:
+ return "NPP_CUDA_KERNEL_EXECUTION_ERROR";
+
+ case NPP_NOT_IMPLEMENTED_ERROR:
+ return "NPP_NOT_IMPLEMENTED_ERROR";
+
+ case NPP_ERROR:
+ return "NPP_ERROR";
+
+ case NPP_SUCCESS:
+ return "NPP_SUCCESS";
+
+ case NPP_WRONG_INTERSECTION_QUAD_WARNING:
+ return "NPP_WRONG_INTERSECTION_QUAD_WARNING";
+
+ case NPP_MISALIGNED_DST_ROI_WARNING:
+ return "NPP_MISALIGNED_DST_ROI_WARNING";
+
+ case NPP_AFFINE_QUAD_INCORRECT_WARNING:
+ return "NPP_AFFINE_QUAD_INCORRECT_WARNING";
+
+ case NPP_DOUBLE_SIZE_WARNING:
+ return "NPP_DOUBLE_SIZE_WARNING";
+
+ case NPP_WRONG_INTERSECTION_ROI_WARNING:
+ return "NPP_WRONG_INTERSECTION_ROI_WARNING";
+
+#if ((NPP_VERSION_MAJOR << 12) + (NPP_VERSION_MINOR << 4)) >= 0x6000
+ /* These are 6.0 or higher */
+ case NPP_LUT_PALETTE_BITSIZE_ERROR:
+ return "NPP_LUT_PALETTE_BITSIZE_ERROR";
+
+ case NPP_ZC_MODE_NOT_SUPPORTED_ERROR:
+ return "NPP_ZC_MODE_NOT_SUPPORTED_ERROR";
+
+ case NPP_QUALITY_INDEX_ERROR:
+ return "NPP_QUALITY_INDEX_ERROR";
+
+ case NPP_CHANNEL_ORDER_ERROR:
+ return "NPP_CHANNEL_ORDER_ERROR";
+
+ case NPP_ZERO_MASK_VALUE_ERROR:
+ return "NPP_ZERO_MASK_VALUE_ERROR";
+
+ case NPP_NUMBER_OF_CHANNELS_ERROR:
+ return "NPP_NUMBER_OF_CHANNELS_ERROR";
+
+ case NPP_COI_ERROR:
+ return "NPP_COI_ERROR";
+
+ case NPP_DIVISOR_ERROR:
+ return "NPP_DIVISOR_ERROR";
+
+ case NPP_CHANNEL_ERROR:
+ return "NPP_CHANNEL_ERROR";
+
+ case NPP_STRIDE_ERROR:
+ return "NPP_STRIDE_ERROR";
+
+ case NPP_ANCHOR_ERROR:
+ return "NPP_ANCHOR_ERROR";
+
+ case NPP_MASK_SIZE_ERROR:
+ return "NPP_MASK_SIZE_ERROR";
+
+ case NPP_MOMENT_00_ZERO_ERROR:
+ return "NPP_MOMENT_00_ZERO_ERROR";
+
+ case NPP_THRESHOLD_NEGATIVE_LEVEL_ERROR:
+ return "NPP_THRESHOLD_NEGATIVE_LEVEL_ERROR";
+
+ case NPP_THRESHOLD_ERROR:
+ return "NPP_THRESHOLD_ERROR";
+
+ case NPP_CONTEXT_MATCH_ERROR:
+ return "NPP_CONTEXT_MATCH_ERROR";
+
+ case NPP_FFT_FLAG_ERROR:
+ return "NPP_FFT_FLAG_ERROR";
+
+ case NPP_FFT_ORDER_ERROR:
+ return "NPP_FFT_ORDER_ERROR";
+
+ case NPP_SCALE_RANGE_ERROR:
+ return "NPP_SCALE_RANGE_ERROR";
+
+ case NPP_DATA_TYPE_ERROR:
+ return "NPP_DATA_TYPE_ERROR";
+
+ case NPP_OUT_OFF_RANGE_ERROR:
+ return "NPP_OUT_OFF_RANGE_ERROR";
+
+ case NPP_DIVIDE_BY_ZERO_ERROR:
+ return "NPP_DIVIDE_BY_ZERO_ERROR";
+
+ case NPP_RANGE_ERROR:
+ return "NPP_RANGE_ERROR";
+
+ case NPP_NO_MEMORY_ERROR:
+ return "NPP_NO_MEMORY_ERROR";
+
+ case NPP_ERROR_RESERVED:
+ return "NPP_ERROR_RESERVED";
+
+ case NPP_NO_OPERATION_WARNING:
+ return "NPP_NO_OPERATION_WARNING";
+
+ case NPP_DIVIDE_BY_ZERO_WARNING:
+ return "NPP_DIVIDE_BY_ZERO_WARNING";
+#endif
+
+#if ((NPP_VERSION_MAJOR << 12) + (NPP_VERSION_MINOR << 4)) >= 0x7000
+ /* These are 7.0 or higher */
+ case NPP_OVERFLOW_ERROR:
+ return "NPP_OVERFLOW_ERROR";
+
+ case NPP_CORRUPTED_DATA_ERROR:
+ return "NPP_CORRUPTED_DATA_ERROR";
+#endif
+ }
+
+ return "<unknown>";
+}
+#endif
+
+#ifdef __DRIVER_TYPES_H__
+#ifndef DEVICE_RESET
+#define DEVICE_RESET cudaDeviceReset();
+#endif
+#else
+#ifndef DEVICE_RESET
+#define DEVICE_RESET
+#endif
+#endif
+
+template< typename T >
+void check(T result, char const *const func, const char *const file, int const line)
+{
+ if (result)
+ {
+ fprintf(stderr, "CUDA error at %s:%d code=%d(%s) \"%s\" \n",
+ file, line, static_cast<unsigned int>(result), _cudaGetErrorEnum(result), func);
+ DEVICE_RESET
+ // Make sure we call CUDA Device Reset before exiting
+ exit(EXIT_FAILURE);
+ }
+}
+
+#ifdef __DRIVER_TYPES_H__
+// This will output the proper CUDA error strings in the event that a CUDA host call returns an error
+#define checkCudaErrors(val) check ( (val), #val, __FILE__, __LINE__ )
+
+// This will output the proper error string when calling cudaGetLastError
+#define getLastCudaError(msg) __getLastCudaError (msg, __FILE__, __LINE__)
+
+inline void __getLastCudaError(const char *errorMessage, const char *file, const int line)
+{
+ cudaError_t err = cudaGetLastError();
+
+ if (cudaSuccess != err)
+ {
+ fprintf(stderr, "%s(%i) : getLastCudaError() CUDA error : %s : (%d) %s.\n",
+ file, line, errorMessage, (int)err, cudaGetErrorString(err));
+ DEVICE_RESET
+ exit(EXIT_FAILURE);
+ }
+}
+
+// This will only print the proper error string when calling cudaGetLastError but not exit program incase error detected.
+#define printLastCudaError(msg) __printLastCudaError (msg, __FILE__, __LINE__)
+
+inline void __printLastCudaError(const char *errorMessage, const char *file, const int line)
+{
+ cudaError_t err = cudaGetLastError();
+
+ if (cudaSuccess != err)
+ {
+ fprintf(stderr, "%s(%i) : getLastCudaError() CUDA error : %s : (%d) %s.\n",
+ file, line, errorMessage, (int)err, cudaGetErrorString(err));
+ }
+}
+#endif
+
+#ifndef MAX
+#define MAX(a,b) (a > b ? a : b)
+#endif
+
+// Float To Int conversion
+inline int ftoi(float value)
+{
+ return (value >= 0 ? (int)(value + 0.5) : (int)(value - 0.5));
+}
+
+// Beginning of GPU Architecture definitions
+inline int _ConvertSMVer2Cores(int major, int minor)
+{
+ // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM
+ typedef struct
+ {
+ int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version
+ int Cores;
+ } sSMtoCores;
+
+ sSMtoCores nGpuArchCoresPerSM[] =
+ {
+ { 0x30, 192}, // Kepler Generation (SM 3.0) GK10x class
+ { 0x32, 192}, // Kepler Generation (SM 3.2) GK10x class
+ { 0x35, 192}, // Kepler Generation (SM 3.5) GK11x class
+ { 0x37, 192}, // Kepler Generation (SM 3.7) GK21x class
+ { 0x50, 128}, // Maxwell Generation (SM 5.0) GM10x class
+ { 0x52, 128}, // Maxwell Generation (SM 5.2) GM20x class
+ { 0x53, 128}, // Maxwell Generation (SM 5.3) GM20x class
+ { 0x60, 64 }, // Pascal Generation (SM 6.0) GP100 class
+ { 0x61, 128}, // Pascal Generation (SM 6.1) GP10x class
+ { 0x62, 128}, // Pascal Generation (SM 6.2) GP10x class
+ { 0x70, 64 }, // Volta Generation (SM 7.0) GV100 class
+ { 0x72, 64 }, // Volta Generation (SM 7.2) GV11b class
+ { -1, -1 }
+ };
+
+ int index = 0;
+
+ while (nGpuArchCoresPerSM[index].SM != -1)
+ {
+ if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor))
+ {
+ return nGpuArchCoresPerSM[index].Cores;
+ }
+
+ index++;
+ }
+
+ // If we don't find the values, we default use the previous one to run properly
+ printf("MapSMtoCores for SM %d.%d is undefined. Default to use %d Cores/SM\n", major, minor, nGpuArchCoresPerSM[index-1].Cores);
+ return nGpuArchCoresPerSM[index-1].Cores;
+}
+// end of GPU Architecture definitions
+
+#ifdef __CUDA_RUNTIME_H__
+// General GPU Device CUDA Initialization
+inline int gpuDeviceInit(int devID)
+{
+ int device_count;
+ checkCudaErrors(cudaGetDeviceCount(&device_count));
+
+ if (device_count == 0)
+ {
+ fprintf(stderr, "gpuDeviceInit() CUDA error: no devices supporting CUDA.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (devID < 0)
+ {
+ devID = 0;
+ }
+
+ if (devID > device_count-1)
+ {
+ fprintf(stderr, "\n");
+ fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", device_count);
+ fprintf(stderr, ">> gpuDeviceInit (-device=%d) is not a valid GPU device. <<\n", devID);
+ fprintf(stderr, "\n");
+ return -devID;
+ }
+
+ cudaDeviceProp deviceProp;
+ checkCudaErrors(cudaGetDeviceProperties(&deviceProp, devID));
+
+ if (deviceProp.computeMode == cudaComputeModeProhibited)
+ {
+ fprintf(stderr, "Error: device is running in <Compute Mode Prohibited>, no threads can use ::cudaSetDevice().\n");
+ return -1;
+ }
+
+ if (deviceProp.major < 1)
+ {
+ fprintf(stderr, "gpuDeviceInit(): GPU device does not support CUDA.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ checkCudaErrors(cudaSetDevice(devID));
+ printf("gpuDeviceInit() CUDA Device [%d]: \"%s\n", devID, deviceProp.name);
+
+ return devID;
+}
+
+// This function returns the best GPU (with maximum GFLOPS)
+inline int gpuGetMaxGflopsDeviceId()
+{
+ int current_device = 0, sm_per_multiproc = 0;
+ int max_perf_device = 0;
+ int device_count = 0, best_SM_arch = 0;
+ int devices_prohibited = 0;
+
+ unsigned long long max_compute_perf = 0;
+ cudaDeviceProp deviceProp;
+ checkCudaErrors(cudaGetDeviceCount(&device_count));
+
+ if (device_count == 0)
+ {
+ fprintf(stderr, "gpuGetMaxGflopsDeviceId() CUDA error: no devices supporting CUDA.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Find the best major SM Architecture GPU device
+ while (current_device < device_count)
+ {
+ cudaGetDeviceProperties(&deviceProp, current_device);
+
+ // If this GPU is not running on Compute Mode prohibited, then we can add it to the list
+ if (deviceProp.computeMode != cudaComputeModeProhibited)
+ {
+ if (deviceProp.major > 0 && deviceProp.major < 9999)
+ {
+ best_SM_arch = MAX(best_SM_arch, deviceProp.major);
+ }
+ }
+ else
+ {
+ devices_prohibited++;
+ }
+
+ current_device++;
+ }
+
+ if (devices_prohibited == device_count)
+ {
+ fprintf(stderr, "gpuGetMaxGflopsDeviceId() CUDA error: all devices have compute mode prohibited.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Find the best CUDA capable GPU device
+ current_device = 0;
+
+ while (current_device < device_count)
+ {
+ cudaGetDeviceProperties(&deviceProp, current_device);
+
+ // If this GPU is not running on Compute Mode prohibited, then we can add it to the list
+ if (deviceProp.computeMode != cudaComputeModeProhibited)
+ {
+ if (deviceProp.major == 9999 && deviceProp.minor == 9999)
+ {
+ sm_per_multiproc = 1;
+ }
+ else
+ {
+ sm_per_multiproc = _ConvertSMVer2Cores(deviceProp.major, deviceProp.minor);
+ }
+
+ unsigned long long compute_perf = (unsigned long long) deviceProp.multiProcessorCount * sm_per_multiproc * deviceProp.clockRate;
+
+ if (compute_perf > max_compute_perf)
+ {
+ // If we find GPU with SM major > 2, search only these
+ if (best_SM_arch > 2)
+ {
+ // If our device==dest_SM_arch, choose this, or else pass
+ if (deviceProp.major == best_SM_arch)
+ {
+ max_compute_perf = compute_perf;
+ max_perf_device = current_device;
+ }
+ }
+ else
+ {
+ max_compute_perf = compute_perf;
+ max_perf_device = current_device;
+ }
+ }
+ }
+
+ ++current_device;
+ }
+
+ return max_perf_device;
+}
+
+
+// Initialization code to find the best CUDA Device
+inline int findCudaDevice(int argc, const char **argv)
+{
+ cudaDeviceProp deviceProp;
+ int devID = 0;
+
+ // If the command-line has a device number specified, use it
+ if (checkCmdLineFlag(argc, argv, "device"))
+ {
+ devID = getCmdLineArgumentInt(argc, argv, "device=");
+
+ if (devID < 0)
+ {
+ printf("Invalid command line parameter\n ");
+ exit(EXIT_FAILURE);
+ }
+ else
+ {
+ devID = gpuDeviceInit(devID);
+
+ if (devID < 0)
+ {
+ printf("exiting...\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ }
+ else
+ {
+ // Otherwise pick the device with highest Gflops/s
+ devID = gpuGetMaxGflopsDeviceId();
+ checkCudaErrors(cudaSetDevice(devID));
+ checkCudaErrors(cudaGetDeviceProperties(&deviceProp, devID));
+ printf("GPU Device %d: \"%s\" with compute capability %d.%d\n\n", devID, deviceProp.name, deviceProp.major, deviceProp.minor);
+ }
+
+ return devID;
+}
+
+inline int findIntegratedGPU()
+{
+ int current_device = 0;
+ int device_count = 0;
+ int devices_prohibited = 0;
+
+ cudaDeviceProp deviceProp;
+ checkCudaErrors(cudaGetDeviceCount(&device_count));
+
+ if (device_count == 0)
+ {
+ fprintf(stderr, "CUDA error: no devices supporting CUDA.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Find the integrated GPU which is compute capable
+ while (current_device < device_count)
+ {
+ cudaGetDeviceProperties(&deviceProp, current_device);
+
+ // If GPU is integrated and is not running on Compute Mode prohibited, then cuda can map to GLES resource
+ if (deviceProp.integrated && (deviceProp.computeMode != cudaComputeModeProhibited))
+ {
+ checkCudaErrors(cudaSetDevice(current_device));
+ checkCudaErrors(cudaGetDeviceProperties(&deviceProp, current_device));
+ printf("GPU Device %d: \"%s\" with compute capability %d.%d\n\n", current_device, deviceProp.name, deviceProp.major, deviceProp.minor);
+
+ return current_device;
+ }
+ else
+ {
+ devices_prohibited++;
+ }
+
+ current_device++;
+ }
+
+ if (devices_prohibited == device_count)
+ {
+ fprintf(stderr, "CUDA error: No GLES-CUDA Interop capable GPU found.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return -1;
+}
+
+// General check for CUDA GPU SM Capabilities
+inline bool checkCudaCapabilities(int major_version, int minor_version)
+{
+ cudaDeviceProp deviceProp;
+ deviceProp.major = 0;
+ deviceProp.minor = 0;
+ int dev;
+
+ checkCudaErrors(cudaGetDevice(&dev));
+ checkCudaErrors(cudaGetDeviceProperties(&deviceProp, dev));
+
+ if ((deviceProp.major > major_version) ||
+ (deviceProp.major == major_version && deviceProp.minor >= minor_version))
+ {
+ printf(" Device %d: <%16s >, Compute SM %d.%d detected\n", dev, deviceProp.name, deviceProp.major, deviceProp.minor);
+ return true;
+ }
+ else
+ {
+ printf(" No GPU device was found that can support CUDA compute capability %d.%d.\n", major_version, minor_version);
+ return false;
+ }
+}
+#endif
+
+// end of CUDA Helper Functions
+
+
+#endif
diff --git a/tests/projects/cuda_console/inc/helper_cuda_drvapi.h b/tests/projects/cuda_console/inc/helper_cuda_drvapi.h
new file mode 100644
index 000000000..1d35305f1
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_cuda_drvapi.h
@@ -0,0 +1,572 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+// Helper functions for CUDA Driver API error handling (make sure that CUDA_H is included in your projects)
+#ifndef HELPER_CUDA_DRVAPI_H
+#define HELPER_CUDA_DRVAPI_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <helper_string.h>
+#include <drvapi_error_string.h>
+
+#ifndef MAX
+#define MAX(a,b) (a > b ? a : b)
+#endif
+
+#ifndef HELPER_CUDA_H
+inline int ftoi(float value)
+{
+ return (value >= 0 ? (int)(value + 0.5) : (int)(value - 0.5));
+}
+#endif
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// These are CUDA Helper functions
+
+// add a level of protection to the CUDA SDK samples, let's force samples to explicitly include CUDA.H
+#ifdef __cuda_cuda_h__
+// This will output the proper CUDA error strings in the event that a CUDA host call returns an error
+#ifndef checkCudaErrors
+#define checkCudaErrors(err) __checkCudaErrors (err, __FILE__, __LINE__)
+
+// These are the inline versions for all of the SDK helper functions
+inline void __checkCudaErrors(CUresult err, const char *file, const int line)
+{
+ if (CUDA_SUCCESS != err)
+ {
+ fprintf(stderr, "checkCudaErrors() Driver API error = %04d \"%s\" from file <%s>, line %i.\n",
+ err, getCudaDrvErrorString(err), file, line);
+ exit(EXIT_FAILURE);
+ }
+}
+#endif
+
+#ifdef getLastCudaDrvErrorMsg
+#undef getLastCudaDrvErrorMsg
+#endif
+
+#define getLastCudaDrvErrorMsg(msg) __getLastCudaDrvErrorMsg (msg, __FILE__, __LINE__)
+
+inline void __getLastCudaDrvErrorMsg(const char *msg, const char *file, const int line)
+{
+ CUresult err = cuCtxSynchronize();
+
+ if (CUDA_SUCCESS != err)
+ {
+ fprintf(stderr, "getLastCudaDrvErrorMsg -> %s", msg);
+ fprintf(stderr, "getLastCudaDrvErrorMsg -> cuCtxSynchronize API error = %04d \"%s\" in file <%s>, line %i.\n",
+ err, getCudaDrvErrorString(err), file, line);
+ exit(EXIT_FAILURE);
+ }
+}
+
+// This function wraps the CUDA Driver API into a template function
+template <class T>
+inline void getCudaAttribute(T *attribute, CUdevice_attribute device_attribute, int device)
+{
+ CUresult error_result = cuDeviceGetAttribute(attribute, device_attribute, device);
+
+ if (error_result != CUDA_SUCCESS)
+ {
+ printf("cuDeviceGetAttribute returned %d\n-> %s\n", (int)error_result, getCudaDrvErrorString(error_result));
+ exit(EXIT_SUCCESS);
+ }
+}
+#endif
+
+// Beginning of GPU Architecture definitions
+inline int _ConvertSMVer2CoresDRV(int major, int minor)
+{
+ // Defines for GPU Architecture types (using the SM version to determine the # of cores per SM
+ typedef struct
+ {
+ int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM minor version
+ int Cores;
+ } sSMtoCores;
+
+ sSMtoCores nGpuArchCoresPerSM[] =
+ {
+ { 0x30, 192}, // Kepler Generation (SM 3.0) GK10x class
+ { 0x32, 192}, // Kepler Generation (SM 3.2) GK10x class
+ { 0x35, 192}, // Kepler Generation (SM 3.5) GK11x class
+ { 0x37, 192}, // Kepler Generation (SM 3.7) GK21x class
+ { 0x50, 128}, // Maxwell Generation (SM 5.0) GM10x class
+ { 0x52, 128}, // Maxwell Generation (SM 5.2) GM20x class
+ { 0x53, 128}, // Maxwell Generation (SM 5.3) GM20x class
+ { 0x60, 64 }, // Pascal Generation (SM 6.0) GP100 class
+ { 0x61, 128}, // Pascal Generation (SM 6.1) GP10x class
+ { 0x62, 128}, // Pascal Generation (SM 6.2) GP10x class
+ { 0x70, 64 }, // Volta Generation (SM 7.0) GV100 class
+ { 0x72, 64 }, // Volta Generation (SM 7.2) GV11b class
+ { -1, -1 }
+ };
+
+ int index = 0;
+
+ while (nGpuArchCoresPerSM[index].SM != -1)
+ {
+ if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor))
+ {
+ return nGpuArchCoresPerSM[index].Cores;
+ }
+
+ index++;
+ }
+
+ // If we don't find the values, we default use the previous one to run properly
+ printf("MapSMtoCores for SM %d.%d is undefined. Default to use %d Cores/SM\n", major, minor, nGpuArchCoresPerSM[index-1].Cores);
+ return nGpuArchCoresPerSM[index-1].Cores;
+}
+// end of GPU Architecture definitions
+
+#ifdef __cuda_cuda_h__
+// General GPU Device CUDA Initialization
+inline int gpuDeviceInitDRV(int ARGC, const char **ARGV)
+{
+ int cuDevice = 0;
+ int deviceCount = 0;
+ CUresult err = cuInit(0);
+
+ if (CUDA_SUCCESS == err)
+ {
+ checkCudaErrors(cuDeviceGetCount(&deviceCount));
+ }
+
+ if (deviceCount == 0)
+ {
+ fprintf(stderr, "cudaDeviceInit error: no devices supporting CUDA\n");
+ exit(EXIT_FAILURE);
+ }
+
+ int dev = 0;
+ dev = getCmdLineArgumentInt(ARGC, (const char **) ARGV, "device=");
+
+ if (dev < 0)
+ {
+ dev = 0;
+ }
+
+ if (dev > deviceCount-1)
+ {
+ fprintf(stderr, "\n");
+ fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount);
+ fprintf(stderr, ">> cudaDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev);
+ fprintf(stderr, "\n");
+ return -dev;
+ }
+
+ checkCudaErrors(cuDeviceGet(&cuDevice, dev));
+ char name[100];
+ cuDeviceGetName(name, 100, cuDevice);
+
+ int computeMode;
+ getCudaAttribute<int>(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, dev);
+
+ if (computeMode == CU_COMPUTEMODE_PROHIBITED)
+ {
+ fprintf(stderr, "Error: device is running in <CU_COMPUTEMODE_PROHIBITED>, no threads can use this CUDA Device.\n");
+ return -1;
+ }
+
+ if (checkCmdLineFlag(ARGC, (const char **) ARGV, "quiet") == false)
+ {
+ printf("gpuDeviceInitDRV() Using CUDA Device [%d]: %s\n", dev, name);
+ }
+
+ return dev;
+}
+
+// This function returns the best GPU based on performance
+inline int gpuGetMaxGflopsDeviceIdDRV()
+{
+ CUdevice current_device = 0;
+ CUdevice max_perf_device = 0;
+ int device_count = 0;
+ int sm_per_multiproc = 0;
+ unsigned long long max_compute_perf = 0;
+ int best_SM_arch = 0;
+ int major = 0;
+ int minor = 0;
+ int multiProcessorCount;
+ int clockRate;
+ int devices_prohibited = 0;
+
+ cuInit(0);
+ checkCudaErrors(cuDeviceGetCount(&device_count));
+
+ if (device_count == 0)
+ {
+ fprintf(stderr, "gpuGetMaxGflopsDeviceIdDRV error: no devices supporting CUDA\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Find the best major SM Architecture GPU device
+ while (current_device < device_count)
+ {
+ checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device));
+
+ if (major > 0 && major < 9999)
+ {
+ best_SM_arch = MAX(best_SM_arch, major);
+ }
+
+ current_device++;
+ }
+
+ // Find the best CUDA capable GPU device
+ current_device = 0;
+
+ while (current_device < device_count)
+ {
+ checkCudaErrors(cuDeviceGetAttribute(&multiProcessorCount,
+ CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
+ current_device));
+ checkCudaErrors(cuDeviceGetAttribute(&clockRate,
+ CU_DEVICE_ATTRIBUTE_CLOCK_RATE,
+ current_device));
+ checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device));
+
+ int computeMode;
+ getCudaAttribute<int>(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device);
+
+ if (computeMode != CU_COMPUTEMODE_PROHIBITED)
+ {
+ if (major == 9999 && minor == 9999)
+ {
+ sm_per_multiproc = 1;
+ }
+ else
+ {
+ sm_per_multiproc = _ConvertSMVer2CoresDRV(major, minor);
+ }
+
+ unsigned long long compute_perf = (unsigned long long) (multiProcessorCount * sm_per_multiproc * clockRate);
+
+ if (compute_perf > max_compute_perf)
+ {
+ // If we find GPU with SM major > 2, search only these
+ if (best_SM_arch > 2)
+ {
+ // If our device==dest_SM_arch, choose this, or else pass
+ if (major == best_SM_arch)
+ {
+ max_compute_perf = compute_perf;
+ max_perf_device = current_device;
+ }
+ }
+ else
+ {
+ max_compute_perf = compute_perf;
+ max_perf_device = current_device;
+ }
+ }
+ }
+ else
+ {
+ devices_prohibited++;
+ }
+
+ ++current_device;
+ }
+
+ if (devices_prohibited == device_count)
+ {
+ fprintf(stderr, "gpuGetMaxGflopsDeviceIdDRV error: all devices have compute mode prohibited.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return max_perf_device;
+}
+
+// This function returns the best Graphics GPU based on performance
+inline int gpuGetMaxGflopsGLDeviceIdDRV()
+{
+ CUdevice current_device = 0, max_perf_device = 0;
+ int device_count = 0, sm_per_multiproc = 0;
+ int max_compute_perf = 0, best_SM_arch = 0;
+ int major = 0, minor = 0, multiProcessorCount, clockRate;
+ int bTCC = 0;
+ int devices_prohibited = 0;
+ char deviceName[256];
+
+ cuInit(0);
+ checkCudaErrors(cuDeviceGetCount(&device_count));
+
+ if (device_count == 0)
+ {
+ fprintf(stderr, "gpuGetMaxGflopsGLDeviceIdDRV error: no devices supporting CUDA\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Find the best major SM Architecture GPU device that are graphics devices
+ while (current_device < device_count)
+ {
+ checkCudaErrors(cuDeviceGetName(deviceName, 256, current_device));
+ checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device));
+
+#if CUDA_VERSION >= 3020
+ checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device));
+#else
+
+ // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1
+ if (deviceName[0] == 'T')
+ {
+ bTCC = 1;
+ }
+
+#endif
+
+ int computeMode;
+ getCudaAttribute<int>(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device);
+
+ if (computeMode != CU_COMPUTEMODE_PROHIBITED)
+ {
+ if (!bTCC)
+ {
+ if (major > 0 && major < 9999)
+ {
+ best_SM_arch = MAX(best_SM_arch, major);
+ }
+ }
+ }
+ else
+ {
+ devices_prohibited++;
+ }
+
+ current_device++;
+ }
+
+ if (devices_prohibited == device_count)
+ {
+ fprintf(stderr, "gpuGetMaxGflopsGLDeviceIdDRV error: all devices have compute mode prohibited.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Find the best CUDA capable GPU device
+ current_device = 0;
+
+ while (current_device < device_count)
+ {
+ checkCudaErrors(cuDeviceGetAttribute(&multiProcessorCount,
+ CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
+ current_device));
+ checkCudaErrors(cuDeviceGetAttribute(&clockRate,
+ CU_DEVICE_ATTRIBUTE_CLOCK_RATE,
+ current_device));
+ checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device));
+
+#if CUDA_VERSION >= 3020
+ checkCudaErrors(cuDeviceGetAttribute(&bTCC, CU_DEVICE_ATTRIBUTE_TCC_DRIVER, current_device));
+#else
+
+ // Assume a Tesla GPU is running in TCC if we are running CUDA 3.1
+ if (deviceName[0] == 'T')
+ {
+ bTCC = 1;
+ }
+
+#endif
+
+ int computeMode;
+ getCudaAttribute<int>(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device);
+
+ if (computeMode != CU_COMPUTEMODE_PROHIBITED)
+ {
+ if (major == 9999 && minor == 9999)
+ {
+ sm_per_multiproc = 1;
+ }
+ else
+ {
+ sm_per_multiproc = _ConvertSMVer2CoresDRV(major, minor);
+ }
+
+ // If this is a Tesla based GPU and SM 2.0, and TCC is disabled, this is a contendor
+ if (!bTCC) // Is this GPU running the TCC driver? If so we pass on this
+ {
+ int compute_perf = multiProcessorCount * sm_per_multiproc * clockRate;
+
+ if (compute_perf > max_compute_perf)
+ {
+ // If we find GPU with SM major > 2, search only these
+ if (best_SM_arch > 2)
+ {
+ // If our device = dest_SM_arch, then we pick this one
+ if (major == best_SM_arch)
+ {
+ max_compute_perf = compute_perf;
+ max_perf_device = current_device;
+ }
+ }
+ else
+ {
+ max_compute_perf = compute_perf;
+ max_perf_device = current_device;
+ }
+ }
+ }
+ }
+
+ ++current_device;
+ }
+
+ return max_perf_device;
+}
+
+// General initialization call to pick the best CUDA Device
+inline CUdevice findCudaDeviceDRV(int argc, const char **argv)
+{
+ CUdevice cuDevice;
+ int devID = 0;
+
+ // If the command-line has a device number specified, use it
+ if (checkCmdLineFlag(argc, (const char **)argv, "device"))
+ {
+ devID = gpuDeviceInitDRV(argc, argv);
+
+ if (devID < 0)
+ {
+ printf("exiting...\n");
+ exit(EXIT_SUCCESS);
+ }
+ }
+ else
+ {
+ // Otherwise pick the device with highest Gflops/s
+ char name[100];
+ devID = gpuGetMaxGflopsDeviceIdDRV();
+ checkCudaErrors(cuDeviceGet(&cuDevice, devID));
+ cuDeviceGetName(name, 100, cuDevice);
+ printf("> Using CUDA Device [%d]: %s\n", devID, name);
+ }
+
+ cuDeviceGet(&cuDevice, devID);
+
+ return cuDevice;
+}
+
+inline CUdevice findIntegratedGPUDrv()
+{
+ CUdevice current_device = 0;
+ int device_count = 0;
+ int devices_prohibited = 0;
+ int isIntegrated;
+
+ cuInit(0);
+ checkCudaErrors(cuDeviceGetCount(&device_count));
+
+ if (device_count == 0)
+ {
+ fprintf(stderr, "CUDA error: no devices supporting CUDA.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // Find the integrated GPU which is compute capable
+ while (current_device < device_count)
+ {
+ int computeMode = -1;
+ checkCudaErrors(cuDeviceGetAttribute(&isIntegrated, CU_DEVICE_ATTRIBUTE_INTEGRATED, current_device));
+ checkCudaErrors(cuDeviceGetAttribute(&computeMode, CU_DEVICE_ATTRIBUTE_COMPUTE_MODE, current_device));
+
+ // If GPU is integrated and is not running on Compute Mode prohibited use that
+ if (isIntegrated && (computeMode != CU_COMPUTEMODE_PROHIBITED))
+ {
+ int major = 0, minor = 0;
+ char deviceName[256];
+ checkCudaErrors(cuDeviceComputeCapability(&major, &minor, current_device));
+ checkCudaErrors(cuDeviceGetName(deviceName, 256, current_device));
+ printf("GPU Device %d: \"%s\" with compute capability %d.%d\n\n", current_device, deviceName, major, minor);
+
+ return current_device;
+ }
+ else
+ {
+ devices_prohibited++;
+ }
+
+ current_device++;
+ }
+
+ if (devices_prohibited == device_count)
+ {
+ fprintf(stderr, "CUDA error: No Integrated CUDA capable GPU found.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ return -1;
+}
+
+// This function will pick the best CUDA device available with OpenGL interop
+inline CUdevice findCudaGLDeviceDRV(int argc, const char **argv)
+{
+ CUdevice cuDevice;
+ int devID = 0;
+
+ // If the command-line has a device number specified, use it
+ if (checkCmdLineFlag(argc, (const char **)argv, "device"))
+ {
+ devID = gpuDeviceInitDRV(argc, (const char **)argv);
+
+ if (devID < 0)
+ {
+ printf("no CUDA capable devices found, exiting...\n");
+ exit(EXIT_SUCCESS);
+ }
+ }
+ else
+ {
+ char name[100];
+ // Otherwise pick the device with highest Gflops/s
+ devID = gpuGetMaxGflopsGLDeviceIdDRV();
+ checkCudaErrors(cuDeviceGet(&cuDevice, devID));
+ cuDeviceGetName(name, 100, cuDevice);
+ printf("> Using CUDA/GL Device [%d]: %s\n", devID, name);
+ }
+
+ return devID;
+}
+
+// General check for CUDA GPU SM Capabilities
+inline bool checkCudaCapabilitiesDRV(int major_version, int minor_version, int devID)
+{
+ CUdevice cuDevice;
+ char name[256];
+ int major = 0, minor = 0;
+
+ checkCudaErrors(cuDeviceGet(&cuDevice, devID));
+ checkCudaErrors(cuDeviceGetName(name, 100, cuDevice));
+ checkCudaErrors(cuDeviceComputeCapability(&major, &minor, devID));
+
+ if ((major > major_version) ||
+ (major == major_version && minor >= minor_version))
+ {
+ printf("> Device %d: <%16s >, Compute SM %d.%d detected\n", devID, name, major, minor);
+ return true;
+ }
+ else
+ {
+ printf("No GPU device was found that can support CUDA compute capability %d.%d.\n", major_version, minor_version);
+ return false;
+ }
+}
+#endif
+
+// end of CUDA Helper Functions
+
+#endif
diff --git a/tests/projects/cuda_console/inc/helper_cuda_gl.h b/tests/projects/cuda_console/inc/helper_cuda_gl.h
new file mode 100644
index 000000000..1923b8da0
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_cuda_gl.h
@@ -0,0 +1,183 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef HELPER_CUDA_GL_H
+#define HELPER_CUDA_GL_H
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+// includes, graphics
+#if defined (__APPLE__) || defined(MACOSX)
+#include <OpenGL/gl.h>
+#else
+#include <GL/gl.h>
+#endif
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+#ifdef __DRIVER_TYPES_H__
+#ifndef DEVICE_RESET
+#define DEVICE_RESET cudaDeviceReset()
+#endif
+#else
+#ifndef DEVICE_RESET
+#define DEVICE_RESET
+#endif
+#endif
+
+#ifdef __CUDA_GL_INTEROP_H__
+////////////////////////////////////////////////////////////////////////////////
+// These are CUDA OpenGL Helper functions
+
+inline int gpuGLDeviceInit(int ARGC, const char **ARGV)
+{
+ int deviceCount;
+ checkCudaErrors(cudaGetDeviceCount(&deviceCount));
+
+ if (deviceCount == 0)
+ {
+ fprintf(stderr, "CUDA error: no devices supporting CUDA.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ int dev = 0;
+ dev = getCmdLineArgumentInt(ARGC, ARGV, "device=");
+
+ if (dev < 0)
+ {
+ dev = 0;
+ }
+
+ if (dev > deviceCount-1)
+ {
+ fprintf(stderr, "\n");
+ fprintf(stderr, ">> %d CUDA capable GPU device(s) detected. <<\n", deviceCount);
+ fprintf(stderr, ">> gpuGLDeviceInit (-device=%d) is not a valid GPU device. <<\n", dev);
+ fprintf(stderr, "\n");
+ return -dev;
+ }
+
+ cudaDeviceProp deviceProp;
+ checkCudaErrors(cudaGetDeviceProperties(&deviceProp, dev));
+
+ if (deviceProp.computeMode == cudaComputeModeProhibited)
+ {
+ fprintf(stderr, "Error: device is running in <Compute Mode Prohibited>, no threads can use ::cudaSetDevice().\n");
+ return -1;
+ }
+
+ if (deviceProp.major < 1)
+ {
+ fprintf(stderr, "Error: device does not support CUDA.\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (checkCmdLineFlag(ARGC, ARGV, "quiet") == false)
+ {
+ fprintf(stderr, "Using device %d: %s\n", dev, deviceProp.name);
+ }
+
+ checkCudaErrors(cudaGLSetGLDevice(dev));
+ return dev;
+}
+
+// This function will pick the best CUDA device available with OpenGL interop
+inline int findCudaGLDevice(int argc, const char **argv)
+{
+ int devID = 0;
+
+ // If the command-line has a device number specified, use it
+ if (checkCmdLineFlag(argc, (const char **)argv, "device"))
+ {
+ devID = gpuGLDeviceInit(argc, (const char **)argv);
+
+ if (devID < 0)
+ {
+ printf("no CUDA capable devices found, exiting...\n");
+ DEVICE_RESET
+ exit(EXIT_SUCCESS);
+ }
+ }
+ else
+ {
+ // Otherwise pick the device with highest Gflops/s
+ devID = gpuGetMaxGflopsDeviceId();
+ cudaGLSetGLDevice(devID);
+ }
+
+ return devID;
+}
+
+static inline const char* glErrorToString(GLenum err)
+{
+#define CASE_RETURN_MACRO(arg) case arg: return #arg
+ switch(err)
+ {
+ CASE_RETURN_MACRO(GL_NO_ERROR);
+ CASE_RETURN_MACRO(GL_INVALID_ENUM);
+ CASE_RETURN_MACRO(GL_INVALID_VALUE);
+ CASE_RETURN_MACRO(GL_INVALID_OPERATION);
+ CASE_RETURN_MACRO(GL_OUT_OF_MEMORY);
+ CASE_RETURN_MACRO(GL_STACK_UNDERFLOW);
+ CASE_RETURN_MACRO(GL_STACK_OVERFLOW);
+#ifdef GL_INVALID_FRAMEBUFFER_OPERATION
+ CASE_RETURN_MACRO(GL_INVALID_FRAMEBUFFER_OPERATION);
+#endif
+ default: break;
+ }
+#undef CASE_RETURN_MACRO
+ return "*UNKNOWN*";
+}
+////////////////////////////////////////////////////////////////////////////
+//! Check for OpenGL error
+//! @return bool if no GL error has been encountered, otherwise 0
+//! @param file __FILE__ macro
+//! @param line __LINE__ macro
+//! @note The GL error is listed on stderr
+//! @note This function should be used via the CHECK_ERROR_GL() macro
+////////////////////////////////////////////////////////////////////////////
+inline bool
+sdkCheckErrorGL(const char *file, const int line)
+{
+ bool ret_val = true;
+
+ // check for error
+ GLenum gl_error = glGetError();
+
+ if (gl_error != GL_NO_ERROR)
+ {
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+ char tmpStr[512];
+ // NOTE: "%s(%i) : " allows Visual Studio to directly jump to the file at the right line
+ // when the user double clicks on the error line in the Output pane. Like any compile error.
+ sprintf_s(tmpStr, 255, "\n%s(%i) : GL Error : %s\n\n", file, line, glErrorToString(gl_error));
+ fprintf(stderr, "%s", tmpStr);
+#endif
+ fprintf(stderr, "GL Error in file '%s' in line %d :\n", file, line);
+ fprintf(stderr, "%s\n", glErrorToString(gl_error));
+ ret_val = false;
+ }
+
+ return ret_val;
+}
+
+#define SDK_CHECK_ERROR_GL() \
+ if( false == sdkCheckErrorGL( __FILE__, __LINE__)) { \
+ DEVICE_RESET \
+ exit(EXIT_FAILURE); \
+ }
+#endif
+
+#endif
diff --git a/tests/projects/cuda_console/inc/helper_cusolver.h b/tests/projects/cuda_console/inc/helper_cusolver.h
new file mode 100644
index 000000000..d614d1f4e
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_cusolver.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2015 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef HELPER_CUSOLVER
+#define HELPER_CUSOLVER
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <cuda_runtime.h>
+
+#include "cusparse.h"
+
+#define SWITCH_CHAR '-'
+
+struct testOpts {
+ char *sparse_mat_filename; // by switch -F<filename>
+ const char *testFunc; // by switch -R<name>
+ const char *reorder; // by switch -P<name>
+ int lda; // by switch -lda<int>
+};
+
+double vec_norminf(int n, const double *x)
+{
+ double norminf = 0;
+ for(int j = 0 ; j < n ; j++){
+ double x_abs = fabs(x[j]);
+ norminf = (norminf > x_abs)? norminf : x_abs;
+ }
+ return norminf;
+}
+
+/*
+ * |A| = max { |A|*ones(m,1) }
+ */
+double mat_norminf(
+ int m,
+ int n,
+ const double *A,
+ int lda)
+{
+ double norminf = 0;
+ for(int i = 0 ; i < m ; i++){
+ double sum = 0.0;
+ for(int j = 0 ; j < n ; j++){
+ double A_abs = fabs(A[i + j*lda]);
+ sum += A_abs;
+ }
+ norminf = (norminf > sum)? norminf : sum;
+ }
+ return norminf;
+}
+
+/*
+ * |A| = max { |A|*ones(m,1) }
+ */
+double csr_mat_norminf(
+ int m,
+ int n,
+ int nnzA,
+ const cusparseMatDescr_t descrA,
+ const double *csrValA,
+ const int *csrRowPtrA,
+ const int *csrColIndA)
+{
+ const int baseA = (CUSPARSE_INDEX_BASE_ONE == cusparseGetMatIndexBase(descrA))? 1:0;
+
+ double norminf = 0;
+ for(int i = 0 ; i < m ; i++){
+ double sum = 0.0;
+ const int start = csrRowPtrA[i ] - baseA;
+ const int end = csrRowPtrA[i+1] - baseA;
+ for(int colidx = start ; colidx < end ; colidx++){
+ // const int j = csrColIndA[colidx] - baseA;
+ double A_abs = fabs( csrValA[colidx] );
+ sum += A_abs;
+ }
+ norminf = (norminf > sum)? norminf : sum;
+ }
+ return norminf;
+}
+
+
+void display_matrix(
+ int m,
+ int n,
+ int nnzA,
+ const cusparseMatDescr_t descrA,
+ const double *csrValA,
+ const int *csrRowPtrA,
+ const int *csrColIndA)
+{
+ const int baseA = (CUSPARSE_INDEX_BASE_ONE == cusparseGetMatIndexBase(descrA))? 1:0;
+
+ printf("m = %d, n = %d, nnz = %d, matlab base-1\n", m, n, nnzA);
+
+ for(int row = 0 ; row < m ; row++){
+ const int start = csrRowPtrA[row ] - baseA;
+ const int end = csrRowPtrA[row+1] - baseA;
+ for(int colidx = start ; colidx < end ; colidx++){
+ const int col = csrColIndA[colidx] - baseA;
+ double Areg = csrValA[colidx];
+ printf("A(%d, %d) = %20.16E\n", row+1, col+1, Areg);
+ }
+ }
+}
+
+
+#if defined(_WIN32)
+#if !defined(WIN32_LEAN_AND_MEAN)
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+double second (void)
+{
+ LARGE_INTEGER t;
+ static double oofreq;
+ static int checkedForHighResTimer;
+ static BOOL hasHighResTimer;
+
+ if (!checkedForHighResTimer) {
+ hasHighResTimer = QueryPerformanceFrequency (&t);
+ oofreq = 1.0 / (double)t.QuadPart;
+ checkedForHighResTimer = 1;
+ }
+ if (hasHighResTimer) {
+ QueryPerformanceCounter (&t);
+ return (double)t.QuadPart * oofreq;
+ } else {
+ return (double)GetTickCount() / 1000.0;
+ }
+}
+
+#elif defined(__linux) || defined(__QNX__)
+#include <stddef.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+double second (void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
+}
+
+#elif defined(__APPLE__)
+#include <stddef.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+double second (void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
+}
+#else
+#error unsupported platform
+#endif
+
+#endif
+
diff --git a/tests/projects/cuda_console/inc/helper_functions.h b/tests/projects/cuda_console/inc/helper_functions.h
new file mode 100644
index 000000000..11538ba72
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_functions.h
@@ -0,0 +1,42 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+// These are helper functions for the SDK samples (string parsing, timers, image helpers, etc)
+#ifndef HELPER_FUNCTIONS_H
+#define HELPER_FUNCTIONS_H
+
+#ifdef WIN32
+#pragma warning(disable:4996)
+#endif
+
+// includes, project
+#include <stdio.h>
+#include <stdlib.h>
+#include <string>
+#include <assert.h>
+#include <exception.h>
+#include <math.h>
+
+#include <fstream>
+#include <vector>
+#include <iostream>
+#include <algorithm>
+
+// includes, timer, string parsing, image helpers
+#include <helper_timer.h> // helper functions for timers
+#include <helper_string.h> // helper functions for string parsing
+#include <helper_image.h> // helper functions for image compare, dump, data comparisons
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+#endif // HELPER_FUNCTIONS_H
diff --git a/tests/projects/cuda_console/inc/helper_gl.h b/tests/projects/cuda_console/inc/helper_gl.h
new file mode 100644
index 000000000..83addd433
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_gl.h
@@ -0,0 +1,191 @@
+/**
+ * Copyright 2014 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+// These are helper functions for the SDK samples (OpenGL)
+#ifndef HELPER_GL_H
+#define HELPER_GL_H
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+ #include <GL/glew.h>
+#endif
+
+#if defined(__APPLE__) || defined(MACOSX)
+ #include <OpenGL/gl.h>
+#else
+ #include <GL/gl.h>
+ #ifdef __linux__
+ #include <GL/glx.h>
+ #endif /* __linux__ */
+#endif
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+#include <vector>
+#include <assert.h>
+
+
+/* Prototypes */
+namespace __HelperGL {
+ static int isGLVersionSupported(unsigned reqMajor, unsigned reqMinor);
+ static int areGLExtensionsSupported(const std::string &);
+#ifdef __linux__
+
+ #ifndef HELPERGL_EXTERN_GL_FUNC_IMPLEMENTATION
+ #define USE_GL_FUNC(name, proto) proto name = (proto) glXGetProcAddress ((const GLubyte *)#name)
+ #else
+ #define USE_GL_FUNC(name, proto) extern proto name
+ #endif
+
+ USE_GL_FUNC(glBindBuffer, PFNGLBINDBUFFERPROC);
+ USE_GL_FUNC(glDeleteBuffers, PFNGLDELETEBUFFERSPROC);
+ USE_GL_FUNC(glBufferData, PFNGLBUFFERDATAPROC);
+ USE_GL_FUNC(glBufferSubData, PFNGLBUFFERSUBDATAPROC);
+ USE_GL_FUNC(glGenBuffers, PFNGLGENBUFFERSPROC);
+ USE_GL_FUNC(glCreateProgram, PFNGLCREATEPROGRAMPROC);
+ USE_GL_FUNC(glBindProgramARB, PFNGLBINDPROGRAMARBPROC);
+ USE_GL_FUNC(glGenProgramsARB, PFNGLGENPROGRAMSARBPROC);
+ USE_GL_FUNC(glDeleteProgramsARB, PFNGLDELETEPROGRAMSARBPROC);
+ USE_GL_FUNC(glDeleteProgram, PFNGLDELETEPROGRAMPROC);
+ USE_GL_FUNC(glGetProgramInfoLog, PFNGLGETPROGRAMINFOLOGPROC);
+ USE_GL_FUNC(glGetProgramiv, PFNGLGETPROGRAMIVPROC);
+ USE_GL_FUNC(glProgramParameteriEXT, PFNGLPROGRAMPARAMETERIEXTPROC);
+ USE_GL_FUNC(glProgramStringARB, PFNGLPROGRAMSTRINGARBPROC);
+ USE_GL_FUNC(glUnmapBuffer, PFNGLUNMAPBUFFERPROC);
+ USE_GL_FUNC(glMapBuffer, PFNGLMAPBUFFERPROC);
+ USE_GL_FUNC(glGetBufferParameteriv, PFNGLGETBUFFERPARAMETERIVPROC);
+ USE_GL_FUNC(glLinkProgram, PFNGLLINKPROGRAMPROC);
+ USE_GL_FUNC(glUseProgram, PFNGLUSEPROGRAMPROC);
+ USE_GL_FUNC(glAttachShader, PFNGLATTACHSHADERPROC);
+ USE_GL_FUNC(glCreateShader, PFNGLCREATESHADERPROC);
+ USE_GL_FUNC(glShaderSource, PFNGLSHADERSOURCEPROC);
+ USE_GL_FUNC(glCompileShader, PFNGLCOMPILESHADERPROC);
+ USE_GL_FUNC(glDeleteShader, PFNGLDELETESHADERPROC);
+ USE_GL_FUNC(glGetShaderInfoLog, PFNGLGETSHADERINFOLOGPROC);
+ USE_GL_FUNC(glGetShaderiv, PFNGLGETSHADERIVPROC);
+ USE_GL_FUNC(glUniform1i, PFNGLUNIFORM1IPROC);
+ USE_GL_FUNC(glUniform1f, PFNGLUNIFORM1FPROC);
+ USE_GL_FUNC(glUniform2f, PFNGLUNIFORM2FPROC);
+ USE_GL_FUNC(glUniform3f, PFNGLUNIFORM3FPROC);
+ USE_GL_FUNC(glUniform4f, PFNGLUNIFORM4FPROC);
+ USE_GL_FUNC(glUniform1fv, PFNGLUNIFORM1FVPROC);
+ USE_GL_FUNC(glUniform2fv, PFNGLUNIFORM2FVPROC);
+ USE_GL_FUNC(glUniform3fv, PFNGLUNIFORM3FVPROC);
+ USE_GL_FUNC(glUniform4fv, PFNGLUNIFORM4FVPROC);
+ USE_GL_FUNC(glUniformMatrix4fv, PFNGLUNIFORMMATRIX4FVPROC);
+ USE_GL_FUNC(glSecondaryColor3fv, PFNGLSECONDARYCOLOR3FVPROC);
+ USE_GL_FUNC(glGetUniformLocation, PFNGLGETUNIFORMLOCATIONPROC);
+ USE_GL_FUNC(glGenFramebuffersEXT, PFNGLGENFRAMEBUFFERSEXTPROC);
+ USE_GL_FUNC(glBindFramebufferEXT, PFNGLBINDFRAMEBUFFEREXTPROC);
+ USE_GL_FUNC(glDeleteFramebuffersEXT, PFNGLDELETEFRAMEBUFFERSEXTPROC);
+ USE_GL_FUNC(glCheckFramebufferStatusEXT, PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC);
+ USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT, PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC);
+ USE_GL_FUNC(glFramebufferTexture1DEXT, PFNGLFRAMEBUFFERTEXTURE1DEXTPROC);
+ USE_GL_FUNC(glFramebufferTexture2DEXT, PFNGLFRAMEBUFFERTEXTURE2DEXTPROC);
+ USE_GL_FUNC(glFramebufferTexture3DEXT, PFNGLFRAMEBUFFERTEXTURE3DEXTPROC);
+ USE_GL_FUNC(glGenerateMipmapEXT, PFNGLGENERATEMIPMAPEXTPROC);
+ USE_GL_FUNC(glGenRenderbuffersEXT, PFNGLGENRENDERBUFFERSEXTPROC);
+ USE_GL_FUNC(glDeleteRenderbuffersEXT, PFNGLDELETERENDERBUFFERSEXTPROC);
+ USE_GL_FUNC(glBindRenderbufferEXT, PFNGLBINDRENDERBUFFEREXTPROC);
+ USE_GL_FUNC(glRenderbufferStorageEXT, PFNGLRENDERBUFFERSTORAGEEXTPROC);
+ USE_GL_FUNC(glFramebufferRenderbufferEXT, PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC);
+ USE_GL_FUNC(glClampColorARB, PFNGLCLAMPCOLORARBPROC);
+ USE_GL_FUNC(glBindFragDataLocationEXT, PFNGLBINDFRAGDATALOCATIONEXTPROC);
+
+#if !defined(GLX_EXTENSION_NAME) || !defined(GL_VERSION_1_3)
+ USE_GL_FUNC(glActiveTexture, PFNGLACTIVETEXTUREPROC);
+ USE_GL_FUNC(glClientActiveTexture, PFNGLACTIVETEXTUREPROC);
+#endif
+
+ #undef USE_GL_FUNC
+#endif /*__linux__ */
+}
+
+
+namespace __HelperGL {
+ namespace __Int {
+ static std::vector<std::string> split(const std::string &str)
+ {
+ std::istringstream ss(str);
+ std::istream_iterator<std::string> it(ss);
+ return std::vector<std::string> (it, std::istream_iterator<std::string>());
+ }
+
+ /* Sort the vector passed by reference */
+ template<typename T> static inline void sort(std::vector<T> &a)
+ {
+ std::sort(a.begin(), a.end());
+ }
+
+ /* Compare two vectors */
+ template<typename T> static int equals(std::vector<T> a, std::vector<T> b)
+ {
+ if (a.size() != b.size()) return 0;
+ sort(a);
+ sort(b);
+
+ return std::equal(a.begin(), a.end(), b.begin());
+ }
+
+ template<typename T> static std::vector<T> getIntersection(std::vector<T> a, std::vector<T> b)
+ {
+ sort(a);
+ sort(b);
+
+ std::vector<T> rc;
+ std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
+ std::back_inserter<std::vector<std::string> >(rc));
+ return rc;
+ }
+
+ static std::vector<std::string> getGLExtensions()
+ {
+ std::string extensionsStr( (const char *)glGetString(GL_EXTENSIONS));
+ return split (extensionsStr);
+ }
+ }
+
+ static int areGLExtensionsSupported(const std::string &extensions)
+ {
+ std::vector<std::string> all = __Int::getGLExtensions();
+
+ std::vector<std::string> requested = __Int::split(extensions);
+ std::vector<std::string> matched = __Int::getIntersection(all, requested);
+
+ return __Int::equals(matched, requested);
+ }
+
+ static int isGLVersionSupported(unsigned reqMajor, unsigned reqMinor)
+ {
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+ if (glewInit() != GLEW_OK)
+ {
+ std::cerr << "glewInit() failed!" << std::endl;
+ return 0;
+ }
+#endif
+ std::string version ((const char *) glGetString (GL_VERSION));
+ std::stringstream stream (version);
+ unsigned major, minor;
+ char dot;
+
+ stream >> major >> dot >> minor;
+
+ assert (dot == '.');
+ return major > reqMajor || (major == reqMajor && minor >= reqMinor);
+ }
+} /* of namespace __HelperGL*/
+
+using namespace __HelperGL;
+
+#endif /*HELPER_GL_H*/
diff --git a/tests/projects/cuda_console/inc/helper_image.h b/tests/projects/cuda_console/inc/helper_image.h
new file mode 100644
index 000000000..4e8b25cdf
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_image.h
@@ -0,0 +1,1110 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+// These are helper functions for the SDK samples (image,bitmap)
+#ifndef HELPER_IMAGE_H
+#define HELPER_IMAGE_H
+
+#include <string>
+#include <fstream>
+#include <vector>
+#include <iostream>
+#include <algorithm>
+
+#include <assert.h>
+#include <exception.h>
+#include <math.h>
+
+#ifndef MIN
+#define MIN(a,b) ((a < b) ? a : b)
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a > b) ? a : b)
+#endif
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+#include <helper_string.h>
+
+// namespace unnamed (internal)
+namespace
+{
+ //! size of PGM file header
+ const unsigned int PGMHeaderSize = 0x40;
+
+ // types
+
+ //! Data converter from unsigned char / unsigned byte to type T
+ template<class T>
+ struct ConverterFromUByte;
+
+ //! Data converter from unsigned char / unsigned byte
+ template<>
+ struct ConverterFromUByte<unsigned char>
+ {
+ //! Conversion operator
+ //! @return converted value
+ //! @param val value to convert
+ float operator()(const unsigned char &val)
+ {
+ return static_cast<unsigned char>(val);
+ }
+ };
+
+ //! Data converter from unsigned char / unsigned byte to float
+ template<>
+ struct ConverterFromUByte<float>
+ {
+ //! Conversion operator
+ //! @return converted value
+ //! @param val value to convert
+ float operator()(const unsigned char &val)
+ {
+ return static_cast<float>(val) / 255.0f;
+ }
+ };
+
+ //! Data converter from unsigned char / unsigned byte to type T
+ template<class T>
+ struct ConverterToUByte;
+
+ //! Data converter from unsigned char / unsigned byte to unsigned int
+ template<>
+ struct ConverterToUByte<unsigned char>
+ {
+ //! Conversion operator (essentially a passthru
+ //! @return converted value
+ //! @param val value to convert
+ unsigned char operator()(const unsigned char &val)
+ {
+ return val;
+ }
+ };
+
+ //! Data converter from unsigned char / unsigned byte to unsigned int
+ template<>
+ struct ConverterToUByte<float>
+ {
+ //! Conversion operator
+ //! @return converted value
+ //! @param val value to convert
+ unsigned char operator()(const float &val)
+ {
+ return static_cast<unsigned char>(val * 255.0f);
+ }
+ };
+}
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#ifndef FOPEN
+#define FOPEN(fHandle,filename,mode) fopen_s(&fHandle, filename, mode)
+#endif
+#ifndef FOPEN_FAIL
+#define FOPEN_FAIL(result) (result != 0)
+#endif
+#ifndef SSCANF
+#define SSCANF sscanf_s
+#endif
+#else
+#ifndef FOPEN
+#define FOPEN(fHandle,filename,mode) (fHandle = fopen(filename, mode))
+#endif
+#ifndef FOPEN_FAIL
+#define FOPEN_FAIL(result) (result == NULL)
+#endif
+#ifndef SSCANF
+#define SSCANF sscanf
+#endif
+#endif
+
+inline bool
+__loadPPM(const char *file, unsigned char **data,
+ unsigned int *w, unsigned int *h, unsigned int *channels)
+{
+ FILE *fp = NULL;
+
+ if (FOPEN_FAIL(FOPEN(fp, file, "rb")))
+ {
+ std::cerr << "__LoadPPM() : Failed to open file: " << file << std::endl;
+ return false;
+ }
+
+ // check header
+ char header[PGMHeaderSize];
+
+ if (fgets(header, PGMHeaderSize, fp) == NULL)
+ {
+ std::cerr << "__LoadPPM() : reading PGM header returned NULL" << std::endl;
+ return false;
+ }
+
+ if (strncmp(header, "P5", 2) == 0)
+ {
+ *channels = 1;
+ }
+ else if (strncmp(header, "P6", 2) == 0)
+ {
+ *channels = 3;
+ }
+ else
+ {
+ std::cerr << "__LoadPPM() : File is not a PPM or PGM image" << std::endl;
+ *channels = 0;
+ return false;
+ }
+
+ // parse header, read maxval, width and height
+ unsigned int width = 0;
+ unsigned int height = 0;
+ unsigned int maxval = 0;
+ unsigned int i = 0;
+
+ while (i < 3)
+ {
+ if (fgets(header, PGMHeaderSize, fp) == NULL)
+ {
+ std::cerr << "__LoadPPM() : reading PGM header returned NULL" << std::endl;
+ return false;
+ }
+
+ if (header[0] == '#')
+ {
+ continue;
+ }
+
+ if (i == 0)
+ {
+ i += SSCANF(header, "%u %u %u", &width, &height, &maxval);
+ }
+ else if (i == 1)
+ {
+ i += SSCANF(header, "%u %u", &height, &maxval);
+ }
+ else if (i == 2)
+ {
+ i += SSCANF(header, "%u", &maxval);
+ }
+ }
+
+ // check if given handle for the data is initialized
+ if (NULL != *data)
+ {
+ if (*w != width || *h != height)
+ {
+ std::cerr << "__LoadPPM() : Invalid image dimensions." << std::endl;
+ }
+ }
+ else
+ {
+ *data = (unsigned char *) malloc(sizeof(unsigned char) * width * height **channels);
+ *w = width;
+ *h = height;
+ }
+
+ // read and close file
+ if (fread(*data, sizeof(unsigned char), width * height **channels, fp) == 0)
+ {
+ std::cerr << "__LoadPPM() read data returned error." << std::endl;
+ }
+
+ fclose(fp);
+
+ return true;
+}
+
+template <class T>
+inline bool
+sdkLoadPGM(const char *file, T **data, unsigned int *w, unsigned int *h)
+{
+ unsigned char *idata = NULL;
+ unsigned int channels;
+
+ if (true != __loadPPM(file, &idata, w, h, &channels))
+ {
+ return false;
+ }
+
+ unsigned int size = *w **h * channels;
+
+ // initialize mem if necessary
+ // the correct size is checked / set in loadPGMc()
+ if (NULL == *data)
+ {
+ *data = (T *) malloc(sizeof(T) * size);
+ }
+
+ // copy and cast data
+ std::transform(idata, idata + size, *data, ConverterFromUByte<T>());
+
+ free(idata);
+
+ return true;
+}
+
+template <class T>
+inline bool
+sdkLoadPPM4(const char *file, T **data,
+ unsigned int *w,unsigned int *h)
+{
+ unsigned char *idata = 0;
+ unsigned int channels;
+
+ if (__loadPPM(file, &idata, w, h, &channels))
+ {
+ // pad 4th component
+ int size = *w **h;
+ // keep the original pointer
+ unsigned char *idata_orig = idata;
+ *data = (T *) malloc(sizeof(T) * size * 4);
+ unsigned char *ptr = *data;
+
+ for (int i=0; i<size; i++)
+ {
+ *ptr++ = *idata++;
+ *ptr++ = *idata++;
+ *ptr++ = *idata++;
+ *ptr++ = 0;
+ }
+
+ free(idata_orig);
+ return true;
+ }
+ else
+ {
+ free(idata);
+ return false;
+ }
+}
+
+inline bool
+__savePPM(const char *file, unsigned char *data,
+ unsigned int w, unsigned int h, unsigned int channels)
+{
+ assert(NULL != data);
+ assert(w > 0);
+ assert(h > 0);
+
+ std::fstream fh(file, std::fstream::out | std::fstream::binary);
+
+ if (fh.bad())
+ {
+ std::cerr << "__savePPM() : Opening file failed." << std::endl;
+ return false;
+ }
+
+ if (channels == 1)
+ {
+ fh << "P5\n";
+ }
+ else if (channels == 3)
+ {
+ fh << "P6\n";
+ }
+ else
+ {
+ std::cerr << "__savePPM() : Invalid number of channels." << std::endl;
+ return false;
+ }
+
+ fh << w << "\n" << h << "\n" << 0xff << std::endl;
+
+ for (unsigned int i = 0; (i < (w*h*channels)) && fh.good(); ++i)
+ {
+ fh << data[i];
+ }
+
+ fh.flush();
+
+ if (fh.bad())
+ {
+ std::cerr << "__savePPM() : Writing data failed." << std::endl;
+ return false;
+ }
+
+ fh.close();
+
+ return true;
+}
+
+template<class T>
+inline bool
+sdkSavePGM(const char *file, T *data, unsigned int w, unsigned int h)
+{
+ unsigned int size = w * h;
+ unsigned char *idata =
+ (unsigned char *) malloc(sizeof(unsigned char) * size);
+
+ std::transform(data, data + size, idata, ConverterToUByte<T>());
+
+ // write file
+ bool result = __savePPM(file, idata, w, h, 1);
+
+ // cleanup
+ free(idata);
+
+ return result;
+}
+
+inline bool
+sdkSavePPM4ub(const char *file, unsigned char *data,
+ unsigned int w, unsigned int h)
+{
+ // strip 4th component
+ int size = w * h;
+ unsigned char *ndata = (unsigned char *) malloc(sizeof(unsigned char) * size*3);
+ unsigned char *ptr = ndata;
+
+ for (int i=0; i<size; i++)
+ {
+ *ptr++ = *data++;
+ *ptr++ = *data++;
+ *ptr++ = *data++;
+ data++;
+ }
+
+ bool result = __savePPM(file, ndata, w, h, 3);
+ free(ndata);
+ return result;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//! Read file \filename and return the data
+//! @return bool if reading the file succeeded, otherwise false
+//! @param filename name of the source file
+//! @param data uninitialized pointer, returned initialized and pointing to
+//! the data read
+//! @param len number of data elements in data, -1 on error
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+inline bool
+sdkReadFile(const char *filename, T **data, unsigned int *len, bool verbose)
+{
+ // check input arguments
+ assert(NULL != filename);
+ assert(NULL != len);
+
+ // intermediate storage for the data read
+ std::vector<T> data_read;
+
+ // open file for reading
+ FILE *fh = NULL;
+
+ // check if filestream is valid
+ if (FOPEN_FAIL(FOPEN(fh, filename, "r")))
+ {
+ printf("Unable to open input file: %s\n", filename);
+ return false;
+ }
+
+ // read all data elements
+ T token;
+
+ while (!feof(fh))
+ {
+ fscanf(fh, "%f", &token);
+ data_read.push_back(token);
+ }
+
+ // the last element is read twice
+ data_read.pop_back();
+ fclose(fh);
+
+ // check if the given handle is already initialized
+ if (NULL != *data)
+ {
+ if (*len != data_read.size())
+ {
+ std::cerr << "sdkReadFile() : Initialized memory given but "
+ << "size mismatch with signal read "
+ << "(data read / data init = " << (unsigned int)data_read.size()
+ << " / " << *len << ")" << std::endl;
+
+ return false;
+ }
+ }
+ else
+ {
+ // allocate storage for the data read
+ *data = (T *) malloc(sizeof(T) * data_read.size());
+ // store signal size
+ *len = static_cast<unsigned int>(data_read.size());
+ }
+
+ // copy data
+ memcpy(*data, &data_read.front(), sizeof(T) * data_read.size());
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//! Read file \filename and return the data
+//! @return bool if reading the file succeeded, otherwise false
+//! @param filename name of the source file
+//! @param data uninitialized pointer, returned initialized and pointing to
+//! the data read
+//! @param len number of data elements in data, -1 on error
+//////////////////////////////////////////////////////////////////////////////
+template<class T>
+inline bool
+sdkReadFileBlocks(const char *filename, T **data, unsigned int *len, unsigned int block_num, unsigned int block_size, bool verbose)
+{
+ // check input arguments
+ assert(NULL != filename);
+ assert(NULL != len);
+
+ // open file for reading
+ FILE *fh = fopen(filename, "rb");
+
+ if (fh == NULL && verbose)
+ {
+ std::cerr << "sdkReadFile() : Opening file failed." << std::endl;
+ return false;
+ }
+
+ // check if the given handle is already initialized
+ // allocate storage for the data read
+ data[block_num] = (T *) malloc(block_size);
+
+ // read all data elements
+ fseek(fh, block_num * block_size, SEEK_SET);
+ *len = fread(data[block_num], sizeof(T), block_size/sizeof(T), fh);
+
+ fclose(fh);
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//! Write a data file \filename
+//! @return true if writing the file succeeded, otherwise false
+//! @param filename name of the source file
+//! @param data data to write
+//! @param len number of data elements in data, -1 on error
+//! @param epsilon epsilon for comparison
+//////////////////////////////////////////////////////////////////////////////
+template<class T, class S>
+inline bool
+sdkWriteFile(const char *filename, const T *data, unsigned int len,
+ const S epsilon, bool verbose, bool append = false)
+{
+ assert(NULL != filename);
+ assert(NULL != data);
+
+ // open file for writing
+ // if (append) {
+ std::fstream fh(filename, std::fstream::out | std::fstream::ate);
+
+ if (verbose)
+ {
+ std::cerr << "sdkWriteFile() : Open file " << filename << " for write/append." << std::endl;
+ }
+
+ /* } else {
+ std::fstream fh(filename, std::fstream::out);
+ if (verbose) {
+ std::cerr << "sdkWriteFile() : Open file " << filename << " for write." << std::endl;
+ }
+ }
+ */
+
+ // check if filestream is valid
+ if (! fh.good())
+ {
+ if (verbose)
+ {
+ std::cerr << "sdkWriteFile() : Opening file failed." << std::endl;
+ }
+
+ return false;
+ }
+
+ // first write epsilon
+ fh << "# " << epsilon << "\n";
+
+ // write data
+ for (unsigned int i = 0; (i < len) && (fh.good()); ++i)
+ {
+ fh << data[i] << ' ';
+ }
+
+ // Check if writing succeeded
+ if (! fh.good())
+ {
+ if (verbose)
+ {
+ std::cerr << "sdkWriteFile() : Writing file failed." << std::endl;
+ }
+
+ return false;
+ }
+
+ // file ends with nl
+ fh << std::endl;
+
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//! Compare two arrays of arbitrary type
+//! @return true if \a reference and \a data are identical, otherwise false
+//! @param reference timer_interface to the reference data / gold image
+//! @param data handle to the computed data
+//! @param len number of elements in reference and data
+//! @param epsilon epsilon to use for the comparison
+//////////////////////////////////////////////////////////////////////////////
+template<class T, class S>
+inline bool
+compareData(const T *reference, const T *data, const unsigned int len,
+ const S epsilon, const float threshold)
+{
+ assert(epsilon >= 0);
+
+ bool result = true;
+ unsigned int error_count = 0;
+
+ for (unsigned int i = 0; i < len; ++i)
+ {
+ float diff = (float)reference[i] - (float)data[i];
+ bool comp = (diff <= epsilon) && (diff >= -epsilon);
+ result &= comp;
+
+ error_count += !comp;
+
+#if 0
+
+ if (! comp)
+ {
+ std::cerr << "ERROR, i = " << i << ",\t "
+ << reference[i] << " / "
+ << data[i]
+ << " (reference / data)\n";
+ }
+
+#endif
+ }
+
+ if (threshold == 0.0f)
+ {
+ return (result) ? true : false;
+ }
+ else
+ {
+ if (error_count)
+ {
+ printf("%4.2f(%%) of bytes mismatched (count=%d)\n", (float)error_count*100/(float)len, error_count);
+ }
+
+ return (len*threshold > error_count) ? true : false;
+ }
+}
+
+#ifndef __MIN_EPSILON_ERROR
+#define __MIN_EPSILON_ERROR 1e-3f
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//! Compare two arrays of arbitrary type
+//! @return true if \a reference and \a data are identical, otherwise false
+//! @param reference handle to the reference data / gold image
+//! @param data handle to the computed data
+//! @param len number of elements in reference and data
+//! @param epsilon epsilon to use for the comparison
+//! @param epsilon threshold % of (# of bytes) for pass/fail
+//////////////////////////////////////////////////////////////////////////////
+template<class T, class S>
+inline bool
+compareDataAsFloatThreshold(const T *reference, const T *data, const unsigned int len,
+ const S epsilon, const float threshold)
+{
+ assert(epsilon >= 0);
+
+ // If we set epsilon to be 0, let's set a minimum threshold
+ float max_error = MAX((float)epsilon, __MIN_EPSILON_ERROR);
+ int error_count = 0;
+ bool result = true;
+
+ for (unsigned int i = 0; i < len; ++i)
+ {
+ float diff = fabs((float)reference[i] - (float)data[i]);
+ bool comp = (diff < max_error);
+ result &= comp;
+
+ if (! comp)
+ {
+ error_count++;
+#if 0
+
+ if (error_count < 50)
+ {
+ printf("\n ERROR(epsilon=%4.3f), i=%d, (ref)0x%02x / (data)0x%02x / (diff)%d\n",
+ max_error, i,
+ *(unsigned int *)&reference[i],
+ *(unsigned int *)&data[i],
+ (unsigned int)diff);
+ }
+
+#endif
+ }
+ }
+
+ if (threshold == 0.0f)
+ {
+ if (error_count)
+ {
+ printf("total # of errors = %d\n", error_count);
+ }
+
+ return (error_count == 0) ? true : false;
+ }
+ else
+ {
+ if (error_count)
+ {
+ printf("%4.2f(%%) of bytes mismatched (count=%d)\n", (float)error_count*100/(float)len, error_count);
+ }
+
+ return ((len*threshold > error_count) ? true : false);
+ }
+}
+
+inline
+void sdkDumpBin(void *data, unsigned int bytes, const char *filename)
+{
+ printf("sdkDumpBin: <%s>\n", filename);
+ FILE *fp;
+ FOPEN(fp, filename, "wb");
+ fwrite(data, bytes, 1, fp);
+ fflush(fp);
+ fclose(fp);
+}
+
+inline
+bool sdkCompareBin2BinUint(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold, char *exec_path)
+{
+ unsigned int *src_buffer, *ref_buffer;
+ FILE *src_fp = NULL, *ref_fp = NULL;
+
+ unsigned long error_count = 0;
+ size_t fsize = 0;
+
+ if (FOPEN_FAIL(FOPEN(src_fp, src_file, "rb")))
+ {
+ printf("compareBin2Bin <unsigned int> unable to open src_file: %s\n", src_file);
+ error_count++;
+ }
+
+ char *ref_file_path = sdkFindFilePath(ref_file, exec_path);
+
+ if (ref_file_path == NULL)
+ {
+ printf("compareBin2Bin <unsigned int> unable to find <%s> in <%s>\n", ref_file, exec_path);
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ else
+ {
+ if (FOPEN_FAIL(FOPEN(ref_fp, ref_file_path, "rb")))
+ {
+ printf("compareBin2Bin <unsigned int> unable to open ref_file: %s\n", ref_file_path);
+ error_count++;
+ }
+
+ if (src_fp && ref_fp)
+ {
+ src_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int));
+ ref_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int));
+
+ fsize = fread(src_buffer, nelements, sizeof(unsigned int), src_fp);
+ fsize = fread(ref_buffer, nelements, sizeof(unsigned int), ref_fp);
+
+ printf("> compareBin2Bin <unsigned int> nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold);
+ printf(" src_file <%s>, size=%d bytes\n", src_file, (int)fsize);
+ printf(" ref_file <%s>, size=%d bytes\n", ref_file_path, (int)fsize);
+
+ if (!compareData<unsigned int, float>(ref_buffer, src_buffer, nelements, epsilon, threshold))
+ {
+ error_count++;
+ }
+
+ fclose(src_fp);
+ fclose(ref_fp);
+
+ free(src_buffer);
+ free(ref_buffer);
+ }
+ else
+ {
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+}
+
+inline
+bool sdkCompareBin2BinFloat(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold, char *exec_path)
+{
+ float *src_buffer, *ref_buffer;
+ FILE *src_fp = NULL, *ref_fp = NULL;
+ size_t fsize = 0;
+
+ unsigned long error_count = 0;
+
+ if (FOPEN_FAIL(FOPEN(src_fp, src_file, "rb")))
+ {
+ printf("compareBin2Bin <float> unable to open src_file: %s\n", src_file);
+ error_count = 1;
+ }
+
+ char *ref_file_path = sdkFindFilePath(ref_file, exec_path);
+
+ if (ref_file_path == NULL)
+ {
+ printf("compareBin2Bin <float> unable to find <%s> in <%s>\n", ref_file, exec_path);
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", exec_path);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ else
+ {
+ if (FOPEN_FAIL(FOPEN(ref_fp, ref_file_path, "rb")))
+ {
+ printf("compareBin2Bin <float> unable to open ref_file: %s\n", ref_file_path);
+ error_count = 1;
+ }
+
+ if (src_fp && ref_fp)
+ {
+ src_buffer = (float *)malloc(nelements*sizeof(float));
+ ref_buffer = (float *)malloc(nelements*sizeof(float));
+
+ fsize = fread(src_buffer, nelements, sizeof(float), src_fp);
+ fsize = fread(ref_buffer, nelements, sizeof(float), ref_fp);
+
+ printf("> compareBin2Bin <float> nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold);
+ printf(" src_file <%s>, size=%d bytes\n", src_file, (int)fsize);
+ printf(" ref_file <%s>, size=%d bytes\n", ref_file_path, (int)fsize);
+
+ if (!compareDataAsFloatThreshold<float, float>(ref_buffer, src_buffer, nelements, epsilon, threshold))
+ {
+ error_count++;
+ }
+
+ fclose(src_fp);
+ fclose(ref_fp);
+
+ free(src_buffer);
+ free(ref_buffer);
+ }
+ else
+ {
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+}
+
+inline bool
+sdkCompareL2fe(const float *reference, const float *data,
+ const unsigned int len, const float epsilon)
+{
+ assert(epsilon >= 0);
+
+ float error = 0;
+ float ref = 0;
+
+ for (unsigned int i = 0; i < len; ++i)
+ {
+
+ float diff = reference[i] - data[i];
+ error += diff * diff;
+ ref += reference[i] * reference[i];
+ }
+
+ float normRef = sqrtf(ref);
+
+ if (fabs(ref) < 1e-7)
+ {
+#ifdef _DEBUG
+ std::cerr << "ERROR, reference l2-norm is 0\n";
+#endif
+ return false;
+ }
+
+ float normError = sqrtf(error);
+ error = normError / normRef;
+ bool result = error < epsilon;
+#ifdef _DEBUG
+
+ if (! result)
+ {
+ std::cerr << "ERROR, l2-norm error "
+ << error << " is greater than epsilon " << epsilon << "\n";
+ }
+
+#endif
+
+ return result;
+}
+
+inline bool
+sdkLoadPPMub(const char *file, unsigned char **data,
+ unsigned int *w,unsigned int *h)
+{
+ unsigned int channels;
+ return __loadPPM(file, data, w, h, &channels);
+}
+
+inline bool
+sdkLoadPPM4ub(const char *file, unsigned char **data,
+ unsigned int *w, unsigned int *h)
+{
+ unsigned char *idata = 0;
+ unsigned int channels;
+
+ if (__loadPPM(file, &idata, w, h, &channels))
+ {
+ // pad 4th component
+ int size = *w **h;
+ // keep the original pointer
+ unsigned char *idata_orig = idata;
+ *data = (unsigned char *) malloc(sizeof(unsigned char) * size * 4);
+ unsigned char *ptr = *data;
+
+ for (int i=0; i<size; i++)
+ {
+ *ptr++ = *idata++;
+ *ptr++ = *idata++;
+ *ptr++ = *idata++;
+ *ptr++ = 0;
+ }
+
+ free(idata_orig);
+ return true;
+ }
+ else
+ {
+ free(idata);
+ return false;
+ }
+}
+
+
+inline bool
+sdkComparePPM(const char *src_file, const char *ref_file,
+ const float epsilon, const float threshold, bool verboseErrors)
+{
+ unsigned char *src_data, *ref_data;
+ unsigned long error_count = 0;
+ unsigned int ref_width, ref_height;
+ unsigned int src_width, src_height;
+
+ if (src_file == NULL || ref_file == NULL)
+ {
+ if (verboseErrors)
+ {
+ std::cerr << "PPMvsPPM: src_file or ref_file is NULL. Aborting comparison\n";
+ }
+
+ return false;
+ }
+
+ if (verboseErrors)
+ {
+ std::cerr << "> Compare (a)rendered: <" << src_file << ">\n";
+ std::cerr << "> (b)reference: <" << ref_file << ">\n";
+ }
+
+
+ if (sdkLoadPPM4ub(ref_file, &ref_data, &ref_width, &ref_height) != true)
+ {
+ if (verboseErrors)
+ {
+ std::cerr << "PPMvsPPM: unable to load ref image file: "<< ref_file << "\n";
+ }
+
+ return false;
+ }
+
+ if (sdkLoadPPM4ub(src_file, &src_data, &src_width, &src_height) != true)
+ {
+ std::cerr << "PPMvsPPM: unable to load src image file: " << src_file << "\n";
+ return false;
+ }
+
+ if (src_height != ref_height || src_width != ref_width)
+ {
+ if (verboseErrors) std::cerr << "PPMvsPPM: source and ref size mismatch (" << src_width <<
+ "," << src_height << ")vs(" << ref_width << "," << ref_height << ")\n";
+ }
+
+ if (verboseErrors) std::cerr << "PPMvsPPM: comparing images size (" << src_width <<
+ "," << src_height << ") epsilon(" << epsilon << "), threshold(" << threshold*100 << "%)\n";
+
+ if (compareData(ref_data, src_data, src_width*src_height*4, epsilon, threshold) == false)
+ {
+ error_count=1;
+ }
+
+ if (error_count == 0)
+ {
+ if (verboseErrors)
+ {
+ std::cerr << " OK\n\n";
+ }
+ }
+ else
+ {
+ if (verboseErrors)
+ {
+ std::cerr << " FAILURE! "<<error_count<<" errors...\n\n";
+ }
+ }
+
+ return (error_count == 0)? true : false; // returns true if all pixels pass
+}
+
+inline bool
+sdkComparePGM(const char *src_file, const char *ref_file,
+ const float epsilon, const float threshold, bool verboseErrors)
+{
+ unsigned char *src_data = 0, *ref_data = 0;
+ unsigned long error_count = 0;
+ unsigned int ref_width, ref_height;
+ unsigned int src_width, src_height;
+
+ if (src_file == NULL || ref_file == NULL)
+ {
+ if (verboseErrors)
+ {
+ std::cerr << "PGMvsPGM: src_file or ref_file is NULL. Aborting comparison\n";
+ }
+
+ return false;
+ }
+
+ if (verboseErrors)
+ {
+ std::cerr << "> Compare (a)rendered: <" << src_file << ">\n";
+ std::cerr << "> (b)reference: <" << ref_file << ">\n";
+ }
+
+
+ if (sdkLoadPPMub(ref_file, &ref_data, &ref_width, &ref_height) != true)
+ {
+ if (verboseErrors)
+ {
+ std::cerr << "PGMvsPGM: unable to load ref image file: "<< ref_file << "\n";
+ }
+
+ return false;
+ }
+
+ if (sdkLoadPPMub(src_file, &src_data, &src_width, &src_height) != true)
+ {
+ std::cerr << "PGMvsPGM: unable to load src image file: " << src_file << "\n";
+ return false;
+ }
+
+ if (src_height != ref_height || src_width != ref_width)
+ {
+ if (verboseErrors) std::cerr << "PGMvsPGM: source and ref size mismatch (" << src_width <<
+ "," << src_height << ")vs(" << ref_width << "," << ref_height << ")\n";
+ }
+
+ if (verboseErrors) std::cerr << "PGMvsPGM: comparing images size (" << src_width <<
+ "," << src_height << ") epsilon(" << epsilon << "), threshold(" << threshold*100 << "%)\n";
+
+ if (compareData(ref_data, src_data, src_width*src_height, epsilon, threshold) == false)
+ {
+ error_count=1;
+ }
+
+ if (error_count == 0)
+ {
+ if (verboseErrors)
+ {
+ std::cerr << " OK\n\n";
+ }
+ }
+ else
+ {
+ if (verboseErrors)
+ {
+ std::cerr << " FAILURE! "<<error_count<<" errors...\n\n";
+ }
+ }
+
+ return (error_count == 0)? true : false; // returns true if all pixels pass
+}
+
+#endif // HELPER_IMAGE_H
diff --git a/tests/projects/cuda_console/inc/helper_math.h b/tests/projects/cuda_console/inc/helper_math.h
new file mode 100644
index 000000000..c9c07c3e7
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_math.h
@@ -0,0 +1,1453 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+/*
+ * This file implements common mathematical operations on vector types
+ * (float3, float4 etc.) since these are not provided as standard by CUDA.
+ *
+ * The syntax is modeled on the Cg standard library.
+ *
+ * This is part of the Helper library includes
+ *
+ * Thanks to Linh Hah for additions and fixes.
+ */
+
+#ifndef HELPER_MATH_H
+#define HELPER_MATH_H
+
+#include "cuda_runtime.h"
+
+typedef unsigned int uint;
+typedef unsigned short ushort;
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+#ifndef __CUDACC__
+#include <math.h>
+
+////////////////////////////////////////////////////////////////////////////////
+// host implementations of CUDA functions
+////////////////////////////////////////////////////////////////////////////////
+
+inline float fminf(float a, float b)
+{
+ return a < b ? a : b;
+}
+
+inline float fmaxf(float a, float b)
+{
+ return a > b ? a : b;
+}
+
+inline int max(int a, int b)
+{
+ return a > b ? a : b;
+}
+
+inline int min(int a, int b)
+{
+ return a < b ? a : b;
+}
+
+inline float rsqrtf(float x)
+{
+ return 1.0f / sqrtf(x);
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// constructors
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 make_float2(float s)
+{
+ return make_float2(s, s);
+}
+inline __host__ __device__ float2 make_float2(float3 a)
+{
+ return make_float2(a.x, a.y);
+}
+inline __host__ __device__ float2 make_float2(int2 a)
+{
+ return make_float2(float(a.x), float(a.y));
+}
+inline __host__ __device__ float2 make_float2(uint2 a)
+{
+ return make_float2(float(a.x), float(a.y));
+}
+
+inline __host__ __device__ int2 make_int2(int s)
+{
+ return make_int2(s, s);
+}
+inline __host__ __device__ int2 make_int2(int3 a)
+{
+ return make_int2(a.x, a.y);
+}
+inline __host__ __device__ int2 make_int2(uint2 a)
+{
+ return make_int2(int(a.x), int(a.y));
+}
+inline __host__ __device__ int2 make_int2(float2 a)
+{
+ return make_int2(int(a.x), int(a.y));
+}
+
+inline __host__ __device__ uint2 make_uint2(uint s)
+{
+ return make_uint2(s, s);
+}
+inline __host__ __device__ uint2 make_uint2(uint3 a)
+{
+ return make_uint2(a.x, a.y);
+}
+inline __host__ __device__ uint2 make_uint2(int2 a)
+{
+ return make_uint2(uint(a.x), uint(a.y));
+}
+
+inline __host__ __device__ float3 make_float3(float s)
+{
+ return make_float3(s, s, s);
+}
+inline __host__ __device__ float3 make_float3(float2 a)
+{
+ return make_float3(a.x, a.y, 0.0f);
+}
+inline __host__ __device__ float3 make_float3(float2 a, float s)
+{
+ return make_float3(a.x, a.y, s);
+}
+inline __host__ __device__ float3 make_float3(float4 a)
+{
+ return make_float3(a.x, a.y, a.z);
+}
+inline __host__ __device__ float3 make_float3(int3 a)
+{
+ return make_float3(float(a.x), float(a.y), float(a.z));
+}
+inline __host__ __device__ float3 make_float3(uint3 a)
+{
+ return make_float3(float(a.x), float(a.y), float(a.z));
+}
+
+inline __host__ __device__ int3 make_int3(int s)
+{
+ return make_int3(s, s, s);
+}
+inline __host__ __device__ int3 make_int3(int2 a)
+{
+ return make_int3(a.x, a.y, 0);
+}
+inline __host__ __device__ int3 make_int3(int2 a, int s)
+{
+ return make_int3(a.x, a.y, s);
+}
+inline __host__ __device__ int3 make_int3(uint3 a)
+{
+ return make_int3(int(a.x), int(a.y), int(a.z));
+}
+inline __host__ __device__ int3 make_int3(float3 a)
+{
+ return make_int3(int(a.x), int(a.y), int(a.z));
+}
+
+inline __host__ __device__ uint3 make_uint3(uint s)
+{
+ return make_uint3(s, s, s);
+}
+inline __host__ __device__ uint3 make_uint3(uint2 a)
+{
+ return make_uint3(a.x, a.y, 0);
+}
+inline __host__ __device__ uint3 make_uint3(uint2 a, uint s)
+{
+ return make_uint3(a.x, a.y, s);
+}
+inline __host__ __device__ uint3 make_uint3(uint4 a)
+{
+ return make_uint3(a.x, a.y, a.z);
+}
+inline __host__ __device__ uint3 make_uint3(int3 a)
+{
+ return make_uint3(uint(a.x), uint(a.y), uint(a.z));
+}
+
+inline __host__ __device__ float4 make_float4(float s)
+{
+ return make_float4(s, s, s, s);
+}
+inline __host__ __device__ float4 make_float4(float3 a)
+{
+ return make_float4(a.x, a.y, a.z, 0.0f);
+}
+inline __host__ __device__ float4 make_float4(float3 a, float w)
+{
+ return make_float4(a.x, a.y, a.z, w);
+}
+inline __host__ __device__ float4 make_float4(int4 a)
+{
+ return make_float4(float(a.x), float(a.y), float(a.z), float(a.w));
+}
+inline __host__ __device__ float4 make_float4(uint4 a)
+{
+ return make_float4(float(a.x), float(a.y), float(a.z), float(a.w));
+}
+
+inline __host__ __device__ int4 make_int4(int s)
+{
+ return make_int4(s, s, s, s);
+}
+inline __host__ __device__ int4 make_int4(int3 a)
+{
+ return make_int4(a.x, a.y, a.z, 0);
+}
+inline __host__ __device__ int4 make_int4(int3 a, int w)
+{
+ return make_int4(a.x, a.y, a.z, w);
+}
+inline __host__ __device__ int4 make_int4(uint4 a)
+{
+ return make_int4(int(a.x), int(a.y), int(a.z), int(a.w));
+}
+inline __host__ __device__ int4 make_int4(float4 a)
+{
+ return make_int4(int(a.x), int(a.y), int(a.z), int(a.w));
+}
+
+
+inline __host__ __device__ uint4 make_uint4(uint s)
+{
+ return make_uint4(s, s, s, s);
+}
+inline __host__ __device__ uint4 make_uint4(uint3 a)
+{
+ return make_uint4(a.x, a.y, a.z, 0);
+}
+inline __host__ __device__ uint4 make_uint4(uint3 a, uint w)
+{
+ return make_uint4(a.x, a.y, a.z, w);
+}
+inline __host__ __device__ uint4 make_uint4(int4 a)
+{
+ return make_uint4(uint(a.x), uint(a.y), uint(a.z), uint(a.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// negate
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 operator-(float2 &a)
+{
+ return make_float2(-a.x, -a.y);
+}
+inline __host__ __device__ int2 operator-(int2 &a)
+{
+ return make_int2(-a.x, -a.y);
+}
+inline __host__ __device__ float3 operator-(float3 &a)
+{
+ return make_float3(-a.x, -a.y, -a.z);
+}
+inline __host__ __device__ int3 operator-(int3 &a)
+{
+ return make_int3(-a.x, -a.y, -a.z);
+}
+inline __host__ __device__ float4 operator-(float4 &a)
+{
+ return make_float4(-a.x, -a.y, -a.z, -a.w);
+}
+inline __host__ __device__ int4 operator-(int4 &a)
+{
+ return make_int4(-a.x, -a.y, -a.z, -a.w);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// addition
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 operator+(float2 a, float2 b)
+{
+ return make_float2(a.x + b.x, a.y + b.y);
+}
+inline __host__ __device__ void operator+=(float2 &a, float2 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+}
+inline __host__ __device__ float2 operator+(float2 a, float b)
+{
+ return make_float2(a.x + b, a.y + b);
+}
+inline __host__ __device__ float2 operator+(float b, float2 a)
+{
+ return make_float2(a.x + b, a.y + b);
+}
+inline __host__ __device__ void operator+=(float2 &a, float b)
+{
+ a.x += b;
+ a.y += b;
+}
+
+inline __host__ __device__ int2 operator+(int2 a, int2 b)
+{
+ return make_int2(a.x + b.x, a.y + b.y);
+}
+inline __host__ __device__ void operator+=(int2 &a, int2 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+}
+inline __host__ __device__ int2 operator+(int2 a, int b)
+{
+ return make_int2(a.x + b, a.y + b);
+}
+inline __host__ __device__ int2 operator+(int b, int2 a)
+{
+ return make_int2(a.x + b, a.y + b);
+}
+inline __host__ __device__ void operator+=(int2 &a, int b)
+{
+ a.x += b;
+ a.y += b;
+}
+
+inline __host__ __device__ uint2 operator+(uint2 a, uint2 b)
+{
+ return make_uint2(a.x + b.x, a.y + b.y);
+}
+inline __host__ __device__ void operator+=(uint2 &a, uint2 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+}
+inline __host__ __device__ uint2 operator+(uint2 a, uint b)
+{
+ return make_uint2(a.x + b, a.y + b);
+}
+inline __host__ __device__ uint2 operator+(uint b, uint2 a)
+{
+ return make_uint2(a.x + b, a.y + b);
+}
+inline __host__ __device__ void operator+=(uint2 &a, uint b)
+{
+ a.x += b;
+ a.y += b;
+}
+
+
+inline __host__ __device__ float3 operator+(float3 a, float3 b)
+{
+ return make_float3(a.x + b.x, a.y + b.y, a.z + b.z);
+}
+inline __host__ __device__ void operator+=(float3 &a, float3 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+}
+inline __host__ __device__ float3 operator+(float3 a, float b)
+{
+ return make_float3(a.x + b, a.y + b, a.z + b);
+}
+inline __host__ __device__ void operator+=(float3 &a, float b)
+{
+ a.x += b;
+ a.y += b;
+ a.z += b;
+}
+
+inline __host__ __device__ int3 operator+(int3 a, int3 b)
+{
+ return make_int3(a.x + b.x, a.y + b.y, a.z + b.z);
+}
+inline __host__ __device__ void operator+=(int3 &a, int3 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+}
+inline __host__ __device__ int3 operator+(int3 a, int b)
+{
+ return make_int3(a.x + b, a.y + b, a.z + b);
+}
+inline __host__ __device__ void operator+=(int3 &a, int b)
+{
+ a.x += b;
+ a.y += b;
+ a.z += b;
+}
+
+inline __host__ __device__ uint3 operator+(uint3 a, uint3 b)
+{
+ return make_uint3(a.x + b.x, a.y + b.y, a.z + b.z);
+}
+inline __host__ __device__ void operator+=(uint3 &a, uint3 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+}
+inline __host__ __device__ uint3 operator+(uint3 a, uint b)
+{
+ return make_uint3(a.x + b, a.y + b, a.z + b);
+}
+inline __host__ __device__ void operator+=(uint3 &a, uint b)
+{
+ a.x += b;
+ a.y += b;
+ a.z += b;
+}
+
+inline __host__ __device__ int3 operator+(int b, int3 a)
+{
+ return make_int3(a.x + b, a.y + b, a.z + b);
+}
+inline __host__ __device__ uint3 operator+(uint b, uint3 a)
+{
+ return make_uint3(a.x + b, a.y + b, a.z + b);
+}
+inline __host__ __device__ float3 operator+(float b, float3 a)
+{
+ return make_float3(a.x + b, a.y + b, a.z + b);
+}
+
+inline __host__ __device__ float4 operator+(float4 a, float4 b)
+{
+ return make_float4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+}
+inline __host__ __device__ void operator+=(float4 &a, float4 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+ a.w += b.w;
+}
+inline __host__ __device__ float4 operator+(float4 a, float b)
+{
+ return make_float4(a.x + b, a.y + b, a.z + b, a.w + b);
+}
+inline __host__ __device__ float4 operator+(float b, float4 a)
+{
+ return make_float4(a.x + b, a.y + b, a.z + b, a.w + b);
+}
+inline __host__ __device__ void operator+=(float4 &a, float b)
+{
+ a.x += b;
+ a.y += b;
+ a.z += b;
+ a.w += b;
+}
+
+inline __host__ __device__ int4 operator+(int4 a, int4 b)
+{
+ return make_int4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+}
+inline __host__ __device__ void operator+=(int4 &a, int4 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+ a.w += b.w;
+}
+inline __host__ __device__ int4 operator+(int4 a, int b)
+{
+ return make_int4(a.x + b, a.y + b, a.z + b, a.w + b);
+}
+inline __host__ __device__ int4 operator+(int b, int4 a)
+{
+ return make_int4(a.x + b, a.y + b, a.z + b, a.w + b);
+}
+inline __host__ __device__ void operator+=(int4 &a, int b)
+{
+ a.x += b;
+ a.y += b;
+ a.z += b;
+ a.w += b;
+}
+
+inline __host__ __device__ uint4 operator+(uint4 a, uint4 b)
+{
+ return make_uint4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
+}
+inline __host__ __device__ void operator+=(uint4 &a, uint4 b)
+{
+ a.x += b.x;
+ a.y += b.y;
+ a.z += b.z;
+ a.w += b.w;
+}
+inline __host__ __device__ uint4 operator+(uint4 a, uint b)
+{
+ return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b);
+}
+inline __host__ __device__ uint4 operator+(uint b, uint4 a)
+{
+ return make_uint4(a.x + b, a.y + b, a.z + b, a.w + b);
+}
+inline __host__ __device__ void operator+=(uint4 &a, uint b)
+{
+ a.x += b;
+ a.y += b;
+ a.z += b;
+ a.w += b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// subtract
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 operator-(float2 a, float2 b)
+{
+ return make_float2(a.x - b.x, a.y - b.y);
+}
+inline __host__ __device__ void operator-=(float2 &a, float2 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+}
+inline __host__ __device__ float2 operator-(float2 a, float b)
+{
+ return make_float2(a.x - b, a.y - b);
+}
+inline __host__ __device__ float2 operator-(float b, float2 a)
+{
+ return make_float2(b - a.x, b - a.y);
+}
+inline __host__ __device__ void operator-=(float2 &a, float b)
+{
+ a.x -= b;
+ a.y -= b;
+}
+
+inline __host__ __device__ int2 operator-(int2 a, int2 b)
+{
+ return make_int2(a.x - b.x, a.y - b.y);
+}
+inline __host__ __device__ void operator-=(int2 &a, int2 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+}
+inline __host__ __device__ int2 operator-(int2 a, int b)
+{
+ return make_int2(a.x - b, a.y - b);
+}
+inline __host__ __device__ int2 operator-(int b, int2 a)
+{
+ return make_int2(b - a.x, b - a.y);
+}
+inline __host__ __device__ void operator-=(int2 &a, int b)
+{
+ a.x -= b;
+ a.y -= b;
+}
+
+inline __host__ __device__ uint2 operator-(uint2 a, uint2 b)
+{
+ return make_uint2(a.x - b.x, a.y - b.y);
+}
+inline __host__ __device__ void operator-=(uint2 &a, uint2 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+}
+inline __host__ __device__ uint2 operator-(uint2 a, uint b)
+{
+ return make_uint2(a.x - b, a.y - b);
+}
+inline __host__ __device__ uint2 operator-(uint b, uint2 a)
+{
+ return make_uint2(b - a.x, b - a.y);
+}
+inline __host__ __device__ void operator-=(uint2 &a, uint b)
+{
+ a.x -= b;
+ a.y -= b;
+}
+
+inline __host__ __device__ float3 operator-(float3 a, float3 b)
+{
+ return make_float3(a.x - b.x, a.y - b.y, a.z - b.z);
+}
+inline __host__ __device__ void operator-=(float3 &a, float3 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ a.z -= b.z;
+}
+inline __host__ __device__ float3 operator-(float3 a, float b)
+{
+ return make_float3(a.x - b, a.y - b, a.z - b);
+}
+inline __host__ __device__ float3 operator-(float b, float3 a)
+{
+ return make_float3(b - a.x, b - a.y, b - a.z);
+}
+inline __host__ __device__ void operator-=(float3 &a, float b)
+{
+ a.x -= b;
+ a.y -= b;
+ a.z -= b;
+}
+
+inline __host__ __device__ int3 operator-(int3 a, int3 b)
+{
+ return make_int3(a.x - b.x, a.y - b.y, a.z - b.z);
+}
+inline __host__ __device__ void operator-=(int3 &a, int3 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ a.z -= b.z;
+}
+inline __host__ __device__ int3 operator-(int3 a, int b)
+{
+ return make_int3(a.x - b, a.y - b, a.z - b);
+}
+inline __host__ __device__ int3 operator-(int b, int3 a)
+{
+ return make_int3(b - a.x, b - a.y, b - a.z);
+}
+inline __host__ __device__ void operator-=(int3 &a, int b)
+{
+ a.x -= b;
+ a.y -= b;
+ a.z -= b;
+}
+
+inline __host__ __device__ uint3 operator-(uint3 a, uint3 b)
+{
+ return make_uint3(a.x - b.x, a.y - b.y, a.z - b.z);
+}
+inline __host__ __device__ void operator-=(uint3 &a, uint3 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ a.z -= b.z;
+}
+inline __host__ __device__ uint3 operator-(uint3 a, uint b)
+{
+ return make_uint3(a.x - b, a.y - b, a.z - b);
+}
+inline __host__ __device__ uint3 operator-(uint b, uint3 a)
+{
+ return make_uint3(b - a.x, b - a.y, b - a.z);
+}
+inline __host__ __device__ void operator-=(uint3 &a, uint b)
+{
+ a.x -= b;
+ a.y -= b;
+ a.z -= b;
+}
+
+inline __host__ __device__ float4 operator-(float4 a, float4 b)
+{
+ return make_float4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+}
+inline __host__ __device__ void operator-=(float4 &a, float4 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ a.z -= b.z;
+ a.w -= b.w;
+}
+inline __host__ __device__ float4 operator-(float4 a, float b)
+{
+ return make_float4(a.x - b, a.y - b, a.z - b, a.w - b);
+}
+inline __host__ __device__ void operator-=(float4 &a, float b)
+{
+ a.x -= b;
+ a.y -= b;
+ a.z -= b;
+ a.w -= b;
+}
+
+inline __host__ __device__ int4 operator-(int4 a, int4 b)
+{
+ return make_int4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+}
+inline __host__ __device__ void operator-=(int4 &a, int4 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ a.z -= b.z;
+ a.w -= b.w;
+}
+inline __host__ __device__ int4 operator-(int4 a, int b)
+{
+ return make_int4(a.x - b, a.y - b, a.z - b, a.w - b);
+}
+inline __host__ __device__ int4 operator-(int b, int4 a)
+{
+ return make_int4(b - a.x, b - a.y, b - a.z, b - a.w);
+}
+inline __host__ __device__ void operator-=(int4 &a, int b)
+{
+ a.x -= b;
+ a.y -= b;
+ a.z -= b;
+ a.w -= b;
+}
+
+inline __host__ __device__ uint4 operator-(uint4 a, uint4 b)
+{
+ return make_uint4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
+}
+inline __host__ __device__ void operator-=(uint4 &a, uint4 b)
+{
+ a.x -= b.x;
+ a.y -= b.y;
+ a.z -= b.z;
+ a.w -= b.w;
+}
+inline __host__ __device__ uint4 operator-(uint4 a, uint b)
+{
+ return make_uint4(a.x - b, a.y - b, a.z - b, a.w - b);
+}
+inline __host__ __device__ uint4 operator-(uint b, uint4 a)
+{
+ return make_uint4(b - a.x, b - a.y, b - a.z, b - a.w);
+}
+inline __host__ __device__ void operator-=(uint4 &a, uint b)
+{
+ a.x -= b;
+ a.y -= b;
+ a.z -= b;
+ a.w -= b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// multiply
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 operator*(float2 a, float2 b)
+{
+ return make_float2(a.x * b.x, a.y * b.y);
+}
+inline __host__ __device__ void operator*=(float2 &a, float2 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+}
+inline __host__ __device__ float2 operator*(float2 a, float b)
+{
+ return make_float2(a.x * b, a.y * b);
+}
+inline __host__ __device__ float2 operator*(float b, float2 a)
+{
+ return make_float2(b * a.x, b * a.y);
+}
+inline __host__ __device__ void operator*=(float2 &a, float b)
+{
+ a.x *= b;
+ a.y *= b;
+}
+
+inline __host__ __device__ int2 operator*(int2 a, int2 b)
+{
+ return make_int2(a.x * b.x, a.y * b.y);
+}
+inline __host__ __device__ void operator*=(int2 &a, int2 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+}
+inline __host__ __device__ int2 operator*(int2 a, int b)
+{
+ return make_int2(a.x * b, a.y * b);
+}
+inline __host__ __device__ int2 operator*(int b, int2 a)
+{
+ return make_int2(b * a.x, b * a.y);
+}
+inline __host__ __device__ void operator*=(int2 &a, int b)
+{
+ a.x *= b;
+ a.y *= b;
+}
+
+inline __host__ __device__ uint2 operator*(uint2 a, uint2 b)
+{
+ return make_uint2(a.x * b.x, a.y * b.y);
+}
+inline __host__ __device__ void operator*=(uint2 &a, uint2 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+}
+inline __host__ __device__ uint2 operator*(uint2 a, uint b)
+{
+ return make_uint2(a.x * b, a.y * b);
+}
+inline __host__ __device__ uint2 operator*(uint b, uint2 a)
+{
+ return make_uint2(b * a.x, b * a.y);
+}
+inline __host__ __device__ void operator*=(uint2 &a, uint b)
+{
+ a.x *= b;
+ a.y *= b;
+}
+
+inline __host__ __device__ float3 operator*(float3 a, float3 b)
+{
+ return make_float3(a.x * b.x, a.y * b.y, a.z * b.z);
+}
+inline __host__ __device__ void operator*=(float3 &a, float3 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+ a.z *= b.z;
+}
+inline __host__ __device__ float3 operator*(float3 a, float b)
+{
+ return make_float3(a.x * b, a.y * b, a.z * b);
+}
+inline __host__ __device__ float3 operator*(float b, float3 a)
+{
+ return make_float3(b * a.x, b * a.y, b * a.z);
+}
+inline __host__ __device__ void operator*=(float3 &a, float b)
+{
+ a.x *= b;
+ a.y *= b;
+ a.z *= b;
+}
+
+inline __host__ __device__ int3 operator*(int3 a, int3 b)
+{
+ return make_int3(a.x * b.x, a.y * b.y, a.z * b.z);
+}
+inline __host__ __device__ void operator*=(int3 &a, int3 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+ a.z *= b.z;
+}
+inline __host__ __device__ int3 operator*(int3 a, int b)
+{
+ return make_int3(a.x * b, a.y * b, a.z * b);
+}
+inline __host__ __device__ int3 operator*(int b, int3 a)
+{
+ return make_int3(b * a.x, b * a.y, b * a.z);
+}
+inline __host__ __device__ void operator*=(int3 &a, int b)
+{
+ a.x *= b;
+ a.y *= b;
+ a.z *= b;
+}
+
+inline __host__ __device__ uint3 operator*(uint3 a, uint3 b)
+{
+ return make_uint3(a.x * b.x, a.y * b.y, a.z * b.z);
+}
+inline __host__ __device__ void operator*=(uint3 &a, uint3 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+ a.z *= b.z;
+}
+inline __host__ __device__ uint3 operator*(uint3 a, uint b)
+{
+ return make_uint3(a.x * b, a.y * b, a.z * b);
+}
+inline __host__ __device__ uint3 operator*(uint b, uint3 a)
+{
+ return make_uint3(b * a.x, b * a.y, b * a.z);
+}
+inline __host__ __device__ void operator*=(uint3 &a, uint b)
+{
+ a.x *= b;
+ a.y *= b;
+ a.z *= b;
+}
+
+inline __host__ __device__ float4 operator*(float4 a, float4 b)
+{
+ return make_float4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
+}
+inline __host__ __device__ void operator*=(float4 &a, float4 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+ a.z *= b.z;
+ a.w *= b.w;
+}
+inline __host__ __device__ float4 operator*(float4 a, float b)
+{
+ return make_float4(a.x * b, a.y * b, a.z * b, a.w * b);
+}
+inline __host__ __device__ float4 operator*(float b, float4 a)
+{
+ return make_float4(b * a.x, b * a.y, b * a.z, b * a.w);
+}
+inline __host__ __device__ void operator*=(float4 &a, float b)
+{
+ a.x *= b;
+ a.y *= b;
+ a.z *= b;
+ a.w *= b;
+}
+
+inline __host__ __device__ int4 operator*(int4 a, int4 b)
+{
+ return make_int4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
+}
+inline __host__ __device__ void operator*=(int4 &a, int4 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+ a.z *= b.z;
+ a.w *= b.w;
+}
+inline __host__ __device__ int4 operator*(int4 a, int b)
+{
+ return make_int4(a.x * b, a.y * b, a.z * b, a.w * b);
+}
+inline __host__ __device__ int4 operator*(int b, int4 a)
+{
+ return make_int4(b * a.x, b * a.y, b * a.z, b * a.w);
+}
+inline __host__ __device__ void operator*=(int4 &a, int b)
+{
+ a.x *= b;
+ a.y *= b;
+ a.z *= b;
+ a.w *= b;
+}
+
+inline __host__ __device__ uint4 operator*(uint4 a, uint4 b)
+{
+ return make_uint4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w);
+}
+inline __host__ __device__ void operator*=(uint4 &a, uint4 b)
+{
+ a.x *= b.x;
+ a.y *= b.y;
+ a.z *= b.z;
+ a.w *= b.w;
+}
+inline __host__ __device__ uint4 operator*(uint4 a, uint b)
+{
+ return make_uint4(a.x * b, a.y * b, a.z * b, a.w * b);
+}
+inline __host__ __device__ uint4 operator*(uint b, uint4 a)
+{
+ return make_uint4(b * a.x, b * a.y, b * a.z, b * a.w);
+}
+inline __host__ __device__ void operator*=(uint4 &a, uint b)
+{
+ a.x *= b;
+ a.y *= b;
+ a.z *= b;
+ a.w *= b;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// divide
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 operator/(float2 a, float2 b)
+{
+ return make_float2(a.x / b.x, a.y / b.y);
+}
+inline __host__ __device__ void operator/=(float2 &a, float2 b)
+{
+ a.x /= b.x;
+ a.y /= b.y;
+}
+inline __host__ __device__ float2 operator/(float2 a, float b)
+{
+ return make_float2(a.x / b, a.y / b);
+}
+inline __host__ __device__ void operator/=(float2 &a, float b)
+{
+ a.x /= b;
+ a.y /= b;
+}
+inline __host__ __device__ float2 operator/(float b, float2 a)
+{
+ return make_float2(b / a.x, b / a.y);
+}
+
+inline __host__ __device__ float3 operator/(float3 a, float3 b)
+{
+ return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
+}
+inline __host__ __device__ void operator/=(float3 &a, float3 b)
+{
+ a.x /= b.x;
+ a.y /= b.y;
+ a.z /= b.z;
+}
+inline __host__ __device__ float3 operator/(float3 a, float b)
+{
+ return make_float3(a.x / b, a.y / b, a.z / b);
+}
+inline __host__ __device__ void operator/=(float3 &a, float b)
+{
+ a.x /= b;
+ a.y /= b;
+ a.z /= b;
+}
+inline __host__ __device__ float3 operator/(float b, float3 a)
+{
+ return make_float3(b / a.x, b / a.y, b / a.z);
+}
+
+inline __host__ __device__ float4 operator/(float4 a, float4 b)
+{
+ return make_float4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w);
+}
+inline __host__ __device__ void operator/=(float4 &a, float4 b)
+{
+ a.x /= b.x;
+ a.y /= b.y;
+ a.z /= b.z;
+ a.w /= b.w;
+}
+inline __host__ __device__ float4 operator/(float4 a, float b)
+{
+ return make_float4(a.x / b, a.y / b, a.z / b, a.w / b);
+}
+inline __host__ __device__ void operator/=(float4 &a, float b)
+{
+ a.x /= b;
+ a.y /= b;
+ a.z /= b;
+ a.w /= b;
+}
+inline __host__ __device__ float4 operator/(float b, float4 a)
+{
+ return make_float4(b / a.x, b / a.y, b / a.z, b / a.w);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// min
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 fminf(float2 a, float2 b)
+{
+ return make_float2(fminf(a.x,b.x), fminf(a.y,b.y));
+}
+inline __host__ __device__ float3 fminf(float3 a, float3 b)
+{
+ return make_float3(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z));
+}
+inline __host__ __device__ float4 fminf(float4 a, float4 b)
+{
+ return make_float4(fminf(a.x,b.x), fminf(a.y,b.y), fminf(a.z,b.z), fminf(a.w,b.w));
+}
+
+inline __host__ __device__ int2 min(int2 a, int2 b)
+{
+ return make_int2(min(a.x,b.x), min(a.y,b.y));
+}
+inline __host__ __device__ int3 min(int3 a, int3 b)
+{
+ return make_int3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
+}
+inline __host__ __device__ int4 min(int4 a, int4 b)
+{
+ return make_int4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w));
+}
+
+inline __host__ __device__ uint2 min(uint2 a, uint2 b)
+{
+ return make_uint2(min(a.x,b.x), min(a.y,b.y));
+}
+inline __host__ __device__ uint3 min(uint3 a, uint3 b)
+{
+ return make_uint3(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z));
+}
+inline __host__ __device__ uint4 min(uint4 a, uint4 b)
+{
+ return make_uint4(min(a.x,b.x), min(a.y,b.y), min(a.z,b.z), min(a.w,b.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// max
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 fmaxf(float2 a, float2 b)
+{
+ return make_float2(fmaxf(a.x,b.x), fmaxf(a.y,b.y));
+}
+inline __host__ __device__ float3 fmaxf(float3 a, float3 b)
+{
+ return make_float3(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z));
+}
+inline __host__ __device__ float4 fmaxf(float4 a, float4 b)
+{
+ return make_float4(fmaxf(a.x,b.x), fmaxf(a.y,b.y), fmaxf(a.z,b.z), fmaxf(a.w,b.w));
+}
+
+inline __host__ __device__ int2 max(int2 a, int2 b)
+{
+ return make_int2(max(a.x,b.x), max(a.y,b.y));
+}
+inline __host__ __device__ int3 max(int3 a, int3 b)
+{
+ return make_int3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
+}
+inline __host__ __device__ int4 max(int4 a, int4 b)
+{
+ return make_int4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w));
+}
+
+inline __host__ __device__ uint2 max(uint2 a, uint2 b)
+{
+ return make_uint2(max(a.x,b.x), max(a.y,b.y));
+}
+inline __host__ __device__ uint3 max(uint3 a, uint3 b)
+{
+ return make_uint3(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z));
+}
+inline __host__ __device__ uint4 max(uint4 a, uint4 b)
+{
+ return make_uint4(max(a.x,b.x), max(a.y,b.y), max(a.z,b.z), max(a.w,b.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// lerp
+// - linear interpolation between a and b, based on value t in [0, 1] range
+////////////////////////////////////////////////////////////////////////////////
+
+inline __device__ __host__ float lerp(float a, float b, float t)
+{
+ return a + t*(b-a);
+}
+inline __device__ __host__ float2 lerp(float2 a, float2 b, float t)
+{
+ return a + t*(b-a);
+}
+inline __device__ __host__ float3 lerp(float3 a, float3 b, float t)
+{
+ return a + t*(b-a);
+}
+inline __device__ __host__ float4 lerp(float4 a, float4 b, float t)
+{
+ return a + t*(b-a);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// clamp
+// - clamp the value v to be in the range [a, b]
+////////////////////////////////////////////////////////////////////////////////
+
+inline __device__ __host__ float clamp(float f, float a, float b)
+{
+ return fmaxf(a, fminf(f, b));
+}
+inline __device__ __host__ int clamp(int f, int a, int b)
+{
+ return max(a, min(f, b));
+}
+inline __device__ __host__ uint clamp(uint f, uint a, uint b)
+{
+ return max(a, min(f, b));
+}
+
+inline __device__ __host__ float2 clamp(float2 v, float a, float b)
+{
+ return make_float2(clamp(v.x, a, b), clamp(v.y, a, b));
+}
+inline __device__ __host__ float2 clamp(float2 v, float2 a, float2 b)
+{
+ return make_float2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
+}
+inline __device__ __host__ float3 clamp(float3 v, float a, float b)
+{
+ return make_float3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
+}
+inline __device__ __host__ float3 clamp(float3 v, float3 a, float3 b)
+{
+ return make_float3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
+}
+inline __device__ __host__ float4 clamp(float4 v, float a, float b)
+{
+ return make_float4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
+}
+inline __device__ __host__ float4 clamp(float4 v, float4 a, float4 b)
+{
+ return make_float4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
+}
+
+inline __device__ __host__ int2 clamp(int2 v, int a, int b)
+{
+ return make_int2(clamp(v.x, a, b), clamp(v.y, a, b));
+}
+inline __device__ __host__ int2 clamp(int2 v, int2 a, int2 b)
+{
+ return make_int2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
+}
+inline __device__ __host__ int3 clamp(int3 v, int a, int b)
+{
+ return make_int3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
+}
+inline __device__ __host__ int3 clamp(int3 v, int3 a, int3 b)
+{
+ return make_int3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
+}
+inline __device__ __host__ int4 clamp(int4 v, int a, int b)
+{
+ return make_int4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
+}
+inline __device__ __host__ int4 clamp(int4 v, int4 a, int4 b)
+{
+ return make_int4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
+}
+
+inline __device__ __host__ uint2 clamp(uint2 v, uint a, uint b)
+{
+ return make_uint2(clamp(v.x, a, b), clamp(v.y, a, b));
+}
+inline __device__ __host__ uint2 clamp(uint2 v, uint2 a, uint2 b)
+{
+ return make_uint2(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y));
+}
+inline __device__ __host__ uint3 clamp(uint3 v, uint a, uint b)
+{
+ return make_uint3(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b));
+}
+inline __device__ __host__ uint3 clamp(uint3 v, uint3 a, uint3 b)
+{
+ return make_uint3(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z));
+}
+inline __device__ __host__ uint4 clamp(uint4 v, uint a, uint b)
+{
+ return make_uint4(clamp(v.x, a, b), clamp(v.y, a, b), clamp(v.z, a, b), clamp(v.w, a, b));
+}
+inline __device__ __host__ uint4 clamp(uint4 v, uint4 a, uint4 b)
+{
+ return make_uint4(clamp(v.x, a.x, b.x), clamp(v.y, a.y, b.y), clamp(v.z, a.z, b.z), clamp(v.w, a.w, b.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// dot product
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float dot(float2 a, float2 b)
+{
+ return a.x * b.x + a.y * b.y;
+}
+inline __host__ __device__ float dot(float3 a, float3 b)
+{
+ return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+inline __host__ __device__ float dot(float4 a, float4 b)
+{
+ return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
+}
+
+inline __host__ __device__ int dot(int2 a, int2 b)
+{
+ return a.x * b.x + a.y * b.y;
+}
+inline __host__ __device__ int dot(int3 a, int3 b)
+{
+ return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+inline __host__ __device__ int dot(int4 a, int4 b)
+{
+ return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
+}
+
+inline __host__ __device__ uint dot(uint2 a, uint2 b)
+{
+ return a.x * b.x + a.y * b.y;
+}
+inline __host__ __device__ uint dot(uint3 a, uint3 b)
+{
+ return a.x * b.x + a.y * b.y + a.z * b.z;
+}
+inline __host__ __device__ uint dot(uint4 a, uint4 b)
+{
+ return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// length
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float length(float2 v)
+{
+ return sqrtf(dot(v, v));
+}
+inline __host__ __device__ float length(float3 v)
+{
+ return sqrtf(dot(v, v));
+}
+inline __host__ __device__ float length(float4 v)
+{
+ return sqrtf(dot(v, v));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// normalize
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 normalize(float2 v)
+{
+ float invLen = rsqrtf(dot(v, v));
+ return v * invLen;
+}
+inline __host__ __device__ float3 normalize(float3 v)
+{
+ float invLen = rsqrtf(dot(v, v));
+ return v * invLen;
+}
+inline __host__ __device__ float4 normalize(float4 v)
+{
+ float invLen = rsqrtf(dot(v, v));
+ return v * invLen;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// floor
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 floorf(float2 v)
+{
+ return make_float2(floorf(v.x), floorf(v.y));
+}
+inline __host__ __device__ float3 floorf(float3 v)
+{
+ return make_float3(floorf(v.x), floorf(v.y), floorf(v.z));
+}
+inline __host__ __device__ float4 floorf(float4 v)
+{
+ return make_float4(floorf(v.x), floorf(v.y), floorf(v.z), floorf(v.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// frac - returns the fractional portion of a scalar or each vector component
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float fracf(float v)
+{
+ return v - floorf(v);
+}
+inline __host__ __device__ float2 fracf(float2 v)
+{
+ return make_float2(fracf(v.x), fracf(v.y));
+}
+inline __host__ __device__ float3 fracf(float3 v)
+{
+ return make_float3(fracf(v.x), fracf(v.y), fracf(v.z));
+}
+inline __host__ __device__ float4 fracf(float4 v)
+{
+ return make_float4(fracf(v.x), fracf(v.y), fracf(v.z), fracf(v.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// fmod
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 fmodf(float2 a, float2 b)
+{
+ return make_float2(fmodf(a.x, b.x), fmodf(a.y, b.y));
+}
+inline __host__ __device__ float3 fmodf(float3 a, float3 b)
+{
+ return make_float3(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z));
+}
+inline __host__ __device__ float4 fmodf(float4 a, float4 b)
+{
+ return make_float4(fmodf(a.x, b.x), fmodf(a.y, b.y), fmodf(a.z, b.z), fmodf(a.w, b.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// absolute value
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float2 fabs(float2 v)
+{
+ return make_float2(fabs(v.x), fabs(v.y));
+}
+inline __host__ __device__ float3 fabs(float3 v)
+{
+ return make_float3(fabs(v.x), fabs(v.y), fabs(v.z));
+}
+inline __host__ __device__ float4 fabs(float4 v)
+{
+ return make_float4(fabs(v.x), fabs(v.y), fabs(v.z), fabs(v.w));
+}
+
+inline __host__ __device__ int2 abs(int2 v)
+{
+ return make_int2(abs(v.x), abs(v.y));
+}
+inline __host__ __device__ int3 abs(int3 v)
+{
+ return make_int3(abs(v.x), abs(v.y), abs(v.z));
+}
+inline __host__ __device__ int4 abs(int4 v)
+{
+ return make_int4(abs(v.x), abs(v.y), abs(v.z), abs(v.w));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// reflect
+// - returns reflection of incident ray I around surface normal N
+// - N should be normalized, reflected vector's length is equal to length of I
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float3 reflect(float3 i, float3 n)
+{
+ return i - 2.0f * n * dot(n,i);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// cross product
+////////////////////////////////////////////////////////////////////////////////
+
+inline __host__ __device__ float3 cross(float3 a, float3 b)
+{
+ return make_float3(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// smoothstep
+// - returns 0 if x < a
+// - returns 1 if x > b
+// - otherwise returns smooth interpolation between 0 and 1 based on x
+////////////////////////////////////////////////////////////////////////////////
+
+inline __device__ __host__ float smoothstep(float a, float b, float x)
+{
+ float y = clamp((x - a) / (b - a), 0.0f, 1.0f);
+ return (y*y*(3.0f - (2.0f*y)));
+}
+inline __device__ __host__ float2 smoothstep(float2 a, float2 b, float2 x)
+{
+ float2 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
+ return (y*y*(make_float2(3.0f) - (make_float2(2.0f)*y)));
+}
+inline __device__ __host__ float3 smoothstep(float3 a, float3 b, float3 x)
+{
+ float3 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
+ return (y*y*(make_float3(3.0f) - (make_float3(2.0f)*y)));
+}
+inline __device__ __host__ float4 smoothstep(float4 a, float4 b, float4 x)
+{
+ float4 y = clamp((x - a) / (b - a), 0.0f, 1.0f);
+ return (y*y*(make_float4(3.0f) - (make_float4(2.0f)*y)));
+}
+
+#endif
diff --git a/tests/projects/cuda_console/inc/helper_string.h b/tests/projects/cuda_console/inc/helper_string.h
new file mode 100644
index 000000000..c4cc273fc
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_string.h
@@ -0,0 +1,527 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+// These are helper functions for the SDK samples (string parsing, timers, etc)
+#ifndef STRING_HELPER_H
+#define STRING_HELPER_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fstream>
+#include <string>
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#ifndef STRCASECMP
+#define STRCASECMP _stricmp
+#endif
+#ifndef STRNCASECMP
+#define STRNCASECMP _strnicmp
+#endif
+#ifndef STRCPY
+#define STRCPY(sFilePath, nLength, sPath) strcpy_s(sFilePath, nLength, sPath)
+#endif
+
+#ifndef FOPEN
+#define FOPEN(fHandle,filename,mode) fopen_s(&fHandle, filename, mode)
+#endif
+#ifndef FOPEN_FAIL
+#define FOPEN_FAIL(result) (result != 0)
+#endif
+#ifndef SSCANF
+#define SSCANF sscanf_s
+#endif
+#ifndef SPRINTF
+#define SPRINTF sprintf_s
+#endif
+#else // Linux Includes
+#include <string.h>
+#include <strings.h>
+
+#ifndef STRCASECMP
+#define STRCASECMP strcasecmp
+#endif
+#ifndef STRNCASECMP
+#define STRNCASECMP strncasecmp
+#endif
+#ifndef STRCPY
+#define STRCPY(sFilePath, nLength, sPath) strcpy(sFilePath, sPath)
+#endif
+
+#ifndef FOPEN
+#define FOPEN(fHandle,filename,mode) (fHandle = fopen(filename, mode))
+#endif
+#ifndef FOPEN_FAIL
+#define FOPEN_FAIL(result) (result == NULL)
+#endif
+#ifndef SSCANF
+#define SSCANF sscanf
+#endif
+#ifndef SPRINTF
+#define SPRINTF sprintf
+#endif
+#endif
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+// CUDA Utility Helper Functions
+inline int stringRemoveDelimiter(char delimiter, const char *string)
+{
+ int string_start = 0;
+
+ while (string[string_start] == delimiter)
+ {
+ string_start++;
+ }
+
+ if (string_start >= (int)strlen(string)-1)
+ {
+ return 0;
+ }
+
+ return string_start;
+}
+
+inline int getFileExtension(char *filename, char **extension)
+{
+ int string_length = (int)strlen(filename);
+
+ while (filename[string_length--] != '.')
+ {
+ if (string_length == 0)
+ break;
+ }
+
+ if (string_length > 0) string_length += 2;
+
+ if (string_length == 0)
+ *extension = NULL;
+ else
+ *extension = &filename[string_length];
+
+ return string_length;
+}
+
+
+inline bool checkCmdLineFlag(const int argc, const char **argv, const char *string_ref)
+{
+ bool bFound = false;
+
+ if (argc >= 1)
+ {
+ for (int i=1; i < argc; i++)
+ {
+ int string_start = stringRemoveDelimiter('-', argv[i]);
+ const char *string_argv = &argv[i][string_start];
+
+ const char *equal_pos = strchr(string_argv, '=');
+ int argv_length = (int)(equal_pos == 0 ? strlen(string_argv) : equal_pos - string_argv);
+
+ int length = (int)strlen(string_ref);
+
+ if (length == argv_length && !STRNCASECMP(string_argv, string_ref, length))
+ {
+ bFound = true;
+ continue;
+ }
+ }
+ }
+
+ return bFound;
+}
+
+// This function wraps the CUDA Driver API into a template function
+template <class T>
+inline bool getCmdLineArgumentValue(const int argc, const char **argv, const char *string_ref, T *value)
+{
+ bool bFound = false;
+
+ if (argc >= 1)
+ {
+ for (int i=1; i < argc; i++)
+ {
+ int string_start = stringRemoveDelimiter('-', argv[i]);
+ const char *string_argv = &argv[i][string_start];
+ int length = (int)strlen(string_ref);
+
+ if (!STRNCASECMP(string_argv, string_ref, length))
+ {
+ if (length+1 <= (int)strlen(string_argv))
+ {
+ int auto_inc = (string_argv[length] == '=') ? 1 : 0;
+ *value = (T)atoi(&string_argv[length + auto_inc]);
+ }
+
+ bFound = true;
+ i=argc;
+ }
+ }
+ }
+
+ return bFound;
+}
+
+inline int getCmdLineArgumentInt(const int argc, const char **argv, const char *string_ref)
+{
+ bool bFound = false;
+ int value = -1;
+
+ if (argc >= 1)
+ {
+ for (int i=1; i < argc; i++)
+ {
+ int string_start = stringRemoveDelimiter('-', argv[i]);
+ const char *string_argv = &argv[i][string_start];
+ int length = (int)strlen(string_ref);
+
+ if (!STRNCASECMP(string_argv, string_ref, length))
+ {
+ if (length+1 <= (int)strlen(string_argv))
+ {
+ int auto_inc = (string_argv[length] == '=') ? 1 : 0;
+ value = atoi(&string_argv[length + auto_inc]);
+ }
+ else
+ {
+ value = 0;
+ }
+
+ bFound = true;
+ continue;
+ }
+ }
+ }
+
+ if (bFound)
+ {
+ return value;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+inline float getCmdLineArgumentFloat(const int argc, const char **argv, const char *string_ref)
+{
+ bool bFound = false;
+ float value = -1;
+
+ if (argc >= 1)
+ {
+ for (int i=1; i < argc; i++)
+ {
+ int string_start = stringRemoveDelimiter('-', argv[i]);
+ const char *string_argv = &argv[i][string_start];
+ int length = (int)strlen(string_ref);
+
+ if (!STRNCASECMP(string_argv, string_ref, length))
+ {
+ if (length+1 <= (int)strlen(string_argv))
+ {
+ int auto_inc = (string_argv[length] == '=') ? 1 : 0;
+ value = (float)atof(&string_argv[length + auto_inc]);
+ }
+ else
+ {
+ value = 0.f;
+ }
+
+ bFound = true;
+ continue;
+ }
+ }
+ }
+
+ if (bFound)
+ {
+ return value;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+inline bool getCmdLineArgumentString(const int argc, const char **argv,
+ const char *string_ref, char **string_retval)
+{
+ bool bFound = false;
+
+ if (argc >= 1)
+ {
+ for (int i=1; i < argc; i++)
+ {
+ int string_start = stringRemoveDelimiter('-', argv[i]);
+ char *string_argv = (char *)&argv[i][string_start];
+ int length = (int)strlen(string_ref);
+
+ if (!STRNCASECMP(string_argv, string_ref, length))
+ {
+ *string_retval = &string_argv[length+1];
+ bFound = true;
+ continue;
+ }
+ }
+ }
+
+ if (!bFound)
+ {
+ *string_retval = NULL;
+ }
+
+ return bFound;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//! Find the path for a file assuming that
+//! files are found in the searchPath.
+//!
+//! @return the path if succeeded, otherwise 0
+//! @param filename name of the file
+//! @param executable_path optional absolute path of the executable
+//////////////////////////////////////////////////////////////////////////////
+inline char *sdkFindFilePath(const char *filename, const char *executable_path)
+{
+ // <executable_name> defines a variable that is replaced with the name of the executable
+
+ // Typical relative search paths to locate needed companion files (e.g. sample input data, or JIT source files)
+ // The origin for the relative search may be the .exe file, a .bat file launching an .exe, a browser .exe launching the .exe or .bat, etc
+ const char *searchPath[] =
+ {
+ "./", // same dir
+ "./<executable_name>_data_files/",
+ "./common/", // "/common/" subdir
+ "./common/data/", // "/common/data/" subdir
+ "./data/", // "/data/" subdir
+ "./src/", // "/src/" subdir
+ "./src/<executable_name>/data/", // "/src/<executable_name>/data/" subdir
+ "./inc/", // "/inc/" subdir
+ "./0_Simple/", // "/0_Simple/" subdir
+ "./1_Utilities/", // "/1_Utilities/" subdir
+ "./2_Graphics/", // "/2_Graphics/" subdir
+ "./3_Imaging/", // "/3_Imaging/" subdir
+ "./4_Finance/", // "/4_Finance/" subdir
+ "./5_Simulations/", // "/5_Simulations/" subdir
+ "./6_Advanced/", // "/6_Advanced/" subdir
+ "./7_CUDALibraries/", // "/7_CUDALibraries/" subdir
+ "./8_Android/", // "/8_Android/" subdir
+ "./samples/", // "/samples/" subdir
+
+ "./0_Simple/<executable_name>/data/", // "/0_Simple/<executable_name>/data/" subdir
+ "./1_Utilities/<executable_name>/data/", // "/1_Utilities/<executable_name>/data/" subdir
+ "./2_Graphics/<executable_name>/data/", // "/2_Graphics/<executable_name>/data/" subdir
+ "./3_Imaging/<executable_name>/data/", // "/3_Imaging/<executable_name>/data/" subdir
+ "./4_Finance/<executable_name>/data/", // "/4_Finance/<executable_name>/data/" subdir
+ "./5_Simulations/<executable_name>/data/", // "/5_Simulations/<executable_name>/data/" subdir
+ "./6_Advanced/<executable_name>/data/", // "/6_Advanced/<executable_name>/data/" subdir
+ "./7_CUDALibraries/<executable_name>/", // "/7_CUDALibraries/<executable_name>/" subdir
+ "./7_CUDALibraries/<executable_name>/data/", // "/7_CUDALibraries/<executable_name>/data/" subdir
+
+ "../", // up 1 in tree
+ "../common/", // up 1 in tree, "/common/" subdir
+ "../common/data/", // up 1 in tree, "/common/data/" subdir
+ "../data/", // up 1 in tree, "/data/" subdir
+ "../src/", // up 1 in tree, "/src/" subdir
+ "../inc/", // up 1 in tree, "/inc/" subdir
+
+ "../0_Simple/<executable_name>/data/", // up 1 in tree, "/0_Simple/<executable_name>/" subdir
+ "../1_Utilities/<executable_name>/data/", // up 1 in tree, "/1_Utilities/<executable_name>/" subdir
+ "../2_Graphics/<executable_name>/data/", // up 1 in tree, "/2_Graphics/<executable_name>/" subdir
+ "../3_Imaging/<executable_name>/data/", // up 1 in tree, "/3_Imaging/<executable_name>/" subdir
+ "../4_Finance/<executable_name>/data/", // up 1 in tree, "/4_Finance/<executable_name>/" subdir
+ "../5_Simulations/<executable_name>/data/", // up 1 in tree, "/5_Simulations/<executable_name>/" subdir
+ "../6_Advanced/<executable_name>/data/", // up 1 in tree, "/6_Advanced/<executable_name>/" subdir
+ "../7_CUDALibraries/<executable_name>/data/",// up 1 in tree, "/7_CUDALibraries/<executable_name>/" subdir
+ "../8_Android/<executable_name>/data/", // up 1 in tree, "/8_Android/<executable_name>/" subdir
+ "../samples/<executable_name>/data/", // up 1 in tree, "/samples/<executable_name>/" subdir
+ "../../", // up 2 in tree
+ "../../common/", // up 2 in tree, "/common/" subdir
+ "../../common/data/", // up 2 in tree, "/common/data/" subdir
+ "../../data/", // up 2 in tree, "/data/" subdir
+ "../../src/", // up 2 in tree, "/src/" subdir
+ "../../inc/", // up 2 in tree, "/inc/" subdir
+ "../../sandbox/<executable_name>/data/", // up 2 in tree, "/sandbox/<executable_name>/" subdir
+ "../../0_Simple/<executable_name>/data/", // up 2 in tree, "/0_Simple/<executable_name>/" subdir
+ "../../1_Utilities/<executable_name>/data/", // up 2 in tree, "/1_Utilities/<executable_name>/" subdir
+ "../../2_Graphics/<executable_name>/data/", // up 2 in tree, "/2_Graphics/<executable_name>/" subdir
+ "../../3_Imaging/<executable_name>/data/", // up 2 in tree, "/3_Imaging/<executable_name>/" subdir
+ "../../4_Finance/<executable_name>/data/", // up 2 in tree, "/4_Finance/<executable_name>/" subdir
+ "../../5_Simulations/<executable_name>/data/", // up 2 in tree, "/5_Simulations/<executable_name>/" subdir
+ "../../6_Advanced/<executable_name>/data/", // up 2 in tree, "/6_Advanced/<executable_name>/" subdir
+ "../../7_CUDALibraries/<executable_name>/data/", // up 2 in tree, "/7_CUDALibraries/<executable_name>/" subdir
+ "../../8_Android/<executable_name>/data/", // up 2 in tree, "/8_Android/<executable_name>/" subdir
+ "../../samples/<executable_name>/data/", // up 2 in tree, "/samples/<executable_name>/" subdir
+ "../../../", // up 3 in tree
+ "../../../src/<executable_name>/", // up 3 in tree, "/src/<executable_name>/" subdir
+ "../../../src/<executable_name>/data/", // up 3 in tree, "/src/<executable_name>/data/" subdir
+ "../../../src/<executable_name>/src/", // up 3 in tree, "/src/<executable_name>/src/" subdir
+ "../../../src/<executable_name>/inc/", // up 3 in tree, "/src/<executable_name>/inc/" subdir
+ "../../../sandbox/<executable_name>/", // up 3 in tree, "/sandbox/<executable_name>/" subdir
+ "../../../sandbox/<executable_name>/data/", // up 3 in tree, "/sandbox/<executable_name>/data/" subdir
+ "../../../sandbox/<executable_name>/src/", // up 3 in tree, "/sandbox/<executable_name>/src/" subdir
+ "../../../sandbox/<executable_name>/inc/", // up 3 in tree, "/sandbox/<executable_name>/inc/" subdir
+ "../../../0_Simple/<executable_name>/data/", // up 3 in tree, "/0_Simple/<executable_name>/" subdir
+ "../../../1_Utilities/<executable_name>/data/", // up 3 in tree, "/1_Utilities/<executable_name>/" subdir
+ "../../../2_Graphics/<executable_name>/data/", // up 3 in tree, "/2_Graphics/<executable_name>/" subdir
+ "../../../3_Imaging/<executable_name>/data/", // up 3 in tree, "/3_Imaging/<executable_name>/" subdir
+ "../../../4_Finance/<executable_name>/data/", // up 3 in tree, "/4_Finance/<executable_name>/" subdir
+ "../../../5_Simulations/<executable_name>/data/", // up 3 in tree, "/5_Simulations/<executable_name>/" subdir
+ "../../../6_Advanced/<executable_name>/data/", // up 3 in tree, "/6_Advanced/<executable_name>/" subdir
+ "../../../7_CUDALibraries/<executable_name>/data/", // up 3 in tree, "/7_CUDALibraries/<executable_name>/" subdir
+ "../../../8_Android/<executable_name>/data/", // up 3 in tree, "/8_Android/<executable_name>/" subdir
+ "../../../0_Simple/<executable_name>/", // up 3 in tree, "/0_Simple/<executable_name>/" subdir
+ "../../../1_Utilities/<executable_name>/", // up 3 in tree, "/1_Utilities/<executable_name>/" subdir
+ "../../../2_Graphics/<executable_name>/", // up 3 in tree, "/2_Graphics/<executable_name>/" subdir
+ "../../../3_Imaging/<executable_name>/", // up 3 in tree, "/3_Imaging/<executable_name>/" subdir
+ "../../../4_Finance/<executable_name>/", // up 3 in tree, "/4_Finance/<executable_name>/" subdir
+ "../../../5_Simulations/<executable_name>/", // up 3 in tree, "/5_Simulations/<executable_name>/" subdir
+ "../../../6_Advanced/<executable_name>/", // up 3 in tree, "/6_Advanced/<executable_name>/" subdir
+ "../../../7_CUDALibraries/<executable_name>/", // up 3 in tree, "/7_CUDALibraries/<executable_name>/" subdir
+ "../../../8_Android/<executable_name>/", // up 3 in tree, "/8_Android/<executable_name>/" subdir
+ "../../../samples/<executable_name>/data/", // up 3 in tree, "/samples/<executable_name>/" subdir
+ "../../../common/", // up 3 in tree, "../../../common/" subdir
+ "../../../common/data/", // up 3 in tree, "../../../common/data/" subdir
+ "../../../data/", // up 3 in tree, "../../../data/" subdir
+ "../../../../", // up 4 in tree
+ "../../../../src/<executable_name>/", // up 4 in tree, "/src/<executable_name>/" subdir
+ "../../../../src/<executable_name>/data/", // up 4 in tree, "/src/<executable_name>/data/" subdir
+ "../../../../src/<executable_name>/src/", // up 4 in tree, "/src/<executable_name>/src/" subdir
+ "../../../../src/<executable_name>/inc/", // up 4 in tree, "/src/<executable_name>/inc/" subdir
+ "../../../../sandbox/<executable_name>/", // up 4 in tree, "/sandbox/<executable_name>/" subdir
+ "../../../../sandbox/<executable_name>/data/", // up 4 in tree, "/sandbox/<executable_name>/data/" subdir
+ "../../../../sandbox/<executable_name>/src/", // up 4 in tree, "/sandbox/<executable_name>/src/" subdir
+ "../../../../sandbox/<executable_name>/inc/", // up 4 in tree, "/sandbox/<executable_name>/inc/" subdir
+ "../../../../0_Simple/<executable_name>/data/", // up 4 in tree, "/0_Simple/<executable_name>/" subdir
+ "../../../../1_Utilities/<executable_name>/data/", // up 4 in tree, "/1_Utilities/<executable_name>/" subdir
+ "../../../../2_Graphics/<executable_name>/data/", // up 4 in tree, "/2_Graphics/<executable_name>/" subdir
+ "../../../../3_Imaging/<executable_name>/data/", // up 4 in tree, "/3_Imaging/<executable_name>/" subdir
+ "../../../../4_Finance/<executable_name>/data/", // up 4 in tree, "/4_Finance/<executable_name>/" subdir
+ "../../../../5_Simulations/<executable_name>/data/",// up 4 in tree, "/5_Simulations/<executable_name>/" subdir
+ "../../../../6_Advanced/<executable_name>/data/", // up 4 in tree, "/6_Advanced/<executable_name>/" subdir
+ "../../../../7_CUDALibraries/<executable_name>/data/", // up 4 in tree, "/7_CUDALibraries/<executable_name>/" subdir
+ "../../../../8_Android/<executable_name>/data/", // up 4 in tree, "/8_Android/<executable_name>/" subdir
+ "../../../../0_Simple/<executable_name>/", // up 4 in tree, "/0_Simple/<executable_name>/" subdir
+ "../../../../1_Utilities/<executable_name>/", // up 4 in tree, "/1_Utilities/<executable_name>/" subdir
+ "../../../../2_Graphics/<executable_name>/", // up 4 in tree, "/2_Graphics/<executable_name>/" subdir
+ "../../../../3_Imaging/<executable_name>/", // up 4 in tree, "/3_Imaging/<executable_name>/" subdir
+ "../../../../4_Finance/<executable_name>/", // up 4 in tree, "/4_Finance/<executable_name>/" subdir
+ "../../../../5_Simulations/<executable_name>/",// up 4 in tree, "/5_Simulations/<executable_name>/" subdir
+ "../../../../6_Advanced/<executable_name>/", // up 4 in tree, "/6_Advanced/<executable_name>/" subdir
+ "../../../../7_CUDALibraries/<executable_name>/", // up 4 in tree, "/7_CUDALibraries/<executable_name>/" subdir
+ "../../../../8_Android/<executable_name>/", // up 4 in tree, "/8_Android/<executable_name>/" subdir
+ "../../../../samples/<executable_name>/data/", // up 4 in tree, "/samples/<executable_name>/" subdir
+ "../../../../common/", // up 4 in tree, "../../../common/" subdir
+ "../../../../common/data/", // up 4 in tree, "../../../common/data/" subdir
+ "../../../../data/", // up 4 in tree, "../../../data/" subdir
+ "../../../../../", // up 5 in tree
+ "../../../../../src/<executable_name>/", // up 5 in tree, "/src/<executable_name>/" subdir
+ "../../../../../src/<executable_name>/data/", // up 5 in tree, "/src/<executable_name>/data/" subdir
+ "../../../../../src/<executable_name>/src/", // up 5 in tree, "/src/<executable_name>/src/" subdir
+ "../../../../../src/<executable_name>/inc/", // up 5 in tree, "/src/<executable_name>/inc/" subdir
+ "../../../../../sandbox/<executable_name>/", // up 5 in tree, "/sandbox/<executable_name>/" subdir
+ "../../../../../sandbox/<executable_name>/data/", // up 5 in tree, "/sandbox/<executable_name>/data/" subdir
+ "../../../../../sandbox/<executable_name>/src/", // up 5 in tree, "/sandbox/<executable_name>/src/" subdir
+ "../../../../../sandbox/<executable_name>/inc/", // up 5 in tree, "/sandbox/<executable_name>/inc/" subdir
+ "../../../../../0_Simple/<executable_name>/data/", // up 5 in tree, "/0_Simple/<executable_name>/" subdir
+ "../../../../../1_Utilities/<executable_name>/data/", // up 5 in tree, "/1_Utilities/<executable_name>/" subdir
+ "../../../../../2_Graphics/<executable_name>/data/", // up 5 in tree, "/2_Graphics/<executable_name>/" subdir
+ "../../../../../3_Imaging/<executable_name>/data/", // up 5 in tree, "/3_Imaging/<executable_name>/" subdir
+ "../../../../../4_Finance/<executable_name>/data/", // up 5 in tree, "/4_Finance/<executable_name>/" subdir
+ "../../../../../5_Simulations/<executable_name>/data/",// up 5 in tree, "/5_Simulations/<executable_name>/" subdir
+ "../../../../../6_Advanced/<executable_name>/data/", // up 5 in tree, "/6_Advanced/<executable_name>/" subdir
+ "../../../../../7_CUDALibraries/<executable_name>/data/", // up 5 in tree, "/7_CUDALibraries/<executable_name>/" subdir
+ "../../../../../8_Android/<executable_name>/data/", // up 5 in tree, "/8_Android/<executable_name>/" subdir
+ "../../../../../samples/<executable_name>/data/", // up 5 in tree, "/samples/<executable_name>/" subdir
+ "../../../../../common/", // up 5 in tree, "../../../common/" subdir
+ "../../../../../common/data/", // up 5 in tree, "../../../common/data/" subdir
+ };
+
+ // Extract the executable name
+ std::string executable_name;
+
+ if (executable_path != 0)
+ {
+ executable_name = std::string(executable_path);
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+ // Windows path delimiter
+ size_t delimiter_pos = executable_name.find_last_of('\\');
+ executable_name.erase(0, delimiter_pos + 1);
+
+ if (executable_name.rfind(".exe") != std::string::npos)
+ {
+ // we strip .exe, only if the .exe is found
+ executable_name.resize(executable_name.size() - 4);
+ }
+
+#else
+ // Linux & OSX path delimiter
+ size_t delimiter_pos = executable_name.find_last_of('/');
+ executable_name.erase(0,delimiter_pos+1);
+#endif
+ }
+
+ // Loop over all search paths and return the first hit
+ for (unsigned int i = 0; i < sizeof(searchPath)/sizeof(char *); ++i)
+ {
+ std::string path(searchPath[i]);
+ size_t executable_name_pos = path.find("<executable_name>");
+
+ // If there is executable_name variable in the searchPath
+ // replace it with the value
+ if (executable_name_pos != std::string::npos)
+ {
+ if (executable_path != 0)
+ {
+ path.replace(executable_name_pos, strlen("<executable_name>"), executable_name);
+ }
+ else
+ {
+ // Skip this path entry if no executable argument is given
+ continue;
+ }
+ }
+
+#ifdef _DEBUG
+ printf("sdkFindFilePath <%s> in %s\n", filename, path.c_str());
+#endif
+
+ // Test if the file exists
+ path.append(filename);
+ FILE *fp;
+ FOPEN(fp, path.c_str(), "rb");
+
+ if (fp != NULL)
+ {
+ fclose(fp);
+ // File found
+ // returning an allocated array here for backwards compatibility reasons
+ char *file_path = (char *) malloc(path.length() + 1);
+ STRCPY(file_path, path.length() + 1, path.c_str());
+ return file_path;
+ }
+
+ if (fp)
+ {
+ fclose(fp);
+ }
+ }
+
+ // File not found
+ return 0;
+}
+
+#endif
diff --git a/tests/projects/cuda_console/inc/helper_timer.h b/tests/projects/cuda_console/inc/helper_timer.h
new file mode 100644
index 000000000..39ddc77f2
--- /dev/null
+++ b/tests/projects/cuda_console/inc/helper_timer.h
@@ -0,0 +1,499 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+// Helper Timing Functions
+#ifndef HELPER_TIMER_H
+#define HELPER_TIMER_H
+
+#ifndef EXIT_WAIVED
+#define EXIT_WAIVED 2
+#endif
+
+// includes, system
+#include <vector>
+
+// includes, project
+#include <exception.h>
+
+// Definition of the StopWatch Interface, this is used if we don't want to use the CUT functions
+// But rather in a self contained class interface
+class StopWatchInterface
+{
+ public:
+ StopWatchInterface() {};
+ virtual ~StopWatchInterface() {};
+
+ public:
+ //! Start time measurement
+ virtual void start() = 0;
+
+ //! Stop time measurement
+ virtual void stop() = 0;
+
+ //! Reset time counters to zero
+ virtual void reset() = 0;
+
+ //! Time in msec. after start. If the stop watch is still running (i.e. there
+ //! was no call to stop()) then the elapsed time is returned, otherwise the
+ //! time between the last start() and stop call is returned
+ virtual float getTime() = 0;
+
+ //! Mean time to date based on the number of times the stopwatch has been
+ //! _stopped_ (ie finished sessions) and the current total time
+ virtual float getAverageTime() = 0;
+};
+
+
+//////////////////////////////////////////////////////////////////
+// Begin Stopwatch timer class definitions for all OS platforms //
+//////////////////////////////////////////////////////////////////
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+// includes, system
+#define WINDOWS_LEAN_AND_MEAN
+#include <windows.h>
+#undef min
+#undef max
+
+//! Windows specific implementation of StopWatch
+class StopWatchWin : public StopWatchInterface
+{
+ public:
+ //! Constructor, default
+ StopWatchWin() :
+ start_time(), end_time(),
+ diff_time(0.0f), total_time(0.0f),
+ running(false), clock_sessions(0), freq(0), freq_set(false)
+ {
+ if (! freq_set)
+ {
+ // helper variable
+ LARGE_INTEGER temp;
+
+ // get the tick frequency from the OS
+ QueryPerformanceFrequency((LARGE_INTEGER *) &temp);
+
+ // convert to type in which it is needed
+ freq = ((double) temp.QuadPart) / 1000.0;
+
+ // rememeber query
+ freq_set = true;
+ }
+ };
+
+ // Destructor
+ ~StopWatchWin() { };
+
+ public:
+ //! Start time measurement
+ inline void start();
+
+ //! Stop time measurement
+ inline void stop();
+
+ //! Reset time counters to zero
+ inline void reset();
+
+ //! Time in msec. after start. If the stop watch is still running (i.e. there
+ //! was no call to stop()) then the elapsed time is returned, otherwise the
+ //! time between the last start() and stop call is returned
+ inline float getTime();
+
+ //! Mean time to date based on the number of times the stopwatch has been
+ //! _stopped_ (ie finished sessions) and the current total time
+ inline float getAverageTime();
+
+ private:
+ // member variables
+
+ //! Start of measurement
+ LARGE_INTEGER start_time;
+ //! End of measurement
+ LARGE_INTEGER end_time;
+
+ //! Time difference between the last start and stop
+ float diff_time;
+
+ //! TOTAL time difference between starts and stops
+ float total_time;
+
+ //! flag if the stop watch is running
+ bool running;
+
+ //! Number of times clock has been started
+ //! and stopped to allow averaging
+ int clock_sessions;
+
+ //! tick frequency
+ double freq;
+
+ //! flag if the frequency has been set
+ bool freq_set;
+};
+
+// functions, inlined
+
+////////////////////////////////////////////////////////////////////////////////
+//! Start time measurement
+////////////////////////////////////////////////////////////////////////////////
+inline void
+StopWatchWin::start()
+{
+ QueryPerformanceCounter((LARGE_INTEGER *) &start_time);
+ running = true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Stop time measurement and increment add to the current diff_time summation
+//! variable. Also increment the number of times this clock has been run.
+////////////////////////////////////////////////////////////////////////////////
+inline void
+StopWatchWin::stop()
+{
+ QueryPerformanceCounter((LARGE_INTEGER *) &end_time);
+ diff_time = (float)
+ (((double) end_time.QuadPart - (double) start_time.QuadPart) / freq);
+
+ total_time += diff_time;
+ clock_sessions++;
+ running = false;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Reset the timer to 0. Does not change the timer running state but does
+//! recapture this point in time as the current start time if it is running.
+////////////////////////////////////////////////////////////////////////////////
+inline void
+StopWatchWin::reset()
+{
+ diff_time = 0;
+ total_time = 0;
+ clock_sessions = 0;
+
+ if (running)
+ {
+ QueryPerformanceCounter((LARGE_INTEGER *) &start_time);
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//! Time in msec. after start. If the stop watch is still running (i.e. there
+//! was no call to stop()) then the elapsed time is returned added to the
+//! current diff_time sum, otherwise the current summed time difference alone
+//! is returned.
+////////////////////////////////////////////////////////////////////////////////
+inline float
+StopWatchWin::getTime()
+{
+ // Return the TOTAL time to date
+ float retval = total_time;
+
+ if (running)
+ {
+ LARGE_INTEGER temp;
+ QueryPerformanceCounter((LARGE_INTEGER *) &temp);
+ retval += (float)
+ (((double)(temp.QuadPart - start_time.QuadPart)) / freq);
+ }
+
+ return retval;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Time in msec. for a single run based on the total number of COMPLETED runs
+//! and the total time.
+////////////////////////////////////////////////////////////////////////////////
+inline float
+StopWatchWin::getAverageTime()
+{
+ return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f;
+}
+#else
+// Declarations for Stopwatch on Linux and Mac OSX
+// includes, system
+#include <ctime>
+#include <sys/time.h>
+
+//! Windows specific implementation of StopWatch
+class StopWatchLinux : public StopWatchInterface
+{
+ public:
+ //! Constructor, default
+ StopWatchLinux() :
+ start_time(), diff_time(0.0), total_time(0.0),
+ running(false), clock_sessions(0)
+ { };
+
+ // Destructor
+ virtual ~StopWatchLinux()
+ { };
+
+ public:
+ //! Start time measurement
+ inline void start();
+
+ //! Stop time measurement
+ inline void stop();
+
+ //! Reset time counters to zero
+ inline void reset();
+
+ //! Time in msec. after start. If the stop watch is still running (i.e. there
+ //! was no call to stop()) then the elapsed time is returned, otherwise the
+ //! time between the last start() and stop call is returned
+ inline float getTime();
+
+ //! Mean time to date based on the number of times the stopwatch has been
+ //! _stopped_ (ie finished sessions) and the current total time
+ inline float getAverageTime();
+
+ private:
+
+ // helper functions
+
+ //! Get difference between start time and current time
+ inline float getDiffTime();
+
+ private:
+
+ // member variables
+
+ //! Start of measurement
+ struct timeval start_time;
+
+ //! Time difference between the last start and stop
+ float diff_time;
+
+ //! TOTAL time difference between starts and stops
+ float total_time;
+
+ //! flag if the stop watch is running
+ bool running;
+
+ //! Number of times clock has been started
+ //! and stopped to allow averaging
+ int clock_sessions;
+};
+
+// functions, inlined
+
+////////////////////////////////////////////////////////////////////////////////
+//! Start time measurement
+////////////////////////////////////////////////////////////////////////////////
+inline void
+StopWatchLinux::start()
+{
+ gettimeofday(&start_time, 0);
+ running = true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Stop time measurement and increment add to the current diff_time summation
+//! variable. Also increment the number of times this clock has been run.
+////////////////////////////////////////////////////////////////////////////////
+inline void
+StopWatchLinux::stop()
+{
+ diff_time = getDiffTime();
+ total_time += diff_time;
+ running = false;
+ clock_sessions++;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Reset the timer to 0. Does not change the timer running state but does
+//! recapture this point in time as the current start time if it is running.
+////////////////////////////////////////////////////////////////////////////////
+inline void
+StopWatchLinux::reset()
+{
+ diff_time = 0;
+ total_time = 0;
+ clock_sessions = 0;
+
+ if (running)
+ {
+ gettimeofday(&start_time, 0);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Time in msec. after start. If the stop watch is still running (i.e. there
+//! was no call to stop()) then the elapsed time is returned added to the
+//! current diff_time sum, otherwise the current summed time difference alone
+//! is returned.
+////////////////////////////////////////////////////////////////////////////////
+inline float
+StopWatchLinux::getTime()
+{
+ // Return the TOTAL time to date
+ float retval = total_time;
+
+ if (running)
+ {
+ retval += getDiffTime();
+ }
+
+ return retval;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Time in msec. for a single run based on the total number of COMPLETED runs
+//! and the total time.
+////////////////////////////////////////////////////////////////////////////////
+inline float
+StopWatchLinux::getAverageTime()
+{
+ return (clock_sessions > 0) ? (total_time/clock_sessions) : 0.0f;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////////////
+inline float
+StopWatchLinux::getDiffTime()
+{
+ struct timeval t_time;
+ gettimeofday(&t_time, 0);
+
+ // time difference in milli-seconds
+ return (float)(1000.0 * (t_time.tv_sec - start_time.tv_sec)
+ + (0.001 * (t_time.tv_usec - start_time.tv_usec)));
+}
+#endif // WIN32
+
+////////////////////////////////////////////////////////////////////////////////
+//! Timer functionality exported
+
+////////////////////////////////////////////////////////////////////////////////
+//! Create a new timer
+//! @return true if a time has been created, otherwise false
+//! @param name of the new timer, 0 if the creation failed
+////////////////////////////////////////////////////////////////////////////////
+inline bool
+sdkCreateTimer(StopWatchInterface **timer_interface)
+{
+ //printf("sdkCreateTimer called object %08x\n", (void *)*timer_interface);
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+ *timer_interface = (StopWatchInterface *)new StopWatchWin();
+#else
+ *timer_interface = (StopWatchInterface *)new StopWatchLinux();
+#endif
+ return (*timer_interface != NULL) ? true : false;
+}
+
+
+////////////////////////////////////////////////////////////////////////////////
+//! Delete a timer
+//! @return true if a time has been deleted, otherwise false
+//! @param name of the timer to delete
+////////////////////////////////////////////////////////////////////////////////
+inline bool
+sdkDeleteTimer(StopWatchInterface **timer_interface)
+{
+ //printf("sdkDeleteTimer called object %08x\n", (void *)*timer_interface);
+ if (*timer_interface)
+ {
+ delete *timer_interface;
+ *timer_interface = NULL;
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Start the time with name \a name
+//! @param name name of the timer to start
+////////////////////////////////////////////////////////////////////////////////
+inline bool
+sdkStartTimer(StopWatchInterface **timer_interface)
+{
+ //printf("sdkStartTimer called object %08x\n", (void *)*timer_interface);
+ if (*timer_interface)
+ {
+ (*timer_interface)->start();
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Stop the time with name \a name. Does not reset.
+//! @param name name of the timer to stop
+////////////////////////////////////////////////////////////////////////////////
+inline bool
+sdkStopTimer(StopWatchInterface **timer_interface)
+{
+ // printf("sdkStopTimer called object %08x\n", (void *)*timer_interface);
+ if (*timer_interface)
+ {
+ (*timer_interface)->stop();
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Resets the timer's counter.
+//! @param name name of the timer to reset.
+////////////////////////////////////////////////////////////////////////////////
+inline bool
+sdkResetTimer(StopWatchInterface **timer_interface)
+{
+ // printf("sdkResetTimer called object %08x\n", (void *)*timer_interface);
+ if (*timer_interface)
+ {
+ (*timer_interface)->reset();
+ }
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Return the average time for timer execution as the total time
+//! for the timer dividied by the number of completed (stopped) runs the timer
+//! has made.
+//! Excludes the current running time if the timer is currently running.
+//! @param name name of the timer to return the time of
+////////////////////////////////////////////////////////////////////////////////
+inline float
+sdkGetAverageTimerValue(StopWatchInterface **timer_interface)
+{
+ // printf("sdkGetAverageTimerValue called object %08x\n", (void *)*timer_interface);
+ if (*timer_interface)
+ {
+ return (*timer_interface)->getAverageTime();
+ }
+ else
+ {
+ return 0.0f;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//! Total execution time for the timer over all runs since the last reset
+//! or timer creation.
+//! @param name name of the timer to obtain the value of.
+////////////////////////////////////////////////////////////////////////////////
+inline float
+sdkGetTimerValue(StopWatchInterface **timer_interface)
+{
+ // printf("sdkGetTimerValue called object %08x\n", (void *)*timer_interface);
+ if (*timer_interface)
+ {
+ return (*timer_interface)->getTime();
+ }
+ else
+ {
+ return 0.0f;
+ }
+}
+
+#endif // HELPER_TIMER_H
diff --git a/tests/projects/cuda_console/inc/multithreading.h b/tests/projects/cuda_console/inc/multithreading.h
new file mode 100644
index 000000000..f31b72737
--- /dev/null
+++ b/tests/projects/cuda_console/inc/multithreading.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef MULTITHREADING_H
+#define MULTITHREADING_H
+
+
+//Simple portable thread library.
+
+//Windows threads.
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#include <windows.h>
+
+typedef HANDLE CUTThread;
+typedef unsigned(WINAPI *CUT_THREADROUTINE)(void *);
+
+#define CUT_THREADPROC unsigned WINAPI
+#define CUT_THREADEND return 0
+
+#else
+//POSIX threads.
+#include <pthread.h>
+
+typedef pthread_t CUTThread;
+typedef void *(*CUT_THREADROUTINE)(void *);
+
+#define CUT_THREADPROC void
+#define CUT_THREADEND
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//Create thread.
+CUTThread cutStartThread(CUT_THREADROUTINE, void *data);
+
+//Wait for thread to finish.
+void cutEndThread(CUTThread thread);
+
+//Destroy thread.
+void cutDestroyThread(CUTThread thread);
+
+//Wait for multiple threads.
+void cutWaitForThreads(const CUTThread *threads, int num);
+
+#ifdef __cplusplus
+} //extern "C"
+#endif
+
+#endif //MULTITHREADING_H
diff --git a/tests/projects/cuda_console/inc/nvMath.h b/tests/projects/cuda_console/inc/nvMath.h
new file mode 100644
index 000000000..a9b91522e
--- /dev/null
+++ b/tests/projects/cuda_console/inc/nvMath.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+//
+// Template math library for common 3D functionality
+//
+// This code is in part deriver from glh, a cross platform glut helper library.
+// The copyright for glh follows this notice.
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ Copyright (c) 2000 Cass Everitt
+ Copyright (c) 2000 NVIDIA Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, are permitted provided that the following
+ conditions are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * The names of contributors to this software may not be used
+ to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+
+ Cass Everitt - [email protected]
+*/
+
+#ifndef NV_MATH_H
+#define NV_MATH_H
+
+#include <math.h>
+
+#include <nvVector.h>
+#include <nvMatrix.h>
+#include <nvQuaternion.h>
+
+#define NV_PI float(3.1415926535897932384626433832795)
+
+namespace nv
+{
+
+ typedef vec2<float> vec2f;
+ typedef vec3<float> vec3f;
+ typedef vec3<int> vec3i;
+ typedef vec3<unsigned int> vec3ui;
+ typedef vec4<float> vec4f;
+ typedef matrix4<float> matrix4f;
+ typedef quaternion<float> quaternionf;
+
+
+ inline void applyRotation(const quaternionf &r)
+ {
+ float angle;
+ vec3f axis;
+ r.get_value(axis, angle);
+ glRotatef(angle/3.1415926f * 180.0f, axis[0], axis[1], axis[2]);
+ }
+
+
+
+};
+
+#endif
diff --git a/tests/projects/cuda_console/inc/nvMatrix.h b/tests/projects/cuda_console/inc/nvMatrix.h
new file mode 100644
index 000000000..31ad6ecc5
--- /dev/null
+++ b/tests/projects/cuda_console/inc/nvMatrix.h
@@ -0,0 +1,524 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+//
+// Template math library for common 3D functionality
+//
+// nvMatrix.h - template matrix code
+//
+// This code is in part deriver from glh, a cross platform glut helper library.
+// The copyright for glh follows this notice.
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ Copyright (c) 2000 Cass Everitt
+ Copyright (c) 2000 NVIDIA Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, are permitted provided that the following
+ conditions are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * The names of contributors to this software may not be used
+ to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+
+ Cass Everitt - [email protected]
+*/
+
+#ifndef NV_MATRIX_H
+#define NV_MATRIX_H
+
+namespace nv
+{
+
+ template <class T> class vec2;
+ template <class T> class vec3;
+ template <class T> class vec4;
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Matrix
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+ template<class T>
+ class matrix4
+ {
+
+ public:
+
+ matrix4()
+ {
+ make_identity();
+ }
+
+ matrix4(T t)
+ {
+ set_value(t);
+ }
+
+ matrix4(const T *m)
+ {
+ set_value(m);
+ }
+
+ matrix4(T a00, T a01, T a02, T a03,
+ T a10, T a11, T a12, T a13,
+ T a20, T a21, T a22, T a23,
+ T a30, T a31, T a32, T a33) :
+ _11(a00), _12(a01), _13(a02), _14(a03),
+ _21(a10), _22(a11), _23(a12), _24(a13),
+ _31(a20), _32(a21), _33(a22), _34(a23),
+ _41(a30), _42(a31), _43(a32), _44(a33)
+ {}
+
+
+ void get_value(T *mp) const
+ {
+ int c = 0;
+
+ for (int j=0; j < 4; j++)
+ for (int i=0; i < 4; i++)
+ {
+ mp[c++] = element(i,j);
+ }
+ }
+
+ const T *get_value() const
+ {
+ return _array;
+ }
+
+ void set_value(T *mp)
+ {
+ int c = 0;
+
+ for (int j=0; j < 4; j++)
+ for (int i=0; i < 4; i++)
+ {
+ element(i,j) = mp[c++];
+ }
+ }
+
+ void set_value(T r)
+ {
+ for (int i=0; i < 4; i++)
+ for (int j=0; j < 4; j++)
+ {
+ element(i,j) = r;
+ }
+ }
+
+ void make_identity()
+ {
+ element(0,0) = 1.0;
+ element(0,1) = 0.0;
+ element(0,2) = 0.0;
+ element(0,3) = 0.0;
+
+ element(1,0) = 0.0;
+ element(1,1) = 1.0;
+ element(1,2) = 0.0;
+ element(1,3) = 0.0;
+
+ element(2,0) = 0.0;
+ element(2,1) = 0.0;
+ element(2,2) = 1.0;
+ element(2,3) = 0.0;
+
+ element(3,0) = 0.0;
+ element(3,1) = 0.0;
+ element(3,2) = 0.0;
+ element(3,3) = 1.0;
+ }
+
+ // set a uniform scale
+ void set_scale(T s)
+ {
+ element(0,0) = s;
+ element(1,1) = s;
+ element(2,2) = s;
+ }
+
+ void set_scale(const vec3<T> &s)
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ element(i,i) = s[i];
+ }
+ }
+
+
+ void set_translate(const vec3<T> &t)
+ {
+ for (int i = 0; i < 3; i++)
+ {
+ element(i,3) = t[i];
+ }
+ }
+
+ void set_row(int r, const vec4<T> &t)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ element(r,i) = t[i];
+ }
+ }
+
+ void set_column(int c, const vec4<T> &t)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ element(i,c) = t[i];
+ }
+ }
+
+ vec4<T> get_row(int r) const
+ {
+ vec4<T> v;
+
+ for (int i = 0; i < 4; i++)
+ {
+ v[i] = element(r,i);
+ }
+
+ return v;
+ }
+
+ vec4<T> get_column(int c) const
+ {
+ vec4<T> v;
+
+ for (int i = 0; i < 4; i++)
+ {
+ v[i] = element(i,c);
+ }
+
+ return v;
+ }
+
+ friend matrix4 inverse(const matrix4 &m)
+ {
+ matrix4 minv;
+
+ T r1[8], r2[8], r3[8], r4[8];
+ T *s[4], *tmprow;
+
+ s[0] = &r1[0];
+ s[1] = &r2[0];
+ s[2] = &r3[0];
+ s[3] = &r4[0];
+
+ register int i,j,p,jj;
+
+ for (i=0; i<4; i++)
+ {
+ for (j=0; j<4; j++)
+ {
+ s[i][j] = m.element(i,j);
+
+ if (i==j)
+ {
+ s[i][j+4] = 1.0;
+ }
+ else
+ {
+ s[i][j+4] = 0.0;
+ }
+ }
+ }
+
+ T scp[4];
+
+ for (i=0; i<4; i++)
+ {
+ scp[i] = T(fabs(s[i][0]));
+
+ for (j=1; j<4; j++)
+ if (T(fabs(s[i][j])) > scp[i])
+ {
+ scp[i] = T(fabs(s[i][j]));
+ }
+
+ if (scp[i] == 0.0)
+ {
+ return minv; // singular matrix!
+ }
+ }
+
+ int pivot_to;
+ T scp_max;
+
+ for (i=0; i<4; i++)
+ {
+ // select pivot row
+ pivot_to = i;
+ scp_max = T(fabs(s[i][i]/scp[i]));
+
+ // find out which row should be on top
+ for (p=i+1; p<4; p++)
+ if (T(fabs(s[p][i]/scp[p])) > scp_max)
+ {
+ scp_max = T(fabs(s[p][i]/scp[p]));
+ pivot_to = p;
+ }
+
+ // Pivot if necessary
+ if (pivot_to != i)
+ {
+ tmprow = s[i];
+ s[i] = s[pivot_to];
+ s[pivot_to] = tmprow;
+ T tmpscp;
+ tmpscp = scp[i];
+ scp[i] = scp[pivot_to];
+ scp[pivot_to] = tmpscp;
+ }
+
+ T mji;
+
+ // perform gaussian elimination
+ for (j=i+1; j<4; j++)
+ {
+ mji = s[j][i]/s[i][i];
+ s[j][i] = 0.0;
+
+ for (jj=i+1; jj<8; jj++)
+ {
+ s[j][jj] -= mji*s[i][jj];
+ }
+ }
+ }
+
+ if (s[3][3] == 0.0)
+ {
+ return minv; // singular matrix!
+ }
+
+ //
+ // Now we have an upper triangular matrix.
+ //
+ // x x x x | y y y y
+ // 0 x x x | y y y y
+ // 0 0 x x | y y y y
+ // 0 0 0 x | y y y y
+ //
+ // we'll back substitute to get the inverse
+ //
+ // 1 0 0 0 | z z z z
+ // 0 1 0 0 | z z z z
+ // 0 0 1 0 | z z z z
+ // 0 0 0 1 | z z z z
+ //
+
+ T mij;
+
+ for (i=3; i>0; i--)
+ {
+ for (j=i-1; j > -1; j--)
+ {
+ mij = s[j][i]/s[i][i];
+
+ for (jj=j+1; jj<8; jj++)
+ {
+ s[j][jj] -= mij*s[i][jj];
+ }
+ }
+ }
+
+ for (i=0; i<4; i++)
+ for (j=0; j<4; j++)
+ {
+ minv(i,j) = s[i][j+4] / s[i][i];
+ }
+
+ return minv;
+ }
+
+
+ friend matrix4 transpose(const matrix4 &m)
+ {
+ matrix4 mtrans;
+
+ for (int i=0; i<4; i++)
+ for (int j=0; j<4; j++)
+ {
+ mtrans(i,j) = m.element(j,i);
+ }
+
+ return mtrans;
+ }
+
+ matrix4 &operator *= (const matrix4 &rhs)
+ {
+ matrix4 mt(*this);
+ set_value(T(0));
+
+ for (int i=0; i < 4; i++)
+ for (int j=0; j < 4; j++)
+ for (int c=0; c < 4; c++)
+ {
+ element(i,j) += mt(i,c) * rhs(c,j);
+ }
+
+ return *this;
+ }
+
+ friend matrix4 operator * (const matrix4 &lhs, const matrix4 &rhs)
+ {
+ matrix4 r(T(0));
+
+ for (int i=0; i < 4; i++)
+ for (int j=0; j < 4; j++)
+ for (int c=0; c < 4; c++)
+ {
+ r.element(i,j) += lhs(i,c) * rhs(c,j);
+ }
+
+ return r;
+ }
+
+ // dst = M * src
+ vec4<T> operator *(const vec4<T> &src) const
+ {
+ vec4<T> r;
+
+ for (int i = 0; i < 4; i++)
+ r[i] = (src[0] * element(i,0) + src[1] * element(i,1) +
+ src[2] * element(i,2) + src[3] * element(i,3));
+
+ return r;
+ }
+
+ // dst = src * M
+ friend vec4<T> operator *(const vec4<T> &lhs, const matrix4 &rhs)
+ {
+ vec4<T> r;
+
+ for (int i = 0; i < 4; i++)
+ r[i] = (lhs[0] * rhs.element(0,i) + lhs[1] * rhs.element(1,i) +
+ lhs[2] * rhs.element(2,i) + lhs[3] * rhs.element(3,i));
+
+ return r;
+ }
+
+ T &operator()(int row, int col)
+ {
+ return element(row,col);
+ }
+
+ const T &operator()(int row, int col) const
+ {
+ return element(row,col);
+ }
+
+ T &element(int row, int col)
+ {
+ return _array[row | (col<<2)];
+ }
+
+ const T &element(int row, int col) const
+ {
+ return _array[row | (col<<2)];
+ }
+
+ matrix4 &operator *= (const T &r)
+ {
+ for (int i = 0; i < 4; ++i)
+ {
+ element(0,i) *= r;
+ element(1,i) *= r;
+ element(2,i) *= r;
+ element(3,i) *= r;
+ }
+
+ return *this;
+ }
+
+ matrix4 &operator += (const matrix4 &mat)
+ {
+ for (int i = 0; i < 4; ++i)
+ {
+ element(0,i) += mat.element(0,i);
+ element(1,i) += mat.element(1,i);
+ element(2,i) += mat.element(2,i);
+ element(3,i) += mat.element(3,i);
+ }
+
+ return *this;
+ }
+
+
+ friend bool operator == (const matrix4 &lhs, const matrix4 &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < 16; i++)
+ {
+ r &= lhs._array[i] == rhs._array[i];
+ }
+
+ return r;
+ }
+
+ friend bool operator != (const matrix4 &lhs, const matrix4 &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < 16; i++)
+ {
+ r &= lhs._array[i] != rhs._array[i];
+ }
+
+ return r;
+ }
+
+ union
+ {
+ struct
+ {
+ T _11, _12, _13, _14; // standard names for components
+ T _21, _22, _23, _24; // standard names for components
+ T _31, _32, _33, _34; // standard names for components
+ T _41, _42, _43, _44; // standard names for components
+ };
+ T _array[16]; // array access
+ };
+ };
+
+};
+
+#endif
diff --git a/tests/projects/cuda_console/inc/nvQuaternion.h b/tests/projects/cuda_console/inc/nvQuaternion.h
new file mode 100644
index 000000000..9b5d9b93e
--- /dev/null
+++ b/tests/projects/cuda_console/inc/nvQuaternion.h
@@ -0,0 +1,514 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+//
+// Template math library for common 3D functionality
+//
+// nvQuaterion.h - quaternion template and utility functions
+//
+// This code is in part deriver from glh, a cross platform glut helper library.
+// The copyright for glh follows this notice.
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ Copyright (c) 2000 Cass Everitt
+ Copyright (c) 2000 NVIDIA Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, are permitted provided that the following
+ conditions are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * The names of contributors to this software may not be used
+ to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+
+ Cass Everitt - [email protected]
+*/
+#ifndef NV_QUATERNION_H
+#define NV_QUATERNION_H
+
+namespace nv
+{
+
+ template <class T> class vec2;
+ template <class T> class vec3;
+ template <class T> class vec4;
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Quaternion
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+
+ template< class T>
+ class quaternion
+ {
+ public:
+
+ quaternion() : x(0.0), y(0.0), z(0.0), w(0.0)
+ {
+ }
+
+ quaternion(const T v[4])
+ {
+ set_value(v);
+ }
+
+
+ quaternion(T q0, T q1, T q2, T q3)
+ {
+ set_value(q0, q1, q2, q3);
+ }
+
+
+ quaternion(const matrix4<T> &m)
+ {
+ set_value(m);
+ }
+
+
+ quaternion(const vec3<T> &axis, T radians)
+ {
+ set_value(axis, radians);
+ }
+
+
+ quaternion(const vec3<T> &rotateFrom, const vec3<T> &rotateTo)
+ {
+ set_value(rotateFrom, rotateTo);
+ }
+
+ quaternion(const vec3<T> &from_look, const vec3<T> &from_up,
+ const vec3<T> &to_look, const vec3<T> &to_up)
+ {
+ set_value(from_look, from_up, to_look, to_up);
+ }
+
+ const T *get_value() const
+ {
+ return &_array[0];
+ }
+
+ void get_value(T &q0, T &q1, T &q2, T &q3) const
+ {
+ q0 = _array[0];
+ q1 = _array[1];
+ q2 = _array[2];
+ q3 = _array[3];
+ }
+
+ quaternion &set_value(T q0, T q1, T q2, T q3)
+ {
+ _array[0] = q0;
+ _array[1] = q1;
+ _array[2] = q2;
+ _array[3] = q3;
+ return *this;
+ }
+
+ void get_value(vec3<T> &axis, T &radians) const
+ {
+ radians = T(acos(_array[3]) * T(2.0));
+
+ if (radians == T(0.0))
+ {
+ axis = vec3<T>(0.0, 0.0, 1.0);
+ }
+ else
+ {
+ axis[0] = _array[0];
+ axis[1] = _array[1];
+ axis[2] = _array[2];
+ axis = normalize(axis);
+ }
+ }
+
+ void get_value(matrix4<T> &m) const
+ {
+ T s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
+
+ T norm = _array[0] * _array[0] + _array[1] * _array[1] + _array[2] * _array[2] + _array[3] * _array[3];
+
+ s = (norm == T(0.0)) ? T(0.0) : (T(2.0) / norm);
+
+ xs = _array[0] * s;
+ ys = _array[1] * s;
+ zs = _array[2] * s;
+
+ wx = _array[3] * xs;
+ wy = _array[3] * ys;
+ wz = _array[3] * zs;
+
+ xx = _array[0] * xs;
+ xy = _array[0] * ys;
+ xz = _array[0] * zs;
+
+ yy = _array[1] * ys;
+ yz = _array[1] * zs;
+ zz = _array[2] * zs;
+
+ m(0,0) = T(T(1.0) - (yy + zz));
+ m(1,0) = T(xy + wz);
+ m(2,0) = T(xz - wy);
+
+ m(0,1) = T(xy - wz);
+ m(1,1) = T(T(1.0) - (xx + zz));
+ m(2,1) = T(yz + wx);
+
+ m(0,2) = T(xz + wy);
+ m(1,2) = T(yz - wx);
+ m(2,2) = T(T(1.0) - (xx + yy));
+
+ m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = T(0.0);
+ m(3,3) = T(1.0);
+ }
+
+ quaternion &set_value(const T *qp)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ _array[i] = qp[i];
+ }
+
+ return *this;
+ }
+
+ quaternion &set_value(const matrix4<T> &m)
+ {
+ T tr, s;
+ int i, j, k;
+ const int nxt[3] = { 1, 2, 0 };
+
+ tr = m(0,0) + m(1,1) + m(2,2);
+
+ if (tr > T(0))
+ {
+ s = T(sqrt(tr + m(3,3)));
+ _array[3] = T(s * 0.5);
+ s = T(0.5) / s;
+
+ _array[0] = T((m(1,2) - m(2,1)) * s);
+ _array[1] = T((m(2,0) - m(0,2)) * s);
+ _array[2] = T((m(0,1) - m(1,0)) * s);
+ }
+ else
+ {
+ i = 0;
+
+ if (m(1,1) > m(0,0))
+ {
+ i = 1;
+ }
+
+ if (m(2,2) > m(i,i))
+ {
+ i = 2;
+ }
+
+ j = nxt[i];
+ k = nxt[j];
+
+ s = T(sqrt((m(i,j) - (m(j,j) + m(k,k))) + T(1.0)));
+
+ _array[i] = T(s * 0.5);
+ s = T(0.5 / s);
+
+ _array[3] = T((m(j,k) - m(k,j)) * s);
+ _array[j] = T((m(i,j) + m(j,i)) * s);
+ _array[k] = T((m(i,k) + m(k,i)) * s);
+ }
+
+ return *this;
+ }
+
+ quaternion &set_value(const vec3<T> &axis, T theta)
+ {
+ T sqnorm = square_norm(axis);
+
+ if (sqnorm == T(0.0))
+ {
+ // axis too small.
+ x = y = z = T(0.0);
+ w = T(1.0);
+ }
+ else
+ {
+ theta *= T(0.5);
+ T sin_theta = T(sin(theta));
+
+ if (sqnorm != T(1))
+ {
+ sin_theta /= T(sqrt(sqnorm));
+ }
+
+ x = sin_theta * axis[0];
+ y = sin_theta * axis[1];
+ z = sin_theta * axis[2];
+ w = T(cos(theta));
+ }
+
+ return *this;
+ }
+
+ quaternion &set_value(const vec3<T> &rotateFrom, const vec3<T> &rotateTo)
+ {
+ vec3<T> p1, p2;
+ T alpha;
+
+ p1 = normalize(rotateFrom);
+ p2 = normalize(rotateTo);
+
+ alpha = dot(p1, p2);
+
+ if (alpha == T(1.0))
+ {
+ *this = quaternion();
+ return *this;
+ }
+
+ // ensures that the anti-parallel case leads to a positive dot
+ if (alpha == T(-1.0))
+ {
+ vec3<T> v;
+
+ if (p1[0] != p1[1] || p1[0] != p1[2])
+ {
+ v = vec3<T>(p1[1], p1[2], p1[0]);
+ }
+ else
+ {
+ v = vec3<T>(-p1[0], p1[1], p1[2]);
+ }
+
+ v -= p1 * dot(p1, v);
+ v = normalize(v);
+
+ set_value(v, T(3.1415926));
+ return *this;
+ }
+
+ p1 = normalize(cross(p1, p2));
+
+ set_value(p1,T(acos(alpha)));
+
+ return *this;
+ }
+
+ quaternion &set_value(const vec3<T> &from_look, const vec3<T> &from_up,
+ const vec3<T> &to_look, const vec3<T> &to_up)
+ {
+ quaternion r_look = quaternion(from_look, to_look);
+
+ vec3<T> rotated_from_up(from_up);
+ r_look.mult_vec(rotated_from_up);
+
+ quaternion r_twist = quaternion(rotated_from_up, to_up);
+
+ *this = r_twist;
+ *this *= r_look;
+ return *this;
+ }
+
+ quaternion &operator *= (const quaternion<T> &qr)
+ {
+ quaternion ql(*this);
+
+ w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z;
+ x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y;
+ y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z;
+ z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x;
+
+ return *this;
+ }
+
+ friend quaternion normalize(const quaternion<T> &q)
+ {
+ quaternion r(q);
+ T rnorm = T(1.0) / T(sqrt(q.w * q.w + q.x * q.x + q.y * q.y + q.z * q.z));
+
+ r.x *= rnorm;
+ r.y *= rnorm;
+ r.z *= rnorm;
+ r.w *= rnorm;
+ }
+
+ friend quaternion<T> conjugate(const quaternion<T> &q)
+ {
+ quaternion<T> r(q);
+ r._array[0] *= T(-1.0);
+ r._array[1] *= T(-1.0);
+ r._array[2] *= T(-1.0);
+ return r;
+ }
+
+ friend quaternion<T> inverse(const quaternion<T> &q)
+ {
+ return conjugate(q);
+ }
+
+ //
+ // Quaternion multiplication with cartesian vector
+ // v' = q*v*q(star)
+ //
+ void mult_vec(const vec3<T> &src, vec3<T> &dst) const
+ {
+ T v_coef = w * w - x * x - y * y - z * z;
+ T u_coef = T(2.0) * (src[0] * x + src[1] * y + src[2] * z);
+ T c_coef = T(2.0) * w;
+
+ dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]);
+ dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]);
+ dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]);
+ }
+
+ void mult_vec(vec3<T> &src_and_dst) const
+ {
+ mult_vec(vec3<T>(src_and_dst), src_and_dst);
+ }
+
+ void scale_angle(T scaleFactor)
+ {
+ vec3<T> axis;
+ T radians;
+
+ get_value(axis, radians);
+ radians *= scaleFactor;
+ set_value(axis, radians);
+ }
+
+ friend quaternion<T> slerp(const quaternion<T> &p, const quaternion<T> &q, T alpha)
+ {
+ quaternion r;
+
+ T cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w;
+ // if B is on opposite hemisphere from A, use -B instead
+
+ int bflip;
+
+ if ((bflip = (cos_omega < T(0))))
+ {
+ cos_omega = -cos_omega;
+ }
+
+ // complementary interpolation parameter
+ T beta = T(1) - alpha;
+
+ if (cos_omega >= T(1))
+ {
+ return p;
+ }
+
+ T omega = T(acos(cos_omega));
+ T one_over_sin_omega = T(1.0) / T(sin(omega));
+
+ beta = T(sin(omega*beta) * one_over_sin_omega);
+ alpha = T(sin(omega*alpha) * one_over_sin_omega);
+
+ if (bflip)
+ {
+ alpha = -alpha;
+ }
+
+ r.x = beta * p._array[0]+ alpha * q._array[0];
+ r.y = beta * p._array[1]+ alpha * q._array[1];
+ r.z = beta * p._array[2]+ alpha * q._array[2];
+ r.w = beta * p._array[3]+ alpha * q._array[3];
+ return r;
+ }
+
+ T &operator [](int i)
+ {
+ return _array[i];
+ }
+
+ const T &operator [](int i) const
+ {
+ return _array[i];
+ }
+
+
+ friend bool operator == (const quaternion<T> &lhs, const quaternion<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < 4; i++)
+ {
+ r &= lhs._array[i] == rhs._array[i];
+ }
+
+ return r;
+ }
+
+ friend bool operator != (const quaternion<T> &lhs, const quaternion<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < 4; i++)
+ {
+ r &= lhs._array[i] == rhs._array[i];
+ }
+
+ return r;
+ }
+
+ friend quaternion<T> operator * (const quaternion<T> &lhs, const quaternion<T> &rhs)
+ {
+ quaternion r(lhs);
+ r *= rhs;
+ return r;
+ }
+
+
+ union
+ {
+ struct
+ {
+ T x;
+ T y;
+ T z;
+ T w;
+ };
+ T _array[4];
+ };
+
+ };
+
+
+
+};
+
+#endif
diff --git a/tests/projects/cuda_console/inc/nvShaderUtils.h b/tests/projects/cuda_console/inc/nvShaderUtils.h
new file mode 100644
index 000000000..3c41c763f
--- /dev/null
+++ b/tests/projects/cuda_console/inc/nvShaderUtils.h
@@ -0,0 +1,255 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+/*
+ *
+ * Utility functions for compiling shaders and programs
+ *
+ * Author: Evan Hart
+ * Copyright (c) NVIDIA Corporation. All rights reserved.
+ *
+ */
+
+
+#ifndef NV_SHADER_UTILS_H
+#define NV_SHADER_UTILS_H
+
+#include <stdio.h>
+#include <string.h>
+
+namespace nv
+{
+
+
+ //
+ //
+ ////////////////////////////////////////////////////////////
+ inline GLuint CompileGLSLShader(GLenum target, const char *shader)
+ {
+ GLuint object;
+
+ object = glCreateShader(target);
+
+ if (!object)
+ {
+ return object;
+ }
+
+ glShaderSource(object, 1, &shader, NULL);
+
+ glCompileShader(object);
+
+ // check if shader compiled
+ GLint compiled = 0;
+ glGetShaderiv(object, GL_COMPILE_STATUS, &compiled);
+
+ if (!compiled)
+ {
+#ifdef NV_REPORT_COMPILE_ERRORS
+ char temp[256] = "";
+ glGetShaderInfoLog(object, 256, NULL, temp);
+ fprintf(stderr, "Compile failed:\n%s\n", temp);
+#endif
+ glDeleteShader(object);
+ return 0;
+ }
+
+ return object;
+ }
+
+ //
+ //
+ ////////////////////////////////////////////////////////////
+ inline GLuint CompileGLSLShaderFromFile(GLenum target, const char *filename)
+ {
+ FILE *shaderFile;
+ char *text;
+ long size;
+ size_t fsize = 0;
+
+ // read files as binary to prevent problems from newline translation
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+
+ if (fopen_s(&shaderFile, filename, "rb") != 0)
+#else
+ if ((shaderFile = fopen(filename, "rb")) == 0)
+#endif
+ {
+ return 0;
+ }
+
+ // Get the length of the file
+ fseek(shaderFile, 0, SEEK_END);
+ size = ftell(shaderFile);
+
+ // Read the file contents from the start, then close file and add a null terminator
+ fseek(shaderFile, 0, SEEK_SET);
+ text = new char[size+1];
+ fsize = fread(text, size, 1, shaderFile);
+ fclose(shaderFile);
+
+ if (fsize == 0)
+ {
+ printf("CompileGLSLShaderFromFile(), error... fsize = 0\n");
+ }
+
+ text[size] = '\0';
+
+ GLuint object = CompileGLSLShader(target, text);
+
+ delete []text;
+
+ return object;
+ }
+
+
+ // Create a program composed of vertex and fragment shaders.
+ inline GLuint LinkGLSLProgram(GLuint vertexShader, GLuint fragmentShader)
+ {
+ GLuint program = glCreateProgram();
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, fragmentShader);
+ glLinkProgram(program);
+
+#ifdef NV_REPORT_COMPILE_ERRORS
+ // Get error log.
+ GLint charsWritten, infoLogLength;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+ char *infoLog = new char[infoLogLength];
+ glGetProgramInfoLog(program, infoLogLength, &charsWritten, infoLog);
+ printf(infoLog);
+ delete [] infoLog;
+#endif
+
+ // Test linker result.
+ GLint linkSucceed = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkSucceed);
+
+ if (linkSucceed == GL_FALSE)
+ {
+ glDeleteProgram(program);
+ return 0;
+ }
+
+ return program;
+ }
+
+
+ // Create a program composed of vertex, geometry and fragment shaders.
+ inline GLuint LinkGLSLProgram(GLuint vertexShader, GLuint geometryShader, GLint inputType, GLint vertexOut, GLint outputType, GLuint fragmentShader)
+ {
+ GLuint program = glCreateProgram();
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, geometryShader);
+ glProgramParameteriEXT(program, GL_GEOMETRY_INPUT_TYPE_EXT, inputType);
+ glProgramParameteriEXT(program, GL_GEOMETRY_VERTICES_OUT_EXT, vertexOut);
+ glProgramParameteriEXT(program, GL_GEOMETRY_OUTPUT_TYPE_EXT, outputType);
+ glAttachShader(program, fragmentShader);
+ glLinkProgram(program);
+
+#ifdef NV_REPORT_COMPILE_ERRORS
+ // Get error log.
+ GLint charsWritten, infoLogLength;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+ char *infoLog = new char[infoLogLength];
+ glGetProgramInfoLog(program, infoLogLength, &charsWritten, infoLog);
+ printf(infoLog);
+ delete [] infoLog;
+#endif
+
+ // Test linker result.
+ GLint linkSucceed = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkSucceed);
+
+ if (linkSucceed == GL_FALSE)
+ {
+ glDeleteProgram(program);
+ return 0;
+ }
+
+ return program;
+ }
+
+ //
+ //
+ ////////////////////////////////////////////////////////////
+ inline GLuint CompileASMShader(GLenum program_type, const char *code)
+ {
+ GLuint program_id;
+ glGenProgramsARB(1, &program_id);
+ glBindProgramARB(program_type, program_id);
+ glProgramStringARB(program_type, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei) strlen(code), (GLubyte *) code);
+
+ GLint error_pos;
+ glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);
+
+ if (error_pos != -1)
+ {
+#ifdef NV_REPORT_COMPILE_ERRORS
+ const GLubyte *error_string;
+ error_string = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
+ fprintf(stderr, "Program error at position: %d\n%s\n", (int)error_pos, error_string);
+#endif
+ return 0;
+ }
+
+ return program_id;
+ }
+
+ //
+ //
+ ////////////////////////////////////////////////////////////
+ inline GLuint CompileASMShaderFromFile(GLenum target, const char *filename)
+ {
+ FILE *shaderFile;
+ char *text;
+ long size;
+ size_t fsize = 0;
+
+ // read files as binary to prevent problems from newline translation
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+
+ if (fopen_s(&shaderFile, filename, "rb") != 0)
+#else
+ if ((shaderFile = fopen(filename, "rb")) == 0)
+#endif
+ {
+ return 0;
+ }
+
+ // Get the length of the file
+ fseek(shaderFile, 0, SEEK_END);
+ size = ftell(shaderFile);
+
+ // Read the file contents from the start, then close file and add a null terminator
+ fseek(shaderFile, 0, SEEK_SET);
+ text = new char[size+1];
+ fsize = fread(text, size, 1, shaderFile);
+ fclose(shaderFile);
+
+ if (fsize == 0)
+ {
+ printf("CompileGLSLShaderFromFile(), error... fsize = 0\n");
+ }
+
+ text[size] = '\0';
+
+ GLuint program_id = CompileASMShader(target, text);
+
+ delete []text;
+
+ return program_id;
+ }
+
+} // nv namespace
+#endif
diff --git a/tests/projects/cuda_console/inc/nvVector.h b/tests/projects/cuda_console/inc/nvVector.h
new file mode 100644
index 000000000..f0c25759e
--- /dev/null
+++ b/tests/projects/cuda_console/inc/nvVector.h
@@ -0,0 +1,1058 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+//
+// Template math library for common 3D functionality
+//
+// nvVector.h - 2-vector, 3-vector, and 4-vector templates and utilities
+//
+// This code is in part deriver from glh, a cross platform glut helper library.
+// The copyright for glh follows this notice.
+//
+// Copyright (c) NVIDIA Corporation. All rights reserved.
+////////////////////////////////////////////////////////////////////////////////
+
+/*
+ Copyright (c) 2000 Cass Everitt
+ Copyright (c) 2000 NVIDIA Corporation
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, are permitted provided that the following
+ conditions are met:
+
+ * Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the following
+ disclaimer.
+
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * The names of contributors to this software may not be used
+ to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+
+
+ Cass Everitt - [email protected]
+*/
+#ifndef NV_VECTOR_H
+#define NV_VECTOR_H
+
+namespace nv
+{
+
+ template <class T> class vec2;
+ template <class T> class vec3;
+ template <class T> class vec4;
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // vec2 - template class for 2-tuple vector
+ //
+ //////////////////////////////////////////////////////////////////////
+ template <class T>
+ class vec2
+ {
+ public:
+
+ typedef T value_type;
+ int size() const
+ {
+ return 2;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Constructors
+ //
+ ////////////////////////////////////////////////////////
+
+ // Default/scalar constructor
+ vec2(const T &t = T())
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = t;
+ }
+ }
+
+ // Construct from array
+ vec2(const T *tp)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = tp[i];
+ }
+ }
+
+ // Construct from explicit values
+ vec2(const T v0, const T v1)
+ {
+ x = v0;
+ y = v1;
+ }
+
+ explicit vec2(const vec3<T> &u)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = u._array[i];
+ }
+ }
+
+ explicit vec2(const vec4<T> &u)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = u._array[i];
+ }
+ }
+
+ const T *get_value() const
+ {
+ return _array;
+ }
+
+ vec2<T> &set_value(const T *rhs)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = rhs[i];
+ }
+
+ return *this;
+ }
+
+ // indexing operators
+ T &operator [](int i)
+ {
+ return _array[i];
+ }
+
+ const T &operator [](int i) const
+ {
+ return _array[i];
+ }
+
+ // type-cast operators
+ operator T *()
+ {
+ return _array;
+ }
+
+ operator const T *() const
+ {
+ return _array;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Math operators
+ //
+ ////////////////////////////////////////////////////////
+
+ // scalar multiply assign
+ friend vec2<T> &operator *= (vec2<T> &lhs, T d)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] *= d;
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector multiply assign
+ friend vec2<T> &operator *= (vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] *= rhs[i];
+ }
+
+ return lhs;
+ }
+
+ // scalar divide assign
+ friend vec2<T> &operator /= (vec2<T> &lhs, T d)
+ {
+ if (d == 0)
+ {
+ return lhs;
+ }
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] /= d;
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector divide assign
+ friend vec2<T> &operator /= (vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] /= rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector add assign
+ friend vec2<T> &operator += (vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] += rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector subtract assign
+ friend vec2<T> &operator -= (vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] -= rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // unary negate
+ friend vec2<T> operator - (const vec2<T> &rhs)
+ {
+ vec2<T> rv;
+
+ for (int i = 0; i < rhs.size(); i++)
+ {
+ rv._array[i] = -rhs._array[i];
+ }
+
+ return rv;
+ }
+
+ // vector add
+ friend vec2<T> operator + (const vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ vec2<T> rt(lhs);
+ return rt += rhs;
+ }
+
+ // vector subtract
+ friend vec2<T> operator - (const vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ vec2<T> rt(lhs);
+ return rt -= rhs;
+ }
+
+ // scalar multiply
+ friend vec2<T> operator * (const vec2<T> &lhs, T rhs)
+ {
+ vec2<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // scalar multiply
+ friend vec2<T> operator * (T lhs, const vec2<T> &rhs)
+ {
+ vec2<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // vector component-wise multiply
+ friend vec2<T> operator * (const vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ vec2<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // scalar multiply
+ friend vec2<T> operator / (const vec2<T> &lhs, T rhs)
+ {
+ vec2<T> rt(lhs);
+ return rt /= rhs;
+ }
+
+ // vector component-wise multiply
+ friend vec2<T> operator / (const vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ vec2<T> rt(lhs);
+ return rt /= rhs;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Comparison operators
+ //
+ ////////////////////////////////////////////////////////
+
+ // equality
+ friend bool operator == (const vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ r &= lhs._array[i] == rhs._array[i];
+ }
+
+ return r;
+ }
+
+ // inequality
+ friend bool operator != (const vec2<T> &lhs, const vec2<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ r &= lhs._array[i] != rhs._array[i];
+ }
+
+ return r;
+ }
+
+ //data intentionally left public to allow vec2.x
+ union
+ {
+ struct
+ {
+ T x,y; // standard names for components
+ };
+ struct
+ {
+ T s,t; // standard names for components
+ };
+ T _array[2]; // array access
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // vec3 - template class for 3-tuple vector
+ //
+ //////////////////////////////////////////////////////////////////////
+ template <class T>
+ class vec3
+ {
+ public:
+
+ typedef T value_type;
+ int size() const
+ {
+ return 3;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Constructors
+ //
+ ////////////////////////////////////////////////////////
+
+ // Default/scalar constructor
+ vec3(const T &t = T())
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = t;
+ }
+ }
+
+ // Construct from array
+ vec3(const T *tp)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = tp[i];
+ }
+ }
+
+ // Construct from explicit values
+ vec3(const T v0, const T v1, const T v2)
+ {
+ x = v0;
+ y = v1;
+ z = v2;
+ }
+
+ explicit vec3(const vec4<T> &u)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = u._array[i];
+ }
+ }
+
+ explicit vec3(const vec2<T> &u, T v0)
+ {
+ x = u.x;
+ y = u.y;
+ z = v0;
+ }
+
+ const T *get_value() const
+ {
+ return _array;
+ }
+
+ vec3<T> &set_value(const T *rhs)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = rhs[i];
+ }
+
+ return *this;
+ }
+
+ // indexing operators
+ T &operator [](int i)
+ {
+ return _array[i];
+ }
+
+ const T &operator [](int i) const
+ {
+ return _array[i];
+ }
+
+ // type-cast operators
+ operator T *()
+ {
+ return _array;
+ }
+
+ operator const T *() const
+ {
+ return _array;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Math operators
+ //
+ ////////////////////////////////////////////////////////
+
+ // scalar multiply assign
+ friend vec3<T> &operator *= (vec3<T> &lhs, T d)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] *= d;
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector multiply assign
+ friend vec3<T> &operator *= (vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] *= rhs[i];
+ }
+
+ return lhs;
+ }
+
+ // scalar divide assign
+ friend vec3<T> &operator /= (vec3<T> &lhs, T d)
+ {
+ if (d == 0)
+ {
+ return lhs;
+ }
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] /= d;
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector divide assign
+ friend vec3<T> &operator /= (vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] /= rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector add assign
+ friend vec3<T> &operator += (vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] += rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector subtract assign
+ friend vec3<T> &operator -= (vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] -= rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // unary negate
+ friend vec3<T> operator - (const vec3<T> &rhs)
+ {
+ vec3<T> rv;
+
+ for (int i = 0; i < rhs.size(); i++)
+ {
+ rv._array[i] = -rhs._array[i];
+ }
+
+ return rv;
+ }
+
+ // vector add
+ friend vec3<T> operator + (const vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ vec3<T> rt(lhs);
+ return rt += rhs;
+ }
+
+ // vector subtract
+ friend vec3<T> operator - (const vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ vec3<T> rt(lhs);
+ return rt -= rhs;
+ }
+
+ // scalar multiply
+ friend vec3<T> operator * (const vec3<T> &lhs, T rhs)
+ {
+ vec3<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // scalar multiply
+ friend vec3<T> operator * (T lhs, const vec3<T> &rhs)
+ {
+ vec3<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // vector component-wise multiply
+ friend vec3<T> operator * (const vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ vec3<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // scalar multiply
+ friend vec3<T> operator / (const vec3<T> &lhs, T rhs)
+ {
+ vec3<T> rt(lhs);
+ return rt /= rhs;
+ }
+
+ // vector component-wise multiply
+ friend vec3<T> operator / (const vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ vec3<T> rt(lhs);
+ return rt /= rhs;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Comparison operators
+ //
+ ////////////////////////////////////////////////////////
+
+ // equality
+ friend bool operator == (const vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ r &= lhs._array[i] == rhs._array[i];
+ }
+
+ return r;
+ }
+
+ // inequality
+ friend bool operator != (const vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ r &= lhs._array[i] != rhs._array[i];
+ }
+
+ return r;
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // dimension specific operations
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // cross product
+ friend vec3<T> cross(const vec3<T> &lhs, const vec3<T> &rhs)
+ {
+ vec3<T> r;
+
+ r.x = lhs.y * rhs.z - lhs.z * rhs.y;
+ r.y = lhs.z * rhs.x - lhs.x * rhs.z;
+ r.z = lhs.x * rhs.y - lhs.y * rhs.x;
+
+ return r;
+ }
+
+ //data intentionally left public to allow vec2.x
+ union
+ {
+ struct
+ {
+ T x, y, z; // standard names for components
+ };
+ struct
+ {
+ T s, t, r; // standard names for components
+ };
+ T _array[3]; // array access
+ };
+ };
+
+ //////////////////////////////////////////////////////////////////////
+ //
+ // vec4 - template class for 4-tuple vector
+ //
+ //////////////////////////////////////////////////////////////////////
+ template <class T>
+ class vec4
+ {
+ public:
+
+ typedef T value_type;
+ int size() const
+ {
+ return 4;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Constructors
+ //
+ ////////////////////////////////////////////////////////
+
+ // Default/scalar constructor
+ vec4(const T &t = T())
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = t;
+ }
+ }
+
+ // Construct from array
+ vec4(const T *tp)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = tp[i];
+ }
+ }
+
+ // Construct from explicit values
+ vec4(const T v0, const T v1, const T v2, const T v3)
+ {
+ x = v0;
+ y = v1;
+ z = v2;
+ w = v3;
+ }
+
+ explicit vec4(const vec3<T> &u, T v0)
+ {
+ x = u.x;
+ y = u.y;
+ z = u.z;
+ w = v0;
+ }
+
+ explicit vec4(const vec2<T> &u, T v0, T v1)
+ {
+ x = u.x;
+ y = u.y;
+ z = v0;
+ w = v1;
+ }
+
+ const T *get_value() const
+ {
+ return _array;
+ }
+
+ vec4<T> &set_value(const T *rhs)
+ {
+ for (int i = 0; i < size(); i++)
+ {
+ _array[i] = rhs[i];
+ }
+
+ return *this;
+ }
+
+ // indexing operators
+ T &operator [](int i)
+ {
+ return _array[i];
+ }
+
+ const T &operator [](int i) const
+ {
+ return _array[i];
+ }
+
+ // type-cast operators
+ operator T *()
+ {
+ return _array;
+ }
+
+ operator const T *() const
+ {
+ return _array;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Math operators
+ //
+ ////////////////////////////////////////////////////////
+
+ // scalar multiply assign
+ friend vec4<T> &operator *= (vec4<T> &lhs, T d)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] *= d;
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector multiply assign
+ friend vec4<T> &operator *= (vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] *= rhs[i];
+ }
+
+ return lhs;
+ }
+
+ // scalar divide assign
+ friend vec4<T> &operator /= (vec4<T> &lhs, T d)
+ {
+ if (d == 0)
+ {
+ return lhs;
+ }
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] /= d;
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector divide assign
+ friend vec4<T> &operator /= (vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] /= rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector add assign
+ friend vec4<T> &operator += (vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] += rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // component-wise vector subtract assign
+ friend vec4<T> &operator -= (vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ lhs._array[i] -= rhs._array[i];
+ }
+
+ return lhs;
+ }
+
+ // unary negate
+ friend vec4<T> operator - (const vec4<T> &rhs)
+ {
+ vec4<T> rv;
+
+ for (int i = 0; i < rhs.size(); i++)
+ {
+ rv._array[i] = -rhs._array[i];
+ }
+
+ return rv;
+ }
+
+ // vector add
+ friend vec4<T> operator + (const vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ vec4<T> rt(lhs);
+ return rt += rhs;
+ }
+
+ // vector subtract
+ friend vec4<T> operator - (const vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ vec4<T> rt(lhs);
+ return rt -= rhs;
+ }
+
+ // scalar multiply
+ friend vec4<T> operator * (const vec4<T> &lhs, T rhs)
+ {
+ vec4<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // scalar multiply
+ friend vec4<T> operator * (T lhs, const vec4<T> &rhs)
+ {
+ vec4<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // vector component-wise multiply
+ friend vec4<T> operator * (const vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ vec4<T> rt(lhs);
+ return rt *= rhs;
+ }
+
+ // scalar multiply
+ friend vec4<T> operator / (const vec4<T> &lhs, T rhs)
+ {
+ vec4<T> rt(lhs);
+ return rt /= rhs;
+ }
+
+ // vector component-wise multiply
+ friend vec4<T> operator / (const vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ vec4<T> rt(lhs);
+ return rt /= rhs;
+ }
+
+ ////////////////////////////////////////////////////////
+ //
+ // Comparison operators
+ //
+ ////////////////////////////////////////////////////////
+
+ // equality
+ friend bool operator == (const vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ r &= lhs._array[i] == rhs._array[i];
+ }
+
+ return r;
+ }
+
+ // inequality
+ friend bool operator != (const vec4<T> &lhs, const vec4<T> &rhs)
+ {
+ bool r = true;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ r &= lhs._array[i] != rhs._array[i];
+ }
+
+ return r;
+ }
+
+ //data intentionally left public to allow vec2.x
+ union
+ {
+ struct
+ {
+ T x, y, z, w; // standard names for components
+ };
+ struct
+ {
+ T s, t, r, q; // standard names for components
+ };
+ T _array[4]; // array access
+ };
+ };
+
+ ////////////////////////////////////////////////////////////////////////////////
+ //
+ // Generic vector operations
+ //
+ ////////////////////////////////////////////////////////////////////////////////
+
+ // compute the dot product of two vectors
+ template<class T>
+ inline typename T::value_type dot(const T &lhs, const T &rhs)
+ {
+ typename T::value_type r = 0;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ r += lhs._array[i] * rhs._array[i];
+ }
+
+ return r;
+ }
+
+ // return the length of the provided vector
+ template< class T>
+ inline typename T::value_type length(const T &vec)
+ {
+ typename T::value_type r = 0;
+
+ for (int i = 0; i < vec.size(); i++)
+ {
+ r += vec._array[i]*vec._array[i];
+ }
+
+ return typename T::value_type(sqrt(r));
+ }
+
+ // return the squared norm
+ template< class T>
+ inline typename T::value_type square_norm(const T &vec)
+ {
+ typename T::value_type r = 0;
+
+ for (int i = 0; i < vec.size(); i++)
+ {
+ r += vec._array[i]*vec._array[i];
+ }
+
+ return r;
+ }
+
+ // return the normalized version of the vector
+ template< class T>
+ inline T normalize(const T &vec)
+ {
+ typename T::value_type sum(0);
+ T r;
+
+ for (int i = 0; i < vec.size(); i++)
+ {
+ sum += vec._array[i] * vec._array[i];
+ }
+
+ sum = typename T::value_type(sqrt(sum));
+
+ if (sum > 0)
+ for (int i = 0; i < vec.size(); i++)
+ {
+ r._array[i] = vec._array[i] / sum;
+ }
+
+ return r;
+ }
+
+ // In VC8 : min and max are already defined by a #define...
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
+ //componentwise min
+ template< class T>
+ inline T min(const T &lhs, const T &rhs)
+ {
+ T rt;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ rt._array[i] = std::min(lhs._array[i], rhs._array[i]);
+ }
+
+ return rt;
+ }
+
+ // componentwise max
+ template< class T>
+ inline T max(const T &lhs, const T &rhs)
+ {
+ T rt;
+
+ for (int i = 0; i < lhs.size(); i++)
+ {
+ rt._array[i] = std::max(lhs._array[i], rhs._array[i]);
+ }
+
+ return rt;
+ }
+
+
+};
+
+#endif
diff --git a/tests/projects/cuda_console/inc/nvrtc_helper.h b/tests/projects/cuda_console/inc/nvrtc_helper.h
new file mode 100644
index 000000000..14abc65f4
--- /dev/null
+++ b/tests/projects/cuda_console/inc/nvrtc_helper.h
@@ -0,0 +1,134 @@
+#if !defined(__NVRTC_HELPER__)
+
+#define __NVRTC_HELPER__ 1
+
+#include <cuda.h>
+#include <nvrtc.h>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <helper_cuda_drvapi.h>
+
+#define NVRTC_SAFE_CALL(Name, x) \
+ do { \
+ nvrtcResult result = x; \
+ if (result != NVRTC_SUCCESS) { \
+ std::cerr << "\nerror: " << Name << " failed with error " << \
+ nvrtcGetErrorString(result); \
+ exit(1); \
+ } \
+ } while(0)
+
+void compileFileToPTX(char *filename, int argc, char **argv,
+ char **ptxResult, size_t *ptxResultSize, int requiresCGheaders)
+{
+ std::ifstream inputFile(filename, std::ios::in | std::ios::binary |
+ std::ios::ate);
+
+ if (!inputFile.is_open())
+ {
+ std::cerr << "\nerror: unable to open " << filename << " for reading!\n";
+ exit(1);
+ }
+
+ std::streampos pos = inputFile.tellg();
+ size_t inputSize = (size_t)pos;
+ char * memBlock = new char [inputSize + 1];
+
+ inputFile.seekg (0, std::ios::beg);
+ inputFile.read (memBlock, inputSize);
+ inputFile.close();
+ memBlock[inputSize] = '\x0';
+
+ int numCompileOptions = 0;
+
+ char *compileParams[1];
+
+ if (requiresCGheaders)
+ {
+ std::string compileOptions;
+ char *HeaderNames = "cooperative_groups.h";
+
+ compileOptions = "--include-path=";
+
+ std::string path = sdkFindFilePath(HeaderNames, argv[0]);
+ if (!path.empty())
+ {
+ std::size_t found = path.find(HeaderNames);
+ path.erase(found);
+ }
+ else
+ {
+ printf("\nCooperativeGroups headers not found, please install it in %s sample directory..\n Exiting..\n", argv[0]);
+ }
+ compileOptions += path.c_str();
+ compileParams[0] = (char *) malloc(sizeof(char)* (compileOptions.length() + 1));
+ strcpy(compileParams[0], compileOptions.c_str());
+ numCompileOptions++;
+ }
+
+ // compile
+ nvrtcProgram prog;
+ NVRTC_SAFE_CALL("nvrtcCreateProgram", nvrtcCreateProgram(&prog, memBlock,
+ filename, 0, NULL, NULL));
+
+ nvrtcResult res = nvrtcCompileProgram(prog, numCompileOptions, compileParams);
+
+ // dump log
+ size_t logSize;
+ NVRTC_SAFE_CALL("nvrtcGetProgramLogSize", nvrtcGetProgramLogSize(prog, &logSize));
+ char *log = (char *) malloc(sizeof(char) * logSize + 1);
+ NVRTC_SAFE_CALL("nvrtcGetProgramLog", nvrtcGetProgramLog(prog, log));
+ log[logSize] = '\x0';
+
+
+ if (strlen(log) >= 2)
+ {
+ std::cerr << "\n compilation log ---\n";
+ std::cerr << log;
+ std::cerr << "\n end log ---\n";
+ }
+
+ free(log);
+
+ NVRTC_SAFE_CALL("nvrtcCompileProgram", res);
+ // fetch PTX
+ size_t ptxSize;
+ NVRTC_SAFE_CALL("nvrtcGetPTXSize", nvrtcGetPTXSize(prog, &ptxSize));
+ char *ptx = (char *) malloc(sizeof(char) * ptxSize);
+ NVRTC_SAFE_CALL("nvrtcGetPTX", nvrtcGetPTX(prog, ptx));
+ NVRTC_SAFE_CALL("nvrtcDestroyProgram", nvrtcDestroyProgram(&prog));
+ *ptxResult = ptx;
+ *ptxResultSize = ptxSize;
+
+ if (requiresCGheaders)
+ free(compileParams[0]);
+}
+
+CUmodule loadPTX(char *ptx, int argc, char **argv)
+{
+ CUmodule module;
+ CUcontext context;
+ int major = 0, minor = 0;
+ char deviceName[256];
+
+ // Picks the best CUDA device available
+ CUdevice cuDevice = findCudaDeviceDRV(argc, (const char **)argv);
+
+ // get compute capabilities and the devicename
+ checkCudaErrors(cuDeviceComputeCapability(&major, &minor, cuDevice));
+ checkCudaErrors(cuDeviceGetName(deviceName, 256, cuDevice));
+ printf("> GPU Device has SM %d.%d compute capability\n", major, minor);
+
+ checkCudaErrors(cuInit(0));
+ checkCudaErrors(cuDeviceGet(&cuDevice, 0));
+ checkCudaErrors(cuCtxCreate(&context, 0, cuDevice));
+
+ checkCudaErrors(cuModuleLoadDataEx(&module, ptx, 0, 0, 0));
+ free(ptx);
+
+ return module;
+}
+
+#endif
+
diff --git a/tests/projects/cuda_console/inc/param.h b/tests/projects/cuda_console/inc/param.h
new file mode 100644
index 000000000..22962c07e
--- /dev/null
+++ b/tests/projects/cuda_console/inc/param.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+/*
+ Simple parameter system
+*/
+
+#ifndef PARAM_H
+#define PARAM_H
+
+#include <string>
+#include <vector>
+#include <map>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+// base class for named parameter
+class ParamBase
+{
+ public:
+ ParamBase(const char *name) : m_name(name) { }
+ virtual ~ParamBase() { }
+
+ std::string &GetName()
+ {
+ return m_name;
+ }
+
+ virtual float GetFloatValue() = 0;
+ virtual int GetIntValue() = 0;
+ virtual std::string GetValueString() = 0;
+
+ virtual void Reset() = 0;
+ virtual void Increment() = 0;
+ virtual void Decrement() = 0;
+
+ virtual float GetPercentage() = 0;
+ virtual void SetPercentage(float p) = 0;
+
+ virtual void Write(std::ostream &stream) = 0;
+ virtual void Read(std::istream &stream) = 0;
+
+ virtual bool IsList() = 0;
+
+ protected:
+ std::string m_name;
+};
+
+// derived class for single-valued parameter
+template<class T> class Param : public ParamBase
+{
+ public:
+ Param(const char *name, T value = 0, T min = 0, T max = 10000, T step = 1, T *ptr = 0) :
+ ParamBase(name),
+ m_default(value),
+ m_min(min),
+ m_max(max),
+ m_step(step),
+ m_precision(3)
+ {
+ if (ptr)
+ {
+ m_ptr = ptr;
+ }
+ else
+ {
+ m_ptr = &m_value;
+ }
+
+ *m_ptr = value;
+ }
+ ~Param() { }
+
+ T GetValue() const
+ {
+ return *m_ptr;
+ }
+ T SetValue(const T value)
+ {
+ *m_ptr = value;
+ }
+
+ float GetFloatValue()
+ {
+ return (float) *m_ptr;
+ }
+ int GetIntValue()
+ {
+ return (int) *m_ptr;
+ }
+
+ std::string GetValueString()
+ {
+ std::ostringstream ost;
+ ost<<std::setprecision(m_precision)<<std::fixed;
+ ost<<*m_ptr;
+ return ost.str();
+ }
+
+ void SetPrecision(int x)
+ {
+ m_precision = x;
+ }
+
+ float GetPercentage()
+ {
+ return (*m_ptr - m_min) / (float)(m_max - m_min);
+ }
+
+ void SetPercentage(float p)
+ {
+ *m_ptr = (T)(m_min + p * (m_max - m_min));
+ }
+
+ void Reset()
+ {
+ *m_ptr = m_default;
+ }
+
+ void Increment()
+ {
+ *m_ptr += m_step;
+
+ if (*m_ptr > m_max)
+ {
+ *m_ptr = m_max;
+ }
+ }
+
+ void Decrement()
+ {
+ *m_ptr -= m_step;
+
+ if (*m_ptr < m_min)
+ {
+ *m_ptr = m_min;
+ }
+ }
+
+ void Write(std::ostream &stream)
+ {
+ stream << m_name << " " << *m_ptr << '\n';
+ }
+ void Read(std::istream &stream)
+ {
+ stream >> m_name >> *m_ptr;
+ }
+
+ bool IsList()
+ {
+ return false;
+ }
+
+ private:
+ T m_value;
+ T *m_ptr; // pointer to value declared elsewhere
+ T m_default, m_min, m_max, m_step;
+ int m_precision; // number of digits after decimal point in string output
+};
+
+const Param<int> dummy("error");
+
+// list of parameters
+class ParamList : public ParamBase
+{
+ public:
+ ParamList(const char *name = "") :
+ ParamBase(name)
+ {
+ active = true;
+ }
+ ~ParamList() { }
+
+ float GetFloatValue()
+ {
+ return 0.0f;
+ }
+ int GetIntValue()
+ {
+ return 0;
+ }
+
+ void AddParam(ParamBase *param)
+ {
+ m_params.push_back(param);
+ m_map[param->GetName()] = param;
+ m_current = m_params.begin();
+ }
+
+ // look-up parameter based on name
+ ParamBase *GetParam(char *name)
+ {
+ ParamBase *p = m_map[name];
+
+ if (p)
+ {
+ return p;
+ }
+ else
+ {
+ return (ParamBase *) &dummy;
+ }
+ }
+
+ ParamBase *GetParam(int i)
+ {
+ return m_params[i];
+ }
+
+ ParamBase *GetCurrent()
+ {
+ return *m_current;
+ }
+
+ int GetSize()
+ {
+ return (int)m_params.size();
+ }
+
+ std::string GetValueString()
+ {
+ return m_name;
+ }
+
+ // functions to traverse list
+ void Reset()
+ {
+ m_current = m_params.begin();
+ }
+
+ void Increment()
+ {
+ m_current++;
+
+ if (m_current == m_params.end())
+ {
+ m_current = m_params.begin();
+ }
+ }
+
+ void Decrement()
+ {
+ if (m_current == m_params.begin())
+ {
+ m_current = m_params.end()-1;
+ }
+ else
+ {
+ m_current--;
+ }
+
+ }
+
+ float GetPercentage()
+ {
+ return 0.0f;
+ }
+ void SetPercentage(float /*p*/) {}
+
+ void Write(std::ostream &stream)
+ {
+ stream << m_name << '\n';
+
+ for (std::vector<ParamBase *>::const_iterator p = m_params.begin(); p != m_params.end(); ++p)
+ {
+ (*p)->Write(stream);
+ }
+ }
+
+ void Read(std::istream &stream)
+ {
+ stream >> m_name;
+
+ for (std::vector<ParamBase *>::const_iterator p = m_params.begin(); p != m_params.end(); ++p)
+ {
+ (*p)->Read(stream);
+ }
+ }
+
+ bool IsList()
+ {
+ return true;
+ }
+
+ void ResetAll()
+ {
+ for (std::vector<ParamBase *>::const_iterator p = m_params.begin(); p != m_params.end(); ++p)
+ {
+ (*p)->Reset();
+ }
+ }
+
+ protected:
+ bool active;
+ std::vector<ParamBase *> m_params;
+ std::map<std::string, ParamBase *> m_map;
+ std::vector<ParamBase *>::const_iterator m_current;
+};
+
+#endif
diff --git a/tests/projects/cuda_console/inc/paramgl.h b/tests/projects/cuda_console/inc/paramgl.h
new file mode 100644
index 000000000..1c42b0b89
--- /dev/null
+++ b/tests/projects/cuda_console/inc/paramgl.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+/*
+ ParamListGL
+ - class derived from ParamList to do simple OpenGL rendering of a parameter list
+ sgg 8/2001
+*/
+
+#ifndef PARAMGL_H
+#define PARAMGL_H
+
+#if defined(__APPLE__) || defined(MACOSX)
+#include <GLUT/glut.h>
+#else
+#include <GL/freeglut.h>
+#endif
+
+#include <string.h>
+#include <param.h>
+
+inline void beginWinCoords(void)
+{
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glTranslatef(0.0, (GLfloat)(glutGet(GLUT_WINDOW_HEIGHT) - 1.0), 0.0);
+ glScalef(1.0, -1.0, 1.0);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT), -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+}
+
+inline void endWinCoords(void)
+{
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+}
+
+inline void glPrint(int x, int y, const char *s, void *font)
+{
+ glRasterPos2f((GLfloat)x, (GLfloat)y);
+ int len = (int) strlen(s);
+
+ for (int i = 0; i < len; i++)
+ {
+ glutBitmapCharacter(font, s[i]);
+ }
+}
+
+inline void glPrintShadowed(int x, int y, const char *s, void *font, float *color)
+{
+ glColor3f(0.0, 0.0, 0.0);
+ glPrint(x-1, y-1, s, font);
+
+ glColor3fv((GLfloat *) color);
+ glPrint(x, y, s, font);
+}
+
+class ParamListGL : public ParamList
+{
+ public:
+ ParamListGL(const char *name = "") :
+ ParamList(name),
+ m_active(true),
+ m_text_color_selected(1.0, 1.0, 1.0),
+ m_text_color_unselected(0.75, 0.75, 0.75),
+ m_text_color_shadow(0.0, 0.0, 0.0),
+ m_bar_color_outer(0.25, 0.25, 0.25),
+ m_bar_color_inner(1.0, 1.0, 1.0)
+ {
+ m_font = (void *) GLUT_BITMAP_9_BY_15; // GLUT_BITMAP_8_BY_13;
+ m_font_h = 15;
+ m_bar_x = 260;
+ m_bar_w = 250;
+ m_bar_h = 10;
+ m_bar_offset = 5;
+ m_text_x = 5;
+ m_separation = 15;
+ m_value_x = 200;
+ m_start_x = 0;
+ m_start_y = 0;
+ }
+
+ void Render(int x, int y, bool shadow = false)
+ {
+ beginWinCoords();
+
+ m_start_x = x;
+ m_start_y = y;
+
+ for (std::vector<ParamBase *>::const_iterator p = m_params.begin(); p != m_params.end(); ++p)
+ {
+ if ((*p)->IsList())
+ {
+ ParamListGL *list = (ParamListGL *)(*p);
+ list->Render(x+10, y);
+ y += m_separation*list->GetSize();
+ }
+ else
+ {
+ if (p == m_current)
+ {
+ glColor3fv(&m_text_color_selected.r);
+ }
+ else
+ {
+ glColor3fv(&m_text_color_unselected.r);
+ }
+
+ if (shadow)
+ {
+ glPrintShadowed(x + m_text_x, y + m_font_h, (*p)->GetName().c_str(), m_font, (p == m_current) ? &m_text_color_selected.r : &m_text_color_unselected.r);
+ glPrintShadowed(x + m_value_x, y + m_font_h, (*p)->GetValueString().c_str(), m_font, (p == m_current) ? &m_text_color_selected.r : &m_text_color_unselected.r);
+ }
+ else
+ {
+ glPrint(x + m_text_x, y + m_font_h, (*p)->GetName().c_str(), m_font);
+ glPrint(x + m_value_x, y + m_font_h, (*p)->GetValueString().c_str(), m_font);
+ }
+
+ glColor3fv((GLfloat *) &m_bar_color_outer.r);
+ glBegin(GL_LINE_LOOP);
+ glVertex2f((GLfloat)(x + m_bar_x) , (GLfloat)(y + m_bar_offset));
+ glVertex2f((GLfloat)(x + m_bar_x + m_bar_w), (GLfloat)(y + m_bar_offset));
+ glVertex2f((GLfloat)(x + m_bar_x + m_bar_w), (GLfloat)(y + m_bar_offset + m_bar_h));
+ glVertex2f((GLfloat)(x + m_bar_x) , (GLfloat)(y + m_bar_offset + m_bar_h));
+ glEnd();
+
+ glColor3fv((GLfloat *) &m_bar_color_inner.r);
+ glRectf((GLfloat)(x + m_bar_x), (GLfloat)(y + m_bar_offset + m_bar_h), (GLfloat)(x + m_bar_x + ((m_bar_w-1)*(*p)->GetPercentage())), (GLfloat)(y + m_bar_offset + 1));
+
+ y += m_separation;
+ }
+ }
+
+ endWinCoords();
+ }
+
+ bool Mouse(int x, int y, int button=GLUT_LEFT_BUTTON, int state=GLUT_DOWN)
+ {
+ if ((y < m_start_y) || (y > (int)(m_start_y + (m_separation * m_params.size()) - 1)))
+ {
+ m_active = false;
+ return false;
+ }
+
+ m_active = true;
+
+ int i = (y - m_start_y) / m_separation;
+
+ if ((button==GLUT_LEFT_BUTTON) && (state==GLUT_DOWN))
+ {
+#if defined(__GNUC__) && (__GNUC__ < 3)
+ m_current = &m_params[i];
+#else
+
+ // MJH: workaround since the version of vector::at used here is non-standard
+ for (m_current = m_params.begin(); m_current != m_params.end() && i > 0; m_current++, i--) ;
+
+ //m_current = (std::vector<ParamBase *>::const_iterator)&m_params.at(i);
+#endif
+
+ if ((x > m_bar_x) && (x < m_bar_x + m_bar_w))
+ {
+ Motion(x, y);
+ }
+ }
+
+ return true;
+ }
+
+ bool Motion(int x, int y)
+ {
+ if ((y < m_start_y) || (y > m_start_y + (m_separation * (int)m_params.size()) - 1))
+ {
+ return false;
+ }
+
+ if (x < m_bar_x)
+ {
+ (*m_current)->SetPercentage(0.0);
+ return true;
+ }
+
+ if (x > m_bar_x + m_bar_w)
+ {
+ (*m_current)->SetPercentage(1.0);
+ return true;
+ }
+
+ (*m_current)->SetPercentage((x-m_bar_x) / (float) m_bar_w);
+ return true;
+ }
+
+ void Special(int key, int x, int y)
+ {
+ if (!m_active)
+ return;
+
+ switch (key)
+ {
+ case GLUT_KEY_DOWN:
+ Increment();
+ break;
+
+ case GLUT_KEY_UP:
+ Decrement();
+ break;
+
+ case GLUT_KEY_RIGHT:
+ GetCurrent()->Increment();
+ break;
+
+ case GLUT_KEY_LEFT:
+ GetCurrent()->Decrement();
+ break;
+
+ case GLUT_KEY_HOME:
+ GetCurrent()->Reset();
+ break;
+
+ case GLUT_KEY_END:
+ GetCurrent()->SetPercentage(1.0);
+ break;
+ }
+
+ glutPostRedisplay();
+ }
+
+ void SetFont(void *font, int height)
+ {
+ m_font = font;
+ m_font_h = height;
+ }
+
+ void SetSelectedColor(float r, float g, float b)
+ {
+ m_text_color_selected = Color(r, g, b);
+ }
+ void SetUnSelectedColor(float r, float g, float b)
+ {
+ m_text_color_unselected = Color(r, g, b);
+ }
+ void SetBarColorInner(float r, float g, float b)
+ {
+ m_bar_color_inner = Color(r, g, b);
+ }
+ void SetBarColorOuter(float r, float g, float b)
+ {
+ m_bar_color_outer = Color(r, g, b);
+ }
+
+ void SetActive(bool b)
+ {
+ m_active = b;
+ }
+
+ private:
+ void *m_font;
+ int m_font_h; // font height
+
+ int m_bar_x; // bar start x position
+ int m_bar_w; // bar width
+ int m_bar_h; // bar height
+ int m_text_x; // text start x position
+ int m_separation; // bar separation in y
+ int m_value_x; // value text x position
+ int m_bar_offset; // bar offset in y
+
+ int m_start_x, m_start_y;
+
+ bool m_active;
+
+ struct Color
+ {
+ Color(float _r, float _g, float _b)
+ {
+ r = _r;
+ g = _g;
+ b = _b;
+ }
+ float r, g, b;
+ };
+
+ Color m_text_color_selected;
+ Color m_text_color_unselected;
+ Color m_text_color_shadow;
+ Color m_bar_color_outer;
+ Color m_bar_color_inner;
+};
+
+#endif
diff --git a/tests/projects/cuda_console/inc/rendercheck_d3d10.h b/tests/projects/cuda_console/inc/rendercheck_d3d10.h
new file mode 100644
index 000000000..594429c7f
--- /dev/null
+++ b/tests/projects/cuda_console/inc/rendercheck_d3d10.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#pragma once
+
+#ifndef _RENDERCHECK_D3D10_H_
+#define _RENDERCHECK_D3D10_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <d3d10.h>
+#include <d3dx10.h>
+
+class CheckRenderD3D10
+{
+ public:
+
+ CheckRenderD3D10() {}
+
+ static HRESULT ActiveRenderTargetToPPM(ID3D10Device *pDevice, const char *zFileName);
+ static HRESULT ResourceToPPM(ID3D10Device *pDevice, ID3D10Resource *pResource, const char *zFileName);
+
+ static bool PPMvsPPM(const char *src_file, const char *ref_file, const char *exec_path,
+ const float epsilon, const float threshold = 0.0f);
+};
+
+#endif \ No newline at end of file
diff --git a/tests/projects/cuda_console/inc/rendercheck_d3d11.h b/tests/projects/cuda_console/inc/rendercheck_d3d11.h
new file mode 100644
index 000000000..c2f21f0a6
--- /dev/null
+++ b/tests/projects/cuda_console/inc/rendercheck_d3d11.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#pragma once
+
+#ifndef _RENDERCHECK_D3D11_H_
+#define _RENDERCHECK_D3D11_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <d3d11.h>
+#include <d3dx11.h>
+
+class CheckRenderD3D11
+{
+ public:
+
+ CheckRenderD3D11() {}
+
+ static HRESULT ActiveRenderTargetToPPM(ID3D11Device *pDevice, const char *zFileName);
+ static HRESULT ResourceToPPM(ID3D11Device *pDevice, ID3D11Resource *pResource, const char *zFileName);
+
+ static bool PPMvsPPM(const char *src_file, const char *ref_file, const char *exec_path,
+ const float epsilon, const float threshold = 0.0f);
+};
+
+#endif \ No newline at end of file
diff --git a/tests/projects/cuda_console/inc/rendercheck_d3d9.h b/tests/projects/cuda_console/inc/rendercheck_d3d9.h
new file mode 100644
index 000000000..c577abcde
--- /dev/null
+++ b/tests/projects/cuda_console/inc/rendercheck_d3d9.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#pragma once
+
+#ifndef _RENDERCHECK_D3D9_H_
+#define _RENDERCHECK_D3D9_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <d3d9.h>
+
+class CheckRenderD3D9
+{
+ public:
+
+ CheckRenderD3D9() {}
+
+ static HRESULT BackbufferToPPM(IDirect3DDevice9 *pDevice, const char *zFileName);
+ static HRESULT SurfaceToPPM(IDirect3DDevice9 *pDevice, IDirect3DSurface9 *pSurface, const char *zFileName);
+
+ static bool PPMvsPPM(const char *src_file, const char *ref_file, const char *exec_path,
+ const float epsilon, const float threshold = 0.0f);
+};
+
+#endif \ No newline at end of file
diff --git a/tests/projects/cuda_console/inc/rendercheck_gl.h b/tests/projects/cuda_console/inc/rendercheck_gl.h
new file mode 100644
index 000000000..3c5c036a9
--- /dev/null
+++ b/tests/projects/cuda_console/inc/rendercheck_gl.h
@@ -0,0 +1,1473 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+
+#ifndef _RENDERCHECK_GL_H_
+#define _RENDERCHECK_GL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <vector>
+#include <map>
+#include <string>
+
+#if defined(__APPLE__) || defined(MACOSX)
+#include <GLUT/glut.h>
+#else
+#include <GL/freeglut.h>
+#endif
+
+#include <nvShaderUtils.h>
+
+#include <helper_image.h>
+
+
+using std::vector;
+using std::map;
+using std::string;
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#if _DEBUG
+#define CHECK_FBO checkStatus(__FILE__, __LINE__, true)
+#else
+#define CHECK_FBO true
+#endif
+
+
+
+class CheckRender
+{
+ public:
+ CheckRender(unsigned int width, unsigned int height, unsigned int Bpp,
+ bool bQAReadback, bool bUseFBO, bool bUsePBO) :
+ m_Width(width), m_Height(height), m_Bpp(Bpp), m_bQAReadback(bQAReadback),
+ m_bUseFBO(bUseFBO), m_bUsePBO(bUsePBO), m_PixelFormat(GL_BGRA), m_fThresholdCompare(0.0f)
+ {
+ allocateMemory(width, height, Bpp, bUseFBO, bUsePBO);
+ }
+
+ virtual ~CheckRender()
+ {
+ // Release PBO resources
+ if (m_bUsePBO)
+ {
+ glDeleteBuffers(1, &m_pboReadback);
+ m_pboReadback = 0;
+ }
+
+ free(m_pImageData);
+ }
+
+ virtual void allocateMemory(unsigned int width, unsigned int height, unsigned int Bpp,
+ bool bUseFBO, bool bUsePBO)
+ {
+ // Create the PBO for readbacks
+ if (bUsePBO)
+ {
+ glGenBuffers(1, &m_pboReadback);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, m_pboReadback);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB, width*height*Bpp, NULL, GL_STREAM_READ);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
+ }
+
+ m_pImageData = (unsigned char *)malloc(width*height*Bpp); // This is the image data stored in system memory
+ }
+
+
+ virtual void setExecPath(char *path)
+ {
+ m_ExecPath = path;
+ }
+ virtual void EnableQAReadback(bool bStatus)
+ {
+ m_bQAReadback = bStatus;
+ }
+ virtual bool IsQAReadback()
+ {
+ return m_bQAReadback;
+ }
+ virtual bool IsFBO()
+ {
+ return m_bUseFBO;
+ }
+ virtual bool IsPBO()
+ {
+ return m_bUsePBO;
+ }
+ virtual void *imageData()
+ {
+ return m_pImageData;
+ }
+
+ // Interface to this class functions
+ virtual void setPixelFormat(GLenum format)
+ {
+ m_PixelFormat = format;
+ }
+ virtual int getPixelFormat()
+ {
+ return m_PixelFormat;
+ }
+ virtual bool checkStatus(const char *zfile, int line, bool silent) = 0;
+ virtual bool readback(GLuint width, GLuint height) = 0;
+ virtual bool readback(GLuint width, GLuint height, GLuint bufObject) = 0;
+ virtual bool readback(GLuint width, GLuint height, unsigned char *membuf) = 0;
+
+ virtual void bindReadback()
+ {
+ if (!m_bQAReadback)
+ {
+ printf("CheckRender::bindReadback() uninitialized!\n");
+ return;
+ }
+
+ if (m_bUsePBO)
+ {
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, m_pboReadback); // Bind the PBO
+ }
+ }
+
+ virtual void unbindReadback()
+ {
+ if (!m_bQAReadback)
+ {
+ printf("CheckRender::unbindReadback() uninitialized!\n");
+ return;
+ }
+
+ if (m_bUsePBO)
+ {
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); // Release the bind on the PBO
+ }
+ }
+
+ virtual void savePGM(const char *zfilename, bool bInvert, void **ppReadBuf)
+ {
+ if (zfilename != NULL)
+ {
+ if (bInvert)
+ {
+ unsigned char *readBuf;
+ unsigned char *writeBuf= (unsigned char *)malloc(m_Width * m_Height);
+
+ for (unsigned int y=0; y < m_Height; y++)
+ {
+ if (ppReadBuf)
+ {
+ readBuf = *(unsigned char **)ppReadBuf;
+ }
+ else
+ {
+ readBuf = (unsigned char *)m_pImageData;
+ }
+
+ memcpy(&writeBuf[m_Width*m_Bpp*y], (readBuf+ m_Width*(m_Height-1-y)), m_Width);
+ }
+
+ // we copy the results back to original system buffer
+ if (ppReadBuf)
+ {
+ memcpy(*ppReadBuf, writeBuf, m_Width*m_Height);
+ }
+ else
+ {
+ memcpy(m_pImageData, writeBuf, m_Width*m_Height);
+ }
+
+ free(writeBuf);
+ }
+
+ printf("> Saving PGM: <%s>\n", zfilename);
+
+ if (ppReadBuf)
+ {
+ sdkSavePGM<unsigned char>(zfilename, *(unsigned char **)ppReadBuf, m_Width, m_Height);
+ }
+ else
+ {
+ sdkSavePGM<unsigned char>(zfilename, (unsigned char *)m_pImageData, m_Width, m_Height);
+ }
+ }
+ }
+
+ virtual void savePPM(const char *zfilename, bool bInvert, void **ppReadBuf)
+ {
+ if (zfilename != NULL)
+ {
+ if (bInvert)
+ {
+ unsigned char *readBuf;
+ unsigned char *writeBuf= (unsigned char *)malloc(m_Width * m_Height * m_Bpp);
+
+ for (unsigned int y=0; y < m_Height; y++)
+ {
+ if (ppReadBuf)
+ {
+ readBuf = *(unsigned char **)ppReadBuf;
+ }
+ else
+ {
+ readBuf = (unsigned char *)m_pImageData;
+ }
+
+ memcpy(&writeBuf[m_Width*m_Bpp*y], (readBuf+ m_Width*m_Bpp*(m_Height-1-y)), m_Width*m_Bpp);
+ }
+
+ // we copy the results back to original system buffer
+ if (ppReadBuf)
+ {
+ memcpy(*ppReadBuf, writeBuf, m_Width*m_Height*m_Bpp);
+ }
+ else
+ {
+ memcpy(m_pImageData, writeBuf, m_Width*m_Height*m_Bpp);
+ }
+
+ free(writeBuf);
+ }
+
+ printf("> Saving PPM: <%s>\n", zfilename);
+
+ if (ppReadBuf)
+ {
+ sdkSavePPM4ub(zfilename, *(unsigned char **)ppReadBuf, m_Width, m_Height);
+ }
+ else
+ {
+ sdkSavePPM4ub(zfilename, (unsigned char *)m_pImageData, m_Width, m_Height);
+ }
+ }
+ }
+
+ virtual bool PGMvsPGM(const char *src_file, const char *ref_file, const float epsilon, const float threshold = 0.0f)
+ {
+ unsigned char *src_data = NULL, *ref_data = NULL;
+ unsigned long error_count = 0;
+ unsigned int width, height;
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("CheckRender::PGMvsPGM unable to find <%s> in <%s> Aborting comparison!\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+ }
+ else
+ {
+
+ if (src_file == NULL || ref_file_path == NULL)
+ {
+ printf("PGMvsPGM: Aborting comparison\n");
+ return false;
+ }
+
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+
+ if (sdkLoadPPMub(ref_file_path, &ref_data, &width, &height) != true)
+ {
+ printf("PGMvsPGM: unable to load ref image file: %s\n", ref_file_path);
+ return false;
+ }
+
+ if (sdkLoadPPMub(src_file, &src_data, &width, &height) != true)
+ {
+ printf("PGMvsPGM: unable to load src image file: %s\n", src_file);
+ return false;
+ }
+
+ printf("PGMvsPGM: comparing images size (%d,%d) epsilon(%2.4f), threshold(%4.2f%%)\n", m_Height, m_Width, epsilon, threshold*100);
+
+ if (compareDataAsFloatThreshold<unsigned char, float>(ref_data, src_data, m_Height*m_Width, epsilon, threshold) == false)
+ {
+ error_count = 1;
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+ }
+
+ virtual bool PPMvsPPM(const char *src_file, const char *ref_file, const float epsilon, const float threshold = 0.0f)
+ {
+ unsigned long error_count = 0;
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("CheckRender::PPMvsPPM unable to find <%s> in <%s> Aborting comparison!\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+ }
+
+ if (src_file == NULL || ref_file_path == NULL)
+ {
+ printf("PPMvsPPM: Aborting comparison\n");
+ return false;
+ }
+
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+ return (sdkComparePPM(src_file, ref_file_path, epsilon, threshold, true) == true ? true : false);
+ }
+
+
+ void setThresholdCompare(float value)
+ {
+ m_fThresholdCompare = value;
+ }
+
+ virtual void dumpBin(void *data, unsigned int bytes, const char *filename)
+ {
+ FILE *fp;
+ printf("CheckRender::dumpBin: <%s>\n", filename);
+ FOPEN(fp, filename, "wb");
+ fwrite(data, bytes, 1, fp);
+ fflush(fp);
+ fclose(fp);
+ }
+
+ virtual bool compareBin2BinUint(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold)
+ {
+ unsigned int *src_buffer, *ref_buffer;
+ FILE *src_fp = NULL, *ref_fp = NULL;
+
+ unsigned long error_count = 0;
+ size_t fsize = 0;
+
+ FOPEN(src_fp, src_file, "rb");
+
+ if (src_fp == NULL)
+ {
+ printf("compareBin2Bin <unsigned int> unable to open src_file: %s\n", src_file);
+ error_count++;
+ }
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("compareBin2Bin <unsigned int> unable to find <%s> in <%s>\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ else
+ {
+ FOPEN(ref_fp, ref_file_path, "rb");
+
+ if (ref_fp == NULL)
+ {
+ printf("compareBin2Bin <unsigned int> unable to open ref_file: %s\n", ref_file_path);
+ error_count++;
+ }
+
+ if (src_fp && ref_fp)
+ {
+ src_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int));
+ ref_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int));
+
+ fsize = fread(src_buffer, sizeof(unsigned int), nelements, src_fp);
+
+ if (fsize != nelements)
+ {
+ printf("compareBin2Bin <unsigned int> failed to read %u elements from %s\n", nelements, src_file);
+ error_count++;
+ }
+
+ fsize = fread(ref_buffer, sizeof(unsigned int), nelements, ref_fp);
+
+ if (fsize == 0)
+ {
+ printf("compareBin2Bin <unsigned int> failed to read %u elements from %s\n", nelements, ref_file_path);
+ error_count++;
+ }
+
+
+ printf("> compareBin2Bin <unsigned int> nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold);
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+
+ if (!compareData<unsigned int, float>(ref_buffer, src_buffer, nelements, epsilon, threshold))
+ {
+ error_count++;
+ }
+
+ fclose(src_fp);
+ fclose(ref_fp);
+
+ free(src_buffer);
+ free(ref_buffer);
+ }
+ else
+ {
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+ }
+
+ virtual bool compareBin2BinFloat(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold)
+ {
+ float *src_buffer, *ref_buffer;
+ FILE *src_fp = NULL, *ref_fp = NULL;
+ size_t fsize = 0;
+
+ unsigned long error_count = 0;
+
+ FOPEN(src_fp, src_file, "rb");
+
+ if (src_fp == NULL)
+ {
+ printf("compareBin2Bin <float> unable to open src_file: %s\n", src_file);
+ error_count = 1;
+ }
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("compareBin2Bin <float> unable to find <%s> in <%s>\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", m_ExecPath.c_str());
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ else
+ {
+ FOPEN(ref_fp, ref_file_path, "rb");
+
+ if (ref_fp == NULL)
+ {
+ printf("compareBin2Bin <float> unable to open ref_file: %s\n", ref_file_path);
+ error_count = 1;
+ }
+
+ if (src_fp && ref_fp)
+ {
+ src_buffer = (float *)malloc(nelements*sizeof(float));
+ ref_buffer = (float *)malloc(nelements*sizeof(float));
+
+ fsize = fread(src_buffer, sizeof(float), nelements, src_fp);
+
+ if (fsize != nelements)
+ {
+ printf("compareBin2Bin <float> failed to read %u elements from %s\n", nelements, src_file);
+ error_count++;
+ }
+
+ fsize = fread(ref_buffer, sizeof(float), nelements, ref_fp);
+
+ if (fsize == 0)
+ {
+ printf("compareBin2Bin <float> failed to read %u elements from %s\n", nelements, ref_file_path);
+ error_count++;
+ }
+
+ printf("> compareBin2Bin <float> nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold);
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+
+ if (!compareDataAsFloatThreshold<float, float>(ref_buffer, src_buffer, nelements, epsilon, threshold))
+ {
+ error_count++;
+ }
+
+ fclose(src_fp);
+ fclose(ref_fp);
+
+ free(src_buffer);
+ free(ref_buffer);
+ }
+ else
+ {
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+ }
+
+
+ protected:
+ unsigned int m_Width, m_Height, m_Bpp;
+ unsigned char *m_pImageData; // This is the image data stored in system memory
+ bool m_bQAReadback, m_bUseFBO, m_bUsePBO;
+ GLuint m_pboReadback;
+ GLenum m_PixelFormat;
+ float m_fThresholdCompare;
+ string m_ExecPath;
+};
+
+
+class CheckBackBuffer : public CheckRender
+{
+ public:
+ CheckBackBuffer(unsigned int width, unsigned int height, unsigned int Bpp, bool bUseOpenGL = true) :
+ CheckRender(width, height, Bpp, false, false, bUseOpenGL)
+ {
+ }
+
+ virtual ~CheckBackBuffer()
+ {
+ }
+
+ virtual bool checkStatus(const char *zfile, int line, bool silent)
+ {
+ GLenum nErrorCode = glGetError();
+
+ if (nErrorCode != GL_NO_ERROR)
+ {
+ if (!silent)
+ {
+ printf("Assertion failed(%s,%d): %s\n", zfile, line, gluErrorString(nErrorCode));
+ }
+ }
+
+ return true;
+ }
+
+ virtual bool readback(GLuint width, GLuint height)
+ {
+ bool ret = false;
+
+ if (m_bUsePBO)
+ {
+ // binds the PBO for readback
+ bindReadback();
+
+ // Initiate the readback BLT from BackBuffer->PBO->membuf
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::glReadPixels() checkStatus = %d\n", ret);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ // reading direct from the backbuffer
+ glReadBuffer(GL_FRONT);
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+ }
+
+ return ret;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, GLuint bufObject)
+ {
+ bool ret = false;
+
+ if (m_bUseFBO)
+ {
+ if (m_bUsePBO)
+ {
+ printf("CheckBackBuffer::readback() FBO->PBO->m_pImageData\n");
+ // binds the PBO for readback
+ bindReadback();
+
+ // bind FBO buffer (we want to transfer FBO -> PBO)
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufObject);
+
+ // Now initiate the readback to PBO
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::readback() FBO->PBO checkStatus = %d\n", ret);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+
+ // release the FBO
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ printf("CheckBackBuffer::readback() FBO->m_pImageData\n");
+ // Reading direct to FBO using glReadPixels
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufObject);
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::readback::glBindFramebufferEXT() fbo=%d checkStatus = %d\n", bufObject, ret);
+ }
+
+ glReadBuffer(static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT));
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::readback::glReadBuffer() fbo=%d checkStatus = %d\n", bufObject, ret);
+ }
+
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+ }
+ else
+ {
+
+ printf("CheckBackBuffer::readback() PBO->m_pImageData\n");
+ // read from bufObject (PBO) to system memorys image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, bufObject); // Bind the PBO
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+
+ // allocate a buffer so we can flip the image
+ unsigned char *temp_buf = (unsigned char *)malloc(width*height*m_Bpp);
+ memcpy(temp_buf, ioMem, width*height*m_Bpp);
+
+ // let's flip the image as we copy
+ for (unsigned int y = 0; y < height; y++)
+ {
+ memcpy((void *)&(m_pImageData[(height-y)*width*m_Bpp]), (void *)&(temp_buf[y*width*m_Bpp]), width*m_Bpp);
+ }
+
+ free(temp_buf);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+
+ // read from bufObject (PBO) to system memory image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); // unBind the PBO
+ }
+
+ return CHECK_FBO;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, unsigned char *memBuf)
+ {
+ // let's flip the image as we copy
+ for (unsigned int y = 0; y < height; y++)
+ {
+ memcpy((void *)&(m_pImageData[(height-y)*width*m_Bpp]), (void *)&(memBuf[y*width*m_Bpp]), width*m_Bpp);
+ }
+
+ return true;
+ }
+
+ private:
+ virtual void bindFragmentProgram() {};
+ virtual void bindRenderPath() {};
+ virtual void unbindRenderPath() {};
+
+ // bind to the BackBuffer to Texture
+ virtual void bindTexture() {};
+
+ // release this bind
+ virtual void unbindTexture() {};
+};
+
+
+// structure defining the properties of a single buffer
+struct bufferConfig
+{
+ string name;
+ GLenum format;
+ int bits;
+};
+
+// structures defining properties of an FBO
+struct fboConfig
+{
+ string name;
+ GLenum colorFormat;
+ GLenum depthFormat;
+ int redbits;
+ int depthBits;
+ int depthSamples;
+ int coverageSamples;
+};
+
+struct fboData
+{
+ GLuint colorTex; //color texture
+ GLuint depthTex; //depth texture
+ GLuint fb; // render framebuffer
+ GLuint resolveFB; //multisample resolve target
+ GLuint colorRB; //color render buffer
+ GLuint depthRB; // depth render buffer
+};
+
+
+class CFrameBufferObject
+{
+ public:
+ CFrameBufferObject(unsigned int width, unsigned int height, unsigned int Bpp, bool bUseFloat, GLenum eTarget) :
+ m_Width(width),
+ m_Height(height),
+ m_bUseFloat(bUseFloat),
+ m_eGLTarget(eTarget)
+ {
+ glGenFramebuffersEXT(1, &m_fboData.fb);
+
+ m_fboData.colorTex = createTexture(m_eGLTarget, width, height,
+ (bUseFloat ? GL_RGBA32F_ARB : GL_RGBA8), GL_RGBA);
+
+ m_fboData.depthTex = createTexture(m_eGLTarget, width, height,
+ GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT);
+
+ attachTexture(m_eGLTarget, m_fboData.colorTex, GL_COLOR_ATTACHMENT0_EXT);
+ attachTexture(m_eGLTarget, m_fboData.depthTex, GL_DEPTH_ATTACHMENT_EXT);
+
+ // bool ret = checkStatus(__FILE__, __LINE__, true);
+ }
+
+ virtual ~CFrameBufferObject()
+ {
+ // freeResources();
+ }
+
+ GLuint createTexture(GLenum target, int w, int h, GLint internalformat, GLenum format)
+ {
+ GLuint texid;
+ glGenTextures(1, &texid);
+ glBindTexture(target, texid);
+
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(target, 0, internalformat, w, h, 0, format, GL_FLOAT, 0);
+ return texid;
+ }
+
+ void attachTexture(GLenum texTarget,
+ GLuint texId,
+ GLenum attachment = GL_COLOR_ATTACHMENT0_EXT,
+ int mipLevel = 0,
+ int zSlice = 0)
+ {
+ bindRenderPath();
+
+ switch (texTarget)
+ {
+ case GL_TEXTURE_1D:
+ glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, attachment,
+ GL_TEXTURE_1D, texId, mipLevel);
+ break;
+
+ case GL_TEXTURE_3D:
+ glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, attachment,
+ GL_TEXTURE_3D, texId, mipLevel, zSlice);
+ break;
+
+ default:
+ // Default is GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, or cube faces
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment,
+ texTarget, texId, mipLevel);
+ break;
+ }
+
+ unbindRenderPath();
+ }
+
+ bool initialize(unsigned width, unsigned height, fboConfig &rConfigFBO, fboData &rActiveFBO)
+ {
+ //Framebuffer config options
+ vector<bufferConfig> colorConfigs;
+ vector<bufferConfig> depthConfigs;
+ bufferConfig temp;
+
+ //add default color configs
+ temp.name = (m_bUseFloat ? "RGBA32F" : "RGBA8");
+ temp.bits = (m_bUseFloat ? 32 : 8);
+ temp.format = (m_bUseFloat ? GL_RGBA32F_ARB : GL_RGBA8);
+ colorConfigs.push_back(temp);
+
+ //add default depth configs
+ temp.name = "D24";
+ temp.bits = 24;
+ temp.format = GL_DEPTH_COMPONENT24;
+ depthConfigs.push_back(temp);
+
+ // If the FBO can be created, add it to the list of available configs, and make a menu entry
+ string root = colorConfigs[0].name + " " + depthConfigs[0].name;
+
+ rConfigFBO.colorFormat = colorConfigs[0].format;
+ rConfigFBO.depthFormat = depthConfigs[0].format;
+ rConfigFBO.redbits = colorConfigs[0].bits;
+ rConfigFBO.depthBits = depthConfigs[0].bits;
+
+ //single sample
+ rConfigFBO.name = root;
+ rConfigFBO.coverageSamples = 0;
+ rConfigFBO.depthSamples = 0;
+
+ create(width, height, rConfigFBO, rActiveFBO);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ if (m_bUseFloat)
+ {
+ // load fragment programs
+ const char *strTextureProgram2D =
+ "!!ARBfp1.0\n"
+ "TEX result.color, fragment.texcoord[0], texture[0], 2D;\n"
+ "END\n";
+
+ m_textureProgram = nv::CompileASMShader(GL_FRAGMENT_PROGRAM_ARB, strTextureProgram2D);
+
+ const char *strOverlayProgram =
+ "!!ARBfp1.0\n"
+ "TEMP t;\n"
+ "TEX t, fragment.texcoord[0], texture[0], 2D;\n"
+ "MOV result.color, t;\n"
+ "END\n";
+
+ m_overlayProgram = nv::CompileASMShader(GL_FRAGMENT_PROGRAM_ARB, strOverlayProgram);
+ }
+
+ return CHECK_FBO;
+ }
+
+ bool create(GLuint width, GLuint height, fboConfig &config, fboData &data)
+ {
+ bool multisample = config.depthSamples > 0;
+ bool ret = true;
+ GLint query;
+
+ printf("\nCreating FBO <%s> (%dx%d) Float:%s\n", config.name.c_str(), (int)width, (int)height, (m_bUseFloat ? "Y":"N"));
+
+ glGenFramebuffersEXT(1, &data.fb);
+ glGenTextures(1, &data.colorTex);
+
+ // init texture
+ glBindTexture(m_eGLTarget, data.colorTex);
+ glTexImage2D(m_eGLTarget, 0, config.colorFormat,
+ width, height, 0, GL_RGBA,
+ (m_bUseFloat ? GL_FLOAT : GL_UNSIGNED_BYTE),
+ NULL);
+
+ glGenerateMipmapEXT(m_eGLTarget);
+
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR);
+
+ {
+ glGenTextures(1, &data.depthTex);
+ data.depthRB = 0;
+ data.colorRB = 0;
+ data.resolveFB = 0;
+
+ //non-multisample, so bind things directly to the FBO
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, data.fb);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_eGLTarget, data.colorTex, 0);
+
+ glBindTexture(m_eGLTarget, data.depthTex);
+ glTexImage2D(m_eGLTarget, 0, config.depthFormat,
+ width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
+
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterf(m_eGLTarget, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
+
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, m_eGLTarget, data.depthTex, 0);
+
+ ret &= checkStatus(__FILE__, __LINE__, true);
+ }
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, data.fb);
+ glGetIntegerv(GL_RED_BITS, &query);
+
+ if (query != config.redbits)
+ {
+ ret = false;
+ }
+
+ glGetIntegerv(GL_DEPTH_BITS, &query);
+
+ if (query != config.depthBits)
+ {
+ ret = false;
+ }
+
+ if (multisample)
+ {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, data.resolveFB);
+ glGetIntegerv(GL_RED_BITS, &query);
+
+ if (query != config.redbits)
+ {
+ ret = false;
+ }
+ }
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ return ret;
+ }
+
+ virtual void freeResources()
+ {
+ if (m_fboData.fb)
+ {
+ glDeleteFramebuffersEXT(1, &m_fboData.fb);
+ }
+
+ if (m_fboData.resolveFB)
+ {
+ glDeleteFramebuffersEXT(1, &m_fboData.resolveFB);
+ }
+
+ if (m_fboData.colorRB)
+ {
+ glDeleteRenderbuffersEXT(1, &m_fboData.colorRB);
+ }
+
+ if (m_fboData.depthRB)
+ {
+ glDeleteRenderbuffersEXT(1, &m_fboData.depthRB);
+ }
+
+ if (m_fboData.colorTex)
+ {
+ glDeleteTextures(1, &m_fboData.colorTex);
+ }
+
+ if (m_fboData.depthTex)
+ {
+ glDeleteTextures(1, &m_fboData.depthTex);
+ }
+
+ glDeleteProgramsARB(1, &m_textureProgram);
+ glDeleteProgramsARB(1, &m_overlayProgram);
+ }
+
+ virtual bool checkStatus(const char *zfile, int line, bool silent)
+ {
+ GLenum status;
+ status = (GLenum) glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+ {
+ printf("<%s : %d> - ", zfile, line);
+ }
+
+ switch (status)
+ {
+ case GL_FRAMEBUFFER_COMPLETE_EXT:
+ break;
+
+ case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ if (!silent)
+ {
+ printf("Unsupported framebuffer format\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing attachment\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, duplicate attachment\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, attached images must have same dimensions\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, attached images must have same format\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing draw buffer\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing read buffer\n");
+ }
+
+ return false;
+
+ default:
+ assert(0);
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual void renderQuad(int width, int height, GLenum eTarget)
+ {
+ float width_norm = (float)width/(float)m_Width,
+ height_norm = (float)height/(float)m_Height;
+
+ // Bind the FBO texture for the display path
+ glBindTexture(eTarget, m_fboData.colorTex);
+
+ glGenerateMipmapEXT(GL_TEXTURE_2D);
+ glBindTexture(eTarget, 0);
+
+ // now render to the full screen using this texture
+ glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_textureProgram);
+ glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ glDisable(GL_DEPTH_TEST);
+
+ glBegin(GL_QUADS);
+ {
+ glVertex2f(0.0f , 0.0f);
+ glTexCoord2f(0.0f , 0.0f);
+ glVertex2f(0.0f , height_norm);
+ glTexCoord2f(width_norm, 0.0f);
+ glVertex2f(width_norm, height_norm);
+ glTexCoord2f(width_norm, height_norm);
+ glVertex2f(width_norm, 0.0f);
+ glTexCoord2f(0.0f , height_norm);
+ }
+ glEnd();
+
+ // Release the FBO texture (finished rendering)
+ glBindTexture(eTarget, 0);
+ }
+
+ // bind to the Fragment Program
+ void bindFragmentProgram()
+ {
+ glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_textureProgram);
+ glEnable(GL_FRAGMENT_PROGRAM_ARB);
+ }
+
+ // bind to the FrameBuffer Object
+ void bindRenderPath()
+ {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboData.fb);
+ }
+
+ // release current FrameBuffer Object
+ void unbindRenderPath()
+ {
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+ // bind to the FBO to Texture
+ void bindTexture()
+ {
+ glBindTexture(m_eGLTarget, m_fboData.colorTex);
+ }
+
+ // release this bind
+ void unbindTexture()
+ {
+ glBindTexture(m_eGLTarget, 0);
+ }
+
+ GLuint getFbo()
+ {
+ return m_fboData.fb;
+ }
+ GLuint getTex()
+ {
+ return m_fboData.colorTex;
+ }
+ GLuint getDepthTex()
+ {
+ return m_fboData.depthTex;
+ }
+
+ private:
+ GLuint m_Width, m_Height;
+ fboData m_fboData;
+ fboConfig m_fboConfig;
+
+ GLuint m_textureProgram;
+ GLuint m_overlayProgram;
+
+ bool m_bUseFloat;
+ GLenum m_eGLTarget;
+};
+
+
+// CheckFBO - render and verify contents of the FBO
+class CheckFBO: public CheckRender
+{
+ public:
+ CheckFBO(unsigned int width, unsigned int height, unsigned int Bpp) :
+ CheckRender(width, height, Bpp, false, false, true),
+ m_pFrameBufferObject(NULL)
+ {
+ }
+
+ CheckFBO(unsigned int width, unsigned int height, unsigned int Bpp, CFrameBufferObject *pFrameBufferObject) :
+ CheckRender(width, height, Bpp, false, true, true),
+ m_pFrameBufferObject(pFrameBufferObject)
+ {
+ }
+
+ virtual ~CheckFBO()
+ {
+ }
+
+ virtual bool checkStatus(const char *zfile, int line, bool silent)
+ {
+ GLenum status;
+ status = (GLenum) glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
+ {
+ printf("<%s : %d> - ", zfile, line);
+ }
+
+ switch (status)
+ {
+ case GL_FRAMEBUFFER_COMPLETE_EXT:
+ break;
+
+ case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ if (!silent)
+ {
+ printf("Unsupported framebuffer format\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing attachment\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, duplicate attachment\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, attached images must have same dimensions\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, attached images must have same format\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing draw buffer\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing read buffer\n");
+ }
+
+ return false;
+
+ default:
+ assert(0);
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual bool readback(GLuint width, GLuint height)
+ {
+ bool ret = false;
+
+ if (m_bUsePBO)
+ {
+ // binds the PBO for readback
+ bindReadback();
+
+ // bind FBO buffer (we want to transfer FBO -> PBO)
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_pFrameBufferObject->getFbo());
+
+ // Now initiate the readback to PBO
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback() FBO->PBO checkStatus = %d\n", ret);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+
+ // release the FBO
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ // Reading back from FBO using glReadPixels
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_pFrameBufferObject->getFbo());
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glBindFramebufferEXT() checkStatus = %d\n", ret);
+ }
+
+ glReadBuffer(static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT));
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glReadBuffer() checkStatus = %d\n", ret);
+ }
+
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+
+ return CHECK_FBO;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, GLuint bufObject)
+ {
+ bool ret = false;
+
+ if (m_bUseFBO)
+ {
+ if (m_bUsePBO)
+ {
+ printf("CheckFBO::readback() FBO->PBO->m_pImageData\n");
+ // binds the PBO for readback
+ bindReadback();
+
+ // bind FBO buffer (we want to transfer FBO -> PBO)
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufObject);
+
+ // Now initiate the readback to PBO
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback() FBO->PBO checkStatus = %d\n", ret);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+
+ // release the FBO
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ printf("CheckFBO::readback() FBO->m_pImageData\n");
+ // Reading direct to FBO using glReadPixels
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, bufObject);
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glBindFramebufferEXT() fbo=%d checkStatus = %d\n", (int)bufObject, (int)ret);
+ }
+
+ glReadBuffer(static_cast<GLenum>(GL_COLOR_ATTACHMENT0_EXT));
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glReadBuffer() fbo=%d checkStatus = %d\n", (int)bufObject, (int)ret);
+ }
+
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ }
+ }
+ else
+ {
+ printf("CheckFBO::readback() PBO->m_pImageData\n");
+ // read from bufObject (PBO) to system memorys image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, bufObject); // Bind the PBO
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBuffer(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER_ARB);
+
+ // read from bufObject (PBO) to system memory image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0); // unBind the PBO
+ }
+
+ return CHECK_FBO;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, unsigned char *memBuf)
+ {
+ // let's flip the image as we copy
+ for (unsigned int y = 0; y < height; y++)
+ {
+ memcpy((void *)&(m_pImageData[(height-y)*width*m_Bpp]), (void *)&(memBuf[y*width*m_Bpp]), width*m_Bpp);
+ }
+
+ return true;
+ }
+
+ private:
+ CFrameBufferObject *m_pFrameBufferObject;
+};
+
+#endif // _RENDERCHECK_GL_H_
+
diff --git a/tests/projects/cuda_console/inc/rendercheck_gles.h b/tests/projects/cuda_console/inc/rendercheck_gles.h
new file mode 100644
index 000000000..a35984b06
--- /dev/null
+++ b/tests/projects/cuda_console/inc/rendercheck_gles.h
@@ -0,0 +1,1419 @@
+/**
+ * Copyright 1993-2015 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+
+#ifndef _RENDERCHECK_GLES_H_
+#define _RENDERCHECK_GLES_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <vector>
+#include <map>
+#include <string>
+
+#include <GLES3/gl31.h>
+
+#include <helper_image.h>
+
+using std::vector;
+using std::map;
+using std::string;
+
+#define BUFFER_OFFSET(i) ((char *)NULL + (i))
+
+#if _DEBUG
+#define CHECK_FBO checkStatus(__FILE__, __LINE__, true)
+#else
+#define CHECK_FBO true
+#endif
+
+class CheckRender
+{
+ public:
+ CheckRender(unsigned int width, unsigned int height, unsigned int Bpp,
+ bool bQAReadback, bool bUseFBO, bool bUsePBO) :
+ m_Width(width), m_Height(height), m_Bpp(Bpp), m_bQAReadback(bQAReadback),
+ m_bUseFBO(bUseFBO), m_bUsePBO(bUsePBO), m_PixelFormat(GL_RGBA), m_fThresholdCompare(0.0f)
+ {
+ allocateMemory(width, height, Bpp, bUseFBO, bUsePBO);
+ }
+
+ virtual ~CheckRender()
+ {
+ // Release PBO resources
+ if (m_bUsePBO)
+ {
+ glDeleteBuffers(1, &m_pboReadback);
+ m_pboReadback = 0;
+ }
+
+ free(m_pImageData);
+ }
+
+ virtual void allocateMemory(unsigned int width, unsigned int height, unsigned int Bpp,
+ bool bUseFBO, bool bUsePBO)
+ {
+ // Create the PBO for readbacks
+ if (bUsePBO)
+ {
+ glGenBuffers(1, &m_pboReadback);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pboReadback);
+ glBufferData(GL_PIXEL_UNPACK_BUFFER, width*height*Bpp, NULL, GL_STREAM_READ);
+ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
+ }
+
+ m_pImageData = (unsigned char *)malloc(width*height*Bpp); // This is the image data stored in system memory
+ }
+
+
+ virtual void setExecPath(char *path)
+ {
+ m_ExecPath = path;
+ }
+ virtual void EnableQAReadback(bool bStatus)
+ {
+ m_bQAReadback = bStatus;
+ }
+ virtual bool IsQAReadback()
+ {
+ return m_bQAReadback;
+ }
+ virtual bool IsFBO()
+ {
+ return m_bUseFBO;
+ }
+ virtual bool IsPBO()
+ {
+ return m_bUsePBO;
+ }
+ virtual void *imageData()
+ {
+ return m_pImageData;
+ }
+
+ // Interface to this class functions
+ virtual void setPixelFormat(GLenum format)
+ {
+ m_PixelFormat = format;
+ }
+ virtual int getPixelFormat()
+ {
+ return m_PixelFormat;
+ }
+ virtual bool checkStatus(const char *zfile, int line, bool silent) = 0;
+ virtual bool readback(GLuint width, GLuint height) = 0;
+ virtual bool readback(GLuint width, GLuint height, GLuint bufObject) = 0;
+ virtual bool readback(GLuint width, GLuint height, unsigned char *membuf) = 0;
+
+ virtual void bindReadback()
+ {
+ if (!m_bQAReadback)
+ {
+ printf("CheckRender::bindReadback() uninitialized!\n");
+ return;
+ }
+
+ if (m_bUsePBO)
+ {
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, m_pboReadback); // Bind the PBO
+ }
+ }
+
+ virtual void unbindReadback()
+ {
+ if (!m_bQAReadback)
+ {
+ printf("CheckRender::unbindReadback() uninitialized!\n");
+ return;
+ }
+
+ if (m_bUsePBO)
+ {
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); // Release the bind on the PBO
+ }
+ }
+
+ virtual void savePGM(const char *zfilename, bool bInvert, void **ppReadBuf)
+ {
+ if (zfilename != NULL)
+ {
+ if (bInvert)
+ {
+ unsigned char *readBuf;
+ unsigned char *writeBuf= (unsigned char *)malloc(m_Width * m_Height);
+
+ for (unsigned int y=0; y < m_Height; y++)
+ {
+ if (ppReadBuf)
+ {
+ readBuf = *(unsigned char **)ppReadBuf;
+ }
+ else
+ {
+ readBuf = (unsigned char *)m_pImageData;
+ }
+
+ memcpy(&writeBuf[m_Width*m_Bpp*y], (readBuf+ m_Width*(m_Height-1-y)), m_Width);
+ }
+
+ // we copy the results back to original system buffer
+ if (ppReadBuf)
+ {
+ memcpy(*ppReadBuf, writeBuf, m_Width*m_Height);
+ }
+ else
+ {
+ memcpy(m_pImageData, writeBuf, m_Width*m_Height);
+ }
+
+ free(writeBuf);
+ }
+
+ printf("> Saving PGM: <%s>\n", zfilename);
+
+ if (ppReadBuf)
+ {
+ sdkSavePGM<unsigned char>(zfilename, *(unsigned char **)ppReadBuf, m_Width, m_Height);
+ }
+ else
+ {
+ sdkSavePGM<unsigned char>(zfilename, (unsigned char *)m_pImageData, m_Width, m_Height);
+ }
+ }
+ }
+
+ virtual void savePPM(const char *zfilename, bool bInvert, void **ppReadBuf)
+ {
+ if (zfilename != NULL)
+ {
+ if (bInvert)
+ {
+ unsigned char *readBuf;
+ unsigned char *writeBuf= (unsigned char *)malloc(m_Width * m_Height * m_Bpp);
+
+ for (unsigned int y=0; y < m_Height; y++)
+ {
+ if (ppReadBuf)
+ {
+ readBuf = *(unsigned char **)ppReadBuf;
+ }
+ else
+ {
+ readBuf = (unsigned char *)m_pImageData;
+ }
+ memcpy(&writeBuf[m_Width*m_Bpp*y], (readBuf+ m_Width*m_Bpp*(m_Height-1-y)), m_Width*m_Bpp);
+ }
+
+ // we copy the results back to original system buffer
+ if (ppReadBuf)
+ {
+ memcpy(*ppReadBuf, writeBuf, m_Width*m_Height*m_Bpp);
+ }
+ else
+ {
+ memcpy(m_pImageData, writeBuf, m_Width*m_Height*m_Bpp);
+ }
+
+ free(writeBuf);
+ }
+
+ printf("> Saving PPM: <%s>\n", zfilename);
+
+ if (ppReadBuf)
+ {
+ sdkSavePPM4ub(zfilename, *(unsigned char **)ppReadBuf, m_Width, m_Height);
+ }
+ else
+ {
+ sdkSavePPM4ub(zfilename, (unsigned char *)m_pImageData, m_Width, m_Height);
+ }
+ }
+ }
+
+ virtual bool PGMvsPGM(const char *src_file, const char *ref_file, const float epsilon, const float threshold = 0.0f)
+ {
+ unsigned char *src_data = NULL, *ref_data = NULL;
+ unsigned long error_count = 0;
+ unsigned int width, height;
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("CheckRender::PGMvsPGM unable to find <%s> in <%s> Aborting comparison!\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+ }
+ else
+ {
+
+ if (src_file == NULL || ref_file_path == NULL)
+ {
+ printf("PGMvsPGM: Aborting comparison\n");
+ return false;
+ }
+
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+
+ if (sdkLoadPPMub(ref_file_path, &ref_data, &width, &height) != true)
+ {
+ printf("PGMvsPGM: unable to load ref image file: %s\n", ref_file_path);
+ return false;
+ }
+
+ if (sdkLoadPPMub(src_file, &src_data, &width, &height) != true)
+ {
+ printf("PGMvsPGM: unable to load src image file: %s\n", src_file);
+ return false;
+ }
+
+ printf("PGMvsPGM: comparing images size (%d,%d) epsilon(%2.4f), threshold(%4.2f%%)\n", m_Height, m_Width, epsilon, threshold*100);
+
+ if (compareDataAsFloatThreshold<unsigned char, float>(ref_data, src_data, m_Height*m_Width, epsilon, threshold) == false)
+ {
+ error_count = 1;
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+ }
+
+ virtual bool PPMvsPPM(const char *src_file, const char *ref_file, const float epsilon, const float threshold = 0.0f)
+ {
+ unsigned long error_count = 0;
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("CheckRender::PPMvsPPM unable to find <%s> in <%s> Aborting comparison!\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+ }
+
+ if (src_file == NULL || ref_file_path == NULL)
+ {
+ printf("PPMvsPPM: Aborting comparison\n");
+ return false;
+ }
+
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+ return (sdkComparePPM(src_file, ref_file_path, epsilon, threshold, true) == true ? true : false);
+ }
+
+
+ void setThresholdCompare(float value)
+ {
+ m_fThresholdCompare = value;
+ }
+
+ virtual void dumpBin(void *data, unsigned int bytes, const char *filename)
+ {
+ FILE *fp;
+ printf("CheckRender::dumpBin: <%s>\n", filename);
+ FOPEN(fp, filename, "wb");
+ fwrite(data, bytes, 1, fp);
+ fflush(fp);
+ fclose(fp);
+ }
+
+ virtual bool compareBin2BinUint(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold)
+ {
+ unsigned int *src_buffer, *ref_buffer;
+ FILE *src_fp = NULL, *ref_fp = NULL;
+
+ unsigned long error_count = 0;
+ size_t fsize = 0;
+
+ FOPEN(src_fp, src_file, "rb");
+
+ if (src_fp == NULL)
+ {
+ printf("compareBin2Bin <unsigned int> unable to open src_file: %s\n", src_file);
+ error_count++;
+ }
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("compareBin2Bin <unsigned int> unable to find <%s> in <%s>\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", ref_file);
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ else
+ {
+ FOPEN(ref_fp, ref_file_path, "rb");
+
+ if (ref_fp == NULL)
+ {
+ printf("compareBin2Bin <unsigned int> unable to open ref_file: %s\n", ref_file_path);
+ error_count++;
+ }
+
+ if (src_fp && ref_fp)
+ {
+ src_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int));
+ ref_buffer = (unsigned int *)malloc(nelements*sizeof(unsigned int));
+
+ fsize = fread(src_buffer, sizeof(unsigned int), nelements, src_fp);
+
+ if (fsize != nelements)
+ {
+ printf("compareBin2Bin <unsigned int> failed to read %u elements from %s\n", nelements, src_file);
+ error_count++;
+ }
+
+ fsize = fread(ref_buffer, sizeof(unsigned int), nelements, ref_fp);
+
+ if (fsize == 0)
+ {
+ printf("compareBin2Bin <unsigned int> failed to read %u elements from %s\n", nelements, ref_file_path);
+ error_count++;
+ }
+
+
+ printf("> compareBin2Bin <unsigned int> nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold);
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+
+ if (!compareData<unsigned int, float>(ref_buffer, src_buffer, nelements, epsilon, threshold))
+ {
+ error_count++;
+ }
+
+ fclose(src_fp);
+ fclose(ref_fp);
+
+ free(src_buffer);
+ free(ref_buffer);
+ }
+ else
+ {
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+ }
+
+ virtual bool compareBin2BinFloat(const char *src_file, const char *ref_file, unsigned int nelements, const float epsilon, const float threshold)
+ {
+ float *src_buffer, *ref_buffer;
+ FILE *src_fp = NULL, *ref_fp = NULL;
+ size_t fsize = 0;
+
+ unsigned long error_count = 0;
+
+ FOPEN(src_fp, src_file, "rb");
+
+ if (src_fp == NULL)
+ {
+ printf("compareBin2Bin <float> unable to open src_file: %s\n", src_file);
+ error_count = 1;
+ }
+
+ char *ref_file_path = sdkFindFilePath(ref_file, m_ExecPath.c_str());
+
+ if (ref_file_path == NULL)
+ {
+ printf("compareBin2Bin <float> unable to find <%s> in <%s>\n", ref_file, m_ExecPath.c_str());
+ printf(">>> Check info.xml and [project//data] folder <%s> <<<\n", m_ExecPath.c_str());
+ printf("Aborting comparison!\n");
+ printf(" FAILED\n");
+ error_count++;
+
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ else
+ {
+ FOPEN(ref_fp, ref_file_path, "rb");
+
+ if (ref_fp == NULL)
+ {
+ printf("compareBin2Bin <float> unable to open ref_file: %s\n", ref_file_path);
+ error_count = 1;
+ }
+
+ if (src_fp && ref_fp)
+ {
+ src_buffer = (float *)malloc(nelements*sizeof(float));
+ ref_buffer = (float *)malloc(nelements*sizeof(float));
+
+ fsize = fread(src_buffer, sizeof(float), nelements, src_fp);
+
+ if (fsize != nelements)
+ {
+ printf("compareBin2Bin <float> failed to read %u elements from %s\n", nelements, src_file);
+ error_count++;
+ }
+
+ fsize = fread(ref_buffer, sizeof(float), nelements, ref_fp);
+
+ if (fsize == 0)
+ {
+ printf("compareBin2Bin <float> failed to read %u elements from %s\n", nelements, ref_file_path);
+ error_count++;
+ }
+
+ printf("> compareBin2Bin <float> nelements=%d, epsilon=%4.2f, threshold=%4.2f\n", nelements, epsilon, threshold);
+ printf(" src_file <%s>\n", src_file);
+ printf(" ref_file <%s>\n", ref_file_path);
+
+ if (!compareDataAsFloatThreshold<float, float>(ref_buffer, src_buffer, nelements, epsilon, threshold))
+ {
+ error_count++;
+ }
+
+ fclose(src_fp);
+ fclose(ref_fp);
+
+ free(src_buffer);
+ free(ref_buffer);
+ }
+ else
+ {
+ if (src_fp)
+ {
+ fclose(src_fp);
+ }
+
+ if (ref_fp)
+ {
+ fclose(ref_fp);
+ }
+ }
+ }
+
+ if (error_count == 0)
+ {
+ printf(" OK\n");
+ }
+ else
+ {
+ printf(" FAILURE: %d errors...\n", (unsigned int)error_count);
+ }
+
+ return (error_count == 0); // returns true if all pixels pass
+ }
+
+
+ protected:
+ unsigned int m_Width, m_Height, m_Bpp;
+ unsigned char *m_pImageData; // This is the image data stored in system memory
+ bool m_bQAReadback, m_bUseFBO, m_bUsePBO;
+ GLuint m_pboReadback;
+ GLenum m_PixelFormat;
+ float m_fThresholdCompare;
+ string m_ExecPath;
+};
+
+
+class CheckBackBuffer : public CheckRender
+{
+ public:
+ CheckBackBuffer(unsigned int width, unsigned int height, unsigned int Bpp, bool bUseOpenGL = true) :
+ CheckRender(width, height, Bpp, false, false, bUseOpenGL)
+ {
+ }
+
+ virtual ~CheckBackBuffer()
+ {
+ }
+
+ virtual bool checkStatus(const char *zfile, int line, bool silent)
+ {
+ GLenum nErrorCode = glGetError();
+
+ if (nErrorCode != GL_NO_ERROR)
+ {
+ if (!silent)
+ {
+ //printf("Assertion failed(%s,%d): %s\n", zfile, line, gluErrorString(nErrorCode));
+ }
+ }
+
+ return true;
+ }
+
+ virtual bool readback(GLuint width, GLuint height)
+ {
+ bool ret = false;
+
+ if (m_bUsePBO)
+ {
+ // binds the PBO for readback
+ bindReadback();
+
+ // Initiate the readback BLT from BackBuffer->PBO->membuf
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::glReadPixels() checkStatus = %d\n", ret);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, width*height*m_Bpp, GL_READ_ONLY);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ // reading direct from the backbuffer
+ glReadBuffer(GL_FRONT);
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+ }
+
+ return ret;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, GLuint bufObject)
+ {
+ bool ret = false;
+
+ if (m_bUseFBO)
+ {
+ if (m_bUsePBO)
+ {
+ printf("CheckBackBuffer::readback() FBO->PBO->m_pImageData\n");
+ // binds the PBO for readback
+ bindReadback();
+
+ // bind FBO buffer (we want to transfer FBO -> PBO)
+ glBindFramebuffer(GL_FRAMEBUFFER, bufObject);
+
+ // Now initiate the readback to PBO
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::readback() FBO->PBO checkStatus = %d\n", ret);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, width*height*m_Bpp, GL_MAP_READ_BIT);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+
+ // release the FBO
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ printf("CheckBackBuffer::readback() FBO->m_pImageData\n");
+ // Reading direct to FBO using glReadPixels
+ glBindFramebuffer(GL_FRAMEBUFFER, bufObject);
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::readback::glBindFramebufferEXT() fbo=%d checkStatus = %d\n", bufObject, ret);
+ }
+
+ glReadBuffer(static_cast<GLenum>(GL_COLOR_ATTACHMENT0));
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckBackBuffer::readback::glReadBuffer() fbo=%d checkStatus = %d\n", bufObject, ret);
+ }
+
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+ }
+ else
+ {
+
+ printf("CheckBackBuffer::readback() PBO->m_pImageData\n");
+ // read from bufObject (PBO) to system memorys image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, bufObject); // Bind the PBO
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, width*height*m_Bpp, GL_MAP_READ_BIT);
+
+ // allocate a buffer so we can flip the image
+ unsigned char *temp_buf = (unsigned char *)malloc(width*height*m_Bpp);
+ memcpy(temp_buf, ioMem, width*height*m_Bpp);
+
+ // let's flip the image as we copy
+ for (unsigned int y = 0; y < height; y++)
+ {
+ memcpy((void *)&(m_pImageData[(height-y)*width*m_Bpp]), (void *)&(temp_buf[y*width*m_Bpp]), width*m_Bpp);
+ }
+
+ free(temp_buf);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+
+ // read from bufObject (PBO) to system memory image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); // unBind the PBO
+ }
+
+ return CHECK_FBO;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, unsigned char *memBuf)
+ {
+ // let's flip the image as we copy
+ for (unsigned int y = 0; y < height; y++)
+ {
+ memcpy((void *)&(m_pImageData[(height-y)*width*m_Bpp]), (void *)&(memBuf[y*width*m_Bpp]), width*m_Bpp);
+ }
+
+ return true;
+ }
+
+ private:
+ virtual void bindFragmentProgram() {};
+ virtual void bindRenderPath() {};
+ virtual void unbindRenderPath() {};
+
+ // bind to the BackBuffer to Texture
+ virtual void bindTexture() {};
+
+ // release this bind
+ virtual void unbindTexture() {};
+};
+
+// structure defining the properties of a single buffer
+struct bufferConfig
+{
+ string name;
+ GLenum format;
+ int bits;
+};
+
+// structures defining properties of an FBO
+struct fboConfig
+{
+ string name;
+ GLenum colorFormat;
+ GLenum depthFormat;
+ int redbits;
+ int depthBits;
+ int depthSamples;
+ int coverageSamples;
+};
+
+struct fboData
+{
+ GLuint colorTex; //color texture
+ GLuint depthTex; //depth texture
+ GLuint fb; // render framebuffer
+ GLuint resolveFB; //multisample resolve target
+ GLuint colorRB; //color render buffer
+ GLuint depthRB; // depth render buffer
+};
+
+
+class CFrameBufferObject
+{
+ public:
+ CFrameBufferObject(unsigned int width, unsigned int height, unsigned int Bpp, bool bUseFloat, GLenum eTarget) :
+ m_Width(width),
+ m_Height(height),
+ m_bUseFloat(bUseFloat),
+ m_eGLTarget(eTarget)
+ {
+ glGenFramebuffers(1, &m_fboData.fb);
+
+ m_fboData.colorTex = createTexture(m_eGLTarget, width, height, GL_RGBA, GL_RGBA);
+ m_fboData.depthTex = createTexture(m_eGLTarget, width, height, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT);
+
+ attachTexture(m_eGLTarget, m_fboData.depthTex, GL_DEPTH_ATTACHMENT);
+ attachTexture(m_eGLTarget, m_fboData.colorTex, GL_COLOR_ATTACHMENT0);
+
+ bool ret = checkStatus(__FILE__, __LINE__, false);
+ }
+
+ void check_gl_error(const char *file, int line)
+ {
+ GLenum err (glGetError());
+
+ while(err!=GL_NO_ERROR) {
+ char error[64];
+
+ switch(err) {
+ case GL_INVALID_OPERATION: strcpy(error, "INVALID_OPERATION"); break;
+ case GL_INVALID_ENUM: strcpy(error, "INVALID_ENUM"); break;
+ case GL_INVALID_VALUE: strcpy(error, "INVALID_VALUE"); break;
+ case GL_OUT_OF_MEMORY: strcpy(error, "OUT_OF_MEMORY"); break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION: strcpy(error, "INVALID_FRAMEBUFFER_OPERATION"); break;
+ }
+
+ printf ( "GL_%s - %s : %d\n", error, file, line);
+ err=glGetError();
+ }
+ }
+
+ virtual ~CFrameBufferObject()
+ {
+ freeResources();
+ }
+
+ GLuint createTexture(GLenum target, int w, int h, GLint internalformat, GLenum format)
+ {
+ GLuint texid;
+ glGenTextures(1, &texid);
+
+ glBindTexture(target, texid);
+
+ if (format != GL_DEPTH_COMPONENT)
+ {
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ }
+ else
+ {
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if (internalformat == GL_DEPTH_COMPONENT24)
+ {
+ glTexImage2D(target, 0, internalformat, w, h, 0, format, GL_UNSIGNED_INT, 0);
+ }
+ else
+ {
+ glTexImage2D(target, 0, internalformat, w, h, 0, format, GL_UNSIGNED_BYTE, 0);
+ }
+
+ check_gl_error(__FILE__, __LINE__);
+ glBindTexture(target, 0);
+
+ return texid;
+ }
+
+ void attachTexture(GLenum texTarget,
+ GLuint texId,
+ GLenum attachment = GL_COLOR_ATTACHMENT0,
+ int mipLevel = 0,
+ int zSlice = 0)
+ {
+ bindRenderPath();
+ check_gl_error(__FILE__, __LINE__);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, texTarget, texId, mipLevel);
+
+ checkStatus(__FILE__, __LINE__, false);
+
+ unbindRenderPath();
+ }
+
+ bool initialize(unsigned width, unsigned height, fboConfig &rConfigFBO, fboData &rActiveFBO)
+ {
+ //Framebuffer config options
+ vector<bufferConfig> colorConfigs;
+ vector<bufferConfig> depthConfigs;
+ bufferConfig temp;
+
+ //add default color configs
+ temp.name = (m_bUseFloat ? "RGBA32F" : "RGBA8");
+ temp.bits = (m_bUseFloat ? 32 : 8);
+ temp.format = (m_bUseFloat ? GL_RGBA32F : GL_RGBA8);
+ colorConfigs.push_back(temp);
+
+ //add default depth configs
+ temp.name = "D24";
+ temp.bits = 24;
+ temp.format = GL_DEPTH_COMPONENT24;
+ depthConfigs.push_back(temp);
+
+ // If the FBO can be created, add it to the list of available configs, and make a menu entry
+ string root = colorConfigs[0].name + " " + depthConfigs[0].name;
+
+ rConfigFBO.colorFormat = colorConfigs[0].format;
+ rConfigFBO.depthFormat = depthConfigs[0].format;
+ rConfigFBO.redbits = colorConfigs[0].bits;
+ rConfigFBO.depthBits = depthConfigs[0].bits;
+
+ //single sample
+ rConfigFBO.name = root;
+ rConfigFBO.coverageSamples = 0;
+ rConfigFBO.depthSamples = 0;
+
+ create(width, height, rConfigFBO, rActiveFBO);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ return CHECK_FBO;
+ }
+
+ bool create(GLuint width, GLuint height, fboConfig &config, fboData &data)
+ {
+ bool multisample = config.depthSamples > 0;
+ bool ret = true;
+ GLint query;
+
+ printf("\nCreating FBO <%s> (%dx%d) Float:%s\n", config.name.c_str(), (int)width, (int)height, (m_bUseFloat ? "Y":"N"));
+
+ glGenFramebuffers(1, &data.fb);
+ glGenTextures(1, &data.colorTex);
+
+ // init texture
+ glBindTexture(m_eGLTarget, data.colorTex);
+ glTexImage2D(m_eGLTarget, 0, config.colorFormat,
+ width, height, 0, GL_RGBA,
+ (m_bUseFloat ? GL_FLOAT : GL_UNSIGNED_BYTE),
+ NULL);
+
+ glGenerateMipmap(m_eGLTarget);
+
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR);
+
+ {
+ glGenTextures(1, &data.depthTex);
+ data.depthRB = 0;
+ data.colorRB = 0;
+ data.resolveFB = 0;
+
+ //non-multisample, so bind things directly to the FBO
+ glBindFramebuffer(GL_FRAMEBUFFER, data.fb);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_eGLTarget, data.colorTex, 0);
+
+ glBindTexture(m_eGLTarget, data.depthTex);
+ glTexImage2D(m_eGLTarget, 0, config.depthFormat,
+ width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
+
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // GL_LINEAR);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // GL_LINEAR);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(m_eGLTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+// glTexParameterf(m_eGLTarget, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, m_eGLTarget, data.depthTex, 0);
+
+ ret &= checkStatus(__FILE__, __LINE__, false);
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, data.fb);
+ glGetIntegerv(GL_RED_BITS, &query);
+
+ if (query != config.redbits)
+ {
+ ret = false;
+ }
+
+ glGetIntegerv(GL_DEPTH_BITS, &query);
+
+ if (query != config.depthBits)
+ {
+ ret = false;
+ }
+
+ if (multisample)
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, data.resolveFB);
+ glGetIntegerv(GL_RED_BITS, &query);
+
+ if (query != config.redbits)
+ {
+ ret = false;
+ }
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ return ret;
+ }
+
+ virtual void freeResources()
+ {
+ if (m_fboData.fb)
+ {
+ glDeleteFramebuffers(1, &m_fboData.fb);
+ }
+
+ if (m_fboData.resolveFB)
+ {
+ glDeleteFramebuffers(1, &m_fboData.resolveFB);
+ }
+
+ if (m_fboData.colorRB)
+ {
+ glDeleteRenderbuffers(1, &m_fboData.colorRB);
+ }
+
+ if (m_fboData.depthRB)
+ {
+ glDeleteRenderbuffers(1, &m_fboData.depthRB);
+ }
+
+ if (m_fboData.colorTex)
+ {
+ glDeleteTextures(1, &m_fboData.colorTex);
+ }
+
+ if (m_fboData.depthTex)
+ {
+ glDeleteTextures(1, &m_fboData.depthTex);
+ }
+
+ glDeleteProgram(m_textureProgram);
+ glDeleteProgram(m_overlayProgram);
+ }
+
+ virtual bool checkStatus(const char *zfile, int line, bool silent)
+ {
+ GLenum status;
+ status = (GLenum) glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ {
+ printf("<%s : %d> - this one ", zfile, line);
+ }
+
+ switch (status)
+ {
+ case GL_FRAMEBUFFER_COMPLETE:
+ break;
+
+ case GL_FRAMEBUFFER_UNSUPPORTED:
+ if (!silent)
+ {
+ printf("Unsupported framebuffer format\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing attachment\n");
+ }
+
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, duplicate attachment\n");
+ }
+
+ return false;
+
+ default:
+ assert(0);
+ return false;
+ }
+
+ return true;
+ }
+
+ // bind to the FrameBuffer Object
+ void bindRenderPath()
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fboData.fb);
+ }
+
+ // release current FrameBuffer Object
+ void unbindRenderPath()
+ {
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ // bind to the FBO to Texture
+ void bindTexture()
+ {
+ glBindTexture(m_eGLTarget, m_fboData.colorTex);
+ }
+
+ // release this bind
+ void unbindTexture()
+ {
+ glBindTexture(m_eGLTarget, 0);
+ }
+
+ GLuint getFbo()
+ {
+ return m_fboData.fb;
+ }
+ GLuint getTex()
+ {
+ return m_fboData.colorTex;
+ }
+ GLuint getDepthTex()
+ {
+ return m_fboData.depthTex;
+ }
+
+ private:
+ GLuint m_Width, m_Height;
+ fboData m_fboData;
+ fboConfig m_fboConfig;
+
+ GLuint m_textureProgram;
+ GLuint m_overlayProgram;
+
+ bool m_bUseFloat;
+ GLenum m_eGLTarget;
+};
+
+
+// CheckFBO - render and verify contents of the FBO
+class CheckFBO: public CheckRender
+{
+ public:
+ CheckFBO(unsigned int width, unsigned int height, unsigned int Bpp) :
+ CheckRender(width, height, Bpp, false, false, true),
+ m_pFrameBufferObject(NULL)
+ {
+ }
+
+ CheckFBO(unsigned int width, unsigned int height, unsigned int Bpp, CFrameBufferObject *pFrameBufferObject) :
+ CheckRender(width, height, Bpp, false, true, true),
+ m_pFrameBufferObject(pFrameBufferObject)
+ {
+ }
+
+ void check_gl_error(const char *file, int line)
+ {
+ GLenum err (glGetError());
+
+ while(err!=GL_NO_ERROR)
+ {
+ char error[64];
+
+ switch(err)
+ {
+ case GL_INVALID_OPERATION: strcpy(error, "INVALID_OPERATION"); break;
+ case GL_INVALID_ENUM: strcpy(error, "INVALID_ENUM"); break;
+ case GL_INVALID_VALUE: strcpy(error, "INVALID_VALUE"); break;
+ case GL_OUT_OF_MEMORY: strcpy(error, "OUT_OF_MEMORY"); break;
+ case GL_INVALID_FRAMEBUFFER_OPERATION: strcpy(error, "INVALID_FRAMEBUFFER_OPERATION"); break;
+ }
+
+ printf ( "GL_%s - %s : %d\n", error, file, line);
+ err=glGetError();
+ }
+ }
+
+ virtual ~CheckFBO()
+ {
+ }
+
+ virtual bool checkStatus(const char *zfile, int line, bool silent)
+ {
+ GLenum status;
+ status = (GLenum) glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE)
+ {
+ printf("<%s : %d> - here ", zfile, line);
+ }
+
+ switch (status)
+ {
+ case GL_FRAMEBUFFER_COMPLETE:
+ break;
+
+ case GL_FRAMEBUFFER_UNSUPPORTED:
+ if (!silent)
+ {
+ printf("Unsupported framebuffer format\n");
+ }
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, missing attachment\n");
+ }
+ return false;
+
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, duplicate attachment\n");
+ }
+ return false;
+
+ case GL_FRAMEBUFFER_UNDEFINED:
+ if (!silent)
+ {
+ printf("Framebuffer undefined\n");
+ }
+ return false;
+
+ default:
+ if (!silent)
+ {
+ printf("Framebuffer incomplete, default state\n");
+ }
+ assert(0);
+ return false;
+ }
+
+ return true;
+ }
+
+ virtual bool readback(GLuint width, GLuint height)
+ {
+ bool ret = false;
+
+ if (m_bUsePBO)
+ {
+ // binds the PBO for readback
+ bindReadback();
+
+ // bind FBO buffer (we want to transfer FBO -> PBO)
+ glBindFramebuffer(GL_FRAMEBUFFER, m_pFrameBufferObject->getFbo());
+
+ ret = checkStatus(__FILE__, __LINE__, false);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback() glBindFramebuffer checkStatus = %d\n", ret);
+ }
+
+ // Now initiate the readback to PBO
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+
+ ret = checkStatus(__FILE__, __LINE__, false);
+
+ check_gl_error(__FILE__, __LINE__);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback() FBO->PBO checkStatus = %d\n", ret);
+ }
+
+ int nBufferSize = 0;
+ glGetBufferParameteriv(GL_PIXEL_PACK_BUFFER, GL_BUFFER_SIZE, &nBufferSize);
+
+ if (nBufferSize != width*height*m_Bpp)
+ {
+ printf("Buffer size incorrect, exiting..\n");
+ exit(EXIT_FAILURE);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, width*height*m_Bpp, GL_MAP_READ_BIT);
+ check_gl_error(__FILE__, __LINE__);
+
+ if (ioMem != NULL)
+ {
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+ }
+ else
+ {
+ printf("\nError: Unable to map the PBO\n");
+ exit(EXIT_FAILURE);
+ }
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+
+ // release the FBO
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ // Reading back from FBO using glReadPixels
+ glBindFramebuffer(GL_FRAMEBUFFER, m_pFrameBufferObject->getFbo());
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glBindFramebufferEXT() checkStatus = %d\n", ret);
+ }
+
+ glReadBuffer(static_cast<GLenum>(GL_COLOR_ATTACHMENT0));
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glReadBuffer() checkStatus = %d\n", ret);
+ }
+
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+
+ return CHECK_FBO;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, GLuint bufObject)
+ {
+ bool ret = false;
+
+ if (m_bUseFBO)
+ {
+ if (m_bUsePBO)
+ {
+ printf("CheckFBO::readback() FBO->PBO->m_pImageData\n");
+ // binds the PBO for readback
+ bindReadback();
+
+ // bind FBO buffer (we want to transfer FBO -> PBO)
+ glBindFramebuffer(GL_FRAMEBUFFER, bufObject);
+
+ // Now initiate the readback to PBO
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback() FBO->PBO checkStatus = %d\n", ret);
+ }
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, width*height*m_Bpp, GL_MAP_READ_BIT);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+
+ // release the FBO
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ // release the PBO
+ unbindReadback();
+ }
+ else
+ {
+ printf("CheckFBO::readback() FBO->m_pImageData\n");
+ // Reading direct to FBO using glReadPixels
+ glBindFramebuffer(GL_FRAMEBUFFER, bufObject);
+ ret = checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glBindFramebufferEXT() fbo=%d checkStatus = %d\n", (int)bufObject, (int)ret);
+ }
+
+ glReadBuffer(static_cast<GLenum>(GL_COLOR_ATTACHMENT0));
+ ret &= checkStatus(__FILE__, __LINE__, true);
+
+ if (!ret)
+ {
+ printf("CheckFBO::readback::glReadBuffer() fbo=%d checkStatus = %d\n", (int)bufObject, (int)ret);
+ }
+
+ glReadPixels(0, 0, width, height, getPixelFormat(), GL_UNSIGNED_BYTE, m_pImageData);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ }
+ }
+ else
+ {
+ printf("CheckFBO::readback() PBO->m_pImageData\n");
+ // read from bufObject (PBO) to system memorys image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, bufObject); // Bind the PBO
+
+ // map - unmap simulates readback without the copy
+ void *ioMem = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, width*height*m_Bpp, GL_MAP_READ_BIT);
+ memcpy(m_pImageData, ioMem, width*height*m_Bpp);
+
+ glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+
+ // read from bufObject (PBO) to system memory image
+ glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); // unBind the PBO
+ }
+
+ return CHECK_FBO;
+ }
+
+ virtual bool readback(GLuint width, GLuint height, unsigned char *memBuf)
+ {
+ // let's flip the image as we copy
+ for (unsigned int y = 0; y < height; y++)
+ {
+ memcpy((void *)&(m_pImageData[(height-y)*width*m_Bpp]), (void *)&(memBuf[y*width*m_Bpp]), width*m_Bpp);
+ }
+
+ return true;
+ }
+
+ private:
+ CFrameBufferObject *m_pFrameBufferObject;
+};
+
+#endif // _RENDERCHECK_GLES_H_
+
diff --git a/tests/projects/cuda_console/inc/timer.h b/tests/projects/cuda_console/inc/timer.h
new file mode 100644
index 000000000..d856eb1f3
--- /dev/null
+++ b/tests/projects/cuda_console/inc/timer.h
@@ -0,0 +1,64 @@
+/**
+ * Copyright 1993-2013 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+#ifndef TIMER_H
+#define TIMER_H
+
+#include <stdlib.h>
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+double PCFreq = 0.0;
+__int64 timerStart = 0;
+#else
+struct timeval timerStart;
+#endif
+
+void StartTimer()
+{
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+ LARGE_INTEGER li;
+
+ if (!QueryPerformanceFrequency(&li))
+ {
+ printf("QueryPerformanceFrequency failed!\n");
+ }
+
+ PCFreq = (double)li.QuadPart/1000.0;
+ QueryPerformanceCounter(&li);
+ timerStart = li.QuadPart;
+#else
+ gettimeofday(&timerStart, NULL);
+#endif
+}
+
+// time elapsed in ms
+double GetTimer()
+{
+#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
+ LARGE_INTEGER li;
+ QueryPerformanceCounter(&li);
+ return (double)(li.QuadPart-timerStart)/PCFreq;
+#else
+ struct timeval timerStop, timerElapsed;
+ gettimeofday(&timerStop, NULL);
+ timersub(&timerStop, &timerStart, &timerElapsed);
+ return timerElapsed.tv_sec*1000.0+timerElapsed.tv_usec/1000.0;
+#endif
+}
+#endif // TIMER_H
+
diff --git a/tests/projects/cuda_console/src/main.cu b/tests/projects/cuda_console/src/main.cu
new file mode 100644
index 000000000..a02371a2d
--- /dev/null
+++ b/tests/projects/cuda_console/src/main.cu
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1993-2015 NVIDIA Corporation. All rights reserved.
+ *
+ * Please refer to the NVIDIA end user license agreement (EULA) associated
+ * with this source code for terms and conditions that govern your use of
+ * this software. Any use, reproduction, disclosure, or distribution of
+ * this software and related documentation outside the terms of the EULA
+ * is strictly prohibited.
+ *
+ */
+
+
+// System includes
+#include <stdio.h>
+#include <assert.h>
+
+// CUDA runtime
+#include <cuda_runtime.h>
+
+// helper functions and utilities to work with CUDA
+#include <helper_functions.h>
+#include <helper_cuda.h>
+
+#ifndef MAX
+#define MAX(a,b) (a > b ? a : b)
+#endif
+
+__global__ void testKernel(int val)
+{
+ printf("[%d, %d]:\t\tValue is:%d\n",\
+ blockIdx.y*gridDim.x+blockIdx.x,\
+ threadIdx.z*blockDim.x*blockDim.y+threadIdx.y*blockDim.x+threadIdx.x,\
+ val);
+}
+
+int main(int argc, char **argv)
+{
+ int devID;
+ cudaDeviceProp props;
+
+ // This will pick the best possible CUDA capable device
+ devID = findCudaDevice(argc, (const char **)argv);
+
+ //Get GPU information
+ checkCudaErrors(cudaGetDevice(&devID));
+ checkCudaErrors(cudaGetDeviceProperties(&props, devID));
+ printf("Device %d: \"%s\" with Compute %d.%d capability\n",
+ devID, props.name, props.major, props.minor);
+
+ printf("printf() is called. Output:\n\n");
+
+ //Kernel configuration, where a two-dimensional grid and
+ //three-dimensional blocks are configured.
+ dim3 dimGrid(2, 2);
+ dim3 dimBlock(2, 2, 2);
+ testKernel<<<dimGrid, dimBlock>>>(10);
+ cudaDeviceSynchronize();
+
+ return EXIT_SUCCESS;
+}
+
diff --git a/tests/projects/cuda_console/xmake.lua b/tests/projects/cuda_console/xmake.lua
new file mode 100644
index 000000000..a1590891e
--- /dev/null
+++ b/tests/projects/cuda_console/xmake.lua
@@ -0,0 +1,23 @@
+-- define target
+target("cuda_console")
+
+ -- set kind
+ set_kind("binary")
+
+ -- add include directories
+ add_includedirs("inc")
+
+ -- add files
+ add_files("src/*.cu")
+
+ -- generate SASS code for each SM architecture
+ for _, sm in ipairs({"30", "35", "37", "50", "52", "60", "61", "70"}) do
+ add_cuflags("-gencode arch=compute_" .. sm .. ",code=sm_" .. sm)
+ add_ldflags("-gencode arch=compute_" .. sm .. ",code=sm_" .. sm)
+ end
+
+ -- generate PTX code from the highest SM architecture to guarantee forward-compatibility
+ sm = "70"
+ add_cuflags("-gencode arch=compute_" .. sm .. ",code=compute_" .. sm)
+ add_ldflags("-gencode arch=compute_" .. sm .. ",code=compute_" .. sm)
+