mirror of
https://github.com/NVIDIA/cuda-samples.git
synced 2024-11-28 18:39:16 +08:00
268 lines
11 KiB
C
268 lines
11 KiB
C
|
/* Copyright (c) 2020, 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.
|
||
|
* * Neither the name of NVIDIA CORPORATION nor the names of its
|
||
|
* contributors may be used to endorse or promote products derived
|
||
|
* from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``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 COPYRIGHT OWNER 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.
|
||
|
*/
|
||
|
|
||
|
// 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 <cstdio>
|
||
|
#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);
|
||
|
}
|
||
|
|
||
|
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__)) { \
|
||
|
exit(EXIT_FAILURE); \
|
||
|
}
|
||
|
|
||
|
} /* of namespace __HelperGL*/
|
||
|
|
||
|
using namespace __HelperGL;
|
||
|
|
||
|
#endif /*HELPER_GL_H*/
|