/* * Copyright (c) Advanced Micro Devices, Inc., or its affiliates. * * SPDX-License-Identifier: MIT */ #include "OCLDX11Common.h" #define D3D_FEATURE_LEVEL_11_1 0xb100 #define INITPFN(x) \ x = (x##_fn)clGetExtensionFunctionAddressForPlatform(platform_, #x); \ if ((x) == NULL) { \ char* buf = (char*)malloc(4096); \ _errorFlag = true; \ int rc = snprintf(buf, 4096, "Failed to get function pointer for %s", #x); \ assert(rc >= 0 && rc < (int)4096); \ printf("%s:%d - %s\n", __FILE__, __LINE__, buf); \ _errorMsg = std::string(buf); \ _crcword += 1; \ free(buf); \ return; \ } OCLDX11Common::OCLDX11Common() : OCLTestImp() { clGetDeviceIDsFromD3D11KHR = NULL; clCreateFromD3D11BufferKHR = NULL; clCreateFromD3D11Texture2DKHR = NULL; clCreateFromD3D11Texture3DKHR = NULL; clEnqueueAcquireD3D11ObjectsKHR = NULL; clEnqueueReleaseD3D11ObjectsKHR = NULL; clGetPlaneFromImageAMD = NULL; } OCLDX11Common::~OCLDX11Common() {} void OCLDX11Common::ExtensionCheck() { cl_int result = CL_SUCCESS; char extensions[1024]; result = _wrapper->clGetPlatformInfo(platform_, CL_PLATFORM_EXTENSIONS, sizeof(extensions), extensions, NULL); CHECK_RESULT(result != CL_SUCCESS, "Failed to list platform extensions."); extensionsAvailable = strstr(extensions, "cl_khr_d3d11_sharing") ? true : false; if (!extensionsAvailable) { printf("cl_khr_d3d11_sharing extension is required for this test!\n"); } OSVERSIONINFOEX versionInfo = {0}; versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); versionInfo.dwMajorVersion = 6; DWORDLONG conditionMask = 0; VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); if (VerifyVersionInfo(&versionInfo, VER_MAJORVERSION, conditionMask)) { CHECK_RESULT(!extensionsAvailable, "Extension should be exported on Windows >= 6"); } else { CHECK_RESULT(extensionsAvailable, "Extension should not be exported on Windows < 6"); } result = _wrapper->clGetDeviceInfo(devices_[_deviceId], CL_DEVICE_EXTENSIONS, sizeof(extensions), extensions, NULL); CHECK_RESULT(result != CL_SUCCESS, "Failed to list device extensions."); extensionsAvailable = strstr(extensions, "cl_amd_planar_yuv") ? true : false; if (!extensionsAvailable) { printf("cl_amd_planar_yuv extension is required for this test!\n"); } } void OCLDX11Common::open(unsigned int test, char* units, double& conversion, unsigned int deviceId) { // OpenCL Initialization // OCLTestImp::open(test, units, conversion, deviceId); BaseTestImp::open(); devices_ = 0; deviceCount_ = 0; context_ = 0; program_ = 0; kernel_ = 0; _queue = 0; _deviceId = deviceId; dxD3D11Context = NULL; dxD3D11Device = NULL; CHECK_RESULT((error_ != CL_SUCCESS), "Error opening test (%d)", error_); cl_uint numPlatforms = 0; error_ = _wrapper->clGetPlatformIDs(0, NULL, &numPlatforms); CHECK_RESULT((error_ != CL_SUCCESS), "clGetPlatformIDs failed"); CHECK_RESULT((numPlatforms == 0), "No platform found"); cl_platform_id* platforms = new cl_platform_id[numPlatforms]; error_ = _wrapper->clGetPlatformIDs(numPlatforms, platforms, NULL); CHECK_RESULT(error_ != CL_SUCCESS, "clGetPlatformIDs failed"); platform_ = platforms[_platformIndex]; CHECK_RESULT((platform_ == 0), "AMD Platform not found"); delete[] platforms; error_ = _wrapper->clGetDeviceIDs(platform_, type_, 0, NULL, &deviceCount_); CHECK_RESULT(error_ != CL_SUCCESS, "clGetDeviceIDs() failed"); devices_ = new cl_device_id[deviceCount_]; error_ = _wrapper->clGetDeviceIDs(platform_, type_, deviceCount_, devices_, NULL); CHECK_RESULT(error_ != CL_SUCCESS, "clGetDeviceIDs() failed"); ExtensionCheck(); if (!extensionsAvailable) { return; } // extract function pointers for exported functions INITPFN(clGetDeviceIDsFromD3D11KHR); INITPFN(clCreateFromD3D11BufferKHR); INITPFN(clCreateFromD3D11Texture2DKHR); INITPFN(clCreateFromD3D11Texture3DKHR); INITPFN(clEnqueueAcquireD3D11ObjectsKHR); INITPFN(clEnqueueReleaseD3D11ObjectsKHR); INITPFN(clGetPlaneFromImageAMD); char name[1024] = {0}; size_t size = 0; if (deviceId >= deviceCount_) { _errorFlag = true; return; } HRESULT hr = S_OK; UINT createDeviceFlags = 0; D3D_FEATURE_LEVEL featureLevels[] = { (D3D_FEATURE_LEVEL)D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0 }; D3D_FEATURE_LEVEL featureLevel; // Create only the device, not the swapchain. We can't create the swapchain // anyways without a handle to a window we explicitly own hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevels, _countof(featureLevels), D3D11_SDK_VERSION, &dxD3D11Device, &featureLevel, &dxD3D11Context); if (FAILED(hr)) { hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevels + 1, _countof(featureLevels) - 1, D3D11_SDK_VERSION, &dxD3D11Device, &featureLevel, &dxD3D11Context); } if (FAILED(hr)) { hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_SOFTWARE, NULL, createDeviceFlags, featureLevels, _countof(featureLevels), D3D11_SDK_VERSION, &dxD3D11Device, &featureLevel, &dxD3D11Context); } if (FAILED(hr)) { hr = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_SOFTWARE, NULL, createDeviceFlags, featureLevels + 1, _countof(featureLevels) - 1, D3D11_SDK_VERSION, &dxD3D11Device, &featureLevel, &dxD3D11Context); } cl_int status = 0; cl_context_properties cps[7] = {CL_CONTEXT_D3D11_DEVICE_KHR, (cl_context_properties)(ID3D11Device*)dxD3D11Device, CL_CONTEXT_INTEROP_USER_SYNC, CL_FALSE, CL_CONTEXT_PLATFORM, (cl_context_properties)platform_, 0}; cl_context_properties* cprops = (NULL == platform_) ? NULL : cps; cl_uint deviceListSize = 0; clGetDeviceIDsFromD3D11KHR(platform_, CL_D3D11_DEVICE_KHR, dxD3D11Device, CL_PREFERRED_DEVICES_FOR_D3D11_KHR, 0, NULL, &deviceListSize); std::vector devices; devices.resize(deviceListSize); clGetDeviceIDsFromD3D11KHR(platform_, CL_D3D11_DEVICE_KHR, dxD3D11Device, CL_PREFERRED_DEVICES_FOR_D3D11_KHR, deviceListSize, &devices[0], NULL); bool ret = false; // Check that current device can be associated with OpenGL context for (unsigned int i = 0; i < deviceListSize; i++) { if (devices[i] == devices_[_deviceId]) { ret = true; break; } } if (ret) { char buf[2000]; _wrapper->clGetDeviceInfo(devices_[deviceId], CL_DEVICE_EXTENSIONS, sizeof(buf), buf, NULL); context_ = clCreateContext(cprops, 1, &devices_[_deviceId], NULL, NULL, &status); _queue = clCreateCommandQueue(context_, devices_[_deviceId], 0, &status); } CHECK_RESULT((ret != true), "Can't find D3D device!"); } unsigned int OCLDX11Common::close(void) { clReleaseCommandQueue(_queue); unsigned int retVal = OCLTestImp::close(); // deleteDXDevice(hDX_); if (dxD3D11Context) dxD3D11Context->Release(); if (dxD3D11Device) dxD3D11Device->Release(); return retVal; }