blob: 8347f88486716fbe64607ab4cef15b67ab8e6ade [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
Chia-I Wu3c3fd122014-11-22 02:51:25 +0800308TEST_F(XglBlitTest, CopyMemoryHazard)
309{
310 XGL_GPU_MEMORY mem[3];
311 XGL_MEMORY_COPY region;
312 XGL_MEMORY_STATE_TRANSITION transition;
313 XGL_RESULT err;
314 void *data;
315 XGL_UINT i;
316
317 ClearMemoryRefs();
318
319 for (i = 0; i < 3; i++) {
320 mem[i] = AddMemory(256, false);
321 ASSERT_NE((XGL_GPU_MEMORY) XGL_NULL_HANDLE, mem[i]);
322
323 err = xglMapMemory(mem[i], 0, &data);
324 ASSERT_XGL_SUCCESS(err);
325 ((char *) data)[0] = 5 * (i + 1);
326 xglUnmapMemory(mem[i]);
327 }
328
329 region.srcOffset = 0;
330 region.destOffset = 0;
331 region.copySize = 1;
332
333 BeginCmd();
334
335 xglCmdCopyMemory(m_cmd, mem[0], mem[1], 1, &region);
336
337 memset(&transition, 0, sizeof(transition));
338 transition.sType = XGL_STRUCTURE_TYPE_MEMORY_STATE_TRANSITION;
339 transition.mem = mem[1];
340 transition.oldState = XGL_MEMORY_STATE_DATA_TRANSFER;
341 transition.newState = XGL_MEMORY_STATE_DATA_TRANSFER;
342 transition.offset = region.destOffset;
343 transition.regionSize = region.copySize;
344 xglCmdPrepareMemoryRegions(m_cmd, 1, &transition);
345
346 xglCmdCopyMemory(m_cmd, mem[1], mem[2], 1, &region);
347
348 EndAndSubmitCmd();
349
350 err = xglMapMemory(mem[2], 0, &data);
351 ASSERT_XGL_SUCCESS(err);
352
353 ASSERT_EQ(5, ((const unsigned char *) data)[0]);
354
355 xglUnmapMemory(mem[2]);
356
357 for (i = 0; i < 3; i++)
358 xglFreeMemory(mem[i]);
359}
360
Chia-I Wucb67c652014-10-21 11:06:26 +0800361TEST_F(XglBlitTest, ClearColorImageBasic)
362{
363 const XGL_FLOAT color[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
364 const XGL_UINT width = 64;
365 const XGL_UINT height = 64;
366 XglImage *img;
367 XGL_FORMAT format;
368 XGL_IMAGE_SUBRESOURCE subres;
369 XGL_IMAGE_SUBRESOURCE_RANGE subres_range;
370 XGL_IMAGE_STATE_TRANSITION transition;
371 XGL_RESULT err;
372
373 format.channelFormat = XGL_CH_FMT_R8G8B8A8;
374 format.numericFormat = XGL_NUM_FMT_UNORM;
375
376 subres.aspect = XGL_IMAGE_ASPECT_COLOR;
377 subres.mipLevel = 0;
378 subres.arraySlice = 0;
379
380 subres_range.aspect = XGL_IMAGE_ASPECT_COLOR;
381 subres_range.baseMipLevel = 0;
382 subres_range.mipLevels = 1;
383 subres_range.baseArraySlice = 0;
384 subres_range.arraySize = 1;
385
386 img = new XglImage(m_device);
387 img->init(width, height, format, XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
388
389 ClearMemoryRefs();
390 AddMemoryRef(img->memory(), false);
391
392 BeginCmd();
393
394 transition.image = img->image();
395 transition.oldState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
396 transition.newState = XGL_IMAGE_STATE_CLEAR;
397 transition.subresourceRange = subres_range;
398 xglCmdPrepareImages(m_cmd, 1, &transition);
399
400 xglCmdClearColorImage(m_cmd, img->image(), color, 1, &subres_range);
401
402 EndAndSubmitCmd();
403
404 {
405 XGL_SUBRESOURCE_LAYOUT layout;
Jon Ashburn6317c492014-11-21 11:33:20 -0700406 XGL_SIZE layout_size= sizeof(layout);
Chia-I Wucb67c652014-10-21 11:06:26 +0800407 XGL_UINT x, y;
408 void *data;
409
410 err = img->MapMemory(&data);
411 ASSERT_XGL_SUCCESS(err);
412
413 err = xglGetImageSubresourceInfo(img->image(), &subres,
414 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout);
415 ASSERT_XGL_SUCCESS(err);
416 ASSERT_EQ(sizeof(layout), layout_size);
417
418 for (y = 0; y < height; y++) {
419 const XGL_UINT *real = (const XGL_UINT *)
420 ((char *) data + layout.offset + layout.rowPitch * y);
421
422 for (x = 0; x < width; x++)
423 ASSERT_EQ(0xff00ff00, real[x]);
424 }
425
426 img->UnmapMemory();
427 }
428
429 delete img;
430}
431
Chia-I Wucb67c652014-10-21 11:06:26 +0800432TEST_F(XglBlitTest, ClearDepthStencilBasic)
433{
434 const XGL_FLOAT clear_depth = 0.4f;
435 const XGL_UINT width = 64;
436 const XGL_UINT height = 64;
437 XglImage *img;
438 XGL_FORMAT format;
439 XGL_IMAGE_SUBRESOURCE subres;
440 XGL_IMAGE_SUBRESOURCE_RANGE subres_range;
441 XGL_IMAGE_STATE_TRANSITION transition;
442 XGL_RESULT err;
443
444 format.channelFormat = XGL_CH_FMT_R32;
445 format.numericFormat = XGL_NUM_FMT_DS;
446
447 subres.aspect = XGL_IMAGE_ASPECT_DEPTH;
448 subres.mipLevel = 0;
449 subres.arraySlice = 0;
450
451 subres_range.aspect = XGL_IMAGE_ASPECT_DEPTH;
452 subres_range.baseMipLevel = 0;
453 subres_range.mipLevels = 1;
454 subres_range.baseArraySlice = 0;
455 subres_range.arraySize = 1;
456
457 img = new XglImage(m_device);
458 img->init(width, height, format, XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT,
459 XGL_OPTIMAL_TILING);
460
461 ClearMemoryRefs();
462 AddMemoryRef(img->memory(), false);
463
464 BeginCmd();
465
466 transition.image = img->image();
467 transition.oldState = XGL_IMAGE_STATE_UNINITIALIZED_TARGET;
468 transition.newState = XGL_IMAGE_STATE_CLEAR;
469 transition.subresourceRange = subres_range;
470 xglCmdPrepareImages(m_cmd, 1, &transition);
471
472 xglCmdClearDepthStencil(m_cmd, img->image(), clear_depth,
473 0, 1, &subres_range);
474
475 EndAndSubmitCmd();
476
477 /*
478 * TODO xglCmdCopyImageToMemory to linearize
479 *
480 * This works only because xglMapMemory calls intel_bo_map_gtt_async.
481 */
482 {
483 XGL_SUBRESOURCE_LAYOUT layout;
Jon Ashburn6317c492014-11-21 11:33:20 -0700484 XGL_SIZE layout_size = sizeof(layout);
Chia-I Wucb67c652014-10-21 11:06:26 +0800485 XGL_UINT x, y;
486 void *data;
487
488 err = img->MapMemory(&data);
489 ASSERT_XGL_SUCCESS(err);
490
491 err = xglGetImageSubresourceInfo(img->image(), &subres,
492 XGL_INFO_TYPE_SUBRESOURCE_LAYOUT, &layout_size, &layout);
493 ASSERT_XGL_SUCCESS(err);
494 ASSERT_EQ(sizeof(layout), layout_size);
495
496 for (y = 0; y < height; y++) {
497 const float *real = (const float *)
498 ((char *) data + layout.offset + layout.rowPitch * y);
499
500 for (x = 0; x < width; x++)
501 ASSERT_EQ(clear_depth, real[x]);
502 }
503
504 img->UnmapMemory();
505 }
506}
507
508int main(int argc, char **argv)
509{
510 int result;
511
512 ::testing::InitGoogleTest(&argc, argv);
513 XglTestFramework::InitArgs(&argc, argv);
514
515 ::testing::Environment* const xgl_test_env = ::testing::AddGlobalTestEnvironment(new TestEnvironment);
516
517 result = RUN_ALL_TESTS();
518
519 XglTestFramework::Finish();
520 return result;
521}