• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //    http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #define _CRT_SECURE_NO_WARNINGS
17 #include "harness.h"
18 
19 Texture3DSize texture3DSizes[] =
20 {
21     {
22         4, // Width
23         4, // Height
24         4, // Depth
25         1, // MipLevels
26         1, // SubResourceCount
27         {  // SubResources
28             { 0 }, // MipLevel
29             { 0 }, // MipLevel
30             { 0 }, // MipLevel
31             { 0 }, // MipLevel
32         },
33         0, // MiscFlags
34     },
35     {
36         127, // Width
37         25, // Height
38         33, // Depth
39         1, // MipLevels
40         1, // SubResourceCount
41         {  // SubResources
42             { 0 }, // MipLevel
43             { 0 }, // MipLevel
44             { 0 }, // MipLevel
45             { 0 }, // MipLevel
46         },
47         0, // MiscFlags
48     },
49     {
50         128, // Width
51         256, // Height
52         64, // Depth
53         4, // MipLevels
54         3, // SubResourceCount
55         {  // SubResources
56             { 2 }, // MipLevel
57             { 1 }, // MipLevel
58             { 0 }, // MipLevel
59             { 0 }, // MipLevel
60         },
61         0, // MiscFlags
62     },
63     {
64         512, // Width
65          64, // Height
66          32, // Depth
67         3, // MipLevels
68         1, // SubResourceCount
69         {  // SubResources
70             { 2 }, // MipLevel
71             { 0 }, // MipLevel
72             { 0 }, // MipLevel
73             { 0 }, // MipLevel
74         },
75         0, // MiscFlags
76     },
77 };
78 UINT texture3DSizeCount = sizeof(texture3DSizes)/sizeof(texture3DSizes[0]);
79 
80 const char *
81 texture3DPatterns[2][2][2] =
82 {
83     {
84         {"PlaceTheCasseroleDis", "hInAColdOvenPlaceACh"},
85         {"airFacingTheOvenAndS", "itInItForeverThinkAb"},
86     },
87     {
88         {"outHowHungryYouAreWh", "enNightFallsDoNotTur"},
89         {"nOnTheLightMyEyeBeca", "meInflamedIHateCamus"},
90     },
91 };
92 
SubTestTexture3D(cl_context context,cl_command_queue command_queue,ID3D10Device * pDevice,const TextureFormat * format,const Texture3DSize * size)93 void SubTestTexture3D(
94     cl_context context,
95     cl_command_queue command_queue,
96     ID3D10Device* pDevice,
97     const TextureFormat* format,
98     const Texture3DSize* size)
99 {
100     ID3D10Texture3D* pTexture = NULL;
101     HRESULT hr = S_OK;
102 
103     cl_int result = CL_SUCCESS;
104 
105     HarnessD3D10_TestBegin("3D Texture: Format=%s, Width=%d, Height=%d, Depth=%d, MipLevels=%d",
106         format->name_format,
107         size->Width,
108         size->Height,
109         size->Depth,
110         size->MipLevels);
111 
112     struct
113     {
114         cl_mem mem;
115         UINT subResource;
116         UINT width;
117         UINT height;
118         UINT depth;
119     }
120     subResourceInfo[4];
121 
122     // create the D3D10 resources
123     {
124         D3D10_TEXTURE3D_DESC desc;
125         memset(&desc, 0, sizeof(desc) );
126         desc.Width      = size->Width;
127         desc.Height     = size->Height;
128         desc.Depth      = size->Depth;
129         desc.MipLevels  = size->MipLevels;
130         desc.Format     = format->format;
131         desc.Usage = D3D10_USAGE_DEFAULT;
132         desc.BindFlags = D3D10_BIND_SHADER_RESOURCE;
133         desc.CPUAccessFlags = 0;
134         desc.MiscFlags = 0;
135 
136         hr = pDevice->CreateTexture3D(&desc, NULL, &pTexture);
137         TestRequire(SUCCEEDED(hr), "CreateTexture3D failed.");
138     }
139 
140     // initialize some useful variables
141     for (UINT i = 0; i < size->SubResourceCount; ++i)
142     {
143         // compute the expected values for the subresource
144         subResourceInfo[i].subResource = size->subResources[i].MipLevel;
145         subResourceInfo[i].width = size->Width;
146         subResourceInfo[i].height = size->Height;
147         subResourceInfo[i].depth = size->Depth;
148         for (UINT j = 0; j < size->subResources[i].MipLevel; ++j) {
149             subResourceInfo[i].width /= 2;
150             subResourceInfo[i].height /= 2;
151             subResourceInfo[i].depth /= 2;
152         }
153     }
154 
155     // copy a pattern into the corners of the image, coordinates
156     for (UINT i = 0; i < size->SubResourceCount; ++i)
157     for (UINT x = 0; x < 2; ++x)
158     for (UINT y = 0; y < 2; ++y)
159     for (UINT z = 0; z < 2; ++z)
160     {
161         // create the staging buffer
162         ID3D10Texture3D* pStagingBuffer = NULL;
163         {
164             D3D10_TEXTURE3D_DESC desc = {0};
165             desc.Width      = 1;
166             desc.Height     = 1;
167             desc.Depth      = 1;
168             desc.MipLevels  = 1;
169             desc.Format     = format->format;
170             desc.Usage = D3D10_USAGE_STAGING;
171             desc.BindFlags = 0;
172             desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
173             desc.MiscFlags = 0;
174             hr = pDevice->CreateTexture3D(&desc, NULL, &pStagingBuffer);
175             TestRequire(SUCCEEDED(hr), "CreateTexture3D failed.");
176         }
177 
178         // write the data to the staging buffer
179         {
180             D3D10_MAPPED_TEXTURE3D mappedTexture;
181             hr = pStagingBuffer->Map(
182                 0,
183                 D3D10_MAP_READ_WRITE,
184                 0,
185                 &mappedTexture);
186             memcpy(mappedTexture.pData, texture3DPatterns[x][y][z], format->bytesPerPixel);
187             pStagingBuffer->Unmap(0);
188         }
189 
190         // copy the data to to the texture
191         {
192             D3D10_BOX box = {0};
193             box.front   = 0; box.back    = 1;
194             box.top     = 0; box.bottom  = 1;
195             box.left    = 0; box.right   = 1;
196             pDevice->CopySubresourceRegion(
197                 pTexture,
198                 subResourceInfo[i].subResource,
199                 x ? subResourceInfo[i].width  - 1 : 0,
200                 y ? subResourceInfo[i].height - 1 : 0,
201                 z ? subResourceInfo[i].depth  - 1 : 0,
202                 pStagingBuffer,
203                 0,
204                 &box);
205         }
206 
207         pStagingBuffer->Release();
208     }
209 
210     // create the cl_mem objects for the resources and verify its sanity
211     for (UINT i = 0; i < size->SubResourceCount; ++i)
212     {
213         // create a cl_mem for the resource
214         subResourceInfo[i].mem = clCreateFromD3D10Texture3DKHR(
215             context,
216             0,
217             pTexture,
218             subResourceInfo[i].subResource,
219             &result);
220         TestRequire(result == CL_SUCCESS, "clCreateFromD3D10Texture3DKHR failed");
221 
222         // query resource pointer and verify
223         ID3D10Resource* clResource = NULL;
224         result = clGetMemObjectInfo(
225             subResourceInfo[i].mem,
226             CL_MEM_D3D10_RESOURCE_KHR,
227             sizeof(clResource),
228             &clResource,
229             NULL);
230         TestRequire(result == CL_SUCCESS, "clGetMemObjectInfo for CL_MEM_D3D10_RESOURCE_KHR failed.");
231         TestRequire(clResource == pTexture, "clGetMemObjectInfo for CL_MEM_D3D10_RESOURCE_KHR returned incorrect value.");
232 
233         // query subresource and verify
234         UINT clSubResource;
235         result = clGetImageInfo(
236             subResourceInfo[i].mem,
237             CL_IMAGE_D3D10_SUBRESOURCE_KHR,
238             sizeof(clSubResource),
239             &clSubResource,
240             NULL);
241         TestRequire(result == CL_SUCCESS, "clGetImageInfo for CL_IMAGE_D3D10_SUBRESOURCE_KHR failed");
242         TestRequire(clSubResource == subResourceInfo[i].subResource, "clGetImageInfo for CL_IMAGE_D3D10_SUBRESOURCE_KHR returned incorrect value.");
243 
244         // query format and verify
245         cl_image_format clFormat;
246         result = clGetImageInfo(
247             subResourceInfo[i].mem,
248             CL_IMAGE_FORMAT,
249             sizeof(clFormat),
250             &clFormat,
251             NULL);
252         TestRequire(result == CL_SUCCESS, "clGetImageInfo for CL_IMAGE_FORMAT failed");
253         TestRequire(clFormat.image_channel_order == format->channel_order, "clGetImageInfo for CL_IMAGE_FORMAT returned incorrect channel order.");
254         TestRequire(clFormat.image_channel_data_type == format->channel_type, "clGetImageInfo for CL_IMAGE_FORMAT returned incorrect channel data type.");
255 
256         // query width
257         size_t width;
258         result = clGetImageInfo(
259             subResourceInfo[i].mem,
260             CL_IMAGE_WIDTH,
261             sizeof(width),
262             &width,
263             NULL);
264         TestRequire(result == CL_SUCCESS, "clGetImageInfo for CL_IMAGE_WIDTH failed");
265         TestRequire(width == subResourceInfo[i].width, "clGetImageInfo for CL_IMAGE_HEIGHT returned incorrect value.");
266 
267         // query height
268         size_t height;
269         result = clGetImageInfo(
270             subResourceInfo[i].mem,
271             CL_IMAGE_HEIGHT,
272             sizeof(height),
273             &height,
274             NULL);
275         TestRequire(result == CL_SUCCESS, "clGetImageInfo for CL_IMAGE_HEIGHT failed");
276         TestRequire(height == subResourceInfo[i].height, "clGetImageInfo for CL_IMAGE_HEIGHT returned incorrect value.");
277 
278         // query depth
279         size_t depth;
280         result = clGetImageInfo(
281             subResourceInfo[i].mem,
282             CL_IMAGE_DEPTH,
283             sizeof(depth),
284             &depth,
285             NULL);
286         TestRequire(result == CL_SUCCESS, "clGetImageInfo for CL_IMAGE_DEPTH failed");
287         TestRequire(depth == subResourceInfo[i].depth, "clGetImageInfo for CL_IMAGE_DEPTH returned incorrect value.");
288 
289     }
290 
291     // acquire the resources for OpenCL
292     {
293         cl_mem memToAcquire[MAX_REGISTERED_SUBRESOURCES];
294 
295         // cut the registered sub-resources into two sets and send the acquire calls for them separately
296         for(UINT i = 0; i < size->SubResourceCount; ++i)
297         {
298             memToAcquire[i] = subResourceInfo[i].mem;
299         }
300 
301         // do the acquire
302         result = clEnqueueAcquireD3D10ObjectsKHR(
303             command_queue,
304             size->SubResourceCount,
305             memToAcquire,
306             0,
307             NULL,
308             NULL);
309         TestRequire(result == CL_SUCCESS, "clEnqueueAcquireD3D10ObjectsKHR failed.");
310     }
311 
312     // download the data using OpenCL & compare with the expected results
313     // copy the corners of the image into the image
314     for (UINT i = 0; i < size->SubResourceCount; ++i)
315     for (UINT x = 0; x < 2; ++x)
316     for (UINT y = 0; y < 2; ++y)
317     for (UINT z = 0; z < 2; ++z)
318     {
319         if (x == y && y == z && 0)
320         {
321             continue;
322         }
323         size_t src[3] =
324         {
325             x ? subResourceInfo[i].width  - 1 : 0,
326             y ? subResourceInfo[i].height - 1 : 0,
327             z ? subResourceInfo[i].depth  - 1 : 0,
328         };
329         size_t dst[3] =
330         {
331             x ? subResourceInfo[i].width  - 2 : 1,
332             y ? subResourceInfo[i].height - 2 : 1,
333             z ? subResourceInfo[i].depth  - 2 : 1,
334         };
335         size_t region[3] =
336         {
337             1,
338             1,
339             1,
340         };
341         result = clEnqueueCopyImage(
342             command_queue,
343             subResourceInfo[i].mem,
344             subResourceInfo[i].mem,
345             src,
346             dst,
347             region,
348             0,
349             NULL,
350             NULL);
351         TestRequire(result == CL_SUCCESS, "clEnqueueCopyImage failed.");
352     }
353 
354     // release the resource from OpenCL
355     {
356         cl_mem memToAcquire[MAX_REGISTERED_SUBRESOURCES];
357         for(UINT i = 0; i < size->SubResourceCount; ++i)
358         {
359             memToAcquire[i] = subResourceInfo[i].mem;
360         }
361 
362         // do the release
363         result = clEnqueueReleaseD3D10ObjectsKHR(
364             command_queue,
365             size->SubResourceCount,
366             memToAcquire,
367             0,
368             NULL,
369             NULL);
370         TestRequire(result == CL_SUCCESS, "clEnqueueReleaseD3D10ObjectsKHR failed.");
371     }
372 
373     for (UINT i = 0; i < size->SubResourceCount; ++i)
374     for (UINT x = 0; x < 2; ++x)
375     for (UINT y = 0; y < 2; ++y)
376     for (UINT z = 0; z < 2; ++z)
377     {
378         // create the staging buffer
379         ID3D10Texture3D* pStagingBuffer = NULL;
380         {
381             D3D10_TEXTURE3D_DESC desc = {0};
382             desc.Width      = 1;
383             desc.Height     = 1;
384             desc.Depth      = 1;
385             desc.MipLevels  = 1;
386             desc.Format     = format->format;
387             desc.Usage = D3D10_USAGE_STAGING;
388             desc.BindFlags = 0;
389             desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
390             desc.MiscFlags = 0;
391             hr = pDevice->CreateTexture3D(&desc, NULL, &pStagingBuffer);
392             TestRequire(SUCCEEDED(hr), "Failed to create staging buffer.");
393         }
394 
395         // wipe out the staging buffer to make sure we don't get stale values
396         {
397             D3D10_MAPPED_TEXTURE3D mappedTexture;
398             hr = pStagingBuffer->Map(
399                 0,
400                 D3D10_MAP_READ_WRITE,
401                 0,
402                 &mappedTexture);
403             TestRequire(SUCCEEDED(hr), "Failed to map staging buffer");
404             memset(mappedTexture.pData, 0, format->bytesPerPixel);
405             pStagingBuffer->Unmap(0);
406         }
407 
408         // copy the pixel to the staging buffer
409         {
410             D3D10_BOX box = {0};
411             box.left    = x ? subResourceInfo[i].width  - 2 : 1; box.right  = box.left  + 1;
412             box.top     = y ? subResourceInfo[i].height - 2 : 1; box.bottom = box.top   + 1;
413             box.front   = z ? subResourceInfo[i].depth  - 2 : 1; box.back   = box.front + 1;
414             pDevice->CopySubresourceRegion(
415                 pStagingBuffer,
416                 0,
417                 0,
418                 0,
419                 0,
420                 pTexture,
421                 subResourceInfo[i].subResource,
422                 &box);
423         }
424 
425         // make sure we read back what was written next door
426         {
427             D3D10_MAPPED_TEXTURE3D mappedTexture;
428             hr = pStagingBuffer->Map(
429                 0,
430                 D3D10_MAP_READ_WRITE,
431                 0,
432                 &mappedTexture);
433             TestRequire(SUCCEEDED(hr), "Failed to map staging buffer");
434 
435             /*
436             // This can be helpful in debugging...
437             printf("\n");
438             for (UINT k = 0; k < format->bytesPerPixel; ++k)
439             {
440                 printf("[%c %c]\n",
441                     texture2DPatterns[x][y][k],
442                     ( (char *)mappedTexture.pData )[k]);
443             }
444             */
445 
446             TestRequire(
447                 !memcmp(mappedTexture.pData, texture3DPatterns[x][y][z], format->bytesPerPixel),
448                 "Failed to map staging buffer");
449 
450             pStagingBuffer->Unmap(0);
451         }
452 
453         pStagingBuffer->Release();
454     }
455 
456 
457 Cleanup:
458 
459     if (pTexture)
460     {
461         pTexture->Release();
462     }
463     for (UINT i = 0; i < size->SubResourceCount; ++i)
464     {
465         clReleaseMemObject(subResourceInfo[i].mem);
466     }
467 
468     HarnessD3D10_TestEnd();
469 }
470 
471 
TestDeviceTexture3D(cl_device_id device,cl_context context,cl_command_queue command_queue,ID3D10Device * pDevice)472 void TestDeviceTexture3D(
473     cl_device_id device,
474     cl_context context,
475     cl_command_queue command_queue,
476     ID3D10Device* pDevice)
477 {
478     cl_int result = CL_SUCCESS;
479 
480 
481     for (UINT format = 0, size = 0; format < formatCount; ++size, ++format)
482     {
483         SubTestTexture3D(
484             context,
485             command_queue,
486             pDevice,
487             &formats[format],
488             &texture3DSizes[size % texture3DSizeCount]);
489     }
490 }
491 
492