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