1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2019 The Khronos Group Inc.
6 * Copyright (c) 2019 Valve Corporation.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Max Varying Tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktPipelineMaxVaryingsTests.hpp"
26 #include "vktTestGroupUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vkTypeUtil.hpp"
29 #include "vkImageUtil.hpp"
30 #include "vkObjUtil.hpp"
31 #include "vktPipelineMakeUtil.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vktPipelineSpecConstantUtil.hpp"
38 #include "tcuImageCompare.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuTextureUtil.hpp"
54 struct MaxVaryingsParam
56 PipelineConstructionType pipelineConstructionType;
57 VkShaderStageFlags outputStage;
58 VkShaderStageFlags inputStage;
59 VkShaderStageFlags stageToStressIO;
63 std::string getShaderStageName(VkShaderStageFlags stage)
68 DE_FATAL("Unhandled stage!");
70 case VK_SHADER_STAGE_COMPUTE_BIT:
72 case VK_SHADER_STAGE_FRAGMENT_BIT:
74 case VK_SHADER_STAGE_VERTEX_BIT:
76 case VK_SHADER_STAGE_GEOMETRY_BIT:
78 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
79 return "tess_control";
80 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
85 const std::string generateTestName (struct MaxVaryingsParam param)
87 std::ostringstream result;
89 result << "test_" << getShaderStageName(param.stageToStressIO) << "_io_between_";
90 result << getShaderStageName(param.outputStage) << "_";
91 result << getShaderStageName(param.inputStage);
95 const std::string generateTestDescription ()
97 std::string result("Tests to check max varyings per stage");
101 void initPrograms (SourceCollections& programCollection, MaxVaryingsParam param)
103 const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u);
105 // Vertex shader. SPIR-V generated from:
107 // layout(location = 0) in highp vec4 pos;
108 // layout(constant_id = 0) const int arraySize = 1;
109 // layout(location = 0) out ivec4 outputData[arraySize];
110 // out gl_PerVertex {
116 // gl_Position = pos;
118 // for (i = 0; i < arraySize; i++)
120 // outputData[i] = ivec4(i);
123 std::ostringstream vertex_out;
124 vertex_out << "OpCapability Shader\n"
125 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
126 << "OpMemoryModel Logical GLSL450\n"
127 << "OpEntryPoint Vertex %4 \"main\" %10 %14 %32\n"
128 << "OpMemberDecorate %8 0 BuiltIn Position\n"
129 << "OpDecorate %8 Block\n"
130 << "OpDecorate %14 Location 0\n"
131 << "OpDecorate %26 SpecId 0\n"
132 << "OpDecorate %32 Location 0\n"
133 << "%2 = OpTypeVoid\n"
134 << "%3 = OpTypeFunction %2\n"
135 << "%6 = OpTypeFloat 32\n"
136 << "%7 = OpTypeVector %6 4\n"
137 << "%8 = OpTypeStruct %7\n"
138 << "%9 = OpTypePointer Output %8\n"
139 << "%10 = OpVariable %9 Output\n"
140 << "%11 = OpTypeInt 32 1\n"
141 << "%12 = OpConstant %11 0\n"
142 << "%13 = OpTypePointer Input %7\n"
143 << "%14 = OpVariable %13 Input\n"
144 << "%16 = OpTypePointer Output %7\n"
145 << "%18 = OpTypePointer Function %11\n"
146 << "%26 = OpSpecConstant %11 1\n"
147 << "%27 = OpTypeBool\n"
148 << "%29 = OpTypeVector %11 4\n"
149 << "%30 = OpTypeArray %29 %26\n"
150 << "%31 = OpTypePointer Output %30\n"
151 << "%32 = OpVariable %31 Output\n"
152 << "%36 = OpTypePointer Output %29\n"
153 << "%39 = OpConstant %11 1\n"
154 << "%4 = OpFunction %2 None %3\n"
156 << "%19 = OpVariable %18 Function\n"
157 << "%15 = OpLoad %7 %14\n"
158 << "%17 = OpAccessChain %16 %10 %12\n"
159 << "OpStore %17 %15\n"
160 << "OpStore %19 %12\n"
163 << "OpLoopMerge %22 %23 None\n"
166 << "%25 = OpLoad %11 %19\n"
167 << "%28 = OpSLessThan %27 %25 %26\n"
168 << "OpBranchConditional %28 %21 %22\n"
170 << "%33 = OpLoad %11 %19\n"
171 << "%34 = OpLoad %11 %19\n"
172 << "%35 = OpCompositeConstruct %29 %34 %34 %34 %34\n"
173 << "%37 = OpAccessChain %36 %32 %33\n"
174 << "OpStore %37 %35\n"
177 << "%38 = OpLoad %11 %19\n"
178 << "%40 = OpIAdd %11 %38 %39\n"
179 << "OpStore %19 %40\n"
183 << "OpFunctionEnd\n";
185 // Vertex shader passthrough. SPIR-V generated from:
187 // layout(location = 0) in highp vec4 pos;
188 // out gl_PerVertex {
193 // gl_Position = pos;
195 std::ostringstream vertex_passthrough;
196 vertex_passthrough << "OpCapability Shader\n"
197 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
198 << "OpMemoryModel Logical GLSL450\n"
199 << "OpEntryPoint Vertex %4 \"main\" %10 %14\n"
200 << "OpMemberDecorate %8 0 BuiltIn Position\n"
201 << "OpDecorate %8 Block\n"
202 << "OpDecorate %14 Location 0\n"
203 << "%2 = OpTypeVoid\n"
204 << "%3 = OpTypeFunction %2\n"
205 << "%6 = OpTypeFloat 32\n"
206 << "%7 = OpTypeVector %6 4\n"
207 << "%8 = OpTypeStruct %7\n"
208 << "%9 = OpTypePointer Output %8\n"
209 << "%10 = OpVariable %9 Output\n"
210 << "%11 = OpTypeInt 32 1\n"
211 << "%12 = OpConstant %11 0\n"
212 << "%13 = OpTypePointer Input %7\n"
213 << "%14 = OpVariable %13 Input\n"
214 << "%16 = OpTypePointer Output %7\n"
215 << "%4 = OpFunction %2 None %3\n"
217 << "%15 = OpLoad %7 %14\n"
218 << "%17 = OpAccessChain %16 %10 %12\n"
219 << "OpStore %17 %15\n"
221 << "OpFunctionEnd\n";
223 // Tesselation Control shader. SPIR-V generated from:
225 // layout(vertices = 3) out;
236 // if (gl_InvocationID == 0) {
237 // gl_TessLevelInner[0] = 1.0;
238 // gl_TessLevelInner[1] = 1.0;
239 // gl_TessLevelOuter[0] = 1.0;
240 // gl_TessLevelOuter[1] = 1.0;
241 // gl_TessLevelOuter[2] = 1.0;
242 // gl_TessLevelOuter[3] = 1.0;
244 // gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
246 std::ostringstream tcs_passthrough;
247 tcs_passthrough << "OpCapability Tessellation\n"
248 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
249 << "OpMemoryModel Logical GLSL450\n"
250 << "OpEntryPoint TessellationControl %4 \"main\" %8 %20 %29 %41 %47\n"
251 << "OpExecutionMode %4 OutputVertices 3\n"
252 << "OpDecorate %8 BuiltIn InvocationId\n"
253 << "OpDecorate %20 Patch\n"
254 << "OpDecorate %20 BuiltIn TessLevelInner\n"
255 << "OpDecorate %29 Patch\n"
256 << "OpDecorate %29 BuiltIn TessLevelOuter\n"
257 << "OpMemberDecorate %37 0 BuiltIn Position\n"
258 << "OpDecorate %37 Block\n"
259 << "OpMemberDecorate %43 0 BuiltIn Position\n"
260 << "OpDecorate %43 Block\n"
261 << "%2 = OpTypeVoid\n"
262 << "%3 = OpTypeFunction %2\n"
263 << "%6 = OpTypeInt 32 1\n"
264 << "%7 = OpTypePointer Input %6\n"
265 << "%8 = OpVariable %7 Input\n"
266 << "%10 = OpConstant %6 0\n"
267 << "%11 = OpTypeBool\n"
268 << "%15 = OpTypeFloat 32\n"
269 << "%16 = OpTypeInt 32 0\n"
270 << "%17 = OpConstant %16 2\n"
271 << "%18 = OpTypeArray %15 %17\n"
272 << "%19 = OpTypePointer Output %18\n"
273 << "%20 = OpVariable %19 Output\n"
274 << "%21 = OpConstant %15 1\n"
275 << "%22 = OpTypePointer Output %15\n"
276 << "%24 = OpConstant %6 1\n"
277 << "%26 = OpConstant %16 4\n"
278 << "%27 = OpTypeArray %15 %26\n"
279 << "%28 = OpTypePointer Output %27\n"
280 << "%29 = OpVariable %28 Output\n"
281 << "%32 = OpConstant %6 2\n"
282 << "%34 = OpConstant %6 3\n"
283 << "%36 = OpTypeVector %15 4\n"
284 << "%37 = OpTypeStruct %36\n"
285 << "%38 = OpConstant %16 3\n"
286 << "%39 = OpTypeArray %37 %38\n"
287 << "%40 = OpTypePointer Output %39\n"
288 << "%41 = OpVariable %40 Output\n"
289 << "%43 = OpTypeStruct %36\n"
290 << "%44 = OpConstant %16 32\n"
291 << "%45 = OpTypeArray %43 %44\n"
292 << "%46 = OpTypePointer Input %45\n"
293 << "%47 = OpVariable %46 Input\n"
294 << "%49 = OpTypePointer Input %36\n"
295 << "%52 = OpTypePointer Output %36\n"
296 << "%4 = OpFunction %2 None %3\n"
298 << "%9 = OpLoad %6 %8\n"
299 << "%12 = OpIEqual %11 %9 %10\n"
300 << "OpSelectionMerge %14 None\n"
301 << "OpBranchConditional %12 %13 %14\n"
303 << "%23 = OpAccessChain %22 %20 %10\n"
304 << "OpStore %23 %21\n"
305 << "%25 = OpAccessChain %22 %20 %24\n"
306 << "OpStore %25 %21\n"
307 << "%30 = OpAccessChain %22 %29 %10\n"
308 << "OpStore %30 %21\n"
309 << "%31 = OpAccessChain %22 %29 %24\n"
310 << "OpStore %31 %21\n"
311 << "%33 = OpAccessChain %22 %29 %32\n"
312 << "OpStore %33 %21\n"
313 << "%35 = OpAccessChain %22 %29 %34\n"
314 << "OpStore %35 %21\n"
317 << "%42 = OpLoad %6 %8\n"
318 << "%48 = OpLoad %6 %8\n"
319 << "%50 = OpAccessChain %49 %47 %48 %10\n"
320 << "%51 = OpLoad %36 %50\n"
321 << "%53 = OpAccessChain %52 %41 %42 %10\n"
322 << "OpStore %53 %51\n"
324 << "OpFunctionEnd\n";
326 // Tessellation Evaluation shader. SPIR-V generated from:
328 // layout(triangles, equal_spacing, cw) in;
329 // layout(constant_id = 0) const int arraySize = 1;
330 // layout(location = 0) out ivec4 outputData[arraySize];
334 // out gl_PerVertex {
339 // gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position +
340 // gl_TessCoord.y * gl_in[1].gl_Position +
341 // gl_TessCoord.z * gl_in[2].gl_Position);
343 // for (j = 0; j < arraySize; j++)
345 // outputData[j] = ivec4(j);
348 std::ostringstream tes_out;
349 tes_out << "OpCapability Tessellation\n"
350 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
351 << "OpMemoryModel Logical GLSL450\n"
352 << "OpEntryPoint TessellationEvaluation %4 \"main\" %10 %15 %25 %62\n"
353 << "OpExecutionMode %4 Triangles\n"
354 << "OpExecutionMode %4 SpacingEqual\n"
355 << "OpExecutionMode %4 VertexOrderCw\n"
356 << "OpMemberDecorate %8 0 BuiltIn Position\n"
357 << "OpDecorate %8 Block\n"
358 << "OpDecorate %15 BuiltIn TessCoord\n"
359 << "OpMemberDecorate %21 0 BuiltIn Position\n"
360 << "OpDecorate %21 Block\n"
361 << "OpDecorate %56 SpecId 0\n"
362 << "OpDecorate %62 Location 0\n"
363 << "%2 = OpTypeVoid\n"
364 << "%3 = OpTypeFunction %2\n"
365 << "%6 = OpTypeFloat 32\n"
366 << "%7 = OpTypeVector %6 4\n"
367 << "%8 = OpTypeStruct %7\n"
368 << "%9 = OpTypePointer Output %8\n"
369 << "%10 = OpVariable %9 Output\n"
370 << "%11 = OpTypeInt 32 1\n"
371 << "%12 = OpConstant %11 0\n"
372 << "%13 = OpTypeVector %6 3\n"
373 << "%14 = OpTypePointer Input %13\n"
374 << "%15 = OpVariable %14 Input\n"
375 << "%16 = OpTypeInt 32 0\n"
376 << "%17 = OpConstant %16 0\n"
377 << "%18 = OpTypePointer Input %6\n"
378 << "%21 = OpTypeStruct %7\n"
379 << "%22 = OpConstant %16 32\n"
380 << "%23 = OpTypeArray %21 %22\n"
381 << "%24 = OpTypePointer Input %23\n"
382 << "%25 = OpVariable %24 Input\n"
383 << "%26 = OpTypePointer Input %7\n"
384 << "%30 = OpConstant %16 1\n"
385 << "%33 = OpConstant %11 1\n"
386 << "%38 = OpConstant %16 2\n"
387 << "%41 = OpConstant %11 2\n"
388 << "%46 = OpTypePointer Output %7\n"
389 << "%48 = OpTypePointer Function %11\n"
390 << "%56 = OpSpecConstant %11 1\n"
391 << "%57 = OpTypeBool\n"
392 << "%59 = OpTypeVector %11 4\n"
393 << "%60 = OpTypeArray %59 %56\n"
394 << "%61 = OpTypePointer Output %60\n"
395 << "%62 = OpVariable %61 Output\n"
396 << "%66 = OpTypePointer Output %59\n"
397 << "%4 = OpFunction %2 None %3\n"
399 << "%49 = OpVariable %48 Function\n"
400 << "%19 = OpAccessChain %18 %15 %17\n"
401 << "%20 = OpLoad %6 %19\n"
402 << "%27 = OpAccessChain %26 %25 %12 %12\n"
403 << "%28 = OpLoad %7 %27\n"
404 << "%29 = OpVectorTimesScalar %7 %28 %20\n"
405 << "%31 = OpAccessChain %18 %15 %30\n"
406 << "%32 = OpLoad %6 %31\n"
407 << "%34 = OpAccessChain %26 %25 %33 %12\n"
408 << "%35 = OpLoad %7 %34\n"
409 << "%36 = OpVectorTimesScalar %7 %35 %32\n"
410 << "%37 = OpFAdd %7 %29 %36\n"
411 << "%39 = OpAccessChain %18 %15 %38\n"
412 << "%40 = OpLoad %6 %39\n"
413 << "%42 = OpAccessChain %26 %25 %41 %12\n"
414 << "%43 = OpLoad %7 %42\n"
415 << "%44 = OpVectorTimesScalar %7 %43 %40\n"
416 << "%45 = OpFAdd %7 %37 %44\n"
417 << "%47 = OpAccessChain %46 %10 %12\n"
418 << "OpStore %47 %45\n"
419 << "OpStore %49 %12\n"
422 << "OpLoopMerge %52 %53 None\n"
425 << "%55 = OpLoad %11 %49\n"
426 << "%58 = OpSLessThan %57 %55 %56\n"
427 << "OpBranchConditional %58 %51 %52\n"
429 << "%63 = OpLoad %11 %49\n"
430 << "%64 = OpLoad %11 %49\n"
431 << "%65 = OpCompositeConstruct %59 %64 %64 %64 %64\n"
432 << "%67 = OpAccessChain %66 %62 %63\n"
433 << "OpStore %67 %65\n"
436 << "%68 = OpLoad %11 %49\n"
437 << "%69 = OpIAdd %11 %68 %33\n"
438 << "OpStore %49 %69\n"
442 << "OpFunctionEnd\n";
444 // Geometry shader. SPIR-V generated from:
446 // layout (triangles) in;
447 // layout (triangle_strip, max_vertices = 3) out;
448 // layout(constant_id = 0) const int arraySize = 1;
449 // layout(location = 0) out ivec4 outputData[arraySize];
457 // for(i = 0; i < gl_in.length(); i++)
459 // gl_Position = gl_in[i].gl_Position;
460 // for (j = 0; j < arraySize; j++)
462 // outputData[j] = ivec4(j);
468 std::ostringstream geom_out;
469 geom_out << "OpCapability Geometry\n"
470 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
471 << "OpMemoryModel Logical GLSL450\n"
472 << "OpEntryPoint Geometry %4 \"main\" %26 %31 %50\n"
473 << "OpExecutionMode %4 Triangles\n"
474 << "OpExecutionMode %4 Invocations 1\n"
475 << "OpExecutionMode %4 OutputTriangleStrip\n"
476 << "OpExecutionMode %4 OutputVertices 3\n"
477 << "OpMemberDecorate %24 0 BuiltIn Position\n"
478 << "OpDecorate %24 Block\n"
479 << "OpMemberDecorate %27 0 BuiltIn Position\n"
480 << "OpDecorate %27 Block\n"
481 << "OpDecorate %45 SpecId 0\n"
482 << "OpDecorate %50 Location 0\n"
483 << "%2 = OpTypeVoid\n"
484 << "%3 = OpTypeFunction %2\n"
485 << "%6 = OpTypeInt 32 1\n"
486 << "%7 = OpTypePointer Function %6\n"
487 << "%9 = OpConstant %6 0\n"
488 << "%16 = OpConstant %6 3\n"
489 << "%17 = OpTypeBool\n"
490 << "%19 = OpTypeFloat 32\n"
491 << "%20 = OpTypeVector %19 4\n"
492 << "%21 = OpTypeInt 32 0\n"
493 << "%22 = OpConstant %21 1\n"
494 << "%23 = OpTypeArray %19 %22\n"
495 << "%24 = OpTypeStruct %20\n"
496 << "%25 = OpTypePointer Output %24\n"
497 << "%26 = OpVariable %25 Output\n"
498 << "%27 = OpTypeStruct %20\n"
499 << "%28 = OpConstant %21 3\n"
500 << "%29 = OpTypeArray %27 %28\n"
501 << "%30 = OpTypePointer Input %29\n"
502 << "%31 = OpVariable %30 Input\n"
503 << "%33 = OpTypePointer Input %20\n"
504 << "%36 = OpTypePointer Output %20\n"
505 << "%45 = OpSpecConstant %6 1\n"
506 << "%47 = OpTypeVector %6 4\n"
507 << "%48 = OpTypeArray %47 %45\n"
508 << "%49 = OpTypePointer Output %48\n"
509 << "%50 = OpVariable %49 Output\n"
510 << "%54 = OpTypePointer Output %47\n"
511 << "%57 = OpConstant %6 1\n"
512 << "%4 = OpFunction %2 None %3\n"
514 << "%8 = OpVariable %7 Function\n"
515 << "%38 = OpVariable %7 Function\n"
519 << "OpLoopMerge %12 %13 None\n"
522 << "%15 = OpLoad %6 %8\n"
523 << "%18 = OpSLessThan %17 %15 %16\n"
524 << "OpBranchConditional %18 %11 %12\n"
526 << "%32 = OpLoad %6 %8\n"
527 << "%34 = OpAccessChain %33 %31 %32 %9\n"
528 << "%35 = OpLoad %20 %34\n"
529 << "%37 = OpAccessChain %36 %26 %9\n"
530 << "OpStore %37 %35\n"
531 << "OpStore %38 %9\n"
534 << "OpLoopMerge %41 %42 None\n"
537 << "%44 = OpLoad %6 %38\n"
538 << "%46 = OpSLessThan %17 %44 %45\n"
539 << "OpBranchConditional %46 %40 %41\n"
541 << "%51 = OpLoad %6 %38\n"
542 << "%52 = OpLoad %6 %38\n"
543 << "%53 = OpCompositeConstruct %47 %52 %52 %52 %52\n"
544 << "%55 = OpAccessChain %54 %50 %51\n"
545 << "OpStore %55 %53\n"
548 << "%56 = OpLoad %6 %38\n"
549 << "%58 = OpIAdd %6 %56 %57\n"
550 << "OpStore %38 %58\n"
556 << "%59 = OpLoad %6 %8\n"
557 << "%60 = OpIAdd %6 %59 %57\n"
558 << "OpStore %8 %60\n"
561 << "OpEndPrimitive\n"
563 << "OpFunctionEnd\n";
565 // Fragment shader. SPIR-V code generated from:
568 // layout(constant_id = 0) const int arraySize = 1;
569 // layout(location = 0) flat in ivec4 inputData[arraySize];
570 // layout(location = 0) out vec4 color;
573 // color = vec4(1.0, 0.0, 0.0, 1.0);
575 // bool result = true;
576 // for (i = 0; i < arraySize; i++)
578 // if (result && inputData[i] != ivec4(i))
582 // color = vec4(0.0, 1.0, 0.0, 1.0);
584 std::ostringstream fragment_in;
585 fragment_in << "OpCapability Shader\n"
586 << "%1 = OpExtInstImport \"GLSL.std.450\"\n"
587 << "OpMemoryModel Logical GLSL450\n"
588 << "OpEntryPoint Fragment %4 \"main\" %9 %35\n"
589 << "OpExecutionMode %4 OriginUpperLeft\n"
590 << "OpDecorate %9 Location 0\n"
591 << "OpDecorate %27 SpecId 0\n"
592 << "OpDecorate %35 Flat\n"
593 << "OpDecorate %35 Location 0\n"
594 << "%2 = OpTypeVoid\n"
595 << "%3 = OpTypeFunction %2\n"
596 << "%6 = OpTypeFloat 32\n"
597 << "%7 = OpTypeVector %6 4\n"
598 << "%8 = OpTypePointer Output %7\n"
599 << "%9 = OpVariable %8 Output\n"
600 << "%10 = OpConstant %6 1\n"
601 << "%11 = OpConstant %6 0\n"
602 << "%12 = OpConstantComposite %7 %10 %11 %11 %10\n"
603 << "%13 = OpTypeBool\n"
604 << "%14 = OpTypePointer Function %13\n"
605 << "%16 = OpConstantTrue %13\n"
606 << "%17 = OpTypeInt 32 1\n"
607 << "%18 = OpTypePointer Function %17\n"
608 << "%20 = OpConstant %17 0\n"
609 << "%27 = OpSpecConstant %17 1\n"
610 << "%32 = OpTypeVector %17 4\n"
611 << "%33 = OpTypeArray %32 %27\n"
612 << "%34 = OpTypePointer Input %33\n"
613 << "%35 = OpVariable %34 Input\n"
614 << "%37 = OpTypePointer Input %32\n"
615 << "%42 = OpTypeVector %13 4\n"
616 << "%48 = OpConstantFalse %13\n"
617 << "%50 = OpConstant %17 1\n"
618 << "%55 = OpConstantComposite %7 %11 %10 %11 %10\n"
619 << "%4 = OpFunction %2 None %3\n"
621 << "%15 = OpVariable %14 Function\n"
622 << "%19 = OpVariable %18 Function\n"
623 << "OpStore %9 %12\n"
624 << "OpStore %15 %16\n"
625 << "OpStore %19 %20\n"
628 << "OpLoopMerge %23 %24 None\n"
631 << "%26 = OpLoad %17 %19\n"
632 << "%28 = OpSLessThan %13 %26 %27\n"
633 << "OpBranchConditional %28 %22 %23\n"
635 << "%29 = OpLoad %13 %15\n"
636 << "OpSelectionMerge %31 None\n"
637 << "OpBranchConditional %29 %30 %31\n"
639 << "%36 = OpLoad %17 %19\n"
640 << "%38 = OpAccessChain %37 %35 %36\n"
641 << "%39 = OpLoad %32 %38\n"
642 << "%40 = OpLoad %17 %19\n"
643 << "%41 = OpCompositeConstruct %32 %40 %40 %40 %40\n"
644 << "%43 = OpINotEqual %42 %39 %41\n"
645 << "%44 = OpAny %13 %43\n"
648 << "%45 = OpPhi %13 %29 %22 %44 %30\n"
649 << "OpSelectionMerge %47 None\n"
650 << "OpBranchConditional %45 %46 %47\n"
652 << "OpStore %15 %48\n"
657 << "%49 = OpLoad %17 %19\n"
658 << "%51 = OpIAdd %17 %49 %50\n"
659 << "OpStore %19 %51\n"
662 << "%52 = OpLoad %13 %15\n"
663 << "OpSelectionMerge %54 None\n"
664 << "OpBranchConditional %52 %53 %54\n"
666 << "OpStore %9 %55\n"
670 << "OpFunctionEnd\n";
672 if (param.outputStage == VK_SHADER_STAGE_VERTEX_BIT)
674 programCollection.spirvAsmSources.add("vert")
675 << vertex_out.str().c_str();
677 if (param.inputStage == VK_SHADER_STAGE_FRAGMENT_BIT)
679 programCollection.spirvAsmSources.add("frag")
680 << fragment_in.str().c_str();
685 programCollection.spirvAsmSources.add("vert")
686 << vertex_passthrough.str().c_str();
688 if (param.outputStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
690 programCollection.spirvAsmSources.add("tcs")
691 << tcs_passthrough.str().c_str();
692 programCollection.spirvAsmSources.add("tes")
693 << tes_out.str().c_str();
695 if (param.inputStage == VK_SHADER_STAGE_FRAGMENT_BIT)
697 programCollection.spirvAsmSources.add("frag")
698 << fragment_in.str().c_str();
703 if (param.outputStage == VK_SHADER_STAGE_GEOMETRY_BIT)
705 programCollection.spirvAsmSources.add("geom")
706 << geom_out.str().c_str();
707 programCollection.spirvAsmSources.add("frag")
708 << fragment_in.str().c_str();
712 DE_FATAL("Unsupported combination");
715 void supportedCheck (Context& context, MaxVaryingsParam param)
718 const vk::InstanceInterface& vki = context.getInstanceInterface();
719 VkPhysicalDeviceFeatures features;
720 vki.getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
722 // Check support for the tessellation and geometry shaders on the device
723 if ((param.inputStage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
724 param.inputStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ||
725 param.outputStage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
726 param.outputStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
727 && !features.tessellationShader)
729 TCU_THROW(NotSupportedError, "Device does not support tessellation shaders");
732 if ((param.inputStage == VK_SHADER_STAGE_GEOMETRY_BIT || param.outputStage == VK_SHADER_STAGE_GEOMETRY_BIT) && !features.geometryShader)
734 TCU_THROW(NotSupportedError, "Device does not support geometry shaders");
737 // Check data sizes, throw unsupported if the case cannot be tested.
738 VkPhysicalDeviceProperties properties;
739 vki.getPhysicalDeviceProperties(context.getPhysicalDevice(), &properties);
740 std::ostringstream error;
741 if (param.stageToStressIO == VK_SHADER_STAGE_VERTEX_BIT)
743 DE_ASSERT(param.outputStage == VK_SHADER_STAGE_VERTEX_BIT);
744 if (param.inputStage == VK_SHADER_STAGE_FRAGMENT_BIT && properties.limits.maxFragmentInputComponents < (properties.limits.maxVertexOutputComponents - 4))
746 error << "Device supports smaller number of FS inputs (" << properties.limits.maxFragmentInputComponents << ") than VS outputs (" << properties.limits.maxVertexOutputComponents << " - 4 built-ins)";
747 TCU_THROW(NotSupportedError, error.str().c_str());
751 if (param.stageToStressIO == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
753 if (param.inputStage == VK_SHADER_STAGE_FRAGMENT_BIT && properties.limits.maxFragmentInputComponents < (properties.limits.maxTessellationEvaluationOutputComponents - 4))
755 error << "Device supports smaller number of FS inputs (" << properties.limits.maxFragmentInputComponents << ") than TES outputs (" << properties.limits.maxTessellationEvaluationOutputComponents << " - 4 builtins)";
756 TCU_THROW(NotSupportedError, error.str().c_str());
760 if (param.stageToStressIO == VK_SHADER_STAGE_GEOMETRY_BIT)
762 if (param.inputStage == VK_SHADER_STAGE_FRAGMENT_BIT && properties.limits.maxFragmentInputComponents < (properties.limits.maxGeometryOutputComponents - 4))
764 error << "Device supports smaller number of FS inputs (" << properties.limits.maxFragmentInputComponents << ") than GS outputs (" << properties.limits.maxGeometryOutputComponents << " - 4 built-ins)";
765 TCU_THROW(NotSupportedError, error.str().c_str());
769 if (param.stageToStressIO == VK_SHADER_STAGE_FRAGMENT_BIT)
771 DE_ASSERT(param.inputStage == VK_SHADER_STAGE_FRAGMENT_BIT);
773 if (param.outputStage == VK_SHADER_STAGE_VERTEX_BIT && (properties.limits.maxVertexOutputComponents - 4) < properties.limits.maxFragmentInputComponents)
775 error << "Device supports smaller number of VS outputs (" << properties.limits.maxVertexOutputComponents << " - 4 built-ins) than FS inputs (" << properties.limits.maxFragmentInputComponents << ")";
776 TCU_THROW(NotSupportedError, error.str().c_str());
778 if (param.outputStage == VK_SHADER_STAGE_GEOMETRY_BIT && (properties.limits.maxGeometryOutputComponents - 4) < properties.limits.maxFragmentInputComponents)
780 error << "Device supports smaller number of GS outputs (" << properties.limits.maxGeometryOutputComponents << " - 4 built-ins) than FS inputs (" << properties.limits.maxFragmentInputComponents << ")";
781 TCU_THROW(NotSupportedError, error.str().c_str());
783 if (param.outputStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT && (properties.limits.maxTessellationEvaluationOutputComponents - 4) < properties.limits.maxFragmentInputComponents)
785 error << "Device supports smaller number of TES outputs (" << properties.limits.maxTessellationEvaluationOutputComponents << " - 4 built-ins) than FS inputs (" << properties.limits.maxFragmentInputComponents << ")";
786 TCU_THROW(NotSupportedError, error.str().c_str());
790 checkPipelineLibraryRequirements(vki, context.getPhysicalDevice(), param.pipelineConstructionType);
793 VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage)
795 const VkImageCreateInfo imageInfo =
797 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
798 DE_NULL, // const void* pNext;
799 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
800 VK_IMAGE_TYPE_2D, // VkImageType imageType;
801 format, // VkFormat format;
802 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent;
803 1u, // uint32_t mipLevels;
804 1u, // uint32_t arrayLayers;
805 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
806 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
807 usage, // VkImageUsageFlags usage;
808 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
809 0u, // uint32_t queueFamilyIndexCount;
810 DE_NULL, // const uint32_t* pQueueFamilyIndices;
811 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
816 Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize bufferSize, const VkBufferUsageFlags usage)
818 const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(bufferSize, usage);
819 return createBuffer(vk, device, &bufferCreateInfo);
822 void recordImageBarrier (const DeviceInterface& vk,
823 const VkCommandBuffer cmdBuffer,
825 const VkImageAspectFlags aspect,
826 const VkPipelineStageFlags srcStageMask,
827 const VkPipelineStageFlags dstStageMask,
828 const VkAccessFlags srcAccessMask,
829 const VkAccessFlags dstAccessMask,
830 const VkImageLayout oldLayout,
831 const VkImageLayout newLayout,
832 const VkSampleLocationsInfoEXT* pSampleLocationsInfo = DE_NULL)
834 const VkImageMemoryBarrier barrier =
836 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
837 pSampleLocationsInfo, // const void* pNext;
838 srcAccessMask, // VkAccessFlags srcAccessMask;
839 dstAccessMask, // VkAccessFlags dstAccessMask;
840 oldLayout, // VkImageLayout oldLayout;
841 newLayout, // VkImageLayout newLayout;
842 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
843 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
844 image, // VkImage image;
845 makeImageSubresourceRange(aspect, 0u, 1u, 0u, 1u), // VkImageSubresourceRange subresourceRange;
848 vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (VkDependencyFlags)0, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
851 void recordCopyImageToBuffer (const DeviceInterface& vk,
852 const VkCommandBuffer cmdBuffer,
853 const tcu::IVec2& imageSize,
854 const VkImage srcImage,
855 const VkBuffer dstBuffer)
857 // Resolve image -> host buffer
859 const VkBufferImageCopy region =
861 0ull, // VkDeviceSize bufferOffset;
862 0u, // uint32_t bufferRowLength;
863 0u, // uint32_t bufferImageHeight;
864 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource;
865 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
866 makeExtent3D(imageSize.x(), imageSize.y(), 1u), // VkExtent3D imageExtent;
869 vk.cmdCopyImageToBuffer(cmdBuffer, srcImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dstBuffer, 1u, ®ion);
871 // Buffer write barrier
873 const VkBufferMemoryBarrier barrier =
875 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
876 DE_NULL, // const void* pNext;
877 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
878 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
879 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
880 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
881 dstBuffer, // VkBuffer buffer;
882 0ull, // VkDeviceSize offset;
883 VK_WHOLE_SIZE, // VkDeviceSize size;
886 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
887 0u, DE_NULL, 1u, &barrier, DE_NULL, 0u);
891 Move<VkBuffer> createBufferAndBindMemory (Context& context, VkDeviceSize size, VkBufferUsageFlags usage, de::MovePtr<Allocation>* pAlloc)
893 const DeviceInterface& vk = context.getDeviceInterface();
894 const VkDevice vkDevice = context.getDevice();
895 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
897 const VkBufferCreateInfo vertexBufferParams =
899 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
900 DE_NULL, // const void* pNext;
901 0u, // VkBufferCreateFlags flags;
902 size, // VkDeviceSize size;
903 usage, // VkBufferUsageFlags usage;
904 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
905 1u, // deUint32 queueFamilyCount;
906 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
909 Move<VkBuffer> vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
911 *pAlloc = context.getDefaultAllocator().allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible);
912 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, (*pAlloc)->getMemory(), (*pAlloc)->getOffset()));
917 deInt32 getMaxIOComponents(deBool input, VkShaderStageFlags stage, VkPhysicalDeviceProperties properties)
922 case VK_SHADER_STAGE_VERTEX_BIT:
924 data = (properties.limits.maxVertexOutputComponents / 4) - 1; // outputData + gl_Position
927 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
929 data = properties.limits.maxTessellationEvaluationInputComponents / 4;
931 data = (properties.limits.maxTessellationEvaluationOutputComponents / 4) - 1; // outputData + gl_Position
934 case VK_SHADER_STAGE_GEOMETRY_BIT:
936 data = properties.limits.maxGeometryInputComponents / 4;
938 data = (properties.limits.maxGeometryOutputComponents / 4) - 1; // outputData + gl_Position
941 case VK_SHADER_STAGE_FRAGMENT_BIT:
943 data = (properties.limits.maxFragmentInputComponents / 4); // inputData
946 DE_FATAL("Unsupported shader");
952 tcu::TestStatus test(Context& context, const MaxVaryingsParam param)
954 const InstanceInterface& vki = context.getInstanceInterface();
955 const DeviceInterface& vk = context.getDeviceInterface();
956 const VkDevice device = context.getDevice();
957 const VkQueue queue = context.getUniversalQueue();
958 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
959 Allocator& allocator = context.getDefaultAllocator();
960 tcu::TestLog &log = context.getTestContext().getLog();
964 const tcu::IVec2 renderSize = tcu::IVec2(32, 32);
965 const VkFormat imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
966 const Image colorImage (vk, device, allocator, makeImageCreateInfo(renderSize, imageFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::Any);
967 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, imageFormat, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
968 const VkDeviceSize colorBufferSize = renderSize.x() * renderSize.y() * tcu::getPixelSize(mapVkFormat(imageFormat));
969 Move<VkBuffer> colorBuffer = vkt::pipeline::makeBuffer(vk, device, colorBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
970 MovePtr<Allocation> colorBufferAlloc = bindBuffer(vk, device, allocator, *colorBuffer, MemoryRequirement::HostVisible);
973 // Create vertex buffer
974 de::MovePtr<Allocation> vertexBufferMemory;
975 Move<VkBuffer> vertexBuffer = createBufferAndBindMemory(context, sizeof(tcu::Vec4) * 6u, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &vertexBufferMemory);
976 std::vector<tcu::Vec4> vertices;
978 vertices.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
979 vertices.push_back(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f));
980 vertices.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
981 vertices.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f));
982 vertices.push_back(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f));
983 vertices.push_back(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f));
984 // Load vertices into vertex buffer
985 deMemcpy(vertexBufferMemory->getHostPtr(), vertices.data(), vertices.size() * sizeof(tcu::Vec4));
986 flushAlloc(vk, device, *vertexBufferMemory);
990 VkPhysicalDeviceProperties properties;
991 vki.getPhysicalDeviceProperties(context.getPhysicalDevice(), &properties);
992 VkPhysicalDeviceFeatures features;
993 vki.getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
996 size_t dataSize = sizeof(data);
998 deInt32 maxOutput = getMaxIOComponents(false, param.outputStage, properties);
999 deInt32 maxInput = getMaxIOComponents(true, param.inputStage, properties);
1001 data = deMin32(maxOutput, maxInput);
1003 DE_ASSERT(data != 0u);
1005 log << tcu::TestLog::Message << "Testing " << data * 4 << " input components for stage " << getShaderStageName(param.stageToStressIO).c_str() << tcu::TestLog::EndMessage;
1007 VkSpecializationMapEntry mapEntries =
1009 0u, // deUint32 constantID;
1010 0u, // deUint32 offset;
1011 dataSize // size_t size;
1014 VkSpecializationInfo pSpecInfo =
1016 1u, // deUint32 mapEntryCount;
1017 &mapEntries, // const VkSpecializationMapEntry* pMapEntries;
1018 dataSize, // size_t dataSize;
1019 &data // const void* pData;
1024 const Unique<VkRenderPass> renderPass (makeRenderPass (vk, device, imageFormat));
1025 const Unique<VkFramebuffer> framebuffer (makeFramebuffer (vk, device, *renderPass, 1u, &colorImageView.get(), static_cast<deUint32>(renderSize.x()), static_cast<deUint32>(renderSize.y())));
1026 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device));
1027 const Unique<VkCommandPool> cmdPool (createCommandPool (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
1028 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer (vk, device, *cmdPool));
1030 vk::BinaryCollection& binaryCollection(context.getBinaryCollection());
1031 VkPrimitiveTopology topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
1032 const std::vector<VkViewport> viewport { makeViewport(renderSize) };
1033 const std::vector<VkRect2D> scissor { makeRect2D(renderSize) };
1035 Move<VkShaderModule> vertShaderModule = createShaderModule(vk, device, binaryCollection.get("vert"), 0u);
1036 Move<VkShaderModule> tescShaderModule;
1037 Move<VkShaderModule> teseShaderModule;
1038 Move<VkShaderModule> geomShaderModule;
1039 Move<VkShaderModule> fragShaderModule = createShaderModule(vk, device, binaryCollection.get("frag"), 0u);
1041 if (param.inputStage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || param.outputStage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
1042 param.inputStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT || param.outputStage == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
1044 tescShaderModule = createShaderModule(vk, device, binaryCollection.get("tcs"), 0u);
1045 teseShaderModule = createShaderModule(vk, device, binaryCollection.get("tes"), 0u);
1046 topology = VK_PRIMITIVE_TOPOLOGY_PATCH_LIST;
1048 if (param.inputStage == VK_SHADER_STAGE_GEOMETRY_BIT || param.outputStage == VK_SHADER_STAGE_GEOMETRY_BIT)
1049 geomShaderModule = createShaderModule(vk, device, binaryCollection.get("geom"), 0u);
1051 GraphicsPipelineWrapper graphicsPipeline(vk, device, param.pipelineConstructionType);
1052 graphicsPipeline.setDefaultTopology(topology)
1053 .setDefaultRasterizationState()
1054 .setDefaultDepthStencilState()
1055 .setDefaultMultisampleState()
1056 .setDefaultColorBlendState()
1057 .setupVertexInputStete()
1058 .setupPreRasterizationShaderState(viewport,
1069 .setupFragmentShaderState(*pipelineLayout, *renderPass, 0u, *fragShaderModule, DE_NULL, DE_NULL, DE_NULL, &pSpecInfo)
1070 .setupFragmentOutputState(*renderPass)
1071 .setMonolithicPipelineLayout(*pipelineLayout)
1076 const VkRect2D renderArea = makeRect2D(renderSize);
1077 const tcu::Vec4 clearColor (0.0f, 0.0f, 0.0f, 1.0f);
1079 beginCommandBuffer(vk, *cmdBuffer);
1082 const VkImageSubresourceRange imageFullSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1083 const VkImageMemoryBarrier barrierColorAttachmentSetInitialLayout = makeImageMemoryBarrier(
1084 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1085 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1086 *colorImage, imageFullSubresourceRange);
1088 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u,
1089 0u, DE_NULL, 0u, DE_NULL, 1u, &barrierColorAttachmentSetInitialLayout);
1092 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
1094 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.getPipeline());
1095 const VkDeviceSize vertexBufferOffset = 0ull;
1096 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
1099 vk.cmdDraw(*cmdBuffer, (deUint32)vertices.size(), 1u, 0u, 0u);
1100 endRenderPass(vk, *cmdBuffer);
1101 // Resolve image -> host buffer
1102 recordImageBarrier(vk, *cmdBuffer, *colorImage,
1103 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect,
1104 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask,
1105 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask,
1106 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask,
1107 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask,
1108 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout,
1109 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); // VkImageLayout newLayout)
1111 recordCopyImageToBuffer(vk, *cmdBuffer, renderSize, *colorImage, *colorBuffer);
1112 endCommandBuffer(vk, *cmdBuffer);
1113 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
1117 invalidateAlloc(vk, device, *colorBufferAlloc);
1119 const tcu::ConstPixelBufferAccess resultImage (mapVkFormat(imageFormat), renderSize.x(), renderSize.y(), 1u, colorBufferAlloc->getHostPtr());
1120 tcu::TextureLevel referenceImage (mapVkFormat(imageFormat), renderSize.x(), renderSize.y());
1121 tcu::clear(referenceImage.getAccess(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f));
1123 if (!tcu::floatThresholdCompare(log, "Compare", "Result comparison", referenceImage.getAccess(), resultImage, tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT))
1124 TCU_FAIL("Rendered image is not correct");
1126 return tcu::TestStatus::pass("OK");
1130 tcu::TestCaseGroup* createMaxVaryingsTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
1132 std::vector<MaxVaryingsParam> tests
1134 { pipelineConstructionType, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_VERTEX_BIT }, // Test max vertex outputs: VS-FS
1135 { pipelineConstructionType, VK_SHADER_STAGE_VERTEX_BIT, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_FRAGMENT_BIT }, // Test max FS inputs: VS-FS
1136 { pipelineConstructionType, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT }, // Test max tess evaluation outputs: VS-TCS-TES-FS
1137 { pipelineConstructionType, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_FRAGMENT_BIT }, // Test fragment inputs: VS-TCS-TES-FS
1138 { pipelineConstructionType, VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_GEOMETRY_BIT }, // Test geometry outputs: VS-GS-FS
1139 { pipelineConstructionType, VK_SHADER_STAGE_GEOMETRY_BIT, VK_SHADER_STAGE_FRAGMENT_BIT, VK_SHADER_STAGE_FRAGMENT_BIT }, // Test fragment inputs: VS-GS-FS
1142 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "max_varyings", "Max Varyings tests"));
1144 for (const auto& testParams : tests)
1146 addFunctionCaseWithPrograms(group.get(), generateTestName(testParams), generateTestDescription(),
1147 supportedCheck, initPrograms, test, testParams);
1150 return group.release();