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 render pass load tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemAttachmentLoadTests.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 "vktProtectedMemImageValidator.hpp"
41 
42 namespace vkt
43 {
44 namespace ProtectedMem
45 {
46 
47 namespace
48 {
49 
50 enum {
51 	RENDER_WIDTH	= 128,
52 	RENDER_HEIGHT	= 128,
53 };
54 
55 
56 class AttachmentLoadTestInstance : public ProtectedTestInstance
57 {
58 public:
59 								AttachmentLoadTestInstance	(Context&					ctx,
60 															 const vk::VkClearValue&	clearValue,
61 															 const ValidationData&		refData,
62 															 const ImageValidator&		validator);
63 	virtual tcu::TestStatus		iterate						(void);
64 
65 private:
66 	const vk::VkFormat			m_imageFormat;
67 	const vk::VkClearValue&		m_clearValue;
68 	const ValidationData&		m_refData;
69 	const ImageValidator&		m_validator;
70 };
71 
72 
73 class AttachmentLoadTestCase : public TestCase
74 {
75 public:
AttachmentLoadTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearValue clearValue,ValidationData data)76 							AttachmentLoadTestCase	(tcu::TestContext&		testCtx,
77 													 const std::string&		name,
78 													 vk::VkClearValue		clearValue,
79 													 ValidationData			data)
80 								: TestCase		(testCtx, name, "Clear on render pass initialization.")
81 								, m_clearValue	(clearValue)
82 								, m_refData		(data)
83 							{
84 							}
85 
~AttachmentLoadTestCase(void)86 	virtual					~AttachmentLoadTestCase	(void) {}
createInstance(Context & ctx) const87 	virtual TestInstance*	createInstance	(Context&				ctx) const
88 							{
89 								return new AttachmentLoadTestInstance(ctx, m_clearValue, m_refData, m_validator);
90 							}
initPrograms(vk::SourceCollections & programCollection) const91 	virtual void			initPrograms	(vk::SourceCollections&	programCollection) const
92 							{
93 								m_validator.initPrograms(programCollection);
94 							}
95 private:
96 	vk::VkClearValue		m_clearValue;
97 	ValidationData			m_refData;
98 	ImageValidator			m_validator;
99 };
100 
AttachmentLoadTestInstance(Context & ctx,const vk::VkClearValue & clearValue,const ValidationData & refData,const ImageValidator & validator)101 AttachmentLoadTestInstance::AttachmentLoadTestInstance	(Context&					ctx,
102 														 const vk::VkClearValue&	clearValue,
103 														 const ValidationData&		refData,
104 														 const ImageValidator&		validator)
105 	: ProtectedTestInstance	(ctx)
106 	, m_imageFormat	(vk::VK_FORMAT_R8G8B8A8_UNORM)
107 	, m_clearValue	(clearValue)
108 	, m_refData		(refData)
109 	, m_validator	(validator)
110 {
111 }
112 
iterate()113 tcu::TestStatus AttachmentLoadTestInstance::iterate()
114 {
115 	ProtectedContext&					ctx					(m_protectedContext);
116 	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
117 	const vk::VkDevice					device				= ctx.getDevice();
118 	const vk::VkQueue					queue				= ctx.getQueue();
119 	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();
120 
121 	// Create output image
122 	de::MovePtr<vk::ImageWithMemory>	colorImage			(createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
123 																			RENDER_WIDTH, RENDER_HEIGHT,
124 																			m_imageFormat,
125 																			vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|vk::VK_IMAGE_USAGE_SAMPLED_BIT));
126 	vk::Unique<vk::VkImageView>			colorImageView		(createImageView(ctx, **colorImage, m_imageFormat));
127 
128 	vk::Unique<vk::VkRenderPass>		renderPass			(createRenderPass(ctx, m_imageFormat));
129 	vk::Unique<vk::VkFramebuffer>		framebuffer			(createFramebuffer(ctx, RENDER_WIDTH, RENDER_HEIGHT, *renderPass, *colorImageView));
130 	vk::Unique<vk::VkPipelineLayout>	pipelineLayout		(createPipelineLayout(ctx, 0u, DE_NULL));
131 
132 	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
133 	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
134 
135 	// Begin cmd buffer
136 	beginCommandBuffer(vk, *cmdBuffer);
137 
138 	// Start image barrier
139 	{
140 		const vk::VkImageMemoryBarrier	startImgBarrier		=
141 		{
142 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
143 			DE_NULL,											// pNext
144 			0,													// srcAccessMask
145 			vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// dstAccessMask
146 			vk::VK_IMAGE_LAYOUT_UNDEFINED,						// oldLayout
147 			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// newLayout
148 			queueFamilyIndex,									// srcQueueFamilyIndex
149 			queueFamilyIndex,									// dstQueueFamilyIndex
150 			**colorImage,										// image
151 			{
152 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
153 				0u,												// baseMipLevel
154 				1u,												// mipLevels
155 				0u,												// baseArraySlice
156 				1u,												// subresourceRange
157 			}
158 		};
159 
160 		vk.cmdPipelineBarrier(*cmdBuffer,
161 								vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
162 								vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
163 								(vk::VkDependencyFlags)0,
164 								0, (const vk::VkMemoryBarrier*)DE_NULL,
165 								0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
166 								1, &startImgBarrier);
167 	}
168 
169 	// Image clear
170 	beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, vk::makeRect2D(0, 0, RENDER_WIDTH, RENDER_HEIGHT), m_clearValue);
171 	endRenderPass(vk, *cmdBuffer);
172 
173 	{
174 		// Image validator reads image in compute shader
175 		const vk::VkImageMemoryBarrier	endImgBarrier		=
176 		{
177 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
178 			DE_NULL,											// pNext
179 			vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// srcAccessMask
180 			vk::VK_ACCESS_SHADER_READ_BIT,						// dstAccessMask
181 			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// oldLayout
182 			vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// newLayout
183 			queueFamilyIndex,									// srcQueueFamilyIndex
184 			queueFamilyIndex,									// dstQueueFamilyIndex
185 			**colorImage,										// image
186 			{
187 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
188 				0u,												// baseMipLevel
189 				1u,												// mipLevels
190 				0u,												// baseArraySlice
191 				1u,												// subresourceRange
192 			}
193 		};
194 		vk.cmdPipelineBarrier(*cmdBuffer,
195 								vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
196 								vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
197 								(vk::VkDependencyFlags)0,
198 								0, (const vk::VkMemoryBarrier*)DE_NULL,
199 								0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
200 								1, &endImgBarrier);
201 	}
202 
203 	endCommandBuffer(vk, *cmdBuffer);
204 
205 	// Submit command buffer
206 	const vk::Unique<vk::VkFence>	fence		(vk::createFence(vk, device));
207 	VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
208 
209 	// Log out test data
210 	ctx.getTestContext().getLog()
211 		<< tcu::TestLog::Message << "Color clear value: " << tcu::Vec4(m_clearValue.color.float32) << tcu::TestLog::EndMessage
212 		<< tcu::TestLog::Message << "Depth clear value: " << m_clearValue.depthStencil.depth << tcu::TestLog::EndMessage
213 		<< tcu::TestLog::Message << "Stencil clear value: " << m_clearValue.depthStencil.stencil << tcu::TestLog::EndMessage;
214 
215 	// Validate resulting image
216 	if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
217 		return tcu::TestStatus::pass("Everything went OK");
218 	else
219 		return tcu::TestStatus::fail("Something went really wrong");
220 }
221 
222 } // anonymous
223 
createAttachmentLoadTests(tcu::TestContext & testCtx)224 tcu::TestCaseGroup*	createAttachmentLoadTests (tcu::TestContext& testCtx)
225 {
226 	struct {
227 		const vk::VkClearValue		clearValue;
228 		const ValidationData		data;
229 	} testData[] = {
230 		{	vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f),
231 			{
232 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
233 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),  tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
234 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
235 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
236 			}
237 		},
238 		{	vk::makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f),
239 			{
240 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
241 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),  tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
242 				{ tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),  tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
243 				  tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),  tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), }
244 			}
245 		},
246 		{	vk::makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f),
247 			{
248 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
249 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),  tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
250 				{ tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),  tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
251 				  tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),  tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), }
252 			}
253 		},
254 		{	vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f),
255 			{
256 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
257 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),  tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
258 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
259 				  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), }
260 			}
261 		},
262 		{	vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f),
263 			{
264 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
265 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),  tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
266 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
267 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
268 			}
269 		},
270 		{	vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 0.0f),
271 			{
272 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
273 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),  tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
274 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
275 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), }
276 			}
277 		},
278 		{	vk::makeClearValueColorF32(0.1f, 0.2f, 0.3f, 0.0f),
279 			{
280 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f),  tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
281 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f),  tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
282 				{ tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),  tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
283 				  tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),  tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), }
284 			}
285 		},
286 	};
287 
288 	de::MovePtr<tcu::TestCaseGroup>	loadStaticTests	(new tcu::TestCaseGroup(testCtx, "static", "Attachment Load Op Tests with static input"));
289 
290 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
291 	{
292 		const std::string name = "clear_" + de::toString(ndx + 1);
293 		loadStaticTests->addChild(new AttachmentLoadTestCase(testCtx, name.c_str(), testData[ndx].clearValue, testData[ndx].data));
294 	}
295 
296 	/* Add a few randomized tests */
297 	de::MovePtr<tcu::TestCaseGroup>	loadRandomTests		(new tcu::TestCaseGroup(testCtx, "random", "Attachment Load Op Tests with random input"));
298 	const int						testCount			= 10;
299 	de::Random						rnd					(testCtx.getCommandLine().getBaseSeed());
300 	for (int ndx = 0; ndx < testCount; ++ndx)
301 	{
302 		const std::string	name		= "clear_" + de::toString(ndx + 1);
303 		vk::VkClearValue	clearValue	= vk::makeClearValueColorF32(
304 											rnd.getFloat(0.0, 1.0f),
305 											rnd.getFloat(0.0, 1.0f),
306 											rnd.getFloat(0.0, 1.0f),
307 											rnd.getFloat(0.0, 1.0f));
308 
309 		tcu::Vec4			refValue	(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]);
310 		ValidationData		data = {
311 			{ tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)),
312 			  tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)),
313 			  tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)),
314 			  tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)) },
315 			{ refValue, refValue, refValue, refValue }
316 		};
317 
318 		loadRandomTests->addChild(new AttachmentLoadTestCase(testCtx, name.c_str(), clearValue, data));
319 	}
320 
321 	de::MovePtr<tcu::TestCaseGroup> loadTests (new tcu::TestCaseGroup(testCtx, "load_op", "Attachment Load Op Tests"));
322 	loadTests->addChild(loadStaticTests.release());
323 	loadTests->addChild(loadRandomTests.release());
324 	return loadTests.release();
325 }
326 
327 } // ProtectedMem
328 } // vkt
329