OpenSubdiv: Refactor, move device specific code to own files

Also, move all device files to own folder.

Makes it so checks for device availability are done in a localized
place.
This commit is contained in:
Sergey Sharybin 2020-05-18 18:16:10 +02:00
parent e490dc4346
commit 7c0bea0d65
16 changed files with 420 additions and 639 deletions

View File

@ -50,11 +50,20 @@ if(WITH_OPENSUBDIV)
)
list(APPEND SRC
internal/device/device_context_cuda.cc
internal/device/device_context_cuda.h
internal/device/device_context_glsl_compute.cc
internal/device/device_context_glsl_compute.h
internal/device/device_context_glsl_transform_feedback.cc
internal/device/device_context_glsl_transform_feedback.h
internal/device/device_context_opencl.cc
internal/device/device_context_opencl.h
internal/device/device_context_openmp.cc
internal/device/device_context_openmp.h
internal/opensubdiv.cc
internal/opensubdiv_converter_factory.cc
internal/opensubdiv_converter_internal.cc
internal/opensubdiv_device_context_cuda.cc
internal/opensubdiv_device_context_opencl.cc
internal/opensubdiv_evaluator.cc
internal/opensubdiv_evaluator_internal.cc
internal/opensubdiv_topology_refiner.cc
@ -63,8 +72,6 @@ if(WITH_OPENSUBDIV)
internal/opensubdiv_converter_factory.h
internal/opensubdiv_converter_internal.h
internal/opensubdiv_device_context_cuda.h
internal/opensubdiv_device_context_opencl.h
internal/opensubdiv_edge_map.h
internal/opensubdiv_evaluator_internal.h
internal/opensubdiv_internal.h
@ -83,10 +90,8 @@ if(WITH_OPENSUBDIV)
endif()
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENMP)
# TODO(sergey): OpenCL is not tested and totally unstable atm.
# OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
# TODO(sergey): CUDA stays disabled for util it's ported to drievr API.
# OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_OPENCL)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_CUDA)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK)
OPENSUBDIV_DEFINE_COMPONENT(OPENSUBDIV_HAS_GLSL_COMPUTE)
@ -97,21 +102,6 @@ if(WITH_OPENSUBDIV)
add_definitions(-DNOMINMAX)
add_definitions(-D_USE_MATH_DEFINES)
endif()
# TODO(sergey): Put CUEW back when CUDA is officially supported by OSD.
# if(OPENSUBDIV_HAS_CUDA)
# list(APPEND INC
# ../../extern/cuew/include
# )
# add_definitions(-DOPENSUBDIV_HAS_CUEW)
# endif()
if(OPENSUBDIV_HAS_OPENCL)
list(APPEND INC
../../extern/clew/include
)
add_definitions(-DOPENSUBDIV_HAS_CLEW)
endif()
else()
list(APPEND SRC
stub/opensubdiv_stub.cc

View File

@ -0,0 +1,39 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/device/device_context_cuda.h"
namespace blender {
namespace opensubdiv {
bool CUDADeviceContext::isSupported()
{
// TODO(sergey): Add CUDA device support, using CUDA-RT API.
return false;
}
CUDADeviceContext::CUDADeviceContext()
{
}
CUDADeviceContext::~CUDADeviceContext()
{
}
} // namespace opensubdiv
} // namespace blender

View File

@ -0,0 +1,38 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_
#define OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_
namespace blender {
namespace opensubdiv {
class CUDADeviceContext {
public:
// Stateless check to see whether CUDA functionality is available on this
// platform.
static bool isSupported();
CUDADeviceContext();
~CUDADeviceContext();
};
} // namespace opensubdiv
} // namespace blender
#endif // _OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_

View File

@ -0,0 +1,40 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/device/device_context_glsl_compute.h"
#include <GL/glew.h>
namespace blender {
namespace opensubdiv {
bool GLSLComputeDeviceContext::isSupported()
{
return GLEW_VERSION_4_3 || GLEW_ARB_compute_shader;
}
GLSLComputeDeviceContext::GLSLComputeDeviceContext()
{
}
GLSLComputeDeviceContext::~GLSLComputeDeviceContext()
{
}
} // namespace opensubdiv
} // namespace blender

View File

@ -0,0 +1,38 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_DEVICE_CONTEXT_GLSL_COMPUTE_H_
#define OPENSUBDIV_DEVICE_CONTEXT_GLSL_COMPUTE_H_
namespace blender {
namespace opensubdiv {
class GLSLComputeDeviceContext {
public:
// Stateless check to see whether GLSL compute functionality is
// available on this platform.
static bool isSupported();
GLSLComputeDeviceContext();
~GLSLComputeDeviceContext();
};
} // namespace opensubdiv
} // namespace blender
#endif // _OPENSUBDIV_DEVICE_CONTEXT_GLSL_COMPUTE_H_

View File

@ -0,0 +1,40 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/device/device_context_glsl_transform_feedback.h"
#include <GL/glew.h>
namespace blender {
namespace opensubdiv {
bool GLSLTransformFeedbackDeviceContext::isSupported()
{
return GLEW_VERSION_4_1;
}
GLSLTransformFeedbackDeviceContext::GLSLTransformFeedbackDeviceContext()
{
}
GLSLTransformFeedbackDeviceContext::~GLSLTransformFeedbackDeviceContext()
{
}
} // namespace opensubdiv
} // namespace blender

View File

@ -0,0 +1,38 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_DEVICE_CONTEXT_GLSL_TRANSFORM_FEEDBACK_H_
#define OPENSUBDIV_DEVICE_CONTEXT_GLSL_TRANSFORM_FEEDBACK_H_
namespace blender {
namespace opensubdiv {
class GLSLTransformFeedbackDeviceContext {
public:
// Stateless check to see whether GLSL transform feedback functionality is
// available on this platform.
static bool isSupported();
GLSLTransformFeedbackDeviceContext();
~GLSLTransformFeedbackDeviceContext();
};
} // namespace opensubdiv
} // namespace blender
#endif // _OPENSUBDIV_DEVICE_CONTEXT_GLSL_TRANSFORM_FEEDBACK_H_

View File

@ -0,0 +1,39 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/device/device_context_opencl.h"
namespace blender {
namespace opensubdiv {
bool OpenCLDeviceContext::isSupported()
{
// TODO(sergey): Add support of OpenCL devices.
return false;
}
OpenCLDeviceContext::OpenCLDeviceContext()
{
}
OpenCLDeviceContext::~OpenCLDeviceContext()
{
}
} // namespace opensubdiv
} // namespace blender

View File

@ -0,0 +1,38 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_
#define OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_
namespace blender {
namespace opensubdiv {
class OpenCLDeviceContext {
public:
// Stateless check to see whether OpenCL functionality is available on this
// platform.
static bool isSupported();
OpenCLDeviceContext();
~OpenCLDeviceContext();
};
} // namespace opensubdiv
} // namespace blender
#endif // _OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_

View File

@ -0,0 +1,42 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#include "internal/device/device_context_openmp.h"
namespace blender {
namespace opensubdiv {
bool OpenMPDeviceContext::isSupported()
{
#ifdef OPENSUBDIV_HAS_OPENMP
return true;
#else
return false;
#endif
}
OpenMPDeviceContext::OpenMPDeviceContext()
{
}
OpenMPDeviceContext::~OpenMPDeviceContext()
{
}
} // namespace opensubdiv
} // namespace blender

View File

@ -0,0 +1,38 @@
// Copyright 2020 Blender Foundation. All rights reserved.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// Author: Sergey Sharybin
#ifndef OPENSUBDIV_DEVICE_CONTEXT_OPENMP_H_
#define OPENSUBDIV_DEVICE_CONTEXT_OPENMP_H_
namespace blender {
namespace opensubdiv {
class OpenMPDeviceContext {
public:
// Stateless check to see whether OpenMP functionality is available on this
// platform.
static bool isSupported();
OpenMPDeviceContext();
~OpenMPDeviceContext();
};
} // namespace opensubdiv
} // namespace blender
#endif // _OPENSUBDIV_DEVICE_CONTEXT_OPENMP_H_

View File

@ -20,10 +20,17 @@
# include <iso646.h>
#endif
#include <GL/glew.h>
#include "internal/device/device_context_cuda.h"
#include "internal/device/device_context_glsl_compute.h"
#include "internal/device/device_context_glsl_transform_feedback.h"
#include "internal/device/device_context_opencl.h"
#include "internal/device/device_context_openmp.h"
#include "opensubdiv_device_context_cuda.h"
#include "opensubdiv_device_context_opencl.h"
using blender::opensubdiv::CUDADeviceContext;
using blender::opensubdiv::GLSLComputeDeviceContext;
using blender::opensubdiv::GLSLTransformFeedbackDeviceContext;
using blender::opensubdiv::OpenCLDeviceContext;
using blender::opensubdiv::OpenMPDeviceContext;
void openSubdiv_init(void)
{
@ -39,33 +46,25 @@ int openSubdiv_getAvailableEvaluators(void)
{
int flags = OPENSUBDIV_EVALUATOR_CPU;
#ifdef OPENSUBDIV_HAS_OPENMP
flags |= OPENSUBDIV_EVALUATOR_OPENMP;
#endif
if (OpenMPDeviceContext::isSupported()) {
flags |= OPENSUBDIV_EVALUATOR_OPENMP;
}
#ifdef OPENSUBDIV_HAS_OPENCL
if (CLDeviceContext::HAS_CL_VERSION_1_1()) {
if (OpenCLDeviceContext::isSupported()) {
flags |= OPENSUBDIV_EVALUATOR_OPENCL;
}
#endif
#ifdef OPENSUBDIV_HAS_CUDA
if (CudaDeviceContext::HAS_CUDA_VERSION_4_0()) {
if (CUDADeviceContext::isSupported()) {
flags |= OPENSUBDIV_EVALUATOR_CUDA;
}
#endif
#ifdef OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK
if (GLEW_VERSION_4_1) {
if (GLSLTransformFeedbackDeviceContext::isSupported()) {
flags |= OPENSUBDIV_EVALUATOR_GLSL_TRANSFORM_FEEDBACK;
}
#endif
#ifdef OPENSUBDIV_HAS_GLSL_COMPUTE
if (GLEW_VERSION_4_3 || GLEW_ARB_compute_shader) {
if (GLSLComputeDeviceContext::isSupported()) {
flags |= OPENSUBDIV_EVALUATOR_GLSL_COMPUTE;
}
#endif
return flags;
}

View File

@ -1,234 +0,0 @@
// Adopted from OpenSubdiv with the following license:
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
#ifdef OPENSUBDIV_HAS_CUDA
# ifdef _MSC_VER
# include <iso646.h>
# endif
# include "opensubdiv_device_context_cuda.h"
# if defined(_WIN32)
# include <windows.h>
# elif defined(__APPLE__)
# include <OpenGL/OpenGL.h>
# else
# include <GL/glx.h>
# include <X11/Xlib.h>
# endif
# include <cstdio>
# include <cuda.h>
# include <cuda_gl_interop.h>
# include <cuda_runtime_api.h>
# include "internal/opensubdiv_util.h"
# define message(fmt, ...)
// #define message(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
# define error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
namespace {
int getCudaDeviceForCurrentGLContext()
{
// Find and use the CUDA device for the current GL context
unsigned int interop_device_count = 0;
int interopDevices[1];
cudaError_t status = cudaGLGetDevices(
&interop_device_count, interopDevices, 1, cudaGLDeviceListCurrentFrame);
if (status == cudaErrorNoDevice || interop_device_count != 1) {
message("CUDA no interop devices found.\n");
return 0;
}
int device = interopDevices[0];
# if defined(_WIN32)
return device;
# elif defined(__APPLE__)
return device;
# else // X11
Display *display = glXGetCurrentDisplay();
int screen = DefaultScreen(display);
if (device != screen) {
error(
"The CUDA interop device (%d) does not match "
"the screen used by the current GL context (%d), "
"which may cause slow performance on systems "
"with multiple GPU devices.",
device,
screen);
}
message("CUDA init using device for current GL context: %d\n", device);
return device;
# endif
}
// Beginning of GPU Architecture definitions.
int convertSMVer2Cores_local(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[] = {{0x10, 8}, // Tesla Generation (SM 1.0) G80 class.
{0x11, 8}, // Tesla Generation (SM 1.1) G8x class.
{0x12, 8}, // Tesla Generation (SM 1.2) G9x class.
{0x13, 8}, // Tesla Generation (SM 1.3) GT200 class.
{0x20, 32}, // Fermi Generation (SM 2.0) GF100 class.
{0x21, 48}, // Fermi Generation (SM 2.1) GF10x class.
{0x30, 192}, // Fermi Generation (SM 3.0) GK10x class.
{-1, -1}};
int index = 0;
while (nGpuArchCoresPerSM[index].SM != -1) {
if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) {
return nGpuArchCoresPerSM[index].Cores;
}
index++;
}
printf("MapSMtoCores undefined SMversion %d.%d!\n", major, minor);
return -1;
}
// This function returns the best GPU (with maximum GFLOPS).
int cutGetMaxGflopsDeviceId()
{
int current_device = 0, sm_per_multiproc = 0;
int max_compute_perf = 0, max_perf_device = -1;
int device_count = 0, best_SM_arch = 0;
int compat_major, compat_minor;
cuDeviceGetCount(&device_count);
// Find the best major SM Architecture GPU device.
while (current_device < device_count) {
cuDeviceComputeCapability(&compat_major, &compat_minor, current_device);
if (compat_major > 0 && compat_major < 9999) {
best_SM_arch = max(best_SM_arch, compat_major);
}
current_device++;
}
// Find the best CUDA capable GPU device.
current_device = 0;
while (current_device < device_count) {
cuDeviceComputeCapability(&compat_major, &compat_minor, current_device);
if (compat_major == 9999 && compat_minor == 9999) {
sm_per_multiproc = 1;
}
else {
sm_per_multiproc = convertSMVer2Cores_local(compat_major, compat_minor);
}
int multi_processor_count;
cuDeviceGetAttribute(
&multi_processor_count, CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT, current_device);
int clock_rate;
cuDeviceGetAttribute(&clock_rate, CU_DEVICE_ATTRIBUTE_CLOCK_RATE, current_device);
int compute_perf = multi_processor_count * sm_per_multiproc * clock_rate;
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 (compat_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;
}
} // namespace
bool CudaDeviceContext::HAS_CUDA_VERSION_4_0()
{
# ifdef OPENSUBDIV_HAS_CUDA
static bool cuda_initialized = false;
static bool cuda_load_success = true;
if (!cuda_initialized) {
cuda_initialized = true;
# ifdef OPENSUBDIV_HAS_CUEW
cuda_load_success = cuewInit(CUEW_INIT_CUDA) == CUEW_SUCCESS;
if (!cuda_load_success) {
fprintf(stderr, "Loading CUDA failed.\n");
}
# endif
// Need to initialize CUDA here so getting device
// with the maximum FPLOS works fine.
if (cuInit(0) == CUDA_SUCCESS) {
// This is to deal with cases like NVidia Optimus,
// when there might be CUDA library installed but
// NVidia card is not being active.
if (cutGetMaxGflopsDeviceId() < 0) {
cuda_load_success = false;
}
}
else {
cuda_load_success = false;
}
}
return cuda_load_success;
# else
return false;
# endif
}
CudaDeviceContext::CudaDeviceContext() : initialized_(false)
{
}
CudaDeviceContext::~CudaDeviceContext()
{
cudaDeviceReset();
}
bool CudaDeviceContext::Initialize()
{
// See if any cuda device is available.
int device_count = 0;
cudaGetDeviceCount(&device_count);
message("CUDA device count: %d\n", device_count);
if (device_count <= 0) {
return false;
}
cudaGLSetGLDevice(getCudaDeviceForCurrentGLContext());
initialized_ = true;
return true;
}
bool CudaDeviceContext::IsInitialized() const
{
return initialized_;
}
#endif // OPENSUBDIV_HAS_CUDA

View File

@ -1,54 +0,0 @@
// Adopted from OpenSubdiv with the following license:
//
// Copyright 2013 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http: //www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
#ifndef OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_
#define OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_
#ifdef OPENSUBDIV_HAS_CUDA
struct ID3D11Device;
class CudaDeviceContext {
public:
CudaDeviceContext();
~CudaDeviceContext();
static bool HAS_CUDA_VERSION_4_0();
// Initialze cuda device from the current GL context.
bool Initialize();
// Initialze cuda device from the ID3D11Device.
bool Initialize(ID3D11Device *device);
// Returns true if the cuda device has already been initialized.
bool IsInitialized() const;
private:
bool initialized_;
};
#endif // OPENSUBDIV_HAS_CUDA
#endif // _OPENSUBDIV_DEVICE_CONTEXT_CUDA_H_

View File

@ -1,258 +0,0 @@
// Adopted from OpenSubdiv with the following license:
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
#include "opensubdiv_device_context_opencl.h"
#ifdef OPENSUBDIV_HAS_OPENCL
# if defined(_WIN32)
# include <windows.h>
# elif defined(__APPLE__)
# include <OpenGL/OpenGL.h>
# else
# include <GL/glx.h>
# endif
# include <cstdio>
# include <cstring>
# include "internal/opensubdiv_util.h"
# define message(...) // fprintf(stderr, __VA_ARGS__)
# define error(...) fprintf(stderr, __VA_ARGS__)
namespace {
// Returns the first found platform.
cl_platform_id findPlatform()
{
cl_uint num_platforms;
cl_int ci_error_number = clGetPlatformIDs(0, NULL, &num_platforms);
if (ci_error_number != CL_SUCCESS) {
error("Error %d in clGetPlatformIDs call.\n", ci_error_number);
return NULL;
}
if (num_platforms == 0) {
error("No OpenCL platform found.\n");
return NULL;
}
vector<cl_platform_id> cl_platform_ids(num_platforms);
ci_error_number = clGetPlatformIDs(num_platforms, &cl_platform_ids[0], NULL);
char ch_buffer[1024];
for (cl_uint i = 0; i < num_platforms; ++i) {
ci_error_number = clGetPlatformInfo(
cl_platform_ids[i], CL_PLATFORM_NAME, sizeof(ch_buffer), ch_buffer, NULL);
if (ci_error_number == CL_SUCCESS) {
cl_platform_id platform_id = cl_platform_ids[i];
return platform_id;
}
}
return NULL;
}
// Return the device in cl_devices which supports the extension.
int findExtensionSupportedDevice(cl_device_id *cl_devices,
int num_devices,
const char *extension_name)
{
// Find a device that supports sharing with GL/D3D11
// (SLI / X-fire configurations)
cl_int cl_error_number;
for (int i = 0; i < num_devices; ++i) {
// Get extensions string size.
size_t extensions_size;
cl_error_number = clGetDeviceInfo(
cl_devices[i], CL_DEVICE_EXTENSIONS, 0, NULL, &extensions_size);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clGetDeviceInfo\n", cl_error_number);
return -1;
}
if (extensions_size > 0) {
// Get extensions string.
string extensions('\0', extensions_size);
cl_error_number = clGetDeviceInfo(
cl_devices[i], CL_DEVICE_EXTENSIONS, extensions_size, &extensions[0], &extensions_size);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clGetDeviceInfo\n", cl_error_number);
continue;
}
// Parse string. This is bit deficient since the extentions
// is space separated.
//
// The actual string would be "cl_khr_d3d11_sharing"
// or "cl_nv_d3d11_sharing"
if (extensions.find(extension_name) != string::npos) {
return i;
}
}
}
return -1;
}
} // namespace
CLDeviceContext::CLDeviceContext() : cl_context_(NULL), cl_command_queue_(NULL)
{
}
CLDeviceContext::~CLDeviceContext()
{
if (cl_command_queue_) {
clReleaseCommandQueue(cl_command_queue_);
}
if (cl_context_) {
clReleaseContext(cl_context_);
}
}
bool CLDeviceContext::HAS_CL_VERSION_1_1()
{
# ifdef OPENSUBDIV_HAS_CLEW
static bool clew_initialized = false;
static bool clew_load_success;
if (!clew_initialized) {
clew_initialized = true;
clew_load_success = clewInit() == CLEW_SUCCESS;
if (!clew_load_success) {
error("Loading OpenCL failed.\n");
}
}
return clew_load_success;
# endif
return true;
}
bool CLDeviceContext::Initialize()
{
# ifdef OPENSUBDIV_HAS_CLEW
if (!clGetPlatformIDs) {
error("Error clGetPlatformIDs function not bound.\n");
return false;
}
# endif
cl_int cl_error_number;
cl_platform_id cp_platform = findPlatform();
# if defined(_WIN32)
cl_context_properties props[] = {
CL_GL_CONTEXT_KHR,
(cl_context_properties)wglGetCurrentContext(),
CL_WGL_HDC_KHR,
(cl_context_properties)wglGetCurrentDC(),
CL_CONTEXT_PLATFORM,
(cl_context_properties)cp_platform,
0,
};
# elif defined(__APPLE__)
CGLContextObj kCGLContext = CGLGetCurrentContext();
CGLShareGroupObj kCGLShareGroup = CGLGetShareGroup(kCGLContext);
cl_context_properties props[] = {
CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, (cl_context_properties)kCGLShareGroup, 0};
# else
cl_context_properties props[] = {
CL_GL_CONTEXT_KHR,
(cl_context_properties)glXGetCurrentContext(),
CL_GLX_DISPLAY_KHR,
(cl_context_properties)glXGetCurrentDisplay(),
CL_CONTEXT_PLATFORM,
(cl_context_properties)cp_platform,
0,
};
# endif
# if defined(__APPLE__)
_clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL, &cl_error_number);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clCreateContext\n", cl_error_number);
return false;
}
size_t devices_size = 0;
clGetGLContextInfoAPPLE(_clContext,
kCGLContext,
CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
0,
NULL,
&devices_size);
const int num_devices = devices_size / sizeof(cl_device_id);
if (num_devices == 0) {
error("No sharable devices.\n");
return false;
}
vector<cl_device_id> cl_devices(num_devices);
clGetGLContextInfoAPPLE(_clContext,
kCGLContext,
CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
num_devices * sizeof(cl_device_id),
&cl_devices[0],
NULL);
int cl_device_used = 0;
# else // not __APPLE__
// Get the number of GPU devices available to the platform.
cl_uint num_devices = 0;
clGetDeviceIDs(cp_platform, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices);
if (num_devices == 0) {
error("No CL GPU device found.\n");
return false;
}
// Create the device list.
vector<cl_device_id> cl_devices(num_devices);
clGetDeviceIDs(cp_platform, CL_DEVICE_TYPE_GPU, num_devices, &cl_devices[0], NULL);
const char *extension = "cl_khr_gl_sharing";
int cl_device_used = findExtensionSupportedDevice(&cl_devices[0], num_devices, extension);
if (cl_device_used < 0) {
error("No device found that supports CL/GL context sharing\n");
return false;
}
cl_context_ = clCreateContext(
props, 1, &cl_devices[cl_device_used], NULL, NULL, &cl_error_number);
# endif // not __APPLE__
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clCreateContext\n", cl_error_number);
return false;
}
cl_command_queue_ = clCreateCommandQueue(
cl_context_, cl_devices[cl_device_used], 0, &cl_error_number);
if (cl_error_number != CL_SUCCESS) {
error("Error %d in clCreateCommandQueue\n", cl_error_number);
return false;
}
return true;
}
bool CLDeviceContext::IsInitialized() const
{
return (cl_context_ != NULL);
}
cl_context CLDeviceContext::GetContext() const
{
return cl_context_;
}
cl_command_queue CLDeviceContext::GetCommandQueue() const
{
return cl_command_queue_;
}
#endif // OPENSUBDIV_HAS_OPENCL

View File

@ -1,52 +0,0 @@
// Adopted from OpenSubdiv with the following license:
//
// Copyright 2015 Pixar
//
// Licensed under the Apache License, Version 2.0 (the "Apache License")
// with the following modification; you may not use this file except in
// compliance with the Apache License and the following modification to it:
// Section 6. Trademarks. is deleted and replaced with:
//
// 6. Trademarks. This License does not grant permission to use the trade
// names, trademarks, service marks, or product names of the Licensor
// and its affiliates, except as required to comply with Section 4(c) of
// the License and to reproduce the content of the NOTICE file.
//
// You may obtain a copy of the Apache License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the Apache License with the above modification is
// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the Apache License for the specific
// language governing permissions and limitations under the Apache License.
#ifndef OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_
#define OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_
#ifdef OPENSUBDIV_HAS_OPENCL
# include <opensubdiv/osd/opencl.h>
class CLDeviceContext {
public:
static bool HAS_CL_VERSION_1_1();
CLDeviceContext();
~CLDeviceContext();
bool Initialize();
bool IsInitialized() const;
cl_context GetContext() const;
cl_command_queue GetCommandQueue() const;
protected:
cl_context cl_context_;
cl_command_queue cl_command_queue_;
};
#endif // OPENSUBDIV_HAS_OPENCL
#endif // _OPENSUBDIV_DEVICE_CONTEXT_OPENCL_H_