- fixed GL context crashes for Linux / GLFW 3.0

- refactored CLI arguments parsing
- minor code style cleanups
This commit is contained in:
manuelk 2013-02-06 14:07:47 -08:00
parent 758a788b32
commit c53f973651

View File

@ -125,13 +125,14 @@ enum BackendType {
kBackendCL = 2, // OpenCL kBackendCL = 2, // OpenCL
kBackendCount kBackendCount
}; };
static const char* BACKEND_NAMES[kBackendCount] = {
static const char* g_BackendNames[kBackendCount] = {
"CPU", "CPU",
"CPUGL", "CPUGL",
"CL", "CL",
}; };
static int g_Backend = 0; static int g_Backend = -1;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Vertex class implementation // Vertex class implementation
@ -205,6 +206,7 @@ private:
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
class xyzFV; class xyzFV;
typedef OpenSubdiv::HbrMesh<xyzVV> xyzmesh; typedef OpenSubdiv::HbrMesh<xyzVV> xyzmesh;
typedef OpenSubdiv::HbrFace<xyzVV> xyzface; typedef OpenSubdiv::HbrFace<xyzVV> xyzface;
@ -217,9 +219,11 @@ typedef OpenSubdiv::HbrMesh<OpenSubdiv::OsdVertex> OsdHbrMesh;
typedef OpenSubdiv::HbrVertex<OpenSubdiv::OsdVertex> OsdHbrVertex; typedef OpenSubdiv::HbrVertex<OpenSubdiv::OsdVertex> OsdHbrVertex;
typedef OpenSubdiv::HbrFace<OpenSubdiv::OsdVertex> OsdHbrFace; typedef OpenSubdiv::HbrFace<OpenSubdiv::OsdVertex> OsdHbrFace;
typedef OpenSubdiv::HbrHalfedge<OpenSubdiv::OsdVertex> OsdHbrHalfedge; typedef OpenSubdiv::HbrHalfedge<OpenSubdiv::OsdVertex> OsdHbrHalfedge;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Returns true if a vertex or any of its parents is on a boundary // Returns true if a vertex or any of its parents is on a boundary
bool VertexOnBoundary( xyzvertex const * v ) { bool
VertexOnBoundary( xyzvertex const * v ) {
if (not v) if (not v)
return false; return false;
@ -252,10 +256,9 @@ bool VertexOnBoundary( xyzvertex const * v ) {
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int checkVertexBuffer( xyzmesh * hmesh, int
const float * vbData, checkVertexBuffer( xyzmesh * hmesh, const float * vbData, int numElements, std::vector<int> const & remap) {
int numElements,
std::vector<int> const & remap) {
int count=0; int count=0;
float deltaAvg[3] = {0.0f, 0.0f, 0.0f}, float deltaAvg[3] = {0.0f, 0.0f, 0.0f},
deltaCnt[3] = {0.0f, 0.0f, 0.0f}; deltaCnt[3] = {0.0f, 0.0f, 0.0f};
@ -322,7 +325,8 @@ int checkVertexBuffer( xyzmesh * hmesh,
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
static void refine( xyzmesh * mesh, int maxlevel ) { static void
refine( xyzmesh * mesh, int maxlevel ) {
for (int l=0; l<maxlevel; ++l ) { for (int l=0; l<maxlevel; ++l ) {
int nfaces = mesh->GetNumFaces(); int nfaces = mesh->GetNumFaces();
@ -332,68 +336,86 @@ static void refine( xyzmesh * mesh, int maxlevel ) {
f->Refine(); f->Refine();
} }
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int checkMeshCPU ( static int
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh, checkMeshCPU( OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
const std::vector<float>& coarseverts, const std::vector<float>& coarseverts,
xyzmesh * refmesh, xyzmesh * refmesh,
const std::vector<int>& remap) const std::vector<int>& remap) {
{
static OpenSubdiv::OsdCpuComputeController *controller = new OpenSubdiv::OsdCpuComputeController(); static OpenSubdiv::OsdCpuComputeController *controller = new OpenSubdiv::OsdCpuComputeController();
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh); OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh);
OpenSubdiv::OsdCpuVertexBuffer * vb = OpenSubdiv::OsdCpuVertexBuffer::Create(3, farmesh->GetNumVertices()); OpenSubdiv::OsdCpuVertexBuffer * vb = OpenSubdiv::OsdCpuVertexBuffer::Create(3, farmesh->GetNumVertices());
vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 ); vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 );
controller->Refine( context, vb ); controller->Refine( context, vb );
return checkVertexBuffer(refmesh, vb->BindCpuBuffer(), vb->GetNumElements(), remap); return checkVertexBuffer(refmesh, vb->BindCpuBuffer(), vb->GetNumElements(), remap);
} }
int checkMeshCPUGL ( //------------------------------------------------------------------------------
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh, static int
checkMeshCPUGL( OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
const std::vector<float>& coarseverts, const std::vector<float>& coarseverts,
xyzmesh * refmesh, xyzmesh * refmesh,
const std::vector<int>& remap) const std::vector<int>& remap) {
{
static OpenSubdiv::OsdCpuComputeController *controller = new OpenSubdiv::OsdCpuComputeController(); static OpenSubdiv::OsdCpuComputeController *controller = new OpenSubdiv::OsdCpuComputeController();
OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh); OpenSubdiv::OsdCpuComputeContext *context = OpenSubdiv::OsdCpuComputeContext::Create(farmesh);
OpenSubdiv::OsdCpuGLVertexBuffer * vb = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, farmesh->GetNumVertices()); OpenSubdiv::OsdCpuGLVertexBuffer * vb = OpenSubdiv::OsdCpuGLVertexBuffer::Create(3, farmesh->GetNumVertices());
vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 ); vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3 );
controller->Refine( context, vb ); controller->Refine( context, vb );
return checkVertexBuffer(refmesh, vb->BindCpuBuffer(), vb->GetNumElements(), remap); return checkVertexBuffer(refmesh, vb->BindCpuBuffer(), vb->GetNumElements(), remap);
} }
int checkMeshCL ( //------------------------------------------------------------------------------
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh, static int
checkMeshCL( OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex>* farmesh,
const std::vector<float>& coarseverts, const std::vector<float>& coarseverts,
xyzmesh * refmesh, xyzmesh * refmesh,
const std::vector<int>& remap) const std::vector<int>& remap ) {
{
#ifdef OPENSUBDIV_HAS_OPENCL #ifdef OPENSUBDIV_HAS_OPENCL
static OpenSubdiv::OsdCLComputeController *controller = new OpenSubdiv::OsdCLComputeController(g_clContext, g_clQueue); static OpenSubdiv::OsdCLComputeController *controller = new OpenSubdiv::OsdCLComputeController(g_clContext, g_clQueue);
OpenSubdiv::OsdCLComputeContext *context = OpenSubdiv::OsdCLComputeContext::Create(farmesh, g_clContext); OpenSubdiv::OsdCLComputeContext *context = OpenSubdiv::OsdCLComputeContext::Create(farmesh, g_clContext);
OpenSubdiv::OsdCLGLVertexBuffer * vb = OpenSubdiv::OsdCLGLVertexBuffer::Create(3, farmesh->GetNumVertices(), g_clContext); OpenSubdiv::OsdCLGLVertexBuffer * vb = OpenSubdiv::OsdCLGLVertexBuffer::Create(3, farmesh->GetNumVertices(), g_clContext);
vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3, g_clQueue ); vb->UpdateData( & coarseverts[0], (int)coarseverts.size()/3, g_clQueue );
controller->Refine( context, vb ); controller->Refine( context, vb );
// read data back from CL buffer // read data back from CL buffer
size_t dataSize = vb->GetNumVertices() * vb->GetNumElements(); size_t dataSize = vb->GetNumVertices() * vb->GetNumElements();
float* data = new float[dataSize]; float* data = new float[dataSize];
clEnqueueReadBuffer (g_clQueue, vb->BindCLBuffer(g_clQueue), CL_TRUE, 0, dataSize * sizeof(float), data, 0, NULL, NULL); clEnqueueReadBuffer (g_clQueue, vb->BindCLBuffer(g_clQueue), CL_TRUE, 0, dataSize * sizeof(float), data, 0, NULL, NULL);
int result = checkVertexBuffer(refmesh, data, vb->GetNumElements(), remap); int result = checkVertexBuffer(refmesh, data, vb->GetNumElements(), remap);
delete[] data; delete[] data;
return result; return result;
#else
#else
return 0; return 0;
#endif #endif
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme, int backend ) { static int
checkMesh( char const * msg, char const * shape, int levels, Scheme scheme, int backend ) {
int result =0; int result =0;
@ -408,17 +430,16 @@ int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme,
OsdHbrMesh * hmesh = simpleHbr<OpenSubdiv::OsdVertex>(shape, scheme, coarseverts); OsdHbrMesh * hmesh = simpleHbr<OpenSubdiv::OsdVertex>(shape, scheme, coarseverts);
OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex> *farmesh;
OpenSubdiv::FarMeshFactory<OpenSubdiv::OsdVertex> meshFactory(hmesh, levels); OpenSubdiv::FarMeshFactory<OpenSubdiv::OsdVertex> meshFactory(hmesh, levels);
farmesh = meshFactory.Create(); OpenSubdiv::FarMesh<OpenSubdiv::OsdVertex> * farmesh = meshFactory.Create();
std::vector<int> remap = meshFactory.GetRemappingTable(); std::vector<int> remap = meshFactory.GetRemappingTable();
switch (backend) { switch (backend) {
case kBackendCPU: result = checkMeshCPU(farmesh, coarseverts, refmesh, remap); break; case kBackendCPU : result = checkMeshCPU(farmesh, coarseverts, refmesh, remap); break;
case kBackendCPUGL: result = checkMeshCPUGL(farmesh, coarseverts, refmesh, remap); break; case kBackendCPUGL : result = checkMeshCPUGL(farmesh, coarseverts, refmesh, remap); break;
case kBackendCL: result = checkMeshCL(farmesh, coarseverts, refmesh, remap); break; case kBackendCL : result = checkMeshCL(farmesh, coarseverts, refmesh, remap); break;
} }
delete hmesh; delete hmesh;
@ -426,55 +447,21 @@ int checkMesh( char const * msg, char const * shape, int levels, Scheme scheme,
return result; return result;
} }
//------------------------------------------------------------------------------
static void parseArgs(int argc, char ** argv) {
for (int i=1; i<argc; ++i) {
if (not strcmp(argv[i],"-backend")) {
const char * backend = NULL;
if (i<(argc-1))
backend = argv[++i];
if (not strcmp(backend, "all")) {
g_Backend = -1;
} else {
bool found = false;
for (int i = 0; i < kBackendCount; ++i) {
if (not strcmp(backend, BACKEND_NAMES[i])) {
g_Backend = i;
found = true;
break;
}
}
if (not found) {
printf("-backend : must be 'all' or one of: ");
for (int i = 0; i < kBackendCount; ++i) {
printf("%s ", BACKEND_NAMES[i]);
}
printf("\n");
exit(0);
}
}
}
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int checkBackend(int backend, int levels) { int checkBackend(int backend, int levels) {
printf("*** checking backend : %s\n", BACKEND_NAMES[backend]); printf("*** checking backend : %s\n", g_BackendNames[backend]);
if (backend == kBackendCL) { if (backend == kBackendCL) {
#ifdef OPENSUBDIV_HAS_OPENCL #ifdef OPENSUBDIV_HAS_OPENCL
if (initCL(&g_clContext, &g_clQueue) == false) { if (initCL(&g_clContext, &g_clQueue) == false) {
printf(" Cannot initialize OpenCL, skipping...\n"); printf(" Cannot initialize OpenCL, skipping...\n");
return 0; return 0;
} }
#else #else
printf(" No OpenCL available, skipping...\n"); printf(" No OpenCL available, skipping...\n");
return 0; return 0;
#endif #endif
} }
int total = 0; int total = 0;
@ -670,17 +657,78 @@ int checkBackend(int backend, int levels) {
total += checkMesh( "test_bilinear_cube", bilinear_cube, levels, kBilinear, backend ); total += checkMesh( "test_bilinear_cube", bilinear_cube, levels, kBilinear, backend );
#endif #endif
if (backend == kBackendCL) { if (backend == kBackendCL) {
#ifdef OPENSUBDIV_HAS_OPENCL #ifdef OPENSUBDIV_HAS_OPENCL
uninitCL(g_clContext, g_clQueue); uninitCL(g_clContext, g_clQueue);
#endif #endif
} }
return total; return total;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int main(int argc, char ** argv) { static void
usage(char ** argv) {
printf("%s [<options>]\n\n", argv[0]);
printf(" Options :\n");
printf(" -compute <backend>\n");
printf(" Compute backend applied (");
for (int i=0; i < kBackendCount; ++i)
printf("%s ", g_BackendNames[i]);
printf(").\n");
printf(" -help / -h\n");
printf(" Displays usage information.");
}
//------------------------------------------------------------------------------
static void
parseArgs(int argc, char ** argv) {
for (int i=1; i<argc; ++i) {
if (not strcmp(argv[i],"-compute")) {
const char * backend = NULL;
if (i<(argc-1))
backend = argv[++i];
if (not strcmp(backend, "all")) {
g_Backend = -1;
} else {
bool found = false;
for (int i = 0; i < kBackendCount; ++i) {
if (not strcmp(backend, g_BackendNames[i])) {
g_Backend = i;
found = true;
break;
}
}
if (not found) {
printf("-compute : must be 'all' or one of: ");
for (int i = 0; i < kBackendCount; ++i)
printf("%s ", g_BackendNames[i]);
printf("\n");
exit(0);
}
}
} else if ( (not strcmp(argv[i],"-help")) or
(not strcmp(argv[i],"-h")) ) {
usage(argv);
exit(1);
} else {
usage(argv);
exit(0);
}
}
}
//------------------------------------------------------------------------------
int
main(int argc, char ** argv) {
// Run with no args tests default (CPU) backend. // Run with no args tests default (CPU) backend.
// "-backend all" tests all available backends. // "-backend all" tests all available backends.
@ -699,16 +747,24 @@ int main(int argc, char ** argv) {
#if GLFW_VERSION_MAJOR>=3 #if GLFW_VERSION_MAJOR>=3
if (not (g_window=glfwCreateWindow(width, height, windowTitle, NULL, NULL))) { if (not (g_window=glfwCreateWindow(width, height, windowTitle, NULL, NULL))) {
#else
if (glfwOpenWindow(width, height, 8, 8, 8, 8, 24, 8,GLFW_WINDOW) == GL_FALSE) {
#endif
printf("Failed to open window.\n"); printf("Failed to open window.\n");
glfwTerminate(); glfwTerminate();
return 1; return 1;
} }
glfwMakeContextCurrent(g_window);
#else
if (glfwOpenWindow(width, height, 8, 8, 8, 8, 24, 8,GLFW_WINDOW) == GL_FALSE) {
printf("Failed to open window.\n");
glfwTerminate();
return 1;
}
#endif
#if not defined(__APPLE__) #if not defined(__APPLE__)
glewInit(); if (GLenum r = glewInit() != GLEW_OK) {
printf("Failed to initialize glew. error = %d\n", r);
exit(1);
}
#endif #endif
printf("precision : %f\n",PRECISION); printf("precision : %f\n",PRECISION);