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:
Takahito Tejima 2015-04-29 11:51:12 -07:00
parent 766ed5b316
commit dcb022e1db
10 changed files with 353 additions and 143 deletions

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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;
}

View File

@ -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>

View File

@ -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
View 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

View File

@ -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
View 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;
}