1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2022 LunarG, Inc.
6  * Copyright (c) 2022 The Khronos Group Inc.
7  * Copyright (c) 2022 Google LLC
8  * Copyright (c) 2023 Nintendo
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Dynamic State Clear Tests
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vktDynamicStateClearTests.hpp"
28 
29 #include "vktDynamicStateBaseClass.hpp"
30 #include "vktDynamicStateTestCaseUtil.hpp"
31 
32 #include "vkImageUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 
35 #include "tcuImageCompare.hpp"
36 #include "tcuTextureUtil.hpp"
37 #include "tcuRGBA.hpp"
38 #include "vkQueryUtil.hpp"
39 
40 namespace vkt
41 {
42 namespace DynamicState
43 {
44 
45 using namespace Draw;
46 
47 namespace
48 {
49 
50 class CmdBaseCase : public DynamicStateBaseClass
51 {
52 public:
CmdBaseCase(Context & context,vk::PipelineConstructionType pipelineConstructionType,const char * vertexShaderName,const char * fragmentShaderName)53     CmdBaseCase(Context &context, vk::PipelineConstructionType pipelineConstructionType, const char *vertexShaderName,
54                 const char *fragmentShaderName)
55         : DynamicStateBaseClass(context, pipelineConstructionType, vertexShaderName, fragmentShaderName)
56     {
57         m_topology = vk::VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
58 
59         m_data.push_back(PositionColorVertex(tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
60         m_data.push_back(PositionColorVertex(tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f), tcu::RGBA::green().toVec()));
61 
62         m_attachmentState.blendEnable         = VK_TRUE;
63         m_attachmentState.srcColorBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
64         m_attachmentState.dstColorBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR;
65         m_attachmentState.colorBlendOp        = vk::VK_BLEND_OP_ADD;
66         m_attachmentState.srcAlphaBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
67         m_attachmentState.dstAlphaBlendFactor = vk::VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA;
68         m_attachmentState.alphaBlendOp        = vk::VK_BLEND_OP_ADD;
69     }
70 
buildReferenceFrame(int lineWidth)71     virtual tcu::Texture2D buildReferenceFrame(int lineWidth)
72     {
73         (void)lineWidth;
74         DE_ASSERT(false);
75         return tcu::Texture2D(tcu::TextureFormat(), 0, 0);
76     }
77 
command(bool)78     virtual void command(bool)
79     {
80         DE_ASSERT(false);
81     }
82 
iterate(void)83     virtual tcu::TestStatus iterate(void)
84     {
85         tcu::TestLog &log                           = m_context.getTestContext().getLog();
86         const vk::InstanceInterface &vkInstance     = m_context.getInstanceInterface();
87         const vk::VkPhysicalDevice vkPhysicalDevice = m_context.getPhysicalDevice();
88         const vk::VkQueue queue                     = m_context.getUniversalQueue();
89         const vk::VkDevice device                   = m_context.getDevice();
90 
91         const float lineWidth = getPhysicalDeviceProperties(vkInstance, vkPhysicalDevice).limits.lineWidthRange[1];
92 
93         vk::beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
94 
95         // set dynamic states
96         const vk::VkViewport viewport = {0.0f, 0.0f, static_cast<float>(WIDTH / 2), static_cast<float>(HEIGHT / 2),
97                                          0.0f, 0.0f};
98         const vk::VkRect2D scissor    = {{0, 0}, {WIDTH, HEIGHT}};
99 
100         setDynamicViewportState(1, &viewport, &scissor);
101         setDynamicRasterizationState(lineWidth);
102         setDynamicBlendState(0.75f, 0.75f, 0.75f, 0.75f);
103         setDynamicDepthStencilState(0.0f, 1.0f);
104 
105         const vk::VkExtent3D imageExtent = {WIDTH, HEIGHT, 1};
106 
107         vk::VkImageFormatProperties imageFormatProperties(getPhysicalDeviceImageFormatProperties(
108             vkInstance, vkPhysicalDevice, m_colorAttachmentFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL,
109             vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
110                 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT,
111             0));
112         if ((imageFormatProperties.sampleCounts & m_samples) == 0)
113             TCU_THROW(NotSupportedError, "Color image type not supported");
114 
115         const ImageCreateInfo imageCreateInfo(
116             vk::VK_IMAGE_TYPE_2D, m_colorAttachmentFormat, imageExtent, 1, 1, m_samples, vk::VK_IMAGE_TILING_OPTIMAL,
117             vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
118                 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
119         m_image = Image::createAndAlloc(m_vk, device, imageCreateInfo, m_context.getDefaultAllocator(),
120                                         m_context.getUniversalQueueFamilyIndex());
121 
122         if (m_samples > 1)
123         {
124             transition2DImage(m_vk, *m_cmdBuffer, m_image->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT,
125                               vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, 0u,
126                               vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
127                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
128             transition2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT,
129                               vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, 0u,
130                               vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
131                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
132         }
133         else
134         {
135             transition2DImage(m_vk, *m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT,
136                               vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, 0u,
137                               vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
138                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
139             transition2DImage(m_vk, *m_cmdBuffer, m_image->object(), vk::VK_IMAGE_ASPECT_COLOR_BIT,
140                               vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, 0u,
141                               vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
142                               vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
143         }
144 
145         // should not interfere with dynamic state
146         command(false);
147 
148         const vk::VkClearColorValue clearColor = {{0.0f, 0.0f, 0.0f, 1.0f}};
149         beginRenderPassWithClearColor(clearColor, true, true);
150 
151         command(true);
152 
153         m_pipeline.bind(*m_cmdBuffer);
154 
155         const vk::VkDeviceSize vertexBufferOffset = 0;
156         const vk::VkBuffer vertexBuffer           = m_vertexBuffer->object();
157         m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
158 
159         m_vk.cmdDraw(*m_cmdBuffer, 2, 1, 0, 0);
160 
161         m_renderPass.end(m_vk, *m_cmdBuffer);
162         endCommandBuffer(m_vk, *m_cmdBuffer);
163 
164         submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
165 
166         // validation
167         {
168             tcu::Texture2D referenceFrame = buildReferenceFrame(static_cast<int>(lineWidth));
169 
170             const vk::VkOffset3D zeroOffset = {0, 0, 0};
171             const tcu::ConstPixelBufferAccess renderedFrame =
172                 m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), vk::VK_IMAGE_LAYOUT_GENERAL,
173                                                 zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT);
174 
175             if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", referenceFrame.getLevel(0), renderedFrame,
176                                    0.05f, tcu::COMPARE_LOG_RESULT))
177             {
178                 return tcu::TestStatus(QP_TEST_RESULT_FAIL, "Image verification failed");
179             }
180 
181             return tcu::TestStatus(QP_TEST_RESULT_PASS, "Image verification passed");
182         }
183     }
184 
185     de::SharedPtr<Draw::Image> m_image;
186     vk::VkSampleCountFlagBits m_samples = vk::VK_SAMPLE_COUNT_1_BIT;
187 };
188 
189 class ClearTestInstance : public CmdBaseCase
190 {
191 public:
ClearTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)192     ClearTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
193         : CmdBaseCase(context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX],
194                       shaders[glu::SHADERTYPE_FRAGMENT])
195     {
196         DynamicStateBaseClass::initialize();
197     }
198 
command(bool renderPassActive)199     virtual void command(bool renderPassActive)
200     {
201         if (renderPassActive)
202         {
203             // Clear attachment
204             vk::VkClearValue clearValue;
205             clearValue.color.float32[0]                 = 1.0f;
206             clearValue.color.float32[1]                 = 1.0f;
207             clearValue.color.float32[2]                 = 1.0f;
208             clearValue.color.float32[3]                 = 1.0f;
209             const vk::VkClearAttachment clearAttachment = {
210                 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags    aspectMask
211                 0u,                            // uint32_t                colorAttachment
212                 clearValue                     // VkClearValue            clearValue
213             };
214             const vk::VkClearRect rect = {{{0, 0}, {WIDTH, HEIGHT}}, 0, 1};
215             m_vk.cmdClearAttachments(*m_cmdBuffer, 1, &clearAttachment, 1, &rect);
216         }
217     }
218 
buildReferenceFrame(int lineWidth)219     virtual tcu::Texture2D buildReferenceFrame(int lineWidth)
220     {
221         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
222         referenceFrame.allocLevel(0);
223 
224         const int32_t frameWidth  = referenceFrame.getWidth();
225         const int32_t frameHeight = referenceFrame.getHeight();
226 
227         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
228 
229         for (int y = 0; y < frameHeight; y++)
230         {
231             for (int x = 0; x < frameWidth; x++)
232             {
233                 if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 &&
234                     x < frameWidth / 2)
235                     referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.25f, 0.5f, 0.25f, 0.5f), x, y);
236                 else
237                     referenceFrame.getLevel(0).setPixel(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f), x, y);
238             }
239         }
240 
241         return referenceFrame;
242     }
243 };
244 
245 class BlitTestInstance : public CmdBaseCase
246 {
247 public:
BlitTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)248     BlitTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
249         : CmdBaseCase(context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX],
250                       shaders[glu::SHADERTYPE_FRAGMENT])
251     {
252         DynamicStateBaseClass::initialize();
253     }
254 
command(bool renderPassActive)255     virtual void command(bool renderPassActive)
256     {
257         if (!renderPassActive)
258         {
259             const vk::VkImageBlit blitRegion = {// Src
260                                                 {
261                                                     vk::VK_IMAGE_ASPECT_COLOR_BIT,
262                                                     0, // mipLevel
263                                                     0, // arrayLayer
264                                                     1  // layerCount
265                                                 },
266                                                 {
267                                                     {0, 0, 0},
268                                                     {WIDTH, HEIGHT, 1},
269                                                 },
270 
271                                                 // Dst
272                                                 {
273                                                     vk::VK_IMAGE_ASPECT_COLOR_BIT,
274                                                     0, // mipLevel
275                                                     0, // arrayLayer
276                                                     1  // layerCount
277                                                 },
278                                                 {{0, 0, 0}, {WIDTH, HEIGHT, 1u}}};
279             m_vk.cmdBlitImage(*m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
280                               m_image->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &blitRegion, vk::VK_FILTER_NEAREST);
281         }
282     }
283 
buildReferenceFrame(int lineWidth)284     virtual tcu::Texture2D buildReferenceFrame(int lineWidth)
285     {
286         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
287         referenceFrame.allocLevel(0);
288 
289         const int32_t frameWidth  = referenceFrame.getWidth();
290         const int32_t frameHeight = referenceFrame.getHeight();
291 
292         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
293 
294         for (int y = 0; y < frameHeight; y++)
295         {
296             for (int x = 0; x < frameWidth; x++)
297             {
298                 if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 &&
299                     x < frameWidth / 2)
300                     referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.25f, 0.0f, 0.5f), x, y);
301             }
302         }
303 
304         return referenceFrame;
305     }
306 };
307 
308 class CopyTestInstance : public CmdBaseCase
309 {
310 public:
CopyTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)311     CopyTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
312         : CmdBaseCase(context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX],
313                       shaders[glu::SHADERTYPE_FRAGMENT])
314     {
315         DynamicStateBaseClass::initialize();
316     }
317 
command(bool renderPassActive)318     virtual void command(bool renderPassActive)
319     {
320         if (!renderPassActive)
321         {
322             const vk::VkImageSubresourceLayers imgSubResLayers = {
323                 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags  aspectMask;
324                 0u,                            // uint32_t            mipLevel;
325                 0u,                            // uint32_t            baseArrayLayer;
326                 1u,                            // uint32_t            layerCount;
327             };
328             const vk::VkOffset3D offset = {0, 0, 0};
329             const vk::VkExtent3D extent = {WIDTH, HEIGHT, 1};
330 
331             const vk::VkImageCopy copyRegion = {
332                 imgSubResLayers, // VkImageSubresourceCopy  srcSubresource;
333                 offset,          // VkOffset3D              srcOffset;
334                 imgSubResLayers, // VkImageSubresourceCopy  destSubresource;
335                 offset,          // VkOffset3D              destOffset;
336                 extent,          // VkExtent3D              extent;
337             };
338 
339             m_vk.cmdCopyImage(*m_cmdBuffer, m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
340                               m_image->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &copyRegion);
341         }
342     }
343 
buildReferenceFrame(int lineWidth)344     virtual tcu::Texture2D buildReferenceFrame(int lineWidth)
345     {
346         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
347         referenceFrame.allocLevel(0);
348 
349         const int32_t frameWidth  = referenceFrame.getWidth();
350         const int32_t frameHeight = referenceFrame.getHeight();
351 
352         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
353 
354         for (int y = 0; y < frameHeight; y++)
355         {
356             for (int x = 0; x < frameWidth; x++)
357             {
358                 if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 &&
359                     x < frameWidth / 2)
360                     referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.25f, 0.0f, 0.5f), x, y);
361             }
362         }
363 
364         return referenceFrame;
365     }
366 };
367 
368 class ResolveTestInstance : public CmdBaseCase
369 {
370 public:
ResolveTestInstance(Context & context,vk::PipelineConstructionType pipelineConstructionType,ShaderMap shaders)371     ResolveTestInstance(Context &context, vk::PipelineConstructionType pipelineConstructionType, ShaderMap shaders)
372         : CmdBaseCase(context, pipelineConstructionType, shaders[glu::SHADERTYPE_VERTEX],
373                       shaders[glu::SHADERTYPE_FRAGMENT])
374     {
375         DynamicStateBaseClass::initialize();
376 
377         m_samples = vk::VK_SAMPLE_COUNT_2_BIT;
378     }
379 
command(bool renderPassActive)380     virtual void command(bool renderPassActive)
381     {
382         if (!renderPassActive)
383         {
384             const vk::VkImageSubresourceLayers imgSubResLayers = {
385                 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags  aspectMask;
386                 0u,                            // uint32_t            mipLevel;
387                 0u,                            // uint32_t            baseArrayLayer;
388                 1u,                            // uint32_t            layerCount;
389             };
390             const vk::VkOffset3D offset = {0, 0, 0};
391             const vk::VkExtent3D extent = {WIDTH, HEIGHT, 1};
392 
393             const vk::VkImageResolve resolveRegion = {
394                 imgSubResLayers, // VkImageSubresourceLayers srcSubresource;
395                 offset,          // VkOffset3D srcOffset;
396                 imgSubResLayers, // VkImageSubresourceLayers dstSubresource;
397                 offset,          // VkOffset3D dstOffset;
398                 extent,          // VkExtent3D extent;
399             };
400             m_vk.cmdResolveImage(*m_cmdBuffer, m_image->object(), vk::VK_IMAGE_LAYOUT_GENERAL,
401                                  m_colorTargetImage->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &resolveRegion);
402 
403             const vk::VkImageSubresourceRange subresourceRange = {
404                 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
405                 0u,                            // uint32_t baseMipLevel;
406                 1u,                            // uint32_t levelCount;
407                 0u,                            // uint32_t baseArrayLayer;
408                 1u,                            // uint32_t layerCount;
409             };
410             const vk::VkImageMemoryBarrier imageBarrier = {
411                 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
412                 DE_NULL,                                    // const void* pNext;
413                 vk::VK_ACCESS_TRANSFER_WRITE_BIT,           // VkAccessFlags srcAccessMask;
414                 vk::VK_ACCESS_TRANSFER_READ_BIT,            // VkAccessFlags dstAccessMask;
415                 vk::VK_IMAGE_LAYOUT_GENERAL,                // VkImageLayout oldLayout;
416                 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,   // VkImageLayout newLayout;
417                 VK_QUEUE_FAMILY_IGNORED,                    // uint32_t srcQueueFamilyIndex;
418                 VK_QUEUE_FAMILY_IGNORED,                    // uint32_t destQueueFamilyIndex;
419                 m_image->object(),                          // VkImage image;
420                 subresourceRange,                           // VkImageSubresourceRange subresourceRange;
421             };
422             m_vk.cmdPipelineBarrier(*m_cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
423                                     vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u,
424                                     &imageBarrier);
425         }
426     }
427 
buildReferenceFrame(int lineWidth)428     virtual tcu::Texture2D buildReferenceFrame(int lineWidth)
429     {
430         tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), WIDTH, HEIGHT);
431         referenceFrame.allocLevel(0);
432 
433         const int32_t frameWidth  = referenceFrame.getWidth();
434         const int32_t frameHeight = referenceFrame.getHeight();
435 
436         tcu::clear(referenceFrame.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
437 
438         for (int y = 0; y < frameHeight; y++)
439         {
440             for (int x = 0; x < frameWidth; x++)
441             {
442                 if (y < frameHeight / 2 && y >= 32 - lineWidth / 2 && y < 32 + lineWidth / 2 && x >= frameWidth / 4 &&
443                     x < frameWidth / 2)
444                     referenceFrame.getLevel(0).setPixel(tcu::Vec4(0.0f, 0.25f, 0.0f, 0.5f), x, y);
445             }
446         }
447 
448         return referenceFrame;
449     }
450 };
451 
452 } // namespace
453 
DynamicStateClearTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)454 DynamicStateClearTests::DynamicStateClearTests(tcu::TestContext &testCtx,
455                                                vk::PipelineConstructionType pipelineConstructionType)
456     : TestCaseGroup(testCtx, "image")
457     , m_pipelineConstructionType(pipelineConstructionType)
458 {
459     /* Left blank on purpose */
460 }
461 
~DynamicStateClearTests()462 DynamicStateClearTests::~DynamicStateClearTests()
463 {
464 }
465 
init(void)466 void DynamicStateClearTests::init(void)
467 {
468     ShaderMap shaderPaths;
469     shaderPaths[glu::SHADERTYPE_VERTEX]   = "vulkan/dynamic_state/VertexFetch.vert";
470     shaderPaths[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag";
471 
472     // Clear attachment after setting dynamic states
473     addChild(new InstanceFactory<ClearTestInstance>(m_testCtx, "clear", m_pipelineConstructionType, shaderPaths));
474     // Blit image after setting dynamic states
475     addChild(new InstanceFactory<BlitTestInstance>(m_testCtx, "blit", m_pipelineConstructionType, shaderPaths));
476     // Copy image after setting dynamic states
477     addChild(new InstanceFactory<CopyTestInstance>(m_testCtx, "copy", m_pipelineConstructionType, shaderPaths));
478     // Resolve image after setting dynamic states
479     addChild(new InstanceFactory<ResolveTestInstance>(m_testCtx, "resolve", m_pipelineConstructionType, shaderPaths));
480 }
481 
482 } // namespace DynamicState
483 } // namespace vkt
484