diff options
| author | ruki <[email protected]> | 2018-04-15 22:13:08 +0800 |
|---|---|---|
| committer | ruki <[email protected]> | 2018-04-15 22:13:31 +0800 |
| commit | 60c09804728f333500a353610b100a3b59632646 (patch) | |
| tree | ed78422564655949f62f22d917ed70da3d083acb | |
| parent | 6c4f65481bb0df23d34d9e0815ca642804dbb412 (diff) | |
add cuda test
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 + [email protected] 4/2001 +*/ + +#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) + |
