1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  * Copyright (c) 2017 Google Inc.
7  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Differing iterpolation decorations tests
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktDrawDifferingInterpolationTests.hpp"
27 
28 #include "vktDrawBaseClass.hpp"
29 #include "vkQueryUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkTypeUtil.hpp"
32 #include "vktTestGroupUtil.hpp"
33 
34 #include "deDefs.h"
35 #include "deRandom.hpp"
36 #include "deString.h"
37 
38 #include "tcuTestCase.hpp"
39 #include "tcuRGBA.hpp"
40 #include "tcuTextureUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuStringTemplate.hpp"
43 
44 #include "rrRenderer.hpp"
45 
46 #include <string>
47 #include <sstream>
48 
49 namespace vkt
50 {
51 namespace Draw
52 {
53 namespace
54 {
55 using namespace vk;
56 using namespace std;
57 
58 struct DrawParams
59 {
60     string vertShader;
61     string fragShader;
62     string refVertShader;
63     string refFragShader;
64     const SharedGroupParams groupParams;
65 };
66 
67 class DrawTestInstance : public TestInstance
68 {
69 public:
70     DrawTestInstance(Context &context, const DrawParams &data);
71     ~DrawTestInstance(void);
72     tcu::TestStatus iterate(void);
73 
74 protected:
75     void preRenderCommands(VkCommandBuffer cmdBuffer, VkImage colorTargetImage, const VkClearValue &clearColor);
76     void draw(VkCommandBuffer cmdBuffer, VkPipeline pipeline, VkBuffer vertexBuffer);
77 
78 #ifndef CTS_USES_VULKANSC
79     void beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkFormat colorAttachmentFormat,
80                                  VkRenderingFlagsKHR renderingFlags = 0u);
81 #endif // CTS_USES_VULKANSC
82 
83 private:
84     DrawParams m_data;
85 
86     enum
87     {
88         WIDTH  = 256,
89         HEIGHT = 256
90     };
91 };
92 
DrawTestInstance(Context & context,const DrawParams & data)93 DrawTestInstance::DrawTestInstance(Context &context, const DrawParams &data) : vkt::TestInstance(context), m_data(data)
94 {
95 }
96 
~DrawTestInstance(void)97 DrawTestInstance::~DrawTestInstance(void)
98 {
99 }
100 
101 class DrawTestCase : public TestCase
102 {
103 public:
104     DrawTestCase(tcu::TestContext &context, const char *name, const DrawParams data);
105     ~DrawTestCase(void);
106     virtual void initPrograms(SourceCollections &programCollection) const;
107     virtual void checkSupport(Context &context) const;
108     virtual TestInstance *createInstance(Context &context) const;
109 
110 private:
111     DrawParams m_data;
112 };
113 
DrawTestCase(tcu::TestContext & context,const char * name,const DrawParams data)114 DrawTestCase::DrawTestCase(tcu::TestContext &context, const char *name, const DrawParams data)
115     : vkt::TestCase(context, name)
116     , m_data(data)
117 {
118 }
119 
~DrawTestCase(void)120 DrawTestCase::~DrawTestCase(void)
121 {
122 }
123 
initPrograms(SourceCollections & programCollection) const124 void DrawTestCase::initPrograms(SourceCollections &programCollection) const
125 {
126     const tcu::StringTemplate vertShader(string("#version 430\n"
127                                                 "layout(location = 0) in vec4 in_position;\n"
128                                                 "layout(location = 1) in vec4 in_color;\n"
129                                                 "layout(location = 0) ${qualifier:opt} out vec4 out_color;\n"
130                                                 "out gl_PerVertex {\n"
131                                                 "    vec4  gl_Position;\n"
132                                                 "    float gl_PointSize;\n"
133                                                 "};\n"
134                                                 "void main() {\n"
135                                                 "    gl_PointSize = 1.0;\n"
136                                                 "    gl_Position  = in_position;\n"
137                                                 "    out_color    = in_color;\n"
138                                                 "}\n"));
139 
140     const tcu::StringTemplate fragShader(string("#version 430\n"
141                                                 "layout(location = 0) ${qualifier:opt} in vec4 in_color;\n"
142                                                 "layout(location = 0) out vec4 out_color;\n"
143                                                 "void main()\n"
144                                                 "{\n"
145                                                 "    out_color = in_color;\n"
146                                                 "}\n"));
147 
148     map<string, string> empty;
149     map<string, string> flat;
150     flat["qualifier"] = "flat";
151     map<string, string> noPerspective;
152     noPerspective["qualifier"] = "noperspective";
153 
154     programCollection.glslSources.add("vert") << glu::VertexSource(vertShader.specialize(empty));
155     programCollection.glslSources.add("vertFlatColor") << glu::VertexSource(vertShader.specialize(flat));
156     programCollection.glslSources.add("vertNoPerspective") << glu::VertexSource(vertShader.specialize(noPerspective));
157     programCollection.glslSources.add("frag") << glu::FragmentSource(fragShader.specialize(empty));
158     programCollection.glslSources.add("fragFlatColor") << glu::FragmentSource(fragShader.specialize(flat));
159     programCollection.glslSources.add("fragNoPerspective") << glu::FragmentSource(fragShader.specialize(noPerspective));
160 }
161 
checkSupport(Context & context) const162 void DrawTestCase::checkSupport(Context &context) const
163 {
164     if (m_data.groupParams->useDynamicRendering)
165         context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
166 }
167 
createInstance(Context & context) const168 TestInstance *DrawTestCase::createInstance(Context &context) const
169 {
170     return new DrawTestInstance(context, m_data);
171 }
172 
iterate(void)173 tcu::TestStatus DrawTestInstance::iterate(void)
174 {
175     tcu::ConstPixelBufferAccess frames[2];
176     de::SharedPtr<Image> colorTargetImages[2];
177     const string vertShaderNames[2] = {m_data.vertShader, m_data.refVertShader};
178     const string fragShaderNames[2] = {m_data.fragShader, m_data.refFragShader};
179     const DeviceInterface &vk       = m_context.getDeviceInterface();
180     const VkDevice device           = m_context.getDevice();
181     tcu::TestLog &log               = m_context.getTestContext().getLog();
182 
183     // Run two iterations with shaders that have different interpolation decorations. Images should still match.
184     for (uint32_t frameIdx = 0; frameIdx < DE_LENGTH_OF_ARRAY(frames); frameIdx++)
185     {
186         const CmdPoolCreateInfo cmdPoolCreateInfo(m_context.getUniversalQueueFamilyIndex());
187         Move<VkCommandPool> cmdPool     = createCommandPool(vk, device, &cmdPoolCreateInfo);
188         Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
189         Move<VkCommandBuffer> secCmdBuffer;
190         const Unique<VkShaderModule> vs(
191             createShaderModule(vk, device, m_context.getBinaryCollection().get(vertShaderNames[frameIdx].c_str()), 0));
192         const Unique<VkShaderModule> fs(
193             createShaderModule(vk, device, m_context.getBinaryCollection().get(fragShaderNames[frameIdx].c_str()), 0));
194         const VkFormat targetImageFormat = VK_FORMAT_R8G8B8A8_UNORM;
195         de::SharedPtr<Buffer> vertexBuffer;
196         Move<VkRenderPass> renderPass;
197         Move<VkImageView> colorTargetView;
198         Move<VkFramebuffer> framebuffer;
199         Move<VkPipeline> pipeline;
200 
201         // Create color buffer image.
202         {
203             const VkExtent3D targetImageExtent = {WIDTH, HEIGHT, 1};
204             const ImageCreateInfo targetImageCreateInfo(VK_IMAGE_TYPE_2D, targetImageFormat, targetImageExtent, 1, 1,
205                                                         VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
206                                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
207                                                             VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
208                                                             VK_IMAGE_USAGE_TRANSFER_DST_BIT);
209             colorTargetImages[frameIdx] =
210                 Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(),
211                                       m_context.getUniversalQueueFamilyIndex());
212         }
213 
214         const ImageViewCreateInfo colorTargetViewInfo(colorTargetImages[frameIdx]->object(), VK_IMAGE_VIEW_TYPE_2D,
215                                                       targetImageFormat);
216         colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
217 
218         // Create render pass and frame buffer.
219         if (!m_data.groupParams->useDynamicRendering)
220         {
221             RenderPassCreateInfo renderPassCreateInfo;
222             renderPassCreateInfo.addAttachment(
223                 AttachmentDescription(targetImageFormat, VK_SAMPLE_COUNT_1_BIT, VK_ATTACHMENT_LOAD_OP_LOAD,
224                                       VK_ATTACHMENT_STORE_OP_STORE, VK_ATTACHMENT_LOAD_OP_DONT_CARE,
225                                       VK_ATTACHMENT_STORE_OP_STORE, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL));
226 
227             const VkAttachmentReference colorAttachmentRef = {0, VK_IMAGE_LAYOUT_GENERAL};
228             renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS, 0, 0, DE_NULL, 1,
229                                                                &colorAttachmentRef, DE_NULL, AttachmentReference(), 0,
230                                                                DE_NULL));
231 
232             renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
233 
234             vector<VkImageView> colorAttachments{*colorTargetView};
235             const FramebufferCreateInfo framebufferCreateInfo(*renderPass, colorAttachments, WIDTH, HEIGHT, 1);
236             framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
237         }
238 
239         // Create vertex buffer.
240         {
241             const PositionColorVertex vertices[] = {
242                 PositionColorVertex(tcu::Vec4(-0.8f, -0.7f, 1.0f, 1.0f), // Coord
243                                     tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)),  // Color
244 
245                 PositionColorVertex(tcu::Vec4(0.0f, 0.4f, 0.5f, 0.5f),  // Coord
246                                     tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f)), // Color
247 
248                 PositionColorVertex(tcu::Vec4(0.8f, -0.5f, 1.0f, 1.0f), // Coord
249                                     tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f))  // Color
250             };
251 
252             const VkDeviceSize dataSize = DE_LENGTH_OF_ARRAY(vertices) * sizeof(PositionColorVertex);
253             vertexBuffer =
254                 Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
255                                        m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
256             uint8_t *ptr = reinterpret_cast<uint8_t *>(vertexBuffer->getBoundMemory().getHostPtr());
257 
258             deMemcpy(ptr, vertices, static_cast<size_t>(dataSize));
259             flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(),
260                                    vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
261         }
262 
263         const PipelineLayoutCreateInfo pipelineLayoutCreateInfo;
264         Move<VkPipelineLayout> pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
265 
266         // Create pipeline
267         {
268             const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
269 
270             VkViewport viewport = makeViewport(WIDTH, HEIGHT);
271             VkRect2D scissor    = makeRect2D(WIDTH, HEIGHT);
272 
273             const VkVertexInputBindingDescription vertexInputBindingDescription = {0, (uint32_t)sizeof(tcu::Vec4) * 2,
274                                                                                    VK_VERTEX_INPUT_RATE_VERTEX};
275 
276             const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = {
277                 {0u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, 0u},
278                 {1u, 0u, VK_FORMAT_R32G32B32A32_SFLOAT, (uint32_t)(sizeof(float) * 4)}};
279 
280             PipelineCreateInfo::VertexInputState vertexInputState = PipelineCreateInfo::VertexInputState(
281                 1, &vertexInputBindingDescription, 2, vertexInputAttributeDescriptions);
282 
283             PipelineCreateInfo pipelineCreateInfo(*pipelineLayout, *renderPass, 0, 0);
284             pipelineCreateInfo.addShader(
285                 PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
286             pipelineCreateInfo.addShader(
287                 PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
288             pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(vertexInputState));
289             pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST));
290             pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
291             pipelineCreateInfo.addState(
292                 PipelineCreateInfo::ViewportState(1, vector<VkViewport>(1, viewport), vector<VkRect2D>(1, scissor)));
293             pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
294             pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
295             pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
296 
297 #ifndef CTS_USES_VULKANSC
298             VkPipelineRenderingCreateInfoKHR renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
299                                                                  DE_NULL,
300                                                                  0u,
301                                                                  1u,
302                                                                  &targetImageFormat,
303                                                                  VK_FORMAT_UNDEFINED,
304                                                                  VK_FORMAT_UNDEFINED};
305 
306             if (m_data.groupParams->useDynamicRendering)
307                 pipelineCreateInfo.pNext = &renderingCreateInfo;
308 #endif // CTS_USES_VULKANSC
309 
310             pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
311         }
312 
313         const VkRect2D renderArea = makeRect2D(WIDTH, HEIGHT);
314         const VkClearValue clearColor{{{0.0f, 0.0f, 0.0f, 1.0f}}};
315         const VkBuffer buffer = vertexBuffer->object();
316 
317         // Record commands
318 #ifndef CTS_USES_VULKANSC
319         if (m_data.groupParams->useSecondaryCmdBuffer)
320         {
321             secCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
322 
323             // record secondary command buffer
324             if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
325             {
326                 beginSecondaryCmdBuffer(*secCmdBuffer, targetImageFormat,
327                                         VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
328                 beginRendering(vk, *secCmdBuffer, *colorTargetView, renderArea, clearColor, VK_IMAGE_LAYOUT_GENERAL,
329                                VK_ATTACHMENT_LOAD_OP_LOAD, 0u);
330             }
331             else
332                 beginSecondaryCmdBuffer(*secCmdBuffer, targetImageFormat);
333 
334             draw(*secCmdBuffer, *pipeline, buffer);
335 
336             if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
337                 endRendering(vk, *secCmdBuffer);
338 
339             endCommandBuffer(vk, *secCmdBuffer);
340 
341             // record primary command buffer
342             beginCommandBuffer(vk, *cmdBuffer, 0u);
343 
344             preRenderCommands(*cmdBuffer, colorTargetImages[frameIdx]->object(), clearColor);
345 
346             if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
347                 beginRendering(vk, *cmdBuffer, *colorTargetView, renderArea, clearColor, VK_IMAGE_LAYOUT_GENERAL,
348                                VK_ATTACHMENT_LOAD_OP_LOAD, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
349 
350             vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
351 
352             if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
353                 endRendering(vk, *cmdBuffer);
354 
355             endCommandBuffer(vk, *cmdBuffer);
356         }
357         else if (m_data.groupParams->useDynamicRendering)
358         {
359             beginCommandBuffer(vk, *cmdBuffer);
360 
361             preRenderCommands(*cmdBuffer, colorTargetImages[frameIdx]->object(), clearColor);
362             beginRendering(vk, *cmdBuffer, *colorTargetView, renderArea, clearColor, VK_IMAGE_LAYOUT_GENERAL,
363                            VK_ATTACHMENT_LOAD_OP_LOAD);
364             draw(*cmdBuffer, *pipeline, buffer);
365             endRendering(vk, *cmdBuffer);
366 
367             endCommandBuffer(vk, *cmdBuffer);
368         }
369 #endif // CTS_USES_VULKANSC
370 
371         if (!m_data.groupParams->useDynamicRendering)
372         {
373             beginCommandBuffer(vk, *cmdBuffer);
374 
375             preRenderCommands(*cmdBuffer, colorTargetImages[frameIdx]->object(), clearColor);
376             beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea);
377             draw(*cmdBuffer, *pipeline, buffer);
378             endRenderPass(vk, *cmdBuffer);
379 
380             endCommandBuffer(vk, *cmdBuffer);
381         }
382 
383         // Submit and read results.
384         const VkQueue queue         = m_context.getUniversalQueue();
385         const VkOffset3D zeroOffset = {0, 0, 0};
386         submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
387         frames[frameIdx] =
388             colorTargetImages[frameIdx]->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_GENERAL,
389                                                      zeroOffset, WIDTH, HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
390     }
391 
392     qpTestResult res = QP_TEST_RESULT_PASS;
393 
394     if (!tcu::intThresholdCompare(log, "Result", "Image comparison result", frames[0], frames[1], tcu::UVec4(0),
395                                   tcu::COMPARE_LOG_RESULT))
396         res = QP_TEST_RESULT_FAIL;
397 
398     return tcu::TestStatus(res, qpGetTestResultName(res));
399 }
400 
preRenderCommands(VkCommandBuffer cmdBuffer,VkImage colorTargetImage,const VkClearValue & clearColor)401 void DrawTestInstance::preRenderCommands(VkCommandBuffer cmdBuffer, VkImage colorTargetImage,
402                                          const VkClearValue &clearColor)
403 {
404     const DeviceInterface &vk = m_context.getDeviceInterface();
405     const ImageSubresourceRange subresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
406     const VkMemoryBarrier memBarrier{VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT,
407                                      VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT};
408 
409     initialTransitionColor2DImage(vk, cmdBuffer, colorTargetImage, VK_IMAGE_LAYOUT_GENERAL,
410                                   vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
411 
412     vk.cmdClearColorImage(cmdBuffer, colorTargetImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1,
413                           &subresourceRange);
414 
415     vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0,
416                           1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
417 }
418 
draw(VkCommandBuffer cmdBuffer,VkPipeline pipeline,VkBuffer vertexBuffer)419 void DrawTestInstance::draw(VkCommandBuffer cmdBuffer, VkPipeline pipeline, VkBuffer vertexBuffer)
420 {
421     const DeviceInterface &vk             = m_context.getDeviceInterface();
422     const VkDeviceSize vertexBufferOffset = 0;
423 
424     vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
425     vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
426     vk.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
427 }
428 
429 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer,VkFormat colorAttachmentFormat,VkRenderingFlagsKHR renderingFlags)430 void DrawTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkFormat colorAttachmentFormat,
431                                                VkRenderingFlagsKHR renderingFlags)
432 {
433     VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
434         VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
435         DE_NULL,                                                         // const void* pNext;
436         renderingFlags,                                                  // VkRenderingFlagsKHR flags;
437         0u,                                                              // uint32_t viewMask;
438         1u,                                                              // uint32_t colorAttachmentCount;
439         &colorAttachmentFormat,                                          // const VkFormat* pColorAttachmentFormats;
440         VK_FORMAT_UNDEFINED,                                             // VkFormat depthAttachmentFormat;
441         VK_FORMAT_UNDEFINED,                                             // VkFormat stencilAttachmentFormat;
442         VK_SAMPLE_COUNT_1_BIT,                                           // VkSampleCountFlagBits rasterizationSamples;
443     };
444     const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
445 
446     VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
447     if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
448         usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
449 
450     const VkCommandBufferBeginInfo commandBufBeginParams{
451         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
452         DE_NULL,                                     // const void* pNext;
453         usageFlags,                                  // VkCommandBufferUsageFlags flags;
454         &bufferInheritanceInfo};
455 
456     const DeviceInterface &vk = m_context.getDeviceInterface();
457     VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
458 }
459 #endif // CTS_USES_VULKANSC
460 
createTests(tcu::TestCaseGroup * testGroup,const SharedGroupParams groupParams)461 void createTests(tcu::TestCaseGroup *testGroup, const SharedGroupParams groupParams)
462 {
463     tcu::TestContext &testCtx    = testGroup->getTestContext();
464     const DrawParams paramsFlat0 = {"vert", "fragFlatColor", "vertFlatColor", "fragFlatColor", groupParams};
465     const DrawParams paramsFlat1 = {"vertFlatColor", "frag", "vert", "frag", groupParams};
466 
467     const DrawParams paramsNoPerspective0 = {"vert", "fragNoPerspective", "vertNoPerspective", "fragNoPerspective",
468                                              groupParams};
469     const DrawParams paramsNoPerspective1 = {"vertNoPerspective", "frag", "vert", "frag", groupParams};
470 
471     // Mismatching flat interpolation testcase 0.
472     testGroup->addChild(new DrawTestCase(testCtx, "flat_0", paramsFlat0));
473     // Mismatching flat interpolation testcase 1.
474     testGroup->addChild(new DrawTestCase(testCtx, "flat_1", paramsFlat1));
475 
476     // Mismatching noperspective interpolation testcase 0.
477     testGroup->addChild(new DrawTestCase(testCtx, "noperspective_0", paramsNoPerspective0));
478     // Mismatching noperspective interpolation testcase 1.
479     testGroup->addChild(new DrawTestCase(testCtx, "noperspective_1", paramsNoPerspective1));
480 }
481 
482 } // namespace
483 
createDifferingInterpolationTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)484 tcu::TestCaseGroup *createDifferingInterpolationTests(tcu::TestContext &testCtx, const SharedGroupParams groupParams)
485 {
486     return createTestGroup(testCtx, "differing_interpolation", createTests, groupParams);
487 }
488 
489 } // namespace Draw
490 } // namespace vkt
491