• 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 #include "harness.h"
17 
18 #define ADD_BUFFER_PROPERTIES(w, x, y, z) \
19     { w, x, y, z, #x, #y, #z, }
20 
21 BufferProperties bufferProperties[] =
22 {
23     ADD_BUFFER_PROPERTIES(     0x110, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE),
24     ADD_BUFFER_PROPERTIES(    0x1100, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE),
25     ADD_BUFFER_PROPERTIES(    0x8000, D3D11_BIND_CONSTANT_BUFFER, D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE),
26 
27     ADD_BUFFER_PROPERTIES(   0x7FFFF, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0),
28     ADD_BUFFER_PROPERTIES(  0x110000, D3D11_BIND_SHADER_RESOURCE, D3D11_USAGE_DEFAULT, 0),
29     ADD_BUFFER_PROPERTIES(  0x110000, D3D11_BIND_STREAM_OUTPUT,   D3D11_USAGE_DEFAULT, 0),
30     ADD_BUFFER_PROPERTIES(  0x110001, D3D11_BIND_STREAM_OUTPUT,   D3D11_USAGE_DEFAULT, 0),
31 
32     ADD_BUFFER_PROPERTIES(      0x11, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DEFAULT, 0),
33     ADD_BUFFER_PROPERTIES(      0x11, D3D11_BIND_INDEX_BUFFER,    D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE),
34     ADD_BUFFER_PROPERTIES(     0x121, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DEFAULT, 0),
35     ADD_BUFFER_PROPERTIES(    0x1234, D3D11_BIND_INDEX_BUFFER,    D3D11_USAGE_DEFAULT, 0),
36     ADD_BUFFER_PROPERTIES(   0x12345, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE),
37     ADD_BUFFER_PROPERTIES(  0x123456, D3D11_BIND_INDEX_BUFFER,    D3D11_USAGE_DEFAULT, 0),
38 #if 0 // avoid large sizes on automation
39     ADD_BUFFER_PROPERTIES( 0x1234567, D3D11_BIND_INDEX_BUFFER,    D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE),
40 
41     ADD_BUFFER_PROPERTIES( 0x4000000, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DEFAULT, 0),
42     ADD_BUFFER_PROPERTIES( 0x4000004, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DEFAULT, 0),
43     ADD_BUFFER_PROPERTIES( 0x4000008, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DEFAULT, 0),
44     ADD_BUFFER_PROPERTIES( 0x4000011, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DEFAULT, 0),
45     ADD_BUFFER_PROPERTIES( 0x4000014, D3D11_BIND_VERTEX_BUFFER,   D3D11_USAGE_DEFAULT, 0),
46 #endif
47 };
48 UINT bufferPropertyCount = sizeof(bufferProperties)/sizeof(bufferProperties[0]);
49 
SubTestBuffer(cl_context context,cl_command_queue command_queue,ID3D11Device * pDevice,ID3D11DeviceContext * pDC,const BufferProperties * props)50 void SubTestBuffer(
51     cl_context context,
52     cl_command_queue command_queue,
53     ID3D11Device* pDevice,
54     ID3D11DeviceContext* pDC,
55     const BufferProperties* props)
56 {
57     ID3D11Buffer* pBuffer = NULL;
58     HRESULT hr = S_OK;
59     cl_mem mem = NULL;
60     cl_int result = CL_SUCCESS;
61 
62     HarnessD3D11_TestBegin("Buffer: Size=%d, BindFlags=%s, Usage=%s, CPUAccess=%s",
63         props->ByteWidth,
64         props->name_BindFlags,
65         props->name_Usage,
66         props->name_CPUAccess);
67 
68     // create the D3D11 resource
69     {
70         D3D11_BUFFER_DESC desc = {0};
71         desc.ByteWidth = props->ByteWidth;
72         desc.Usage = props->Usage;
73         desc.CPUAccessFlags = props->CPUAccess;
74         desc.BindFlags = props->BindFlags;
75         desc.MiscFlags = 0;
76         hr = pDevice->CreateBuffer(&desc, NULL, &pBuffer);
77         TestRequire(SUCCEEDED(hr), "Creating vertex buffer failed!");
78     }
79 
80     // populate the D3D11 resource with data
81     {
82         ID3D11Buffer* pStagingBuffer = NULL;
83         char *pStagingData = NULL;
84         D3D11_MAPPED_SUBRESOURCE map = {0};
85 
86         // create a staging buffer to use to copy data to the D3D buffer
87         D3D11_BUFFER_DESC desc = {0};
88         desc.ByteWidth      = 16;
89         desc.Usage          = D3D11_USAGE_STAGING;
90         desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE|D3D11_CPU_ACCESS_READ;
91         desc.BindFlags      = 0;
92         desc.MiscFlags      = 0;
93         hr = pDevice->CreateBuffer(&desc, NULL, &pStagingBuffer);
94         TestRequire(SUCCEEDED(hr), "Creating staging vertex buffer failed!");
95 
96         // populate the staging buffer
97         hr = pDC->Map(
98             pStagingBuffer,
99             0,
100             D3D11_MAP_READ_WRITE,
101             0,
102             &map);
103         TestRequire(SUCCEEDED(hr), "Map failed!");
104         memcpy(map.pData, "abcdXXXXxxxx1234", 16);
105         pDC->Unmap(pStagingBuffer, 0);
106         TestRequire(SUCCEEDED(hr), "Unmap failed!");
107 
108         // copy 'abcdXXXX' to the front of the buffer and 'xxxx1234' to the back
109         D3D11_BOX box = {0};
110         box.front   = 0;
111         box.back    = 1;
112         box.top     = 0;
113         box.bottom  = 1;
114 
115         box.left    = 0;
116         box.right   = 8;
117         pDC->CopySubresourceRegion(
118             pBuffer,
119             0,
120             0,
121             0,
122             0,
123             pStagingBuffer,
124             0,
125             &box);
126         box.left    = 8;
127         box.right   = 16;
128         pDC->CopySubresourceRegion(
129             pBuffer,
130             0,
131             props->ByteWidth-8,
132             0,
133             0,
134             pStagingBuffer,
135             0,
136             &box);
137         pStagingBuffer->Release();
138     }
139 
140     // share the resource with OpenCL
141     {
142         mem = clCreateFromD3D11BufferKHR(
143             context,
144             0,
145             pBuffer,
146             &result);
147         TestRequire(CL_SUCCESS == result, "clCreateFromD3D11BufferKHR failed");
148     }
149 
150     // validate the OpenCL mem obj's properties
151     {
152         ID3D11Resource* clResource = NULL;
153         result = clGetMemObjectInfo(
154             mem,
155             CL_MEM_D3D11_RESOURCE_KHR,
156             sizeof(clResource),
157             &clResource,
158             NULL);
159         TestRequire(result == CL_SUCCESS, "clGetMemObjectInfo for CL_MEM_D3D11_RESOURCE_KHR failed.");
160         TestRequire(clResource == pBuffer, "clGetMemObjectInfo for CL_MEM_D3D11_RESOURCE_KHR returned incorrect value.");
161     }
162 
163     // acquire the resource from OpenCL
164     {
165         result = clEnqueueAcquireD3D11ObjectsKHR(
166             command_queue,
167             1,
168             &mem,
169             0,
170             NULL,
171             NULL);
172         TestRequire(result == CL_SUCCESS, "clEnqueueAcquireD3D11ObjectsKHR failed.");
173     }
174 
175     // read+write data from the buffer in OpenCL
176     {
177         // overwrite the 'XXXX' with '1234' and the 'xxxx' with 'abcd' so we now have
178         // 'abcd1234' at the beginning and end of the buffer
179         result = clEnqueueCopyBuffer(
180             command_queue,
181             mem,
182             mem,
183             0,
184             props->ByteWidth-8,
185             4,
186             0,
187             NULL,
188             NULL);
189         TestRequire(result == CL_SUCCESS, "clEnqueueCopyBuffer failed.");
190 
191         result = clEnqueueCopyBuffer(
192             command_queue,
193             mem,
194             mem,
195             props->ByteWidth-4,
196             4,
197             4,
198             0,
199             NULL,
200             NULL);
201         TestRequire(result == CL_SUCCESS, "clEnqueueCopyBuffer failed.");
202     }
203 
204     // release the resource from OpenCL
205     {
206         result = clEnqueueReleaseD3D11ObjectsKHR(
207             command_queue,
208             1,
209             &mem,
210             0,
211             NULL,
212             NULL);
213         TestRequire(result == CL_SUCCESS, "clEnqueueReleaseD3D11ObjectsKHR failed.");
214     }
215 
216     // read data in D3D
217     {
218         ID3D11Buffer* pStagingBuffer = NULL;
219         char *pStagingData = NULL;
220         D3D11_MAPPED_SUBRESOURCE map = {0};
221 
222         // create a staging buffer to read the data back
223         D3D11_BUFFER_DESC desc = {0};
224         desc.ByteWidth      = 16;
225         desc.Usage          = D3D11_USAGE_STAGING;
226         desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE|D3D11_CPU_ACCESS_READ;
227         desc.BindFlags      = 0;
228         desc.MiscFlags      = 0;
229         hr = pDevice->CreateBuffer(&desc, NULL, &pStagingBuffer);
230         TestRequire(SUCCEEDED(hr), "Creating staging vertex buffer failed!");
231 
232         // make sure the staging buffer doesn't get stale data
233         hr = pDC->Map(
234             pStagingBuffer,
235             0,
236             D3D11_MAP_READ_WRITE,
237             0,
238             &map);
239         TestRequire(SUCCEEDED(hr), "Map failed!");
240         memset(map.pData, 0, 16);
241         pDC->Unmap(pStagingBuffer, 0);
242         TestRequire(SUCCEEDED(hr), "Unmap failed!");
243 
244         // copy the 'abcd1234' from the front and back of the buffer to the staging buffer
245         D3D11_BOX box = {0};
246         box.front   = 0;
247         box.back    = 1;
248         box.top     = 0;
249         box.bottom  = 1;
250 
251         box.left    = 0;
252         box.right   = 8;
253         pDC->CopySubresourceRegion(
254             pStagingBuffer,
255             0,
256             0,
257             0,
258             0,
259             pBuffer,
260             0,
261             &box);
262         box.left    = props->ByteWidth-8;
263         box.right   = props->ByteWidth;
264         pDC->CopySubresourceRegion(
265             pStagingBuffer,
266             0,
267             8,
268             0,
269             0,
270             pBuffer,
271             0,
272             &box);
273         TestRequire(SUCCEEDED(hr), "CopySubresourceRegion failed!");
274 
275         // verify that we got the 'abcd1234'
276         hr = pDC->Map(
277             pStagingBuffer,
278             0,
279             D3D11_MAP_READ_WRITE,
280             0,
281             &map);
282         TestRequire(SUCCEEDED(hr), "Map failed!");
283         TestRequire(!memcmp(map.pData, "abcd1234abcd1234", 16), "Data was not accurately");
284         pDC->Unmap(pStagingBuffer, 0);
285         TestRequire(SUCCEEDED(hr), "Unmap failed!");
286 
287         pStagingBuffer->Release();
288     }
289 
290 Cleanup:
291 
292     if (pBuffer)
293     {
294         pBuffer->Release();
295     }
296     if (mem)
297     {
298         clReleaseMemObject(mem);
299     }
300 
301     HarnessD3D11_TestEnd();
302 }
303 
304 
TestDeviceBuffer(cl_context context,cl_command_queue command_queue,ID3D11Device * pDevice,ID3D11DeviceContext * pDC)305 void TestDeviceBuffer(
306     cl_context context,
307     cl_command_queue command_queue,
308     ID3D11Device* pDevice,
309     ID3D11DeviceContext* pDC)
310 {
311     for (UINT i = 0; i < bufferPropertyCount; ++i)
312     {
313         SubTestBuffer(
314             context,
315             command_queue,
316             pDevice,
317             pDC,
318             &bufferProperties[i]);
319     }
320 }
321 
322