• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 attachment clear tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemAttachmentClearTests.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 	RENDER_WIDTH	= 128,
53 	RENDER_HEIGHT	= 128,
54 };
55 
56 class AttachmentClearTestInstance : public ProtectedTestInstance
57 {
58 public:
59 								AttachmentClearTestInstance	(Context&					ctx,
60 															 const vk::VkClearValue&	clearValue,
61 															 const ValidationData&		refData,
62 															 const ImageValidator&		validator,
63 															 const CmdBufferType		cmdBufferType);
64 	virtual tcu::TestStatus		iterate						(void);
65 
66 private:
67 	const vk::VkFormat			m_imageFormat;
68 	const vk::VkClearValue&		m_clearValue;
69 	const ValidationData&		m_refData;
70 	const ImageValidator&		m_validator;
71 	const CmdBufferType			m_cmdBufferType;
72 };
73 
74 
75 class AttachmentClearTestCase : public TestCase
76 {
77 public:
AttachmentClearTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearValue clearValue,ValidationData data,CmdBufferType cmdBufferType)78 							AttachmentClearTestCase		(tcu::TestContext&		testCtx,
79 														 const std::string&		name,
80 														 vk::VkClearValue		clearValue,
81 														 ValidationData			data,
82 														 CmdBufferType			cmdBufferType)
83 								: TestCase			(testCtx, name, "Clear attachment.")
84 								, m_clearValue		(clearValue)
85 								, m_refData			(data)
86 								, m_cmdBufferType	(cmdBufferType)
87 							{
88 							}
89 
~AttachmentClearTestCase(void)90 	virtual					~AttachmentClearTestCase	(void) {}
createInstance(Context & ctx) const91 	virtual TestInstance*	createInstance				(Context& ctx) const
92 							{
93 								return new AttachmentClearTestInstance(ctx, m_clearValue, m_refData, m_validator, m_cmdBufferType);
94 							}
initPrograms(vk::SourceCollections & programCollection) const95 	virtual void			initPrograms				(vk::SourceCollections&	programCollection) const
96 							{
97 								m_validator.initPrograms(programCollection);
98 							}
checkSupport(Context & context) const99 	virtual void			checkSupport				(Context& context) const
100 							{
101 								checkProtectedQueueSupport(context);
102 							}
103 private:
104 	vk::VkClearValue		m_clearValue;
105 	ValidationData			m_refData;
106 	ImageValidator			m_validator;
107 	CmdBufferType			m_cmdBufferType;
108 };
109 
AttachmentClearTestInstance(Context & ctx,const vk::VkClearValue & clearValue,const ValidationData & refData,const ImageValidator & validator,const CmdBufferType cmdBufferType)110 AttachmentClearTestInstance::AttachmentClearTestInstance	(Context&					ctx,
111 															 const vk::VkClearValue&	clearValue,
112 															 const ValidationData&		refData,
113 															 const ImageValidator&		validator,
114 															 const CmdBufferType		cmdBufferType)
115 	: ProtectedTestInstance	(ctx)
116 	, m_imageFormat			(vk::VK_FORMAT_R8G8B8A8_UNORM)
117 	, m_clearValue			(clearValue)
118 	, m_refData				(refData)
119 	, m_validator			(validator)
120 	, m_cmdBufferType		(cmdBufferType)
121 {
122 }
123 
iterate()124 tcu::TestStatus AttachmentClearTestInstance::iterate()
125 {
126 	ProtectedContext&					ctx					(m_protectedContext);
127 	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
128 	const vk::VkDevice					device				= ctx.getDevice();
129 	const vk::VkQueue					queue				= ctx.getQueue();
130 	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();
131 
132 	// Create output image
133 	de::MovePtr<vk::ImageWithMemory>	colorImage			(createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
134 																			RENDER_WIDTH, RENDER_HEIGHT,
135 																			m_imageFormat,
136 																			vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|vk::VK_IMAGE_USAGE_SAMPLED_BIT));
137 	vk::Unique<vk::VkImageView>			colorImageView		(createImageView(ctx, **colorImage, m_imageFormat));
138 
139 	vk::Unique<vk::VkRenderPass>		renderPass			(createRenderPass(ctx, m_imageFormat));
140 	vk::Unique<vk::VkFramebuffer>		framebuffer			(createFramebuffer(ctx, RENDER_WIDTH, RENDER_HEIGHT, *renderPass, *colorImageView));
141 	vk::Unique<vk::VkPipelineLayout>	pipelineLayout		(createPipelineLayout(ctx, 0u, DE_NULL));
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 	// Start image barrier
152 	{
153 		const vk::VkImageMemoryBarrier	startImgBarrier		=
154 		{
155 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
156 			DE_NULL,											// pNext
157 			0,													// srcAccessMask
158 			vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// dstAccessMask
159 			vk::VK_IMAGE_LAYOUT_UNDEFINED,						// oldLayout
160 			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// newLayout
161 			queueFamilyIndex,									// srcQueueFamilyIndex
162 			queueFamilyIndex,									// dstQueueFamilyIndex
163 			**colorImage,										// image
164 			{
165 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
166 				0u,												// baseMipLevel
167 				1u,												// mipLevels
168 				0u,												// baseArraySlice
169 				1u,												// subresourceRange
170 			}
171 		};
172 
173 		vk.cmdPipelineBarrier(*cmdBuffer,
174 							  vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
175 							  vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
176 							  (vk::VkDependencyFlags)0,
177 							  0, (const vk::VkMemoryBarrier*)DE_NULL,
178 							  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
179 							  1, &startImgBarrier);
180 	}
181 
182 	// Image clear to different from input color
183 
184 	const tcu::Vec4						clearValue			(m_clearValue.color.float32[0] < 0.5f ? 1.0f : 0.0f,
185 															 m_clearValue.color.float32[1] < 0.5f ? 1.0f : 0.0f,
186 															 m_clearValue.color.float32[2] < 0.5f ? 1.0f : 0.0f,
187 															 m_clearValue.color.float32[3] < 0.5f ? 1.0f : 0.0f);
188 
189 	const vk::VkSubpassContents			subpassContents		= m_cmdBufferType == CMD_BUFFER_SECONDARY
190 															  ? vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS
191 															  : vk::VK_SUBPASS_CONTENTS_INLINE;
192 	beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, vk::makeRect2D(RENDER_WIDTH, RENDER_HEIGHT), clearValue, subpassContents);
193 
194 	if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
195 	{
196 		// Begin secondary command buffer
197 		const vk::VkCommandBufferInheritanceInfo	bufferInheritanceInfo	=
198 		{
199 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,		// sType
200 			DE_NULL,													// pNext
201 			*renderPass,												// renderPass
202 			0u,															// subpass
203 			*framebuffer,												// framebuffer
204 			VK_FALSE,													// occlusionQueryEnable
205 			(vk::VkQueryControlFlags)0u,								// queryFlags
206 			(vk::VkQueryPipelineStatisticFlags)0u,						// pipelineStatistics
207 		};
208 		beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, bufferInheritanceInfo);
209 	}
210 
211 	{
212 		const vk::VkClearAttachment		pAttachments		=
213 		{
214 			vk::VK_IMAGE_ASPECT_COLOR_BIT,						//VkImageAspectFlags	aspectMask
215 			0u,													//uint32_t				colorAttachment
216 			m_clearValue										// VkClearValue			clearValue;
217 		};
218 		const vk::VkRect2D				rect2D				= vk::makeRect2D(RENDER_WIDTH, RENDER_HEIGHT);
219 		const vk::VkClearRect			clearRect			=
220 		{
221 			rect2D,												// VkRect2D				rect;
222 			0u,													// deUint32				baseArrayLayer;
223 			1u													// deUint32				layerCount;
224 		};
225 		vk.cmdClearAttachments(targetCmdBuffer, 1u, &pAttachments, 1u, &clearRect);
226 	}
227 
228 	if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
229 	{
230 		endCommandBuffer(vk, *secondaryCmdBuffer);
231 		vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
232 	}
233 
234 	endRenderPass(vk, *cmdBuffer);
235 
236 	{
237 		// Image validator reads image in compute shader
238 		const vk::VkImageMemoryBarrier	endImgBarrier		=
239 		{
240 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
241 			DE_NULL,											// pNext
242 			vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// srcAccessMask
243 			vk::VK_ACCESS_SHADER_READ_BIT,						// dstAccessMask
244 			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// oldLayout
245 			vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// newLayout
246 			queueFamilyIndex,									// srcQueueFamilyIndex
247 			queueFamilyIndex,									// dstQueueFamilyIndex
248 			**colorImage,										// image
249 			{
250 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
251 				0u,												// baseMipLevel
252 				1u,												// mipLevels
253 				0u,												// baseArraySlice
254 				1u,												// subresourceRange
255 			}
256 		};
257 		vk.cmdPipelineBarrier(*cmdBuffer,
258 							  vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
259 							  vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
260 							  (vk::VkDependencyFlags)0,
261 							  0, (const vk::VkMemoryBarrier*)DE_NULL,
262 							  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
263 							  1, &endImgBarrier);
264 	}
265 
266 	endCommandBuffer(vk, *cmdBuffer);
267 
268 	// Submit command buffer
269 	const vk::Unique<vk::VkFence>	fence		(vk::createFence(vk, device));
270 	VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
271 
272 	// Log out test data
273 	ctx.getTestContext().getLog()
274 		<< tcu::TestLog::Message << "Color clear value: " << tcu::Vec4(m_clearValue.color.float32) << tcu::TestLog::EndMessage
275 		<< tcu::TestLog::Message << "Depth clear value: " << m_clearValue.depthStencil.depth << tcu::TestLog::EndMessage
276 		<< tcu::TestLog::Message << "Stencil clear value: " << m_clearValue.depthStencil.stencil << tcu::TestLog::EndMessage;
277 
278 	// Validate resulting image
279 	if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
280 		return tcu::TestStatus::pass("Everything went OK");
281 	else
282 		return tcu::TestStatus::fail("Something went really wrong");
283 }
284 
createAttachmentClearTests(tcu::TestContext & testCtx,CmdBufferType cmdBufferType)285 tcu::TestCaseGroup*	createAttachmentClearTests (tcu::TestContext& testCtx, CmdBufferType cmdBufferType)
286 {
287 	struct {
288 		const vk::VkClearValue		clearValue;
289 		const ValidationData		data;
290 	} testData[] = {
291 		{	vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f),
292 			{
293 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
294 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
295 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
296 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
297 			}
298 		},
299 		{	vk::makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f),
300 			{
301 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
302 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
303 				{ tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
304 				  tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), }
305 			}
306 		},
307 		{	vk::makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
308 			{
309 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
310 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
311 				{ tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
312 				  tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), }
313 			}
314 		},
315 		{	vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f),
316 			{
317 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
318 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
319 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
320 				  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), }
321 			}
322 		},
323 		{	vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f),
324 			{
325 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
326 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
327 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
328 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
329 			}
330 		},
331 		{	vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 0.0f),
332 			{
333 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
334 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
335 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
336 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), }
337 			}
338 		},
339 		{	vk::makeClearValueColorF32(0.1f, 0.2f, 0.3f, 0.0f),
340 			{
341 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
342 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
343 				{ tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
344 				  tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), }
345 			}
346 		},
347 	};
348 
349 	de::MovePtr<tcu::TestCaseGroup>	clearStaticTests	(new tcu::TestCaseGroup(testCtx, "static", "Attachment Clear Op Tests with static input"));
350 
351 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
352 	{
353 		const std::string name = "clear_" +  de::toString(ndx + 1);
354 		clearStaticTests->addChild(new AttachmentClearTestCase(testCtx, name.c_str(), testData[ndx].clearValue, testData[ndx].data, cmdBufferType));
355 	}
356 
357 	/* Add a few randomized tests */
358 	de::MovePtr<tcu::TestCaseGroup>	clearRandomTests	(new tcu::TestCaseGroup(testCtx, "random", "Attachment Clear Op Tests with random input"));
359 	const int						testCount			= 10;
360 	de::Random						rnd					(testCtx.getCommandLine().getBaseSeed());
361 	for (int ndx = 0; ndx < testCount; ++ndx)
362 	{
363 		const std::string	name		= "clear_" +  de::toString(ndx + 1);
364 		vk::VkClearValue	clearValue	= vk::makeClearValueColorVec4(tcu::randomVec4(rnd));
365 		const tcu::Vec4		refValue	(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]);
366 		const tcu::Vec4		vec0		= tcu::randomVec4(rnd);
367 		const tcu::Vec4		vec1		= tcu::randomVec4(rnd);
368 		const tcu::Vec4		vec2		= tcu::randomVec4(rnd);
369 		const tcu::Vec4		vec3		= tcu::randomVec4(rnd);
370 
371 		ValidationData		data		=
372 		{
373 			{ vec0, vec1, vec2, vec3 },
374 			{ refValue, refValue, refValue, refValue }
375 		};
376 
377 		clearRandomTests->addChild(new AttachmentClearTestCase(testCtx, name.c_str(), clearValue, data, cmdBufferType));
378 	}
379 
380 	std::string groupName = getCmdBufferTypeStr(cmdBufferType);
381 	std::string groupDesc = "Attachment Clear Op Tests with " + groupName + " command buffer";
382 	de::MovePtr<tcu::TestCaseGroup> clearTests (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
383 	clearTests->addChild(clearStaticTests.release());
384 	clearTests->addChild(clearRandomTests.release());
385 	return clearTests.release();
386 }
387 
388 } // anonymous
389 
createAttachmentClearTests(tcu::TestContext & testCtx)390 tcu::TestCaseGroup*	createAttachmentClearTests (tcu::TestContext& testCtx)
391 {
392 	de::MovePtr<tcu::TestCaseGroup> clearTests (new tcu::TestCaseGroup(testCtx, "clear_op", "Attachment Clear Op Tests"));
393 
394 	clearTests->addChild(createAttachmentClearTests(testCtx, CMD_BUFFER_PRIMARY));
395 	clearTests->addChild(createAttachmentClearTests(testCtx, CMD_BUFFER_SECONDARY));
396 
397 	return clearTests.release();
398 }
399 
400 } // ProtectedMem
401 } // vkt
402