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 default: DE_ASSERT(0 && "not implemented");
183 return (VkBufferUsageFlagBits)0;
186 static void requireFormatUsageSupport(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageUsageFlags requiredUsageFlags)
188 VkFormatProperties properties;
190 vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
192 if ((requiredUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
194 if ((properties.bufferFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
195 TCU_THROW(NotSupportedError, "Image format cannot be used as color attachment");
196 requiredUsageFlags ^= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
200 if ((requiredUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0)
202 if ((properties.bufferFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) == 0)
203 TCU_THROW(NotSupportedError, "Image format cannot be used as transfer source");
204 requiredUsageFlags ^= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
208 DE_ASSERT(!requiredUsageFlags && "checking other image usage bits not supported yet");
211 InstanceContext::InstanceContext (const RGBA (&inputs)[4],
212 const RGBA (&outputs)[4],
213 const map<string, string>& testCodeFragments_,
214 const StageToSpecConstantMap& specConstants_,
215 const PushConstants& pushConsants_,
216 const GraphicsResources& resources_,
217 const GraphicsInterfaces& interfaces_,
218 const vector<string>& extensions_,
219 const vector<string>& features_,
220 ExtensionFeatures extensionFeatures_)
221 : testCodeFragments (testCodeFragments_)
222 , specConstants (specConstants_)
223 , hasTessellation (false)
224 , requiredStages (static_cast<VkShaderStageFlagBits>(0))
225 , requiredDeviceExtensions (extensions_)
226 , requiredDeviceFeatures (features_)
227 , requestedExtensionFeatures (extensionFeatures_)
228 , pushConstants (pushConsants_)
229 , resources (resources_)
230 , interfaces (interfaces_)
231 , failResult (QP_TEST_RESULT_FAIL)
232 , failMessageTemplate ("${reason}")
234 inputColors[0] = inputs[0];
235 inputColors[1] = inputs[1];
236 inputColors[2] = inputs[2];
237 inputColors[3] = inputs[3];
239 outputColors[0] = outputs[0];
240 outputColors[1] = outputs[1];
241 outputColors[2] = outputs[2];
242 outputColors[3] = outputs[3];
245 InstanceContext::InstanceContext (const InstanceContext& other)
246 : moduleMap (other.moduleMap)
247 , testCodeFragments (other.testCodeFragments)
248 , specConstants (other.specConstants)
249 , hasTessellation (other.hasTessellation)
250 , requiredStages (other.requiredStages)
251 , requiredDeviceExtensions (other.requiredDeviceExtensions)
252 , requiredDeviceFeatures (other.requiredDeviceFeatures)
253 , requestedExtensionFeatures (other.requestedExtensionFeatures)
254 , pushConstants (other.pushConstants)
255 , resources (other.resources)
256 , interfaces (other.interfaces)
257 , failResult (other.failResult)
258 , failMessageTemplate (other.failMessageTemplate)
260 inputColors[0] = other.inputColors[0];
261 inputColors[1] = other.inputColors[1];
262 inputColors[2] = other.inputColors[2];
263 inputColors[3] = other.inputColors[3];
265 outputColors[0] = other.outputColors[0];
266 outputColors[1] = other.outputColors[1];
267 outputColors[2] = other.outputColors[2];
268 outputColors[3] = other.outputColors[3];
271 string InstanceContext::getSpecializedFailMessage (const string& failureReason)
273 map<string, string> parameters;
274 parameters["reason"] = failureReason;
275 return StringTemplate(failMessageTemplate).specialize(parameters);
278 ShaderElement::ShaderElement (const string& moduleName_,
279 const string& entryPoint_,
280 VkShaderStageFlagBits shaderStage_)
281 : moduleName(moduleName_)
282 , entryName(entryPoint_)
283 , stage(shaderStage_)
287 void getDefaultColors (RGBA (&colors)[4])
289 colors[0] = RGBA::white();
290 colors[1] = RGBA::red();
291 colors[2] = RGBA::green();
292 colors[3] = RGBA::blue();
295 void getHalfColorsFullAlpha (RGBA (&colors)[4])
297 colors[0] = RGBA(127, 127, 127, 255);
298 colors[1] = RGBA(127, 0, 0, 255);
299 colors[2] = RGBA(0, 127, 0, 255);
300 colors[3] = RGBA(0, 0, 127, 255);
303 void getInvertedDefaultColors (RGBA (&colors)[4])
305 colors[0] = RGBA(0, 0, 0, 255);
306 colors[1] = RGBA(0, 255, 255, 255);
307 colors[2] = RGBA(255, 0, 255, 255);
308 colors[3] = RGBA(255, 255, 0, 255);
311 // For the current InstanceContext, constructs the required modules and shader stage create infos.
312 void createPipelineShaderStages (const DeviceInterface& vk,
313 const VkDevice vkDevice,
314 InstanceContext& instance,
316 vector<ModuleHandleSp>& modules,
317 vector<VkPipelineShaderStageCreateInfo>& createInfos)
319 for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx)
321 const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0)));
322 modules.push_back(ModuleHandleSp(mod));
323 for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx)
325 const EntryToStage& stage = *shaderNdx;
326 const VkPipelineShaderStageCreateInfo shaderParam =
328 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
329 DE_NULL, // const void* pNext;
330 (VkPipelineShaderStageCreateFlags)0,
331 stage.second, // VkShaderStageFlagBits stage;
332 **modules.back(), // VkShaderModule module;
333 stage.first.c_str(), // const char* pName;
334 (const VkSpecializationInfo*)DE_NULL,
336 createInfos.push_back(shaderParam);
341 #define SPIRV_ASSEMBLY_TYPES \
342 "%void = OpTypeVoid\n" \
343 "%bool = OpTypeBool\n" \
345 "%i32 = OpTypeInt 32 1\n" \
346 "%u32 = OpTypeInt 32 0\n" \
348 "%f32 = OpTypeFloat 32\n" \
349 "%v2i32 = OpTypeVector %i32 2\n" \
350 "%v2u32 = OpTypeVector %u32 2\n" \
351 "%v2f32 = OpTypeVector %f32 2\n" \
352 "%v3f32 = OpTypeVector %f32 3\n" \
353 "%v4i32 = OpTypeVector %i32 4\n" \
354 "%v4u32 = OpTypeVector %u32 4\n" \
355 "%v4f32 = OpTypeVector %f32 4\n" \
356 "%v4bool = OpTypeVector %bool 4\n" \
358 "%v4f32_function = OpTypeFunction %v4f32 %v4f32\n" \
359 "%bool_function = OpTypeFunction %bool\n" \
360 "%fun = OpTypeFunction %void\n" \
362 "%ip_f32 = OpTypePointer Input %f32\n" \
363 "%ip_i32 = OpTypePointer Input %i32\n" \
364 "%ip_u32 = OpTypePointer Input %u32\n" \
365 "%ip_v3f32 = OpTypePointer Input %v3f32\n" \
366 "%ip_v2f32 = OpTypePointer Input %v2f32\n" \
367 "%ip_v2i32 = OpTypePointer Input %v2i32\n" \
368 "%ip_v2u32 = OpTypePointer Input %v2u32\n" \
369 "%ip_v4f32 = OpTypePointer Input %v4f32\n" \
370 "%ip_v4i32 = OpTypePointer Input %v4i32\n" \
371 "%ip_v4u32 = OpTypePointer Input %v4u32\n" \
373 "%op_f32 = OpTypePointer Output %f32\n" \
374 "%op_i32 = OpTypePointer Output %i32\n" \
375 "%op_u32 = OpTypePointer Output %u32\n" \
376 "%op_v2f32 = OpTypePointer Output %v2f32\n" \
377 "%op_v2i32 = OpTypePointer Output %v2i32\n" \
378 "%op_v2u32 = OpTypePointer Output %v2u32\n" \
379 "%op_v4f32 = OpTypePointer Output %v4f32\n" \
380 "%op_v4i32 = OpTypePointer Output %v4i32\n" \
381 "%op_v4u32 = OpTypePointer Output %v4u32\n" \
383 "%fp_f32 = OpTypePointer Function %f32\n" \
384 "%fp_i32 = OpTypePointer Function %i32\n" \
385 "%fp_v4f32 = OpTypePointer Function %v4f32\n"
387 #define SPIRV_ASSEMBLY_CONSTANTS \
388 "%c_f32_1 = OpConstant %f32 1.0\n" \
389 "%c_f32_0 = OpConstant %f32 0.0\n" \
390 "%c_f32_0_5 = OpConstant %f32 0.5\n" \
391 "%c_f32_n1 = OpConstant %f32 -1.\n" \
392 "%c_f32_7 = OpConstant %f32 7.0\n" \
393 "%c_f32_8 = OpConstant %f32 8.0\n" \
394 "%c_i32_0 = OpConstant %i32 0\n" \
395 "%c_i32_1 = OpConstant %i32 1\n" \
396 "%c_i32_2 = OpConstant %i32 2\n" \
397 "%c_i32_3 = OpConstant %i32 3\n" \
398 "%c_i32_4 = OpConstant %i32 4\n" \
399 "%c_u32_0 = OpConstant %u32 0\n" \
400 "%c_u32_1 = OpConstant %u32 1\n" \
401 "%c_u32_2 = OpConstant %u32 2\n" \
402 "%c_u32_3 = OpConstant %u32 3\n" \
403 "%c_u32_32 = OpConstant %u32 32\n" \
404 "%c_u32_4 = OpConstant %u32 4\n" \
405 "%c_u32_31_bits = OpConstant %u32 0x7FFFFFFF\n" \
406 "%c_v4f32_1_1_1_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_1\n" \
407 "%c_v4f32_1_0_0_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_0 %c_f32_0 %c_f32_1\n" \
408 "%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"
410 #define SPIRV_ASSEMBLY_ARRAYS \
411 "%a1f32 = OpTypeArray %f32 %c_u32_1\n" \
412 "%a2f32 = OpTypeArray %f32 %c_u32_2\n" \
413 "%a3v4f32 = OpTypeArray %v4f32 %c_u32_3\n" \
414 "%a4f32 = OpTypeArray %f32 %c_u32_4\n" \
415 "%a32v4f32 = OpTypeArray %v4f32 %c_u32_32\n" \
416 "%ip_a3v4f32 = OpTypePointer Input %a3v4f32\n" \
417 "%ip_a32v4f32 = OpTypePointer Input %a32v4f32\n" \
418 "%op_a2f32 = OpTypePointer Output %a2f32\n" \
419 "%op_a3v4f32 = OpTypePointer Output %a3v4f32\n" \
420 "%op_a4f32 = OpTypePointer Output %a4f32\n"
422 // Creates vertex-shader assembly by specializing a boilerplate StringTemplate
423 // on fragments, which must (at least) map "testfun" to an OpFunction definition
424 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
425 // with "BP_" to avoid collisions with fragments.
427 // It corresponds roughly to this GLSL:
429 // layout(location = 0) in vec4 position;
430 // layout(location = 1) in vec4 color;
431 // layout(location = 1) out highp vec4 vtxColor;
432 // void main (void) { gl_Position = position; vtxColor = test_func(color); }
433 string makeVertexShaderAssembly(const map<string, string>& fragments)
435 // \todo [2015-11-23 awoloszyn] Remove OpName once these have stabalized
436 static const char vertexShaderBoilerplate[] =
437 "OpCapability Shader\n"
438 "OpCapability ClipDistance\n"
439 "OpCapability CullDistance\n"
440 "${capability:opt}\n"
442 "OpMemoryModel Logical GLSL450\n"
443 "OpEntryPoint Vertex %main \"main\" %BP_stream %BP_position %BP_vtx_color %BP_color %BP_gl_VertexIndex %BP_gl_InstanceIndex ${IF_entrypoint:opt} \n"
445 "OpName %main \"main\"\n"
446 "OpName %BP_gl_PerVertex \"gl_PerVertex\"\n"
447 "OpMemberName %BP_gl_PerVertex 0 \"gl_Position\"\n"
448 "OpMemberName %BP_gl_PerVertex 1 \"gl_PointSize\"\n"
449 "OpMemberName %BP_gl_PerVertex 2 \"gl_ClipDistance\"\n"
450 "OpMemberName %BP_gl_PerVertex 3 \"gl_CullDistance\"\n"
451 "OpName %test_code \"testfun(vf4;\"\n"
452 "OpName %BP_stream \"\"\n"
453 "OpName %BP_position \"position\"\n"
454 "OpName %BP_vtx_color \"vtxColor\"\n"
455 "OpName %BP_color \"color\"\n"
456 "OpName %BP_gl_VertexIndex \"gl_VertexIndex\"\n"
457 "OpName %BP_gl_InstanceIndex \"gl_InstanceIndex\"\n"
458 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
459 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
460 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
461 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
462 "OpDecorate %BP_gl_PerVertex Block\n"
463 "OpDecorate %BP_position Location 0\n"
464 "OpDecorate %BP_vtx_color Location 1\n"
465 "OpDecorate %BP_color Location 1\n"
466 "OpDecorate %BP_gl_VertexIndex BuiltIn VertexIndex\n"
467 "OpDecorate %BP_gl_InstanceIndex BuiltIn InstanceIndex\n"
468 "${IF_decoration:opt}\n"
469 "${decoration:opt}\n"
471 SPIRV_ASSEMBLY_CONSTANTS
472 SPIRV_ASSEMBLY_ARRAYS
473 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
474 "%BP_op_gl_PerVertex = OpTypePointer Output %BP_gl_PerVertex\n"
475 "%BP_stream = OpVariable %BP_op_gl_PerVertex Output\n"
476 "%BP_position = OpVariable %ip_v4f32 Input\n"
477 "%BP_vtx_color = OpVariable %op_v4f32 Output\n"
478 "%BP_color = OpVariable %ip_v4f32 Input\n"
479 "%BP_gl_VertexIndex = OpVariable %ip_i32 Input\n"
480 "%BP_gl_InstanceIndex = OpVariable %ip_i32 Input\n"
482 "${IF_variable:opt}\n"
483 "%main = OpFunction %void None %fun\n"
484 "%BP_label = OpLabel\n"
485 "${IF_carryforward:opt}\n"
486 "%BP_pos = OpLoad %v4f32 %BP_position\n"
487 "%BP_gl_pos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
488 "OpStore %BP_gl_pos %BP_pos\n"
489 "%BP_col = OpLoad %v4f32 %BP_color\n"
490 "%BP_col_transformed = OpFunctionCall %v4f32 %test_code %BP_col\n"
491 "OpStore %BP_vtx_color %BP_col_transformed\n"
494 "${interface_op_func:opt}\n"
496 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
497 "%getId_label = OpLabel\n"
498 "%vert_id = OpLoad %i32 %BP_gl_VertexIndex\n"
499 "%is_id_0 = OpIEqual %bool %vert_id %c_i32_0\n"
500 "OpReturnValue %is_id_0\n"
504 return tcu::StringTemplate(vertexShaderBoilerplate).specialize(fragments);
507 // Creates tess-control-shader assembly by specializing a boilerplate
508 // StringTemplate on fragments, which must (at least) map "testfun" to an
509 // OpFunction definition for %test_code that takes and returns a %v4f32.
510 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
512 // It roughly corresponds to the following GLSL.
515 // layout(vertices = 3) out;
516 // layout(location = 1) in vec4 in_color[];
517 // layout(location = 1) out vec4 out_color[];
520 // out_color[gl_InvocationID] = testfun(in_color[gl_InvocationID]);
521 // gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
522 // if (gl_InvocationID == 0) {
523 // gl_TessLevelOuter[0] = 1.0;
524 // gl_TessLevelOuter[1] = 1.0;
525 // gl_TessLevelOuter[2] = 1.0;
526 // gl_TessLevelInner[0] = 1.0;
529 string makeTessControlShaderAssembly (const map<string, string>& fragments)
531 static const char tessControlShaderBoilerplate[] =
532 "OpCapability Tessellation\n"
533 "OpCapability ClipDistance\n"
534 "OpCapability CullDistance\n"
535 "${capability:opt}\n"
537 "OpMemoryModel Logical GLSL450\n"
538 "OpEntryPoint TessellationControl %BP_main \"main\" %BP_out_color %BP_gl_InvocationID %BP_in_color %BP_gl_out %BP_gl_in %BP_gl_TessLevelOuter %BP_gl_TessLevelInner ${IF_entrypoint:opt} \n"
539 "OpExecutionMode %BP_main OutputVertices 3\n"
541 "OpName %BP_main \"main\"\n"
542 "OpName %test_code \"testfun(vf4;\"\n"
543 "OpName %BP_out_color \"out_color\"\n"
544 "OpName %BP_gl_InvocationID \"gl_InvocationID\"\n"
545 "OpName %BP_in_color \"in_color\"\n"
546 "OpName %BP_gl_PerVertex \"gl_PerVertex\"\n"
547 "OpMemberName %BP_gl_PerVertex 0 \"gl_Position\"\n"
548 "OpMemberName %BP_gl_PerVertex 1 \"gl_PointSize\"\n"
549 "OpMemberName %BP_gl_PerVertex 2 \"gl_ClipDistance\"\n"
550 "OpMemberName %BP_gl_PerVertex 3 \"gl_CullDistance\"\n"
551 "OpName %BP_gl_out \"gl_out\"\n"
552 "OpName %BP_gl_PVOut \"gl_PerVertex\"\n"
553 "OpMemberName %BP_gl_PVOut 0 \"gl_Position\"\n"
554 "OpMemberName %BP_gl_PVOut 1 \"gl_PointSize\"\n"
555 "OpMemberName %BP_gl_PVOut 2 \"gl_ClipDistance\"\n"
556 "OpMemberName %BP_gl_PVOut 3 \"gl_CullDistance\"\n"
557 "OpName %BP_gl_in \"gl_in\"\n"
558 "OpName %BP_gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
559 "OpName %BP_gl_TessLevelInner \"gl_TessLevelInner\"\n"
560 "OpDecorate %BP_out_color Location 1\n"
561 "OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n"
562 "OpDecorate %BP_in_color Location 1\n"
563 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
564 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
565 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
566 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
567 "OpDecorate %BP_gl_PerVertex Block\n"
568 "OpMemberDecorate %BP_gl_PVOut 0 BuiltIn Position\n"
569 "OpMemberDecorate %BP_gl_PVOut 1 BuiltIn PointSize\n"
570 "OpMemberDecorate %BP_gl_PVOut 2 BuiltIn ClipDistance\n"
571 "OpMemberDecorate %BP_gl_PVOut 3 BuiltIn CullDistance\n"
572 "OpDecorate %BP_gl_PVOut Block\n"
573 "OpDecorate %BP_gl_TessLevelOuter Patch\n"
574 "OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
575 "OpDecorate %BP_gl_TessLevelInner Patch\n"
576 "OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n"
577 "${IF_decoration:opt}\n"
578 "${decoration:opt}\n"
580 SPIRV_ASSEMBLY_CONSTANTS
581 SPIRV_ASSEMBLY_ARRAYS
582 "%BP_out_color = OpVariable %op_a3v4f32 Output\n"
583 "%BP_gl_InvocationID = OpVariable %ip_i32 Input\n"
584 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
585 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
586 "%BP_a3_gl_PerVertex = OpTypeArray %BP_gl_PerVertex %c_u32_3\n"
587 "%BP_op_a3_gl_PerVertex = OpTypePointer Output %BP_a3_gl_PerVertex\n"
588 "%BP_gl_out = OpVariable %BP_op_a3_gl_PerVertex Output\n"
589 "%BP_gl_PVOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
590 "%BP_a32_gl_PVOut = OpTypeArray %BP_gl_PVOut %c_u32_32\n"
591 "%BP_ip_a32_gl_PVOut = OpTypePointer Input %BP_a32_gl_PVOut\n"
592 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PVOut Input\n"
593 "%BP_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
594 "%BP_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
596 "${IF_variable:opt}\n"
598 "%BP_main = OpFunction %void None %fun\n"
599 "%BP_label = OpLabel\n"
600 "%BP_gl_Invoc = OpLoad %i32 %BP_gl_InvocationID\n"
601 "${IF_carryforward:opt}\n"
602 "%BP_in_col_loc = OpAccessChain %ip_v4f32 %BP_in_color %BP_gl_Invoc\n"
603 "%BP_out_col_loc = OpAccessChain %op_v4f32 %BP_out_color %BP_gl_Invoc\n"
604 "%BP_in_col_val = OpLoad %v4f32 %BP_in_col_loc\n"
605 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_in_col_val\n"
606 "OpStore %BP_out_col_loc %BP_clr_transformed\n"
608 "%BP_in_pos_loc = OpAccessChain %ip_v4f32 %BP_gl_in %BP_gl_Invoc %c_i32_0\n"
609 "%BP_out_pos_loc = OpAccessChain %op_v4f32 %BP_gl_out %BP_gl_Invoc %c_i32_0\n"
610 "%BP_in_pos_val = OpLoad %v4f32 %BP_in_pos_loc\n"
611 "OpStore %BP_out_pos_loc %BP_in_pos_val\n"
613 "%BP_cmp = OpIEqual %bool %BP_gl_Invoc %c_i32_0\n"
614 "OpSelectionMerge %BP_merge_label None\n"
615 "OpBranchConditional %BP_cmp %BP_if_label %BP_merge_label\n"
616 "%BP_if_label = OpLabel\n"
617 "%BP_gl_TessLevelOuterPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_0\n"
618 "%BP_gl_TessLevelOuterPos_1 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_1\n"
619 "%BP_gl_TessLevelOuterPos_2 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_2\n"
620 "%BP_gl_TessLevelInnerPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelInner %c_i32_0\n"
621 "OpStore %BP_gl_TessLevelOuterPos_0 %c_f32_1\n"
622 "OpStore %BP_gl_TessLevelOuterPos_1 %c_f32_1\n"
623 "OpStore %BP_gl_TessLevelOuterPos_2 %c_f32_1\n"
624 "OpStore %BP_gl_TessLevelInnerPos_0 %c_f32_1\n"
625 "OpBranch %BP_merge_label\n"
626 "%BP_merge_label = OpLabel\n"
629 "${interface_op_func:opt}\n"
631 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
632 "%getId_label = OpLabel\n"
633 "%invocation_id = OpLoad %i32 %BP_gl_InvocationID\n"
634 "%is_id_0 = OpIEqual %bool %invocation_id %c_i32_0\n"
635 "OpReturnValue %is_id_0\n"
639 return tcu::StringTemplate(tessControlShaderBoilerplate).specialize(fragments);
642 // Creates tess-evaluation-shader assembly by specializing a boilerplate
643 // StringTemplate on fragments, which must (at least) map "testfun" to an
644 // OpFunction definition for %test_code that takes and returns a %v4f32.
645 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
647 // It roughly corresponds to the following glsl.
651 // layout(triangles, equal_spacing, ccw) in;
652 // layout(location = 1) in vec4 in_color[];
653 // layout(location = 1) out vec4 out_color;
655 // #define interpolate(val)
656 // vec4(gl_TessCoord.x) * val[0] + vec4(gl_TessCoord.y) * val[1] +
657 // vec4(gl_TessCoord.z) * val[2]
660 // gl_Position = vec4(gl_TessCoord.x) * gl_in[0].gl_Position +
661 // vec4(gl_TessCoord.y) * gl_in[1].gl_Position +
662 // vec4(gl_TessCoord.z) * gl_in[2].gl_Position;
663 // out_color = testfun(interpolate(in_color));
665 string makeTessEvalShaderAssembly(const map<string, string>& fragments)
667 static const char tessEvalBoilerplate[] =
668 "OpCapability Tessellation\n"
669 "OpCapability ClipDistance\n"
670 "OpCapability CullDistance\n"
671 "${capability:opt}\n"
673 "OpMemoryModel Logical GLSL450\n"
674 "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"
675 "OpExecutionMode %BP_main Triangles\n"
676 "OpExecutionMode %BP_main SpacingEqual\n"
677 "OpExecutionMode %BP_main VertexOrderCcw\n"
679 "OpName %BP_main \"main\"\n"
680 "OpName %test_code \"testfun(vf4;\"\n"
681 "OpName %BP_gl_PerVertexOut \"gl_PerVertex\"\n"
682 "OpMemberName %BP_gl_PerVertexOut 0 \"gl_Position\"\n"
683 "OpMemberName %BP_gl_PerVertexOut 1 \"gl_PointSize\"\n"
684 "OpMemberName %BP_gl_PerVertexOut 2 \"gl_ClipDistance\"\n"
685 "OpMemberName %BP_gl_PerVertexOut 3 \"gl_CullDistance\"\n"
686 "OpName %BP_stream \"\"\n"
687 "OpName %BP_gl_TessCoord \"gl_TessCoord\"\n"
688 "OpName %BP_gl_PerVertexIn \"gl_PerVertex\"\n"
689 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
690 "OpMemberName %BP_gl_PerVertexIn 0 \"gl_Position\"\n"
691 "OpMemberName %BP_gl_PerVertexIn 1 \"gl_PointSize\"\n"
692 "OpMemberName %BP_gl_PerVertexIn 2 \"gl_ClipDistance\"\n"
693 "OpMemberName %BP_gl_PerVertexIn 3 \"gl_CullDistance\"\n"
694 "OpName %BP_gl_in \"gl_in\"\n"
695 "OpName %BP_out_color \"out_color\"\n"
696 "OpName %BP_in_color \"in_color\"\n"
697 "OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n"
698 "OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n"
699 "OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n"
700 "OpMemberDecorate %BP_gl_PerVertexOut 3 BuiltIn CullDistance\n"
701 "OpDecorate %BP_gl_PerVertexOut Block\n"
702 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
703 "OpDecorate %BP_gl_TessCoord BuiltIn TessCoord\n"
704 "OpMemberDecorate %BP_gl_PerVertexIn 0 BuiltIn Position\n"
705 "OpMemberDecorate %BP_gl_PerVertexIn 1 BuiltIn PointSize\n"
706 "OpMemberDecorate %BP_gl_PerVertexIn 2 BuiltIn ClipDistance\n"
707 "OpMemberDecorate %BP_gl_PerVertexIn 3 BuiltIn CullDistance\n"
708 "OpDecorate %BP_gl_PerVertexIn Block\n"
709 "OpDecorate %BP_out_color Location 1\n"
710 "OpDecorate %BP_in_color Location 1\n"
711 "${IF_decoration:opt}\n"
712 "${decoration:opt}\n"
714 SPIRV_ASSEMBLY_CONSTANTS
715 SPIRV_ASSEMBLY_ARRAYS
716 "%BP_gl_PerVertexOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
717 "%BP_op_gl_PerVertexOut = OpTypePointer Output %BP_gl_PerVertexOut\n"
718 "%BP_stream = OpVariable %BP_op_gl_PerVertexOut Output\n"
719 "%BP_gl_TessCoord = OpVariable %ip_v3f32 Input\n"
720 "%BP_gl_PrimitiveID = OpVariable %op_i32 Input\n"
721 "%BP_gl_PerVertexIn = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
722 "%BP_a32_gl_PerVertexIn = OpTypeArray %BP_gl_PerVertexIn %c_u32_32\n"
723 "%BP_ip_a32_gl_PerVertexIn = OpTypePointer Input %BP_a32_gl_PerVertexIn\n"
724 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PerVertexIn Input\n"
725 "%BP_out_color = OpVariable %op_v4f32 Output\n"
726 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
728 "${IF_variable:opt}\n"
729 "%BP_main = OpFunction %void None %fun\n"
730 "%BP_label = OpLabel\n"
731 "${IF_carryforward:opt}\n"
732 "%BP_gl_TC_0 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
733 "%BP_gl_TC_1 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
734 "%BP_gl_TC_2 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
735 "%BP_gl_in_gl_Pos_0 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
736 "%BP_gl_in_gl_Pos_1 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
737 "%BP_gl_in_gl_Pos_2 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
739 "%BP_gl_OPos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
740 "%BP_in_color_0 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
741 "%BP_in_color_1 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
742 "%BP_in_color_2 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
744 "%BP_TC_W_0 = OpLoad %f32 %BP_gl_TC_0\n"
745 "%BP_TC_W_1 = OpLoad %f32 %BP_gl_TC_1\n"
746 "%BP_TC_W_2 = OpLoad %f32 %BP_gl_TC_2\n"
747 "%BP_v4f32_TC_0 = OpCompositeConstruct %v4f32 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0\n"
748 "%BP_v4f32_TC_1 = OpCompositeConstruct %v4f32 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1\n"
749 "%BP_v4f32_TC_2 = OpCompositeConstruct %v4f32 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2\n"
751 "%BP_gl_IP_0 = OpLoad %v4f32 %BP_gl_in_gl_Pos_0\n"
752 "%BP_gl_IP_1 = OpLoad %v4f32 %BP_gl_in_gl_Pos_1\n"
753 "%BP_gl_IP_2 = OpLoad %v4f32 %BP_gl_in_gl_Pos_2\n"
755 "%BP_IP_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_gl_IP_0\n"
756 "%BP_IP_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_gl_IP_1\n"
757 "%BP_IP_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_gl_IP_2\n"
759 "%BP_pos_sum_0 = OpFAdd %v4f32 %BP_IP_W_0 %BP_IP_W_1\n"
760 "%BP_pos_sum_1 = OpFAdd %v4f32 %BP_pos_sum_0 %BP_IP_W_2\n"
762 "OpStore %BP_gl_OPos %BP_pos_sum_1\n"
764 "%BP_IC_0 = OpLoad %v4f32 %BP_in_color_0\n"
765 "%BP_IC_1 = OpLoad %v4f32 %BP_in_color_1\n"
766 "%BP_IC_2 = OpLoad %v4f32 %BP_in_color_2\n"
768 "%BP_IC_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_IC_0\n"
769 "%BP_IC_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_IC_1\n"
770 "%BP_IC_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_IC_2\n"
772 "%BP_col_sum_0 = OpFAdd %v4f32 %BP_IC_W_0 %BP_IC_W_1\n"
773 "%BP_col_sum_1 = OpFAdd %v4f32 %BP_col_sum_0 %BP_IC_W_2\n"
775 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_col_sum_1\n"
777 "OpStore %BP_out_color %BP_clr_transformed\n"
780 "${interface_op_func:opt}\n"
782 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
783 "%getId_label = OpLabel\n"
784 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
785 "%is_id_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
786 "OpReturnValue %is_id_0\n"
790 return tcu::StringTemplate(tessEvalBoilerplate).specialize(fragments);
793 // Creates geometry-shader assembly by specializing a boilerplate StringTemplate
794 // on fragments, which must (at least) map "testfun" to an OpFunction definition
795 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
796 // with "BP_" to avoid collisions with fragments.
798 // Derived from this GLSL:
801 // layout(triangles) in;
802 // layout(triangle_strip, max_vertices = 3) out;
804 // layout(location = 1) in vec4 in_color[];
805 // layout(location = 1) out vec4 out_color;
808 // gl_Position = gl_in[0].gl_Position;
809 // out_color = test_fun(in_color[0]);
811 // gl_Position = gl_in[1].gl_Position;
812 // out_color = test_fun(in_color[1]);
814 // gl_Position = gl_in[2].gl_Position;
815 // out_color = test_fun(in_color[2]);
819 string makeGeometryShaderAssembly(const map<string, string>& fragments)
821 static const char geometryShaderBoilerplate[] =
822 "OpCapability Geometry\n"
823 "OpCapability ClipDistance\n"
824 "OpCapability CullDistance\n"
825 "${capability:opt}\n"
827 "OpMemoryModel Logical GLSL450\n"
828 "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"
829 "OpExecutionMode %BP_main Triangles\n"
830 "OpExecutionMode %BP_main OutputTriangleStrip\n"
831 "OpExecutionMode %BP_main OutputVertices 3\n"
833 "OpName %BP_main \"main\"\n"
834 "OpName %BP_gl_PrimitiveID \"gl_PrimitiveID\"\n"
835 "OpName %BP_per_vertex_in \"gl_PerVertex\"\n"
836 "OpMemberName %BP_per_vertex_in 0 \"gl_Position\"\n"
837 "OpMemberName %BP_per_vertex_in 1 \"gl_PointSize\"\n"
838 "OpMemberName %BP_per_vertex_in 2 \"gl_ClipDistance\"\n"
839 "OpMemberName %BP_per_vertex_in 3 \"gl_CullDistance\"\n"
840 "OpName %BP_gl_in \"gl_in\"\n"
841 "OpName %BP_out_color \"out_color\"\n"
842 "OpName %BP_in_color \"in_color\"\n"
843 "OpName %test_code \"testfun(vf4;\"\n"
844 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
845 "OpDecorate %BP_out_gl_position BuiltIn Position\n"
846 "OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n"
847 "OpMemberDecorate %BP_per_vertex_in 1 BuiltIn PointSize\n"
848 "OpMemberDecorate %BP_per_vertex_in 2 BuiltIn ClipDistance\n"
849 "OpMemberDecorate %BP_per_vertex_in 3 BuiltIn CullDistance\n"
850 "OpDecorate %BP_per_vertex_in Block\n"
851 "OpDecorate %BP_out_color Location 1\n"
852 "OpDecorate %BP_in_color Location 1\n"
853 "${IF_decoration:opt}\n"
854 "${decoration:opt}\n"
856 SPIRV_ASSEMBLY_CONSTANTS
857 SPIRV_ASSEMBLY_ARRAYS
858 "%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
859 "%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n"
860 "%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n"
862 "%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n"
863 "%BP_out_color = OpVariable %op_v4f32 Output\n"
864 "%BP_in_color = OpVariable %ip_a3v4f32 Input\n"
865 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
866 "%BP_out_gl_position = OpVariable %op_v4f32 Output\n"
868 "${IF_variable:opt}\n"
870 "%BP_main = OpFunction %void None %fun\n"
871 "%BP_label = OpLabel\n"
873 "${IF_carryforward:opt}\n"
875 "%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
876 "%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
877 "%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
879 "%BP_in_position_0 = OpLoad %v4f32 %BP_gl_in_0_gl_position\n"
880 "%BP_in_position_1 = OpLoad %v4f32 %BP_gl_in_1_gl_position\n"
881 "%BP_in_position_2 = OpLoad %v4f32 %BP_gl_in_2_gl_position \n"
883 "%BP_in_color_0_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
884 "%BP_in_color_1_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
885 "%BP_in_color_2_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
887 "%BP_in_color_0 = OpLoad %v4f32 %BP_in_color_0_ptr\n"
888 "%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n"
889 "%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n"
891 "%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n"
892 "%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
893 "%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"
896 "OpStore %BP_out_gl_position %BP_in_position_0\n"
897 "OpStore %BP_out_color %BP_transformed_in_color_0\n"
900 "OpStore %BP_out_gl_position %BP_in_position_1\n"
901 "OpStore %BP_out_color %BP_transformed_in_color_1\n"
904 "OpStore %BP_out_gl_position %BP_in_position_2\n"
905 "OpStore %BP_out_color %BP_transformed_in_color_2\n"
911 "${interface_op_func:opt}\n"
913 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
914 "%getId_label = OpLabel\n"
915 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
916 "%is_id_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
917 "OpReturnValue %is_id_0\n"
921 return tcu::StringTemplate(geometryShaderBoilerplate).specialize(fragments);
924 // Creates fragment-shader assembly by specializing a boilerplate StringTemplate
925 // on fragments, which must (at least) map "testfun" to an OpFunction definition
926 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
927 // with "BP_" to avoid collisions with fragments.
929 // Derived from this GLSL:
931 // layout(location = 1) in highp vec4 vtxColor;
932 // layout(location = 0) out highp vec4 fragColor;
933 // highp vec4 testfun(highp vec4 x) { return x; }
934 // void main(void) { fragColor = testfun(vtxColor); }
936 // with modifications including passing vtxColor by value and ripping out
937 // testfun() definition.
938 string makeFragmentShaderAssembly(const map<string, string>& fragments)
940 static const char fragmentShaderBoilerplate[] =
941 "OpCapability Shader\n"
942 "${capability:opt}\n"
944 "OpMemoryModel Logical GLSL450\n"
945 "OpEntryPoint Fragment %BP_main \"main\" %BP_vtxColor %BP_fragColor %BP_gl_FragCoord ${IF_entrypoint:opt} \n"
946 "OpExecutionMode %BP_main OriginUpperLeft\n"
948 "OpName %BP_main \"main\"\n"
949 "OpName %BP_gl_FragCoord \"fragCoord\"\n"
950 "OpName %BP_fragColor \"fragColor\"\n"
951 "OpName %BP_vtxColor \"vtxColor\"\n"
952 "OpName %test_code \"testfun(vf4;\"\n"
953 "OpDecorate %BP_fragColor Location 0\n"
954 "OpDecorate %BP_vtxColor Location 1\n"
955 "OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n"
956 "${IF_decoration:opt}\n"
957 "${decoration:opt}\n"
959 SPIRV_ASSEMBLY_CONSTANTS
960 SPIRV_ASSEMBLY_ARRAYS
961 "%BP_gl_FragCoord = OpVariable %ip_v4f32 Input\n"
962 "%BP_fragColor = OpVariable %op_v4f32 Output\n"
963 "%BP_vtxColor = OpVariable %ip_v4f32 Input\n"
965 "${IF_variable:opt}\n"
966 "%BP_main = OpFunction %void None %fun\n"
967 "%BP_label_main = OpLabel\n"
968 "${IF_carryforward:opt}\n"
969 "%BP_tmp1 = OpLoad %v4f32 %BP_vtxColor\n"
970 "%BP_tmp2 = OpFunctionCall %v4f32 %test_code %BP_tmp1\n"
971 "OpStore %BP_fragColor %BP_tmp2\n"
974 "${interface_op_func:opt}\n"
976 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
977 "%getId_label = OpLabel\n"
978 "%loc_x_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n"
979 "%loc_y_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n"
980 "%x_coord = OpLoad %f32 %loc_x_coord\n"
981 "%y_coord = OpLoad %f32 %loc_y_coord\n"
982 "%is_x_idx0 = OpFOrdEqual %bool %x_coord %c_f32_0_5\n"
983 "%is_y_idx0 = OpFOrdEqual %bool %y_coord %c_f32_0_5\n"
984 "%is_frag_0 = OpLogicalAnd %bool %is_x_idx0 %is_y_idx0\n"
985 "OpReturnValue %is_frag_0\n"
989 return tcu::StringTemplate(fragmentShaderBoilerplate).specialize(fragments);
992 // Creates mappings from placeholders to pass-through shader code which copies
993 // the input to the output faithfully.
994 map<string, string> passthruInterface(const IFDataType& data_type)
996 const string var_type = data_type.str();
997 map<string, string> fragments = passthruFragments();
998 const string functype = string("%") + var_type + "_" + var_type + "_function";
1000 fragments["interface_op_func"] =
1001 string("%interface_op_func = OpFunction %") + var_type + " None " + functype + "\n"
1002 " %io_param1 = OpFunctionParameter %" + var_type + "\n"
1003 " %IF_label = OpLabel\n"
1004 " OpReturnValue %io_param1\n"
1006 fragments["input_type"] = var_type;
1007 fragments["output_type"] = var_type;
1008 fragments["pre_main"] = "";
1010 if (!data_type.elementIs32bit())
1012 if (data_type.elementType == NUMBERTYPE_FLOAT16)
1014 fragments["pre_main"] += "%f16 = OpTypeFloat 16\n";
1016 else if (data_type.elementType == NUMBERTYPE_INT16)
1018 fragments["pre_main"] += "%i16 = OpTypeInt 16 1\n";
1022 fragments["pre_main"] += "%u16 = OpTypeInt 16 0\n";
1025 fragments["capability"] = "OpCapability StorageInputOutput16\n";
1027 if (data_type.isVector())
1029 fragments["pre_main"] += "%" + var_type + " = OpTypeVector %" + IFDataType(1, data_type.elementType).str() + " " + numberToString(data_type.numElements) + "\n";
1032 fragments["pre_main"] +=
1033 "%ip_" + var_type + " = OpTypePointer Input %" + var_type + "\n"
1034 "%op_" + var_type + " = OpTypePointer Output %" + var_type + "\n";
1037 fragments["pre_main"] +=
1038 functype + " = OpTypeFunction %" + var_type + " %" + var_type + "\n"
1039 "%a3" + var_type + " = OpTypeArray %" + var_type + " %c_i32_3\n"
1040 "%ip_a3" + var_type + " = OpTypePointer Input %a3" + var_type + "\n"
1041 "%op_a3" + var_type + " = OpTypePointer Output %a3" + var_type + "\n";
1046 // Returns mappings from interface placeholders to their concrete values.
1048 // The concrete values should be specialized again to provide ${input_type}
1049 // and ${output_type}.
1051 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1052 map<string, string> fillInterfacePlaceholderVert (void)
1054 map<string, string> fragments ;
1056 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1057 fragments["IF_variable"] =
1058 " %IF_input = OpVariable %ip_${input_type} Input\n"
1059 "%IF_output = OpVariable %op_${output_type} Output\n";
1060 fragments["IF_decoration"] =
1061 "OpDecorate %IF_input Location 2\n"
1062 "OpDecorate %IF_output Location 2\n";
1063 fragments["IF_carryforward"] =
1064 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1065 " %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1066 " OpStore %IF_output %IF_result\n";
1068 // Make sure the rest still need to be instantialized.
1069 fragments["capability"] = "${capability:opt}";
1070 fragments["extension"] = "${extension:opt}";
1071 fragments["debug"] = "${debug:opt}";
1072 fragments["decoration"] = "${decoration:opt}";
1073 fragments["pre_main"] = "${pre_main:opt}";
1074 fragments["testfun"] = "${testfun}";
1075 fragments["interface_op_func"] = "${interface_op_func}";
1080 // Returns mappings from interface placeholders to their concrete values.
1082 // The concrete values should be specialized again to provide ${input_type}
1083 // and ${output_type}.
1085 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1086 map<string, string> fillInterfacePlaceholderFrag (void)
1088 map<string, string> fragments ;
1090 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1091 fragments["IF_variable"] =
1092 " %IF_input = OpVariable %ip_${input_type} Input\n"
1093 "%IF_output = OpVariable %op_${output_type} Output\n";
1094 fragments["IF_decoration"] =
1095 "OpDecorate %IF_input Flat\n"
1096 "OpDecorate %IF_input Location 2\n"
1097 "OpDecorate %IF_output Location 1\n"; // Fragment shader should write to location #1.
1098 fragments["IF_carryforward"] =
1099 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1100 " %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1101 " OpStore %IF_output %IF_result\n";
1103 // Make sure the rest still need to be instantialized.
1104 fragments["capability"] = "${capability:opt}";
1105 fragments["extension"] = "${extension:opt}";
1106 fragments["debug"] = "${debug:opt}";
1107 fragments["decoration"] = "${decoration:opt}";
1108 fragments["pre_main"] = "${pre_main:opt}";
1109 fragments["testfun"] = "${testfun}";
1110 fragments["interface_op_func"] = "${interface_op_func}";
1115 // Returns mappings from interface placeholders to their concrete values.
1117 // The concrete values should be specialized again to provide ${input_type}
1118 // and ${output_type}.
1120 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1121 // should also be defined in the final code.
1122 map<string, string> fillInterfacePlaceholderTessCtrl (void)
1124 map<string, string> fragments ;
1126 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1127 fragments["IF_variable"] =
1128 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1129 "%IF_output = OpVariable %op_a3${output_type} Output\n";
1130 fragments["IF_decoration"] =
1131 "OpDecorate %IF_input Location 2\n"
1132 "OpDecorate %IF_output Location 2\n";
1133 fragments["IF_carryforward"] =
1134 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1135 " %IF_input_ptr1 = OpAccessChain %ip_${input_type} %IF_input %c_i32_1\n"
1136 " %IF_input_ptr2 = OpAccessChain %ip_${input_type} %IF_input %c_i32_2\n"
1137 "%IF_output_ptr0 = OpAccessChain %op_${output_type} %IF_output %c_i32_0\n"
1138 "%IF_output_ptr1 = OpAccessChain %op_${output_type} %IF_output %c_i32_1\n"
1139 "%IF_output_ptr2 = OpAccessChain %op_${output_type} %IF_output %c_i32_2\n"
1140 "%IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1141 "%IF_input_val1 = OpLoad %${input_type} %IF_input_ptr1\n"
1142 "%IF_input_val2 = OpLoad %${input_type} %IF_input_ptr2\n"
1143 "%IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1144 "%IF_input_res1 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val1\n"
1145 "%IF_input_res2 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val2\n"
1146 "OpStore %IF_output_ptr0 %IF_input_res0\n"
1147 "OpStore %IF_output_ptr1 %IF_input_res1\n"
1148 "OpStore %IF_output_ptr2 %IF_input_res2\n";
1150 // Make sure the rest still need to be instantialized.
1151 fragments["capability"] = "${capability:opt}";
1152 fragments["extension"] = "${extension:opt}";
1153 fragments["debug"] = "${debug:opt}";
1154 fragments["decoration"] = "${decoration:opt}";
1155 fragments["pre_main"] = "${pre_main:opt}";
1156 fragments["testfun"] = "${testfun}";
1157 fragments["interface_op_func"] = "${interface_op_func}";
1162 // Returns mappings from interface placeholders to their concrete values.
1164 // The concrete values should be specialized again to provide ${input_type}
1165 // and ${output_type}.
1167 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1168 // should also be defined in the final code.
1169 map<string, string> fillInterfacePlaceholderTessEvalGeom (void)
1171 map<string, string> fragments ;
1173 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1174 fragments["IF_variable"] =
1175 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1176 "%IF_output = OpVariable %op_${output_type} Output\n";
1177 fragments["IF_decoration"] =
1178 "OpDecorate %IF_input Location 2\n"
1179 "OpDecorate %IF_output Location 2\n";
1180 fragments["IF_carryforward"] =
1181 // Only get the first value since all three values are the same anyway.
1182 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1183 " %IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1184 " %IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1185 "OpStore %IF_output %IF_input_res0\n";
1187 // Make sure the rest still need to be instantialized.
1188 fragments["capability"] = "${capability:opt}";
1189 fragments["extension"] = "${extension:opt}";
1190 fragments["debug"] = "${debug:opt}";
1191 fragments["decoration"] = "${decoration:opt}";
1192 fragments["pre_main"] = "${pre_main:opt}";
1193 fragments["testfun"] = "${testfun}";
1194 fragments["interface_op_func"] = "${interface_op_func}";
1199 map<string, string> passthruFragments(void)
1201 map<string, string> fragments;
1202 fragments["testfun"] =
1203 // A %test_code function that returns its argument unchanged.
1204 "%test_code = OpFunction %v4f32 None %v4f32_function\n"
1205 "%param1 = OpFunctionParameter %v4f32\n"
1206 "%label_testfun = OpLabel\n"
1207 "OpReturnValue %param1\n"
1212 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1213 // Vertex shader gets custom code from context, the rest are pass-through.
1214 void addShaderCodeCustomVertex(vk::SourceCollections& dst, InstanceContext context)
1216 if (!context.interfaces.empty())
1218 // Inject boilerplate code to wire up additional input/output variables between stages.
1219 // Just copy the contents in input variable to output variable in all stages except
1220 // the customized stage.
1221 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments);
1222 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1224 map<string, string> passthru = passthruFragments();
1226 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(context.testCodeFragments);
1227 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1231 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1232 // Tessellation control shader gets custom code from context, the rest are
1234 void addShaderCodeCustomTessControl(vk::SourceCollections& dst, InstanceContext context)
1236 if (!context.interfaces.empty())
1238 // Inject boilerplate code to wire up additional input/output variables between stages.
1239 // Just copy the contents in input variable to output variable in all stages except
1240 // the customized stage.
1241 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1242 dst.spirvAsmSources.add("tessc") << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments);
1243 dst.spirvAsmSources.add("tesse") << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType()));
1244 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1248 map<string, string> passthru = passthruFragments();
1250 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1251 dst.spirvAsmSources.add("tessc") << makeTessControlShaderAssembly(context.testCodeFragments);
1252 dst.spirvAsmSources.add("tesse") << makeTessEvalShaderAssembly(passthru);
1253 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1257 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1258 // Tessellation evaluation shader gets custom code from context, the rest are
1260 void addShaderCodeCustomTessEval(vk::SourceCollections& dst, InstanceContext context)
1262 if (!context.interfaces.empty())
1264 // Inject boilerplate code to wire up additional input/output variables between stages.
1265 // Just copy the contents in input variable to output variable in all stages except
1266 // the customized stage.
1267 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1268 dst.spirvAsmSources.add("tessc") << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType()));
1269 dst.spirvAsmSources.add("tesse") << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments);
1270 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1274 map<string, string> passthru = passthruFragments();
1275 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1276 dst.spirvAsmSources.add("tessc") << makeTessControlShaderAssembly(passthru);
1277 dst.spirvAsmSources.add("tesse") << makeTessEvalShaderAssembly(context.testCodeFragments);
1278 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1282 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1283 // Geometry shader gets custom code from context, the rest are pass-through.
1284 void addShaderCodeCustomGeometry(vk::SourceCollections& dst, InstanceContext context)
1286 if (!context.interfaces.empty())
1288 // Inject boilerplate code to wire up additional input/output variables between stages.
1289 // Just copy the contents in input variable to output variable in all stages except
1290 // the customized stage.
1291 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1292 dst.spirvAsmSources.add("geom") << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments);
1293 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType()));
1297 map<string, string> passthru = passthruFragments();
1298 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1299 dst.spirvAsmSources.add("geom") << makeGeometryShaderAssembly(context.testCodeFragments);
1300 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(passthru);
1304 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1305 // Fragment shader gets custom code from context, the rest are pass-through.
1306 void addShaderCodeCustomFragment(vk::SourceCollections& dst, InstanceContext context)
1308 if (!context.interfaces.empty())
1310 // Inject boilerplate code to wire up additional input/output variables between stages.
1311 // Just copy the contents in input variable to output variable in all stages except
1312 // the customized stage.
1313 dst.spirvAsmSources.add("vert") << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType()));
1314 dst.spirvAsmSources.add("frag") << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments);
1318 map<string, string> passthru = passthruFragments();
1319 dst.spirvAsmSources.add("vert") << makeVertexShaderAssembly(passthru);
1320 dst.spirvAsmSources.add("frag") << makeFragmentShaderAssembly(context.testCodeFragments);
1324 void createCombinedModule(vk::SourceCollections& dst, InstanceContext)
1326 // \todo [2015-12-07 awoloszyn] Make tessellation / geometry conditional
1327 // \todo [2015-12-07 awoloszyn] Remove OpName and OpMemberName at some point
1328 dst.spirvAsmSources.add("module") <<
1329 "OpCapability Shader\n"
1330 "OpCapability ClipDistance\n"
1331 "OpCapability CullDistance\n"
1332 "OpCapability Geometry\n"
1333 "OpCapability Tessellation\n"
1334 "OpMemoryModel Logical GLSL450\n"
1336 "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_vtxPosition %vert_vertex_id %vert_instance_id\n"
1337 "OpEntryPoint Geometry %geom_main \"main\" %geom_out_gl_position %geom_gl_in %geom_out_color %geom_in_color\n"
1338 "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"
1339 "OpEntryPoint TessellationEvaluation %tesse_main \"main\" %tesse_stream %tesse_gl_tessCoord %tesse_in_position %tesse_out_color %tesse_in_color \n"
1340 "OpEntryPoint Fragment %frag_main \"main\" %frag_vtxColor %frag_fragColor\n"
1342 "OpExecutionMode %geom_main Triangles\n"
1343 "OpExecutionMode %geom_main OutputTriangleStrip\n"
1344 "OpExecutionMode %geom_main OutputVertices 3\n"
1346 "OpExecutionMode %tessc_main OutputVertices 3\n"
1348 "OpExecutionMode %tesse_main Triangles\n"
1349 "OpExecutionMode %tesse_main SpacingEqual\n"
1350 "OpExecutionMode %tesse_main VertexOrderCcw\n"
1352 "OpExecutionMode %frag_main OriginUpperLeft\n"
1354 "OpName %vert_main \"main\"\n"
1355 "OpName %vert_vtxPosition \"vtxPosition\"\n"
1356 "OpName %vert_Position \"position\"\n"
1357 "OpName %vert_vtxColor \"vtxColor\"\n"
1358 "OpName %vert_color \"color\"\n"
1359 "OpName %vert_vertex_id \"gl_VertexIndex\"\n"
1360 "OpName %vert_instance_id \"gl_InstanceIndex\"\n"
1361 "OpName %geom_main \"main\"\n"
1362 "OpName %geom_per_vertex_in \"gl_PerVertex\"\n"
1363 "OpMemberName %geom_per_vertex_in 0 \"gl_Position\"\n"
1364 "OpMemberName %geom_per_vertex_in 1 \"gl_PointSize\"\n"
1365 "OpMemberName %geom_per_vertex_in 2 \"gl_ClipDistance\"\n"
1366 "OpMemberName %geom_per_vertex_in 3 \"gl_CullDistance\"\n"
1367 "OpName %geom_gl_in \"gl_in\"\n"
1368 "OpName %geom_out_color \"out_color\"\n"
1369 "OpName %geom_in_color \"in_color\"\n"
1370 "OpName %tessc_main \"main\"\n"
1371 "OpName %tessc_out_color \"out_color\"\n"
1372 "OpName %tessc_gl_InvocationID \"gl_InvocationID\"\n"
1373 "OpName %tessc_in_color \"in_color\"\n"
1374 "OpName %tessc_out_position \"out_position\"\n"
1375 "OpName %tessc_in_position \"in_position\"\n"
1376 "OpName %tessc_gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
1377 "OpName %tessc_gl_TessLevelInner \"gl_TessLevelInner\"\n"
1378 "OpName %tesse_main \"main\"\n"
1379 "OpName %tesse_per_vertex_out \"gl_PerVertex\"\n"
1380 "OpMemberName %tesse_per_vertex_out 0 \"gl_Position\"\n"
1381 "OpMemberName %tesse_per_vertex_out 1 \"gl_PointSize\"\n"
1382 "OpMemberName %tesse_per_vertex_out 2 \"gl_ClipDistance\"\n"
1383 "OpMemberName %tesse_per_vertex_out 3 \"gl_CullDistance\"\n"
1384 "OpName %tesse_stream \"\"\n"
1385 "OpName %tesse_gl_tessCoord \"gl_TessCoord\"\n"
1386 "OpName %tesse_in_position \"in_position\"\n"
1387 "OpName %tesse_out_color \"out_color\"\n"
1388 "OpName %tesse_in_color \"in_color\"\n"
1389 "OpName %frag_main \"main\"\n"
1390 "OpName %frag_fragColor \"fragColor\"\n"
1391 "OpName %frag_vtxColor \"vtxColor\"\n"
1393 "; Vertex decorations\n"
1394 "OpDecorate %vert_vtxPosition Location 2\n"
1395 "OpDecorate %vert_Position Location 0\n"
1396 "OpDecorate %vert_vtxColor Location 1\n"
1397 "OpDecorate %vert_color Location 1\n"
1398 "OpDecorate %vert_vertex_id BuiltIn VertexIndex\n"
1399 "OpDecorate %vert_instance_id BuiltIn InstanceIndex\n"
1401 "; Geometry decorations\n"
1402 "OpDecorate %geom_out_gl_position BuiltIn Position\n"
1403 "OpMemberDecorate %geom_per_vertex_in 0 BuiltIn Position\n"
1404 "OpMemberDecorate %geom_per_vertex_in 1 BuiltIn PointSize\n"
1405 "OpMemberDecorate %geom_per_vertex_in 2 BuiltIn ClipDistance\n"
1406 "OpMemberDecorate %geom_per_vertex_in 3 BuiltIn CullDistance\n"
1407 "OpDecorate %geom_per_vertex_in Block\n"
1408 "OpDecorate %geom_out_color Location 1\n"
1409 "OpDecorate %geom_in_color Location 1\n"
1411 "; Tessellation Control decorations\n"
1412 "OpDecorate %tessc_out_color Location 1\n"
1413 "OpDecorate %tessc_gl_InvocationID BuiltIn InvocationId\n"
1414 "OpDecorate %tessc_in_color Location 1\n"
1415 "OpDecorate %tessc_out_position Location 2\n"
1416 "OpDecorate %tessc_in_position Location 2\n"
1417 "OpDecorate %tessc_gl_TessLevelOuter Patch\n"
1418 "OpDecorate %tessc_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1419 "OpDecorate %tessc_gl_TessLevelInner Patch\n"
1420 "OpDecorate %tessc_gl_TessLevelInner BuiltIn TessLevelInner\n"
1422 "; Tessellation Evaluation decorations\n"
1423 "OpMemberDecorate %tesse_per_vertex_out 0 BuiltIn Position\n"
1424 "OpMemberDecorate %tesse_per_vertex_out 1 BuiltIn PointSize\n"
1425 "OpMemberDecorate %tesse_per_vertex_out 2 BuiltIn ClipDistance\n"
1426 "OpMemberDecorate %tesse_per_vertex_out 3 BuiltIn CullDistance\n"
1427 "OpDecorate %tesse_per_vertex_out Block\n"
1428 "OpDecorate %tesse_gl_tessCoord BuiltIn TessCoord\n"
1429 "OpDecorate %tesse_in_position Location 2\n"
1430 "OpDecorate %tesse_out_color Location 1\n"
1431 "OpDecorate %tesse_in_color Location 1\n"
1433 "; Fragment decorations\n"
1434 "OpDecorate %frag_fragColor Location 0\n"
1435 "OpDecorate %frag_vtxColor Location 1\n"
1437 SPIRV_ASSEMBLY_TYPES
1438 SPIRV_ASSEMBLY_CONSTANTS
1439 SPIRV_ASSEMBLY_ARRAYS
1441 "; Vertex Variables\n"
1442 "%vert_vtxPosition = OpVariable %op_v4f32 Output\n"
1443 "%vert_Position = OpVariable %ip_v4f32 Input\n"
1444 "%vert_vtxColor = OpVariable %op_v4f32 Output\n"
1445 "%vert_color = OpVariable %ip_v4f32 Input\n"
1446 "%vert_vertex_id = OpVariable %ip_i32 Input\n"
1447 "%vert_instance_id = OpVariable %ip_i32 Input\n"
1449 "; Geometry Variables\n"
1450 "%geom_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1451 "%geom_a3_per_vertex_in = OpTypeArray %geom_per_vertex_in %c_u32_3\n"
1452 "%geom_ip_a3_per_vertex_in = OpTypePointer Input %geom_a3_per_vertex_in\n"
1453 "%geom_gl_in = OpVariable %geom_ip_a3_per_vertex_in Input\n"
1454 "%geom_out_color = OpVariable %op_v4f32 Output\n"
1455 "%geom_in_color = OpVariable %ip_a3v4f32 Input\n"
1456 "%geom_out_gl_position = OpVariable %op_v4f32 Output\n"
1458 "; Tessellation Control Variables\n"
1459 "%tessc_out_color = OpVariable %op_a3v4f32 Output\n"
1460 "%tessc_gl_InvocationID = OpVariable %ip_i32 Input\n"
1461 "%tessc_in_color = OpVariable %ip_a32v4f32 Input\n"
1462 "%tessc_out_position = OpVariable %op_a3v4f32 Output\n"
1463 "%tessc_in_position = OpVariable %ip_a32v4f32 Input\n"
1464 "%tessc_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1465 "%tessc_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1467 "; Tessellation Evaluation Decorations\n"
1468 "%tesse_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1469 "%tesse_op_per_vertex_out = OpTypePointer Output %tesse_per_vertex_out\n"
1470 "%tesse_stream = OpVariable %tesse_op_per_vertex_out Output\n"
1471 "%tesse_gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1472 "%tesse_in_position = OpVariable %ip_a32v4f32 Input\n"
1473 "%tesse_out_color = OpVariable %op_v4f32 Output\n"
1474 "%tesse_in_color = OpVariable %ip_a32v4f32 Input\n"
1476 "; Fragment Variables\n"
1477 "%frag_fragColor = OpVariable %op_v4f32 Output\n"
1478 "%frag_vtxColor = OpVariable %ip_v4f32 Input\n"
1481 "%vert_main = OpFunction %void None %fun\n"
1482 "%vert_label = OpLabel\n"
1483 "%vert_tmp_position = OpLoad %v4f32 %vert_Position\n"
1484 "OpStore %vert_vtxPosition %vert_tmp_position\n"
1485 "%vert_tmp_color = OpLoad %v4f32 %vert_color\n"
1486 "OpStore %vert_vtxColor %vert_tmp_color\n"
1490 "; Geometry Entry\n"
1491 "%geom_main = OpFunction %void None %fun\n"
1492 "%geom_label = OpLabel\n"
1493 "%geom_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_0 %c_i32_0\n"
1494 "%geom_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_1 %c_i32_0\n"
1495 "%geom_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_2 %c_i32_0\n"
1496 "%geom_in_position_0 = OpLoad %v4f32 %geom_gl_in_0_gl_position\n"
1497 "%geom_in_position_1 = OpLoad %v4f32 %geom_gl_in_1_gl_position\n"
1498 "%geom_in_position_2 = OpLoad %v4f32 %geom_gl_in_2_gl_position \n"
1499 "%geom_in_color_0_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_0\n"
1500 "%geom_in_color_1_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_1\n"
1501 "%geom_in_color_2_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_2\n"
1502 "%geom_in_color_0 = OpLoad %v4f32 %geom_in_color_0_ptr\n"
1503 "%geom_in_color_1 = OpLoad %v4f32 %geom_in_color_1_ptr\n"
1504 "%geom_in_color_2 = OpLoad %v4f32 %geom_in_color_2_ptr\n"
1505 "OpStore %geom_out_gl_position %geom_in_position_0\n"
1506 "OpStore %geom_out_color %geom_in_color_0\n"
1508 "OpStore %geom_out_gl_position %geom_in_position_1\n"
1509 "OpStore %geom_out_color %geom_in_color_1\n"
1511 "OpStore %geom_out_gl_position %geom_in_position_2\n"
1512 "OpStore %geom_out_color %geom_in_color_2\n"
1518 "; Tessellation Control Entry\n"
1519 "%tessc_main = OpFunction %void None %fun\n"
1520 "%tessc_label = OpLabel\n"
1521 "%tessc_invocation_id = OpLoad %i32 %tessc_gl_InvocationID\n"
1522 "%tessc_in_color_ptr = OpAccessChain %ip_v4f32 %tessc_in_color %tessc_invocation_id\n"
1523 "%tessc_in_position_ptr = OpAccessChain %ip_v4f32 %tessc_in_position %tessc_invocation_id\n"
1524 "%tessc_in_color_val = OpLoad %v4f32 %tessc_in_color_ptr\n"
1525 "%tessc_in_position_val = OpLoad %v4f32 %tessc_in_position_ptr\n"
1526 "%tessc_out_color_ptr = OpAccessChain %op_v4f32 %tessc_out_color %tessc_invocation_id\n"
1527 "%tessc_out_position_ptr = OpAccessChain %op_v4f32 %tessc_out_position %tessc_invocation_id\n"
1528 "OpStore %tessc_out_color_ptr %tessc_in_color_val\n"
1529 "OpStore %tessc_out_position_ptr %tessc_in_position_val\n"
1530 "%tessc_is_first_invocation = OpIEqual %bool %tessc_invocation_id %c_i32_0\n"
1531 "OpSelectionMerge %tessc_merge_label None\n"
1532 "OpBranchConditional %tessc_is_first_invocation %tessc_first_invocation %tessc_merge_label\n"
1533 "%tessc_first_invocation = OpLabel\n"
1534 "%tessc_tess_outer_0 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_0\n"
1535 "%tessc_tess_outer_1 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_1\n"
1536 "%tessc_tess_outer_2 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_2\n"
1537 "%tessc_tess_inner = OpAccessChain %op_f32 %tessc_gl_TessLevelInner %c_i32_0\n"
1538 "OpStore %tessc_tess_outer_0 %c_f32_1\n"
1539 "OpStore %tessc_tess_outer_1 %c_f32_1\n"
1540 "OpStore %tessc_tess_outer_2 %c_f32_1\n"
1541 "OpStore %tessc_tess_inner %c_f32_1\n"
1542 "OpBranch %tessc_merge_label\n"
1543 "%tessc_merge_label = OpLabel\n"
1547 "; Tessellation Evaluation Entry\n"
1548 "%tesse_main = OpFunction %void None %fun\n"
1549 "%tesse_label = OpLabel\n"
1550 "%tesse_tc_0_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_0\n"
1551 "%tesse_tc_1_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_1\n"
1552 "%tesse_tc_2_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_2\n"
1553 "%tesse_tc_0 = OpLoad %f32 %tesse_tc_0_ptr\n"
1554 "%tesse_tc_1 = OpLoad %f32 %tesse_tc_1_ptr\n"
1555 "%tesse_tc_2 = OpLoad %f32 %tesse_tc_2_ptr\n"
1556 "%tesse_in_pos_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_0\n"
1557 "%tesse_in_pos_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_1\n"
1558 "%tesse_in_pos_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_2\n"
1559 "%tesse_in_pos_0 = OpLoad %v4f32 %tesse_in_pos_0_ptr\n"
1560 "%tesse_in_pos_1 = OpLoad %v4f32 %tesse_in_pos_1_ptr\n"
1561 "%tesse_in_pos_2 = OpLoad %v4f32 %tesse_in_pos_2_ptr\n"
1562 "%tesse_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_0 %tesse_tc_0\n"
1563 "%tesse_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_1 %tesse_tc_1\n"
1564 "%tesse_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_2 %tesse_tc_2\n"
1565 "%tesse_out_pos_ptr = OpAccessChain %op_v4f32 %tesse_stream %c_i32_0\n"
1566 "%tesse_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse_in_pos_0_weighted %tesse_in_pos_1_weighted\n"
1567 "%tesse_computed_out = OpFAdd %v4f32 %tesse_in_pos_0_plus_pos_1 %tesse_in_pos_2_weighted\n"
1568 "OpStore %tesse_out_pos_ptr %tesse_computed_out\n"
1569 "%tesse_in_clr_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_0\n"
1570 "%tesse_in_clr_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_1\n"
1571 "%tesse_in_clr_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_2\n"
1572 "%tesse_in_clr_0 = OpLoad %v4f32 %tesse_in_clr_0_ptr\n"
1573 "%tesse_in_clr_1 = OpLoad %v4f32 %tesse_in_clr_1_ptr\n"
1574 "%tesse_in_clr_2 = OpLoad %v4f32 %tesse_in_clr_2_ptr\n"
1575 "%tesse_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_0 %tesse_tc_0\n"
1576 "%tesse_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_1 %tesse_tc_1\n"
1577 "%tesse_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_2 %tesse_tc_2\n"
1578 "%tesse_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse_in_clr_0_weighted %tesse_in_clr_1_weighted\n"
1579 "%tesse_computed_clr = OpFAdd %v4f32 %tesse_in_clr_0_plus_col_1 %tesse_in_clr_2_weighted\n"
1580 "OpStore %tesse_out_color %tesse_computed_clr\n"
1584 "; Fragment Entry\n"
1585 "%frag_main = OpFunction %void None %fun\n"
1586 "%frag_label_main = OpLabel\n"
1587 "%frag_tmp1 = OpLoad %v4f32 %frag_vtxColor\n"
1588 "OpStore %frag_fragColor %frag_tmp1\n"
1593 void createMultipleEntries(vk::SourceCollections& dst, InstanceContext)
1595 dst.spirvAsmSources.add("vert") <<
1596 // This module contains 2 vertex shaders. One that is a passthrough
1597 // and a second that inverts the color of the output (1.0 - color).
1598 "OpCapability Shader\n"
1599 "OpMemoryModel Logical GLSL450\n"
1600 "OpEntryPoint Vertex %main \"vert1\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1601 "OpEntryPoint Vertex %main2 \"vert2\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1603 "OpName %main \"vert1\"\n"
1604 "OpName %main2 \"vert2\"\n"
1605 "OpName %vtxPosition \"vtxPosition\"\n"
1606 "OpName %Position \"position\"\n"
1607 "OpName %vtxColor \"vtxColor\"\n"
1608 "OpName %color \"color\"\n"
1609 "OpName %vertex_id \"gl_VertexIndex\"\n"
1610 "OpName %instance_id \"gl_InstanceIndex\"\n"
1612 "OpDecorate %vtxPosition Location 2\n"
1613 "OpDecorate %Position Location 0\n"
1614 "OpDecorate %vtxColor Location 1\n"
1615 "OpDecorate %color Location 1\n"
1616 "OpDecorate %vertex_id BuiltIn VertexIndex\n"
1617 "OpDecorate %instance_id BuiltIn InstanceIndex\n"
1618 SPIRV_ASSEMBLY_TYPES
1619 SPIRV_ASSEMBLY_CONSTANTS
1620 SPIRV_ASSEMBLY_ARRAYS
1621 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1622 "%vtxPosition = OpVariable %op_v4f32 Output\n"
1623 "%Position = OpVariable %ip_v4f32 Input\n"
1624 "%vtxColor = OpVariable %op_v4f32 Output\n"
1625 "%color = OpVariable %ip_v4f32 Input\n"
1626 "%vertex_id = OpVariable %ip_i32 Input\n"
1627 "%instance_id = OpVariable %ip_i32 Input\n"
1629 "%main = OpFunction %void None %fun\n"
1630 "%label = OpLabel\n"
1631 "%tmp_position = OpLoad %v4f32 %Position\n"
1632 "OpStore %vtxPosition %tmp_position\n"
1633 "%tmp_color = OpLoad %v4f32 %color\n"
1634 "OpStore %vtxColor %tmp_color\n"
1638 "%main2 = OpFunction %void None %fun\n"
1639 "%label2 = OpLabel\n"
1640 "%tmp_position2 = OpLoad %v4f32 %Position\n"
1641 "OpStore %vtxPosition %tmp_position2\n"
1642 "%tmp_color2 = OpLoad %v4f32 %color\n"
1643 "%tmp_color3 = OpFSub %v4f32 %cval %tmp_color2\n"
1644 "%tmp_color4 = OpVectorInsertDynamic %v4f32 %tmp_color3 %c_f32_1 %c_i32_3\n"
1645 "OpStore %vtxColor %tmp_color4\n"
1649 dst.spirvAsmSources.add("frag") <<
1650 // This is a single module that contains 2 fragment shaders.
1651 // One that passes color through and the other that inverts the output
1652 // color (1.0 - color).
1653 "OpCapability Shader\n"
1654 "OpMemoryModel Logical GLSL450\n"
1655 "OpEntryPoint Fragment %main \"frag1\" %vtxColor %fragColor\n"
1656 "OpEntryPoint Fragment %main2 \"frag2\" %vtxColor %fragColor\n"
1657 "OpExecutionMode %main OriginUpperLeft\n"
1658 "OpExecutionMode %main2 OriginUpperLeft\n"
1660 "OpName %main \"frag1\"\n"
1661 "OpName %main2 \"frag2\"\n"
1662 "OpName %fragColor \"fragColor\"\n"
1663 "OpName %vtxColor \"vtxColor\"\n"
1664 "OpDecorate %fragColor Location 0\n"
1665 "OpDecorate %vtxColor Location 1\n"
1666 SPIRV_ASSEMBLY_TYPES
1667 SPIRV_ASSEMBLY_CONSTANTS
1668 SPIRV_ASSEMBLY_ARRAYS
1669 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1670 "%fragColor = OpVariable %op_v4f32 Output\n"
1671 "%vtxColor = OpVariable %ip_v4f32 Input\n"
1673 "%main = OpFunction %void None %fun\n"
1674 "%label_main = OpLabel\n"
1675 "%tmp1 = OpLoad %v4f32 %vtxColor\n"
1676 "OpStore %fragColor %tmp1\n"
1680 "%main2 = OpFunction %void None %fun\n"
1681 "%label_main2 = OpLabel\n"
1682 "%tmp2 = OpLoad %v4f32 %vtxColor\n"
1683 "%tmp3 = OpFSub %v4f32 %cval %tmp2\n"
1684 "%tmp4 = OpVectorInsertDynamic %v4f32 %tmp3 %c_f32_1 %c_i32_3\n"
1685 "OpStore %fragColor %tmp4\n"
1689 dst.spirvAsmSources.add("geom") <<
1690 "OpCapability Geometry\n"
1691 "OpCapability ClipDistance\n"
1692 "OpCapability CullDistance\n"
1693 "OpMemoryModel Logical GLSL450\n"
1694 "OpEntryPoint Geometry %geom1_main \"geom1\" %out_gl_position %gl_in %out_color %in_color\n"
1695 "OpEntryPoint Geometry %geom2_main \"geom2\" %out_gl_position %gl_in %out_color %in_color\n"
1696 "OpExecutionMode %geom1_main Triangles\n"
1697 "OpExecutionMode %geom2_main Triangles\n"
1698 "OpExecutionMode %geom1_main OutputTriangleStrip\n"
1699 "OpExecutionMode %geom2_main OutputTriangleStrip\n"
1700 "OpExecutionMode %geom1_main OutputVertices 3\n"
1701 "OpExecutionMode %geom2_main OutputVertices 3\n"
1702 "OpName %geom1_main \"geom1\"\n"
1703 "OpName %geom2_main \"geom2\"\n"
1704 "OpName %per_vertex_in \"gl_PerVertex\"\n"
1705 "OpMemberName %per_vertex_in 0 \"gl_Position\"\n"
1706 "OpMemberName %per_vertex_in 1 \"gl_PointSize\"\n"
1707 "OpMemberName %per_vertex_in 2 \"gl_ClipDistance\"\n"
1708 "OpMemberName %per_vertex_in 3 \"gl_CullDistance\"\n"
1709 "OpName %gl_in \"gl_in\"\n"
1710 "OpName %out_color \"out_color\"\n"
1711 "OpName %in_color \"in_color\"\n"
1712 "OpDecorate %out_gl_position BuiltIn Position\n"
1713 "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n"
1714 "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n"
1715 "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n"
1716 "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n"
1717 "OpDecorate %per_vertex_in Block\n"
1718 "OpDecorate %out_color Location 1\n"
1719 "OpDecorate %in_color Location 1\n"
1720 SPIRV_ASSEMBLY_TYPES
1721 SPIRV_ASSEMBLY_CONSTANTS
1722 SPIRV_ASSEMBLY_ARRAYS
1723 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1724 "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1725 "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n"
1726 "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n"
1727 "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n"
1728 "%out_color = OpVariable %op_v4f32 Output\n"
1729 "%in_color = OpVariable %ip_a3v4f32 Input\n"
1730 "%out_gl_position = OpVariable %op_v4f32 Output\n"
1732 "%geom1_main = OpFunction %void None %fun\n"
1733 "%geom1_label = OpLabel\n"
1734 "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1735 "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1736 "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1737 "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n"
1738 "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n"
1739 "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n"
1740 "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1741 "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1742 "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1743 "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n"
1744 "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n"
1745 "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n"
1746 "OpStore %out_gl_position %geom1_in_position_0\n"
1747 "OpStore %out_color %geom1_in_color_0\n"
1749 "OpStore %out_gl_position %geom1_in_position_1\n"
1750 "OpStore %out_color %geom1_in_color_1\n"
1752 "OpStore %out_gl_position %geom1_in_position_2\n"
1753 "OpStore %out_color %geom1_in_color_2\n"
1759 "%geom2_main = OpFunction %void None %fun\n"
1760 "%geom2_label = OpLabel\n"
1761 "%geom2_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1762 "%geom2_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1763 "%geom2_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1764 "%geom2_in_position_0 = OpLoad %v4f32 %geom2_gl_in_0_gl_position\n"
1765 "%geom2_in_position_1 = OpLoad %v4f32 %geom2_gl_in_1_gl_position\n"
1766 "%geom2_in_position_2 = OpLoad %v4f32 %geom2_gl_in_2_gl_position \n"
1767 "%geom2_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1768 "%geom2_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1769 "%geom2_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1770 "%geom2_in_color_0 = OpLoad %v4f32 %geom2_in_color_0_ptr\n"
1771 "%geom2_in_color_1 = OpLoad %v4f32 %geom2_in_color_1_ptr\n"
1772 "%geom2_in_color_2 = OpLoad %v4f32 %geom2_in_color_2_ptr\n"
1773 "%geom2_transformed_in_color_0 = OpFSub %v4f32 %cval %geom2_in_color_0\n"
1774 "%geom2_transformed_in_color_1 = OpFSub %v4f32 %cval %geom2_in_color_1\n"
1775 "%geom2_transformed_in_color_2 = OpFSub %v4f32 %cval %geom2_in_color_2\n"
1776 "%geom2_transformed_in_color_0_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_0 %c_f32_1 %c_i32_3\n"
1777 "%geom2_transformed_in_color_1_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_1 %c_f32_1 %c_i32_3\n"
1778 "%geom2_transformed_in_color_2_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_2 %c_f32_1 %c_i32_3\n"
1779 "OpStore %out_gl_position %geom2_in_position_0\n"
1780 "OpStore %out_color %geom2_transformed_in_color_0_a\n"
1782 "OpStore %out_gl_position %geom2_in_position_1\n"
1783 "OpStore %out_color %geom2_transformed_in_color_1_a\n"
1785 "OpStore %out_gl_position %geom2_in_position_2\n"
1786 "OpStore %out_color %geom2_transformed_in_color_2_a\n"
1792 dst.spirvAsmSources.add("tessc") <<
1793 "OpCapability Tessellation\n"
1794 "OpMemoryModel Logical GLSL450\n"
1795 "OpEntryPoint TessellationControl %tessc1_main \"tessc1\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1796 "OpEntryPoint TessellationControl %tessc2_main \"tessc2\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1797 "OpExecutionMode %tessc1_main OutputVertices 3\n"
1798 "OpExecutionMode %tessc2_main OutputVertices 3\n"
1799 "OpName %tessc1_main \"tessc1\"\n"
1800 "OpName %tessc2_main \"tessc2\"\n"
1801 "OpName %out_color \"out_color\"\n"
1802 "OpName %gl_InvocationID \"gl_InvocationID\"\n"
1803 "OpName %in_color \"in_color\"\n"
1804 "OpName %out_position \"out_position\"\n"
1805 "OpName %in_position \"in_position\"\n"
1806 "OpName %gl_TessLevelOuter \"gl_TessLevelOuter\"\n"
1807 "OpName %gl_TessLevelInner \"gl_TessLevelInner\"\n"
1808 "OpDecorate %out_color Location 1\n"
1809 "OpDecorate %gl_InvocationID BuiltIn InvocationId\n"
1810 "OpDecorate %in_color Location 1\n"
1811 "OpDecorate %out_position Location 2\n"
1812 "OpDecorate %in_position Location 2\n"
1813 "OpDecorate %gl_TessLevelOuter Patch\n"
1814 "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1815 "OpDecorate %gl_TessLevelInner Patch\n"
1816 "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n"
1817 SPIRV_ASSEMBLY_TYPES
1818 SPIRV_ASSEMBLY_CONSTANTS
1819 SPIRV_ASSEMBLY_ARRAYS
1820 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1821 "%out_color = OpVariable %op_a3v4f32 Output\n"
1822 "%gl_InvocationID = OpVariable %ip_i32 Input\n"
1823 "%in_color = OpVariable %ip_a32v4f32 Input\n"
1824 "%out_position = OpVariable %op_a3v4f32 Output\n"
1825 "%in_position = OpVariable %ip_a32v4f32 Input\n"
1826 "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1827 "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1829 "%tessc1_main = OpFunction %void None %fun\n"
1830 "%tessc1_label = OpLabel\n"
1831 "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1832 "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n"
1833 "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n"
1834 "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n"
1835 "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n"
1836 "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n"
1837 "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n"
1838 "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n"
1839 "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n"
1840 "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n"
1841 "OpSelectionMerge %tessc1_merge_label None\n"
1842 "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n"
1843 "%tessc1_first_invocation = OpLabel\n"
1844 "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1845 "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1846 "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1847 "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1848 "OpStore %tessc1_tess_outer_0 %c_f32_1\n"
1849 "OpStore %tessc1_tess_outer_1 %c_f32_1\n"
1850 "OpStore %tessc1_tess_outer_2 %c_f32_1\n"
1851 "OpStore %tessc1_tess_inner %c_f32_1\n"
1852 "OpBranch %tessc1_merge_label\n"
1853 "%tessc1_merge_label = OpLabel\n"
1857 "%tessc2_main = OpFunction %void None %fun\n"
1858 "%tessc2_label = OpLabel\n"
1859 "%tessc2_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1860 "%tessc2_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc2_invocation_id\n"
1861 "%tessc2_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc2_invocation_id\n"
1862 "%tessc2_in_color_val = OpLoad %v4f32 %tessc2_in_color_ptr\n"
1863 "%tessc2_in_position_val = OpLoad %v4f32 %tessc2_in_position_ptr\n"
1864 "%tessc2_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc2_invocation_id\n"
1865 "%tessc2_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc2_invocation_id\n"
1866 "%tessc2_transformed_color = OpFSub %v4f32 %cval %tessc2_in_color_val\n"
1867 "%tessc2_transformed_color_a = OpVectorInsertDynamic %v4f32 %tessc2_transformed_color %c_f32_1 %c_i32_3\n"
1868 "OpStore %tessc2_out_color_ptr %tessc2_transformed_color_a\n"
1869 "OpStore %tessc2_out_position_ptr %tessc2_in_position_val\n"
1870 "%tessc2_is_first_invocation = OpIEqual %bool %tessc2_invocation_id %c_i32_0\n"
1871 "OpSelectionMerge %tessc2_merge_label None\n"
1872 "OpBranchConditional %tessc2_is_first_invocation %tessc2_first_invocation %tessc2_merge_label\n"
1873 "%tessc2_first_invocation = OpLabel\n"
1874 "%tessc2_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1875 "%tessc2_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1876 "%tessc2_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1877 "%tessc2_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1878 "OpStore %tessc2_tess_outer_0 %c_f32_1\n"
1879 "OpStore %tessc2_tess_outer_1 %c_f32_1\n"
1880 "OpStore %tessc2_tess_outer_2 %c_f32_1\n"
1881 "OpStore %tessc2_tess_inner %c_f32_1\n"
1882 "OpBranch %tessc2_merge_label\n"
1883 "%tessc2_merge_label = OpLabel\n"
1887 dst.spirvAsmSources.add("tesse") <<
1888 "OpCapability Tessellation\n"
1889 "OpCapability ClipDistance\n"
1890 "OpCapability CullDistance\n"
1891 "OpMemoryModel Logical GLSL450\n"
1892 "OpEntryPoint TessellationEvaluation %tesse1_main \"tesse1\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
1893 "OpEntryPoint TessellationEvaluation %tesse2_main \"tesse2\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
1894 "OpExecutionMode %tesse1_main Triangles\n"
1895 "OpExecutionMode %tesse1_main SpacingEqual\n"
1896 "OpExecutionMode %tesse1_main VertexOrderCcw\n"
1897 "OpExecutionMode %tesse2_main Triangles\n"
1898 "OpExecutionMode %tesse2_main SpacingEqual\n"
1899 "OpExecutionMode %tesse2_main VertexOrderCcw\n"
1900 "OpName %tesse1_main \"tesse1\"\n"
1901 "OpName %tesse2_main \"tesse2\"\n"
1902 "OpName %per_vertex_out \"gl_PerVertex\"\n"
1903 "OpMemberName %per_vertex_out 0 \"gl_Position\"\n"
1904 "OpMemberName %per_vertex_out 1 \"gl_PointSize\"\n"
1905 "OpMemberName %per_vertex_out 2 \"gl_ClipDistance\"\n"
1906 "OpMemberName %per_vertex_out 3 \"gl_CullDistance\"\n"
1907 "OpName %stream \"\"\n"
1908 "OpName %gl_tessCoord \"gl_TessCoord\"\n"
1909 "OpName %in_position \"in_position\"\n"
1910 "OpName %out_color \"out_color\"\n"
1911 "OpName %in_color \"in_color\"\n"
1912 "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n"
1913 "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n"
1914 "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n"
1915 "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n"
1916 "OpDecorate %per_vertex_out Block\n"
1917 "OpDecorate %gl_tessCoord BuiltIn TessCoord\n"
1918 "OpDecorate %in_position Location 2\n"
1919 "OpDecorate %out_color Location 1\n"
1920 "OpDecorate %in_color Location 1\n"
1921 SPIRV_ASSEMBLY_TYPES
1922 SPIRV_ASSEMBLY_CONSTANTS
1923 SPIRV_ASSEMBLY_ARRAYS
1924 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1925 "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1926 "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n"
1927 "%stream = OpVariable %op_per_vertex_out Output\n"
1928 "%gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1929 "%in_position = OpVariable %ip_a32v4f32 Input\n"
1930 "%out_color = OpVariable %op_v4f32 Output\n"
1931 "%in_color = OpVariable %ip_a32v4f32 Input\n"
1933 "%tesse1_main = OpFunction %void None %fun\n"
1934 "%tesse1_label = OpLabel\n"
1935 "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
1936 "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
1937 "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
1938 "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n"
1939 "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n"
1940 "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n"
1941 "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
1942 "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
1943 "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
1944 "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n"
1945 "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n"
1946 "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n"
1947 "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n"
1948 "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n"
1949 "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n"
1950 "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
1951 "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n"
1952 "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n"
1953 "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n"
1954 "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1955 "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1956 "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1957 "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n"
1958 "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n"
1959 "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n"
1960 "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n"
1961 "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n"
1962 "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n"
1963 "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n"
1964 "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n"
1965 "OpStore %out_color %tesse1_computed_clr\n"
1969 "%tesse2_main = OpFunction %void None %fun\n"
1970 "%tesse2_label = OpLabel\n"
1971 "%tesse2_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
1972 "%tesse2_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
1973 "%tesse2_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
1974 "%tesse2_tc_0 = OpLoad %f32 %tesse2_tc_0_ptr\n"
1975 "%tesse2_tc_1 = OpLoad %f32 %tesse2_tc_1_ptr\n"
1976 "%tesse2_tc_2 = OpLoad %f32 %tesse2_tc_2_ptr\n"
1977 "%tesse2_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
1978 "%tesse2_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
1979 "%tesse2_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
1980 "%tesse2_in_pos_0 = OpLoad %v4f32 %tesse2_in_pos_0_ptr\n"
1981 "%tesse2_in_pos_1 = OpLoad %v4f32 %tesse2_in_pos_1_ptr\n"
1982 "%tesse2_in_pos_2 = OpLoad %v4f32 %tesse2_in_pos_2_ptr\n"
1983 "%tesse2_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_0 %tesse2_tc_0\n"
1984 "%tesse2_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_1 %tesse2_tc_1\n"
1985 "%tesse2_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_2 %tesse2_tc_2\n"
1986 "%tesse2_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
1987 "%tesse2_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse2_in_pos_0_weighted %tesse2_in_pos_1_weighted\n"
1988 "%tesse2_computed_out = OpFAdd %v4f32 %tesse2_in_pos_0_plus_pos_1 %tesse2_in_pos_2_weighted\n"
1989 "OpStore %tesse2_out_pos_ptr %tesse2_computed_out\n"
1990 "%tesse2_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1991 "%tesse2_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1992 "%tesse2_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1993 "%tesse2_in_clr_0 = OpLoad %v4f32 %tesse2_in_clr_0_ptr\n"
1994 "%tesse2_in_clr_1 = OpLoad %v4f32 %tesse2_in_clr_1_ptr\n"
1995 "%tesse2_in_clr_2 = OpLoad %v4f32 %tesse2_in_clr_2_ptr\n"
1996 "%tesse2_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_0 %tesse2_tc_0\n"
1997 "%tesse2_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_1 %tesse2_tc_1\n"
1998 "%tesse2_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_2 %tesse2_tc_2\n"
1999 "%tesse2_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse2_in_clr_0_weighted %tesse2_in_clr_1_weighted\n"
2000 "%tesse2_computed_clr = OpFAdd %v4f32 %tesse2_in_clr_0_plus_col_1 %tesse2_in_clr_2_weighted\n"
2001 "%tesse2_clr_transformed = OpFSub %v4f32 %cval %tesse2_computed_clr\n"
2002 "%tesse2_clr_transformed_a = OpVectorInsertDynamic %v4f32 %tesse2_clr_transformed %c_f32_1 %c_i32_3\n"
2003 "OpStore %out_color %tesse2_clr_transformed_a\n"
2008 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
2010 // We only support RTE, RTZ, or both.
2011 DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);
2013 const Float32 originalFloat (original);
2014 const Float16 returnedFloat (returned);
2016 // Zero are turned into zero under both RTE and RTZ.
2017 if (originalFloat.isZero())
2019 if (returnedFloat.isZero())
2022 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2026 // Inf are always turned into Inf with the same sign, too.
2027 if (originalFloat.isInf())
2029 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2032 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2036 // NaN are always turned into NaN, too.
2037 if (originalFloat.isNaN())
2039 if (returnedFloat.isNaN())
2042 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2046 // Check all rounding modes
2047 for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
2049 if ((flags & (1u << bitNdx)) == 0)
2050 continue; // This rounding mode is not selected.
2052 const Float16 expectedFloat (deFloat32To16Round(original, deRoundingMode(bitNdx)));
2054 // Denormalized numbers can be flushed to zero.
2055 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2058 // If not matched in the above cases, they should have the same bit pattern.
2059 if (expectedFloat.bits() == returnedFloat.bits())
2063 log << TestLog::Message << "Error: found unmatched 32-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
2067 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log)
2069 const Float32 expectedFloat (expected);
2070 const Float32 returnedFloat (returned);
2072 // Denormalized numbers can be flushed to zero
2073 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2076 if (expectedFloat.isNaN())
2078 if (returnedFloat.isNaN())
2081 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2085 if (returned == expected)
2088 log << TestLog::Message << "Error: found unmatched 32-bit float: expected " << expectedFloat.bits() << " vs. returned " << returnedFloat.bits() << TestLog::EndMessage;
2092 Move<VkBuffer> createBufferForResource(const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex)
2094 const VkBufferCreateInfo resourceBufferParams =
2096 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
2098 (VkBufferCreateFlags)0, // flags
2099 (VkDeviceSize)resource.second->getNumBytes(), // size
2100 (VkBufferUsageFlags)getMatchingBufferUsageFlagBit(resource.first), // usage
2101 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2102 1u, // queueFamilyCount
2103 &queueFamilyIndex, // pQueueFamilyIndices
2106 return createBuffer(vk, vkDevice, &resourceBufferParams);
2109 TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance)
2111 const InstanceInterface& vkInstance = context.getInstanceInterface();
2112 const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice();
2113 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2114 // Create a dedicated logic device with required extensions enabled for this test case.
2115 const Unique<VkDevice> vkDevice (createDeviceWithExtensions(context, queueFamilyIndex, context.getDeviceExtensions(), instance.requiredDeviceExtensions));
2116 const DeviceDriver vk (vkInstance, *vkDevice);
2117 const VkQueue queue = getDeviceQueue(vk, *vkDevice, queueFamilyIndex, 0);
2118 const tcu::UVec2 renderSize (256, 256);
2119 vector<ModuleHandleSp> modules;
2120 map<VkShaderStageFlagBits, VkShaderModule> moduleByStage;
2121 const int testSpecificSeed = 31354125;
2122 const int seed = context.getTestContext().getCommandLine().getBaseSeed() ^ testSpecificSeed;
2123 bool supportsGeometry = false;
2124 bool supportsTessellation = false;
2125 bool hasTessellation = false;
2126 const bool hasPushConstants = !instance.pushConstants.empty();
2127 const deUint32 numResources = static_cast<deUint32>(instance.resources.inputs.size() + instance.resources.outputs.size());
2128 const bool needInterface = !instance.interfaces.empty();
2129 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2130 const de::UniquePtr<Allocator> allocatorUptr (createAllocator(vkInstance, vkPhysicalDevice, vk, *vkDevice));
2131 Allocator& allocator = *allocatorUptr;
2133 supportsGeometry = features.geometryShader == VK_TRUE;
2134 supportsTessellation = features.tessellationShader == VK_TRUE;
2135 hasTessellation = (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) ||
2136 (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2138 if (hasTessellation && !supportsTessellation)
2140 throw tcu::NotSupportedError(std::string("Tessellation not supported"));
2143 if ((instance.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT) &&
2146 throw tcu::NotSupportedError(std::string("Geometry not supported"));
2150 for (deUint32 featureNdx = 0; featureNdx < instance.requiredDeviceFeatures.size(); ++featureNdx)
2152 const string& feature = instance.requiredDeviceFeatures[featureNdx];
2154 if (feature == "shaderInt16")
2156 if (features.shaderInt16 != VK_TRUE)
2157 throw tcu::NotSupportedError(std::string("Device feature not supported: ") + feature);
2161 throw tcu::InternalError(std::string("Unimplemented physical device feature: ") + feature);
2166 // 16bit storage features
2168 if (!is16BitStorageFeaturesSupported(vkInstance, vkPhysicalDevice, context.getInstanceExtensions(), instance.requestedExtensionFeatures.ext16BitStorage))
2169 TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
2172 de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4);
2173 de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4);
2174 const Vec4 vertexData[] =
2176 // Upper left corner:
2177 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2178 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2179 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(),
2181 // Upper right corner:
2182 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2183 Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2184 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(),
2186 // Lower left corner:
2187 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2188 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2189 Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(),
2191 // Lower right corner:
2192 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(),
2193 Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(),
2194 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec()
2196 const size_t singleVertexDataSize = 2 * sizeof(Vec4);
2197 const size_t vertexCount = sizeof(vertexData) / singleVertexDataSize;
2199 Move<VkBuffer> vertexInputBuffer ;
2200 de::MovePtr<Allocation> vertexInputMemory ;
2201 Move<VkBuffer> fragOutputBuffer ;
2202 de::MovePtr<Allocation> fragOutputMemory ;
2203 Move<VkImage> fragOutputImage ;
2204 de::MovePtr<Allocation> fragOutputImageMemory ;
2205 Move<VkImageView> fragOutputImageView ;
2207 const VkBufferCreateInfo vertexBufferParams =
2209 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2210 DE_NULL, // const void* pNext;
2211 0u, // VkBufferCreateFlags flags;
2212 (VkDeviceSize)sizeof(vertexData), // VkDeviceSize size;
2213 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2214 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2215 1u, // deUint32 queueFamilyCount;
2216 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2218 const Unique<VkBuffer> vertexBuffer (createBuffer(vk, *vkDevice, &vertexBufferParams));
2219 const UniquePtr<Allocation> vertexBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
2221 VK_CHECK(vk.bindBufferMemory(*vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
2223 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
2224 const VkBufferCreateInfo readImageBufferParams =
2226 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2227 DE_NULL, // const void* pNext;
2228 0u, // VkBufferCreateFlags flags;
2229 imageSizeBytes, // VkDeviceSize size;
2230 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2231 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2232 1u, // deUint32 queueFamilyCount;
2233 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2235 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, *vkDevice, &readImageBufferParams));
2236 const UniquePtr<Allocation> readImageBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
2238 VK_CHECK(vk.bindBufferMemory(*vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2240 VkImageCreateInfo imageParams =
2242 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2243 DE_NULL, // const void* pNext;
2244 0u, // VkImageCreateFlags flags;
2245 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2246 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2247 { renderSize.x(), renderSize.y(), 1 }, // VkExtent3D extent;
2248 1u, // deUint32 mipLevels;
2249 1u, // deUint32 arraySize;
2250 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2251 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2252 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2253 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2254 1u, // deUint32 queueFamilyCount;
2255 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2256 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2259 const Unique<VkImage> image (createImage(vk, *vkDevice, &imageParams));
2260 const UniquePtr<Allocation> imageMemory (allocator.allocate(getImageMemoryRequirements(vk, *vkDevice, *image), MemoryRequirement::Any));
2262 VK_CHECK(vk.bindImageMemory(*vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
2266 // The pipeline renders four triangles, each with three vertexes.
2267 // Test instantialization only provides four data points, each
2268 // for one triangle. So we need allocate space of three times of
2269 // input buffer's size.
2270 const deUint32 inputNumBytes = deUint32(instance.interfaces.getInputBuffer()->getNumBytes() * 3);
2271 // Create an additional buffer and backing memory for one input variable.
2272 const VkBufferCreateInfo vertexInputParams =
2274 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2275 DE_NULL, // const void* pNext;
2276 0u, // VkBufferCreateFlags flags;
2277 inputNumBytes, // VkDeviceSize size;
2278 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2279 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2280 1u, // deUint32 queueFamilyCount;
2281 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2284 vertexInputBuffer = createBuffer(vk, *vkDevice, &vertexInputParams);
2285 vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *vertexInputBuffer), MemoryRequirement::HostVisible);
2286 VK_CHECK(vk.bindBufferMemory(*vkDevice, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset()));
2288 // Create an additional buffer and backing memory for an output variable.
2289 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
2290 const VkBufferCreateInfo fragOutputParams =
2292 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2293 DE_NULL, // const void* pNext;
2294 0u, // VkBufferCreateFlags flags;
2295 fragOutputImgSize, // VkDeviceSize size;
2296 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2297 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2298 1u, // deUint32 queueFamilyCount;
2299 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2301 fragOutputBuffer = createBuffer(vk, *vkDevice, &fragOutputParams);
2302 fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *fragOutputBuffer), MemoryRequirement::HostVisible);
2303 VK_CHECK(vk.bindBufferMemory(*vkDevice, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset()));
2305 // Create an additional image and backing memory for attachment.
2306 // Reuse the previous imageParams since we only need to change the image format.
2307 imageParams.format = instance.interfaces.getOutputType().getVkFormat();
2309 // Check the usage bits on the given image format are supported.
2310 requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.usage);
2312 fragOutputImage = createImage(vk, *vkDevice, &imageParams);
2313 fragOutputImageMemory = allocator.allocate(getImageMemoryRequirements(vk, *vkDevice, *fragOutputImage), MemoryRequirement::Any);
2315 VK_CHECK(vk.bindImageMemory(*vkDevice, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset()));
2318 vector<VkAttachmentDescription> colorAttDescs ;
2319 vector<VkAttachmentReference> colorAttRefs ;
2321 const VkAttachmentDescription attDesc =
2323 0u, // VkAttachmentDescriptionFlags flags;
2324 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2325 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2326 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2327 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2328 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2329 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2330 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2331 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2333 colorAttDescs.push_back(attDesc);
2335 const VkAttachmentReference attRef =
2337 0u, // deUint32 attachment;
2338 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
2340 colorAttRefs.push_back(attRef);
2345 const VkAttachmentDescription attDesc =
2347 0u, // VkAttachmentDescriptionFlags flags;
2348 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
2349 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2350 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2351 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2352 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2353 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2354 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2355 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2357 colorAttDescs.push_back(attDesc);
2359 const VkAttachmentReference attRef =
2361 1u, // deUint32 attachment;
2362 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
2364 colorAttRefs.push_back(attRef);
2367 VkSubpassDescription subpassDesc =
2369 0u, // VkSubpassDescriptionFlags flags;
2370 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2371 0u, // deUint32 inputCount;
2372 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2373 1u, // deUint32 colorCount;
2374 colorAttRefs.data(), // const VkAttachmentReference* pColorAttachments;
2375 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2376 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
2377 0u, // deUint32 preserveCount;
2378 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
2381 VkRenderPassCreateInfo renderPassParams =
2383 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2384 DE_NULL, // const void* pNext;
2385 (VkRenderPassCreateFlags)0,
2386 1u, // deUint32 attachmentCount;
2387 colorAttDescs.data(), // const VkAttachmentDescription* pAttachments;
2388 1u, // deUint32 subpassCount;
2389 &subpassDesc, // const VkSubpassDescription* pSubpasses;
2390 0u, // deUint32 dependencyCount;
2391 DE_NULL, // const VkSubpassDependency* pDependencies;
2396 subpassDesc.colorAttachmentCount += 1;
2397 renderPassParams.attachmentCount += 1;
2400 const Unique<VkRenderPass> renderPass (createRenderPass(vk, *vkDevice, &renderPassParams));
2402 const VkImageViewCreateInfo colorAttViewParams =
2404 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2405 DE_NULL, // const void* pNext;
2406 0u, // VkImageViewCreateFlags flags;
2407 *image, // VkImage image;
2408 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2409 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2411 VK_COMPONENT_SWIZZLE_R,
2412 VK_COMPONENT_SWIZZLE_G,
2413 VK_COMPONENT_SWIZZLE_B,
2414 VK_COMPONENT_SWIZZLE_A
2415 }, // VkChannelMapping channels;
2417 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2418 0u, // deUint32 baseMipLevel;
2419 1u, // deUint32 mipLevels;
2420 0u, // deUint32 baseArrayLayer;
2421 1u, // deUint32 arraySize;
2422 }, // VkImageSubresourceRange subresourceRange;
2424 const Unique<VkImageView> colorAttView (createImageView(vk, *vkDevice, &colorAttViewParams));
2426 vector<VkImageView> attViews ;
2427 attViews.push_back(*colorAttView);
2429 // Handle resources requested by the test instantiation.
2430 const deUint32 numInResources = static_cast<deUint32>(instance.resources.inputs.size());
2431 const deUint32 numOutResources = static_cast<deUint32>(instance.resources.outputs.size());
2432 // These variables should be placed out of the following if block to avoid deallocation after out of scope.
2433 vector<AllocationSp> inResourceMemories ;
2434 vector<AllocationSp> outResourceMemories ;
2435 vector<BufferHandleSp> inResourceBuffers ;
2436 vector<BufferHandleSp> outResourceBuffers ;
2437 Move<VkDescriptorPool> descriptorPool ;
2438 Move<VkDescriptorSetLayout> setLayout ;
2439 VkDescriptorSetLayout rawSetLayout = DE_NULL;
2440 VkDescriptorSet rawSet = DE_NULL;
2442 if (numResources != 0)
2444 vector<VkDescriptorSetLayoutBinding> setLayoutBindings ;
2445 vector<VkDescriptorPoolSize> poolSizes ;
2447 setLayoutBindings.reserve(numResources);
2448 poolSizes.reserve(numResources);
2450 // Process all input resources.
2451 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2453 const Resource& resource = instance.resources.inputs[inputNdx];
2454 // Create buffer and allocate memory.
2455 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, *vkDevice, resource, queueFamilyIndex);
2456 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *resourceBuffer), MemoryRequirement::HostVisible);
2458 VK_CHECK(vk.bindBufferMemory(*vkDevice, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2460 // Copy data to memory.
2461 const VkMappedMemoryRange range =
2463 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
2464 DE_NULL, // const void* pNext;
2465 resourceMemory->getMemory(), // VkDeviceMemory mem;
2466 0, // VkDeviceSize offset;
2467 VK_WHOLE_SIZE, // VkDeviceSize size;
2470 deMemcpy(resourceMemory->getHostPtr(), resource.second->data(), resource.second->getNumBytes());
2471 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
2473 inResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2474 inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2476 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2477 const VkDescriptorSetLayoutBinding binding =
2479 inputNdx, // binding
2480 resource.first, // descriptorType
2481 1u, // descriptorCount
2482 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
2483 DE_NULL, // pImmutableSamplers
2485 setLayoutBindings.push_back(binding);
2487 // Note: the following code doesn't check and unify descriptors of the same type.
2488 const VkDescriptorPoolSize poolSize =
2490 resource.first, // type
2491 1u, // descriptorCount
2493 poolSizes.push_back(poolSize);
2496 // Process all output resources.
2497 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
2499 const Resource& resource = instance.resources.outputs[outputNdx];
2500 // Create buffer and allocate memory.
2501 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, *vkDevice, resource, queueFamilyIndex);
2502 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, *vkDevice, *resourceBuffer), MemoryRequirement::HostVisible);
2504 VK_CHECK(vk.bindBufferMemory(*vkDevice, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2506 // Fill memory with all ones.
2507 const VkMappedMemoryRange range =
2509 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
2510 DE_NULL, // const void* pNext;
2511 resourceMemory->getMemory(), // VkDeviceMemory mem;
2512 0, // VkDeviceSize offset;
2513 VK_WHOLE_SIZE, // VkDeviceSize size;
2516 deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resource.second->getNumBytes());
2517 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
2519 outResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2520 outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2522 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2523 const VkDescriptorSetLayoutBinding binding =
2525 numInResources + outputNdx, // binding
2526 resource.first, // descriptorType
2527 1u, // descriptorCount
2528 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
2529 DE_NULL, // pImmutableSamplers
2531 setLayoutBindings.push_back(binding);
2533 // Note: the following code doesn't check and unify descriptors of the same type.
2534 const VkDescriptorPoolSize poolSize =
2536 resource.first, // type
2537 1u, // descriptorCount
2539 poolSizes.push_back(poolSize);
2542 // Create descriptor set layout, descriptor pool, and allocate descriptor set.
2543 const VkDescriptorSetLayoutCreateInfo setLayoutParams =
2545 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
2547 (VkDescriptorSetLayoutCreateFlags)0, // flags
2548 numResources, // bindingCount
2549 setLayoutBindings.data(), // pBindings
2551 setLayout = createDescriptorSetLayout(vk, *vkDevice, &setLayoutParams);
2552 rawSetLayout = *setLayout;
2554 const VkDescriptorPoolCreateInfo poolParams =
2556 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
2558 (VkDescriptorPoolCreateFlags)0, // flags
2560 numResources, // poolSizeCount
2561 poolSizes.data(), // pPoolSizes
2563 descriptorPool = createDescriptorPool(vk, *vkDevice, &poolParams);
2565 const VkDescriptorSetAllocateInfo setAllocParams =
2567 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
2569 *descriptorPool, // descriptorPool
2570 1u, // descriptorSetCount
2571 &rawSetLayout, // pSetLayouts
2573 VK_CHECK(vk.allocateDescriptorSets(*vkDevice, &setAllocParams, &rawSet));
2575 // Update descriptor set.
2576 vector<VkWriteDescriptorSet> writeSpecs ;
2577 vector<VkDescriptorBufferInfo> dBufferInfos ;
2579 writeSpecs.reserve(numResources);
2580 dBufferInfos.reserve(numResources);
2582 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2584 const VkDescriptorBufferInfo bufInfo =
2586 **inResourceBuffers[inputNdx], // buffer
2588 VK_WHOLE_SIZE, // size
2590 dBufferInfos.push_back(bufInfo);
2592 const VkWriteDescriptorSet writeSpec = {
2593 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
2596 inputNdx, // binding
2597 0, // dstArrayElement
2598 1u, // descriptorCount
2599 instance.resources.inputs[inputNdx].first, // descriptorType
2600 DE_NULL, // pImageInfo
2601 &dBufferInfos.back(), // pBufferInfo
2602 DE_NULL, // pTexelBufferView
2604 writeSpecs.push_back(writeSpec);
2606 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
2608 const VkDescriptorBufferInfo bufInfo =
2610 **outResourceBuffers[outputNdx], // buffer
2612 VK_WHOLE_SIZE, // size
2614 dBufferInfos.push_back(bufInfo);
2616 const VkWriteDescriptorSet writeSpec = {
2617 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
2620 numInResources + outputNdx, // binding
2621 0, // dstArrayElement
2622 1u, // descriptorCount
2623 instance.resources.outputs[outputNdx].first, // descriptorType
2624 DE_NULL, // pImageInfo
2625 &dBufferInfos.back(), // pBufferInfo
2626 DE_NULL, // pTexelBufferView
2628 writeSpecs.push_back(writeSpec);
2630 vk.updateDescriptorSets(*vkDevice, numResources, writeSpecs.data(), 0, DE_NULL);
2634 VkPipelineLayoutCreateInfo pipelineLayoutParams =
2636 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
2637 DE_NULL, // const void* pNext;
2638 (VkPipelineLayoutCreateFlags)0,
2639 0u, // deUint32 descriptorSetCount;
2640 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
2641 0u, // deUint32 pushConstantRangeCount;
2642 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
2645 VkPushConstantRange pushConstantRange =
2647 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags stageFlags;
2648 0, // uint32_t offset;
2649 0, // uint32_t size;
2651 if (hasPushConstants)
2653 pushConstantRange.size = static_cast<deUint32>(instance.pushConstants.getBuffer()->getNumBytes());
2654 pipelineLayoutParams.pushConstantRangeCount = 1;
2655 pipelineLayoutParams.pPushConstantRanges = &pushConstantRange;
2657 if (numResources != 0)
2659 // Update pipeline layout with the descriptor set layout.
2660 pipelineLayoutParams.setLayoutCount = 1;
2661 pipelineLayoutParams.pSetLayouts = &rawSetLayout;
2663 const Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, *vkDevice, &pipelineLayoutParams));
2666 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
2667 // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
2668 vector<vector<VkSpecializationMapEntry> > specConstantEntries;
2669 vector<VkSpecializationInfo> specializationInfos;
2670 createPipelineShaderStages(vk, *vkDevice, instance, context, modules, shaderStageParams);
2672 // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
2673 specConstantEntries.reserve(shaderStageParams.size());
2674 specializationInfos.reserve(shaderStageParams.size());
2676 // Patch the specialization info field in PipelineShaderStageCreateInfos.
2677 for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
2679 const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);
2681 if (stageIt != instance.specConstants.end())
2683 const size_t numSpecConstants = stageIt->second.size();
2684 vector<VkSpecializationMapEntry> entries;
2685 VkSpecializationInfo specInfo;
2687 entries.resize(numSpecConstants);
2689 // Only support 32-bit integers as spec constants now. And their constant IDs are numbered sequentially starting from 0.
2690 for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
2692 entries[ndx].constantID = (deUint32)ndx;
2693 entries[ndx].offset = deUint32(ndx * sizeof(deInt32));
2694 entries[ndx].size = sizeof(deInt32);
2697 specConstantEntries.push_back(entries);
2699 specInfo.mapEntryCount = (deUint32)numSpecConstants;
2700 specInfo.pMapEntries = specConstantEntries.back().data();
2701 specInfo.dataSize = numSpecConstants * sizeof(deInt32);
2702 specInfo.pData = stageIt->second.data();
2703 specializationInfos.push_back(specInfo);
2705 stageInfo->pSpecializationInfo = &specializationInfos.back();
2708 const VkPipelineDepthStencilStateCreateInfo depthStencilParams =
2710 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
2711 DE_NULL, // const void* pNext;
2712 (VkPipelineDepthStencilStateCreateFlags)0,
2713 DE_FALSE, // deUint32 depthTestEnable;
2714 DE_FALSE, // deUint32 depthWriteEnable;
2715 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
2716 DE_FALSE, // deUint32 depthBoundsTestEnable;
2717 DE_FALSE, // deUint32 stencilTestEnable;
2719 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
2720 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
2721 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
2722 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
2723 0u, // deUint32 stencilCompareMask;
2724 0u, // deUint32 stencilWriteMask;
2725 0u, // deUint32 stencilReference;
2726 }, // VkStencilOpState front;
2728 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
2729 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
2730 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
2731 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
2732 0u, // deUint32 stencilCompareMask;
2733 0u, // deUint32 stencilWriteMask;
2734 0u, // deUint32 stencilReference;
2735 }, // VkStencilOpState back;
2736 -1.0f, // float minDepthBounds;
2737 +1.0f, // float maxDepthBounds;
2739 const VkViewport viewport0 =
2741 0.0f, // float originX;
2742 0.0f, // float originY;
2743 (float)renderSize.x(), // float width;
2744 (float)renderSize.y(), // float height;
2745 0.0f, // float minDepth;
2746 1.0f, // float maxDepth;
2748 const VkRect2D scissor0 =
2753 }, // VkOffset2D offset;
2755 renderSize.x(), // deInt32 width;
2756 renderSize.y(), // deInt32 height;
2757 }, // VkExtent2D extent;
2759 const VkPipelineViewportStateCreateInfo viewportParams =
2761 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
2762 DE_NULL, // const void* pNext;
2763 (VkPipelineViewportStateCreateFlags)0,
2764 1u, // deUint32 viewportCount;
2769 const VkSampleMask sampleMask = ~0u;
2770 const VkPipelineMultisampleStateCreateInfo multisampleParams =
2772 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2773 DE_NULL, // const void* pNext;
2774 (VkPipelineMultisampleStateCreateFlags)0,
2775 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterSamples;
2776 DE_FALSE, // deUint32 sampleShadingEnable;
2777 0.0f, // float minSampleShading;
2778 &sampleMask, // const VkSampleMask* pSampleMask;
2779 DE_FALSE, // VkBool32 alphaToCoverageEnable;
2780 DE_FALSE, // VkBool32 alphaToOneEnable;
2782 const VkPipelineRasterizationStateCreateInfo rasterParams =
2784 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
2785 DE_NULL, // const void* pNext;
2786 (VkPipelineRasterizationStateCreateFlags)0,
2787 DE_TRUE, // deUint32 depthClipEnable;
2788 DE_FALSE, // deUint32 rasterizerDiscardEnable;
2789 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
2790 VK_CULL_MODE_NONE, // VkCullMode cullMode;
2791 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
2792 VK_FALSE, // VkBool32 depthBiasEnable;
2793 0.0f, // float depthBias;
2794 0.0f, // float depthBiasClamp;
2795 0.0f, // float slopeScaledDepthBias;
2796 1.0f, // float lineWidth;
2798 const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
2799 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyParams =
2801 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
2802 DE_NULL, // const void* pNext;
2803 (VkPipelineInputAssemblyStateCreateFlags)0,
2804 topology, // VkPrimitiveTopology topology;
2805 DE_FALSE, // deUint32 primitiveRestartEnable;
2808 vector<VkVertexInputBindingDescription> vertexBindings;
2809 vector<VkVertexInputAttributeDescription> vertexAttribs;
2811 const VkVertexInputBindingDescription vertexBinding0 =
2813 0u, // deUint32 binding;
2814 deUint32(singleVertexDataSize), // deUint32 strideInBytes;
2815 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
2817 vertexBindings.push_back(vertexBinding0);
2820 VkVertexInputAttributeDescription attr0 =
2822 0u, // deUint32 location;
2823 0u, // deUint32 binding;
2824 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2825 0u // deUint32 offsetInBytes;
2827 vertexAttribs.push_back(attr0);
2829 VkVertexInputAttributeDescription attr1 =
2831 1u, // deUint32 location;
2832 0u, // deUint32 binding;
2833 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
2834 sizeof(Vec4), // deUint32 offsetInBytes;
2836 vertexAttribs.push_back(attr1);
2839 // If the test instantiation has additional input/output interface variables, we need to create additional bindings.
2840 // Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1
2841 // with location #2.
2844 const VkVertexInputBindingDescription vertexBinding1 =
2846 1u, // deUint32 binding;
2847 instance.interfaces.getInputType().getNumBytes(), // deUint32 strideInBytes;
2848 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
2850 vertexBindings.push_back(vertexBinding1);
2852 VkVertexInputAttributeDescription attr =
2854 2u, // deUint32 location;
2855 1u, // deUint32 binding;
2856 instance.interfaces.getInputType().getVkFormat(), // VkFormat format;
2857 0, // deUint32 offsetInBytes;
2859 vertexAttribs.push_back(attr);
2862 VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
2864 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
2865 DE_NULL, // const void* pNext;
2866 (VkPipelineVertexInputStateCreateFlags)0,
2867 1u, // deUint32 bindingCount;
2868 vertexBindings.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
2869 2u, // deUint32 attributeCount;
2870 vertexAttribs.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
2875 vertexInputStateParams.vertexBindingDescriptionCount += 1;
2876 vertexInputStateParams.vertexAttributeDescriptionCount += 1;
2879 vector<VkPipelineColorBlendAttachmentState> attBlendStates ;
2880 const VkPipelineColorBlendAttachmentState attBlendState =
2882 DE_FALSE, // deUint32 blendEnable;
2883 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
2884 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
2885 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
2886 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
2887 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
2888 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
2889 (VK_COLOR_COMPONENT_R_BIT|
2890 VK_COLOR_COMPONENT_G_BIT|
2891 VK_COLOR_COMPONENT_B_BIT|
2892 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask;
2894 attBlendStates.push_back(attBlendState);
2897 attBlendStates.push_back(attBlendState);
2899 VkPipelineColorBlendStateCreateInfo blendParams =
2901 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
2902 DE_NULL, // const void* pNext;
2903 (VkPipelineColorBlendStateCreateFlags)0,
2904 DE_FALSE, // VkBool32 logicOpEnable;
2905 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
2906 1u, // deUint32 attachmentCount;
2907 attBlendStates.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
2908 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
2912 blendParams.attachmentCount += 1;
2914 const VkPipelineTessellationStateCreateInfo tessellationState =
2916 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
2918 (VkPipelineTessellationStateCreateFlags)0,
2922 const VkPipelineTessellationStateCreateInfo* tessellationInfo = hasTessellation ? &tessellationState: DE_NULL;
2923 const VkGraphicsPipelineCreateInfo pipelineParams =
2925 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
2926 DE_NULL, // const void* pNext;
2927 0u, // VkPipelineCreateFlags flags;
2928 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
2929 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
2930 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
2931 &inputAssemblyParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
2932 tessellationInfo, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
2933 &viewportParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
2934 &rasterParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
2935 &multisampleParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
2936 &depthStencilParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
2937 &blendParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
2938 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
2939 *pipelineLayout, // VkPipelineLayout layout;
2940 *renderPass, // VkRenderPass renderPass;
2941 0u, // deUint32 subpass;
2942 DE_NULL, // VkPipeline basePipelineHandle;
2943 0u, // deInt32 basePipelineIndex;
2946 const Unique<VkPipeline> pipeline (createGraphicsPipeline(vk, *vkDevice, DE_NULL, &pipelineParams));
2950 const VkImageViewCreateInfo fragOutputViewParams =
2952 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2953 DE_NULL, // const void* pNext;
2954 0u, // VkImageViewCreateFlags flags;
2955 *fragOutputImage, // VkImage image;
2956 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2957 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
2959 VK_COMPONENT_SWIZZLE_R,
2960 VK_COMPONENT_SWIZZLE_G,
2961 VK_COMPONENT_SWIZZLE_B,
2962 VK_COMPONENT_SWIZZLE_A
2963 }, // VkChannelMapping channels;
2965 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2966 0u, // deUint32 baseMipLevel;
2967 1u, // deUint32 mipLevels;
2968 0u, // deUint32 baseArrayLayer;
2969 1u, // deUint32 arraySize;
2970 }, // VkImageSubresourceRange subresourceRange;
2972 fragOutputImageView = createImageView(vk, *vkDevice, &fragOutputViewParams);
2973 attViews.push_back(*fragOutputImageView);
2977 VkFramebufferCreateInfo framebufferParams =
2979 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
2980 DE_NULL, // const void* pNext;
2981 (VkFramebufferCreateFlags)0,
2982 *renderPass, // VkRenderPass renderPass;
2983 1u, // deUint32 attachmentCount;
2984 attViews.data(), // const VkImageView* pAttachments;
2985 (deUint32)renderSize.x(), // deUint32 width;
2986 (deUint32)renderSize.y(), // deUint32 height;
2987 1u, // deUint32 layers;
2991 framebufferParams.attachmentCount += 1;
2993 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, *vkDevice, &framebufferParams));
2995 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, *vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
2998 const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, *vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3000 const VkCommandBufferBeginInfo cmdBufBeginParams =
3002 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
3003 DE_NULL, // const void* pNext;
3004 (VkCommandBufferUsageFlags)0,
3005 (const VkCommandBufferInheritanceInfo*)DE_NULL,
3009 VK_CHECK(vk.beginCommandBuffer(*cmdBuf, &cmdBufBeginParams));
3012 const VkMemoryBarrier vertFlushBarrier =
3014 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
3015 DE_NULL, // const void* pNext;
3016 VK_ACCESS_HOST_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3017 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkMemoryInputFlags inputMask;
3019 vector<VkImageMemoryBarrier> colorAttBarriers ;
3021 VkImageMemoryBarrier imgBarrier =
3023 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3024 DE_NULL, // const void* pNext;
3025 0u, // VkMemoryOutputFlags outputMask;
3026 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryInputFlags inputMask;
3027 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3028 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
3029 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3030 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3031 *image, // VkImage image;
3033 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
3034 0u, // deUint32 baseMipLevel;
3035 1u, // deUint32 mipLevels;
3036 0u, // deUint32 baseArraySlice;
3037 1u, // deUint32 arraySize;
3038 } // VkImageSubresourceRange subresourceRange;
3040 colorAttBarriers.push_back(imgBarrier);
3043 imgBarrier.image = *fragOutputImage;
3044 colorAttBarriers.push_back(imgBarrier);
3045 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());
3049 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());
3054 vector<VkClearValue> clearValue ;
3055 clearValue.push_back(makeClearValueColorF32(0.125f, 0.25f, 0.75f, 1.0f));
3058 clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0));
3060 VkRenderPassBeginInfo passBeginParams =
3062 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
3063 DE_NULL, // const void* pNext;
3064 *renderPass, // VkRenderPass renderPass;
3065 *framebuffer, // VkFramebuffer framebuffer;
3066 { { 0, 0 }, { renderSize.x(), renderSize.y() } }, // VkRect2D renderArea;
3067 1u, // deUint32 clearValueCount;
3068 clearValue.data(), // const VkClearValue* pClearValues;
3072 passBeginParams.clearValueCount += 1;
3074 vk.cmdBeginRenderPass(*cmdBuf, &passBeginParams, VK_SUBPASS_CONTENTS_INLINE);
3077 vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
3079 const VkDeviceSize bindingOffset = 0;
3080 vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3084 const VkDeviceSize bindingOffset = 0;
3085 vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset);
3087 if (hasPushConstants)
3089 const deUint32 size = static_cast<deUint32>(instance.pushConstants.getBuffer()->getNumBytes());
3090 const void* data = instance.pushConstants.getBuffer()->data();
3092 vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
3094 if (numResources != 0)
3096 // Bind to set number 0.
3097 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL);
3099 vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/);
3100 vk.cmdEndRenderPass(*cmdBuf);
3103 vector<VkImageMemoryBarrier> renderFinishBarrier;
3104 VkImageMemoryBarrier imgBarrier =
3106 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3107 DE_NULL, // const void* pNext;
3108 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3109 VK_ACCESS_TRANSFER_READ_BIT, // VkMemoryInputFlags inputMask;
3110 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
3111 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
3112 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3113 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3114 *image, // VkImage image;
3116 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
3117 0u, // deUint32 baseMipLevel;
3118 1u, // deUint32 mipLevels;
3119 0u, // deUint32 baseArraySlice;
3120 1u, // deUint32 arraySize;
3121 } // VkImageSubresourceRange subresourceRange;
3123 renderFinishBarrier.push_back(imgBarrier);
3127 imgBarrier.image = *fragOutputImage;
3128 renderFinishBarrier.push_back(imgBarrier);
3129 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());
3133 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());
3138 const VkBufferImageCopy copyParams =
3140 (VkDeviceSize)0u, // VkDeviceSize bufferOffset;
3141 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
3142 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
3144 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
3145 0u, // deUint32 mipLevel;
3146 0u, // deUint32 arrayLayer;
3147 1u, // deUint32 arraySize;
3148 }, // VkImageSubresourceCopy imageSubresource;
3149 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
3150 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
3152 vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
3156 vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, ©Params);
3161 vector<VkBufferMemoryBarrier> cpFinishBarriers ;
3162 VkBufferMemoryBarrier copyFinishBarrier =
3164 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
3165 DE_NULL, // const void* pNext;
3166 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3167 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
3168 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3169 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3170 *readImageBuffer, // VkBuffer buffer;
3171 0u, // VkDeviceSize offset;
3172 imageSizeBytes // VkDeviceSize size;
3174 cpFinishBarriers.push_back(copyFinishBarrier);
3178 copyFinishBarrier.buffer = *fragOutputBuffer;
3179 copyFinishBarrier.size = VK_WHOLE_SIZE;
3180 cpFinishBarriers.push_back(copyFinishBarrier);
3182 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);
3186 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);
3190 VK_CHECK(vk.endCommandBuffer(*cmdBuf));
3192 // Upload vertex data
3194 const VkMappedMemoryRange range =
3196 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3197 DE_NULL, // const void* pNext;
3198 vertexBufferMemory->getMemory(), // VkDeviceMemory mem;
3199 0, // VkDeviceSize offset;
3200 (VkDeviceSize)sizeof(vertexData), // VkDeviceSize size;
3202 void* vertexBufPtr = vertexBufferMemory->getHostPtr();
3204 deMemcpy(vertexBufPtr, &vertexData[0], sizeof(vertexData));
3205 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
3210 const deUint32 typNumBytes = instance.interfaces.getInputType().getNumBytes();
3211 const deUint32 bufNumBytes = static_cast<deUint32>(instance.interfaces.getInputBuffer()->getNumBytes());
3213 // Require that the test instantation provides four output values.
3214 DE_ASSERT(bufNumBytes == 4 * typNumBytes);
3216 // We have four triangles. Because interpolation happens before executing the fragment shader,
3217 // we need to provide the same vertex attribute for the same triangle. That means, duplicate each
3218 // value three times for all four values.
3220 const deUint8* provided = static_cast<const deUint8*>(instance.interfaces.getInputBuffer()->data());
3221 vector<deUint8> data;
3223 data.reserve(3 * bufNumBytes);
3225 for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes)
3226 for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
3227 for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx)
3228 data.push_back(provided[offset + byteNdx]);
3230 deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size());
3232 const VkMappedMemoryRange range =
3234 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3235 DE_NULL, // const void* pNext;
3236 vertexInputMemory->getMemory(), // VkDeviceMemory mem;
3237 0, // VkDeviceSize offset;
3238 VK_WHOLE_SIZE, // VkDeviceSize size;
3241 VK_CHECK(vk.flushMappedMemoryRanges(*vkDevice, 1u, &range));
3244 // Submit & wait for completion
3246 const VkFenceCreateInfo fenceParams =
3248 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
3249 DE_NULL, // const void* pNext;
3250 0u, // VkFenceCreateFlags flags;
3252 const Unique<VkFence> fence (createFence(vk, *vkDevice, &fenceParams));
3253 const VkSubmitInfo submitInfo =
3255 VK_STRUCTURE_TYPE_SUBMIT_INFO,
3258 (const VkSemaphore*)DE_NULL,
3259 (const VkPipelineStageFlags*)DE_NULL,
3263 (const VkSemaphore*)DE_NULL,
3266 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
3267 VK_CHECK(vk.waitForFences(*vkDevice, 1u, &fence.get(), DE_TRUE, ~0ull));
3270 const void* imagePtr = readImageBufferMemory->getHostPtr();
3271 const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
3272 renderSize.x(), renderSize.y(), 1, imagePtr);
3275 const VkMappedMemoryRange range =
3277 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3278 DE_NULL, // const void* pNext;
3279 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
3280 0, // VkDeviceSize offset;
3281 imageSizeBytes, // VkDeviceSize size;
3284 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3285 context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer);
3290 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
3291 const VkMappedMemoryRange range =
3293 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3294 DE_NULL, // const void* pNext;
3295 fragOutputMemory->getMemory(), // VkDeviceMemory mem;
3296 0, // VkDeviceSize offset;
3297 fragOutputImgSize, // VkDeviceSize size;
3300 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3303 { // Make sure all output resources are ready.
3304 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3306 const VkMappedMemoryRange range =
3308 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3309 DE_NULL, // const void* pNext;
3310 outResourceMemories[outputNdx]->getMemory(), // VkDeviceMemory mem;
3311 0, // VkDeviceSize offset;
3312 VK_WHOLE_SIZE, // VkDeviceSize size;
3315 VK_CHECK(vk.invalidateMappedMemoryRanges(*vkDevice, 1u, &range));
3319 const RGBA threshold(1, 1, 1, 1);
3321 const RGBA upperLeft(pixelBuffer.getPixel(1, 1));
3322 if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold))
3323 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch"));
3325 const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1));
3326 if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold))
3327 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch"));
3329 const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1));
3330 if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold))
3331 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch"));
3333 const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1));
3334 if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold))
3335 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch"));
3337 // Check that the contents in the ouput variable matches expected.
3340 const IFDataType& outputType = instance.interfaces.getOutputType();
3341 const void* inputData = instance.interfaces.getInputBuffer()->data();
3342 const void* outputData = instance.interfaces.getOutputBuffer()->data();
3343 vector<std::pair<int, int> > positions;
3344 const tcu::ConstPixelBufferAccess fragOutputBufferAccess (outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr());
3346 positions.push_back(std::make_pair(1, 1));
3347 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1));
3348 positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1));
3349 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1));
3351 for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx)
3353 const int x = positions[posNdx].first;
3354 const int y = positions[posNdx].second;
3357 if (outputType.elementType == NUMBERTYPE_FLOAT32)
3359 const float* expected = static_cast<const float*>(outputData) + posNdx * outputType.numElements;
3360 const float* actual = static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y));
3362 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3363 if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
3366 else if (outputType.elementType == NUMBERTYPE_INT32)
3368 const deInt32* expected = static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements;
3369 const deInt32* actual = static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3371 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3372 if (expected[eleNdx] != actual[eleNdx])
3375 else if (outputType.elementType == NUMBERTYPE_UINT32)
3377 const deUint32* expected = static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements;
3378 const deUint32* actual = static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y));
3380 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3381 if (expected[eleNdx] != actual[eleNdx])
3384 else if (outputType.elementType == NUMBERTYPE_FLOAT16)
3386 const float* original = static_cast<const float*>(inputData) + posNdx * outputType.numElements;
3387 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3389 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3390 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
3393 else if (outputType.elementType == NUMBERTYPE_INT16)
3395 const deInt16* expected = static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements;
3396 const deInt16* actual = static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3398 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3399 if (expected[eleNdx] != actual[eleNdx])
3402 else if (outputType.elementType == NUMBERTYPE_UINT16)
3404 const deUint16* expected = static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements;
3405 const deUint16* actual = static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y));
3407 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3408 if (expected[eleNdx] != actual[eleNdx])
3412 DE_ASSERT(0 && "unhandled type");
3416 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch"));
3420 // Check the contents in output resources match with expected.
3421 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3423 const BufferSp& expected = instance.resources.outputs[outputNdx].second;
3425 if (instance.resources.verifyIO != DE_NULL)
3427 if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog()))
3428 return tcu::TestStatus::fail("Resource returned doesn't match with expected");
3432 if (deMemCmp(expected->data(), outResourceMemories[outputNdx]->getHostPtr(), expected->getNumBytes()))
3433 return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
3437 return TestStatus::pass("Rendered output matches input");
3440 void createTestsForAllStages (const std::string& name,
3441 const RGBA (&inputColors)[4],
3442 const RGBA (&outputColors)[4],
3443 const map<string, string>& testCodeFragments,
3444 const vector<deInt32>& specConstants,
3445 const PushConstants& pushConstants,
3446 const GraphicsResources& resources,
3447 const GraphicsInterfaces& interfaces,
3448 const vector<string>& extensions,
3449 const vector<string>& features,
3450 ExtensionFeatures extensionFeatures,
3451 tcu::TestCaseGroup* tests,
3452 const qpTestResult failResult,
3453 const string& failMessageTemplate)
3455 const ShaderElement vertFragPipelineStages[] =
3457 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3458 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3461 const ShaderElement tessPipelineStages[] =
3463 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3464 ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
3465 ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
3466 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3469 const ShaderElement geomPipelineStages[] =
3471 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3472 ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT),
3473 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3476 StageToSpecConstantMap specConstantMap;
3478 specConstantMap[VK_SHADER_STAGE_VERTEX_BIT] = specConstants;
3479 addFunctionCaseWithPrograms<InstanceContext>(
3480 tests, name + "_vert", "", addShaderCodeCustomVertex, runAndVerifyDefaultPipeline,
3481 createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
3482 specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
3484 specConstantMap.clear();
3485 specConstantMap[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = specConstants;
3486 addFunctionCaseWithPrograms<InstanceContext>(
3487 tests, name + "_tessc", "", addShaderCodeCustomTessControl, runAndVerifyDefaultPipeline,
3488 createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
3489 specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
3491 specConstantMap.clear();
3492 specConstantMap[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = specConstants;
3493 addFunctionCaseWithPrograms<InstanceContext>(
3494 tests, name + "_tesse", "", addShaderCodeCustomTessEval, runAndVerifyDefaultPipeline,
3495 createInstanceContext(tessPipelineStages, inputColors, outputColors, testCodeFragments,
3496 specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
3498 specConstantMap.clear();
3499 specConstantMap[VK_SHADER_STAGE_GEOMETRY_BIT] = specConstants;
3500 addFunctionCaseWithPrograms<InstanceContext>(
3501 tests, name + "_geom", "", addShaderCodeCustomGeometry, runAndVerifyDefaultPipeline,
3502 createInstanceContext(geomPipelineStages, inputColors, outputColors, testCodeFragments,
3503 specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
3505 specConstantMap.clear();
3506 specConstantMap[VK_SHADER_STAGE_FRAGMENT_BIT] = specConstants;
3507 addFunctionCaseWithPrograms<InstanceContext>(
3508 tests, name + "_frag", "", addShaderCodeCustomFragment, runAndVerifyDefaultPipeline,
3509 createInstanceContext(vertFragPipelineStages, inputColors, outputColors, testCodeFragments,
3510 specConstantMap, pushConstants, resources, interfaces, extensions, features, extensionFeatures, failResult, failMessageTemplate));
3513 void addTessCtrlTest(tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
3515 RGBA defaultColors[4];
3516 getDefaultColors(defaultColors);
3517 const ShaderElement pipelineStages[] =
3519 ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT),
3520 ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT),
3521 ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT),
3522 ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT),
3525 addFunctionCaseWithPrograms<InstanceContext>(
3526 group, name, "", addShaderCodeCustomTessControl,
3527 runAndVerifyDefaultPipeline, createInstanceContext(
3528 pipelineStages, defaultColors, defaultColors, fragments,
3529 StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
3530 GraphicsInterfaces(), vector<string>(), vector<string>(),
3531 ExtensionFeatures()));