1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 Google LLC
6 * Copyright (c) 2019 The Khronos Group Inc.
7 * Copyright (c) 2023 LunarG, Inc.
8 * Copyright (c) 2023 Nintendo
9 *
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
21 *
22 *//*!
23 * \file
24 * \brief Miscellaneous pipeline tests.
25 *//*--------------------------------------------------------------------*/
26
27 #include <string>
28 #include <memory>
29 #include <vector>
30 #include <algorithm>
31 #include <array>
32 #include <numeric>
33 #include <memory>
34
35 #include "vkPipelineConstructionUtil.hpp"
36 #include "vktTestGroupUtil.hpp"
37 #include "vktAmberTestCase.hpp"
38 #include "vktPipelineMiscTests.hpp"
39
40 #include "vkDefs.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "vkImageUtil.hpp"
43 #include "deStringUtil.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vkTypeUtil.hpp"
46 #include "vkCmdUtil.hpp"
47 #include "vkObjUtil.hpp"
48 #include "vkImageWithMemory.hpp"
49 #include "vkBarrierUtil.hpp"
50 #include "vkBufferWithMemory.hpp"
51 #include "vkBuilderUtil.hpp"
52 #include "vktPipelineReferenceRenderer.hpp"
53 #include "vkBuilderUtil.hpp"
54
55 namespace vkt
56 {
57 namespace pipeline
58 {
59
60 using namespace vk;
61
62 namespace
63 {
64
65 enum AmberFeatureBits
66 {
67 AMBER_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS = (1 << 0),
68 AMBER_FEATURE_TESSELATION_SHADER = (1 << 1),
69 AMBER_FEATURE_GEOMETRY_SHADER = (1 << 2),
70 };
71
72 using AmberFeatureFlags = deUint32;
73
74 #ifndef CTS_USES_VULKANSC
getFeatureList(AmberFeatureFlags flags)75 std::vector<std::string> getFeatureList (AmberFeatureFlags flags)
76 {
77 std::vector<std::string> requirements;
78
79 if (flags & AMBER_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS)
80 requirements.push_back("Features.vertexPipelineStoresAndAtomics");
81
82 if (flags & AMBER_FEATURE_TESSELATION_SHADER)
83 requirements.push_back("Features.tessellationShader");
84
85 if (flags & AMBER_FEATURE_GEOMETRY_SHADER)
86 requirements.push_back("Features.geometryShader");
87
88 return requirements;
89 }
90 #endif // CTS_USES_VULKANSC
91
addMonolithicAmberTests(tcu::TestCaseGroup * tests)92 void addMonolithicAmberTests (tcu::TestCaseGroup* tests)
93 {
94 #ifndef CTS_USES_VULKANSC
95 tcu::TestContext& testCtx = tests->getTestContext();
96
97 // Shader test files are saved in <path>/external/vulkancts/data/vulkan/amber/pipeline/<basename>.amber
98 struct Case {
99 const char* basename;
100 AmberFeatureFlags flags;
101 };
102
103 const Case cases[] =
104 {
105 {
106 "position_to_ssbo",
107 (AMBER_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS),
108 },
109 {
110 "primitive_id_from_tess",
111 (AMBER_FEATURE_TESSELATION_SHADER | AMBER_FEATURE_GEOMETRY_SHADER),
112 },
113 };
114 for (unsigned i = 0; i < DE_LENGTH_OF_ARRAY(cases) ; ++i)
115 {
116 std::string file = std::string(cases[i].basename) + ".amber";
117 std::vector<std::string> requirements = getFeatureList(cases[i].flags);
118 cts_amber::AmberTestCase *testCase = cts_amber::createAmberTestCase(testCtx, cases[i].basename, "pipeline", file, requirements);
119
120 tests->addChild(testCase);
121 }
122 #else
123 DE_UNREF(tests);
124 #endif
125 }
126
127 class ImplicitPrimitiveIDPassthroughCase : public vkt::TestCase
128 {
129 public:
ImplicitPrimitiveIDPassthroughCase(tcu::TestContext & testCtx,const std::string & name,const PipelineConstructionType pipelineConstructionType,bool withTessellation)130 ImplicitPrimitiveIDPassthroughCase (tcu::TestContext& testCtx,
131 const std::string& name,
132 const PipelineConstructionType pipelineConstructionType,
133 bool withTessellation)
134 : vkt::TestCase(testCtx, name)
135 , m_pipelineConstructionType(pipelineConstructionType)
136 , m_withTessellationPassthrough(withTessellation)
137 {
138 }
~ImplicitPrimitiveIDPassthroughCase(void)139 ~ImplicitPrimitiveIDPassthroughCase (void) {}
140 void initPrograms (SourceCollections& programCollection) const override;
141 void checkSupport (Context& context) const override;
142 TestInstance* createInstance (Context& context) const override;
143
144 const PipelineConstructionType m_pipelineConstructionType;
145 private:
146 bool m_withTessellationPassthrough;
147 };
148
149 class ImplicitPrimitiveIDPassthroughInstance : public vkt::TestInstance
150 {
151 public:
ImplicitPrimitiveIDPassthroughInstance(Context & context,const PipelineConstructionType pipelineConstructionType,bool withTessellation)152 ImplicitPrimitiveIDPassthroughInstance (Context& context,
153 const PipelineConstructionType pipelineConstructionType,
154 bool withTessellation)
155 : vkt::TestInstance (context)
156 , m_pipelineConstructionType (pipelineConstructionType)
157 , m_renderSize (2, 2)
158 , m_extent(makeExtent3D (m_renderSize.x(), m_renderSize.y(), 1u))
159 , m_graphicsPipeline (context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType)
160 , m_withTessellationPassthrough (withTessellation)
161 {
162 }
~ImplicitPrimitiveIDPassthroughInstance(void)163 ~ImplicitPrimitiveIDPassthroughInstance (void) {}
164 tcu::TestStatus iterate (void) override;
165
166 private:
167 PipelineConstructionType m_pipelineConstructionType;
168 const tcu::UVec2 m_renderSize;
169 const VkExtent3D m_extent;
170 const VkFormat m_format = VK_FORMAT_R8G8B8A8_UNORM;
171 GraphicsPipelineWrapper m_graphicsPipeline;
172 bool m_withTessellationPassthrough;
173 };
174
createInstance(Context & context) const175 TestInstance* ImplicitPrimitiveIDPassthroughCase::createInstance (Context& context) const
176 {
177 return new ImplicitPrimitiveIDPassthroughInstance(context, m_pipelineConstructionType, m_withTessellationPassthrough);
178 }
179
checkSupport(Context & context) const180 void ImplicitPrimitiveIDPassthroughCase::checkSupport (Context &context) const
181 {
182 if (m_withTessellationPassthrough)
183 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
184
185 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
186
187 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
188 }
189
initPrograms(SourceCollections & sources) const190 void ImplicitPrimitiveIDPassthroughCase::initPrograms(SourceCollections& sources) const
191 {
192 std::ostringstream vert;
193 // Generate a vertically split framebuffer, filled with red on the
194 // left, and a green on the right.
195 vert
196 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
197 << "void main ()\n"
198 << "{\n"
199 << " switch (gl_VertexIndex) {\n"
200 << " case 0:\n"
201 << " gl_Position = vec4(-3.0, -1.0, 0.0, 1.0);\n"
202 << " break;\n"
203 << " case 1:\n"
204 << " gl_Position = vec4(0.0, 3.0, 0.0, 1.0);\n"
205 << " break;\n"
206 << " case 2:\n"
207 << " gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
208 << " break;\n"
209 << " case 3:\n"
210 << " gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
211 << " break;\n"
212 << " case 4:\n"
213 << " gl_Position = vec4(3.0, -1.0, 0.0, 1.0);\n"
214 << " break;\n"
215 << " case 5:\n"
216 << " gl_Position = vec4(0.0, 3.0, 0.0, 1.0);\n"
217 << " break;\n"
218 << " }\n"
219 << "}\n"
220 ;
221 sources.glslSources.add("vert") << glu::VertexSource(vert.str());
222
223 if (m_withTessellationPassthrough) {
224 std::ostringstream tsc;
225 tsc
226 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
227 << "layout (vertices = 3) out;\n"
228 << "\n"
229 << "void main ()\n"
230 << "{\n"
231 << " if (gl_InvocationID == 0) {\n"
232 << " gl_TessLevelInner[0] = 1.0;\n"
233 << " gl_TessLevelInner[1] = 1.0;\n"
234 << " gl_TessLevelOuter[0] = 1.0;\n"
235 << " gl_TessLevelOuter[1] = 1.0;\n"
236 << " gl_TessLevelOuter[2] = 1.0;\n"
237 << " gl_TessLevelOuter[3] = 1.0;\n"
238 << " }\n"
239 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
240 << "}\n";
241 sources.glslSources.add("tsc") << glu::TessellationControlSource(tsc.str());
242
243 std::ostringstream tse;
244 tse
245 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
246 << "layout (triangles, equal_spacing, cw) in;\n"
247 << "\n"
248 << "void main ()\n"
249 << "{\n"
250 << " gl_Position = gl_in[0].gl_Position * gl_TessCoord.x +\n"
251 << " gl_in[1].gl_Position * gl_TessCoord.y +\n"
252 << " gl_in[2].gl_Position * gl_TessCoord.z;\n"
253 << "}\n"
254 ;
255 sources.glslSources.add("tse") << glu::TessellationEvaluationSource(tse.str());
256 }
257
258 std::ostringstream frag;
259 frag
260 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
261 << "layout (location=0) out vec4 outColor;\n"
262 << "\n"
263 << "void main ()\n"
264 << "{\n"
265 << " const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
266 << " const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
267 << " outColor = (gl_PrimitiveID % 2 == 0) ? red : green;\n"
268 << "}\n"
269 ;
270 sources.glslSources.add("frag") << glu::FragmentSource(frag.str());
271 }
272
iterate()273 tcu::TestStatus ImplicitPrimitiveIDPassthroughInstance::iterate ()
274 {
275 const auto& vkd = m_context.getDeviceInterface();
276 const auto device = m_context.getDevice();
277 auto& alloc = m_context.getDefaultAllocator();
278 const auto qIndex = m_context.getUniversalQueueFamilyIndex();
279 const auto queue = m_context.getUniversalQueue();
280 const auto tcuFormat = mapVkFormat(m_format);
281 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
282 const auto verifBufferUsage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
283 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f);
284
285 // Color attachment.
286 const VkImageCreateInfo colorBufferInfo =
287 {
288 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
289 nullptr, // const void* pNext;
290 0u, // VkImageCreateFlags flags;
291 VK_IMAGE_TYPE_2D, // VkImageType imageType;
292 m_format, // VkFormat format;
293 m_extent, // VkExtent3D extent;
294 1u, // uint32_t mipLevels;
295 1u, // uint32_t arrayLayers;
296 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
297 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
298 colorUsage, // VkImageUsageFlags usage;
299 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
300 0u, // uint32_t queueFamilyIndexCount;
301 nullptr, // const uint32_t* pQueueFamilyIndices;
302 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
303 };
304 ImageWithMemory colorBuffer (vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
305 const auto colorSRR = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
306 const auto colorSRL = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
307 const auto colorBufferView = makeImageView(vkd, device, colorBuffer.get(), VK_IMAGE_VIEW_TYPE_2D, m_format, colorSRR);
308
309 // Verification buffer.
310 const auto verifBufferSize = static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * m_extent.width * m_extent.height;
311 const auto verifBufferInfo = makeBufferCreateInfo(verifBufferSize, verifBufferUsage);
312 BufferWithMemory verifBuffer (vkd, device, alloc, verifBufferInfo, MemoryRequirement::HostVisible);
313 auto& verifBufferAlloc = verifBuffer.getAllocation();
314
315 // Render pass and framebuffer.
316 RenderPassWrapper renderPass (m_pipelineConstructionType, vkd, device, m_format);
317 renderPass.createFramebuffer(vkd, device, colorBuffer.get(), colorBufferView.get(), m_extent.width, m_extent.height);
318
319 // Shader modules.
320 const auto& binaries = m_context.getBinaryCollection();
321 const auto vertModule = ShaderWrapper(vkd, device, binaries.get("vert"));
322 const auto fragModule = ShaderWrapper(vkd, device, binaries.get("frag"));
323 ShaderWrapper tscModule;
324 ShaderWrapper tseModule;
325
326 if (m_withTessellationPassthrough) {
327 tscModule = ShaderWrapper(vkd, device, binaries.get("tsc"));
328 tseModule = ShaderWrapper(vkd, device, binaries.get("tse"));
329 }
330
331 // Viewports and scissors.
332 const std::vector<VkViewport> viewports (1u, makeViewport(m_extent));
333 const std::vector<VkRect2D> scissors (1u, makeRect2D(m_extent));
334
335 const VkPipelineVertexInputStateCreateInfo vertexInputState = initVulkanStructure();
336 const VkPipelineRasterizationStateCreateInfo rasterizationState =
337 {
338 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
339 DE_NULL, // const void* pNext;
340 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
341 VK_FALSE, // VkBool32 depthClampEnable;
342 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
343 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
344 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
345 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
346 VK_FALSE, // VkBool32 depthBiasEnable;
347 0.0f, // float depthBiasConstantFactor;
348 0.0f, // float depthBiasClamp;
349 0.0f, // float depthBiasSlopeFactor;
350 1.0f, // float lineWidth;
351 };
352
353 // Pipeline layout and graphics pipeline.
354 const PipelineLayoutWrapper pipelineLayout (m_pipelineConstructionType, vkd, device);
355
356 const auto topology = m_withTessellationPassthrough ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
357 m_graphicsPipeline.setDefaultRasterizationState()
358 .setDefaultTopology(topology)
359 .setupVertexInputState(&vertexInputState)
360 .setDefaultDepthStencilState()
361 .setDefaultMultisampleState()
362 .setDefaultColorBlendState()
363 .setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *renderPass, 0u, vertModule, &rasterizationState, tscModule, tseModule)
364 .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragModule)
365 .setupFragmentOutputState(*renderPass)
366 .setMonolithicPipelineLayout(pipelineLayout)
367 .buildPipeline();
368
369 // Command pool and buffer.
370 const auto cmdPool = makeCommandPool(vkd, device, qIndex);
371 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
372 const auto cmdBuffer = cmdBufferPtr.get();
373
374 beginCommandBuffer(vkd, cmdBuffer);
375
376 // Draw.
377 renderPass.begin(vkd, cmdBuffer, scissors.at(0u), clearColor);
378 m_graphicsPipeline.bind(cmdBuffer);
379 vkd.cmdDraw(cmdBuffer, 6, 1u, 0u, 0u);
380 renderPass.end(vkd, cmdBuffer);
381
382 // Copy to verification buffer.
383 const auto copyRegion = makeBufferImageCopy(m_extent, colorSRL);
384 const auto transfer2Host = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
385 const auto color2Transfer = makeImageMemoryBarrier(
386 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
387 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
388 colorBuffer.get(), colorSRR);
389
390 cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &color2Transfer);
391 vkd.cmdCopyImageToBuffer(cmdBuffer, colorBuffer.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verifBuffer.get(), 1u, ©Region);
392 cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &transfer2Host);
393
394 endCommandBuffer(vkd, cmdBuffer);
395
396 // Submit and validate result.
397 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
398
399 auto& log = m_context.getTestContext().getLog();
400 const tcu::IVec3 iExtent (static_cast<int>(m_extent.width), static_cast<int>(m_extent.height), static_cast<int>(m_extent.depth));
401 void* verifBufferData = verifBufferAlloc.getHostPtr();
402 const tcu::ConstPixelBufferAccess verifAccess (tcuFormat, iExtent, verifBufferData);
403 invalidateAlloc(vkd, device, verifBufferAlloc);
404
405 const auto red = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
406 const auto green = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
407
408 for (int x = 0; x < iExtent.x(); ++x)
409 for (int y = 0; y < iExtent.y(); ++y) {
410 const auto resultColor = verifAccess.getPixel(x, y);
411 const auto expectedColor = (x < iExtent.x() / 2) ? red : green;
412 if (resultColor != expectedColor) {
413 log << tcu::TestLog::ImageSet("Result image", "Expect left side of framebuffer red, and right side green")
414 << tcu::TestLog::Image("Result", "Verification buffer", verifAccess)
415 << tcu::TestLog::EndImageSet;
416 TCU_FAIL("Expected a vertically split framebuffer, filled with red on the left and green the right; see the log for the unexpected result");
417 }
418 }
419
420 return tcu::TestStatus::pass("Pass");
421 }
422
423 #ifndef CTS_USES_VULKANSC
424 struct UnusedShaderStageParams
425 {
426 PipelineConstructionType pipelineConstructionType;
427 bool useTessShaders;
428 bool useGeomShader;
429 };
430
431 class UnusedShaderStagesCase : public vkt::TestCase
432 {
433 public:
UnusedShaderStagesCase(tcu::TestContext & testCtx,const std::string & name,const UnusedShaderStageParams & params)434 UnusedShaderStagesCase (tcu::TestContext& testCtx, const std::string& name, const UnusedShaderStageParams& params)
435 : vkt::TestCase (testCtx, name)
436 , m_params (params)
437 {}
~UnusedShaderStagesCase(void)438 virtual ~UnusedShaderStagesCase (void) {}
439
440 void initPrograms (vk::SourceCollections& programCollection) const override;
441 TestInstance* createInstance (Context& context) const override;
442 void checkSupport (Context& context) const override;
443
444 protected:
445 UnusedShaderStageParams m_params;
446 };
447
448 class UnusedShaderStagesInstance : public vkt::TestInstance
449 {
450 public:
UnusedShaderStagesInstance(Context & context,const UnusedShaderStageParams & params)451 UnusedShaderStagesInstance (Context& context, const UnusedShaderStageParams& params)
452 : vkt::TestInstance (context)
453 , m_params (params)
454 {}
~UnusedShaderStagesInstance(void)455 virtual ~UnusedShaderStagesInstance (void) {}
456 tcu::TestStatus iterate (void) override;
457
458 protected:
459 UnusedShaderStageParams m_params;
460 };
461
initPrograms(vk::SourceCollections & programCollection) const462 void UnusedShaderStagesCase::initPrograms (vk::SourceCollections &programCollection) const
463 {
464 // Shaders that produce bad results.
465 {
466 std::ostringstream vert;
467 vert
468 << "#version 460\n"
469 << "out gl_PerVertex {\n"
470 << " vec4 gl_Position;\n"
471 << "};\n"
472 << "void main (void) {\n"
473 << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
474 << "}\n"
475 ;
476 programCollection.glslSources.add("bad_vert") << glu::VertexSource(vert.str());
477
478 std::ostringstream tesc;
479 tesc
480 << "#version 460\n"
481 << "layout (vertices=3) out;\n"
482 << "in gl_PerVertex {\n"
483 << " vec4 gl_Position;\n"
484 << "} gl_in[gl_MaxPatchVertices];\n"
485 << "out gl_PerVertex {\n"
486 << " vec4 gl_Position;\n"
487 << "} gl_out[];\n"
488 << "void main (void) {\n"
489 << " gl_TessLevelInner[0] = 1.0;\n"
490 << " gl_TessLevelInner[1] = 1.0;\n"
491 << " gl_TessLevelOuter[0] = 1.0;\n"
492 << " gl_TessLevelOuter[1] = 1.0;\n"
493 << " gl_TessLevelOuter[2] = 1.0;\n"
494 << " gl_TessLevelOuter[3] = 1.0;\n"
495 << " gl_out[gl_InvocationID].gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
496 << "}\n"
497 ;
498 programCollection.glslSources.add("bad_tesc") << glu::TessellationControlSource(tesc.str());
499
500 std::ostringstream tese;
501 tese
502 << "#version 460\n"
503 << "layout (triangles, fractional_odd_spacing, cw) in;\n"
504 << "in gl_PerVertex {\n"
505 << " vec4 gl_Position;\n"
506 << "} gl_in[gl_MaxPatchVertices];\n"
507 << "out gl_PerVertex {\n"
508 << " vec4 gl_Position;\n"
509 << "};\n"
510 << "void main() {\n"
511 << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
512 << "}\n"
513 ;
514 programCollection.glslSources.add("bad_tese") << glu::TessellationEvaluationSource(tese.str());
515
516 std::ostringstream geom;
517 geom
518 << "#version 460\n"
519 << "layout (triangles) in;\n"
520 << "layout (triangle_strip, max_vertices=3) out;\n"
521 << "in gl_PerVertex {\n"
522 << " vec4 gl_Position;\n"
523 << "} gl_in[3];\n"
524 << "out gl_PerVertex {\n"
525 << " vec4 gl_Position;\n"
526 << "};\n"
527 << "void main() {\n"
528 // Avoid emitting any vertices.
529 << "}\n"
530 ;
531 programCollection.glslSources.add("bad_geom") << glu::GeometrySource(geom.str());
532
533 std::ostringstream frag;
534 frag
535 << "#version 460\n"
536 << "layout (location=0) out vec4 outColor;\n"
537 << "void main (void) {\n"
538 << " outColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
539 << "}\n"
540 ;
541 programCollection.glslSources.add("bad_frag") << glu::FragmentSource(frag.str());
542 }
543
544 // Shaders that produce the expected results.
545 {
546 std::ostringstream vert;
547 vert
548 << "#version 460\n"
549 << "out gl_PerVertex {\n"
550 << " vec4 gl_Position;\n"
551 << "};\n"
552 << "vec2 positions[3] = vec2[](\n"
553 << " vec2(-1.0, -1.0),\n"
554 << " vec2(-1.0, 3.0),\n"
555 << " vec2( 3.0, -1.0)\n"
556 << ");\n"
557 << "void main (void) {\n"
558 << " gl_Position = vec4(positions[gl_VertexIndex % 3], 0.0, 1.0);\n"
559 << "}\n"
560 ;
561 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
562
563 std::ostringstream tesc;
564 tesc
565 << "#version 460\n"
566 << "layout (vertices=3) out;\n"
567 << "in gl_PerVertex {\n"
568 << " vec4 gl_Position;\n"
569 << "} gl_in[gl_MaxPatchVertices];\n"
570 << "out gl_PerVertex {\n"
571 << " vec4 gl_Position;\n"
572 << "} gl_out[];\n"
573 << "void main (void) {\n"
574 << " gl_TessLevelInner[0] = 1.0;\n"
575 << " gl_TessLevelInner[1] = 1.0;\n"
576 << " gl_TessLevelOuter[0] = 1.0;\n"
577 << " gl_TessLevelOuter[1] = 1.0;\n"
578 << " gl_TessLevelOuter[2] = 1.0;\n"
579 << " gl_TessLevelOuter[3] = 1.0;\n"
580 << " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
581 << "}\n"
582 ;
583 programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
584
585 std::ostringstream tese;
586 tese
587 << "#version 460\n"
588 << "layout (triangles, fractional_odd_spacing, cw) in;\n"
589 << "in gl_PerVertex {\n"
590 << " vec4 gl_Position;\n"
591 << "} gl_in[gl_MaxPatchVertices];\n"
592 << "out gl_PerVertex {\n"
593 << " vec4 gl_Position;\n"
594 << "};\n"
595 << "void main() {\n"
596 << " gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +\n"
597 << " (gl_TessCoord.y * gl_in[1].gl_Position) +\n"
598 << " (gl_TessCoord.z * gl_in[2].gl_Position);\n"
599 << "}\n"
600 ;
601 programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
602
603 std::ostringstream geom;
604 geom
605 << "#version 460\n"
606 << "layout (triangles) in;\n"
607 << "layout (triangle_strip, max_vertices=3) out;\n"
608 << "in gl_PerVertex {\n"
609 << " vec4 gl_Position;\n"
610 << "} gl_in[3];\n"
611 << "out gl_PerVertex {\n"
612 << " vec4 gl_Position;\n"
613 << "};\n"
614 << "void main() {\n"
615 << " gl_Position = gl_in[0].gl_Position; EmitVertex();\n"
616 << " gl_Position = gl_in[1].gl_Position; EmitVertex();\n"
617 << " gl_Position = gl_in[2].gl_Position; EmitVertex();\n"
618 << "}\n"
619 ;
620 programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
621
622 std::ostringstream frag;
623 frag
624 << "#version 460\n"
625 << "layout (location=0) out vec4 outColor;\n"
626 << "void main (void) {\n"
627 << " outColor = vec4(0.0, 1.0, 0.0, 1.0);\n" // Blue instead of black.
628 << "}\n"
629 ;
630 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
631 }
632 }
633
createInstance(Context & context) const634 TestInstance* UnusedShaderStagesCase::createInstance (Context &context) const
635 {
636 return new UnusedShaderStagesInstance(context, m_params);
637 }
638
checkSupport(Context & context) const639 void UnusedShaderStagesCase::checkSupport (Context &context) const
640 {
641 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
642
643 if (m_params.useTessShaders)
644 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
645
646 if (m_params.useGeomShader)
647 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
648 }
649
iterate()650 tcu::TestStatus UnusedShaderStagesInstance::iterate ()
651 {
652 const auto& vkd = m_context.getDeviceInterface();
653 const auto device = m_context.getDevice();
654 auto& alloc = m_context.getDefaultAllocator();
655 const auto queue = m_context.getUniversalQueue();
656 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
657
658 const bool isOptimized = (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY);
659 const auto colorExtent = makeExtent3D(1u, 1u, 1u);
660 const tcu::IVec3 colorExtentVec (static_cast<int>(colorExtent.width), static_cast<int>(colorExtent.height), static_cast<int>(colorExtent.depth));
661 const auto colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
662 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
663 const auto colorSRR = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
664 const auto colorSRL = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
665 const auto tcuFormat = mapVkFormat(colorFormat);
666 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 0.0f);
667 const tcu::Vec4 expectedColor (0.0f, 1.0f, 0.0f, 1.0f); // Must match the good frag shader.
668
669 // Good and bad shader modules.
670 const auto& binaries = m_context.getBinaryCollection();
671
672 const auto goodVertModule = createShaderModule(vkd, device, binaries.get("vert"));
673 const auto goodTescModule = (m_params.useTessShaders ? createShaderModule(vkd, device, binaries.get("tesc")) : Move<VkShaderModule>());
674 const auto goodTeseModule = (m_params.useTessShaders ? createShaderModule(vkd, device, binaries.get("tese")) : Move<VkShaderModule>());
675 const auto goodGeomModule = (m_params.useGeomShader ? createShaderModule(vkd, device, binaries.get("geom")) : Move<VkShaderModule>());
676 const auto goodFragModule = createShaderModule(vkd, device, binaries.get("frag"));
677
678 const auto goodVertShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, goodVertModule.get());
679 const auto goodTescShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, goodTescModule.get());
680 const auto goodTeseShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, goodTeseModule.get());
681 const auto goodGeomShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_GEOMETRY_BIT, goodGeomModule.get());
682 const auto goodFragShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, goodFragModule.get());
683
684 const auto badVertModule = createShaderModule(vkd, device, binaries.get("bad_vert"));
685 const auto badTescModule = (m_params.useTessShaders ? createShaderModule(vkd, device, binaries.get("bad_tesc")) : Move<VkShaderModule>());
686 const auto badTeseModule = (m_params.useTessShaders ? createShaderModule(vkd, device, binaries.get("bad_tese")) : Move<VkShaderModule>());
687 const auto badGeomModule = (m_params.useGeomShader ? createShaderModule(vkd, device, binaries.get("bad_geom")) : Move<VkShaderModule>());
688 const auto badFragModule = createShaderModule(vkd, device, binaries.get("bad_frag"));
689
690 const auto badVertShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, badVertModule.get());
691 const auto badTescShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, badTescModule.get());
692 const auto badTeseShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, badTeseModule.get());
693 const auto badGeomShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_GEOMETRY_BIT, badGeomModule.get());
694 const auto badFragShaderInfo = makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, badFragModule.get());
695
696 // Color attachment.
697 const VkImageCreateInfo colorAttachmentCreateInfo =
698 {
699 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
700 nullptr, // const void* pNext;
701 0u, // VkImageCreateFlags flags;
702 VK_IMAGE_TYPE_2D, // VkImageType imageType;
703 colorFormat, // VkFormat format;
704 colorExtent, // VkExtent3D extent;
705 1u, // uint32_t mipLevels;
706 1u, // uint32_t arrayLayers;
707 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
708 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
709 colorUsage, // VkImageUsageFlags usage;
710 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
711 0u, // uint32_t queueFamilyIndexCount;
712 nullptr, // const uint32_t* pQueueFamilyIndices;
713 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
714 };
715 ImageWithMemory colorAttachment (vkd, device, alloc, colorAttachmentCreateInfo, MemoryRequirement::Any);
716
717 // Color attachment view.
718 const auto colorAttachmentView = makeImageView(vkd, device, colorAttachment.get(), VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSRR);
719
720 // Verification buffer.
721 const auto verificationBufferSize = static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * colorExtent.width * colorExtent.height * colorExtent.depth;
722 const auto verificationBufferCreateInfo = makeBufferCreateInfo(verificationBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
723 BufferWithMemory verificationBuffer (vkd, device, alloc, verificationBufferCreateInfo, MemoryRequirement::HostVisible);
724 auto& verificationBufferAlloc = verificationBuffer.getAllocation();
725
726 // Render pass and framebuffer.
727 RenderPassWrapper renderPass (m_params.pipelineConstructionType, vkd, device, colorFormat);
728 renderPass.createFramebuffer(vkd, device, *colorAttachment, colorAttachmentView.get(), colorExtent.width, colorExtent.height);
729
730 // Pipeline layout.
731 const auto pipelineLayout = makePipelineLayout(vkd, device);
732
733 // Pipeline state.
734
735 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = initVulkanStructure();
736
737 const auto primitiveTopology = (m_params.useTessShaders ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
738
739 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
740 {
741 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
742 nullptr, // const void* pNext;
743 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
744 primitiveTopology, // VkPrimitiveTopology topology;
745 VK_FALSE, // VkBool32 primitiveRestartEnable;
746 };
747
748 const VkPipelineTessellationStateCreateInfo tessellationStateInfo =
749 {
750 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
751 nullptr, // const void* pNext;
752 0u, // VkPipelineTessellationStateCreateFlags flags;
753 3u, // uint32_t patchControlPoints;
754 };
755
756 const std::vector<VkViewport> viewports (1u, makeViewport(colorExtent));
757 const std::vector<VkRect2D> scissors (1u, makeRect2D(colorExtent));
758
759 const VkPipelineViewportStateCreateInfo viewportStateInfo =
760 {
761 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
762 nullptr, // const void* pNext;
763 0u, // VkPipelineViewportStateCreateFlags flags;
764 de::sizeU32(viewports), // uint32_t viewportCount;
765 de::dataOrNull(viewports), // const VkViewport* pViewports;
766 de::sizeU32(scissors), // uint32_t scissorCount;
767 de::dataOrNull(scissors), // const VkRect2D* pScissors;
768 };
769
770 const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
771 {
772 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
773 nullptr, // const void* pNext;
774 0u, // VkPipelineRasterizationStateCreateFlags flags;
775 VK_FALSE, // VkBool32 depthClampEnable;
776 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
777 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
778 VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode;
779 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
780 VK_FALSE, // VkBool32 depthBiasEnable;
781 0.0f, // float depthBiasConstantFactor;
782 0.0f, // float depthBiasClamp;
783 0.0f, // float depthBiasSlopeFactor;
784 1.0f, // float lineWidth;
785 };
786
787 const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
788 {
789 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
790 nullptr, // const void* pNext;
791 0u, // VkPipelineMultisampleStateCreateFlags flags;
792 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
793 VK_FALSE, // VkBool32 sampleShadingEnable;
794 1.0f, // float minSampleShading;
795 nullptr, // const VkSampleMask* pSampleMask;
796 VK_FALSE, // VkBool32 alphaToCoverageEnable;
797 VK_FALSE, // VkBool32 alphaToOneEnable;
798 };
799
800 const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo = initVulkanStructure();
801
802 const VkColorComponentFlags colorComponentFlags = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
803
804 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
805 {
806 VK_FALSE, // VkBool32 blendEnable;
807 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor;
808 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
809 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
810 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor;
811 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
812 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
813 colorComponentFlags, // VkColorComponentFlags colorWriteMask;
814 };
815
816 const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
817 {
818 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
819 nullptr, // const void* pNext;
820 0u, // VkPipelineColorBlendStateCreateFlags flags;
821 VK_FALSE, // VkBool32 logicOpEnable;
822 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp;
823 1u, // uint32_t attachmentCount;
824 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
825 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
826 };
827
828 // Make a few vectors with the wrong shader modules.
829 std::vector<VkPipelineShaderStageCreateInfo> badPreRasterStages;
830 badPreRasterStages.push_back(badVertShaderInfo);
831 if (m_params.useTessShaders)
832 {
833 badPreRasterStages.push_back(badTescShaderInfo);
834 badPreRasterStages.push_back(badTeseShaderInfo);
835 }
836 if (m_params.useGeomShader)
837 badPreRasterStages.push_back(badGeomShaderInfo);
838
839 std::vector<VkPipelineShaderStageCreateInfo> allBadStages (badPreRasterStages);
840 allBadStages.push_back(badFragShaderInfo);
841
842 // Make a few vectors with the right shader modules.
843 std::vector<VkPipelineShaderStageCreateInfo> goodPreRasterStages;
844 goodPreRasterStages.push_back(goodVertShaderInfo);
845 if (m_params.useTessShaders)
846 {
847 goodPreRasterStages.push_back(goodTescShaderInfo);
848 goodPreRasterStages.push_back(goodTeseShaderInfo);
849 }
850 if (m_params.useGeomShader)
851 goodPreRasterStages.push_back(goodGeomShaderInfo);
852
853 std::vector<VkPipelineShaderStageCreateInfo> allGoodStages (goodPreRasterStages);
854 allGoodStages.push_back(goodFragShaderInfo);
855
856 // Build the different pipeline pieces.
857 Move<VkPipeline> vertexInputLib;
858 Move<VkPipeline> preRasterShaderLib;
859 Move<VkPipeline> fragShaderLib;
860 Move<VkPipeline> fragOutputLib;
861
862 VkPipelineCreateFlags libCreationFlags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
863 VkPipelineCreateFlags linkFlags = 0u;
864
865 if (isOptimized)
866 {
867 libCreationFlags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
868 linkFlags |= VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
869 }
870
871 // Vertex input state library.
872 {
873 VkGraphicsPipelineLibraryCreateInfoEXT vertexInputLibInfo = initVulkanStructure();
874 vertexInputLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
875
876 VkGraphicsPipelineCreateInfo vertexInputPipelineInfo = initVulkanStructure(&vertexInputLibInfo);
877 vertexInputPipelineInfo.flags = libCreationFlags;
878 vertexInputPipelineInfo.pVertexInputState = &vertexInputStateInfo;
879 vertexInputPipelineInfo.pInputAssemblyState = &inputAssemblyStateInfo;
880
881 // Add all bad shaders (they should be ignored).
882 vertexInputPipelineInfo.stageCount = de::sizeU32(allBadStages);
883 vertexInputPipelineInfo.pStages = de::dataOrNull(allBadStages);
884
885 vertexInputLib = createGraphicsPipeline(vkd, device, DE_NULL, &vertexInputPipelineInfo);
886 }
887
888 // Pre-rasterization shader state library.
889 {
890 VkGraphicsPipelineLibraryCreateInfoEXT preRasterShaderLibInfo = initVulkanStructure();
891 preRasterShaderLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
892
893 VkGraphicsPipelineCreateInfo preRasterShaderPipelineInfo = initVulkanStructure(&preRasterShaderLibInfo);
894 preRasterShaderPipelineInfo.flags = libCreationFlags;
895 preRasterShaderPipelineInfo.layout = pipelineLayout.get();
896 preRasterShaderPipelineInfo.pViewportState = &viewportStateInfo;
897 preRasterShaderPipelineInfo.pRasterizationState = &rasterizationStateInfo;
898 if (m_params.useTessShaders)
899 {
900 preRasterShaderPipelineInfo.pInputAssemblyState = &inputAssemblyStateInfo;
901 preRasterShaderPipelineInfo.pTessellationState = &tessellationStateInfo;
902 }
903 preRasterShaderPipelineInfo.renderPass = renderPass.get();
904
905 // All good pre-rasterization stages.
906 auto preRasterStagesVec = goodPreRasterStages;
907 // The bad fragment shader state cannot be added here due to VUID-VkGraphicsPipelineCreateInfo-pStages-06894.
908 //preRasterStagesVec.push_back(badFragShaderInfo);
909
910 preRasterShaderPipelineInfo.stageCount = de::sizeU32(preRasterStagesVec);
911 preRasterShaderPipelineInfo.pStages = de::dataOrNull(preRasterStagesVec);
912
913 preRasterShaderLib = createGraphicsPipeline(vkd, device, DE_NULL, &preRasterShaderPipelineInfo);
914 }
915
916 // Fragment shader stage library.
917 {
918 VkGraphicsPipelineLibraryCreateInfoEXT fragShaderLibInfo = initVulkanStructure();
919 fragShaderLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
920
921 VkGraphicsPipelineCreateInfo fragShaderPipelineInfo = initVulkanStructure(&fragShaderLibInfo);
922 fragShaderPipelineInfo.flags = libCreationFlags;
923 fragShaderPipelineInfo.layout = pipelineLayout.get();
924 fragShaderPipelineInfo.pMultisampleState = &multisampleStateInfo;
925 fragShaderPipelineInfo.pDepthStencilState = &depthStencilStateInfo;
926 fragShaderPipelineInfo.renderPass = renderPass.get();
927
928 // The good fragment shader stage.
929 std::vector<VkPipelineShaderStageCreateInfo> fragShaderStagesVec;
930 // We cannot add the bad pre-rasterization shader stages due to VUID-VkGraphicsPipelineCreateInfo-pStages-06895.
931 //fragShaderStagesVec.insert(fragShaderStagesVec.end(), badPreRasterStages.begin(), badPreRasterStages.end())
932 fragShaderStagesVec.push_back(goodFragShaderInfo);
933
934 fragShaderPipelineInfo.stageCount = de::sizeU32(fragShaderStagesVec);
935 fragShaderPipelineInfo.pStages = de::dataOrNull(fragShaderStagesVec);
936
937 fragShaderLib = createGraphicsPipeline(vkd, device, DE_NULL, &fragShaderPipelineInfo);
938 }
939
940 // Fragment output library.
941 {
942 VkGraphicsPipelineLibraryCreateInfoEXT fragOutputLibInfo = initVulkanStructure();
943 fragOutputLibInfo.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
944
945 VkGraphicsPipelineCreateInfo fragOutputPipelineInfo = initVulkanStructure(&fragOutputLibInfo);
946 fragOutputPipelineInfo.flags = libCreationFlags;
947 fragOutputPipelineInfo.pColorBlendState = &colorBlendStateInfo;
948 fragOutputPipelineInfo.renderPass = renderPass.get();
949 fragOutputPipelineInfo.pMultisampleState = &multisampleStateInfo;
950
951 // Add all bad shaders (they should be ignored).
952 fragOutputPipelineInfo.stageCount = de::sizeU32(allBadStages);
953 fragOutputPipelineInfo.pStages = de::dataOrNull(allBadStages);
954
955 fragOutputLib = createGraphicsPipeline(vkd, device, DE_NULL, &fragOutputPipelineInfo);
956 }
957
958 // Linked pipeline.
959 const std::vector<VkPipeline> libraryHandles
960 {
961 vertexInputLib.get(),
962 preRasterShaderLib.get(),
963 fragShaderLib.get(),
964 fragOutputLib.get(),
965 };
966
967 VkPipelineLibraryCreateInfoKHR linkedPipelineLibraryInfo = initVulkanStructure();
968 linkedPipelineLibraryInfo.libraryCount = de::sizeU32(libraryHandles);
969 linkedPipelineLibraryInfo.pLibraries = de::dataOrNull(libraryHandles);
970
971 VkGraphicsPipelineCreateInfo linkedPipelineInfo = initVulkanStructure(&linkedPipelineLibraryInfo);
972 linkedPipelineInfo.flags = linkFlags;
973 linkedPipelineInfo.layout = pipelineLayout.get();
974 linkedPipelineInfo.stageCount = de::sizeU32(allBadStages);
975 linkedPipelineInfo.pStages = de::dataOrNull(allBadStages);
976
977 const auto pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &linkedPipelineInfo);
978
979 // Command pool, command buffer and draw.
980 const auto cmdPool = makeCommandPool(vkd, device, queueIndex);
981 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
982 const auto cmdBuffer = cmdBufferPtr.get();
983
984 beginCommandBuffer(vkd, cmdBuffer);
985 renderPass.begin(vkd, cmdBuffer, scissors.at(0u), clearColor);
986 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
987 vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
988 renderPass.end(vkd, cmdBuffer);
989
990 // Copy color attachment to verification buffer.
991 const auto preCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
992 VK_ACCESS_TRANSFER_READ_BIT,
993 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
994 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
995 colorAttachment.get(), colorSRR);
996 const auto copyRegion = makeBufferImageCopy(colorExtent, colorSRL);
997 const auto postCopyBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
998
999 cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preCopyBarrier);
1000 vkd.cmdCopyImageToBuffer(cmdBuffer, colorAttachment.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verificationBuffer.get(), 1u, ©Region);
1001 cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyBarrier);
1002
1003 endCommandBuffer(vkd, cmdBuffer);
1004
1005 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1006
1007 // Verify pixel contents.
1008 invalidateAlloc(vkd, device, verificationBufferAlloc);
1009 tcu::PixelBufferAccess resultAccess (tcuFormat, colorExtentVec, verificationBufferAlloc.getHostPtr());
1010
1011 for (int z = 0; z < colorExtentVec.z(); ++z)
1012 for (int y = 0; y < colorExtentVec.y(); ++y)
1013 for (int x = 0; x < colorExtentVec.x(); ++x)
1014 {
1015 const auto resultColor = resultAccess.getPixel(x, y, z);
1016 if (resultColor != expectedColor)
1017 {
1018 const tcu::IVec3 position(x, y, z);
1019 std::ostringstream msg;
1020 msg << "Bad color found at pixel " << position << ": expected " << expectedColor << " but found " << resultColor;
1021 TCU_FAIL(msg.str());
1022 }
1023 }
1024
1025 return tcu::TestStatus::pass("Pass");
1026 }
1027 #endif // CTS_USES_VULKANSC
1028
1029 #ifndef CTS_USES_VULKANSC
1030 class PipelineLibraryInterpolateAtSampleTestCase : public vkt::TestCase
1031 {
1032 public:
1033 PipelineLibraryInterpolateAtSampleTestCase(tcu::TestContext& context, const std::string& name);
1034 void initPrograms (vk::SourceCollections& programCollection) const override;
1035 TestInstance* createInstance (Context& context) const override;
1036 void checkSupport (Context& context) const override;
1037 //there are 4 sample points, which may have a shader invocation each, each of them writes 5 values
1038 //and we render a 2x2 grid.
1039 static constexpr uint32_t width = 2;
1040 static constexpr uint32_t height = 2;
1041 static constexpr VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_4_BIT;
1042 static constexpr uint32_t ResultCount = (sampleCount + 1) * sampleCount * width * height;
1043 };
1044
1045 class PipelineLibraryInterpolateAtSampleTestInstance : public vkt::TestInstance
1046 {
1047 public:
1048 PipelineLibraryInterpolateAtSampleTestInstance(Context& context);
1049 void runTest(BufferWithMemory& index, BufferWithMemory& values, size_t bufferSize, PipelineConstructionType type);
1050 virtual tcu::TestStatus iterate(void);
1051 };
1052
PipelineLibraryInterpolateAtSampleTestCase(tcu::TestContext & context,const std::string & name)1053 PipelineLibraryInterpolateAtSampleTestCase::PipelineLibraryInterpolateAtSampleTestCase(tcu::TestContext& context, const std::string& name):
1054 vkt::TestCase(context, name) { }
1055
checkSupport(Context & context) const1056 void PipelineLibraryInterpolateAtSampleTestCase::checkSupport(Context& context) const
1057 {
1058 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
1059 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS);
1060 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), vk::PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY);
1061 }
1062
initPrograms(vk::SourceCollections & collection) const1063 void PipelineLibraryInterpolateAtSampleTestCase::initPrograms(vk::SourceCollections& collection) const
1064 {
1065 {
1066 std::ostringstream src;
1067 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1068 << "vec2 positions[6] = vec2[](\n"
1069 << " vec2(1.0, 1.0),"
1070 << " vec2(-1.0, 1.0),"
1071 << " vec2(-1.0, -1.0),"
1072 << " vec2(-1.0, -1.0),"
1073 << " vec2(1.0, -1.0),"
1074 << " vec2(1.0, 1.0)"
1075 << ");\n"
1076 << "float values[6] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6};\n"
1077 << "layout (location=0) out float verify;"
1078 << "void main() {\n"
1079 << " gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);\n"
1080 << " verify = values[gl_VertexIndex];\n"
1081 << "}";
1082 collection.glslSources.add("vert") << glu::VertexSource(src.str());
1083 }
1084
1085 {
1086 std::ostringstream src;
1087 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1088 << "layout(location = 0) out vec4 outColor;\n"
1089 << "layout (location=0) in float verify;"
1090 << "layout(std430, binding = 0) buffer Index {"
1091 << " uint writeIndex;"
1092 << "} index;\n"
1093 << "layout(std430, binding = 1) buffer Values {"
1094 << " float num[" << PipelineLibraryInterpolateAtSampleTestCase::ResultCount << "];"
1095 << "} values;\n"
1096 << "void main() {\n"
1097 << " uint index = atomicAdd(index.writeIndex, 5);"
1098 << " float iSample1 = interpolateAtSample(verify, 0);\n"
1099 << " float iSample2 = interpolateAtSample(verify, 1);\n"
1100 << " float iSample3 = interpolateAtSample(verify, 2);\n"
1101 << " float iSample4 = interpolateAtSample(verify, 3);\n"
1102 << " values.num[index] = verify;"
1103 << " values.num[index + 1] = iSample1;"
1104 << " values.num[index + 2] = iSample2;"
1105 << " values.num[index + 3] = iSample3;"
1106 << " values.num[index + 4] = iSample4;"
1107 << " outColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
1108 << "}";
1109 collection.glslSources.add("frag") << glu::FragmentSource(src.str());
1110 }
1111 }
1112
createInstance(Context & context) const1113 TestInstance* PipelineLibraryInterpolateAtSampleTestCase::createInstance(Context& context) const
1114 {
1115 return new PipelineLibraryInterpolateAtSampleTestInstance(context);
1116 }
1117
PipelineLibraryInterpolateAtSampleTestInstance(Context & context)1118 PipelineLibraryInterpolateAtSampleTestInstance::PipelineLibraryInterpolateAtSampleTestInstance(Context& context) : vkt::TestInstance(context) { }
1119
runTest(BufferWithMemory & index,BufferWithMemory & values,size_t bufferSize,PipelineConstructionType type)1120 void PipelineLibraryInterpolateAtSampleTestInstance::runTest(BufferWithMemory& index, BufferWithMemory& values, size_t bufferSize, PipelineConstructionType type)
1121 {
1122 const auto& vki = m_context.getInstanceInterface();
1123 const auto& vkd = m_context.getDeviceInterface();
1124 const auto physDevice = m_context.getPhysicalDevice();
1125 const auto device = m_context.getDevice();
1126 auto& alloc = m_context.getDefaultAllocator();
1127 auto imageFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
1128 auto imageExtent = vk::makeExtent3D(2, 2, 1u);
1129
1130 const std::vector<vk::VkViewport> viewports { makeViewport(imageExtent) };
1131 const std::vector<vk::VkRect2D> scissors { makeRect2D(imageExtent) };
1132
1133 de::MovePtr<vk::ImageWithMemory> colorAttachment;
1134
1135 vk::GraphicsPipelineWrapper pipeline1(vki, vkd, physDevice, device, m_context.getDeviceExtensions(), type);
1136 const auto qIndex = m_context.getUniversalQueueFamilyIndex();
1137
1138 const auto subresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1139 const auto imageUsage = static_cast<vk::VkImageUsageFlags>(vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1140 const vk::VkImageCreateInfo imageCreateInfo =
1141 {
1142 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1143 nullptr, // const void* pNext;
1144 0u, // VkImageCreateFlags flags;
1145 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
1146 imageFormat, // VkFormat format;
1147 imageExtent, // VkExtent3D extent;
1148 1u, // deUint32 mipLevels;
1149 1u, // deUint32 arrayLayers;
1150 vk::VK_SAMPLE_COUNT_4_BIT, // VkSampleCountFlagBits samples;
1151 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1152 imageUsage, // VkImageUsageFlags usage;
1153 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1154 1u, // deUint32 queueFamilyIndexCount;
1155 &qIndex, // const deUint32* pQueueFamilyIndices;
1156 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1157 };
1158
1159 colorAttachment = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vkd, device, alloc, imageCreateInfo, vk::MemoryRequirement::Any));
1160 auto colorAttachmentView = vk::makeImageView(vkd, device, colorAttachment->get(), vk::VK_IMAGE_VIEW_TYPE_2D, imageFormat, subresourceRange);
1161
1162 vk::DescriptorSetLayoutBuilder layoutBuilder;
1163 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
1164 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
1165
1166 auto descriptorSetLayout = layoutBuilder.build(vkd, device);
1167 vk::PipelineLayoutWrapper graphicsPipelineLayout (type, vkd, device, descriptorSetLayout.get());
1168
1169 DescriptorPoolBuilder poolBuilder;
1170 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1171 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1172 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1173 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
1174
1175 // Update descriptor sets.
1176 DescriptorSetUpdateBuilder updater;
1177
1178 const auto indexBufferInfo = makeDescriptorBufferInfo(index.get(), 0ull, sizeof(uint32_t));
1179 const auto valueBufferInfo = makeDescriptorBufferInfo(values.get(), 0ull, bufferSize);
1180 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indexBufferInfo);
1181 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &valueBufferInfo);
1182
1183 updater.update(vkd, device);
1184
1185 auto vtxshader = ShaderWrapper(vkd, device, m_context.getBinaryCollection().get("vert"));
1186 auto frgshader = ShaderWrapper(vkd, device, m_context.getBinaryCollection().get("frag"));
1187
1188 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
1189 {
1190 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
1191 nullptr, // const void* pNext
1192 0u, // VkPipelineVertexInputStateCreateFlags flags
1193 0u, // deUint32 vertexBindingDescriptionCount
1194 nullptr, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
1195 0u, // deUint32 vertexAttributeDescriptionCount
1196 nullptr, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
1197 };
1198
1199 VkPipelineMultisampleStateCreateInfo multisampling = initVulkanStructure();
1200 multisampling.sampleShadingEnable = VK_FALSE;
1201 multisampling.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
1202 multisampling.minSampleShading = 1.0f; // Optional
1203 multisampling.pSampleMask = NULL; // Optional
1204 multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
1205 multisampling.alphaToOneEnable = VK_FALSE; // Optional
1206
1207 pipeline1.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
1208 .setDefaultRasterizationState()
1209 .setDefaultDepthStencilState()
1210 .setDefaultColorBlendState()
1211 .setupVertexInputState(&vertexInputState)
1212 .setupPreRasterizationShaderState(
1213 viewports,
1214 scissors,
1215 graphicsPipelineLayout,
1216 DE_NULL,
1217 0u,
1218 vtxshader)
1219 .setupFragmentShaderState(graphicsPipelineLayout, DE_NULL, 0u,
1220 frgshader)
1221 .setupFragmentOutputState(DE_NULL, 0u, DE_NULL, &multisampling)
1222 .setMonolithicPipelineLayout(graphicsPipelineLayout).buildPipeline();
1223
1224 auto commandPool = createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, qIndex);
1225 auto commandBuffer = vk::allocateCommandBuffer(vkd, device, commandPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1226
1227 const auto clearValueColor = vk::makeClearValueColor(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1228
1229 const vk::VkRect2D renderArea =
1230 {
1231 { 0u, 0u },
1232 { imageExtent.width, imageExtent.height }
1233 };
1234
1235 const vk::VkRenderingAttachmentInfoKHR colorAttachments = {
1236 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1237 DE_NULL, // const void* pNext;
1238 colorAttachmentView.get(), // VkImageView imageView;
1239 vk::VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, // VkImageLayout imageLayout;
1240 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
1241 DE_NULL, // VkImageView resolveImageView;
1242 vk::VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR, // VkImageLayout resolveImageLayout;
1243 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1244 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1245 clearValueColor // VkClearValue clearValue;
1246 };
1247 const VkRenderingInfoKHR render_info = {
1248 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
1249 0,
1250 0,
1251 renderArea,
1252 1,
1253 0,
1254 1,
1255 &colorAttachments,
1256 DE_NULL,
1257 DE_NULL
1258 };
1259
1260 vk::beginCommandBuffer(vkd, commandBuffer.get());
1261 vk::VkImageMemoryBarrier initialBarrier = makeImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
1262 (*colorAttachment).get(), subresourceRange);
1263 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, nullptr,
1264 0, nullptr, 1, &initialBarrier);
1265 vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipelineLayout.get(), 0u, 1, &descriptorSetBuffer.get(), 0u, nullptr);
1266
1267 vkd.cmdBeginRendering(*commandBuffer, &render_info);
1268 pipeline1.bind(commandBuffer.get());
1269 vkd.cmdSetPatchControlPointsEXT(commandBuffer.get(), 3);
1270 vkd.cmdDraw(commandBuffer.get(), 6, 1, 0, 0);
1271 vkd.cmdEndRendering(*commandBuffer);
1272
1273 const VkBufferMemoryBarrier indexBufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, index.get(), 0ull, sizeof(uint32_t));
1274 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1275 0u, 0, nullptr, 1, &indexBufferBarrier, 0, nullptr);
1276
1277 const VkBufferMemoryBarrier valueBufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, values.get(), 0ull, bufferSize);
1278 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1279 0u, 0, nullptr, 1, &valueBufferBarrier, 0, nullptr);
1280
1281 vk::endCommandBuffer(vkd, commandBuffer.get());
1282 vk::submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), commandBuffer.get());
1283 }
1284
iterate(void)1285 tcu::TestStatus PipelineLibraryInterpolateAtSampleTestInstance::iterate(void)
1286 {
1287 const auto& vkd = m_context.getDeviceInterface();
1288 const auto device = m_context.getDevice();
1289 auto& alloc = m_context.getDefaultAllocator();
1290
1291 struct ValueBuffer {
1292 float values[PipelineLibraryInterpolateAtSampleTestCase::ResultCount];
1293 };
1294
1295 size_t resultSize = PipelineLibraryInterpolateAtSampleTestCase::ResultCount;
1296
1297 const auto indexBufferSize = static_cast<VkDeviceSize>(sizeof(uint32_t));
1298 const auto valueBufferSize = static_cast<VkDeviceSize>(sizeof(ValueBuffer));
1299
1300 auto indexCreateInfo = makeBufferCreateInfo(indexBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1301 auto valuesCreateInfo = makeBufferCreateInfo(valueBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1302
1303 BufferWithMemory indexBufferMonolithic (vkd, device, alloc, indexCreateInfo, MemoryRequirement::HostVisible);
1304 BufferWithMemory valuesBufferMonolithic (vkd, device, alloc, valuesCreateInfo, MemoryRequirement::HostVisible);
1305 BufferWithMemory indexBufferGPL (vkd, device, alloc, indexCreateInfo, MemoryRequirement::HostVisible);
1306 BufferWithMemory valuesBufferGPL (vkd, device, alloc, valuesCreateInfo, MemoryRequirement::HostVisible);
1307
1308 auto& indexBufferMonolithicAlloc = indexBufferMonolithic.getAllocation();
1309 auto& valuesBufferMonolithicAlloc = valuesBufferMonolithic.getAllocation();
1310 auto& indexBufferGPLAlloc = indexBufferGPL.getAllocation();
1311 auto& valuesBufferGPLAlloc = valuesBufferGPL.getAllocation();
1312
1313 void* indexBufferMonolithicData = indexBufferMonolithicAlloc.getHostPtr();
1314 void* valuesBufferMonolithicData = valuesBufferMonolithicAlloc.getHostPtr();
1315 void* indexBufferGPLData = indexBufferGPLAlloc.getHostPtr();
1316 void* valuesBufferGPLData = valuesBufferGPLAlloc.getHostPtr();
1317
1318 deMemset(indexBufferMonolithicData, 0, sizeof(uint32_t));
1319 deMemset(valuesBufferMonolithicData, 0, sizeof(ValueBuffer));
1320 deMemset(indexBufferGPLData, 0, sizeof(uint32_t));
1321 deMemset(valuesBufferGPLData, 0, sizeof(ValueBuffer));
1322
1323 flushAlloc(vkd, device, indexBufferMonolithicAlloc);
1324 flushAlloc(vkd, device, valuesBufferMonolithicAlloc);
1325 flushAlloc(vkd, device, indexBufferGPLAlloc);
1326 flushAlloc(vkd, device, valuesBufferGPLAlloc);
1327
1328 runTest(indexBufferMonolithic, valuesBufferMonolithic, valueBufferSize, vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC);
1329 runTest(indexBufferGPL, valuesBufferGPL, valueBufferSize, vk::PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY);
1330
1331 invalidateAlloc(vkd, device, indexBufferMonolithicAlloc);
1332 invalidateAlloc(vkd, device, valuesBufferMonolithicAlloc);
1333 invalidateAlloc(vkd, device, indexBufferGPLAlloc);
1334 invalidateAlloc(vkd, device, valuesBufferGPLAlloc);
1335
1336 uint32_t monolithicIndex;
1337 uint32_t GPLIndex;
1338 struct ValueBuffer monolithicResult = ValueBuffer();
1339 struct ValueBuffer GPLResult = ValueBuffer();
1340 memcpy((void*)&monolithicIndex, indexBufferMonolithicData, sizeof(uint32_t));
1341 memcpy((void*)&GPLIndex, indexBufferGPLData, sizeof(uint32_t));
1342 memcpy((void*)&monolithicResult, valuesBufferMonolithicData, sizeof(ValueBuffer));
1343 memcpy((void*)&GPLResult, valuesBufferGPLData, sizeof(ValueBuffer));
1344
1345 //we can't know which order the shaders will run in
1346 std::sort(monolithicResult.values, monolithicResult.values + resultSize);
1347 std::sort(GPLResult.values, GPLResult.values + resultSize);
1348
1349 //check that the atomic counters are at enough for the number of invocations
1350 constexpr int expected = (PipelineLibraryInterpolateAtSampleTestCase::sampleCount + 1) *
1351 PipelineLibraryInterpolateAtSampleTestCase::width * PipelineLibraryInterpolateAtSampleTestCase::height;
1352
1353 if (monolithicIndex < expected && GPLIndex < expected) {
1354 return tcu::TestStatus::fail("Atomic counter value lower than expected");
1355 }
1356
1357 for (uint32_t i = 1; i < PipelineLibraryInterpolateAtSampleTestCase::ResultCount; i++) {
1358 if (monolithicResult.values[i] != monolithicResult.values[i]) {
1359 return tcu::TestStatus::fail("Comparison failed");
1360 }
1361 }
1362
1363 return tcu::TestStatus::pass("Pass");
1364 }
1365 #endif
1366
1367 struct BindingTestConfig {
1368 PipelineConstructionType construction;
1369 bool backwardsBinding;
1370 bool holes;
1371 };
1372
1373 /*
1374 * Test the following behaviours:
1375 * Descriptor sets updated/bound in backwards order
1376 * Descriptor sets with index holes updated/bound/used
1377 */
1378 class PipelineLayoutBindingTestCases : public vkt::TestCase
1379 {
1380 public:
PipelineLayoutBindingTestCases(tcu::TestContext & testCtx,const std::string & name,const BindingTestConfig & config)1381 PipelineLayoutBindingTestCases (tcu::TestContext& testCtx,
1382 const std::string& name,
1383 const BindingTestConfig& config)
1384 : vkt::TestCase(testCtx, name)
1385 , m_config(config)
1386 {
1387 }
~PipelineLayoutBindingTestCases(void)1388 ~PipelineLayoutBindingTestCases (void) {}
1389 void initPrograms (SourceCollections& programCollection) const override;
1390 void checkSupport (Context& context) const override;
1391 TestInstance* createInstance (Context& context) const override;
1392
1393 const BindingTestConfig m_config;
1394 };
1395
1396 class PipelineLayoutBindingTestInstance : public vkt::TestInstance
1397 {
1398 public:
PipelineLayoutBindingTestInstance(Context & context,const BindingTestConfig & config)1399 PipelineLayoutBindingTestInstance (Context& context,
1400 const BindingTestConfig& config)
1401 : vkt::TestInstance (context)
1402 , m_renderSize (2, 2)
1403 , m_extent (makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u))
1404 , m_format (VK_FORMAT_R8G8B8A8_UNORM)
1405 , m_graphicsPipeline (context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), config.construction)
1406 , m_config (config)
1407 {
1408 }
~PipelineLayoutBindingTestInstance(void)1409 ~PipelineLayoutBindingTestInstance (void) {}
1410 tcu::TestStatus iterate (void) override;
1411
1412 private:
1413 const tcu::UVec2 m_renderSize;
1414 const VkExtent3D m_extent;
1415 const VkFormat m_format;
1416 GraphicsPipelineWrapper m_graphicsPipeline;
1417 const BindingTestConfig m_config;
1418 };
1419
createInstance(Context & context) const1420 TestInstance* PipelineLayoutBindingTestCases::createInstance (Context& context) const
1421 {
1422 return new PipelineLayoutBindingTestInstance(context, m_config);
1423 }
1424
checkSupport(Context & context) const1425 void PipelineLayoutBindingTestCases::checkSupport (Context &context) const
1426 {
1427 checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_config.construction);
1428 }
1429
initPrograms(SourceCollections & sources) const1430 void PipelineLayoutBindingTestCases::initPrograms(SourceCollections& sources) const
1431 {
1432 std::ostringstream src;
1433 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1434 << "vec2 positions[3] = vec2[](\n"
1435 << " vec2(-1.0, -1.0),"
1436 << " vec2(3.0, -1.0),"
1437 << " vec2(-1.0, 3.0)"
1438 << ");\n"
1439 << "void main() {\n"
1440 << " gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);\n"
1441 << "}";
1442 sources.glslSources.add("vert") << glu::VertexSource(src.str());
1443
1444 std::ostringstream frag;
1445 frag
1446 << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1447 << "layout (location=0) out vec4 outColor;\n"
1448 << "layout(set = 0, binding = 0) uniform Output0 {"
1449 << " uint data;"
1450 << "} buf0;\n";
1451 if (!m_config.holes) {
1452 frag
1453 << "layout(set = 1, binding = 0) uniform Output1 {"
1454 << " uint data;"
1455 << "} buf1;\n"
1456 << "layout(set = 2, binding = 0) uniform Output2 {"
1457 << " uint data;"
1458 << "} buf2;\n"
1459 << "\n";
1460 }
1461 frag
1462 << "layout(set = 3, binding = 0) uniform Output3 {"
1463 << " uint data;"
1464 << "} buf3;\n"
1465 << "void main ()\n"
1466 << "{\n"
1467 << " const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1468 << " const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n";
1469 if (!m_config.holes) {
1470 frag
1471 << " outColor = ((buf0.data == 0) && (buf1.data == 1) && (buf2.data == 2) && (buf3.data == 3)) ? green : red;\n";
1472 } else {
1473 frag
1474 << " outColor = ((buf0.data == 0) && (buf3.data == 3)) ? green : red;\n";
1475 }
1476 frag << "}\n";
1477 sources.glslSources.add("frag") << glu::FragmentSource(frag.str());
1478 }
1479
iterate()1480 tcu::TestStatus PipelineLayoutBindingTestInstance::iterate ()
1481 {
1482 const auto& vkd = m_context.getDeviceInterface();
1483 const auto device = m_context.getDevice();
1484 auto& alloc = m_context.getDefaultAllocator();
1485 const auto qIndex = m_context.getUniversalQueueFamilyIndex();
1486 const auto queue = m_context.getUniversalQueue();
1487 const auto tcuFormat = mapVkFormat(m_format);
1488 const auto colorUsage = (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1489 const auto verifBufferUsage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1490 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f);
1491
1492 // Color attachment.
1493 const VkImageCreateInfo colorBufferInfo =
1494 {
1495 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1496 nullptr, // const void* pNext;
1497 0u, // VkImageCreateFlags flags;
1498 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1499 m_format, // VkFormat format;
1500 m_extent, // VkExtent3D extent;
1501 1u, // uint32_t mipLevels;
1502 1u, // uint32_t arrayLayers;
1503 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1504 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1505 colorUsage, // VkImageUsageFlags usage;
1506 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1507 0u, // uint32_t queueFamilyIndexCount;
1508 nullptr, // const uint32_t* pQueueFamilyIndices;
1509 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1510 };
1511 ImageWithMemory colorBuffer (vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
1512 const auto colorSRR = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1513 const auto colorSRL = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1514 const auto colorBufferView = makeImageView(vkd, device, colorBuffer.get(), VK_IMAGE_VIEW_TYPE_2D, m_format, colorSRR);
1515
1516 // Verification buffer.
1517 const auto verifBufferSize = static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * m_extent.width * m_extent.height;
1518 const auto verifBufferInfo = makeBufferCreateInfo(verifBufferSize, verifBufferUsage);
1519 BufferWithMemory verifBuffer (vkd, device, alloc, verifBufferInfo, MemoryRequirement::HostVisible);
1520 auto& verifBufferAlloc = verifBuffer.getAllocation();
1521
1522 // Render pass and framebuffer.
1523 RenderPassWrapper renderPass (m_config.construction, vkd, device, m_format);
1524 renderPass.createFramebuffer(vkd, device, colorBuffer.get(), colorBufferView.get(), m_extent.width, m_extent.height);
1525
1526 // Shader modules.
1527 const auto& binaries = m_context.getBinaryCollection();
1528 const auto vertModule = ShaderWrapper(vkd, device, binaries.get("vert"));
1529 const auto fragModule = ShaderWrapper(vkd, device, binaries.get("frag"));
1530
1531 // Viewports and scissors.
1532 const std::vector<VkViewport> viewports (1u, makeViewport(m_extent));
1533 const std::vector<VkRect2D> scissors (1u, makeRect2D(m_extent));
1534
1535 const VkPipelineVertexInputStateCreateInfo vertexInputState = initVulkanStructure();
1536 const VkPipelineRasterizationStateCreateInfo rasterizationState =
1537 {
1538 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1539 DE_NULL, // const void* pNext;
1540 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1541 VK_FALSE, // VkBool32 depthClampEnable;
1542 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1543 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1544 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
1545 VK_FRONT_FACE_CLOCKWISE, // VkFrontFace frontFace;
1546 VK_FALSE, // VkBool32 depthBiasEnable;
1547 0.0f, // float depthBiasConstantFactor;
1548 0.0f, // float depthBiasClamp;
1549 0.0f, // float depthBiasSlopeFactor;
1550 1.0f, // float lineWidth;
1551 };
1552
1553 std::array<int, 4> tmpIndices = {};
1554 std::array<int, 4> indices = {};
1555 std::iota(tmpIndices.begin(), tmpIndices.end(), 0);
1556 if (m_config.backwardsBinding) {
1557 std::copy(tmpIndices.rbegin(), tmpIndices.rend(), indices.begin());
1558 } else {
1559 std::copy(tmpIndices.begin(), tmpIndices.end(), indices.begin());
1560 }
1561
1562 vk::DescriptorSetLayoutBuilder layoutBuilder;
1563 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
1564
1565 std::vector<vk::Move<VkDescriptorSetLayout>> descriptorSetLayouts = {};
1566
1567 for (size_t i = 0; i < indices.size(); i++) {
1568 descriptorSetLayouts.emplace_back(layoutBuilder.build(vkd, device));
1569 }
1570
1571 // Pipeline layout and graphics pipeline.
1572 uint32_t setAndDescriptorCount = de::sizeU32(indices);
1573 const vk::PipelineLayoutWrapper pipelineLayout (m_config.construction, vkd, device, descriptorSetLayouts);
1574 DescriptorPoolBuilder poolBuilder;
1575 poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, setAndDescriptorCount);
1576 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, setAndDescriptorCount);
1577 std::vector<vk::Move<VkDescriptorSet>> descriptorSetsWrap = {};
1578 std::vector<VkDescriptorSet> descriptorSets = {};
1579
1580 for (const auto& setLayout : descriptorSetLayouts) {
1581 descriptorSetsWrap.emplace_back(makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get()));
1582 }
1583
1584 for (size_t i = 0; i < indices.size(); i++) {
1585 descriptorSets.emplace_back(descriptorSetsWrap[i].get());
1586 }
1587
1588 const auto bufferSize = static_cast<VkDeviceSize>(sizeof(uint32_t));
1589 std::vector<std::unique_ptr<BufferWithMemory>> buffers;
1590 //create uniform buffers
1591 for (size_t i = 0; i < indices.size(); i++) {
1592 auto outBufferInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
1593 auto buffer = std::unique_ptr<vk::BufferWithMemory>(new vk::BufferWithMemory(vkd, device, alloc, outBufferInfo, vk::MemoryRequirement::HostVisible));
1594 auto& bufferAlloc = buffer->getAllocation();
1595 uint32_t* bufferData = (uint32_t*)bufferAlloc.getHostPtr();
1596 *bufferData = (uint32_t)i;
1597 flushAlloc(vkd, device, bufferAlloc);
1598 buffers.push_back(std::move(buffer));
1599 }
1600
1601 DescriptorSetUpdateBuilder updater;
1602
1603 for (auto i : indices) {
1604 const auto bufferInfo = makeDescriptorBufferInfo(buffers[i]->get(), 0ull, bufferSize);
1605 updater.writeSingle(descriptorSets[i], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo);
1606 updater.update(vkd, device);
1607 }
1608
1609 const auto topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1610 m_graphicsPipeline.setDefaultRasterizationState()
1611 .setDefaultTopology(topology)
1612 .setupVertexInputState(&vertexInputState)
1613 .setDefaultDepthStencilState()
1614 .setDefaultMultisampleState()
1615 .setDefaultColorBlendState()
1616 .setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *renderPass, 0u, vertModule, &rasterizationState)
1617 .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragModule)
1618 .setupFragmentOutputState(*renderPass)
1619 .setMonolithicPipelineLayout(pipelineLayout)
1620 .buildPipeline();
1621
1622 // Command pool and buffer.
1623 const auto cmdPool = makeCommandPool(vkd, device, qIndex);
1624 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1625 const auto cmdBuffer = cmdBufferPtr.get();
1626
1627 beginCommandBuffer(vkd, cmdBuffer);
1628
1629 // Draw.
1630 renderPass.begin(vkd, cmdBuffer, scissors.at(0u), clearColor);
1631 for (auto i : indices) {
1632 if (m_config.holes && ((i == 1) || (i == 2))) {
1633 continue;
1634 }
1635 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), i, 1, &descriptorSets[i], 0u, nullptr);
1636 }
1637 m_graphicsPipeline.bind(cmdBuffer);
1638 vkd.cmdDraw(cmdBuffer, 3, 1u, 0u, 0u);
1639 renderPass.end(vkd, cmdBuffer);
1640
1641 // Copy to verification buffer.
1642 const auto copyRegion = makeBufferImageCopy(m_extent, colorSRL);
1643 const auto transfer2Host = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1644 const auto color2Transfer = makeImageMemoryBarrier(
1645 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1646 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1647 colorBuffer.get(), colorSRR);
1648
1649 cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &color2Transfer);
1650 vkd.cmdCopyImageToBuffer(cmdBuffer, colorBuffer.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verifBuffer.get(), 1u, ©Region);
1651 cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &transfer2Host);
1652
1653 endCommandBuffer(vkd, cmdBuffer);
1654
1655 // Submit and validate result.
1656 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1657
1658 const tcu::IVec3 iExtent (static_cast<int>(m_extent.width), static_cast<int>(m_extent.height), static_cast<int>(m_extent.depth));
1659 void* verifBufferData = verifBufferAlloc.getHostPtr();
1660 const tcu::ConstPixelBufferAccess verifAccess (tcuFormat, iExtent, verifBufferData);
1661 invalidateAlloc(vkd, device, verifBufferAlloc);
1662
1663 const auto green = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1664 tcu::TextureLevel referenceLevel(mapVkFormat(m_format), m_extent.height, m_extent.height);
1665 tcu::PixelBufferAccess reference = referenceLevel.getAccess();
1666 tcu::clear(reference, green);
1667
1668 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference, verifAccess, tcu::Vec4(0.0), tcu::COMPARE_LOG_ON_ERROR))
1669 return tcu::TestStatus::fail("Image comparison failed");
1670
1671 return tcu::TestStatus::pass("Pass");
1672 }
1673
1674 } // anonymous
1675
createMiscTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)1676 tcu::TestCaseGroup* createMiscTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
1677 {
1678 de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc"));
1679
1680 // Location of the Amber script files under the data/vulkan/amber source tree.
1681 if (pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1682 addMonolithicAmberTests(miscTests.get());
1683
1684 // Verify implicit access to gl_PrimtiveID works
1685 miscTests->addChild(new ImplicitPrimitiveIDPassthroughCase(testCtx, "implicit_primitive_id", pipelineConstructionType, false));
1686 // Verify implicit access to gl_PrimtiveID works with a tessellation shader
1687 miscTests->addChild(new ImplicitPrimitiveIDPassthroughCase(testCtx, "implicit_primitive_id_with_tessellation", pipelineConstructionType, true));
1688 #ifndef CTS_USES_VULKANSC
1689 if (pipelineConstructionType == vk::PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY) {
1690 // Check if interpolateAtSample works as expected when using a pipeline library and null MSAA state in the fragment shader"
1691 miscTests->addChild(new PipelineLibraryInterpolateAtSampleTestCase(testCtx, "interpolate_at_sample_no_sample_shading"));
1692 }
1693 #endif
1694
1695 #ifndef CTS_USES_VULKANSC
1696 if (isConstructionTypeLibrary(pipelineConstructionType))
1697 {
1698 for (int useTessIdx = 0; useTessIdx < 2; ++useTessIdx)
1699 for (int useGeomIdx = 0; useGeomIdx < 2; ++useGeomIdx)
1700 {
1701 const bool useTess = (useTessIdx > 0);
1702 const bool useGeom = (useGeomIdx > 0);
1703
1704 std::string testName = "unused_shader_stages";
1705
1706 if (useTess)
1707 testName += "_include_tess";
1708
1709 if (useGeom)
1710 testName += "_include_geom";
1711
1712 const UnusedShaderStageParams params { pipelineConstructionType, useTess, useGeom };
1713 miscTests->addChild(new UnusedShaderStagesCase(testCtx, testName, params));
1714 }
1715 }
1716 #endif // CTS_USES_VULKANSC
1717
1718 BindingTestConfig config0 = {pipelineConstructionType, true, false};
1719 BindingTestConfig config1 = {pipelineConstructionType, false, true};
1720 BindingTestConfig config2 = {pipelineConstructionType, true, true};
1721
1722 // Verify implicit access to gl_PrimtiveID works with a tessellation shader
1723 miscTests->addChild(new PipelineLayoutBindingTestCases(testCtx, "descriptor_bind_test_backwards", config0));
1724 // Verify implicit access to gl_PrimtiveID works with a tessellation shader
1725 miscTests->addChild(new PipelineLayoutBindingTestCases(testCtx, "descriptor_bind_test_holes", config1));
1726 // Verify implicit access to gl_PrimtiveID works with a tessellation shader
1727 miscTests->addChild(new PipelineLayoutBindingTestCases(testCtx, "descriptor_bind_test_backwards_holes", config2));
1728
1729 return miscTests.release();
1730 }
1731
1732 } // pipeline
1733 } // vkt
1734