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::__anon0721d3930111::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 };
98
interpolationToString(Interpolation interpolation)99 const char* interpolationToString (Interpolation interpolation)
100 {
101 switch (interpolation)
102 {
103 case SMOOTH:
104 return "smooth";
105 case NOPERSPECTIVE:
106 return "noperspective";
107 default:
108 DE_FATAL("Invalid interpolation enum");
109 }
110
111 return "";
112 }
113
barycentricVariableString(Interpolation interpolation,AuxiliaryQualifier aux)114 std::string barycentricVariableString (Interpolation interpolation, AuxiliaryQualifier aux)
115 {
116 std::ostringstream name;
117 name << "gl_BaryCoord";
118 switch (interpolation)
119 {
120 case SMOOTH:
121 name << "Smooth";
122 break;
123 case NOPERSPECTIVE:
124 name << "NoPersp";
125 break;
126 default:
127 DE_FATAL("Invalid interpolation enum");
128 }
129
130 switch (aux)
131 {
132 case AUX_CENTROID:
133 name << "Centroid";
134 break;
135 case AUX_SAMPLE:
136 name << "Sample";
137 break;
138 case AUX_NONE:
139 name << "";
140 break;
141 default:
142 DE_FATAL("Invalid auxiliary storage qualifier enum");
143 }
144 name << "AMD";
145 return name.str();
146 }
147
auxiliaryQualifierToString(AuxiliaryQualifier aux)148 const char* auxiliaryQualifierToString (AuxiliaryQualifier aux)
149 {
150 switch (aux)
151 {
152 case AUX_CENTROID:
153 return "centroid";
154 case AUX_SAMPLE:
155 return "sample";
156 case AUX_NONE:
157 return "";
158 default:
159 DE_FATAL("Invalid auxiliary storage qualifier enum");
160 }
161
162 return "";
163 }
164
getTestName(DrawParams params)165 std::string getTestName (DrawParams params)
166 {
167 std::ostringstream name;
168
169 name << interpolationToString(params.interpolation) << "_";
170
171 if (params.auxiliaryStorage != AUX_NONE)
172 name << auxiliaryQualifierToString(params.auxiliaryStorage) << "_";
173
174 name << "samples_" << de::toString(params.samples);
175
176 return name.str();
177 }
178
179 class DrawTestInstance : public TestInstance
180 {
181 public:
182 DrawTestInstance (Context& context, const DrawParams& data);
183 ~DrawTestInstance (void);
184 tcu::TestStatus iterate (void);
185 private:
186 DrawParams m_data;
187 };
188
DrawTestInstance(Context & context,const DrawParams & data)189 DrawTestInstance::DrawTestInstance (Context& context, const DrawParams& data)
190 : vkt::TestInstance (context)
191 , m_data (data)
192 {
193 }
194
~DrawTestInstance(void)195 DrawTestInstance::~DrawTestInstance (void)
196 {
197 }
198
199 class DrawTestCase : public TestCase
200 {
201 public:
202 DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const DrawParams data);
203 ~DrawTestCase (void);
204 virtual void initPrograms (SourceCollections& programCollection) const;
205 virtual TestInstance* createInstance (Context& context) const;
206 virtual void checkSupport (Context& context) const;
207
208 private:
209 DrawParams m_data;
210 };
211
DrawTestCase(tcu::TestContext & context,const char * name,const char * desc,const DrawParams data)212 DrawTestCase::DrawTestCase (tcu::TestContext& context, const char* name, const char* desc, const DrawParams data)
213 : vkt::TestCase (context, name, desc)
214 , m_data (data)
215 {
216 }
217
~DrawTestCase(void)218 DrawTestCase::~DrawTestCase (void)
219 {
220 }
221
checkSupport(Context & context) const222 void DrawTestCase::checkSupport(Context &context) const
223 {
224 context.requireDeviceFunctionality("VK_AMD_shader_explicit_vertex_parameter");
225
226 if ((context.getDeviceProperties().limits.framebufferColorSampleCounts & m_data.samples) == 0)
227 TCU_THROW(NotSupportedError, "framebufferColorSampleCounts: sample count not supported");
228 }
229
initPrograms(SourceCollections & programCollection) const230 void DrawTestCase::initPrograms (SourceCollections& programCollection) const
231 {
232 const deUint32 numValues = WIDTH * HEIGHT * m_data.samples;
233
234 const tcu::StringTemplate vertShader (string(
235 "#version 450\n"
236 "#extension GL_AMD_shader_explicit_vertex_parameter : require\n"
237 "\n"
238 "layout(location = 0) in vec4 in_position;\n"
239 "layout(location = 1) in float in_data;\n"
240 "layout(location = 0) __explicitInterpAMD out float out_data_explicit;\n"
241 "layout(location = 1) ${auxqualifier} ${qualifier} out float out_data_${qualifier};\n"
242 "\n"
243 "out gl_PerVertex {\n"
244 " vec4 gl_Position;\n"
245 " float gl_PointSize;\n"
246 "};\n"
247 "\n"
248 "void main() {\n"
249 " gl_PointSize = 1.0;\n"
250 " gl_Position = in_position;\n"
251 " out_data_explicit = in_data;\n"
252 " out_data_${qualifier} = in_data;\n"
253 "}\n"));
254
255 const tcu::StringTemplate fragShader (string(
256 "#version 450\n"
257 "#extension GL_AMD_shader_explicit_vertex_parameter : require\n"
258 "\n"
259 "layout(location = 0) __explicitInterpAMD in float in_data_explicit;\n"
260 "layout(location = 1) ${auxqualifier} ${qualifier} in float in_data_${qualifier};\n"
261 "layout(location = 0) out vec4 out_color;\n"
262 "layout (binding = 0, std140) writeonly buffer Output {\n"
263 " vec4 values [${numValues}];\n"
264 "} sb_out;\n"
265 "\n"
266 "void main()\n"
267 "{\n"
268 " uint index = (uint(gl_FragCoord.y) * ${width} * ${samples}) + uint(gl_FragCoord.x) * ${samples} + gl_SampleID;\n"
269 " // Barycentric coodinates (I, J, K)\n"
270 " vec3 bary_coord = vec3(${barycoord}.x, ${barycoord}.y, 1.0f - ${barycoord}.x - ${barycoord}.y);\n"
271 "\n"
272 " // Vertex 0 -> (I = 0, J = 0, K = 1)\n"
273 " float data0 = interpolateAtVertexAMD(in_data_explicit, 0);\n"
274 " // Vertex 1 -> (I = 1, J = 0, K = 0)\n"
275 " float data1 = interpolateAtVertexAMD(in_data_explicit, 1);\n"
276 " // Vertex 1 -> (I = 0, J = 1, K = 0)\n"
277 " float data2 = interpolateAtVertexAMD(in_data_explicit, 2);\n"
278 " // Match data component with barycentric coordinate\n"
279 " vec3 data = vec3(data1, data2, data0);\n"
280 "\n"
281 " float res = (bary_coord.x * data.x) + (bary_coord.y * data.y) + (bary_coord.z * data.z);\n"
282 " float expected = in_data_${qualifier};\n"
283 "\n"
284 " sb_out.values[ index ] = vec4(expected, res, 0u, 0u);\n"
285 "\n"
286 " const float threshold = 0.0005f;\n"
287 " if (abs(res - expected) < threshold)\n"
288 " out_color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
289 " else\n"
290 " out_color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
291 "}\n"));
292
293 map<string, string> attributes;
294 attributes["width"] = de::toString(WIDTH);
295 attributes["numValues"] = de::toString(numValues * m_data.samples);
296 attributes["qualifier"] = interpolationToString(m_data.interpolation);
297 attributes["auxqualifier"] = auxiliaryQualifierToString(m_data.auxiliaryStorage);
298 attributes["barycoord"] = barycentricVariableString(m_data.interpolation, m_data.auxiliaryStorage);
299 attributes["samples"] = de::toString(m_data.samples);
300
301 programCollection.glslSources.add("vert") << glu::VertexSource(vertShader.specialize(attributes));
302 programCollection.glslSources.add("frag") << glu::FragmentSource(fragShader.specialize(attributes));
303 }
304
createInstance(Context & context) const305 TestInstance* DrawTestCase::createInstance (Context& context) const
306 {
307 return new DrawTestInstance(context, m_data);
308 }
309
iterate(void)310 tcu::TestStatus DrawTestInstance::iterate (void)
311 {
312 de::SharedPtr<Image> colorTargetImage;
313 de::SharedPtr<Image> multisampleTargetImage;
314 tcu::TestLog &log = m_context.getTestContext().getLog();
315
316 // Run two iterations with shaders that have different interpolation decorations. Images should still match.
317 const DeviceInterface& vk = m_context.getDeviceInterface();
318 const VkDevice device = m_context.getDevice();
319 const CmdPoolCreateInfo cmdPoolCreateInfo (m_context.getUniversalQueueFamilyIndex());
320 Move<VkCommandPool> cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
321 Move<VkCommandBuffer> cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
322 const Unique<VkShaderModule> vs (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
323 const Unique<VkShaderModule> fs (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
324 de::SharedPtr<Buffer> vertexBuffer;
325 de::SharedPtr<Buffer> ssboBuffer;
326 Move<VkRenderPass> renderPass;
327 Move<VkImageView> colorTargetView;
328 Move<VkImageView> multisampleTargetView;
329 Move<VkFramebuffer> framebuffer;
330 Move<VkPipeline> pipeline;
331 Move<VkPipelineLayout> pipelineLayout;
332 Move<VkDescriptorPool> descriptorPool;
333 Move<VkDescriptorSet> descriptorSet;
334 Move<VkDescriptorSetLayout> descriptorSetLayout;
335
336 vk::VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
337 const deUint32 numValues = WIDTH * HEIGHT * m_data.samples;
338 const deBool useMultisampling = m_data.samples != VK_SAMPLE_COUNT_1_BIT;
339
340 // Create color buffer images.
341 {
342 const VkExtent3D targetImageExtent = { WIDTH, HEIGHT, 1 };
343 const ImageCreateInfo targetImageCreateInfo (VK_IMAGE_TYPE_2D, imageFormat, targetImageExtent, 1, 1, VK_SAMPLE_COUNT_1_BIT,
344 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
345 colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
346
347 if (useMultisampling)
348 {
349 const ImageCreateInfo multisampleTargetImageCreateInfo (VK_IMAGE_TYPE_2D, imageFormat, targetImageExtent, 1, 1, m_data.samples,
350 VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT);
351 multisampleTargetImage = Image::createAndAlloc(vk, device, multisampleTargetImageCreateInfo, m_context.getDefaultAllocator(), m_context.getUniversalQueueFamilyIndex());
352 }
353 }
354
355 // Create render pass and frame buffer.
356 {
357 const ImageViewCreateInfo colorTargetViewInfo (colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, imageFormat);
358 colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
359
360 RenderPassCreateInfo renderPassCreateInfo;
361 renderPassCreateInfo.addAttachment(AttachmentDescription(imageFormat,
362 VK_SAMPLE_COUNT_1_BIT,
363 VK_ATTACHMENT_LOAD_OP_LOAD,
364 VK_ATTACHMENT_STORE_OP_STORE,
365 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
366 VK_ATTACHMENT_STORE_OP_STORE,
367 VK_IMAGE_LAYOUT_UNDEFINED,
368 VK_IMAGE_LAYOUT_GENERAL));
369
370 const VkAttachmentReference colorAttachmentRef = { 0u, VK_IMAGE_LAYOUT_GENERAL };
371 const VkAttachmentReference multisampleAttachmentRef = { 1u, VK_IMAGE_LAYOUT_GENERAL };
372 vector<VkImageView> colorAttachments;
373 colorAttachments.push_back(*colorTargetView);
374
375 if (useMultisampling)
376 {
377 const ImageViewCreateInfo multisamplingTargetViewInfo (multisampleTargetImage->object(),
378 vk::VK_IMAGE_VIEW_TYPE_2D,
379 imageFormat);
380
381
382 multisampleTargetView = createImageView(vk, device, &multisamplingTargetViewInfo);
383 colorAttachments.push_back(*multisampleTargetView);
384
385 renderPassCreateInfo.addAttachment(AttachmentDescription(imageFormat,
386 m_data.samples,
387 vk::VK_ATTACHMENT_LOAD_OP_CLEAR,
388 vk::VK_ATTACHMENT_STORE_OP_STORE,
389 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,
390 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,
391 vk::VK_IMAGE_LAYOUT_UNDEFINED,
392 vk::VK_IMAGE_LAYOUT_GENERAL));
393 }
394
395 renderPassCreateInfo.addSubpass(SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS,
396 0,
397 0,
398 DE_NULL,
399 1u,
400 useMultisampling ? &multisampleAttachmentRef : &colorAttachmentRef,
401 useMultisampling ? &colorAttachmentRef : DE_NULL,
402 AttachmentReference(),
403 0,
404 DE_NULL));
405
406 renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
407
408 const FramebufferCreateInfo framebufferCreateInfo (*renderPass, colorAttachments, WIDTH, HEIGHT, 1);
409 framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
410 }
411
412 // Create vertex buffer.
413 {
414 const PositionValueVertex vertices[] =
415 {
416 PositionValueVertex(
417 tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f), // Coord
418 float(1.0f)), // Value
419
420 PositionValueVertex(
421 tcu::Vec4(-1.0f, -1.0f, 0.25f, 0.75f), // Coord
422 float(0.0f)), // Value
423 PositionValueVertex(
424 tcu::Vec4( 1.0f, 1.0f, 0.0f, 2.0f), // Coord
425 float(0.5f)), // Value
426 PositionValueVertex(
427 tcu::Vec4( 1.0f, -1.0f, 1.0f, 0.5f), // Coord
428 float(1.0f)), // Value
429 };
430
431 const VkDeviceSize dataSize = DE_LENGTH_OF_ARRAY(vertices) * sizeof(PositionValueVertex);
432 vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
433 deUint8* ptr = reinterpret_cast<deUint8*>(vertexBuffer->getBoundMemory().getHostPtr());
434
435 deMemcpy(ptr, vertices, static_cast<size_t>(dataSize));
436 flushMappedMemoryRange(vk, device, vertexBuffer->getBoundMemory().getMemory(), vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
437 }
438
439 // Create SSBO buffer
440 {
441 const VkDeviceSize dataSize = sizeof(tcu::Vec4) * numValues;
442 ssboBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(dataSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
443 deUint8* ptr = reinterpret_cast<deUint8*>(ssboBuffer->getBoundMemory().getHostPtr());
444
445 deMemset(ptr, 0, static_cast<size_t>(dataSize));
446 flushMappedMemoryRange(vk, device, ssboBuffer->getBoundMemory().getMemory(), ssboBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
447 }
448
449 // Create Descriptor Set layout
450 {
451 descriptorSetLayout = DescriptorSetLayoutBuilder()
452 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT)
453 .build(vk, device);
454 }
455
456 // Create Descriptor Set
457 {
458 descriptorPool = DescriptorPoolBuilder()
459 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
460 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
461
462 descriptorSet = makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout);
463
464 const VkDescriptorBufferInfo bufferInfo =
465 {
466 ssboBuffer->object(), // VkBuffer buffer;
467 0u, // VkDeviceSize offset;
468 VK_WHOLE_SIZE // VkDeviceSize range;
469 };
470
471 DescriptorSetUpdateBuilder()
472 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo)
473 .update(vk, device);
474 }
475
476 // Create pipeline
477 {
478 const PipelineCreateInfo::ColorBlendState::Attachment vkCbAttachmentState;
479
480 VkViewport viewport = makeViewport(WIDTH, HEIGHT);
481 VkRect2D scissor = makeRect2D(WIDTH, HEIGHT);
482
483 const VkVertexInputBindingDescription vertexInputBindingDescription = { 0, (deUint32)(sizeof(tcu::Vec4) + sizeof(float)), VK_VERTEX_INPUT_RATE_VERTEX };
484
485 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
486 {
487 { 0u, 0u, vk::VK_FORMAT_R32G32B32A32_SFLOAT, 0u },
488 { 1u, 0u, vk::VK_FORMAT_R32_SFLOAT, (deUint32)(sizeof(float)* 4) }
489 };
490
491 PipelineCreateInfo::VertexInputState vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription, 2, vertexInputAttributeDescriptions);
492
493 pipelineLayout = makePipelineLayout (vk, device, *descriptorSetLayout);
494
495 PipelineCreateInfo pipelineCreateInfo(*pipelineLayout, *renderPass, 0, 0);
496 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vs, "main", VK_SHADER_STAGE_VERTEX_BIT));
497 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fs, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
498 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(vertexInputState));
499 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP));
500 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
501 pipelineCreateInfo.addState(PipelineCreateInfo::ViewportState(1, vector<VkViewport>(1, viewport), vector<VkRect2D>(1, scissor)));
502 pipelineCreateInfo.addState(PipelineCreateInfo::DepthStencilState());
503 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
504 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState(m_data.samples));
505
506 pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
507 }
508
509 // Queue draw and read results.
510 {
511 const VkQueue queue = m_context.getUniversalQueue();
512 const ImageSubresourceRange subresourceRange (VK_IMAGE_ASPECT_COLOR_BIT);
513 const tcu::Vec4 clearColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
514 const VkRect2D renderArea = makeRect2D(WIDTH, HEIGHT);
515 const VkDeviceSize vertexBufferOffset = 0;
516 const VkBuffer buffer = vertexBuffer->object();
517
518 vector<VkClearValue> clearColors;
519 clearColors.push_back(makeClearValueColor(clearColor));
520
521 if (useMultisampling)
522 clearColors.push_back(makeClearValueColor(clearColor));
523
524 beginCommandBuffer(vk, *cmdBuffer, 0u);
525 const VkRenderPassBeginInfo renderPassBeginInfo =
526 {
527 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
528 DE_NULL, // const void* pNext;
529 *renderPass, // VkRenderPass renderPass;
530 *framebuffer, // VkFramebuffer framebuffer;
531 renderArea, // VkRect2D renderArea;
532 (deUint32)clearColors.size(), // deUint32 clearValueCount;
533 clearColors.data(), // const VkClearValue* pClearValues;
534 };
535
536 vk.cmdBeginRenderPass(*cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
537 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &vertexBufferOffset);
538 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
539 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
540 vk.cmdDraw(*cmdBuffer, 4u, 1u, 0u, 0u);
541 endRenderPass(vk, *cmdBuffer);
542 endCommandBuffer(vk, *cmdBuffer);
543
544 submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
545 }
546
547 qpTestResult res = QP_TEST_RESULT_PASS;
548
549 {
550 const Allocation& resultAlloc = ssboBuffer->getBoundMemory();
551 invalidateAlloc(vk, device, resultAlloc);
552
553 const tcu::Vec4* ptr = reinterpret_cast<tcu::Vec4*>(resultAlloc.getHostPtr());
554 for (deUint32 valueNdx = 0u; valueNdx < numValues; valueNdx++)
555 {
556 if (deFloatAbs(ptr[valueNdx].x() - ptr[valueNdx].y()) > 0.0005f)
557 {
558 log << tcu::TestLog::Message << "Expected value " << valueNdx << " is " << ptr[valueNdx].x() << ", got " << ptr[valueNdx].y()
559 << tcu::TestLog::EndMessage;
560 res = QP_TEST_RESULT_FAIL;
561 }
562 }
563 }
564
565 return tcu::TestStatus(res, qpGetTestResultName(res));
566 }
567
createTests(tcu::TestCaseGroup * testGroup)568 void createTests (tcu::TestCaseGroup* testGroup)
569 {
570 tcu::TestContext& testCtx = testGroup->getTestContext();
571
572 const VkSampleCountFlagBits samples[] =
573 {
574 VK_SAMPLE_COUNT_1_BIT,
575 VK_SAMPLE_COUNT_2_BIT,
576 VK_SAMPLE_COUNT_4_BIT,
577 VK_SAMPLE_COUNT_8_BIT,
578 VK_SAMPLE_COUNT_16_BIT,
579 VK_SAMPLE_COUNT_32_BIT,
580 VK_SAMPLE_COUNT_64_BIT,
581 };
582
583 const Interpolation interTypes[] =
584 {
585 SMOOTH,
586 NOPERSPECTIVE
587 };
588
589 const AuxiliaryQualifier auxQualifiers[] =
590 {
591 AUX_NONE,
592 AUX_SAMPLE,
593 AUX_CENTROID,
594 };
595
596 for (deUint32 sampleNdx = 0; sampleNdx < DE_LENGTH_OF_ARRAY(samples); sampleNdx++)
597 for (deUint32 auxNdx = 0; auxNdx < DE_LENGTH_OF_ARRAY(auxQualifiers); auxNdx++)
598 for (deUint32 interNdx = 0; interNdx < DE_LENGTH_OF_ARRAY(interTypes); interNdx++)
599 {
600 if (samples[sampleNdx] == VK_SAMPLE_COUNT_1_BIT && auxQualifiers[auxNdx] != AUX_NONE)
601 continue;
602
603 const DrawParams params =
604 {
605 interTypes[interNdx],
606 samples[sampleNdx],
607 auxQualifiers[auxNdx],
608 };
609 testGroup->addChild(new DrawTestCase(testCtx, getTestName(params).c_str(), "", params));
610 }
611 }
612
613 } // anonymous
614
createExplicitVertexParameterTests(tcu::TestContext & testCtx)615 tcu::TestCaseGroup* createExplicitVertexParameterTests (tcu::TestContext& testCtx)
616 {
617 return createTestGroup(testCtx, "explicit_vertex_parameter", "Tests for VK_AMD_shader_explicit_vertex_parameter.", createTests);
618 }
619
620 } // Draw
621 } // vkt
622