Make random number usage platform independent
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / protected_memory / vktProtectedMemCopyImageToBufferTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Protected memory copy image to buffer tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktProtectedMemCopyImageToBufferTests.hpp"
26
27 #include "deRandom.hpp"
28 #include "tcuTestLog.hpp"
29 #include "tcuVector.hpp"
30 #include "tcuVectorUtil.hpp"
31
32 #include "vkPrograms.hpp"
33 #include "vktTestCase.hpp"
34 #include "vktTestGroupUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkCmdUtil.hpp"
38
39 #include "vktProtectedMemContext.hpp"
40 #include "vktProtectedMemUtils.hpp"
41 #include "vktProtectedMemBufferValidator.hpp"
42
43 namespace vkt
44 {
45 namespace ProtectedMem
46 {
47
48 namespace
49 {
50
51 enum {
52         BUFFER_SIZE             = 256,
53         RENDER_WIDTH    = 8,
54         RENDER_HEIGHT   = 8,
55
56         MAX_POSITION    = BUFFER_SIZE / 4,
57 };
58
59 template<typename T>
60 class CopyImageToBufferTestInstance : public ProtectedTestInstance
61 {
62 public:
63                                                                         CopyImageToBufferTestInstance   (Context&                                               ctx,
64                                                                                                                                          const vk::VkClearColorValue    fillValue,
65                                                                                                                                          const BufferValidator<T>&              validator,
66                                                                                                                                          const CmdBufferType                    cmdBufferType);
67         virtual tcu::TestStatus                 iterate                                                 (void);
68
69 private:
70         const vk::VkFormat                              m_imageFormat;
71         const vk::VkClearColorValue             m_fillValue;
72         const BufferValidator<T>&               m_validator;
73         const CmdBufferType                                     m_cmdBufferType;
74 };
75
76
77 template<typename T>
78 class CopyImageToBufferTestCase : public TestCase
79 {
80 public:
81                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
82                                                                                                                  const std::string&             name,
83                                                                                                                  vk::VkClearColorValue  fillValue,
84                                                                                                                  ValidationData<T>              data,
85                                                                                                                  CmdBufferType                  cmdBufferType)
86                                                                 : TestCase                              (testCtx, name, "Copy image to buffer.")
87                                                                 , m_fillValue                   (fillValue)
88                                                                 , m_validator                   (data)
89                                                                 , m_cmdBufferType               (cmdBufferType)
90                                                         {
91                                                         }
92
93         virtual                                 ~CopyImageToBufferTestCase      (void) {}
94         virtual TestInstance*   createInstance                          (Context& ctx) const
95                                                         {
96                                                                 return new CopyImageToBufferTestInstance<T>(ctx, m_fillValue, m_validator, m_cmdBufferType);
97                                                         }
98         virtual void                    initPrograms                            (vk::SourceCollections& programCollection) const
99                                                         {
100                                                                 m_validator.initPrograms(programCollection);
101                                                         }
102 private:
103         vk::VkClearColorValue   m_fillValue;
104         BufferValidator<T>              m_validator;
105         CmdBufferType                   m_cmdBufferType;
106 };
107
108 template<typename T>
109 CopyImageToBufferTestInstance<T>::CopyImageToBufferTestInstance (Context&                                               ctx,
110                                                                                                                                  const vk::VkClearColorValue    fillValue,
111                                                                                                                                  const BufferValidator<T>&              validator,
112                                                                                                                                  const CmdBufferType                    cmdBufferType)
113         : ProtectedTestInstance (ctx)
114         , m_imageFormat                 (vk::VK_FORMAT_R32G32B32A32_UINT)
115         , m_fillValue                   (fillValue)
116         , m_validator                   (validator)
117         , m_cmdBufferType               (cmdBufferType)
118 {
119 }
120
121 template<typename T>
122 tcu::TestStatus CopyImageToBufferTestInstance<T>::iterate()
123 {
124         ProtectedContext&                                       ctx                                     (m_protectedContext);
125         const vk::DeviceInterface&                      vk                                      = ctx.getDeviceInterface();
126         const vk::VkDevice                                      device                          = ctx.getDevice();
127         const vk::VkQueue                                       queue                           = ctx.getQueue();
128         const deUint32                                          queueFamilyIndex        = ctx.getQueueFamilyIndex();
129
130         // Create image
131         de::MovePtr<vk::ImageWithMemory>        colorImage                      = createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
132                                                                                                                                                         RENDER_WIDTH, RENDER_HEIGHT,
133                                                                                                                                                         m_imageFormat,
134                                                                                                                                                         vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT
135                                                                                                                                                         | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT
136                                                                                                                                                         | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
137         de::MovePtr<vk::BufferWithMemory>       dstBuffer                       (makeBuffer(ctx,
138                                                                                                                                                 PROTECTION_ENABLED,
139                                                                                                                                                 queueFamilyIndex,
140                                                                                                                                                 (deUint32)(BUFFER_SIZE * sizeof(deUint32)),
141                                                                                                                                                 vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
142                                                                                                                                                         | vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
143                                                                                                                                                 vk::MemoryRequirement::Protected));
144
145         vk::Unique<vk::VkCommandPool>           cmdPool                         (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
146         vk::Unique<vk::VkCommandBuffer>         cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
147         vk::Unique<vk::VkCommandBuffer>         secondaryCmdBuffer      (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
148         vk::VkCommandBuffer                                     targetCmdBuffer         = (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
149
150         // Begin cmd buffer
151         beginCommandBuffer(vk, *cmdBuffer);
152
153         if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
154         {
155                 // Begin secondary command buffer
156                 const vk::VkCommandBufferInheritanceInfo        secCmdBufInheritInfo    =
157                 {
158                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
159                         DE_NULL,
160                         (vk::VkRenderPass)0u,                                                                           // renderPass
161                         0u,                                                                                                                     // subpass
162                         (vk::VkFramebuffer)0u,                                                                          // framebuffer
163                         VK_FALSE,                                                                                                       // occlusionQueryEnable
164                         (vk::VkQueryControlFlags)0u,                                                            // queryFlags
165                         (vk::VkQueryPipelineStatisticFlags)0u,                                          // pipelineStatistics
166                 };
167                 beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, secCmdBufInheritInfo);
168         }
169
170         // Start image barrier for source image.
171         {
172                 const vk::VkImageMemoryBarrier  startImgBarrier         =
173                 {
174                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                     // VkStructureType              sType
175                         DE_NULL,                                                                                        // const void*                  pNext
176                         0,                                                                                                      // VkAccessFlags                srcAccessMask
177                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                dstAccessMask
178                         vk::VK_IMAGE_LAYOUT_UNDEFINED,                                          // VkImageLayout                oldLayout
179                         vk::VK_IMAGE_LAYOUT_GENERAL,                                            // VkImageLayout                newLayout
180                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
181                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
182                         **colorImage,                                                                           // VkImage                              image
183                         {
184                                 vk::VK_IMAGE_ASPECT_COLOR_BIT,                                  // VkImageAspectFlags   aspectMask
185                                 0u,                                                                                             // uint32_t                             baseMipLevel
186                                 1u,                                                                                             // uint32_t                             mipLevels
187                                 0u,                                                                                             // uint32_t                             baseArraySlice
188                                 1u,                                                                                             // uint32_t                             subresourceRange
189                         }
190                 };
191
192                 vk.cmdPipelineBarrier(targetCmdBuffer,
193                                                           vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
194                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
195                                                           (vk::VkDependencyFlags)0,
196                                                           0, (const vk::VkMemoryBarrier*)DE_NULL,
197                                                           0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
198                                                           1, &startImgBarrier);
199         }
200
201         // Image clear
202         const vk::VkImageSubresourceRange subresourceRange =
203         {
204                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask
205                 0u,                                                             // uint32_t                             baseMipLevel
206                 1u,                                                             // uint32_t                             levelCount
207                 0u,                                                             // uint32_t                             baseArrayLayer
208                 1u,                                                             // uint32_t                             layerCount
209         };
210
211         vk.cmdClearColorImage(targetCmdBuffer, **colorImage, vk::VK_IMAGE_LAYOUT_GENERAL, &m_fillValue, 1, &subresourceRange);
212
213         // Image barrier to change accessMask to transfer read bit for source image.
214         {
215                 const vk::VkImageMemoryBarrier initializeBarrier =
216                 {
217                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                     // VkStructureType              sType
218                         DE_NULL,                                                                                        // const void*                  pNext
219                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                srcAccessMask
220                         vk::VK_ACCESS_TRANSFER_READ_BIT,                                        // VkAccessFlags                dstAccessMask
221                         vk::VK_IMAGE_LAYOUT_GENERAL,                                            // VkImageLayout                oldLayout
222                         vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                       // VkImageLayout                newLayout
223                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
224                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
225                         **colorImage,                                                                           // VkImage                              image
226                         {
227                                 vk::VK_IMAGE_ASPECT_COLOR_BIT,                                  // VkImageAspectFlags   aspectMask
228                                 0u,                                                                                             // uint32_t                             baseMipLevel
229                                 1u,                                                                                             // uint32_t                             mipLevels
230                                 0u,                                                                                             // uint32_t                             baseArraySlice
231                                 1u,                                                                                             // uint32_t                             subresourceRange
232                         }
233                 };
234
235                 vk.cmdPipelineBarrier(targetCmdBuffer,
236                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
237                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
238                                                           (vk::VkDependencyFlags)0,
239                                                           0, (const vk::VkMemoryBarrier*)DE_NULL,
240                                                           0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
241                                                           1, &initializeBarrier);
242         }
243
244         // Copy image to buffer
245         const vk::VkImageSubresourceLayers      subresourceLayers       =
246         {
247                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask
248                 0u,                                                             // uint32_t                             mipLevel
249                 0u,                                                             // uint32_t                             baseArrayLayer
250                 1u,                                                             // uint32_t                             layerCount
251         };
252         const vk::VkOffset3D                            nullOffset                      = {0u, 0u, 0u};
253         const vk::VkExtent3D                            imageExtent                     = {(deUint32)RENDER_WIDTH, (deUint32)RENDER_HEIGHT, 1u};
254         const vk::VkBufferImageCopy                     copyRegion                      =
255         {
256                 0ull,                                                   // VkDeviceSize                         srcOffset;
257                 0,                                                              // uint32_t                                     bufferRowLength
258                 0,                                                              // uint32_t                                     bufferImageHeight
259                 subresourceLayers,                              // VkImageSubresourceLayers     imageSubresource
260                 nullOffset,                                             // VkOffset3D                           imageOffset
261                 imageExtent,                                    // VkExtent3D                           imageExtent
262         };
263         vk.cmdCopyImageToBuffer(targetCmdBuffer, **colorImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **dstBuffer, 1u, &copyRegion);
264
265         {
266                 // Buffer validator reads buffer in compute shader
267                 const vk::VkBufferMemoryBarrier endBufferBarrier                =
268                 {
269                         vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,            // VkStructureType              sType
270                         DE_NULL,                                                                                        // const void*                  pNext
271                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                srcAccessMask
272                         vk::VK_ACCESS_SHADER_READ_BIT,                                          // VkAccessFlags                dstAccessMask
273                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
274                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
275                         **dstBuffer,                                                                            // VkBuffer                             buffer
276                         0u,                                                                                                     // VkDeviceSize                 offset
277                         VK_WHOLE_SIZE,                                                                          // VkDeviceSize                 size
278                 };
279                 vk.cmdPipelineBarrier(targetCmdBuffer,
280                                                                 vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
281                                                                 vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
282                                                                 (vk::VkDependencyFlags)0,
283                                                                 0, (const vk::VkMemoryBarrier*)DE_NULL,
284                                                                 1, &endBufferBarrier,
285                                                                 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
286         }
287
288         if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
289         {
290                 endCommandBuffer(vk, *secondaryCmdBuffer);
291                 vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
292         }
293
294         endCommandBuffer(vk, *cmdBuffer);
295
296         // Submit command buffer
297         const vk::Unique<vk::VkFence>   fence           (vk::createFence(vk, device));
298         VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
299
300         // Log out test data
301         ctx.getTestContext().getLog()
302                 << tcu::TestLog::Message << "Fill value: " << m_fillValue << tcu::TestLog::EndMessage;
303
304         // Validate resulting buffer
305         if (m_validator.validateBuffer(ctx, **dstBuffer))
306                 return tcu::TestStatus::pass("Everything went OK");
307         else
308                 return tcu::TestStatus::fail("Something went really wrong");
309 }
310
311 tcu::TestCaseGroup*     createCopyImageToFloatBufferTests(tcu::TestContext& testCtx, CmdBufferType cmdBufferType)
312 {
313         struct {
314                 const vk::VkClearColorValue             fillValue;
315                 const ValidationDataVec4                data;
316         } testData[] = {
317                 {       { { 0.0f, 0.0f, 0.0f, 0.0f } },
318                         {
319                                 { tcu::IVec4(0),        tcu::IVec4(1),          tcu::IVec4(3),          tcu::IVec4(7)           },
320                                 { tcu::Vec4(0.0f),      tcu::Vec4(0.0f),        tcu::Vec4(0.0f),        tcu::Vec4(0.0f)         }
321                         }
322                 },
323                 {       { { 1.0f, 1.0f, 1.0f, 1.0f } },
324                         {
325                                 { tcu::IVec4(2),        tcu::IVec4(4),          tcu::IVec4(16),         tcu::IVec4(15)          },
326                                 { tcu::Vec4(1.0f),      tcu::Vec4(1.0f),        tcu::Vec4(1.0f),        tcu::Vec4(1.0f)         }
327                         }
328                 },
329                 {       { { 0.24f, 0.24f, 0.24f, 0.24f } },
330                         {
331                                 { tcu::IVec4(3),        tcu::IVec4(7),          tcu::IVec4(17),         tcu::IVec4(37)          },
332                                 { tcu::Vec4(0.24f),     tcu::Vec4(0.24f),       tcu::Vec4(0.24f),       tcu::Vec4(0.24f)        }
333                         }
334                 },
335                 {       { { 0.68f, 0.68f, 0.68f, 0.68f } },
336                         {
337                                 { tcu::IVec4(7),        tcu::IVec4(11),         tcu::IVec4(21),         tcu::IVec4(40)          },
338                                 { tcu::Vec4(0.68f),     tcu::Vec4(0.68f),       tcu::Vec4(0.68f),       tcu::Vec4(0.68f)        }
339                         }
340                 },
341                 {       { { 0.92f, 0.92f, 0.92f, 0.92f } },
342                         {
343                                 { tcu::IVec4(5),        tcu::IVec4(21),         tcu::IVec4(40),         tcu::IVec4(57)          },
344                                 { tcu::Vec4(0.92f),     tcu::Vec4(0.92f),       tcu::Vec4(0.92f),       tcu::Vec4(0.92f)        }
345                         }
346                 },
347                 {       { { 0.49f, 0.49f, 0.49f, 0.49f } },
348                         {
349                                 { tcu::IVec4(23),       tcu::IVec4(37),         tcu::IVec4(51),         tcu::IVec4(63)          },
350                                 { tcu::Vec4(0.49f),     tcu::Vec4(0.49f),       tcu::Vec4(0.49f),       tcu::Vec4(0.49f)        }
351                         }
352                 },
353         };
354
355         de::MovePtr<tcu::TestCaseGroup> copyStaticTests         (new tcu::TestCaseGroup(testCtx, "static", "Copy Image to Buffer Tests with static input"));
356
357         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
358         {
359                 DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
360                 DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
361                 DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
362                 DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
363
364                 const std::string name = "copy_" + de::toString(ndx + 1);
365                 copyStaticTests->addChild(new CopyImageToBufferTestCase<tcu::Vec4>(testCtx, name.c_str(), testData[ndx].fillValue, testData[ndx].data, cmdBufferType));
366         }
367
368         /* Add a few randomized tests */
369         de::MovePtr<tcu::TestCaseGroup> copyRandomTests         (new tcu::TestCaseGroup(testCtx, "random", "Copy Image to Buffer Tests with random input"));
370         const int                                               testCount                       = 10;
371         de::Random                                              rnd                                     (testCtx.getCommandLine().getBaseSeed());
372         for (int ndx = 0; ndx < testCount; ++ndx)
373         {
374                 const std::string       name            = "copy_" + de::toString(ndx + 1);
375                 vk::VkClearValue        clearValue      = vk::makeClearValueColorVec4(tcu::randomVec4(rnd));
376                 const tcu::Vec4         refValue        (clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]);
377                 const tcu::IVec4        vec0            = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
378                 const tcu::IVec4        vec1            = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
379                 const tcu::IVec4        vec2            = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
380                 const tcu::IVec4        vec3            = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
381
382                 ValidationDataVec4      data            =
383                 {
384                         { vec0, vec1, vec2, vec3 },
385                         { refValue, refValue, refValue, refValue }
386                 };
387
388                 DE_ASSERT(data.positions[0].x() < MAX_POSITION);
389                 DE_ASSERT(data.positions[1].x() < MAX_POSITION);
390                 DE_ASSERT(data.positions[2].x() < MAX_POSITION);
391                 DE_ASSERT(data.positions[3].x() < MAX_POSITION);
392
393                 copyRandomTests->addChild(new CopyImageToBufferTestCase<tcu::Vec4>(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
394         }
395
396         std::string groupName = getCmdBufferTypeStr(cmdBufferType);
397         std::string groupDesc = "Copy Image to Buffer Tests with " + groupName + " command buffer";
398         de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
399         copyTests->addChild(copyStaticTests.release());
400         copyTests->addChild(copyRandomTests.release());
401         return copyTests.release();
402 }
403
404 } // anonymous
405
406 tcu::TestCaseGroup*     createCopyImageToFloatBufferTests (tcu::TestContext& testCtx)
407 {
408         de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, "copy_image_to_float_buffer", "Copy Image to Buffer Tests"));
409
410         copyTests->addChild(createCopyImageToFloatBufferTests(testCtx, CMD_BUFFER_PRIMARY));
411         copyTests->addChild(createCopyImageToFloatBufferTests(testCtx, CMD_BUFFER_SECONDARY));
412
413         return copyTests.release();
414 }
415
416 } // ProtectedMem
417 } // vkt