Home | History | Annotate | Download | only in protected_memory
      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:
     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 
     86 	virtual					~AttachmentLoadTestCase	(void) {}
     87 	virtual TestInstance*	createInstance	(Context&				ctx) const
     88 							{
     89 								return new AttachmentLoadTestInstance(ctx, m_clearValue, m_refData, m_validator);
     90 							}
     91 	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 
    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 
    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 
    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