1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2018 The Khronos Group Inc.
6  * Copyright (c) 2018 Intel Corporation
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 VK_EXT_conditional_rendering extension tests.
23 *//*--------------------------------------------------------------------*/
24 
25 #include "vktConditionalDrawAndClearTests.hpp"
26 
27 #include "vktTestCaseUtil.hpp"
28 #include "vktDrawBaseClass.hpp"
29 #include "vktDrawTestCaseUtil.hpp"
30 #include "vkBuilderUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkCmdUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkTypeUtil.hpp"
35 
36 #include <bitset>
37 
38 namespace vkt
39 {
40 namespace conditional
41 {
42 namespace
43 {
44 
45 using namespace vk;
46 using namespace Draw;
47 
48 enum ConditionalBufferMemory
49 {
50     LOCAL,
51     HOST
52 };
53 
54 struct ClearTestParams
55 {
56     bool m_discard;
57     bool m_invert;
58     bool m_testDepth;
59     bool m_partialClear;
60     bool m_useOffset;
61     bool m_clearAttachmentTwice;
62     ConditionalBufferMemory m_memoryType;
63 };
64 
65 const ClearTestParams clearColorTestGrid[] = {
66     {false, false, false, false, false, false, HOST},  {true, false, false, false, false, false, HOST},
67     {false, true, false, false, false, false, HOST},   {true, true, false, false, false, false, HOST},
68     {false, false, false, true, false, false, HOST},   {true, false, false, true, false, false, HOST},
69     {false, true, false, true, false, false, HOST},    {true, true, false, true, false, false, HOST},
70     {false, false, false, true, true, false, HOST},    {true, false, false, true, true, false, HOST},
71     {false, true, false, true, true, false, HOST},     {true, true, false, true, true, false, HOST},
72     {true, true, false, false, true, false, HOST},
73 
74     {false, false, false, false, false, false, LOCAL}, {true, false, false, false, false, false, LOCAL},
75     {false, true, false, false, false, false, LOCAL},  {true, true, false, false, false, false, LOCAL},
76     {false, false, false, true, false, false, LOCAL},  {true, false, false, true, false, false, LOCAL},
77     {false, true, false, true, false, false, LOCAL},   {true, true, false, true, false, false, LOCAL},
78     {false, false, false, true, true, false, LOCAL},   {true, false, false, true, true, false, LOCAL},
79     {false, true, false, true, true, false, LOCAL},    {true, true, false, true, true, false, LOCAL},
80     {true, true, false, false, true, false, LOCAL},
81 };
82 
83 const ClearTestParams clearDepthTestGrid[] = {
84     {false, false, true, false, false, false, HOST},  {true, false, true, false, false, false, HOST},
85     {false, true, true, false, false, false, HOST},   {true, true, true, false, false, false, HOST},
86     {false, false, true, true, false, false, HOST},   {true, false, true, true, false, false, HOST},
87     {false, true, true, true, false, false, HOST},    {true, true, true, true, false, false, HOST},
88     {false, false, true, true, true, false, HOST},    {true, false, true, true, true, false, HOST},
89     {false, true, true, true, true, false, HOST},     {true, true, true, true, true, false, HOST},
90 
91     {false, false, true, false, false, false, LOCAL}, {true, false, true, false, false, false, LOCAL},
92     {false, true, true, false, false, false, LOCAL},  {true, true, true, false, false, false, LOCAL},
93     {false, false, true, true, false, false, LOCAL},  {true, false, true, true, false, false, LOCAL},
94     {false, true, true, true, false, false, LOCAL},   {true, true, true, true, false, false, LOCAL},
95     {false, false, true, true, true, false, LOCAL},   {true, false, true, true, true, false, LOCAL},
96     {false, true, true, true, true, false, LOCAL},    {true, true, true, true, true, false, LOCAL},
97 };
98 
99 const ClearTestParams clearColorTwiceGrid[] = {
100     {false, false, false, false, false, true, HOST},  {true, false, false, false, false, true, HOST},
101     {false, true, false, false, false, true, HOST},   {true, true, false, false, false, true, HOST},
102     {false, true, false, true, true, true, HOST},     {true, true, false, true, true, true, HOST},
103 
104     {false, false, false, false, false, true, LOCAL}, {true, false, false, false, false, true, LOCAL},
105     {false, true, false, false, false, true, LOCAL},  {true, true, false, false, false, true, LOCAL},
106     {false, true, false, true, true, true, LOCAL},    {true, true, false, true, true, true, LOCAL},
107 };
108 
109 const ClearTestParams clearDepthTwiceGrid[] = {
110     {false, false, true, false, false, true, HOST},  {true, false, true, false, false, true, HOST},
111     {false, true, true, false, false, true, HOST},   {true, true, true, false, false, true, HOST},
112     {false, true, true, true, true, true, HOST},     {true, true, true, true, true, true, HOST},
113 
114     {false, false, true, false, false, true, LOCAL}, {true, false, true, false, false, true, LOCAL},
115     {false, true, true, false, false, true, LOCAL},  {true, true, true, false, false, true, LOCAL},
116     {false, true, true, true, true, true, LOCAL},    {true, true, true, true, true, true, LOCAL},
117 };
118 
119 enum TogglePredicateMode
120 {
121     FILL,
122     COPY,
123     NONE
124 };
125 
126 struct DrawTestParams
127 {
128     bool
129         m_discard; //controls the setting of the predicate for conditional rendering.Initial state, may be toggled later depending on the m_togglePredicate setting.
130     bool m_invert;
131     bool m_useOffset;
132     bool m_useMaintenance5;
133     uint32_t
134         m_beginSequenceBits; //bits 0..3 control BEFORE which of the 4 draw calls the vkCmdBeginConditionalRenderingEXT call is executed. Least significant bit corresponds to the first draw call.
135     uint32_t
136         m_endSequenceBits; //bits 0..3 control AFTER which of the 4 draw calls the vkCmdEndConditionalRenderingEXT call is executed. Least significant bit corresponds to the first draw call.
137     uint32_t m_resultBits; //used for reference image preparation.
138     bool m_togglePredicate;               //if true, toggle the predicate setting before rendering.
139     TogglePredicateMode m_toggleMode;     //method of the predicate toggling
140     ConditionalBufferMemory m_memoryType; //type of memory used for conditional rendering buffer
141 };
142 
143 enum
144 {
145     b0000 = 0x0,
146     b0001 = 0x1,
147     b0010 = 0x2,
148     b0011 = 0x3,
149     b0100 = 0x4,
150     b0101 = 0x5,
151     b0110 = 0x6,
152     b0111 = 0x7,
153     b1000 = 0x8,
154     b1001 = 0x9,
155     b1010 = 0xA,
156     b1011 = 0xB,
157     b1100 = 0xC,
158     b1101 = 0xD,
159     b1110 = 0xE,
160     b1111 = 0xF,
161 };
162 
163 const DrawTestParams drawTestGrid[] = {
164     {false, false, false, false, b0001, b1000, b1111, false, NONE, HOST},
165     {true, false, false, false, b0001, b1000, b0000, false, NONE, HOST},
166     {true, false, false, false, b0001, b0001, b1110, false, NONE, HOST},
167     {true, false, false, false, b1111, b1111, b0000, false, NONE, HOST},
168     {true, false, false, false, b0010, b0010, b1101, false, NONE, HOST},
169     {true, true, false, false, b1010, b1010, b0101, false, NONE, HOST},
170     {false, true, true, false, b1010, b1010, b1111, false, NONE, HOST},
171     {true, true, true, false, b0010, b1000, b0001, false, NONE, HOST},
172     {true, true, true, false, b1001, b1001, b0110, false, NONE, HOST},
173     {true, true, true, false, b0010, b1000, b1111, true, FILL, HOST},
174     {true, true, true, false, b1001, b1001, b1111, true, FILL, HOST},
175     {false, true, true, false, b1001, b1001, b0110, true, FILL, HOST},
176     {true, true, true, false, b0010, b1000, b1111, true, COPY, HOST},
177     {true, true, true, false, b1001, b1001, b1111, true, COPY, HOST},
178     {false, true, true, false, b1001, b1001, b0110, true, COPY, HOST},
179 
180     {false, false, false, false, b0001, b1000, b1111, false, NONE, LOCAL},
181     {true, false, false, false, b0001, b1000, b0000, false, NONE, LOCAL},
182     {true, false, false, false, b0001, b0001, b1110, false, NONE, LOCAL},
183     {true, false, false, false, b1111, b1111, b0000, false, NONE, LOCAL},
184     {true, false, false, false, b0010, b0010, b1101, false, NONE, LOCAL},
185     {true, true, false, false, b1010, b1010, b0101, false, NONE, LOCAL},
186     {false, true, true, false, b1010, b1010, b1111, false, NONE, LOCAL},
187     {true, true, true, false, b0010, b1000, b0001, false, NONE, LOCAL},
188     {true, true, true, false, b1001, b1001, b0110, false, NONE, LOCAL},
189     {true, true, true, false, b0010, b1000, b1111, true, FILL, LOCAL},
190     {true, true, true, false, b1001, b1001, b1111, true, FILL, LOCAL},
191     {false, true, true, false, b1001, b1001, b0110, true, FILL, LOCAL},
192     {true, true, true, false, b0010, b1000, b1111, true, COPY, LOCAL},
193     {true, true, true, false, b1001, b1001, b1111, true, COPY, LOCAL},
194     {false, true, true, false, b1001, b1001, b0110, true, COPY, LOCAL},
195 };
196 
197 struct UpdateBufferWithDrawTestParams
198 {
199     bool m_testParams;
200     ConditionalBufferMemory m_memoryType;
201 };
202 
203 const UpdateBufferWithDrawTestParams UpdateBufferWithDrawTestGrind[] = {
204     {true, HOST},
205     {false, HOST},
206 
207     {true, LOCAL},
208     {false, LOCAL},
209 };
210 
generateClearTestName(const ClearTestParams & clearTestParams)211 std::string generateClearTestName(const ClearTestParams &clearTestParams)
212 {
213     std::string name = (clearTestParams.m_discard ? "discard_" : "no_discard_");
214     name += (clearTestParams.m_invert ? "invert_" : "no_invert_");
215     name += (clearTestParams.m_partialClear ? "partial_" : "full_");
216     name += (clearTestParams.m_useOffset ? "offset_" : "no_offset_");
217     name += (clearTestParams.m_memoryType ? "host_memory" : "local_memory");
218     return name;
219 }
220 
generateDrawTestName(uint32_t ndx,const DrawTestParams & drawTestParams)221 std::string generateDrawTestName(uint32_t ndx, const DrawTestParams &drawTestParams)
222 {
223     std::string name = "case_";
224     name += de::toString(ndx);
225     name += (drawTestParams.m_memoryType ? "_host_memory" : "_local_memory");
226     return name;
227 }
228 
generateUpdateBufferWithDrawTestName(const UpdateBufferWithDrawTestParams & updateBufferTestParams)229 std::string generateUpdateBufferWithDrawTestName(const UpdateBufferWithDrawTestParams &updateBufferTestParams)
230 {
231     std::string name = "update_with_rendering_";
232     name += (updateBufferTestParams.m_testParams ? "discard_" : "no_discard_");
233     name += (updateBufferTestParams.m_memoryType ? "host_memory" : "local_memory");
234     return name;
235 }
236 
getBit(uint32_t src,int ndx)237 inline uint32_t getBit(uint32_t src, int ndx)
238 {
239     return (src >> ndx) & 1;
240 }
241 
isBitSet(uint32_t src,int ndx)242 inline bool isBitSet(uint32_t src, int ndx)
243 {
244     return getBit(src, ndx) != 0;
245 }
246 
247 class ConditionalRenderingBaseTestInstance : public TestInstance
248 {
249 public:
250     ConditionalRenderingBaseTestInstance(Context &context);
251 
252 protected:
253     virtual tcu::TestStatus iterate(void) = 0;
254     void createInitBufferWithPredicate(ConditionalBufferMemory memoryType, bool discard, bool invert,
255                                        uint32_t offsetMultiplier, VkBufferUsageFlagBits extraUsage, bool maintenance5);
256     void createTargetColorImageAndImageView(void);
257     void createTargetDepthImageAndImageView(void);
258     void createRenderPass(VkFormat format, VkImageLayout layout);
259     void createFramebuffer(VkImageView imageView);
260     void clearWithClearColorImage(const VkClearColorValue &color);
261     void clearWithClearDepthStencilImage(const VkClearDepthStencilValue &value);
262     void clearColorWithClearAttachments(const VkClearColorValue &color, bool partial);
263     void clearDepthWithClearAttachments(const VkClearDepthStencilValue &depthStencil, bool partial);
264     void createResultBuffer(VkFormat format);
265     void createVertexBuffer(void);
266     void createPipelineLayout(void);
267     void createAndUpdateDescriptorSet(void);
268     void createPipeline(void);
269     void copyResultImageToBuffer(VkImageAspectFlags imageAspectFlags, VkImage image);
270     void draw(void);
271     void imageMemoryBarrier(VkImage image, VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
272                             VkImageLayout oldLayout, VkImageLayout newLayout, VkPipelineStageFlags srcStageMask,
273                             VkPipelineStageFlags dstStageMask, VkImageAspectFlags imageAspectFlags);
274     void bufferMemoryBarrier(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size, VkAccessFlags srcAccessMask,
275                              VkAccessFlags dstAccessMask, VkPipelineStageFlags srcStageMask,
276                              VkPipelineStageFlags dstStageMask);
277     void prepareReferenceImageOneColor(tcu::PixelBufferAccess &reference, const VkClearColorValue &clearColor);
278     void prepareReferenceImageOneColor(tcu::PixelBufferAccess &reference, const tcu::Vec4 &color);
279     void prepareReferenceImageOneDepth(tcu::PixelBufferAccess &reference, const VkClearDepthStencilValue &clearValue);
280     void prepareReferenceImageDepthClearPartial(tcu::PixelBufferAccess &reference,
281                                                 const VkClearDepthStencilValue &clearValueInitial,
282                                                 const VkClearDepthStencilValue &clearValueFinal);
283     void prepareReferenceImageColorClearPartial(tcu::PixelBufferAccess &reference,
284                                                 const VkClearColorValue &clearColorInitial,
285                                                 const VkClearColorValue &clearColorFinal);
286 
287     const InstanceInterface &m_vki;
288     const DeviceInterface &m_vkd;
289     const VkDevice m_device;
290     const VkPhysicalDevice m_physicalDevice;
291     const VkQueue m_queue;
292     de::SharedPtr<Buffer> m_conditionalRenderingBuffer;
293     de::SharedPtr<Buffer> m_resultBuffer;
294     de::SharedPtr<Buffer> m_vertexBuffer;
295     de::SharedPtr<Image> m_colorTargetImage;
296     de::SharedPtr<Image> m_depthTargetImage;
297     Move<VkImageView> m_colorTargetView;
298     Move<VkImageView> m_depthTargetView;
299     Move<VkRenderPass> m_renderPass;
300     Move<VkFramebuffer> m_framebuffer;
301     Move<VkCommandPool> m_cmdPool;
302     Move<VkCommandBuffer> m_cmdBufferPrimary;
303     Move<VkDescriptorPool> m_descriptorPool;
304     Move<VkDescriptorSetLayout> m_descriptorSetLayout;
305     Move<VkDescriptorSet> m_descriptorSet;
306     Move<VkPipelineLayout> m_pipelineLayout;
307     Move<VkShaderModule> m_vertexShaderModule;
308     Move<VkShaderModule> m_fragmentShaderModule;
309     Move<VkPipeline> m_pipeline;
310     VkDeviceSize m_conditionalRenderingBufferOffset;
311 
312     enum
313     {
314         WIDTH  = 256,
315         HEIGHT = 256
316     };
317 };
318 
319 class ConditionalRenderingClearAttachmentsTestInstance : public ConditionalRenderingBaseTestInstance
320 {
321 public:
322     ConditionalRenderingClearAttachmentsTestInstance(Context &context, const ClearTestParams &testParams);
323 
324 protected:
325     virtual tcu::TestStatus iterate(void);
326     ClearTestParams m_testParams;
327 };
328 
329 class ConditionalRenderingDrawTestInstance : public ConditionalRenderingBaseTestInstance
330 {
331 public:
332     ConditionalRenderingDrawTestInstance(Context &context, const DrawTestParams &testParams);
333 
334 protected:
335     //Execute 4 draw calls, each can be drawn with or without conditional rendering. Each draw call renders to the different part of an image - this is achieved by
336     //using push constant and 'discard' in the fragment shader. This way it is possible to tell which of the rendering command were discarded by the conditional rendering mechanism.
337     virtual tcu::TestStatus iterate(void);
338     void createPipelineLayout(void);
339     void prepareReferenceImage(tcu::PixelBufferAccess &reference, const VkClearColorValue &clearColor,
340                                uint32_t resultBits);
341 
342     DrawTestParams m_testParams;
343     de::SharedPtr<Buffer> m_conditionalRenderingBufferForCopy;
344 };
345 
346 class ConditionalRenderingUpdateBufferWithDrawTestInstance : public ConditionalRenderingBaseTestInstance
347 {
348 public:
349     ConditionalRenderingUpdateBufferWithDrawTestInstance(Context &context, UpdateBufferWithDrawTestParams testParams);
350 
351 protected:
352     virtual tcu::TestStatus iterate(void);
353     void createAndUpdateDescriptorSets(void);
354     void createPipelines(void);
355     void createRenderPass(VkFormat format, VkImageLayout layout);
356     Move<VkDescriptorSet> m_descriptorSetUpdate;
357     Move<VkShaderModule> m_vertexShaderModuleDraw;
358     Move<VkShaderModule> m_fragmentShaderModuleDraw;
359     Move<VkShaderModule> m_vertexShaderModuleUpdate;
360     Move<VkShaderModule> m_fragmentShaderModuleDiscard;
361     Move<VkPipeline> m_pipelineDraw;
362     Move<VkPipeline> m_pipelineUpdate;
363     UpdateBufferWithDrawTestParams m_testParams;
364 };
365 
ConditionalRenderingBaseTestInstance(Context & context)366 ConditionalRenderingBaseTestInstance::ConditionalRenderingBaseTestInstance(Context &context)
367     : TestInstance(context)
368     , m_vki(m_context.getInstanceInterface())
369     , m_vkd(m_context.getDeviceInterface())
370     , m_device(m_context.getDevice())
371     , m_physicalDevice(m_context.getPhysicalDevice())
372     , m_queue(m_context.getUniversalQueue())
373     , m_conditionalRenderingBufferOffset(0)
374 {
375 }
376 
createInitBufferWithPredicate(ConditionalBufferMemory memoryType,bool discard,bool invert,uint32_t offsetMultiplier=0,VkBufferUsageFlagBits extraUsage=(VkBufferUsageFlagBits)0,bool maintenance5=false)377 void ConditionalRenderingBaseTestInstance::createInitBufferWithPredicate(
378     ConditionalBufferMemory memoryType, bool discard, bool invert, uint32_t offsetMultiplier = 0,
379     VkBufferUsageFlagBits extraUsage = (VkBufferUsageFlagBits)0, bool maintenance5 = false)
380 {
381     m_conditionalRenderingBufferOffset = sizeof(uint32_t) * offsetMultiplier;
382 
383     const VkDeviceSize dataSize = sizeof(uint32_t) + m_conditionalRenderingBufferOffset;
384     uint32_t predicate          = discard ? invert : !invert;
385     const auto usage =
386         (memoryType ? VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT : VK_BUFFER_USAGE_TRANSFER_SRC_BIT) | extraUsage;
387     BufferCreateInfo createInfo(dataSize, usage);
388 
389 #ifndef CTS_USES_VULKANSC
390     vk::VkBufferUsageFlags2CreateInfoKHR bufferUsageFlags2 = initVulkanStructure();
391     if (maintenance5)
392     {
393         bufferUsageFlags2.usage = (VkBufferUsageFlagBits2KHR)createInfo.usage;
394         createInfo.pNext        = &bufferUsageFlags2;
395         createInfo.usage        = 0;
396     }
397 #endif // CTS_USES_VULKANSC
398 
399     de::SharedPtr<Draw::Buffer> buffer = Buffer::createAndAlloc(
400         m_vkd, m_device, createInfo, m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
401 
402     void *conditionalRenderingBufferDataPointer =
403         static_cast<char *>(buffer->getBoundMemory().getHostPtr()) + m_conditionalRenderingBufferOffset;
404 
405     deMemcpy(conditionalRenderingBufferDataPointer, &predicate, static_cast<size_t>(sizeof(uint32_t)));
406     flushMappedMemoryRange(m_vkd, m_device, buffer->getBoundMemory().getMemory(), buffer->getBoundMemory().getOffset(),
407                            VK_WHOLE_SIZE);
408 
409     if (memoryType == ConditionalBufferMemory::LOCAL)
410     {
411         createInfo.usage =
412             VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | extraUsage;
413         createInfo.pNext = nullptr;
414 
415 #ifndef CTS_USES_VULKANSC
416         if (maintenance5)
417         {
418             bufferUsageFlags2.usage = (VkBufferUsageFlagBits2KHR)createInfo.usage;
419             createInfo.pNext        = &bufferUsageFlags2;
420             createInfo.usage        = 0;
421         }
422 #endif // CTS_USES_VULKANSC
423 
424         m_conditionalRenderingBuffer = Buffer::createAndAlloc(
425             m_vkd, m_device, createInfo, m_context.getDefaultAllocator(), MemoryRequirement::Local);
426 
427         auto cmdBuffer = vk::allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
428 
429         const vk::VkCommandBufferBeginInfo commandBufferBeginInfo = {
430             vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, DE_NULL, vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
431             nullptr};
432 
433         VK_CHECK(m_vkd.beginCommandBuffer(*cmdBuffer, &commandBufferBeginInfo));
434 
435         vk::VkBufferCopy copyInfo{buffer->getBoundMemory().getOffset(),
436                                   m_conditionalRenderingBuffer->getBoundMemory().getOffset(),
437                                   static_cast<size_t>(dataSize)};
438         m_vkd.cmdCopyBuffer(*cmdBuffer, buffer->object(), m_conditionalRenderingBuffer->object(), 1, &copyInfo);
439         m_vkd.endCommandBuffer(*cmdBuffer);
440 
441         vk::VkSubmitInfo submitInfo{};
442         submitInfo.sType              = vk::VK_STRUCTURE_TYPE_SUBMIT_INFO;
443         submitInfo.commandBufferCount = 1;
444         submitInfo.pCommandBuffers    = &(*cmdBuffer);
445 
446         auto queue = m_context.getUniversalQueue();
447 
448         m_vkd.queueSubmit(queue, 1, &submitInfo, 0);
449 
450         m_vkd.queueWaitIdle(queue);
451     }
452     else
453     {
454         m_conditionalRenderingBuffer = buffer;
455     }
456 }
457 
createTargetColorImageAndImageView(void)458 void ConditionalRenderingBaseTestInstance::createTargetColorImageAndImageView(void)
459 {
460     const VkExtent3D targetImageExtent = {WIDTH, HEIGHT, 1};
461 
462     const ImageCreateInfo targetImageCreateInfo(VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, targetImageExtent, 1, 1,
463                                                 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
464                                                 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
465                                                     VK_IMAGE_USAGE_TRANSFER_DST_BIT);
466 
467     m_colorTargetImage = Image::createAndAlloc(m_vkd, m_device, targetImageCreateInfo, m_context.getDefaultAllocator(),
468                                                m_context.getUniversalQueueFamilyIndex());
469 
470     const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D,
471                                                   VK_FORMAT_R8G8B8A8_UNORM);
472 
473     m_colorTargetView = createImageView(m_vkd, m_device, &colorTargetViewInfo);
474 }
475 
createTargetDepthImageAndImageView(void)476 void ConditionalRenderingBaseTestInstance::createTargetDepthImageAndImageView(void)
477 {
478     const VkExtent3D targetImageExtent = {WIDTH, HEIGHT, 1};
479 
480     const ImageCreateInfo targetImageCreateInfo(VK_IMAGE_TYPE_2D, VK_FORMAT_D32_SFLOAT, targetImageExtent, 1, 1,
481                                                 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
482                                                 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
483                                                     VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
484 
485     m_depthTargetImage = Image::createAndAlloc(m_vkd, m_device, targetImageCreateInfo, m_context.getDefaultAllocator(),
486                                                m_context.getUniversalQueueFamilyIndex());
487 
488     const ImageViewCreateInfo depthTargetViewInfo(m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D,
489                                                   VK_FORMAT_D32_SFLOAT);
490 
491     m_depthTargetView = createImageView(m_vkd, m_device, &depthTargetViewInfo);
492 }
493 
createRenderPass(VkFormat format,VkImageLayout layout)494 void ConditionalRenderingBaseTestInstance::createRenderPass(VkFormat format, VkImageLayout layout)
495 {
496     RenderPassCreateInfo renderPassCreateInfo;
497 
498     renderPassCreateInfo.addAttachment(
499         AttachmentDescription(format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
500                               VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
501                               isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
502                                                              VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
503                               isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
504                                                              VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
505 
506     const VkAttachmentReference attachmentReference = {
507         0u,    // uint32_t                attachment
508         layout // VkImageLayout        layout
509     };
510 
511     renderPassCreateInfo.addSubpass(
512         SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, DE_NULL, isDepthStencilFormat(format) ? 0 : 1,
513                            isDepthStencilFormat(format) ? DE_NULL : &attachmentReference, DE_NULL,
514                            isDepthStencilFormat(format) ? attachmentReference : AttachmentReference(), 0, DE_NULL));
515 
516     m_renderPass = vk::createRenderPass(m_vkd, m_device, &renderPassCreateInfo);
517 }
518 
createFramebuffer(VkImageView imageView)519 void ConditionalRenderingBaseTestInstance::createFramebuffer(VkImageView imageView)
520 {
521     const VkFramebufferCreateInfo framebufferCreateInfo = {
522         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType                sType
523         DE_NULL,                                   // const void*                    pNext
524         (VkFramebufferCreateFlags)0,               // VkFramebufferCreateFlags flags;
525         *m_renderPass,                             // VkRenderPass                    renderPass
526         1,                                         // uint32_t                        attachmentCount
527         &imageView,                                // const VkImageView*            pAttachments
528         WIDTH,                                     // uint32_t                        width
529         HEIGHT,                                    // uint32_t                        height
530         1                                          // uint32_t                        layers
531     };
532     m_framebuffer = vk::createFramebuffer(m_vkd, m_device, &framebufferCreateInfo);
533 }
534 
imageMemoryBarrier(VkImage image,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkImageLayout oldLayout,VkImageLayout newLayout,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkImageAspectFlags imageAspectFlags)535 void ConditionalRenderingBaseTestInstance::imageMemoryBarrier(VkImage image, VkAccessFlags srcAccessMask,
536                                                               VkAccessFlags dstAccessMask, VkImageLayout oldLayout,
537                                                               VkImageLayout newLayout,
538                                                               VkPipelineStageFlags srcStageMask,
539                                                               VkPipelineStageFlags dstStageMask,
540                                                               VkImageAspectFlags imageAspectFlags)
541 {
542     const struct VkImageSubresourceRange subRangeColor = {
543         imageAspectFlags, // VkImageAspectFlags        aspectMask
544         0u,               // uint32_t                    baseMipLevel
545         1u,               // uint32_t                    mipLevels
546         0u,               // uint32_t                    baseArrayLayer
547         1u,               // uint32_t                    arraySize
548     };
549     const VkImageMemoryBarrier imageBarrier = {
550         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType            sType
551         DE_NULL,                                // const void*                pNext
552         srcAccessMask,                          // VkAccessFlags            srcAccessMask
553         dstAccessMask,                          // VkAccessFlags            dstAccessMask
554         oldLayout,                              // VkImageLayout            oldLayout
555         newLayout,                              // VkImageLayout            newLayout
556         VK_QUEUE_FAMILY_IGNORED,                // uint32_t                    srcQueueFamilyIndex
557         VK_QUEUE_FAMILY_IGNORED,                // uint32_t                    dstQueueFamilyIndex
558         image,                                  // VkImage                    image
559         subRangeColor                           // VkImageSubresourceRange    subresourceRange
560     };
561 
562     m_vkd.cmdPipelineBarrier(*m_cmdBufferPrimary, srcStageMask, dstStageMask, false, 0u, DE_NULL, 0u, DE_NULL, 1u,
563                              &imageBarrier);
564 }
565 
bufferMemoryBarrier(VkBuffer buffer,VkDeviceSize offset,VkDeviceSize size,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask)566 void ConditionalRenderingBaseTestInstance::bufferMemoryBarrier(VkBuffer buffer, VkDeviceSize offset, VkDeviceSize size,
567                                                                VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
568                                                                VkPipelineStageFlags srcStageMask,
569                                                                VkPipelineStageFlags dstStageMask)
570 {
571     const VkBufferMemoryBarrier bufferBarrier = {
572         VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, //VkStructureType sType;
573         DE_NULL,                                 //const void* pNext;
574         srcAccessMask,                           //VkAccessFlags srcAccessMask;
575         dstAccessMask,                           //VkAccessFlags dstAccessMask;
576         VK_QUEUE_FAMILY_IGNORED,                 //uint32_t srcQueueFamilyIndex;
577         VK_QUEUE_FAMILY_IGNORED,                 //uint32_t dstQueueFamilyIndex;
578         buffer,                                  //VkBuffer buffer;
579         offset,                                  //VkDeviceSize offset;
580         size                                     //VkDeviceSize size;
581     };
582 
583     m_vkd.cmdPipelineBarrier(*m_cmdBufferPrimary, srcStageMask, dstStageMask, false, 0u, DE_NULL, 1u, &bufferBarrier,
584                              0u, DE_NULL);
585 }
586 
prepareReferenceImageOneColor(tcu::PixelBufferAccess & reference,const VkClearColorValue & clearColor)587 void ConditionalRenderingBaseTestInstance::prepareReferenceImageOneColor(tcu::PixelBufferAccess &reference,
588                                                                          const VkClearColorValue &clearColor)
589 {
590     for (int w = 0; w < WIDTH; ++w)
591         for (int h = 0; h < HEIGHT; ++h)
592             reference.setPixel(
593                 tcu::Vec4(clearColor.float32[0], clearColor.float32[1], clearColor.float32[2], clearColor.float32[3]),
594                 w, h);
595 }
596 
prepareReferenceImageOneColor(tcu::PixelBufferAccess & reference,const tcu::Vec4 & color)597 void ConditionalRenderingBaseTestInstance::prepareReferenceImageOneColor(tcu::PixelBufferAccess &reference,
598                                                                          const tcu::Vec4 &color)
599 {
600     for (int w = 0; w < WIDTH; ++w)
601         for (int h = 0; h < HEIGHT; ++h)
602             reference.setPixel(tcu::Vec4(color), w, h);
603 }
604 
prepareReferenceImageOneDepth(tcu::PixelBufferAccess & reference,const VkClearDepthStencilValue & clearValue)605 void ConditionalRenderingBaseTestInstance::prepareReferenceImageOneDepth(tcu::PixelBufferAccess &reference,
606                                                                          const VkClearDepthStencilValue &clearValue)
607 {
608     for (int w = 0; w < WIDTH; ++w)
609         for (int h = 0; h < HEIGHT; ++h)
610             reference.setPixDepth(clearValue.depth, w, h);
611 }
612 
prepareReferenceImageDepthClearPartial(tcu::PixelBufferAccess & reference,const VkClearDepthStencilValue & clearValueInitial,const VkClearDepthStencilValue & clearValueFinal)613 void ConditionalRenderingBaseTestInstance::prepareReferenceImageDepthClearPartial(
614     tcu::PixelBufferAccess &reference, const VkClearDepthStencilValue &clearValueInitial,
615     const VkClearDepthStencilValue &clearValueFinal)
616 {
617     for (int w = 0; w < WIDTH; ++w)
618         for (int h = 0; h < HEIGHT; ++h)
619         {
620             if (w >= (WIDTH / 2) && h >= (HEIGHT / 2))
621                 reference.setPixDepth(clearValueFinal.depth, w, h);
622             else
623                 reference.setPixDepth(clearValueInitial.depth, w, h);
624         }
625 }
626 
prepareReferenceImageColorClearPartial(tcu::PixelBufferAccess & reference,const VkClearColorValue & clearColorInitial,const VkClearColorValue & clearColorFinal)627 void ConditionalRenderingBaseTestInstance::prepareReferenceImageColorClearPartial(
628     tcu::PixelBufferAccess &reference, const VkClearColorValue &clearColorInitial,
629     const VkClearColorValue &clearColorFinal)
630 {
631     for (int w = 0; w < WIDTH; ++w)
632         for (int h = 0; h < HEIGHT; ++h)
633         {
634             if (w >= (WIDTH / 2) && h >= (HEIGHT / 2))
635                 reference.setPixel(tcu::Vec4(clearColorFinal.float32[0], clearColorFinal.float32[1],
636                                              clearColorFinal.float32[2], clearColorFinal.float32[3]),
637                                    w, h);
638             else
639                 reference.setPixel(tcu::Vec4(clearColorInitial.float32[0], clearColorInitial.float32[1],
640                                              clearColorInitial.float32[2], clearColorInitial.float32[3]),
641                                    w, h);
642         }
643 }
644 
clearWithClearColorImage(const VkClearColorValue & color)645 void ConditionalRenderingBaseTestInstance::clearWithClearColorImage(const VkClearColorValue &color)
646 {
647     const struct VkImageSubresourceRange subRangeColor = {
648         VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags        aspectMask
649         0u,                        // uint32_t                    baseMipLevel
650         1u,                        // uint32_t                    mipLevels
651         0u,                        // uint32_t                    baseArrayLayer
652         1u,                        // uint32_t                    arraySize
653     };
654     m_vkd.cmdClearColorImage(*m_cmdBufferPrimary, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
655                              &color, 1, &subRangeColor);
656 }
657 
clearWithClearDepthStencilImage(const VkClearDepthStencilValue & value)658 void ConditionalRenderingBaseTestInstance::clearWithClearDepthStencilImage(const VkClearDepthStencilValue &value)
659 {
660     const struct VkImageSubresourceRange subRangeColor = {
661         VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags    aspectMask
662         0u,                        // uint32_t                baseMipLevel
663         1u,                        // uint32_t                mipLevels
664         0u,                        // uint32_t                baseArrayLayer
665         1u,                        // uint32_t                arraySize
666     };
667     m_vkd.cmdClearDepthStencilImage(*m_cmdBufferPrimary, m_depthTargetImage->object(),
668                                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &value, 1, &subRangeColor);
669 }
670 
clearColorWithClearAttachments(const VkClearColorValue & color,bool partial)671 void ConditionalRenderingBaseTestInstance::clearColorWithClearAttachments(const VkClearColorValue &color, bool partial)
672 {
673     const VkClearAttachment clearAttachment = {
674         VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
675         0u,                        // uint32_t colorAttachment;
676         {color}                    // VkClearValue clearValue;
677     };
678     VkRect2D renderArea = {{0, 0}, {WIDTH, HEIGHT}};
679 
680     if (partial)
681     {
682         renderArea.offset.x      = WIDTH / 2;
683         renderArea.offset.y      = HEIGHT / 2;
684         renderArea.extent.width  = WIDTH / 2;
685         renderArea.extent.height = HEIGHT / 2;
686     }
687 
688     const VkClearRect clearRect = {
689         renderArea, // VkRect2D rect;
690         0u,         // uint32_t baseArrayLayer;
691         1u          // uint32_t layerCount;
692     };
693 
694     m_vkd.cmdClearAttachments(*m_cmdBufferPrimary, 1, &clearAttachment, 1, &clearRect);
695 }
696 
clearDepthWithClearAttachments(const VkClearDepthStencilValue & depthStencil,bool partial)697 void ConditionalRenderingBaseTestInstance::clearDepthWithClearAttachments(const VkClearDepthStencilValue &depthStencil,
698                                                                           bool partial)
699 {
700     const VkClearAttachment clearAttachment = {
701         VK_IMAGE_ASPECT_DEPTH_BIT,                                           // VkImageAspectFlags aspectMask;
702         0u,                                                                  // uint32_t colorAttachment;
703         makeClearValueDepthStencil(depthStencil.depth, depthStencil.stencil) // VkClearValue clearValue;
704     };
705     VkRect2D renderArea = {{0, 0}, {WIDTH, HEIGHT}};
706 
707     if (partial)
708     {
709         renderArea.offset.x      = WIDTH / 2;
710         renderArea.offset.y      = HEIGHT / 2;
711         renderArea.extent.width  = WIDTH / 2;
712         renderArea.extent.height = HEIGHT / 2;
713     }
714 
715     const VkClearRect clearRect = {
716         renderArea, // VkRect2D rect;
717         0u,         // uint32_t baseArrayLayer;
718         1u          // uint32_t layerCount;
719     };
720     m_vkd.cmdClearAttachments(*m_cmdBufferPrimary, 1, &clearAttachment, 1, &clearRect);
721 }
722 
createResultBuffer(VkFormat format)723 void ConditionalRenderingBaseTestInstance::createResultBuffer(VkFormat format)
724 {
725     VkDeviceSize size = WIDTH * HEIGHT * mapVkFormat(format).getPixelSize();
726     m_resultBuffer    = Buffer::createAndAlloc(
727         m_vkd, m_device, BufferCreateInfo(size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
728         m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
729 }
730 
createVertexBuffer(void)731 void ConditionalRenderingBaseTestInstance::createVertexBuffer(void)
732 {
733     float triangleData[] = {-1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f,  0.0f, 1.0f,
734                             1.0f,  1.0f,  0.0f, 1.0f, 1.0f,  -1.0f, 0.0f, 1.0f};
735 
736     m_vertexBuffer = Buffer::createAndAlloc(m_vkd, m_device,
737                                             BufferCreateInfo(sizeof(triangleData), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
738                                             m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
739 
740     void *vertexBufferDataPointer = m_vertexBuffer->getBoundMemory().getHostPtr();
741 
742     deMemcpy(vertexBufferDataPointer, triangleData, sizeof(triangleData));
743     flushMappedMemoryRange(m_vkd, m_device, m_vertexBuffer->getBoundMemory().getMemory(),
744                            m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
745 }
746 
createPipelineLayout(void)747 void ConditionalRenderingBaseTestInstance::createPipelineLayout(void)
748 {
749     const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
750         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType                sType
751         DE_NULL,                                       // const void*                    pNext
752         (VkPipelineLayoutCreateFlags)0,                // VkPipelineLayoutCreateFlags    flags
753         1u,                                            // uint32_t                        descriptorSetCount
754         &(m_descriptorSetLayout.get()),                // const VkDescriptorSetLayout*    pSetLayouts
755         0u,                                            // uint32_t                        pushConstantRangeCount
756         DE_NULL                                        // const VkPushConstantRange*    pPushConstantRanges
757     };
758 
759     m_pipelineLayout = vk::createPipelineLayout(m_vkd, m_device, &pipelineLayoutParams);
760 }
761 
createAndUpdateDescriptorSet(void)762 void ConditionalRenderingBaseTestInstance::createAndUpdateDescriptorSet(void)
763 {
764     const VkDescriptorSetAllocateInfo allocInfo = {
765         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType                                sType
766         DE_NULL,                                        // const void*                                    pNext
767         *m_descriptorPool,             // VkDescriptorPool                                descriptorPool
768         1u,                            // uint32_t                                        setLayoutCount
769         &(m_descriptorSetLayout.get()) // const VkDescriptorSetLayout*                    pSetLayouts
770     };
771 
772     m_descriptorSet = allocateDescriptorSet(m_vkd, m_device, &allocInfo);
773     VkDescriptorBufferInfo descriptorInfo =
774         makeDescriptorBufferInfo(m_vertexBuffer->object(), (VkDeviceSize)0u, sizeof(float) * 16);
775 
776     DescriptorSetUpdateBuilder()
777         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
778                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
779         .update(m_vkd, m_device);
780 }
781 
createPipeline(void)782 void ConditionalRenderingBaseTestInstance::createPipeline(void)
783 {
784     const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(WIDTH, HEIGHT)));
785     const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(WIDTH, HEIGHT)));
786     const VkPrimitiveTopology topology                                = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
787     const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
788         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType                                sType
789         DE_NULL, // const void*                                    pNext
790         0u,      // vkPipelineVertexInputStateCreateFlags        flags
791         0u,      // uint32_t                                        bindingCount
792         DE_NULL, // const VkVertexInputBindingDescription*        pVertexBindingDescriptions
793         0u,      // uint32_t                                        attributeCount
794         DE_NULL, // const VkVertexInputAttributeDescription*        pVertexAttributeDescriptions
795     };
796 
797     m_pipeline = makeGraphicsPipeline(
798         m_vkd,                    // const DeviceInterface&                        vk
799         m_device,                 // const VkDevice                                device
800         *m_pipelineLayout,        // const VkPipelineLayout                        pipelineLayout
801         *m_vertexShaderModule,    // const VkShaderModule                            vertexShaderModule
802         DE_NULL,                  // const VkShaderModule                            tessellationControlShaderModule
803         DE_NULL,                  // const VkShaderModule                            tessellationEvalShaderModule
804         DE_NULL,                  // const VkShaderModule                            geometryShaderModule
805         *m_fragmentShaderModule,  // const VkShaderModule                            fragmentShaderModule
806         *m_renderPass,            // const VkRenderPass                            renderPass
807         viewports,                // const std::vector<VkViewport>&                viewports
808         scissors,                 // const std::vector<VkRect2D>&                    scissors
809         topology,                 // const VkPrimitiveTopology                    topology
810         0u,                       // const uint32_t                                subpass
811         0u,                       // const uint32_t                                patchControlPoints
812         &vertexInputStateParams); // const VkPipelineVertexInputStateCreateInfo*    vertexInputStateCreateInfo
813 }
814 
copyResultImageToBuffer(VkImageAspectFlags imageAspectFlags,VkImage image)815 void ConditionalRenderingBaseTestInstance::copyResultImageToBuffer(VkImageAspectFlags imageAspectFlags, VkImage image)
816 {
817     const VkBufferImageCopy region_all = {
818         0,                           // VkDeviceSize                    bufferOffset
819         0,                           // uint32_t                        bufferRowLength
820         0,                           // uint32_t                        bufferImageHeight
821         {imageAspectFlags, 0, 0, 1}, // VkImageSubresourceLayers        imageSubresource
822         {0, 0, 0},                   // VkOffset3D                    imageOffset
823         {WIDTH, HEIGHT, 1}           // VkExtent3D                    imageExtent
824     };
825 
826     m_vkd.cmdCopyImageToBuffer(*m_cmdBufferPrimary, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
827                                m_resultBuffer->object(), 1, &region_all);
828 }
829 
draw(void)830 void ConditionalRenderingBaseTestInstance::draw(void)
831 {
832     m_vkd.cmdDraw(*m_cmdBufferPrimary, 4, 1, 0, 0);
833 }
834 
ConditionalRenderingClearAttachmentsTestInstance(Context & context,const ClearTestParams & testParams)835 ConditionalRenderingClearAttachmentsTestInstance::ConditionalRenderingClearAttachmentsTestInstance(
836     Context &context, const ClearTestParams &testParams)
837     : ConditionalRenderingBaseTestInstance(context)
838     , m_testParams(testParams)
839 {
840 }
841 
iterate(void)842 tcu::TestStatus ConditionalRenderingClearAttachmentsTestInstance::iterate(void)
843 {
844     const uint32_t queueFamilyIndex                 = m_context.getUniversalQueueFamilyIndex();
845     uint32_t offsetMultiplier                       = 0;
846     VkClearColorValue clearColorInitial             = {{0.0f, 0.0f, 1.0f, 1.0f}};
847     VkClearColorValue clearColorMiddle              = {{1.0f, 0.0f, 0.0f, 1.0f}};
848     VkClearColorValue clearColorFinal               = {{0.0f, 1.0f, 0.0f, 1.0f}};
849     VkClearDepthStencilValue clearDepthValueInitial = {0.4f, 0};
850     VkClearDepthStencilValue clearDepthValueMiddle  = {0.6f, 0};
851     VkClearDepthStencilValue clearDepthValueFinal   = {0.9f, 0};
852 
853     if (m_testParams.m_useOffset)
854         offsetMultiplier = 3;
855 
856     m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
857 
858     createInitBufferWithPredicate(m_testParams.m_memoryType, m_testParams.m_discard, m_testParams.m_invert,
859                                   offsetMultiplier);
860     m_testParams.m_testDepth ? createTargetDepthImageAndImageView() : createTargetColorImageAndImageView();
861     createResultBuffer(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM);
862 
863     m_cmdBufferPrimary = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
864 
865     createRenderPass(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM,
866                      m_testParams.m_testDepth ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
867                                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
868     createFramebuffer(m_testParams.m_testDepth ? m_depthTargetView.get() : m_colorTargetView.get());
869 
870     const VkConditionalRenderingBeginInfoEXT conditionalRenderingBeginInfo = {
871         VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, //VkStructureType sType;
872         DE_NULL,                                                //const void* pNext;
873         m_conditionalRenderingBuffer->object(),                 //VkBuffer buffer;
874         sizeof(uint32_t) * offsetMultiplier,                    //VkDeviceSize offset;
875         (m_testParams.m_invert ? (VkConditionalRenderingFlagsEXT)VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT :
876                                  (VkConditionalRenderingFlagsEXT)0) //VkConditionalRenderingFlagsEXT flags;
877     };
878 
879     beginCommandBuffer(m_vkd, *m_cmdBufferPrimary);
880 
881     imageMemoryBarrier(m_testParams.m_testDepth ?
882                            m_depthTargetImage->object() :
883                            m_colorTargetImage->object(),     //VkImage                             image
884                        0u,                                   //VkAccessFlags                        srcAccessMask
885                        VK_ACCESS_TRANSFER_WRITE_BIT,         //VkAccessFlags                        dstAccessMask
886                        VK_IMAGE_LAYOUT_UNDEFINED,            //VkImageLayout                        oldLayout
887                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout                        newLayout
888                        VK_PIPELINE_STAGE_TRANSFER_BIT,       //VkPipelineStageFlags                srcStageMask
889                        VK_PIPELINE_STAGE_TRANSFER_BIT,       //VkPipelineStageFlags                dstStageMask
890                        m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT :
891                                                   VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags                flags
892 
893     m_testParams.m_testDepth ? clearWithClearDepthStencilImage(clearDepthValueInitial) :
894                                clearWithClearColorImage(clearColorInitial);
895 
896     imageMemoryBarrier(
897         m_testParams.m_testDepth ? m_depthTargetImage->object() :
898                                    m_colorTargetImage->object(), //VkImage                            image
899         VK_ACCESS_TRANSFER_WRITE_BIT,                            //VkAccessFlags                        srcAccessMask
900         m_testParams.m_testDepth ?
901             (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) :
902             (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
903              VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), //VkAccessFlags                        dstAccessMask
904         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,       //VkImageLayout                        oldLayout
905         m_testParams.m_testDepth ?
906             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
907             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout                        newLayout
908         VK_PIPELINE_STAGE_TRANSFER_BIT,               //VkPipelineStageFlags                srcStageMask
909         m_testParams.m_testDepth ?
910             VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT :
911             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags                dstStageMask
912         m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT :
913                                    VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags                flags
914 
915     if (m_testParams.m_clearAttachmentTwice)
916     {
917         beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
918 
919         m_testParams.m_testDepth ? clearDepthWithClearAttachments(clearDepthValueMiddle, m_testParams.m_partialClear) :
920                                    clearColorWithClearAttachments(clearColorMiddle, m_testParams.m_partialClear);
921 
922         m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
923 
924         m_testParams.m_testDepth ? clearDepthWithClearAttachments(clearDepthValueFinal, m_testParams.m_partialClear) :
925                                    clearColorWithClearAttachments(clearColorFinal, m_testParams.m_partialClear);
926 
927         m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
928 
929         endRenderPass(m_vkd, *m_cmdBufferPrimary);
930     }
931     else
932     {
933         m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
934 
935         beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
936 
937         m_testParams.m_testDepth ? clearDepthWithClearAttachments(clearDepthValueFinal, m_testParams.m_partialClear) :
938                                    clearColorWithClearAttachments(clearColorFinal, m_testParams.m_partialClear);
939 
940         endRenderPass(m_vkd, *m_cmdBufferPrimary);
941         m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
942     }
943 
944     imageMemoryBarrier(
945         m_testParams.m_testDepth ? m_depthTargetImage->object() :
946                                    m_colorTargetImage->object(), //VkImage                            image
947         m_testParams.m_testDepth ?
948             (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) :
949             (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
950              VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT), //VkAccessFlags                        dstAccessMask
951         VK_ACCESS_TRANSFER_READ_BIT,                //VkAccessFlags                        dstAccessMask
952         m_testParams.m_testDepth ?
953             VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
954             VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout                        oldLayout
955         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,         //VkImageLayout                        newLayout
956         m_testParams.m_testDepth ?
957             VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT :
958             VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags                srcStageMask
959         VK_PIPELINE_STAGE_TRANSFER_BIT,                    //VkPipelineStageFlags                dstStageMask
960         m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT :
961                                    VK_IMAGE_ASPECT_COLOR_BIT); //VkImageAspectFlags                flags
962 
963     copyResultImageToBuffer(m_testParams.m_testDepth ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_COLOR_BIT,
964                             m_testParams.m_testDepth ? m_depthTargetImage->object() : m_colorTargetImage->object());
965 
966     const vk::VkBufferMemoryBarrier bufferMemoryBarrier = {vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
967                                                            DE_NULL,
968                                                            vk::VK_ACCESS_TRANSFER_WRITE_BIT,
969                                                            vk::VK_ACCESS_HOST_READ_BIT,
970                                                            VK_QUEUE_FAMILY_IGNORED,
971                                                            VK_QUEUE_FAMILY_IGNORED,
972                                                            m_resultBuffer->object(),
973                                                            0u,
974                                                            VK_WHOLE_SIZE};
975 
976     m_vkd.cmdPipelineBarrier(*m_cmdBufferPrimary, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
977                              0u, 0u, DE_NULL, 1u, &bufferMemoryBarrier, 0u, DE_NULL);
978 
979     endCommandBuffer(m_vkd, *m_cmdBufferPrimary);
980 
981     submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBufferPrimary);
982 
983     invalidateMappedMemoryRange(m_vkd, m_device, m_resultBuffer->getBoundMemory().getMemory(),
984                                 m_resultBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
985 
986     tcu::ConstPixelBufferAccess result(
987         mapVkFormat(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM),
988         tcu::IVec3(WIDTH, HEIGHT, 1), m_resultBuffer->getBoundMemory().getHostPtr());
989 
990     std::vector<float> referenceData((m_testParams.m_testDepth ? 1 : 4) * WIDTH * HEIGHT, 0);
991     tcu::PixelBufferAccess reference(
992         mapVkFormat(m_testParams.m_testDepth ? VK_FORMAT_D32_SFLOAT : VK_FORMAT_R8G8B8A8_UNORM),
993         tcu::IVec3(WIDTH, HEIGHT, 1), referenceData.data());
994 
995     if (!m_testParams.m_partialClear)
996     {
997         m_testParams.m_testDepth ?
998             prepareReferenceImageOneDepth(
999                 reference, m_testParams.m_discard ?
1000                                (m_testParams.m_clearAttachmentTwice ? clearDepthValueMiddle : clearDepthValueInitial) :
1001                                clearDepthValueFinal) :
1002             prepareReferenceImageOneColor(
1003                 reference, m_testParams.m_discard ?
1004                                (m_testParams.m_clearAttachmentTwice ? clearColorMiddle : clearColorInitial) :
1005                                clearColorFinal);
1006     }
1007     else
1008     {
1009         m_testParams.m_testDepth ?
1010             prepareReferenceImageDepthClearPartial(
1011                 reference, clearDepthValueInitial,
1012                 m_testParams.m_discard ?
1013                     (m_testParams.m_clearAttachmentTwice ? clearDepthValueMiddle : clearDepthValueInitial) :
1014                     clearDepthValueFinal) :
1015             prepareReferenceImageColorClearPartial(
1016                 reference, clearColorInitial,
1017                 m_testParams.m_discard ? (m_testParams.m_clearAttachmentTwice ? clearColorMiddle : clearColorInitial) :
1018                                          clearColorFinal);
1019     }
1020 
1021     if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result,
1022                                     tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
1023         return tcu::TestStatus::fail("Fail");
1024 
1025     return tcu::TestStatus::pass("Pass");
1026 }
1027 
ConditionalRenderingDrawTestInstance(Context & context,const DrawTestParams & testParams)1028 ConditionalRenderingDrawTestInstance::ConditionalRenderingDrawTestInstance(Context &context,
1029                                                                            const DrawTestParams &testParams)
1030     : ConditionalRenderingBaseTestInstance(context)
1031     , m_testParams(testParams)
1032 {
1033 }
1034 
iterate(void)1035 tcu::TestStatus ConditionalRenderingDrawTestInstance::iterate(void)
1036 {
1037     const uint32_t queueFamilyIndex     = m_context.getUniversalQueueFamilyIndex();
1038     VkClearColorValue clearColorInitial = {{0.0f, 0.0f, 1.0f, 1.0f}};
1039     uint32_t offsetMultiplier           = 0;
1040 
1041     if (m_testParams.m_useOffset)
1042         offsetMultiplier = 3;
1043 
1044     VkBufferUsageFlagBits bufferUsageExtraFlags = (VkBufferUsageFlagBits)0;
1045     if (m_testParams.m_togglePredicate)
1046         bufferUsageExtraFlags = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1047 
1048     m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1049 
1050     createInitBufferWithPredicate(m_testParams.m_memoryType, m_testParams.m_discard, m_testParams.m_invert,
1051                                   offsetMultiplier, bufferUsageExtraFlags, m_testParams.m_useMaintenance5);
1052 
1053     if (m_testParams.m_toggleMode == COPY)
1054     {
1055         //we need another buffer to copy from, with toggled predicate value
1056         m_conditionalRenderingBufferForCopy.swap(m_conditionalRenderingBuffer);
1057         createInitBufferWithPredicate(m_testParams.m_memoryType, !m_testParams.m_discard, m_testParams.m_invert,
1058                                       offsetMultiplier, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
1059         m_conditionalRenderingBufferForCopy.swap(m_conditionalRenderingBuffer);
1060     }
1061     createTargetColorImageAndImageView();
1062     createResultBuffer(VK_FORMAT_R8G8B8A8_UNORM);
1063     createVertexBuffer();
1064 
1065     m_cmdBufferPrimary = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1066 
1067     createRenderPass(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
1068     createFramebuffer(m_colorTargetView.get());
1069 
1070     DescriptorSetLayoutBuilder builder;
1071 
1072     builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
1073 
1074     m_descriptorSetLayout = builder.build(m_vkd, m_device, (VkDescriptorSetLayoutCreateFlags)0);
1075 
1076     m_descriptorPool = DescriptorPoolBuilder()
1077                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1078                            .build(m_vkd, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1079 
1080     createPipelineLayout();
1081     createAndUpdateDescriptorSet();
1082 
1083     m_vertexShaderModule =
1084         createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("position_only.vert"), 0);
1085     m_fragmentShaderModule =
1086         createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("only_color_out.frag"), 0);
1087 
1088     createPipeline();
1089 
1090     VkConditionalRenderingBeginInfoEXT conditionalRenderingBeginInfo = {
1091         VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, //VkStructureType sType;
1092         DE_NULL,                                                //const void* pNext;
1093         m_conditionalRenderingBuffer->object(),                 //VkBuffer buffer;
1094         sizeof(uint32_t) * offsetMultiplier,                    //VkDeviceSize offset;
1095         (m_testParams.m_invert ? (VkConditionalRenderingFlagsEXT)VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT :
1096                                  (VkConditionalRenderingFlagsEXT)0) //VkConditionalRenderingFlagsEXT flags;
1097     };
1098 
1099     beginCommandBuffer(m_vkd, *m_cmdBufferPrimary);
1100 
1101     imageMemoryBarrier(m_colorTargetImage->object(),         //VkImage                            image
1102                        0u,                                   //VkAccessFlags                        srcAccessMask
1103                        VK_ACCESS_TRANSFER_WRITE_BIT,         //VkAccessFlags                        dstAccessMask
1104                        VK_IMAGE_LAYOUT_UNDEFINED,            //VkImageLayout                        oldLayout
1105                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout                        newLayout
1106                        VK_PIPELINE_STAGE_TRANSFER_BIT,       //VkPipelineStageFlags                srcStageMask
1107                        VK_PIPELINE_STAGE_TRANSFER_BIT,       //VkPipelineStageFlags                dstStageMask
1108                        VK_IMAGE_ASPECT_COLOR_BIT);           //VkImageAspectFlags                flags
1109 
1110     clearWithClearColorImage(clearColorInitial);
1111 
1112     imageMemoryBarrier(m_colorTargetImage->object(), //VkImage                            image
1113                        VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags                        srcAccessMask
1114                        VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1115                            VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags                        dstAccessMask
1116                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,     //VkImageLayout                        oldLayout
1117                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout                        newLayout
1118                        VK_PIPELINE_STAGE_TRANSFER_BIT,           //VkPipelineStageFlags                srcStageMask
1119                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags                dstStageMask
1120                        VK_IMAGE_ASPECT_COLOR_BIT);                    //VkImageAspectFlags                flags
1121 
1122     m_vkd.cmdBindPipeline(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
1123     m_vkd.cmdBindDescriptorSets(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1,
1124                                 &(*m_descriptorSet), 0, DE_NULL);
1125 
1126     if (m_testParams.m_togglePredicate)
1127     {
1128         if (m_testParams.m_toggleMode == FILL)
1129         {
1130             m_testParams.m_discard = !m_testParams.m_discard;
1131             uint32_t predicate     = m_testParams.m_discard ? m_testParams.m_invert : !m_testParams.m_invert;
1132             m_vkd.cmdFillBuffer(*m_cmdBufferPrimary, m_conditionalRenderingBuffer->object(),
1133                                 m_conditionalRenderingBufferOffset, sizeof(predicate), predicate);
1134             bufferMemoryBarrier(m_conditionalRenderingBuffer->object(), m_conditionalRenderingBufferOffset,
1135                                 sizeof(predicate), VK_ACCESS_TRANSFER_WRITE_BIT,
1136                                 VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1137                                 VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT);
1138         }
1139         if (m_testParams.m_toggleMode == COPY)
1140         {
1141             VkBufferCopy region = {
1142                 m_conditionalRenderingBufferOffset, //VkDeviceSize srcOffset;
1143                 m_conditionalRenderingBufferOffset, //VkDeviceSize dstOffset;
1144                 sizeof(uint32_t)                    //VkDeviceSize size;
1145             };
1146             m_vkd.cmdCopyBuffer(*m_cmdBufferPrimary, m_conditionalRenderingBufferForCopy->object(),
1147                                 m_conditionalRenderingBuffer->object(), 1, &region);
1148             bufferMemoryBarrier(m_conditionalRenderingBuffer->object(), m_conditionalRenderingBufferOffset,
1149                                 sizeof(uint32_t), VK_ACCESS_TRANSFER_WRITE_BIT,
1150                                 VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1151                                 VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT);
1152         }
1153     }
1154 
1155     beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
1156 
1157     int32_t data[4] = {-1, -1, -1, -1};
1158     void *dataPtr   = data;
1159 
1160     for (int drawNdx = 0; drawNdx < 4; drawNdx++)
1161     {
1162         data[0] = drawNdx;
1163         m_vkd.cmdPushConstants(*m_cmdBufferPrimary, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, 16, dataPtr);
1164 
1165         if (isBitSet(m_testParams.m_beginSequenceBits, drawNdx))
1166             m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
1167 
1168         draw();
1169 
1170         if (isBitSet(m_testParams.m_endSequenceBits, drawNdx))
1171             m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
1172     }
1173 
1174     endRenderPass(m_vkd, *m_cmdBufferPrimary);
1175 
1176     imageMemoryBarrier(m_colorTargetImage->object(),             //VkImage                            image
1177                        VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,     //VkAccessFlags                        srcAccessMask
1178                        VK_ACCESS_TRANSFER_READ_BIT,              //VkAccessFlags                        dstAccessMask
1179                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout                        oldLayout
1180                        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,     //VkImageLayout                        newLayout
1181                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags                srcStageMask
1182                        VK_PIPELINE_STAGE_TRANSFER_BIT,                //VkPipelineStageFlags                dstStageMask
1183                        VK_IMAGE_ASPECT_COLOR_BIT);                    //VkImageAspectFlags                flags
1184 
1185     copyResultImageToBuffer(VK_IMAGE_ASPECT_COLOR_BIT, m_colorTargetImage->object());
1186 
1187     const vk::VkBufferMemoryBarrier bufferMemoryBarrier = {vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1188                                                            DE_NULL,
1189                                                            vk::VK_ACCESS_TRANSFER_WRITE_BIT,
1190                                                            vk::VK_ACCESS_HOST_READ_BIT,
1191                                                            VK_QUEUE_FAMILY_IGNORED,
1192                                                            VK_QUEUE_FAMILY_IGNORED,
1193                                                            m_resultBuffer->object(),
1194                                                            0u,
1195                                                            VK_WHOLE_SIZE};
1196 
1197     m_vkd.cmdPipelineBarrier(*m_cmdBufferPrimary, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
1198                              0u, 0u, DE_NULL, 1u, &bufferMemoryBarrier, 0u, DE_NULL);
1199 
1200     endCommandBuffer(m_vkd, *m_cmdBufferPrimary);
1201 
1202     submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBufferPrimary);
1203 
1204     invalidateMappedMemoryRange(m_vkd, m_device, m_resultBuffer->getBoundMemory().getMemory(),
1205                                 m_resultBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
1206 
1207     tcu::ConstPixelBufferAccess result(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1),
1208                                        m_resultBuffer->getBoundMemory().getHostPtr());
1209 
1210     std::vector<float> referenceData(4 * WIDTH * HEIGHT, 0.5f);
1211     tcu::PixelBufferAccess reference(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1),
1212                                      referenceData.data());
1213 
1214     prepareReferenceImage(reference, clearColorInitial, m_testParams.m_resultBits);
1215 
1216     if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result,
1217                                     tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
1218         return tcu::TestStatus::fail("Fail");
1219 
1220     return tcu::TestStatus::pass("Pass");
1221 }
1222 
createPipelineLayout(void)1223 void ConditionalRenderingDrawTestInstance::createPipelineLayout(void)
1224 {
1225     const VkPushConstantRange pushConstantRange = {
1226         VK_SHADER_STAGE_FRAGMENT_BIT, //VkShaderStageFlags stageFlags;
1227         0,                            //uint32_t offset;
1228         16                            //uint32_t size;
1229     };
1230 
1231     const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
1232         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, //VkStructureType                sType
1233         DE_NULL,                                       //const void*                    pNext
1234         (VkPipelineLayoutCreateFlags)0,                //VkPipelineLayoutCreateFlags    flags
1235         1u,                                            //uint32_t                        descriptorSetCount
1236         &(m_descriptorSetLayout.get()),                //const VkDescriptorSetLayout*    pSetLayouts
1237         1u,                                            //uint32_t                        pushConstantRangeCount
1238         &pushConstantRange                             //const VkPushConstantRange*    pPushConstantRanges
1239     };
1240 
1241     m_pipelineLayout = vk::createPipelineLayout(m_vkd, m_device, &pipelineLayoutParams);
1242 }
1243 
prepareReferenceImage(tcu::PixelBufferAccess & reference,const VkClearColorValue & clearColor,uint32_t resultBits)1244 void ConditionalRenderingDrawTestInstance::prepareReferenceImage(tcu::PixelBufferAccess &reference,
1245                                                                  const VkClearColorValue &clearColor,
1246                                                                  uint32_t resultBits)
1247 {
1248     for (int w = 0; w < WIDTH; w++)
1249         for (int h = 0; h < HEIGHT; h++)
1250             reference.setPixel(tcu::Vec4(clearColor.float32), w, h);
1251 
1252     int step = (HEIGHT / 4);
1253     for (int w = 0; w < WIDTH; w++)
1254         for (int h = 0; h < HEIGHT; h++)
1255         {
1256             if (h < step && isBitSet(resultBits, 0))
1257                 reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
1258             if (h >= step && h < (step * 2) && isBitSet(resultBits, 1))
1259                 reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
1260             if (h >= (step * 2) && h < (step * 3) && isBitSet(resultBits, 2))
1261                 reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
1262             if (h >= (step * 3) && isBitSet(resultBits, 3))
1263                 reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
1264         }
1265 }
1266 
ConditionalRenderingUpdateBufferWithDrawTestInstance(Context & context,UpdateBufferWithDrawTestParams testParams)1267 ConditionalRenderingUpdateBufferWithDrawTestInstance::ConditionalRenderingUpdateBufferWithDrawTestInstance(
1268     Context &context, UpdateBufferWithDrawTestParams testParams)
1269     : ConditionalRenderingBaseTestInstance(context)
1270     , m_testParams(testParams)
1271 {
1272 }
1273 
createAndUpdateDescriptorSets(void)1274 void ConditionalRenderingUpdateBufferWithDrawTestInstance::createAndUpdateDescriptorSets(void)
1275 {
1276     //the same descriptor set layout can be used for the creation of both descriptor sets
1277     const VkDescriptorSetAllocateInfo allocInfo = {
1278         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, //VkStructureType                        sType
1279         DE_NULL,                                        //const void*                            pNext
1280         *m_descriptorPool,                              //VkDescriptorPool                        descriptorPool
1281         1u,                                             //uint32_t                                setLayoutCount
1282         &(m_descriptorSetLayout.get())                  //const VkDescriptorSetLayout*            pSetLayouts
1283     };
1284 
1285     m_descriptorSet = allocateDescriptorSet(m_vkd, m_device, &allocInfo);
1286     VkDescriptorBufferInfo descriptorInfo =
1287         makeDescriptorBufferInfo(m_vertexBuffer->object(), (VkDeviceSize)0u, sizeof(float) * 16);
1288 
1289     DescriptorSetUpdateBuilder()
1290         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
1291                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
1292         .update(m_vkd, m_device);
1293 
1294     m_descriptorSetUpdate = allocateDescriptorSet(m_vkd, m_device, &allocInfo);
1295     VkDescriptorBufferInfo descriptorInfoUpdate =
1296         makeDescriptorBufferInfo(m_conditionalRenderingBuffer->object(), (VkDeviceSize)0u, sizeof(uint32_t));
1297 
1298     DescriptorSetUpdateBuilder()
1299         .writeSingle(*m_descriptorSetUpdate, DescriptorSetUpdateBuilder::Location::binding(0u),
1300                      VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfoUpdate)
1301         .update(m_vkd, m_device);
1302 }
1303 
createPipelines(void)1304 void ConditionalRenderingUpdateBufferWithDrawTestInstance::createPipelines(void)
1305 {
1306     const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(WIDTH, HEIGHT)));
1307     const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(WIDTH, HEIGHT)));
1308     const VkPrimitiveTopology topology                                = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
1309     const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1310         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, //VkStructureType                                sType
1311         DE_NULL, //const void*                                    pNext
1312         0u,      //vkPipelineVertexInputStateCreateFlags            flags
1313         0u,      //uint32_t                                        bindingCount
1314         DE_NULL, //const VkVertexInputBindingDescription*        pVertexBindingDescriptions
1315         0u,      //uint32_t                                        attributeCount
1316         DE_NULL, //const VkVertexInputAttributeDescription*        pVertexAttributeDescriptions
1317     };
1318 
1319     m_pipelineDraw = makeGraphicsPipeline(
1320         m_vkd,                       //const DeviceInterface&                        vk
1321         m_device,                    //const VkDevice                                device
1322         *m_pipelineLayout,           //const VkPipelineLayout                        pipelineLayout
1323         *m_vertexShaderModuleDraw,   //const VkShaderModule                            vertexShaderModule
1324         DE_NULL,                     //const VkShaderModule                            tessellationControlShaderModule
1325         DE_NULL,                     //const VkShaderModule                            tessellationEvalShaderModule
1326         DE_NULL,                     //const VkShaderModule                            geometryShaderModule
1327         *m_fragmentShaderModuleDraw, //const VkShaderModule                            fragmentShaderModule
1328         *m_renderPass,               //const VkRenderPass                            renderPass
1329         viewports,                   //const std::vector<VkViewport>&                viewports
1330         scissors,                    //const std::vector<VkRect2D>&                    scissors
1331         topology,                    //const VkPrimitiveTopology                        topology
1332         0u,                          //const uint32_t                                subpass
1333         0u,                          //const uint32_t                                patchControlPoints
1334         &vertexInputStateParams);    //const VkPipelineVertexInputStateCreateInfo*    vertexInputStateCreateInfo
1335 
1336     m_pipelineUpdate = makeGraphicsPipeline(
1337         m_vkd,                       //const DeviceInterface&                        vk
1338         m_device,                    //const VkDevice                                device
1339         *m_pipelineLayout,           //const VkPipelineLayout                        pipelineLayout
1340         *m_vertexShaderModuleUpdate, //const VkShaderModule                            vertexShaderModule
1341         DE_NULL,                     //const VkShaderModule                            tessellationControlShaderModule
1342         DE_NULL,                     //const VkShaderModule                            tessellationEvalShaderModule
1343         DE_NULL,                     //const VkShaderModule                            geometryShaderModule
1344         *m_fragmentShaderModuleDiscard, //const VkShaderModule                            fragmentShaderModule
1345         *m_renderPass,                  //const VkRenderPass                            renderPass
1346         viewports,                      //const std::vector<VkViewport>&                viewports
1347         scissors,                       //const std::vector<VkRect2D>&                    scissors
1348         topology,                       //const VkPrimitiveTopology                        topology
1349         0u,                             //const uint32_t                                subpass
1350         0u,                             //const uint32_t                                patchControlPoints
1351         &vertexInputStateParams);       //const VkPipelineVertexInputStateCreateInfo*    vertexInputStateCreateInfo
1352 }
1353 
createRenderPass(VkFormat format,VkImageLayout layout)1354 void ConditionalRenderingUpdateBufferWithDrawTestInstance::createRenderPass(VkFormat format, VkImageLayout layout)
1355 {
1356     RenderPassCreateInfo renderPassCreateInfo;
1357 
1358     renderPassCreateInfo.addAttachment(
1359         AttachmentDescription(format, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE,
1360                               VK_ATTACHMENT_LOAD_OP_DONT_CARE, VK_ATTACHMENT_STORE_OP_STORE,
1361                               isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1362                                                              VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1363                               isDepthStencilFormat(format) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1364                                                              VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
1365 
1366     const VkAttachmentReference attachmentReference = {
1367         0u,    // uint32_t                attachment
1368         layout // VkImageLayout        layout
1369     };
1370 
1371     renderPassCreateInfo.addSubpass(
1372         SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, DE_NULL, isDepthStencilFormat(format) ? 0 : 1,
1373                            isDepthStencilFormat(format) ? DE_NULL : &attachmentReference, DE_NULL,
1374                            isDepthStencilFormat(format) ? attachmentReference : AttachmentReference(), 0, DE_NULL));
1375 
1376     VkSubpassDependency dependency = {
1377         0,                                               //uint32_t srcSubpass;
1378         0,                                               //uint32_t dstSubpass;
1379         VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,             //VkPipelineStageFlags srcStageMask;
1380         VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT, //VkPipelineStageFlags dstStageMask;
1381         VK_ACCESS_SHADER_WRITE_BIT,                      //VkAccessFlags srcAccessMask;
1382         VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,    //VkAccessFlags dstAccessMask;
1383         (VkDependencyFlags)0                             //VkDependencyFlags dependencyFlags;
1384     };
1385 
1386     renderPassCreateInfo.addDependency(dependency);
1387 
1388     m_renderPass = vk::createRenderPass(m_vkd, m_device, &renderPassCreateInfo);
1389 }
1390 
iterate(void)1391 tcu::TestStatus ConditionalRenderingUpdateBufferWithDrawTestInstance::iterate(void)
1392 {
1393     const uint32_t queueFamilyIndex     = m_context.getUniversalQueueFamilyIndex();
1394     VkClearColorValue clearColorInitial = {{0.0f, 0.0f, 1.0f, 1.0f}};
1395 
1396     m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1397 
1398     createInitBufferWithPredicate(m_testParams.m_memoryType, m_testParams.m_testParams, true, 0,
1399                                   VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1400 
1401     createTargetColorImageAndImageView();
1402     createResultBuffer(VK_FORMAT_R8G8B8A8_UNORM);
1403     createVertexBuffer();
1404 
1405     m_cmdBufferPrimary = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1406 
1407     createRenderPass(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
1408     createFramebuffer(m_colorTargetView.get());
1409 
1410     DescriptorSetLayoutBuilder builder;
1411     builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
1412     m_descriptorSetLayout = builder.build(m_vkd, m_device, (VkDescriptorSetLayoutCreateFlags)0);
1413 
1414     m_descriptorPool = DescriptorPoolBuilder()
1415                            .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2)
1416                            .build(m_vkd, m_device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 2u);
1417 
1418     createPipelineLayout();
1419     createAndUpdateDescriptorSets();
1420 
1421     m_vertexShaderModuleDraw =
1422         createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("position_only.vert"), 0);
1423     m_fragmentShaderModuleDraw =
1424         createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("only_color_out.frag"), 0);
1425     m_vertexShaderModuleUpdate =
1426         createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("update.vert"), 0);
1427     m_fragmentShaderModuleDiscard =
1428         createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("discard.frag"), 0);
1429 
1430     createPipelines();
1431 
1432     VkConditionalRenderingBeginInfoEXT conditionalRenderingBeginInfo = {
1433         VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, //VkStructureType sType;
1434         DE_NULL,                                                //const void* pNext;
1435         m_conditionalRenderingBuffer->object(),                 //VkBuffer buffer;
1436         0,                                                      //VkDeviceSize offset;
1437         VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT               //VkConditionalRenderingFlagsEXT flags;
1438     };
1439 
1440     beginCommandBuffer(m_vkd, *m_cmdBufferPrimary);
1441 
1442     imageMemoryBarrier(m_colorTargetImage->object(),         //VkImage                            image
1443                        0u,                                   //VkAccessFlags                        srcAccessMask
1444                        VK_ACCESS_TRANSFER_WRITE_BIT,         //VkAccessFlags                        dstAccessMask
1445                        VK_IMAGE_LAYOUT_UNDEFINED,            //VkImageLayout                        oldLayout
1446                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, //VkImageLayout                        newLayout
1447                        VK_PIPELINE_STAGE_TRANSFER_BIT,       //VkPipelineStageFlags                srcStageMask
1448                        VK_PIPELINE_STAGE_TRANSFER_BIT,       //VkPipelineStageFlags                dstStageMask
1449                        VK_IMAGE_ASPECT_COLOR_BIT);           //VkImageAspectFlags                flags
1450 
1451     clearWithClearColorImage(clearColorInitial);
1452 
1453     imageMemoryBarrier(m_colorTargetImage->object(), //VkImage                            image
1454                        VK_ACCESS_TRANSFER_WRITE_BIT, //VkAccessFlags                        srcAccessMask
1455                        VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1456                            VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags                        dstAccessMask
1457                        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,     //VkImageLayout                        oldLayout
1458                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout                        newLayout
1459                        VK_PIPELINE_STAGE_TRANSFER_BIT,           //VkPipelineStageFlags                srcStageMask
1460                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags                dstStageMask
1461                        VK_IMAGE_ASPECT_COLOR_BIT);                    //VkImageAspectFlags                flags
1462 
1463     beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
1464 
1465     m_vkd.cmdBindPipeline(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineUpdate);
1466     m_vkd.cmdBindDescriptorSets(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1,
1467                                 &(*m_descriptorSetUpdate), 0, DE_NULL);
1468 
1469     draw();
1470 
1471     endRenderPass(m_vkd, *m_cmdBufferPrimary);
1472 
1473     bufferMemoryBarrier(m_conditionalRenderingBuffer->object(), m_conditionalRenderingBufferOffset, sizeof(uint32_t),
1474                         VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
1475                         VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT);
1476 
1477     beginRenderPass(m_vkd, *m_cmdBufferPrimary, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, WIDTH, HEIGHT));
1478 
1479     m_vkd.cmdBindPipeline(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineDraw);
1480     m_vkd.cmdBindDescriptorSets(*m_cmdBufferPrimary, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1,
1481                                 &(*m_descriptorSet), 0, DE_NULL);
1482 
1483     m_vkd.cmdBeginConditionalRenderingEXT(*m_cmdBufferPrimary, &conditionalRenderingBeginInfo);
1484     draw();
1485     m_vkd.cmdEndConditionalRenderingEXT(*m_cmdBufferPrimary);
1486 
1487     endRenderPass(m_vkd, *m_cmdBufferPrimary);
1488 
1489     imageMemoryBarrier(m_colorTargetImage->object(), //VkImage                            image
1490                        VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1491                            VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, //VkAccessFlags                        srcAccessMask
1492                        VK_ACCESS_TRANSFER_READ_BIT,              //VkAccessFlags                        dstAccessMask
1493                        VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, //VkImageLayout                        oldLayout
1494                        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,     //VkImageLayout                        newLayout
1495                        VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, //VkPipelineStageFlags                srcStageMask
1496                        VK_PIPELINE_STAGE_TRANSFER_BIT,                //VkPipelineStageFlags                dstStageMask
1497                        VK_IMAGE_ASPECT_COLOR_BIT);                    //VkImageAspectFlags                flags
1498 
1499     copyResultImageToBuffer(VK_IMAGE_ASPECT_COLOR_BIT, m_colorTargetImage->object());
1500 
1501     const vk::VkBufferMemoryBarrier bufferMemoryBarrier = {vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1502                                                            DE_NULL,
1503                                                            vk::VK_ACCESS_TRANSFER_WRITE_BIT,
1504                                                            vk::VK_ACCESS_HOST_READ_BIT,
1505                                                            VK_QUEUE_FAMILY_IGNORED,
1506                                                            VK_QUEUE_FAMILY_IGNORED,
1507                                                            m_resultBuffer->object(),
1508                                                            0u,
1509                                                            VK_WHOLE_SIZE};
1510 
1511     m_vkd.cmdPipelineBarrier(*m_cmdBufferPrimary, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
1512                              0u, 0u, DE_NULL, 1u, &bufferMemoryBarrier, 0u, DE_NULL);
1513 
1514     endCommandBuffer(m_vkd, *m_cmdBufferPrimary);
1515 
1516     submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBufferPrimary);
1517 
1518     invalidateMappedMemoryRange(m_vkd, m_device, m_resultBuffer->getBoundMemory().getMemory(),
1519                                 m_resultBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
1520 
1521     tcu::ConstPixelBufferAccess result(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1),
1522                                        m_resultBuffer->getBoundMemory().getHostPtr());
1523 
1524     std::vector<float> referenceData(4 * WIDTH * HEIGHT, 0.0f);
1525     tcu::PixelBufferAccess reference(mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM), tcu::IVec3(WIDTH, HEIGHT, 1),
1526                                      referenceData.data());
1527 
1528     m_testParams.m_testParams ? prepareReferenceImageOneColor(reference, tcu::Vec4(0, 1, 0, 1)) :
1529                                 prepareReferenceImageOneColor(reference, clearColorInitial);
1530 
1531     if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result,
1532                                     tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
1533         return tcu::TestStatus::fail("Fail");
1534 
1535     return tcu::TestStatus::pass("Pass");
1536 }
1537 
1538 struct AddProgramsDraw
1539 {
initvkt::conditional::__anonafd749590111::AddProgramsDraw1540     void init(SourceCollections &sources, DrawTestParams testParams) const
1541     {
1542         DE_UNREF(testParams);
1543 
1544         const char *const vertexShader = "#version 430\n"
1545 
1546                                          "layout(std430, binding = 0) buffer BufferPos {\n"
1547                                          "vec4 p[100];\n"
1548                                          "} pos;\n"
1549 
1550                                          "out gl_PerVertex{\n"
1551                                          "vec4 gl_Position;\n"
1552                                          "};\n"
1553 
1554                                          "void main() {\n"
1555                                          "gl_Position = pos.p[gl_VertexIndex];\n"
1556                                          "}\n";
1557 
1558         sources.glslSources.add("position_only.vert") << glu::VertexSource(vertexShader);
1559 
1560         const char *const fragmentShader =
1561             "#version 430\n"
1562 
1563             "layout(location = 0) out vec4 my_FragColor;\n"
1564 
1565             "layout (push_constant) uniform AreaSelect {\n"
1566             "    ivec4 number;\n"
1567             "} Area;\n"
1568 
1569             "void main() {\n"
1570             "    if((gl_FragCoord.y < 64) && (Area.number.x != 0)) discard;\n"
1571             "    if((gl_FragCoord.y >= 64) && (gl_FragCoord.y < 128) && (Area.number.x != 1)) discard;\n"
1572             "    if((gl_FragCoord.y >= 128) && (gl_FragCoord.y < 192) && (Area.number.x != 2)) discard;\n"
1573             "    if((gl_FragCoord.y >= 192) && (Area.number.x != 3)) discard;\n"
1574             "    my_FragColor = vec4(0,1,0,1);\n"
1575             "}\n";
1576 
1577         sources.glslSources.add("only_color_out.frag") << glu::FragmentSource(fragmentShader);
1578     }
1579 };
1580 
1581 struct AddProgramsUpdateBufferUsingRendering
1582 {
initvkt::conditional::__anonafd749590111::AddProgramsUpdateBufferUsingRendering1583     void init(SourceCollections &sources, UpdateBufferWithDrawTestParams testParams) const
1584     {
1585         std::string atomicOperation =
1586             (testParams.m_testParams ? "atomicMin(predicate.p, 0);" : "atomicMax(predicate.p, 1);");
1587 
1588         std::string vertexShaderUpdate = "#version 430\n"
1589 
1590                                          "layout(std430, binding = 0) buffer Predicate {\n"
1591                                          "uint p;\n"
1592                                          "} predicate;\n"
1593 
1594                                          "out gl_PerVertex{\n"
1595                                          "vec4 gl_Position;\n"
1596                                          "};\n"
1597 
1598                                          "void main() {\n" +
1599                                          atomicOperation +
1600                                          "gl_Position = vec4(1.0);\n"
1601                                          "}\n";
1602 
1603         sources.glslSources.add("update.vert") << glu::VertexSource(vertexShaderUpdate);
1604 
1605         const char *const vertexShaderDraw = "#version 430\n"
1606 
1607                                              "layout(std430, binding = 0) buffer BufferPos {\n"
1608                                              "vec4 p[100];\n"
1609                                              "} pos;\n"
1610 
1611                                              "out gl_PerVertex{\n"
1612                                              "vec4 gl_Position;\n"
1613                                              "};\n"
1614 
1615                                              "void main() {\n"
1616                                              "gl_Position = pos.p[gl_VertexIndex];\n"
1617                                              "}\n";
1618 
1619         sources.glslSources.add("position_only.vert") << glu::VertexSource(vertexShaderDraw);
1620 
1621         const char *const fragmentShaderDiscard = "#version 430\n"
1622 
1623                                                   "layout(location = 0) out vec4 my_FragColor;\n"
1624 
1625                                                   "void main() {\n"
1626                                                   "    discard;\n"
1627                                                   "}\n";
1628 
1629         sources.glslSources.add("discard.frag") << glu::FragmentSource(fragmentShaderDiscard);
1630 
1631         const char *const fragmentShaderDraw = "#version 430\n"
1632 
1633                                                "layout(location = 0) out vec4 my_FragColor;\n"
1634 
1635                                                "void main() {\n"
1636                                                "    my_FragColor = vec4(0,1,0,1);\n"
1637                                                "}\n";
1638 
1639         sources.glslSources.add("only_color_out.frag") << glu::FragmentSource(fragmentShaderDraw);
1640     }
1641 };
1642 
checkSupport(Context & context)1643 void checkSupport(Context &context)
1644 {
1645     context.requireDeviceFunctionality("VK_EXT_conditional_rendering");
1646 }
1647 
checkFan(Context & context)1648 void checkFan(Context &context)
1649 {
1650     checkSupport(context);
1651 
1652     if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
1653         !context.getPortabilitySubsetFeatures().triangleFans)
1654     {
1655         TCU_THROW(NotSupportedError,
1656                   "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
1657     }
1658 }
1659 
checkMaintenance5Support(Context & context)1660 void checkMaintenance5Support(Context &context)
1661 {
1662     checkFan(context);
1663     context.requireDeviceFunctionality("VK_KHR_maintenance5");
1664 }
1665 
checkFanAndVertexStores(Context & context)1666 void checkFanAndVertexStores(Context &context)
1667 {
1668     checkFan(context);
1669 
1670     const auto &features = context.getDeviceFeatures();
1671     if (!features.vertexPipelineStoresAndAtomics)
1672         TCU_THROW(NotSupportedError, "Vertex pipeline stores and atomics not supported");
1673 }
1674 
1675 } // unnamed namespace
1676 
ConditionalRenderingDrawAndClearTests(tcu::TestContext & testCtx)1677 ConditionalRenderingDrawAndClearTests::ConditionalRenderingDrawAndClearTests(tcu::TestContext &testCtx)
1678     : TestCaseGroup(testCtx, "draw_clear")
1679 {
1680     /* Left blank on purpose */
1681 }
1682 
init(void)1683 void ConditionalRenderingDrawAndClearTests::init(void)
1684 {
1685     tcu::TestCaseGroup *clear = new tcu::TestCaseGroup(m_testCtx, "clear");
1686     tcu::TestCaseGroup *color = new tcu::TestCaseGroup(m_testCtx, "color");
1687     tcu::TestCaseGroup *depth = new tcu::TestCaseGroup(m_testCtx, "depth");
1688     tcu::TestCaseGroup *draw  = new tcu::TestCaseGroup(m_testCtx, "draw");
1689 
1690     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearColorTestGrid); testNdx++)
1691         color->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance,
1692                                                         ClearTestParams, FunctionSupport0>(
1693             m_testCtx, generateClearTestName(clearColorTestGrid[testNdx]), clearColorTestGrid[testNdx], checkSupport));
1694 
1695     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearDepthTestGrid); testNdx++)
1696         depth->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance,
1697                                                         ClearTestParams, FunctionSupport0>(
1698             m_testCtx, generateClearTestName(clearDepthTestGrid[testNdx]), clearDepthTestGrid[testNdx], checkSupport));
1699 
1700     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearColorTwiceGrid); testNdx++)
1701         color->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance,
1702                                                         ClearTestParams, FunctionSupport0>(
1703             m_testCtx, "clear_attachment_twice_" + generateClearTestName(clearColorTwiceGrid[testNdx]),
1704             clearColorTwiceGrid[testNdx], checkSupport));
1705 
1706     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(clearDepthTwiceGrid); testNdx++)
1707         depth->addChild(new InstanceFactory1WithSupport<ConditionalRenderingClearAttachmentsTestInstance,
1708                                                         ClearTestParams, FunctionSupport0>(
1709             m_testCtx, "clear_attachment_twice_" + generateClearTestName(clearDepthTwiceGrid[testNdx]),
1710             clearDepthTwiceGrid[testNdx], checkSupport));
1711 
1712     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(drawTestGrid); testNdx++)
1713         draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingDrawTestInstance, DrawTestParams,
1714                                                        FunctionSupport0, AddProgramsDraw>(
1715             m_testCtx, generateDrawTestName(testNdx, drawTestGrid[testNdx]), AddProgramsDraw(), drawTestGrid[testNdx],
1716             checkFan));
1717 
1718 #ifndef CTS_USES_VULKANSC
1719     DrawTestParams maintenance5TestParams    = drawTestGrid[5];
1720     maintenance5TestParams.m_useMaintenance5 = true;
1721     draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingDrawTestInstance, DrawTestParams,
1722                                                    FunctionSupport0, AddProgramsDraw>(
1723         m_testCtx, "maintenance5", AddProgramsDraw(), maintenance5TestParams, checkMaintenance5Support));
1724 #endif
1725 
1726     for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(UpdateBufferWithDrawTestGrind); testNdx++)
1727         draw->addChild(new InstanceFactory1WithSupport<ConditionalRenderingUpdateBufferWithDrawTestInstance,
1728                                                        UpdateBufferWithDrawTestParams, FunctionSupport0,
1729                                                        AddProgramsUpdateBufferUsingRendering>(
1730             m_testCtx, generateUpdateBufferWithDrawTestName(UpdateBufferWithDrawTestGrind[testNdx]),
1731             AddProgramsUpdateBufferUsingRendering(), UpdateBufferWithDrawTestGrind[testNdx], checkFanAndVertexStores));
1732 
1733     clear->addChild(color);
1734     clear->addChild(depth);
1735     addChild(clear);
1736     addChild(draw);
1737 }
1738 
1739 } // namespace conditional
1740 } // namespace vkt
1741