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