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