2783273e9d97b10cd2054107de5b71d9825c29b2
[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
31 #include "vkPrograms.hpp"
32 #include "vktTestCase.hpp"
33 #include "vktTestGroupUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 #include "vkBuilderUtil.hpp"
36 #include "vkCmdUtil.hpp"
37
38 #include "vktProtectedMemContext.hpp"
39 #include "vktProtectedMemUtils.hpp"
40 #include "vktProtectedMemBufferValidator.hpp"
41
42 namespace vkt
43 {
44 namespace ProtectedMem
45 {
46
47 namespace
48 {
49
50 enum {
51         BUFFER_SIZE             = 256,
52         RENDER_WIDTH    = 8,
53         RENDER_HEIGHT   = 8,
54
55         MAX_POSITION    = BUFFER_SIZE / 4,
56 };
57
58 template<typename T>
59 class CopyImageToBufferTestInstance : public ProtectedTestInstance
60 {
61 public:
62                                                                         CopyImageToBufferTestInstance   (Context&                                               ctx,
63                                                                                                                                          const vk::VkClearColorValue    fillValue,
64                                                                                                                                          const BufferValidator<T>&              validator,
65                                                                                                                                          const CmdBufferType                    cmdBufferType);
66         virtual tcu::TestStatus                 iterate                                                 (void);
67
68 private:
69         const vk::VkFormat                              m_imageFormat;
70         const vk::VkClearColorValue             m_fillValue;
71         const BufferValidator<T>&               m_validator;
72         const CmdBufferType                                     m_cmdBufferType;
73 };
74
75
76 template<typename T>
77 class CopyImageToBufferTestCase : public TestCase
78 {
79 public:
80                                                         CopyImageToBufferTestCase       (tcu::TestContext&              testCtx,
81                                                                                                                  const std::string&             name,
82                                                                                                                  vk::VkClearColorValue  fillValue,
83                                                                                                                  ValidationData<T>              data,
84                                                                                                                  CmdBufferType                  cmdBufferType)
85                                                                 : TestCase                              (testCtx, name, "Copy image to buffer.")
86                                                                 , m_fillValue                   (fillValue)
87                                                                 , m_validator                   (data)
88                                                                 , m_cmdBufferType               (cmdBufferType)
89                                                         {
90                                                         }
91
92         virtual                                 ~CopyImageToBufferTestCase      (void) {}
93         virtual TestInstance*   createInstance                          (Context& ctx) const
94                                                         {
95                                                                 return new CopyImageToBufferTestInstance<T>(ctx, m_fillValue, m_validator, m_cmdBufferType);
96                                                         }
97         virtual void                    initPrograms                            (vk::SourceCollections& programCollection) const
98                                                         {
99                                                                 m_validator.initPrograms(programCollection);
100                                                         }
101 private:
102         vk::VkClearColorValue   m_fillValue;
103         BufferValidator<T>              m_validator;
104         CmdBufferType                   m_cmdBufferType;
105 };
106
107 template<typename T>
108 CopyImageToBufferTestInstance<T>::CopyImageToBufferTestInstance (Context&                                               ctx,
109                                                                                                                                  const vk::VkClearColorValue    fillValue,
110                                                                                                                                  const BufferValidator<T>&              validator,
111                                                                                                                                  const CmdBufferType                    cmdBufferType)
112         : ProtectedTestInstance (ctx)
113         , m_imageFormat                 (vk::VK_FORMAT_R32G32B32A32_UINT)
114         , m_fillValue                   (fillValue)
115         , m_validator                   (validator)
116         , m_cmdBufferType               (cmdBufferType)
117 {
118 }
119
120 template<typename T>
121 tcu::TestStatus CopyImageToBufferTestInstance<T>::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 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_TRANSFER_DST_BIT
134                                                                                                                                                         | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT
135                                                                                                                                                         | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
136         de::MovePtr<vk::BufferWithMemory>       dstBuffer                       (makeBuffer(ctx,
137                                                                                                                                                 PROTECTION_ENABLED,
138                                                                                                                                                 queueFamilyIndex,
139                                                                                                                                                 (deUint32)(BUFFER_SIZE * sizeof(deUint32)),
140                                                                                                                                                 vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
141                                                                                                                                                         | vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
142                                                                                                                                                 vk::MemoryRequirement::Protected));
143
144         vk::Unique<vk::VkCommandPool>           cmdPool                         (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
145         vk::Unique<vk::VkCommandBuffer>         cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
146         vk::Unique<vk::VkCommandBuffer>         secondaryCmdBuffer      (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
147         vk::VkCommandBuffer                                     targetCmdBuffer         = (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
148
149         // Begin cmd buffer
150         beginCommandBuffer(vk, *cmdBuffer);
151
152         if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
153         {
154                 // Begin secondary command buffer
155                 const vk::VkCommandBufferInheritanceInfo        secCmdBufInheritInfo    =
156                 {
157                         vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
158                         DE_NULL,
159                         (vk::VkRenderPass)0u,                                                                           // renderPass
160                         0u,                                                                                                                     // subpass
161                         (vk::VkFramebuffer)0u,                                                                          // framebuffer
162                         VK_FALSE,                                                                                                       // occlusionQueryEnable
163                         (vk::VkQueryControlFlags)0u,                                                            // queryFlags
164                         (vk::VkQueryPipelineStatisticFlags)0u,                                          // pipelineStatistics
165                 };
166                 beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, secCmdBufInheritInfo);
167         }
168
169         // Start image barrier for source image.
170         {
171                 const vk::VkImageMemoryBarrier  startImgBarrier         =
172                 {
173                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                     // VkStructureType              sType
174                         DE_NULL,                                                                                        // const void*                  pNext
175                         0,                                                                                                      // VkAccessFlags                srcAccessMask
176                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                dstAccessMask
177                         vk::VK_IMAGE_LAYOUT_UNDEFINED,                                          // VkImageLayout                oldLayout
178                         vk::VK_IMAGE_LAYOUT_GENERAL,                                            // VkImageLayout                newLayout
179                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
180                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
181                         **colorImage,                                                                           // VkImage                              image
182                         {
183                                 vk::VK_IMAGE_ASPECT_COLOR_BIT,                                  // VkImageAspectFlags   aspectMask
184                                 0u,                                                                                             // uint32_t                             baseMipLevel
185                                 1u,                                                                                             // uint32_t                             mipLevels
186                                 0u,                                                                                             // uint32_t                             baseArraySlice
187                                 1u,                                                                                             // uint32_t                             subresourceRange
188                         }
189                 };
190
191                 vk.cmdPipelineBarrier(targetCmdBuffer,
192                                                           vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
193                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
194                                                           (vk::VkDependencyFlags)0,
195                                                           0, (const vk::VkMemoryBarrier*)DE_NULL,
196                                                           0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
197                                                           1, &startImgBarrier);
198         }
199
200         // Image clear
201         const vk::VkImageSubresourceRange subresourceRange =
202         {
203                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask
204                 0u,                                                             // uint32_t                             baseMipLevel
205                 1u,                                                             // uint32_t                             levelCount
206                 0u,                                                             // uint32_t                             baseArrayLayer
207                 1u,                                                             // uint32_t                             layerCount
208         };
209
210         vk.cmdClearColorImage(targetCmdBuffer, **colorImage, vk::VK_IMAGE_LAYOUT_GENERAL, &m_fillValue, 1, &subresourceRange);
211
212         // Image barrier to change accessMask to transfer read bit for source image.
213         {
214                 const vk::VkImageMemoryBarrier initializeBarrier =
215                 {
216                         vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                     // VkStructureType              sType
217                         DE_NULL,                                                                                        // const void*                  pNext
218                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                srcAccessMask
219                         vk::VK_ACCESS_TRANSFER_READ_BIT,                                        // VkAccessFlags                dstAccessMask
220                         vk::VK_IMAGE_LAYOUT_GENERAL,                                            // VkImageLayout                oldLayout
221                         vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,                       // VkImageLayout                newLayout
222                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
223                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
224                         **colorImage,                                                                           // VkImage                              image
225                         {
226                                 vk::VK_IMAGE_ASPECT_COLOR_BIT,                                  // VkImageAspectFlags   aspectMask
227                                 0u,                                                                                             // uint32_t                             baseMipLevel
228                                 1u,                                                                                             // uint32_t                             mipLevels
229                                 0u,                                                                                             // uint32_t                             baseArraySlice
230                                 1u,                                                                                             // uint32_t                             subresourceRange
231                         }
232                 };
233
234                 vk.cmdPipelineBarrier(targetCmdBuffer,
235                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
236                                                           vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
237                                                           (vk::VkDependencyFlags)0,
238                                                           0, (const vk::VkMemoryBarrier*)DE_NULL,
239                                                           0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
240                                                           1, &initializeBarrier);
241         }
242
243         // Copy image to buffer
244         const vk::VkImageSubresourceLayers      subresourceLayers       =
245         {
246                 vk::VK_IMAGE_ASPECT_COLOR_BIT,  // VkImageAspectFlags   aspectMask
247                 0u,                                                             // uint32_t                             mipLevel
248                 0u,                                                             // uint32_t                             baseArrayLayer
249                 1u,                                                             // uint32_t                             layerCount
250         };
251         const vk::VkOffset3D                            nullOffset                      = {0u, 0u, 0u};
252         const vk::VkExtent3D                            imageExtent                     = {(deUint32)RENDER_WIDTH, (deUint32)RENDER_HEIGHT, 1u};
253         const vk::VkBufferImageCopy                     copyRegion                      =
254         {
255                 0ull,                                                   // VkDeviceSize                         srcOffset;
256                 0,                                                              // uint32_t                                     bufferRowLength
257                 0,                                                              // uint32_t                                     bufferImageHeight
258                 subresourceLayers,                              // VkImageSubresourceLayers     imageSubresource
259                 nullOffset,                                             // VkOffset3D                           imageOffset
260                 imageExtent,                                    // VkExtent3D                           imageExtent
261         };
262         vk.cmdCopyImageToBuffer(targetCmdBuffer, **colorImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **dstBuffer, 1u, &copyRegion);
263
264         {
265                 // Buffer validator reads buffer in compute shader
266                 const vk::VkBufferMemoryBarrier endBufferBarrier                =
267                 {
268                         vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,            // VkStructureType              sType
269                         DE_NULL,                                                                                        // const void*                  pNext
270                         vk::VK_ACCESS_TRANSFER_WRITE_BIT,                                       // VkAccessFlags                srcAccessMask
271                         vk::VK_ACCESS_SHADER_READ_BIT,                                          // VkAccessFlags                dstAccessMask
272                         queueFamilyIndex,                                                                       // uint32_t                             srcQueueFamilyIndex
273                         queueFamilyIndex,                                                                       // uint32_t                             dstQueueFamilyIndex
274                         **dstBuffer,                                                                            // VkBuffer                             buffer
275                         0u,                                                                                                     // VkDeviceSize                 offset
276                         VK_WHOLE_SIZE,                                                                          // VkDeviceSize                 size
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                                                                 1, &endBufferBarrier,
284                                                                 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
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 buffer
304         if (m_validator.validateBuffer(ctx, **dstBuffer))
305                 return tcu::TestStatus::pass("Everything went OK");
306         else
307                 return tcu::TestStatus::fail("Something went really wrong");
308 }
309
310 tcu::TestCaseGroup*     createCopyImageToFloatBufferTests(tcu::TestContext& testCtx, CmdBufferType cmdBufferType)
311 {
312         struct {
313                 const vk::VkClearColorValue             fillValue;
314                 const ValidationDataVec4                data;
315         } testData[] = {
316                 {       { { 0.0f, 0.0f, 0.0f, 0.0f } },
317                         {
318                                 { tcu::IVec4(0),        tcu::IVec4(1),          tcu::IVec4(3),          tcu::IVec4(7)           },
319                                 { tcu::Vec4(0.0f),      tcu::Vec4(0.0f),        tcu::Vec4(0.0f),        tcu::Vec4(0.0f)         }
320                         }
321                 },
322                 {       { { 1.0f, 1.0f, 1.0f, 1.0f } },
323                         {
324                                 { tcu::IVec4(2),        tcu::IVec4(4),          tcu::IVec4(16),         tcu::IVec4(15)          },
325                                 { tcu::Vec4(1.0f),      tcu::Vec4(1.0f),        tcu::Vec4(1.0f),        tcu::Vec4(1.0f)         }
326                         }
327                 },
328                 {       { { 0.24f, 0.24f, 0.24f, 0.24f } },
329                         {
330                                 { tcu::IVec4(3),        tcu::IVec4(7),          tcu::IVec4(17),         tcu::IVec4(37)          },
331                                 { tcu::Vec4(0.24f),     tcu::Vec4(0.24f),       tcu::Vec4(0.24f),       tcu::Vec4(0.24f)        }
332                         }
333                 },
334                 {       { { 0.68f, 0.68f, 0.68f, 0.68f } },
335                         {
336                                 { tcu::IVec4(7),        tcu::IVec4(11),         tcu::IVec4(21),         tcu::IVec4(40)          },
337                                 { tcu::Vec4(0.68f),     tcu::Vec4(0.68f),       tcu::Vec4(0.68f),       tcu::Vec4(0.68f)        }
338                         }
339                 },
340                 {       { { 0.92f, 0.92f, 0.92f, 0.92f } },
341                         {
342                                 { tcu::IVec4(5),        tcu::IVec4(21),         tcu::IVec4(40),         tcu::IVec4(57)          },
343                                 { tcu::Vec4(0.92f),     tcu::Vec4(0.92f),       tcu::Vec4(0.92f),       tcu::Vec4(0.92f)        }
344                         }
345                 },
346                 {       { { 0.49f, 0.49f, 0.49f, 0.49f } },
347                         {
348                                 { tcu::IVec4(23),       tcu::IVec4(37),         tcu::IVec4(51),         tcu::IVec4(63)          },
349                                 { tcu::Vec4(0.49f),     tcu::Vec4(0.49f),       tcu::Vec4(0.49f),       tcu::Vec4(0.49f)        }
350                         }
351                 },
352         };
353
354         de::MovePtr<tcu::TestCaseGroup> copyStaticTests         (new tcu::TestCaseGroup(testCtx, "static", "Copy Image to Buffer Tests with static input"));
355
356         for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
357         {
358                 DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
359                 DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
360                 DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
361                 DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
362
363                 const std::string name = "copy_" + de::toString(ndx + 1);
364                 copyStaticTests->addChild(new CopyImageToBufferTestCase<tcu::Vec4>(testCtx, name.c_str(), testData[ndx].fillValue, testData[ndx].data, cmdBufferType));
365         }
366
367         /* Add a few randomized tests */
368         de::MovePtr<tcu::TestCaseGroup> copyRandomTests         (new tcu::TestCaseGroup(testCtx, "random", "Copy Image to Buffer Tests with random input"));
369         const int                                               testCount                       = 10;
370         de::Random                                              rnd                                     (testCtx.getCommandLine().getBaseSeed());
371         for (int ndx = 0; ndx < testCount; ++ndx)
372         {
373                 const std::string       name            = "copy_" + de::toString(ndx + 1);
374                 vk::VkClearValue        clearValue      = vk::makeClearValueColorF32(
375                                                                                         rnd.getFloat(0.0, 1.0f),
376                                                                                         rnd.getFloat(0.0, 1.0f),
377                                                                                         rnd.getFloat(0.0, 1.0f),
378                                                                                         rnd.getFloat(0.0, 1.0f));
379
380                 tcu::Vec4                       refValue        (clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]);
381                 ValidationDataVec4      data            =
382                 {
383                         { tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
384                           tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
385                           tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
386                           tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)) },
387                         { refValue, refValue, refValue, refValue }
388                 };
389
390                 DE_ASSERT(data.positions[0].x() < MAX_POSITION);
391                 DE_ASSERT(data.positions[1].x() < MAX_POSITION);
392                 DE_ASSERT(data.positions[2].x() < MAX_POSITION);
393                 DE_ASSERT(data.positions[3].x() < MAX_POSITION);
394
395                 copyRandomTests->addChild(new CopyImageToBufferTestCase<tcu::Vec4>(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
396         }
397
398         std::string groupName = getCmdBufferTypeStr(cmdBufferType);
399         std::string groupDesc = "Copy Image to Buffer Tests with " + groupName + " command buffer";
400         de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
401         copyTests->addChild(copyStaticTests.release());
402         copyTests->addChild(copyRandomTests.release());
403         return copyTests.release();
404 }
405
406 } // anonymous
407
408 tcu::TestCaseGroup*     createCopyImageToFloatBufferTests (tcu::TestContext& testCtx)
409 {
410         de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, "copy_image_to_float_buffer", "Copy Image to Buffer Tests"));
411
412         copyTests->addChild(createCopyImageToFloatBufferTests(testCtx, CMD_BUFFER_PRIMARY));
413         copyTests->addChild(createCopyImageToFloatBufferTests(testCtx, CMD_BUFFER_SECONDARY));
414
415         return copyTests.release();
416 }
417
418 } // ProtectedMem
419 } // vkt