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