/* * Copyright (C) 2018-2021 Intel Corporation * * SPDX-License-Identifier: MIT * */ #include "opencl/source/context/context.inl" #include "opencl/source/os_interface/windows/d3d_sharing_functions.h" #include "opencl/source/sharings/d3d/d3d_sharing.h" #include "opencl/source/sharings/sharing_factory.h" using namespace NEO; template class D3DSharingFunctions; template class D3DSharingFunctions; const uint32_t D3DSharingFunctions::sharingId = SharingType::D3D10_SHARING; const uint32_t D3DSharingFunctions::sharingId = SharingType::D3D11_SHARING; static const DXGI_FORMAT DXGIFormats[] = { DXGI_FORMAT_R32G32B32A32_TYPELESS, DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_SINT, DXGI_FORMAT_R32G32B32_TYPELESS, DXGI_FORMAT_R32G32B32_FLOAT, DXGI_FORMAT_R32G32B32_UINT, DXGI_FORMAT_R32G32B32_SINT, DXGI_FORMAT_R16G16B16A16_TYPELESS, DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_UNORM, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_SINT, DXGI_FORMAT_R32G32_TYPELESS, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32_UINT, DXGI_FORMAT_R32G32_SINT, DXGI_FORMAT_R32G8X24_TYPELESS, DXGI_FORMAT_D32_FLOAT_S8X24_UINT, DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS, DXGI_FORMAT_X32_TYPELESS_G8X24_UINT, DXGI_FORMAT_R10G10B10A2_TYPELESS, DXGI_FORMAT_R10G10B10A2_UNORM, DXGI_FORMAT_R10G10B10A2_UINT, DXGI_FORMAT_R11G11B10_FLOAT, DXGI_FORMAT_R8G8B8A8_TYPELESS, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SINT, DXGI_FORMAT_R16G16_TYPELESS, DXGI_FORMAT_R16G16_FLOAT, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R32_TYPELESS, DXGI_FORMAT_D32_FLOAT, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32_UINT, DXGI_FORMAT_R32_SINT, DXGI_FORMAT_R24G8_TYPELESS, DXGI_FORMAT_D24_UNORM_S8_UINT, DXGI_FORMAT_R24_UNORM_X8_TYPELESS, DXGI_FORMAT_X24_TYPELESS_G8_UINT, DXGI_FORMAT_R8G8_TYPELESS, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R16_TYPELESS, DXGI_FORMAT_R16_FLOAT, DXGI_FORMAT_D16_UNORM, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R8_TYPELESS, DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8_SINT, DXGI_FORMAT_A8_UNORM, DXGI_FORMAT_R1_UNORM, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, DXGI_FORMAT_R8G8_B8G8_UNORM, DXGI_FORMAT_G8R8_G8B8_UNORM, DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM, DXGI_FORMAT_BC1_UNORM_SRGB, DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM, DXGI_FORMAT_BC2_UNORM_SRGB, DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM, DXGI_FORMAT_BC3_UNORM_SRGB, DXGI_FORMAT_BC4_TYPELESS, DXGI_FORMAT_BC4_UNORM, DXGI_FORMAT_BC4_SNORM, DXGI_FORMAT_BC5_TYPELESS, DXGI_FORMAT_BC5_UNORM, DXGI_FORMAT_BC5_SNORM, DXGI_FORMAT_B5G6R5_UNORM, DXGI_FORMAT_B5G5R5A1_UNORM, DXGI_FORMAT_B8G8R8A8_UNORM, DXGI_FORMAT_B8G8R8X8_UNORM, DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM, DXGI_FORMAT_B8G8R8A8_TYPELESS, DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, DXGI_FORMAT_B8G8R8X8_TYPELESS, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, DXGI_FORMAT_BC6H_TYPELESS, DXGI_FORMAT_BC6H_UF16, DXGI_FORMAT_BC6H_SF16, DXGI_FORMAT_BC7_TYPELESS, DXGI_FORMAT_BC7_UNORM, DXGI_FORMAT_BC7_UNORM_SRGB, DXGI_FORMAT_AYUV, DXGI_FORMAT_Y410, DXGI_FORMAT_Y416, DXGI_FORMAT_NV12, DXGI_FORMAT_P010, DXGI_FORMAT_P016, DXGI_FORMAT_YUY2, DXGI_FORMAT_Y210, DXGI_FORMAT_Y216, DXGI_FORMAT_AI44, DXGI_FORMAT_IA44, DXGI_FORMAT_P8, DXGI_FORMAT_A8P8, DXGI_FORMAT_B4G4R4A4_UNORM, DXGI_FORMAT_V208, DXGI_FORMAT_V408, DXGI_FORMAT_FORCE_UINT}; template void D3DSharingFunctions::createQuery(D3DQuery **query) { D3DQueryDesc desc = {}; d3dDevice->CreateQuery(&desc, query); } template void D3DSharingFunctions::updateDevice(D3DResource *resource) { resource->GetDevice(&d3dDevice); } template void D3DSharingFunctions::fillCreateBufferDesc(D3DBufferDesc &desc, unsigned int width) { desc.ByteWidth = width; desc.MiscFlags = D3DResourceFlags::MISC_SHARED; } template void D3DSharingFunctions::fillCreateTexture2dDesc(D3DTexture2dDesc &desc, D3DTexture2dDesc *srcDesc, cl_uint subresource) { desc.Width = srcDesc->Width; desc.Height = srcDesc->Height; desc.MipLevels = 1; desc.ArraySize = 1; desc.Format = srcDesc->Format; desc.MiscFlags = D3DResourceFlags::MISC_SHARED; desc.SampleDesc.Count = srcDesc->SampleDesc.Count; desc.SampleDesc.Quality = srcDesc->SampleDesc.Quality; for (uint32_t i = 0u; i < (subresource % srcDesc->MipLevels); i++) { desc.Width /= 2; desc.Height /= 2; } } template void D3DSharingFunctions::fillCreateTexture3dDesc(D3DTexture3dDesc &desc, D3DTexture3dDesc *srcDesc, cl_uint subresource) { desc.Width = srcDesc->Width; desc.Height = srcDesc->Height; desc.Depth = srcDesc->Depth; desc.MipLevels = 1; desc.Format = srcDesc->Format; desc.MiscFlags = D3DResourceFlags::MISC_SHARED; for (uint32_t i = 0u; i < (subresource % srcDesc->MipLevels); i++) { desc.Width /= 2; desc.Height /= 2; desc.Depth /= 2; } } template void D3DSharingFunctions::createBuffer(D3DBufferObj **buffer, unsigned int width) { D3DBufferDesc stagingDesc = {}; fillCreateBufferDesc(stagingDesc, width); d3dDevice->CreateBuffer(&stagingDesc, nullptr, buffer); } template void D3DSharingFunctions::createTexture2d(D3DTexture2d **texture, D3DTexture2dDesc *desc, cl_uint subresource) { D3DTexture2dDesc stagingDesc = {}; fillCreateTexture2dDesc(stagingDesc, desc, subresource); d3dDevice->CreateTexture2D(&stagingDesc, nullptr, texture); } template void D3DSharingFunctions::createTexture3d(D3DTexture3d **texture, D3DTexture3dDesc *desc, cl_uint subresource) { D3DTexture3dDesc stagingDesc = {}; fillCreateTexture3dDesc(stagingDesc, desc, subresource); d3dDevice->CreateTexture3D(&stagingDesc, nullptr, texture); } template bool D3DSharingFunctions::checkFormatSupport(DXGI_FORMAT format, UINT *pFormat) { auto errorCode = d3dDevice->CheckFormatSupport(format, pFormat); return errorCode == S_OK; } template cl_int D3DSharingFunctions::validateFormatSupport(DXGI_FORMAT format, cl_mem_object_type type) { auto &formats = retrieveTextureFormats(type, 0); auto iter = std::find(formats.begin(), formats.end(), format); if (iter != formats.end()) { return CL_SUCCESS; } return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR; } template std::vector &D3DSharingFunctions::retrieveTextureFormats(cl_mem_object_type imageType, cl_uint plane) { auto cached = textureFormatCache.find(imageType); if (cached == textureFormatCache.end()) { bool success; std::tie(cached, success) = textureFormatCache.emplace(imageType, std::vector(0)); if (!success) { return DXGINoFormats; } std::vector &cached_formats = cached->second; std::vector planarFormats(0); cached_formats.reserve(arrayCount(DXGIFormats)); for (auto DXGIFormat : DXGIFormats) { UINT format = 0; if (checkFormatSupport(DXGIFormat, &format)) { if (memObjectFormatSupport(imageType, format)) { cached_formats.push_back(DXGIFormat); if (D3DSharing::isFormatWithPlane1(DXGIFormat)) { planarFormats.push_back(DXGIFormat); } } } } cached_formats.shrink_to_fit(); textureFormatPlane1Cache.emplace(imageType, planarFormats); } if (plane == 1) { return textureFormatPlane1Cache.find(imageType)->second; } return cached->second; } template <> bool D3DSharingFunctions::memObjectFormatSupport(cl_mem_object_type objectType, UINT format) { auto d3dformat = static_cast(format); return ((objectType & CL_MEM_OBJECT_BUFFER) && (d3dformat & D3D10_FORMAT_SUPPORT_BUFFER)) || ((objectType & CL_MEM_OBJECT_IMAGE2D) && (d3dformat & D3D10_FORMAT_SUPPORT_TEXTURE2D)) || ((objectType & CL_MEM_OBJECT_IMAGE3D) && (d3dformat & D3D10_FORMAT_SUPPORT_TEXTURE3D)); } template <> bool D3DSharingFunctions::memObjectFormatSupport(cl_mem_object_type objectType, UINT format) { auto d3dformat = static_cast(format); return ((objectType & CL_MEM_OBJECT_BUFFER) && (d3dformat & D3D11_FORMAT_SUPPORT_BUFFER)) || ((objectType & CL_MEM_OBJECT_IMAGE2D) && (d3dformat & D3D11_FORMAT_SUPPORT_TEXTURE2D)) || ((objectType & CL_MEM_OBJECT_IMAGE3D) && (d3dformat & D3D11_FORMAT_SUPPORT_TEXTURE3D)); } template void D3DSharingFunctions::getBufferDesc(D3DBufferDesc *bufferDesc, D3DBufferObj *buffer) { buffer->GetDesc(bufferDesc); } template void D3DSharingFunctions::getTexture2dDesc(D3DTexture2dDesc *textureDesc, D3DTexture2d *texture) { texture->GetDesc(textureDesc); } template void D3DSharingFunctions::getTexture3dDesc(D3DTexture3dDesc *textureDesc, D3DTexture3d *texture) { texture->GetDesc(textureDesc); } template void D3DSharingFunctions::getSharedHandle(D3DResource *resource, void **handle) { IDXGIResource *dxgiResource = nullptr; resource->QueryInterface(__uuidof(IDXGIResource), (void **)&dxgiResource); dxgiResource->GetSharedHandle(handle); dxgiResource->Release(); } template void D3DSharingFunctions::getSharedNTHandle(D3DResource *resource, void **handle) { IDXGIResource *dxgiResource = nullptr; IDXGIResource1 *dxgiResource1 = nullptr; resource->QueryInterface(__uuidof(IDXGIResource), (void **)&dxgiResource); dxgiResource->QueryInterface(__uuidof(IDXGIResource1), (void **)&dxgiResource1); dxgiResource1->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr, handle); dxgiResource1->Release(); dxgiResource->Release(); } template void D3DSharingFunctions::addRef(D3DResource *resource) { resource->AddRef(); } template void D3DSharingFunctions::release(IUnknown *resource) { resource->Release(); } template void D3DSharingFunctions::lockRect(D3DTexture2d *resource, D3DLOCKED_RECT *lockedRect, uint32_t flags) { } template void D3DSharingFunctions::unlockRect(D3DTexture2d *resource) { } template void D3DSharingFunctions::updateSurface(D3DTexture2d *src, D3DTexture2d *dst) { } template void D3DSharingFunctions::getRenderTargetData(D3DTexture2d *renderTarget, D3DTexture2d *dstSurface) { } template <> void D3DSharingFunctions::copySubresourceRegion(D3DResource *dst, cl_uint dstSubresource, D3DResource *src, cl_uint srcSubresource) { d3dDevice->CopySubresourceRegion(dst, dstSubresource, 0, 0, 0, src, srcSubresource, nullptr); } template <> void D3DSharingFunctions::copySubresourceRegion(D3DResource *dst, cl_uint dstSubresource, D3DResource *src, cl_uint srcSubresource) { d3d11DeviceContext->CopySubresourceRegion(dst, dstSubresource, 0, 0, 0, src, srcSubresource, nullptr); } template <> void D3DSharingFunctions::flushAndWait(D3DQuery *query) { query->End(); d3dDevice->Flush(); while (query->GetData(nullptr, 0, 0) != S_OK) ; } template <> void D3DSharingFunctions::flushAndWait(D3DQuery *query) { d3d11DeviceContext->End(query); d3d11DeviceContext->Flush(); while (d3d11DeviceContext->GetData(query, nullptr, 0, 0) != S_OK) ; } template <> void D3DSharingFunctions::getDeviceContext(D3DQuery *query) { } template <> void D3DSharingFunctions::getDeviceContext(D3DQuery *query) { d3dDevice->GetImmediateContext(&d3d11DeviceContext); } template <> void D3DSharingFunctions::releaseDeviceContext(D3DQuery *query) { } template <> void D3DSharingFunctions::releaseDeviceContext(D3DQuery *query) { d3d11DeviceContext->Release(); d3d11DeviceContext = nullptr; } template void D3DSharingFunctions::getDxgiDesc(DXGI_ADAPTER_DESC *dxgiDesc, IDXGIAdapter *adapter, D3DDevice *device) { if (!adapter) { IDXGIDevice *dxgiDevice = nullptr; device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice); dxgiDevice->GetAdapter(&adapter); dxgiDevice->Release(); } else { adapter->AddRef(); } adapter->GetDesc(dxgiDesc); adapter->Release(); } template D3DSharingFunctions *Context::getSharing>(); template D3DSharingFunctions *Context::getSharing>();