• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  * Copyright (c) 2018 Danylo Piliaiev <danylo.piliaiev@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 
ConditionalClearAttachmentTest(Context & context,ConditionalTestSpec testSpec)70 ConditionalClearAttachmentTest::ConditionalClearAttachmentTest (Context &context, ConditionalTestSpec testSpec)
71 	: Draw::DrawTestsBaseClass(context,
72 							   testSpec.shaders[glu::SHADERTYPE_VERTEX],
73 							   testSpec.shaders[glu::SHADERTYPE_FRAGMENT],
74 							   Draw::SharedGroupParams(new Draw::GroupParams{ false, false, false }),
75 							   vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
76 	, m_conditionalData(testSpec.conditionalData)
77 {
78 	checkConditionalRenderingCapabilities(context, m_conditionalData);
79 
80 	m_data.push_back(Draw::VertexElementData(tcu::Vec4(0.0f), tcu::Vec4(0.0f), 0));
81 
82 	initialize();
83 
84 	m_secondaryCmdBuffer = vk::allocateCommandBuffer(m_vk, m_context.getDevice(), *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY);
85 }
86 
iterate(void)87 tcu::TestStatus ConditionalClearAttachmentTest::iterate (void)
88 {
89 	tcu::TestLog&		log		= m_context.getTestContext().getLog();
90 	const vk::VkQueue	queue	= m_context.getUniversalQueue();
91 	const vk::VkDevice	device	= m_context.getDevice();
92 
93 	const tcu::Vec4 clearColor	= tcu::RGBA::black().toVec();
94 	const tcu::Vec4 drawColor	= tcu::RGBA::blue().toVec();
95 
96 	beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
97 	preRenderBarriers();
98 	const bool useSecondaryCmdBuffer = m_conditionalData.conditionInherited || m_conditionalData.conditionInSecondaryCommandBuffer;
99 	beginLegacyRender(*m_cmdBuffer, useSecondaryCmdBuffer ? vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : vk::VK_SUBPASS_CONTENTS_INLINE);
100 
101 	vk::VkCommandBuffer targetCmdBuffer = *m_cmdBuffer;
102 
103 	if (useSecondaryCmdBuffer)
104 	{
105 		const vk::VkCommandBufferInheritanceConditionalRenderingInfoEXT conditionalRenderingInheritanceInfo =
106 		{
107 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT,
108 			DE_NULL,
109 			m_conditionalData.conditionInherited ? VK_TRUE : VK_FALSE	// conditionalRenderingEnable
110 		};
111 
112 		const vk::VkCommandBufferInheritanceInfo inheritanceInfo =
113 		{
114 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
115 			&conditionalRenderingInheritanceInfo,
116 			*m_renderPass,										        // renderPass
117 			0u,															// subpass
118 			*m_framebuffer,										        // framebuffer
119 			VK_FALSE,													// occlusionQueryEnable
120 			(vk::VkQueryControlFlags)0u,								// queryFlags
121 			(vk::VkQueryPipelineStatisticFlags)0u,						// pipelineStatistics
122 		};
123 
124 		const vk::VkCommandBufferBeginInfo commandBufferBeginInfo =
125 		{
126 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
127 			DE_NULL,
128 			vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
129 			&inheritanceInfo
130 		};
131 
132 		VK_CHECK(m_vk.beginCommandBuffer(*m_secondaryCmdBuffer, &commandBufferBeginInfo));
133 
134 		targetCmdBuffer = *m_secondaryCmdBuffer;
135 	}
136 
137 	m_vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
138 
139 	const vk::VkClearAttachment	clearAttachment	=
140 	{
141 		vk::VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask;
142 		0u,										// deUint32				colorAttachment;
143 		vk::makeClearValueColor(drawColor)		// VkClearValue			clearValue;
144 	};
145 
146 	const vk::VkClearRect rect =
147 	{
148 		vk::makeRect2D(WIDTH, HEIGHT),	// VkRect2D    rect;
149 		0u,								// uint32_t    baseArrayLayer;
150 		1u,								// uint32_t    layerCount;
151 	};
152 
153 	m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
154 
155 	if (m_conditionalData.conditionInSecondaryCommandBuffer)
156 	{
157 		beginConditionalRendering(m_vk, *m_secondaryCmdBuffer, *m_conditionalBuffer, m_conditionalData);
158 		m_vk.cmdClearAttachments(*m_secondaryCmdBuffer, 1, &clearAttachment, 1, &rect);
159 		m_vk.cmdEndConditionalRenderingEXT(*m_secondaryCmdBuffer);
160 		m_vk.endCommandBuffer(*m_secondaryCmdBuffer);
161 	}
162 	else if (m_conditionalData.conditionInherited)
163 	{
164 		m_vk.cmdClearAttachments(*m_secondaryCmdBuffer, 1, &clearAttachment, 1, &rect);
165 		m_vk.endCommandBuffer(*m_secondaryCmdBuffer);
166 	}
167 
168 	if (m_conditionalData.conditionInPrimaryCommandBuffer)
169 	{
170 		beginConditionalRendering(m_vk, *m_cmdBuffer, *m_conditionalBuffer, m_conditionalData);
171 
172 		if (m_conditionalData.conditionInherited)
173 		{
174 			m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get());
175 		}
176 		else
177 		{
178 			m_vk.cmdClearAttachments(*m_cmdBuffer, 1, &clearAttachment, 1, &rect);
179 		}
180 
181 		m_vk.cmdEndConditionalRenderingEXT(*m_cmdBuffer);
182 	}
183 	else if (useSecondaryCmdBuffer)
184 	{
185 		m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get());
186 	}
187 
188 	endLegacyRender(*m_cmdBuffer);
189 	endCommandBuffer(m_vk, *m_cmdBuffer);
190 
191 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
192 
193 	// Validation
194 	tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
195 								  referenceFrame.allocLevel(0);
196 
197 	const deInt32 frameWidth	= referenceFrame.getWidth();
198 	const deInt32 frameHeight	= referenceFrame.getHeight();
199 
200 	tcu::clear(referenceFrame.getLevel(0), clearColor);
201 
202 	const tcu::Vec4 referenceColor = m_conditionalData.expectCommandExecution ?
203 										drawColor : clearColor;
204 
205 	for (int y = 0; y < frameHeight; y++)
206 	{
207 		for (int x = 0; x < frameWidth; x++)
208 		{
209 			referenceFrame.getLevel(0).setPixel(referenceColor, x, y);
210 		}
211 	}
212 
213 	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
214 	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
215 		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
216 
217 	qpTestResult res = QP_TEST_RESULT_PASS;
218 
219 	if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
220 		referenceFrame.getLevel(0), renderedFrame, 0.05f,
221 		tcu::COMPARE_LOG_RESULT))
222 	{
223 		res = QP_TEST_RESULT_FAIL;
224 	}
225 
226 	return tcu::TestStatus(res, qpGetTestResultName(res));
227 }
228 
229 }	// anonymous
230 
ConditionalClearAttachmentTests(tcu::TestContext & testCtx)231 ConditionalClearAttachmentTests::ConditionalClearAttachmentTests (tcu::TestContext &testCtx)
232 	: TestCaseGroup	(testCtx, "clear_attachments", "vkCmdClearAttachments with conditional rendering")
233 {
234 	/* Left blank on purpose */
235 }
236 
~ConditionalClearAttachmentTests(void)237 ConditionalClearAttachmentTests::~ConditionalClearAttachmentTests (void) {}
238 
init(void)239 void ConditionalClearAttachmentTests::init (void)
240 {
241 	for (int conditionNdx = 0; conditionNdx < DE_LENGTH_OF_ARRAY(conditional::s_testsData); conditionNdx++)
242 	{
243 		const ConditionalData& conditionData = conditional::s_testsData[conditionNdx];
244 
245 		if (conditionData.clearInRenderPass)
246 			continue;
247 
248 		tcu::TestCaseGroup* conditionalDrawRootGroup = new tcu::TestCaseGroup(m_testCtx, de::toString(conditionData).c_str(), "");
249 
250 		ConditionalTestSpec testSpec;
251 		testSpec.conditionalData = conditionData;
252 		testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
253 		testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
254 
255 		conditionalDrawRootGroup->addChild(new Draw::InstanceFactory<ConditionalClearAttachmentTest>(m_testCtx, "clear_attachments", "", testSpec));
256 
257 		addChild(conditionalDrawRootGroup);
258 	}
259 }
260 
261 }	// conditional
262 }	// vkt
263