Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / draw / vktDrawExplicitVertexParameterTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  * Copyright (c) 2020 Valve 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_AMD_shader_explicit_vertex_parameter tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawExplicitVertexParameterTests.hpp"
26
27 #include "vktDrawBaseClass.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkCmdUtil.hpp"
30 #include "vkTypeUtil.hpp"
31 #include "vktTestGroupUtil.hpp"
32
33 #include "vkObjUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkTypeUtil.hpp"
36
37 #include "deDefs.h"
38 #include "deRandom.hpp"
39 #include "deString.h"
40 #include "deMath.h"
41
42 #include "tcuTestCase.hpp"
43 #include "tcuRGBA.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuStringTemplate.hpp"
47
48 #include "rrRenderer.hpp"
49
50 #include <string>
51 #include <sstream>
52
53 namespace vkt
54 {
55 namespace Draw
56 {
57 namespace
58 {
59 using namespace vk;
60 using namespace std;
61
62 enum Interpolation
63 {
64         SMOOTH = 0,
65         NOPERSPECTIVE = 1,
66 };
67
68 enum AuxiliaryQualifier
69 {
70         AUX_NONE = 0,
71         AUX_CENTROID = 1,
72         AUX_SAMPLE = 2,
73 };
74
75
76 enum
77 {
78         WIDTH = 16,
79         HEIGHT = 16
80 };
81
82 struct PositionValueVertex {
83         PositionValueVertex(tcu::Vec4 pos, float val)
84         : position(pos)
85         , value(val)
86         {}
87 public:
88         tcu::Vec4       position;
89         float           value;
90 };
91
92 struct DrawParams
93 {
94         Interpolation                           interpolation;
95         vk::VkSampleCountFlagBits       samples;
96         AuxiliaryQualifier                      auxiliaryStorage;
97         const SharedGroupParams         groupParams;
98 };
99
100 const char* interpolationToString (Interpolation interpolation)
101 {
102         switch (interpolation)
103         {
104                 case SMOOTH:
105                         return "smooth";
106                 case NOPERSPECTIVE:
107                         return "noperspective";
108                 default:
109                         DE_FATAL("Invalid interpolation enum");
110         }
111
112         return "";
113 }
114
115 std::string barycentricVariableString (Interpolation interpolation, AuxiliaryQualifier aux)
116 {
117         std::ostringstream name;
118         name << "gl_BaryCoord";
119         switch (interpolation)
120         {
121                 case SMOOTH:
122                         name << "Smooth";
123                         break;
124                 case NOPERSPECTIVE:
125                         name << "NoPersp";
126                         break;
127                 default:
128                         DE_FATAL("Invalid interpolation enum");
129         }
130
131         switch (aux)
132         {
133                 case AUX_CENTROID:
134                         name << "Centroid";
135                         break;
136                 case AUX_SAMPLE:
137                         name << "Sample";
138                         break;
139                 case AUX_NONE:
140                         name << "";
141                         break;
142                 default:
143                         DE_FATAL("Invalid auxiliary storage qualifier enum");
144         }
145         name << "AMD";
146         return name.str();
147 }
148
149 const char* auxiliaryQualifierToString (AuxiliaryQualifier aux)
150 {
151         switch (aux)
152         {
153                 case AUX_CENTROID:
154                         return "centroid";
155                 case AUX_SAMPLE:
156                         return "sample";
157                 case AUX_NONE:
158                         return "";
159                 default:
160                         DE_FATAL("Invalid auxiliary storage qualifier enum");
161         }
162
163         return "";
164 }
165
166 std::string getTestName (DrawParams params)
167 {
168         std::ostringstream      name;
169
170         name << interpolationToString(params.interpolation) << "_";
171
172         if (params.auxiliaryStorage != AUX_NONE)
173                 name << auxiliaryQualifierToString(params.auxiliaryStorage) << "_";
174
175         name << "samples_" << de::toString(params.samples);
176
177         return name.str();
178 }
179
180 class DrawTestInstance : public TestInstance
181 {
182 public:
183                                                 DrawTestInstance                (Context& context, const DrawParams& data);
184                                                 ~DrawTestInstance               (void);
185         tcu::TestStatus         iterate                                 (void);
186
187 protected:
188         void                            preRenderCommands               (VkCommandBuffer cmdBuffer, VkImage colorTargetImage) const;
189         void                            beginRenderPass                 (VkCommandBuffer cmdBuffer, VkRect2D renderArea,
190                                                                                                  const VkClearValue* pClearValues, deUint32 clearValueCount) const;
191         void                            drawCommands                    (VkCommandBuffer cmdBuffer, VkBuffer vertexBuffer) const;
192
193 #ifndef CTS_USES_VULKANSC
194         void                            beginSecondaryCmdBuffer (VkCommandBuffer cmdBuffer, VkFormat colorFormat,
195                                                                                                  VkRenderingFlagsKHR renderingFlags = 0u) const;
196         void                            beginDynamicRender              (VkCommandBuffer cmdBuffer, VkRect2D renderArea,
197                                                                                                  const VkClearValue* pClearValues, VkRenderingFlagsKHR renderingFlags = 0u) const;
198 #endif // CTS_USES_VULKANSC
199
200 private:
201         DrawParams                                              m_data;
202         Move<VkRenderPass>                              m_renderPass;
203         Move<VkImageView>                               m_colorTargetView;
204         Move<VkImageView>                               m_multisampleTargetView;
205         Move<VkFramebuffer>                             m_framebuffer;
206         Move<VkPipeline>                                m_pipeline;
207         Move<VkPipelineLayout>                  m_pipelineLayout;
208         Move<VkDescriptorPool>                  m_descriptorPool;
209         Move<VkDescriptorSet>                   m_descriptorSet;
210         Move<VkDescriptorSetLayout>             m_descriptorSetLayout;
211 };
212
213 DrawTestInstance::DrawTestInstance (Context& context, const DrawParams& data)
214         : vkt::TestInstance             (context)
215         , m_data                                (data)
216 {
217 }
218
219 DrawTestInstance::~DrawTestInstance (void)
220 {
221 }
222
223 class DrawTestCase : public TestCase
224 {
225         public:
226                                                                 DrawTestCase            (tcu::TestContext& context, const char* name, const char* desc, const DrawParams data);
227                                                                 ~DrawTestCase           (void);
228         virtual void                            initPrograms            (SourceCollections& programCollection) const;
229         virtual TestInstance*           createInstance          (Context& context) const;
230         virtual void                            checkSupport            (Context& context) const;
231
232 private:
233         DrawParams                                      m_data;
234 };
235
236 DrawTestCase::DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const DrawParams data)
237         : vkt::TestCase (context, name, desc)
238         , m_data                (data)
239 {
240 }
241
242 DrawTestCase::~DrawTestCase     (void)
243 {
244 }
245
246 void DrawTestCase::checkSupport(Context &context) const
247 {
248         context.requireDeviceFunctionality("VK_AMD_shader_explicit_vertex_parameter");
249
250         if ((context.getDeviceProperties().limits.framebufferColorSampleCounts & m_data.samples) == 0)
251                 TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");
252
253         if (m_data.groupParams->useDynamicRendering)
254                 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
255 }
256
257 void DrawTestCase::initPrograms (SourceCollections& programCollection) const
258 {
259         const deUint32                          numValues       = WIDTH * HEIGHT * m_data.samples;
260
261         const tcu::StringTemplate       vertShader      (string(
262                 "#version 450\n"
263                 "#extension GL_AMD_shader_explicit_vertex_parameter : require\n"
264                 "\n"
265                 "layout(location = 0) in vec4 in_position;\n"
266                 "layout(location = 1) in float in_data;\n"
267                 "layout(location = 0) __explicitInterpAMD out float out_data_explicit;\n"
268                 "layout(location = 1) ${auxqualifier} ${qualifier}        out float out_data_${qualifier};\n"
269                 "\n"
270                 "out gl_PerVertex {\n"
271                 "    vec4  gl_Position;\n"
272                 "    float gl_PointSize;\n"
273                 "};\n"
274                 "\n"
275                 "void main() {\n"
276                 "    gl_PointSize              = 1.0;\n"
277                 "    gl_Position               = in_position;\n"
278                 "    out_data_explicit         = in_data;\n"
279                 "    out_data_${qualifier}     = in_data;\n"
280                 "}\n"));
281
282         const tcu::StringTemplate       fragShader      (string(
283                 "#version 450\n"
284                 "#extension GL_AMD_shader_explicit_vertex_parameter : require\n"
285                 "\n"
286                 "layout(location = 0) __explicitInterpAMD in float in_data_explicit;\n"
287                 "layout(location = 1) ${auxqualifier} ${qualifier}        in float in_data_${qualifier};\n"
288                 "layout(location = 0) out vec4 out_color;\n"
289                 "layout (binding = 0, std140) writeonly buffer Output {\n"
290                 "    vec4 values [${numValues}];\n"
291                 "} sb_out;\n"
292                 "\n"
293                 "void main()\n"
294                 "{\n"
295                 "    uint index = (uint(gl_FragCoord.y) * ${width} * ${samples}) + uint(gl_FragCoord.x) * ${samples} + gl_SampleID;\n"
296                 "    // Barycentric coodinates (I, J, K)\n"
297                 "    vec3 bary_coord = vec3(${barycoord}.x, ${barycoord}.y, 1.0f - ${barycoord}.x - ${barycoord}.y);\n"
298                 "\n"
299                 "    // Vertex 0 -> (I = 0, J = 0, K = 1)\n"
300                 "    float data0 = interpolateAtVertexAMD(in_data_explicit, 0);\n"
301                 "    // Vertex 1 -> (I = 1, J = 0, K = 0)\n"
302                 "    float data1 = interpolateAtVertexAMD(in_data_explicit, 1);\n"
303                 "    // Vertex 1 -> (I = 0, J = 1, K = 0)\n"
304                 "    float data2 = interpolateAtVertexAMD(in_data_explicit, 2);\n"
305                 "    // Match data component with barycentric coordinate\n"
306                 "    vec3  data  = vec3(data1, data2, data0);\n"
307                 "\n"
308                 "    float res      = (bary_coord.x * data.x) + (bary_coord.y * data.y) + (bary_coord.z * data.z);\n"
309                 "    float expected = in_data_${qualifier};\n"
310                 "\n"
311                 "    sb_out.values[ index ] = vec4(expected, res, 0u, 0u);\n"
312                 "\n"
313                 "    const float threshold = 0.0005f;\n"
314                 "    if (abs(res - expected) < threshold)\n"
315                 "        out_color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
316                 "    else\n"
317                 "        out_color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
318                 "}\n"));
319
320         map<string, string> attributes;
321         attributes["width"]                     = de::toString(WIDTH);
322         attributes["numValues"]         = de::toString(numValues * m_data.samples);
323         attributes["qualifier"]         = interpolationToString(m_data.interpolation);
324         attributes["auxqualifier"]      = auxiliaryQualifierToString(m_data.auxiliaryStorage);
325         attributes["barycoord"]         = barycentricVariableString(m_data.interpolation, m_data.auxiliaryStorage);
326         attributes["samples"]           = de::toString(m_data.samples);
327
328         programCollection.glslSources.add("vert") << glu::VertexSource(vertShader.specialize(attributes));
329         programCollection.glslSources.add("frag") << glu::FragmentSource(fragShader.specialize(attributes));
330 }
331
332 TestInstance* DrawTestCase::createInstance (Context& context) const
333 {
334         return new DrawTestInstance(context, m_data);
335 }
336
337 tcu::TestStatus DrawTestInstance::iterate (void)
338 {
339         de::SharedPtr<Image>                    colorTargetImage;
340         de::SharedPtr<Image>                    multisampleTargetImage;
341         tcu::TestLog                                    &log                                    = m_context.getTestContext().getLog();
342
343         // Run two iterations with shaders that have different interpolation decorations. Images should still match.
344         const DeviceInterface&                  vk                                              = m_context.getDeviceInterface();
345         const VkDevice                                  device                                  = m_context.getDevice();
346         const CmdPoolCreateInfo                 cmdPoolCreateInfo               (m_context.getUniversalQueueFamilyIndex());
347         Move<VkCommandPool>                             cmdPool                                 = createCommandPool(vk, device, &cmdPoolCreateInfo);
348         Move<VkCommandBuffer>                   cmdBuffer                               = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
349         Move<VkCommandBuffer>                   secCmdBuffer;
350         const Unique<VkShaderModule>    vs                                              (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
351         const Unique<VkShaderModule>    fs                                              (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
352         de::SharedPtr<Buffer>                   vertexBuffer;
353         de::SharedPtr<Buffer>                   ssboBuffer;
354
355         vk::VkFormat                                    imageFormat                             = VK_FORMAT_R8G8B8A8_UNORM;
356         const deUint32                                  numValues                               = WIDTH * HEIGHT * m_data.samples;
357         const deBool                                    useMultisampling                = m_data.samples != VK_SAMPLE_COUNT_1_BIT;
358
359         // Create color buffer images.
360         {
361                 const VkExtent3D                        targetImageExtent               = { WIDTH, HEIGHT, 1 };
362                 const ImageCreateInfo           targetImageCreateInfo   (VK_IMAGE_TYPE_2D, imageFormat, targetImageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT,
363                                                                                                                          VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
364                 colorTargetImage                                                                        = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
365
366                 if (useMultisampling)
367                 {
368                         const ImageCreateInfo           multisampleTargetImageCreateInfo        (VK_IMAGE_TYPE_2D, imageFormat, targetImageExtent, 1, 1, m_data.samples,
369                                                                                                                                                          VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
370                         multisampleTargetImage                                                                                  = Image::createAndAlloc(vk, device, multisampleTargetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
371                 }
372         }
373
374         const ImageViewCreateInfo colorTargetViewInfo(colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, imageFormat);
375         m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
376
377         if (useMultisampling)
378         {
379                 const ImageViewCreateInfo multisamplingTargetViewInfo(multisampleTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, imageFormat);
380                 m_multisampleTargetView = createImageView(vk, device, &multisamplingTargetViewInfo);
381         }
382
383         // Create render pass
384         if (!m_data.groupParams->useDynamicRendering)
385         {
386                 RenderPassCreateInfo                    renderPassCreateInfo;
387                 renderPassCreateInfo.addAttachment(AttachmentDescription(imageFormat,
388                                                                                                                                  VK_SAMPLE_COUNT_1_BIT,
389                                                                                                                                  VK_ATTACHMENT_LOAD_OP_CLEAR,
390                                                                                                                                  VK_ATTACHMENT_STORE_OP_STORE,
391                                                                                                                                  VK_ATTACHMENT_LOAD_OP_DONT_CARE,
392                                                                                                                                  VK_ATTACHMENT_STORE_OP_STORE,
393                                                                                                                                  VK_IMAGE_LAYOUT_UNDEFINED,
394                                                                                                                                  VK_IMAGE_LAYOUT_GENERAL));
395
396                 const VkAttachmentReference             colorAttachmentRef                      = { 0u, VK_IMAGE_LAYOUT_GENERAL };
397                 const VkAttachmentReference             multisampleAttachmentRef        = { 1u, VK_IMAGE_LAYOUT_GENERAL };
398
399                 if (useMultisampling)
400                 {
401                         renderPassCreateInfo.addAttachment(AttachmentDescription(imageFormat,
402                                                                                                                                          m_data.samples,
403                                                                                                                                          vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
404                                                                                                                                          vk::VK_ATTACHMENT_STORE_OP_STORE,
405                                                                                                                                          vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
406                                                                                                                                          vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
407                                                                                                                                          vk::VK_IMAGE_LAYOUT_UNDEFINED,
408                                                                                                                                          vk::VK_IMAGE_LAYOUT_GENERAL));
409                 }
410
411                 renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS,
412                                                                                                                    0,
413                                                                                                                    0,
414                                                                                                                    DE_NULL,
415                                                                                                                    1u,
416                                                                                                                    useMultisampling ? &multisampleAttachmentRef : &colorAttachmentRef,
417                                                                                                                    useMultisampling ? &colorAttachmentRef : DE_NULL,
418                                                                                                                    AttachmentReference(),
419                                                                                                                    0,
420                                                                                                                    DE_NULL));
421
422                 m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
423
424                 // Create framebuffer
425                 vector<VkImageView> colorAttachments { *m_colorTargetView };
426                 if (useMultisampling)
427                         colorAttachments.push_back(*m_multisampleTargetView);
428
429                 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, colorAttachments, WIDTH, HEIGHT, 1);
430                 m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
431         }
432
433         // Create vertex buffer.
434         {
435                 const PositionValueVertex       vertices[]      =
436                 {
437                         PositionValueVertex(
438                                 tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f),             // Coord
439                                 float(1.0f)),                                                   // Value
440
441                         PositionValueVertex(
442                                 tcu::Vec4(-1.0f, -1.0f, 0.25f, 0.75f),  // Coord
443                                 float(0.0f)),                                                   // Value
444                         PositionValueVertex(
445                                 tcu::Vec4( 1.0f,  1.0f, 0.0f, 2.0f),    // Coord
446                                 float(0.5f)),                                                   // Value
447                         PositionValueVertex(
448                                 tcu::Vec4( 1.0f, -1.0f, 1.0f, 0.5f),    // Coord
449                                 float(1.0f)),                                                   // Value
450                 };
451
452                 const VkDeviceSize                      dataSize        = DE_LENGTH_OF_ARRAY(vertices) * sizeof(PositionValueVertex);
453                 vertexBuffer                                                    = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
454                 deUint8*                                        ptr                     = reinterpret_cast<deUint8*>(vertexBuffer->getBoundMemory().getHostPtr());
455
456                 deMemcpy(ptr, vertices, static_cast<size_t>(dataSize));
457                 flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(), vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
458         }
459
460         // Create SSBO buffer
461         {
462                 const VkDeviceSize              dataSize        = sizeof(tcu::Vec4) * numValues;
463                 ssboBuffer                                                      = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
464                 deUint8*                                ptr                     = reinterpret_cast<deUint8*>(ssboBuffer->getBoundMemory().getHostPtr());
465
466                 deMemset(ptr, 0, static_cast<size_t>(dataSize));
467                 flushMappedMemoryRange(vk, device, ssboBuffer->getBoundMemory().getMemory(), ssboBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
468         }
469
470         // Create Descriptor Set layout
471         {
472                 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
473                         .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
474                         .build(vk, device);
475         }
476
477         // Create Descriptor Set
478         {
479                 m_descriptorPool = DescriptorPoolBuilder()
480                         .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
481                         .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
482
483                 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
484
485                 const VkDescriptorBufferInfo    bufferInfo =
486                 {
487                         ssboBuffer->object(),           // VkBuffer             buffer;
488                         0u,                                                     // VkDeviceSize offset;
489                         VK_WHOLE_SIZE                           // VkDeviceSize range;
490                 };
491
492                 DescriptorSetUpdateBuilder()
493                         .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
494                         .update(vk, device);
495         }
496
497         // Create pipeline
498         {
499                 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
500
501                 VkViewport      viewport        = makeViewport(WIDTH, HEIGHT);
502                 VkRect2D        scissor         = makeRect2D(WIDTH, HEIGHT);
503
504                 const VkVertexInputBindingDescription vertexInputBindingDescription = { 0, (deUint32)(sizeof(tcu::Vec4) + sizeof(float)), VK_VERTEX_INPUT_RATE_VERTEX };
505
506                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
507                 {
508                         { 0u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 0u },
509                         { 1u, 0u, vk::VK_FORMAT_R32_SFLOAT, (deUint32)(sizeof(float)* 4) }
510                 };
511
512                 PipelineCreateInfo::VertexInputState vertexInputState   = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription, 2, vertexInputAttributeDescriptions);
513
514                 m_pipelineLayout = makePipelineLayout   (vk, device, *m_descriptorSetLayout);
515
516                 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, 0);
517                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
518                 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
519                 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(vertexInputState));
520                 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
521                 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
522                 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, vector<VkViewport>(1, viewport), vector<VkRect2D>(1, scissor)));
523                 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
524                 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
525                 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState(m_data.samples));
526
527 #ifndef CTS_USES_VULKANSC
528                 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
529                 {
530                         VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
531                         DE_NULL,
532                         0u,
533                         1u,
534                         &imageFormat,
535                         VK_FORMAT_UNDEFINED,
536                         VK_FORMAT_UNDEFINED
537                 };
538
539                 if (m_data.groupParams->useDynamicRendering)
540                         pipelineCreateInfo.pNext = &renderingCreateInfo;
541 #endif // CTS_USES_VULKANSC
542
543                 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
544         }
545
546         // Queue draw and read results.
547         {
548                 const VkQueue                           queue                           = m_context.getUniversalQueue();
549                 const ImageSubresourceRange subresourceRange    (VK_IMAGE_ASPECT_COLOR_BIT);
550                 const tcu::Vec4                         clearColor                      = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
551                 const VkRect2D                          renderArea                      = makeRect2D(WIDTH, HEIGHT);
552                 const VkBuffer                          buffer                          = vertexBuffer->object();
553
554                 vector<VkClearValue>            clearColors;
555                 clearColors.push_back(makeClearValueColor(clearColor));
556                 if (useMultisampling)
557                         clearColors.push_back(makeClearValueColor(clearColor));
558
559 #ifndef CTS_USES_VULKANSC
560                 if (m_data.groupParams->useSecondaryCmdBuffer)
561                 {
562                         secCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
563
564                         // record secondary command buffer
565                         if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
566                         {
567                                 beginSecondaryCmdBuffer(*secCmdBuffer, imageFormat, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
568                                 beginDynamicRender(*secCmdBuffer, renderArea, clearColors.data());
569                         }
570                         else
571                                 beginSecondaryCmdBuffer(*secCmdBuffer, imageFormat);
572
573                         drawCommands(*secCmdBuffer, buffer);
574
575                         if (m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
576                                 endRendering(vk, *secCmdBuffer);
577
578                         endCommandBuffer(vk, *secCmdBuffer);
579
580                         // record primary command buffer
581                         beginCommandBuffer(vk, *cmdBuffer, 0u);
582
583                         if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
584                                 beginDynamicRender(*cmdBuffer, renderArea, clearColors.data(), VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
585
586                         vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
587
588                         if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
589                                 endRendering(vk, *cmdBuffer);
590
591                         endCommandBuffer(vk, *cmdBuffer);
592                 }
593                 else if (m_data.groupParams->useDynamicRendering)
594                 {
595                         beginCommandBuffer(vk, *cmdBuffer);
596                         beginDynamicRender(*cmdBuffer, renderArea, clearColors.data());
597                         drawCommands(*cmdBuffer, buffer);
598                         endRendering(vk, *cmdBuffer);
599                         endCommandBuffer(vk, *cmdBuffer);
600                 }
601 #endif // CTS_USES_VULKANSC
602
603                 if (!m_data.groupParams->useDynamicRendering)
604                 {
605                         beginCommandBuffer(vk, *cmdBuffer);
606                         beginRenderPass(*cmdBuffer, renderArea, clearColors.data(), (deUint32)clearColors.size());
607                         drawCommands(*cmdBuffer, buffer);
608                         endRenderPass(vk, *cmdBuffer);
609                         endCommandBuffer(vk, *cmdBuffer);
610                 }
611
612                 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
613         }
614
615         qpTestResult res = QP_TEST_RESULT_PASS;
616
617         {
618                 const Allocation& resultAlloc = ssboBuffer->getBoundMemory();
619                 invalidateAlloc(vk, device, resultAlloc);
620
621                 const tcu::Vec4*        ptr             = reinterpret_cast<tcu::Vec4*>(resultAlloc.getHostPtr());
622                 for (deUint32 valueNdx = 0u; valueNdx < numValues; valueNdx++)
623                 {
624                         if (deFloatAbs(ptr[valueNdx].x() - ptr[valueNdx].y()) > 0.0005f)
625                         {
626                                 log << tcu::TestLog::Message << "Expected value " << valueNdx << " is " << ptr[valueNdx].x() << ", got " << ptr[valueNdx].y()
627                                         << tcu::TestLog::EndMessage;
628                                 res = QP_TEST_RESULT_FAIL;
629                         }
630                 }
631         }
632
633         return tcu::TestStatus(res, qpGetTestResultName(res));
634 }
635
636 void DrawTestInstance::beginRenderPass(VkCommandBuffer cmdBuffer, VkRect2D renderArea,
637                                                                            const VkClearValue* pClearValues, deUint32 clearValueCount) const
638 {
639         const DeviceInterface& vk = m_context.getDeviceInterface();
640
641         const VkRenderPassBeginInfo renderPassBeginInfo
642         {
643                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType                                              sType;
644                 DE_NULL,                                                                                                // const void*                                                  pNext;
645                 *m_renderPass,                                                                                  // VkRenderPass                                                 renderPass;
646                 *m_framebuffer,                                                                                 // VkFramebuffer                                                framebuffer;
647                 renderArea,                                                                                             // VkRect2D                                                             renderArea;
648                 clearValueCount,                                                                                // deUint32                                                             clearValueCount;
649                 pClearValues,                                                                                   // const VkClearValue*                                  pClearValues;
650         };
651
652         vk.cmdBeginRenderPass(cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
653 }
654
655 void DrawTestInstance::drawCommands(VkCommandBuffer cmdBuffer, VkBuffer vertexBuffer) const
656 {
657         const DeviceInterface&  vk = m_context.getDeviceInterface();
658         const VkDeviceSize              vertexBufferOffset = 0;
659
660         vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
661         vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
662         vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, DE_NULL);
663         vk.cmdDraw(cmdBuffer, 4u, 1u, 0u, 0u);
664 }
665
666 #ifndef CTS_USES_VULKANSC
667 void DrawTestInstance::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkFormat colorFormat, VkRenderingFlagsKHR renderingFlags) const
668 {
669         VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
670         {
671                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,                // VkStructureType                                      sType;
672                 DE_NULL,                                                                                                                                // const void*                                          pNext;
673                 renderingFlags,                                                                                                                 // VkRenderingFlagsKHR                          flags;
674                 0u,                                                                                                                                             // uint32_t                                                     viewMask;
675                 1u,                                                                                                                                             // uint32_t                                                     colorAttachmentCount;
676                 &colorFormat,                                                                                                                   // const VkFormat*                                      pColorAttachmentFormats;
677                 VK_FORMAT_UNDEFINED,                                                                                                    // VkFormat                                                     depthAttachmentFormat;
678                 VK_FORMAT_UNDEFINED,                                                                                                    // VkFormat                                                     stencilAttachmentFormat;
679                 m_data.samples,                                                                                                                 // VkSampleCountFlagBits                        rasterizationSamples;
680         };
681         const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
682
683         VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
684         if (!m_data.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
685                 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
686
687         const VkCommandBufferBeginInfo commandBufBeginParams
688         {
689                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,                                                    // VkStructureType                                      sType;
690                 DE_NULL,                                                                                                                                // const void*                                          pNext;
691                 usageFlags,                                                                                                                             // VkCommandBufferUsageFlags            flags;
692                 &bufferInheritanceInfo
693         };
694
695         const DeviceInterface& vk = m_context.getDeviceInterface();
696         VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
697 }
698
699 void DrawTestInstance::beginDynamicRender(VkCommandBuffer cmdBuffer, VkRect2D renderArea, const VkClearValue* pClearValues, VkRenderingFlagsKHR renderingFlags) const
700 {
701         const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
702         const deBool                    useMultisampling        = m_data.samples != VK_SAMPLE_COUNT_1_BIT;
703
704         VkRenderingAttachmentInfoKHR colorAttachment
705         {
706                 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,                                                                // VkStructureType                                              sType;
707                 DE_NULL,                                                                                                                                                // const void*                                                  pNext;
708                 useMultisampling ? *m_multisampleTargetView : *m_colorTargetView,                               // VkImageView                                                  imageView;
709                 VK_IMAGE_LAYOUT_GENERAL,                                                                                                                // VkImageLayout                                                imageLayout;
710                 useMultisampling ? VK_RESOLVE_MODE_AVERAGE_BIT : VK_RESOLVE_MODE_NONE,                  // VkResolveModeFlagBits                                resolveMode;
711                 useMultisampling ? *m_colorTargetView : DE_NULL,                                                                // VkImageView                                                  resolveImageView;
712                 VK_IMAGE_LAYOUT_GENERAL,                                                                                                                // VkImageLayout                                                resolveImageLayout;
713                 useMultisampling ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD,    // VkAttachmentLoadOp                                   loadOp;
714                 VK_ATTACHMENT_STORE_OP_STORE,                                                                                                   // VkAttachmentStoreOp                                  storeOp;
715                 pClearValues[0]                                                                                                                                 // VkClearValue                                                 clearValue;
716         };
717
718         VkRenderingInfoKHR renderingInfo
719         {
720                 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
721                 DE_NULL,
722                 renderingFlags,                                                                                 // VkRenderingFlagsKHR                                  flags;
723                 renderArea,                                                                                             // VkRect2D                                                             renderArea;
724                 1u,                                                                                                             // deUint32                                                             layerCount;
725                 0u,                                                                                                             // deUint32                                                             viewMask;
726                 1u,                                                                                                             // deUint32                                                             colorAttachmentCount;
727                 &colorAttachment,                                                                               // const VkRenderingAttachmentInfoKHR*  pColorAttachments;
728                 DE_NULL,                                                                                                // const VkRenderingAttachmentInfoKHR*  pDepthAttachment;
729                 DE_NULL,                                                                                                // const VkRenderingAttachmentInfoKHR*  pStencilAttachment;
730         };
731
732         vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
733 }
734 #endif // CTS_USES_VULKANSC
735
736 void createTests (tcu::TestCaseGroup* testGroup, const SharedGroupParams groupParams)
737 {
738         tcu::TestContext&       testCtx         = testGroup->getTestContext();
739
740         const VkSampleCountFlagBits samples[] =
741         {
742                 VK_SAMPLE_COUNT_1_BIT,
743                 VK_SAMPLE_COUNT_2_BIT,
744                 VK_SAMPLE_COUNT_4_BIT,
745                 VK_SAMPLE_COUNT_8_BIT,
746                 VK_SAMPLE_COUNT_16_BIT,
747                 VK_SAMPLE_COUNT_32_BIT,
748                 VK_SAMPLE_COUNT_64_BIT,
749         };
750
751         const Interpolation interTypes[] =
752         {
753                 SMOOTH,
754                 NOPERSPECTIVE
755         };
756
757         const AuxiliaryQualifier auxQualifiers[] =
758         {
759                 AUX_NONE,
760                 AUX_SAMPLE,
761                 AUX_CENTROID,
762         };
763
764         for (deUint32 sampleNdx = 0; sampleNdx < DE_LENGTH_OF_ARRAY(samples); sampleNdx++)
765         {
766                 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
767                 if (groupParams->useSecondaryCmdBuffer && (sampleNdx > VK_SAMPLE_COUNT_2_BIT))
768                         continue;
769
770                 for (deUint32 auxNdx    = 0;    auxNdx          < DE_LENGTH_OF_ARRAY(auxQualifiers);    auxNdx++)
771                 for (deUint32 interNdx  = 0;    interNdx        < DE_LENGTH_OF_ARRAY(interTypes);               interNdx++)
772                 {
773                         if (samples[sampleNdx] == VK_SAMPLE_COUNT_1_BIT && auxQualifiers[auxNdx] != AUX_NONE)
774                                 continue;
775
776                         const DrawParams params
777                         {
778                                 interTypes[interNdx],
779                                 samples[sampleNdx],
780                                 auxQualifiers[auxNdx],
781                                 groupParams
782                         };
783                         testGroup->addChild(new DrawTestCase(testCtx, getTestName(params).c_str(), "", params));
784                 }
785         }
786 }
787
788 }       // anonymous
789
790 tcu::TestCaseGroup*     createExplicitVertexParameterTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
791 {
792         return createTestGroup(testCtx, "explicit_vertex_parameter", "Tests for VK_AMD_shader_explicit_vertex_parameter.", createTests, groupParams);
793 }
794
795 }       // Draw
796 }       // vkt