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