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