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