Make random number usage platform independent
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / protected_memory / vktProtectedMemCopyBufferToImageTests.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 content copy buffer to image tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktProtectedMemCopyBufferToImageTests.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 "vktProtectedMemImageValidator.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
57 class CopyBufferToImageTestInstance : public ProtectedTestInstance
58 {
59 public:
60                                                                         CopyBufferToImageTestInstance   (Context&                                       ctx,
61                                                                                                                                          const deUint32                         fillValue,
62                                                                                                                                          const ValidationData&          refData,
63                                                                                                                                          const ImageValidator&          validator,
64                                                                                                                                          const CmdBufferType            cmdBufferType);
65 virtual tcu::TestStatus                         iterate                                                  (void);
66
67 private:
68         const vk::VkFormat                              m_imageFormat;
69         const deUint32                                  m_fillValue;
70         const ValidationData&                   m_refData;
71         const ImageValidator&                   m_validator;
72         const CmdBufferType                             m_cmdBufferType;
73 };
74
75 class CopyBufferToImageTestCase : public TestCase
76 {
77 public:
78                                                                 CopyBufferToImageTestCase       (tcu::TestContext&                      testCtx,
79                                                                                                                          const std::string&                     name,
80                                                                                                                          deUint32                                       fillValue,
81                                                                                                                          ValidationData                         data,
82                                                                                                                          CmdBufferType                          cmdBufferType)
83                                                                         : TestCase                              (testCtx, name, "Copy buffer to image.")
84                                                                         , m_fillValue                   (fillValue)
85                                                                         , m_refData                             (data)
86                                                                         , m_validator                   (vk::VK_FORMAT_R32G32B32A32_SFLOAT)
87                                                                         , m_cmdBufferType               (cmdBufferType)
88                                                                 {
89                                                                 }
90
91         virtual                                         ~CopyBufferToImageTestCase      (void) {}
92         virtual TestInstance*           createInstance                          (Context& ctx) const
93                                                                 {
94                                                                         return new CopyBufferToImageTestInstance(ctx, m_fillValue, m_refData, m_validator, m_cmdBufferType);
95                                                                 }
96         virtual void                            initPrograms                            (vk::SourceCollections& programCollection) const
97                                                                 {
98                                                                         m_validator.initPrograms(programCollection);
99                                                                 }
100 private:
101         deUint32                                        m_fillValue;
102         ValidationData                          m_refData;
103         ImageValidator                          m_validator;
104         CmdBufferType                           m_cmdBufferType;
105 };
106
107 CopyBufferToImageTestInstance::CopyBufferToImageTestInstance    (Context&                                       ctx,
108                                                                                                                                  const deUint32                         fillValue,
109                                                                                                                                  const ValidationData&          refData,
110                                                                                                                                  const ImageValidator&          validator,
111                                                                                                                                  const CmdBufferType            cmdBufferType)
112         : ProtectedTestInstance         (ctx)
113         , m_imageFormat                         (vk::VK_FORMAT_R32G32B32A32_SFLOAT)
114         , m_fillValue                           (fillValue)
115         , m_refData                                     (refData)
116         , m_validator                           (validator)
117         , m_cmdBufferType                       (cmdBufferType)
118 {
119 }
120
121 tcu::TestStatus CopyBufferToImageTestInstance::iterate()
122 {
123         ProtectedContext&                                       ctx                                     (m_protectedContext);
124         const vk::DeviceInterface&                      vk                                      = ctx.getDeviceInterface();
125         const vk::VkDevice                                      device                          = ctx.getDevice();
126         const vk::VkQueue                                       queue                           = ctx.getQueue();
127         const deUint32                                          queueFamilyIndex        = ctx.getQueueFamilyIndex();
128
129         // Create destination image
130         de::MovePtr<vk::ImageWithMemory>        colorImage                      = createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
131                                                                                                                                                         RENDER_WIDTH, RENDER_HEIGHT,
132                                                                                                                                                         m_imageFormat,
133                                                                                                                                                         vk::VK_IMAGE_USAGE_SAMPLED_BIT|vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
134         de::MovePtr<vk::BufferWithMemory>       srcBuffer                       (makeBuffer(ctx,
135                                                                                                                                                 PROTECTION_ENABLED,
136                                                                                                                                                 queueFamilyIndex,
137                                                                                                                                                 (deUint32)(BUFFER_SIZE * sizeof(deUint32)),
138                                                                                                                                                 vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
139                                                                                                                                                         | vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
140                                                                                                                                                         | vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
141                                                                                                                                                 vk::MemoryRequirement::Protected));
142
143         vk::Unique<vk::VkCommandPool>           cmdPool                         (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
144         vk::Unique<vk::VkCommandBuffer>         cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
145         vk::Unique<vk::VkCommandBuffer>         secondaryCmdBuffer      (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
146         vk::VkCommandBuffer                                     targetCmdBuffer         = (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
147
148         // Begin cmd buffer
149         beginCommandBuffer(vk, *cmdBuffer);
150
151         if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
152         {
153                 // Begin secondary command buffer
154                 const vk::VkCommandBufferInheritanceInfo        bufferInheritanceInfo   =
155                 {
156                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,          // sType
157                         DE_NULL,                                                                                                        // pNext
158                         DE_NULL,                                                                                                        // renderPass
159                         0u,                                                                                                                     // subpass
160                         DE_NULL,                                                                                                        // framebuffer
161                         VK_FALSE,                                                                                                       // occlusionQueryEnable
162                         (vk::VkQueryControlFlags)0u,                                                            // queryFlags
163                         (vk::VkQueryPipelineStatisticFlags)0u,                                          // pipelineStatistics
164                 };
165                 beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, bufferInheritanceInfo);
166         }
167
168         // Start src buffer barrier
169         {
170                 const vk::VkBufferMemoryBarrier startBufferBarrier =
171                 {
172                         vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,    // VkStructureType              sType
173                         DE_NULL,                                                                                // const void*                  pNext
174                         0,                                                                                              // VkAccessFlags                srcAccessMask
175                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                               // VkAccessFlags                dstAccessMask
176                         queueFamilyIndex,                                                               // uint32_t                             srcQueueFamilyIndex
177                         queueFamilyIndex,                                                               // uint32_t                             dstQueueFamilyIndex
178                         **srcBuffer,                                                                    // VkBuffer                             buffer
179                         0u,                                                                                             // VkDeviceSize                 offset
180                         VK_WHOLE_SIZE,                                                                  // VkDeviceSize                 size
181                 };
182                 vk.cmdPipelineBarrier(targetCmdBuffer,
183                                                           vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
184                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
185                                                           (vk::VkDependencyFlags) 0,
186                                                           0, (const vk::VkMemoryBarrier *) DE_NULL,
187                                                           1, &startBufferBarrier,
188                                                           0, (const vk::VkImageMemoryBarrier *) DE_NULL);
189         }
190         vk.cmdFillBuffer(targetCmdBuffer, **srcBuffer, 0u, VK_WHOLE_SIZE, m_fillValue);
191
192         {
193                 // Barrier to change accessMask to transfer read bit for source buffer
194                 const vk::VkBufferMemoryBarrier startCopyBufferBarrier =
195                 {
196                         vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,            // VkStructureType              sType
197                         DE_NULL,                                                                                        // const void*                  pNext
198                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                srcAccessMask
199                         vk::VK_ACCESS_TRANSFER_READ_BIT,                                        // VkAccessFlags                dstAccessMask
200                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
201                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
202                         **srcBuffer,                                                                            // VkBuffer                             buffer
203                         0u,                                                                                                     // VkDeviceSize                 offset
204                         VK_WHOLE_SIZE,                                                                          // VkDeviceSize                 size
205                 };
206
207                 // Start image barrier for destination image.
208                 const vk::VkImageMemoryBarrier  startImgBarrier         =
209                 {
210                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                     // VkStructureType              sType
211                         DE_NULL,                                                                                        // const void*                  pNext
212                         0,                                                                                                      // VkAccessFlags                srcAccessMask
213                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                dstAccessMask
214                         vk::VK_IMAGE_LAYOUT_UNDEFINED,                                          // VkImageLayout                oldLayout
215                         vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                       // VkImageLayout                newLayout
216                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
217                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
218                         **colorImage,                                                                           // VkImage                              image
219                         {
220                                 vk::VK_IMAGE_ASPECT_COLOR_BIT,                                  // VkImageAspectFlags   aspectMask
221                                 0u,                                                                                             // uint32_t                             baseMipLevel
222                                 1u,                                                                                             // uint32_t                             mipLevels
223                                 0u,                                                                                             // uint32_t                             baseArraySlice
224                                 1u,                                                                                             // uint32_t                             subresourceRange
225                         }
226                 };
227
228                 vk.cmdPipelineBarrier(targetCmdBuffer,
229                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
230                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
231                                                           (vk::VkDependencyFlags)0,
232                                                           0, (const vk::VkMemoryBarrier*)DE_NULL,
233                                                           1, &startCopyBufferBarrier,
234                                                           1, &startImgBarrier);
235         }
236
237         // Copy buffer to image
238         const vk::VkImageSubresourceLayers      subresourceLayers       =
239         {
240                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags           aspectMask
241                 0u,                                                             // uint32_t                                     mipLevel
242                 0u,                                                             // uint32_t                                     baseArrayLayer
243                 1u,                                                             // uint32_t                                     layerCount
244         };
245         const vk::VkOffset3D                            nullOffset                      = {0u, 0u, 0u};
246         const vk::VkExtent3D                            imageExtent                     = {(deUint32)RENDER_WIDTH, (deUint32)RENDER_HEIGHT, 1u};
247         const vk::VkBufferImageCopy                     copyRegion                      =
248         {
249                 0ull,                                                   // VkDeviceSize                         srcOffset;
250                 0,                                                              // uint32_t                                     bufferRowLength
251                 0,                                                              // uint32_t                                     bufferImageHeight
252                 subresourceLayers,                              // VkImageSubresourceLayers     imageSubresource
253                 nullOffset,                                             // VkOffset3D                           imageOffset
254                 imageExtent,                                    // VkExtent3D                           imageExtent
255         };
256         vk.cmdCopyBufferToImage(targetCmdBuffer, **srcBuffer, **colorImage, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
257
258         {
259                 const vk::VkImageMemoryBarrier  endImgBarrier           =
260                 {
261                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                     // VkStructureType              sType
262                         DE_NULL,                                                                                        // const void*                  pNext
263                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                srcAccessMask
264                         vk::VK_ACCESS_SHADER_READ_BIT,                                          // VkAccessFlags                dstAccessMask
265                         vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,                       // VkImageLayout                oldLayout
266                         vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,           // VkImageLayout                newLayout
267                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
268                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
269                         **colorImage,                                                                           // VkImage                              image
270                         {
271                                 vk::VK_IMAGE_ASPECT_COLOR_BIT,                                  // VkImageAspectFlags   aspectMask
272                                 0u,                                                                                             // uint32_t                             baseMipLevel
273                                 1u,                                                                                             // uint32_t                             mipLevels
274                                 0u,                                                                                             // uint32_t                             baseArraySlice
275                                 1u,                                                                                             // uint32_t                             subresourceRange
276                         }
277                 };
278                 vk.cmdPipelineBarrier(targetCmdBuffer,
279                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
280                                                           vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
281                                                           (vk::VkDependencyFlags)0,
282                                                           0, (const vk::VkMemoryBarrier*)DE_NULL,
283                                                           0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
284                                                           1, &endImgBarrier);
285         }
286
287         if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
288         {
289                 endCommandBuffer(vk, *secondaryCmdBuffer);
290                 vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
291         }
292
293         endCommandBuffer(vk, *cmdBuffer);
294
295         // Submit command buffer
296         const vk::Unique<vk::VkFence>   fence           (vk::createFence(vk, device));
297         VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
298
299         // Log out test data
300         ctx.getTestContext().getLog()
301                 << tcu::TestLog::Message << "Fill value: " << m_fillValue << tcu::TestLog::EndMessage;
302
303         // Validate resulting image
304         if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
305                 return tcu::TestStatus::pass("Everything went OK");
306         else
307                 return tcu::TestStatus::fail("Something went really wrong");
308 }
309
310 tcu::TestCaseGroup*     createCopyBufferToImageTests (tcu::TestContext& testCtx, CmdBufferType cmdBufferType)
311 {
312         struct {
313                 const union {
314                         float           flt;
315                         deUint32        uint;
316                 }                                               fillValue;
317                 const ValidationData    data;
318         } testData[] = {
319                 {       { 0.0f },
320                         {
321                                 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
322                                   tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
323                                 { tcu::Vec4(0.0f), tcu::Vec4(0.0f),
324                                   tcu::Vec4(0.0f), tcu::Vec4(0.0f), }
325                         }
326                 },
327                 {       { 1.0f },
328                         {
329                                 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
330                                   tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
331                                 { tcu::Vec4(1.0f), tcu::Vec4(1.0f),
332                                   tcu::Vec4(1.0f), tcu::Vec4(1.0f), }
333                         }
334                 },
335                 {       { 0.2f },
336                         {
337                                 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
338                                   tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
339                                 { tcu::Vec4(0.2f), tcu::Vec4(0.2f),
340                                   tcu::Vec4(0.2f), tcu::Vec4(0.2f), }
341                         }
342                 },
343                 {       { 0.55f },
344                         {
345                                 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
346                                   tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
347                                 { tcu::Vec4(0.55f), tcu::Vec4(0.55f),
348                                   tcu::Vec4(0.55f), tcu::Vec4(0.55f), }
349                         }
350                 },
351                 {       { 0.82f },
352                         {
353                                 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
354                                   tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
355                                 { tcu::Vec4(0.82f), tcu::Vec4(0.82f),
356                                   tcu::Vec4(0.82f), tcu::Vec4(0.82f), }
357                         }
358                 },
359                 {       { 0.96f },
360                         {
361                                 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
362                                   tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
363                                 { tcu::Vec4(0.96f), tcu::Vec4(0.96f),
364                                   tcu::Vec4(0.96f), tcu::Vec4(0.96f), }
365                         }
366                 },
367         };
368
369         de::MovePtr<tcu::TestCaseGroup> copyStaticTests         (new tcu::TestCaseGroup(testCtx, "static", "Copy Buffer To Image Tests with static input"));
370
371         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
372         {
373                 const std::string name = "copy_" + de::toString(ndx + 1);
374                 copyStaticTests->addChild(new CopyBufferToImageTestCase(testCtx, name.c_str(), testData[ndx].fillValue.uint, testData[ndx].data, cmdBufferType));
375         }
376
377         /* Add a few randomized tests */
378         de::MovePtr<tcu::TestCaseGroup> copyRandomTests         (new tcu::TestCaseGroup(testCtx, "random", "Copy Buffer To Image Tests with random input"));
379         const int                                               testCount                       = 10;
380         de::Random                                              rnd                                     (testCtx.getCommandLine().getBaseSeed());
381         for (int ndx = 0; ndx < testCount; ++ndx)
382         {
383                 const std::string       name            = "copy_" + de::toString(ndx + 1);
384
385                 const union {
386                         float           flt;
387                         deUint32        uint;
388                 }                                       fillValue       = { rnd.getFloat(0.0, 1.0f) };
389
390                 const tcu::Vec4         refValue        (fillValue.flt);
391                 const tcu::Vec4         vec0            = tcu::randomVec4(rnd);
392                 const tcu::Vec4         vec1            = tcu::randomVec4(rnd);
393                 const tcu::Vec4         vec2            = tcu::randomVec4(rnd);
394                 const tcu::Vec4         vec3            = tcu::randomVec4(rnd);
395
396                 ValidationData          data            =
397                 {
398                         { vec0, vec1, vec2, vec3 },
399                         { refValue, refValue, refValue, refValue }
400                 };
401                 copyRandomTests->addChild(new CopyBufferToImageTestCase(testCtx, name.c_str(), fillValue.uint, data, cmdBufferType));
402         }
403
404         std::string groupName = getCmdBufferTypeStr(cmdBufferType);
405         std::string groupDesc = "Copy Buffer To Image Tests with " + groupName + " command buffer";
406         de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
407         copyTests->addChild(copyStaticTests.release());
408         copyTests->addChild(copyRandomTests.release());
409         return copyTests.release();
410 }
411
412 } // anonymous
413
414 tcu::TestCaseGroup*     createCopyBufferToImageTests (tcu::TestContext& testCtx)
415 {
416         de::MovePtr<tcu::TestCaseGroup> clearTests (new tcu::TestCaseGroup(testCtx, "copy_buffer_to_image", "Copy Buffer To Image Tests"));
417
418         clearTests->addChild(createCopyBufferToImageTests(testCtx, CMD_BUFFER_PRIMARY));
419         clearTests->addChild(createCopyBufferToImageTests(testCtx, CMD_BUFFER_SECONDARY));
420
421         return clearTests.release();
422 }
423
424 } // ProtectedMem
425 } // vkt