• 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, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], false, 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 
iterate(void)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 	const bool useSecondaryCmdBuffer = m_conditionalData.conditionInherited || m_conditionalData.conditionInSecondaryCommandBuffer;
93 	beginRender(useSecondaryCmdBuffer ? vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : vk::VK_SUBPASS_CONTENTS_INLINE);
94 
95 	vk::VkCommandBuffer targetCmdBuffer = *m_cmdBuffer;
96 
97 	if (useSecondaryCmdBuffer)
98 	{
99 		const vk::VkCommandBufferInheritanceConditionalRenderingInfoEXT conditionalRenderingInheritanceInfo =
100 		{
101 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT,
102 			DE_NULL,
103 			m_conditionalData.conditionInherited ? VK_TRUE : VK_FALSE	// conditionalRenderingEnable
104 		};
105 
106 		const vk::VkCommandBufferInheritanceInfo inheritanceInfo =
107 		{
108 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
109 			&conditionalRenderingInheritanceInfo,
110 			*m_renderPass,										        // renderPass
111 			0u,															// subpass
112 			*m_framebuffer,										        // framebuffer
113 			VK_FALSE,													// occlusionQueryEnable
114 			(vk::VkQueryControlFlags)0u,								// queryFlags
115 			(vk::VkQueryPipelineStatisticFlags)0u,						// pipelineStatistics
116 		};
117 
118 		const vk::VkCommandBufferBeginInfo commandBufferBeginInfo =
119 		{
120 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
121 			DE_NULL,
122 			vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT,
123 			&inheritanceInfo
124 		};
125 
126 		m_vk.beginCommandBuffer(*m_secondaryCmdBuffer, &commandBufferBeginInfo);
127 
128 		targetCmdBuffer = *m_secondaryCmdBuffer;
129 	}
130 
131 	m_vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
132 
133 	const vk::VkClearAttachment	clearAttachment	=
134 	{
135 		vk::VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask;
136 		0u,										// deUint32				colorAttachment;
137 		vk::makeClearValueColor(drawColor)		// VkClearValue			clearValue;
138 	};
139 
140 	const vk::VkClearRect rect =
141 	{
142 		vk::makeRect2D(WIDTH, HEIGHT),	// VkRect2D    rect;
143 		0u,								// uint32_t    baseArrayLayer;
144 		1u,								// uint32_t    layerCount;
145 	};
146 
147 	m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData);
148 
149 	if (m_conditionalData.conditionInSecondaryCommandBuffer)
150 	{
151 		beginConditionalRendering(m_vk, *m_secondaryCmdBuffer, *m_conditionalBuffer, m_conditionalData);
152 		m_vk.cmdClearAttachments(*m_secondaryCmdBuffer, 1, &clearAttachment, 1, &rect);
153 		m_vk.cmdEndConditionalRenderingEXT(*m_secondaryCmdBuffer);
154 		m_vk.endCommandBuffer(*m_secondaryCmdBuffer);
155 	}
156 	else if (m_conditionalData.conditionInherited)
157 	{
158 		m_vk.cmdClearAttachments(*m_secondaryCmdBuffer, 1, &clearAttachment, 1, &rect);
159 		m_vk.endCommandBuffer(*m_secondaryCmdBuffer);
160 	}
161 
162 	if (m_conditionalData.conditionInPrimaryCommandBuffer)
163 	{
164 		beginConditionalRendering(m_vk, *m_cmdBuffer, *m_conditionalBuffer, m_conditionalData);
165 
166 		if (m_conditionalData.conditionInherited)
167 		{
168 			m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get());
169 		}
170 		else
171 		{
172 			m_vk.cmdClearAttachments(*m_cmdBuffer, 1, &clearAttachment, 1, &rect);
173 		}
174 
175 		m_vk.cmdEndConditionalRenderingEXT(*m_cmdBuffer);
176 	}
177 	else if (useSecondaryCmdBuffer)
178 	{
179 		m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get());
180 	}
181 
182 	endRender();
183 	endCommandBuffer(m_vk, *m_cmdBuffer);
184 
185 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
186 
187 	// Validation
188 	tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5f + static_cast<float>(WIDTH)), (int)(0.5f + static_cast<float>(HEIGHT)));
189 								  referenceFrame.allocLevel(0);
190 
191 	const deInt32 frameWidth	= referenceFrame.getWidth();
192 	const deInt32 frameHeight	= referenceFrame.getHeight();
193 
194 	tcu::clear(referenceFrame.getLevel(0), clearColor);
195 
196 	const tcu::Vec4 referenceColor = m_conditionalData.expectCommandExecution ?
197 										drawColor : clearColor;
198 
199 	for (int y = 0; y < frameHeight; y++)
200 	{
201 		for (int x = 0; x < frameWidth; x++)
202 		{
203 			referenceFrame.getLevel(0).setPixel(referenceColor, x, y);
204 		}
205 	}
206 
207 	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
208 	const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
209 		vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
210 
211 	qpTestResult res = QP_TEST_RESULT_PASS;
212 
213 	if (!tcu::fuzzyCompare(log, "Result", "Image comparison result",
214 		referenceFrame.getLevel(0), renderedFrame, 0.05f,
215 		tcu::COMPARE_LOG_RESULT))
216 	{
217 		res = QP_TEST_RESULT_FAIL;
218 	}
219 
220 	return tcu::TestStatus(res, qpGetTestResultName(res));
221 }
222 
223 }	// anonymous
224 
ConditionalClearAttachmentTests(tcu::TestContext & testCtx)225 ConditionalClearAttachmentTests::ConditionalClearAttachmentTests (tcu::TestContext &testCtx)
226 	: TestCaseGroup	(testCtx, "clear_attachments", "vkCmdClearAttachments with conditional rendering")
227 {
228 	/* Left blank on purpose */
229 }
230 
~ConditionalClearAttachmentTests(void)231 ConditionalClearAttachmentTests::~ConditionalClearAttachmentTests (void) {}
232 
init(void)233 void ConditionalClearAttachmentTests::init (void)
234 {
235 	for (int conditionNdx = 0; conditionNdx < DE_LENGTH_OF_ARRAY(conditional::s_testsData); conditionNdx++)
236 	{
237 		const ConditionalData& conditionData = conditional::s_testsData[conditionNdx];
238 
239 		tcu::TestCaseGroup* conditionalDrawRootGroup = new tcu::TestCaseGroup(m_testCtx, de::toString(conditionData).c_str(), "");
240 
241 		ConditionalTestSpec testSpec;
242 		testSpec.conditionalData = conditionData;
243 		testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert";
244 		testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
245 
246 		conditionalDrawRootGroup->addChild(new Draw::InstanceFactory<ConditionalClearAttachmentTest>(m_testCtx, "clear_attachments", "", testSpec));
247 
248 		addChild(conditionalDrawRootGroup);
249 	}
250 }
251 
252 }	// conditional
253 }	// vkt
254