Home | History | Annotate | Download | only in conditional_rendering
      1 /*------------------------------------------------------------------------
      2  * Vulkan Conformance Tests
      3  * ------------------------
      4  *
      5  * Copyright (c) 2018 The Khronos Group Inc.
      6  * Copyright (c) 2018 Danylo Piliaiev <danylo.piliaiev (at) gmail.com>
      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 Test for conditional rendering of vkCmdClearAttachments
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktConditionalClearAttachmentTests.hpp"
     26 #include "vktConditionalRenderingTestUtil.hpp"
     27 
     28 #include "vktTestCaseUtil.hpp"
     29 #include "vktDrawTestCaseUtil.hpp"
     30 
     31 #include "vktDrawBaseClass.hpp"
     32 
     33 #include "tcuTestLog.hpp"
     34 #include "tcuResource.hpp"
     35 #include "tcuImageCompare.hpp"
     36 #include "tcuTextureUtil.hpp"
     37 #include "tcuRGBA.hpp"
     38 
     39 #include "vkDefs.hpp"
     40 #include "vkCmdUtil.hpp"
     41 #include "vkTypeUtil.hpp"
     42 
     43 namespace vkt
     44 {
     45 namespace conditional
     46 {
     47 namespace
     48 {
     49 
     50 struct ConditionalTestSpec : public Draw::TestSpecBase
     51 {
     52 	ConditionalData	conditionalData;
     53 };
     54 
     55 class ConditionalClearAttachmentTest : public Draw::DrawTestsBaseClass
     56 {
     57 public:
     58 	typedef		ConditionalTestSpec	TestSpec;
     59 
     60 								ConditionalClearAttachmentTest	(Context &context, ConditionalTestSpec testSpec);
     61 
     62 	virtual		tcu::TestStatus iterate							(void);
     63 protected:
     64 	const ConditionalData			m_conditionalData;
     65 	de::SharedPtr<Draw::Buffer>		m_conditionalBuffer;
     66 
     67 	vk::Move<vk::VkCommandBuffer>	m_secondaryCmdBuffer;
     68 };
     69 
     70 ConditionalClearAttachmentTest::ConditionalClearAttachmentTest (Context &context, ConditionalTestSpec testSpec)
     71 	: Draw::DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
     72 	, m_conditionalData(testSpec.conditionalData)
     73 {
     74 	checkConditionalRenderingCapabilities(context, m_conditionalData);
     75 
     76 	m_data.push_back(Draw::VertexElementData(tcu::Vec4(0.0f), tcu::Vec4(0.0f), 0));
     77 
     78 	initialize();
     79 
     80 	m_secondaryCmdBuffer = vk::allocateCommandBuffer(m_vk, m_context.getDevice(), *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY);
     81 };
     82 
     83 tcu::TestStatus ConditionalClearAttachmentTest::iterate (void)
     84 {
     85 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
     86 	const vk::VkQueue	queue	= m_context.getUniversalQueue();
     87 	const vk::VkDevice	device	= m_context.getDevice();
     88 
     89 	const tcu::Vec4 clearColor	= tcu::RGBA::black().toVec();
     90 	const tcu::Vec4 drawColor	= tcu::RGBA::blue().toVec();
     91 
     92 	beginRenderPass(m_conditionalData.useSecondaryBuffer ? vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : vk::VK_SUBPASS_CONTENTS_INLINE);
     93 
     94 	vk::VkCommandBuffer targetCmdBuffer = *m_cmdBuffer;
     95 
     96 	if (m_conditionalData.useSecondaryBuffer)
     97 	{
     98 		const vk::VkCommandBufferInheritanceConditionalRenderingInfoEXT conditionalRenderingInheritanceInfo =
     99 		{
    100 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT,
    101 			DE_NULL,
    102 			VK_TRUE														// conditionalRenderingEnable
    103 		};
    104 
    105 		const vk::VkCommandBufferInheritanceInfo inheritanceInfo =
    106 		{
    107 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
    108 			&conditionalRenderingInheritanceInfo,
    109 			*m_renderPass,										        // renderPass
    110 			0u,															// subpass
    111 			*m_framebuffer,										        // framebuffer
    112 			VK_FALSE,													// occlusionQueryEnable
    113 			(vk::VkQueryControlFlags)0u,								// queryFlags
    114 			(vk::VkQueryPipelineStatisticFlags)0u,						// pipelineStatistics
    115 		};
    116 
    117 		const vk::VkCommandBufferBeginInfo commandBufferBeginInfo =
    118 		{
    119 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
    120 			DE_NULL,
    121 			vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
    122 			&inheritanceInfo
    123 		};
    124 
    125 		m_vk.beginCommandBuffer(*m_secondaryCmdBuffer, &commandBufferBeginInfo);
    126 
    127 		targetCmdBuffer = *m_secondaryCmdBuffer;
    128 	}
    129 
    130 	m_vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
    131 
    132 	const vk::VkClearAttachment	clearAttachment	=
    133 	{
    134 		vk::VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask;
    135 		0u,										// deUint32				colorAttachment;
    136 		vk::makeClearValueColor(drawColor)		// VkClearValue			clearValue;
    137 	};
    138 
    139 	const vk::VkClearRect rect =
    140 	{
    141 		vk::makeRect2D(WIDTH, HEIGHT),	// VkRect2D    rect;
    142 		0u,								// uint32_t    baseArrayLayer;
    143 		1u,								// uint32_t    layerCount;
    144 	};
    145 
    146 	if (m_conditionalData.useSecondaryBuffer)
    147 	{
    148 		m_vk.cmdClearAttachments(*m_secondaryCmdBuffer, 1, &clearAttachment, 1, &rect);
    149 	}
    150 
    151 	if (m_conditionalData.conditionEnabled)
    152 	{
    153 		m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
    154 		beginConditionalRendering(m_vk, *m_cmdBuffer, *m_conditionalBuffer, m_conditionalData);
    155 	}
    156 
    157 	if (!m_conditionalData.useSecondaryBuffer)
    158 	{
    159 		m_vk.cmdClearAttachments(*m_cmdBuffer, 1, &clearAttachment, 1, &rect);
    160 	}
    161 
    162 	if (m_conditionalData.useSecondaryBuffer)
    163 	{
    164 		m_vk.endCommandBuffer(*m_secondaryCmdBuffer);
    165 
    166 		m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get());
    167 	}
    168 
    169 	if (m_conditionalData.conditionEnabled)
    170 	{
    171 		m_vk.cmdEndConditionalRenderingEXT(*m_cmdBuffer);
    172 	}
    173 
    174 	endRenderPass(m_vk, *m_cmdBuffer);
    175 	endCommandBuffer(m_vk, *m_cmdBuffer);
    176 
    177 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
    178 
    179 	// Validation
    180 	tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT));
    181 								  referenceFrame.allocLevel(0);
    182 
    183 	const deInt32 frameWidth	= referenceFrame.getWidth();
    184 	const deInt32 frameHeight	= referenceFrame.getHeight();
    185 
    186 	tcu::clear(referenceFrame.getLevel(0), clearColor);
    187 
    188 	const tcu::Vec4 referenceColor = m_conditionalData.expectCommandExecution ?
    189 										drawColor : clearColor;
    190 
    191 	for (int y = 0; y < frameHeight; y++)
    192 	{
    193 		for (int x = 0; x < frameWidth; x++)
    194 		{
    195 			referenceFrame.getLevel(0).setPixel(referenceColor, x, y);
    196 		}
    197 	}
    198 
    199 	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
    200 	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
    201 		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
    202 
    203 	qpTestResult res = QP_TEST_RESULT_PASS;
    204 
    205 	if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
    206 		referenceFrame.getLevel(0), renderedFrame, 0.05f,
    207 		tcu::COMPARE_LOG_RESULT))
    208 	{
    209 		res = QP_TEST_RESULT_FAIL;
    210 	}
    211 
    212 	return tcu::TestStatus(res, qpGetTestResultName(res));
    213 };
    214 
    215 }	// anonymous
    216 
    217 ConditionalClearAttachmentTests::ConditionalClearAttachmentTests (tcu::TestContext &testCtx)
    218 	: TestCaseGroup	(testCtx, "clear_attachments", "vkCmdClearAttachments with conditional rendering")
    219 {
    220 	/* Left blank on purpose */
    221 }
    222 
    223 ConditionalClearAttachmentTests::~ConditionalClearAttachmentTests (void) {}
    224 
    225 void ConditionalClearAttachmentTests::init (void)
    226 {
    227 	for (int conditionNdx = 0; conditionNdx < DE_LENGTH_OF_ARRAY(conditional::s_testsData); conditionNdx++)
    228 	{
    229 		const ConditionalData& conditionData = conditional::s_testsData[conditionNdx];
    230 
    231 		tcu::TestCaseGroup* conditionalDrawRootGroup = new tcu::TestCaseGroup(m_testCtx, de::toString(conditionData).c_str(), "");
    232 
    233 		ConditionalTestSpec testSpec;
    234 		testSpec.conditionalData = conditionData;
    235 		testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
    236 		testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
    237 
    238 		conditionalDrawRootGroup->addChild(new Draw::InstanceFactory<ConditionalClearAttachmentTest>(m_testCtx, "clear_attachments", "", testSpec));
    239 
    240 		addChild(conditionalDrawRootGroup);
    241 	}
    242 }
    243 
    244 }	// conditional
    245 }	// vkt
    246