1 #ifndef _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP
2 #define _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP
3 /*------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
7 * Copyright (c) 2017 The Khronos Group Inc.
8 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
14 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 * \brief Protected content buffer validator helper
25 *//*--------------------------------------------------------------------*/
27 #include "tcuVector.hpp"
29 #include "vktTestCase.hpp"
30 #include "tcuVector.hpp"
31 #include "tcuTestLog.hpp"
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"
42 #include "vktProtectedMemUtils.hpp"
43 #include "vktProtectedMemContext.hpp"
47 namespace ProtectedMem
50 class ProtectedContext;
53 struct ValidationData {
54 const tcu::IVec4 positions[4];
59 struct ValidationDataStorage {
63 typedef ValidationData<tcu::UVec4> ValidationDataUVec4;
64 typedef ValidationData<tcu::IVec4> ValidationDataIVec4;
65 typedef ValidationData<tcu::Vec4> ValidationDataVec4;
78 void initBufferValidatorPrograms (vk::SourceCollections& programCollection, TestType testType, BufferType bufferType);
79 vk::VkDescriptorType getDescriptorType (BufferType bufferType);
85 BufferValidator (const ValidationData<T> data, vk::VkFormat format)
87 , m_refDataStorage (*reinterpret_cast<ValidationDataStorage<T>*>( &std::vector<char>(sizeof(ValidationDataStorage<T>), '\0').front()))
88 , m_bufferType (SAMPLER_BUFFER)
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)
101 ~BufferValidator () {}
102 void initPrograms (vk::SourceCollections& programCollection) const;
104 bool validateBuffer (ProtectedContext& ctx,
105 const vk::VkBuffer buffer) const;
107 deUint32 getReferenceDataSize () const;
108 const void * getReferenceDataSrc () const;
109 void printReferenceInfo (ProtectedContext& ctx) const;
111 const ValidationData<T> m_refData;
112 const ValidationDataStorage<T> m_refDataStorage;
114 BufferType m_bufferType;
115 vk::VkFormat m_format;
119 inline void BufferValidator<tcu::UVec4>::initPrograms (vk::SourceCollections& programCollection) const
121 initBufferValidatorPrograms(programCollection, TYPE_UINT, m_bufferType);
125 inline void BufferValidator<tcu::IVec4>::initPrograms (vk::SourceCollections& programCollection) const
127 initBufferValidatorPrograms(programCollection, TYPE_INT, m_bufferType);
131 inline void BufferValidator<tcu::Vec4>::initPrograms (vk::SourceCollections& programCollection) const
133 initBufferValidatorPrograms(programCollection, TYPE_FLOAT, m_bufferType);
137 deUint32 BufferValidator<T>::getReferenceDataSize () const
139 return m_bufferType == SAMPLER_BUFFER ? (deUint32)sizeof(m_refData) : (deUint32)sizeof(m_refDataStorage);
143 const void * BufferValidator<T>::getReferenceDataSrc () const
145 return m_bufferType == SAMPLER_BUFFER ? (void*)&m_refData : (void*)&m_refDataStorage;
149 void BufferValidator<T>::printReferenceInfo (ProtectedContext& ctx) const
151 if (m_bufferType == SAMPLER_BUFFER)
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)
168 ctx.getTestContext().getLog()
169 << tcu::TestLog::Message << "Reference values: \n"
170 << "1: " << m_refDataStorage.values << "\n"
171 << tcu::TestLog::EndMessage;
176 bool BufferValidator<T>::validateBuffer (ProtectedContext& ctx,
177 const vk::VkBuffer buffer) const
179 // Log out a few reference info
180 printReferenceInfo(ctx);
182 const deUint64 oneSec = 1000 * 1000 * 1000;
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();
189 vk::Move<vk::VkBufferView> bufferView;
191 const deUint32 refDataSize = getReferenceDataSize();
192 de::UniquePtr<vk::BufferWithMemory> refUniform (makeBuffer(ctx,
196 vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
197 vk::MemoryRequirement::HostVisible));
199 // Set the reference uniform data
201 deMemcpy(refUniform->getAllocation().getHostPtr(), getReferenceDataSrc(), refDataSize);
202 flushAlloc(vk, device, refUniform->getAllocation());
205 const deUint32 helperBufferSize = (deUint32)(2 * sizeof(deUint32));
206 de::MovePtr<vk::BufferWithMemory> helperBuffer (makeBuffer(ctx,
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));
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)
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));
229 // Update descriptor set information
231 vk::VkDescriptorBufferInfo descRefUniform = makeDescriptorBufferInfo(**refUniform, 0, refDataSize);
232 vk::VkDescriptorBufferInfo descBuffer = makeDescriptorBufferInfo(**helperBuffer, 0, helperBufferSize);
234 vk::DescriptorSetUpdateBuilder descriptorSetUpdateBuilder;
235 switch (m_bufferType)
239 const vk::VkBufferViewCreateInfo viewParams =
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
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());
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);
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)
270 vk::Unique<vk::VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
272 vk::Unique<vk::VkCommandPool> cmdPool (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
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);
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);
285 endCommandBuffer(vk, *resetCmdBuffer);
286 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *resetCmdBuffer, *fence, ~0ull));
289 // Create validation compute commands & submit
290 vk::VkResult queueSubmitResult;
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));
296 beginCommandBuffer(vk, *cmdBuffer);
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);
302 endCommandBuffer(vk, *cmdBuffer);
304 queueSubmitResult = queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, oneSec);
307 // \todo do we need to check the fence status?
308 if (queueSubmitResult == vk::VK_TIMEOUT)
311 // at this point the submit result should be VK_TRUE
312 VK_CHECK(queueSubmitResult);
320 #endif // _VKTPROTECTEDMEMBUFFERVALIDATOR_HPP