Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/opensubdiv/opensubdiv_device_context_opencl.cc')
-rw-r--r--intern/opensubdiv/opensubdiv_device_context_opencl.cc251
1 files changed, 251 insertions, 0 deletions
diff --git a/intern/opensubdiv/opensubdiv_device_context_opencl.cc b/intern/opensubdiv/opensubdiv_device_context_opencl.cc
new file mode 100644
index 00000000000..4cacdc9e845
--- /dev/null
+++ b/intern/opensubdiv/opensubdiv_device_context_opencl.cc
@@ -0,0 +1,251 @@
+/*
+ * 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_OPENCL
+
+#ifdef _MSC_VER
+# include "iso646.h"
+#endif
+
+#include "opensubdiv_device_context_opencl.h"
+
+#if defined(_WIN32)
+# include <windows.h>
+#elif defined(__APPLE__)
+# include <OpenGL/OpenGL.h>
+#else
+# include <GL/glx.h>
+#endif
+
+#include <cstdio>
+#include <cstring>
+#include <string>
+
+#define message(...) // fprintf(stderr, __VA_ARGS__)
+#define error(...) fprintf(stderr, __VA_ARGS__)
+
+/* Returns the first found platform. */
+static cl_platform_id findPlatform() {
+ cl_uint numPlatforms;
+ cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms);
+ if (ciErrNum != CL_SUCCESS) {
+ error("Error %d in clGetPlatformIDs call.\n", ciErrNum);
+ return NULL;
+ }
+ if (numPlatforms == 0) {
+ error("No OpenCL platform found.\n");
+ return NULL;
+ }
+ cl_platform_id *clPlatformIDs = new cl_platform_id[numPlatforms];
+ ciErrNum = clGetPlatformIDs(numPlatforms, clPlatformIDs, NULL);
+ char chBuffer[1024];
+ for (cl_uint i = 0; i < numPlatforms; ++i) {
+ ciErrNum = clGetPlatformInfo(clPlatformIDs[i], CL_PLATFORM_NAME,
+ 1024, chBuffer,NULL);
+ if (ciErrNum == CL_SUCCESS) {
+ cl_platform_id platformId = clPlatformIDs[i];
+ delete[] clPlatformIDs;
+ return platformId;
+ }
+ }
+ delete[] clPlatformIDs;
+ return NULL;
+}
+
+/* Return. the device in clDevices which supports the extension. */
+static int findExtensionSupportedDevice(cl_device_id *clDevices,
+ int numDevices,
+ const char *extensionName) {
+ /* Find a device that supports sharing with GL/D3D11
+ * (SLI / X-fire configurations)
+ */
+ cl_int ciErrNum;
+ for (int i = 0; i < numDevices; ++i) {
+ /* Get extensions string size. */
+ size_t extensionSize;
+ ciErrNum = clGetDeviceInfo(clDevices[i],
+ CL_DEVICE_EXTENSIONS, 0, NULL,
+ &extensionSize);
+ if (ciErrNum != CL_SUCCESS) {
+ error("Error %d in clGetDeviceInfo\n", ciErrNum);
+ return -1;
+ }
+ if (extensionSize > 0) {
+ /* Get extensions string. */
+ char *extensions = new char[extensionSize];
+ ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS,
+ extensionSize, extensions,
+ &extensionSize);
+ if (ciErrNum != CL_SUCCESS) {
+ error("Error %d in clGetDeviceInfo\n", ciErrNum);
+ delete[] extensions;
+ continue;
+ }
+ std::string extString(extensions);
+ delete[] extensions;
+ /* 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 (extString.find(extensionName) != std::string::npos) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+CLDeviceContext::CLDeviceContext()
+ : _clContext(NULL),
+ _clCommandQueue(NULL) {
+}
+
+CLDeviceContext::~CLDeviceContext() {
+ if (_clCommandQueue)
+ clReleaseCommandQueue(_clCommandQueue);
+ if (_clContext)
+ clReleaseContext(_clContext);
+}
+
+bool CLDeviceContext::HAS_CL_VERSION_1_1()
+{
+#ifdef OPENSUBDIV_HAS_CLEW
+ static bool clewInitialized = false;
+ static bool clewLoadSuccess;
+ if (not clewInitialized) {
+ clewInitialized = true;
+ clewLoadSuccess = clewInit() == CLEW_SUCCESS;
+ if (!clewLoadSuccess) {
+ error("Loading OpenCL failed.\n");
+ }
+ }
+ return clewLoadSuccess;
+#endif
+ return true;
+}
+
+bool CLDeviceContext::Initialize()
+{
+#ifdef OPENSUBDIV_HAS_CLEW
+ if (!clGetPlatformIDs) {
+ error("Error clGetPlatformIDs function not bound.\n");
+ return false;
+ }
+#endif
+ cl_int ciErrNum;
+ cl_platform_id cpPlatform = 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)cpPlatform,
+ 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)cpPlatform,
+ 0
+ };
+#endif
+
+#if defined(__APPLE__)
+ _clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE,
+ NULL, &ciErrNum);
+ if (ciErrNum != CL_SUCCESS) {
+ error("Error %d in clCreateContext\n", ciErrNum);
+ return false;
+ }
+
+ size_t devicesSize = 0;
+ clGetGLContextInfoAPPLE(_clContext, kCGLContext,
+ CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
+ 0, NULL, &devicesSize);
+ int numDevices = int(devicesSize / sizeof(cl_device_id));
+ if (numDevices == 0) {
+ error("No sharable devices.\n");
+ return false;
+ }
+ cl_device_id *clDevices = new cl_device_id[numDevices];
+ clGetGLContextInfoAPPLE(_clContext, kCGLContext,
+ CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
+ numDevices * sizeof(cl_device_id), clDevices, NULL);
+ int clDeviceUsed = 0;
+
+#else // not __APPLE__
+ /* Get the number of GPU devices available to the platform. */
+ cl_uint numDevices = 0;
+ clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
+ if (numDevices == 0) {
+ error("No CL GPU device found.\n");
+ return false;
+ }
+
+ /* Create the device list. */
+ cl_device_id *clDevices = new cl_device_id[numDevices];
+ clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, numDevices, clDevices, NULL);
+
+ const char *extension = "cl_khr_gl_sharing";
+ int clDeviceUsed = findExtensionSupportedDevice(clDevices, numDevices,
+ extension);
+
+ if (clDeviceUsed < 0) {
+ error("No device found that supports CL/GL context sharing\n");
+ delete[] clDevices;
+ return false;
+ }
+
+ _clContext = clCreateContext(props, 1, &clDevices[clDeviceUsed],
+ NULL, NULL, &ciErrNum);
+#endif // not __APPLE__
+ if (ciErrNum != CL_SUCCESS) {
+ error("Error %d in clCreateContext\n", ciErrNum);
+ delete[] clDevices;
+ return false;
+ }
+ _clCommandQueue = clCreateCommandQueue(_clContext, clDevices[clDeviceUsed],
+ 0, &ciErrNum);
+ delete[] clDevices;
+ if (ciErrNum != CL_SUCCESS) {
+ error("Error %d in clCreateCommandQueue\n", ciErrNum);
+ return false;
+ }
+ return true;
+}
+
+#endif /* OPENSUBDIV_HAS_OPENCL */