mirror of
https://github.com/PixarAnimationStudios/OpenSubdiv
synced 2024-11-27 05:50:05 +00:00
Fix DX-OpenCL/CUDA interop.
- resolves DX-CL interop functions in Osd::ClD3D11VertexBuffer. - enable CL kernels in DX build. - more cleanup in test harnesses, adding D3D11 initializations into DeviceContext. - add new defines OPENSUBDIV_HAS_OPENGL and OPENSUBDIV_HAS_DX for convenience.
This commit is contained in:
parent
766ed5b316
commit
dcb022e1db
@ -345,6 +345,9 @@ if(NOT NO_PTEX)
|
||||
find_package(PTex 2.0)
|
||||
endif()
|
||||
if (OPENGL_FOUND AND NOT IOS)
|
||||
add_definitions(
|
||||
-DOPENSUBDIV_HAS_OPENGL
|
||||
)
|
||||
if (APPLE)
|
||||
find_package(GLEW)
|
||||
else()
|
||||
@ -353,7 +356,12 @@ if (OPENGL_FOUND AND NOT IOS)
|
||||
endif()
|
||||
|
||||
if (WIN32 AND NOT NO_DX)
|
||||
find_package(DXSDK)
|
||||
find_package(DXSDK)
|
||||
if(DXSDK_FOUND)
|
||||
add_definitions(
|
||||
-DOPENSUBDIV_HAS_DX
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT NO_MAYA)
|
||||
|
@ -36,6 +36,98 @@
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX)
|
||||
#include <D3D11.h>
|
||||
#include <CL/cl_d3d11.h>
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
// returns 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) {
|
||||
}
|
||||
@ -59,7 +151,7 @@ CLDeviceContext::HAS_CL_VERSION_1_1 () {
|
||||
clewInitialized = true;
|
||||
clewLoadSuccess = clewInit() == CLEW_SUCCESS;
|
||||
if (not clewLoadSuccess) {
|
||||
fprintf(stderr, "Loading OpenCL failed.\n");
|
||||
error(stderr, "Loading OpenCL failed.\n");
|
||||
}
|
||||
}
|
||||
return clewLoadSuccess;
|
||||
@ -72,33 +164,13 @@ CLDeviceContext::Initialize() {
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CLEW
|
||||
if (!clGetPlatformIDs) {
|
||||
printf("Error clGetPlatformIDs function not bound.\n");
|
||||
error("Error clGetPlatformIDs function not bound.\n");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
cl_int ciErrNum;
|
||||
|
||||
cl_platform_id cpPlatform = 0;
|
||||
cl_uint num_platforms;
|
||||
ciErrNum = clGetPlatformIDs(0, NULL, &num_platforms);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clGetPlatformIDs call.\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
if (num_platforms == 0) {
|
||||
printf("No OpenCL platform found.\n");
|
||||
return false;
|
||||
}
|
||||
cl_platform_id *clPlatformIDs = new cl_platform_id[num_platforms];
|
||||
ciErrNum = clGetPlatformIDs(num_platforms, clPlatformIDs, NULL);
|
||||
char chBuffer[1024];
|
||||
for (cl_uint i = 0; i < num_platforms; ++i) {
|
||||
ciErrNum = clGetPlatformInfo(clPlatformIDs[i], CL_PLATFORM_NAME, 1024, chBuffer,NULL);
|
||||
if (ciErrNum == CL_SUCCESS) {
|
||||
cpPlatform = clPlatformIDs[i];
|
||||
}
|
||||
}
|
||||
cl_platform_id cpPlatform = findPlatform();
|
||||
|
||||
#if defined(_WIN32)
|
||||
cl_context_properties props[] = {
|
||||
@ -122,33 +194,36 @@ CLDeviceContext::Initialize() {
|
||||
0
|
||||
};
|
||||
#endif
|
||||
delete[] clPlatformIDs;
|
||||
|
||||
int clDeviceUsed = 0;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
_clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE, NULL, &ciErrNum);
|
||||
_clContext = clCreateContext(props, 0, NULL, clLogMessagesToStdoutAPPLE,
|
||||
NULL, &ciErrNum);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clCreateContext\n", ciErrNum);
|
||||
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);
|
||||
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) {
|
||||
printf("No sharable devices.\n");
|
||||
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);
|
||||
#else
|
||||
clGetGLContextInfoAPPLE(_clContext, kCGLContext,
|
||||
CL_CGL_DEVICES_FOR_SUPPORTED_VIRTUAL_SCREENS_APPLE,
|
||||
numDevices * sizeof(cl_device_id), clDevices, NULL);
|
||||
|
||||
#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) {
|
||||
printf("No CL GPU device found.\n");
|
||||
error("No CL GPU device found.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -156,46 +231,77 @@ CLDeviceContext::Initialize() {
|
||||
cl_device_id *clDevices = new cl_device_id[numDevices];
|
||||
clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, numDevices, clDevices, NULL);
|
||||
|
||||
#define GL_SHARING_EXTENSION "cl_khr_gl_sharing"
|
||||
const char *extension = "cl_khr_gl_sharing";
|
||||
int clDeviceUsed = findExtensionSupportedDevice(clDevices, numDevices,
|
||||
extension);
|
||||
|
||||
// find a device that supports sharing with GL (SLI / X-fire configurations)
|
||||
bool sharingSupported=false;
|
||||
for (int i=0; i<(int)numDevices; ++i) {
|
||||
|
||||
size_t extensionSize;
|
||||
ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS, 0, NULL, &extensionSize );
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clGetDeviceInfo\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extensionSize>0) {
|
||||
char* extensions = (char*)malloc(extensionSize);
|
||||
ciErrNum = clGetDeviceInfo(clDevices[i], CL_DEVICE_EXTENSIONS, extensionSize, extensions, &extensionSize);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clGetDeviceInfo\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
std::string stdDevString(extensions);
|
||||
free(extensions);
|
||||
size_t szOldPos = 0, szSpacePos = stdDevString.find(' ', szOldPos); // extensions string is space delimited
|
||||
while (szSpacePos != stdDevString.npos) {
|
||||
if (strcmp(GL_SHARING_EXTENSION,
|
||||
stdDevString.substr(szOldPos, szSpacePos - szOldPos).c_str())==0) {
|
||||
clDeviceUsed = i;
|
||||
sharingSupported = true;
|
||||
break;
|
||||
}
|
||||
do {
|
||||
szOldPos = szSpacePos + 1;
|
||||
szSpacePos = stdDevString.find(' ', szOldPos);
|
||||
} while (szSpacePos == szOldPos);
|
||||
}
|
||||
}
|
||||
if (clDeviceUsed < 0) {
|
||||
error("No device found that supports CL/GL context sharing\n");
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not sharingSupported) {
|
||||
printf("No device found that supports CL/GL context sharing\n");
|
||||
_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;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
CLD3D11DeviceContext::Initialize(ID3D11DeviceContext *d3dDeviceContext) {
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX)
|
||||
_d3dDeviceContext = d3dDeviceContext;
|
||||
|
||||
cl_int ciErrNum;
|
||||
cl_platform_id cpPlatform = findPlatform();
|
||||
|
||||
ID3D11Device *device;
|
||||
d3dDeviceContext->GetDevice(&device);
|
||||
|
||||
cl_context_properties props[] = {
|
||||
CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)device,
|
||||
CL_CONTEXT_PLATFORM, (cl_context_properties)cpPlatform,
|
||||
0
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
// we're cheating a little bit.
|
||||
// try to find both cl_khr_d3d11_sharing and cl_nv_d3d11_sharing.
|
||||
const char *extension = "_d3d11_sharing";
|
||||
int clDeviceUsed = findExtensionSupportedDevice(clDevices, numDevices,
|
||||
extension);
|
||||
|
||||
if (clDeviceUsed < 0) {
|
||||
error("No device found that supports CL/D3D11 context sharing\n");
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
@ -203,19 +309,21 @@ CLDeviceContext::Initialize() {
|
||||
_clContext = clCreateContext(props, 1, &clDevices[clDeviceUsed],
|
||||
NULL, NULL, &ciErrNum);
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clCreateContext\n", ciErrNum);
|
||||
error("Error %d in clCreateContext\n", ciErrNum);
|
||||
delete[] clDevices;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
_clCommandQueue = clCreateCommandQueue(_clContext, clDevices[clDeviceUsed],
|
||||
0, &ciErrNum);
|
||||
delete[] clDevices;
|
||||
if (ciErrNum != CL_SUCCESS) {
|
||||
printf("Error %d in clCreateCommandQueue\n", ciErrNum);
|
||||
error("Error %d in clCreateCommandQueue\n", ciErrNum);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
(void)d3dDeviceContext; // unused
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -47,11 +47,24 @@ public:
|
||||
return _clCommandQueue;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
cl_context _clContext;
|
||||
cl_command_queue _clCommandQueue;
|
||||
};
|
||||
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
class CLD3D11DeviceContext : public CLDeviceContext {
|
||||
public:
|
||||
bool Initialize(ID3D11DeviceContext *deviceContext);
|
||||
|
||||
ID3D11DeviceContext *GetDeviceContext() const {
|
||||
return _d3dDeviceContext;
|
||||
}
|
||||
|
||||
private:
|
||||
ID3D11DeviceContext *_d3dDeviceContext;
|
||||
};
|
||||
|
||||
|
||||
#endif // OSD_EXAMPLES_COMMON_CL_DEVICE_CONTEXT_H
|
||||
|
@ -38,6 +38,10 @@
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_gl_interop.h>
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX)
|
||||
#include <cuda_d3d11_interop.h>
|
||||
#endif
|
||||
|
||||
#define message(fmt, ...)
|
||||
//#define message(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
|
||||
#define error(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
|
||||
@ -135,3 +139,15 @@ CudaDeviceContext::Initialize() {
|
||||
_initialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CudaDeviceContext::Initialize(ID3D11Device *device) {
|
||||
|
||||
#if defined(OPENSUBDIV_HAS_DX)
|
||||
cudaD3D11SetDirect3DDevice(device);
|
||||
return true;
|
||||
#else
|
||||
(void)device; // unused
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
@ -25,13 +25,20 @@
|
||||
#ifndef OSD_EXAMPLES_COMMON_CUDA_DEVICE_CONTEXT_H
|
||||
#define OSD_EXAMPLES_COMMON_CUDA_DEVICE_CONTEXT_H
|
||||
|
||||
struct ID3D11Device;
|
||||
|
||||
class CudaDeviceContext {
|
||||
public:
|
||||
CudaDeviceContext();
|
||||
~CudaDeviceContext();
|
||||
|
||||
/// 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 {
|
||||
return _initialized;
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ include_directories("${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
_add_possibly_cuda_executable(dxPtexViewer WIN32
|
||||
"${SOURCE_FILES}"
|
||||
"${SHADER_FILES}"
|
||||
"${INC_FILES}"
|
||||
$<TARGET_OBJECTS:regression_common_obj>
|
||||
$<TARGET_OBJECTS:regression_vtr_utils_obj>
|
||||
|
@ -41,22 +41,14 @@ OpenSubdiv::Osd::CpuComputeController * g_cpuComputeController = NULL;
|
||||
OpenSubdiv::Osd::OmpComputeController * g_ompComputeController = NULL;
|
||||
#endif
|
||||
|
||||
#undef OPENSUBDIV_HAS_OPENCL // XXX: dyu OpenCL D3D11 interop needs work...
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
#include <osd/clD3D11VertexBuffer.h>
|
||||
#include <osd/clComputeContext.h>
|
||||
#include <osd/clComputeController.h>
|
||||
|
||||
#include "../common/clInit.h"
|
||||
#include "../common/clDeviceContext.h"
|
||||
|
||||
struct CLContext {
|
||||
cl_context GetContext() const { return clContext; }
|
||||
cl_command_queue GetCommandQueue() const { return clQueue; }
|
||||
cl_context clContext;
|
||||
cl_command_queue clQueue;
|
||||
ID3D11DeviceContext *pd3dDeviceContext;
|
||||
};
|
||||
CLContext g_clContext;
|
||||
CLD3D11DeviceContext g_clDeviceContext;
|
||||
OpenSubdiv::Osd::CLComputeController * g_clComputeController = NULL;
|
||||
#endif
|
||||
|
||||
@ -65,10 +57,9 @@ OpenSubdiv::Osd::CpuComputeController * g_cpuComputeController = NULL;
|
||||
#include <osd/cudaComputeContext.h>
|
||||
#include <osd/cudaComputeController.h>
|
||||
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_d3d11_interop.h>
|
||||
#include "../common/cudaDeviceContext.h"
|
||||
|
||||
bool g_cudaInitialized = false;
|
||||
CudaDeviceContext g_cudaDeviceContext;
|
||||
OpenSubdiv::Osd::CudaComputeController * g_cudaComputeController = NULL;
|
||||
#endif
|
||||
|
||||
@ -695,6 +686,8 @@ createOsdMesh(int level, int kernel) {
|
||||
OpenSubdiv::Osd::MeshBitset bits;
|
||||
bits.set(OpenSubdiv::Osd::MeshAdaptive, doAdaptive);
|
||||
bits.set(OpenSubdiv::Osd::MeshPtexData, true);
|
||||
// gregory basis hasn't supported yet in D3D11Mesh
|
||||
bits.set(OpenSubdiv::Osd::MeshEndCapLegacyGregory, true);
|
||||
|
||||
int numVertexElements = 6; //g_adaptive ? 3 : 6;
|
||||
int numVaryingElements = 0;
|
||||
@ -731,17 +724,18 @@ createOsdMesh(int level, int kernel) {
|
||||
} else if (kernel == kCL) {
|
||||
if (not g_clComputeController) {
|
||||
g_clComputeController = new OpenSubdiv::Osd::CLComputeController(
|
||||
g_clContext.clContext, g_clContext.clQueue);
|
||||
g_clDeviceContext.GetContext(),
|
||||
g_clDeviceContext.GetCommandQueue());
|
||||
}
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CLD3D11VertexBuffer,
|
||||
OpenSubdiv::Osd::CLComputeController,
|
||||
OpenSubdiv::Osd::D3D11DrawContext,
|
||||
CLContext>(
|
||||
CLD3D11DeviceContext>(
|
||||
g_clComputeController,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits, &g_clContext);
|
||||
level, bits, &g_clDeviceContext);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
} else if (kernel == kCUDA) {
|
||||
@ -1137,12 +1131,10 @@ quit() {
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
delete g_clComputeController;
|
||||
uninitCL(g_clContext.clContext, g_clContext.clQueue);
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
delete g_cudaComputeController;
|
||||
cudaDeviceReset();
|
||||
#endif
|
||||
|
||||
delete g_d3d11ComputeController;
|
||||
@ -1179,18 +1171,19 @@ callbackKernel(int k) {
|
||||
g_kernel = k;
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
if (g_kernel == kCL and g_clContext.clContext == NULL) {
|
||||
if (initCL(&g_clContext.clContext, &g_clContext.clQueue) == false) {
|
||||
if (g_kernel == kCL and (not g_clDeviceContext.IsInitialized())) {
|
||||
if (g_clDeviceContext.Initialize(g_pd3dDeviceContext) == false) {
|
||||
printf("Error in initializing OpenCL\n");
|
||||
exit(1);
|
||||
}
|
||||
g_clContext.pd3dDeviceContext = g_pd3dDeviceContext;
|
||||
}
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
if (g_kernel == kCUDA and g_cudaInitialized == false) {
|
||||
g_cudaInitialized = true;
|
||||
cudaD3D11SetDirect3DDevice( g_pd3dDevice );
|
||||
if (g_kernel == kCUDA and (not g_cudaDeviceContext.IsInitialized())) {
|
||||
if (g_cudaDeviceContext.Initialize(g_pd3dDevice) == false) {
|
||||
printf("Error in initializing Cuda\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1288,7 +1281,7 @@ initHUD() {
|
||||
g_hud->AddRadioButton(0, "CUDA", false, 10, 50, callbackKernel, kCUDA, 'K');
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
if (HAS_CL_VERSION_1_1()) {
|
||||
if (CLDeviceContext::HAS_CL_VERSION_1_1()) {
|
||||
g_hud->AddRadioButton(0, "OPENCL", false, 10, 70, callbackKernel, kCL, 'K');
|
||||
}
|
||||
#endif
|
||||
|
44
examples/dxViewer/dxviewer.cpp
Executable file → Normal file
44
examples/dxViewer/dxviewer.cpp
Executable file → Normal file
@ -45,25 +45,14 @@ OpenSubdiv::Osd::CpuComputeController * g_cpuComputeController = NULL;
|
||||
OpenSubdiv::Osd::TbbComputeController *g_tbbComputeController = NULL;
|
||||
#endif
|
||||
|
||||
#undef OPENSUBDIV_HAS_OPENCL // XXX: dyu OpenCL D3D11 interop needs work...
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
#include <osd/clD3D11VertexBuffer.h>
|
||||
#include <osd/clComputeContext.h>
|
||||
#include <osd/clComputeController.h>
|
||||
|
||||
#include "../common/clInit.h"
|
||||
|
||||
struct CLContext {
|
||||
cl_context GetContext() const { return clContext; }
|
||||
cl_command_queue GetCommandQueue() const { return clQueue; }
|
||||
ID3D11DeviceContext *GetDeviceContext() const { return pd3dDeviceContext; }
|
||||
|
||||
cl_context clContext;
|
||||
cl_command_queue clQueue;
|
||||
ID3D11DeviceContext *pd3dDeviceContext;
|
||||
};
|
||||
CLContext g_clContext;
|
||||
#include "../common/clDeviceContext.h"
|
||||
|
||||
CLD3D11DeviceContext g_clDeviceContext;
|
||||
OpenSubdiv::Osd::CLComputeController * g_clComputeController = NULL;
|
||||
#endif
|
||||
|
||||
@ -72,10 +61,9 @@ OpenSubdiv::Osd::CpuComputeController * g_cpuComputeController = NULL;
|
||||
#include <osd/cudaComputeContext.h>
|
||||
#include <osd/cudaComputeController.h>
|
||||
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <cuda_d3d11_interop.h>
|
||||
#include "../common/cudaDeviceContext.h"
|
||||
|
||||
bool g_cudaInitialized = false;
|
||||
CudaDeviceContext g_cudaDeviceContext;
|
||||
OpenSubdiv::Osd::CudaComputeController * g_cudaComputeController = NULL;
|
||||
#endif
|
||||
|
||||
@ -385,18 +373,19 @@ createOsdMesh(ShapeDesc const & shapeDesc, int level, int kernel, Scheme scheme=
|
||||
} else if(kernel == kCL) {
|
||||
if (not g_clComputeController) {
|
||||
g_clComputeController = new OpenSubdiv::Osd::CLComputeController(
|
||||
g_clContext.clContext, g_clContext.clQueue);
|
||||
g_clDeviceContext.GetContext(),
|
||||
g_clDeviceContext.GetCommandQueue());
|
||||
}
|
||||
g_mesh = new OpenSubdiv::Osd::Mesh<OpenSubdiv::Osd::CLD3D11VertexBuffer,
|
||||
OpenSubdiv::Osd::CLComputeController,
|
||||
OpenSubdiv::Osd::D3D11DrawContext,
|
||||
CLContext>(
|
||||
CLD3D11DeviceContext>(
|
||||
g_clComputeController,
|
||||
refiner,
|
||||
numVertexElements,
|
||||
numVaryingElements,
|
||||
level, bits,
|
||||
&g_clContext);
|
||||
&g_clDeviceContext);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
} else if (g_kernel == kCUDA) {
|
||||
@ -1019,12 +1008,10 @@ quit() {
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
delete g_clComputeController;
|
||||
uninitCL(g_clContext.clContext, g_clContext.clQueue);
|
||||
#endif
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
delete g_cudaComputeController;
|
||||
cudaDeviceReset();
|
||||
#endif
|
||||
|
||||
delete g_d3d11ComputeController;
|
||||
@ -1061,18 +1048,19 @@ callbackKernel(int k) {
|
||||
g_kernel = k;
|
||||
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
if (g_kernel == kCL and g_clContext.clContext == NULL) {
|
||||
if (initCL(&g_clContext.clContext, &g_clContext.clQueue) == false) {
|
||||
if (g_kernel == kCL and (not g_clDeviceContext.IsInitialized())) {
|
||||
if (g_clDeviceContext.Initialize(g_pd3dDeviceContext) == false) {
|
||||
printf("Error in initializing OpenCL\n");
|
||||
exit(1);
|
||||
}
|
||||
g_clContext.pd3dDeviceContext = g_pd3dDeviceContext;
|
||||
}
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_CUDA
|
||||
if (g_kernel == kCUDA and g_cudaInitialized == false) {
|
||||
g_cudaInitialized = true;
|
||||
cudaD3D11SetDirect3DDevice( g_pd3dDevice );
|
||||
if (g_kernel == kCUDA and (not g_cudaDeviceContext.IsInitialized())) {
|
||||
if (g_cudaDeviceContext.Initialize(g_pd3dDevice) == false) {
|
||||
printf("Error in initializing Cuda\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1184,7 +1172,7 @@ initHUD() {
|
||||
g_hud->AddPullDownButton(compute_pulldown, "CUDA", kCUDA);
|
||||
#endif
|
||||
#ifdef OPENSUBDIV_HAS_OPENCL
|
||||
if (HAS_CL_VERSION_1_1()) {
|
||||
if (CLDeviceContext::HAS_CL_VERSION_1_1()) {
|
||||
g_hud->AddPullDownButton(compute_pulldown, "OpenCL", kCL);
|
||||
}
|
||||
#endif
|
||||
|
@ -322,15 +322,14 @@ if ( OPENCL_FOUND )
|
||||
list(APPEND PUBLIC_HEADER_FILES clGLVertexBuffer.h)
|
||||
endif()
|
||||
|
||||
# OpenCL D3D11 interop needs work...
|
||||
#if ( DXSDK_FOUND )
|
||||
# list(APPEND GPU_SOURCE_FILES
|
||||
# clD3D11VertexBuffer.cpp
|
||||
# )
|
||||
# list(APPEND PUBLIC_HEADER_FILES
|
||||
# clD3D11VertexBuffer.h)
|
||||
# )
|
||||
#endif()
|
||||
if ( DXSDK_FOUND )
|
||||
list(APPEND GPU_SOURCE_FILES
|
||||
clD3D11VertexBuffer.cpp
|
||||
)
|
||||
list(APPEND PUBLIC_HEADER_FILES
|
||||
clD3D11VertexBuffer.h
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND DOXY_HEADER_FILES ${OPENCL_PUBLIC_HEADERS})
|
||||
|
87
opensubdiv/osd/clD3D11VertexBuffer.cpp
Normal file → Executable file
87
opensubdiv/osd/clD3D11VertexBuffer.cpp
Normal file → Executable file
@ -35,6 +35,51 @@ namespace OPENSUBDIV_VERSION {
|
||||
|
||||
namespace Osd {
|
||||
|
||||
static clCreateFromD3D11BufferKHR_fn clCreateFromD3D11Buffer = NULL;
|
||||
static clEnqueueAcquireD3D11ObjectsKHR_fn clEnqueueAcquireD3D11Objects = NULL;
|
||||
static clEnqueueReleaseD3D11ObjectsKHR_fn clEnqueueReleaseD3D11Objects = NULL;
|
||||
|
||||
// XXX: clGetExtensionFunctionAddress is marked as deprecated and
|
||||
// clGetExtensionFunctionAddressForPlatform should be used,
|
||||
// however it requires OpenCL 1.2.
|
||||
// until we bump the requirement to 1.2, mute the deprecated warning.
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable: 4996)
|
||||
#endif
|
||||
|
||||
|
||||
static void resolveInteropFunctions() {
|
||||
|
||||
if (not clCreateFromD3D11Buffer) {
|
||||
clCreateFromD3D11Buffer =
|
||||
(clCreateFromD3D11BufferKHR_fn)
|
||||
clGetExtensionFunctionAddress("clCreateFromD3D11BufferKHR");
|
||||
}
|
||||
if (not clCreateFromD3D11Buffer) {
|
||||
clCreateFromD3D11Buffer =
|
||||
(clCreateFromD3D11BufferKHR_fn)
|
||||
clGetExtensionFunctionAddress("clCreateFromD3D11BufferNV");
|
||||
}
|
||||
|
||||
if (not clEnqueueAcquireD3D11Objects) {
|
||||
clEnqueueAcquireD3D11Objects = (clEnqueueAcquireD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddress("clEnqueueAcquireD3D11ObjectsKHR");
|
||||
}
|
||||
if (not clEnqueueAcquireD3D11Objects) {
|
||||
clEnqueueAcquireD3D11Objects = (clEnqueueAcquireD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddress("clEnqueueAcquireD3D11ObjectsNV");
|
||||
}
|
||||
|
||||
if (not clEnqueueReleaseD3D11Objects) {
|
||||
clEnqueueReleaseD3D11Objects = (clEnqueueReleaseD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddress("clEnqueueReleaseD3D11ObjectsKHR");
|
||||
}
|
||||
if (not clEnqueueReleaseD3D11Objects) {
|
||||
clEnqueueReleaseD3D11Objects = (clEnqueueReleaseD3D11ObjectsKHR_fn)
|
||||
clGetExtensionFunctionAddress("clEnqueueReleaseD3D11ObjectsNV");
|
||||
}
|
||||
}
|
||||
|
||||
CLD3D11VertexBuffer::CLD3D11VertexBuffer(int numElements, int numVertices)
|
||||
: _numElements(numElements), _numVertices(numVertices),
|
||||
_d3d11Buffer(NULL), _clMemory(NULL), _clQueue(NULL), _clMapped(false) {
|
||||
@ -73,6 +118,18 @@ CLD3D11VertexBuffer::UpdateData(const float *src, int startVertex,
|
||||
clEnqueueWriteBuffer(queue, _clMemory, true, offset, size, src, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
CLD3D11VertexBuffer::GetNumElements() const {
|
||||
|
||||
return _numElements;
|
||||
}
|
||||
|
||||
int
|
||||
CLD3D11VertexBuffer::GetNumVertices() const {
|
||||
|
||||
return _numVertices;
|
||||
}
|
||||
|
||||
cl_mem
|
||||
CLD3D11VertexBuffer::BindCLBuffer(cl_command_queue queue) {
|
||||
|
||||
@ -105,9 +162,17 @@ CLD3D11VertexBuffer::allocate(cl_context clContext, ID3D11Device *device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not clCreateFromD3D11Buffer) {
|
||||
resolveInteropFunctions();
|
||||
if (not clCreateFromD3D11Buffer) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// register d3d11buffer as cl memory
|
||||
cl_int err;
|
||||
_clMemory = clCreateFromD3D11BufferKHR(clContext, CL_MEM_READ_WRITE, _d3d11Buffer, &err);
|
||||
|
||||
_clMemory = clCreateFromD3D11Buffer(clContext, CL_MEM_READ_WRITE, _d3d11Buffer, &err);
|
||||
|
||||
if (err != CL_SUCCESS) return false;
|
||||
return true;
|
||||
@ -118,15 +183,29 @@ CLD3D11VertexBuffer::map(cl_command_queue queue) {
|
||||
|
||||
if (_clMapped) return;
|
||||
_clQueue = queue;
|
||||
clEnqueueAcquireD3D11ObjectsKHR(queue, 1, &_clMemory, 0, 0, 0);
|
||||
|
||||
if (not clEnqueueAcquireD3D11Objects) {
|
||||
resolveInteropFunctions();
|
||||
if (not clEnqueueAcquireD3D11Objects) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
clEnqueueAcquireD3D11Objects(queue, 1, &_clMemory, 0, 0, 0);
|
||||
_clMapped = true;
|
||||
}
|
||||
|
||||
void
|
||||
CLD3D11VertexBuffer::unmap() {
|
||||
|
||||
|
||||
if (not _clMapped) return;
|
||||
clEnqueueReleaseD3D11ObjectsKHR(_clQueue, 1, &_clMemory, 0, 0, 0);
|
||||
if (not clEnqueueReleaseD3D11Objects) {
|
||||
resolveInteropFunctions();
|
||||
if (not clEnqueueReleaseD3D11Objects) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
clEnqueueReleaseD3D11Objects(_clQueue, 1, &_clMemory, 0, 0, 0);
|
||||
_clMapped = false;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user