1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 Google Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Graphics pipeline for SPIR-V assembly tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
26 #include "tcuFloat.hpp"
27 #include "tcuStringTemplate.hpp"
30 #include "vkMemUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkRefUtil.hpp"
34 #include "vkTypeUtil.hpp"
36 #include "deRandom.hpp"
40 namespace SpirVAssembly
53 using tcu::TestStatus;
56 using tcu::StringTemplate;
59 deUint32 IFDataType::getElementNumBytes (void) const
61 if (elementType < NUMBERTYPE_END32)
67 VkFormat IFDataType::getVkFormat (void) const
73 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32_SFLOAT;
74 case NUMBERTYPE_INT32: return VK_FORMAT_R32_SINT;
75 case NUMBERTYPE_UINT32: return VK_FORMAT_R32_UINT;
76 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16_SFLOAT;
77 case NUMBERTYPE_INT16: return VK_FORMAT_R16_SINT;
78 case NUMBERTYPE_UINT16: return VK_FORMAT_R16_UINT;
82 else if (numElements == 2)
86 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32_SFLOAT;
87 case NUMBERTYPE_INT32: return VK_FORMAT_R32G32_SINT;
88 case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32_UINT;
89 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16_SFLOAT;
90 case NUMBERTYPE_INT16: return VK_FORMAT_R16G16_SINT;
91 case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16_UINT;
95 else if (numElements == 3)
99 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32B32_SFLOAT;
100 case NUMBERTYPE_INT32: return VK_FORMAT_R32G32B32_SINT;
101 case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32B32_UINT;
102 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16B16_SFLOAT;
103 case NUMBERTYPE_INT16: return VK_FORMAT_R16G16B16_SINT;
104 case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16B16_UINT;
108 else if (numElements == 4)
112 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32B32A32_SFLOAT;
113 case NUMBERTYPE_INT32: return VK_FORMAT_R32G32B32A32_SINT;
114 case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32B32A32_UINT;
115 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16B16A16_SFLOAT;
116 case NUMBERTYPE_INT16: return VK_FORMAT_R16G16B16A16_SINT;
117 case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16B16A16_UINT;
123 return VK_FORMAT_UNDEFINED;
126 tcu::TextureFormat IFDataType::getTextureFormat (void) const
128 tcu::TextureFormat::ChannelType ct = tcu::TextureFormat::CHANNELTYPE_LAST;
129 tcu::TextureFormat::ChannelOrder co = tcu::TextureFormat::CHANNELORDER_LAST;
133 case NUMBERTYPE_FLOAT32: ct = tcu::TextureFormat::FLOAT; break;
134 case NUMBERTYPE_INT32: ct = tcu::TextureFormat::SIGNED_INT32; break;
135 case NUMBERTYPE_UINT32: ct = tcu::TextureFormat::UNSIGNED_INT32; break;
136 case NUMBERTYPE_FLOAT16: ct = tcu::TextureFormat::HALF_FLOAT; break;
137 case NUMBERTYPE_INT16: ct = tcu::TextureFormat::SIGNED_INT16; break;
138 case NUMBERTYPE_UINT16: ct = tcu::TextureFormat::UNSIGNED_INT16; break;
139 default: DE_ASSERT(false);
144 case 1: co = tcu::TextureFormat::R; break;
145 case 2: co = tcu::TextureFormat::RG; break;
146 case 3: co = tcu::TextureFormat::RGB; break;
147 case 4: co = tcu::TextureFormat::RGBA; break;
148 default: DE_ASSERT(false);
151 return tcu::TextureFormat(co, ct);
154 string IFDataType::str (void) const
160 case NUMBERTYPE_FLOAT32: ret = "f32"; break;
161 case NUMBERTYPE_INT32: ret = "i32"; break;
162 case NUMBERTYPE_UINT32: ret = "u32"; break;
163 case NUMBERTYPE_FLOAT16: ret = "f16"; break;
164 case NUMBERTYPE_INT16: ret = "i16"; break;
165 case NUMBERTYPE_UINT16: ret = "u16"; break;
166 default: DE_ASSERT(false);
169 if (numElements == 1)
172 return string("v") + numberToString(numElements) + ret;
175 VkBufferUsageFlagBits getMatchingBufferUsageFlagBit(VkDescriptorType dType)
179 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
180 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
181 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
182 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
183 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
184 default: DE_ASSERT(0 && "not implemented");
186 return (VkBufferUsageFlagBits)0;
189 VkImageUsageFlags getMatchingImageUsageFlags(VkDescriptorType dType)
193 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
194 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
195 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
196 default: DE_FATAL("Not implemented");
198 return (VkImageUsageFlags)0;
201 static void requireFormatUsageSupport(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling imageTiling, VkImageUsageFlags requiredUsageFlags)
203 VkFormatProperties properties;
204 VkFormatFeatureFlags tilingFeatures = 0;
206 vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
210 case VK_IMAGE_TILING_LINEAR:
211 tilingFeatures = properties.linearTilingFeatures;
214 case VK_IMAGE_TILING_OPTIMAL:
215 tilingFeatures = properties.optimalTilingFeatures;
223 if ((requiredUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
225 if ((tilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
226 TCU_THROW(NotSupportedError, "Image format cannot be used as color attachment");
227 requiredUsageFlags ^= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
231 if ((requiredUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0)
233 if ((tilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) == 0)
234 TCU_THROW(NotSupportedError, "Image format cannot be used as transfer source");
235 requiredUsageFlags ^= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
239 DE_ASSERT(!requiredUsageFlags && "checking other image usage bits not supported yet");
242 InstanceContext::InstanceContext (const RGBA (&inputs)[4],
243 const RGBA (&outputs)[4],
244 const map<string, string>& testCodeFragments_,
245 const StageToSpecConstantMap& specConstants_,
246 const PushConstants& pushConsants_,
247 const GraphicsResources& resources_,
248 const GraphicsInterfaces& interfaces_,
249 const vector<string>& extensions_,
250 const vector<string>& features_,
251 VulkanFeatures vulkanFeatures_,
252 VkShaderStageFlags customizedStages_)
253 : testCodeFragments (testCodeFragments_)
254 , specConstants (specConstants_)
255 , hasTessellation (false)
256 , requiredStages (static_cast<VkShaderStageFlagBits>(0))
257 , requiredDeviceExtensions (extensions_)
258 , requiredDeviceFeatures (features_)
259 , requestedFeatures (vulkanFeatures_)
260 , pushConstants (pushConsants_)
261 , customizedStages (customizedStages_)
262 , resources (resources_)
263 , interfaces (interfaces_)
264 , failResult (QP_TEST_RESULT_FAIL)
265 , failMessageTemplate ("${reason}")
267 inputColors[0] = inputs[0];
268 inputColors[1] = inputs[1];
269 inputColors[2] = inputs[2];
270 inputColors[3] = inputs[3];
272 outputColors[0] = outputs[0];
273 outputColors[1] = outputs[1];
274 outputColors[2] = outputs[2];
275 outputColors[3] = outputs[3];
278 InstanceContext::InstanceContext (const InstanceContext& other)
279 : moduleMap (other.moduleMap)
280 , testCodeFragments (other.testCodeFragments)
281 , specConstants (other.specConstants)
282 , hasTessellation (other.hasTessellation)
283 , requiredStages (other.requiredStages)
284 , requiredDeviceExtensions (other.requiredDeviceExtensions)
285 , requiredDeviceFeatures (other.requiredDeviceFeatures)
286 , requestedFeatures (other.requestedFeatures)
287 , pushConstants (other.pushConstants)
288 , customizedStages (other.customizedStages)
289 , resources (other.resources)
290 , interfaces (other.interfaces)
291 , failResult (other.failResult)
292 , failMessageTemplate (other.failMessageTemplate)
294 inputColors[0] = other.inputColors[0];
295 inputColors[1] = other.inputColors[1];
296 inputColors[2] = other.inputColors[2];
297 inputColors[3] = other.inputColors[3];
299 outputColors[0] = other.outputColors[0];
300 outputColors[1] = other.outputColors[1];
301 outputColors[2] = other.outputColors[2];
302 outputColors[3] = other.outputColors[3];
305 string InstanceContext::getSpecializedFailMessage (const string& failureReason)
307 map<string, string> parameters;
308 parameters["reason"] = failureReason;
309 return StringTemplate(failMessageTemplate).specialize(parameters);
312 ShaderElement::ShaderElement (const string& moduleName_,
313 const string& entryPoint_,
314 VkShaderStageFlagBits shaderStage_)
315 : moduleName(moduleName_)
316 , entryName(entryPoint_)
317 , stage(shaderStage_)
321 void getDefaultColors (RGBA (&colors)[4])
323 colors[0] = RGBA::white();
324 colors[1] = RGBA::red();
325 colors[2] = RGBA::green();
326 colors[3] = RGBA::blue();
329 void getHalfColorsFullAlpha (RGBA (&colors)[4])
331 colors[0] = RGBA(127, 127, 127, 255);
332 colors[1] = RGBA(127, 0, 0, 255);
333 colors[2] = RGBA(0, 127, 0, 255);
334 colors[3] = RGBA(0, 0, 127, 255);
337 void getInvertedDefaultColors (RGBA (&colors)[4])
339 colors[0] = RGBA(0, 0, 0, 255);
340 colors[1] = RGBA(0, 255, 255, 255);
341 colors[2] = RGBA(255, 0, 255, 255);
342 colors[3] = RGBA(255, 255, 0, 255);
345 // For the current InstanceContext, constructs the required modules and shader stage create infos.
346 void createPipelineShaderStages (const DeviceInterface& vk,
347 const VkDevice vkDevice,
348 InstanceContext& instance,
350 vector<ModuleHandleSp>& modules,
351 vector<VkPipelineShaderStageCreateInfo>& createInfos)
353 for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx)
355 const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0)));
356 modules.push_back(ModuleHandleSp(mod));
357 for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx)
359 const EntryToStage& stage = *shaderNdx;
360 const VkPipelineShaderStageCreateInfo shaderParam =
362 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
363 DE_NULL, // const void* pNext;
364 (VkPipelineShaderStageCreateFlags)0,
365 stage.second, // VkShaderStageFlagBits stage;
366 **modules.back(), // VkShaderModule module;
367 stage.first.c_str(), // const char* pName;
368 (const VkSpecializationInfo*)DE_NULL,
370 createInfos.push_back(shaderParam);
375 #define SPIRV_ASSEMBLY_TYPES \
376 "%void = OpTypeVoid\n" \
377 "%bool = OpTypeBool\n" \
379 "%i32 = OpTypeInt 32 1\n" \
380 "%u32 = OpTypeInt 32 0\n" \
382 "%f32 = OpTypeFloat 32\n" \
383 "%v2i32 = OpTypeVector %i32 2\n" \
384 "%v2u32 = OpTypeVector %u32 2\n" \
385 "%v2f32 = OpTypeVector %f32 2\n" \
386 "%v3f32 = OpTypeVector %f32 3\n" \
387 "%v4i32 = OpTypeVector %i32 4\n" \
388 "%v4u32 = OpTypeVector %u32 4\n" \
389 "%v4f32 = OpTypeVector %f32 4\n" \
390 "%v4bool = OpTypeVector %bool 4\n" \
392 "%v4f32_function = OpTypeFunction %v4f32 %v4f32\n" \
393 "%bool_function = OpTypeFunction %bool\n" \
394 "%fun = OpTypeFunction %void\n" \
396 "%ip_f32 = OpTypePointer Input %f32\n" \
397 "%ip_i32 = OpTypePointer Input %i32\n" \
398 "%ip_u32 = OpTypePointer Input %u32\n" \
399 "%ip_v3f32 = OpTypePointer Input %v3f32\n" \
400 "%ip_v2f32 = OpTypePointer Input %v2f32\n" \
401 "%ip_v2i32 = OpTypePointer Input %v2i32\n" \
402 "%ip_v2u32 = OpTypePointer Input %v2u32\n" \
403 "%ip_v4f32 = OpTypePointer Input %v4f32\n" \
404 "%ip_v4i32 = OpTypePointer Input %v4i32\n" \
405 "%ip_v4u32 = OpTypePointer Input %v4u32\n" \
407 "%op_f32 = OpTypePointer Output %f32\n" \
408 "%op_i32 = OpTypePointer Output %i32\n" \
409 "%op_u32 = OpTypePointer Output %u32\n" \
410 "%op_v2f32 = OpTypePointer Output %v2f32\n" \
411 "%op_v2i32 = OpTypePointer Output %v2i32\n" \
412 "%op_v2u32 = OpTypePointer Output %v2u32\n" \
413 "%op_v4f32 = OpTypePointer Output %v4f32\n" \
414 "%op_v4i32 = OpTypePointer Output %v4i32\n" \
415 "%op_v4u32 = OpTypePointer Output %v4u32\n" \
417 "%fp_f32 = OpTypePointer Function %f32\n" \
418 "%fp_i32 = OpTypePointer Function %i32\n" \
419 "%fp_v4f32 = OpTypePointer Function %v4f32\n"
421 #define SPIRV_ASSEMBLY_CONSTANTS \
422 "%c_f32_1 = OpConstant %f32 1.0\n" \
423 "%c_f32_0 = OpConstant %f32 0.0\n" \
424 "%c_f32_0_5 = OpConstant %f32 0.5\n" \
425 "%c_f32_n1 = OpConstant %f32 -1.\n" \
426 "%c_f32_7 = OpConstant %f32 7.0\n" \
427 "%c_f32_8 = OpConstant %f32 8.0\n" \
428 "%c_i32_0 = OpConstant %i32 0\n" \
429 "%c_i32_1 = OpConstant %i32 1\n" \
430 "%c_i32_2 = OpConstant %i32 2\n" \
431 "%c_i32_3 = OpConstant %i32 3\n" \
432 "%c_i32_4 = OpConstant %i32 4\n" \
433 "%c_u32_0 = OpConstant %u32 0\n" \
434 "%c_u32_1 = OpConstant %u32 1\n" \
435 "%c_u32_2 = OpConstant %u32 2\n" \
436 "%c_u32_3 = OpConstant %u32 3\n" \
437 "%c_u32_32 = OpConstant %u32 32\n" \
438 "%c_u32_4 = OpConstant %u32 4\n" \
439 "%c_u32_31_bits = OpConstant %u32 0x7FFFFFFF\n" \
440 "%c_v4f32_1_1_1_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_1\n" \
441 "%c_v4f32_1_0_0_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_0 %c_f32_0 %c_f32_1\n" \
442 "%c_v4f32_0_5_0_5_0_5_0_5 = OpConstantComposite %v4f32 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5\n"
444 #define SPIRV_ASSEMBLY_ARRAYS \
445 "%a1f32 = OpTypeArray %f32 %c_u32_1\n" \
446 "%a2f32 = OpTypeArray %f32 %c_u32_2\n" \
447 "%a3v4f32 = OpTypeArray %v4f32 %c_u32_3\n" \
448 "%a4f32 = OpTypeArray %f32 %c_u32_4\n" \
449 "%a32v4f32 = OpTypeArray %v4f32 %c_u32_32\n" \
450 "%ip_a3v4f32 = OpTypePointer Input %a3v4f32\n" \
451 "%ip_a32v4f32 = OpTypePointer Input %a32v4f32\n" \
452 "%op_a2f32 = OpTypePointer Output %a2f32\n" \
453 "%op_a3v4f32 = OpTypePointer Output %a3v4f32\n" \
454 "%op_a4f32 = OpTypePointer Output %a4f32\n"
456 // Creates vertex-shader assembly by specializing a boilerplate StringTemplate
457 // on fragments, which must (at least) map "testfun" to an OpFunction definition
458 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
459 // with "BP_" to avoid collisions with fragments.
461 // It corresponds roughly to this GLSL:
463 // layout(location = 0) in vec4 position;
464 // layout(location = 1) in vec4 color;
465 // layout(location = 1) out highp vec4 vtxColor;
466 // void main (void) { gl_Position = position; vtxColor = test_func(color); }
467 string makeVertexShaderAssembly(const map<string, string>& fragments)
469 // \todo [2015-11-23 awoloszyn] Remove OpName once these have stabalized
470 static const char vertexShaderBoilerplate[] =
471 "OpCapability Shader\n"
472 "OpCapability ClipDistance\n"
473 "OpCapability CullDistance\n"
474 "${capability:opt}\n"
476 "OpMemoryModel Logical GLSL450\n"
477 "OpEntryPoint Vertex %main \"main\" %BP_stream %BP_position %BP_vtx_color %BP_color %BP_gl_VertexIndex %BP_gl_InstanceIndex ${IF_entrypoint:opt} \n"
479 "OpName %main \"main\"\n"
480 "OpName %BP_gl_PerVertex \"gl_PerVertex\"\n"
481 "OpMemberName %BP_gl_PerVertex 0 \"gl_Position\"\n"
482 "OpMemberName %BP_gl_PerVertex 1 \"gl_PointSize\"\n"
483 "OpMemberName %BP_gl_PerVertex 2 \"gl_ClipDistance\"\n"
484 "OpMemberName %BP_gl_PerVertex 3 \"gl_CullDistance\"\n"
485 "OpName %test_code \"testfun(vf4;\"\n"
486 "OpName %BP_stream \"\"\n"
487 "OpName %BP_position \"position\"\n"
488 "OpName %BP_vtx_color \"vtxColor\"\n"
489 "OpName %BP_color \"color\"\n"
490 "OpName %BP_gl_VertexIndex \"gl_VertexIndex\"\n"
491 "OpName %BP_gl_InstanceIndex \"gl_InstanceIndex\"\n"
492 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
493 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
494 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
495 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
496 "OpDecorate %BP_gl_PerVertex Block\n"
497 "OpDecorate %BP_position Location 0\n"
498 "OpDecorate %BP_vtx_color Location 1\n"
499 "OpDecorate %BP_color Location 1\n"
500 "OpDecorate %BP_gl_VertexIndex BuiltIn VertexIndex\n"
501 "OpDecorate %BP_gl_InstanceIndex BuiltIn InstanceIndex\n"
502 "${IF_decoration:opt}\n"
503 "${decoration:opt}\n"
505 SPIRV_ASSEMBLY_CONSTANTS
506 SPIRV_ASSEMBLY_ARRAYS
507 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
508 "%BP_op_gl_PerVertex = OpTypePointer Output %BP_gl_PerVertex\n"
509 "%BP_stream = OpVariable %BP_op_gl_PerVertex Output\n"
510 "%BP_position = OpVariable %ip_v4f32 Input\n"
511 "%BP_vtx_color = OpVariable %op_v4f32 Output\n"
512 "%BP_color = OpVariable %ip_v4f32 Input\n"
513 "%BP_gl_VertexIndex = OpVariable %ip_i32 Input\n"
514 "%BP_gl_InstanceIndex = OpVariable %ip_i32 Input\n"
516 "${IF_variable:opt}\n"
517 "%main = OpFunction %void None %fun\n"
518 "%BP_label = OpLabel\n"
519 "${IF_carryforward:opt}\n"
520 "%BP_pos = OpLoad %v4f32 %BP_position\n"
521 "%BP_gl_pos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
522 "OpStore %BP_gl_pos %BP_pos\n"
523 "%BP_col = OpLoad %v4f32 %BP_color\n"
524 "%BP_col_transformed = OpFunctionCall %v4f32 %test_code %BP_col\n"
525 "OpStore %BP_vtx_color %BP_col_transformed\n"
528 "${interface_op_func:opt}\n"
530 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
531 "%getId_label = OpLabel\n"
532 "%vert_id = OpLoad %i32 %BP_gl_VertexIndex\n"
533 "%is_id_0 = OpIEqual %bool %vert_id %c_i32_0\n"
534 "OpReturnValue %is_id_0\n"
538 return tcu::StringTemplate(vertexShaderBoilerplate).specialize(fragments);
541 // Creates tess-control-shader assembly by specializing a boilerplate
542 // StringTemplate on fragments, which must (at least) map "testfun" to an
543 // OpFunction definition for %test_code that takes and returns a %v4f32.
544 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
546 // It roughly corresponds to the following GLSL.
549 // layout(vertices = 3) out;
550 // layout(location = 1) in vec4 in_color[];
551 // layout(location = 1) out vec4 out_color[];
554 // out_color[gl_InvocationID] = testfun(in_color[gl_InvocationID]);
555 // gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
556 // if (gl_InvocationID == 0) {
557 // gl_TessLevelOuter[0] = 1.0;
558 // gl_TessLevelOuter[1] = 1.0;
559 // gl_TessLevelOuter[2] = 1.0;
560 // gl_TessLevelInner[0] = 1.0;
563 string makeTessControlShaderAssembly (const map<string, string>& fragments)
565 static const char tessControlShaderBoilerplate[] =
566 "OpCapability Tessellation\n"
567 "OpCapability ClipDistance\n"
568 "OpCapability CullDistance\n"
569 "${capability:opt}\n"
571 "OpMemoryModel Logical GLSL450\n"
572 "OpEntryPoint TessellationControl %BP_main \"main\" %BP_out_color %BP_gl_InvocationID %BP_gl_PrimitiveID %BP_in_color %BP_gl_out %BP_gl_in %BP_gl_TessLevelOuter %BP_gl_TessLevelInner ${IF_entrypoint:opt} \n"
573 "OpExecutionMode %BP_main OutputVertices 3\n"
575 "OpName %BP_main \"main\"\n"
576 "OpName %test_code \"testfun(vf4;\"\n"
577 "OpName %BP_out_color \"out_color\"\n"
578 "OpName %BP_gl_InvocationID \"gl_InvocationID\"\n"
579 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
580 "OpName %BP_in_color \"in_color\"\n"
581 "OpName %BP_gl_PerVertex \"gl_PerVertex\"\n"
582 "OpMemberName %BP_gl_PerVertex 0 \"gl_Position\"\n"
583 "OpMemberName %BP_gl_PerVertex 1 \"gl_PointSize\"\n"
584 "OpMemberName %BP_gl_PerVertex 2 \"gl_ClipDistance\"\n"
585 "OpMemberName %BP_gl_PerVertex 3 \"gl_CullDistance\"\n"
586 "OpName %BP_gl_out \"gl_out\"\n"
587 "OpName %BP_gl_PVOut \"gl_PerVertex\"\n"
588 "OpMemberName %BP_gl_PVOut 0 \"gl_Position\"\n"
589 "OpMemberName %BP_gl_PVOut 1 \"gl_PointSize\"\n"
590 "OpMemberName %BP_gl_PVOut 2 \"gl_ClipDistance\"\n"
591 "OpMemberName %BP_gl_PVOut 3 \"gl_CullDistance\"\n"
592 "OpName %BP_gl_in \"gl_in\"\n"
593 "OpName %BP_gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
594 "OpName %BP_gl_TessLevelInner \"gl_TessLevelInner\"\n"
595 "OpDecorate %BP_out_color Location 1\n"
596 "OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n"
597 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
598 "OpDecorate %BP_in_color Location 1\n"
599 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
600 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
601 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
602 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
603 "OpDecorate %BP_gl_PerVertex Block\n"
604 "OpMemberDecorate %BP_gl_PVOut 0 BuiltIn Position\n"
605 "OpMemberDecorate %BP_gl_PVOut 1 BuiltIn PointSize\n"
606 "OpMemberDecorate %BP_gl_PVOut 2 BuiltIn ClipDistance\n"
607 "OpMemberDecorate %BP_gl_PVOut 3 BuiltIn CullDistance\n"
608 "OpDecorate %BP_gl_PVOut Block\n"
609 "OpDecorate %BP_gl_TessLevelOuter Patch\n"
610 "OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
611 "OpDecorate %BP_gl_TessLevelInner Patch\n"
612 "OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n"
613 "${IF_decoration:opt}\n"
614 "${decoration:opt}\n"
616 SPIRV_ASSEMBLY_CONSTANTS
617 SPIRV_ASSEMBLY_ARRAYS
618 "%BP_out_color = OpVariable %op_a3v4f32 Output\n"
619 "%BP_gl_InvocationID = OpVariable %ip_i32 Input\n"
620 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
621 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
622 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
623 "%BP_a3_gl_PerVertex = OpTypeArray %BP_gl_PerVertex %c_u32_3\n"
624 "%BP_op_a3_gl_PerVertex = OpTypePointer Output %BP_a3_gl_PerVertex\n"
625 "%BP_gl_out = OpVariable %BP_op_a3_gl_PerVertex Output\n"
626 "%BP_gl_PVOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
627 "%BP_a32_gl_PVOut = OpTypeArray %BP_gl_PVOut %c_u32_32\n"
628 "%BP_ip_a32_gl_PVOut = OpTypePointer Input %BP_a32_gl_PVOut\n"
629 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PVOut Input\n"
630 "%BP_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
631 "%BP_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
633 "${IF_variable:opt}\n"
635 "%BP_main = OpFunction %void None %fun\n"
636 "%BP_label = OpLabel\n"
637 "%BP_gl_Invoc = OpLoad %i32 %BP_gl_InvocationID\n"
638 "${IF_carryforward:opt}\n"
639 "%BP_in_col_loc = OpAccessChain %ip_v4f32 %BP_in_color %BP_gl_Invoc\n"
640 "%BP_out_col_loc = OpAccessChain %op_v4f32 %BP_out_color %BP_gl_Invoc\n"
641 "%BP_in_col_val = OpLoad %v4f32 %BP_in_col_loc\n"
642 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_in_col_val\n"
643 "OpStore %BP_out_col_loc %BP_clr_transformed\n"
645 "%BP_in_pos_loc = OpAccessChain %ip_v4f32 %BP_gl_in %BP_gl_Invoc %c_i32_0\n"
646 "%BP_out_pos_loc = OpAccessChain %op_v4f32 %BP_gl_out %BP_gl_Invoc %c_i32_0\n"
647 "%BP_in_pos_val = OpLoad %v4f32 %BP_in_pos_loc\n"
648 "OpStore %BP_out_pos_loc %BP_in_pos_val\n"
650 "%BP_cmp = OpIEqual %bool %BP_gl_Invoc %c_i32_0\n"
651 "OpSelectionMerge %BP_merge_label None\n"
652 "OpBranchConditional %BP_cmp %BP_if_label %BP_merge_label\n"
653 "%BP_if_label = OpLabel\n"
654 "%BP_gl_TessLevelOuterPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_0\n"
655 "%BP_gl_TessLevelOuterPos_1 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_1\n"
656 "%BP_gl_TessLevelOuterPos_2 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_2\n"
657 "%BP_gl_TessLevelInnerPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelInner %c_i32_0\n"
658 "OpStore %BP_gl_TessLevelOuterPos_0 %c_f32_1\n"
659 "OpStore %BP_gl_TessLevelOuterPos_1 %c_f32_1\n"
660 "OpStore %BP_gl_TessLevelOuterPos_2 %c_f32_1\n"
661 "OpStore %BP_gl_TessLevelInnerPos_0 %c_f32_1\n"
662 "OpBranch %BP_merge_label\n"
663 "%BP_merge_label = OpLabel\n"
666 "${interface_op_func:opt}\n"
668 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
669 "%getId_label = OpLabel\n"
670 "%invocation_id = OpLoad %i32 %BP_gl_InvocationID\n"
671 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
672 "%is_invocation_0 = OpIEqual %bool %invocation_id %c_i32_0\n"
673 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
674 "%is_id_0 = OpLogicalAnd %bool %is_invocation_0 %is_primitive_0\n"
675 "OpReturnValue %is_id_0\n"
679 return tcu::StringTemplate(tessControlShaderBoilerplate).specialize(fragments);
682 // Creates tess-evaluation-shader assembly by specializing a boilerplate
683 // StringTemplate on fragments, which must (at least) map "testfun" to an
684 // OpFunction definition for %test_code that takes and returns a %v4f32.
685 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
687 // It roughly corresponds to the following glsl.
691 // layout(triangles, equal_spacing, ccw) in;
692 // layout(location = 1) in vec4 in_color[];
693 // layout(location = 1) out vec4 out_color;
695 // #define interpolate(val)
696 // vec4(gl_TessCoord.x) * val[0] + vec4(gl_TessCoord.y) * val[1] +
697 // vec4(gl_TessCoord.z) * val[2]
700 // gl_Position = vec4(gl_TessCoord.x) * gl_in[0].gl_Position +
701 // vec4(gl_TessCoord.y) * gl_in[1].gl_Position +
702 // vec4(gl_TessCoord.z) * gl_in[2].gl_Position;
703 // out_color = testfun(interpolate(in_color));
705 string makeTessEvalShaderAssembly(const map<string, string>& fragments)
707 static const char tessEvalBoilerplate[] =
708 "OpCapability Tessellation\n"
709 "OpCapability ClipDistance\n"
710 "OpCapability CullDistance\n"
711 "${capability:opt}\n"
713 "OpMemoryModel Logical GLSL450\n"
714 "OpEntryPoint TessellationEvaluation %BP_main \"main\" %BP_stream %BP_gl_TessCoord %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} \n"
715 "OpExecutionMode %BP_main Triangles\n"
716 "OpExecutionMode %BP_main SpacingEqual\n"
717 "OpExecutionMode %BP_main VertexOrderCcw\n"
719 "OpName %BP_main \"main\"\n"
720 "OpName %test_code \"testfun(vf4;\"\n"
721 "OpName %BP_gl_PerVertexOut \"gl_PerVertex\"\n"
722 "OpMemberName %BP_gl_PerVertexOut 0 \"gl_Position\"\n"
723 "OpMemberName %BP_gl_PerVertexOut 1 \"gl_PointSize\"\n"
724 "OpMemberName %BP_gl_PerVertexOut 2 \"gl_ClipDistance\"\n"
725 "OpMemberName %BP_gl_PerVertexOut 3 \"gl_CullDistance\"\n"
726 "OpName %BP_stream \"\"\n"
727 "OpName %BP_gl_TessCoord \"gl_TessCoord\"\n"
728 "OpName %BP_gl_PerVertexIn \"gl_PerVertex\"\n"
729 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
730 "OpMemberName %BP_gl_PerVertexIn 0 \"gl_Position\"\n"
731 "OpMemberName %BP_gl_PerVertexIn 1 \"gl_PointSize\"\n"
732 "OpMemberName %BP_gl_PerVertexIn 2 \"gl_ClipDistance\"\n"
733 "OpMemberName %BP_gl_PerVertexIn 3 \"gl_CullDistance\"\n"
734 "OpName %BP_gl_in \"gl_in\"\n"
735 "OpName %BP_out_color \"out_color\"\n"
736 "OpName %BP_in_color \"in_color\"\n"
737 "OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n"
738 "OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n"
739 "OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n"
740 "OpMemberDecorate %BP_gl_PerVertexOut 3 BuiltIn CullDistance\n"
741 "OpDecorate %BP_gl_PerVertexOut Block\n"
742 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
743 "OpDecorate %BP_gl_TessCoord BuiltIn TessCoord\n"
744 "OpMemberDecorate %BP_gl_PerVertexIn 0 BuiltIn Position\n"
745 "OpMemberDecorate %BP_gl_PerVertexIn 1 BuiltIn PointSize\n"
746 "OpMemberDecorate %BP_gl_PerVertexIn 2 BuiltIn ClipDistance\n"
747 "OpMemberDecorate %BP_gl_PerVertexIn 3 BuiltIn CullDistance\n"
748 "OpDecorate %BP_gl_PerVertexIn Block\n"
749 "OpDecorate %BP_out_color Location 1\n"
750 "OpDecorate %BP_in_color Location 1\n"
751 "${IF_decoration:opt}\n"
752 "${decoration:opt}\n"
754 SPIRV_ASSEMBLY_CONSTANTS
755 SPIRV_ASSEMBLY_ARRAYS
756 "%BP_gl_PerVertexOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
757 "%BP_op_gl_PerVertexOut = OpTypePointer Output %BP_gl_PerVertexOut\n"
758 "%BP_stream = OpVariable %BP_op_gl_PerVertexOut Output\n"
759 "%BP_gl_TessCoord = OpVariable %ip_v3f32 Input\n"
760 "%BP_gl_PrimitiveID = OpVariable %op_i32 Input\n"
761 "%BP_gl_PerVertexIn = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
762 "%BP_a32_gl_PerVertexIn = OpTypeArray %BP_gl_PerVertexIn %c_u32_32\n"
763 "%BP_ip_a32_gl_PerVertexIn = OpTypePointer Input %BP_a32_gl_PerVertexIn\n"
764 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PerVertexIn Input\n"
765 "%BP_out_color = OpVariable %op_v4f32 Output\n"
766 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
768 "${IF_variable:opt}\n"
769 "%BP_main = OpFunction %void None %fun\n"
770 "%BP_label = OpLabel\n"
771 "${IF_carryforward:opt}\n"
772 "%BP_gl_TC_0 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
773 "%BP_gl_TC_1 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
774 "%BP_gl_TC_2 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
775 "%BP_gl_in_gl_Pos_0 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
776 "%BP_gl_in_gl_Pos_1 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
777 "%BP_gl_in_gl_Pos_2 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
779 "%BP_gl_OPos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
780 "%BP_in_color_0 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
781 "%BP_in_color_1 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
782 "%BP_in_color_2 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
784 "%BP_TC_W_0 = OpLoad %f32 %BP_gl_TC_0\n"
785 "%BP_TC_W_1 = OpLoad %f32 %BP_gl_TC_1\n"
786 "%BP_TC_W_2 = OpLoad %f32 %BP_gl_TC_2\n"
787 "%BP_v4f32_TC_0 = OpCompositeConstruct %v4f32 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0\n"
788 "%BP_v4f32_TC_1 = OpCompositeConstruct %v4f32 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1\n"
789 "%BP_v4f32_TC_2 = OpCompositeConstruct %v4f32 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2\n"
791 "%BP_gl_IP_0 = OpLoad %v4f32 %BP_gl_in_gl_Pos_0\n"
792 "%BP_gl_IP_1 = OpLoad %v4f32 %BP_gl_in_gl_Pos_1\n"
793 "%BP_gl_IP_2 = OpLoad %v4f32 %BP_gl_in_gl_Pos_2\n"
795 "%BP_IP_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_gl_IP_0\n"
796 "%BP_IP_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_gl_IP_1\n"
797 "%BP_IP_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_gl_IP_2\n"
799 "%BP_pos_sum_0 = OpFAdd %v4f32 %BP_IP_W_0 %BP_IP_W_1\n"
800 "%BP_pos_sum_1 = OpFAdd %v4f32 %BP_pos_sum_0 %BP_IP_W_2\n"
802 "OpStore %BP_gl_OPos %BP_pos_sum_1\n"
804 "%BP_IC_0 = OpLoad %v4f32 %BP_in_color_0\n"
805 "%BP_IC_1 = OpLoad %v4f32 %BP_in_color_1\n"
806 "%BP_IC_2 = OpLoad %v4f32 %BP_in_color_2\n"
808 "%BP_IC_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_IC_0\n"
809 "%BP_IC_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_IC_1\n"
810 "%BP_IC_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_IC_2\n"
812 "%BP_col_sum_0 = OpFAdd %v4f32 %BP_IC_W_0 %BP_IC_W_1\n"
813 "%BP_col_sum_1 = OpFAdd %v4f32 %BP_col_sum_0 %BP_IC_W_2\n"
815 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_col_sum_1\n"
817 "OpStore %BP_out_color %BP_clr_transformed\n"
820 "${interface_op_func:opt}\n"
822 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
823 "%getId_label = OpLabel\n"
824 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
825 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
826 "%TC_0_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
827 "%TC_1_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
828 "%TC_2_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
829 "%TC_W_0 = OpLoad %f32 %TC_0_loc\n"
830 "%TC_W_1 = OpLoad %f32 %TC_1_loc\n"
831 "%TC_W_2 = OpLoad %f32 %TC_2_loc\n"
832 "%is_W_0_1 = OpFOrdEqual %bool %TC_W_0 %c_f32_1\n"
833 "%is_W_1_0 = OpFOrdEqual %bool %TC_W_1 %c_f32_0\n"
834 "%is_W_2_0 = OpFOrdEqual %bool %TC_W_2 %c_f32_0\n"
835 "%is_tessCoord_1_0 = OpLogicalAnd %bool %is_W_0_1 %is_W_1_0\n"
836 "%is_tessCoord_1_0_0 = OpLogicalAnd %bool %is_tessCoord_1_0 %is_W_2_0\n"
837 "%is_unique_id_0 = OpLogicalAnd %bool %is_tessCoord_1_0_0 %is_primitive_0\n"
838 "OpReturnValue %is_unique_id_0\n"
842 return tcu::StringTemplate(tessEvalBoilerplate).specialize(fragments);
845 // Creates geometry-shader assembly by specializing a boilerplate StringTemplate
846 // on fragments, which must (at least) map "testfun" to an OpFunction definition
847 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
848 // with "BP_" to avoid collisions with fragments.
850 // Derived from this GLSL:
853 // layout(triangles) in;
854 // layout(triangle_strip, max_vertices = 3) out;
856 // layout(location = 1) in vec4 in_color[];
857 // layout(location = 1) out vec4 out_color;
860 // gl_Position = gl_in[0].gl_Position;
861 // out_color = test_fun(in_color[0]);
863 // gl_Position = gl_in[1].gl_Position;
864 // out_color = test_fun(in_color[1]);
866 // gl_Position = gl_in[2].gl_Position;
867 // out_color = test_fun(in_color[2]);
871 string makeGeometryShaderAssembly(const map<string, string>& fragments)
873 static const char geometryShaderBoilerplate[] =
874 "OpCapability Geometry\n"
875 "OpCapability ClipDistance\n"
876 "OpCapability CullDistance\n"
877 "${capability:opt}\n"
879 "OpMemoryModel Logical GLSL450\n"
880 "OpEntryPoint Geometry %BP_main \"main\" %BP_out_gl_position %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} \n"
881 "OpExecutionMode %BP_main Triangles\n"
882 "OpExecutionMode %BP_main OutputTriangleStrip\n"
883 "OpExecutionMode %BP_main OutputVertices 3\n"
885 "OpName %BP_main \"main\"\n"
886 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
887 "OpName %BP_per_vertex_in \"gl_PerVertex\"\n"
888 "OpMemberName %BP_per_vertex_in 0 \"gl_Position\"\n"
889 "OpMemberName %BP_per_vertex_in 1 \"gl_PointSize\"\n"
890 "OpMemberName %BP_per_vertex_in 2 \"gl_ClipDistance\"\n"
891 "OpMemberName %BP_per_vertex_in 3 \"gl_CullDistance\"\n"
892 "OpName %BP_gl_in \"gl_in\"\n"
893 "OpName %BP_out_color \"out_color\"\n"
894 "OpName %BP_in_color \"in_color\"\n"
895 "OpName %test_code \"testfun(vf4;\"\n"
896 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
897 "OpDecorate %BP_out_gl_position BuiltIn Position\n"
898 "OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n"
899 "OpMemberDecorate %BP_per_vertex_in 1 BuiltIn PointSize\n"
900 "OpMemberDecorate %BP_per_vertex_in 2 BuiltIn ClipDistance\n"
901 "OpMemberDecorate %BP_per_vertex_in 3 BuiltIn CullDistance\n"
902 "OpDecorate %BP_per_vertex_in Block\n"
903 "OpDecorate %BP_out_color Location 1\n"
904 "OpDecorate %BP_in_color Location 1\n"
905 "${IF_decoration:opt}\n"
906 "${decoration:opt}\n"
908 SPIRV_ASSEMBLY_CONSTANTS
909 SPIRV_ASSEMBLY_ARRAYS
910 "%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
911 "%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n"
912 "%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n"
913 "%BP_pp_i32 = OpTypePointer Private %i32\n"
914 "%BP_pp_v4i32 = OpTypePointer Private %v4i32\n"
916 "%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n"
917 "%BP_out_color = OpVariable %op_v4f32 Output\n"
918 "%BP_in_color = OpVariable %ip_a3v4f32 Input\n"
919 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
920 "%BP_out_gl_position = OpVariable %op_v4f32 Output\n"
921 "%BP_vertexIdInCurrentPatch = OpVariable %BP_pp_v4i32 Private\n"
923 "${IF_variable:opt}\n"
925 "%BP_main = OpFunction %void None %fun\n"
926 "%BP_label = OpLabel\n"
928 "${IF_carryforward:opt}\n"
930 "%BP_primitiveId = OpLoad %i32 %BP_gl_PrimitiveID\n"
931 "%BP_addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %BP_primitiveId\n"
933 "%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
934 "%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
935 "%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
937 "%BP_in_position_0 = OpLoad %v4f32 %BP_gl_in_0_gl_position\n"
938 "%BP_in_position_1 = OpLoad %v4f32 %BP_gl_in_1_gl_position\n"
939 "%BP_in_position_2 = OpLoad %v4f32 %BP_gl_in_2_gl_position \n"
941 "%BP_in_color_0_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
942 "%BP_in_color_1_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
943 "%BP_in_color_2_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
945 "%BP_in_color_0 = OpLoad %v4f32 %BP_in_color_0_ptr\n"
946 "%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n"
947 "%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n"
949 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_0\n"
950 "%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n"
951 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_1\n"
952 "%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
953 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_2\n"
954 "%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"
957 "OpStore %BP_out_gl_position %BP_in_position_0\n"
958 "OpStore %BP_out_color %BP_transformed_in_color_0\n"
961 "OpStore %BP_out_gl_position %BP_in_position_1\n"
962 "OpStore %BP_out_color %BP_transformed_in_color_1\n"
965 "OpStore %BP_out_gl_position %BP_in_position_2\n"
966 "OpStore %BP_out_color %BP_transformed_in_color_2\n"
972 "${interface_op_func:opt}\n"
974 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
975 "%getId_label = OpLabel\n"
976 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
977 "%addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %primitive_id\n"
978 "%vertexIdInCurrentPatch = OpLoad %i32 %addr_vertexIdInCurrentPatch\n"
979 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
980 "%is_vertex_0 = OpIEqual %bool %vertexIdInCurrentPatch %c_i32_0\n"
981 "%is_unique_id_0 = OpLogicalAnd %bool %is_primitive_0 %is_vertex_0\n"
982 "OpReturnValue %is_unique_id_0\n"
986 return tcu::StringTemplate(geometryShaderBoilerplate).specialize(fragments);
989 // Creates fragment-shader assembly by specializing a boilerplate StringTemplate
990 // on fragments, which must (at least) map "testfun" to an OpFunction definition
991 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
992 // with "BP_" to avoid collisions with fragments.
994 // Derived from this GLSL:
996 // layout(location = 1) in highp vec4 vtxColor;
997 // layout(location = 0) out highp vec4 fragColor;
998 // highp vec4 testfun(highp vec4 x) { return x; }
999 // void main(void) { fragColor = testfun(vtxColor); }
1001 // with modifications including passing vtxColor by value and ripping out
1002 // testfun() definition.
1003 string makeFragmentShaderAssembly(const map<string, string>& fragments)
1005 static const char fragmentShaderBoilerplate[] =
1006 "OpCapability Shader\n"
1007 "${capability:opt}\n"
1008 "${extension:opt}\n"
1009 "OpMemoryModel Logical GLSL450\n"
1010 "OpEntryPoint Fragment %BP_main \"main\" %BP_vtxColor %BP_fragColor %BP_gl_FragCoord ${IF_entrypoint:opt} \n"
1011 "OpExecutionMode %BP_main OriginUpperLeft\n"
1013 "OpName %BP_main \"main\"\n"
1014 "OpName %BP_gl_FragCoord \"fragCoord\"\n"
1015 "OpName %BP_fragColor \"fragColor\"\n"
1016 "OpName %BP_vtxColor \"vtxColor\"\n"
1017 "OpName %test_code \"testfun(vf4;\"\n"
1018 "OpDecorate %BP_fragColor Location 0\n"
1019 "OpDecorate %BP_vtxColor Location 1\n"
1020 "OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n"
1021 "${IF_decoration:opt}\n"
1022 "${decoration:opt}\n"
1023 SPIRV_ASSEMBLY_TYPES
1024 SPIRV_ASSEMBLY_CONSTANTS
1025 SPIRV_ASSEMBLY_ARRAYS
1026 "%BP_gl_FragCoord = OpVariable %ip_v4f32 Input\n"
1027 "%BP_fragColor = OpVariable %op_v4f32 Output\n"
1028 "%BP_vtxColor = OpVariable %ip_v4f32 Input\n"
1030 "${IF_variable:opt}\n"
1031 "%BP_main = OpFunction %void None %fun\n"
1032 "%BP_label_main = OpLabel\n"
1033 "${IF_carryforward:opt}\n"
1034 "%BP_tmp1 = OpLoad %v4f32 %BP_vtxColor\n"
1035 "%BP_tmp2 = OpFunctionCall %v4f32 %test_code %BP_tmp1\n"
1036 "OpStore %BP_fragColor %BP_tmp2\n"
1039 "${interface_op_func:opt}\n"
1041 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
1042 "%getId_label = OpLabel\n"
1043 "%loc_x_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n"
1044 "%loc_y_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n"
1045 "%x_coord = OpLoad %f32 %loc_x_coord\n"
1046 "%y_coord = OpLoad %f32 %loc_y_coord\n"
1047 "%is_x_idx0 = OpFOrdEqual %bool %x_coord %c_f32_0_5\n"
1048 "%is_y_idx0 = OpFOrdEqual %bool %y_coord %c_f32_0_5\n"
1049 "%is_frag_0 = OpLogicalAnd %bool %is_x_idx0 %is_y_idx0\n"
1050 "OpReturnValue %is_frag_0\n"
1054 return tcu::StringTemplate(fragmentShaderBoilerplate).specialize(fragments);
1057 // Creates mappings from placeholders to pass-through shader code which copies
1058 // the input to the output faithfully.
1059 map<string, string> passthruInterface(const IFDataType& data_type)
1061 const string var_type = data_type.str();
1062 map<string, string> fragments = passthruFragments();
1063 const string functype = string("%") + var_type + "_" + var_type + "_function";
1065 fragments["interface_op_func"] =
1066 string("%interface_op_func = OpFunction %") + var_type + " None " + functype + "\n"
1067 " %io_param1 = OpFunctionParameter %" + var_type + "\n"
1068 " %IF_label = OpLabel\n"
1069 " OpReturnValue %io_param1\n"
1071 fragments["input_type"] = var_type;
1072 fragments["output_type"] = var_type;
1073 fragments["pre_main"] = "";
1075 if (!data_type.elementIs32bit())
1077 if (data_type.elementType == NUMBERTYPE_FLOAT16)
1079 fragments["pre_main"] += "%f16 = OpTypeFloat 16\n";
1081 else if (data_type.elementType == NUMBERTYPE_INT16)
1083 fragments["pre_main"] += "%i16 = OpTypeInt 16 1\n";
1087 fragments["pre_main"] += "%u16 = OpTypeInt 16 0\n";
1090 fragments["capability"] = "OpCapability StorageInputOutput16\n";
1091 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
1093 if (data_type.isVector())
1095 fragments["pre_main"] += "%" + var_type + " = OpTypeVector %" + IFDataType(1, data_type.elementType).str() + " " + numberToString(data_type.numElements) + "\n";
1098 fragments["pre_main"] +=
1099 "%ip_" + var_type + " = OpTypePointer Input %" + var_type + "\n"
1100 "%op_" + var_type + " = OpTypePointer Output %" + var_type + "\n";
1103 fragments["pre_main"] +=
1104 functype + " = OpTypeFunction %" + var_type + " %" + var_type + "\n"
1105 "%a3" + var_type + " = OpTypeArray %" + var_type + " %c_i32_3\n"
1106 "%ip_a3" + var_type + " = OpTypePointer Input %a3" + var_type + "\n"
1107 "%op_a3" + var_type + " = OpTypePointer Output %a3" + var_type + "\n";
1112 // Returns mappings from interface placeholders to their concrete values.
1114 // The concrete values should be specialized again to provide ${input_type}
1115 // and ${output_type}.
1117 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1118 map<string, string> fillInterfacePlaceholderVert (void)
1120 map<string, string> fragments;
1122 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1123 fragments["IF_variable"] =
1124 " %IF_input = OpVariable %ip_${input_type} Input\n"
1125 "%IF_output = OpVariable %op_${output_type} Output\n";
1126 fragments["IF_decoration"] =
1127 "OpDecorate %IF_input Location 2\n"
1128 "OpDecorate %IF_output Location 2\n";
1129 fragments["IF_carryforward"] =
1130 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1131 " %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1132 " OpStore %IF_output %IF_result\n";
1134 // Make sure the rest still need to be instantialized.
1135 fragments["capability"] = "${capability:opt}";
1136 fragments["extension"] = "${extension:opt}";
1137 fragments["debug"] = "${debug:opt}";
1138 fragments["decoration"] = "${decoration:opt}";
1139 fragments["pre_main"] = "${pre_main:opt}";
1140 fragments["testfun"] = "${testfun}";
1141 fragments["interface_op_func"] = "${interface_op_func}";
1146 // Returns mappings from interface placeholders to their concrete values.
1148 // The concrete values should be specialized again to provide ${input_type}
1149 // and ${output_type}.
1151 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1152 map<string, string> fillInterfacePlaceholderFrag (void)
1154 map<string, string> fragments;
1156 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1157 fragments["IF_variable"] =
1158 " %IF_input = OpVariable %ip_${input_type} Input\n"
1159 "%IF_output = OpVariable %op_${output_type} Output\n";
1160 fragments["IF_decoration"] =
1161 "OpDecorate %IF_input Flat\n"
1162 "OpDecorate %IF_input Location 2\n"
1163 "OpDecorate %IF_output Location 1\n"; // Fragment shader should write to location #1.
1164 fragments["IF_carryforward"] =
1165 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1166 " %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1167 " OpStore %IF_output %IF_result\n";
1169 // Make sure the rest still need to be instantialized.
1170 fragments["capability"] = "${capability:opt}";
1171 fragments["extension"] = "${extension:opt}";
1172 fragments["debug"] = "${debug:opt}";
1173 fragments["decoration"] = "${decoration:opt}";
1174 fragments["pre_main"] = "${pre_main:opt}";
1175 fragments["testfun"] = "${testfun}";
1176 fragments["interface_op_func"] = "${interface_op_func}";
1181 // Returns mappings from interface placeholders to their concrete values.
1183 // The concrete values should be specialized again to provide ${input_type}
1184 // and ${output_type}.
1186 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1187 // should also be defined in the final code.
1188 map<string, string> fillInterfacePlaceholderTessCtrl (void)
1190 map<string, string> fragments;
1192 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1193 fragments["IF_variable"] =
1194 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1195 "%IF_output = OpVariable %op_a3${output_type} Output\n";
1196 fragments["IF_decoration"] =
1197 "OpDecorate %IF_input Location 2\n"
1198 "OpDecorate %IF_output Location 2\n";
1199 fragments["IF_carryforward"] =
1200 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1201 " %IF_input_ptr1 = OpAccessChain %ip_${input_type} %IF_input %c_i32_1\n"
1202 " %IF_input_ptr2 = OpAccessChain %ip_${input_type} %IF_input %c_i32_2\n"
1203 "%IF_output_ptr0 = OpAccessChain %op_${output_type} %IF_output %c_i32_0\n"
1204 "%IF_output_ptr1 = OpAccessChain %op_${output_type} %IF_output %c_i32_1\n"
1205 "%IF_output_ptr2 = OpAccessChain %op_${output_type} %IF_output %c_i32_2\n"
1206 "%IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1207 "%IF_input_val1 = OpLoad %${input_type} %IF_input_ptr1\n"
1208 "%IF_input_val2 = OpLoad %${input_type} %IF_input_ptr2\n"
1209 "%IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1210 "%IF_input_res1 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val1\n"
1211 "%IF_input_res2 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val2\n"
1212 "OpStore %IF_output_ptr0 %IF_input_res0\n"
1213 "OpStore %IF_output_ptr1 %IF_input_res1\n"
1214 "OpStore %IF_output_ptr2 %IF_input_res2\n";
1216 // Make sure the rest still need to be instantialized.
1217 fragments["capability"] = "${capability:opt}";
1218 fragments["extension"] = "${extension:opt}";
1219 fragments["debug"] = "${debug:opt}";
1220 fragments["decoration"] = "${decoration:opt}";
1221 fragments["pre_main"] = "${pre_main:opt}";
1222 fragments["testfun"] = "${testfun}";
1223 fragments["interface_op_func"] = "${interface_op_func}";
1228 // Returns mappings from interface placeholders to their concrete values.
1230 // The concrete values should be specialized again to provide ${input_type}
1231 // and ${output_type}.
1233 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1234 // should also be defined in the final code.
1235 map<string, string> fillInterfacePlaceholderTessEvalGeom (void)
1237 map<string, string> fragments;
1239 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1240 fragments["IF_variable"] =
1241 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1242 "%IF_output = OpVariable %op_${output_type} Output\n";
1243 fragments["IF_decoration"] =
1244 "OpDecorate %IF_input Location 2\n"
1245 "OpDecorate %IF_output Location 2\n";
1246 fragments["IF_carryforward"] =
1247 // Only get the first value since all three values are the same anyway.
1248 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1249 " %IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1250 " %IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1251 "OpStore %IF_output %IF_input_res0\n";
1253 // Make sure the rest still need to be instantialized.
1254 fragments["capability"] = "${capability:opt}";
1255 fragments["extension"] = "${extension:opt}";
1256 fragments["debug"] = "${debug:opt}";
1257 fragments["decoration"] = "${decoration:opt}";
1258 fragments["pre_main"] = "${pre_main:opt}";
1259 fragments["testfun"] = "${testfun}";
1260 fragments["interface_op_func"] = "${interface_op_func}";
1265 map<string, string> passthruFragments(void)
1267 map<string, string> fragments;
1268 fragments["testfun"] =
1269 // A %test_code function that returns its argument unchanged.
1270 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1271 "%param1 = OpFunctionParameter %v4f32\n"
1272 "%label_testfun = OpLabel\n"
1273 "OpReturnValue %param1\n"
1278 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1279 // Vertex shader gets custom code from context, the rest are pass-through.
1280 void addShaderCodeCustomVertex(vk::SourceCollections& dst, InstanceContext context)
1282 if (!context.interfaces.empty())
1284 // Inject boilerplate code to wire up additional input/output variables between stages.
1285 // Just copy the contents in input variable to output variable in all stages except
1286 // the customized stage.
1287 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments);
1288 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1290 map<string, string> passthru = passthruFragments();
1292 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(context.testCodeFragments);
1293 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1297 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1298 // Tessellation control shader gets custom code from context, the rest are
1300 void addShaderCodeCustomTessControl(vk::SourceCollections& dst, InstanceContext context)
1302 if (!context.interfaces.empty())
1304 // Inject boilerplate code to wire up additional input/output variables between stages.
1305 // Just copy the contents in input variable to output variable in all stages except
1306 // the customized stage.
1307 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1308 dst.spirvAsmSources.add("tessc") << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments);
1309 dst.spirvAsmSources.add("tesse") << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType()));
1310 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1314 map<string, string> passthru = passthruFragments();
1316 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1317 dst.spirvAsmSources.add("tessc") << makeTessControlShaderAssembly(context.testCodeFragments);
1318 dst.spirvAsmSources.add("tesse") << makeTessEvalShaderAssembly(passthru);
1319 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1323 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1324 // Tessellation evaluation shader gets custom code from context, the rest are
1326 void addShaderCodeCustomTessEval(vk::SourceCollections& dst, InstanceContext context)
1328 if (!context.interfaces.empty())
1330 // Inject boilerplate code to wire up additional input/output variables between stages.
1331 // Just copy the contents in input variable to output variable in all stages except
1332 // the customized stage.
1333 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1334 dst.spirvAsmSources.add("tessc") << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType()));
1335 dst.spirvAsmSources.add("tesse") << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments);
1336 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1340 map<string, string> passthru = passthruFragments();
1341 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1342 dst.spirvAsmSources.add("tessc") << makeTessControlShaderAssembly(passthru);
1343 dst.spirvAsmSources.add("tesse") << makeTessEvalShaderAssembly(context.testCodeFragments);
1344 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1348 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1349 // Geometry shader gets custom code from context, the rest are pass-through.
1350 void addShaderCodeCustomGeometry(vk::SourceCollections& dst, InstanceContext context)
1352 if (!context.interfaces.empty())
1354 // Inject boilerplate code to wire up additional input/output variables between stages.
1355 // Just copy the contents in input variable to output variable in all stages except
1356 // the customized stage.
1357 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1358 dst.spirvAsmSources.add("geom") << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments);
1359 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1363 map<string, string> passthru = passthruFragments();
1364 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1365 dst.spirvAsmSources.add("geom") << makeGeometryShaderAssembly(context.testCodeFragments);
1366 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1370 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1371 // Fragment shader gets custom code from context, the rest are pass-through.
1372 void addShaderCodeCustomFragment(vk::SourceCollections& dst, InstanceContext context)
1374 if (!context.interfaces.empty())
1376 // Inject boilerplate code to wire up additional input/output variables between stages.
1377 // Just copy the contents in input variable to output variable in all stages except
1378 // the customized stage.
1379 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1380 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments);
1384 map<string, string> passthru = passthruFragments();
1385 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1386 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(context.testCodeFragments);
1390 void createCombinedModule(vk::SourceCollections& dst, InstanceContext)
1392 // \todo [2015-12-07 awoloszyn] Make tessellation / geometry conditional
1393 // \todo [2015-12-07 awoloszyn] Remove OpName and OpMemberName at some point
1394 dst.spirvAsmSources.add("module") <<
1395 "OpCapability Shader\n"
1396 "OpCapability ClipDistance\n"
1397 "OpCapability CullDistance\n"
1398 "OpCapability Geometry\n"
1399 "OpCapability Tessellation\n"
1400 "OpMemoryModel Logical GLSL450\n"
1402 "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_vtxPosition %vert_vertex_id %vert_instance_id\n"
1403 "OpEntryPoint Geometry %geom_main \"main\" %geom_out_gl_position %geom_gl_in %geom_out_color %geom_in_color\n"
1404 "OpEntryPoint TessellationControl %tessc_main \"main\" %tessc_out_color %tessc_gl_InvocationID %tessc_in_color %tessc_out_position %tessc_in_position %tessc_gl_TessLevelOuter %tessc_gl_TessLevelInner\n"
1405 "OpEntryPoint TessellationEvaluation %tesse_main \"main\" %tesse_stream %tesse_gl_tessCoord %tesse_in_position %tesse_out_color %tesse_in_color \n"
1406 "OpEntryPoint Fragment %frag_main \"main\" %frag_vtxColor %frag_fragColor\n"
1408 "OpExecutionMode %geom_main Triangles\n"
1409 "OpExecutionMode %geom_main OutputTriangleStrip\n"
1410 "OpExecutionMode %geom_main OutputVertices 3\n"
1412 "OpExecutionMode %tessc_main OutputVertices 3\n"
1414 "OpExecutionMode %tesse_main Triangles\n"
1415 "OpExecutionMode %tesse_main SpacingEqual\n"
1416 "OpExecutionMode %tesse_main VertexOrderCcw\n"
1418 "OpExecutionMode %frag_main OriginUpperLeft\n"
1420 "OpName %vert_main \"main\"\n"
1421 "OpName %vert_vtxPosition \"vtxPosition\"\n"
1422 "OpName %vert_Position \"position\"\n"
1423 "OpName %vert_vtxColor \"vtxColor\"\n"
1424 "OpName %vert_color \"color\"\n"
1425 "OpName %vert_vertex_id \"gl_VertexIndex\"\n"
1426 "OpName %vert_instance_id \"gl_InstanceIndex\"\n"
1427 "OpName %geom_main \"main\"\n"
1428 "OpName %geom_per_vertex_in \"gl_PerVertex\"\n"
1429 "OpMemberName %geom_per_vertex_in 0 \"gl_Position\"\n"
1430 "OpMemberName %geom_per_vertex_in 1 \"gl_PointSize\"\n"
1431 "OpMemberName %geom_per_vertex_in 2 \"gl_ClipDistance\"\n"
1432 "OpMemberName %geom_per_vertex_in 3 \"gl_CullDistance\"\n"
1433 "OpName %geom_gl_in \"gl_in\"\n"
1434 "OpName %geom_out_color \"out_color\"\n"
1435 "OpName %geom_in_color \"in_color\"\n"
1436 "OpName %tessc_main \"main\"\n"
1437 "OpName %tessc_out_color \"out_color\"\n"
1438 "OpName %tessc_gl_InvocationID \"gl_InvocationID\"\n"
1439 "OpName %tessc_in_color \"in_color\"\n"
1440 "OpName %tessc_out_position \"out_position\"\n"
1441 "OpName %tessc_in_position \"in_position\"\n"
1442 "OpName %tessc_gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
1443 "OpName %tessc_gl_TessLevelInner \"gl_TessLevelInner\"\n"
1444 "OpName %tesse_main \"main\"\n"
1445 "OpName %tesse_per_vertex_out \"gl_PerVertex\"\n"
1446 "OpMemberName %tesse_per_vertex_out 0 \"gl_Position\"\n"
1447 "OpMemberName %tesse_per_vertex_out 1 \"gl_PointSize\"\n"
1448 "OpMemberName %tesse_per_vertex_out 2 \"gl_ClipDistance\"\n"
1449 "OpMemberName %tesse_per_vertex_out 3 \"gl_CullDistance\"\n"
1450 "OpName %tesse_stream \"\"\n"
1451 "OpName %tesse_gl_tessCoord \"gl_TessCoord\"\n"
1452 "OpName %tesse_in_position \"in_position\"\n"
1453 "OpName %tesse_out_color \"out_color\"\n"
1454 "OpName %tesse_in_color \"in_color\"\n"
1455 "OpName %frag_main \"main\"\n"
1456 "OpName %frag_fragColor \"fragColor\"\n"
1457 "OpName %frag_vtxColor \"vtxColor\"\n"
1459 "; Vertex decorations\n"
1460 "OpDecorate %vert_vtxPosition Location 2\n"
1461 "OpDecorate %vert_Position Location 0\n"
1462 "OpDecorate %vert_vtxColor Location 1\n"
1463 "OpDecorate %vert_color Location 1\n"
1464 "OpDecorate %vert_vertex_id BuiltIn VertexIndex\n"
1465 "OpDecorate %vert_instance_id BuiltIn InstanceIndex\n"
1467 "; Geometry decorations\n"
1468 "OpDecorate %geom_out_gl_position BuiltIn Position\n"
1469 "OpMemberDecorate %geom_per_vertex_in 0 BuiltIn Position\n"
1470 "OpMemberDecorate %geom_per_vertex_in 1 BuiltIn PointSize\n"
1471 "OpMemberDecorate %geom_per_vertex_in 2 BuiltIn ClipDistance\n"
1472 "OpMemberDecorate %geom_per_vertex_in 3 BuiltIn CullDistance\n"
1473 "OpDecorate %geom_per_vertex_in Block\n"
1474 "OpDecorate %geom_out_color Location 1\n"
1475 "OpDecorate %geom_in_color Location 1\n"
1477 "; Tessellation Control decorations\n"
1478 "OpDecorate %tessc_out_color Location 1\n"
1479 "OpDecorate %tessc_gl_InvocationID BuiltIn InvocationId\n"
1480 "OpDecorate %tessc_in_color Location 1\n"
1481 "OpDecorate %tessc_out_position Location 2\n"
1482 "OpDecorate %tessc_in_position Location 2\n"
1483 "OpDecorate %tessc_gl_TessLevelOuter Patch\n"
1484 "OpDecorate %tessc_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1485 "OpDecorate %tessc_gl_TessLevelInner Patch\n"
1486 "OpDecorate %tessc_gl_TessLevelInner BuiltIn TessLevelInner\n"
1488 "; Tessellation Evaluation decorations\n"
1489 "OpMemberDecorate %tesse_per_vertex_out 0 BuiltIn Position\n"
1490 "OpMemberDecorate %tesse_per_vertex_out 1 BuiltIn PointSize\n"
1491 "OpMemberDecorate %tesse_per_vertex_out 2 BuiltIn ClipDistance\n"
1492 "OpMemberDecorate %tesse_per_vertex_out 3 BuiltIn CullDistance\n"
1493 "OpDecorate %tesse_per_vertex_out Block\n"
1494 "OpDecorate %tesse_gl_tessCoord BuiltIn TessCoord\n"
1495 "OpDecorate %tesse_in_position Location 2\n"
1496 "OpDecorate %tesse_out_color Location 1\n"
1497 "OpDecorate %tesse_in_color Location 1\n"
1499 "; Fragment decorations\n"
1500 "OpDecorate %frag_fragColor Location 0\n"
1501 "OpDecorate %frag_vtxColor Location 1\n"
1503 SPIRV_ASSEMBLY_TYPES
1504 SPIRV_ASSEMBLY_CONSTANTS
1505 SPIRV_ASSEMBLY_ARRAYS
1507 "; Vertex Variables\n"
1508 "%vert_vtxPosition = OpVariable %op_v4f32 Output\n"
1509 "%vert_Position = OpVariable %ip_v4f32 Input\n"
1510 "%vert_vtxColor = OpVariable %op_v4f32 Output\n"
1511 "%vert_color = OpVariable %ip_v4f32 Input\n"
1512 "%vert_vertex_id = OpVariable %ip_i32 Input\n"
1513 "%vert_instance_id = OpVariable %ip_i32 Input\n"
1515 "; Geometry Variables\n"
1516 "%geom_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1517 "%geom_a3_per_vertex_in = OpTypeArray %geom_per_vertex_in %c_u32_3\n"
1518 "%geom_ip_a3_per_vertex_in = OpTypePointer Input %geom_a3_per_vertex_in\n"
1519 "%geom_gl_in = OpVariable %geom_ip_a3_per_vertex_in Input\n"
1520 "%geom_out_color = OpVariable %op_v4f32 Output\n"
1521 "%geom_in_color = OpVariable %ip_a3v4f32 Input\n"
1522 "%geom_out_gl_position = OpVariable %op_v4f32 Output\n"
1524 "; Tessellation Control Variables\n"
1525 "%tessc_out_color = OpVariable %op_a3v4f32 Output\n"
1526 "%tessc_gl_InvocationID = OpVariable %ip_i32 Input\n"
1527 "%tessc_in_color = OpVariable %ip_a32v4f32 Input\n"
1528 "%tessc_out_position = OpVariable %op_a3v4f32 Output\n"
1529 "%tessc_in_position = OpVariable %ip_a32v4f32 Input\n"
1530 "%tessc_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1531 "%tessc_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1533 "; Tessellation Evaluation Decorations\n"
1534 "%tesse_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1535 "%tesse_op_per_vertex_out = OpTypePointer Output %tesse_per_vertex_out\n"
1536 "%tesse_stream = OpVariable %tesse_op_per_vertex_out Output\n"
1537 "%tesse_gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1538 "%tesse_in_position = OpVariable %ip_a32v4f32 Input\n"
1539 "%tesse_out_color = OpVariable %op_v4f32 Output\n"
1540 "%tesse_in_color = OpVariable %ip_a32v4f32 Input\n"
1542 "; Fragment Variables\n"
1543 "%frag_fragColor = OpVariable %op_v4f32 Output\n"
1544 "%frag_vtxColor = OpVariable %ip_v4f32 Input\n"
1547 "%vert_main = OpFunction %void None %fun\n"
1548 "%vert_label = OpLabel\n"
1549 "%vert_tmp_position = OpLoad %v4f32 %vert_Position\n"
1550 "OpStore %vert_vtxPosition %vert_tmp_position\n"
1551 "%vert_tmp_color = OpLoad %v4f32 %vert_color\n"
1552 "OpStore %vert_vtxColor %vert_tmp_color\n"
1556 "; Geometry Entry\n"
1557 "%geom_main = OpFunction %void None %fun\n"
1558 "%geom_label = OpLabel\n"
1559 "%geom_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_0 %c_i32_0\n"
1560 "%geom_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_1 %c_i32_0\n"
1561 "%geom_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_2 %c_i32_0\n"
1562 "%geom_in_position_0 = OpLoad %v4f32 %geom_gl_in_0_gl_position\n"
1563 "%geom_in_position_1 = OpLoad %v4f32 %geom_gl_in_1_gl_position\n"
1564 "%geom_in_position_2 = OpLoad %v4f32 %geom_gl_in_2_gl_position \n"
1565 "%geom_in_color_0_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_0\n"
1566 "%geom_in_color_1_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_1\n"
1567 "%geom_in_color_2_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_2\n"
1568 "%geom_in_color_0 = OpLoad %v4f32 %geom_in_color_0_ptr\n"
1569 "%geom_in_color_1 = OpLoad %v4f32 %geom_in_color_1_ptr\n"
1570 "%geom_in_color_2 = OpLoad %v4f32 %geom_in_color_2_ptr\n"
1571 "OpStore %geom_out_gl_position %geom_in_position_0\n"
1572 "OpStore %geom_out_color %geom_in_color_0\n"
1574 "OpStore %geom_out_gl_position %geom_in_position_1\n"
1575 "OpStore %geom_out_color %geom_in_color_1\n"
1577 "OpStore %geom_out_gl_position %geom_in_position_2\n"
1578 "OpStore %geom_out_color %geom_in_color_2\n"
1584 "; Tessellation Control Entry\n"
1585 "%tessc_main = OpFunction %void None %fun\n"
1586 "%tessc_label = OpLabel\n"
1587 "%tessc_invocation_id = OpLoad %i32 %tessc_gl_InvocationID\n"
1588 "%tessc_in_color_ptr = OpAccessChain %ip_v4f32 %tessc_in_color %tessc_invocation_id\n"
1589 "%tessc_in_position_ptr = OpAccessChain %ip_v4f32 %tessc_in_position %tessc_invocation_id\n"
1590 "%tessc_in_color_val = OpLoad %v4f32 %tessc_in_color_ptr\n"
1591 "%tessc_in_position_val = OpLoad %v4f32 %tessc_in_position_ptr\n"
1592 "%tessc_out_color_ptr = OpAccessChain %op_v4f32 %tessc_out_color %tessc_invocation_id\n"
1593 "%tessc_out_position_ptr = OpAccessChain %op_v4f32 %tessc_out_position %tessc_invocation_id\n"
1594 "OpStore %tessc_out_color_ptr %tessc_in_color_val\n"
1595 "OpStore %tessc_out_position_ptr %tessc_in_position_val\n"
1596 "%tessc_is_first_invocation = OpIEqual %bool %tessc_invocation_id %c_i32_0\n"
1597 "OpSelectionMerge %tessc_merge_label None\n"
1598 "OpBranchConditional %tessc_is_first_invocation %tessc_first_invocation %tessc_merge_label\n"
1599 "%tessc_first_invocation = OpLabel\n"
1600 "%tessc_tess_outer_0 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_0\n"
1601 "%tessc_tess_outer_1 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_1\n"
1602 "%tessc_tess_outer_2 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_2\n"
1603 "%tessc_tess_inner = OpAccessChain %op_f32 %tessc_gl_TessLevelInner %c_i32_0\n"
1604 "OpStore %tessc_tess_outer_0 %c_f32_1\n"
1605 "OpStore %tessc_tess_outer_1 %c_f32_1\n"
1606 "OpStore %tessc_tess_outer_2 %c_f32_1\n"
1607 "OpStore %tessc_tess_inner %c_f32_1\n"
1608 "OpBranch %tessc_merge_label\n"
1609 "%tessc_merge_label = OpLabel\n"
1613 "; Tessellation Evaluation Entry\n"
1614 "%tesse_main = OpFunction %void None %fun\n"
1615 "%tesse_label = OpLabel\n"
1616 "%tesse_tc_0_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_0\n"
1617 "%tesse_tc_1_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_1\n"
1618 "%tesse_tc_2_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_2\n"
1619 "%tesse_tc_0 = OpLoad %f32 %tesse_tc_0_ptr\n"
1620 "%tesse_tc_1 = OpLoad %f32 %tesse_tc_1_ptr\n"
1621 "%tesse_tc_2 = OpLoad %f32 %tesse_tc_2_ptr\n"
1622 "%tesse_in_pos_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_0\n"
1623 "%tesse_in_pos_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_1\n"
1624 "%tesse_in_pos_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_2\n"
1625 "%tesse_in_pos_0 = OpLoad %v4f32 %tesse_in_pos_0_ptr\n"
1626 "%tesse_in_pos_1 = OpLoad %v4f32 %tesse_in_pos_1_ptr\n"
1627 "%tesse_in_pos_2 = OpLoad %v4f32 %tesse_in_pos_2_ptr\n"
1628 "%tesse_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_0 %tesse_tc_0\n"
1629 "%tesse_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_1 %tesse_tc_1\n"
1630 "%tesse_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_2 %tesse_tc_2\n"
1631 "%tesse_out_pos_ptr = OpAccessChain %op_v4f32 %tesse_stream %c_i32_0\n"
1632 "%tesse_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse_in_pos_0_weighted %tesse_in_pos_1_weighted\n"
1633 "%tesse_computed_out = OpFAdd %v4f32 %tesse_in_pos_0_plus_pos_1 %tesse_in_pos_2_weighted\n"
1634 "OpStore %tesse_out_pos_ptr %tesse_computed_out\n"
1635 "%tesse_in_clr_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_0\n"
1636 "%tesse_in_clr_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_1\n"
1637 "%tesse_in_clr_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_2\n"
1638 "%tesse_in_clr_0 = OpLoad %v4f32 %tesse_in_clr_0_ptr\n"
1639 "%tesse_in_clr_1 = OpLoad %v4f32 %tesse_in_clr_1_ptr\n"
1640 "%tesse_in_clr_2 = OpLoad %v4f32 %tesse_in_clr_2_ptr\n"
1641 "%tesse_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_0 %tesse_tc_0\n"
1642 "%tesse_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_1 %tesse_tc_1\n"
1643 "%tesse_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_2 %tesse_tc_2\n"
1644 "%tesse_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse_in_clr_0_weighted %tesse_in_clr_1_weighted\n"
1645 "%tesse_computed_clr = OpFAdd %v4f32 %tesse_in_clr_0_plus_col_1 %tesse_in_clr_2_weighted\n"
1646 "OpStore %tesse_out_color %tesse_computed_clr\n"
1650 "; Fragment Entry\n"
1651 "%frag_main = OpFunction %void None %fun\n"
1652 "%frag_label_main = OpLabel\n"
1653 "%frag_tmp1 = OpLoad %v4f32 %frag_vtxColor\n"
1654 "OpStore %frag_fragColor %frag_tmp1\n"
1659 void createMultipleEntries(vk::SourceCollections& dst, InstanceContext)
1661 dst.spirvAsmSources.add("vert") <<
1662 // This module contains 2 vertex shaders. One that is a passthrough
1663 // and a second that inverts the color of the output (1.0 - color).
1664 "OpCapability Shader\n"
1665 "OpMemoryModel Logical GLSL450\n"
1666 "OpEntryPoint Vertex %main \"vert1\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1667 "OpEntryPoint Vertex %main2 \"vert2\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1669 "OpName %main \"vert1\"\n"
1670 "OpName %main2 \"vert2\"\n"
1671 "OpName %vtxPosition \"vtxPosition\"\n"
1672 "OpName %Position \"position\"\n"
1673 "OpName %vtxColor \"vtxColor\"\n"
1674 "OpName %color \"color\"\n"
1675 "OpName %vertex_id \"gl_VertexIndex\"\n"
1676 "OpName %instance_id \"gl_InstanceIndex\"\n"
1678 "OpDecorate %vtxPosition Location 2\n"
1679 "OpDecorate %Position Location 0\n"
1680 "OpDecorate %vtxColor Location 1\n"
1681 "OpDecorate %color Location 1\n"
1682 "OpDecorate %vertex_id BuiltIn VertexIndex\n"
1683 "OpDecorate %instance_id BuiltIn InstanceIndex\n"
1684 SPIRV_ASSEMBLY_TYPES
1685 SPIRV_ASSEMBLY_CONSTANTS
1686 SPIRV_ASSEMBLY_ARRAYS
1687 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1688 "%vtxPosition = OpVariable %op_v4f32 Output\n"
1689 "%Position = OpVariable %ip_v4f32 Input\n"
1690 "%vtxColor = OpVariable %op_v4f32 Output\n"
1691 "%color = OpVariable %ip_v4f32 Input\n"
1692 "%vertex_id = OpVariable %ip_i32 Input\n"
1693 "%instance_id = OpVariable %ip_i32 Input\n"
1695 "%main = OpFunction %void None %fun\n"
1696 "%label = OpLabel\n"
1697 "%tmp_position = OpLoad %v4f32 %Position\n"
1698 "OpStore %vtxPosition %tmp_position\n"
1699 "%tmp_color = OpLoad %v4f32 %color\n"
1700 "OpStore %vtxColor %tmp_color\n"
1704 "%main2 = OpFunction %void None %fun\n"
1705 "%label2 = OpLabel\n"
1706 "%tmp_position2 = OpLoad %v4f32 %Position\n"
1707 "OpStore %vtxPosition %tmp_position2\n"
1708 "%tmp_color2 = OpLoad %v4f32 %color\n"
1709 "%tmp_color3 = OpFSub %v4f32 %cval %tmp_color2\n"
1710 "%tmp_color4 = OpVectorInsertDynamic %v4f32 %tmp_color3 %c_f32_1 %c_i32_3\n"
1711 "OpStore %vtxColor %tmp_color4\n"
1715 dst.spirvAsmSources.add("frag") <<
1716 // This is a single module that contains 2 fragment shaders.
1717 // One that passes color through and the other that inverts the output
1718 // color (1.0 - color).
1719 "OpCapability Shader\n"
1720 "OpMemoryModel Logical GLSL450\n"
1721 "OpEntryPoint Fragment %main \"frag1\" %vtxColor %fragColor\n"
1722 "OpEntryPoint Fragment %main2 \"frag2\" %vtxColor %fragColor\n"
1723 "OpExecutionMode %main OriginUpperLeft\n"
1724 "OpExecutionMode %main2 OriginUpperLeft\n"
1726 "OpName %main \"frag1\"\n"
1727 "OpName %main2 \"frag2\"\n"
1728 "OpName %fragColor \"fragColor\"\n"
1729 "OpName %vtxColor \"vtxColor\"\n"
1730 "OpDecorate %fragColor Location 0\n"
1731 "OpDecorate %vtxColor Location 1\n"
1732 SPIRV_ASSEMBLY_TYPES
1733 SPIRV_ASSEMBLY_CONSTANTS
1734 SPIRV_ASSEMBLY_ARRAYS
1735 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1736 "%fragColor = OpVariable %op_v4f32 Output\n"
1737 "%vtxColor = OpVariable %ip_v4f32 Input\n"
1739 "%main = OpFunction %void None %fun\n"
1740 "%label_main = OpLabel\n"
1741 "%tmp1 = OpLoad %v4f32 %vtxColor\n"
1742 "OpStore %fragColor %tmp1\n"
1746 "%main2 = OpFunction %void None %fun\n"
1747 "%label_main2 = OpLabel\n"
1748 "%tmp2 = OpLoad %v4f32 %vtxColor\n"
1749 "%tmp3 = OpFSub %v4f32 %cval %tmp2\n"
1750 "%tmp4 = OpVectorInsertDynamic %v4f32 %tmp3 %c_f32_1 %c_i32_3\n"
1751 "OpStore %fragColor %tmp4\n"
1755 dst.spirvAsmSources.add("geom") <<
1756 "OpCapability Geometry\n"
1757 "OpCapability ClipDistance\n"
1758 "OpCapability CullDistance\n"
1759 "OpMemoryModel Logical GLSL450\n"
1760 "OpEntryPoint Geometry %geom1_main \"geom1\" %out_gl_position %gl_in %out_color %in_color\n"
1761 "OpEntryPoint Geometry %geom2_main \"geom2\" %out_gl_position %gl_in %out_color %in_color\n"
1762 "OpExecutionMode %geom1_main Triangles\n"
1763 "OpExecutionMode %geom2_main Triangles\n"
1764 "OpExecutionMode %geom1_main OutputTriangleStrip\n"
1765 "OpExecutionMode %geom2_main OutputTriangleStrip\n"
1766 "OpExecutionMode %geom1_main OutputVertices 3\n"
1767 "OpExecutionMode %geom2_main OutputVertices 3\n"
1768 "OpName %geom1_main \"geom1\"\n"
1769 "OpName %geom2_main \"geom2\"\n"
1770 "OpName %per_vertex_in \"gl_PerVertex\"\n"
1771 "OpMemberName %per_vertex_in 0 \"gl_Position\"\n"
1772 "OpMemberName %per_vertex_in 1 \"gl_PointSize\"\n"
1773 "OpMemberName %per_vertex_in 2 \"gl_ClipDistance\"\n"
1774 "OpMemberName %per_vertex_in 3 \"gl_CullDistance\"\n"
1775 "OpName %gl_in \"gl_in\"\n"
1776 "OpName %out_color \"out_color\"\n"
1777 "OpName %in_color \"in_color\"\n"
1778 "OpDecorate %out_gl_position BuiltIn Position\n"
1779 "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n"
1780 "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n"
1781 "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n"
1782 "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n"
1783 "OpDecorate %per_vertex_in Block\n"
1784 "OpDecorate %out_color Location 1\n"
1785 "OpDecorate %in_color Location 1\n"
1786 SPIRV_ASSEMBLY_TYPES
1787 SPIRV_ASSEMBLY_CONSTANTS
1788 SPIRV_ASSEMBLY_ARRAYS
1789 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1790 "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1791 "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n"
1792 "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n"
1793 "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n"
1794 "%out_color = OpVariable %op_v4f32 Output\n"
1795 "%in_color = OpVariable %ip_a3v4f32 Input\n"
1796 "%out_gl_position = OpVariable %op_v4f32 Output\n"
1798 "%geom1_main = OpFunction %void None %fun\n"
1799 "%geom1_label = OpLabel\n"
1800 "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1801 "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1802 "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1803 "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n"
1804 "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n"
1805 "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n"
1806 "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1807 "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1808 "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1809 "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n"
1810 "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n"
1811 "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n"
1812 "OpStore %out_gl_position %geom1_in_position_0\n"
1813 "OpStore %out_color %geom1_in_color_0\n"
1815 "OpStore %out_gl_position %geom1_in_position_1\n"
1816 "OpStore %out_color %geom1_in_color_1\n"
1818 "OpStore %out_gl_position %geom1_in_position_2\n"
1819 "OpStore %out_color %geom1_in_color_2\n"
1825 "%geom2_main = OpFunction %void None %fun\n"
1826 "%geom2_label = OpLabel\n"
1827 "%geom2_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1828 "%geom2_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1829 "%geom2_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1830 "%geom2_in_position_0 = OpLoad %v4f32 %geom2_gl_in_0_gl_position\n"
1831 "%geom2_in_position_1 = OpLoad %v4f32 %geom2_gl_in_1_gl_position\n"
1832 "%geom2_in_position_2 = OpLoad %v4f32 %geom2_gl_in_2_gl_position \n"
1833 "%geom2_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1834 "%geom2_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1835 "%geom2_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1836 "%geom2_in_color_0 = OpLoad %v4f32 %geom2_in_color_0_ptr\n"
1837 "%geom2_in_color_1 = OpLoad %v4f32 %geom2_in_color_1_ptr\n"
1838 "%geom2_in_color_2 = OpLoad %v4f32 %geom2_in_color_2_ptr\n"
1839 "%geom2_transformed_in_color_0 = OpFSub %v4f32 %cval %geom2_in_color_0\n"
1840 "%geom2_transformed_in_color_1 = OpFSub %v4f32 %cval %geom2_in_color_1\n"
1841 "%geom2_transformed_in_color_2 = OpFSub %v4f32 %cval %geom2_in_color_2\n"
1842 "%geom2_transformed_in_color_0_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_0 %c_f32_1 %c_i32_3\n"
1843 "%geom2_transformed_in_color_1_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_1 %c_f32_1 %c_i32_3\n"
1844 "%geom2_transformed_in_color_2_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_2 %c_f32_1 %c_i32_3\n"
1845 "OpStore %out_gl_position %geom2_in_position_0\n"
1846 "OpStore %out_color %geom2_transformed_in_color_0_a\n"
1848 "OpStore %out_gl_position %geom2_in_position_1\n"
1849 "OpStore %out_color %geom2_transformed_in_color_1_a\n"
1851 "OpStore %out_gl_position %geom2_in_position_2\n"
1852 "OpStore %out_color %geom2_transformed_in_color_2_a\n"
1858 dst.spirvAsmSources.add("tessc") <<
1859 "OpCapability Tessellation\n"
1860 "OpMemoryModel Logical GLSL450\n"
1861 "OpEntryPoint TessellationControl %tessc1_main \"tessc1\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1862 "OpEntryPoint TessellationControl %tessc2_main \"tessc2\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1863 "OpExecutionMode %tessc1_main OutputVertices 3\n"
1864 "OpExecutionMode %tessc2_main OutputVertices 3\n"
1865 "OpName %tessc1_main \"tessc1\"\n"
1866 "OpName %tessc2_main \"tessc2\"\n"
1867 "OpName %out_color \"out_color\"\n"
1868 "OpName %gl_InvocationID \"gl_InvocationID\"\n"
1869 "OpName %in_color \"in_color\"\n"
1870 "OpName %out_position \"out_position\"\n"
1871 "OpName %in_position \"in_position\"\n"
1872 "OpName %gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
1873 "OpName %gl_TessLevelInner \"gl_TessLevelInner\"\n"
1874 "OpDecorate %out_color Location 1\n"
1875 "OpDecorate %gl_InvocationID BuiltIn InvocationId\n"
1876 "OpDecorate %in_color Location 1\n"
1877 "OpDecorate %out_position Location 2\n"
1878 "OpDecorate %in_position Location 2\n"
1879 "OpDecorate %gl_TessLevelOuter Patch\n"
1880 "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1881 "OpDecorate %gl_TessLevelInner Patch\n"
1882 "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n"
1883 SPIRV_ASSEMBLY_TYPES
1884 SPIRV_ASSEMBLY_CONSTANTS
1885 SPIRV_ASSEMBLY_ARRAYS
1886 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1887 "%out_color = OpVariable %op_a3v4f32 Output\n"
1888 "%gl_InvocationID = OpVariable %ip_i32 Input\n"
1889 "%in_color = OpVariable %ip_a32v4f32 Input\n"
1890 "%out_position = OpVariable %op_a3v4f32 Output\n"
1891 "%in_position = OpVariable %ip_a32v4f32 Input\n"
1892 "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1893 "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1895 "%tessc1_main = OpFunction %void None %fun\n"
1896 "%tessc1_label = OpLabel\n"
1897 "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1898 "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n"
1899 "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n"
1900 "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n"
1901 "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n"
1902 "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n"
1903 "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n"
1904 "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n"
1905 "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n"
1906 "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n"
1907 "OpSelectionMerge %tessc1_merge_label None\n"
1908 "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n"
1909 "%tessc1_first_invocation = OpLabel\n"
1910 "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1911 "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1912 "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1913 "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1914 "OpStore %tessc1_tess_outer_0 %c_f32_1\n"
1915 "OpStore %tessc1_tess_outer_1 %c_f32_1\n"
1916 "OpStore %tessc1_tess_outer_2 %c_f32_1\n"
1917 "OpStore %tessc1_tess_inner %c_f32_1\n"
1918 "OpBranch %tessc1_merge_label\n"
1919 "%tessc1_merge_label = OpLabel\n"
1923 "%tessc2_main = OpFunction %void None %fun\n"
1924 "%tessc2_label = OpLabel\n"
1925 "%tessc2_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1926 "%tessc2_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc2_invocation_id\n"
1927 "%tessc2_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc2_invocation_id\n"
1928 "%tessc2_in_color_val = OpLoad %v4f32 %tessc2_in_color_ptr\n"
1929 "%tessc2_in_position_val = OpLoad %v4f32 %tessc2_in_position_ptr\n"
1930 "%tessc2_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc2_invocation_id\n"
1931 "%tessc2_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc2_invocation_id\n"
1932 "%tessc2_transformed_color = OpFSub %v4f32 %cval %tessc2_in_color_val\n"
1933 "%tessc2_transformed_color_a = OpVectorInsertDynamic %v4f32 %tessc2_transformed_color %c_f32_1 %c_i32_3\n"
1934 "OpStore %tessc2_out_color_ptr %tessc2_transformed_color_a\n"
1935 "OpStore %tessc2_out_position_ptr %tessc2_in_position_val\n"
1936 "%tessc2_is_first_invocation = OpIEqual %bool %tessc2_invocation_id %c_i32_0\n"
1937 "OpSelectionMerge %tessc2_merge_label None\n"
1938 "OpBranchConditional %tessc2_is_first_invocation %tessc2_first_invocation %tessc2_merge_label\n"
1939 "%tessc2_first_invocation = OpLabel\n"
1940 "%tessc2_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1941 "%tessc2_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1942 "%tessc2_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1943 "%tessc2_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1944 "OpStore %tessc2_tess_outer_0 %c_f32_1\n"
1945 "OpStore %tessc2_tess_outer_1 %c_f32_1\n"
1946 "OpStore %tessc2_tess_outer_2 %c_f32_1\n"
1947 "OpStore %tessc2_tess_inner %c_f32_1\n"
1948 "OpBranch %tessc2_merge_label\n"
1949 "%tessc2_merge_label = OpLabel\n"
1953 dst.spirvAsmSources.add("tesse") <<
1954 "OpCapability Tessellation\n"
1955 "OpCapability ClipDistance\n"
1956 "OpCapability CullDistance\n"
1957 "OpMemoryModel Logical GLSL450\n"
1958 "OpEntryPoint TessellationEvaluation %tesse1_main \"tesse1\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
1959 "OpEntryPoint TessellationEvaluation %tesse2_main \"tesse2\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
1960 "OpExecutionMode %tesse1_main Triangles\n"
1961 "OpExecutionMode %tesse1_main SpacingEqual\n"
1962 "OpExecutionMode %tesse1_main VertexOrderCcw\n"
1963 "OpExecutionMode %tesse2_main Triangles\n"
1964 "OpExecutionMode %tesse2_main SpacingEqual\n"
1965 "OpExecutionMode %tesse2_main VertexOrderCcw\n"
1966 "OpName %tesse1_main \"tesse1\"\n"
1967 "OpName %tesse2_main \"tesse2\"\n"
1968 "OpName %per_vertex_out \"gl_PerVertex\"\n"
1969 "OpMemberName %per_vertex_out 0 \"gl_Position\"\n"
1970 "OpMemberName %per_vertex_out 1 \"gl_PointSize\"\n"
1971 "OpMemberName %per_vertex_out 2 \"gl_ClipDistance\"\n"
1972 "OpMemberName %per_vertex_out 3 \"gl_CullDistance\"\n"
1973 "OpName %stream \"\"\n"
1974 "OpName %gl_tessCoord \"gl_TessCoord\"\n"
1975 "OpName %in_position \"in_position\"\n"
1976 "OpName %out_color \"out_color\"\n"
1977 "OpName %in_color \"in_color\"\n"
1978 "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n"
1979 "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n"
1980 "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n"
1981 "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n"
1982 "OpDecorate %per_vertex_out Block\n"
1983 "OpDecorate %gl_tessCoord BuiltIn TessCoord\n"
1984 "OpDecorate %in_position Location 2\n"
1985 "OpDecorate %out_color Location 1\n"
1986 "OpDecorate %in_color Location 1\n"
1987 SPIRV_ASSEMBLY_TYPES
1988 SPIRV_ASSEMBLY_CONSTANTS
1989 SPIRV_ASSEMBLY_ARRAYS
1990 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1991 "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1992 "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n"
1993 "%stream = OpVariable %op_per_vertex_out Output\n"
1994 "%gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1995 "%in_position = OpVariable %ip_a32v4f32 Input\n"
1996 "%out_color = OpVariable %op_v4f32 Output\n"
1997 "%in_color = OpVariable %ip_a32v4f32 Input\n"
1999 "%tesse1_main = OpFunction %void None %fun\n"
2000 "%tesse1_label = OpLabel\n"
2001 "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
2002 "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
2003 "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
2004 "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n"
2005 "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n"
2006 "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n"
2007 "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
2008 "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
2009 "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
2010 "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n"
2011 "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n"
2012 "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n"
2013 "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n"
2014 "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n"
2015 "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n"
2016 "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
2017 "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n"
2018 "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n"
2019 "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n"
2020 "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2021 "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2022 "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2023 "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n"
2024 "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n"
2025 "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n"
2026 "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n"
2027 "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n"
2028 "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n"
2029 "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n"
2030 "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n"
2031 "OpStore %out_color %tesse1_computed_clr\n"
2035 "%tesse2_main = OpFunction %void None %fun\n"
2036 "%tesse2_label = OpLabel\n"
2037 "%tesse2_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
2038 "%tesse2_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
2039 "%tesse2_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
2040 "%tesse2_tc_0 = OpLoad %f32 %tesse2_tc_0_ptr\n"
2041 "%tesse2_tc_1 = OpLoad %f32 %tesse2_tc_1_ptr\n"
2042 "%tesse2_tc_2 = OpLoad %f32 %tesse2_tc_2_ptr\n"
2043 "%tesse2_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
2044 "%tesse2_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
2045 "%tesse2_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
2046 "%tesse2_in_pos_0 = OpLoad %v4f32 %tesse2_in_pos_0_ptr\n"
2047 "%tesse2_in_pos_1 = OpLoad %v4f32 %tesse2_in_pos_1_ptr\n"
2048 "%tesse2_in_pos_2 = OpLoad %v4f32 %tesse2_in_pos_2_ptr\n"
2049 "%tesse2_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_0 %tesse2_tc_0\n"
2050 "%tesse2_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_1 %tesse2_tc_1\n"
2051 "%tesse2_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_2 %tesse2_tc_2\n"
2052 "%tesse2_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
2053 "%tesse2_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse2_in_pos_0_weighted %tesse2_in_pos_1_weighted\n"
2054 "%tesse2_computed_out = OpFAdd %v4f32 %tesse2_in_pos_0_plus_pos_1 %tesse2_in_pos_2_weighted\n"
2055 "OpStore %tesse2_out_pos_ptr %tesse2_computed_out\n"
2056 "%tesse2_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2057 "%tesse2_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2058 "%tesse2_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2059 "%tesse2_in_clr_0 = OpLoad %v4f32 %tesse2_in_clr_0_ptr\n"
2060 "%tesse2_in_clr_1 = OpLoad %v4f32 %tesse2_in_clr_1_ptr\n"
2061 "%tesse2_in_clr_2 = OpLoad %v4f32 %tesse2_in_clr_2_ptr\n"
2062 "%tesse2_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_0 %tesse2_tc_0\n"
2063 "%tesse2_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_1 %tesse2_tc_1\n"
2064 "%tesse2_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_2 %tesse2_tc_2\n"
2065 "%tesse2_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse2_in_clr_0_weighted %tesse2_in_clr_1_weighted\n"
2066 "%tesse2_computed_clr = OpFAdd %v4f32 %tesse2_in_clr_0_plus_col_1 %tesse2_in_clr_2_weighted\n"
2067 "%tesse2_clr_transformed = OpFSub %v4f32 %cval %tesse2_computed_clr\n"
2068 "%tesse2_clr_transformed_a = OpVectorInsertDynamic %v4f32 %tesse2_clr_transformed %c_f32_1 %c_i32_3\n"
2069 "OpStore %out_color %tesse2_clr_transformed_a\n"
2074 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
2076 // We only support RTE, RTZ, or both.
2077 DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);
2079 const Float32 originalFloat (original);
2080 const Float16 returnedFloat (returned);
2082 // Zero are turned into zero under both RTE and RTZ.
2083 if (originalFloat.isZero())
2085 if (returnedFloat.isZero())
2088 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2092 // Any denormalized value input into a shader may be flushed to 0.
2093 if (originalFloat.isDenorm() && returnedFloat.isZero())
2096 // Inf are always turned into Inf with the same sign, too.
2097 if (originalFloat.isInf())
2099 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2102 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2106 // NaN are always turned into NaN, too.
2107 if (originalFloat.isNaN())
2109 if (returnedFloat.isNaN())
2112 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2116 // Check all rounding modes
2117 for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
2119 if ((flags & (1u << bitNdx)) == 0)
2120 continue; // This rounding mode is not selected.
2122 const Float16 expectedFloat (deFloat32To16Round(original, deRoundingMode(bitNdx)));
2124 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2125 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2128 // If not matched in the above cases, they should have the same bit pattern.
2129 if (expectedFloat.bits() == returnedFloat.bits())
2133 log << TestLog::Message << "Error: found unmatched 32-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
2137 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log)
2139 const Float32 expectedFloat (expected);
2140 const Float32 returnedFloat (returned);
2142 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2143 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2147 const Float16 originalFloat (deFloat32To16(expected));
2149 // Any denormalized value input into a shader may be flushed to 0.
2150 if (originalFloat.isDenorm() && returnedFloat.isZero())
2154 if (expectedFloat.isNaN())
2156 if (returnedFloat.isNaN())
2159 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2163 if (returned == expected)
2166 log << TestLog::Message << "Error: found unmatched 32-bit float: expected " << expectedFloat.bits() << " vs. returned " << returnedFloat.bits() << TestLog::EndMessage;
2170 Move<VkBuffer> createBufferForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex)
2172 vector<deUint8> resourceBytes;
2173 resource.second->getBytes(resourceBytes);
2175 const VkBufferCreateInfo resourceBufferParams =
2177 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
2179 (VkBufferCreateFlags)0, // flags
2180 (VkDeviceSize)resourceBytes.size(), // size
2181 (VkBufferUsageFlags)getMatchingBufferUsageFlagBit(resource.first), // usage
2182 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2183 1u, // queueFamilyCount
2184 &queueFamilyIndex, // pQueueFamilyIndices
2187 return createBuffer(vk, vkDevice, &resourceBufferParams);
2190 Move<VkImage> createImageForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex)
2192 const VkImageCreateInfo resourceImageParams =
2194 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2195 DE_NULL, // const void* pNext;
2196 0u, // VkImageCreateFlags flags;
2197 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2198 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2199 { 8, 8, 1 }, // VkExtent3D extent;
2200 1u, // deUint32 mipLevels;
2201 1u, // deUint32 arraySize;
2202 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2203 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2204 getMatchingImageUsageFlags(resource.first), // VkImageUsageFlags usage;
2205 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2206 1u, // deUint32 queueFamilyCount;
2207 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2208 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2211 return createImage(vk, vkDevice, &resourceImageParams);
2214 void copyBufferToImage (const DeviceInterface& vk, const VkDevice& device, const VkQueue& queue, VkCommandBuffer cmdBuffer, VkBuffer buffer, VkImage image)
2216 const VkBufferImageCopy copyRegion =
2218 0u, // VkDeviceSize bufferOffset;
2219 0u, // deUint32 bufferRowLength;
2220 0u, // deUint32 bufferImageHeight;
2222 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
2223 0u, // deUint32 mipLevel;
2224 0u, // deUint32 baseArrayLayer;
2225 1u, // deUint32 layerCount;
2226 }, // VkImageSubresourceLayers imageSubresource;
2227 { 0, 0, 0 }, // VkOffset3D imageOffset;
2228 { 8, 8, 1 } // VkExtent3D imageExtent;
2231 // Copy buffer to image
2232 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
2234 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
2235 DE_NULL, // const void* pNext;
2236 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
2237 DE_NULL // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
2240 const VkImageMemoryBarrier imageBarriers[] =
2243 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2244 DE_NULL, // const void* pNext;
2245 DE_NULL, // VkAccessFlags srcAccessMask;
2246 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2247 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2248 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2249 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2250 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2251 image, // VkImage image;
2252 { // VkImageSubresourceRange subresourceRange;
2253 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2254 0u, // deUint32 baseMipLevel;
2255 1u, // deUint32 mipLevels;
2256 0u, // deUint32 baseArraySlice;
2257 1u // deUint32 arraySize;
2261 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2262 DE_NULL, // const void* pNext;
2263 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2264 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
2265 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2266 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
2267 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2268 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2269 image, // VkImage image;
2270 { // VkImageSubresourceRange subresourceRange;
2271 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2272 0u, // deUint32 baseMipLevel;
2273 1u, // deUint32 mipLevels;
2274 0u, // deUint32 baseArraySlice;
2275 1u // deUint32 arraySize;
2280 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &cmdBufferBeginInfo));
2281 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
2282 0u, DE_NULL, 1u, &imageBarriers[0]);
2283 vk.cmdCopyBufferToImage(cmdBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
2284 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
2285 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarriers[1]);
2287 VK_CHECK(vk.endCommandBuffer(cmdBuffer));
2290 const VkFenceCreateInfo fenceParams =
2292 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
2293 DE_NULL, // const void* pNext;
2294 0u, // VkFenceCreateFlags flags;
2297 const Unique<VkFence> fence (createFence(vk, device, &fenceParams));
2298 const VkSubmitInfo submitInfo =
2300 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
2301 DE_NULL, // const void* pNext;
2302 0u, // deUint32 waitSemaphoreCount;
2303 DE_NULL, // const VkSemaphore* pWaitSemaphores;
2304 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
2305 1u, // deUint32 commandBufferCount;
2306 &cmdBuffer, // const VkCommandBuffer* pCommandBuffers;
2307 0u, // deUint32 signalSemaphoreCount;
2308 DE_NULL // const VkSemaphore* pSignalSemaphores;
2311 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
2312 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
2316 TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance)
2318 const InstanceInterface& vkInstance = context.getInstanceInterface();
2319 const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice();
2320 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2321 // Create a dedicated logic device with required extensions enabled for this test case.
2322 const tcu::UVec2 renderSize (256, 256);
2323 const int testSpecificSeed = 31354125;
2324 const int seed = context.getTestContext().getCommandLine().getBaseSeed() ^ testSpecificSeed;
2325 bool supportsGeometry = false;
2326 bool supportsTessellation = false;
2327 bool hasTessellation = false;
2328 const bool hasPushConstants = !instance.pushConstants.empty();
2329 const deUint32 numResources = static_cast<deUint32>(instance.resources.inputs.size() + instance.resources.outputs.size());
2330 const bool needInterface = !instance.interfaces.empty();
2331 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2333 supportsGeometry = features.geometryShader == VK_TRUE;
2334 supportsTessellation = features.tessellationShader == VK_TRUE;
2335 hasTessellation = (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) ||
2336 (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2338 if (hasTessellation && !supportsTessellation)
2340 TCU_THROW(NotSupportedError, "Tessellation not supported");
2343 if ((instance.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT) &&
2346 TCU_THROW(NotSupportedError, "Geometry not supported");
2350 for (deUint32 featureNdx = 0; featureNdx < instance.requiredDeviceFeatures.size(); ++featureNdx)
2352 const string& feature = instance.requiredDeviceFeatures[featureNdx];
2354 if (feature == "shaderInt16")
2356 if (features.shaderInt16 != VK_TRUE)
2357 TCU_THROW(NotSupportedError, "Device feature not supported: shaderInt16");
2359 else if (feature == "shaderInt64")
2361 if (features.shaderInt64 != VK_TRUE)
2362 TCU_THROW(NotSupportedError, "Device feature not supported: shaderInt64");
2364 else if (feature == "shaderFloat64")
2366 if (features.shaderFloat64 != VK_TRUE)
2367 TCU_THROW(NotSupportedError, "Device feature not supported: shaderFloat64");
2371 TCU_THROW(InternalError, (std::string("Unimplemented physical device feature: ") + feature).c_str());
2376 // 16bit storage features
2378 if (!is16BitStorageFeaturesSupported(vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedFeatures.ext16BitStorage))
2379 TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
2382 // Variable Pointers features
2384 if (!isVariablePointersFeaturesSupported(vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedFeatures.extVariablePointers))
2385 TCU_THROW(NotSupportedError, "Requested Variable Pointer features not supported");
2387 if (instance.requestedFeatures.extVariablePointers)
2389 // The device doesn't have the vertexPipelineStoresAndAtomics feature, but the test requires the feature for
2390 // vertex, tesselation, and geometry stages.
2391 if (features.vertexPipelineStoresAndAtomics == DE_FALSE &&
2392 instance.requestedFeatures.coreFeatures.vertexPipelineStoresAndAtomics == DE_TRUE &&
2393 (instance.customizedStages & vk::VK_SHADER_STAGE_VERTEX_BIT ||
2394 instance.customizedStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT ||
2395 instance.customizedStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ||
2396 instance.customizedStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT))
2397 TCU_THROW(NotSupportedError, "This VK_KHR_variable_pointers extension test requires vertexPipelineStoresAndAtomics device feature.");
2399 // The device doesn't have the fragmentStoresAndAtomics feature, but the test requires this feature for the fragment stage.
2400 if (features.fragmentStoresAndAtomics == DE_FALSE &&
2401 instance.requestedFeatures.coreFeatures.fragmentStoresAndAtomics == DE_TRUE &&
2402 instance.customizedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2403 TCU_THROW(NotSupportedError, "This VK_KHR_variable_pointers extension test requires fragmentStoresAndAtomics device feature.");
2407 // defer device and other resource creation until after feature checks
2408 const Unique<VkDevice> vkDevice (createDeviceWithExtensions(context, queueFamilyIndex, context.getDeviceExtensions(), instance.requiredDeviceExtensions));
2409 const DeviceDriver vk (vkInstance, *vkDevice);
2410 const VkQueue queue = getDeviceQueue(vk, *vkDevice, queueFamilyIndex, 0);
2411 const de::UniquePtr<Allocator> allocatorUptr (createAllocator(vkInstance, vkPhysicalDevice, vk, *vkDevice));
2412 Allocator& allocator = *allocatorUptr;
2413 vector<ModuleHandleSp> modules;
2414 map<VkShaderStageFlagBits, VkShaderModule> moduleByStage;
2417 de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4);
2418 de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4);
2419 const Vec4 vertexData[] =
2421 // Upper left corner:
2422 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2423 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2424 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2426 // Upper right corner:
2427 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2428 Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2429 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2431 // Lower left corner:
2432 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2433 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2434 Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2436 // Lower right corner:
2437 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(),
2438 Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(),
2439 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec()
2441 const size_t singleVertexDataSize = 2 * sizeof(Vec4);
2442 const size_t vertexCount = sizeof(vertexData) / singleVertexDataSize;
2444 Move<VkBuffer> vertexInputBuffer;
2445 de::MovePtr<Allocation> vertexInputMemory;
2446 Move<VkBuffer> fragOutputBuffer;
2447 de::MovePtr<Allocation> fragOutputMemory;
2448 Move<VkImage> fragOutputImage;
2449 de::MovePtr<Allocation> fragOutputImageMemory;
2450 Move<VkImageView> fragOutputImageView;
2452 const VkBufferCreateInfo vertexBufferParams =
2454 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2455 DE_NULL, // const void* pNext;
2456 0u, // VkBufferCreateFlags flags;
2457 (VkDeviceSize)sizeof(vertexData), // VkDeviceSize size;
2458 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2459 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2460 1u, // deUint32 queueFamilyCount;
2461 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2463 const Unique<VkBuffer> vertexBuffer (createBuffer(vk, *vkDevice, &vertexBufferParams));
2464 const UniquePtr<Allocation> vertexBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
2466 VK_CHECK(vk.bindBufferMemory(*vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
2468 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
2469 const VkBufferCreateInfo readImageBufferParams =
2471 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2472 DE_NULL, // const void* pNext;
2473 0u, // VkBufferCreateFlags flags;
2474 imageSizeBytes, // VkDeviceSize size;
2475 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2476 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2477 1u, // deUint32 queueFamilyCount;
2478 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2480 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, *vkDevice, &readImageBufferParams));
2481 const UniquePtr<Allocation> readImageBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2483 VK_CHECK(vk.bindBufferMemory(*vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2485 VkImageCreateInfo imageParams =
2487 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2488 DE_NULL, // const void* pNext;
2489 0u, // VkImageCreateFlags flags;
2490 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2491 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2492 { renderSize.x(), renderSize.y(), 1 }, // VkExtent3D extent;
2493 1u, // deUint32 mipLevels;
2494 1u, // deUint32 arraySize;
2495 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2496 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2497 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2498 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2499 1u, // deUint32 queueFamilyCount;
2500 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2501 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2504 const Unique<VkImage> image (createImage(vk, *vkDevice, &imageParams));
2505 const UniquePtr<Allocation> imageMemory (allocator.allocate(getImageMemoryRequirements(vk, *vkDevice, *image), MemoryRequirement::Any));
2507 VK_CHECK(vk.bindImageMemory(*vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
2511 // The pipeline renders four triangles, each with three vertexes.
2512 // Test instantialization only provides four data points, each
2513 // for one triangle. So we need allocate space of three times of
2514 // input buffer's size.
2515 vector<deUint8> inputBufferBytes;
2516 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
2518 const deUint32 inputNumBytes = deUint32(inputBufferBytes.size() * 3);
2519 // Create an additional buffer and backing memory for one input variable.
2520 const VkBufferCreateInfo vertexInputParams =
2522 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2523 DE_NULL, // const void* pNext;
2524 0u, // VkBufferCreateFlags flags;
2525 inputNumBytes, // VkDeviceSize size;
2526 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2527 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2528 1u, // deUint32 queueFamilyCount;
2529 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2532 vertexInputBuffer = createBuffer(vk, *vkDevice, &vertexInputParams);
2533 vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *vertexInputBuffer), MemoryRequirement::HostVisible);
2534 VK_CHECK(vk.bindBufferMemory(*vkDevice, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset()));
2536 // Create an additional buffer and backing memory for an output variable.
2537 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
2538 const VkBufferCreateInfo fragOutputParams =
2540 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2541 DE_NULL, // const void* pNext;
2542 0u, // VkBufferCreateFlags flags;
2543 fragOutputImgSize, // VkDeviceSize size;
2544 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2545 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2546 1u, // deUint32 queueFamilyCount;
2547 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2549 fragOutputBuffer = createBuffer(vk, *vkDevice, &fragOutputParams);
2550 fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *fragOutputBuffer), MemoryRequirement::HostVisible);
2551 VK_CHECK(vk.bindBufferMemory(*vkDevice, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset()));
2553 // Create an additional image and backing memory for attachment.
2554 // Reuse the previous imageParams since we only need to change the image format.
2555 imageParams.format = instance.interfaces.getOutputType().getVkFormat();
2557 // Check the usage bits on the given image format are supported.
2558 requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.tiling, imageParams.usage);
2560 fragOutputImage = createImage(vk, *vkDevice, &imageParams);
2561 fragOutputImageMemory = allocator.allocate(getImageMemoryRequirements(vk, *vkDevice, *fragOutputImage), MemoryRequirement::Any);
2563 VK_CHECK(vk.bindImageMemory(*vkDevice, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset()));
2566 vector<VkAttachmentDescription> colorAttDescs;
2567 vector<VkAttachmentReference> colorAttRefs;
2569 const VkAttachmentDescription attDesc =
2571 0u, // VkAttachmentDescriptionFlags flags;
2572 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2573 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2574 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2575 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2576 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2577 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2578 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2579 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2581 colorAttDescs.push_back(attDesc);
2583 const VkAttachmentReference attRef =
2585 0u, // deUint32 attachment;
2586 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
2588 colorAttRefs.push_back(attRef);
2593 const VkAttachmentDescription attDesc =
2595 0u, // VkAttachmentDescriptionFlags flags;
2596 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
2597 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2598 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2599 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2600 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2601 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2602 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2603 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2605 colorAttDescs.push_back(attDesc);
2607 const VkAttachmentReference attRef =
2609 1u, // deUint32 attachment;
2610 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
2612 colorAttRefs.push_back(attRef);
2615 VkSubpassDescription subpassDesc =
2617 0u, // VkSubpassDescriptionFlags flags;
2618 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2619 0u, // deUint32 inputCount;
2620 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2621 1u, // deUint32 colorCount;
2622 colorAttRefs.data(), // const VkAttachmentReference* pColorAttachments;
2623 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2624 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
2625 0u, // deUint32 preserveCount;
2626 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
2629 VkRenderPassCreateInfo renderPassParams =
2631 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2632 DE_NULL, // const void* pNext;
2633 (VkRenderPassCreateFlags)0,
2634 1u, // deUint32 attachmentCount;
2635 colorAttDescs.data(), // const VkAttachmentDescription* pAttachments;
2636 1u, // deUint32 subpassCount;
2637 &subpassDesc, // const VkSubpassDescription* pSubpasses;
2638 0u, // deUint32 dependencyCount;
2639 DE_NULL, // const VkSubpassDependency* pDependencies;
2644 subpassDesc.colorAttachmentCount += 1;
2645 renderPassParams.attachmentCount += 1;
2648 const Unique<VkRenderPass> renderPass (createRenderPass(vk, *vkDevice, &renderPassParams));
2650 const VkImageViewCreateInfo colorAttViewParams =
2652 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2653 DE_NULL, // const void* pNext;
2654 0u, // VkImageViewCreateFlags flags;
2655 *image, // VkImage image;
2656 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2657 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2659 VK_COMPONENT_SWIZZLE_R,
2660 VK_COMPONENT_SWIZZLE_G,
2661 VK_COMPONENT_SWIZZLE_B,
2662 VK_COMPONENT_SWIZZLE_A
2663 }, // VkChannelMapping channels;
2665 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2666 0u, // deUint32 baseMipLevel;
2667 1u, // deUint32 mipLevels;
2668 0u, // deUint32 baseArrayLayer;
2669 1u, // deUint32 arraySize;
2670 }, // VkImageSubresourceRange subresourceRange;
2672 const Unique<VkImageView> colorAttView (createImageView(vk, *vkDevice, &colorAttViewParams));
2674 vector<VkImageView> attViews;
2675 attViews.push_back(*colorAttView);
2677 // Handle resources requested by the test instantiation.
2678 const deUint32 numInResources = static_cast<deUint32>(instance.resources.inputs.size());
2679 const deUint32 numOutResources = static_cast<deUint32>(instance.resources.outputs.size());
2680 // These variables should be placed out of the following if block to avoid deallocation after out of scope.
2681 vector<AllocationSp> inResourceMemories;
2682 vector<AllocationSp> outResourceMemories;
2683 vector<BufferHandleSp> inResourceBuffers;
2684 vector<BufferHandleSp> outResourceBuffers;
2685 vector<ImageHandleSp> inResourceImages;
2686 vector<ImageViewHandleSp> inResourceImageViews;
2687 vector<SamplerHandleSp> inResourceSamplers;
2688 Move<VkDescriptorPool> descriptorPool;
2689 Move<VkDescriptorSetLayout> setLayout;
2690 VkDescriptorSetLayout rawSetLayout = DE_NULL;
2691 VkDescriptorSet rawSet = DE_NULL;
2693 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, *vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
2696 const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, *vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2698 if (numResources != 0)
2700 vector<VkDescriptorSetLayoutBinding> setLayoutBindings;
2701 vector<VkDescriptorPoolSize> poolSizes;
2703 setLayoutBindings.reserve(numResources);
2704 poolSizes.reserve(numResources);
2706 // Process all input resources.
2707 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2709 const Resource& resource = instance.resources.inputs[inputNdx];
2711 const bool hasImage = (resource.first == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
2712 (resource.first == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2713 (resource.first == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2715 const bool hasSampler = (resource.first == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2716 (resource.first == VK_DESCRIPTOR_TYPE_SAMPLER) ||
2717 (resource.first == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2719 // Resource is a buffer
2720 if (!hasImage && !hasSampler)
2722 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, *vkDevice, resource, queueFamilyIndex);
2723 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *resourceBuffer), MemoryRequirement::HostVisible);
2725 VK_CHECK(vk.bindBufferMemory(*vkDevice, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2727 // Copy data to memory.
2729 const VkMappedMemoryRange range =
2731 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
2732 DE_NULL, // const void* pNext;
2733 resourceMemory->getMemory(), // VkDeviceMemory mem;
2734 0, // VkDeviceSize offset;
2735 VK_WHOLE_SIZE, // VkDeviceSize size;
2738 vector<deUint8> resourceBytes;
2739 resource.second->getBytes(resourceBytes);
2741 deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
2742 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
2745 inResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2746 inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2748 // Resource is an image
2751 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, *vkDevice, resource, queueFamilyIndex);
2752 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *resourceBuffer), MemoryRequirement::HostVisible);
2754 VK_CHECK(vk.bindBufferMemory(*vkDevice, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2756 // Copy data to memory.
2758 const VkMappedMemoryRange range =
2760 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
2761 DE_NULL, // const void* pNext;
2762 resourceMemory->getMemory(), // VkDeviceMemory mem;
2763 0, // VkDeviceSize offset;
2764 VK_WHOLE_SIZE, // VkDeviceSize size;
2767 vector<deUint8> resourceBytes;
2768 resource.second->getBytes(resourceBytes);
2770 deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
2771 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
2774 Move<VkImage> resourceImage = createImageForResource(vk, *vkDevice, resource, queueFamilyIndex);
2775 de::MovePtr<Allocation> resourceImageMemory = allocator.allocate(getImageMemoryRequirements(vk, *vkDevice, *resourceImage), MemoryRequirement::Any);
2777 VK_CHECK(vk.bindImageMemory(*vkDevice, *resourceImage, resourceImageMemory->getMemory(), resourceImageMemory->getOffset()));
2779 copyBufferToImage(vk, *vkDevice, queue, *cmdBuf, resourceBuffer.get(), resourceImage.get());
2781 inResourceMemories.push_back(AllocationSp(resourceImageMemory.release()));
2782 inResourceImages.push_back(ImageHandleSp(new ImageHandleUp(resourceImage)));
2785 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2786 const VkDescriptorSetLayoutBinding binding =
2788 inputNdx, // binding
2789 resource.first, // descriptorType
2790 1u, // descriptorCount
2791 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
2792 DE_NULL, // pImmutableSamplers
2794 setLayoutBindings.push_back(binding);
2796 // Note: the following code doesn't check and unify descriptors of the same type.
2797 const VkDescriptorPoolSize poolSize =
2799 resource.first, // type
2800 1u, // descriptorCount
2802 poolSizes.push_back(poolSize);
2805 // Process all output resources.
2806 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
2808 const Resource& resource = instance.resources.outputs[outputNdx];
2809 // Create buffer and allocate memory.
2810 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, *vkDevice, resource, queueFamilyIndex);
2811 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *resourceBuffer), MemoryRequirement::HostVisible);
2812 vector<deUint8> resourceBytes;
2814 VK_CHECK(vk.bindBufferMemory(*vkDevice, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2816 // Fill memory with all ones.
2817 const VkMappedMemoryRange range =
2819 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
2820 DE_NULL, // const void* pNext;
2821 resourceMemory->getMemory(), // VkDeviceMemory mem;
2822 0, // VkDeviceSize offset;
2823 VK_WHOLE_SIZE, // VkDeviceSize size;
2826 resource.second->getBytes(resourceBytes);
2827 deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resourceBytes.size());
2828 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
2830 outResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2831 outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2833 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2834 const VkDescriptorSetLayoutBinding binding =
2836 numInResources + outputNdx, // binding
2837 resource.first, // descriptorType
2838 1u, // descriptorCount
2839 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
2840 DE_NULL, // pImmutableSamplers
2842 setLayoutBindings.push_back(binding);
2844 // Note: the following code doesn't check and unify descriptors of the same type.
2845 const VkDescriptorPoolSize poolSize =
2847 resource.first, // type
2848 1u, // descriptorCount
2850 poolSizes.push_back(poolSize);
2853 // Create descriptor set layout, descriptor pool, and allocate descriptor set.
2854 const VkDescriptorSetLayoutCreateInfo setLayoutParams =
2856 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
2858 (VkDescriptorSetLayoutCreateFlags)0, // flags
2859 numResources, // bindingCount
2860 setLayoutBindings.data(), // pBindings
2862 setLayout = createDescriptorSetLayout(vk, *vkDevice, &setLayoutParams);
2863 rawSetLayout = *setLayout;
2865 const VkDescriptorPoolCreateInfo poolParams =
2867 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
2869 (VkDescriptorPoolCreateFlags)0, // flags
2871 numResources, // poolSizeCount
2872 poolSizes.data(), // pPoolSizes
2874 descriptorPool = createDescriptorPool(vk, *vkDevice, &poolParams);
2876 const VkDescriptorSetAllocateInfo setAllocParams =
2878 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
2880 *descriptorPool, // descriptorPool
2881 1u, // descriptorSetCount
2882 &rawSetLayout, // pSetLayouts
2884 VK_CHECK(vk.allocateDescriptorSets(*vkDevice, &setAllocParams, &rawSet));
2886 // Update descriptor set.
2887 vector<VkWriteDescriptorSet> writeSpecs;
2888 vector<VkDescriptorBufferInfo> dBufferInfos;
2889 vector<VkDescriptorImageInfo> dImageInfos;
2891 writeSpecs.reserve(numResources);
2892 dBufferInfos.reserve(numResources);
2893 dImageInfos.reserve(numResources);
2895 deUint32 imgResourceNdx = 0u;
2896 deUint32 bufResourceNdx = 0u;
2898 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2900 const Resource& resource = instance.resources.inputs[inputNdx];
2902 const bool hasImage = (resource.first == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
2903 (resource.first == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2904 (resource.first == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2906 const bool hasSampler = (resource.first == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2907 (resource.first == VK_DESCRIPTOR_TYPE_SAMPLER) ||
2908 (resource.first == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2910 // Create image view and sampler
2911 if (hasImage || hasSampler)
2913 if (resource.first != VK_DESCRIPTOR_TYPE_SAMPLER)
2915 const VkImageViewCreateInfo imgViewParams =
2917 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2918 DE_NULL, // const void* pNext;
2919 0u, // VkImageViewCreateFlags flags;
2920 **inResourceImages[imgResourceNdx++], // VkImage image;
2921 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2922 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2924 VK_COMPONENT_SWIZZLE_R,
2925 VK_COMPONENT_SWIZZLE_G,
2926 VK_COMPONENT_SWIZZLE_B,
2927 VK_COMPONENT_SWIZZLE_A
2928 }, // VkChannelMapping channels;
2930 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2931 0u, // deUint32 baseMipLevel;
2932 1u, // deUint32 mipLevels;
2933 0u, // deUint32 baseArrayLayer;
2934 1u, // deUint32 arraySize;
2935 }, // VkImageSubresourceRange subresourceRange;
2938 Move<VkImageView> imgView (createImageView(vk, *vkDevice, &imgViewParams));
2939 inResourceImageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imgView)));
2944 const VkSamplerCreateInfo samplerParams =
2946 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
2947 DE_NULL, // const void* pNext;
2948 0, // VkSamplerCreateFlags flags;
2949 VK_FILTER_NEAREST, // VkFilter magFilter:
2950 VK_FILTER_NEAREST, // VkFilter minFilter;
2951 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
2952 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
2953 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
2954 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
2955 0.0f, // float mipLodBias;
2956 VK_FALSE, // VkBool32 anistoropyÉnable;
2957 1.0f, // float maxAnisotropy;
2958 VK_FALSE, // VkBool32 compareEnable;
2959 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
2960 0.0f, // float minLod;
2961 0.0f, // float maxLod;
2962 VK_BORDER_COLOR_INT_OPAQUE_BLACK, // VkBorderColor borderColor;
2963 VK_FALSE // VkBool32 unnormalizedCoordinates;
2966 Move<VkSampler> sampler (createSampler(vk, *vkDevice, &samplerParams));
2967 inResourceSamplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler)));
2971 // Create descriptor buffer and image infos
2972 switch (resource.first)
2974 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
2975 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
2977 const VkDescriptorBufferInfo bufInfo =
2979 **inResourceBuffers[bufResourceNdx++], // buffer
2981 VK_WHOLE_SIZE, // size
2983 dBufferInfos.push_back(bufInfo);
2986 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
2987 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2989 const VkDescriptorImageInfo imgInfo =
2992 **inResourceImageViews.back(), // imageView
2993 VK_IMAGE_LAYOUT_GENERAL // imageLayout
2995 dImageInfos.push_back(imgInfo);
2998 case VK_DESCRIPTOR_TYPE_SAMPLER:
3000 const VkDescriptorImageInfo imgInfo =
3002 **inResourceSamplers.back(), // sampler
3003 DE_NULL, // imageView
3004 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3006 dImageInfos.push_back(imgInfo);
3009 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3012 const VkDescriptorImageInfo imgInfo =
3014 **inResourceSamplers.back(), // sampler
3015 **inResourceImageViews.back(), // imageView
3016 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3018 dImageInfos.push_back(imgInfo);
3022 DE_FATAL("Not implemented");
3025 const VkWriteDescriptorSet writeSpec = {
3026 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3029 inputNdx, // binding
3030 0, // dstArrayElement
3031 1u, // descriptorCount
3032 instance.resources.inputs[inputNdx].first, // descriptorType
3033 ( (hasImage | hasSampler) ? &dImageInfos.back() : DE_NULL), // pImageInfo
3034 (!(hasImage | hasSampler) ? &dBufferInfos.back() : DE_NULL), // pBufferInfo
3035 DE_NULL, // pTexelBufferView
3037 writeSpecs.push_back(writeSpec);
3040 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3042 const VkDescriptorBufferInfo bufInfo =
3044 **outResourceBuffers[outputNdx], // buffer
3046 VK_WHOLE_SIZE, // size
3048 dBufferInfos.push_back(bufInfo);
3050 const VkWriteDescriptorSet writeSpec = {
3051 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3054 numInResources + outputNdx, // binding
3055 0, // dstArrayElement
3056 1u, // descriptorCount
3057 instance.resources.outputs[outputNdx].first, // descriptorType
3058 DE_NULL, // pImageInfo
3059 &dBufferInfos.back(), // pBufferInfo
3060 DE_NULL, // pTexelBufferView
3062 writeSpecs.push_back(writeSpec);
3064 vk.updateDescriptorSets(*vkDevice, numResources, writeSpecs.data(), 0, DE_NULL);
3068 VkPipelineLayoutCreateInfo pipelineLayoutParams =
3070 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3071 DE_NULL, // const void* pNext;
3072 (VkPipelineLayoutCreateFlags)0,
3073 0u, // deUint32 descriptorSetCount;
3074 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
3075 0u, // deUint32 pushConstantRangeCount;
3076 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
3079 VkPushConstantRange pushConstantRange =
3081 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags stageFlags;
3082 0, // uint32_t offset;
3083 0, // uint32_t size;
3085 if (hasPushConstants)
3087 vector<deUint8> pushConstantsBytes;
3088 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3090 pushConstantRange.size = static_cast<deUint32>(pushConstantsBytes.size());
3091 pipelineLayoutParams.pushConstantRangeCount = 1;
3092 pipelineLayoutParams.pPushConstantRanges = &pushConstantRange;
3094 if (numResources != 0)
3096 // Update pipeline layout with the descriptor set layout.
3097 pipelineLayoutParams.setLayoutCount = 1;
3098 pipelineLayoutParams.pSetLayouts = &rawSetLayout;
3100 const Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, *vkDevice, &pipelineLayoutParams));
3103 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
3104 // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
3105 vector<vector<VkSpecializationMapEntry> > specConstantEntries;
3106 vector<VkSpecializationInfo> specializationInfos;
3107 createPipelineShaderStages(vk, *vkDevice, instance, context, modules, shaderStageParams);
3109 // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
3110 specConstantEntries.reserve(shaderStageParams.size());
3111 specializationInfos.reserve(shaderStageParams.size());
3113 // Patch the specialization info field in PipelineShaderStageCreateInfos.
3114 for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
3116 const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);
3118 if (stageIt != instance.specConstants.end())
3120 const size_t numSpecConstants = stageIt->second.size();
3121 vector<VkSpecializationMapEntry> entries;
3122 VkSpecializationInfo specInfo;
3124 entries.resize(numSpecConstants);
3126 // Only support 32-bit integers as spec constants now. And their constant IDs are numbered sequentially starting from 0.
3127 for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
3129 entries[ndx].constantID = (deUint32)ndx;
3130 entries[ndx].offset = deUint32(ndx * sizeof(deInt32));
3131 entries[ndx].size = sizeof(deInt32);
3134 specConstantEntries.push_back(entries);
3136 specInfo.mapEntryCount = (deUint32)numSpecConstants;
3137 specInfo.pMapEntries = specConstantEntries.back().data();
3138 specInfo.dataSize = numSpecConstants * sizeof(deInt32);
3139 specInfo.pData = stageIt->second.data();
3140 specializationInfos.push_back(specInfo);
3142 stageInfo->pSpecializationInfo = &specializationInfos.back();
3145 const VkPipelineDepthStencilStateCreateInfo depthStencilParams =
3147 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
3148 DE_NULL, // const void* pNext;
3149 (VkPipelineDepthStencilStateCreateFlags)0,
3150 DE_FALSE, // deUint32 depthTestEnable;
3151 DE_FALSE, // deUint32 depthWriteEnable;
3152 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
3153 DE_FALSE, // deUint32 depthBoundsTestEnable;
3154 DE_FALSE, // deUint32 stencilTestEnable;
3156 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
3157 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
3158 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
3159 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
3160 0u, // deUint32 stencilCompareMask;
3161 0u, // deUint32 stencilWriteMask;
3162 0u, // deUint32 stencilReference;
3163 }, // VkStencilOpState front;
3165 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
3166 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
3167 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
3168 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
3169 0u, // deUint32 stencilCompareMask;
3170 0u, // deUint32 stencilWriteMask;
3171 0u, // deUint32 stencilReference;
3172 }, // VkStencilOpState back;
3173 -1.0f, // float minDepthBounds;
3174 +1.0f, // float maxDepthBounds;
3176 const VkViewport viewport0 =
3178 0.0f, // float originX;
3179 0.0f, // float originY;
3180 (float)renderSize.x(), // float width;
3181 (float)renderSize.y(), // float height;
3182 0.0f, // float minDepth;
3183 1.0f, // float maxDepth;
3185 const VkRect2D scissor0 =
3190 }, // VkOffset2D offset;
3192 renderSize.x(), // deInt32 width;
3193 renderSize.y(), // deInt32 height;
3194 }, // VkExtent2D extent;
3196 const VkPipelineViewportStateCreateInfo viewportParams =
3198 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
3199 DE_NULL, // const void* pNext;
3200 (VkPipelineViewportStateCreateFlags)0,
3201 1u, // deUint32 viewportCount;
3206 const VkSampleMask sampleMask = ~0u;
3207 const VkPipelineMultisampleStateCreateInfo multisampleParams =
3209 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
3210 DE_NULL, // const void* pNext;
3211 (VkPipelineMultisampleStateCreateFlags)0,
3212 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterSamples;
3213 DE_FALSE, // deUint32 sampleShadingEnable;
3214 0.0f, // float minSampleShading;
3215 &sampleMask, // const VkSampleMask* pSampleMask;
3216 DE_FALSE, // VkBool32 alphaToCoverageEnable;
3217 DE_FALSE, // VkBool32 alphaToOneEnable;
3219 const VkPipelineRasterizationStateCreateInfo rasterParams =
3221 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
3222 DE_NULL, // const void* pNext;
3223 (VkPipelineRasterizationStateCreateFlags)0,
3224 DE_FALSE, // deUint32 depthClampEnable;
3225 DE_FALSE, // deUint32 rasterizerDiscardEnable;
3226 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
3227 VK_CULL_MODE_NONE, // VkCullMode cullMode;
3228 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
3229 VK_FALSE, // VkBool32 depthBiasEnable;
3230 0.0f, // float depthBias;
3231 0.0f, // float depthBiasClamp;
3232 0.0f, // float slopeScaledDepthBias;
3233 1.0f, // float lineWidth;
3235 const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
3236 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyParams =
3238 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
3239 DE_NULL, // const void* pNext;
3240 (VkPipelineInputAssemblyStateCreateFlags)0,
3241 topology, // VkPrimitiveTopology topology;
3242 DE_FALSE, // deUint32 primitiveRestartEnable;
3245 vector<VkVertexInputBindingDescription> vertexBindings;
3246 vector<VkVertexInputAttributeDescription> vertexAttribs;
3248 const VkVertexInputBindingDescription vertexBinding0 =
3250 0u, // deUint32 binding;
3251 deUint32(singleVertexDataSize), // deUint32 strideInBytes;
3252 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
3254 vertexBindings.push_back(vertexBinding0);
3257 VkVertexInputAttributeDescription attr0 =
3259 0u, // deUint32 location;
3260 0u, // deUint32 binding;
3261 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3262 0u // deUint32 offsetInBytes;
3264 vertexAttribs.push_back(attr0);
3266 VkVertexInputAttributeDescription attr1 =
3268 1u, // deUint32 location;
3269 0u, // deUint32 binding;
3270 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3271 sizeof(Vec4), // deUint32 offsetInBytes;
3273 vertexAttribs.push_back(attr1);
3276 // If the test instantiation has additional input/output interface variables, we need to create additional bindings.
3277 // Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1
3278 // with location #2.
3281 const VkVertexInputBindingDescription vertexBinding1 =
3283 1u, // deUint32 binding;
3284 instance.interfaces.getInputType().getNumBytes(), // deUint32 strideInBytes;
3285 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
3287 vertexBindings.push_back(vertexBinding1);
3289 VkVertexInputAttributeDescription attr =
3291 2u, // deUint32 location;
3292 1u, // deUint32 binding;
3293 instance.interfaces.getInputType().getVkFormat(), // VkFormat format;
3294 0, // deUint32 offsetInBytes;
3296 vertexAttribs.push_back(attr);
3299 VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3301 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
3302 DE_NULL, // const void* pNext;
3303 (VkPipelineVertexInputStateCreateFlags)0,
3304 1u, // deUint32 bindingCount;
3305 vertexBindings.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
3306 2u, // deUint32 attributeCount;
3307 vertexAttribs.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
3312 vertexInputStateParams.vertexBindingDescriptionCount += 1;
3313 vertexInputStateParams.vertexAttributeDescriptionCount += 1;
3316 vector<VkPipelineColorBlendAttachmentState> attBlendStates;
3317 const VkPipelineColorBlendAttachmentState attBlendState =
3319 DE_FALSE, // deUint32 blendEnable;
3320 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
3321 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
3322 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
3323 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
3324 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
3325 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
3326 (VK_COLOR_COMPONENT_R_BIT|
3327 VK_COLOR_COMPONENT_G_BIT|
3328 VK_COLOR_COMPONENT_B_BIT|
3329 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask;
3331 attBlendStates.push_back(attBlendState);
3334 attBlendStates.push_back(attBlendState);
3336 VkPipelineColorBlendStateCreateInfo blendParams =
3338 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
3339 DE_NULL, // const void* pNext;
3340 (VkPipelineColorBlendStateCreateFlags)0,
3341 DE_FALSE, // VkBool32 logicOpEnable;
3342 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
3343 1u, // deUint32 attachmentCount;
3344 attBlendStates.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
3345 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
3349 blendParams.attachmentCount += 1;
3351 const VkPipelineTessellationStateCreateInfo tessellationState =
3353 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
3355 (VkPipelineTessellationStateCreateFlags)0,
3359 const VkPipelineTessellationStateCreateInfo* tessellationInfo = hasTessellation ? &tessellationState: DE_NULL;
3360 const VkGraphicsPipelineCreateInfo pipelineParams =
3362 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
3363 DE_NULL, // const void* pNext;
3364 0u, // VkPipelineCreateFlags flags;
3365 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
3366 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
3367 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
3368 &inputAssemblyParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
3369 tessellationInfo, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
3370 &viewportParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
3371 &rasterParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
3372 &multisampleParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
3373 &depthStencilParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
3374 &blendParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
3375 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
3376 *pipelineLayout, // VkPipelineLayout layout;
3377 *renderPass, // VkRenderPass renderPass;
3378 0u, // deUint32 subpass;
3379 DE_NULL, // VkPipeline basePipelineHandle;
3380 0u, // deInt32 basePipelineIndex;
3383 const Unique<VkPipeline> pipeline (createGraphicsPipeline(vk, *vkDevice, DE_NULL, &pipelineParams));
3387 const VkImageViewCreateInfo fragOutputViewParams =
3389 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3390 DE_NULL, // const void* pNext;
3391 0u, // VkImageViewCreateFlags flags;
3392 *fragOutputImage, // VkImage image;
3393 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3394 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
3396 VK_COMPONENT_SWIZZLE_R,
3397 VK_COMPONENT_SWIZZLE_G,
3398 VK_COMPONENT_SWIZZLE_B,
3399 VK_COMPONENT_SWIZZLE_A
3400 }, // VkChannelMapping channels;
3402 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
3403 0u, // deUint32 baseMipLevel;
3404 1u, // deUint32 mipLevels;
3405 0u, // deUint32 baseArrayLayer;
3406 1u, // deUint32 arraySize;
3407 }, // VkImageSubresourceRange subresourceRange;
3409 fragOutputImageView = createImageView(vk, *vkDevice, &fragOutputViewParams);
3410 attViews.push_back(*fragOutputImageView);
3414 VkFramebufferCreateInfo framebufferParams =
3416 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
3417 DE_NULL, // const void* pNext;
3418 (VkFramebufferCreateFlags)0,
3419 *renderPass, // VkRenderPass renderPass;
3420 1u, // deUint32 attachmentCount;
3421 attViews.data(), // const VkImageView* pAttachments;
3422 (deUint32)renderSize.x(), // deUint32 width;
3423 (deUint32)renderSize.y(), // deUint32 height;
3424 1u, // deUint32 layers;
3428 framebufferParams.attachmentCount += 1;
3430 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, *vkDevice, &framebufferParams));
3432 const VkCommandBufferBeginInfo cmdBufBeginParams =
3434 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
3435 DE_NULL, // const void* pNext;
3436 (VkCommandBufferUsageFlags)0,
3437 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3441 VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginParams));
3444 const VkMemoryBarrier vertFlushBarrier =
3446 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
3447 DE_NULL, // const void* pNext;
3448 VK_ACCESS_HOST_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3449 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkMemoryInputFlags inputMask;
3451 vector<VkImageMemoryBarrier> colorAttBarriers;
3453 VkImageMemoryBarrier imgBarrier =
3455 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3456 DE_NULL, // const void* pNext;
3457 0u, // VkMemoryOutputFlags outputMask;
3458 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryInputFlags inputMask;
3459 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3460 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
3461 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3462 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3463 *image, // VkImage image;
3465 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
3466 0u, // deUint32 baseMipLevel;
3467 1u, // deUint32 mipLevels;
3468 0u, // deUint32 baseArraySlice;
3469 1u, // deUint32 arraySize;
3470 } // VkImageSubresourceRange subresourceRange;
3472 colorAttBarriers.push_back(imgBarrier);
3475 imgBarrier.image = *fragOutputImage;
3476 colorAttBarriers.push_back(imgBarrier);
3477 vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, colorAttBarriers.data());
3481 vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, colorAttBarriers.data());
3486 vector<VkClearValue> clearValue;
3487 clearValue.push_back(makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f));
3490 clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0));
3492 VkRenderPassBeginInfo passBeginParams =
3494 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
3495 DE_NULL, // const void* pNext;
3496 *renderPass, // VkRenderPass renderPass;
3497 *framebuffer, // VkFramebuffer framebuffer;
3498 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
3499 1u, // deUint32 clearValueCount;
3500 clearValue.data(), // const VkClearValue* pClearValues;
3504 passBeginParams.clearValueCount += 1;
3506 vk.cmdBeginRenderPass(*cmdBuf, &passBeginParams, VK_SUBPASS_CONTENTS_INLINE);
3509 vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
3511 const VkDeviceSize bindingOffset = 0;
3512 vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3516 const VkDeviceSize bindingOffset = 0;
3517 vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset);
3519 if (hasPushConstants)
3521 vector<deUint8> pushConstantsBytes;
3522 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3524 const deUint32 size = static_cast<deUint32>(pushConstantsBytes.size());
3525 const void* data = &pushConstantsBytes.front();
3527 vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
3529 if (numResources != 0)
3531 // Bind to set number 0.
3532 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL);
3534 vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/);
3535 vk.cmdEndRenderPass(*cmdBuf);
3538 vector<VkImageMemoryBarrier> renderFinishBarrier;
3539 VkImageMemoryBarrier imgBarrier =
3541 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3542 DE_NULL, // const void* pNext;
3543 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3544 VK_ACCESS_TRANSFER_READ_BIT, // VkMemoryInputFlags inputMask;
3545 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
3546 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
3547 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3548 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3549 *image, // VkImage image;
3551 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
3552 0u, // deUint32 baseMipLevel;
3553 1u, // deUint32 mipLevels;
3554 0u, // deUint32 baseArraySlice;
3555 1u, // deUint32 arraySize;
3556 } // VkImageSubresourceRange subresourceRange;
3558 renderFinishBarrier.push_back(imgBarrier);
3562 imgBarrier.image = *fragOutputImage;
3563 renderFinishBarrier.push_back(imgBarrier);
3564 vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 2, renderFinishBarrier.data());
3568 vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, renderFinishBarrier.data());
3573 const VkBufferImageCopy copyParams =
3575 (VkDeviceSize)0u, // VkDeviceSize bufferOffset;
3576 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
3577 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
3579 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
3580 0u, // deUint32 mipLevel;
3581 0u, // deUint32 arrayLayer;
3582 1u, // deUint32 arraySize;
3583 }, // VkImageSubresourceCopy imageSubresource;
3584 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
3585 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
3587 vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
3591 vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, ©Params);
3596 vector<VkBufferMemoryBarrier> cpFinishBarriers;
3597 VkBufferMemoryBarrier copyFinishBarrier =
3599 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
3600 DE_NULL, // const void* pNext;
3601 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3602 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
3603 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3604 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3605 *readImageBuffer, // VkBuffer buffer;
3606 0u, // VkDeviceSize offset;
3607 imageSizeBytes // VkDeviceSize size;
3609 cpFinishBarriers.push_back(copyFinishBarrier);
3613 copyFinishBarrier.buffer = *fragOutputBuffer;
3614 copyFinishBarrier.size = VK_WHOLE_SIZE;
3615 cpFinishBarriers.push_back(copyFinishBarrier);
3617 vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 2, cpFinishBarriers.data(), 0, (const VkImageMemoryBarrier*)DE_NULL);
3621 vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, cpFinishBarriers.data(), 0, (const VkImageMemoryBarrier*)DE_NULL);
3625 VK_CHECK(vk.endCommandBuffer(*cmdBuf));
3627 // Upload vertex data
3629 const VkMappedMemoryRange range =
3631 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3632 DE_NULL, // const void* pNext;
3633 vertexBufferMemory->getMemory(), // VkDeviceMemory mem;
3634 0, // VkDeviceSize offset;
3635 (VkDeviceSize)sizeof(vertexData), // VkDeviceSize size;
3637 void* vertexBufPtr = vertexBufferMemory->getHostPtr();
3639 deMemcpy(vertexBufPtr, &vertexData[0], sizeof(vertexData));
3640 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
3645 vector<deUint8> inputBufferBytes;
3646 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3648 const deUint32 typNumBytes = instance.interfaces.getInputType().getNumBytes();
3649 const deUint32 bufNumBytes = static_cast<deUint32>(inputBufferBytes.size());
3651 // Require that the test instantation provides four output values.
3652 DE_ASSERT(bufNumBytes == 4 * typNumBytes);
3654 // We have four triangles. Because interpolation happens before executing the fragment shader,
3655 // we need to provide the same vertex attribute for the same triangle. That means, duplicate each
3656 // value three times for all four values.
3658 const deUint8* provided = static_cast<const deUint8*>(&inputBufferBytes.front());
3659 vector<deUint8> data;
3661 data.reserve(3 * bufNumBytes);
3663 for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes)
3664 for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
3665 for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx)
3666 data.push_back(provided[offset + byteNdx]);
3668 deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size());
3670 const VkMappedMemoryRange range =
3672 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3673 DE_NULL, // const void* pNext;
3674 vertexInputMemory->getMemory(), // VkDeviceMemory mem;
3675 0, // VkDeviceSize offset;
3676 VK_WHOLE_SIZE, // VkDeviceSize size;
3679 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
3682 // Submit & wait for completion
3684 const VkFenceCreateInfo fenceParams =
3686 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
3687 DE_NULL, // const void* pNext;
3688 0u, // VkFenceCreateFlags flags;
3690 const Unique<VkFence> fence (createFence(vk, *vkDevice, &fenceParams));
3691 const VkSubmitInfo submitInfo =
3693 VK_STRUCTURE_TYPE_SUBMIT_INFO,
3696 (const VkSemaphore*)DE_NULL,
3697 (const VkPipelineStageFlags*)DE_NULL,
3701 (const VkSemaphore*)DE_NULL,
3704 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
3705 VK_CHECK(vk.waitForFences(*vkDevice, 1u, &fence.get(), DE_TRUE, ~0ull));
3708 const void* imagePtr = readImageBufferMemory->getHostPtr();
3709 const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
3710 renderSize.x(), renderSize.y(), 1, imagePtr);
3713 const VkMappedMemoryRange range =
3715 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3716 DE_NULL, // const void* pNext;
3717 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
3718 0, // VkDeviceSize offset;
3719 imageSizeBytes, // VkDeviceSize size;
3722 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3723 context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer);
3728 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
3729 const VkMappedMemoryRange range =
3731 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3732 DE_NULL, // const void* pNext;
3733 fragOutputMemory->getMemory(), // VkDeviceMemory mem;
3734 0, // VkDeviceSize offset;
3735 fragOutputImgSize, // VkDeviceSize size;
3738 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3741 { // Make sure all output resources are ready.
3742 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3744 const VkMappedMemoryRange range =
3746 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3747 DE_NULL, // const void* pNext;
3748 outResourceMemories[outputNdx]->getMemory(), // VkDeviceMemory mem;
3749 0, // VkDeviceSize offset;
3750 VK_WHOLE_SIZE, // VkDeviceSize size;
3753 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3757 const RGBA threshold(1, 1, 1, 1);
3759 const RGBA upperLeft(pixelBuffer.getPixel(1, 1));
3760 if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold))
3761 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch"));
3763 const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1));
3764 if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold))
3765 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch"));
3767 const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1));
3768 if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold))
3769 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch"));
3771 const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1));
3772 if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold))
3773 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch"));
3775 // Check that the contents in the ouput variable matches expected.
3778 vector<deUint8> inputBufferBytes;
3779 vector<deUint8> outputBufferBytes;
3781 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3782 instance.interfaces.getOutputBuffer()->getBytes(outputBufferBytes);
3784 const IFDataType& outputType = instance.interfaces.getOutputType();
3785 const void* inputData = &inputBufferBytes.front();
3786 const void* outputData = &outputBufferBytes.front();
3787 vector<std::pair<int, int> > positions;
3788 const tcu::ConstPixelBufferAccess fragOutputBufferAccess (outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr());
3790 positions.push_back(std::make_pair(1, 1));
3791 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1));
3792 positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1));
3793 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1));
3795 for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx)
3797 const int x = positions[posNdx].first;
3798 const int y = positions[posNdx].second;
3801 if (outputType.elementType == NUMBERTYPE_FLOAT32)
3803 const float* expected = static_cast<const float*>(outputData) + posNdx * outputType.numElements;
3804 const float* actual = static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y));
3806 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3807 if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
3810 else if (outputType.elementType == NUMBERTYPE_INT32)
3812 const deInt32* expected = static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements;
3813 const deInt32* actual = static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3815 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3816 if (expected[eleNdx] != actual[eleNdx])
3819 else if (outputType.elementType == NUMBERTYPE_UINT32)
3821 const deUint32* expected = static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements;
3822 const deUint32* actual = static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3824 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3825 if (expected[eleNdx] != actual[eleNdx])
3828 else if (outputType.elementType == NUMBERTYPE_FLOAT16)
3830 const float* original = static_cast<const float*>(inputData) + posNdx * outputType.numElements;
3831 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3833 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3834 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
3837 else if (outputType.elementType == NUMBERTYPE_INT16)
3839 const deInt16* expected = static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements;
3840 const deInt16* actual = static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3842 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3843 if (expected[eleNdx] != actual[eleNdx])
3846 else if (outputType.elementType == NUMBERTYPE_UINT16)
3848 const deUint16* expected = static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements;
3849 const deUint16* actual = static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3851 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3852 if (expected[eleNdx] != actual[eleNdx])
3856 DE_ASSERT(0 && "unhandled type");
3860 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch"));
3864 // Check the contents in output resources match with expected.
3865 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3867 const BufferSp& expected = instance.resources.outputs[outputNdx].second;
3869 if (instance.resources.verifyIO != DE_NULL)
3871 if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog()))
3872 return tcu::TestStatus::fail("Resource returned doesn't match with expected");
3876 vector<deUint8> expectedBytes;
3877 expected->getBytes(expectedBytes);
3879 if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
3880 return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
3884 return TestStatus::pass("Rendered output matches input");
3887 void createTestsForAllStages (const std::string& name,
3888 const RGBA (&inputColors)[4],
3889 const RGBA (&outputColors)[4],
3890 const map<string, string>& testCodeFragments,
3891 const vector<deInt32>& specConstants,
3892 const PushConstants& pushConstants,
3893 const GraphicsResources& resources,
3894 const GraphicsInterfaces& interfaces,
3895 const vector<string>& extensions,
3896 const vector<string>& features,
3897 VulkanFeatures vulkanFeatures,
3898 tcu::TestCaseGroup* tests,
3899 const qpTestResult failResult,
3900 const string& failMessageTemplate)
3902 const ShaderElement vertFragPipelineStages[] =
3904 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3905 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3908 const ShaderElement tessPipelineStages[] =
3910 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3911 ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
3912 ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
3913 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3916 const ShaderElement geomPipelineStages[] =
3918 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3919 ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT),
3920 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3923 StageToSpecConstantMap specConstantMap;
3925 specConstantMap[VK_SHADER_STAGE_VERTEX_BIT] = specConstants;
3926 addFunctionCaseWithPrograms<InstanceContext>(
3927 tests, name + "_vert", "", addShaderCodeCustomVertex, runAndVerifyDefaultPipeline,
3928 createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
3929 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_VERTEX_BIT, failResult, failMessageTemplate));
3931 specConstantMap.clear();
3932 specConstantMap[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = specConstants;
3933 addFunctionCaseWithPrograms<InstanceContext>(
3934 tests, name + "_tessc", "", addShaderCodeCustomTessControl, runAndVerifyDefaultPipeline,
3935 createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
3936 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, failResult, failMessageTemplate));
3938 specConstantMap.clear();
3939 specConstantMap[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = specConstants;
3940 addFunctionCaseWithPrograms<InstanceContext>(
3941 tests, name + "_tesse", "", addShaderCodeCustomTessEval, runAndVerifyDefaultPipeline,
3942 createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
3943 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, failResult, failMessageTemplate));
3945 specConstantMap.clear();
3946 specConstantMap[VK_SHADER_STAGE_GEOMETRY_BIT] = specConstants;
3947 addFunctionCaseWithPrograms<InstanceContext>(
3948 tests, name + "_geom", "", addShaderCodeCustomGeometry, runAndVerifyDefaultPipeline,
3949 createInstanceContext(geomPipelineStages, inputColors, outputColors, testCodeFragments,
3950 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_GEOMETRY_BIT, failResult, failMessageTemplate));
3952 specConstantMap.clear();
3953 specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = specConstants;
3954 addFunctionCaseWithPrograms<InstanceContext>(
3955 tests, name + "_frag", "", addShaderCodeCustomFragment, runAndVerifyDefaultPipeline,
3956 createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
3957 specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, vk::VK_SHADER_STAGE_FRAGMENT_BIT, failResult, failMessageTemplate));
3960 void addTessCtrlTest(tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
3962 RGBA defaultColors[4];
3963 getDefaultColors(defaultColors);
3964 const ShaderElement pipelineStages[] =
3966 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3967 ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
3968 ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
3969 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3972 addFunctionCaseWithPrograms<InstanceContext>(
3973 group, name, "", addShaderCodeCustomTessControl,
3974 runAndVerifyDefaultPipeline, createInstanceContext(
3975 pipelineStages, defaultColors, defaultColors, fragments,
3976 StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
3977 GraphicsInterfaces(), vector<string>(), vector<string>(),
3978 VulkanFeatures(), vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));