Merge vk-gl-cts/vulkan-cts-1.2.2 into vk-gl-cts/vulkan-cts-1.2.3
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / protected_memory / vktProtectedMemBufferValidator.hpp
1 #ifndef _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP
2 #define _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2017 The Khronos Group Inc.
8  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Protected content buffer validator helper
25  *//*--------------------------------------------------------------------*/
26
27 #include "tcuVector.hpp"
28 #include "vkDefs.hpp"
29 #include "vktTestCase.hpp"
30 #include "tcuVector.hpp"
31 #include "tcuTestLog.hpp"
32
33 #include "vkBuilderUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkCmdUtil.hpp"
37 #include "vkObjUtil.hpp"
38 #include "vktTestCase.hpp"
39 #include "vktTestGroupUtil.hpp"
40 #include "tcuStringTemplate.hpp"
41
42 #include "vktProtectedMemUtils.hpp"
43 #include "vktProtectedMemContext.hpp"
44
45 namespace vkt
46 {
47 namespace ProtectedMem
48 {
49
50 class ProtectedContext;
51
52 template<typename T>
53 struct ValidationData {
54         const tcu::IVec4        positions[4];
55         const T                         values[4];
56 };
57
58 template<typename T>
59 struct ValidationDataStorage {
60         T                                       values;
61 };
62
63 typedef ValidationData<tcu::UVec4>      ValidationDataUVec4;
64 typedef ValidationData<tcu::IVec4>      ValidationDataIVec4;
65 typedef ValidationData<tcu::Vec4>       ValidationDataVec4;
66
67 enum TestType {
68         TYPE_UINT,
69         TYPE_INT,
70         TYPE_FLOAT,
71 };
72
73 enum BufferType {
74         SAMPLER_BUFFER,
75         STORAGE_BUFFER,
76 };
77
78 void                                    initBufferValidatorPrograms             (vk::SourceCollections& programCollection, TestType testType, BufferType bufferType);
79 vk::VkDescriptorType    getDescriptorType                               (BufferType bufferType);
80
81 template<typename T>
82 class BufferValidator
83 {
84 public:
85                                                                         BufferValidator                 (const ValidationData<T> data, vk::VkFormat format)
86                                                                                 : m_refData                     (data)
87                                                                                 , m_refDataStorage      (*reinterpret_cast<ValidationDataStorage<T>*>( &std::vector<char>(sizeof(ValidationDataStorage<T>), '\0').front()))
88                                                                                 , m_bufferType          (SAMPLER_BUFFER)
89                                                                                 , m_format                      (format)
90                                                                         {
91                                                                         }
92
93                                                                         BufferValidator                 (const ValidationDataStorage<T> data, vk::VkFormat format)
94                                                                                 : m_refData                     (*reinterpret_cast<ValidationData<T>*>( &std::vector<char>(sizeof(ValidationData<T>), '\0').front()))
95                                                                                 , m_refDataStorage      (data)
96                                                                                 , m_bufferType          (STORAGE_BUFFER)
97                                                                                 , m_format                      (format)
98                                                                         {
99                                                                         }
100
101                                                                         ~BufferValidator                () {}
102         void                                                    initPrograms                    (vk::SourceCollections& programCollection) const;
103
104         bool                                                    validateBuffer                  (ProtectedContext&      ctx,
105                                                                                                                                  const vk::VkBuffer     buffer) const;
106 private:
107         deUint32                                                getReferenceDataSize    () const;
108         const void *                                    getReferenceDataSrc             () const;
109         void                                                    printReferenceInfo              (ProtectedContext&              ctx) const;
110
111         const ValidationData<T>                 m_refData;
112         const ValidationDataStorage<T>  m_refDataStorage;
113
114         BufferType                                              m_bufferType;
115         vk::VkFormat                                    m_format;
116 };
117
118 template<>
119 inline void BufferValidator<tcu::UVec4>::initPrograms (vk::SourceCollections& programCollection) const
120 {
121         initBufferValidatorPrograms(programCollection, TYPE_UINT, m_bufferType);
122 }
123
124 template<>
125 inline void BufferValidator<tcu::IVec4>::initPrograms (vk::SourceCollections& programCollection) const
126 {
127         initBufferValidatorPrograms(programCollection, TYPE_INT, m_bufferType);
128 }
129
130 template<>
131 inline void BufferValidator<tcu::Vec4>::initPrograms (vk::SourceCollections& programCollection) const
132 {
133         initBufferValidatorPrograms(programCollection, TYPE_FLOAT, m_bufferType);
134 }
135
136 template<typename T>
137 deUint32 BufferValidator<T>::getReferenceDataSize () const
138 {
139         return m_bufferType == SAMPLER_BUFFER ? (deUint32)sizeof(m_refData) : (deUint32)sizeof(m_refDataStorage);
140 }
141
142 template<typename T>
143 const void * BufferValidator<T>::getReferenceDataSrc () const
144 {
145         return m_bufferType == SAMPLER_BUFFER ? (void*)&m_refData : (void*)&m_refDataStorage;
146 }
147
148 template<typename T>
149 void BufferValidator<T>::printReferenceInfo (ProtectedContext& ctx) const
150 {
151         if (m_bufferType == SAMPLER_BUFFER)
152         {
153                 ctx.getTestContext().getLog()
154                                 << tcu::TestLog::Message << "Reference positions: \n"
155                                 << "1: " << m_refData.positions[0] << "\n"
156                                 << "2: " << m_refData.positions[1] << "\n"
157                                 << "3: " << m_refData.positions[2] << "\n"
158                                 << "4: " << m_refData.positions[3] << "\n"
159                                 << tcu::TestLog::EndMessage
160                                 << tcu::TestLog::Message << "Reference fill values: \n"
161                                 << "1: " << m_refData.values[0] << "\n"
162                                 << "2: " << m_refData.values[1] << "\n"
163                                 << "3: " << m_refData.values[2] << "\n"
164                                 << "4: " << m_refData.values[3] << "\n"
165                                 << tcu::TestLog::EndMessage;
166         } else if (m_bufferType == STORAGE_BUFFER)
167         {
168                 ctx.getTestContext().getLog()
169                                 << tcu::TestLog::Message << "Reference values: \n"
170                                 << "1: " << m_refDataStorage.values << "\n"
171                                 << tcu::TestLog::EndMessage;
172         }
173 }
174
175 template<typename T>
176 bool BufferValidator<T>::validateBuffer (ProtectedContext&              ctx,
177                                                                                  const vk::VkBuffer             buffer) const
178 {
179         // Log out a few reference info
180         printReferenceInfo(ctx);
181
182         const deUint64                                                  oneSec                          = 1000 * 1000 * 1000;
183
184         const vk::DeviceInterface&                              vk                                      = ctx.getDeviceInterface();
185         const vk::VkDevice                                              device                          = ctx.getDevice();
186         const vk::VkQueue                                               queue                           = ctx.getQueue();
187         const deUint32                                                  queueFamilyIndex        = ctx.getQueueFamilyIndex();
188
189         vk::Move<vk::VkBufferView>                              bufferView;
190
191         const deUint32                                                  refDataSize                     = getReferenceDataSize();
192         de::UniquePtr<vk::BufferWithMemory>             refUniform                      (makeBuffer(ctx,
193                                                                                                                                  PROTECTION_DISABLED,
194                                                                                                                                  queueFamilyIndex,
195                                                                                                                                  refDataSize,
196                                                                                                                                  vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
197                                                                                                                                  vk::MemoryRequirement::HostVisible));
198
199         // Set the reference uniform data
200         {
201                 deMemcpy(refUniform->getAllocation().getHostPtr(), getReferenceDataSrc(), refDataSize);
202                 flushAlloc(vk, device, refUniform->getAllocation());
203         }
204
205         const deUint32                                                  helperBufferSize        = (deUint32)(2 * sizeof(deUint32));
206         de::MovePtr<vk::BufferWithMemory>               helperBuffer            (makeBuffer(ctx,
207                                                                                                                                  PROTECTION_ENABLED,
208                                                                                                                                  queueFamilyIndex,
209                                                                                                                                  helperBufferSize,
210                                                                                                                                  vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
211                                                                                                                                  vk::MemoryRequirement::Protected));
212         vk::Unique<vk::VkShaderModule>                  resetSSBOShader         (vk::createShaderModule(vk, device, ctx.getBinaryCollection().get("ResetSSBO"), 0));
213         vk::Unique<vk::VkShaderModule>                  validatorShader         (vk::createShaderModule(vk, device, ctx.getBinaryCollection().get("BufferValidator"), 0));
214
215         // Create descriptors
216         vk::Unique<vk::VkDescriptorSetLayout>   descriptorSetLayout     (vk::DescriptorSetLayoutBuilder()
217                                                                                                                                         .addSingleBinding(getDescriptorType(m_bufferType), vk::VK_SHADER_STAGE_COMPUTE_BIT)
218                                                                                                                                         .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
219                                                                                                                                         .addSingleBinding(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT)
220                                                                                                                                         .build(vk, device));
221         vk::Unique<vk::VkDescriptorPool>                descriptorPool          (vk::DescriptorPoolBuilder()
222                                                                                                                                         .addType(getDescriptorType(m_bufferType), 1u)
223                                                                                                                                         .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u)
224                                                                                                                                         .addType(vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u)
225                                                                                                                                         .build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
226         vk::Unique<vk::VkDescriptorSet>                 descriptorSet           (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
227
228
229         // Update descriptor set information
230         {
231                 vk::VkDescriptorBufferInfo      descRefUniform  = makeDescriptorBufferInfo(**refUniform, 0, refDataSize);
232                 vk::VkDescriptorBufferInfo      descBuffer              = makeDescriptorBufferInfo(**helperBuffer, 0, helperBufferSize);
233
234                 vk::DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
235                 switch (m_bufferType)
236                 {
237                         case SAMPLER_BUFFER:
238                         {
239                                 const vk::VkBufferViewCreateInfo                viewParams                      =
240                                         {
241                                                 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,  // VkStructureType                      sType
242                                                 DE_NULL,                                                                                // const void*                          pNext
243                                                 0u,                                                                                             // VkBufferViewCreateFlags      flags
244                                                 buffer,                                                                                 // VkBuffer                                     buffer
245                                                 m_format,                                                                               // VkFormat                                     format
246                                                 0u,                                                                                             // VkDeviceSize                         offset
247                                                 VK_WHOLE_SIZE                                                                   // VkDeviceSize                         range
248                                         };
249                                 bufferView = vk::Move<vk::VkBufferView> (vk::createBufferView(vk, device, &viewParams));
250                                 descriptorSetUpdateBuilder
251                                         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, &bufferView.get());
252                                 break;
253                         }
254                         case STORAGE_BUFFER:
255                         {
256                                 const deUint32                                  testBufferSize  = (deUint32)(sizeof(ValidationDataStorage<T>));
257                                 vk::VkDescriptorBufferInfo              descTestBuffer  = makeDescriptorBufferInfo(buffer, 0, testBufferSize);
258                                 descriptorSetUpdateBuilder
259                                         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descTestBuffer);
260                                 break;
261                         }
262                 }
263                 descriptorSetUpdateBuilder
264                         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descBuffer)
265                         .writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &descRefUniform)
266                 .update(vk, device);
267         }
268
269         // Build pipeline
270         vk::Unique<vk::VkPipelineLayout>                pipelineLayout          (makePipelineLayout(vk, device, *descriptorSetLayout));
271
272         vk::Unique<vk::VkCommandPool>                   cmdPool                         (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
273
274         // Reset helper SSBO
275         {
276                 const vk::Unique<vk::VkFence>           fence                           (vk::createFence(vk, device));
277                 vk::Unique<vk::VkPipeline>                      resetSSBOPipeline       (makeComputePipeline(vk, device, *pipelineLayout, *resetSSBOShader, DE_NULL));
278                 vk::Unique<vk::VkCommandBuffer>         resetCmdBuffer          (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
279                 beginCommandBuffer(vk, *resetCmdBuffer);
280
281                 vk.cmdBindPipeline(*resetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *resetSSBOPipeline);
282                 vk.cmdBindDescriptorSets(*resetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
283                 vk.cmdDispatch(*resetCmdBuffer, 1u, 1u, 1u);
284
285                 endCommandBuffer(vk, *resetCmdBuffer);
286                 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *resetCmdBuffer, *fence, ~0ull));
287         }
288
289         // Create validation compute commands & submit
290         vk::VkResult                                                    queueSubmitResult;
291         {
292                 const vk::Unique<vk::VkFence>           fence                           (vk::createFence(vk, device));
293                 vk::Unique<vk::VkPipeline>                      validationPipeline      (makeComputePipeline(vk, device, *pipelineLayout, *validatorShader, DE_NULL));
294                 vk::Unique<vk::VkCommandBuffer>         cmdBuffer                       (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
295
296                 beginCommandBuffer(vk, *cmdBuffer);
297
298                 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *validationPipeline);
299                 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &*descriptorSet, 0u, DE_NULL);
300                 vk.cmdDispatch(*cmdBuffer, 1u, 1u, 1u);
301
302                 endCommandBuffer(vk, *cmdBuffer);
303
304                 queueSubmitResult = queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, oneSec);
305         }
306
307         // \todo do we need to check the fence status?
308         if (queueSubmitResult == vk::VK_TIMEOUT)
309                 return false;
310
311         // at this point the submit result should be VK_TRUE
312         VK_CHECK(queueSubmitResult);
313         return true;
314 }
315
316
317 } // ProtectedMem
318 } // vkt
319
320 #endif // _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP