SWDEV-381627 - adding cl interop files to vdi

Change-Id: Ic40363587a2bc56f977a148eba386dfb73d6286e
Этот коммит содержится в:
Ajay
2023-02-07 22:33:18 +00:00
коммит произвёл Maneesh Gupta
родитель 53c071199e
Коммит 88736010fb
14 изменённых файлов: 4429 добавлений и 10 удалений
+5
Просмотреть файл
@@ -84,6 +84,7 @@ target_sources(rocclr PRIVATE
${ROCCLR_SRC_DIR}/platform/ndrange.cpp
${ROCCLR_SRC_DIR}/platform/program.cpp
${ROCCLR_SRC_DIR}/platform/runtime.cpp
${ROCCLR_SRC_DIR}/platform/interop_gl.cpp
${ROCCLR_SRC_DIR}/thread/monitor.cpp
${ROCCLR_SRC_DIR}/thread/semaphore.cpp
${ROCCLR_SRC_DIR}/thread/thread.cpp
@@ -91,6 +92,10 @@ target_sources(rocclr PRIVATE
${ROCCLR_SRC_DIR}/utils/flags.cpp)
if(WIN32)
target_sources(rocclr PRIVATE
${ROCCLR_SRC_DIR}/platform/interop_d3d9.cpp
${ROCCLR_SRC_DIR}/platform/interop_d3d10.cpp
${ROCCLR_SRC_DIR}/platform/interop_d3d11.cpp)
target_compile_definitions(rocclr PUBLIC ATI_OS_WIN)
else()
target_compile_definitions(rocclr PUBLIC ATI_OS_LINUX)
+4 -4
Просмотреть файл
@@ -29,11 +29,11 @@
#ifdef _WIN32
#include <d3d10_1.h>
#include "amdocl/cl_d3d9_amd.hpp"
#include "amdocl/cl_d3d10_amd.hpp"
#include "amdocl/cl_d3d11_amd.hpp"
#include "platform/interop_d3d9.hpp"
#include "platform/interop_d3d10.hpp"
#include "platform/interop_d3d11.hpp"
#endif //_WIN32
#include "amdocl/cl_gl_amd.hpp"
#include "platform/interop_gl.hpp"
#include "amdocl/cl_vk_amd.hpp"
#include <string>
+3 -3
Просмотреть файл
@@ -45,9 +45,9 @@
#ifdef _WIN32
#include <d3d10_1.h>
#include "amdocl/cl_d3d9_amd.hpp"
#include "amdocl/cl_d3d10_amd.hpp"
#include "amdocl/cl_d3d11_amd.hpp"
#include "platform/interop_d3d9.hpp"
#include "platform/interop_d3d10.hpp"
#include "platform/interop_d3d11.hpp"
#endif // _WIN32
namespace pal {
+1 -1
Просмотреть файл
@@ -35,7 +35,7 @@
#include "thread/monitor.hpp"
#include "platform/memory.hpp"
#include "platform/sampler.hpp"
#include "amdocl/cl_gl_amd.hpp"
#include "platform/interop_gl.hpp"
#include "amdocl/cl_vk_amd.hpp"
namespace roc {
+1 -1
Просмотреть файл
@@ -19,7 +19,7 @@
THE SOFTWARE. */
#include "platform/context.hpp"
#include "amdocl/cl_gl_amd.hpp"
#include "platform/interop_gl.hpp"
#include "vdi_common.hpp"
#include "platform/commandqueue.hpp"
+871
Просмотреть файл
@@ -0,0 +1,871 @@
/* Copyright (c) 2009 - 2023 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 "platform/interop_d3d10.hpp"
#include "platform/command.hpp"
#include <cstring>
#include <utility>
namespace amd {
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<ID3D10Buffer*>(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, nullptr, (ID3D10Buffer**)&obj.pD3D10Res_);
STORE_SHARED_FLAGS(ID3D10Buffer);
}
} break;
case D3D10_RESOURCE_DIMENSION_TEXTURE1D: // = 2,
{
D3D10_TEXTURE1D_DESC desc;
(reinterpret_cast<ID3D10Texture1D*>(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, nullptr, (ID3D10Texture1D**)&obj.pD3D10Res_);
STORE_SHARED_FLAGS(ID3D10Texture1D);
}
} break;
case D3D10_RESOURCE_DIMENSION_TEXTURE2D: // = 3,
{
D3D10_TEXTURE2D_DESC desc;
(reinterpret_cast<ID3D10Texture2D*>(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, nullptr, (ID3D10Texture2D**)&obj.pD3D10Res_);
STORE_SHARED_FLAGS(ID3D10Texture2D);
}
} break;
case D3D10_RESOURCE_DIMENSION_TEXTURE3D: // = 4
{
D3D10_TEXTURE3D_DESC desc;
(reinterpret_cast<ID3D10Texture3D*>(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, nullptr, (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 (nullptr == 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_, nullptr);
// 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 (nullptr == 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, nullptr);
d3dDev->Release();
return true;
}
std::vector<std::pair<void*, UINT>> D3D10Object::resources_;
Monitor D3D10Object::resLock_;
void BufferD3D10::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(BufferD3D10));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
void Image1DD3D10::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(Image1DD3D10));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
void Image2DD3D10::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(Image2DD3D10));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
void Image3DD3D10::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(Image3DD3D10));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
} // namespace amd
#endif //_WIN32
+303
Просмотреть файл
@@ -0,0 +1,303 @@
/* Copyright (c) 2008 - 2023 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. */
#pragma once
#include "cl_common.hpp"
#include "platform/context.hpp"
#include "platform/memory.hpp"
#include <utility>
namespace amd
{
typedef struct
{
union
{
UINT ByteWidth;
UINT Width;
};
UINT Height;
UINT Depth;
} D3D10ObjSize_t;
typedef struct
{
D3D10_USAGE d3d10Usage_;
UINT bindFlags_;
UINT cpuAccessFlags_;
UINT miscFlags_;
} D3D10Flags_t;
typedef struct
{
D3D10_RESOURCE_DIMENSION objDim_;
D3D10ObjSize_t objSize_;
D3D10Flags_t objFlags_;
UINT mipLevels_;
UINT arraySize_;
DXGI_FORMAT dxgiFormat_;
DXGI_SAMPLE_DESC dxgiSampleDesc_;
} D3D10ObjDesc_t;
const DXGI_SAMPLE_DESC dxgiSampleDescDefault = {1, 0};
//! Class D3D10Object keeps all the info about the D3D10 object
//! from which the CL object is created
class D3D10Object : public InteropObject
{
private:
ID3D10Resource* pD3D10Aux_;
bool releaseResources_;
static std::vector<std::pair<void*, UINT>> resources_;
//! Global lock.
static Monitor resLock_;
protected:
ID3D10Resource* pD3D10Res_;
ID3D10Resource* pD3D10ResOrig_;
ID3D10Query* pQuery_;
D3D10ObjDesc_t objDesc_;
D3D10ObjDesc_t objDescOrig_;
UINT subRes_;
public:
// Default constructor
D3D10Object()
:pD3D10Aux_(nullptr)
,releaseResources_(false)
,pD3D10Res_(nullptr)
,pD3D10ResOrig_(nullptr)
,pQuery_(nullptr)
,subRes_(0)
{
memset(&objDesc_,0,sizeof(objDesc_));
memset(&objDescOrig_,0,sizeof(objDescOrig_));
}
// Copy constructor
D3D10Object(D3D10Object& d3d10obj)
: pQuery_(nullptr)
{
*this = d3d10obj;
this->releaseResources_ = true;
// Add reference to the D3D10 resource to prevent its disappearance
if(pD3D10ResOrig_) {
pD3D10ResOrig_->AddRef();
}
else if(pD3D10Res_) {
pD3D10Res_->AddRef();
}
}
//! Virtual destructor
virtual ~D3D10Object()
{
ScopedLock sl(resLock_);
if(releaseResources_) {
// Decrement reference to the D3D10 objects
if(pD3D10Res_) pD3D10Res_->Release();
if(pD3D10Aux_) pD3D10Aux_->Release();
if(pD3D10ResOrig_) pD3D10ResOrig_->Release();
if(pQuery_) pQuery_->Release();
// Check if this resource has already been used for interop
if(resources_.size()) {
for(auto& it = resources_.cbegin(); it != resources_.cend(); it++) {
if(((pD3D10ResOrig_ && (*it).first == (void*) pD3D10ResOrig_)
|| ((*it).first == (void*) pD3D10Res_))
&& (*it).second == subRes_) {
resources_.erase(it);
break;
}
}
}
}
}
static int initD3D10Object(const Context& amdContext, ID3D10Resource* pRes, UINT subresource,
D3D10Object& obj);
D3D10Object* asD3D10Object() { return this; }
//! D3D10Object query functions to get D3D10 info from member variables
ID3D10Resource* getD3D10Resource() const {return pD3D10Res_;}
ID3D10Resource* getD3D10ResOrig() const {return pD3D10ResOrig_;}
ID3D10Query* getQuery() const {return pQuery_;}
UINT getWidth() const {return objDesc_.objSize_.Width;}
UINT getHeight() const {return objDesc_.objSize_.Height;}
UINT getDepth() const {return objDesc_.objSize_.Depth;}
size_t getElementBytes(DXGI_FORMAT dxgiFomat);
size_t getElementBytes() {return getElementBytes(objDesc_.dxgiFormat_);}
DXGI_FORMAT getDxgiFormat() {return objDesc_.dxgiFormat_;}
UINT getSubresource() const {return subRes_;}
const D3D10ObjDesc_t* getObjDesc() const { return &objDesc_; }
//! Returns bytes per pixel > 0 if conversion successful, 0 otherwise;
//! if formats are not compatible, cl format channel
//! order and type are set to 0
cl_image_format getCLFormatFromDXGI(DXGI_FORMAT dxgiFmt);
cl_image_format getCLFormatFromDXGI()
{
return getCLFormatFromDXGI(objDesc_.dxgiFormat_);
}
size_t getResourceByteSize();
// On acquire copy data from original resource to shared resource
virtual bool copyOrigToShared();
// On release copy data from shared copy to the original resource
virtual bool copySharedToOrig();
};
//! Class BufferD3D10 is derived from classes Buffer and D3D10Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D10 object
class BufferD3D10 : public D3D10Object, public Buffer
{
protected:
//! Initializes the device memory array which is nested
// after 'BufferD3D10' object in memory layout.
virtual void initDeviceMemory();
public:
//! BufferD3D10 constructor just calls constructors of base classes
//! to pass down the parameters
BufferD3D10(
Context& amdContext,
cl_mem_flags clFlags,
D3D10Object& d3d10obj)
: // Call base classes constructors
D3D10Object(d3d10obj),
Buffer(
amdContext,
clFlags,
d3d10obj.getResourceByteSize())
{
setInteropObj(this);
}
virtual ~BufferD3D10() {}
};
//! Class Image1DD3D10 is derived from classes Image1D and D3D10Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D10 object
class Image1DD3D10 : public D3D10Object, public Image
{
protected:
//! Initializes the device memory array which is nested
// after'Image1DD3D10' object in memory layout.
virtual void initDeviceMemory();
public:
//! Image1DD3D10 constructor just calls constructors of base classes
//! to pass down the parameters
Image1DD3D10(
Context& amdContext,
cl_mem_flags clFlags,
D3D10Object& d3d10obj)
: // Call base classes constructors
D3D10Object(d3d10obj),
Image(
amdContext,
CL_MEM_OBJECT_IMAGE1D,
clFlags,
getCLFormatFromDXGI(d3d10obj.getDxgiFormat()), //format,
d3d10obj.getWidth(),
1,
1,
d3d10obj.getWidth() * d3d10obj.getElementBytes(), //rowPitch),
0)
{
setInteropObj(this);
}
virtual ~Image1DD3D10() {}
};
//! Class Image2DD3D10 is derived from classes Image2D and D3D10Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D10 object
class Image2DD3D10 : public D3D10Object, public Image
{
protected:
//! Initializes the device memory array which is nested
// after'Image2DD3D10' object in memory layout.
virtual void initDeviceMemory();
public:
//! Image2DD3D10 constructor just calls constructors of base classes
//! to pass down the parameters
Image2DD3D10(
Context& amdContext,
cl_mem_flags clFlags,
D3D10Object& d3d10obj)
: // Call base classes constructors
D3D10Object(d3d10obj),
Image(
amdContext,
CL_MEM_OBJECT_IMAGE2D,
clFlags,
getCLFormatFromDXGI(d3d10obj.getDxgiFormat()), //format,
d3d10obj.getWidth(),
d3d10obj.getHeight(),
1,
d3d10obj.getWidth() * d3d10obj.getElementBytes(), //rowPitch),
0)
{
setInteropObj(this);
}
virtual ~Image2DD3D10() {}
};
//! Class Image3DD3D10 is derived from classes Image3D and D3D10Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D10 object
class Image3DD3D10 : public D3D10Object, public Image
{
protected:
//! Initializes the device memory array which is nested
// after'Image3DD3D10' object in memory layout.
virtual void initDeviceMemory();
public:
//! Image2DD3D10 constructor just calls constructors of base classes
//! to pass down the parameters
Image3DD3D10(
Context& amdContext,
cl_mem_flags clFlags,
D3D10Object& d3d10obj)
: // Call base classes constructors
D3D10Object(d3d10obj),
Image(
amdContext,
CL_MEM_OBJECT_IMAGE3D,
clFlags,
getCLFormatFromDXGI(d3d10obj.getDxgiFormat()), //format,
d3d10obj.getWidth(),
d3d10obj.getHeight(),
d3d10obj.getDepth(),
d3d10obj.getWidth() * d3d10obj.getElementBytes(), //rowPitch),
d3d10obj.getWidth() * d3d10obj.getHeight() * d3d10obj.getElementBytes())
{
setInteropObj(this);
}
virtual ~Image3DD3D10() {}
};
} //namespace amd
+976
Просмотреть файл
@@ -0,0 +1,976 @@
/* Copyright (c) 2009 - 2023 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 "platform/interop_d3d11.hpp"
#include "platform/command.hpp"
#include <cstring>
#include <utility>
namespace amd {
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<ID3D11Buffer*>(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, nullptr, (ID3D11Buffer**)&obj.pD3D11Res_);
STORE_SHARED_FLAGS_BUFFER(ID3D11Buffer);
}
} break;
case D3D11_RESOURCE_DIMENSION_TEXTURE1D: // = 2,
{
D3D11_TEXTURE1D_DESC desc;
(reinterpret_cast<ID3D11Texture1D*>(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, nullptr, (ID3D11Texture1D**)&obj.pD3D11Res_);
STORE_SHARED_FLAGS(ID3D11Texture1D);
}
} break;
case D3D11_RESOURCE_DIMENSION_TEXTURE2D: // = 3,
{
D3D11_TEXTURE2D_DESC desc;
(reinterpret_cast<ID3D11Texture2D*>(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, nullptr, (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<ID3D11Texture3D*>(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, nullptr, (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 (nullptr == getD3D11ResOrig()) return true;
ID3D11Device* d3dDev;
pD3D11Res_->GetDevice(&d3dDev);
if (!d3dDev) {
LogError("\nCannot get D3D11 device from D3D11 resource\n");
return false;
}
ID3D11DeviceContext* pImmediateContext = nullptr;
d3dDev->GetImmediateContext(&pImmediateContext);
if (!pImmediateContext) {
LogError("\nCannot get D3D11 device context");
return false;
}
assert(pD3D11ResOrig_ != nullptr);
// Any usage source can be read by GPU
pImmediateContext->CopySubresourceRegion(pD3D11Res_, 0, 0, 0, 0, pD3D11ResOrig_, subRes_, nullptr);
// 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 (nullptr == getD3D11ResOrig()) return true;
ID3D11Device* d3dDev;
pD3D11Res_->GetDevice(&d3dDev);
if (!d3dDev) {
LogError("\nCannot get D3D11 device from D3D11 resource\n");
return false;
}
ID3D11DeviceContext* pImmediateContext = nullptr;
d3dDev->GetImmediateContext(&pImmediateContext);
if (!pImmediateContext) {
LogError("\nCannot get D3D11 device context");
return false;
}
assert(pD3D11ResOrig_);
pImmediateContext->CopySubresourceRegion(pD3D11ResOrig_, subRes_, 0, 0, 0, pD3D11Res_, 0, nullptr);
pImmediateContext->Release();
d3dDev->Release();
return true;
}
std::vector<std::pair<void*, std::pair<UINT, UINT>>> D3D11Object::resources_;
Monitor D3D11Object::resLock_;
//
// Class BufferD3D11 implementation
//
void BufferD3D11::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(BufferD3D11));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
//
// Class Image1DD3D11 implementation
//
void Image1DD3D11::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(Image1DD3D11));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
//
// Class Image2DD3D11 implementation
//
void Image2DD3D11::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(Image2DD3D11));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
//
// Class Image3DD3D11 implementation
//
void Image3DD3D11::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(Image3DD3D11));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
//
// 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
+305
Просмотреть файл
@@ -0,0 +1,305 @@
/* Copyright (c) 2008 - 2023 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. */
#pragma once
#include "interop_d3d10.hpp"
#include "platform/context.hpp"
#include "platform/memory.hpp"
#include <utility>
namespace amd
{
typedef struct
{
union
{
UINT ByteWidth;
UINT Width;
};
UINT Height;
UINT Depth;
} D3D11ObjSize_t;
typedef struct
{
D3D11_USAGE d3d11Usage_;
UINT bindFlags_;
UINT cpuAccessFlags_;
UINT miscFlags_;
UINT structureByteStride_;
} D3D11Flags_t;
typedef struct
{
D3D11_RESOURCE_DIMENSION objDim_;
D3D11ObjSize_t objSize_;
D3D11Flags_t objFlags_;
UINT mipLevels_;
UINT arraySize_;
DXGI_FORMAT dxgiFormat_;
DXGI_SAMPLE_DESC dxgiSampleDesc_;
} D3D11ObjDesc_t;
//! Class D3D11Object keeps all the info about the D3D11 object
//! from which the CL object is created
class D3D11Object : public InteropObject
{
private:
ID3D11Resource* pD3D11Aux_;
bool releaseResources_;
static std::vector<std::pair<void*, std::pair<UINT,UINT>>> resources_;
protected:
//! Global lock.
static Monitor resLock_;
ID3D11Resource* pD3D11Res_;
ID3D11Resource* pD3D11ResOrig_;
ID3D11Query* pQuery_;
D3D11ObjDesc_t objDesc_;
UINT subRes_;
INT plane_;
public:
// Default constructor
D3D11Object()
:pD3D11Aux_(nullptr)
,releaseResources_(false)
,pD3D11Res_(nullptr)
,pD3D11ResOrig_(nullptr)
,pQuery_(nullptr)
,subRes_(NULL)
,plane_(NULL)
{
memset(&objDesc_,0,sizeof(objDesc_));
}
// Copy constructor
D3D11Object(D3D11Object& d3d11obj)
: pQuery_(NULL)
{
*this = d3d11obj;
this->releaseResources_ = true;
// Add reference to the D3D11 resource to prevent its disappearance
if(pD3D11ResOrig_) {
pD3D11ResOrig_->AddRef();
}
else if(pD3D11Res_) {
pD3D11Res_->AddRef();
}
assert(pD3D11Res_ != pD3D11ResOrig_);
}
//! Virtual destructor
virtual ~D3D11Object()
{
ScopedLock sl(resLock_);
if(releaseResources_) {
// Decrement reference to the D3D11 objects
if(pD3D11Res_) pD3D11Res_->Release();
if(pD3D11Aux_) pD3D11Aux_->Release();
if(pD3D11ResOrig_) pD3D11ResOrig_->Release();
if(pQuery_) pQuery_->Release();
// Check if this resource has already been used for interop
if(resources_.size()) {
for(auto& it = resources_.cbegin(); it != resources_.cend(); it++) {
if(((pD3D11ResOrig_ && (*it).first == (void*) pD3D11ResOrig_)
|| ((*it).first == (void*) pD3D11Res_))
&& (*it).second.first == subRes_
&& (*it).second.second == plane_) {
resources_.erase(it);
break;
}
}
}
}
}
static int initD3D11Object(const Context& amdContext, ID3D11Resource* pRes, UINT subresource,
D3D11Object& obj, INT plane = -1);
D3D11Object* asD3D11Object() { return this; }
//! D3D11Object query functions to get D3D11 info from member variables
ID3D11Resource* getD3D11Resource() const {return pD3D11Res_;}
ID3D11Resource* getD3D11ResOrig() const {return pD3D11ResOrig_;}
ID3D11Query* getQuery() const {return pQuery_;}
Monitor& getResLock() { return resLock_;}
UINT getWidth() const {return objDesc_.objSize_.Width;}
UINT getHeight() const {return objDesc_.objSize_.Height;}
UINT getDepth() const {return objDesc_.objSize_.Depth;}
size_t getElementBytes(DXGI_FORMAT dxgiFomat, cl_uint plane);
size_t getElementBytes() {return getElementBytes(objDesc_.dxgiFormat_, plane_);}
DXGI_FORMAT getDxgiFormat() {return objDesc_.dxgiFormat_;}
UINT getSubresource() const {return subRes_;}
INT getPlane() const {return plane_;}
const D3D11ObjDesc_t* getObjDesc() const { return &objDesc_; }
cl_uint getMiscFlag(void);
//! Returns bytes per pixel > 0 if conversion successful, 0 otherwise;
//! if formats are not compatible, cl format channel
//! order and type are set to 0
cl_image_format getCLFormatFromDXGI(DXGI_FORMAT dxgiFmt, cl_uint plane);
cl_image_format getCLFormatFromDXGI()
{
return getCLFormatFromDXGI(objDesc_.dxgiFormat_, plane_);
}
size_t getResourceByteSize();
// On acquire copy data from original resource to shared resource
virtual bool copyOrigToShared();
// On release copy data from shared copy to the original resource
virtual bool copySharedToOrig();
};
//! Class BufferD3D11 is derived from classes Buffer and D3D11Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D11 object
class BufferD3D11 : public D3D11Object, public Buffer
{
protected:
//! Initializes the device memory array which is nested
// after'BufferD3D11' object in memory layout.
virtual void initDeviceMemory();
public:
//! BufferD3D11 constructor just calls constructors of base classes
//! to pass down the parameters
BufferD3D11(
Context& amdContext,
cl_mem_flags clFlags,
D3D11Object& d3d11obj)
: // Call base classes constructors
D3D11Object(d3d11obj),
Buffer(
amdContext,
clFlags,
d3d11obj.getResourceByteSize())
{
setInteropObj(this);
}
virtual ~BufferD3D11() {}
};
//! Class Image1DD3D11 is derived from classes Image1D and D3D11Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D11 object
class Image1DD3D11 : public D3D11Object, public Image
{
protected:
//! Initializes the device memory array which is nested
// after'Image1DD3D11' object in memory layout.
virtual void initDeviceMemory();
public:
//! Image1DD3D11 constructor just calls constructors of base classes
//! to pass down the parameters
Image1DD3D11(
Context& amdContext,
cl_mem_flags clFlags,
D3D11Object& d3d11obj)
: // Call base classes constructors
D3D11Object(d3d11obj),
Image(
amdContext,
CL_MEM_OBJECT_IMAGE1D,
clFlags,
getCLFormatFromDXGI(d3d11obj.getDxgiFormat(), d3d11obj.getPlane()), //format,
d3d11obj.getWidth(),
1,
1,
d3d11obj.getWidth() * d3d11obj.getElementBytes(), //rowPitch),
0)
{
setInteropObj(this);
}
virtual ~Image1DD3D11() {}
};
//! Class Image2DD3D11 is derived from classes Image2D and D3D11Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D11 object
class Image2DD3D11 : public Image, public D3D11Object
{
protected:
//! Initializes the device memory array which is nested
// after'Image2DD3D11' object in memory layout.
virtual void initDeviceMemory();
public:
//! Image2DD3D11 constructor just calls constructors of base classes
//! to pass down the parameters
Image2DD3D11(
Context& amdContext,
cl_mem_flags clFlags,
D3D11Object& d3d11obj)
: // Call base classes constructors
D3D11Object(d3d11obj),
Image(
amdContext,
CL_MEM_OBJECT_IMAGE2D,
clFlags,
getCLFormatFromDXGI(d3d11obj.getDxgiFormat(), d3d11obj.getPlane()), //format,
d3d11obj.getWidth(),
d3d11obj.getHeight(),
1,
d3d11obj.getWidth() * d3d11obj.getElementBytes(), //rowPitch),
0)
{
setInteropObj(this);
}
virtual ~Image2DD3D11() {}
};
//! Class Image3DD3D11 is derived from classes Image3D and D3D11Object
//! where the former keeps all data for CL object and
//! the latter keeps all data for D3D11 object
class Image3DD3D11 : public D3D11Object, public Image
{
protected:
//! Initializes the device memory array which is nested
// after'Image3DD3D11' object in memory layout.
virtual void initDeviceMemory();
public:
//! Image2DD3D11 constructor just calls constructors of base classes
//! to pass down the parameters
Image3DD3D11(
Context& amdContext,
cl_mem_flags clFlags,
D3D11Object& d3d11obj)
: // Call base classes constructors
D3D11Object(d3d11obj),
Image(
amdContext,
CL_MEM_OBJECT_IMAGE3D,
clFlags,
getCLFormatFromDXGI(d3d11obj.getDxgiFormat(), d3d11obj.getPlane()), //format,
d3d11obj.getWidth(),
d3d11obj.getHeight(),
d3d11obj.getDepth(),
d3d11obj.getWidth() * d3d11obj.getElementBytes(), //rowPitch),
d3d11obj.getWidth() * d3d11obj.getHeight() * d3d11obj.getElementBytes())
{
setInteropObj(this);
}
virtual ~Image3DD3D11() {}
};
} //namespace amd
+570
Просмотреть файл
@@ -0,0 +1,570 @@
/* Copyright (c) 2012 - 2023 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 "platform/interop_d3d9.hpp"
#include "platform/command.hpp"
#include <cstring>
#include <utility>
namespace amd {
std::vector<std::pair<TD3D9RESINFO, TD3D9RESINFO>> D3D9Object::resources_;
Monitor D3D9Object::resLock_;
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 = nullptr;
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 nullptr
// first check if the format is NV12 or YV12, which we need special handling
if (nullptr == 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_ = nullptr;
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 (nullptr == 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, nullptr, dstSurf, nullptr, 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 (nullptr == 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(), nullptr, getD3D9ResOrig(), nullptr, 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<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(Image2DD3D9));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
} // namespace amd
#endif //_WIN32
+190
Просмотреть файл
@@ -0,0 +1,190 @@
/* Copyright (c) 2010 - 2023 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. */
#pragma once
#include "cl_common.hpp"
#include "platform/context.hpp"
#include "platform/memory.hpp"
#include <utility>
/* cl_amd_d3d9_sharing error codes */
#define CL_INVALID_D3D9_RESOURCE_KHR -1022
#define D3DFMT_NV_12 static_cast<D3DFORMAT>(MAKEFOURCC('N', 'V', '1', '2'))
#define D3DFMT_P010 static_cast<D3DFORMAT>(MAKEFOURCC('P', '0', '1', '0'))
#define D3DFMT_YV_12 static_cast<D3DFORMAT>(MAKEFOURCC('Y', 'V', '1', '2'))
#define D3DFMT_YUY2 static_cast<D3DFORMAT>(MAKEFOURCC('Y', 'U', 'Y', '2'))
namespace amd
{
typedef struct
{
union
{
UINT ByteWidth;
UINT Width;
};
UINT Height;
UINT Depth;
} D3D9ObjSize_t;
typedef struct
{
D3D9ObjSize_t objSize_;
D3DFORMAT d3dFormat_;
D3DRESOURCETYPE resType_;
UINT usage_;
D3DPOOL d3dPool_;
D3DMULTISAMPLE_TYPE msType_;
UINT msQuality_;
UINT mipLevels_;
UINT fvf_;
RECT surfRect_;
} D3D9ObjDesc_t;
typedef struct d3d9ResInfo {
cl_dx9_surface_info_khr surfInfo;
cl_uint surfPlane;
} TD3D9RESINFO;
//typedef std::pair<cl_dx9_surface_info_khr, D3D9Object*> TD3D9OBJINFO;
//! Class D3D9Object keeps all the info about the D3D9 object
//! from which the CL object is created
class D3D9Object : public InteropObject
{
private:
IDirect3DSurface9* pD3D9Aux_;
bool releaseResources_;
static std::vector<std::pair<TD3D9RESINFO, TD3D9RESINFO>> resources_;
//!Global lock
static Monitor resLock_;
cl_uint surfPlane_;
cl_dx9_surface_info_khr surfInfo_;
protected:
IDirect3DSurface9* pD3D9Res_;
IDirect3DSurface9* pD3D9ResOrig_;
IDirect3DQuery9* pQuery_;
D3D9ObjDesc_t objDesc_;
D3D9ObjDesc_t objDescOrig_;
HANDLE handleShared_;
cl_dx9_media_adapter_type_khr adapterType_;
public:
//! D3D9Object constructor initializes memeber variables
D3D9Object()
: releaseResources_(false),
pQuery_(nullptr)
{
// @todo Incorrect initialization!!!
memset(this, 0, sizeof(D3D9Object));
}
//copy constructor
D3D9Object(D3D9Object& d3d9obj)
:pQuery_(nullptr)
{
*this = d3d9obj;
this->releaseResources_ = true;
}
//virtual destructor
virtual ~D3D9Object()
{
ScopedLock sl(resLock_);
if(releaseResources_) {
if(pD3D9ResOrig_) pD3D9ResOrig_->Release();
if(pD3D9Res_) pD3D9Res_->Release();
if(pD3D9Aux_) pD3D9Aux_->Release();
if(pQuery_) pQuery_->Release();
//if the resouce is being used
if(resources_.size()) {
for(auto& it = resources_.cbegin(); it != resources_.cend(); it++) {
if( surfInfo_.resource &&
((*it).first.surfInfo.resource == surfInfo_.resource) &&
((*it).first.surfPlane == surfPlane_)) {
resources_.erase(it);
break;
}
}
}
}
}
static int 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);
cl_uint getMiscFlag(void);
D3D9Object* asD3D9Object() {return this;}
IDirect3DSurface9* getD3D9Resource() const {return pD3D9Res_;}
HANDLE getD3D9SharedHandle() const {return handleShared_;}
IDirect3DSurface9* getD3D9ResOrig() const {return pD3D9ResOrig_;}
IDirect3DQuery9* getQuery() const {return pQuery_;}
Monitor & getResLock() { return resLock_;}
UINT getWidth() const {return objDesc_.objSize_.Width;}
UINT getHeight() const {return objDesc_.objSize_.Height;}
cl_uint getPlane() const {return surfPlane_;}
cl_dx9_media_adapter_type_khr getAdapterType() const { return adapterType_;};
const cl_dx9_surface_info_khr& getSurfInfo() const {return surfInfo_;};
size_t getElementBytes(D3DFORMAT d3d9Format, cl_uint plane);
size_t getElementBytes() {return getElementBytes(objDesc_.d3dFormat_, surfPlane_);}
D3D9ObjDesc_t* getObjDesc() {return &objDesc_;}
cl_image_format getCLFormatFromD3D9();
cl_image_format getCLFormatFromD3D9(D3DFORMAT d3d9Fmt, cl_uint plane);
// On acquire copy data from original resource to shared resource
virtual bool copyOrigToShared();
// On release copy data from shared copy to the original resource
virtual bool copySharedToOrig();
};
class Image2DD3D9 : public D3D9Object , public Image
{
protected:
//! Initializes the device memory array which is nested
// after'Image2DD3D9' object in memory layout.
virtual void initDeviceMemory();
public:
//! Image2DD3D9 constructor just calls constructors of base classes
//! to pass down the parameters
Image2DD3D9(
Context& amdContext,
cl_mem_flags clFlags,
D3D9Object& d3d9obj)
: // Call base classes constructors
D3D9Object(d3d9obj),
Image(
amdContext,
CL_MEM_OBJECT_IMAGE2D,
clFlags,
d3d9obj.getCLFormatFromD3D9(),
d3d9obj.getWidth(),
d3d9obj.getHeight(),
1,
d3d9obj.getWidth() * d3d9obj.getElementBytes(), //rowPitch),
0)
{
setInteropObj(this);
}
virtual ~Image2DD3D9() {}
};
} //namespace amd
+803
Просмотреть файл
@@ -0,0 +1,803 @@
/* Copyright (c) 2010 - 2023 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 <d3d10_1.h>
#include <d3d9.h>
#include <dxgi.h>
#endif //_WIN32
#include <GL/gl.h>
#include <GL/glext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#include "cl_common.hpp"
#include "device/device.hpp"
#include "platform/command.hpp"
#include "platform/interop_gl.hpp"
/* The pixel internal format for DOPP texture defined in gl_enum.h */
#define GL_BGR8_ATI 0x8083
#define GL_BGRA8_ATI 0x8088
#include <cstring>
#include <vector>
// 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 amd::ClGlEvent::waitForFence() {
GLenum ret;
// get fence id associated with fence event
GLsync gs = reinterpret_cast<GLsync>(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<GLuint64>(-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<intptr_t>(tempDC_),
reinterpret_cast<intptr_t>(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<GLuint64>(-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<GLuint64>(-1));
if (!(ret == GL_ALREADY_SIGNALED || ret == GL_CONDITION_SATISFIED)) return false;
} else {
if (!context().glenv()->init(reinterpret_cast<intptr_t>(context().glenv()->getIntDpy()),
reinterpret_cast<intptr_t>(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<GLuint64>(-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;
}
void amd::BufferGL::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(BufferGL));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
void amd::ImageGL::initDeviceMemory() {
deviceMemories_ =
reinterpret_cast<DeviceMemory*>(reinterpret_cast<char*>(this) + sizeof(ImageGL));
memset(deviceMemories_, 0, context_().devices().size() * sizeof(DeviceMemory));
}
#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_STR_TYPE>(#fcn)))) ++missed_; \
}
amd::GLFunctions::SetIntEnv::SetIntEnv(GLFunctions* env) : env_(env) {
env_->getLock().lock();
// Set environment (DC and GLRC)
isValid_ = env_->setIntEnv();
}
amd::GLFunctions::SetIntEnv::~SetIntEnv() {
// Restore environment (CL DC and CL GLRC)
env_->restoreEnv();
env_->getLock().unlock();
}
amd::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_(nullptr),
XCloseDisplay_(nullptr),
glXGetCurrentDrawable_(nullptr),
glXGetCurrentDisplay_(nullptr),
glXGetCurrentContext_(nullptr),
glXChooseVisual_(nullptr),
glXCreateContext_(nullptr),
glXDestroyContext_(nullptr),
glXMakeCurrent_(nullptr)
#endif //!_WIN32
{
#define VERIFY_POINTER(p) \
if (nullptr == 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 (nullptr != 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
}
amd::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_ = nullptr;
}
XCloseDisplay_(intDpy_);
intDpy_ = nullptr;
}
#endif //!_WIN32
}
// in case of HIP GL interop we want to make sure we have the updated context
bool amd::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;
}
void amd::GLFunctions::WaitCurrentGlContext(const amd::Context::Info& info) const {
if (IsCurrentGlContext(info)) {
glFinish_();
}
}
bool amd::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_() == nullptr) {
wglMakeCurrent_(hDC_, hIntGLRC_);
makeCurrentNull = true;
}
// Initialize pointers to GL functions
#include "gl_functions.hpp"
if (makeCurrentNull) {
wglMakeCurrent_(nullptr, nullptr);
}
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 amd::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 amd::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, nullptr)) {
LogWarning("cannot reelase internal GL environment");
return false;
}
}
#endif //!_WIN32
return true;
}
//! Function getCLFormatFromGL returns "true" if GL format
//! is compatible with CL format, "false" otherwise.
bool amd::getCLFormatFromGL(const amd::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;
}
+396
Просмотреть файл
@@ -0,0 +1,396 @@
/* Copyright (c) 2010 - 2023 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. */
#pragma once
#ifdef _WIN32
#include <windows.h>
#else //!_WIN32
#include <dlfcn.h>
#endif //!_WIN32
#include <GL/gl.h>
#include <GL/glext.h>
#include "CL/cl_gl.h"
#ifndef _WIN32
#include <GL/glx.h>
#endif //!_WIN32
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
#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<GLint>(width), static_cast<GLint>(height),
static_cast<GLint>(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
+1 -1
Просмотреть файл
@@ -27,7 +27,7 @@
#include "platform/context.hpp"
#include "platform/agent.hpp"
#include "amdocl/cl_gl_amd.hpp"
#include "platform/interop_gl.hpp"
#ifdef _WIN32
#include <d3d10_1.h>