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], 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 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
ConditionalClearAttachmentTests(tcu::TestContext & testCtx)217 ConditionalClearAttachmentTests::ConditionalClearAttachmentTests (tcu::TestContext &testCtx)
218 : TestCaseGroup (testCtx, "clear_attachments", "vkCmdClearAttachments with conditional rendering")
219 {
220 /* Left blank on purpose */
221 }
222
~ConditionalClearAttachmentTests(void)223 ConditionalClearAttachmentTests::~ConditionalClearAttachmentTests (void) {}
224
init(void)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