1 /*
2  * Copyright (C) 2018-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "opencl/source/context/context.inl"
9 #include "opencl/source/os_interface/windows/d3d_sharing_functions.h"
10 #include "opencl/source/sharings/d3d/d3d_sharing.h"
11 #include "opencl/source/sharings/sharing_factory.h"
12 
13 using namespace NEO;
14 
15 template class D3DSharingFunctions<D3DTypesHelper::D3D10>;
16 template class D3DSharingFunctions<D3DTypesHelper::D3D11>;
17 
18 const uint32_t D3DSharingFunctions<D3DTypesHelper::D3D10>::sharingId = SharingType::D3D10_SHARING;
19 const uint32_t D3DSharingFunctions<D3DTypesHelper::D3D11>::sharingId = SharingType::D3D11_SHARING;
20 
21 static const DXGI_FORMAT DXGIFormats[] = {
22     DXGI_FORMAT_R32G32B32A32_TYPELESS,
23     DXGI_FORMAT_R32G32B32A32_FLOAT,
24     DXGI_FORMAT_R32G32B32A32_UINT,
25     DXGI_FORMAT_R32G32B32A32_SINT,
26     DXGI_FORMAT_R32G32B32_TYPELESS,
27     DXGI_FORMAT_R32G32B32_FLOAT,
28     DXGI_FORMAT_R32G32B32_UINT,
29     DXGI_FORMAT_R32G32B32_SINT,
30     DXGI_FORMAT_R16G16B16A16_TYPELESS,
31     DXGI_FORMAT_R16G16B16A16_FLOAT,
32     DXGI_FORMAT_R16G16B16A16_UNORM,
33     DXGI_FORMAT_R16G16B16A16_UINT,
34     DXGI_FORMAT_R16G16B16A16_SNORM,
35     DXGI_FORMAT_R16G16B16A16_SINT,
36     DXGI_FORMAT_R32G32_TYPELESS,
37     DXGI_FORMAT_R32G32_FLOAT,
38     DXGI_FORMAT_R32G32_UINT,
39     DXGI_FORMAT_R32G32_SINT,
40     DXGI_FORMAT_R32G8X24_TYPELESS,
41     DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
42     DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
43     DXGI_FORMAT_X32_TYPELESS_G8X24_UINT,
44     DXGI_FORMAT_R10G10B10A2_TYPELESS,
45     DXGI_FORMAT_R10G10B10A2_UNORM,
46     DXGI_FORMAT_R10G10B10A2_UINT,
47     DXGI_FORMAT_R11G11B10_FLOAT,
48     DXGI_FORMAT_R8G8B8A8_TYPELESS,
49     DXGI_FORMAT_R8G8B8A8_UNORM,
50     DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
51     DXGI_FORMAT_R8G8B8A8_UINT,
52     DXGI_FORMAT_R8G8B8A8_SNORM,
53     DXGI_FORMAT_R8G8B8A8_SINT,
54     DXGI_FORMAT_R16G16_TYPELESS,
55     DXGI_FORMAT_R16G16_FLOAT,
56     DXGI_FORMAT_R16G16_UNORM,
57     DXGI_FORMAT_R16G16_UINT,
58     DXGI_FORMAT_R16G16_SNORM,
59     DXGI_FORMAT_R16G16_SINT,
60     DXGI_FORMAT_R32_TYPELESS,
61     DXGI_FORMAT_D32_FLOAT,
62     DXGI_FORMAT_R32_FLOAT,
63     DXGI_FORMAT_R32_UINT,
64     DXGI_FORMAT_R32_SINT,
65     DXGI_FORMAT_R24G8_TYPELESS,
66     DXGI_FORMAT_D24_UNORM_S8_UINT,
67     DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
68     DXGI_FORMAT_X24_TYPELESS_G8_UINT,
69     DXGI_FORMAT_R8G8_TYPELESS,
70     DXGI_FORMAT_R8G8_UNORM,
71     DXGI_FORMAT_R8G8_UINT,
72     DXGI_FORMAT_R8G8_SNORM,
73     DXGI_FORMAT_R8G8_SINT,
74     DXGI_FORMAT_R16_TYPELESS,
75     DXGI_FORMAT_R16_FLOAT,
76     DXGI_FORMAT_D16_UNORM,
77     DXGI_FORMAT_R16_UNORM,
78     DXGI_FORMAT_R16_UINT,
79     DXGI_FORMAT_R16_SNORM,
80     DXGI_FORMAT_R16_SINT,
81     DXGI_FORMAT_R8_TYPELESS,
82     DXGI_FORMAT_R8_UNORM,
83     DXGI_FORMAT_R8_UINT,
84     DXGI_FORMAT_R8_SNORM,
85     DXGI_FORMAT_R8_SINT,
86     DXGI_FORMAT_A8_UNORM,
87     DXGI_FORMAT_R1_UNORM,
88     DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
89     DXGI_FORMAT_R8G8_B8G8_UNORM,
90     DXGI_FORMAT_G8R8_G8B8_UNORM,
91     DXGI_FORMAT_BC1_TYPELESS,
92     DXGI_FORMAT_BC1_UNORM,
93     DXGI_FORMAT_BC1_UNORM_SRGB,
94     DXGI_FORMAT_BC2_TYPELESS,
95     DXGI_FORMAT_BC2_UNORM,
96     DXGI_FORMAT_BC2_UNORM_SRGB,
97     DXGI_FORMAT_BC3_TYPELESS,
98     DXGI_FORMAT_BC3_UNORM,
99     DXGI_FORMAT_BC3_UNORM_SRGB,
100     DXGI_FORMAT_BC4_TYPELESS,
101     DXGI_FORMAT_BC4_UNORM,
102     DXGI_FORMAT_BC4_SNORM,
103     DXGI_FORMAT_BC5_TYPELESS,
104     DXGI_FORMAT_BC5_UNORM,
105     DXGI_FORMAT_BC5_SNORM,
106     DXGI_FORMAT_B5G6R5_UNORM,
107     DXGI_FORMAT_B5G5R5A1_UNORM,
108     DXGI_FORMAT_B8G8R8A8_UNORM,
109     DXGI_FORMAT_B8G8R8X8_UNORM,
110     DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM,
111     DXGI_FORMAT_B8G8R8A8_TYPELESS,
112     DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
113     DXGI_FORMAT_B8G8R8X8_TYPELESS,
114     DXGI_FORMAT_B8G8R8X8_UNORM_SRGB,
115     DXGI_FORMAT_BC6H_TYPELESS,
116     DXGI_FORMAT_BC6H_UF16,
117     DXGI_FORMAT_BC6H_SF16,
118     DXGI_FORMAT_BC7_TYPELESS,
119     DXGI_FORMAT_BC7_UNORM,
120     DXGI_FORMAT_BC7_UNORM_SRGB,
121     DXGI_FORMAT_AYUV,
122     DXGI_FORMAT_Y410,
123     DXGI_FORMAT_Y416,
124     DXGI_FORMAT_NV12,
125     DXGI_FORMAT_P010,
126     DXGI_FORMAT_P016,
127     DXGI_FORMAT_YUY2,
128     DXGI_FORMAT_Y210,
129     DXGI_FORMAT_Y216,
130     DXGI_FORMAT_AI44,
131     DXGI_FORMAT_IA44,
132     DXGI_FORMAT_P8,
133     DXGI_FORMAT_A8P8,
134     DXGI_FORMAT_B4G4R4A4_UNORM,
135     DXGI_FORMAT_V208,
136     DXGI_FORMAT_V408,
137     DXGI_FORMAT_FORCE_UINT};
138 
139 template <typename D3D>
createQuery(D3DQuery ** query)140 void D3DSharingFunctions<D3D>::createQuery(D3DQuery **query) {
141     D3DQueryDesc desc = {};
142     d3dDevice->CreateQuery(&desc, query);
143 }
144 
145 template <typename D3D>
updateDevice(D3DResource * resource)146 void D3DSharingFunctions<D3D>::updateDevice(D3DResource *resource) {
147     resource->GetDevice(&d3dDevice);
148 }
149 
150 template <typename D3D>
fillCreateBufferDesc(D3DBufferDesc & desc,unsigned int width)151 void D3DSharingFunctions<D3D>::fillCreateBufferDesc(D3DBufferDesc &desc, unsigned int width) {
152     desc.ByteWidth = width;
153     desc.MiscFlags = D3DResourceFlags::MISC_SHARED;
154 }
155 
156 template <typename D3D>
fillCreateTexture2dDesc(D3DTexture2dDesc & desc,D3DTexture2dDesc * srcDesc,cl_uint subresource)157 void D3DSharingFunctions<D3D>::fillCreateTexture2dDesc(D3DTexture2dDesc &desc, D3DTexture2dDesc *srcDesc, cl_uint subresource) {
158     desc.Width = srcDesc->Width;
159     desc.Height = srcDesc->Height;
160     desc.MipLevels = 1;
161     desc.ArraySize = 1;
162     desc.Format = srcDesc->Format;
163     desc.MiscFlags = D3DResourceFlags::MISC_SHARED;
164     desc.SampleDesc.Count = srcDesc->SampleDesc.Count;
165     desc.SampleDesc.Quality = srcDesc->SampleDesc.Quality;
166 
167     for (uint32_t i = 0u; i < (subresource % srcDesc->MipLevels); i++) {
168         desc.Width /= 2;
169         desc.Height /= 2;
170     }
171 }
172 
173 template <typename D3D>
fillCreateTexture3dDesc(D3DTexture3dDesc & desc,D3DTexture3dDesc * srcDesc,cl_uint subresource)174 void D3DSharingFunctions<D3D>::fillCreateTexture3dDesc(D3DTexture3dDesc &desc, D3DTexture3dDesc *srcDesc, cl_uint subresource) {
175     desc.Width = srcDesc->Width;
176     desc.Height = srcDesc->Height;
177     desc.Depth = srcDesc->Depth;
178     desc.MipLevels = 1;
179     desc.Format = srcDesc->Format;
180     desc.MiscFlags = D3DResourceFlags::MISC_SHARED;
181 
182     for (uint32_t i = 0u; i < (subresource % srcDesc->MipLevels); i++) {
183         desc.Width /= 2;
184         desc.Height /= 2;
185         desc.Depth /= 2;
186     }
187 }
188 
189 template <typename D3D>
createBuffer(D3DBufferObj ** buffer,unsigned int width)190 void D3DSharingFunctions<D3D>::createBuffer(D3DBufferObj **buffer, unsigned int width) {
191     D3DBufferDesc stagingDesc = {};
192     fillCreateBufferDesc(stagingDesc, width);
193     d3dDevice->CreateBuffer(&stagingDesc, nullptr, buffer);
194 }
195 
196 template <typename D3D>
createTexture2d(D3DTexture2d ** texture,D3DTexture2dDesc * desc,cl_uint subresource)197 void D3DSharingFunctions<D3D>::createTexture2d(D3DTexture2d **texture, D3DTexture2dDesc *desc, cl_uint subresource) {
198     D3DTexture2dDesc stagingDesc = {};
199     fillCreateTexture2dDesc(stagingDesc, desc, subresource);
200     d3dDevice->CreateTexture2D(&stagingDesc, nullptr, texture);
201 }
202 
203 template <typename D3D>
createTexture3d(D3DTexture3d ** texture,D3DTexture3dDesc * desc,cl_uint subresource)204 void D3DSharingFunctions<D3D>::createTexture3d(D3DTexture3d **texture, D3DTexture3dDesc *desc, cl_uint subresource) {
205     D3DTexture3dDesc stagingDesc = {};
206     fillCreateTexture3dDesc(stagingDesc, desc, subresource);
207     d3dDevice->CreateTexture3D(&stagingDesc, nullptr, texture);
208 }
209 
210 template <typename D3D>
checkFormatSupport(DXGI_FORMAT format,UINT * pFormat)211 bool D3DSharingFunctions<D3D>::checkFormatSupport(DXGI_FORMAT format, UINT *pFormat) {
212     auto errorCode = d3dDevice->CheckFormatSupport(format, pFormat);
213     return errorCode == S_OK;
214 }
215 
216 template <typename D3D>
validateFormatSupport(DXGI_FORMAT format,cl_mem_object_type type)217 cl_int D3DSharingFunctions<D3D>::validateFormatSupport(DXGI_FORMAT format, cl_mem_object_type type) {
218     auto &formats = retrieveTextureFormats(type, 0);
219     auto iter = std::find(formats.begin(), formats.end(), format);
220 
221     if (iter != formats.end()) {
222         return CL_SUCCESS;
223     }
224 
225     return CL_INVALID_IMAGE_FORMAT_DESCRIPTOR;
226 }
227 
228 template <typename D3D>
retrieveTextureFormats(cl_mem_object_type imageType,cl_uint plane)229 std::vector<DXGI_FORMAT> &D3DSharingFunctions<D3D>::retrieveTextureFormats(cl_mem_object_type imageType, cl_uint plane) {
230     auto cached = textureFormatCache.find(imageType);
231     if (cached == textureFormatCache.end()) {
232         bool success;
233         std::tie(cached, success) = textureFormatCache.emplace(imageType, std::vector<DXGI_FORMAT>(0));
234         if (!success) {
235             return DXGINoFormats;
236         }
237         std::vector<DXGI_FORMAT> &cached_formats = cached->second;
238         std::vector<DXGI_FORMAT> planarFormats(0);
239 
240         cached_formats.reserve(arrayCount(DXGIFormats));
241         for (auto DXGIFormat : DXGIFormats) {
242             UINT format = 0;
243             if (checkFormatSupport(DXGIFormat, &format)) {
244                 if (memObjectFormatSupport(imageType, format)) {
245                     cached_formats.push_back(DXGIFormat);
246                     if (D3DSharing<D3D>::isFormatWithPlane1(DXGIFormat)) {
247                         planarFormats.push_back(DXGIFormat);
248                     }
249                 }
250             }
251         }
252         cached_formats.shrink_to_fit();
253         textureFormatPlane1Cache.emplace(imageType, planarFormats);
254     }
255 
256     if (plane == 1) {
257         return textureFormatPlane1Cache.find(imageType)->second;
258     }
259     return cached->second;
260 }
261 
262 template <>
memObjectFormatSupport(cl_mem_object_type objectType,UINT format)263 bool D3DSharingFunctions<D3DTypesHelper::D3D10>::memObjectFormatSupport(cl_mem_object_type objectType, UINT format) {
264     auto d3dformat = static_cast<D3D10_FORMAT_SUPPORT>(format);
265     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));
266 }
267 
268 template <>
memObjectFormatSupport(cl_mem_object_type objectType,UINT format)269 bool D3DSharingFunctions<D3DTypesHelper::D3D11>::memObjectFormatSupport(cl_mem_object_type objectType, UINT format) {
270     auto d3dformat = static_cast<D3D11_FORMAT_SUPPORT>(format);
271     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));
272 }
273 
274 template <typename D3D>
getBufferDesc(D3DBufferDesc * bufferDesc,D3DBufferObj * buffer)275 void D3DSharingFunctions<D3D>::getBufferDesc(D3DBufferDesc *bufferDesc, D3DBufferObj *buffer) {
276     buffer->GetDesc(bufferDesc);
277 }
278 
279 template <typename D3D>
getTexture2dDesc(D3DTexture2dDesc * textureDesc,D3DTexture2d * texture)280 void D3DSharingFunctions<D3D>::getTexture2dDesc(D3DTexture2dDesc *textureDesc, D3DTexture2d *texture) {
281     texture->GetDesc(textureDesc);
282 }
283 
284 template <typename D3D>
getTexture3dDesc(D3DTexture3dDesc * textureDesc,D3DTexture3d * texture)285 void D3DSharingFunctions<D3D>::getTexture3dDesc(D3DTexture3dDesc *textureDesc, D3DTexture3d *texture) {
286     texture->GetDesc(textureDesc);
287 }
288 
289 template <typename D3D>
getSharedHandle(D3DResource * resource,void ** handle)290 void D3DSharingFunctions<D3D>::getSharedHandle(D3DResource *resource, void **handle) {
291     IDXGIResource *dxgiResource = nullptr;
292     resource->QueryInterface(__uuidof(IDXGIResource), (void **)&dxgiResource);
293     dxgiResource->GetSharedHandle(handle);
294     dxgiResource->Release();
295 }
296 
297 template <typename D3D>
getSharedNTHandle(D3DResource * resource,void ** handle)298 void D3DSharingFunctions<D3D>::getSharedNTHandle(D3DResource *resource, void **handle) {
299     IDXGIResource *dxgiResource = nullptr;
300     IDXGIResource1 *dxgiResource1 = nullptr;
301     resource->QueryInterface(__uuidof(IDXGIResource), (void **)&dxgiResource);
302     dxgiResource->QueryInterface(__uuidof(IDXGIResource1), (void **)&dxgiResource1);
303     dxgiResource1->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, nullptr, handle);
304     dxgiResource1->Release();
305     dxgiResource->Release();
306 }
307 
308 template <typename D3D>
addRef(D3DResource * resource)309 void D3DSharingFunctions<D3D>::addRef(D3DResource *resource) {
310     resource->AddRef();
311 }
312 
313 template <typename D3D>
release(IUnknown * resource)314 void D3DSharingFunctions<D3D>::release(IUnknown *resource) {
315     resource->Release();
316 }
317 
318 template <typename D3D>
lockRect(D3DTexture2d * resource,D3DLOCKED_RECT * lockedRect,uint32_t flags)319 void D3DSharingFunctions<D3D>::lockRect(D3DTexture2d *resource, D3DLOCKED_RECT *lockedRect, uint32_t flags) {
320 }
321 
322 template <typename D3D>
unlockRect(D3DTexture2d * resource)323 void D3DSharingFunctions<D3D>::unlockRect(D3DTexture2d *resource) {
324 }
325 
326 template <typename D3D>
updateSurface(D3DTexture2d * src,D3DTexture2d * dst)327 void D3DSharingFunctions<D3D>::updateSurface(D3DTexture2d *src, D3DTexture2d *dst) {
328 }
329 
330 template <typename D3D>
getRenderTargetData(D3DTexture2d * renderTarget,D3DTexture2d * dstSurface)331 void D3DSharingFunctions<D3D>::getRenderTargetData(D3DTexture2d *renderTarget, D3DTexture2d *dstSurface) {
332 }
333 
334 template <>
copySubresourceRegion(D3DResource * dst,cl_uint dstSubresource,D3DResource * src,cl_uint srcSubresource)335 void D3DSharingFunctions<D3DTypesHelper::D3D10>::copySubresourceRegion(D3DResource *dst, cl_uint dstSubresource,
336                                                                        D3DResource *src, cl_uint srcSubresource) {
337     d3dDevice->CopySubresourceRegion(dst, dstSubresource, 0, 0, 0, src, srcSubresource, nullptr);
338 }
339 
340 template <>
copySubresourceRegion(D3DResource * dst,cl_uint dstSubresource,D3DResource * src,cl_uint srcSubresource)341 void D3DSharingFunctions<D3DTypesHelper::D3D11>::copySubresourceRegion(D3DResource *dst, cl_uint dstSubresource,
342                                                                        D3DResource *src, cl_uint srcSubresource) {
343     d3d11DeviceContext->CopySubresourceRegion(dst, dstSubresource, 0, 0, 0, src, srcSubresource, nullptr);
344 }
345 
346 template <>
flushAndWait(D3DQuery * query)347 void D3DSharingFunctions<D3DTypesHelper::D3D10>::flushAndWait(D3DQuery *query) {
348     query->End();
349     d3dDevice->Flush();
350     while (query->GetData(nullptr, 0, 0) != S_OK)
351         ;
352 }
353 
354 template <>
flushAndWait(D3DQuery * query)355 void D3DSharingFunctions<D3DTypesHelper::D3D11>::flushAndWait(D3DQuery *query) {
356     d3d11DeviceContext->End(query);
357     d3d11DeviceContext->Flush();
358     while (d3d11DeviceContext->GetData(query, nullptr, 0, 0) != S_OK)
359         ;
360 }
361 
362 template <>
getDeviceContext(D3DQuery * query)363 void D3DSharingFunctions<D3DTypesHelper::D3D10>::getDeviceContext(D3DQuery *query) {
364 }
365 
366 template <>
getDeviceContext(D3DQuery * query)367 void D3DSharingFunctions<D3DTypesHelper::D3D11>::getDeviceContext(D3DQuery *query) {
368     d3dDevice->GetImmediateContext(&d3d11DeviceContext);
369 }
370 
371 template <>
releaseDeviceContext(D3DQuery * query)372 void D3DSharingFunctions<D3DTypesHelper::D3D10>::releaseDeviceContext(D3DQuery *query) {
373 }
374 
375 template <>
releaseDeviceContext(D3DQuery * query)376 void D3DSharingFunctions<D3DTypesHelper::D3D11>::releaseDeviceContext(D3DQuery *query) {
377     d3d11DeviceContext->Release();
378     d3d11DeviceContext = nullptr;
379 }
380 template <typename D3D>
getDxgiDesc(DXGI_ADAPTER_DESC * dxgiDesc,IDXGIAdapter * adapter,D3DDevice * device)381 void D3DSharingFunctions<D3D>::getDxgiDesc(DXGI_ADAPTER_DESC *dxgiDesc, IDXGIAdapter *adapter, D3DDevice *device) {
382     if (!adapter) {
383         IDXGIDevice *dxgiDevice = nullptr;
384         device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
385         dxgiDevice->GetAdapter(&adapter);
386         dxgiDevice->Release();
387     } else {
388         adapter->AddRef();
389     }
390     adapter->GetDesc(dxgiDesc);
391     adapter->Release();
392 }
393 
394 template D3DSharingFunctions<D3DTypesHelper::D3D10> *Context::getSharing<D3DSharingFunctions<D3DTypesHelper::D3D10>>();
395 template D3DSharingFunctions<D3DTypesHelper::D3D11> *Context::getSharing<D3DSharingFunctions<D3DTypesHelper::D3D11>>();
396