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