diff --git a/projects/clr/hipamd/src/CMakeLists.txt b/projects/clr/hipamd/src/CMakeLists.txt index c1346d4277..2578c610a0 100644 --- a/projects/clr/hipamd/src/CMakeLists.txt +++ b/projects/clr/hipamd/src/CMakeLists.txt @@ -95,7 +95,6 @@ if(NOT WIN32) endif() target_sources(amdhip64 PRIVATE - cl_gl.cpp fixme.cpp hip_activity.cpp hip_code_object.cpp @@ -127,9 +126,6 @@ target_sources(amdhip64 PRIVATE if(WIN32) target_sources(amdhip64 PRIVATE - cl_d3d9.cpp - cl_d3d10.cpp - cl_d3d11.cpp hip_runtime.cpp) endif() diff --git a/projects/clr/hipamd/src/cl_d3d10.cpp b/projects/clr/hipamd/src/cl_d3d10.cpp deleted file mode 100644 index 692b26cb7e..0000000000 --- a/projects/clr/hipamd/src/cl_d3d10.cpp +++ /dev/null @@ -1,1450 +0,0 @@ -/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. */ - -#ifdef _WIN32 - -#include "top.hpp" - -#include "cl_common.hpp" -#include "cl_d3d10_amd.hpp" -#include "platform/command.hpp" - -#include -#include - - -/*! \addtogroup API - * @{ - * - * \addtogroup CL_D3D10_Interops - * - * This section discusses OpenCL functions that allow applications to use Direct3D 10 - * resources (buffers/textures) as OpenCL memory objects. This allows efficient sharing of - * data between OpenCL and Direct3D 10. The OpenCL API can be used to execute kernels that - * read and/or write memory objects that are also the Direct3D resources. - * An OpenCL image object can be created from a D3D10 texture object. An - * OpenCL buffer object can be created from a D3D10 buffer object (index/vertex). - * - * @} - * \addtogroup clGetDeviceIDsFromD3D10KHR - * @{ - */ - -RUNTIME_ENTRY(cl_int, clGetDeviceIDsFromD3D10KHR, - (cl_platform_id platform, cl_d3d10_device_source_khr d3d_device_source, - void* d3d_object, cl_d3d10_device_set_khr d3d_device_set, cl_uint num_entries, - cl_device_id* devices, cl_uint* num_devices)) { - cl_int errcode; - ID3D10Device* d3d10_device = NULL; - cl_device_id* gpu_devices; - cl_uint num_gpu_devices = 0; - bool create_d3d10Device = false; - static const bool VALIDATE_ONLY = true; - HMODULE d3d10Module = NULL; - - if (platform != NULL && platform != AMD_PLATFORM) { - LogWarning("\"platrform\" is not a valid AMD platform"); - return CL_INVALID_PLATFORM; - } - if (((num_entries > 0 || num_devices == NULL) && devices == NULL) || - (num_entries == 0 && devices != NULL)) { - return CL_INVALID_VALUE; - } - // Get GPU devices - errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 0, NULL, &num_gpu_devices); - if (errcode != CL_SUCCESS && errcode != CL_DEVICE_NOT_FOUND) { - return CL_INVALID_VALUE; - } - - if (!num_gpu_devices) { - *not_null(num_devices) = 0; - return CL_DEVICE_NOT_FOUND; - } - - switch (d3d_device_source) { - case CL_D3D10_DEVICE_KHR: - d3d10_device = static_cast(d3d_object); - break; - case CL_D3D10_DXGI_ADAPTER_KHR: { - typedef HRESULT(WINAPI * LPD3D10CREATEDEVICE)(IDXGIAdapter*, D3D10_DRIVER_TYPE, HMODULE, UINT, - UINT32, ID3D10Device**); - static LPD3D10CREATEDEVICE dynamicD3D10CreateDevice = NULL; - - d3d10Module = LoadLibrary("D3D10.dll"); - if (d3d10Module == NULL) { - return CL_INVALID_PLATFORM; - } - - dynamicD3D10CreateDevice = - (LPD3D10CREATEDEVICE)GetProcAddress(d3d10Module, "D3D10CreateDevice"); - - IDXGIAdapter* dxgi_adapter = static_cast(d3d_object); - HRESULT hr = dynamicD3D10CreateDevice(dxgi_adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, 0, - D3D10_SDK_VERSION, &d3d10_device); - if (SUCCEEDED(hr) && (NULL != d3d10_device)) { - create_d3d10Device = true; - } else { - FreeLibrary(d3d10Module); - return CL_INVALID_VALUE; - } - } break; - default: - LogWarning("\"d3d_device_source\" is invalid"); - return CL_INVALID_VALUE; - } - - switch (d3d_device_set) { - case CL_PREFERRED_DEVICES_FOR_D3D10_KHR: - case CL_ALL_DEVICES_FOR_D3D10_KHR: { - gpu_devices = (cl_device_id*)alloca(num_gpu_devices * sizeof(cl_device_id)); - - errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, num_gpu_devices, gpu_devices, NULL); - if (errcode != CL_SUCCESS) { - break; - } - - void* external_device[amd::Context::DeviceFlagIdx::LastDeviceFlagIdx] = {}; - external_device[amd::Context::DeviceFlagIdx::D3D10DeviceKhrIdx] = d3d10_device; - - std::vector compatible_devices; - for (cl_uint i = 0; i < num_gpu_devices; ++i) { - cl_device_id device = gpu_devices[i]; - if (is_valid(device) && - as_amd(device)->bindExternalDevice(amd::Context::Flags::D3D10DeviceKhr, external_device, - NULL, VALIDATE_ONLY)) { - compatible_devices.push_back(as_amd(device)); - } - } - if (compatible_devices.size() == 0) { - *not_null(num_devices) = 0; - errcode = CL_DEVICE_NOT_FOUND; - break; - } - - auto it = compatible_devices.cbegin(); - cl_uint compatible_count = std::min(num_entries, (cl_uint)compatible_devices.size()); - - while (compatible_count--) { - *devices++ = as_cl(*it++); - --num_entries; - } - while (num_entries--) { - *devices++ = (cl_device_id)0; - } - - *not_null(num_devices) = (cl_uint)compatible_devices.size(); - } break; - - default: - LogWarning("\"d3d_device_set\" is invalid"); - errcode = CL_INVALID_VALUE; - } - - if (create_d3d10Device) { - d3d10_device->Release(); - FreeLibrary(d3d10Module); - } - return errcode; -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromD3D10BufferKHR - * @{ - */ - -/*! \brief Creates an OpenCL buffer object from a Direct3D 10 resource. - * - * \param context is a valid OpenCL context. - * - * \param flags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param pD3DResource is a valid pointer to a D3D10 resource of type ID3D10Buffer. - * - * \return valid non-zero OpenCL buffer object and \a errcode_ret is set - * to CL_SUCCESS if the buffer object is created successfully. It returns a NULL - * value with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a context is not a valid context or if Direct3D 10 - * interoperatbility has not been initialized between context and the ID3D10Device - * from which pD3DResource was created. - * - CL_INVALID_VALUE if values specified in \a clFlags are not valid. - * - CL_INVALID_D3D_RESOURCE if \a pD3DResource is not of type ID3D10Buffer. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r33? - */ - -RUNTIME_ENTRY_RET(cl_mem, clCreateFromD3D10BufferKHR, - (cl_context context, cl_mem_flags flags, ID3D10Buffer* pD3DResource, - cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - if (!flags) flags = CL_MEM_READ_WRITE; - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - if (!pD3DResource) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("parameter \"pD3DResource\" is a NULL pointer"); - return clMemObj; - } - return ( - amd::clCreateBufferFromD3D10ResourceAMD(*as_amd(context), flags, pD3DResource, errcode_ret)); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateImageFromD3D10Resource - * @{ - */ - -/*! \brief Create an OpenCL 2D or 3D image object from a D3D10 resource. - * - * \param context is a valid OpenCL context. - * - * \param flags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param pD3DResource is a valid pointer to a D3D10 resource of type - * ID3D10Texture2D, ID3D10Texture2D, or ID3D10Texture3D. - * If pD3DResource is of type ID3D10Texture1D then the created image object - * will be a 1D mipmapped image object. - * If pD3DResource is of type ID3D10Texture2D and was not created with flag - * D3D10_RESOURCE_MISC_TEXTURECUBE then the created image object will be a - * 2D mipmapped image object. - * If pD3DResource is of type ID3D10Texture2D and was created with flag - * D3D10_RESOURCE_MISC_TEXTURECUBE then the created image object will be - * a cubemap mipmapped image object. - * errocde_ret returns CL_INVALID_D3D_RESOURCE if an OpenCL memory object has - * already been created from pD3DResource in context. - * If pD3DResource is of type ID3D10Texture3D then the created image object will - * be a 3D mipmapped imageobject. - * - * \return valid non-zero OpenCL image object and \a errcode_ret is set - * to CL_SUCCESS if the image object is created successfully. It returns a NULL - * value with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a context is not a valid context or if Direct3D 10 - * interoperatbility has not been initialized between context and the ID3D10Device - * from which pD3DResource was created. - * - CL_INVALID_VALUE if values specified in \a flags are not valid. - * - CL_INVALID_D3D_RESOURCE if \a pD3DResource is not of type ID3D10Texture1D, - * ID3D10Texture2D, or ID3D10Texture3D. - * - CL_INVALID_D3D_RESOURCE if an OpenCL memory object has already been created - * from \a pD3DResource in context. - * - CL_INVALID_IMAGE_FORMAT if the Direct3D 10 texture format does not map - * to an appropriate OpenCL image format. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r48? - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateImageFromD3D10Resource, - (cl_context context, cl_mem_flags flags, ID3D10Resource* pD3DResource, - UINT subresource, int* errcode_ret, UINT dimension)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - if (!flags) flags = CL_MEM_READ_WRITE; - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - if (!pD3DResource) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("parameter \"pD3DResource\" is a NULL pointer"); - return clMemObj; - } - - // Verify context init'ed for interop - ID3D10Device* pDev; - pD3DResource->GetDevice(&pDev); - if (pDev == NULL) { - *not_null(errcode_ret) = CL_INVALID_D3D10_DEVICE_KHR; - LogWarning("Cannot retrieve D3D10 device from D3D10 resource"); - return (cl_mem)0; - } - pDev->Release(); - if (!((*as_amd(context)).info().flags_ & amd::Context::D3D10DeviceKhr)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from D3D10 device"); - return (cl_mem)0; - } - - // Check for image support - const std::vector& devices = as_amd(context)->devices(); - bool supportPass = false; - for (const auto& it : devices) { - if (it->info().imageSupport_) { - supportPass = true; - } - } - if (!supportPass) { - *not_null(errcode_ret) = CL_INVALID_OPERATION; - LogWarning("there are no devices in context to support images"); - return (cl_mem)0; - } - - switch (dimension) { -#if 0 - case 1: - return(amd::clCreateImage1DFromD3D10ResourceAMD( - *as_amd(context), - flags, - pD3DResource, - subresource, - errcode_ret)); -#endif // 0 - case 2: - return (amd::clCreateImage2DFromD3D10ResourceAMD(*as_amd(context), flags, pD3DResource, - subresource, errcode_ret)); - case 3: - return (amd::clCreateImage3DFromD3D10ResourceAMD(*as_amd(context), flags, pD3DResource, - subresource, errcode_ret)); - default: - break; - } - - *not_null(errcode_ret) = CL_INVALID_D3D10_RESOURCE_KHR; - return (cl_mem)0; -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromD3D10Texture2DKHR - * @{ - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromD3D10Texture2DKHR, - (cl_context context, cl_mem_flags flags, ID3D10Texture2D* resource, - UINT subresource, cl_int* errcode_ret)) { - return clCreateImageFromD3D10Resource(context, flags, resource, subresource, errcode_ret, 2); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromD3D10Texture3DKHR - * @{ - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromD3D10Texture3DKHR, - (cl_context context, cl_mem_flags flags, ID3D10Texture3D* resource, - UINT subresource, cl_int* errcode_ret)) { - return clCreateImageFromD3D10Resource(context, flags, resource, subresource, errcode_ret, 3); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clEnqueueAcquireD3D10ObjectsKHR - * @{ - */ -RUNTIME_ENTRY(cl_int, clEnqueueAcquireD3D10ObjectsKHR, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueAcquireExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_ACQUIRE_D3D10_OBJECTS_KHR); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clEnqueueReleaseD3D10ObjectsKHR - * @{ - */ -RUNTIME_ENTRY(cl_int, clEnqueueReleaseD3D10ObjectsKHR, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueReleaseExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_RELEASE_D3D10_OBJECTS_KHR); -} -RUNTIME_EXIT - - -// -// -// namespace amd -// -// -namespace amd { -/*! @} - * \addtogroup CL-D3D10 interop helper functions - * @{ - */ - - -//******************************************************************* -// -// Internal implementation of CL API functions -// -//******************************************************************* -// -// clCreateBufferFromD3D10ResourceAMD -// -cl_mem clCreateBufferFromD3D10ResourceAMD(Context& amdContext, cl_mem_flags flags, - ID3D10Resource* pD3DResource, int* errcode_ret) { - // Verify pD3DResource is a buffer - D3D10_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if (rType != D3D10_RESOURCE_DIMENSION_BUFFER) { - *not_null(errcode_ret) = CL_INVALID_D3D10_RESOURCE_KHR; - return (cl_mem)0; - } - - D3D10Object obj; - int errcode = D3D10Object::initD3D10Object(amdContext, pD3DResource, 0, obj); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - BufferD3D10* pBufferD3D10 = new (amdContext) BufferD3D10(amdContext, flags, obj); - if (!pBufferD3D10) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pBufferD3D10->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pBufferD3D10->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pBufferD3D10); -} -#if 0 -// There is no support for 1D images in the base imagee code -// -// clCreateImage1DFromD3D10ResourceAMD -// -cl_mem clCreateImage1DFromD3D10ResourceAMD( - Context& amdContext, - cl_mem_flags flags, - ID3D10Resource* pD3DResource, - UINT subresource, - int* errcode_ret) -{ - - // Verify the resource is a 1D texture - D3D10_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if(rType != D3D10_RESOURCE_DIMENSION_TEXTURE1D) { - *not_null(errcode_ret) = CL_INVALID_D3D10_RESOURCE_KHR; - return (cl_mem) 0; - } - - D3D10Object obj; - int errcode = D3D10Object::initD3D10Object(pD3DResource, subresource, obj); - if(CL_SUCCESS != errcode) - { - *not_null(errcode_ret) = errcode; - return (cl_mem) 0; - } - - Image1DD3D10 *pImage1DD3D10 = new Image1DD3D10(amdContext, flags, obj); - if(!pImage1DD3D10) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem) 0; - } - if (!pImage1DD3D10->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImage1DD3D10->release(); - return (cl_mem) 0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImage1DD3D10); -} -#endif - -// -// clCreateImage2DFromD3D10ResourceAMD -// -cl_mem clCreateImage2DFromD3D10ResourceAMD(Context& amdContext, cl_mem_flags flags, - ID3D10Resource* pD3DResource, UINT subresource, - int* errcode_ret) { - // Verify the resource is a 2D texture - D3D10_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if (rType != D3D10_RESOURCE_DIMENSION_TEXTURE2D) { - *not_null(errcode_ret) = CL_INVALID_D3D10_RESOURCE_KHR; - return (cl_mem)0; - } - - D3D10Object obj; - int errcode = D3D10Object::initD3D10Object(amdContext, pD3DResource, subresource, obj); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - Image2DD3D10* pImage2DD3D10 = new (amdContext) Image2DD3D10(amdContext, flags, obj); - if (!pImage2DD3D10) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pImage2DD3D10->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImage2DD3D10->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImage2DD3D10); -} - -// -// clCreateImage2DFromD3D10ResourceAMD -// -cl_mem clCreateImage3DFromD3D10ResourceAMD(Context& amdContext, cl_mem_flags flags, - ID3D10Resource* pD3DResource, UINT subresource, - int* errcode_ret) { - // Verify the resource is a 2D texture - D3D10_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if (rType != D3D10_RESOURCE_DIMENSION_TEXTURE3D) { - *not_null(errcode_ret) = CL_INVALID_D3D10_RESOURCE_KHR; - return (cl_mem)0; - } - - D3D10Object obj; - int errcode = D3D10Object::initD3D10Object(amdContext, pD3DResource, subresource, obj); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - Image3DD3D10* pImage3DD3D10 = new (amdContext) Image3DD3D10(amdContext, flags, obj); - if (!pImage3DD3D10) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pImage3DD3D10->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImage3DD3D10->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImage3DD3D10); -} - -// -// Helper function SyncD3D10Objects -// -void SyncD3D10Objects(std::vector& memObjects) { - Memory*& mem = memObjects.front(); - if (!mem) { - LogWarning("\nNULL memory object\n"); - return; - } - InteropObject* interop = mem->getInteropObj(); - if (!interop) { - LogWarning("\nNULL interop object\n"); - return; - } - D3D10Object* d3d10Obj = interop->asD3D10Object(); - if (!d3d10Obj) { - LogWarning("\nNULL D3D10 object\n"); - return; - } - ID3D10Query* query = d3d10Obj->getQuery(); - if (!query) { - LogWarning("\nNULL ID3D10Query\n"); - return; - } - query->End(); - BOOL data = FALSE; - while (S_OK != query->GetData(&data, sizeof(BOOL), 0)) { - } -} - -// -// Class D3D10Object implementation -// -size_t D3D10Object::getElementBytes(DXGI_FORMAT dxgiFmt) { - size_t bytesPerPixel; - - switch (dxgiFmt) { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - bytesPerPixel = 16; - break; - - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - bytesPerPixel = 12; - break; - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - bytesPerPixel = 8; - break; - - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - bytesPerPixel = 4; - break; - - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - bytesPerPixel = 2; - break; - - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - case DXGI_FORMAT_R1_UNORM: - bytesPerPixel = 1; - break; - - - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - // Less than 1 byte per pixel - needs special consideration - bytesPerPixel = 0; - break; - - default: - bytesPerPixel = 0; - _ASSERT(FALSE); - break; - } - return bytesPerPixel; -} - -cl_image_format D3D10Object::getCLFormatFromDXGI(DXGI_FORMAT dxgiFmt) { - cl_image_format fmt; - - //! @todo [odintsov]: add real fmt conversion from DXGI to CL - fmt.image_channel_order = 0; // CL_RGBA; - fmt.image_channel_data_type = 0; // CL_UNSIGNED_INT8; - - switch (dxgiFmt) { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R32G32B32A32_FLOAT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32G32B32A32_UINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32B32A32_SINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32B32_TYPELESS: - fmt.image_channel_order = CL_RGB; - break; - - case DXGI_FORMAT_R32G32B32_FLOAT: - fmt.image_channel_order = CL_RGB; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32G32B32_UINT: - fmt.image_channel_order = CL_RGB; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32B32_SINT: - fmt.image_channel_order = CL_RGB; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case DXGI_FORMAT_R16G16B16A16_UNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16G16B16A16_UINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNSIGNED_INT16; - break; - - case DXGI_FORMAT_R16G16B16A16_SNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SNORM_INT16; - break; - - case DXGI_FORMAT_R16G16B16A16_SINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SIGNED_INT16; - break; - - case DXGI_FORMAT_R32G32_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_R32G32_FLOAT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32G32_UINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32_SINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R32G8X24_TYPELESS: - break; - - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - break; - - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - break; - - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - break; - - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R10G10B10A2_UNORM: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R10G10B10A2_UINT: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R11G11B10_FLOAT: - fmt.image_channel_order = CL_RGB; - break; - - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R8G8B8A8_UNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_UINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_SNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SNORM_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_SINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SIGNED_INT8; - break; - - case DXGI_FORMAT_R16G16_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_R16G16_FLOAT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case DXGI_FORMAT_R16G16_UNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16G16_UINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNSIGNED_INT16; - break; - - case DXGI_FORMAT_R16G16_SNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SNORM_INT16; - break; - - case DXGI_FORMAT_R16G16_SINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SIGNED_INT16; - break; - - case DXGI_FORMAT_R32_TYPELESS: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_D32_FLOAT: - break; - - case DXGI_FORMAT_R32_FLOAT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32_UINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32_SINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R24G8_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_D24_UNORM_S8_UINT: - break; - - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - break; - - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - break; - - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - break; - - case DXGI_FORMAT_R8G8_B8G8_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_G8R8_G8B8_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_B8G8R8A8_UNORM: - fmt.image_channel_order = CL_BGRA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_B8G8R8X8_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_R8G8_UNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8_UINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - break; - - case DXGI_FORMAT_R8G8_SNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SNORM_INT8; - break; - - case DXGI_FORMAT_R8G8_SINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SIGNED_INT8; - break; - - case DXGI_FORMAT_R16_TYPELESS: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_R16_FLOAT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case DXGI_FORMAT_D16_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16_UNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16_UINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT16; - break; - - case DXGI_FORMAT_R16_SNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SNORM_INT16; - break; - - case DXGI_FORMAT_R16_SINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SIGNED_INT16; - break; - - case DXGI_FORMAT_B5G6R5_UNORM: - fmt.image_channel_data_type = CL_UNORM_SHORT_565; - break; - - case DXGI_FORMAT_B5G5R5A1_UNORM: - fmt.image_channel_order = CL_BGRA; - break; - - case DXGI_FORMAT_R8_TYPELESS: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_R8_UNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8_UINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - break; - - case DXGI_FORMAT_R8_SNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SNORM_INT8; - break; - - case DXGI_FORMAT_R8_SINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SIGNED_INT8; - break; - - case DXGI_FORMAT_A8_UNORM: - fmt.image_channel_order = CL_A; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R1_UNORM: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - break; - - default: - _ASSERT(FALSE); - break; - } - - return fmt; -} - -size_t D3D10Object::getResourceByteSize() { - size_t bytes = 1; - - //! @todo [odintsov]: take into consideration the mip level?! - - switch (objDesc_.objDim_) { - case D3D10_RESOURCE_DIMENSION_BUFFER: - bytes = objDesc_.objSize_.ByteWidth; - break; - - case D3D10_RESOURCE_DIMENSION_TEXTURE3D: - bytes = objDesc_.objSize_.Depth; - - case D3D10_RESOURCE_DIMENSION_TEXTURE2D: - bytes *= objDesc_.objSize_.Height; - - case D3D10_RESOURCE_DIMENSION_TEXTURE1D: - bytes *= objDesc_.objSize_.Width * getElementBytes(); - break; - - default: - LogError("getResourceByteSize: unknown type of D3D10 resource"); - bytes = 0; - break; - } - return bytes; -} - -int D3D10Object::initD3D10Object(const Context& amdContext, ID3D10Resource* pRes, UINT subres, - D3D10Object& obj) { - ID3D10Device* pDev; - HRESULT hr; - ScopedLock sl(resLock_); - - // Check if this ressource has already been used for interop - for (const auto& it : resources_) { - if (it.first == (void*)pRes && it.second == subres) { - return CL_INVALID_D3D10_RESOURCE_KHR; - } - } - - (obj.pD3D10Res_ = pRes)->GetDevice(&pDev); - - if (!pDev) { - return CL_INVALID_D3D10_DEVICE_KHR; - } - - D3D10_QUERY_DESC desc = {D3D10_QUERY_EVENT, 0}; - pDev->CreateQuery(&desc, &obj.pQuery_); - -#define SET_SHARED_FLAGS() \ - { \ - obj.pD3D10ResOrig_ = obj.pD3D10Res_; \ - memcpy(&obj.objDescOrig_, &obj.objDesc_, sizeof(D3D10ObjDesc_t)); \ - /* @todo - Check device type and select right usage for resource */ \ - /* For now get only DPU path, CPU path for buffers */ \ - /* will not worl on DEFAUL resources */ \ - /*desc.Usage = D3D10_USAGE_STAGING;*/ \ - desc.Usage = D3D10_USAGE_DEFAULT; \ - desc.MiscFlags = D3D10_RESOURCE_MISC_SHARED; \ - desc.CPUAccessFlags = 0; \ - } - -#define STORE_SHARED_FLAGS(restype) \ - { \ - if (S_OK == hr && obj.pD3D10Res_) { \ - obj.objDesc_.objFlags_.d3d10Usage_ = desc.Usage; \ - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; \ - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; \ - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; \ - } else { \ - LogError("\nCannot create shared " #restype "\n"); \ - return CL_INVALID_D3D10_RESOURCE_KHR; \ - } \ - } - -#define SET_BINDING() \ - { \ - switch (desc.Format) { \ - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: \ - case DXGI_FORMAT_D32_FLOAT: \ - case DXGI_FORMAT_D24_UNORM_S8_UINT: \ - case DXGI_FORMAT_D16_UNORM: \ - desc.BindFlags = D3D10_BIND_DEPTH_STENCIL; \ - break; \ - default: \ - desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET; \ - break; \ - } \ - } - - pRes->GetType(&obj.objDesc_.objDim_); - - // Init defaults - obj.objDesc_.objSize_.Height = 1; - obj.objDesc_.objSize_.Depth = 1; - obj.objDesc_.mipLevels_ = 1; - obj.objDesc_.arraySize_ = 1; - obj.objDesc_.dxgiFormat_ = DXGI_FORMAT_UNKNOWN; - obj.objDesc_.dxgiSampleDesc_ = dxgiSampleDescDefault; - - switch (obj.objDesc_.objDim_) { - case D3D10_RESOURCE_DIMENSION_BUFFER: // = 1, - { - D3D10_BUFFER_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - obj.objDesc_.objSize_.ByteWidth = desc.ByteWidth; - obj.objDesc_.objFlags_.d3d10Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - // Handle D3D10Buffer without shared handle - create - // a duplicate with shared handle to provide for CAL - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D10_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - desc.BindFlags = D3D10_BIND_SHADER_RESOURCE | D3D10_BIND_RENDER_TARGET; - hr = pDev->CreateBuffer(&desc, NULL, (ID3D10Buffer**)&obj.pD3D10Res_); - STORE_SHARED_FLAGS(ID3D10Buffer); - } - } break; - - case D3D10_RESOURCE_DIMENSION_TEXTURE1D: // = 2, - { - D3D10_TEXTURE1D_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - - if (subres) { - // Calculate correct size of the subresource - UINT miplevel = subres; - if (desc.ArraySize > 1) { - miplevel = subres % desc.ArraySize; - } - if (miplevel >= desc.MipLevels) { - LogWarning("\nMiplevel >= number of miplevels\n"); - } - if (subres >= desc.MipLevels * desc.ArraySize) { - return CL_INVALID_VALUE; - } - desc.Width >>= miplevel; - if (!desc.Width) { - desc.Width = 1; - } - } - obj.objDesc_.objSize_.Width = desc.Width; - obj.objDesc_.mipLevels_ = desc.MipLevels; - obj.objDesc_.arraySize_ = desc.ArraySize; - obj.objDesc_.dxgiFormat_ = desc.Format; - obj.objDesc_.objFlags_.d3d10Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - // Handle D3D10Texture1D without shared handle - create - // a duplicate with shared handle and provide it for CAL - // Workaround for subresource > 0 in shared resource - if (subres) obj.objDesc_.objFlags_.miscFlags_ &= ~(D3D10_RESOURCE_MISC_SHARED); - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D10_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - SET_BINDING(); - obj.objDesc_.mipLevels_ = desc.MipLevels = 1; - obj.objDesc_.arraySize_ = desc.ArraySize = 1; - hr = pDev->CreateTexture1D(&desc, NULL, (ID3D10Texture1D**)&obj.pD3D10Res_); - STORE_SHARED_FLAGS(ID3D10Texture1D); - } - } break; - - case D3D10_RESOURCE_DIMENSION_TEXTURE2D: // = 3, - { - D3D10_TEXTURE2D_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - - if (subres) { - // Calculate correct size of the subresource - UINT miplevel = subres; - if (desc.ArraySize > 1) { - miplevel = subres % desc.MipLevels; - } - if (miplevel >= desc.MipLevels) { - LogWarning("\nMiplevel >= number of miplevels\n"); - } - if (subres >= desc.MipLevels * desc.ArraySize) { - return CL_INVALID_VALUE; - } - desc.Width >>= miplevel; - if (!desc.Width) { - desc.Width = 1; - } - desc.Height >>= miplevel; - if (!desc.Height) { - desc.Height = 1; - } - } - obj.objDesc_.objSize_.Width = desc.Width; - obj.objDesc_.objSize_.Height = desc.Height; - obj.objDesc_.mipLevels_ = desc.MipLevels; - obj.objDesc_.arraySize_ = desc.ArraySize; - obj.objDesc_.dxgiFormat_ = desc.Format; - obj.objDesc_.dxgiSampleDesc_ = desc.SampleDesc; - obj.objDesc_.objFlags_.d3d10Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - // Handle D3D10Texture2D without shared handle - create - // a duplicate with shared handle and provide it for CAL - // Workaround for subresource > 0 in shared resource - if (subres) obj.objDesc_.objFlags_.miscFlags_ &= ~(D3D10_RESOURCE_MISC_SHARED); - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D10_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - SET_BINDING(); - obj.objDesc_.mipLevels_ = desc.MipLevels = 1; - obj.objDesc_.arraySize_ = desc.ArraySize = 1; - hr = pDev->CreateTexture2D(&desc, NULL, (ID3D10Texture2D**)&obj.pD3D10Res_); - STORE_SHARED_FLAGS(ID3D10Texture2D); - } - } break; - - case D3D10_RESOURCE_DIMENSION_TEXTURE3D: // = 4 - { - D3D10_TEXTURE3D_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - - if (subres) { - // Calculate correct size of the subresource - UINT miplevel = subres; - if (miplevel >= desc.MipLevels) { - LogWarning("\nMiplevel >= number of miplevels\n"); - } - if (subres >= desc.MipLevels) { - return CL_INVALID_VALUE; - } - desc.Width >>= miplevel; - if (!desc.Width) { - desc.Width = 1; - } - desc.Height >>= miplevel; - if (!desc.Height) { - desc.Height = 1; - } - desc.Depth >>= miplevel; - if (!desc.Depth) { - desc.Depth = 1; - } - } - obj.objDesc_.objSize_.Width = desc.Width; - obj.objDesc_.objSize_.Height = desc.Height; - obj.objDesc_.objSize_.Depth = desc.Depth; - obj.objDesc_.mipLevels_ = desc.MipLevels; - obj.objDesc_.dxgiFormat_ = desc.Format; - obj.objDesc_.objFlags_.d3d10Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - // Handle D3D10Texture3D without shared handle - create - // a duplicate with shared handle and provide it for CAL - // Workaround for subresource > 0 in shared resource - if (obj.objDesc_.mipLevels_ > 1) - obj.objDesc_.objFlags_.miscFlags_ &= ~(D3D10_RESOURCE_MISC_SHARED); - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D10_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - SET_BINDING(); - obj.objDesc_.mipLevels_ = desc.MipLevels = 1; - hr = pDev->CreateTexture3D(&desc, NULL, (ID3D10Texture3D**)&obj.pD3D10Res_); - STORE_SHARED_FLAGS(ID3D10Texture3D); - } - } break; - - default: - LogError("unknown type of D3D10 resource"); - return CL_INVALID_D3D10_RESOURCE_KHR; - } - obj.subRes_ = subres; - pDev->Release(); - // Check for CL format compatibilty - if (obj.objDesc_.objDim_ != D3D10_RESOURCE_DIMENSION_BUFFER) { - cl_image_format clFmt = obj.getCLFormatFromDXGI(obj.objDesc_.dxgiFormat_); - amd::Image::Format imageFormat(clFmt); - if (!imageFormat.isSupported(amdContext)) { - return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - } - } - resources_.push_back({pRes, subres}); - return CL_SUCCESS; -} - -bool D3D10Object::copyOrigToShared() { - // Don't copy if there is no orig - if (NULL == getD3D10ResOrig()) return true; - - ID3D10Device* d3dDev; - pD3D10Res_->GetDevice(&d3dDev); - if (!d3dDev) { - LogError("\nCannot get D3D10 device from D3D10 resource\n"); - return false; - } - // Any usage source can be read by GPU - d3dDev->CopySubresourceRegion(pD3D10Res_, 0, 0, 0, 0, pD3D10ResOrig_, subRes_, NULL); - - // Flush D3D queues and make sure D3D stuff is finished - d3dDev->Flush(); - pQuery_->End(); - BOOL data = FALSE; - while ((S_OK != pQuery_->GetData(&data, sizeof(BOOL), 0)) || (data != TRUE)) { - } - - d3dDev->Release(); - return true; -} - -bool D3D10Object::copySharedToOrig() { - // Don't copy if there is no orig - if (NULL == getD3D10ResOrig()) return true; - - ID3D10Device* d3dDev; - pD3D10Res_->GetDevice(&d3dDev); - if (!d3dDev) { - LogError("\nCannot get D3D10 device from D3D10 resource\n"); - return false; - } - - d3dDev->CopySubresourceRegion(pD3D10ResOrig_, subRes_, 0, 0, 0, pD3D10Res_, 0, NULL); - - d3dDev->Release(); - return true; -} - -std::vector> D3D10Object::resources_; -Monitor D3D10Object::resLock_; - -// -// Class BufferD3D10 implementation -// -void BufferD3D10::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(BufferD3D10)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -// -// Class Image1DD3D10 implementation -// - -void Image1DD3D10::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(Image1DD3D10)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -// -// Class Image2DD3D10 implementation -// - -void Image2DD3D10::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(Image2DD3D10)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -// -// Class Image3DD3D10 implementation -// -void Image3DD3D10::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(Image3DD3D10)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -} // namespace amd - -#endif //_WIN32 diff --git a/projects/clr/hipamd/src/cl_d3d11.cpp b/projects/clr/hipamd/src/cl_d3d11.cpp deleted file mode 100644 index 9ad60cd2ab..0000000000 --- a/projects/clr/hipamd/src/cl_d3d11.cpp +++ /dev/null @@ -1,1570 +0,0 @@ -/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. */ - -#ifdef _WIN32 - -#include "top.hpp" - -#include "cl_d3d11_amd.hpp" -#include "platform/command.hpp" - -#include -#include - -/*! \addtogroup API - * @{ - * - * \addtogroup CL_D3D11_Interops - * - * This section discusses OpenCL functions that allow applications to use Direct3D 11 - * resources (buffers/textures) as OpenCL memory objects. This allows efficient sharing of - * data between OpenCL and Direct3D 11. The OpenCL API can be used to execute kernels that - * read and/or write memory objects that are also the Direct3D resources. - * An OpenCL image object can be created from a D3D11 texture object. An - * OpenCL buffer object can be created from a D3D11 buffer object (index/vertex). - * - * @} - * \addtogroup clGetDeviceIDsFromD3D11KHR - * @{ - */ - -RUNTIME_ENTRY(cl_int, clGetDeviceIDsFromD3D11KHR, - (cl_platform_id platform, cl_d3d11_device_source_khr d3d_device_source, - void* d3d_object, cl_d3d11_device_set_khr d3d_device_set, cl_uint num_entries, - cl_device_id* devices, cl_uint* num_devices)) { - cl_int errcode; - ID3D11Device* d3d11_device = NULL; - cl_device_id* gpu_devices; - cl_uint num_gpu_devices = 0; - bool create_d3d11Device = false; - static const bool VALIDATE_ONLY = true; - HMODULE d3d11Module = NULL; - - if (platform != NULL && platform != AMD_PLATFORM) { - LogWarning("\"platrform\" is not a valid AMD platform"); - return CL_INVALID_PLATFORM; - } - if (((num_entries > 0 || num_devices == NULL) && devices == NULL) || - (num_entries == 0 && devices != NULL)) { - return CL_INVALID_VALUE; - } - // Get GPU devices - errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 0, NULL, &num_gpu_devices); - if (errcode != CL_SUCCESS && errcode != CL_DEVICE_NOT_FOUND) { - return CL_INVALID_VALUE; - } - - if (!num_gpu_devices) { - *not_null(num_devices) = 0; - return CL_DEVICE_NOT_FOUND; - } - - switch (d3d_device_source) { - case CL_D3D11_DEVICE_KHR: - d3d11_device = static_cast(d3d_object); - break; - case CL_D3D11_DXGI_ADAPTER_KHR: { - static PFN_D3D11_CREATE_DEVICE dynamicD3D11CreateDevice = NULL; - - d3d11Module = LoadLibrary("D3D11.dll"); - if (d3d11Module == NULL) { - return CL_INVALID_PLATFORM; - } - - dynamicD3D11CreateDevice = - (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11Module, "D3D11CreateDevice"); - - IDXGIAdapter* dxgi_adapter = static_cast(d3d_object); - D3D_FEATURE_LEVEL requestedFeatureLevels[] = {D3D_FEATURE_LEVEL_10_0}; - D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; - HRESULT hr = dynamicD3D11CreateDevice(dxgi_adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, - requestedFeatureLevels, 1, D3D11_SDK_VERSION, - &d3d11_device, &featureLevel, NULL); - if (SUCCEEDED(hr) && (NULL != d3d11_device)) { - create_d3d11Device = true; - } else { - FreeLibrary(d3d11Module); - return CL_INVALID_VALUE; - } - } break; - default: - LogWarning("\"d3d_device_source\" is invalid"); - return CL_INVALID_VALUE; - } - - switch (d3d_device_set) { - case CL_PREFERRED_DEVICES_FOR_D3D11_KHR: - case CL_ALL_DEVICES_FOR_D3D11_KHR: { - gpu_devices = (cl_device_id*)alloca(num_gpu_devices * sizeof(cl_device_id)); - - errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, num_gpu_devices, gpu_devices, NULL); - if (errcode != CL_SUCCESS) { - break; - } - - std::vector compatible_devices; - for (cl_uint i = 0; i < num_gpu_devices; ++i) { - void* external_device[amd::Context::DeviceFlagIdx::LastDeviceFlagIdx] = {}; - external_device[amd::Context::DeviceFlagIdx::D3D11DeviceKhrIdx] = d3d11_device; - - cl_device_id device = gpu_devices[i]; - if (is_valid(device) && - as_amd(device)->bindExternalDevice(amd::Context::Flags::D3D11DeviceKhr, external_device, - NULL, VALIDATE_ONLY)) { - compatible_devices.push_back(as_amd(device)); - } - } - if (compatible_devices.size() == 0) { - *not_null(num_devices) = 0; - errcode = CL_DEVICE_NOT_FOUND; - break; - } - - auto it = compatible_devices.cbegin(); - cl_uint compatible_count = std::min(num_entries, (cl_uint)compatible_devices.size()); - - while (compatible_count--) { - *devices++ = as_cl(*it++); - --num_entries; - } - while (num_entries--) { - *devices++ = (cl_device_id)0; - } - - *not_null(num_devices) = (cl_uint)compatible_devices.size(); - } break; - - default: - LogWarning("\"d3d_device_set\" is invalid"); - errcode = CL_INVALID_VALUE; - } - - if (create_d3d11Device) { - d3d11_device->Release(); - FreeLibrary(d3d11Module); - } - return errcode; -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromD3D11BufferKHR - * @{ - */ - -/*! \brief Creates an OpenCL buffer object from a Direct3D 10 resource. - * - * \param context is a valid OpenCL context. - * - * \param flags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param pD3DResource is a valid pointer to a D3D11 resource of type ID3D11Buffer. - * - * \return valid non-zero OpenCL buffer object and \a errcode_ret is set - * to CL_SUCCESS if the buffer object is created successfully. It returns a NULL - * value with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a context is not a valid context or if Direct3D 10 - * interoperatbility has not been initialized between context and the ID3D11Device - * from which pD3DResource was created. - * - CL_INVALID_VALUE if values specified in \a clFlags are not valid. - * - CL_INVALID_D3D_RESOURCE if \a pD3DResource is not of type ID3D11Buffer. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r33? - */ - -RUNTIME_ENTRY_RET(cl_mem, clCreateFromD3D11BufferKHR, - (cl_context context, cl_mem_flags flags, ID3D11Buffer* pD3DResource, - cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - if (!flags) flags = CL_MEM_READ_WRITE; - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - if (!pD3DResource) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("parameter \"pD3DResource\" is a NULL pointer"); - return clMemObj; - } - return ( - amd::clCreateBufferFromD3D11ResourceAMD(*as_amd(context), flags, pD3DResource, errcode_ret)); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateImageFromD3D11Resource - * @{ - */ - -/*! \brief Create an OpenCL 2D or 3D image object from a D3D11 resource. - * - * \param context is a valid OpenCL context. - * - * \param flags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param pD3DResource is a valid pointer to a D3D11 resource of type - * ID3D11Texture2D, ID3D11Texture2D, or ID3D11Texture3D. - * If pD3DResource is of type ID3D11Texture1D then the created image object - * will be a 1D mipmapped image object. - * If pD3DResource is of type ID3D11Texture2D and was not created with flag - * D3D11_RESOURCE_MISC_TEXTURECUBE then the created image object will be a - * 2D mipmapped image object. - * If pD3DResource is of type ID3D11Texture2D and was created with flag - * D3D11_RESOURCE_MISC_TEXTURECUBE then the created image object will be - * a cubemap mipmapped image object. - * errocde_ret returns CL_INVALID_D3D_RESOURCE if an OpenCL memory object has - * already been created from pD3DResource in context. - * If pD3DResource is of type ID3D11Texture3D then the created image object will - * be a 3D mipmapped imageobject. - * - * \return valid non-zero OpenCL image object and \a errcode_ret is set - * to CL_SUCCESS if the image object is created successfully. It returns a NULL - * value with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a context is not a valid context or if Direct3D 11 - * interoperatbility has not been initialized between context and the ID3D11Device - * from which pD3DResource was created. - * - CL_INVALID_VALUE if values specified in \a flags are not valid. - * - CL_INVALID_D3D_RESOURCE if \a pD3DResource is not of type ID3D11Texture1D, - * ID3D11Texture2D, or ID3D11Texture3D. - * - CL_INVALID_D3D_RESOURCE if an OpenCL memory object has already been created - * from \a pD3DResource in context. - * - CL_INVALID_IMAGE_FORMAT if the Direct3D 11 texture format does not map - * to an appropriate OpenCL image format. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r48? - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateImageFromD3D11Resource, - (cl_context context, cl_mem_flags flags, ID3D11Resource* pD3DResource, - UINT subresource, int* errcode_ret, UINT dimension)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - if (!flags) flags = CL_MEM_READ_WRITE; - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - if (!pD3DResource) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("parameter \"pD3DResource\" is a NULL pointer"); - return clMemObj; - } - - // Verify context init'ed for interop - ID3D11Device* pDev; - pD3DResource->GetDevice(&pDev); - if (pDev == NULL) { - *not_null(errcode_ret) = CL_INVALID_D3D11_DEVICE_KHR; - LogWarning("Cannot retrieve D3D11 device from D3D11 resource"); - return (cl_mem)0; - } - pDev->Release(); - if (!((*as_amd(context)).info().flags_ & amd::Context::D3D11DeviceKhr)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from D3D11 device"); - return (cl_mem)0; - } - - // Check for image support - const std::vector& devices = as_amd(context)->devices(); - bool supportPass = false; - for (const auto& it : devices) { - if (it->info().imageSupport_) { - supportPass = true; - } - } - if (!supportPass) { - *not_null(errcode_ret) = CL_INVALID_OPERATION; - LogWarning("there are no devices in context to support images"); - return (cl_mem)0; - } - - switch (dimension) { -#if 0 - case 1: - return(amd::clCreateImage1DFromD3D11ResourceAMD( - *as_amd(context), - flags, - pD3DResource, - subresource, - errcode_ret)); -#endif // 0 - case 2: - return (amd::clCreateImage2DFromD3D11ResourceAMD(*as_amd(context), flags, pD3DResource, - subresource, errcode_ret)); - case 3: - return (amd::clCreateImage3DFromD3D11ResourceAMD(*as_amd(context), flags, pD3DResource, - subresource, errcode_ret)); - default: - break; - } - - *not_null(errcode_ret) = CL_INVALID_D3D11_RESOURCE_KHR; - return (cl_mem)0; -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromD3D11Texture2DKHR - * @{ - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromD3D11Texture2DKHR, - (cl_context context, cl_mem_flags flags, ID3D11Texture2D* resource, - UINT subresource, cl_int* errcode_ret)) { - return clCreateImageFromD3D11Resource(context, flags, resource, subresource, errcode_ret, 2); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromD3D11Texture3DKHR - * @{ - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromD3D11Texture3DKHR, - (cl_context context, cl_mem_flags flags, ID3D11Texture3D* resource, - UINT subresource, cl_int* errcode_ret)) { - return clCreateImageFromD3D11Resource(context, flags, resource, subresource, errcode_ret, 3); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clEnqueueAcquireD3D11ObjectsKHR - * @{ - */ -RUNTIME_ENTRY(cl_int, clEnqueueAcquireD3D11ObjectsKHR, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueAcquireExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_ACQUIRE_D3D11_OBJECTS_KHR); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clEnqueueReleaseD3D11ObjectsKHR - * @{ - */ -RUNTIME_ENTRY(cl_int, clEnqueueReleaseD3D11ObjectsKHR, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueReleaseExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_RELEASE_D3D11_OBJECTS_KHR); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clGetPlaneFromImageAMD - * @{ - */ -RUNTIME_ENTRY_RET(cl_mem, clGetPlaneFromImageAMD, - (cl_context context, cl_mem mem, cl_uint plane, cl_int* errcode_ret)) { - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return 0; - } - if (mem == 0) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - return 0; - } - if (!is_valid(mem)) { - *not_null(errcode_ret) = CL_INVALID_MEM_OBJECT; - return 0; - } - amd::Memory* amdMem = as_amd(mem); - amd::Context& amdContext = *as_amd(context); - if (amdMem->getInteropObj() == NULL) { - *not_null(errcode_ret) = CL_INVALID_MEM_OBJECT; - return 0; - } - amd::Image2DD3D11* pImage = reinterpret_cast(amdMem); - ID3D11Resource* pD3DResource = pImage->getD3D11Resource(); - // Verify the resource is a 2D texture - D3D11_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if (rType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { - *not_null(errcode_ret) = CL_INVALID_D3D11_RESOURCE_KHR; - return (cl_mem)0; - } - - amd::D3D11Object obj; - int errcode = amd::D3D11Object::initD3D11Object(amdContext, pD3DResource, 0, obj, plane); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - amd::Image2DD3D11* pImage2DD3D11 = - new (amdContext) amd::Image2DD3D11(amdContext, pImage->getMemFlags(), obj); - if (!pImage2DD3D11) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pImage2DD3D11->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImage2DD3D11->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImage2DD3D11); -} -RUNTIME_EXIT - -// -// -// namespace amd -// -// -namespace amd { -/*! @} - * \addtogroup CL-D3D11 interop helper functions - * @{ - */ - - -//******************************************************************* -// -// Internal implementation of CL API functions -// -//******************************************************************* -// -// clCreateBufferFromD3D11ResourceAMD -// -cl_mem clCreateBufferFromD3D11ResourceAMD(Context& amdContext, cl_mem_flags flags, - ID3D11Resource* pD3DResource, int* errcode_ret) { - // Verify pD3DResource is a buffer - D3D11_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if (rType != D3D11_RESOURCE_DIMENSION_BUFFER) { - *not_null(errcode_ret) = CL_INVALID_D3D11_RESOURCE_KHR; - return (cl_mem)0; - } - - D3D11Object obj; - int errcode = D3D11Object::initD3D11Object(amdContext, pD3DResource, 0, obj); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - BufferD3D11* pBufferD3D11 = new (amdContext) BufferD3D11(amdContext, flags, obj); - if (!pBufferD3D11) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pBufferD3D11->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pBufferD3D11->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pBufferD3D11); -} - -// -// clCreateImage2DFromD3D11ResourceAMD -// -cl_mem clCreateImage2DFromD3D11ResourceAMD(Context& amdContext, cl_mem_flags flags, - ID3D11Resource* pD3DResource, UINT subresource, - int* errcode_ret) { - // Verify the resource is a 2D texture - D3D11_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if (rType != D3D11_RESOURCE_DIMENSION_TEXTURE2D) { - *not_null(errcode_ret) = CL_INVALID_D3D11_RESOURCE_KHR; - return (cl_mem)0; - } - - D3D11Object obj; - int errcode = D3D11Object::initD3D11Object(amdContext, pD3DResource, subresource, obj); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - Image2DD3D11* pImage2DD3D11 = new (amdContext) Image2DD3D11(amdContext, flags, obj); - if (!pImage2DD3D11) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pImage2DD3D11->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImage2DD3D11->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImage2DD3D11); -} - -// -// clCreateImage2DFromD3D11ResourceAMD -// -cl_mem clCreateImage3DFromD3D11ResourceAMD(Context& amdContext, cl_mem_flags flags, - ID3D11Resource* pD3DResource, UINT subresource, - int* errcode_ret) { - // Verify the resource is a 2D texture - D3D11_RESOURCE_DIMENSION rType; - pD3DResource->GetType(&rType); - if (rType != D3D11_RESOURCE_DIMENSION_TEXTURE3D) { - *not_null(errcode_ret) = CL_INVALID_D3D11_RESOURCE_KHR; - return (cl_mem)0; - } - - D3D11Object obj; - int errcode = D3D11Object::initD3D11Object(amdContext, pD3DResource, subresource, obj); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - Image3DD3D11* pImage3DD3D11 = new (amdContext) Image3DD3D11(amdContext, flags, obj); - if (!pImage3DD3D11) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pImage3DD3D11->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImage3DD3D11->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImage3DD3D11); -} - -size_t D3D11Object::getResourceByteSize() { - size_t bytes = 1; - - //! @todo [odintsov]: take into consideration the mip level?! - - switch (objDesc_.objDim_) { - case D3D11_RESOURCE_DIMENSION_BUFFER: - bytes = objDesc_.objSize_.ByteWidth; - break; - - case D3D11_RESOURCE_DIMENSION_TEXTURE3D: - bytes = objDesc_.objSize_.Depth; - - case D3D11_RESOURCE_DIMENSION_TEXTURE2D: - bytes *= objDesc_.objSize_.Height; - - case D3D11_RESOURCE_DIMENSION_TEXTURE1D: - bytes *= objDesc_.objSize_.Width * getElementBytes(); - break; - - default: - LogError("getResourceByteSize: unknown type of D3D11 resource"); - bytes = 0; - break; - } - return bytes; -} - -cl_uint D3D11Object::getMiscFlag() { - if ((objDesc_.dxgiFormat_ == DXGI_FORMAT_NV12) || - (objDesc_.dxgiFormat_ == DXGI_FORMAT_P010)) { - return 1; - } - else if (objDesc_.dxgiFormat_ == DXGI_FORMAT_YUY2) { - return 3; - } - return 0; -} - -int D3D11Object::initD3D11Object(const Context& amdContext, ID3D11Resource* pRes, UINT subres, - D3D11Object& obj, INT plane) { - ID3D11Device* pDev; - HRESULT hr; - ScopedLock sl(resLock_); - - // Check if this ressource has already been used for interop - for (const auto& it : resources_) { - if (it.first == (void*)pRes && it.second.first == subres && - it.second.second == plane) { - return CL_INVALID_D3D11_RESOURCE_KHR; - } - } - - (obj.pD3D11Res_ = pRes)->GetDevice(&pDev); - - if (!pDev) { - return CL_INVALID_D3D11_DEVICE_KHR; - } - - D3D11_QUERY_DESC desc = {D3D11_QUERY_EVENT, 0}; - pDev->CreateQuery(&desc, &obj.pQuery_); - -#define SET_SHARED_FLAGS() \ - { \ - obj.pD3D11ResOrig_ = obj.pD3D11Res_; \ - /* @todo - Check device type and select right usage for resource */ \ - /* For now get only DPU path, CPU path for buffers */ \ - /* will not worl on DEFAUL resources */ \ - /*desc.Usage = D3D11_USAGE_STAGING;*/ \ - desc.Usage = D3D11_USAGE_DEFAULT; \ - desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; \ - desc.CPUAccessFlags = 0; \ - } - -#define STORE_SHARED_FLAGS_BUFFER(restype) \ - { \ - if (S_OK == hr && obj.pD3D11Res_) { \ - obj.objDesc_.objFlags_.d3d11Usage_ = desc.Usage; \ - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; \ - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; \ - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; \ - obj.objDesc_.objFlags_.structureByteStride_ = desc.StructureByteStride; \ - } else { \ - LogError("\nCannot create shared " #restype "\n"); \ - return CL_INVALID_D3D11_RESOURCE_KHR; \ - } \ - } - -#define STORE_SHARED_FLAGS(restype) \ - { \ - if (S_OK == hr && obj.pD3D11Res_) { \ - obj.objDesc_.objFlags_.d3d11Usage_ = desc.Usage; \ - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; \ - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; \ - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; \ - } else { \ - LogError("\nCannot create shared " #restype "\n"); \ - return CL_INVALID_D3D11_RESOURCE_KHR; \ - } \ - } - -#define SET_BINDING() \ - { \ - switch (desc.Format) { \ - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: \ - case DXGI_FORMAT_D32_FLOAT: \ - case DXGI_FORMAT_D24_UNORM_S8_UINT: \ - case DXGI_FORMAT_D16_UNORM: \ - desc.BindFlags = D3D11_BIND_DEPTH_STENCIL; \ - break; \ - default: \ - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; \ - break; \ - } \ - } - - pRes->GetType(&obj.objDesc_.objDim_); - - // Init defaults - obj.objDesc_.objSize_.Height = 1; - obj.objDesc_.objSize_.Depth = 1; - obj.objDesc_.mipLevels_ = 1; - obj.objDesc_.arraySize_ = 1; - obj.objDesc_.dxgiFormat_ = DXGI_FORMAT_UNKNOWN; - obj.objDesc_.dxgiSampleDesc_ = dxgiSampleDescDefault; - - switch (obj.objDesc_.objDim_) { - case D3D11_RESOURCE_DIMENSION_BUFFER: // = 1, - { - D3D11_BUFFER_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - obj.objDesc_.objSize_.ByteWidth = desc.ByteWidth; - obj.objDesc_.objFlags_.d3d11Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - obj.objDesc_.objFlags_.structureByteStride_ = desc.StructureByteStride; - // Handle D3D11Buffer without shared handle - create - // a duplicate with shared handle to provide for CAL - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D11_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - hr = pDev->CreateBuffer(&desc, NULL, (ID3D11Buffer**)&obj.pD3D11Res_); - STORE_SHARED_FLAGS_BUFFER(ID3D11Buffer); - } - } break; - - case D3D11_RESOURCE_DIMENSION_TEXTURE1D: // = 2, - { - D3D11_TEXTURE1D_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - - if (subres) { - // Calculate correct size of the subresource - UINT miplevel = subres; - if (desc.ArraySize > 1) { - miplevel = subres % desc.ArraySize; - } - if (miplevel >= desc.MipLevels) { - LogWarning("\nMiplevel >= number of miplevels\n"); - } - if (subres >= desc.MipLevels * desc.ArraySize) { - return CL_INVALID_VALUE; - } - desc.Width >>= miplevel; - if (!desc.Width) { - desc.Width = 1; - } - } - obj.objDesc_.objSize_.Width = desc.Width; - obj.objDesc_.mipLevels_ = desc.MipLevels; - obj.objDesc_.arraySize_ = desc.ArraySize; - obj.objDesc_.dxgiFormat_ = desc.Format; - obj.objDesc_.objFlags_.d3d11Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - // Handle D3D11Texture1D without shared handle - create - // a duplicate with shared handle and provide it for CAL - // Workaround for subresource > 0 in shared resource - if (subres) obj.objDesc_.objFlags_.miscFlags_ &= ~(D3D11_RESOURCE_MISC_SHARED); - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D11_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - SET_BINDING(); - obj.objDesc_.mipLevels_ = desc.MipLevels = 1; - obj.objDesc_.arraySize_ = desc.ArraySize = 1; - hr = pDev->CreateTexture1D(&desc, NULL, (ID3D11Texture1D**)&obj.pD3D11Res_); - STORE_SHARED_FLAGS(ID3D11Texture1D); - } - } break; - - case D3D11_RESOURCE_DIMENSION_TEXTURE2D: // = 3, - { - D3D11_TEXTURE2D_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - - if (subres) { - // Calculate correct size of the subresource - UINT miplevel = subres; - if (desc.ArraySize > 1) { - miplevel = subres % desc.MipLevels; - } - if (miplevel >= desc.MipLevels) { - LogWarning("\nMiplevel >= number of miplevels\n"); - } - if (subres >= desc.MipLevels * desc.ArraySize) { - return CL_INVALID_VALUE; - } - desc.Width >>= miplevel; - if (!desc.Width) { - desc.Width = 1; - } - desc.Height >>= miplevel; - if (!desc.Height) { - desc.Height = 1; - } - } - obj.objDesc_.objSize_.Width = desc.Width; - obj.objDesc_.objSize_.Height = desc.Height; - obj.objDesc_.mipLevels_ = desc.MipLevels; - obj.objDesc_.arraySize_ = desc.ArraySize; - obj.objDesc_.dxgiFormat_ = desc.Format; - obj.objDesc_.dxgiSampleDesc_ = desc.SampleDesc; - obj.objDesc_.objFlags_.d3d11Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - - // Handle D3D11Texture2D without shared handle - create - // a duplicate with shared handle and provide it for CAL - // Workaround for subresource > 0 in shared resource - if (subres) obj.objDesc_.objFlags_.miscFlags_ &= ~(D3D11_RESOURCE_MISC_SHARED); - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D11_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - SET_BINDING(); - obj.objDesc_.mipLevels_ = desc.MipLevels = 1; - obj.objDesc_.arraySize_ = desc.ArraySize = 1; - hr = pDev->CreateTexture2D(&desc, NULL, (ID3D11Texture2D**)&obj.pD3D11Res_); - STORE_SHARED_FLAGS(ID3D11Texture2D); - } - - if ((desc.Format == DXGI_FORMAT_NV12) || (desc.Format == DXGI_FORMAT_P010)) { - if (plane == -1) { - obj.objDesc_.objSize_.Height += obj.objDesc_.objSize_.Height / 2; - } - if (plane == 1) { - obj.objDesc_.objSize_.Width /= 2; - obj.objDesc_.objSize_.Height /= 2; - } - } - // RGBA8 covers 2 pixels, thus divide width by 2 - if (desc.Format == DXGI_FORMAT_YUY2) { - obj.objDesc_.objSize_.Width /= 2; - } - } break; - - case D3D11_RESOURCE_DIMENSION_TEXTURE3D: // = 4 - { - D3D11_TEXTURE3D_DESC desc; - (reinterpret_cast(pRes))->GetDesc(&desc); - - if (subres) { - // Calculate correct size of the subresource - UINT miplevel = subres; - if (miplevel >= desc.MipLevels) { - LogWarning("\nMiplevel >= number of miplevels\n"); - } - if (subres >= desc.MipLevels) { - return CL_INVALID_VALUE; - } - desc.Width >>= miplevel; - if (!desc.Width) { - desc.Width = 1; - } - desc.Height >>= miplevel; - if (!desc.Height) { - desc.Height = 1; - } - desc.Depth >>= miplevel; - if (!desc.Depth) { - desc.Depth = 1; - } - } - obj.objDesc_.objSize_.Width = desc.Width; - obj.objDesc_.objSize_.Height = desc.Height; - obj.objDesc_.objSize_.Depth = desc.Depth; - obj.objDesc_.mipLevels_ = desc.MipLevels; - obj.objDesc_.dxgiFormat_ = desc.Format; - obj.objDesc_.objFlags_.d3d11Usage_ = desc.Usage; - obj.objDesc_.objFlags_.bindFlags_ = desc.BindFlags; - obj.objDesc_.objFlags_.cpuAccessFlags_ = desc.CPUAccessFlags; - obj.objDesc_.objFlags_.miscFlags_ = desc.MiscFlags; - // Handle D3D11Texture3D without shared handle - create - // a duplicate with shared handle and provide it for CAL - // Workaround for subresource > 0 in shared resource - if (obj.objDesc_.mipLevels_ > 1) - obj.objDesc_.objFlags_.miscFlags_ &= ~(D3D11_RESOURCE_MISC_SHARED); - if (!(obj.objDesc_.objFlags_.miscFlags_ & D3D11_RESOURCE_MISC_SHARED)) { - SET_SHARED_FLAGS(); - SET_BINDING(); - obj.objDesc_.mipLevels_ = desc.MipLevels = 1; - hr = pDev->CreateTexture3D(&desc, NULL, (ID3D11Texture3D**)&obj.pD3D11Res_); - STORE_SHARED_FLAGS(ID3D11Texture3D); - } - } break; - - default: - LogError("unknown type of D3D11 resource"); - return CL_INVALID_D3D11_RESOURCE_KHR; - } - obj.subRes_ = subres; - obj.plane_ = plane; - pDev->Release(); - // Check for CL format compatibilty - if (obj.objDesc_.objDim_ != D3D11_RESOURCE_DIMENSION_BUFFER) { - cl_image_format clFmt = obj.getCLFormatFromDXGI(obj.objDesc_.dxgiFormat_, plane); - amd::Image::Format imageFormat(clFmt); - if (!imageFormat.isSupported(amdContext)) { - return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - } - } - resources_.push_back({pRes, {subres, plane}}); - return CL_SUCCESS; -} - -bool D3D11Object::copyOrigToShared() { - // Don't copy if there is no orig - if (NULL == getD3D11ResOrig()) return true; - - ID3D11Device* d3dDev; - pD3D11Res_->GetDevice(&d3dDev); - if (!d3dDev) { - LogError("\nCannot get D3D11 device from D3D11 resource\n"); - return false; - } - ID3D11DeviceContext* pImmediateContext = NULL; - d3dDev->GetImmediateContext(&pImmediateContext); - if (!pImmediateContext) { - LogError("\nCannot get D3D11 device context"); - return false; - } - assert(pD3D11ResOrig_ != NULL); - // Any usage source can be read by GPU - pImmediateContext->CopySubresourceRegion(pD3D11Res_, 0, 0, 0, 0, pD3D11ResOrig_, subRes_, NULL); - - // Flush D3D queues and make sure D3D stuff is finished - { - ScopedLock sl(resLock_); // protect from multiple - pImmediateContext->Flush(); - pImmediateContext->End(pQuery_); - BOOL data = FALSE; - while (S_OK != pImmediateContext->GetData(pQuery_, &data, sizeof(BOOL), 0)) { - } - } - - pImmediateContext->Release(); - d3dDev->Release(); - return true; -} - -bool D3D11Object::copySharedToOrig() { - // Don't copy if there is no orig - if (NULL == getD3D11ResOrig()) return true; - - ID3D11Device* d3dDev; - pD3D11Res_->GetDevice(&d3dDev); - if (!d3dDev) { - LogError("\nCannot get D3D11 device from D3D11 resource\n"); - return false; - } - ID3D11DeviceContext* pImmediateContext = NULL; - d3dDev->GetImmediateContext(&pImmediateContext); - if (!pImmediateContext) { - LogError("\nCannot get D3D11 device context"); - return false; - } - assert(pD3D11ResOrig_); - pImmediateContext->CopySubresourceRegion(pD3D11ResOrig_, subRes_, 0, 0, 0, pD3D11Res_, 0, NULL); - pImmediateContext->Release(); - - d3dDev->Release(); - return true; -} - -std::vector>> D3D11Object::resources_; -Monitor D3D11Object::resLock_; - -// -// Class BufferD3D11 implementation -// -void BufferD3D11::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(BufferD3D11)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -// -// Class Image1DD3D11 implementation -// -void Image1DD3D11::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(Image1DD3D11)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -// -// Class Image2DD3D11 implementation -// - -void Image2DD3D11::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(Image2DD3D11)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -// -// Class Image3DD3D11 implementation -// -void Image3DD3D11::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(Image3DD3D11)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -// -// Helper function SyncD3D11Objects -// -void SyncD3D11Objects(std::vector& memObjects) { - Memory*& mem = memObjects.front(); - if (!mem) { - LogWarning("\nNULL memory object\n"); - return; - } - InteropObject* interop = mem->getInteropObj(); - if (!interop) { - LogWarning("\nNULL interop object\n"); - return; - } - D3D11Object* d3dObj = interop->asD3D11Object(); - if (!d3dObj) { - LogWarning("\nNULL D3D11 object\n"); - return; - } - ID3D11Query* query = d3dObj->getQuery(); - if (!query) { - LogWarning("\nNULL ID3D11Query\n"); - return; - } - ID3D11Device* d3dDev; - query->GetDevice(&d3dDev); - if (!d3dDev) { - LogError("\nCannot get D3D11 device from D3D11 resource\n"); - return; - } - ID3D11DeviceContext* pImmediateContext = NULL; - d3dDev->GetImmediateContext(&pImmediateContext); - if (!pImmediateContext) { - LogError("\nCannot get D3D11 device context"); - return; - } - pImmediateContext->Release(); - - // Flush D3D queues and make sure D3D stuff is finished - { - ScopedLock sl(d3dObj->getResLock()); - pImmediateContext->End(query); - BOOL data = FALSE; - while ((S_OK != pImmediateContext->GetData(query, &data, sizeof(BOOL), 0)) || (data != TRUE)) { - } - } - - d3dDev->Release(); -} - -// -// Class D3D11Object implementation -// -size_t D3D11Object::getElementBytes(DXGI_FORMAT dxgiFmt, cl_uint plane) { - size_t bytesPerPixel; - - switch (dxgiFmt) { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_UINT: - case DXGI_FORMAT_R32G32B32A32_SINT: - bytesPerPixel = 16; - break; - - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_UINT: - case DXGI_FORMAT_R32G32B32_SINT: - bytesPerPixel = 12; - break; - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - bytesPerPixel = 8; - break; - - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM: - - case DXGI_FORMAT_YUY2: - bytesPerPixel = 4; - break; - - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_SINT: - - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_B5G5R5A1_UNORM: - bytesPerPixel = 2; - break; - - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_A8_UNORM: - case DXGI_FORMAT_R1_UNORM: - bytesPerPixel = 1; - break; - - - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - // Less than 1 byte per pixel - needs special consideration - bytesPerPixel = 0; - break; - case DXGI_FORMAT_NV12: - bytesPerPixel = 1; - if (plane == 1) { - bytesPerPixel = 2; - } - break; - case DXGI_FORMAT_P010: - bytesPerPixel = 2; - if (plane == 1) { - bytesPerPixel = 4; - } - break; - default: - bytesPerPixel = 0; - _ASSERT(FALSE); - break; - } - return bytesPerPixel; -} - -cl_image_format D3D11Object::getCLFormatFromDXGI(DXGI_FORMAT dxgiFmt, cl_uint plane) { - cl_image_format fmt; - - //! @todo [odintsov]: add real fmt conversion from DXGI to CL - fmt.image_channel_order = 0; // CL_RGBA; - fmt.image_channel_data_type = 0; // CL_UNSIGNED_INT8; - - switch (dxgiFmt) { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R32G32B32A32_FLOAT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32G32B32A32_UINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32B32A32_SINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32B32_TYPELESS: - fmt.image_channel_order = CL_RGB; - break; - - case DXGI_FORMAT_R32G32B32_FLOAT: - fmt.image_channel_order = CL_RGB; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32G32B32_UINT: - fmt.image_channel_order = CL_RGB; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32B32_SINT: - fmt.image_channel_order = CL_RGB; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case DXGI_FORMAT_R16G16B16A16_UNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16G16B16A16_UINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNSIGNED_INT16; - break; - - case DXGI_FORMAT_R16G16B16A16_SNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SNORM_INT16; - break; - - case DXGI_FORMAT_R16G16B16A16_SINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SIGNED_INT16; - break; - - case DXGI_FORMAT_R32G32_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_R32G32_FLOAT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32G32_UINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32G32_SINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R32G8X24_TYPELESS: - break; - - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - break; - - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - break; - - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - break; - - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R10G10B10A2_UNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT_101010; - break; - - case DXGI_FORMAT_R10G10B10A2_UINT: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R11G11B10_FLOAT: - fmt.image_channel_order = CL_RGB; - break; - - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - fmt.image_channel_order = CL_RGBA; - break; - - case DXGI_FORMAT_R8G8B8A8_UNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_YUY2: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_SNORM: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SNORM_INT8; - break; - - case DXGI_FORMAT_R8G8B8A8_SINT: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_SIGNED_INT8; - break; - - case DXGI_FORMAT_R16G16_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_R16G16_FLOAT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case DXGI_FORMAT_R16G16_UNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16G16_UINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNSIGNED_INT16; - break; - - case DXGI_FORMAT_R16G16_SNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SNORM_INT16; - break; - - case DXGI_FORMAT_R16G16_SINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SIGNED_INT16; - break; - - case DXGI_FORMAT_R32_TYPELESS: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_D32_FLOAT: - break; - - case DXGI_FORMAT_R32_FLOAT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case DXGI_FORMAT_R32_UINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT32; - break; - - case DXGI_FORMAT_R32_SINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SIGNED_INT32; - break; - - case DXGI_FORMAT_R24G8_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_D24_UNORM_S8_UINT: - break; - - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - break; - - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - break; - - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - break; - - case DXGI_FORMAT_R8G8_B8G8_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_G8R8_G8B8_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_B8G8R8A8_UNORM: - fmt.image_channel_order = CL_BGRA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_B8G8R8X8_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8_TYPELESS: - fmt.image_channel_order = CL_RG; - break; - - case DXGI_FORMAT_R8G8_UNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8G8_UINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - break; - - case DXGI_FORMAT_R8G8_SNORM: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SNORM_INT8; - break; - - case DXGI_FORMAT_R8G8_SINT: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_SIGNED_INT8; - break; - - case DXGI_FORMAT_R16_TYPELESS: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_R16_FLOAT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case DXGI_FORMAT_D16_UNORM: - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16_UNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case DXGI_FORMAT_R16_UINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT16; - break; - - case DXGI_FORMAT_R16_SNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SNORM_INT16; - break; - - case DXGI_FORMAT_R16_SINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SIGNED_INT16; - break; - - case DXGI_FORMAT_B5G6R5_UNORM: - fmt.image_channel_data_type = CL_UNORM_SHORT_565; - break; - - case DXGI_FORMAT_B5G5R5A1_UNORM: - fmt.image_channel_order = CL_BGRA; - break; - - case DXGI_FORMAT_R8_TYPELESS: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_R8_UNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R8_UINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - break; - - case DXGI_FORMAT_R8_SNORM: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SNORM_INT8; - break; - - case DXGI_FORMAT_R8_SINT: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_SIGNED_INT8; - break; - - case DXGI_FORMAT_A8_UNORM: - fmt.image_channel_order = CL_A; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case DXGI_FORMAT_R1_UNORM: - fmt.image_channel_order = CL_R; - break; - - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC5_SNORM: - break; - case DXGI_FORMAT_NV12: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - if (plane == 1) { - fmt.image_channel_order = CL_RG; - } - break; - case DXGI_FORMAT_P010: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNSIGNED_INT16; - if (plane == 1) { - fmt.image_channel_order = CL_RG; - } - break; - default: - _ASSERT(FALSE); - break; - } - - return fmt; -} - -} // namespace amd - -#endif //_WIN32 diff --git a/projects/clr/hipamd/src/cl_d3d9.cpp b/projects/clr/hipamd/src/cl_d3d9.cpp deleted file mode 100644 index 1b78b68054..0000000000 --- a/projects/clr/hipamd/src/cl_d3d9.cpp +++ /dev/null @@ -1,854 +0,0 @@ -/* Copyright (c) 2012 - 2021 Advanced Micro Devices, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. */ - -#ifdef _WIN32 - -#include "top.hpp" - -#include "cl_d3d9_amd.hpp" -#include "platform/command.hpp" - -#include -#include - -#define D3DFMT_NV_12 static_cast(MAKEFOURCC('N', 'V', '1', '2')) -#define D3DFMT_P010 static_cast(MAKEFOURCC('P', '0', '1', '0')) -#define D3DFMT_YV_12 static_cast(MAKEFOURCC('Y', 'V', '1', '2')) -#define D3DFMT_YUY2 static_cast(MAKEFOURCC('Y', 'U', 'Y', '2')) - - -RUNTIME_ENTRY(cl_int, clGetDeviceIDsFromDX9MediaAdapterKHR, - (cl_platform_id platform, cl_uint num_media_adapters, - cl_dx9_media_adapter_type_khr* media_adapters_type, void* media_adapters, - cl_dx9_media_adapter_set_khr media_adapter_set, cl_uint num_entries, - cl_device_id* devices, cl_uint* num_devices)) { - cl_int errcode; - // Accept an array of DX9 devices here as the spec mention of array of num_media_adapters size. - IDirect3DDevice9Ex** d3d9_device = static_cast(media_adapters); - cl_device_id* gpu_devices = NULL; - cl_uint num_gpu_devices = 0; - static const bool VALIDATE_ONLY = true; - - if (platform != NULL && platform != AMD_PLATFORM) { - LogWarning("\"platrform\" is not a valid AMD platform"); - return CL_INVALID_PLATFORM; - } - // check if input parameter are correct - if ((num_media_adapters == 0) || (media_adapters_type == NULL) || (media_adapters == NULL) || - (media_adapter_set != CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR && - media_adapter_set != CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR) || - (num_entries == 0 && devices != NULL)) { - return CL_INVALID_VALUE; - } - // Get GPU devices - errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 0, NULL, &num_gpu_devices); - if (errcode != CL_SUCCESS && errcode != CL_DEVICE_NOT_FOUND) { - return CL_INVALID_VALUE; - } - - if (!num_gpu_devices) { - *not_null(num_devices) = 0; - return CL_DEVICE_NOT_FOUND; - } - - switch (media_adapter_set) { - case CL_PREFERRED_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR: - case CL_ALL_DEVICES_FOR_DX9_MEDIA_ADAPTER_KHR: { - gpu_devices = new cl_device_id[num_gpu_devices]; - errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, num_gpu_devices, gpu_devices, NULL); - if (errcode != CL_SUCCESS) { - break; - } - - std::vector compatible_devices; - for (cl_uint i = 0; i < num_gpu_devices; ++i) { - cl_device_id device = gpu_devices[i]; - amd::Context::Flags context_flag; - amd::Context::DeviceFlagIdx devIdx; - switch (media_adapters_type[i]) { - case CL_ADAPTER_D3D9_KHR: - context_flag = amd::Context::Flags::D3D9DeviceKhr; - devIdx = amd::Context::DeviceFlagIdx::D3D9DeviceKhrIdx; - break; - case CL_ADAPTER_D3D9EX_KHR: - context_flag = amd::Context::Flags::D3D9DeviceEXKhr; - devIdx = amd::Context::DeviceFlagIdx::D3D9DeviceEXKhrIdx; - break; - case CL_ADAPTER_DXVA_KHR: - context_flag = amd::Context::Flags::D3D9DeviceVAKhr; - devIdx = amd::Context::DeviceFlagIdx::D3D9DeviceVAKhrIdx; - break; - } - - for (cl_uint j = 0; j < num_media_adapters; ++j) { - // Since there can be multiple DX9 adapters passed in the array we need to validate - // interopability with each. - void* external_device[amd::Context::DeviceFlagIdx::LastDeviceFlagIdx] = {}; - external_device[devIdx] = d3d9_device[j]; - - if (is_valid(device) && (media_adapters_type[j] == CL_ADAPTER_D3D9EX_KHR) && - as_amd(device)->bindExternalDevice(context_flag, external_device, NULL, - VALIDATE_ONLY)) { - compatible_devices.push_back(as_amd(device)); - } - } - } - if (compatible_devices.size() == 0) { - *not_null(num_devices) = 0; - errcode = CL_DEVICE_NOT_FOUND; - break; - } - - auto it = compatible_devices.cbegin(); - cl_uint compatible_count = std::min(num_entries, (cl_uint)compatible_devices.size()); - - while (compatible_count--) { - *devices++ = as_cl(*it++); - --num_entries; - } - while (num_entries--) { - *devices++ = (cl_device_id)0; - } - - *not_null(num_devices) = (cl_uint)compatible_devices.size(); - } break; - - default: - LogWarning("\"d3d9_device_set\" is invalid"); - errcode = CL_INVALID_VALUE; - } - - delete[] gpu_devices; - return errcode; -} -RUNTIME_EXIT - -RUNTIME_ENTRY_RET(cl_mem, clCreateFromDX9MediaSurfaceKHR, - (cl_context context, cl_mem_flags flags, - cl_dx9_media_adapter_type_khr adapter_type, void* surface_info, cl_uint plane, - cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - cl_dx9_surface_info_khr* cl_surf_info = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - - if (!flags) flags = CL_MEM_READ_WRITE; - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - - if ((adapter_type != CL_ADAPTER_D3D9_KHR) && (adapter_type != CL_ADAPTER_D3D9EX_KHR) && - (adapter_type != CL_ADAPTER_DXVA_KHR)) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - return clMemObj; - } - - if (!surface_info) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("parameter \"pD3DResource\" is a NULL pointer"); - return clMemObj; - } - - cl_surf_info = (cl_dx9_surface_info_khr*)surface_info; - IDirect3DSurface9* pD3D9Resource = cl_surf_info->resource; - HANDLE shared_handle = cl_surf_info->shared_handle; - - if (!pD3D9Resource) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("parameter \"surface_info\" is a NULL pointer"); - return clMemObj; - } - - D3DSURFACE_DESC Desc; - pD3D9Resource->GetDesc(&Desc); - - if ((Desc.Format != D3DFMT_NV_12) && - (Desc.Format != D3DFMT_P010) && - (Desc.Format != D3DFMT_YV_12) && (plane != 0)) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("The plane has to be Zero if the surface format is non-planar !"); - return clMemObj; - } - - // Check for image support - const std::vector& devices = as_amd(context)->devices(); - bool supportPass = false; - for (const auto& it : devices) { - if (it->info().imageSupport_) { - supportPass = true; - } - } - if (!supportPass) { - *not_null(errcode_ret) = CL_INVALID_OPERATION; - LogWarning("there are no devices in context to support images"); - return (cl_mem)0; - } - // Verify the resource is a 2D image - return amd::clCreateImage2DFromD3D9ResourceAMD(*as_amd(context), flags, adapter_type, - cl_surf_info, plane, errcode_ret); -} -RUNTIME_EXIT - -RUNTIME_ENTRY(cl_int, clEnqueueAcquireDX9MediaSurfacesKHR, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueAcquireExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_ACQUIRE_DX9_MEDIA_SURFACES_KHR); -} -RUNTIME_EXIT - -RUNTIME_ENTRY(cl_int, clEnqueueReleaseDX9MediaSurfacesKHR, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueReleaseExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_RELEASE_DX9_MEDIA_SURFACES_KHR); -} -RUNTIME_EXIT - -// -// -// namespace amd -// -// -namespace amd { -/*! @} - * \addtogroup CL-D3D9 interop helper functions - * @{ - */ -// -// Class D3D9Object implementation -// -std::vector> D3D9Object::resources_; -Monitor D3D9Object::resLock_; - -// -// clCreateImage2DFromD3D9ResourceAMD -// -cl_mem clCreateImage2DFromD3D9ResourceAMD(Context& amdContext, cl_mem_flags flags, - cl_dx9_media_adapter_type_khr adapter_type, - cl_dx9_surface_info_khr* surface_info, cl_uint plane, - int* errcode_ret) { - cl_dx9_surface_info_khr* cl_surf_info = reinterpret_cast(surface_info); - IDirect3DSurface9* pD3D9Resource = cl_surf_info->resource; - HANDLE shared_handle = cl_surf_info->shared_handle; - - D3D9Object obj; - cl_int errcode = D3D9Object::initD3D9Object(amdContext, adapter_type, surface_info, plane, obj); - if (CL_SUCCESS != errcode) { - *not_null(errcode_ret) = errcode; - return (cl_mem)0; - } - - Image2DD3D9* pImage2DD3D9 = new (amdContext) Image2DD3D9(amdContext, flags, obj); - if (!pImage2DD3D9) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - return (cl_mem)0; - } - if (!pImage2DD3D9->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImage2DD3D9->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImage2DD3D9); -} - -// -// Helper function SyncD3D9Objects -// -void SyncD3D9Objects(std::vector& memObjects) { - Memory*& mem = memObjects.front(); - if (!mem) { - LogWarning("\nNULL memory object\n"); - return; - } - InteropObject* interop = mem->getInteropObj(); - if (!interop) { - LogWarning("\nNULL interop object\n"); - return; - } - D3D9Object* d3d9Obj = interop->asD3D9Object(); - if (!d3d9Obj) { - LogWarning("\nNULL D3D9 object\n"); - return; - } - IDirect3DQuery9* query = d3d9Obj->getQuery(); - if (!query) { - LogWarning("\nNULL IDirect3DQuery9\n"); - return; - } - ScopedLock sl(d3d9Obj->getResLock()); - query->Issue(D3DISSUE_END); - BOOL data = FALSE; - while (S_OK != query->GetData(&data, sizeof(BOOL), D3DGETDATA_FLUSH)) { - } -} - -// -// Class D3D10Object implementation -// -size_t D3D9Object::getElementBytes(D3DFORMAT d3d9Format, cl_uint plane) { - size_t bytesPerPixel; - - switch (d3d9Format) { - case D3DFMT_UNKNOWN: - case D3DFMT_UYVY: - case D3DFMT_DXT1: - case D3DFMT_DXT2: - case D3DFMT_DXT3: - case D3DFMT_DXT4: - case D3DFMT_DXT5: - case D3DFMT_VERTEXDATA: - case D3DFMT_D32: - case D3DFMT_D15S1: - case D3DFMT_D24S8: - case D3DFMT_D24X8: - case D3DFMT_D24X4S4: - case D3DFMT_D16: - case D3DFMT_INDEX16: - case D3DFMT_INDEX32: - case D3DFMT_MULTI2_ARGB8: - case D3DFMT_CxV8U8: - // Less than 1 byte per pixel - needs special consideration - bytesPerPixel = 0; - break; - - case D3DFMT_R3G3B2: - case D3DFMT_P8: - case D3DFMT_A8: - case D3DFMT_L8: - case D3DFMT_A4L4: - bytesPerPixel = 1; - break; - - case D3DFMT_R16F: - case D3DFMT_R5G6B5: - case D3DFMT_X1R5G5B5: - case D3DFMT_A1R5G5B5: - case D3DFMT_A4R4G4B4: - case D3DFMT_A8R3G3B2: - case D3DFMT_X4R4G4B4: - case D3DFMT_A8P8: - case D3DFMT_A8L8: - case D3DFMT_V8U8: - case D3DFMT_L6V5U5: - case D3DFMT_D16_LOCKABLE: - case D3DFMT_L16: - bytesPerPixel = 2; - break; - - case D3DFMT_R8G8B8: - case D3DFMT_D24FS8: - bytesPerPixel = 3; - break; - - case D3DFMT_D32F_LOCKABLE: - case D3DFMT_A8R8G8B8: - case D3DFMT_R32F: - case D3DFMT_X8R8G8B8: - case D3DFMT_A2B10G10R10: - case D3DFMT_A8B8G8R8: - case D3DFMT_X8B8G8R8: - case D3DFMT_G16R16: - case D3DFMT_A2R10G10B10: - case D3DFMT_Q8W8V8U8: - case D3DFMT_X8L8V8U8: - case D3DFMT_V16U16: - case D3DFMT_A2W10V10U10: - case D3DFMT_R8G8_B8G8: - case D3DFMT_G8R8_G8B8: - case D3DFMT_G16R16F: - case D3DFMT_YUY2: - bytesPerPixel = 4; - break; - - case D3DFMT_G32R32F: - case D3DFMT_A16B16G16R16: - case D3DFMT_A16B16G16R16F: - case D3DFMT_Q16W16V16U16: - bytesPerPixel = 8; - break; - case D3DFMT_A32B32G32R32F: - bytesPerPixel = 16; - break; - //#if !defined(D3D_DISABLE_9EX) - // case D3DFMT_D32_LOCKABLE: - // case D3DFMT_S8_LOCKABLE: - //#endif // !D3D_DISABLE_9EX - case D3DFMT_NV_12: - if (plane == 0) { - bytesPerPixel = 1; - } else if (plane == 1) { - bytesPerPixel = 2; - } // plane != 0 or != 1 shouldn't happen here - break; - case D3DFMT_P010: - if (plane == 0) { - bytesPerPixel = 2; - } else if (plane == 1) { - bytesPerPixel = 4; - } // plane != 0 or != 1 shouldn't happen here - break; - case D3DFMT_YV_12: - bytesPerPixel = 1; - break; - - default: - bytesPerPixel = 0; - _ASSERT(FALSE); - break; - } - return bytesPerPixel; -} - -void setObjDesc(amd::D3D9ObjDesc_t& objDesc, D3DSURFACE_DESC& resDesc, cl_uint plane) { - objDesc.d3dPool_ = resDesc.Pool; - objDesc.resType_ = resDesc.Type; - objDesc.usage_ = resDesc.Usage; - objDesc.d3dFormat_ = resDesc.Format; - switch (resDesc.Format) { - case D3DFMT_NV_12: - case D3DFMT_P010: - objDesc.surfRect_.left = 0; - objDesc.surfRect_.top = 0; - if (plane == 0) { - objDesc.objSize_.Height = resDesc.Height; - objDesc.objSize_.Width = resDesc.Width; - objDesc.surfRect_.right = resDesc.Width; // resDesc.Width/2-1; - objDesc.surfRect_.bottom = 3 * resDesc.Height / 2; - ; // 3*resDesc.Height/2-1; - } else if (plane == 1) { - objDesc.objSize_.Height = resDesc.Height / 2; - objDesc.objSize_.Width = resDesc.Width / 2; - objDesc.surfRect_.right = resDesc.Width; // resDesc.Width/2-1; - objDesc.surfRect_.bottom = 3 * resDesc.Height / 2; - ; // 3*resDesc.Height/2-1; - } // plane != 0 or != 1 shouldn't happen here - break; - case D3DFMT_YV_12: - objDesc.surfRect_.left = 0; - if (plane == 0) { - objDesc.objSize_.Height = resDesc.Height; - objDesc.objSize_.Width = resDesc.Width; - objDesc.surfRect_.top = 0; - objDesc.surfRect_.right = resDesc.Width - 1; - objDesc.surfRect_.bottom = resDesc.Height - 1; - } else if (plane == 1) { - objDesc.objSize_.Height = resDesc.Height / 2; - objDesc.objSize_.Width = resDesc.Width / 2; - objDesc.surfRect_.top = resDesc.Height; - objDesc.surfRect_.right = resDesc.Width / 2 - 1; - objDesc.surfRect_.bottom = 3 * resDesc.Height / 2 - 1; - } else if (plane == 2) { - objDesc.objSize_.Height = resDesc.Height / 2; - objDesc.objSize_.Width = resDesc.Width / 2; - objDesc.surfRect_.top = 3 * resDesc.Height / 2; - objDesc.surfRect_.right = resDesc.Width / 2 - 1; - objDesc.surfRect_.bottom = 2 * resDesc.Height - 1; - } // plane > 0 or > 2 shouldn't happen here - break; - default: - objDesc.objSize_.Height = resDesc.Height; - objDesc.objSize_.Width = resDesc.Width; - objDesc.surfRect_.left = 0; - objDesc.surfRect_.top = 0; - objDesc.surfRect_.right = resDesc.Width - 1; - objDesc.surfRect_.bottom = resDesc.Height - 1; - if (resDesc.Format == D3DFMT_YUY2) { - objDesc.objSize_.Width >>= 1; - } - break; - } -} - -int D3D9Object::initD3D9Object(const Context& amdContext, - cl_dx9_media_adapter_type_khr adapter_type, - cl_dx9_surface_info_khr* cl_surf_info, cl_uint plane, - D3D9Object& obj) { - ScopedLock sl(resLock_); - - IDirect3DDevice9Ex* pDev9Ex = NULL; - cl_int errcode = CL_SUCCESS; - - // Check if this ressource has already been used for interop - IDirect3DSurface9* pD3D9res = cl_surf_info->resource; - HANDLE shared_handle = cl_surf_info->shared_handle; - - if ((adapter_type == CL_ADAPTER_D3D9_KHR) || (adapter_type == CL_ADAPTER_DXVA_KHR)) { - return CL_INVALID_DX9_MEDIA_ADAPTER_KHR; // Not supported yet - } - - for (const auto& it : resources_) { - if (it.first.surfInfo.resource == cl_surf_info->resource && it.first.surfPlane == plane) { - return CL_INVALID_D3D9_RESOURCE_KHR; - } - } - - HRESULT hr; - D3DQUERYTYPE desc = D3DQUERYTYPE_EVENT; - - D3DSURFACE_DESC resDesc; - if (D3D_OK != pD3D9res->GetDesc(&resDesc)) { - return CL_INVALID_D3D9_RESOURCE_KHR; - } - - hr = pD3D9res->GetContainer(IID_IDirect3DDevice9Ex, (void**)&pDev9Ex); - if (hr == D3D_OK) { - pDev9Ex->CreateQuery(desc, &(obj.pQuery_)); - } else { - return CL_INVALID_D3D9_RESOURCE_KHR; // d3d9ex should be supported - } - - obj.handleShared_ = shared_handle; - obj.surfPlane_ = plane; - obj.surfInfo_ = *cl_surf_info; - obj.adapterType_ = adapter_type; - - // Init defaults - setObjDesc(obj.objDescOrig_, resDesc, plane); - obj.objDesc_ = obj.objDescOrig_; - - // shared handle cases if the shared_handle is NULL - // first check if the format is NV12 or YV12, which we need special handling - if (NULL == shared_handle) { - bool found = false; - for (const auto& it : resources_) { - if (it.first.surfInfo.resource == cl_surf_info->resource && - it.first.surfPlane != plane) { - obj.handleShared_ = it.second.surfInfo.shared_handle; - obj.pD3D9Res_ = it.second.surfInfo.resource; - obj.pD3D9Res_->AddRef(); - obj.objDesc_ = obj.objDescOrig_; - found = true; - break; - } - } - if (!found) { - obj.handleShared_ = 0; - hr = pDev9Ex->CreateOffscreenPlainSurface(resDesc.Width, resDesc.Height, resDesc.Format, - resDesc.Pool, &obj.pD3D9Res_, &obj.handleShared_); - - if (D3D_OK != hr) { - errcode = CL_INVALID_D3D9_RESOURCE_KHR; - } - } - - // put the original info into the obj - obj.pD3D9ResOrig_ = pD3D9res; - obj.pD3D9ResOrig_->AddRef(); // addRef in case lost the resource - } else { - // Share the original resource - obj.pD3D9ResOrig_ = NULL; - obj.pD3D9Res_ = pD3D9res; - obj.pD3D9Res_->AddRef(); - } - - // Release the Ex interface - if (pDev9Ex) pDev9Ex->Release(); - - // Check for CL format compatibilty - if (obj.objDesc_.resType_ == D3DRTYPE_SURFACE) { - cl_image_format clFmt = obj.getCLFormatFromD3D9(obj.objDesc_.d3dFormat_, plane); - amd::Image::Format imageFormat(clFmt); - if (!imageFormat.isSupported(amdContext)) { - return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - } - } - - TD3D9RESINFO d3d9ObjOri = {*cl_surf_info, plane}; - TD3D9RESINFO d3d9ObjShared = {{obj.pD3D9Res_, obj.handleShared_}, plane}; - - if (errcode == CL_SUCCESS) { - resources_.push_back({d3d9ObjOri, d3d9ObjShared}); - } - - return errcode; -} -cl_uint D3D9Object::getMiscFlag() { - switch (objDescOrig_.d3dFormat_) { - case D3DFMT_NV_12: - case D3DFMT_P010: - return 1; - break; - case D3DFMT_YV_12: - return 2; - break; - case D3DFMT_YUY2: - return 3; - break; - default: - return 0; - break; - } -} - -cl_image_format D3D9Object::getCLFormatFromD3D9() { - return getCLFormatFromD3D9(objDesc_.d3dFormat_, surfPlane_); -} - -cl_image_format D3D9Object::getCLFormatFromD3D9(D3DFORMAT d3d9Fmt, cl_uint plane) { - cl_image_format fmt; - - fmt.image_channel_order = 0; // CL_RGBA; - fmt.image_channel_data_type = 0; // CL_UNSIGNED_INT8; - - switch (d3d9Fmt) { - case D3DFMT_R32F: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case D3DFMT_R16F: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case D3DFMT_L16: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case D3DFMT_A8: - fmt.image_channel_order = CL_A; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case D3DFMT_L8: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case D3DFMT_G32R32F: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case D3DFMT_G16R16F: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case D3DFMT_G16R16: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case D3DFMT_A8L8: - fmt.image_channel_order = CL_RG; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case D3DFMT_A32B32G32R32F: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_FLOAT; - break; - - case D3DFMT_A16B16G16R16F: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_HALF_FLOAT; - break; - - case D3DFMT_A16B16G16R16: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT16; - break; - - case D3DFMT_A8B8G8R8: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case D3DFMT_X8B8G8R8: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case D3DFMT_A8R8G8B8: - fmt.image_channel_order = CL_BGRA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - - case D3DFMT_X8R8G8B8: - fmt.image_channel_order = CL_BGRA; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - case D3DFMT_NV_12: - fmt.image_channel_data_type = CL_UNORM_INT8; - if (plane == 0) { - fmt.image_channel_order = CL_R; - } else if (plane == 1) { - fmt.image_channel_order = CL_RG; - } - break; - case D3DFMT_P010: - fmt.image_channel_data_type = CL_UNORM_INT16; - if (plane == 0) { - fmt.image_channel_order = CL_R; - } else if (plane == 1) { - fmt.image_channel_order = CL_RG; - } - break; - case D3DFMT_YV_12: - fmt.image_channel_order = CL_R; - fmt.image_channel_data_type = CL_UNORM_INT8; - break; - case D3DFMT_YUY2: - fmt.image_channel_order = CL_RGBA; - fmt.image_channel_data_type = CL_UNSIGNED_INT8; - break; - case D3DFMT_UNKNOWN: - case D3DFMT_R8G8B8: - case D3DFMT_R5G6B5: - case D3DFMT_X1R5G5B5: - case D3DFMT_A1R5G5B5: - case D3DFMT_A4R4G4B4: - case D3DFMT_R3G3B2: - case D3DFMT_A8R3G3B2: - case D3DFMT_X4R4G4B4: - case D3DFMT_A2B10G10R10: - case D3DFMT_A2R10G10B10: - case D3DFMT_A8P8: - case D3DFMT_P8: - case D3DFMT_A4L4: - case D3DFMT_V8U8: - case D3DFMT_L6V5U5: - case D3DFMT_X8L8V8U8: - case D3DFMT_Q8W8V8U8: - case D3DFMT_V16U16: - case D3DFMT_A2W10V10U10: - case D3DFMT_UYVY: - case D3DFMT_R8G8_B8G8: - case D3DFMT_G8R8_G8B8: - case D3DFMT_DXT1: - case D3DFMT_DXT2: - case D3DFMT_DXT3: - case D3DFMT_DXT4: - case D3DFMT_DXT5: - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D32: - case D3DFMT_D15S1: - case D3DFMT_D24S8: - case D3DFMT_D24X8: - case D3DFMT_D24X4S4: - case D3DFMT_D16: - case D3DFMT_D32F_LOCKABLE: - case D3DFMT_D24FS8: - //#if !defined(D3D_DISABLE_9EX) - case D3DFMT_D32_LOCKABLE: - case D3DFMT_S8_LOCKABLE: - //#endif // !D3D_DISABLE_9EX - case D3DFMT_VERTEXDATA: - case D3DFMT_INDEX16: - case D3DFMT_INDEX32: - case D3DFMT_Q16W16V16U16: - case D3DFMT_MULTI2_ARGB8: - case D3DFMT_CxV8U8: - //#if !defined(D3D_DISABLE_9EX) - case D3DFMT_A1: - case D3DFMT_A2B10G10R10_XR_BIAS: - case D3DFMT_BINARYBUFFER: - _ASSERT(FALSE); // NOT SURPPORTED - break; - //#endif // !D3D_DISABLE_9EX - default: - _ASSERT(FALSE); - break; - } - - return fmt; -} - -bool D3D9Object::copyOrigToShared() { - // Don't copy if there is no orig - if (NULL == getD3D9ResOrig()) return true; - - IDirect3DDevice9Ex* d3dDev; - HRESULT hr; - ScopedLock sl(getResLock()); - - IDirect3DSurface9* srcSurf = getD3D9ResOrig(); - IDirect3DSurface9* dstSurf = getD3D9Resource(); - - hr = getD3D9Resource()->GetContainer(IID_IDirect3DDevice9Ex, (void**)&d3dDev); - if (hr != D3D_OK || !d3dDev) { - LogError("\nCannot get D3D9 device from D3D9 surface\n"); - return false; - } - - hr = d3dDev->StretchRect(srcSurf, NULL, dstSurf, NULL, D3DTEXF_NONE); - if (hr != D3D_OK) { - LogError("\ncopy original surface to shared surface failed\n"); - return false; - } - // Flush D3D queues and make sure D3D stuff is finished - pQuery_->Issue(D3DISSUE_END); - BOOL data; - while ((D3D_OK != pQuery_->GetData(&data, sizeof(BOOL), D3DGETDATA_FLUSH)) && (data != TRUE)) { - } - - if (d3dDev) d3dDev->Release(); - return true; -} - -bool D3D9Object::copySharedToOrig() { - // Don't copy if there is no orig - if (NULL == getD3D9ResOrig()) return true; - - IDirect3DDevice9Ex* d3dDev; - HRESULT hr; - ScopedLock sl(getResLock()); - - hr = getD3D9Resource()->GetContainer(IID_IDirect3DDevice9Ex, (void**)&d3dDev); - if (hr != D3D_OK || !d3dDev) { - LogError("\nCannot get D3D9 device from D3D9 surface\n"); - return false; - } - - hr = d3dDev->StretchRect(getD3D9Resource(), NULL, getD3D9ResOrig(), NULL, D3DTEXF_NONE); - if (hr != D3D_OK) { - LogError("\ncopy shared surface to original surface failed\n"); - return false; - } - - if (d3dDev) d3dDev->Release(); - return true; -} - -void Image2DD3D9::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(Image2DD3D9)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -} // namespace amd - -#endif //_WIN32 diff --git a/projects/clr/hipamd/src/cl_gl.cpp b/projects/clr/hipamd/src/cl_gl.cpp deleted file mode 100644 index 241e3f20b1..0000000000 --- a/projects/clr/hipamd/src/cl_gl.cpp +++ /dev/null @@ -1,2472 +0,0 @@ -/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. */ - -#include "top.hpp" - -#ifdef _WIN32 -#include -#include -#include -// This is necessary since there are common GL/D3D10 functions -#include "cl_d3d9_amd.hpp" -#include "cl_d3d10_amd.hpp" -#include "cl_d3d11_amd.hpp" -#endif //_WIN32 - -#include -#include - -#include -#include -#include - -#include "cl_common.hpp" -#include "cl_gl_amd.hpp" - -#include "device/device.hpp" - -/* The pixel internal format for DOPP texture defined in gl_enum.h */ -#define GL_BGR8_ATI 0x8083 -#define GL_BGRA8_ATI 0x8088 - -#include -#include - - -/*! \addtogroup API - * @{ - * - * \addtogroup CL_GL_Interops - * - * This section discusses OpenCL functions that allow applications to - * use OpenGL buffer/texture/render-buffer objects as OpenCL memory - * objects. This allows efficient sharing of data between these OpenCL - * and OpenGL. The OpenCL API can be used to execute kernels that read - * and/or write memory objects that are also an OpenGL buffer object - * or a texture. An OpenCL image object can be created from an OpenGL - * texture or renderbuffer object. An OpenCL buffer object can be - * created from an OpenGL buffer object. An OpenCL memory object can - * be created from an OpenGL texture/buffer/render-buffer object or - * the default system provided framebuffer if any only if the OpenCL - * clContext has been created from a GL clContext. OpenGL contexts are - * created using platform specific APIs (EGL, CGL, WGL, GLX are some - * of the platform specific APIs that allow applications to create GL - * contexts). The appropriate platform API (such as EGL, CGL, WGL, - * GLX) will be extended to allow a CL clContext to be created from a - * GL clContext. Creating an OpenCL memory object from the default - * system provided framebuffer will also require an appropriate - * extension to the platform API. Refer to the appropriate platform - * API documentation to understand how to create a CL clContext from a - * GL clContext and creating a CL memory object from the default - * system provided framebuffer. - * - * @{ - * - * \addtogroup clCreateFromGLBuffer - * - * @{ - */ - -/*! \brief Creates an OpenCL buffer object from an OpenGL buffer object. - * - * \param clContext is a valid OpenCL clContext created from an OpenGL clContext. - * - * \param clFlags is a bit-field that is used to specify usage information. Only - * CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE can be used. - * - * \param glBufferName is a GL buffer object name. The GL buffer - * object must have a data store created though it does not need to - * be initialized. The size of the data store will be used to - * determine the size of the CL buffer object. - * - * \param pCpuMem is a pointer to the buffer data that may already be - * allocated by the application. The size of the buffer that pCpuMem points - * to must be >= \a size bytes. Passing in a pointer to an already allocated - * buffer on the host and using it as a buffer object allows applications to - * share data efficiently with kernels and the host. - * - * \param errcode_ret will return an appropriate error code. If errcode_ret - * is NULL, no error code is returned. - * - * \return valid non-zero OpenCL buffer object and errcode_ret is set - * to CL_SUCCESS if the buffer object is created successfully. It - * returns a NULL value with one of the following error values - * returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a clContext is not a valid clContext. - * - CL_INVALID_VALUE if values specified in \a clFlags are not valid. - * - CL_INVALID_GL_OBJECT if glBufferName is not a GL buffer object or is a - * GL buffer object but does not have a data store created. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromGLBuffer, - (cl_context context, cl_mem_flags flags, GLuint bufobj, cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - - return (amd::clCreateFromGLBufferAMD(*as_amd(context), flags, bufobj, errcode_ret)); -} -RUNTIME_EXIT - -/*! \brief creates the following: - * - an OpenCL 2D image object from an OpenGL 2D texture object - * or a single face of an OpenGL cubemap texture object, - * - an OpenCL 2D image array object from an OpenGL 2D texture array object, - * - an OpenCL 1D image object from an OpenGL 1D texture object, - * - an OpenCL 1D image buffer object from an OpenGL texture buffer object, - * - an OpenCL 1D image array object from an OpenGL 1D texture array object, - * - an OpenCL 3D image object from an OpenGL 3D texture object. - * - * \param clContext is a valid OpenCL clContext created from an OpenGL clContext. - * - * \param clFlags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param texture_target must be GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY, - * GL_TEXTURE_BUFFER, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D, - * GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_POSITIVE_X, - * GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - * GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - * GL_TEXTURE_CUBE_MAP_NEGATIVE_Z or GL_TEXTURE_RECTANGLE_ARB. - * - * \param miplevel is the mipmap level to be used. If \a texture_target - * is GL_TEXTURE_BUFFER, \a miplevel must be 0. - * - * \param texture is a GL 1D, 2D, 3D, 1D array, 2D array, cubemap, - * rectangle or buffer texture object. - * The texture object must be a complete texture as per - * OpenGL rules on texture completeness. The texture format and dimensions - * defined by OpenGL for the specified miplevel of the texture will be - * used to create the OpenCL image memory object. Only GL texture formats - * that map to appropriate image channel order and data type can be used - * to create the the OpenCL image memory object. - * - * \param errcode_ret will return an appropriate error code. If \a - * errcode_ret is NULL, no error code is returned. - * - * \return A valid non-zero OpenCL image object and \a errcode_ret is set to - * CL_SUCCESS if the image object is created successfully. It returns a NULL value - * with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a clContext is not a valid clContext or was not - * created from a GL clContext. - * - CL_INVALID_VALUE if values specified in \a clFlags are not valid. - * - CL_INVALID_MIP_LEVEL if \a miplevel is not a valid mip-level for \a texture. - * - CL_INVALID_GL_OBJECT if \a texture is not an appropriate GL 2D texture, - * cubemap or texture rectangle. - * - CL_INVALID_IMAGE_FORMAT_DESCRIPTOR if the OpenGL texture format does not - * map to an appropriate OpenCL image format. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.2r07 - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromGLTexture, - (cl_context context, cl_mem_flags flags, GLenum texture_target, GLint miplevel, - GLuint texture, cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - - const std::vector& devices = as_amd(context)->devices(); - bool supportPass = false; - for (const auto& it : devices) { - if (it->info().imageSupport_) { - supportPass = true; - } - } - if (!supportPass) { - *not_null(errcode_ret) = CL_INVALID_OPERATION; - LogWarning("there are no devices in context to support images"); - return static_cast(0); - } - - return amd::clCreateFromGLTextureAMD(*as_amd(context), flags, texture_target, miplevel, texture, - errcode_ret); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromGLTexture2D - * @{ - */ - -/*! \brief Create an OpenCL 2D image object from an OpenGL 2D texture object. - * - * \param clContext is a valid OpenCL clContext created from an OpenGL clContext. - * - * \param clFlags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param target must be GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP_POSITIVE_X, - * GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, - * GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, - * GL_TEXTURE_CUBE_MAP_NEGATIVE_Z or GL_TEXTURE_RECTANGLE_ARB. - * - * \param miplevel is the mipmap level to be used. - * - * \param texture is a GL 2D texture, cubemap or texture rectangle - * object name. The texture object must be a complete texture as per - * OpenGL rules on texture completeness. The \a texture format and - * dimensions specified using appropriate glTexImage2D call for \a - * miplevel will be used to create the 2D image object. Only GL - * texture formats that map to appropriate image channel order and - * data type can be used to create the 2D image object. - * - * \param errcode_ret will return an appropriate error code. If \a - * errcode_ret is NULL, no error code is returned. - * - * \return A valid non-zero OpenCL image object and \a errcode_ret is set to - * CL_SUCCESS if the image object is created successfully. It returns a NULL value - * with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a clContext is not a valid clContext or was not - * created from a GL clContext. - * - CL_INVALID_VALUE if values specified in \a clFlags are not valid. - * - CL_INVALID_MIP_LEVEL if \a miplevel is not a valid mip-level for \a texture. - * - CL_INVALID_GL_OBJECT if \a texture is not an appropriate GL 2D texture, - * cubemap or texture rectangle. - * - CL_INVALID_IMAGE_FORMAT_DESCRIPTOR if the OpenGL texture format does not - * map to an appropriate OpenCL image format. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromGLTexture2D, - (cl_context context, cl_mem_flags flags, GLenum target, GLint miplevel, - GLuint texture, cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - - const std::vector& devices = as_amd(context)->devices(); - bool supportPass = false; - for (const auto& it : devices) { - if (it->info().imageSupport_) { - supportPass = true; - } - } - if (!supportPass) { - *not_null(errcode_ret) = CL_INVALID_OPERATION; - LogWarning("there are no devices in context to support images"); - return static_cast(0); - } - - return amd::clCreateFromGLTextureAMD(*as_amd(context), flags, target, miplevel, texture, - errcode_ret); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromGLTexture3D - * @{ - */ - -/*! \brief Create an OpenCL 3D image object from an OpenGL 3D texture object. - * - * \param clContext is a valid OpenCL clContext created from an OpenGL clContext. - * - * \param clFlags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param target must be GL_TEXTURE_3D. - * - * \param miplevel is the mipmap level to be used. - * - * \param texture is a GL 3D texture object [name]. - * The texture object must be a complete texture as per OpenGL rules on texture - * completeness. The \a texture format and dimensions specified using appropriate - * glTexImage3D call for \a miplevel will be used to create the 3D image object. - * Only GL texture formats that map to appropriate image channel order and - * data type can be used to create the 3D image object. - * - * \param errcode_ret will return an appropriate error code. If \a errcode_ret - * is NULL, no error code is returned. - * - * \return A valid non-zero OpenCL image object and \a errcode_ret is set to - * CL_SUCCESS if the image object is created successfully. It returns a NULL value - * with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a clContext is not a valid clContext or was not - * created from a GL clContext. - * - CL_INVALID_VALUE if values specified in \a clFlags are not valid. - * - CL_INVALID_MIP_LEVEL if \a miplevel is not a valid mip-level for \a texture. - * - CL_INVALID_GL_OBJECT if \a texture is not an GL 3D texture. - * - CL_INVALID_IMAGE_FORMAT_DESCRIPTOR if the OpenGL texture format does not - * map to an appropriate OpenCL image format. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromGLTexture3D, - (cl_context context, cl_mem_flags flags, GLenum target, GLint miplevel, - GLuint texture, cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - - const std::vector& devices = as_amd(context)->devices(); - bool supportPass = false; - for (const auto& it : devices) { - if (it->info().imageSupport_) { - supportPass = true; - } - } - if (!supportPass) { - *not_null(errcode_ret) = CL_INVALID_OPERATION; - LogWarning("there are no devices in context to support images"); - return static_cast(0); - } - - return amd::clCreateFromGLTextureAMD(*as_amd(context), flags, target, miplevel, texture, - errcode_ret); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clCreateFromGLRenderbuffer - * @{ - */ - -/*! \brief Create an OpenCL 2D image object from an OpenGL renderbuffer object. - * - * \param clContext is a valid OpenCL clContext created from an OpenGL clContext. - * - * \param clFlags is a bit-field that is used to specify usage information. - * Only CL_MEM_READ_ONLY, CL_MEM_WRITE_ONLY and CL_MEM_READ_WRITE values - * can be used. - * - * \param renderbuffer is a GL renderbuffer object name. The renderbuffer - * storage must be specified before the image object can be created. Only - * GL renderbuffer formats that map to appropriate image channel order and - * data type can be used to create the 2D image object. - * - * \param errcode_ret will return an appropriate error code. If \a errcode_ret - * is NULL, no error code is returned. - * - * \return A valid non-zero OpenCL image object and \a errcode_ret is set - * to CL_SUCCESS if the image object is created successfully. It returns a - * NULL value with one of the following error values returned in \a errcode_ret: - * - CL_INVALID_CONTEXT if \a clContext is not a valid clContext or was not - * created from a GL clContext. - * - CL_INVALID_VALUE if values specified in \a clFlags are not valid. - * - CL_INVALID_GL_OBJECT if \a renderbuffer is not an GL renderbuffer object. - * - CL_INVALID_IMAGE_FORMAT_DESCRIPTOR if the OpenGL renderbuffer format - * does not map to an appropriate OpenCL image format. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources required - * by the runtime. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY_RET(cl_mem, clCreateFromGLRenderbuffer, (cl_context context, cl_mem_flags flags, - GLuint renderbuffer, cl_int* errcode_ret)) { - cl_mem clMemObj = NULL; - - if (!is_valid(context)) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("invalid parameter \"context\""); - return clMemObj; - } - - if (!(((flags & CL_MEM_READ_ONLY) == CL_MEM_READ_ONLY) || - ((flags & CL_MEM_WRITE_ONLY) == CL_MEM_WRITE_ONLY) || - ((flags & CL_MEM_READ_WRITE) == CL_MEM_READ_WRITE))) { - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid parameter \"flags\""); - return clMemObj; - } - - return (amd::clCreateFromGLRenderbufferAMD(*as_amd(context), flags, renderbuffer, errcode_ret)); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clGetGLObjectInfo - * @{ - */ - -/*! \brief Query GL object type from a CL memory object. - * - * \param memobj [is a valid cl_mem object created from a GL object]. - * - * \param gl_object_type returns the type of GL object attached to memobj - * and can be CL_GL_OBJECT_BUFFER, CL_GL_OBJECT_TEXTURE2D, - * CL_GL_OBJECT_TEXTURE_RECTANGLE, CL_GL_OBJECT_TEXTURE3D, or - * CL_GL_OBJECT_RENDERBUFFER. If \a gl_object_type is NULL, it is ignored. - * - * \param gl_object_name returns the GL object name used to create memobj. - * If \a gl_object_name is NULL, it is ignored. - * - * \return One of the following values is returned: - * - CL_SUCCESS if the call was executed successfully. - * - CL_INVALID_MEM_OBJECT if \a memobj is not a valid OpenCL memory object. - * - CL_INVALID_GL_OBJECT if there is no GL object associated with \a memobj. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY(cl_int, clGetGLObjectInfo, - (cl_mem memobj, cl_gl_object_type* gl_object_type, GLuint* gl_object_name)) { - if (!is_valid(memobj)) { - LogWarning("\"memobj\" is not a valid cl_mem object"); - return CL_INVALID_MEM_OBJECT; - } - - amd::InteropObject* interop = as_amd(memobj)->getInteropObj(); - if (NULL == interop) { - LogWarning("CL object \"memobj\" is not created from GL object"); - return CL_INVALID_GL_OBJECT; - } - - amd::GLObject* glObject = interop->asGLObject(); - if (NULL == glObject) { - LogWarning("CL object \"memobj\" is not created from GL object"); - return CL_INVALID_GL_OBJECT; - } - - cl_int result; - - cl_gl_object_type clGLType = glObject->getCLGLObjectType(); - result = amd::clGetInfo(clGLType, sizeof(cl_gl_object_type), gl_object_type, NULL); - - GLuint glName = glObject->getGLName(); - result |= amd::clGetInfo(glName, sizeof(GLuint), gl_object_name, NULL); - - return result; -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clGetGLTextureInfo - * @{ - */ - -/*! \brief Query additional information about the GL texture object associated - * with \a memobj. - * - * \param memobj [is a valid cl_mem object created from a GL object]. - * - * \param param_name specifies what additional information about the GL - * texture object associated with \a memobj to query: - * - CL_GL_TEXTURE_TARGET (GLenum) to query the \a target argument specified - * in clCreateGLTexture2D or clCreateGLTexture3D calls. - * - CL_GL_MIPMAP_LEVEL (GLint) to query the \a miplevel argument specified - * in clCreateGLTexture2D or clCreateGLTexture3D calls. - * - * \param param_value is a pointer to memory where the appropriate result - * being queried is returned. If \a param_value is NULL, it is ignored. - * - * \param param_value_size is used to specify the size in bytes of memory - * pointed to by \a param_value. This size must be >= size of return type as - * described for \a param_name argumnet (GLenum or GLint). - * \a param_value_size_ret returns the actual size in bytes of data copied to - * \a param_value. If \a param_value_size_ret is NULL, it is ignored - * - * \return One of the following values is returned: - * - CL_SUCCESS if the function is executed successfully. - * - CL_INVALID_MEM_OBJECT if \a memobj is not a valid OpenCL memory object. - * - CL_INVALID_GL_OBJECT if there is no GL texture object (2D or 3D texture) - * associated with \a memobj. - * - CL_INVALID_VALUE if \a param_name is not valid, or if size in bytes - * specified by \a param_value_size is < size of return type required by - * \a param_name and \a param_value is not NULL, or if \a param_value and - * \a param_value_size_ret are NULL. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY(cl_int, clGetGLTextureInfo, - (cl_mem memobj, cl_gl_texture_info param_name, size_t param_value_size, - void* param_value, size_t* param_value_size_ret)) { - if (!is_valid(memobj)) { - LogWarning("\"memobj\" is not a valid cl_mem object"); - return CL_INVALID_MEM_OBJECT; - } - amd::InteropObject* interop = as_amd(memobj)->getInteropObj(); - if (NULL == interop) { - LogWarning("CL object \"memobj\" is not created from GL object"); - return CL_INVALID_GL_OBJECT; - } - amd::GLObject* glObject = interop->asGLObject(); - if ((NULL == glObject) || (NULL != glObject->asBufferGL())) { - LogWarning("CL object \"memobj\" is not created from GL texture"); - return CL_INVALID_GL_OBJECT; - } - - switch (param_name) { - case CL_GL_TEXTURE_TARGET: { - GLenum glTarget = glObject->getGLTarget(); - if (glTarget == GL_TEXTURE_CUBE_MAP) { - glTarget = glObject->getCubemapFace(); - } - return amd::clGetInfo(glTarget, param_value_size, param_value, param_value_size_ret); - } - case CL_GL_MIPMAP_LEVEL: { - GLint mipLevel = glObject->getGLMipLevel(); - return amd::clGetInfo(mipLevel, param_value_size, param_value, param_value_size_ret); - } - case CL_GL_NUM_SAMPLES: { - GLsizei numSamples = glObject->getNumSamples(); - return amd::clGetInfo(numSamples, param_value_size, param_value, param_value_size_ret); - } - default: - LogWarning("Unknown param_name in clGetGLTextureInfoAMD"); - break; - } - - return CL_INVALID_VALUE; -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clEnqueueAcquireExtObjects - * @{ - */ - -/*! \brief Acquire OpenCL memory objects that have been created from external - * objects (OpenGL, D3D). - * - * \param command_queue is a valid command-queue. - * - * \param num_objects is the number of memory objects to be acquired - * in \a mem_objects. - * - * \param mem_objects is a pointer to a list of CL memory objects that refer - * to a GL object (buffer/texture/renderbuffer objects or the framebuffer). - * - * \param event_wait_list specify [is a pointer to] events that need to - * complete before this particular command can be executed. - * If \a event_wait_list is NULL, then this particular command does not wait - * on any event to complete. If \a event_wait_list is NULL, - * \a num_events_in_wait_list must be 0. If \a event_wait_list is not NULL, - * the list of events pointed to by \a event_wait_list must be valid and - * \a num_events_in_wait_list must be greater than 0. The events specified in - * \a event_wait_list act as synchronization points. - * - * \param num_events_in_wait_list specify the number of events in - * \a event_wait_list. It must be 0 if \a event_wait_list is NULL. It must be - * greater than 0 if \a event_wait_list is not NULL. - * - * \param event returns an event object that identifies this particular - * command and can be used to query or queue a wait for this particular - * command to complete. \a event can be NULL in which case it will not be - * possible for the application to query the status of this command or queue a - * wait for this command to complete. - * - * \return One of the following values is returned: - * - CL_SUCCESS if the function is executed successfully. - * - CL_SUCCESS if \a num_objects is 0 and \a mem_objects is NULL; the - * function does nothing. - * - CL_INVALID_VALUE if \a num_objects is zero and \a mem_objects is not a - * NULL value or if \a num_objects > 0 and \a mem_objects is NULL. - * - CL_INVALID_MEM_OBJECT if memory objects in \a mem_objects are not valid - * OpenCL memory objects. - * - CL_INVALID_COMMAND_QUEUE if \a command_queue is not a valid command-queue. - * - CL_INVALID_CONTEXT if clContext associated with \a command_queue was not - * created from an OpenGL clContext. - * - CL_INVALID_GL_OBJECT if memory objects in \a mem_objects have not been - * created from a GL object(s). - * - CL_INVALID_EVENT_WAIT_LIST if \a event_wait_list is NULL and - * \a num_events_in_wait_list > 0, or \a event_wait_list is not NULL and - * \a num_events_in_wait_list is 0, or if event objects in \a event_wait_list - * are not valid events. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources - * required by the OpenCL implementation on the host. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY(cl_int, clEnqueueAcquireGLObjects, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueAcquireExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_ACQUIRE_GL_OBJECTS); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clEnqueueReleaseGLObjects - * @{ - */ - -/*! \brief Release OpenCL memory objects that have been created from OpenGL - * objects. - * - * \param command_queue is a valid command-queue [which is associated with the - * OpenCL clContext releasing the OpenGL objects]. - * - * \param num_objects is the number of memory objects to be released - * in \a mem_objects. - * - * \param mem_objects is a pointer to a list of CL memory objects that refer - * to a GL object (buffer/texture/renderbuffer objects or the framebuffer). - * - * \param event_wait_list specify [is a pointer to] events that need to - * complete before this particular command can be executed. - * If \a event_wait_list is NULL, then this particular command does not wait - * on any event to complete. If \a event_wait_list is NULL, - * \a num_events_in_wait_list must be 0. If \a event_wait_list is not NULL, - * the list of events pointed to by \a event_wait_list must be valid and - * \a num_events_in_wait_list must be greater than 0. The events specified in - * \a event_wait_list act as synchronization points. - * - * \param num_events_in_wait_list specify the number of events in - * \a event_wait_list. It must be 0 if \a event_wait_list is NULL. It must be - * greater than 0 if \a event_wait_list is not NULL. - * - * \param event returns an event object that identifies this particular - * command and can be used to query or queue a wait for this particular - * command to complete. \a event can be NULL in which case it will not be - * possible for the application to query the status of this command or queue a - * wait for this command to complete. - * - * \return One of the following values is returned: - * - CL_SUCCESS if the function is executed successfully. - * - CL_SUCCESS if \a num_objects is 0 and \a mem_objects is NULL; the - * function does nothing. - * - CL_INVALID_VALUE if \a num_objects is zero and \a mem_objects is not a - * NULL value or if \a num_objects > 0 and \a mem_objects is NULL. - * - CL_INVALID_MEM_OBJECT if memory objects in \a mem_objects are not valid - * OpenCL memory objects. - * - CL_INVALID_COMMAND_QUEUE if \a command_queue is not a valid command-queue. - * - CL_INVALID_CONTEXT if clContext associated with \a command_queue was not - * created from an OpenGL clContext. - * - CL_INVALID_GL_OBJECT if memory objects in \a mem_objects have not been - * created from a GL object(s). - * - CL_INVALID_EVENT_WAIT_LIST if \a event_wait_list is NULL and - * \a num_events_in_wait_list > 0, or \a event_wait_list is not NULL and - * \a num_events_in_wait_list is 0, or if event objects in \a event_wait_list - * are not valid events. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources - * required by the OpenCL implementation on the host. - * - * \version 1.0r29 - */ -RUNTIME_ENTRY(cl_int, clEnqueueReleaseGLObjects, - (cl_command_queue command_queue, cl_uint num_objects, const cl_mem* mem_objects, - cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event)) { - return amd::clEnqueueReleaseExtObjectsAMD(command_queue, num_objects, mem_objects, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_RELEASE_GL_OBJECTS); -} -RUNTIME_EXIT - -/*! @} -* \addtogroup clCreateEventFromGLsyncKHR -* @{ -*/ - -/*! \brief Creates an event object linked to an OpenGL sync object. -* Completion of such an event object is equivalent to waiting for completion -* of the fence command associated with the linked GL sync object. -* -* \param context is valid OpenCL context created from an OpenGL context -* or share group, using the cl_khr_gl_sharing extension. -* -* \param sync is the 'name' of a sync object in the GL share group associated -* with context. -* -* \param errcode_ret Returns an appropriate error code as described below. -* If errcode_ret is NULL, no error code is returned. -* -* \return a valid OpenCL event object and errcode_ret is set to CL_SUCCESS -* if the event object is created successfully.Otherwise, it returns a NULL -* value with one of the following error values returned in errcode_ret: -* - CL_INVALID_CONTEXT if context is not a valid context or was not created -* from a GL context. -* - CL_INVALID_GL_OBJECT if sync is not the name of a sync object in the -* GL share group associated with context. -* -* \version 1.1 -*/ - -RUNTIME_ENTRY_RET(cl_event, clCreateEventFromGLsyncKHR, - (cl_context context, cl_GLsync clGLsync, cl_int* errcode_ret)) { - // create event of fence sync type - amd::ClGlEvent* clglEvent = new amd::ClGlEvent(*as_amd(context)); - clglEvent->context().glenv()->glFlush_(); - // initially set the status of fence as queued - clglEvent->setStatus(CL_SUBMITTED); - // store GLsync id of the fence in event in order to associate them together - clglEvent->setData(clGLsync); - amd::Event* evt = dynamic_cast(clglEvent); - evt->retain(); - return as_cl(evt); -} -RUNTIME_EXIT - -/*! @} - * \addtogroup clGetGLContextInfoKHR - * @{ - */ - -/*! \brief This f-n is defined in CL extension cl_khr_gl_sharing and serves - * the purpose of quering current device and all devices that support - * CL-GL interoperability. - * - * \param properties points to an , which is a array of - * ordered pairs terminated with zero. If an - * attribute is not specified in , then its default value - * (listed in table 4.attr) is used (it is said to be specified - * implicitly). If is NULL or empty (points to a list - * whose first value is zero), all attributes take on their default - * values. - * - * \param param_name may accept one of the following enumerated values: - * - CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR 0x2006 - * - CL_DEVICES_FOR_GL_CONTEXT_KHR 0x2007. - * - * \param param_value_size is used to specify the size in bytes of memory - * pointed to by \a param_value. This size must be >= size of return type as - * described for \a param_name argumnet (GLenum or GLint). - * \a param_value_size_ret returns the actual size in bytes of data copied to - * \a param_value. If \a param_value_size_ret is NULL, it is ignored - * - * \param param_value is a pointer to memory where the appropriate result - * being queried is returned. If \a param_value is NULL, it is ignored. - * - * \param param_value_size is used to specify the size in bytes of memory - * pointed to by \a param_value. This size must be >= size of return type as - * described for \a param_name argumnet (GLenum or GLint). - * \a param_value_size_ret returns the actual size in bytes of data copied to - * \a param_value. If \a param_value_size_ret is NULL, it is ignored - * - * \return one of the following values is returned: - * - CL_SUCCESS if the function is executed successfully. - * - CL_SUCCESS if \a num_objects is 0 and \a mem_objects is NULL; the - * function does nothing. - * - CL_INVALID_VALUE if \a num_objects is zero and \a mem_objects is not a - * NULL value or if \a num_objects > 0 and \a mem_objects is NULL. - * - CL_INVALID_MEM_OBJECT if memory objects in \a mem_objects are not valid - * OpenCL memory objects. - * - CL_INVALID_COMMAND_QUEUE if \a command_queue is not a valid command-queue. - * - CL_INVALID_CONTEXT if clContext associated with \a command_queue was not - * created from an OpenGL clContext. - * - CL_INVALID_GL_OBJECT if memory objects in \a mem_objects have not been - * created from a GL object(s). - * - CL_INVALID_EVENT_WAIT_LIST if \a event_wait_list is NULL and - * \a num_events_in_wait_list > 0, or \a event_wait_list is not NULL and - * \a num_events_in_wait_list is 0, or if event objects in \a event_wait_list - * are not valid events. - * - CL_OUT_OF_HOST_MEMORY if there is a failure to allocate resources - * required by the OpenCL implementation on the host. - * - CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR if - * - * \version 1.0r47 - */ -RUNTIME_ENTRY(cl_int, clGetGLContextInfoKHR, - (const cl_context_properties* properties, cl_gl_context_info param_name, - size_t param_value_size, void* param_value, size_t* param_value_size_ret)) { - cl_int errcode=0; - cl_device_id* gpu_devices; - cl_uint num_gpu_devices = 0; - amd::Context::Info info; - static const bool VALIDATE_ONLY = true; - - errcode = amd::Context::checkProperties(properties, &info); - if (CL_SUCCESS != errcode) { - return errcode; - } - - if (!(info.flags_ & amd::Context::GLDeviceKhr)) { - // No GL context is specified - return CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR; - } - - // Get devices - //errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, 0, NULL, &num_gpu_devices); - if (errcode != CL_SUCCESS && errcode != CL_DEVICE_NOT_FOUND) { - return CL_INVALID_VALUE; - } - - if (!num_gpu_devices) { - return CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR; - } - - switch (param_name) { - case CL_CURRENT_DEVICE_FOR_GL_CONTEXT_KHR: - // Return the CL device currently associated with the specified OpenGL context. - if (num_gpu_devices) { - gpu_devices = (cl_device_id*)alloca(num_gpu_devices * sizeof(cl_device_id)); - - //errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, num_gpu_devices, gpu_devices, NULL); - if (errcode != CL_SUCCESS) { - return errcode; - } - - for (cl_uint i = 0; i < num_gpu_devices; ++i) { - cl_device_id device = gpu_devices[i]; - if (is_valid(device) && - as_amd(device)->bindExternalDevice(info.flags_, info.hDev_, info.hCtx_, - VALIDATE_ONLY)) { - return amd::clGetInfo(device, param_value_size, param_value, param_value_size_ret); - } - } - - *not_null(param_value_size_ret) = 0; - } - break; - - case CL_DEVICES_FOR_GL_CONTEXT_KHR: { - // List of all CL devices that can be associated with the specified OpenGL context. - cl_uint total_devices = num_gpu_devices; - size_t size = total_devices * sizeof(cl_device_id); - - cl_device_id* devices = (cl_device_id*)alloca(size); - - //errcode = clGetDeviceIDs(NULL, CL_DEVICE_TYPE_GPU, total_devices, devices, NULL); - if (errcode != CL_SUCCESS) { - return errcode; - } - - std::vector compatible_devices; - - for (cl_uint i = 0; i < total_devices; ++i) { - cl_device_id device = devices[i]; - if (is_valid(device) && - as_amd(device)->bindExternalDevice(info.flags_, info.hDev_, info.hCtx_, - VALIDATE_ONLY)) { - compatible_devices.push_back(as_amd(device)); - } - } - - size_t deviceCount = compatible_devices.size(); - size_t deviceCountSize = deviceCount * sizeof(cl_device_id); - - if (param_value != NULL && param_value_size < deviceCountSize) { - return CL_INVALID_VALUE; - } - - *not_null(param_value_size_ret) = deviceCountSize; - - if (param_value != NULL) { - cl_device_id* deviceList = (cl_device_id*)param_value; - for (const auto& it : compatible_devices) { - *deviceList++ = as_cl(it); - } - } - - return CL_SUCCESS; - } break; - - default: - LogWarning("\"param_name\" is not valid"); - return CL_INVALID_VALUE; - } - return CL_SUCCESS; -} -RUNTIME_EXIT - -// -// -// namespace amd -// -// -namespace amd { - -typedef struct { - GLenum glBinding; - GLenum glTarget; -} TargetBindings_t; - -/*! @} - * \addtogroup CL-GL interop helper functions - * @{ - */ - -//! Function clearGLErrors() to clear all GL error bits, if any -void clearGLErrors(const Context& amdContext) { - GLenum glErr, glLastErr = GL_NO_ERROR; - while (1) { - glErr = amdContext.glenv()->glGetError_(); - if (glErr == GL_NO_ERROR || glErr == glLastErr) { - break; - } - glLastErr = glErr; - LogWarning("GL error"); - } -} - -GLenum checkForGLError(const Context& amdContext) { - GLenum glRetErr = GL_NO_ERROR; - GLenum glErr; - while (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - glRetErr = glErr; // Just return the last GL error - LogWarning("Check GL error"); - } - return glRetErr; -} - -//! Function getCLFormatFromGL returns "true" if GL format -//! is compatible with CL format, "false" otherwise. -bool getCLFormatFromGL(const Context& amdContext, GLint gliInternalFormat, - cl_image_format* pclImageFormat, int* piBytesPerPixel, cl_mem_flags flags) { - bool bRetVal = false; - - /* - Available values for "image_channel_order" - ========================================== - CL_R - CL_A - CL_INTENSITY - CL_LUMINANCE - CL_RG - CL_RA - CL_RGB - CL_RGBA - CL_ARGB - CL_BGRA - - Available values for "image_channel_data_type" - ============================================== - CL_SNORM_INT8 - CL_SNORM_INT16 - CL_UNORM_INT8 - CL_UNORM_INT16 - CL_UNORM_SHORT_565 - CL_UNORM_SHORT_555 - CL_UNORM_INT_101010 - CL_SIGNED_INT8 - CL_SIGNED_INT16 - CL_SIGNED_INT32 - CL_UNSIGNED_INT8 - CL_UNSIGNED_INT16 - CL_UNSIGNED_INT32 - CL_HALF_FLOAT - CL_FLOAT - */ - - switch (gliInternalFormat) { - case GL_RGB10_EXT: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = CL_UNORM_INT_101010; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_RGB10_A2: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = CL_UNORM_INT_101010; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_BGR8_ATI: - case GL_BGRA8_ATI: - pclImageFormat->image_channel_order = CL_BGRA; - pclImageFormat->image_channel_data_type = CL_UNORM_INT8; // CL_UNSIGNED_INT8; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_ALPHA8: - pclImageFormat->image_channel_order = CL_A; - pclImageFormat->image_channel_data_type = CL_UNORM_INT8; // CL_UNSIGNED_INT8; - *piBytesPerPixel = 1; - bRetVal = true; - break; - - case GL_R8: - case GL_R8UI: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_R8) ? CL_UNORM_INT8 : CL_UNSIGNED_INT8; - *piBytesPerPixel = 1; - bRetVal = true; - break; - - case GL_R8I: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT8; - *piBytesPerPixel = 1; - bRetVal = true; - break; - - case GL_RG8: - case GL_RG8UI: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_RG8) ? CL_UNORM_INT8 : CL_UNSIGNED_INT8; - *piBytesPerPixel = 2; - bRetVal = true; - break; - - case GL_RG8I: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT8; - *piBytesPerPixel = 2; - bRetVal = true; - break; - - case GL_RGB8: - case GL_RGB8UI: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_RGB8) ? CL_UNORM_INT8 : CL_UNSIGNED_INT8; - *piBytesPerPixel = 3; - bRetVal = true; - break; - - case GL_RGB8I: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT8; - *piBytesPerPixel = 3; - bRetVal = true; - break; - - case GL_RGBA: - case GL_RGBA8: - case GL_RGBA8UI: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_RGBA8UI) ? CL_UNSIGNED_INT8 : CL_UNORM_INT8; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_RGBA8I: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT8; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_R16: - case GL_R16UI: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_R16) ? CL_UNORM_INT16 : CL_UNSIGNED_INT16; - bRetVal = true; - *piBytesPerPixel = 2; - break; - - case GL_R16I: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT16; - *piBytesPerPixel = 2; - bRetVal = true; - break; - - case GL_R16F: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = CL_HALF_FLOAT; - *piBytesPerPixel = 2; - bRetVal = true; - break; - - case GL_RG16: - case GL_RG16UI: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_RG16) ? CL_UNORM_INT16 : CL_UNSIGNED_INT16; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_RG16I: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT16; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_RG16F: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = CL_HALF_FLOAT; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_RGB16: - case GL_RGB16UI: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_RGB16) ? CL_UNORM_INT16 : CL_UNSIGNED_INT16; - *piBytesPerPixel = 6; - bRetVal = true; - break; - - case GL_RGB16I: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT16; - *piBytesPerPixel = 6; - bRetVal = true; - break; - - case GL_RGB16F: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = CL_HALF_FLOAT; - *piBytesPerPixel = 6; - bRetVal = true; - break; - - case GL_RGBA16: - case GL_RGBA16UI: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = - (gliInternalFormat == GL_RGBA16) ? CL_UNORM_INT16 : CL_UNSIGNED_INT16; - *piBytesPerPixel = 8; - bRetVal = true; - break; - - case GL_RGBA16I: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT16; - *piBytesPerPixel = 8; - bRetVal = true; - break; - - case GL_RGBA16F: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = CL_HALF_FLOAT; - *piBytesPerPixel = 8; - bRetVal = true; - break; - - case GL_R32I: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT32; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_R32UI: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = CL_UNSIGNED_INT32; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_R32F: - pclImageFormat->image_channel_order = CL_R; - pclImageFormat->image_channel_data_type = CL_FLOAT; - *piBytesPerPixel = 4; - bRetVal = true; - break; - - case GL_RG32I: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT32; - *piBytesPerPixel = 8; - bRetVal = true; - break; - - case GL_RG32UI: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = CL_UNSIGNED_INT32; - *piBytesPerPixel = 8; - bRetVal = true; - break; - - case GL_RG32F: - pclImageFormat->image_channel_order = CL_RG; - pclImageFormat->image_channel_data_type = CL_FLOAT; - *piBytesPerPixel = 8; - bRetVal = true; - break; - - case GL_RGB32I: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT32; - *piBytesPerPixel = 12; - bRetVal = true; - break; - - case GL_RGB32UI: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = CL_UNSIGNED_INT32; - *piBytesPerPixel = 12; - bRetVal = true; - break; - - case GL_RGB32F: - pclImageFormat->image_channel_order = CL_RGB; - pclImageFormat->image_channel_data_type = CL_FLOAT; - *piBytesPerPixel = 12; - bRetVal = true; - break; - - case GL_RGBA32I: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = CL_SIGNED_INT32; - *piBytesPerPixel = 16; - bRetVal = true; - break; - - case GL_RGBA32UI: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = CL_UNSIGNED_INT32; - *piBytesPerPixel = 16; - bRetVal = true; - break; - - case GL_RGBA32F: - pclImageFormat->image_channel_order = CL_RGBA; - pclImageFormat->image_channel_data_type = CL_FLOAT; - *piBytesPerPixel = 16; - bRetVal = true; - break; - case GL_DEPTH_COMPONENT32F: - pclImageFormat->image_channel_order = CL_DEPTH; - pclImageFormat->image_channel_data_type = CL_FLOAT; - *piBytesPerPixel = 4; - bRetVal = true; - break; - case GL_DEPTH_COMPONENT16: - pclImageFormat->image_channel_order = CL_DEPTH; - pclImageFormat->image_channel_data_type = CL_UNORM_INT16; - *piBytesPerPixel = 2; - bRetVal = true; - break; - case GL_DEPTH24_STENCIL8: - pclImageFormat->image_channel_order = CL_DEPTH_STENCIL; - pclImageFormat->image_channel_data_type = CL_UNORM_INT24; - *piBytesPerPixel = 4; - bRetVal = true; - break; - case GL_DEPTH32F_STENCIL8: - pclImageFormat->image_channel_order = CL_DEPTH_STENCIL; - pclImageFormat->image_channel_data_type = CL_FLOAT; - *piBytesPerPixel = 5; - bRetVal = true; - break; - default: - LogWarning("unsupported GL internal format"); - break; - } - amd::Image::Format imageFormat(*pclImageFormat); - if (bRetVal && !imageFormat.isSupported(amdContext, 0, flags)) { - bRetVal = false; - } - return bRetVal; -} - -void BufferGL::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(BufferGL)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -static GLenum clChannelDataTypeToGlType(cl_channel_type channel_type) { - // Pick - // GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_INT, - // GL_UNSIGNED_INT, GL_FLOAT, GL_2_BYTES, GL_3_BYTES, GL_4_BYTES - // or GL_DOUBLE - switch (channel_type) { - case CL_SNORM_INT8: - return GL_BYTE; - case CL_SNORM_INT16: - return GL_SHORT; - case CL_UNORM_INT8: - return GL_UNSIGNED_BYTE; - case CL_UNORM_INT16: - return GL_UNSIGNED_SHORT; - case CL_SIGNED_INT8: - return GL_BYTE; - case CL_SIGNED_INT16: - return GL_SHORT; - case CL_SIGNED_INT32: - return GL_INT; - case CL_UNSIGNED_INT8: - return GL_UNSIGNED_BYTE; - case CL_UNSIGNED_INT16: - return GL_UNSIGNED_SHORT; - case CL_UNSIGNED_INT32: - return GL_UNSIGNED_INT; - case CL_FLOAT: - return GL_FLOAT; - case CL_UNORM_INT_101010: - return GL_UNSIGNED_INT_10_10_10_2; - case CL_HALF_FLOAT: - case CL_UNORM_SHORT_565: - case CL_UNORM_SHORT_555: - default: - guarantee(false, "Unexpected CL type."); - return 0; - } -} - -static GLenum glInternalFormatToGlFormat(GLenum internalFormat) { - switch (internalFormat) { - // Base internal formats - case GL_RGBA: - case GL_BGRA: - return internalFormat; - // Sized internal formats - case GL_RGBA8: - case GL_RGBA16: - case GL_RGBA16F: - case GL_RGBA32F: - return GL_RGBA; - case GL_RGBA8I: - case GL_RGBA8UI: - case GL_RGBA16I: - case GL_RGBA16UI: - case GL_RGBA32I: - case GL_RGBA32UI: - return GL_RGBA_INTEGER; - - default: - guarantee(false, "Unexpected GL internal format."); - return 0; - } -} - -void ImageGL::initDeviceMemory() { - deviceMemories_ = - reinterpret_cast(reinterpret_cast(this) + sizeof(ImageGL)); - memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory)); -} - -//******************************************************************* -// -// Internal implementation of CL API functions -// -//******************************************************************* - -// -// clCreateFromGLBufferAMD -// -cl_mem clCreateFromGLBufferAMD(Context& amdContext, cl_mem_flags flags, GLuint bufobj, - cl_int* errcode_ret) { - BufferGL* pBufferGL = NULL; - GLenum glErr; - GLenum glTarget = GL_ARRAY_BUFFER; - GLint gliSize = 0; - GLint gliMapped = 0; - - // Verify context init'ed for interop - if (!amdContext.glenv() || !amdContext.glenv()->isAssociated()) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from GL context or share list"); - return (cl_mem)0; - } - - // Add this scope to bound the scoped lock - { - GLFunctions::SetIntEnv ie(amdContext.glenv()); - if (!ie.isValid()) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from GL context or share list"); - return as_cl(0); - } - - // Verify GL buffer object - clearGLErrors(amdContext); - if ((GL_FALSE == amdContext.glenv()->glIsBuffer_(bufobj)) || - (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_()))) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("\"bufobj\" is not a GL buffer object"); - return (cl_mem)0; - } - - // It seems that CL spec is not concerned with GL_BUFFER_USAGE, so skip it - - // Check if size is available - data store is created - - amdContext.glenv()->glBindBuffer_(glTarget, bufobj); - clearGLErrors(amdContext); - amdContext.glenv()->glGetBufferParameteriv_(glTarget, GL_BUFFER_SIZE, &gliSize); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("cannot get the GL buffer size"); - return (cl_mem)0; - } - if (gliSize == 0) { - //@todo - check why sometime the size is zero - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("the GL buffer's data store is not created"); - return (cl_mem)0; - } - - // Mapping will be done at acquire time (sync point) - - } // Release scoped lock - - // Now create BufferGL object - pBufferGL = new (amdContext) BufferGL(amdContext, flags, gliSize, 0, bufobj); - - if (!pBufferGL) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - LogWarning("cannot create object of class BufferGL"); - return (cl_mem)0; - } - - if (!pBufferGL->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pBufferGL->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - - // Create interop object - if (pBufferGL->getInteropObj() == NULL) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("cannot create object of class BufferGL"); - return (cl_mem)0; - } - - // Fixme: If more than one device is present in the context, we choose the first device. - // We should come up with a more elegant solution to handle this. - assert(amdContext.devices().size() == 1); - - const auto it = amdContext.devices().cbegin(); - const amd::Device& dev = *(*it); - - device::Memory* mem = pBufferGL->getDeviceMemory(dev); - if (NULL == mem) { - LogPrintfError("Can't allocate memory size - 0x%08X bytes!", pBufferGL->getSize()); - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - return (cl_mem)0; - } - mem->processGLResource(device::Memory::GLDecompressResource); - - return as_cl(pBufferGL); -} - -cl_mem clCreateFromGLTextureAMD(Context& amdContext, cl_mem_flags clFlags, GLenum target, - GLint miplevel, GLuint texture, int* errcode_ret) { - ImageGL* pImageGL = NULL; - GLenum glErr; - GLenum glTarget = 0; - GLenum glInternalFormat; - cl_image_format clImageFormat; - uint dim = 1; - cl_mem_object_type clType; - cl_gl_object_type clGLType; - GLsizei numSamples = 1; - - // Verify context init'ed for interop - if (!amdContext.glenv() || !amdContext.glenv()->isAssociated()) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from GL context or share list"); - return static_cast(0); - } - - GLint gliTexWidth = 1; - GLint gliTexHeight = 1; - GLint gliTexDepth = 1; - - // Add this scope to bound the scoped lock - { - GLFunctions::SetIntEnv ie(amdContext.glenv()); - if (!ie.isValid()) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from GL context or share list"); - return as_cl(0); - } - - // Verify GL texture object - clearGLErrors(amdContext); - if ((GL_FALSE == amdContext.glenv()->glIsTexture_(texture)) || - (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_()))) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("\"texture\" is not a GL texture object"); - return static_cast(0); - } - - bool image = true; - - // Check target value validity - switch (target) { - case GL_TEXTURE_BUFFER: - glTarget = GL_TEXTURE_BUFFER; - dim = 1; - clType = CL_MEM_OBJECT_IMAGE1D_BUFFER; - clGLType = CL_GL_OBJECT_TEXTURE_BUFFER; - image = false; - break; - - case GL_TEXTURE_1D: - glTarget = GL_TEXTURE_1D; - dim = 1; - clType = CL_MEM_OBJECT_IMAGE1D; - clGLType = CL_GL_OBJECT_TEXTURE1D; - break; - - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - glTarget = GL_TEXTURE_CUBE_MAP; - dim = 2; - clType = CL_MEM_OBJECT_IMAGE2D; - clGLType = CL_GL_OBJECT_TEXTURE2D; - break; - - case GL_TEXTURE_1D_ARRAY: - glTarget = GL_TEXTURE_1D_ARRAY; - dim = 2; - clType = CL_MEM_OBJECT_IMAGE1D_ARRAY; - clGLType = CL_GL_OBJECT_TEXTURE1D_ARRAY; - break; - - case GL_TEXTURE_2D: - glTarget = GL_TEXTURE_2D; - dim = 2; - clType = CL_MEM_OBJECT_IMAGE2D; - clGLType = CL_GL_OBJECT_TEXTURE2D; - break; - - case GL_TEXTURE_2D_MULTISAMPLE: - glTarget = GL_TEXTURE_2D_MULTISAMPLE; - dim = 2; - clType = CL_MEM_OBJECT_IMAGE2D; - clGLType = CL_GL_OBJECT_TEXTURE2D; - break; - - case GL_TEXTURE_RECTANGLE_ARB: - glTarget = GL_TEXTURE_RECTANGLE_ARB; - dim = 2; - clType = CL_MEM_OBJECT_IMAGE2D; - clGLType = CL_GL_OBJECT_TEXTURE2D; - break; - - case GL_TEXTURE_2D_ARRAY: - glTarget = GL_TEXTURE_2D_ARRAY; - dim = 3; - clType = CL_MEM_OBJECT_IMAGE2D_ARRAY; - clGLType = CL_GL_OBJECT_TEXTURE2D_ARRAY; - break; - - case GL_TEXTURE_3D: - glTarget = GL_TEXTURE_3D; - dim = 3; - clType = CL_MEM_OBJECT_IMAGE3D; - clGLType = CL_GL_OBJECT_TEXTURE3D; - break; - - default: - // wrong value - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid \"target\" value"); - return static_cast(0); - break; - } - - amdContext.glenv()->glBindTexture_(glTarget, texture); - - // Check if size is available - data store is created - if (image) { - // Check mipmap level for "texture" name - GLint gliTexBaseLevel; - GLint gliTexMaxLevel; - - clearGLErrors(amdContext); - amdContext.glenv()->glGetTexParameteriv_(glTarget, GL_TEXTURE_BASE_LEVEL, &gliTexBaseLevel); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_MIP_LEVEL; - LogWarning("Cannot get base mipmap level of a GL \"texture\" object"); - return static_cast(0); - } - clearGLErrors(amdContext); - amdContext.glenv()->glGetTexParameteriv_(glTarget, GL_TEXTURE_MAX_LEVEL, &gliTexMaxLevel); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_MIP_LEVEL; - LogWarning("Cannot get max mipmap level of a GL \"texture\" object"); - return static_cast(0); - } - if ((gliTexBaseLevel > miplevel) || (miplevel > gliTexMaxLevel)) { - *not_null(errcode_ret) = CL_INVALID_MIP_LEVEL; - LogWarning("\"miplevel\" is not a valid mipmap level of the GL \"texture\" object"); - return static_cast(0); - } - - // Get GL texture format and check if it's compatible with CL format - clearGLErrors(amdContext); - amdContext.glenv()->glGetTexLevelParameteriv_(target, miplevel, GL_TEXTURE_INTERNAL_FORMAT, - (GLint*)&glInternalFormat); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("Cannot get internal format of \"miplevel\" of GL \"texture\" object"); - return static_cast(0); - } - - amdContext.glenv()->glGetTexLevelParameteriv_(target, miplevel, GL_TEXTURE_SAMPLES, - (GLint*)&numSamples); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("Cannot get numbers of samples of GL \"texture\" object"); - return static_cast(0); - } - if (numSamples > 1) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("MSAA \"texture\" object is not suppoerted for the device"); - return static_cast(0); - } - - // Now get CL format from GL format and bytes per pixel - int iBytesPerPixel = 0; - if (!getCLFormatFromGL(amdContext, glInternalFormat, &clImageFormat, &iBytesPerPixel, - clFlags)) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("\"texture\" format does not map to an appropriate CL image format"); - return static_cast(0); - } - - switch (dim) { - case 3: - clearGLErrors(amdContext); - amdContext.glenv()->glGetTexLevelParameteriv_(target, miplevel, GL_TEXTURE_DEPTH, - &gliTexDepth); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("Cannot get the depth of \"miplevel\" of GL \"texure\""); - return static_cast(0); - } - // Fall trough to process other dimensions... - case 2: - clearGLErrors(amdContext); - amdContext.glenv()->glGetTexLevelParameteriv_(target, miplevel, GL_TEXTURE_HEIGHT, - &gliTexHeight); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("Cannot get the height of \"miplevel\" of GL \"texure\""); - return static_cast(0); - } - // Fall trough to process other dimensions... - case 1: - clearGLErrors(amdContext); - amdContext.glenv()->glGetTexLevelParameteriv_(target, miplevel, GL_TEXTURE_WIDTH, - &gliTexWidth); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("Cannot get the width of \"miplevel\" of GL \"texure\""); - return static_cast(0); - } - break; - default: - *not_null(errcode_ret) = CL_INVALID_VALUE; - LogWarning("invalid \"target\" value"); - return static_cast(0); - } - } else { - GLint size; - - // In case target is GL_TEXTURE_BUFFER - GLint backingBuffer; - clearGLErrors(amdContext); - amdContext.glenv()->glGetTexLevelParameteriv_( - glTarget, 0, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, &backingBuffer); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("Cannot get backing buffer for GL \"texture buffer\" object"); - return static_cast(0); - } - amdContext.glenv()->glBindBuffer_(glTarget, backingBuffer); - - // Get GL texture format and check if it's compatible with CL format - clearGLErrors(amdContext); - amdContext.glenv()->glGetIntegerv_(GL_TEXTURE_BUFFER_FORMAT_EXT, - reinterpret_cast(&glInternalFormat)); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("Cannot get internal format of \"miplevel\" of GL \"texture\" object"); - return static_cast(0); - } - - // Now get CL format from GL format and bytes per pixel - int iBytesPerPixel = 0; - if (!getCLFormatFromGL(amdContext, glInternalFormat, &clImageFormat, &iBytesPerPixel, - clFlags)) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("\"texture\" format does not map to an appropriate CL image format"); - return static_cast(0); - } - - clearGLErrors(amdContext); - amdContext.glenv()->glGetBufferParameteriv_(glTarget, GL_BUFFER_SIZE, &size); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("Cannot get internal format of \"miplevel\" of GL \"texture\" object"); - return static_cast(0); - } - - gliTexWidth = size / iBytesPerPixel; - } - size_t imageSize = (clType == CL_MEM_OBJECT_IMAGE1D_ARRAY) ? static_cast(gliTexHeight) - : static_cast(gliTexDepth); - - if (!amd::Image::validateDimensions( - amdContext.devices(), clType, static_cast(gliTexWidth), - static_cast(gliTexHeight), static_cast(gliTexDepth), imageSize)) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("The GL \"texture\" data store is not created or out of supported dimensions"); - return static_cast(0); - } - - // PBO and mapping will be done at "acquire" time (sync point) - - } // Release scoped lock - - target = (glTarget == GL_TEXTURE_CUBE_MAP) ? target : 0; - - pImageGL = new (amdContext) - ImageGL(amdContext, clType, clFlags, clImageFormat, static_cast(gliTexWidth), - static_cast(gliTexHeight), static_cast(gliTexDepth), glTarget, - texture, miplevel, glInternalFormat, clGLType, numSamples, target); - - if (!pImageGL) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - LogWarning("Cannot create class ImageGL - out of memory?"); - return static_cast(0); - } - - if (!pImageGL->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImageGL->release(); - return static_cast(0); - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImageGL); -} - -// -// clCreateFromGLRenderbufferDAMD -// -cl_mem clCreateFromGLRenderbufferAMD(Context& amdContext, cl_mem_flags clFlags, GLuint renderbuffer, - int* errcode_ret) { - ImageGL* pImageGL = NULL; - GLenum glErr; - - GLenum glTarget = GL_RENDERBUFFER; - GLenum glInternalFormat; - cl_image_format clImageFormat; - - // Verify context init'ed for interop - if (!amdContext.glenv() || !amdContext.glenv()->isAssociated()) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from GL context or share list"); - return (cl_mem)0; - } - - GLint gliRbWidth; - GLint gliRbHeight; - - // Add this scope to bound the scoped lock - { - GLFunctions::SetIntEnv ie(amdContext.glenv()); - if (!ie.isValid()) { - *not_null(errcode_ret) = CL_INVALID_CONTEXT; - LogWarning("\"amdContext\" is not created from GL context or share list"); - return as_cl(0); - } - - // Verify GL renderbuffer object - clearGLErrors(amdContext); - if ((GL_FALSE == amdContext.glenv()->glIsRenderbufferEXT_(renderbuffer)) || - (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_()))) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("\"renderbuffer\" is not a GL texture object"); - return (cl_mem)0; - } - - amdContext.glenv()->glBindRenderbuffer_(glTarget, renderbuffer); - - // Get GL RB format and check if it's compatible with CL format - clearGLErrors(amdContext); - amdContext.glenv()->glGetRenderbufferParameterivEXT_(glTarget, GL_RENDERBUFFER_INTERNAL_FORMAT, - (GLint*)&glInternalFormat); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("Cannot get internal format of GL \"renderbuffer\" object"); - return (cl_mem)0; - } - - // Now get CL format from GL format and bytes per pixel - int iBytesPerPixel = 0; - if (!getCLFormatFromGL(amdContext, glInternalFormat, &clImageFormat, &iBytesPerPixel, - clFlags)) { - *not_null(errcode_ret) = CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; - LogWarning("\"renderbuffer\" format does not map to an appropriate CL image format"); - return (cl_mem)0; - } - - // Check if size is available - data store is created - clearGLErrors(amdContext); - amdContext.glenv()->glGetRenderbufferParameterivEXT_(glTarget, GL_RENDERBUFFER_WIDTH, - &gliRbWidth); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("Cannot get the width of GL \"renderbuffer\""); - return (cl_mem)0; - } - if (gliRbWidth == 0) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("The GL \"renderbuffer\" data store is not created"); - return (cl_mem)0; - } - clearGLErrors(amdContext); - amdContext.glenv()->glGetRenderbufferParameterivEXT_(glTarget, GL_RENDERBUFFER_HEIGHT, - &gliRbHeight); - if (GL_NO_ERROR != (glErr = amdContext.glenv()->glGetError_())) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("Cannot get the height of GL \"renderbuffer\""); - return (cl_mem)0; - } - if (gliRbHeight == 0) { - *not_null(errcode_ret) = CL_INVALID_GL_OBJECT; - LogWarning("The GL \"renderbuffer\" data store is not created"); - return (cl_mem)0; - } - - // PBO and mapping will be done at "acquire" time (sync point) - - } // Release scoped lock - - pImageGL = - new (amdContext) ImageGL(amdContext, CL_MEM_OBJECT_IMAGE2D, clFlags, clImageFormat, - (size_t)gliRbWidth, (size_t)gliRbHeight, 1, glTarget, renderbuffer, - 0, glInternalFormat, CL_GL_OBJECT_RENDERBUFFER, 0); - - if (!pImageGL) { - *not_null(errcode_ret) = CL_OUT_OF_HOST_MEMORY; - LogWarning("Cannot create class ImageGL from renderbuffer - out of memory?"); - return (cl_mem)0; - } - - if (!pImageGL->create()) { - *not_null(errcode_ret) = CL_MEM_OBJECT_ALLOCATION_FAILURE; - pImageGL->release(); - return (cl_mem)0; - } - - *not_null(errcode_ret) = CL_SUCCESS; - return as_cl(pImageGL); -} - -// -// clEnqueueAcquireExtObjectsAMD -// - -static cl_int clSetInteropObjects(cl_uint num_objects, const cl_mem* mem_objects, - std::vector& interopObjects) { - if ((num_objects == 0 && mem_objects != NULL) || (num_objects != 0 && mem_objects == NULL)) { - return CL_INVALID_VALUE; - } - - while (num_objects-- > 0) { - cl_mem obj = *mem_objects++; - if (!is_valid(obj)) { - return CL_INVALID_MEM_OBJECT; - } - - amd::Memory* mem = as_amd(obj); - if (mem->getInteropObj() == NULL) { - return CL_INVALID_GL_OBJECT; - } - - interopObjects.push_back(mem); - } - return CL_SUCCESS; -} - -cl_int clEnqueueAcquireExtObjectsAMD(cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event, - cl_command_type cmd_type) { - if (!is_valid(command_queue)) { - return CL_INVALID_COMMAND_QUEUE; - } - - amd::HostQueue* queue = as_amd(command_queue)->asHostQueue(); - if (NULL == queue) { - return CL_INVALID_COMMAND_QUEUE; - } - amd::HostQueue& hostQueue = *queue; - - if (cmd_type == CL_COMMAND_ACQUIRE_GL_OBJECTS) { - // Verify context init'ed for interop - if (!hostQueue.context().glenv() || !hostQueue.context().glenv()->isAssociated()) { - LogWarning("\"amdContext\" is not created from GL context or share list"); - return CL_INVALID_CONTEXT; - } - } - - std::vector memObjects; - cl_int err = clSetInteropObjects(num_objects, mem_objects, memObjects); - if (err != CL_SUCCESS) { - return err; - } - - amd::Command::EventWaitList eventWaitList; - err = amd::clSetEventWaitList(eventWaitList, hostQueue, num_events_in_wait_list, - event_wait_list); - if (err != CL_SUCCESS) { - return err; - } - -#ifdef _WIN32 - if ((hostQueue.context().info().flags_ & amd::Context::InteropUserSync) == 0) { - //! Make sure D3D10 queues are flushed and all commands are finished - //! before CL side would access interop objects - if (cmd_type == CL_COMMAND_ACQUIRE_D3D10_OBJECTS_KHR) { - SyncD3D10Objects(memObjects); - } - //! Make sure D3D11 queues are flushed and all commands are finished - //! before CL side would access interop objects - if (cmd_type == CL_COMMAND_ACQUIRE_D3D11_OBJECTS_KHR) { - SyncD3D11Objects(memObjects); - } - //! Make sure D3D9 queues are flushed and all commands are finished - //! before CL side would access interop objects - if (cmd_type == CL_COMMAND_ACQUIRE_DX9_MEDIA_SURFACES_KHR) { - SyncD3D9Objects(memObjects); - } - } -#endif //_WIN32 - - //! Now create command and enqueue - amd::AcquireExtObjectsCommand* command = new amd::AcquireExtObjectsCommand( - hostQueue, eventWaitList, num_objects, memObjects, cmd_type); - if (command == NULL) { - return CL_OUT_OF_HOST_MEMORY; - } - - // Make sure we have memory for the command execution - if (!command->validateMemory()) { - delete command; - return CL_MEM_OBJECT_ALLOCATION_FAILURE; - } - - command->enqueue(); - - *not_null(event) = as_cl(&command->event()); - if (event == NULL) { - command->release(); - } - return CL_SUCCESS; -} - - -// -// clEnqueueReleaseExtObjectsAMD -// -cl_int clEnqueueReleaseExtObjectsAMD(cl_command_queue command_queue, cl_uint num_objects, - const cl_mem* mem_objects, cl_uint num_events_in_wait_list, - const cl_event* event_wait_list, cl_event* event, - cl_command_type cmd_type) { - if (!is_valid(command_queue)) { - return CL_INVALID_COMMAND_QUEUE; - } - - amd::HostQueue* queue = as_amd(command_queue)->asHostQueue(); - if (NULL == queue) { - return CL_INVALID_COMMAND_QUEUE; - } - amd::HostQueue& hostQueue = *queue; - - std::vector memObjects; - cl_int err = clSetInteropObjects(num_objects, mem_objects, memObjects); - if (err != CL_SUCCESS) { - return err; - } - - amd::Command::EventWaitList eventWaitList; - err = amd::clSetEventWaitList(eventWaitList, hostQueue, num_events_in_wait_list, - event_wait_list); - if (err != CL_SUCCESS) { - return err; - } - - //! Now create command and enqueue - amd::ReleaseExtObjectsCommand* command = new amd::ReleaseExtObjectsCommand( - hostQueue, eventWaitList, num_objects, memObjects, cmd_type); - if (command == NULL) { - return CL_OUT_OF_HOST_MEMORY; - } - - // Make sure we have memory for the command execution - if (!command->validateMemory()) { - delete command; - return CL_MEM_OBJECT_ALLOCATION_FAILURE; - } - - command->enqueue(); - -#ifdef _WIN32 - if ((hostQueue.context().info().flags_ & amd::Context::InteropUserSync) == 0) { - //! Make sure CL command queue is flushed and all commands are finished - //! before D3D10 side would access interop resources - if (cmd_type == CL_COMMAND_RELEASE_DX9_MEDIA_SURFACES_KHR || - cmd_type == CL_COMMAND_RELEASE_D3D10_OBJECTS_KHR || - cmd_type == CL_COMMAND_RELEASE_D3D11_OBJECTS_KHR) { - command->awaitCompletion(); - } - } -#endif //_WIN32 - - *not_null(event) = as_cl(&command->event()); - - if (event == NULL) { - command->release(); - } - - return CL_SUCCESS; -} - -// Placed here as opposed to command.cpp, as glext.h and cl_gl_amd.hpp will have -// to be included because of the GL calls -bool ClGlEvent::waitForFence() { - GLenum ret; - // get fence id associated with fence event - GLsync gs = reinterpret_cast(command().data()); - if (!gs) return false; - -// Try to use DC and GLRC of current thread, if it doesn't exist -// create a new GL context on this thread, which is shared with the original context - -#ifdef _WIN32 - HDC tempDC_ = wglGetCurrentDC(); - HGLRC tempGLRC_ = wglGetCurrentContext(); - // Set DC and GLRC - if (tempDC_ && tempGLRC_) { - ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT, - static_cast(-1)); - if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false; - } else { - tempDC_ = context().glenv()->getDC(); - tempGLRC_ = context().glenv()->getIntGLRC(); - if (!context().glenv()->init(reinterpret_cast(tempDC_), - reinterpret_cast(tempGLRC_))) - return false; - - // Make the newly created GL context current to this thread - context().glenv()->setIntEnv(); - // If fence has not yet executed, wait till it finishes - ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT, - static_cast(-1)); - if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false; - // Since we're done making GL calls, restore whatever context was previously current to this - // thread - context().glenv()->restoreEnv(); - } -#else // Lnx - Display* tempDpy_ = context().glenv()->glXGetCurrentDisplay_(); - GLXDrawable tempDrawable_ = context().glenv()->glXGetCurrentDrawable_(); - GLXContext tempCtx_ = context().glenv()->glXGetCurrentContext_(); - // Set internal Display and GLXContext - if (tempDpy_ && tempCtx_) { - ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT, - static_cast(-1)); - if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false; - } else { - if (!context().glenv()->init(reinterpret_cast(context().glenv()->getIntDpy()), - reinterpret_cast(context().glenv()->getIntCtx()))) - return false; - - // Make the newly created GL context current to this thread - context().glenv()->setIntEnv(); - // If fence has not yet executed, wait till it finishes - ret = context().glenv()->glClientWaitSync_(gs, GL_SYNC_FLUSH_COMMANDS_BIT, - static_cast(-1)); - if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false; - // Since we're done making GL calls, restore whatever context was previously current to this - // thread - context().glenv()->restoreEnv(); - } -#endif - // If we reach this point, fence should have completed - setStatus(CL_COMPLETE); - return true; -} - -// -// GLFunctions implementation -// - -#ifdef _WIN32 -#define CONVERT_CHAR_GLUBYTE -#else //!_WIN32 -#define CONVERT_CHAR_GLUBYTE (GLubyte*) -#endif //!_WIN32 - -#define GLPREFIX(rtype, fcn, dclargs) \ - if (!(fcn##_ = (PFN_##fcn)GETPROCADDRESS(libHandle_, #fcn))) { \ - if (!(fcn##_ = (PFN_##fcn)GetProcAddress_(reinterpret_cast(#fcn)))) ++missed_; \ - } - -GLFunctions::SetIntEnv::SetIntEnv(GLFunctions* env) : env_(env) { - env_->getLock().lock(); - - // Set environment (DC and GLRC) - isValid_ = env_->setIntEnv(); -} - -GLFunctions::SetIntEnv::~SetIntEnv() { - // Restore environment (CL DC and CL GLRC) - env_->restoreEnv(); - - env_->getLock().unlock(); -} - -GLFunctions::GLFunctions(HMODULE h, bool isEGL) - : libHandle_(h), - missed_(0), - eglDisplay_(EGL_NO_DISPLAY), - eglOriginalContext_(EGL_NO_CONTEXT), - eglInternalContext_(EGL_NO_CONTEXT), - eglTempContext_(EGL_NO_CONTEXT), - isEGL_(isEGL), -#ifdef _WIN32 - hOrigGLRC_(0), - hDC_(0), - hIntGLRC_(0) -#else //!_WIN32 - Dpy_(0), - Drawable_(0), - origCtx_(0), - intDpy_(0), - intDrawable_(0), - intCtx_(0), - XOpenDisplay_(NULL), - XCloseDisplay_(NULL), - glXGetCurrentDrawable_(NULL), - glXGetCurrentDisplay_(NULL), - glXGetCurrentContext_(NULL), - glXChooseVisual_(NULL), - glXCreateContext_(NULL), - glXDestroyContext_(NULL), - glXMakeCurrent_(NULL) -#endif //!_WIN32 -{ -#define VERIFY_POINTER(p) \ - if (NULL == p) { \ - missed_++; \ - } - - if (isEGL_) { - GetProcAddress_ = (PFN_xxxGetProcAddress)GETPROCADDRESS(h, "eglGetProcAddress"); - } else { - GetProcAddress_ = (PFN_xxxGetProcAddress)GETPROCADDRESS(h, API_GETPROCADDR); - } -#ifndef _WIN32 - // Initialize pointers to X11/GLX functions - // We can not link with these functions on compile time since we need to support - // console mode. In console mode X server and X server components may be absent. - // Hence linking with X11 or libGL will fail module image loading in console mode.-tzachi cohen - - if (!isEGL_) { - glXGetCurrentDrawable_ = (PFNglXGetCurrentDrawable)GETPROCADDRESS(h, "glXGetCurrentDrawable"); - VERIFY_POINTER(glXGetCurrentDrawable_) - glXGetCurrentDisplay_ = (PFNglXGetCurrentDisplay)GETPROCADDRESS(h, "glXGetCurrentDisplay"); - VERIFY_POINTER(glXGetCurrentDisplay_) - glXGetCurrentContext_ = (PFNglXGetCurrentContext)GETPROCADDRESS(h, "glXGetCurrentContext"); - VERIFY_POINTER(glXGetCurrentContext_) - glXChooseVisual_ = (PFNglXChooseVisual)GETPROCADDRESS(h, "glXChooseVisual"); - VERIFY_POINTER(glXChooseVisual_) - glXCreateContext_ = (PFNglXCreateContext)GETPROCADDRESS(h, "glXCreateContext"); - VERIFY_POINTER(glXCreateContext_) - glXDestroyContext_ = (PFNglXDestroyContext)GETPROCADDRESS(h, "glXDestroyContext"); - VERIFY_POINTER(glXDestroyContext_) - glXMakeCurrent_ = (PFNglXMakeCurrent)GETPROCADDRESS(h, "glXMakeCurrent"); - VERIFY_POINTER(glXMakeCurrent_) - - HMODULE hXModule = (HMODULE)Os::loadLibrary("libX11.so.6"); - if (NULL != hXModule) { - XOpenDisplay_ = (PFNXOpenDisplay)GETPROCADDRESS(hXModule, "XOpenDisplay"); - VERIFY_POINTER(XOpenDisplay_) - XCloseDisplay_ = (PFNXCloseDisplay)GETPROCADDRESS(hXModule, "XCloseDisplay"); - VERIFY_POINTER(XCloseDisplay_) - } else { - missed_ += 2; - } - } -// Initialize pointers to GL functions -#include "gl_functions.hpp" -#else - if (!isEGL_) { - wglCreateContext_ = (PFN_wglCreateContext)GETPROCADDRESS(h, "wglCreateContext"); - VERIFY_POINTER(wglCreateContext_) - wglGetCurrentContext_ = (PFN_wglGetCurrentContext)GETPROCADDRESS(h, "wglGetCurrentContext"); - VERIFY_POINTER(wglGetCurrentContext_) - wglGetCurrentDC_ = (PFN_wglGetCurrentDC)GETPROCADDRESS(h, "wglGetCurrentDC"); - VERIFY_POINTER(wglGetCurrentDC_) - wglDeleteContext_ = (PFN_wglDeleteContext)GETPROCADDRESS(h, "wglDeleteContext"); - VERIFY_POINTER(wglDeleteContext_) - wglMakeCurrent_ = (PFN_wglMakeCurrent)GETPROCADDRESS(h, "wglMakeCurrent"); - VERIFY_POINTER(wglMakeCurrent_) - wglShareLists_ = (PFN_wglShareLists)GETPROCADDRESS(h, "wglShareLists"); - VERIFY_POINTER(wglShareLists_) - } -#endif -} - -GLFunctions::~GLFunctions() { -#ifdef _WIN32 - if (hIntGLRC_) { - if (!wglDeleteContext_(hIntGLRC_)) { - DWORD dwErr = GetLastError(); - LogWarning("Cannot delete GLRC"); - } - } -#else //!_WIN32 - if (intDpy_) { - if (intCtx_) { - glXDestroyContext_(intDpy_, intCtx_); - intCtx_ = NULL; - } - XCloseDisplay_(intDpy_); - intDpy_ = NULL; - } -#endif //!_WIN32 -} -// in case of HIP GL interop we want to make sure we have the updated context -bool GLFunctions::update(intptr_t hglrc) { -#ifdef _WIN32 - DWORD err; - if (hOrigGLRC_ == (HGLRC)hglrc) { - return true; - } - hOrigGLRC_ = (HGLRC)hglrc; - if (hIntGLRC_ != nullptr) { - wglDeleteContext_(hIntGLRC_); - } - if (!(hIntGLRC_ = wglCreateContext_(wglGetCurrentDC_()))) { - err = GetLastError(); - return false; - } - if (!wglShareLists_(hOrigGLRC_, hIntGLRC_)) { - err = GetLastError(); - return false; - } -#else //!_WIN32 - Dpy_ = glXGetCurrentDisplay_(); - Drawable_ = glXGetCurrentDrawable_(); - if (origCtx_ == (GLXContext)hglrc) { - return true; - } - - origCtx_ = (GLXContext)hglrc; - if (intCtx_ != nullptr) { - glXDestroyContext_(Dpy_,intCtx_); - } - - int attribList[] = {GLX_RGBA, None}; - XVisualInfo* vis; - int defaultScreen = DefaultScreen(intDpy_); - if (!(vis = glXChooseVisual_(intDpy_, defaultScreen, attribList))) { - return false; - } - if (!(intCtx_ = glXCreateContext_(intDpy_, vis, origCtx_, true))) { - return false; - } -#endif - return true; -} - -bool GLFunctions::init(intptr_t hdc, intptr_t hglrc) { - if (isEGL_) { - eglDisplay_ = (EGLDisplay)hdc; - eglOriginalContext_ = (EGLContext)hglrc; - return true; - } - -#ifdef _WIN32 - DWORD err; - - if (missed_) { - return false; - } - - if (!hdc) { - hDC_ = wglGetCurrentDC_(); - } else { - hDC_ = (HDC)hdc; - } - hOrigGLRC_ = (HGLRC)hglrc; - if (!(hIntGLRC_ = wglCreateContext_(hDC_))) { - err = GetLastError(); - return false; - } - if (!wglShareLists_(hOrigGLRC_, hIntGLRC_)) { - err = GetLastError(); - return false; - } - - bool makeCurrentNull = false; - - if (wglGetCurrentContext_() == NULL) { - wglMakeCurrent_(hDC_, hIntGLRC_); - - makeCurrentNull = true; - } - -// Initialize pointers to GL functions -#include "gl_functions.hpp" - - if (makeCurrentNull) { - wglMakeCurrent_(NULL, NULL); - } - - if (missed_ == 0) { - return true; - } -#else //!_WIN32 - if (!missed_) { - if (!hdc) { - Dpy_ = glXGetCurrentDisplay_(); - } else { - Dpy_ = (Display*)hdc; - } - Drawable_ = glXGetCurrentDrawable_(); - origCtx_ = (GLXContext)hglrc; - - int attribList[] = {GLX_RGBA, None}; - if (!(intDpy_ = XOpenDisplay_(DisplayString(Dpy_)))) { -#if defined(ATI_ARCH_X86) - asm("int $3"); -#endif - } - intDrawable_ = DefaultRootWindow(intDpy_); - - XVisualInfo* vis; - int defaultScreen = DefaultScreen(intDpy_); - if (!(vis = glXChooseVisual_(intDpy_, defaultScreen, attribList))) { - return false; - } - if (!(intCtx_ = glXCreateContext_(intDpy_, vis, origCtx_, true))) { - return false; - } - return true; - } -#endif //!_WIN32 - return false; -} - -bool GLFunctions::setIntEnv() { - if (isEGL_) { - return true; - } -#ifdef _WIN32 - // Save current DC and GLRC - tempDC_ = wglGetCurrentDC_(); - tempGLRC_ = wglGetCurrentContext_(); - // Set internal DC and GLRC - if (tempDC_ != getDC() || tempGLRC_ != getIntGLRC()) { - if (!wglMakeCurrent_(getDC(), getIntGLRC())) { - DWORD err = GetLastError(); - LogWarning("cannot set internal GL environment"); - return false; - } - } -#else //!_WIN32 - tempDpy_ = glXGetCurrentDisplay_(); - tempDrawable_ = glXGetCurrentDrawable_(); - tempCtx_ = glXGetCurrentContext_(); - // Set internal Display and GLXContext - if (tempDpy_ != getDpy() || tempCtx_ != getIntCtx()) { - if (!glXMakeCurrent_(getIntDpy(), getIntDrawable(), getIntCtx())) { - LogWarning("cannot set internal GL environment"); - return false; - } - } -#endif //!_WIN32 - - return true; -} - -bool GLFunctions::restoreEnv() { - if (isEGL_) { - // eglMakeCurrent( ); - return true; - } -#ifdef _WIN32 - // Restore original DC and GLRC - if (!wglMakeCurrent_(tempDC_, tempGLRC_)) { - DWORD err = GetLastError(); - LogWarning("cannot restore original GL environment"); - return false; - } -#else //!_WIN32 - // Restore Display and GLXContext - if (tempDpy_) { - if (!glXMakeCurrent_(tempDpy_, tempDrawable_, tempCtx_)) { - LogWarning("cannot restore original GL environment"); - return false; - } - } else { - // Just release internal context - if (!glXMakeCurrent_(getIntDpy(), None, NULL)) { - LogWarning("cannot reelase internal GL environment"); - return false; - } - } -#endif //!_WIN32 - - return true; -} - -} // namespace amd diff --git a/projects/clr/hipamd/src/cl_gl_amd.hpp b/projects/clr/hipamd/src/cl_gl_amd.hpp deleted file mode 100644 index b804ba0ff0..0000000000 --- a/projects/clr/hipamd/src/cl_gl_amd.hpp +++ /dev/null @@ -1,398 +0,0 @@ -/* Copyright (c) 2010 - 2021 Advanced Micro Devices, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. */ - -#ifndef CL_GL_AMD_HPP_ -#define CL_GL_AMD_HPP_ - -#ifdef _WIN32 -#include -#else //!_WIN32 -#include -#endif //!_WIN32 - -#include -#include -#include "CL/cl_gl.h" -#ifndef _WIN32 -#include -#endif //!_WIN32 - -#include -#include -#include - -#include "platform/context.hpp" -#include "platform/command.hpp" - -namespace amd -{ - -//! Class GLObject keeps all the info about the GL object -//! from which the CL object is created -class GLObject : public InteropObject -{ -protected: - cl_gl_object_type clGLType_; //!< CL GL object type - GLenum glTarget_; - GLuint gluiName_; - GLint gliMipLevel_; - GLenum glInternalFormat_; - GLint gliWidth_; - GLint gliHeight_; - GLint gliDepth_; - GLenum glCubemapFace_; - GLsizei glNumSamples_; - -public: -//! GLObject constructor initializes member variables - GLObject( - GLenum glTarget, - GLuint gluiName, - GLint gliMipLevel, - GLenum glInternalFormat, - GLint gliWidth, - GLint gliHeight, - GLint gliDepth, - cl_gl_object_type clGLType, - GLenum glCubemapFace, - GLsizei glNumSamples - ): // Initialization of member variables - clGLType_(clGLType), - glTarget_(glTarget), - gluiName_(gluiName), - gliMipLevel_(gliMipLevel), - glInternalFormat_(glInternalFormat), - gliWidth_(gliWidth), - gliHeight_(gliHeight), - gliDepth_(gliDepth), - glCubemapFace_(glCubemapFace), - glNumSamples_(glNumSamples) - { - } - - virtual ~GLObject() {} - virtual GLObject* asGLObject() {return this;} - -//! GLObject query functions to get GL info from member variables - GLenum getGLTarget() const {return glTarget_;} - GLuint getGLName() const {return gluiName_;} - GLint getGLMipLevel() const {return gliMipLevel_;} - GLenum getGLInternalFormat() const {return glInternalFormat_;} - GLint getGLSize() const {return gliWidth_;} - GLint getGLWidth() const {return gliWidth_;} - GLint getGLHeight() const {return gliHeight_;} - GLint getGLDepth() const {return gliDepth_;} - cl_gl_object_type getCLGLObjectType() const { return clGLType_; } - GLenum getCubemapFace() const {return glCubemapFace_;} - GLsizei getNumSamples() const { return glNumSamples_;} -}; - - -//! Class BufferGL is drived from classes Buffer and GLObject -//! where the former keeps all data for CL object and -//! the latter keeps all data for GL object -class BufferGL : public Buffer, public GLObject -{ -protected: - //! Initializes the device memory array which is nested - // after'BufferGL' object in memory layout. - virtual void initDeviceMemory(); -public: -//! BufferGL constructor just calls constructors of base classes -//! to pass down the parameters - BufferGL( - Context& amdContext, - cl_mem_flags clFlags, - size_t uiSizeInBytes, - GLenum glTarget, - GLuint gluiName) - : // Call base classes constructors - Buffer( - amdContext, - clFlags, - uiSizeInBytes - ), - GLObject( - glTarget, - gluiName, - 0, // Mipmap level default - GL_ARRAY_BUFFER, // Just init to some value - (GLint) uiSizeInBytes, - 1, - 1, - CL_GL_OBJECT_BUFFER, - 0, - 0 - ) - { - setInteropObj(this); - } - virtual ~BufferGL() {} - - virtual BufferGL* asBufferGL() { return this; } -}; - - -//! Class ImageGL is derived from classes Image and GLObject -//! where the former keeps all data for CL object and -//! the latter keeps all data for GL object -class ImageGL : public Image, public GLObject -{ -public: - //! ImageGL constructor just calls constructors of base classes - //! to pass down the parameters - ImageGL( - Context& amdContext, - cl_mem_object_type clType, - cl_mem_flags clFlags, - const Format& format, - size_t width, - size_t height, - size_t depth, - GLenum glTarget, - GLuint gluiName, - GLint gliMipLevel, - GLenum glInternalFormat, - cl_gl_object_type clGLType, - GLsizei numSamples, - GLenum glCubemapFace = 0) - : Image(amdContext, clType, clFlags, format, width, height, depth, - Format(format).getElementSize() * width, - Format(format).getElementSize() * width * height) - , GLObject(glTarget, gluiName, gliMipLevel, glInternalFormat, - static_cast(width), static_cast(height), - static_cast(depth), clGLType, glCubemapFace,numSamples) - { - setInteropObj(this); - } - - virtual ~ImageGL() {} - -protected: - //! Initializes the device memory array which is nested - // after'BufferGL' object in memory layout. - virtual void initDeviceMemory(); -}; - - typedef EGLContext (*PFN_eglGetCurrentContext) (); -#ifdef _WIN32 -#define APICALL WINAPI -#define GETPROCADDRESS GetProcAddress -#define API_GETPROCADDR "wglGetProcAddress" -#define FCN_STR_TYPE LPCSTR - typedef PROC (WINAPI* PFN_xxxGetProcAddress) (LPCSTR fcnName); - typedef HGLRC (APICALL* PFN_wglCreateContext) (HDC hdc); - typedef HGLRC (APICALL* PFN_wglGetCurrentContext) (void); - typedef HDC (APICALL* PFN_wglGetCurrentDC) (void); - typedef BOOL (APICALL* PFN_wglDeleteContext) (HGLRC hglrc); - typedef BOOL (APICALL* PFN_wglMakeCurrent) (HDC hdc, HGLRC hglrc); - typedef BOOL (APICALL* PFN_wglShareLists) (HGLRC hglrc1, HGLRC hglrc2); -#else //!_WIN32 -#define APICALL // __stdcall //??? todo odintsov -#define API_GETPROCADDR "glXGetProcAddress" -#define GETPROCADDRESS dlsym -#define FCN_STR_TYPE const GLubyte* -#define WINAPI -#define PROC void* - typedef void* (*PFN_xxxGetProcAddress) (const GLubyte* procName); - // X11 typedef - typedef Display* (*PFNXOpenDisplay)(_Xconst char* display_name ); - typedef int (*PFNXCloseDisplay)(Display* display ); - - //glx typedefs - typedef GLXDrawable (*PFNglXGetCurrentDrawable)(); - typedef Display* (*PFNglXGetCurrentDisplay)(); - typedef GLXContext (*PFNglXGetCurrentContext)( void ); - typedef XVisualInfo* (*PFNglXChooseVisual)(Display *dpy, int screen, int *attribList); - typedef GLXContext(*PFNglXCreateContext)(Display* dpy,XVisualInfo* vis,GLXContext shareList,Bool direct); - typedef void(*PFNglXDestroyContext)(Display* dpy, GLXContext ctx); - typedef Bool(*PFNglXMakeCurrent)( Display* dpy, GLXDrawable drawable, GLXContext ctx); - typedef void* HMODULE; -#endif //!_WIN32 - -#define GLPREFIX(rtype, fcn, dclargs) \ - typedef rtype (APICALL* PFN_##fcn) dclargs; - -// Declare prototypes for GL functions -#include "gl_functions.hpp" - -class GLFunctions -{ -public: - //! Locks any access to the virtual GPUs - class SetIntEnv : public amd::StackObject { - public: - //! Default constructor - SetIntEnv(GLFunctions* env); - - //! Destructor - ~SetIntEnv(); - - //! Checks if the environment setup was successful - bool isValid() const { return isValid_; } - - private: - GLFunctions* env_; //!< GL environment - bool isValid_; //!< If TRUE, then it's a valid setup - }; - -private: - HMODULE libHandle_; - int missed_; // Indicates how many GL functions not init'ed, if any - - amd::Monitor lock_; - - EGLDisplay eglDisplay_; - EGLContext eglOriginalContext_; - EGLContext eglInternalContext_; - EGLContext eglTempContext_; - bool isEGL_; - PFN_eglGetCurrentContext eglGetCurrentContext_; - -#ifdef _WIN32 - HGLRC hOrigGLRC_; - HDC hDC_; - HGLRC hIntGLRC_; // handle for internal GLRC to access shared context - HDC tempDC_; - HGLRC tempGLRC_; - -public: - PFN_wglCreateContext wglCreateContext_; - PFN_wglGetCurrentContext wglGetCurrentContext_; - PFN_wglGetCurrentDC wglGetCurrentDC_; - PFN_wglDeleteContext wglDeleteContext_; - PFN_wglMakeCurrent wglMakeCurrent_; - PFN_wglShareLists wglShareLists_; -#else -public: - Display* Dpy_; - GLXDrawable Drawable_; - GLXContext origCtx_; - Display* intDpy_; - Window intDrawable_; - GLXContext intCtx_; - Display* tempDpy_; - GLXDrawable tempDrawable_; - GLXContext tempCtx_; - - //pointers to X11 functions - PFNXOpenDisplay XOpenDisplay_; - PFNXCloseDisplay XCloseDisplay_; - - //pointers to GLX functions - PFNglXGetCurrentDrawable glXGetCurrentDrawable_; - PFNglXGetCurrentDisplay glXGetCurrentDisplay_; - PFNglXGetCurrentContext glXGetCurrentContext_; - PFNglXChooseVisual glXChooseVisual_; - PFNglXCreateContext glXCreateContext_; - PFNglXDestroyContext glXDestroyContext_; - PFNglXMakeCurrent glXMakeCurrent_; -#endif -public: - - GLFunctions(HMODULE h, bool isEGL); - ~GLFunctions(); - - bool update(intptr_t hglrc); - bool IsCurrentGlContext(const amd::Context::Info& info) const { - if (isEGL_) { - return ((info.hCtx_ != nullptr) && (eglGetCurrentContext_ != nullptr) && - (info.hCtx_ == eglGetCurrentContext_())); - } else { -#ifdef _WIN32 - return ((info.hCtx_ != nullptr) && (info.hCtx_ == wglGetCurrentContext_())); -#else - return ((info.hCtx_ != nullptr) && (info.hCtx_ == glXGetCurrentContext_())); -#endif // _WIN32 - } - } - - void WaitCurrentGlContext(const amd::Context::Info& info) const; - - // Query CL-GL context association - bool isAssociated() const - { - if (isEGL_ && eglDisplay_ && eglOriginalContext_) return true; -#ifdef _WIN32 - if(hDC_ && hOrigGLRC_) return true; -#else //!_WIN32 - if(Dpy_ && origCtx_) return true; -#endif //!_WIN32 - return false; - } - bool isEGL() const - { - return isEGL_; - } - // Accessor methods -#ifdef _WIN32 - HGLRC getOrigGLRC() const {return hOrigGLRC_;} - HDC getDC() const {return hDC_;} - HGLRC getIntGLRC() const {return hIntGLRC_;} -#else //!_WIN32 - Display* getDpy() const {return Dpy_;} - GLXDrawable getDrawable() const {return Drawable_;} - GLXContext getOrigCtx() const {return origCtx_;} - - Display* getIntDpy() const {return intDpy_;} - GLXDrawable getIntDrawable() const {return intDrawable_;} - GLXContext getIntCtx() const {return intCtx_;} - - EGLDisplay getEglDpy() const { return eglDisplay_; } - EGLContext getEglOrigCtx() const { return eglOriginalContext_; } -#endif //!_WIN32 - - // Initialize GL dynamic library and function pointers - bool init(intptr_t hdc, intptr_t hglrc); - - // Return true if successful, false - if error occurred - bool setIntEnv(); - bool restoreEnv(); - - amd::Monitor& getLock() { return lock_; } - - PFN_xxxGetProcAddress GetProcAddress_; - -#define GLPREFIX(rtype, fcn, dclargs) \ - PFN_##fcn fcn##_; -// Declare pointers to GL functions -#include "gl_functions.hpp" -}; - -//! Functions for executing the GL related stuff -cl_mem clCreateFromGLBufferAMD(Context& amdContext, cl_mem_flags flags, - GLuint bufobj, cl_int* errcode_ret); -cl_mem clCreateFromGLTextureAMD(Context& amdContext, cl_mem_flags flags, - GLenum target, GLint miplevel, GLuint texture, int* errcode_ret); -cl_mem clCreateFromGLRenderbufferAMD(Context& amdContext, cl_mem_flags flags, - GLuint renderbuffer, int* errcode_ret); - -bool -getCLFormatFromGL( - const Context& amdContext, - GLint gliInternalFormat, - cl_image_format* pclImageFormat, - int* piBytesPerPixel, - cl_mem_flags flags -); - -} //namespace amd - -#endif //CL_GL_AMD_HPP_ diff --git a/projects/clr/hipamd/src/hip_gl.cpp b/projects/clr/hipamd/src/hip_gl.cpp index ce692753e4..50d7422fdd 100644 --- a/projects/clr/hipamd/src/hip_gl.cpp +++ b/projects/clr/hipamd/src/hip_gl.cpp @@ -21,7 +21,7 @@ #include "top.hpp" #include "hip/hip_runtime.h" #include "hip_internal.hpp" -#include "cl_gl_amd.hpp" +#include "platform/interop_gl.hpp" #include "cl_common.hpp" #include #include @@ -398,7 +398,7 @@ hipError_t hipGraphicsGLRegisterImage(hipGraphicsResource** resource, GLuint ima // Now get CL format from GL format and bytes per pixel int iBytesPerPixel = 0; - if (!getCLFormatFromGL(amdContext, glInternalFormat, &clImageFormat, &iBytesPerPixel, + if (!amd::getCLFormatFromGL(amdContext, glInternalFormat, &clImageFormat, &iBytesPerPixel, 0)) { //clFlags)) { LogWarning("\"texture\" format does not map to an appropriate CL image format"); HIP_RETURN(hipErrorInvalidValue); @@ -462,7 +462,7 @@ hipError_t hipGraphicsGLRegisterImage(hipGraphicsResource** resource, GLuint ima // Now get CL format from GL format and bytes per pixel int iBytesPerPixel = 0; - if (!getCLFormatFromGL(amdContext, glInternalFormat, &clImageFormat, &iBytesPerPixel, + if (!amd::getCLFormatFromGL(amdContext, glInternalFormat, &clImageFormat, &iBytesPerPixel, flags)) { LogWarning("\"texture\" format does not map to an appropriate CL image format"); HIP_RETURN(hipErrorInvalidValue);