blob: d5b679333eefbeff59e9f552751635f7b6072001 [file] [log] [blame]
Chia-I Wucb67c652014-10-21 11:06:26 +08001// Copyright 2005, Google Inc.
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met:
7//
8// * Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above
11// copyright notice, this list of conditions and the following disclaimer
12// in the documentation and/or other materials provided with the
13// distribution.
14// * Neither the name of Google Inc. nor the names of its
15// contributors may be used to endorse or promote products derived from
16// this software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
31// XGL tests
32//
33// Copyright (C) 2014 LunarG, Inc.
34//
35// Permission is hereby granted, free of charge, to any person obtaining a
36// copy of this software and associated documentation files (the "Software"),
37// to deal in the Software without restriction, including without limitation
38// the rights to use, copy, modify, merge, publish, distribute, sublicense,
39// and/or sell copies of the Software, and to permit persons to whom the
40// Software is furnished to do so, subject to the following conditions:
41//
42// The above copyright notice and this permission notice shall be included
43// in all copies or substantial portions of the Software.
44//
45// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
48// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
50// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
51// DEALINGS IN THE SOFTWARE.
52
53// Blit (copy, clear, and resolve) tests
54
55#include <string.h>
56#include <xgl.h>
57#include "gtest-1.7.0/include/gtest/gtest.h"
58#include "xgldevice.h"
59#include "xglimage.h"
60#include "xgltestframework.h"
61
62#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
63
64class XglBlitTest : public XglTestFramework
65{
66protected:
67 XGL_APPLICATION_INFO app_info;
68 XglDevice *m_device;
69
70 XGL_CMD_BUFFER m_cmd;
71
72 XGL_MEMORY_REF m_mem_refs[8];
73 XGL_UINT m_mem_ref_count;
74
75 virtual void SetUp();
76 virtual void TearDown();
77
78 XGL_DEVICE device() { return m_device->device(); }
79
80 void ClearMemoryRefs()
81 {
82 m_mem_ref_count = 0;
83 }
84
85 void AddMemoryRef(XGL_GPU_MEMORY mem, bool readonly)
86 {
87 ASSERT_LE(m_mem_ref_count, ARRAY_SIZE(m_mem_refs));
88
89 m_mem_refs[m_mem_ref_count].mem = mem;
90 m_mem_refs[m_mem_ref_count].flags =
91 (readonly) ? XGL_MEMORY_REF_READ_ONLY_BIT : 0;
92 m_mem_ref_count++;
93 }
94
95 XGL_GPU_MEMORY AllocMemory(XGL_GPU_SIZE size)
96 {
97 XGL_MEMORY_ALLOC_INFO info;
98 XGL_GPU_MEMORY mem;
99 XGL_RESULT err;
100
101 memset(&info, 0, sizeof(info));
102 info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
103 info.allocationSize = size;
104 info.alignment = 1;
105 info.heapCount = 1;
106 info.memPriority = XGL_MEMORY_PRIORITY_NORMAL;
107
108 err = xglAllocMemory(device(), &info, &mem);
109 if (err)
110 mem = XGL_NULL_HANDLE;
111
112 return mem;
113 }
114
115 XGL_GPU_MEMORY AddMemory(XGL_GPU_SIZE size, bool readonly)
116 {
117 XGL_GPU_MEMORY mem;
118
119 mem = AllocMemory(size);
120 if (mem)
121 AddMemoryRef(mem, readonly);
122
123 return mem;
124 }
125
126 void BeginCmd()
127 {
128 XGL_RESULT err;
129
130 err = xglBeginCommandBuffer(m_cmd,
131 XGL_CMD_BUFFER_OPTIMIZE_GPU_SMALL_BATCH_BIT |
132 XGL_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT);
133 ASSERT_XGL_SUCCESS(err);
134 }
135
136 void EndAndSubmitCmd()
137 {
138 XGL_RESULT err;
139
140 err = xglEndCommandBuffer(m_cmd);
141 ASSERT_XGL_SUCCESS(err);
142
143 err = xglQueueSubmit(m_device->m_queue, 1, &m_cmd, m_mem_ref_count, m_mem_refs, NULL );
144 ASSERT_XGL_SUCCESS(err);
145
146 err = xglQueueWaitIdle(m_device->m_queue);
147 ASSERT_XGL_SUCCESS(err);
148 }
149};
150
151void XglBlitTest::SetUp()
152{
153 XGL_CMD_BUFFER_CREATE_INFO cmd_info;
154 XGL_PHYSICAL_GPU gpu;
155 XGL_UINT count;
156 XGL_RESULT err;
157
158 memset(&app_info, 0, sizeof(app_info));
159 app_info.sType = XGL_STRUCTURE_TYPE_APPLICATION_INFO;
160 app_info.pNext = NULL;
161 app_info.pAppName = (const XGL_CHAR *) "blit tests";
162 app_info.appVersion = 1;
163 app_info.pEngineName = (const XGL_CHAR *) "unittest";
164 app_info.engineVersion = 1;
165 app_info.apiVersion = XGL_MAKE_VERSION(0, 22, 0);
166
167 err = xglInitAndEnumerateGpus(&app_info, NULL, 1, &count, &gpu);
168 ASSERT_XGL_SUCCESS(err);
169 ASSERT_GE(1, count) << "No GPU available";
170
171 m_device = new XglDevice(0, gpu);
172 m_device->get_device_queue();
173
174 memset(&cmd_info, 0, sizeof(cmd_info));
175 cmd_info.sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO;
176 cmd_info.queueType = XGL_QUEUE_TYPE_GRAPHICS;
177
178 err = xglCreateCommandBuffer(device(), &cmd_info, &m_cmd);
179 ASSERT_XGL_SUCCESS(err) << "xglCreateCommandBuffer failed";
180}
181
182void XglBlitTest::TearDown()
183{
184 XGL_UINT dummy_count;
185
186 xglDestroyObject(m_cmd);
187 xglInitAndEnumerateGpus(&app_info, NULL, 0, &dummy_count, NULL);
188}
189
190TEST_F(XglBlitTest, FillMemory)
191{
192 const struct {
193 XGL_GPU_SIZE offset;
194 XGL_GPU_SIZE size;
195 XGL_UINT value;
196 } ranges[] = {
197 { 0, 64, 0x11111111 }, // 16-byte aligned
198 { 64, 12, 0x22222222 }, // 4-byte aligned
199 { 76, 4, 0x33333333 }, // min. fill size
200 { 80, 20, 0x44444444 },
201 { 92, 8, 0x55555555 }, // overlapped
202 };
203 XGL_GPU_MEMORY mem;
204 XGL_RESULT err;
205 void *data;
206 XGL_UINT i;
207
208 ClearMemoryRefs();
209
210 mem = AddMemory(256, false);
211 ASSERT_NE((XGL_GPU_MEMORY) XGL_NULL_HANDLE, mem);
212
213 BeginCmd();
214 for (i = 0; i < ARRAY_SIZE(ranges); i++) {
215 xglCmdFillMemory(m_cmd, mem, ranges[i].offset,
216 ranges[i].size, ranges[i].value);
217 }
218 EndAndSubmitCmd();
219
220 err = xglMapMemory(mem, 0, &data);
221 ASSERT_XGL_SUCCESS(err);
222
223 for (i = 0; i < ARRAY_SIZE(ranges); i++) {
224 const XGL_UINT expected = ranges[i].value;
225 const XGL_UINT *real = (const XGL_UINT *)
226 ((char *) data + ranges[i].offset);
227 XGL_UINT count, j;
228
229 count = ranges[i].size / 4;
230
231 /* check if the next range overlaps */
232 if (i + 1 < ARRAY_SIZE(ranges)) {
233 if (ranges[i].offset + ranges[i].size > ranges[i + 1].offset)
234 count = (ranges[i + 1].offset - ranges[i].offset) / 4;
235 }
236
237 for (j = 0; j < count; j++)
238 ASSERT_EQ(expected, real[j]);
239 }
240
241 xglUnmapMemory(mem);
242 xglFreeMemory(mem);
243}
244
245TEST_F(XglBlitTest, CopyMemory)
246{
247 XGL_GPU_MEMORY src, dst;
248 XGL_MEMORY_COPY regions[17];
249 XGL_RESULT err;
250 void *data;
251 XGL_UINT i;
252
253 ClearMemoryRefs();
254
255 src = AddMemory(256, false);
256 ASSERT_NE((XGL_GPU_MEMORY) XGL_NULL_HANDLE, src);
257
258 err = xglMapMemory(src, 0, &data);
259 ASSERT_XGL_SUCCESS(err);
260 for (i = 0; i < 256; i++)
261 ((char *) data)[i] = i;
262 xglUnmapMemory(src);
263
264 dst = AddMemory(256, false);
265 ASSERT_NE((XGL_GPU_MEMORY) XGL_NULL_HANDLE, dst);
266
267 /* copy with various alignments */
268 for (i = 0; i < 16; i++) {
269 regions[i].copySize = i + 1;
270 regions[i].srcOffset = i * 8;
271
272 if (i > 0) {
273 regions[i].destOffset = regions[i - 1].destOffset +
274 regions[i - 1].copySize;
275 } else {
276 regions[i].destOffset = 0;
277 }
278 }
279
280 regions[i].srcOffset = 192;
281 regions[i].destOffset = 192;
282 regions[i].copySize = 64;
283
284 BeginCmd();
285
286 xglCmdCopyMemory(m_cmd, src, dst, 16, regions);
287 xglCmdCopyMemory(m_cmd, src, dst, 1, &regions[16]);
288
289 EndAndSubmitCmd();
290
291 err = xglMapMemory(dst, 0, &data);
292 ASSERT_XGL_SUCCESS(err);
293
294 for (i = 0; i < ARRAY_SIZE(regions); i++) {
295 const unsigned char *real = (const unsigned char *) data +
296 regions[i].destOffset;
297 XGL_UINT j;
298
299 for (j = 0; j < regions[i].copySize; j++)
300 ASSERT_EQ(regions[i].srcOffset + j, real[j]);
301 }
302
303 xglUnmapMemory(dst);
304 xglFreeMemory(src);
305 xglFreeMemory(dst);
306}
307
308TEST_F(XglBlitTest, ClearColorImageBasic)
309{
310 const XGL_FLOAT color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
311 const XGL_UINT width = 64;
312 const XGL_UINT height = 64;
313 XglImage *img;
314 XGL_FORMAT format;
315 XGL_IMAGE_SUBRESOURCE subres;
316 XGL_IMAGE_SUBRESOURCE_RANGE subres_range;
317 XGL_IMAGE_STATE_TRANSITION transition;
318 XGL_RESULT err;
319
320 format.channelFormat = XGL_CH_FMT_R8G8B8A8;
321 format.numericFormat = XGL_NUM_FMT_UNORM;
322
323 subres.aspect = XGL_IMAGE_ASPECT_COLOR;
324 subres.mipLevel = 0;
325 subres.arraySlice = 0;
326
327 subres_range.aspect = XGL_IMAGE_ASPECT_COLOR;
328 subres_range.baseMipLevel = 0;
329 subres_range.mipLevels = 1;
330 subres_range.baseArraySlice = 0;
331 subres_range.arraySize = 1;
332
333 img = new XglImage(m_device);
334 img->init(width, height, format, XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
335
336 ClearMemoryRefs();
337 AddMemoryRef(img->memory(), false);
338
339 BeginCmd();
340
341 transition.image = img->image();
342 transition.oldState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
343 transition.newState = XGL_IMAGE_STATE_CLEAR;
344 transition.subresourceRange = subres_range;
345 xglCmdPrepareImages(m_cmd, 1, &transition);
346
347 xglCmdClearColorImage(m_cmd, img->image(), color, 1, &subres_range);
348
349 EndAndSubmitCmd();
350
351 {
352 XGL_SUBRESOURCE_LAYOUT layout;
Jon Ashburn6317c492014-11-21 11:33:20 -0700353 XGL_SIZE layout_size= sizeof(layout);
Chia-I Wucb67c652014-10-21 11:06:26 +0800354 XGL_UINT x, y;
355 void *data;
356
357 err = img->MapMemory(&data);
358 ASSERT_XGL_SUCCESS(err);
359
360 err = xglGetImageSubresourceInfo(img->image(), &subres,
361 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout);
362 ASSERT_XGL_SUCCESS(err);
363 ASSERT_EQ(sizeof(layout), layout_size);
364
365 for (y = 0; y < height; y++) {
366 const XGL_UINT *real = (const XGL_UINT *)
367 ((char *) data + layout.offset + layout.rowPitch * y);
368
369 for (x = 0; x < width; x++)
370 ASSERT_EQ(0xff00ff00, real[x]);
371 }
372
373 img->UnmapMemory();
374 }
375
376 delete img;
377}
378
Chia-I Wucb67c652014-10-21 11:06:26 +0800379TEST_F(XglBlitTest, ClearDepthStencilBasic)
380{
381 const XGL_FLOAT clear_depth = 0.4f;
382 const XGL_UINT width = 64;
383 const XGL_UINT height = 64;
384 XglImage *img;
385 XGL_FORMAT format;
386 XGL_IMAGE_SUBRESOURCE subres;
387 XGL_IMAGE_SUBRESOURCE_RANGE subres_range;
388 XGL_IMAGE_STATE_TRANSITION transition;
389 XGL_RESULT err;
390
391 format.channelFormat = XGL_CH_FMT_R32;
392 format.numericFormat = XGL_NUM_FMT_DS;
393
394 subres.aspect = XGL_IMAGE_ASPECT_DEPTH;
395 subres.mipLevel = 0;
396 subres.arraySlice = 0;
397
398 subres_range.aspect = XGL_IMAGE_ASPECT_DEPTH;
399 subres_range.baseMipLevel = 0;
400 subres_range.mipLevels = 1;
401 subres_range.baseArraySlice = 0;
402 subres_range.arraySize = 1;
403
404 img = new XglImage(m_device);
405 img->init(width, height, format, XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT,
406 XGL_OPTIMAL_TILING);
407
408 ClearMemoryRefs();
409 AddMemoryRef(img->memory(), false);
410
411 BeginCmd();
412
413 transition.image = img->image();
414 transition.oldState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
415 transition.newState = XGL_IMAGE_STATE_CLEAR;
416 transition.subresourceRange = subres_range;
417 xglCmdPrepareImages(m_cmd, 1, &transition);
418
419 xglCmdClearDepthStencil(m_cmd, img->image(), clear_depth,
420 0, 1, &subres_range);
421
422 EndAndSubmitCmd();
423
424 /*
425 * TODO xglCmdCopyImageToMemory to linearize
426 *
427 * This works only because xglMapMemory calls intel_bo_map_gtt_async.
428 */
429 {
430 XGL_SUBRESOURCE_LAYOUT layout;
Jon Ashburn6317c492014-11-21 11:33:20 -0700431 XGL_SIZE layout_size = sizeof(layout);
Chia-I Wucb67c652014-10-21 11:06:26 +0800432 XGL_UINT x, y;
433 void *data;
434
435 err = img->MapMemory(&data);
436 ASSERT_XGL_SUCCESS(err);
437
438 err = xglGetImageSubresourceInfo(img->image(), &subres,
439 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout);
440 ASSERT_XGL_SUCCESS(err);
441 ASSERT_EQ(sizeof(layout), layout_size);
442
443 for (y = 0; y < height; y++) {
444 const float *real = (const float *)
445 ((char *) data + layout.offset + layout.rowPitch * y);
446
447 for (x = 0; x < width; x++)
448 ASSERT_EQ(clear_depth, real[x]);
449 }
450
451 img->UnmapMemory();
452 }
453}
454
455int main(int argc, char **argv)
456{
457 int result;
458
459 ::testing::InitGoogleTest(&argc, argv);
460 XglTestFramework::InitArgs(&argc, argv);
461
462 ::testing::Environment* const xgl_test_env = ::testing::AddGlobalTestEnvironment(new TestEnvironment);
463
464 result = RUN_ALL_TESTS();
465
466 XglTestFramework::Finish();
467 return result;
468}