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 {
PositionValueVertexvkt::Draw::__anon239c8b120111::PositionValueVertex83 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 bool useDynamicRendering;
98 };
99
interpolationToString(Interpolation interpolation)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
barycentricVariableString(Interpolation interpolation,AuxiliaryQualifier aux)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
auxiliaryQualifierToString(AuxiliaryQualifier aux)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
getTestName(DrawParams params)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 private:
187 DrawParams m_data;
188 };
189
DrawTestInstance(Context & context,const DrawParams & data)190 DrawTestInstance::DrawTestInstance (Context& context, const DrawParams& data)
191 : vkt::TestInstance (context)
192 , m_data (data)
193 {
194 }
195
~DrawTestInstance(void)196 DrawTestInstance::~DrawTestInstance (void)
197 {
198 }
199
200 class DrawTestCase : public TestCase
201 {
202 public:
203 DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const DrawParams data);
204 ~DrawTestCase (void);
205 virtual void initPrograms (SourceCollections& programCollection) const;
206 virtual TestInstance* createInstance (Context& context) const;
207 virtual void checkSupport (Context& context) const;
208
209 private:
210 DrawParams m_data;
211 };
212
DrawTestCase(tcu::TestContext & context,const char * name,const char * desc,const DrawParams data)213 DrawTestCase::DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const DrawParams data)
214 : vkt::TestCase (context, name, desc)
215 , m_data (data)
216 {
217 }
218
~DrawTestCase(void)219 DrawTestCase::~DrawTestCase (void)
220 {
221 }
222
checkSupport(Context & context) const223 void DrawTestCase::checkSupport(Context &context) const
224 {
225 context.requireDeviceFunctionality("VK_AMD_shader_explicit_vertex_parameter");
226
227 if ((context.getDeviceProperties().limits.framebufferColorSampleCounts & m_data.samples) == 0)
228 TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");
229
230 if (m_data.useDynamicRendering)
231 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
232 }
233
initPrograms(SourceCollections & programCollection) const234 void DrawTestCase::initPrograms (SourceCollections& programCollection) const
235 {
236 const deUint32 numValues = WIDTH * HEIGHT * m_data.samples;
237
238 const tcu::StringTemplate vertShader (string(
239 "#version 450\n"
240 "#extension GL_AMD_shader_explicit_vertex_parameter : require\n"
241 "\n"
242 "layout(location = 0) in vec4 in_position;\n"
243 "layout(location = 1) in float in_data;\n"
244 "layout(location = 0) __explicitInterpAMD out float out_data_explicit;\n"
245 "layout(location = 1) ${auxqualifier} ${qualifier} out float out_data_${qualifier};\n"
246 "\n"
247 "out gl_PerVertex {\n"
248 " vec4 gl_Position;\n"
249 " float gl_PointSize;\n"
250 "};\n"
251 "\n"
252 "void main() {\n"
253 " gl_PointSize = 1.0;\n"
254 " gl_Position = in_position;\n"
255 " out_data_explicit = in_data;\n"
256 " out_data_${qualifier} = in_data;\n"
257 "}\n"));
258
259 const tcu::StringTemplate fragShader (string(
260 "#version 450\n"
261 "#extension GL_AMD_shader_explicit_vertex_parameter : require\n"
262 "\n"
263 "layout(location = 0) __explicitInterpAMD in float in_data_explicit;\n"
264 "layout(location = 1) ${auxqualifier} ${qualifier} in float in_data_${qualifier};\n"
265 "layout(location = 0) out vec4 out_color;\n"
266 "layout (binding = 0, std140) writeonly buffer Output {\n"
267 " vec4 values [${numValues}];\n"
268 "} sb_out;\n"
269 "\n"
270 "void main()\n"
271 "{\n"
272 " uint index = (uint(gl_FragCoord.y) * ${width} * ${samples}) + uint(gl_FragCoord.x) * ${samples} + gl_SampleID;\n"
273 " // Barycentric coodinates (I, J, K)\n"
274 " vec3 bary_coord = vec3(${barycoord}.x, ${barycoord}.y, 1.0f - ${barycoord}.x - ${barycoord}.y);\n"
275 "\n"
276 " // Vertex 0 -> (I = 0, J = 0, K = 1)\n"
277 " float data0 = interpolateAtVertexAMD(in_data_explicit, 0);\n"
278 " // Vertex 1 -> (I = 1, J = 0, K = 0)\n"
279 " float data1 = interpolateAtVertexAMD(in_data_explicit, 1);\n"
280 " // Vertex 1 -> (I = 0, J = 1, K = 0)\n"
281 " float data2 = interpolateAtVertexAMD(in_data_explicit, 2);\n"
282 " // Match data component with barycentric coordinate\n"
283 " vec3 data = vec3(data1, data2, data0);\n"
284 "\n"
285 " float res = (bary_coord.x * data.x) + (bary_coord.y * data.y) + (bary_coord.z * data.z);\n"
286 " float expected = in_data_${qualifier};\n"
287 "\n"
288 " sb_out.values[ index ] = vec4(expected, res, 0u, 0u);\n"
289 "\n"
290 " const float threshold = 0.0005f;\n"
291 " if (abs(res - expected) < threshold)\n"
292 " out_color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
293 " else\n"
294 " out_color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
295 "}\n"));
296
297 map<string, string> attributes;
298 attributes["width"] = de::toString(WIDTH);
299 attributes["numValues"] = de::toString(numValues * m_data.samples);
300 attributes["qualifier"] = interpolationToString(m_data.interpolation);
301 attributes["auxqualifier"] = auxiliaryQualifierToString(m_data.auxiliaryStorage);
302 attributes["barycoord"] = barycentricVariableString(m_data.interpolation, m_data.auxiliaryStorage);
303 attributes["samples"] = de::toString(m_data.samples);
304
305 programCollection.glslSources.add("vert") << glu::VertexSource(vertShader.specialize(attributes));
306 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShader.specialize(attributes));
307 }
308
createInstance(Context & context) const309 TestInstance* DrawTestCase::createInstance (Context& context) const
310 {
311 return new DrawTestInstance(context, m_data);
312 }
313
iterate(void)314 tcu::TestStatus DrawTestInstance::iterate (void)
315 {
316 de::SharedPtr<Image> colorTargetImage;
317 de::SharedPtr<Image> multisampleTargetImage;
318 tcu::TestLog &log = m_context.getTestContext().getLog();
319
320 // Run two iterations with shaders that have different interpolation decorations. Images should still match.
321 const DeviceInterface& vk = m_context.getDeviceInterface();
322 const VkDevice device = m_context.getDevice();
323 const CmdPoolCreateInfo cmdPoolCreateInfo (m_context.getUniversalQueueFamilyIndex());
324 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
325 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
326 const Unique<VkShaderModule> vs (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
327 const Unique<VkShaderModule> fs (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
328 de::SharedPtr<Buffer> vertexBuffer;
329 de::SharedPtr<Buffer> ssboBuffer;
330 Move<VkRenderPass> renderPass;
331 Move<VkImageView> colorTargetView;
332 Move<VkImageView> multisampleTargetView;
333 Move<VkFramebuffer> framebuffer;
334 Move<VkPipeline> pipeline;
335 Move<VkPipelineLayout> pipelineLayout;
336 Move<VkDescriptorPool> descriptorPool;
337 Move<VkDescriptorSet> descriptorSet;
338 Move<VkDescriptorSetLayout> descriptorSetLayout;
339
340 vk::VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
341 const deUint32 numValues = WIDTH * HEIGHT * m_data.samples;
342 const deBool useMultisampling = m_data.samples != VK_SAMPLE_COUNT_1_BIT;
343
344 // Create color buffer images.
345 {
346 const VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
347 const ImageCreateInfo targetImageCreateInfo (VK_IMAGE_TYPE_2D, imageFormat, targetImageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT,
348 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
349 colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
350
351 if (useMultisampling)
352 {
353 const ImageCreateInfo multisampleTargetImageCreateInfo (VK_IMAGE_TYPE_2D, imageFormat, targetImageExtent, 1, 1, m_data.samples,
354 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
355 multisampleTargetImage = Image::createAndAlloc(vk, device, multisampleTargetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
356 }
357 }
358
359 const ImageViewCreateInfo colorTargetViewInfo(colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, imageFormat);
360 colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
361
362 if (useMultisampling)
363 {
364 const ImageViewCreateInfo multisamplingTargetViewInfo(multisampleTargetImage->object(), vk::VK_IMAGE_VIEW_TYPE_2D, imageFormat);
365 multisampleTargetView = createImageView(vk, device, &multisamplingTargetViewInfo);
366 }
367
368 // Create render pass
369 if (!m_data.useDynamicRendering)
370 {
371 RenderPassCreateInfo renderPassCreateInfo;
372 renderPassCreateInfo.addAttachment(AttachmentDescription(imageFormat,
373 VK_SAMPLE_COUNT_1_BIT,
374 VK_ATTACHMENT_LOAD_OP_LOAD,
375 VK_ATTACHMENT_STORE_OP_STORE,
376 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
377 VK_ATTACHMENT_STORE_OP_STORE,
378 VK_IMAGE_LAYOUT_UNDEFINED,
379 VK_IMAGE_LAYOUT_GENERAL));
380
381 const VkAttachmentReference colorAttachmentRef = { 0u, VK_IMAGE_LAYOUT_GENERAL };
382 const VkAttachmentReference multisampleAttachmentRef = { 1u, VK_IMAGE_LAYOUT_GENERAL };
383
384 if (useMultisampling)
385 {
386 renderPassCreateInfo.addAttachment(AttachmentDescription(imageFormat,
387 m_data.samples,
388 vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
389 vk::VK_ATTACHMENT_STORE_OP_STORE,
390 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
391 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
392 vk::VK_IMAGE_LAYOUT_UNDEFINED,
393 vk::VK_IMAGE_LAYOUT_GENERAL));
394 }
395
396 renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS,
397 0,
398 0,
399 DE_NULL,
400 1u,
401 useMultisampling ? &multisampleAttachmentRef : &colorAttachmentRef,
402 useMultisampling ? &colorAttachmentRef : DE_NULL,
403 AttachmentReference(),
404 0,
405 DE_NULL));
406
407 renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
408
409 // Create framebuffer
410 vector<VkImageView> colorAttachments { *colorTargetView };
411 if (useMultisampling)
412 colorAttachments.push_back(*multisampleTargetView);
413
414 const FramebufferCreateInfo framebufferCreateInfo(*renderPass, colorAttachments, WIDTH, HEIGHT, 1);
415 framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
416 }
417
418 // Create vertex buffer.
419 {
420 const PositionValueVertex vertices[] =
421 {
422 PositionValueVertex(
423 tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), // Coord
424 float(1.0f)), // Value
425
426 PositionValueVertex(
427 tcu::Vec4(-1.0f, -1.0f, 0.25f, 0.75f), // Coord
428 float(0.0f)), // Value
429 PositionValueVertex(
430 tcu::Vec4( 1.0f, 1.0f, 0.0f, 2.0f), // Coord
431 float(0.5f)), // Value
432 PositionValueVertex(
433 tcu::Vec4( 1.0f, -1.0f, 1.0f, 0.5f), // Coord
434 float(1.0f)), // Value
435 };
436
437 const VkDeviceSize dataSize = DE_LENGTH_OF_ARRAY(vertices) * sizeof(PositionValueVertex);
438 vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
439 deUint8* ptr = reinterpret_cast<deUint8*>(vertexBuffer->getBoundMemory().getHostPtr());
440
441 deMemcpy(ptr, vertices, static_cast<size_t>(dataSize));
442 flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(), vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
443 }
444
445 // Create SSBO buffer
446 {
447 const VkDeviceSize dataSize = sizeof(tcu::Vec4) * numValues;
448 ssboBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
449 deUint8* ptr = reinterpret_cast<deUint8*>(ssboBuffer->getBoundMemory().getHostPtr());
450
451 deMemset(ptr, 0, static_cast<size_t>(dataSize));
452 flushMappedMemoryRange(vk, device, ssboBuffer->getBoundMemory().getMemory(), ssboBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
453 }
454
455 // Create Descriptor Set layout
456 {
457 descriptorSetLayout = DescriptorSetLayoutBuilder()
458 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
459 .build(vk, device);
460 }
461
462 // Create Descriptor Set
463 {
464 descriptorPool = DescriptorPoolBuilder()
465 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
466 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
467
468 descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
469
470 const VkDescriptorBufferInfo bufferInfo =
471 {
472 ssboBuffer->object(), // VkBuffer buffer;
473 0u, // VkDeviceSize offset;
474 VK_WHOLE_SIZE // VkDeviceSize range;
475 };
476
477 DescriptorSetUpdateBuilder()
478 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
479 .update(vk, device);
480 }
481
482 // Create pipeline
483 {
484 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
485
486 VkViewport viewport = makeViewport(WIDTH, HEIGHT);
487 VkRect2D scissor = makeRect2D(WIDTH, HEIGHT);
488
489 const VkVertexInputBindingDescription vertexInputBindingDescription = { 0, (deUint32)(sizeof(tcu::Vec4) + sizeof(float)), VK_VERTEX_INPUT_RATE_VERTEX };
490
491 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
492 {
493 { 0u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 0u },
494 { 1u, 0u, vk::VK_FORMAT_R32_SFLOAT, (deUint32)(sizeof(float)* 4) }
495 };
496
497 PipelineCreateInfo::VertexInputState vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription, 2, vertexInputAttributeDescriptions);
498
499 pipelineLayout = makePipelineLayout (vk, device, *descriptorSetLayout);
500
501 PipelineCreateInfo pipelineCreateInfo(*pipelineLayout, *renderPass, 0, 0);
502 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
503 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
504 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(vertexInputState));
505 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
506 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
507 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, vector<VkViewport>(1, viewport), vector<VkRect2D>(1, scissor)));
508 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
509 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
510 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState(m_data.samples));
511
512 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
513 {
514 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
515 DE_NULL,
516 0u,
517 1u,
518 &imageFormat,
519 VK_FORMAT_UNDEFINED,
520 VK_FORMAT_UNDEFINED
521 };
522
523 if (m_data.useDynamicRendering)
524 pipelineCreateInfo.pNext = &renderingCreateInfo;
525
526 pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
527 }
528
529 // Queue draw and read results.
530 {
531 const VkQueue queue = m_context.getUniversalQueue();
532 const ImageSubresourceRange subresourceRange (VK_IMAGE_ASPECT_COLOR_BIT);
533 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
534 const VkRect2D renderArea = makeRect2D(WIDTH, HEIGHT);
535 const VkDeviceSize vertexBufferOffset = 0;
536 const VkBuffer buffer = vertexBuffer->object();
537
538 vector<VkClearValue> clearColors;
539 clearColors.push_back(makeClearValueColor(clearColor));
540 if (useMultisampling)
541 clearColors.push_back(makeClearValueColor(clearColor));
542
543 beginCommandBuffer(vk, *cmdBuffer, 0u);
544
545 if (m_data.useDynamicRendering)
546 {
547 VkRenderingAttachmentInfoKHR colorAttachment
548 {
549 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
550 DE_NULL, // const void* pNext;
551 useMultisampling ? *multisampleTargetView : *colorTargetView, // VkImageView imageView;
552 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout;
553 useMultisampling ? VK_RESOLVE_MODE_AVERAGE_BIT : VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
554 useMultisampling ? *colorTargetView : DE_NULL, // VkImageView resolveImageView;
555 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout resolveImageLayout;
556 useMultisampling ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
557 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
558 clearColors[0] // VkClearValue clearValue;
559 };
560
561 VkRenderingInfoKHR renderingInfo
562 {
563 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
564 DE_NULL,
565 0u, // VkRenderingFlagsKHR flags;
566 renderArea, // VkRect2D renderArea;
567 1u, // deUint32 layerCount;
568 0u, // deUint32 viewMask;
569 1u, // deUint32 colorAttachmentCount;
570 &colorAttachment, // const VkRenderingAttachmentInfoKHR* pColorAttachments;
571 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
572 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
573 };
574
575 vk.cmdBeginRenderingKHR(*cmdBuffer, &renderingInfo);
576 }
577 else
578 {
579 const VkRenderPassBeginInfo renderPassBeginInfo =
580 {
581 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
582 DE_NULL, // const void* pNext;
583 *renderPass, // VkRenderPass renderPass;
584 *framebuffer, // VkFramebuffer framebuffer;
585 renderArea, // VkRect2D renderArea;
586 (deUint32)clearColors.size(), // deUint32 clearValueCount;
587 clearColors.data(), // const VkClearValue* pClearValues;
588 };
589
590 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
591 }
592
593 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &vertexBufferOffset);
594 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
595 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
596 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
597
598 if (m_data.useDynamicRendering)
599 endRendering(vk, *cmdBuffer);
600 else
601 endRenderPass(vk, *cmdBuffer);
602
603 endCommandBuffer(vk, *cmdBuffer);
604
605 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
606 }
607
608 qpTestResult res = QP_TEST_RESULT_PASS;
609
610 {
611 const Allocation& resultAlloc = ssboBuffer->getBoundMemory();
612 invalidateAlloc(vk, device, resultAlloc);
613
614 const tcu::Vec4* ptr = reinterpret_cast<tcu::Vec4*>(resultAlloc.getHostPtr());
615 for (deUint32 valueNdx = 0u; valueNdx < numValues; valueNdx++)
616 {
617 if (deFloatAbs(ptr[valueNdx].x() - ptr[valueNdx].y()) > 0.0005f)
618 {
619 log << tcu::TestLog::Message << "Expected value " << valueNdx << " is " << ptr[valueNdx].x() << ", got " << ptr[valueNdx].y()
620 << tcu::TestLog::EndMessage;
621 res = QP_TEST_RESULT_FAIL;
622 }
623 }
624 }
625
626 return tcu::TestStatus(res, qpGetTestResultName(res));
627 }
628
createTests(tcu::TestCaseGroup * testGroup,bool useDynamicRendering)629 void createTests (tcu::TestCaseGroup* testGroup, bool useDynamicRendering)
630 {
631 tcu::TestContext& testCtx = testGroup->getTestContext();
632
633 const VkSampleCountFlagBits samples[] =
634 {
635 VK_SAMPLE_COUNT_1_BIT,
636 VK_SAMPLE_COUNT_2_BIT,
637 VK_SAMPLE_COUNT_4_BIT,
638 VK_SAMPLE_COUNT_8_BIT,
639 VK_SAMPLE_COUNT_16_BIT,
640 VK_SAMPLE_COUNT_32_BIT,
641 VK_SAMPLE_COUNT_64_BIT,
642 };
643
644 const Interpolation interTypes[] =
645 {
646 SMOOTH,
647 NOPERSPECTIVE
648 };
649
650 const AuxiliaryQualifier auxQualifiers[] =
651 {
652 AUX_NONE,
653 AUX_SAMPLE,
654 AUX_CENTROID,
655 };
656
657 for (deUint32 sampleNdx = 0; sampleNdx < DE_LENGTH_OF_ARRAY(samples); sampleNdx++)
658 for (deUint32 auxNdx = 0; auxNdx < DE_LENGTH_OF_ARRAY(auxQualifiers); auxNdx++)
659 for (deUint32 interNdx = 0; interNdx < DE_LENGTH_OF_ARRAY(interTypes); interNdx++)
660 {
661 if (samples[sampleNdx] == VK_SAMPLE_COUNT_1_BIT && auxQualifiers[auxNdx] != AUX_NONE)
662 continue;
663
664 const DrawParams params =
665 {
666 interTypes[interNdx],
667 samples[sampleNdx],
668 auxQualifiers[auxNdx],
669 useDynamicRendering
670 };
671 testGroup->addChild(new DrawTestCase(testCtx, getTestName(params).c_str(), "", params));
672 }
673 }
674
675 } // anonymous
676
createExplicitVertexParameterTests(tcu::TestContext & testCtx,bool useDynamicRendering)677 tcu::TestCaseGroup* createExplicitVertexParameterTests (tcu::TestContext& testCtx, bool useDynamicRendering)
678 {
679 return createTestGroup(testCtx, "explicit_vertex_parameter", "Tests for VK_AMD_shader_explicit_vertex_parameter.", createTests, useDynamicRendering);
680 }
681
682 } // Draw
683 } // vkt
684