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"
28 #include "tcuTextureUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPlatform.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkCmdUtil.hpp"
39 #include "deRandom.hpp"
43 namespace SpirVAssembly
57 using tcu::TestStatus;
60 using tcu::StringTemplate;
63 deUint32 IFDataType::getElementNumBytes (void) const
65 if (elementType < NUMBERTYPE_END32)
68 if (elementType < NUMBERTYPE_END16)
74 VkFormat IFDataType::getVkFormat (void) const
80 case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64_SFLOAT;
81 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32_SFLOAT;
82 case NUMBERTYPE_INT32: return VK_FORMAT_R32_SINT;
83 case NUMBERTYPE_UINT32: return VK_FORMAT_R32_UINT;
84 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16_SFLOAT;
85 case NUMBERTYPE_INT16: return VK_FORMAT_R16_SINT;
86 case NUMBERTYPE_UINT16: return VK_FORMAT_R16_UINT;
90 else if (numElements == 2)
94 case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64G64_SFLOAT;
95 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32_SFLOAT;
96 case NUMBERTYPE_INT32: return VK_FORMAT_R32G32_SINT;
97 case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32_UINT;
98 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16_SFLOAT;
99 case NUMBERTYPE_INT16: return VK_FORMAT_R16G16_SINT;
100 case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16_UINT;
104 else if (numElements == 3)
108 case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64G64B64_SFLOAT;
109 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32B32_SFLOAT;
110 case NUMBERTYPE_INT32: return VK_FORMAT_R32G32B32_SINT;
111 case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32B32_UINT;
112 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16B16_SFLOAT;
113 case NUMBERTYPE_INT16: return VK_FORMAT_R16G16B16_SINT;
114 case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16B16_UINT;
118 else if (numElements == 4)
122 case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64G64B64A64_SFLOAT;
123 case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32B32A32_SFLOAT;
124 case NUMBERTYPE_INT32: return VK_FORMAT_R32G32B32A32_SINT;
125 case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32B32A32_UINT;
126 case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16B16A16_SFLOAT;
127 case NUMBERTYPE_INT16: return VK_FORMAT_R16G16B16A16_SINT;
128 case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16B16A16_UINT;
134 return VK_FORMAT_UNDEFINED;
137 tcu::TextureFormat IFDataType::getTextureFormat (void) const
139 tcu::TextureFormat::ChannelType ct = tcu::TextureFormat::CHANNELTYPE_LAST;
140 tcu::TextureFormat::ChannelOrder co = tcu::TextureFormat::CHANNELORDER_LAST;
144 case NUMBERTYPE_FLOAT64: ct = tcu::TextureFormat::FLOAT64; break;
145 case NUMBERTYPE_FLOAT32: ct = tcu::TextureFormat::FLOAT; break;
146 case NUMBERTYPE_INT32: ct = tcu::TextureFormat::SIGNED_INT32; break;
147 case NUMBERTYPE_UINT32: ct = tcu::TextureFormat::UNSIGNED_INT32; break;
148 case NUMBERTYPE_FLOAT16: ct = tcu::TextureFormat::HALF_FLOAT; break;
149 case NUMBERTYPE_INT16: ct = tcu::TextureFormat::SIGNED_INT16; break;
150 case NUMBERTYPE_UINT16: ct = tcu::TextureFormat::UNSIGNED_INT16; break;
151 default: DE_ASSERT(false);
156 case 1: co = tcu::TextureFormat::R; break;
157 case 2: co = tcu::TextureFormat::RG; break;
158 case 3: co = tcu::TextureFormat::RGB; break;
159 case 4: co = tcu::TextureFormat::RGBA; break;
160 default: DE_ASSERT(false);
163 return tcu::TextureFormat(co, ct);
166 string IFDataType::str (void) const
172 case NUMBERTYPE_FLOAT64: ret = "f64"; break;
173 case NUMBERTYPE_FLOAT32: ret = "f32"; break;
174 case NUMBERTYPE_INT32: ret = "i32"; break;
175 case NUMBERTYPE_UINT32: ret = "u32"; break;
176 case NUMBERTYPE_FLOAT16: ret = "f16"; break;
177 case NUMBERTYPE_INT16: ret = "i16"; break;
178 case NUMBERTYPE_UINT16: ret = "u16"; break;
179 default: DE_ASSERT(false);
182 if (numElements == 1)
185 return string("v") + numberToString(numElements) + ret;
188 VkBufferUsageFlagBits getMatchingBufferUsageFlagBit (VkDescriptorType dType)
192 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
193 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
194 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
195 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
196 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
197 default: DE_ASSERT(0 && "not implemented");
199 return (VkBufferUsageFlagBits)0;
202 VkImageUsageFlags getMatchingImageUsageFlags (VkDescriptorType dType)
206 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
207 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
208 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
209 default: DE_FATAL("Not implemented");
211 return (VkImageUsageFlags)0;
214 static void requireFormatUsageSupport (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling imageTiling, VkImageUsageFlags requiredUsageFlags)
216 VkFormatProperties properties;
217 VkFormatFeatureFlags tilingFeatures = 0;
219 vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties);
223 case VK_IMAGE_TILING_LINEAR:
224 tilingFeatures = properties.linearTilingFeatures;
227 case VK_IMAGE_TILING_OPTIMAL:
228 tilingFeatures = properties.optimalTilingFeatures;
236 if ((requiredUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0)
238 if ((tilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
239 TCU_THROW(NotSupportedError, "Image format cannot be used as color attachment");
240 requiredUsageFlags ^= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
244 if ((requiredUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0)
246 if ((tilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR) == 0)
247 TCU_THROW(NotSupportedError, "Image format cannot be used as transfer source");
248 requiredUsageFlags ^= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
252 DE_ASSERT(!requiredUsageFlags && "checking other image usage bits not supported yet");
255 InstanceContext::InstanceContext (const RGBA (&inputs)[4],
256 const RGBA (&outputs)[4],
257 const map<string, string>& testCodeFragments_,
258 const StageToSpecConstantMap& specConstants_,
259 const PushConstants& pushConsants_,
260 const GraphicsResources& resources_,
261 const GraphicsInterfaces& interfaces_,
262 const vector<string>& extensions_,
263 VulkanFeatures vulkanFeatures_,
264 VkShaderStageFlags customizedStages_)
265 : testCodeFragments (testCodeFragments_)
266 , specConstants (specConstants_)
267 , hasTessellation (false)
268 , requiredStages (static_cast<VkShaderStageFlagBits>(0))
269 , requiredDeviceExtensions (extensions_)
270 , requestedFeatures (vulkanFeatures_)
271 , pushConstants (pushConsants_)
272 , customizedStages (customizedStages_)
273 , resources (resources_)
274 , interfaces (interfaces_)
275 , failResult (QP_TEST_RESULT_FAIL)
276 , failMessageTemplate ("${reason}")
277 , renderFullSquare (false)
279 inputColors[0] = inputs[0];
280 inputColors[1] = inputs[1];
281 inputColors[2] = inputs[2];
282 inputColors[3] = inputs[3];
284 outputColors[0] = outputs[0];
285 outputColors[1] = outputs[1];
286 outputColors[2] = outputs[2];
287 outputColors[3] = outputs[3];
290 InstanceContext::InstanceContext (const InstanceContext& other)
291 : moduleMap (other.moduleMap)
292 , testCodeFragments (other.testCodeFragments)
293 , specConstants (other.specConstants)
294 , hasTessellation (other.hasTessellation)
295 , requiredStages (other.requiredStages)
296 , requiredDeviceExtensions (other.requiredDeviceExtensions)
297 , requestedFeatures (other.requestedFeatures)
298 , pushConstants (other.pushConstants)
299 , customizedStages (other.customizedStages)
300 , resources (other.resources)
301 , interfaces (other.interfaces)
302 , failResult (other.failResult)
303 , failMessageTemplate (other.failMessageTemplate)
304 , renderFullSquare (other.renderFullSquare)
306 inputColors[0] = other.inputColors[0];
307 inputColors[1] = other.inputColors[1];
308 inputColors[2] = other.inputColors[2];
309 inputColors[3] = other.inputColors[3];
311 outputColors[0] = other.outputColors[0];
312 outputColors[1] = other.outputColors[1];
313 outputColors[2] = other.outputColors[2];
314 outputColors[3] = other.outputColors[3];
317 string InstanceContext::getSpecializedFailMessage (const string& failureReason)
319 map<string, string> parameters;
320 parameters["reason"] = failureReason;
321 return StringTemplate(failMessageTemplate).specialize(parameters);
324 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
325 const tcu::RGBA (&inputColors)[4],
326 const tcu::RGBA (&outputColors)[4],
327 const std::map<std::string, std::string>& testCodeFragments,
328 const StageToSpecConstantMap& specConstants,
329 const PushConstants& pushConstants,
330 const GraphicsResources& resources,
331 const GraphicsInterfaces& interfaces,
332 const std::vector<std::string>& extensions,
333 VulkanFeatures vulkanFeatures,
334 VkShaderStageFlags customizedStages,
335 const qpTestResult failResult,
336 const std::string& failMessageTemplate)
338 InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, interfaces, extensions, vulkanFeatures, customizedStages);
339 for (size_t i = 0; i < elements.size(); ++i)
341 ctx.moduleMap[elements[i].moduleName].push_back(std::make_pair(elements[i].entryName, elements[i].stage));
342 ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | elements[i].stage);
344 ctx.failResult = failResult;
345 if (!failMessageTemplate.empty())
346 ctx.failMessageTemplate = failMessageTemplate;
350 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
351 tcu::RGBA (&inputColors)[4],
352 const tcu::RGBA (&outputColors)[4],
353 const std::map<std::string, std::string>& testCodeFragments)
355 return createInstanceContext(elements, inputColors, outputColors, testCodeFragments,
356 StageToSpecConstantMap(), PushConstants(), GraphicsResources(),
357 GraphicsInterfaces(), std::vector<std::string>(),
358 VulkanFeatures(), vk::VK_SHADER_STAGE_ALL);
361 InstanceContext createInstanceContext (const std::vector<ShaderElement>& elements,
362 const std::map<std::string, std::string>& testCodeFragments)
364 tcu::RGBA defaultColors[4];
365 getDefaultColors(defaultColors);
366 return createInstanceContext(elements, defaultColors, defaultColors, testCodeFragments);
369 UnusedVariableContext createUnusedVariableContext(const ShaderTaskArray& shaderTasks, const VariableLocation& location)
371 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(shaderTasks); ++i)
373 DE_ASSERT(shaderTasks[i] >= 0 && shaderTasks[i] < SHADER_TASK_LAST);
376 std::vector<ShaderElement> elements;
378 DE_ASSERT(shaderTasks[SHADER_TASK_INDEX_VERTEX] != SHADER_TASK_NONE);
379 DE_ASSERT(shaderTasks[SHADER_TASK_INDEX_FRAGMENT] != SHADER_TASK_NONE);
380 elements.push_back(ShaderElement("vert", "main", vk::VK_SHADER_STAGE_VERTEX_BIT));
381 elements.push_back(ShaderElement("frag", "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT));
383 if (shaderTasks[SHADER_TASK_INDEX_GEOMETRY] != SHADER_TASK_NONE)
384 elements.push_back(ShaderElement("geom", "main", vk::VK_SHADER_STAGE_GEOMETRY_BIT));
386 if (shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL] != SHADER_TASK_NONE)
387 elements.push_back(ShaderElement("tessc", "main", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
389 if (shaderTasks[SHADER_TASK_INDEX_TESS_EVAL] != SHADER_TASK_NONE)
390 elements.push_back(ShaderElement("tesse", "main", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
392 return UnusedVariableContext(
393 createInstanceContext(elements, map<string, string>()),
398 ShaderElement::ShaderElement (const string& moduleName_,
399 const string& entryPoint_,
400 VkShaderStageFlagBits shaderStage_)
401 : moduleName(moduleName_)
402 , entryName(entryPoint_)
403 , stage(shaderStage_)
407 void getDefaultColors (RGBA (&colors)[4])
409 colors[0] = RGBA::white();
410 colors[1] = RGBA::red();
411 colors[2] = RGBA::green();
412 colors[3] = RGBA::blue();
415 void getHalfColorsFullAlpha (RGBA (&colors)[4])
417 colors[0] = RGBA(127, 127, 127, 255);
418 colors[1] = RGBA(127, 0, 0, 255);
419 colors[2] = RGBA(0, 127, 0, 255);
420 colors[3] = RGBA(0, 0, 127, 255);
423 void getInvertedDefaultColors (RGBA (&colors)[4])
425 colors[0] = RGBA(0, 0, 0, 255);
426 colors[1] = RGBA(0, 255, 255, 255);
427 colors[2] = RGBA(255, 0, 255, 255);
428 colors[3] = RGBA(255, 255, 0, 255);
431 // For the current InstanceContext, constructs the required modules and shader stage create infos.
432 void createPipelineShaderStages (const DeviceInterface& vk,
433 const VkDevice vkDevice,
434 InstanceContext& instance,
436 vector<ModuleHandleSp>& modules,
437 vector<VkPipelineShaderStageCreateInfo>& createInfos)
439 for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx)
441 const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0)));
442 modules.push_back(ModuleHandleSp(mod));
443 for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx)
445 const EntryToStage& stage = *shaderNdx;
446 const VkPipelineShaderStageCreateInfo shaderParam =
448 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
449 DE_NULL, // const void* pNext;
450 (VkPipelineShaderStageCreateFlags)0,
451 stage.second, // VkShaderStageFlagBits stage;
452 **modules.back(), // VkShaderModule module;
453 stage.first.c_str(), // const char* pName;
454 (const VkSpecializationInfo*)DE_NULL,
456 createInfos.push_back(shaderParam);
461 // Creates vertex-shader assembly by specializing a boilerplate StringTemplate
462 // on fragments, which must (at least) map "testfun" to an OpFunction definition
463 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
464 // with "BP_" to avoid collisions with fragments.
466 // It corresponds roughly to this GLSL:
468 // layout(location = 0) in vec4 position;
469 // layout(location = 1) in vec4 color;
470 // layout(location = 1) out highp vec4 vtxColor;
471 // void main (void) { gl_Position = position; vtxColor = test_func(color); }
472 string makeVertexShaderAssembly (const map<string, string>& fragments)
474 static const char vertexShaderBoilerplate[] =
475 "OpCapability Shader\n"
476 "${capability:opt}\n"
478 "OpMemoryModel Logical GLSL450\n"
479 "OpEntryPoint Vertex %BP_main \"main\" %BP_stream %BP_position %BP_vtx_color %BP_color %BP_gl_VertexIndex %BP_gl_InstanceIndex ${IF_entrypoint:opt} \n"
480 "${execution_mode:opt}\n"
482 "${moduleprocessed:opt}\n"
483 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
484 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
485 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
486 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
487 "OpDecorate %BP_gl_PerVertex Block\n"
488 "OpDecorate %BP_position Location 0\n"
489 "OpDecorate %BP_vtx_color Location 1\n"
490 "OpDecorate %BP_color Location 1\n"
491 "OpDecorate %BP_gl_VertexIndex BuiltIn VertexIndex\n"
492 "OpDecorate %BP_gl_InstanceIndex BuiltIn InstanceIndex\n"
493 "${IF_decoration:opt}\n"
494 "${decoration:opt}\n"
496 SPIRV_ASSEMBLY_CONSTANTS
497 SPIRV_ASSEMBLY_ARRAYS
498 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
499 "%BP_op_gl_PerVertex = OpTypePointer Output %BP_gl_PerVertex\n"
500 "%BP_stream = OpVariable %BP_op_gl_PerVertex Output\n"
501 "%BP_position = OpVariable %ip_v4f32 Input\n"
502 "%BP_vtx_color = OpVariable %op_v4f32 Output\n"
503 "%BP_color = OpVariable %ip_v4f32 Input\n"
504 "%BP_gl_VertexIndex = OpVariable %ip_i32 Input\n"
505 "%BP_gl_InstanceIndex = OpVariable %ip_i32 Input\n"
507 "${IF_variable:opt}\n"
508 "%BP_main = OpFunction %void None %voidf\n"
509 "%BP_label = OpLabel\n"
510 "${IF_carryforward:opt}\n"
511 "${post_interface_op_vert:opt}\n"
512 "%BP_pos = OpLoad %v4f32 %BP_position\n"
513 "%BP_gl_pos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
514 "OpStore %BP_gl_pos %BP_pos\n"
515 "%BP_col = OpLoad %v4f32 %BP_color\n"
516 "%BP_col_transformed = OpFunctionCall %v4f32 %test_code %BP_col\n"
517 "OpStore %BP_vtx_color %BP_col_transformed\n"
520 "${interface_op_func:opt}\n"
522 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
523 "%getId_label = OpLabel\n"
524 "%vert_id = OpLoad %i32 %BP_gl_VertexIndex\n"
525 "%is_id_0 = OpIEqual %bool %vert_id %c_i32_0\n"
526 "OpReturnValue %is_id_0\n"
530 return tcu::StringTemplate(vertexShaderBoilerplate).specialize(fragments);
533 // Creates tess-control-shader assembly by specializing a boilerplate
534 // StringTemplate on fragments, which must (at least) map "testfun" to an
535 // OpFunction definition for %test_code that takes and returns a %v4f32.
536 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
538 // It roughly corresponds to the following GLSL.
541 // layout(vertices = 3) out;
542 // layout(location = 1) in vec4 in_color[];
543 // layout(location = 1) out vec4 out_color[];
546 // out_color[gl_InvocationID] = testfun(in_color[gl_InvocationID]);
547 // gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
548 // if (gl_InvocationID == 0) {
549 // gl_TessLevelOuter[0] = 1.0;
550 // gl_TessLevelOuter[1] = 1.0;
551 // gl_TessLevelOuter[2] = 1.0;
552 // gl_TessLevelInner[0] = 1.0;
555 string makeTessControlShaderAssembly (const map<string, string>& fragments)
557 static const char tessControlShaderBoilerplate[] =
558 "OpCapability Tessellation\n"
559 "${capability:opt}\n"
561 "OpMemoryModel Logical GLSL450\n"
562 "OpEntryPoint TessellationControl %BP_main \"main\" %BP_out_color %BP_gl_InvocationID %BP_gl_PrimitiveID %BP_in_color %BP_gl_out %BP_gl_in %BP_gl_TessLevelOuter %BP_gl_TessLevelInner ${IF_entrypoint:opt} \n"
563 "OpExecutionMode %BP_main OutputVertices 3\n"
564 "${execution_mode:opt}\n"
566 "${moduleprocessed:opt}\n"
567 "OpDecorate %BP_out_color Location 1\n"
568 "OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n"
569 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
570 "OpDecorate %BP_in_color Location 1\n"
571 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
572 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
573 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
574 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
575 "OpDecorate %BP_gl_PerVertex Block\n"
576 "OpMemberDecorate %BP_gl_PVOut 0 BuiltIn Position\n"
577 "OpMemberDecorate %BP_gl_PVOut 1 BuiltIn PointSize\n"
578 "OpMemberDecorate %BP_gl_PVOut 2 BuiltIn ClipDistance\n"
579 "OpMemberDecorate %BP_gl_PVOut 3 BuiltIn CullDistance\n"
580 "OpDecorate %BP_gl_PVOut Block\n"
581 "OpDecorate %BP_gl_TessLevelOuter Patch\n"
582 "OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
583 "OpDecorate %BP_gl_TessLevelInner Patch\n"
584 "OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n"
585 "${IF_decoration:opt}\n"
586 "${decoration:opt}\n"
587 "${decoration_tessc:opt}\n"
589 SPIRV_ASSEMBLY_CONSTANTS
590 SPIRV_ASSEMBLY_ARRAYS
591 "%BP_out_color = OpVariable %op_a3v4f32 Output\n"
592 "%BP_gl_InvocationID = OpVariable %ip_i32 Input\n"
593 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
594 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
595 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
596 "%BP_a3_gl_PerVertex = OpTypeArray %BP_gl_PerVertex %c_u32_3\n"
597 "%BP_op_a3_gl_PerVertex = OpTypePointer Output %BP_a3_gl_PerVertex\n"
598 "%BP_gl_out = OpVariable %BP_op_a3_gl_PerVertex Output\n"
599 "%BP_gl_PVOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
600 "%BP_a32_gl_PVOut = OpTypeArray %BP_gl_PVOut %c_u32_32\n"
601 "%BP_ip_a32_gl_PVOut = OpTypePointer Input %BP_a32_gl_PVOut\n"
602 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PVOut Input\n"
603 "%BP_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
604 "%BP_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
606 "${IF_variable:opt}\n"
608 "%BP_main = OpFunction %void None %voidf\n"
609 "%BP_label = OpLabel\n"
610 "%BP_gl_Invoc = OpLoad %i32 %BP_gl_InvocationID\n"
611 "${IF_carryforward:opt}\n"
612 "${post_interface_op_tessc:opt}\n"
613 "%BP_in_col_loc = OpAccessChain %ip_v4f32 %BP_in_color %BP_gl_Invoc\n"
614 "%BP_out_col_loc = OpAccessChain %op_v4f32 %BP_out_color %BP_gl_Invoc\n"
615 "%BP_in_col_val = OpLoad %v4f32 %BP_in_col_loc\n"
616 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_in_col_val\n"
617 "OpStore %BP_out_col_loc %BP_clr_transformed\n"
619 "%BP_in_pos_loc = OpAccessChain %ip_v4f32 %BP_gl_in %BP_gl_Invoc %c_i32_0\n"
620 "%BP_out_pos_loc = OpAccessChain %op_v4f32 %BP_gl_out %BP_gl_Invoc %c_i32_0\n"
621 "%BP_in_pos_val = OpLoad %v4f32 %BP_in_pos_loc\n"
622 "OpStore %BP_out_pos_loc %BP_in_pos_val\n"
624 "%BP_cmp = OpIEqual %bool %BP_gl_Invoc %c_i32_0\n"
625 "OpSelectionMerge %BP_merge_label None\n"
626 "OpBranchConditional %BP_cmp %BP_if_label %BP_merge_label\n"
627 "%BP_if_label = OpLabel\n"
628 "%BP_gl_TessLevelOuterPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_0\n"
629 "%BP_gl_TessLevelOuterPos_1 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_1\n"
630 "%BP_gl_TessLevelOuterPos_2 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_2\n"
631 "%BP_gl_TessLevelInnerPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelInner %c_i32_0\n"
632 "OpStore %BP_gl_TessLevelOuterPos_0 %c_f32_1\n"
633 "OpStore %BP_gl_TessLevelOuterPos_1 %c_f32_1\n"
634 "OpStore %BP_gl_TessLevelOuterPos_2 %c_f32_1\n"
635 "OpStore %BP_gl_TessLevelInnerPos_0 %c_f32_1\n"
636 "OpBranch %BP_merge_label\n"
637 "%BP_merge_label = OpLabel\n"
640 "${interface_op_func:opt}\n"
642 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
643 "%getId_label = OpLabel\n"
644 "%invocation_id = OpLoad %i32 %BP_gl_InvocationID\n"
645 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
646 "%is_invocation_0 = OpIEqual %bool %invocation_id %c_i32_0\n"
647 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
648 "%is_id_0 = OpLogicalAnd %bool %is_invocation_0 %is_primitive_0\n"
649 "OpReturnValue %is_id_0\n"
653 return tcu::StringTemplate(tessControlShaderBoilerplate).specialize(fragments);
656 // Creates tess-evaluation-shader assembly by specializing a boilerplate
657 // StringTemplate on fragments, which must (at least) map "testfun" to an
658 // OpFunction definition for %test_code that takes and returns a %v4f32.
659 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
661 // It roughly corresponds to the following glsl.
665 // layout(triangles, equal_spacing, ccw) in;
666 // layout(location = 1) in vec4 in_color[];
667 // layout(location = 1) out vec4 out_color;
669 // #define interpolate(val)
670 // vec4(gl_TessCoord.x) * val[0] + vec4(gl_TessCoord.y) * val[1] +
671 // vec4(gl_TessCoord.z) * val[2]
674 // gl_Position = vec4(gl_TessCoord.x) * gl_in[0].gl_Position +
675 // vec4(gl_TessCoord.y) * gl_in[1].gl_Position +
676 // vec4(gl_TessCoord.z) * gl_in[2].gl_Position;
677 // out_color = testfun(interpolate(in_color));
679 string makeTessEvalShaderAssembly (const map<string, string>& fragments)
681 static const char tessEvalBoilerplate[] =
682 "OpCapability Tessellation\n"
683 "${capability:opt}\n"
685 "OpMemoryModel Logical GLSL450\n"
686 "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"
687 "OpExecutionMode %BP_main Triangles\n"
688 "OpExecutionMode %BP_main SpacingEqual\n"
689 "OpExecutionMode %BP_main VertexOrderCcw\n"
690 "${execution_mode:opt}\n"
692 "${moduleprocessed:opt}\n"
693 "OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n"
694 "OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n"
695 "OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n"
696 "OpMemberDecorate %BP_gl_PerVertexOut 3 BuiltIn CullDistance\n"
697 "OpDecorate %BP_gl_PerVertexOut Block\n"
698 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
699 "OpDecorate %BP_gl_TessCoord BuiltIn TessCoord\n"
700 "OpMemberDecorate %BP_gl_PerVertexIn 0 BuiltIn Position\n"
701 "OpMemberDecorate %BP_gl_PerVertexIn 1 BuiltIn PointSize\n"
702 "OpMemberDecorate %BP_gl_PerVertexIn 2 BuiltIn ClipDistance\n"
703 "OpMemberDecorate %BP_gl_PerVertexIn 3 BuiltIn CullDistance\n"
704 "OpDecorate %BP_gl_PerVertexIn Block\n"
705 "OpDecorate %BP_out_color Location 1\n"
706 "OpDecorate %BP_in_color Location 1\n"
707 "${IF_decoration:opt}\n"
708 "${decoration:opt}\n"
710 SPIRV_ASSEMBLY_CONSTANTS
711 SPIRV_ASSEMBLY_ARRAYS
712 "%BP_gl_PerVertexOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
713 "%BP_op_gl_PerVertexOut = OpTypePointer Output %BP_gl_PerVertexOut\n"
714 "%BP_stream = OpVariable %BP_op_gl_PerVertexOut Output\n"
715 "%BP_gl_TessCoord = OpVariable %ip_v3f32 Input\n"
716 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
717 "%BP_gl_PerVertexIn = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
718 "%BP_a32_gl_PerVertexIn = OpTypeArray %BP_gl_PerVertexIn %c_u32_32\n"
719 "%BP_ip_a32_gl_PerVertexIn = OpTypePointer Input %BP_a32_gl_PerVertexIn\n"
720 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PerVertexIn Input\n"
721 "%BP_out_color = OpVariable %op_v4f32 Output\n"
722 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
724 "${IF_variable:opt}\n"
725 "%BP_main = OpFunction %void None %voidf\n"
726 "%BP_label = OpLabel\n"
727 "${IF_carryforward:opt}\n"
728 "${post_interface_op_tesse:opt}\n"
729 "%BP_gl_TC_0 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
730 "%BP_gl_TC_1 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
731 "%BP_gl_TC_2 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
732 "%BP_gl_in_gl_Pos_0 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
733 "%BP_gl_in_gl_Pos_1 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
734 "%BP_gl_in_gl_Pos_2 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
736 "%BP_gl_OPos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
737 "%BP_in_color_0 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
738 "%BP_in_color_1 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
739 "%BP_in_color_2 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
741 "%BP_TC_W_0 = OpLoad %f32 %BP_gl_TC_0\n"
742 "%BP_TC_W_1 = OpLoad %f32 %BP_gl_TC_1\n"
743 "%BP_TC_W_2 = OpLoad %f32 %BP_gl_TC_2\n"
744 "%BP_v4f32_TC_0 = OpCompositeConstruct %v4f32 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0\n"
745 "%BP_v4f32_TC_1 = OpCompositeConstruct %v4f32 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1\n"
746 "%BP_v4f32_TC_2 = OpCompositeConstruct %v4f32 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2\n"
748 "%BP_gl_IP_0 = OpLoad %v4f32 %BP_gl_in_gl_Pos_0\n"
749 "%BP_gl_IP_1 = OpLoad %v4f32 %BP_gl_in_gl_Pos_1\n"
750 "%BP_gl_IP_2 = OpLoad %v4f32 %BP_gl_in_gl_Pos_2\n"
752 "%BP_IP_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_gl_IP_0\n"
753 "%BP_IP_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_gl_IP_1\n"
754 "%BP_IP_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_gl_IP_2\n"
756 "%BP_pos_sum_0 = OpFAdd %v4f32 %BP_IP_W_0 %BP_IP_W_1\n"
757 "%BP_pos_sum_1 = OpFAdd %v4f32 %BP_pos_sum_0 %BP_IP_W_2\n"
759 "OpStore %BP_gl_OPos %BP_pos_sum_1\n"
761 "%BP_IC_0 = OpLoad %v4f32 %BP_in_color_0\n"
762 "%BP_IC_1 = OpLoad %v4f32 %BP_in_color_1\n"
763 "%BP_IC_2 = OpLoad %v4f32 %BP_in_color_2\n"
765 "%BP_IC_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_IC_0\n"
766 "%BP_IC_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_IC_1\n"
767 "%BP_IC_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_IC_2\n"
769 "%BP_col_sum_0 = OpFAdd %v4f32 %BP_IC_W_0 %BP_IC_W_1\n"
770 "%BP_col_sum_1 = OpFAdd %v4f32 %BP_col_sum_0 %BP_IC_W_2\n"
772 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_col_sum_1\n"
774 "OpStore %BP_out_color %BP_clr_transformed\n"
777 "${interface_op_func:opt}\n"
779 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
780 "%getId_label = OpLabel\n"
781 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
782 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
783 "%TC_0_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
784 "%TC_1_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
785 "%TC_2_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
786 "%TC_W_0 = OpLoad %f32 %TC_0_loc\n"
787 "%TC_W_1 = OpLoad %f32 %TC_1_loc\n"
788 "%TC_W_2 = OpLoad %f32 %TC_2_loc\n"
789 "%is_W_0_1 = OpFOrdEqual %bool %TC_W_0 %c_f32_1\n"
790 "%is_W_1_0 = OpFOrdEqual %bool %TC_W_1 %c_f32_0\n"
791 "%is_W_2_0 = OpFOrdEqual %bool %TC_W_2 %c_f32_0\n"
792 "%is_tessCoord_1_0 = OpLogicalAnd %bool %is_W_0_1 %is_W_1_0\n"
793 "%is_tessCoord_1_0_0 = OpLogicalAnd %bool %is_tessCoord_1_0 %is_W_2_0\n"
794 "%is_unique_id_0 = OpLogicalAnd %bool %is_tessCoord_1_0_0 %is_primitive_0\n"
795 "OpReturnValue %is_unique_id_0\n"
799 return tcu::StringTemplate(tessEvalBoilerplate).specialize(fragments);
802 // Creates geometry-shader assembly by specializing a boilerplate StringTemplate
803 // on fragments, which must (at least) map "testfun" to an OpFunction definition
804 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
805 // with "BP_" to avoid collisions with fragments.
807 // Derived from this GLSL:
810 // layout(triangles) in;
811 // layout(triangle_strip, max_vertices = 3) out;
813 // layout(location = 1) in vec4 in_color[];
814 // layout(location = 1) out vec4 out_color;
817 // gl_Position = gl_in[0].gl_Position;
818 // out_color = test_fun(in_color[0]);
820 // gl_Position = gl_in[1].gl_Position;
821 // out_color = test_fun(in_color[1]);
823 // gl_Position = gl_in[2].gl_Position;
824 // out_color = test_fun(in_color[2]);
828 string makeGeometryShaderAssembly (const map<string, string>& fragments)
830 static const char geometryShaderBoilerplate[] =
831 "OpCapability Geometry\n"
832 "${capability:opt}\n"
834 "OpMemoryModel Logical GLSL450\n"
835 "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"
836 "OpExecutionMode %BP_main Triangles\n"
837 "OpExecutionMode %BP_main Invocations 1\n"
838 "OpExecutionMode %BP_main OutputTriangleStrip\n"
839 "OpExecutionMode %BP_main OutputVertices 3\n"
840 "${execution_mode:opt}\n"
842 "${moduleprocessed:opt}\n"
843 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
844 "OpDecorate %BP_out_gl_position BuiltIn Position\n"
845 "OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n"
846 "OpMemberDecorate %BP_per_vertex_in 1 BuiltIn PointSize\n"
847 "OpMemberDecorate %BP_per_vertex_in 2 BuiltIn ClipDistance\n"
848 "OpMemberDecorate %BP_per_vertex_in 3 BuiltIn CullDistance\n"
849 "OpDecorate %BP_per_vertex_in Block\n"
850 "OpDecorate %BP_out_color Location 1\n"
851 "OpDecorate %BP_in_color Location 1\n"
852 "${IF_decoration:opt}\n"
853 "${decoration:opt}\n"
855 SPIRV_ASSEMBLY_CONSTANTS
856 SPIRV_ASSEMBLY_ARRAYS
857 "%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
858 "%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n"
859 "%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n"
860 "%BP_pp_i32 = OpTypePointer Private %i32\n"
861 "%BP_pp_v4i32 = OpTypePointer Private %v4i32\n"
863 "%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n"
864 "%BP_out_color = OpVariable %op_v4f32 Output\n"
865 "%BP_in_color = OpVariable %ip_a3v4f32 Input\n"
866 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
867 "%BP_out_gl_position = OpVariable %op_v4f32 Output\n"
868 "%BP_vertexIdInCurrentPatch = OpVariable %BP_pp_v4i32 Private\n"
870 "${IF_variable:opt}\n"
872 "%BP_main = OpFunction %void None %voidf\n"
873 "%BP_label = OpLabel\n"
875 "${IF_carryforward:opt}\n"
876 "${post_interface_op_geom:opt}\n"
878 "%BP_primitiveId = OpLoad %i32 %BP_gl_PrimitiveID\n"
879 "%BP_addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %BP_primitiveId\n"
881 "%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
882 "%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
883 "%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
885 "%BP_in_position_0 = OpLoad %v4f32 %BP_gl_in_0_gl_position\n"
886 "%BP_in_position_1 = OpLoad %v4f32 %BP_gl_in_1_gl_position\n"
887 "%BP_in_position_2 = OpLoad %v4f32 %BP_gl_in_2_gl_position \n"
889 "%BP_in_color_0_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
890 "%BP_in_color_1_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
891 "%BP_in_color_2_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
893 "%BP_in_color_0 = OpLoad %v4f32 %BP_in_color_0_ptr\n"
894 "%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n"
895 "%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n"
897 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_0\n"
898 "%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n"
899 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_1\n"
900 "%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
901 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_2\n"
902 "%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"
905 "OpStore %BP_out_gl_position %BP_in_position_0\n"
906 "OpStore %BP_out_color %BP_transformed_in_color_0\n"
909 "OpStore %BP_out_gl_position %BP_in_position_1\n"
910 "OpStore %BP_out_color %BP_transformed_in_color_1\n"
913 "OpStore %BP_out_gl_position %BP_in_position_2\n"
914 "OpStore %BP_out_color %BP_transformed_in_color_2\n"
920 "${interface_op_func:opt}\n"
922 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
923 "%getId_label = OpLabel\n"
924 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
925 "%addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %primitive_id\n"
926 "%vertexIdInCurrentPatch = OpLoad %i32 %addr_vertexIdInCurrentPatch\n"
927 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
928 "%is_vertex_0 = OpIEqual %bool %vertexIdInCurrentPatch %c_i32_0\n"
929 "%is_unique_id_0 = OpLogicalAnd %bool %is_primitive_0 %is_vertex_0\n"
930 "OpReturnValue %is_unique_id_0\n"
934 return tcu::StringTemplate(geometryShaderBoilerplate).specialize(fragments);
937 // Creates fragment-shader assembly by specializing a boilerplate StringTemplate
938 // on fragments, which must (at least) map "testfun" to an OpFunction definition
939 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
940 // with "BP_" to avoid collisions with fragments.
942 // Derived from this GLSL:
944 // layout(location = 1) in highp vec4 vtxColor;
945 // layout(location = 0) out highp vec4 fragColor;
946 // highp vec4 testfun(highp vec4 x) { return x; }
947 // void main(void) { fragColor = testfun(vtxColor); }
949 // with modifications including passing vtxColor by value and ripping out
950 // testfun() definition.
951 string makeFragmentShaderAssembly (const map<string, string>& fragments)
953 static const char fragmentShaderBoilerplate[] =
954 "OpCapability Shader\n"
955 "${capability:opt}\n"
957 "OpMemoryModel Logical GLSL450\n"
958 "OpEntryPoint Fragment %BP_main \"main\" %BP_vtxColor %BP_fragColor %BP_gl_FragCoord ${IF_entrypoint:opt} \n"
959 "OpExecutionMode %BP_main OriginUpperLeft\n"
960 "${execution_mode:opt}\n"
962 "${moduleprocessed:opt}\n"
963 "OpDecorate %BP_fragColor Location 0\n"
964 "OpDecorate %BP_vtxColor Location 1\n"
965 "OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n"
966 "${IF_decoration:opt}\n"
967 "${decoration:opt}\n"
969 SPIRV_ASSEMBLY_CONSTANTS
970 SPIRV_ASSEMBLY_ARRAYS
971 "%BP_gl_FragCoord = OpVariable %ip_v4f32 Input\n"
972 "%BP_fragColor = OpVariable %op_v4f32 Output\n"
973 "%BP_vtxColor = OpVariable %ip_v4f32 Input\n"
975 "${IF_variable:opt}\n"
976 "%BP_main = OpFunction %void None %voidf\n"
977 "%BP_label_main = OpLabel\n"
978 "${IF_carryforward:opt}\n"
979 "${post_interface_op_frag:opt}\n"
980 "%BP_tmp1 = OpLoad %v4f32 %BP_vtxColor\n"
981 "%BP_tmp2 = OpFunctionCall %v4f32 %test_code %BP_tmp1\n"
982 "OpStore %BP_fragColor %BP_tmp2\n"
985 "${interface_op_func:opt}\n"
987 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
988 "%getId_label = OpLabel\n"
989 "%loc_x_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n"
990 "%loc_y_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n"
991 "%x_coord = OpLoad %f32 %loc_x_coord\n"
992 "%y_coord = OpLoad %f32 %loc_y_coord\n"
993 "%is_x_idx0 = OpFOrdEqual %bool %x_coord %c_f32_0_5\n"
994 "%is_y_idx0 = OpFOrdEqual %bool %y_coord %c_f32_0_5\n"
995 "%is_frag_0 = OpLogicalAnd %bool %is_x_idx0 %is_y_idx0\n"
996 "OpReturnValue %is_frag_0\n"
1000 return tcu::StringTemplate(fragmentShaderBoilerplate).specialize(fragments);
1003 // Creates mappings from placeholders to pass-through shader code which copies
1004 // the input to the output faithfully.
1005 map<string, string> passthruInterface (const IFDataType& data_type)
1007 const string var_type = data_type.str();
1008 map<string, string> fragments = passthruFragments();
1009 const string functype = string("%") + var_type + "_" + var_type + "_function";
1011 fragments["interface_op_call"] = "OpCopyObject %" + var_type;
1012 fragments["interface_op_func"] = "";
1013 fragments["input_type"] = var_type;
1014 fragments["output_type"] = var_type;
1015 fragments["pre_main"] = "";
1017 if (!data_type.elementIs32bit())
1019 if (data_type.elementType == NUMBERTYPE_FLOAT64)
1021 fragments["capability"] = "OpCapability Float64\n\n";
1022 fragments["pre_main"] += "%f64 = OpTypeFloat 64\n";
1024 else if (data_type.elementType == NUMBERTYPE_FLOAT16)
1026 fragments["capability"] = "OpCapability StorageInputOutput16\n";
1027 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
1028 fragments["pre_main"] += "%f16 = OpTypeFloat 16\n";
1030 else if (data_type.elementType == NUMBERTYPE_INT16)
1032 fragments["capability"] = "OpCapability StorageInputOutput16\n";
1033 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
1034 fragments["pre_main"] += "%i16 = OpTypeInt 16 1\n";
1036 else if (data_type.elementType == NUMBERTYPE_UINT16)
1038 fragments["capability"] = "OpCapability StorageInputOutput16\n";
1039 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
1040 fragments["pre_main"] += "%u16 = OpTypeInt 16 0\n";
1044 DE_ASSERT(0 && "unhandled type");
1047 if (data_type.isVector())
1049 fragments["pre_main"] += "%" + var_type + " = OpTypeVector %" + IFDataType(1, data_type.elementType).str() + " " + numberToString(data_type.numElements) + "\n";
1052 fragments["pre_main"] +=
1053 "%ip_" + var_type + " = OpTypePointer Input %" + var_type + "\n"
1054 "%op_" + var_type + " = OpTypePointer Output %" + var_type + "\n";
1057 if (strcmp(var_type.c_str(), "v4f32") != 0)
1058 fragments["pre_main"] +=
1059 functype + " = OpTypeFunction %" + var_type + " %" + var_type + "\n"
1060 "%a3" + var_type + " = OpTypeArray %" + var_type + " %c_i32_3\n"
1061 "%ip_a3" + var_type + " = OpTypePointer Input %a3" + var_type + "\n"
1062 "%op_a3" + var_type + " = OpTypePointer Output %a3" + var_type + "\n";
1067 // Returns mappings from interface placeholders to their concrete values.
1069 // The concrete values should be specialized again to provide ${input_type}
1070 // and ${output_type}.
1072 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1073 map<string, string> fillInterfacePlaceholderVert (void)
1075 map<string, string> fragments;
1077 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1078 fragments["IF_variable"] =
1079 " %IF_input = OpVariable %ip_${input_type} Input\n"
1080 "%IF_output = OpVariable %op_${output_type} Output\n";
1081 fragments["IF_decoration"] =
1082 "OpDecorate %IF_input Location 2\n"
1083 "OpDecorate %IF_output Location 2\n";
1084 fragments["IF_carryforward"] =
1085 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1086 " %IF_result = ${interface_op_call} %IF_input_val\n"
1087 " OpStore %IF_output %IF_result\n";
1089 // Make sure the rest still need to be instantialized.
1090 fragments["capability"] = "${capability:opt}";
1091 fragments["extension"] = "${extension:opt}";
1092 fragments["execution_mode"] = "${execution_mode:opt}";
1093 fragments["debug"] = "${debug:opt}";
1094 fragments["decoration"] = "${decoration:opt}";
1095 fragments["pre_main"] = "${pre_main:opt}";
1096 fragments["testfun"] = "${testfun}";
1097 fragments["interface_op_call"] = "${interface_op_call}";
1098 fragments["interface_op_func"] = "${interface_op_func}";
1099 fragments["post_interface_op_vert"] = "${post_interface_op_vert:opt}";
1104 // Returns mappings from interface placeholders to their concrete values.
1106 // The concrete values should be specialized again to provide ${input_type}
1107 // and ${output_type}.
1109 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1110 map<string, string> fillInterfacePlaceholderFrag (void)
1112 map<string, string> fragments;
1114 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1115 fragments["IF_variable"] =
1116 " %IF_input = OpVariable %ip_${input_type} Input\n"
1117 "%IF_output = OpVariable %op_${output_type} Output\n";
1118 fragments["IF_decoration"] =
1119 "OpDecorate %IF_input Flat\n"
1120 "OpDecorate %IF_input Location 2\n"
1121 "OpDecorate %IF_output Location 1\n"; // Fragment shader should write to location #1.
1122 fragments["IF_carryforward"] =
1123 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1124 " %IF_result = ${interface_op_call} %IF_input_val\n"
1125 " OpStore %IF_output %IF_result\n";
1127 // Make sure the rest still need to be instantialized.
1128 fragments["capability"] = "${capability:opt}";
1129 fragments["extension"] = "${extension:opt}";
1130 fragments["execution_mode"] = "${execution_mode:opt}";
1131 fragments["debug"] = "${debug:opt}";
1132 fragments["decoration"] = "${decoration:opt}";
1133 fragments["pre_main"] = "${pre_main:opt}";
1134 fragments["testfun"] = "${testfun}";
1135 fragments["interface_op_call"] = "${interface_op_call}";
1136 fragments["interface_op_func"] = "${interface_op_func}";
1137 fragments["post_interface_op_frag"] = "${post_interface_op_frag:opt}";
1142 // Returns mappings from interface placeholders to their concrete values.
1144 // The concrete values should be specialized again to provide ${input_type}
1145 // and ${output_type}.
1147 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1148 // should also be defined in the final code.
1149 map<string, string> fillInterfacePlaceholderTessCtrl (void)
1151 map<string, string> fragments;
1153 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1154 fragments["IF_variable"] =
1155 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1156 "%IF_output = OpVariable %op_a3${output_type} Output\n";
1157 fragments["IF_decoration"] =
1158 "OpDecorate %IF_input Location 2\n"
1159 "OpDecorate %IF_output Location 2\n";
1160 fragments["IF_carryforward"] =
1161 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1162 " %IF_input_ptr1 = OpAccessChain %ip_${input_type} %IF_input %c_i32_1\n"
1163 " %IF_input_ptr2 = OpAccessChain %ip_${input_type} %IF_input %c_i32_2\n"
1164 "%IF_output_ptr0 = OpAccessChain %op_${output_type} %IF_output %c_i32_0\n"
1165 "%IF_output_ptr1 = OpAccessChain %op_${output_type} %IF_output %c_i32_1\n"
1166 "%IF_output_ptr2 = OpAccessChain %op_${output_type} %IF_output %c_i32_2\n"
1167 "%IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1168 "%IF_input_val1 = OpLoad %${input_type} %IF_input_ptr1\n"
1169 "%IF_input_val2 = OpLoad %${input_type} %IF_input_ptr2\n"
1170 "%IF_input_res0 = ${interface_op_call} %IF_input_val0\n"
1171 "%IF_input_res1 = ${interface_op_call} %IF_input_val1\n"
1172 "%IF_input_res2 = ${interface_op_call} %IF_input_val2\n"
1173 "OpStore %IF_output_ptr0 %IF_input_res0\n"
1174 "OpStore %IF_output_ptr1 %IF_input_res1\n"
1175 "OpStore %IF_output_ptr2 %IF_input_res2\n";
1177 // Make sure the rest still need to be instantialized.
1178 fragments["capability"] = "${capability:opt}";
1179 fragments["extension"] = "${extension:opt}";
1180 fragments["execution_mode"] = "${execution_mode:opt}";
1181 fragments["debug"] = "${debug:opt}";
1182 fragments["decoration"] = "${decoration:opt}";
1183 fragments["decoration_tessc"] = "${decoration_tessc:opt}";
1184 fragments["pre_main"] = "${pre_main:opt}";
1185 fragments["testfun"] = "${testfun}";
1186 fragments["interface_op_call"] = "${interface_op_call}";
1187 fragments["interface_op_func"] = "${interface_op_func}";
1188 fragments["post_interface_op_tessc"] = "${post_interface_op_tessc:opt}";
1193 // Returns mappings from interface placeholders to their concrete values.
1195 // The concrete values should be specialized again to provide ${input_type}
1196 // and ${output_type}.
1198 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1199 // should also be defined in the final code.
1200 map<string, string> fillInterfacePlaceholderTessEvalGeom (void)
1202 map<string, string> fragments;
1204 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1205 fragments["IF_variable"] =
1206 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1207 "%IF_output = OpVariable %op_${output_type} Output\n";
1208 fragments["IF_decoration"] =
1209 "OpDecorate %IF_input Location 2\n"
1210 "OpDecorate %IF_output Location 2\n";
1211 fragments["IF_carryforward"] =
1212 // Only get the first value since all three values are the same anyway.
1213 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1214 " %IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1215 " %IF_input_res0 = ${interface_op_call} %IF_input_val0\n"
1216 "OpStore %IF_output %IF_input_res0\n";
1218 // Make sure the rest still need to be instantialized.
1219 fragments["capability"] = "${capability:opt}";
1220 fragments["extension"] = "${extension:opt}";
1221 fragments["execution_mode"] = "${execution_mode:opt}";
1222 fragments["debug"] = "${debug:opt}";
1223 fragments["decoration"] = "${decoration:opt}";
1224 fragments["pre_main"] = "${pre_main:opt}";
1225 fragments["testfun"] = "${testfun}";
1226 fragments["interface_op_call"] = "${interface_op_call}";
1227 fragments["interface_op_func"] = "${interface_op_func}";
1228 fragments["post_interface_op_tesse"] = "${post_interface_op_tesse:opt}";
1229 fragments["post_interface_op_geom"] = "${post_interface_op_geom:opt}";
1234 map<string, string> passthruFragments (void)
1236 map<string, string> fragments;
1237 fragments["testfun"] =
1238 // A %test_code function that returns its argument unchanged.
1239 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
1240 "%param1 = OpFunctionParameter %v4f32\n"
1241 "%label_testfun = OpLabel\n"
1242 "OpReturnValue %param1\n"
1247 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1248 // Vertex shader gets custom code from context, the rest are pass-through.
1249 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1251 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1252 SpirvVersion targetSpirvVersion;
1254 if (spirVAsmBuildOptions == DE_NULL)
1255 targetSpirvVersion = context.resources.spirvVersion;
1257 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1259 if (!context.interfaces.empty())
1261 // Inject boilerplate code to wire up additional input/output variables between stages.
1262 // Just copy the contents in input variable to output variable in all stages except
1263 // the customized stage.
1264 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1265 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1267 map<string, string> passthru = passthruFragments();
1269 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1270 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1274 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext context)
1276 addShaderCodeCustomVertex(dst, context, DE_NULL);
1279 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1280 // Tessellation control shader gets custom code from context, the rest are
1282 void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1284 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1285 SpirvVersion targetSpirvVersion;
1287 if (spirVAsmBuildOptions == DE_NULL)
1288 targetSpirvVersion = context.resources.spirvVersion;
1290 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1292 if (!context.interfaces.empty())
1294 // Inject boilerplate code to wire up additional input/output variables between stages.
1295 // Just copy the contents in input variable to output variable in all stages except
1296 // the customized stage.
1297 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1298 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1299 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1300 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1304 map<string, string> passthru = passthruFragments();
1306 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1307 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1308 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1309 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1313 void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext context)
1315 addShaderCodeCustomTessControl(dst, context, DE_NULL);
1318 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1319 // Tessellation evaluation shader gets custom code from context, the rest are
1321 void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1323 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1324 SpirvVersion targetSpirvVersion;
1326 if (spirVAsmBuildOptions == DE_NULL)
1327 targetSpirvVersion = context.resources.spirvVersion;
1329 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1331 if (!context.interfaces.empty())
1333 // Inject boilerplate code to wire up additional input/output variables between stages.
1334 // Just copy the contents in input variable to output variable in all stages except
1335 // the customized stage.
1336 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1337 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1338 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1339 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1343 map<string, string> passthru = passthruFragments();
1344 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1345 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1346 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1347 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1351 void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext context)
1353 addShaderCodeCustomTessEval(dst, context, DE_NULL);
1356 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1357 // Geometry shader gets custom code from context, the rest are pass-through.
1358 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1360 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1361 SpirvVersion targetSpirvVersion;
1363 if (spirVAsmBuildOptions == DE_NULL)
1364 targetSpirvVersion = context.resources.spirvVersion;
1366 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1368 if (!context.interfaces.empty())
1370 // Inject boilerplate code to wire up additional input/output variables between stages.
1371 // Just copy the contents in input variable to output variable in all stages except
1372 // the customized stage.
1373 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1374 dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1375 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1379 map<string, string> passthru = passthruFragments();
1380 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1381 dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << makeGeometryShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1382 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1386 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext context)
1388 addShaderCodeCustomGeometry(dst, context, DE_NULL);
1391 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1392 // Fragment shader gets custom code from context, the rest are pass-through.
1393 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1395 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1396 SpirvVersion targetSpirvVersion;
1398 if (spirVAsmBuildOptions == DE_NULL)
1399 targetSpirvVersion = context.resources.spirvVersion;
1401 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1403 if (!context.interfaces.empty())
1405 // Inject boilerplate code to wire up additional input/output variables between stages.
1406 // Just copy the contents in input variable to output variable in all stages except
1407 // the customized stage.
1408 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1409 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1413 map<string, string> passthru = passthruFragments();
1414 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1415 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1419 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext context)
1421 addShaderCodeCustomFragment(dst, context, DE_NULL);
1424 void createCombinedModule (vk::SourceCollections& dst, InstanceContext ctx)
1426 const bool useTessellation (ctx.requiredStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
1427 const bool useGeometry (ctx.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT);
1428 std::stringstream combinedModule;
1429 std::stringstream opCapabilities;
1430 std::stringstream opEntryPoints;
1434 opCapabilities << "OpCapability Shader\n";
1437 opCapabilities << "OpCapability Geometry\n";
1439 if (useTessellation)
1440 opCapabilities << "OpCapability Tessellation\n";
1445 if (useTessellation)
1446 opEntryPoints << "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_vtxPosition %vert_vertex_id %vert_instance_id\n";
1448 opEntryPoints << "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_glPerVertex %vert_vertex_id %vert_instance_id\n";
1451 opEntryPoints << "OpEntryPoint Geometry %geom_main \"main\" %geom_out_gl_position %geom_gl_in %geom_out_color %geom_in_color\n";
1453 if (useTessellation)
1455 opEntryPoints << "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"
1456 "OpEntryPoint TessellationEvaluation %tesse_main \"main\" %tesse_stream %tesse_gl_tessCoord %tesse_in_position %tesse_out_color %tesse_in_color \n";
1459 opEntryPoints << "OpEntryPoint Fragment %frag_main \"main\" %frag_vtxColor %frag_fragColor\n";
1462 combinedModule << opCapabilities.str()
1463 << "OpMemoryModel Logical GLSL450\n"
1464 << opEntryPoints.str();
1468 combinedModule << "OpExecutionMode %geom_main Triangles\n"
1469 "OpExecutionMode %geom_main Invocations 1\n"
1470 "OpExecutionMode %geom_main OutputTriangleStrip\n"
1471 "OpExecutionMode %geom_main OutputVertices 3\n";
1474 if (useTessellation)
1476 combinedModule << "OpExecutionMode %tessc_main OutputVertices 3\n"
1477 "OpExecutionMode %tesse_main Triangles\n"
1478 "OpExecutionMode %tesse_main SpacingEqual\n"
1479 "OpExecutionMode %tesse_main VertexOrderCcw\n";
1482 combinedModule << "OpExecutionMode %frag_main OriginUpperLeft\n"
1484 "; Vertex decorations\n"
1485 "OpDecorate %vert_Position Location 0\n"
1486 "OpDecorate %vert_vtxColor Location 1\n"
1487 "OpDecorate %vert_color Location 1\n"
1488 "OpDecorate %vert_vertex_id BuiltIn VertexIndex\n"
1489 "OpDecorate %vert_instance_id BuiltIn InstanceIndex\n";
1491 // If tessellation is used, vertex position is written by tessellation stage.
1492 // Otherwise it will be written by vertex stage.
1493 if (useTessellation)
1494 combinedModule << "OpDecorate %vert_vtxPosition Location 2\n";
1497 combinedModule << "OpMemberDecorate %vert_per_vertex_out 0 BuiltIn Position\n"
1498 "OpMemberDecorate %vert_per_vertex_out 1 BuiltIn PointSize\n"
1499 "OpMemberDecorate %vert_per_vertex_out 2 BuiltIn ClipDistance\n"
1500 "OpMemberDecorate %vert_per_vertex_out 3 BuiltIn CullDistance\n"
1501 "OpDecorate %vert_per_vertex_out Block\n";
1506 combinedModule << "; Geometry decorations\n"
1507 "OpDecorate %geom_out_gl_position BuiltIn Position\n"
1508 "OpMemberDecorate %geom_per_vertex_in 0 BuiltIn Position\n"
1509 "OpMemberDecorate %geom_per_vertex_in 1 BuiltIn PointSize\n"
1510 "OpMemberDecorate %geom_per_vertex_in 2 BuiltIn ClipDistance\n"
1511 "OpMemberDecorate %geom_per_vertex_in 3 BuiltIn CullDistance\n"
1512 "OpDecorate %geom_per_vertex_in Block\n"
1513 "OpDecorate %geom_out_color Location 1\n"
1514 "OpDecorate %geom_in_color Location 1\n";
1517 if (useTessellation)
1519 combinedModule << "; Tessellation Control decorations\n"
1520 "OpDecorate %tessc_out_color Location 1\n"
1521 "OpDecorate %tessc_gl_InvocationID BuiltIn InvocationId\n"
1522 "OpDecorate %tessc_in_color Location 1\n"
1523 "OpDecorate %tessc_out_position Location 2\n"
1524 "OpDecorate %tessc_in_position Location 2\n"
1525 "OpDecorate %tessc_gl_TessLevelOuter Patch\n"
1526 "OpDecorate %tessc_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1527 "OpDecorate %tessc_gl_TessLevelInner Patch\n"
1528 "OpDecorate %tessc_gl_TessLevelInner BuiltIn TessLevelInner\n"
1530 "; Tessellation Evaluation decorations\n"
1531 "OpMemberDecorate %tesse_per_vertex_out 0 BuiltIn Position\n"
1532 "OpMemberDecorate %tesse_per_vertex_out 1 BuiltIn PointSize\n"
1533 "OpMemberDecorate %tesse_per_vertex_out 2 BuiltIn ClipDistance\n"
1534 "OpMemberDecorate %tesse_per_vertex_out 3 BuiltIn CullDistance\n"
1535 "OpDecorate %tesse_per_vertex_out Block\n"
1536 "OpDecorate %tesse_gl_tessCoord BuiltIn TessCoord\n"
1537 "OpDecorate %tesse_in_position Location 2\n"
1538 "OpDecorate %tesse_out_color Location 1\n"
1539 "OpDecorate %tesse_in_color Location 1\n";
1542 combinedModule << "; Fragment decorations\n"
1543 "OpDecorate %frag_fragColor Location 0\n"
1544 "OpDecorate %frag_vtxColor Location 1\n"
1546 SPIRV_ASSEMBLY_TYPES
1547 SPIRV_ASSEMBLY_CONSTANTS
1548 SPIRV_ASSEMBLY_ARRAYS
1550 "; Vertex Variables\n"
1551 "%vert_Position = OpVariable %ip_v4f32 Input\n"
1552 "%vert_vtxColor = OpVariable %op_v4f32 Output\n"
1553 "%vert_color = OpVariable %ip_v4f32 Input\n"
1554 "%vert_vertex_id = OpVariable %ip_i32 Input\n"
1555 "%vert_instance_id = OpVariable %ip_i32 Input\n";
1557 if (useTessellation)
1558 combinedModule << "%vert_vtxPosition = OpVariable %op_v4f32 Output\n";
1561 combinedModule << "%vert_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1562 "%vert_op_per_vertex_out = OpTypePointer Output %vert_per_vertex_out\n"
1563 "%vert_glPerVertex = OpVariable %vert_op_per_vertex_out Output\n";
1568 combinedModule << "; Geometry Variables\n"
1569 "%geom_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1570 "%geom_a3_per_vertex_in = OpTypeArray %geom_per_vertex_in %c_u32_3\n"
1571 "%geom_ip_a3_per_vertex_in = OpTypePointer Input %geom_a3_per_vertex_in\n"
1572 "%geom_gl_in = OpVariable %geom_ip_a3_per_vertex_in Input\n"
1573 "%geom_out_color = OpVariable %op_v4f32 Output\n"
1574 "%geom_in_color = OpVariable %ip_a3v4f32 Input\n"
1575 "%geom_out_gl_position = OpVariable %op_v4f32 Output\n";
1578 if (useTessellation)
1580 combinedModule << "; Tessellation Control Variables\n"
1581 "%tessc_out_color = OpVariable %op_a3v4f32 Output\n"
1582 "%tessc_gl_InvocationID = OpVariable %ip_i32 Input\n"
1583 "%tessc_in_color = OpVariable %ip_a32v4f32 Input\n"
1584 "%tessc_out_position = OpVariable %op_a3v4f32 Output\n"
1585 "%tessc_in_position = OpVariable %ip_a32v4f32 Input\n"
1586 "%tessc_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1587 "%tessc_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1589 "; Tessellation Evaluation Decorations\n"
1590 "%tesse_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1591 "%tesse_op_per_vertex_out = OpTypePointer Output %tesse_per_vertex_out\n"
1592 "%tesse_stream = OpVariable %tesse_op_per_vertex_out Output\n"
1593 "%tesse_gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1594 "%tesse_in_position = OpVariable %ip_a32v4f32 Input\n"
1595 "%tesse_out_color = OpVariable %op_v4f32 Output\n"
1596 "%tesse_in_color = OpVariable %ip_a32v4f32 Input\n";
1599 combinedModule << "; Fragment Variables\n"
1600 "%frag_fragColor = OpVariable %op_v4f32 Output\n"
1601 "%frag_vtxColor = OpVariable %ip_v4f32 Input\n"
1604 "%vert_main = OpFunction %void None %voidf\n"
1605 "%vert_label = OpLabel\n"
1606 "%vert_tmp_position = OpLoad %v4f32 %vert_Position\n";
1608 if (useTessellation)
1609 combinedModule << "OpStore %vert_vtxPosition %vert_tmp_position\n";
1612 combinedModule << "%vert_out_pos_ptr = OpAccessChain %op_v4f32 %vert_glPerVertex %c_i32_0\n"
1613 "OpStore %vert_out_pos_ptr %vert_tmp_position\n";
1616 combinedModule << "%vert_tmp_color = OpLoad %v4f32 %vert_color\n"
1617 "OpStore %vert_vtxColor %vert_tmp_color\n"
1623 combinedModule << "; Geometry Entry\n"
1624 "%geom_main = OpFunction %void None %voidf\n"
1625 "%geom_label = OpLabel\n"
1626 "%geom_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_0 %c_i32_0\n"
1627 "%geom_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_1 %c_i32_0\n"
1628 "%geom_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_2 %c_i32_0\n"
1629 "%geom_in_position_0 = OpLoad %v4f32 %geom_gl_in_0_gl_position\n"
1630 "%geom_in_position_1 = OpLoad %v4f32 %geom_gl_in_1_gl_position\n"
1631 "%geom_in_position_2 = OpLoad %v4f32 %geom_gl_in_2_gl_position \n"
1632 "%geom_in_color_0_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_0\n"
1633 "%geom_in_color_1_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_1\n"
1634 "%geom_in_color_2_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_2\n"
1635 "%geom_in_color_0 = OpLoad %v4f32 %geom_in_color_0_ptr\n"
1636 "%geom_in_color_1 = OpLoad %v4f32 %geom_in_color_1_ptr\n"
1637 "%geom_in_color_2 = OpLoad %v4f32 %geom_in_color_2_ptr\n"
1638 "OpStore %geom_out_gl_position %geom_in_position_0\n"
1639 "OpStore %geom_out_color %geom_in_color_0\n"
1641 "OpStore %geom_out_gl_position %geom_in_position_1\n"
1642 "OpStore %geom_out_color %geom_in_color_1\n"
1644 "OpStore %geom_out_gl_position %geom_in_position_2\n"
1645 "OpStore %geom_out_color %geom_in_color_2\n"
1652 if (useTessellation)
1654 combinedModule << "; Tessellation Control Entry\n"
1655 "%tessc_main = OpFunction %void None %voidf\n"
1656 "%tessc_label = OpLabel\n"
1657 "%tessc_invocation_id = OpLoad %i32 %tessc_gl_InvocationID\n"
1658 "%tessc_in_color_ptr = OpAccessChain %ip_v4f32 %tessc_in_color %tessc_invocation_id\n"
1659 "%tessc_in_position_ptr = OpAccessChain %ip_v4f32 %tessc_in_position %tessc_invocation_id\n"
1660 "%tessc_in_color_val = OpLoad %v4f32 %tessc_in_color_ptr\n"
1661 "%tessc_in_position_val = OpLoad %v4f32 %tessc_in_position_ptr\n"
1662 "%tessc_out_color_ptr = OpAccessChain %op_v4f32 %tessc_out_color %tessc_invocation_id\n"
1663 "%tessc_out_position_ptr = OpAccessChain %op_v4f32 %tessc_out_position %tessc_invocation_id\n"
1664 "OpStore %tessc_out_color_ptr %tessc_in_color_val\n"
1665 "OpStore %tessc_out_position_ptr %tessc_in_position_val\n"
1666 "%tessc_is_first_invocation = OpIEqual %bool %tessc_invocation_id %c_i32_0\n"
1667 "OpSelectionMerge %tessc_merge_label None\n"
1668 "OpBranchConditional %tessc_is_first_invocation %tessc_first_invocation %tessc_merge_label\n"
1669 "%tessc_first_invocation = OpLabel\n"
1670 "%tessc_tess_outer_0 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_0\n"
1671 "%tessc_tess_outer_1 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_1\n"
1672 "%tessc_tess_outer_2 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_2\n"
1673 "%tessc_tess_inner = OpAccessChain %op_f32 %tessc_gl_TessLevelInner %c_i32_0\n"
1674 "OpStore %tessc_tess_outer_0 %c_f32_1\n"
1675 "OpStore %tessc_tess_outer_1 %c_f32_1\n"
1676 "OpStore %tessc_tess_outer_2 %c_f32_1\n"
1677 "OpStore %tessc_tess_inner %c_f32_1\n"
1678 "OpBranch %tessc_merge_label\n"
1679 "%tessc_merge_label = OpLabel\n"
1683 "; Tessellation Evaluation Entry\n"
1684 "%tesse_main = OpFunction %void None %voidf\n"
1685 "%tesse_label = OpLabel\n"
1686 "%tesse_tc_0_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_0\n"
1687 "%tesse_tc_1_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_1\n"
1688 "%tesse_tc_2_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_2\n"
1689 "%tesse_tc_0 = OpLoad %f32 %tesse_tc_0_ptr\n"
1690 "%tesse_tc_1 = OpLoad %f32 %tesse_tc_1_ptr\n"
1691 "%tesse_tc_2 = OpLoad %f32 %tesse_tc_2_ptr\n"
1692 "%tesse_in_pos_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_0\n"
1693 "%tesse_in_pos_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_1\n"
1694 "%tesse_in_pos_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_2\n"
1695 "%tesse_in_pos_0 = OpLoad %v4f32 %tesse_in_pos_0_ptr\n"
1696 "%tesse_in_pos_1 = OpLoad %v4f32 %tesse_in_pos_1_ptr\n"
1697 "%tesse_in_pos_2 = OpLoad %v4f32 %tesse_in_pos_2_ptr\n"
1698 "%tesse_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_0 %tesse_tc_0\n"
1699 "%tesse_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_1 %tesse_tc_1\n"
1700 "%tesse_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_2 %tesse_tc_2\n"
1701 "%tesse_out_pos_ptr = OpAccessChain %op_v4f32 %tesse_stream %c_i32_0\n"
1702 "%tesse_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse_in_pos_0_weighted %tesse_in_pos_1_weighted\n"
1703 "%tesse_computed_out = OpFAdd %v4f32 %tesse_in_pos_0_plus_pos_1 %tesse_in_pos_2_weighted\n"
1704 "OpStore %tesse_out_pos_ptr %tesse_computed_out\n"
1705 "%tesse_in_clr_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_0\n"
1706 "%tesse_in_clr_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_1\n"
1707 "%tesse_in_clr_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_2\n"
1708 "%tesse_in_clr_0 = OpLoad %v4f32 %tesse_in_clr_0_ptr\n"
1709 "%tesse_in_clr_1 = OpLoad %v4f32 %tesse_in_clr_1_ptr\n"
1710 "%tesse_in_clr_2 = OpLoad %v4f32 %tesse_in_clr_2_ptr\n"
1711 "%tesse_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_0 %tesse_tc_0\n"
1712 "%tesse_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_1 %tesse_tc_1\n"
1713 "%tesse_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_2 %tesse_tc_2\n"
1714 "%tesse_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse_in_clr_0_weighted %tesse_in_clr_1_weighted\n"
1715 "%tesse_computed_clr = OpFAdd %v4f32 %tesse_in_clr_0_plus_col_1 %tesse_in_clr_2_weighted\n"
1716 "OpStore %tesse_out_color %tesse_computed_clr\n"
1721 combinedModule << "; Fragment Entry\n"
1722 "%frag_main = OpFunction %void None %voidf\n"
1723 "%frag_label_main = OpLabel\n"
1724 "%frag_tmp1 = OpLoad %v4f32 %frag_vtxColor\n"
1725 "OpStore %frag_fragColor %frag_tmp1\n"
1729 dst.spirvAsmSources.add("module") << combinedModule.str();
1732 void createUnusedVariableModules (vk::SourceCollections& dst, UnusedVariableContext ctx)
1734 if (ctx.shaderTasks[SHADER_TASK_INDEX_VERTEX] != SHADER_TASK_NONE)
1736 std::ostringstream shader;
1737 bool tessellation = (ctx.shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL] != SHADER_TASK_NONE
1738 || ctx.shaderTasks[SHADER_TASK_INDEX_TESS_EVAL] != SHADER_TASK_NONE);
1739 const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_VERTEX];
1741 shader << "OpCapability Shader\n"
1742 << "OpMemoryModel Logical GLSL450\n";
1744 // Entry point depends on if tessellation is enabled or not to provide the vertex position.
1745 shader << "OpEntryPoint Vertex %main \"main\" %Position %vtxColor %color "
1746 << (tessellation ? "%vtxPosition" : "%vtx_glPerVertex")
1747 << " %vertex_id %instance_id\n";
1748 if (task == SHADER_TASK_UNUSED_FUNC)
1750 shader << getUnusedEntryPoint();
1754 shader << "OpDecorate %Position Location 0\n"
1755 << "OpDecorate %vtxColor Location 1\n"
1756 << "OpDecorate %color Location 1\n"
1757 << "OpDecorate %vertex_id BuiltIn VertexIndex\n"
1758 << "OpDecorate %instance_id BuiltIn InstanceIndex\n";
1761 shader << "OpDecorate %vtxPosition Location 2\n";
1765 shader << "OpMemberDecorate %vert_per_vertex_out 0 BuiltIn Position\n"
1766 << "OpMemberDecorate %vert_per_vertex_out 1 BuiltIn PointSize\n"
1767 << "OpMemberDecorate %vert_per_vertex_out 2 BuiltIn ClipDistance\n"
1768 << "OpMemberDecorate %vert_per_vertex_out 3 BuiltIn CullDistance\n"
1769 << "OpDecorate %vert_per_vertex_out Block\n";
1771 if (task != SHADER_TASK_NORMAL)
1773 shader << getUnusedDecorations(ctx.variableLocation);
1776 // Standard types, constants and arrays.
1777 shader << "; Start of standard types, constants and arrays\n"
1778 << SPIRV_ASSEMBLY_TYPES
1779 << SPIRV_ASSEMBLY_CONSTANTS
1780 << SPIRV_ASSEMBLY_ARRAYS
1781 << "; End of standard types, constants and arrays\n";
1782 if (task != SHADER_TASK_NORMAL)
1784 shader << getUnusedTypesAndConstants();
1790 shader << "%vtxPosition = OpVariable %op_v4f32 Output\n";
1794 shader << "%vert_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1795 << "%vert_op_per_vertex_out = OpTypePointer Output %vert_per_vertex_out\n"
1796 << "%vtx_glPerVertex = OpVariable %vert_op_per_vertex_out Output\n";
1798 shader << "%Position = OpVariable %ip_v4f32 Input\n"
1799 << "%vtxColor = OpVariable %op_v4f32 Output\n"
1800 << "%color = OpVariable %ip_v4f32 Input\n"
1801 << "%vertex_id = OpVariable %ip_i32 Input\n"
1802 << "%instance_id = OpVariable %ip_i32 Input\n";
1803 if (task != SHADER_TASK_NORMAL)
1805 shader << getUnusedBuffer();
1808 // Vertex main function.
1809 shader << "%main = OpFunction %void None %voidf\n"
1810 << "%label = OpLabel\n"
1811 << "%tmp_position = OpLoad %v4f32 %Position\n";
1814 shader << "OpStore %vtxPosition %tmp_position\n";
1818 shader << "%vert_out_pos_ptr = OpAccessChain %op_v4f32 %vtx_glPerVertex %c_i32_0\n"
1819 << "OpStore %vert_out_pos_ptr %tmp_position\n";
1821 shader << "%tmp_color = OpLoad %v4f32 %color\n"
1822 << "OpStore %vtxColor %tmp_color\n"
1824 << "OpFunctionEnd\n";
1825 if (task == SHADER_TASK_UNUSED_FUNC)
1827 shader << getUnusedFunctionBody();
1830 dst.spirvAsmSources.add("vert") << shader.str();
1833 if (ctx.shaderTasks[SHADER_TASK_INDEX_GEOMETRY] != SHADER_TASK_NONE)
1835 const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_GEOMETRY];
1836 std::ostringstream shader;
1838 if (task != SHADER_TASK_NORMAL)
1840 shader << getOpCapabilityShader();
1842 shader << "OpCapability Geometry\n"
1843 << "OpMemoryModel Logical GLSL450\n";
1846 shader << "OpEntryPoint Geometry %geom1_main \"main\" %out_gl_position %gl_in %out_color %in_color\n";
1847 if (task == SHADER_TASK_UNUSED_FUNC)
1849 shader << getUnusedEntryPoint();
1851 shader << "OpExecutionMode %geom1_main Triangles\n"
1852 << "OpExecutionMode %geom1_main OutputTriangleStrip\n"
1853 << "OpExecutionMode %geom1_main OutputVertices 3\n";
1856 shader << "OpDecorate %out_gl_position BuiltIn Position\n"
1857 << "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n"
1858 << "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n"
1859 << "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n"
1860 << "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n"
1861 << "OpDecorate %per_vertex_in Block\n"
1862 << "OpDecorate %out_color Location 1\n"
1863 << "OpDecorate %in_color Location 1\n";
1864 if (task != SHADER_TASK_NORMAL)
1866 shader << getUnusedDecorations(ctx.variableLocation);
1869 // Standard types, constants and arrays.
1870 shader << "; Start of standard types, constants and arrays\n"
1871 << SPIRV_ASSEMBLY_TYPES
1872 << SPIRV_ASSEMBLY_CONSTANTS
1873 << SPIRV_ASSEMBLY_ARRAYS
1874 << "; End of standard types, constants and arrays\n";
1875 if (task != SHADER_TASK_NORMAL)
1877 shader << getUnusedTypesAndConstants();
1881 shader << "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1882 << "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n"
1883 << "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n"
1884 << "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n"
1885 << "%out_color = OpVariable %op_v4f32 Output\n"
1886 << "%in_color = OpVariable %ip_a3v4f32 Input\n"
1887 << "%out_gl_position = OpVariable %op_v4f32 Output\n";
1888 if (task != SHADER_TASK_NORMAL)
1890 shader << getUnusedBuffer();
1894 shader << "%geom1_main = OpFunction %void None %voidf\n"
1895 << "%geom1_label = OpLabel\n"
1896 << "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1897 << "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1898 << "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1899 << "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n"
1900 << "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n"
1901 << "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n"
1902 << "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1903 << "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1904 << "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1905 << "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n"
1906 << "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n"
1907 << "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n"
1908 << "OpStore %out_gl_position %geom1_in_position_0\n"
1909 << "OpStore %out_color %geom1_in_color_0\n"
1911 << "OpStore %out_gl_position %geom1_in_position_1\n"
1912 << "OpStore %out_color %geom1_in_color_1\n"
1914 << "OpStore %out_gl_position %geom1_in_position_2\n"
1915 << "OpStore %out_color %geom1_in_color_2\n"
1917 << "OpEndPrimitive\n"
1919 << "OpFunctionEnd\n";
1920 if (task == SHADER_TASK_UNUSED_FUNC)
1922 shader << getUnusedFunctionBody();
1925 dst.spirvAsmSources.add("geom") << shader.str();
1928 if (ctx.shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL] != SHADER_TASK_NONE)
1930 const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL];
1931 std::ostringstream shader;
1933 if (task != SHADER_TASK_NORMAL)
1935 shader << getOpCapabilityShader();
1937 shader << "OpCapability Tessellation\n"
1938 << "OpMemoryModel Logical GLSL450\n";
1941 shader << "OpEntryPoint TessellationControl %tessc1_main \"main\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n";
1942 if (task == SHADER_TASK_UNUSED_FUNC)
1944 shader << getUnusedEntryPoint();
1946 shader << "OpExecutionMode %tessc1_main OutputVertices 3\n";
1949 shader << "OpDecorate %out_color Location 1\n"
1950 << "OpDecorate %gl_InvocationID BuiltIn InvocationId\n"
1951 << "OpDecorate %in_color Location 1\n"
1952 << "OpDecorate %out_position Location 2\n"
1953 << "OpDecorate %in_position Location 2\n"
1954 << "OpDecorate %gl_TessLevelOuter Patch\n"
1955 << "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1956 << "OpDecorate %gl_TessLevelInner Patch\n"
1957 << "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n";
1958 if (task != SHADER_TASK_NORMAL)
1960 shader << getUnusedDecorations(ctx.variableLocation);
1963 // Standard types, constants and arrays.
1964 shader << "; Start of standard types, constants and arrays\n"
1965 << SPIRV_ASSEMBLY_TYPES
1966 << SPIRV_ASSEMBLY_CONSTANTS
1967 << SPIRV_ASSEMBLY_ARRAYS
1968 << "; End of standard types, constants and arrays\n";
1969 if (task != SHADER_TASK_NORMAL)
1971 shader << getUnusedTypesAndConstants();
1975 shader << "%out_color = OpVariable %op_a3v4f32 Output\n"
1976 << "%gl_InvocationID = OpVariable %ip_i32 Input\n"
1977 << "%in_color = OpVariable %ip_a32v4f32 Input\n"
1978 << "%out_position = OpVariable %op_a3v4f32 Output\n"
1979 << "%in_position = OpVariable %ip_a32v4f32 Input\n"
1980 << "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1981 << "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n";
1982 if (task != SHADER_TASK_NORMAL)
1984 shader << getUnusedBuffer();
1987 // Main entry point.
1988 shader << "%tessc1_main = OpFunction %void None %voidf\n"
1989 << "%tessc1_label = OpLabel\n"
1990 << "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1991 << "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n"
1992 << "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n"
1993 << "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n"
1994 << "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n"
1995 << "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n"
1996 << "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n"
1997 << "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n"
1998 << "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n"
1999 << "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n"
2000 << "OpSelectionMerge %tessc1_merge_label None\n"
2001 << "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n"
2002 << "%tessc1_first_invocation = OpLabel\n"
2003 << "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
2004 << "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
2005 << "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
2006 << "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
2007 << "OpStore %tessc1_tess_outer_0 %c_f32_1\n"
2008 << "OpStore %tessc1_tess_outer_1 %c_f32_1\n"
2009 << "OpStore %tessc1_tess_outer_2 %c_f32_1\n"
2010 << "OpStore %tessc1_tess_inner %c_f32_1\n"
2011 << "OpBranch %tessc1_merge_label\n"
2012 << "%tessc1_merge_label = OpLabel\n"
2014 << "OpFunctionEnd\n";
2015 if (task == SHADER_TASK_UNUSED_FUNC)
2017 shader << getUnusedFunctionBody();
2020 dst.spirvAsmSources.add("tessc") << shader.str();
2023 if (ctx.shaderTasks[SHADER_TASK_INDEX_TESS_EVAL] != SHADER_TASK_NONE)
2025 const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_TESS_EVAL];
2026 std::ostringstream shader;
2028 if (task != SHADER_TASK_NORMAL)
2030 shader << getOpCapabilityShader();
2032 shader << "OpCapability Tessellation\n"
2033 << "OpMemoryModel Logical GLSL450\n";
2036 shader << "OpEntryPoint TessellationEvaluation %tesse1_main \"main\" %stream %gl_tessCoord %in_position %out_color %in_color \n";
2037 if (task == SHADER_TASK_UNUSED_FUNC)
2039 shader << getUnusedEntryPoint();
2041 shader << "OpExecutionMode %tesse1_main Triangles\n"
2042 << "OpExecutionMode %tesse1_main SpacingEqual\n"
2043 << "OpExecutionMode %tesse1_main VertexOrderCcw\n";
2046 shader << "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n"
2047 << "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n"
2048 << "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n"
2049 << "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n"
2050 << "OpDecorate %per_vertex_out Block\n"
2051 << "OpDecorate %gl_tessCoord BuiltIn TessCoord\n"
2052 << "OpDecorate %in_position Location 2\n"
2053 << "OpDecorate %out_color Location 1\n"
2054 << "OpDecorate %in_color Location 1\n";
2055 if (task != SHADER_TASK_NORMAL)
2057 shader << getUnusedDecorations(ctx.variableLocation);
2060 // Standard types, constants and arrays.
2061 shader << "; Start of standard types, constants and arrays\n"
2062 << SPIRV_ASSEMBLY_TYPES
2063 << SPIRV_ASSEMBLY_CONSTANTS
2064 << SPIRV_ASSEMBLY_ARRAYS
2065 << "; End of standard types, constants and arrays\n";
2066 if (task != SHADER_TASK_NORMAL)
2068 shader << getUnusedTypesAndConstants();
2072 shader << "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
2073 << "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n"
2074 << "%stream = OpVariable %op_per_vertex_out Output\n"
2075 << "%gl_tessCoord = OpVariable %ip_v3f32 Input\n"
2076 << "%in_position = OpVariable %ip_a32v4f32 Input\n"
2077 << "%out_color = OpVariable %op_v4f32 Output\n"
2078 << "%in_color = OpVariable %ip_a32v4f32 Input\n";
2079 if (task != SHADER_TASK_NORMAL)
2081 shader << getUnusedBuffer();
2084 // Main entry point.
2085 shader << "%tesse1_main = OpFunction %void None %voidf\n"
2086 << "%tesse1_label = OpLabel\n"
2087 << "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
2088 << "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
2089 << "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
2090 << "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n"
2091 << "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n"
2092 << "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n"
2093 << "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
2094 << "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
2095 << "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
2096 << "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n"
2097 << "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n"
2098 << "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n"
2099 << "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n"
2100 << "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n"
2101 << "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n"
2102 << "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
2103 << "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n"
2104 << "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n"
2105 << "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n"
2106 << "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2107 << "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2108 << "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2109 << "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n"
2110 << "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n"
2111 << "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n"
2112 << "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n"
2113 << "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n"
2114 << "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n"
2115 << "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n"
2116 << "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n"
2117 << "OpStore %out_color %tesse1_computed_clr\n"
2119 << "OpFunctionEnd\n";
2120 if (task == SHADER_TASK_UNUSED_FUNC)
2122 shader << getUnusedFunctionBody();
2125 dst.spirvAsmSources.add("tesse") << shader.str();
2128 if (ctx.shaderTasks[SHADER_TASK_INDEX_FRAGMENT] != SHADER_TASK_NONE)
2130 const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_FRAGMENT];
2131 std::ostringstream shader;
2133 shader << "OpCapability Shader\n"
2134 << "OpMemoryModel Logical GLSL450\n";
2137 shader << "OpEntryPoint Fragment %main \"main\" %vtxColor %fragColor\n";
2138 if (task == SHADER_TASK_UNUSED_FUNC)
2140 shader << getUnusedEntryPoint();
2142 shader << "OpExecutionMode %main OriginUpperLeft\n";
2145 shader << "OpDecorate %fragColor Location 0\n"
2146 << "OpDecorate %vtxColor Location 1\n";
2147 if (task != SHADER_TASK_NORMAL)
2149 shader << getUnusedDecorations(ctx.variableLocation);
2152 // Standard types, constants and arrays.
2153 shader << "; Start of standard types, constants and arrays\n"
2154 << SPIRV_ASSEMBLY_TYPES
2155 << SPIRV_ASSEMBLY_CONSTANTS
2156 << SPIRV_ASSEMBLY_ARRAYS
2157 << "; End of standard types, constants and arrays\n";
2158 if (task != SHADER_TASK_NORMAL)
2160 shader << getUnusedTypesAndConstants();
2164 shader << "%fragColor = OpVariable %op_v4f32 Output\n"
2165 << "%vtxColor = OpVariable %ip_v4f32 Input\n";
2166 if (task != SHADER_TASK_NORMAL)
2168 shader << getUnusedBuffer();
2171 // Main entry point.
2172 shader << "%main = OpFunction %void None %voidf\n"
2173 << "%label_main = OpLabel\n"
2174 << "%tmp1 = OpLoad %v4f32 %vtxColor\n"
2175 << "OpStore %fragColor %tmp1\n"
2177 << "OpFunctionEnd\n";
2178 if (task == SHADER_TASK_UNUSED_FUNC)
2180 shader << getUnusedFunctionBody();
2183 dst.spirvAsmSources.add("frag") << shader.str();
2187 void createMultipleEntries (vk::SourceCollections& dst, InstanceContext)
2189 dst.spirvAsmSources.add("vert") <<
2190 // This module contains 2 vertex shaders. One that is a passthrough
2191 // and a second that inverts the color of the output (1.0 - color).
2192 "OpCapability Shader\n"
2193 "OpMemoryModel Logical GLSL450\n"
2194 "OpEntryPoint Vertex %main \"vert1\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
2195 "OpEntryPoint Vertex %main2 \"vert2\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
2197 "OpDecorate %vtxPosition Location 2\n"
2198 "OpDecorate %Position Location 0\n"
2199 "OpDecorate %vtxColor Location 1\n"
2200 "OpDecorate %color Location 1\n"
2201 "OpDecorate %vertex_id BuiltIn VertexIndex\n"
2202 "OpDecorate %instance_id BuiltIn InstanceIndex\n"
2203 SPIRV_ASSEMBLY_TYPES
2204 SPIRV_ASSEMBLY_CONSTANTS
2205 SPIRV_ASSEMBLY_ARRAYS
2206 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
2207 "%vtxPosition = OpVariable %op_v4f32 Output\n"
2208 "%Position = OpVariable %ip_v4f32 Input\n"
2209 "%vtxColor = OpVariable %op_v4f32 Output\n"
2210 "%color = OpVariable %ip_v4f32 Input\n"
2211 "%vertex_id = OpVariable %ip_i32 Input\n"
2212 "%instance_id = OpVariable %ip_i32 Input\n"
2214 "%main = OpFunction %void None %voidf\n"
2215 "%label = OpLabel\n"
2216 "%tmp_position = OpLoad %v4f32 %Position\n"
2217 "OpStore %vtxPosition %tmp_position\n"
2218 "%tmp_color = OpLoad %v4f32 %color\n"
2219 "OpStore %vtxColor %tmp_color\n"
2223 "%main2 = OpFunction %void None %voidf\n"
2224 "%label2 = OpLabel\n"
2225 "%tmp_position2 = OpLoad %v4f32 %Position\n"
2226 "OpStore %vtxPosition %tmp_position2\n"
2227 "%tmp_color2 = OpLoad %v4f32 %color\n"
2228 "%tmp_color3 = OpFSub %v4f32 %cval %tmp_color2\n"
2229 "%tmp_color4 = OpVectorInsertDynamic %v4f32 %tmp_color3 %c_f32_1 %c_i32_3\n"
2230 "OpStore %vtxColor %tmp_color4\n"
2234 dst.spirvAsmSources.add("frag") <<
2235 // This is a single module that contains 2 fragment shaders.
2236 // One that passes color through and the other that inverts the output
2237 // color (1.0 - color).
2238 "OpCapability Shader\n"
2239 "OpMemoryModel Logical GLSL450\n"
2240 "OpEntryPoint Fragment %main \"frag1\" %vtxColor %fragColor\n"
2241 "OpEntryPoint Fragment %main2 \"frag2\" %vtxColor %fragColor\n"
2242 "OpExecutionMode %main OriginUpperLeft\n"
2243 "OpExecutionMode %main2 OriginUpperLeft\n"
2245 "OpDecorate %fragColor Location 0\n"
2246 "OpDecorate %vtxColor Location 1\n"
2247 SPIRV_ASSEMBLY_TYPES
2248 SPIRV_ASSEMBLY_CONSTANTS
2249 SPIRV_ASSEMBLY_ARRAYS
2250 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
2251 "%fragColor = OpVariable %op_v4f32 Output\n"
2252 "%vtxColor = OpVariable %ip_v4f32 Input\n"
2254 "%main = OpFunction %void None %voidf\n"
2255 "%label_main = OpLabel\n"
2256 "%tmp1 = OpLoad %v4f32 %vtxColor\n"
2257 "OpStore %fragColor %tmp1\n"
2261 "%main2 = OpFunction %void None %voidf\n"
2262 "%label_main2 = OpLabel\n"
2263 "%tmp2 = OpLoad %v4f32 %vtxColor\n"
2264 "%tmp3 = OpFSub %v4f32 %cval %tmp2\n"
2265 "%tmp4 = OpVectorInsertDynamic %v4f32 %tmp3 %c_f32_1 %c_i32_3\n"
2266 "OpStore %fragColor %tmp4\n"
2270 dst.spirvAsmSources.add("geom") <<
2271 "OpCapability Geometry\n"
2272 "OpMemoryModel Logical GLSL450\n"
2273 "OpEntryPoint Geometry %geom1_main \"geom1\" %out_gl_position %gl_in %out_color %in_color\n"
2274 "OpEntryPoint Geometry %geom2_main \"geom2\" %out_gl_position %gl_in %out_color %in_color\n"
2275 "OpExecutionMode %geom1_main Triangles\n"
2276 "OpExecutionMode %geom2_main Triangles\n"
2277 "OpExecutionMode %geom1_main OutputTriangleStrip\n"
2278 "OpExecutionMode %geom2_main OutputTriangleStrip\n"
2279 "OpExecutionMode %geom1_main OutputVertices 3\n"
2280 "OpExecutionMode %geom2_main OutputVertices 3\n"
2281 "OpDecorate %out_gl_position BuiltIn Position\n"
2282 "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n"
2283 "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n"
2284 "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n"
2285 "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n"
2286 "OpDecorate %per_vertex_in Block\n"
2287 "OpDecorate %out_color Location 1\n"
2288 "OpDecorate %in_color Location 1\n"
2289 SPIRV_ASSEMBLY_TYPES
2290 SPIRV_ASSEMBLY_CONSTANTS
2291 SPIRV_ASSEMBLY_ARRAYS
2292 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
2293 "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
2294 "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n"
2295 "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n"
2296 "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n"
2297 "%out_color = OpVariable %op_v4f32 Output\n"
2298 "%in_color = OpVariable %ip_a3v4f32 Input\n"
2299 "%out_gl_position = OpVariable %op_v4f32 Output\n"
2301 "%geom1_main = OpFunction %void None %voidf\n"
2302 "%geom1_label = OpLabel\n"
2303 "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
2304 "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
2305 "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
2306 "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n"
2307 "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n"
2308 "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n"
2309 "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2310 "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2311 "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2312 "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n"
2313 "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n"
2314 "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n"
2315 "OpStore %out_gl_position %geom1_in_position_0\n"
2316 "OpStore %out_color %geom1_in_color_0\n"
2318 "OpStore %out_gl_position %geom1_in_position_1\n"
2319 "OpStore %out_color %geom1_in_color_1\n"
2321 "OpStore %out_gl_position %geom1_in_position_2\n"
2322 "OpStore %out_color %geom1_in_color_2\n"
2328 "%geom2_main = OpFunction %void None %voidf\n"
2329 "%geom2_label = OpLabel\n"
2330 "%geom2_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
2331 "%geom2_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
2332 "%geom2_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
2333 "%geom2_in_position_0 = OpLoad %v4f32 %geom2_gl_in_0_gl_position\n"
2334 "%geom2_in_position_1 = OpLoad %v4f32 %geom2_gl_in_1_gl_position\n"
2335 "%geom2_in_position_2 = OpLoad %v4f32 %geom2_gl_in_2_gl_position \n"
2336 "%geom2_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2337 "%geom2_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2338 "%geom2_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2339 "%geom2_in_color_0 = OpLoad %v4f32 %geom2_in_color_0_ptr\n"
2340 "%geom2_in_color_1 = OpLoad %v4f32 %geom2_in_color_1_ptr\n"
2341 "%geom2_in_color_2 = OpLoad %v4f32 %geom2_in_color_2_ptr\n"
2342 "%geom2_transformed_in_color_0 = OpFSub %v4f32 %cval %geom2_in_color_0\n"
2343 "%geom2_transformed_in_color_1 = OpFSub %v4f32 %cval %geom2_in_color_1\n"
2344 "%geom2_transformed_in_color_2 = OpFSub %v4f32 %cval %geom2_in_color_2\n"
2345 "%geom2_transformed_in_color_0_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_0 %c_f32_1 %c_i32_3\n"
2346 "%geom2_transformed_in_color_1_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_1 %c_f32_1 %c_i32_3\n"
2347 "%geom2_transformed_in_color_2_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_2 %c_f32_1 %c_i32_3\n"
2348 "OpStore %out_gl_position %geom2_in_position_0\n"
2349 "OpStore %out_color %geom2_transformed_in_color_0_a\n"
2351 "OpStore %out_gl_position %geom2_in_position_1\n"
2352 "OpStore %out_color %geom2_transformed_in_color_1_a\n"
2354 "OpStore %out_gl_position %geom2_in_position_2\n"
2355 "OpStore %out_color %geom2_transformed_in_color_2_a\n"
2361 dst.spirvAsmSources.add("tessc") <<
2362 "OpCapability Tessellation\n"
2363 "OpMemoryModel Logical GLSL450\n"
2364 "OpEntryPoint TessellationControl %tessc1_main \"tessc1\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
2365 "OpEntryPoint TessellationControl %tessc2_main \"tessc2\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
2366 "OpExecutionMode %tessc1_main OutputVertices 3\n"
2367 "OpExecutionMode %tessc2_main OutputVertices 3\n"
2368 "OpDecorate %out_color Location 1\n"
2369 "OpDecorate %gl_InvocationID BuiltIn InvocationId\n"
2370 "OpDecorate %in_color Location 1\n"
2371 "OpDecorate %out_position Location 2\n"
2372 "OpDecorate %in_position Location 2\n"
2373 "OpDecorate %gl_TessLevelOuter Patch\n"
2374 "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n"
2375 "OpDecorate %gl_TessLevelInner Patch\n"
2376 "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n"
2377 SPIRV_ASSEMBLY_TYPES
2378 SPIRV_ASSEMBLY_CONSTANTS
2379 SPIRV_ASSEMBLY_ARRAYS
2380 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
2381 "%out_color = OpVariable %op_a3v4f32 Output\n"
2382 "%gl_InvocationID = OpVariable %ip_i32 Input\n"
2383 "%in_color = OpVariable %ip_a32v4f32 Input\n"
2384 "%out_position = OpVariable %op_a3v4f32 Output\n"
2385 "%in_position = OpVariable %ip_a32v4f32 Input\n"
2386 "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
2387 "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
2389 "%tessc1_main = OpFunction %void None %voidf\n"
2390 "%tessc1_label = OpLabel\n"
2391 "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n"
2392 "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n"
2393 "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n"
2394 "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n"
2395 "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n"
2396 "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n"
2397 "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n"
2398 "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n"
2399 "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n"
2400 "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n"
2401 "OpSelectionMerge %tessc1_merge_label None\n"
2402 "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n"
2403 "%tessc1_first_invocation = OpLabel\n"
2404 "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
2405 "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
2406 "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
2407 "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
2408 "OpStore %tessc1_tess_outer_0 %c_f32_1\n"
2409 "OpStore %tessc1_tess_outer_1 %c_f32_1\n"
2410 "OpStore %tessc1_tess_outer_2 %c_f32_1\n"
2411 "OpStore %tessc1_tess_inner %c_f32_1\n"
2412 "OpBranch %tessc1_merge_label\n"
2413 "%tessc1_merge_label = OpLabel\n"
2417 "%tessc2_main = OpFunction %void None %voidf\n"
2418 "%tessc2_label = OpLabel\n"
2419 "%tessc2_invocation_id = OpLoad %i32 %gl_InvocationID\n"
2420 "%tessc2_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc2_invocation_id\n"
2421 "%tessc2_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc2_invocation_id\n"
2422 "%tessc2_in_color_val = OpLoad %v4f32 %tessc2_in_color_ptr\n"
2423 "%tessc2_in_position_val = OpLoad %v4f32 %tessc2_in_position_ptr\n"
2424 "%tessc2_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc2_invocation_id\n"
2425 "%tessc2_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc2_invocation_id\n"
2426 "%tessc2_transformed_color = OpFSub %v4f32 %cval %tessc2_in_color_val\n"
2427 "%tessc2_transformed_color_a = OpVectorInsertDynamic %v4f32 %tessc2_transformed_color %c_f32_1 %c_i32_3\n"
2428 "OpStore %tessc2_out_color_ptr %tessc2_transformed_color_a\n"
2429 "OpStore %tessc2_out_position_ptr %tessc2_in_position_val\n"
2430 "%tessc2_is_first_invocation = OpIEqual %bool %tessc2_invocation_id %c_i32_0\n"
2431 "OpSelectionMerge %tessc2_merge_label None\n"
2432 "OpBranchConditional %tessc2_is_first_invocation %tessc2_first_invocation %tessc2_merge_label\n"
2433 "%tessc2_first_invocation = OpLabel\n"
2434 "%tessc2_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
2435 "%tessc2_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
2436 "%tessc2_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
2437 "%tessc2_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
2438 "OpStore %tessc2_tess_outer_0 %c_f32_1\n"
2439 "OpStore %tessc2_tess_outer_1 %c_f32_1\n"
2440 "OpStore %tessc2_tess_outer_2 %c_f32_1\n"
2441 "OpStore %tessc2_tess_inner %c_f32_1\n"
2442 "OpBranch %tessc2_merge_label\n"
2443 "%tessc2_merge_label = OpLabel\n"
2447 dst.spirvAsmSources.add("tesse") <<
2448 "OpCapability Tessellation\n"
2449 "OpMemoryModel Logical GLSL450\n"
2450 "OpEntryPoint TessellationEvaluation %tesse1_main \"tesse1\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
2451 "OpEntryPoint TessellationEvaluation %tesse2_main \"tesse2\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
2452 "OpExecutionMode %tesse1_main Triangles\n"
2453 "OpExecutionMode %tesse1_main SpacingEqual\n"
2454 "OpExecutionMode %tesse1_main VertexOrderCcw\n"
2455 "OpExecutionMode %tesse2_main Triangles\n"
2456 "OpExecutionMode %tesse2_main SpacingEqual\n"
2457 "OpExecutionMode %tesse2_main VertexOrderCcw\n"
2458 "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n"
2459 "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n"
2460 "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n"
2461 "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n"
2462 "OpDecorate %per_vertex_out Block\n"
2463 "OpDecorate %gl_tessCoord BuiltIn TessCoord\n"
2464 "OpDecorate %in_position Location 2\n"
2465 "OpDecorate %out_color Location 1\n"
2466 "OpDecorate %in_color Location 1\n"
2467 SPIRV_ASSEMBLY_TYPES
2468 SPIRV_ASSEMBLY_CONSTANTS
2469 SPIRV_ASSEMBLY_ARRAYS
2470 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
2471 "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
2472 "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n"
2473 "%stream = OpVariable %op_per_vertex_out Output\n"
2474 "%gl_tessCoord = OpVariable %ip_v3f32 Input\n"
2475 "%in_position = OpVariable %ip_a32v4f32 Input\n"
2476 "%out_color = OpVariable %op_v4f32 Output\n"
2477 "%in_color = OpVariable %ip_a32v4f32 Input\n"
2479 "%tesse1_main = OpFunction %void None %voidf\n"
2480 "%tesse1_label = OpLabel\n"
2481 "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
2482 "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
2483 "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
2484 "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n"
2485 "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n"
2486 "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n"
2487 "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
2488 "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
2489 "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
2490 "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n"
2491 "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n"
2492 "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n"
2493 "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n"
2494 "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n"
2495 "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n"
2496 "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
2497 "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n"
2498 "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n"
2499 "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n"
2500 "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2501 "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2502 "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2503 "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n"
2504 "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n"
2505 "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n"
2506 "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n"
2507 "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n"
2508 "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n"
2509 "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n"
2510 "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n"
2511 "OpStore %out_color %tesse1_computed_clr\n"
2515 "%tesse2_main = OpFunction %void None %voidf\n"
2516 "%tesse2_label = OpLabel\n"
2517 "%tesse2_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
2518 "%tesse2_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
2519 "%tesse2_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
2520 "%tesse2_tc_0 = OpLoad %f32 %tesse2_tc_0_ptr\n"
2521 "%tesse2_tc_1 = OpLoad %f32 %tesse2_tc_1_ptr\n"
2522 "%tesse2_tc_2 = OpLoad %f32 %tesse2_tc_2_ptr\n"
2523 "%tesse2_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
2524 "%tesse2_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
2525 "%tesse2_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
2526 "%tesse2_in_pos_0 = OpLoad %v4f32 %tesse2_in_pos_0_ptr\n"
2527 "%tesse2_in_pos_1 = OpLoad %v4f32 %tesse2_in_pos_1_ptr\n"
2528 "%tesse2_in_pos_2 = OpLoad %v4f32 %tesse2_in_pos_2_ptr\n"
2529 "%tesse2_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_0 %tesse2_tc_0\n"
2530 "%tesse2_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_1 %tesse2_tc_1\n"
2531 "%tesse2_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_2 %tesse2_tc_2\n"
2532 "%tesse2_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
2533 "%tesse2_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse2_in_pos_0_weighted %tesse2_in_pos_1_weighted\n"
2534 "%tesse2_computed_out = OpFAdd %v4f32 %tesse2_in_pos_0_plus_pos_1 %tesse2_in_pos_2_weighted\n"
2535 "OpStore %tesse2_out_pos_ptr %tesse2_computed_out\n"
2536 "%tesse2_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
2537 "%tesse2_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
2538 "%tesse2_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
2539 "%tesse2_in_clr_0 = OpLoad %v4f32 %tesse2_in_clr_0_ptr\n"
2540 "%tesse2_in_clr_1 = OpLoad %v4f32 %tesse2_in_clr_1_ptr\n"
2541 "%tesse2_in_clr_2 = OpLoad %v4f32 %tesse2_in_clr_2_ptr\n"
2542 "%tesse2_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_0 %tesse2_tc_0\n"
2543 "%tesse2_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_1 %tesse2_tc_1\n"
2544 "%tesse2_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_2 %tesse2_tc_2\n"
2545 "%tesse2_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse2_in_clr_0_weighted %tesse2_in_clr_1_weighted\n"
2546 "%tesse2_computed_clr = OpFAdd %v4f32 %tesse2_in_clr_0_plus_col_1 %tesse2_in_clr_2_weighted\n"
2547 "%tesse2_clr_transformed = OpFSub %v4f32 %cval %tesse2_computed_clr\n"
2548 "%tesse2_clr_transformed_a = OpVectorInsertDynamic %v4f32 %tesse2_clr_transformed %c_f32_1 %c_i32_3\n"
2549 "OpStore %out_color %tesse2_clr_transformed_a\n"
2554 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
2556 // We only support RTE, RTZ, or both.
2557 DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);
2559 const Float32 originalFloat (original);
2560 const Float16 returnedFloat (returned);
2562 // Zero are turned into zero under both RTE and RTZ.
2563 if (originalFloat.isZero())
2565 if (returnedFloat.isZero())
2568 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2572 // Any denormalized value input into a shader may be flushed to 0.
2573 if (originalFloat.isDenorm() && returnedFloat.isZero())
2576 // Inf are always turned into Inf with the same sign, too.
2577 if (originalFloat.isInf())
2579 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2582 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2586 // NaN are always turned into NaN, too.
2587 if (originalFloat.isNaN())
2589 if (returnedFloat.isNaN())
2592 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2596 // Check all rounding modes
2597 for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
2599 if ((flags & (1u << bitNdx)) == 0)
2600 continue; // This rounding mode is not selected.
2602 const Float16 expectedFloat (deFloat32To16Round(original, deRoundingMode(bitNdx)));
2604 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2605 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2608 // If not matched in the above cases, they should have the same bit pattern.
2609 if (expectedFloat.bits() == returnedFloat.bits())
2613 log << TestLog::Message << "Error: found unmatched 32-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
2617 bool compare16BitFloat (deUint16 original, deUint16 returned, tcu::TestLog& log)
2619 const Float16 originalFloat (original);
2620 const Float16 returnedFloat (returned);
2622 if (originalFloat.isZero())
2624 if (returnedFloat.isZero())
2627 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2631 // Any denormalized value input into a shader or potentially generated by any instruction in a shader
2632 // may be flushed to 0.
2633 if (originalFloat.isDenorm() && returnedFloat.isZero())
2636 // Inf are always turned into Inf with the same sign, too.
2637 if (originalFloat.isInf())
2639 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2642 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2646 // NaN are always turned into NaN, too.
2647 if (originalFloat.isNaN())
2649 if (returnedFloat.isNaN())
2652 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2656 // If not matched in the above cases, they should have the same bit pattern.
2657 if (originalFloat.bits() == returnedFloat.bits())
2660 log << TestLog::Message << "Error: found unmatched 16-bit and 16-bit floats: " << original << " vs " << returned << TestLog::EndMessage;
2664 bool compare16BitFloat(deUint16 original, float returned, tcu::TestLog & log)
2666 const Float16 originalFloat (original);
2667 const Float32 returnedFloat (returned);
2669 // Zero are turned into zero under both RTE and RTZ.
2670 if (originalFloat.isZero())
2672 if (returnedFloat.isZero())
2675 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2679 // Any denormalized value input into a shader may be flushed to 0.
2680 if (originalFloat.isDenorm() && returnedFloat.isZero())
2683 // Inf are always turned into Inf with the same sign, too.
2684 if (originalFloat.isInf())
2686 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2689 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2693 // NaN are always turned into NaN, too.
2694 if (originalFloat.isNaN())
2696 if (returnedFloat.isNaN())
2699 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2703 // In all other cases, conversion should be exact.
2704 const Float32 expectedFloat (deFloat16To32(original));
2705 if (expectedFloat.bits() == returnedFloat.bits())
2708 log << TestLog::Message << "Error: found unmatched 16-bit and 32-bit floats: " << original << " vs " << returnedFloat.bits() << TestLog::EndMessage;
2712 bool compare16BitFloat (deFloat16 original, deFloat16 returned, std::string& error)
2714 std::ostringstream log;
2715 const Float16 originalFloat (original);
2716 const Float16 returnedFloat (returned);
2718 if (originalFloat.isZero())
2720 if (returnedFloat.isZero())
2723 log << "Error: expected zero but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
2728 // Any denormalized value input into a shader may be flushed to 0.
2729 if (originalFloat.isDenorm() && returnedFloat.isZero())
2732 // Inf are always turned into Inf with the same sign, too.
2733 if (originalFloat.isInf())
2735 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2738 log << "Error: expected Inf but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
2743 // NaN are always turned into NaN, too.
2744 if (originalFloat.isNaN())
2746 if (returnedFloat.isNaN())
2749 log << "Error: expected NaN but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
2754 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2755 if (originalFloat.isDenorm() && returnedFloat.isZero())
2758 // If not matched in the above cases, they should have the same bit pattern.
2759 if (originalFloat.bits() == returnedFloat.bits())
2762 log << "Error: found unmatched 16-bit and 16-bit floats: 0x"
2763 << std::hex << original << " <=> 0x" << returned
2764 << " (" << originalFloat.asFloat() << " <=> " << returnedFloat.asFloat() << ")";
2769 bool compare16BitFloat64 (double original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
2771 // We only support RTE, RTZ, or both.
2772 DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);
2774 const Float64 originalFloat (original);
2775 const Float16 returnedFloat (returned);
2777 // Zero are turned into zero under both RTE and RTZ.
2778 if (originalFloat.isZero())
2780 if (returnedFloat.isZero())
2783 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2787 // Any denormalized value input into a shader may be flushed to 0.
2788 if (originalFloat.isDenorm() && returnedFloat.isZero())
2791 // Inf are always turned into Inf with the same sign, too.
2792 if (originalFloat.isInf())
2794 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2797 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2801 // NaN are always turned into NaN, too.
2802 if (originalFloat.isNaN())
2804 if (returnedFloat.isNaN())
2807 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2811 // Check all rounding modes
2812 for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
2814 if ((flags & (1u << bitNdx)) == 0)
2815 continue; // This rounding mode is not selected.
2817 const Float16 expectedFloat (deFloat64To16Round(original, deRoundingMode(bitNdx)));
2819 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2820 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2823 // If not matched in the above cases, they should have the same bit pattern.
2824 if (expectedFloat.bits() == returnedFloat.bits())
2828 log << TestLog::Message << "Error: found unmatched 64-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
2832 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log)
2834 const Float32 expectedFloat (expected);
2835 const Float32 returnedFloat (returned);
2837 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2838 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2842 const Float16 originalFloat (deFloat32To16(expected));
2844 // Any denormalized value input into a shader may be flushed to 0.
2845 if (originalFloat.isDenorm() && returnedFloat.isZero())
2849 if (expectedFloat.isNaN())
2851 if (returnedFloat.isNaN())
2854 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2858 if (returned == expected)
2861 log << TestLog::Message << "Error: found unmatched 32-bit float: expected " << expectedFloat.bits() << " vs. returned " << returnedFloat.bits() << TestLog::EndMessage;
2865 bool compare64BitFloat (double expected, double returned, tcu::TestLog& log)
2867 const Float64 expectedDouble (expected);
2868 const Float64 returnedDouble (returned);
2870 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2871 if (expectedDouble.isDenorm() && returnedDouble.isZero())
2875 const Float16 originalDouble (deFloat64To16(expected));
2877 // Any denormalized value input into a shader may be flushed to 0.
2878 if (originalDouble.isDenorm() && returnedDouble.isZero())
2882 if (expectedDouble.isNaN())
2884 if (returnedDouble.isNaN())
2887 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2891 if (returned == expected)
2894 log << TestLog::Message << "Error: found unmatched 64-bit float: expected " << expectedDouble.bits() << " vs. returned " << returnedDouble.bits() << TestLog::EndMessage;
2898 Move<VkBuffer> createBufferForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex)
2900 const vk::VkDescriptorType resourceType = resource.getDescriptorType();
2902 vector<deUint8> resourceBytes;
2903 resource.getBytes(resourceBytes);
2905 const VkBufferCreateInfo resourceBufferParams =
2907 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
2909 (VkBufferCreateFlags)0, // flags
2910 (VkDeviceSize)resourceBytes.size(), // size
2911 (VkBufferUsageFlags)getMatchingBufferUsageFlagBit(resourceType), // usage
2912 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2913 1u, // queueFamilyCount
2914 &queueFamilyIndex, // pQueueFamilyIndices
2917 return createBuffer(vk, vkDevice, &resourceBufferParams);
2920 Move<VkImage> createImageForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, VkFormat inputFormat, deUint32 queueFamilyIndex)
2922 const VkImageCreateInfo resourceImageParams =
2924 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2925 DE_NULL, // const void* pNext;
2926 0u, // VkImageCreateFlags flags;
2927 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2928 inputFormat, // VkFormat format;
2929 { 8, 8, 1 }, // VkExtent3D extent;
2930 1u, // deUint32 mipLevels;
2931 1u, // deUint32 arraySize;
2932 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2933 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2934 getMatchingImageUsageFlags(resource.getDescriptorType()), // VkImageUsageFlags usage;
2935 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2936 1u, // deUint32 queueFamilyCount;
2937 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2938 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2941 return createImage(vk, vkDevice, &resourceImageParams);
2944 void copyBufferToImage (const DeviceInterface& vk, const VkDevice& device, const VkQueue& queue, VkCommandBuffer cmdBuffer, VkBuffer buffer, VkImage image, VkImageAspectFlags aspect)
2946 const VkBufferImageCopy copyRegion =
2948 0u, // VkDeviceSize bufferOffset;
2949 0u, // deUint32 bufferRowLength;
2950 0u, // deUint32 bufferImageHeight;
2952 aspect, // VkImageAspectFlags aspect;
2953 0u, // deUint32 mipLevel;
2954 0u, // deUint32 baseArrayLayer;
2955 1u, // deUint32 layerCount;
2956 }, // VkImageSubresourceLayers imageSubresource;
2957 { 0, 0, 0 }, // VkOffset3D imageOffset;
2958 { 8, 8, 1 } // VkExtent3D imageExtent;
2961 // Copy buffer to image
2962 beginCommandBuffer(vk, cmdBuffer);
2964 copyBufferToImage(vk, cmdBuffer, buffer, VK_WHOLE_SIZE, vector<VkBufferImageCopy>(1, copyRegion), aspect, 1u, 1u, image, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
2966 endCommandBuffer(vk, cmdBuffer);
2968 submitCommandsAndWait(vk, device, queue, cmdBuffer);
2971 VkImageAspectFlags getImageAspectFlags (VkFormat format)
2973 const tcu::TextureFormat::ChannelOrder channelOrder = vk::mapVkFormat(format).order;
2974 VkImageAspectFlags aspectFlags = (VkImageAspectFlags)0u;
2976 if (tcu::hasDepthComponent(channelOrder))
2977 aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
2979 if (tcu::hasStencilComponent(channelOrder))
2980 aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
2983 aspectFlags |= VK_IMAGE_ASPECT_COLOR_BIT;
2988 TestStatus runAndVerifyUnusedVariablePipeline (Context &context, UnusedVariableContext unusedVariableContext)
2990 return runAndVerifyDefaultPipeline(context, unusedVariableContext.instanceContext);
2993 TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance)
2995 if (getMinRequiredVulkanVersion(instance.resources.spirvVersion) > context.getUsedApiVersion())
2997 TCU_THROW(NotSupportedError, string("Vulkan higher than or equal to " + getVulkanName(getMinRequiredVulkanVersion(instance.resources.spirvVersion)) + " is required for this test to run").c_str());
3000 const DeviceInterface& vk = context.getDeviceInterface();
3001 const InstanceInterface& vkInstance = context.getInstanceInterface();
3002 const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice();
3003 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
3004 const VkQueue queue = context.getUniversalQueue();
3005 const VkDevice& device = context.getDevice();
3006 Allocator& allocator = context.getDefaultAllocator();
3007 vector<ModuleHandleSp> modules;
3008 map<VkShaderStageFlagBits, VkShaderModule> moduleByStage;
3009 const tcu::UVec2 renderSize (256, 256);
3010 const int testSpecificSeed = 31354125;
3011 const int seed = context.getTestContext().getCommandLine().getBaseSeed() ^ testSpecificSeed;
3012 bool supportsGeometry = false;
3013 bool supportsTessellation = false;
3014 bool hasGeometry = false;
3015 bool hasTessellation = false;
3016 const bool hasPushConstants = !instance.pushConstants.empty();
3017 const deUint32 numResources = static_cast<deUint32>(instance.resources.inputs.size() + instance.resources.outputs.size());
3018 const bool needInterface = !instance.interfaces.empty();
3019 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
3020 const Vec4 defaulClearColor (0.125f, 0.25f, 0.75f, 1.0f);
3022 supportsGeometry = features.geometryShader == VK_TRUE;
3023 supportsTessellation = features.tessellationShader == VK_TRUE;
3024 hasGeometry = (instance.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT);
3025 hasTessellation = (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) ||
3026 (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
3028 if (hasGeometry && !supportsGeometry)
3030 TCU_THROW(NotSupportedError, "Geometry not supported");
3033 if (hasTessellation && !supportsTessellation)
3035 TCU_THROW(NotSupportedError, "Tessellation not supported");
3038 // Check all required extensions are supported
3039 for (std::vector<std::string>::const_iterator i = instance.requiredDeviceExtensions.begin(); i != instance.requiredDeviceExtensions.end(); ++i)
3041 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), *i))
3042 TCU_THROW(NotSupportedError, (std::string("Extension not supported: ") + *i).c_str());
3047 const VkShaderStageFlags vertexPipelineStoresAndAtomicsAffected = vk::VK_SHADER_STAGE_VERTEX_BIT
3048 | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
3049 | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
3050 | vk::VK_SHADER_STAGE_GEOMETRY_BIT;
3051 const char* unsupportedFeature = DE_NULL;
3052 vk::VkPhysicalDeviceFeatures localRequiredCoreFeatures = instance.requestedFeatures.coreFeatures;
3054 // reset fragment stores and atomics feature requirement
3055 if ((localRequiredCoreFeatures.fragmentStoresAndAtomics != DE_FALSE) &&
3056 (instance.customizedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
3058 localRequiredCoreFeatures.fragmentStoresAndAtomics = DE_FALSE;
3061 // reset vertex pipeline stores and atomics feature requirement
3062 if (localRequiredCoreFeatures.vertexPipelineStoresAndAtomics != DE_FALSE &&
3063 (instance.customizedStages & vertexPipelineStoresAndAtomicsAffected) == 0)
3065 localRequiredCoreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
3068 if (!isCoreFeaturesSupported(context, localRequiredCoreFeatures, &unsupportedFeature))
3069 TCU_THROW(NotSupportedError, std::string("At least following requested core feature is not supported: ") + unsupportedFeature);
3072 // Extension features
3074 // 8bit storage features
3076 if (!is8BitStorageFeaturesSupported(context, instance.requestedFeatures.ext8BitStorage))
3077 TCU_THROW(NotSupportedError, "Requested 8bit storage features not supported");
3080 // 16bit storage features
3082 if (!is16BitStorageFeaturesSupported(context, instance.requestedFeatures.ext16BitStorage))
3083 TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
3086 // Variable Pointers features
3088 if (!isVariablePointersFeaturesSupported(context, instance.requestedFeatures.extVariablePointers))
3089 TCU_THROW(NotSupportedError, "Requested Variable Pointer features not supported");
3092 // Float16/Int8 shader features
3094 if (!isFloat16Int8FeaturesSupported(context, instance.requestedFeatures.extFloat16Int8))
3095 TCU_THROW(NotSupportedError, "Requested 16bit float or 8bit int feature not supported");
3099 // FloatControls features
3101 if (!isFloatControlsFeaturesSupported(context, instance.requestedFeatures.floatControlsProperties))
3102 TCU_THROW(NotSupportedError, "Requested Float Controls features not supported");
3105 // Check Interface Input/Output formats are supported
3108 VkFormatProperties formatProperties;
3109 vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getInputType().getVkFormat(), &formatProperties);
3110 if ((formatProperties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0)
3112 std::string error = "Interface Input format (";
3113 const std::string formatName = getFormatName(instance.interfaces.getInputType().getVkFormat());
3114 error += formatName + ") not supported";
3115 TCU_THROW(NotSupportedError, error.c_str());
3118 vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getOutputType().getVkFormat(), &formatProperties);
3119 if (((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) ||
3120 ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0))
3122 std::string error = "Interface Output format (";
3123 const std::string formatName = getFormatName(instance.interfaces.getInputType().getVkFormat());
3124 error += formatName + ") not supported";
3125 TCU_THROW(NotSupportedError, error.c_str());
3129 de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4);
3130 de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4);
3131 const Vec4 vertexData[] =
3133 // Upper left corner:
3134 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //1
3135 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //2
3136 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //3
3138 // Upper right corner:
3139 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //4
3140 Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //5
3141 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //6
3143 // Lower left corner:
3144 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //7
3145 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //8
3146 Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //9
3148 // Lower right corner:
3149 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //10
3150 Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //11
3151 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //12
3153 // The rest is used only renderFullSquare specified. Fills area already filled with clear color
3155 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //3
3156 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2
3157 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //7
3160 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //7
3161 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2
3162 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8
3165 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8
3166 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2
3167 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4
3170 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4
3171 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12
3172 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8
3175 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4
3176 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //6
3177 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12
3180 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12
3181 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //6
3182 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //10
3185 const size_t singleVertexDataSize = 2 * sizeof(Vec4);
3186 const size_t vertexCount = instance.renderFullSquare ? sizeof(vertexData) / singleVertexDataSize : 4*3;
3187 const size_t vertexDataSize = vertexCount * singleVertexDataSize;
3189 Move<VkBuffer> vertexInputBuffer;
3190 de::MovePtr<Allocation> vertexInputMemory;
3191 Move<VkBuffer> fragOutputBuffer;
3192 de::MovePtr<Allocation> fragOutputMemory;
3193 Move<VkImage> fragOutputImage;
3194 de::MovePtr<Allocation> fragOutputImageMemory;
3195 Move<VkImageView> fragOutputImageView;
3197 const VkBufferCreateInfo vertexBufferParams =
3199 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3200 DE_NULL, // const void* pNext;
3201 0u, // VkBufferCreateFlags flags;
3202 (VkDeviceSize)vertexDataSize, // VkDeviceSize size;
3203 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
3204 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3205 1u, // deUint32 queueFamilyCount;
3206 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3208 const Unique<VkBuffer> vertexBuffer (createBuffer(vk, device, &vertexBufferParams));
3209 const UniquePtr<Allocation> vertexBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexBuffer), MemoryRequirement::HostVisible));
3211 VK_CHECK(vk.bindBufferMemory(device, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
3213 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
3214 const VkBufferCreateInfo readImageBufferParams =
3216 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3217 DE_NULL, // const void* pNext;
3218 0u, // VkBufferCreateFlags flags;
3219 imageSizeBytes, // VkDeviceSize size;
3220 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
3221 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3222 1u, // deUint32 queueFamilyCount;
3223 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3225 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, device, &readImageBufferParams));
3226 const UniquePtr<Allocation> readImageBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible));
3228 VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
3230 VkImageCreateInfo imageParams =
3232 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3233 DE_NULL, // const void* pNext;
3234 0u, // VkImageCreateFlags flags;
3235 VK_IMAGE_TYPE_2D, // VkImageType imageType;
3236 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
3237 { renderSize.x(), renderSize.y(), 1 }, // VkExtent3D extent;
3238 1u, // deUint32 mipLevels;
3239 1u, // deUint32 arraySize;
3240 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3241 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3242 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
3243 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3244 1u, // deUint32 queueFamilyCount;
3245 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3246 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3249 const Unique<VkImage> image (createImage(vk, device, &imageParams));
3250 const UniquePtr<Allocation> imageMemory (allocator.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any));
3252 VK_CHECK(vk.bindImageMemory(device, *image, imageMemory->getMemory(), imageMemory->getOffset()));
3256 // The pipeline renders four triangles, each with three vertexes.
3257 // Test instantialization only provides four data points, each
3258 // for one triangle. So we need allocate space of three times of
3259 // input buffer's size.
3260 vector<deUint8> inputBufferBytes;
3261 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3263 const deUint32 inputNumBytes = deUint32(inputBufferBytes.size() * 3);
3264 // Create an additional buffer and backing memory for one input variable.
3265 const VkBufferCreateInfo vertexInputParams =
3267 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3268 DE_NULL, // const void* pNext;
3269 0u, // VkBufferCreateFlags flags;
3270 inputNumBytes, // VkDeviceSize size;
3271 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
3272 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3273 1u, // deUint32 queueFamilyCount;
3274 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3277 vertexInputBuffer = createBuffer(vk, device, &vertexInputParams);
3278 vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexInputBuffer), MemoryRequirement::HostVisible);
3279 VK_CHECK(vk.bindBufferMemory(device, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset()));
3281 // Create an additional buffer and backing memory for an output variable.
3282 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
3283 const VkBufferCreateInfo fragOutputParams =
3285 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
3286 DE_NULL, // const void* pNext;
3287 0u, // VkBufferCreateFlags flags;
3288 fragOutputImgSize, // VkDeviceSize size;
3289 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
3290 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3291 1u, // deUint32 queueFamilyCount;
3292 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3294 fragOutputBuffer = createBuffer(vk, device, &fragOutputParams);
3295 fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *fragOutputBuffer), MemoryRequirement::HostVisible);
3296 VK_CHECK(vk.bindBufferMemory(device, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset()));
3298 // Create an additional image and backing memory for attachment.
3299 // Reuse the previous imageParams since we only need to change the image format.
3300 imageParams.format = instance.interfaces.getOutputType().getVkFormat();
3302 // Check the usage bits on the given image format are supported.
3303 requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.tiling, imageParams.usage);
3305 fragOutputImage = createImage(vk, device, &imageParams);
3306 fragOutputImageMemory = allocator.allocate(getImageMemoryRequirements(vk, device, *fragOutputImage), MemoryRequirement::Any);
3308 VK_CHECK(vk.bindImageMemory(device, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset()));
3311 vector<VkAttachmentDescription> colorAttDescs;
3312 vector<VkAttachmentReference> colorAttRefs;
3314 const VkAttachmentDescription attDesc =
3316 0u, // VkAttachmentDescriptionFlags flags;
3317 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
3318 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3319 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
3320 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3321 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3322 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3323 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3324 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
3326 colorAttDescs.push_back(attDesc);
3328 const VkAttachmentReference attRef =
3330 0u, // deUint32 attachment;
3331 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
3333 colorAttRefs.push_back(attRef);
3338 const VkAttachmentDescription attDesc =
3340 0u, // VkAttachmentDescriptionFlags flags;
3341 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
3342 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3343 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
3344 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3345 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3346 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3347 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3348 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
3350 colorAttDescs.push_back(attDesc);
3352 const VkAttachmentReference attRef =
3354 1u, // deUint32 attachment;
3355 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
3357 colorAttRefs.push_back(attRef);
3360 VkSubpassDescription subpassDesc =
3362 0u, // VkSubpassDescriptionFlags flags;
3363 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
3364 0u, // deUint32 inputCount;
3365 DE_NULL, // const VkAttachmentReference* pInputAttachments;
3366 1u, // deUint32 colorCount;
3367 colorAttRefs.data(), // const VkAttachmentReference* pColorAttachments;
3368 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
3369 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
3370 0u, // deUint32 preserveCount;
3371 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
3374 VkRenderPassCreateInfo renderPassParams =
3376 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
3377 DE_NULL, // const void* pNext;
3378 (VkRenderPassCreateFlags)0,
3379 1u, // deUint32 attachmentCount;
3380 colorAttDescs.data(), // const VkAttachmentDescription* pAttachments;
3381 1u, // deUint32 subpassCount;
3382 &subpassDesc, // const VkSubpassDescription* pSubpasses;
3383 0u, // deUint32 dependencyCount;
3384 DE_NULL, // const VkSubpassDependency* pDependencies;
3389 subpassDesc.colorAttachmentCount += 1;
3390 renderPassParams.attachmentCount += 1;
3393 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, &renderPassParams));
3395 const VkImageViewCreateInfo colorAttViewParams =
3397 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3398 DE_NULL, // const void* pNext;
3399 0u, // VkImageViewCreateFlags flags;
3400 *image, // VkImage image;
3401 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3402 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
3404 VK_COMPONENT_SWIZZLE_R,
3405 VK_COMPONENT_SWIZZLE_G,
3406 VK_COMPONENT_SWIZZLE_B,
3407 VK_COMPONENT_SWIZZLE_A
3408 }, // VkChannelMapping channels;
3410 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
3411 0u, // deUint32 baseMipLevel;
3412 1u, // deUint32 mipLevels;
3413 0u, // deUint32 baseArrayLayer;
3414 1u, // deUint32 arraySize;
3415 }, // VkImageSubresourceRange subresourceRange;
3417 const Unique<VkImageView> colorAttView (createImageView(vk, device, &colorAttViewParams));
3418 const VkImageAspectFlags inputImageAspect = getImageAspectFlags(instance.resources.inputFormat);
3420 vector<VkImageView> attViews;
3421 attViews.push_back(*colorAttView);
3423 // Handle resources requested by the test instantiation.
3424 const deUint32 numInResources = static_cast<deUint32>(instance.resources.inputs.size());
3425 const deUint32 numOutResources = static_cast<deUint32>(instance.resources.outputs.size());
3426 // These variables should be placed out of the following if block to avoid deallocation after out of scope.
3427 vector<AllocationSp> inResourceMemories;
3428 vector<AllocationSp> outResourceMemories;
3429 vector<BufferHandleSp> inResourceBuffers;
3430 vector<BufferHandleSp> outResourceBuffers;
3431 vector<ImageHandleSp> inResourceImages;
3432 vector<ImageViewHandleSp> inResourceImageViews;
3433 vector<SamplerHandleSp> inResourceSamplers;
3434 Move<VkDescriptorPool> descriptorPool;
3435 Move<VkDescriptorSetLayout> setLayout;
3436 VkDescriptorSetLayout rawSetLayout = DE_NULL;
3437 VkDescriptorSet rawSet = DE_NULL;
3439 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
3442 const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3444 if (numResources != 0)
3446 vector<VkDescriptorSetLayoutBinding> setLayoutBindings;
3447 vector<VkDescriptorPoolSize> poolSizes;
3449 setLayoutBindings.reserve(numResources);
3450 poolSizes.reserve(numResources);
3452 // Process all input resources.
3453 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
3455 const Resource& resource = instance.resources.inputs[inputNdx];
3457 const bool hasImage = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
3458 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
3459 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3461 const bool hasSampler = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
3462 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER) ||
3463 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3465 // Resource is a buffer
3466 if (!hasImage && !hasSampler)
3468 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex);
3469 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
3471 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
3473 // Copy data to memory.
3475 const VkMappedMemoryRange range =
3477 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3478 DE_NULL, // const void* pNext;
3479 resourceMemory->getMemory(), // VkDeviceMemory mem;
3480 0, // VkDeviceSize offset;
3481 VK_WHOLE_SIZE, // VkDeviceSize size;
3484 vector<deUint8> resourceBytes;
3485 resource.getBytes(resourceBytes);
3487 deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
3488 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3491 inResourceMemories.push_back(AllocationSp(resourceMemory.release()));
3492 inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
3494 // Resource is an image
3497 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex);
3498 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
3500 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
3502 // Copy data to memory.
3504 const VkMappedMemoryRange range =
3506 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3507 DE_NULL, // const void* pNext;
3508 resourceMemory->getMemory(), // VkDeviceMemory mem;
3509 0, // VkDeviceSize offset;
3510 VK_WHOLE_SIZE, // VkDeviceSize size;
3513 vector<deUint8> resourceBytes;
3514 resource.getBytes(resourceBytes);
3516 deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
3517 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3520 Move<VkImage> resourceImage = createImageForResource(vk, device, resource, instance.resources.inputFormat, queueFamilyIndex);
3521 de::MovePtr<Allocation> resourceImageMemory = allocator.allocate(getImageMemoryRequirements(vk, device, *resourceImage), MemoryRequirement::Any);
3523 VK_CHECK(vk.bindImageMemory(device, *resourceImage, resourceImageMemory->getMemory(), resourceImageMemory->getOffset()));
3525 copyBufferToImage(vk, device, queue, *cmdBuf, resourceBuffer.get(), resourceImage.get(), inputImageAspect);
3527 inResourceMemories.push_back(AllocationSp(resourceImageMemory.release()));
3528 inResourceImages.push_back(ImageHandleSp(new ImageHandleUp(resourceImage)));
3531 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
3532 const VkDescriptorSetLayoutBinding binding =
3534 inputNdx, // binding
3535 resource.getDescriptorType(), // descriptorType
3536 1u, // descriptorCount
3537 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
3538 DE_NULL, // pImmutableSamplers
3540 setLayoutBindings.push_back(binding);
3542 // Note: the following code doesn't check and unify descriptors of the same type.
3543 const VkDescriptorPoolSize poolSize =
3545 resource.getDescriptorType(), // type
3546 1u, // descriptorCount
3548 poolSizes.push_back(poolSize);
3551 // Process all output resources.
3552 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3554 const Resource& resource = instance.resources.outputs[outputNdx];
3555 // Create buffer and allocate memory.
3556 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex);
3557 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
3558 vector<deUint8> resourceBytes;
3560 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
3562 // Fill memory with all ones.
3563 const VkMappedMemoryRange range =
3565 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3566 DE_NULL, // const void* pNext;
3567 resourceMemory->getMemory(), // VkDeviceMemory mem;
3568 0, // VkDeviceSize offset;
3569 VK_WHOLE_SIZE, // VkDeviceSize size;
3572 resource.getBytes(resourceBytes);
3573 deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resourceBytes.size());
3574 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3576 outResourceMemories.push_back(AllocationSp(resourceMemory.release()));
3577 outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
3579 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
3580 const VkDescriptorSetLayoutBinding binding =
3582 numInResources + outputNdx, // binding
3583 resource.getDescriptorType(), // descriptorType
3584 1u, // descriptorCount
3585 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
3586 DE_NULL, // pImmutableSamplers
3588 setLayoutBindings.push_back(binding);
3590 // Note: the following code doesn't check and unify descriptors of the same type.
3591 const VkDescriptorPoolSize poolSize =
3593 resource.getDescriptorType(), // type
3594 1u, // descriptorCount
3596 poolSizes.push_back(poolSize);
3599 // Create descriptor set layout, descriptor pool, and allocate descriptor set.
3600 const VkDescriptorSetLayoutCreateInfo setLayoutParams =
3602 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
3604 (VkDescriptorSetLayoutCreateFlags)0, // flags
3605 numResources, // bindingCount
3606 setLayoutBindings.data(), // pBindings
3608 setLayout = createDescriptorSetLayout(vk, device, &setLayoutParams);
3609 rawSetLayout = *setLayout;
3611 const VkDescriptorPoolCreateInfo poolParams =
3613 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
3615 (VkDescriptorPoolCreateFlags)0, // flags
3617 numResources, // poolSizeCount
3618 poolSizes.data(), // pPoolSizes
3620 descriptorPool = createDescriptorPool(vk, device, &poolParams);
3622 const VkDescriptorSetAllocateInfo setAllocParams =
3624 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
3626 *descriptorPool, // descriptorPool
3627 1u, // descriptorSetCount
3628 &rawSetLayout, // pSetLayouts
3630 VK_CHECK(vk.allocateDescriptorSets(device, &setAllocParams, &rawSet));
3632 // Update descriptor set.
3633 vector<VkWriteDescriptorSet> writeSpecs;
3634 vector<VkDescriptorBufferInfo> dBufferInfos;
3635 vector<VkDescriptorImageInfo> dImageInfos;
3637 writeSpecs.reserve(numResources);
3638 dBufferInfos.reserve(numResources);
3639 dImageInfos.reserve(numResources);
3641 deUint32 imgResourceNdx = 0u;
3642 deUint32 bufResourceNdx = 0u;
3644 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
3646 const Resource& resource = instance.resources.inputs[inputNdx];
3648 const bool hasImage = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
3649 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
3650 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3652 const bool hasSampler = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
3653 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER) ||
3654 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3656 // Create image view and sampler
3657 if (hasImage || hasSampler)
3659 if (resource.getDescriptorType() != VK_DESCRIPTOR_TYPE_SAMPLER)
3661 const VkImageViewCreateInfo imgViewParams =
3663 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3664 DE_NULL, // const void* pNext;
3665 0u, // VkImageViewCreateFlags flags;
3666 **inResourceImages[imgResourceNdx++], // VkImage image;
3667 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3668 instance.resources.inputFormat, // VkFormat format;
3670 VK_COMPONENT_SWIZZLE_R,
3671 VK_COMPONENT_SWIZZLE_G,
3672 VK_COMPONENT_SWIZZLE_B,
3673 VK_COMPONENT_SWIZZLE_A
3674 }, // VkComponentMapping channels;
3676 inputImageAspect, // VkImageAspectFlags aspectMask;
3677 0u, // deUint32 baseMipLevel;
3678 1u, // deUint32 mipLevels;
3679 0u, // deUint32 baseArrayLayer;
3680 1u, // deUint32 arraySize;
3681 }, // VkImageSubresourceRange subresourceRange;
3684 Move<VkImageView> imgView (createImageView(vk, device, &imgViewParams));
3685 inResourceImageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imgView)));
3690 const bool hasDepthComponent = tcu::hasDepthComponent(vk::mapVkFormat(instance.resources.inputFormat).order);
3691 const VkSamplerCreateInfo samplerParams =
3693 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
3694 DE_NULL, // const void* pNext;
3695 0, // VkSamplerCreateFlags flags;
3696 VK_FILTER_NEAREST, // VkFilter magFilter:
3697 VK_FILTER_NEAREST, // VkFilter minFilter;
3698 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
3699 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
3700 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
3701 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
3702 0.0f, // float mipLodBias;
3703 VK_FALSE, // VkBool32 anistoropyEnable;
3704 1.0f, // float maxAnisotropy;
3705 (hasDepthComponent) ? VK_TRUE : VK_FALSE, // VkBool32 compareEnable;
3706 VK_COMPARE_OP_LESS, // VkCompareOp compareOp;
3707 0.0f, // float minLod;
3708 0.0f, // float maxLod;
3709 VK_BORDER_COLOR_INT_OPAQUE_BLACK, // VkBorderColor borderColor;
3710 VK_FALSE // VkBool32 unnormalizedCoordinates;
3713 Move<VkSampler> sampler (createSampler(vk, device, &samplerParams));
3714 inResourceSamplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler)));
3718 // Create descriptor buffer and image infos
3719 switch (resource.getDescriptorType())
3721 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3722 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3724 const VkDescriptorBufferInfo bufInfo =
3726 **inResourceBuffers[bufResourceNdx++], // buffer
3728 VK_WHOLE_SIZE, // size
3730 dBufferInfos.push_back(bufInfo);
3733 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3734 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3736 const VkDescriptorImageInfo imgInfo =
3739 **inResourceImageViews.back(), // imageView
3740 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3742 dImageInfos.push_back(imgInfo);
3745 case VK_DESCRIPTOR_TYPE_SAMPLER:
3747 const VkDescriptorImageInfo imgInfo =
3749 **inResourceSamplers.back(), // sampler
3750 DE_NULL, // imageView
3751 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3753 dImageInfos.push_back(imgInfo);
3756 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3759 const VkDescriptorImageInfo imgInfo =
3761 **inResourceSamplers.back(), // sampler
3762 **inResourceImageViews.back(), // imageView
3763 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3765 dImageInfos.push_back(imgInfo);
3769 DE_FATAL("Not implemented");
3772 const VkWriteDescriptorSet writeSpec = {
3773 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3776 inputNdx, // binding
3777 0, // dstArrayElement
3778 1u, // descriptorCount
3779 instance.resources.inputs[inputNdx].getDescriptorType(), // descriptorType
3780 ( (hasImage | hasSampler) ? &dImageInfos.back() : DE_NULL), // pImageInfo
3781 (!(hasImage | hasSampler) ? &dBufferInfos.back() : DE_NULL), // pBufferInfo
3782 DE_NULL, // pTexelBufferView
3784 writeSpecs.push_back(writeSpec);
3787 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3789 const VkDescriptorBufferInfo bufInfo =
3791 **outResourceBuffers[outputNdx], // buffer
3793 VK_WHOLE_SIZE, // size
3795 dBufferInfos.push_back(bufInfo);
3797 const VkWriteDescriptorSet writeSpec = {
3798 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3801 numInResources + outputNdx, // binding
3802 0, // dstArrayElement
3803 1u, // descriptorCount
3804 instance.resources.outputs[outputNdx].getDescriptorType(), // descriptorType
3805 DE_NULL, // pImageInfo
3806 &dBufferInfos.back(), // pBufferInfo
3807 DE_NULL, // pTexelBufferView
3809 writeSpecs.push_back(writeSpec);
3811 vk.updateDescriptorSets(device, numResources, writeSpecs.data(), 0, DE_NULL);
3815 VkPipelineLayoutCreateInfo pipelineLayoutParams =
3817 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3818 DE_NULL, // const void* pNext;
3819 (VkPipelineLayoutCreateFlags)0,
3820 0u, // deUint32 descriptorSetCount;
3821 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
3822 0u, // deUint32 pushConstantRangeCount;
3823 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
3826 VkPushConstantRange pushConstantRange =
3828 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags stageFlags;
3829 0, // uint32_t offset;
3830 0, // uint32_t size;
3832 if (hasPushConstants)
3834 vector<deUint8> pushConstantsBytes;
3835 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3837 pushConstantRange.size = static_cast<deUint32>(pushConstantsBytes.size());
3838 pipelineLayoutParams.pushConstantRangeCount = 1;
3839 pipelineLayoutParams.pPushConstantRanges = &pushConstantRange;
3841 if (numResources != 0)
3843 // Update pipeline layout with the descriptor set layout.
3844 pipelineLayoutParams.setLayoutCount = 1;
3845 pipelineLayoutParams.pSetLayouts = &rawSetLayout;
3847 const Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, device, &pipelineLayoutParams));
3850 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
3851 // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
3852 vector<vector<VkSpecializationMapEntry> > specConstantEntries;
3853 vector<VkSpecializationInfo> specializationInfos;
3854 if (DE_NULL != instance.resources.verifyBinary)
3856 std::string shaderName;
3857 switch(instance.customizedStages)
3859 case VK_SHADER_STAGE_VERTEX_BIT:
3862 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
3863 shaderName= "tessc";
3865 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
3866 shaderName= "tesse";
3868 case VK_SHADER_STAGE_GEOMETRY_BIT:
3871 case VK_SHADER_STAGE_FRAGMENT_BIT:
3878 const ProgramBinary& binary = context.getBinaryCollection().get(shaderName);
3879 if (!instance.resources.verifyBinary(binary))
3880 return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed");
3883 createPipelineShaderStages(vk, device, instance, context, modules, shaderStageParams);
3885 // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
3886 specConstantEntries.reserve(shaderStageParams.size());
3887 specializationInfos.reserve(shaderStageParams.size());
3889 // Patch the specialization info field in PipelineShaderStageCreateInfos.
3890 for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
3892 const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);
3894 if (stageIt != instance.specConstants.end())
3896 const size_t numSpecConstants = stageIt->second.getValuesCount();
3897 vector<VkSpecializationMapEntry> entries;
3898 VkSpecializationInfo specInfo;
3901 entries.resize(numSpecConstants);
3903 // Constant IDs are numbered sequentially starting from 0.
3904 for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
3906 const size_t valueSize = stageIt->second.getValueSize(ndx);
3908 entries[ndx].constantID = (deUint32)ndx;
3909 entries[ndx].offset = static_cast<deUint32>(offset);
3910 entries[ndx].size = valueSize;
3912 offset += valueSize;
3915 specConstantEntries.push_back(entries);
3917 specInfo.mapEntryCount = (deUint32)numSpecConstants;
3918 specInfo.pMapEntries = specConstantEntries.back().data();
3919 specInfo.dataSize = offset;
3920 specInfo.pData = stageIt->second.getValuesBuffer();
3921 specializationInfos.push_back(specInfo);
3923 stageInfo->pSpecializationInfo = &specializationInfos.back();
3926 const VkPipelineDepthStencilStateCreateInfo depthStencilParams =
3928 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
3929 DE_NULL, // const void* pNext;
3930 (VkPipelineDepthStencilStateCreateFlags)0,
3931 DE_FALSE, // deUint32 depthTestEnable;
3932 DE_FALSE, // deUint32 depthWriteEnable;
3933 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
3934 DE_FALSE, // deUint32 depthBoundsTestEnable;
3935 DE_FALSE, // deUint32 stencilTestEnable;
3937 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
3938 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
3939 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
3940 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
3941 0u, // deUint32 stencilCompareMask;
3942 0u, // deUint32 stencilWriteMask;
3943 0u, // deUint32 stencilReference;
3944 }, // VkStencilOpState front;
3946 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
3947 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
3948 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
3949 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
3950 0u, // deUint32 stencilCompareMask;
3951 0u, // deUint32 stencilWriteMask;
3952 0u, // deUint32 stencilReference;
3953 }, // VkStencilOpState back;
3954 -1.0f, // float minDepthBounds;
3955 +1.0f, // float maxDepthBounds;
3957 const VkViewport viewport0 = makeViewport(renderSize);
3958 const VkRect2D scissor0 = makeRect2D(renderSize);
3959 const VkPipelineViewportStateCreateInfo viewportParams =
3961 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
3962 DE_NULL, // const void* pNext;
3963 (VkPipelineViewportStateCreateFlags)0,
3964 1u, // deUint32 viewportCount;
3969 const VkSampleMask sampleMask = ~0u;
3970 const VkPipelineMultisampleStateCreateInfo multisampleParams =
3972 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
3973 DE_NULL, // const void* pNext;
3974 (VkPipelineMultisampleStateCreateFlags)0,
3975 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterSamples;
3976 DE_FALSE, // deUint32 sampleShadingEnable;
3977 0.0f, // float minSampleShading;
3978 &sampleMask, // const VkSampleMask* pSampleMask;
3979 DE_FALSE, // VkBool32 alphaToCoverageEnable;
3980 DE_FALSE, // VkBool32 alphaToOneEnable;
3982 const VkPipelineRasterizationStateCreateInfo rasterParams =
3984 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
3985 DE_NULL, // const void* pNext;
3986 (VkPipelineRasterizationStateCreateFlags)0,
3987 DE_FALSE, // deUint32 depthClampEnable;
3988 DE_FALSE, // deUint32 rasterizerDiscardEnable;
3989 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
3990 VK_CULL_MODE_NONE, // VkCullMode cullMode;
3991 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
3992 VK_FALSE, // VkBool32 depthBiasEnable;
3993 0.0f, // float depthBias;
3994 0.0f, // float depthBiasClamp;
3995 0.0f, // float slopeScaledDepthBias;
3996 1.0f, // float lineWidth;
3998 const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
3999 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyParams =
4001 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
4002 DE_NULL, // const void* pNext;
4003 (VkPipelineInputAssemblyStateCreateFlags)0,
4004 topology, // VkPrimitiveTopology topology;
4005 DE_FALSE, // deUint32 primitiveRestartEnable;
4008 vector<VkVertexInputBindingDescription> vertexBindings;
4009 vector<VkVertexInputAttributeDescription> vertexAttribs;
4011 const VkVertexInputBindingDescription vertexBinding0 =
4013 0u, // deUint32 binding;
4014 deUint32(singleVertexDataSize), // deUint32 strideInBytes;
4015 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
4017 vertexBindings.push_back(vertexBinding0);
4020 VkVertexInputAttributeDescription attr0 =
4022 0u, // deUint32 location;
4023 0u, // deUint32 binding;
4024 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
4025 0u // deUint32 offsetInBytes;
4027 vertexAttribs.push_back(attr0);
4029 VkVertexInputAttributeDescription attr1 =
4031 1u, // deUint32 location;
4032 0u, // deUint32 binding;
4033 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
4034 sizeof(Vec4), // deUint32 offsetInBytes;
4036 vertexAttribs.push_back(attr1);
4039 // If the test instantiation has additional input/output interface variables, we need to create additional bindings.
4040 // Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1
4041 // with location #2.
4044 const VkVertexInputBindingDescription vertexBinding1 =
4046 1u, // deUint32 binding;
4047 instance.interfaces.getInputType().getNumBytes(), // deUint32 strideInBytes;
4048 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
4050 vertexBindings.push_back(vertexBinding1);
4052 VkVertexInputAttributeDescription attr =
4054 2u, // deUint32 location;
4055 1u, // deUint32 binding;
4056 instance.interfaces.getInputType().getVkFormat(), // VkFormat format;
4057 0, // deUint32 offsetInBytes;
4059 vertexAttribs.push_back(attr);
4062 VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
4064 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
4065 DE_NULL, // const void* pNext;
4066 (VkPipelineVertexInputStateCreateFlags)0,
4067 1u, // deUint32 bindingCount;
4068 vertexBindings.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
4069 2u, // deUint32 attributeCount;
4070 vertexAttribs.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
4075 vertexInputStateParams.vertexBindingDescriptionCount += 1;
4076 vertexInputStateParams.vertexAttributeDescriptionCount += 1;
4079 vector<VkPipelineColorBlendAttachmentState> attBlendStates;
4080 const VkPipelineColorBlendAttachmentState attBlendState =
4082 DE_FALSE, // deUint32 blendEnable;
4083 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
4084 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
4085 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
4086 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
4087 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
4088 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
4089 (VK_COLOR_COMPONENT_R_BIT|
4090 VK_COLOR_COMPONENT_G_BIT|
4091 VK_COLOR_COMPONENT_B_BIT|
4092 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask;
4094 attBlendStates.push_back(attBlendState);
4097 attBlendStates.push_back(attBlendState);
4099 VkPipelineColorBlendStateCreateInfo blendParams =
4101 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
4102 DE_NULL, // const void* pNext;
4103 (VkPipelineColorBlendStateCreateFlags)0,
4104 DE_FALSE, // VkBool32 logicOpEnable;
4105 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
4106 1u, // deUint32 attachmentCount;
4107 attBlendStates.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
4108 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
4112 blendParams.attachmentCount += 1;
4114 const VkPipelineTessellationStateCreateInfo tessellationState =
4116 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
4118 (VkPipelineTessellationStateCreateFlags)0,
4122 const VkPipelineTessellationStateCreateInfo* tessellationInfo = hasTessellation ? &tessellationState: DE_NULL;
4123 const VkGraphicsPipelineCreateInfo pipelineParams =
4125 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
4126 DE_NULL, // const void* pNext;
4127 0u, // VkPipelineCreateFlags flags;
4128 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
4129 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
4130 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
4131 &inputAssemblyParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
4132 tessellationInfo, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
4133 &viewportParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
4134 &rasterParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
4135 &multisampleParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
4136 &depthStencilParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
4137 &blendParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
4138 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
4139 *pipelineLayout, // VkPipelineLayout layout;
4140 *renderPass, // VkRenderPass renderPass;
4141 0u, // deUint32 subpass;
4142 DE_NULL, // VkPipeline basePipelineHandle;
4143 0u, // deInt32 basePipelineIndex;
4146 const Unique<VkPipeline> pipeline (createGraphicsPipeline(vk, device, DE_NULL, &pipelineParams));
4150 const VkImageViewCreateInfo fragOutputViewParams =
4152 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
4153 DE_NULL, // const void* pNext;
4154 0u, // VkImageViewCreateFlags flags;
4155 *fragOutputImage, // VkImage image;
4156 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
4157 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
4159 VK_COMPONENT_SWIZZLE_R,
4160 VK_COMPONENT_SWIZZLE_G,
4161 VK_COMPONENT_SWIZZLE_B,
4162 VK_COMPONENT_SWIZZLE_A
4163 }, // VkChannelMapping channels;
4165 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
4166 0u, // deUint32 baseMipLevel;
4167 1u, // deUint32 mipLevels;
4168 0u, // deUint32 baseArrayLayer;
4169 1u, // deUint32 arraySize;
4170 }, // VkImageSubresourceRange subresourceRange;
4172 fragOutputImageView = createImageView(vk, device, &fragOutputViewParams);
4173 attViews.push_back(*fragOutputImageView);
4177 VkFramebufferCreateInfo framebufferParams =
4179 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
4180 DE_NULL, // const void* pNext;
4181 (VkFramebufferCreateFlags)0,
4182 *renderPass, // VkRenderPass renderPass;
4183 1u, // deUint32 attachmentCount;
4184 attViews.data(), // const VkImageView* pAttachments;
4185 (deUint32)renderSize.x(), // deUint32 width;
4186 (deUint32)renderSize.y(), // deUint32 height;
4187 1u, // deUint32 layers;
4191 framebufferParams.attachmentCount += 1;
4193 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, &framebufferParams));
4196 beginCommandBuffer(vk, *cmdBuf);
4199 const VkMemoryBarrier vertFlushBarrier =
4201 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
4202 DE_NULL, // const void* pNext;
4203 VK_ACCESS_HOST_WRITE_BIT, // VkMemoryOutputFlags outputMask;
4204 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkMemoryInputFlags inputMask;
4206 vector<VkImageMemoryBarrier> colorAttBarriers;
4208 VkImageMemoryBarrier imgBarrier =
4210 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4211 DE_NULL, // const void* pNext;
4212 0u, // VkMemoryOutputFlags outputMask;
4213 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryInputFlags inputMask;
4214 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4215 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
4216 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
4217 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
4218 *image, // VkImage image;
4220 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
4221 0u, // deUint32 baseMipLevel;
4222 1u, // deUint32 mipLevels;
4223 0u, // deUint32 baseArraySlice;
4224 1u, // deUint32 arraySize;
4225 } // VkImageSubresourceRange subresourceRange;
4227 colorAttBarriers.push_back(imgBarrier);
4230 imgBarrier.image = *fragOutputImage;
4231 colorAttBarriers.push_back(imgBarrier);
4232 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());
4236 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());
4241 vector<VkClearValue> clearValue;
4242 clearValue.push_back(makeClearValueColorF32(defaulClearColor[0], defaulClearColor[1], defaulClearColor[2], defaulClearColor[3]));
4245 clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0));
4247 beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), (deUint32)clearValue.size(), clearValue.data());
4250 vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
4252 const VkDeviceSize bindingOffset = 0;
4253 vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
4257 const VkDeviceSize bindingOffset = 0;
4258 vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset);
4260 if (hasPushConstants)
4262 vector<deUint8> pushConstantsBytes;
4263 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
4265 const deUint32 size = static_cast<deUint32>(pushConstantsBytes.size());
4266 const void* data = &pushConstantsBytes.front();
4268 vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
4270 if (numResources != 0)
4272 // Bind to set number 0.
4273 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL);
4275 vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/);
4276 endRenderPass(vk, *cmdBuf);
4279 vector<VkImageMemoryBarrier> renderFinishBarrier;
4280 VkImageMemoryBarrier imgBarrier =
4282 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4283 DE_NULL, // const void* pNext;
4284 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryOutputFlags outputMask;
4285 VK_ACCESS_TRANSFER_READ_BIT, // VkMemoryInputFlags inputMask;
4286 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
4287 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
4288 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
4289 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
4290 *image, // VkImage image;
4292 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
4293 0u, // deUint32 baseMipLevel;
4294 1u, // deUint32 mipLevels;
4295 0u, // deUint32 baseArraySlice;
4296 1u, // deUint32 arraySize;
4297 } // VkImageSubresourceRange subresourceRange;
4299 renderFinishBarrier.push_back(imgBarrier);
4303 imgBarrier.image = *fragOutputImage;
4304 renderFinishBarrier.push_back(imgBarrier);
4305 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());
4309 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());
4314 const VkBufferImageCopy copyParams =
4316 (VkDeviceSize)0u, // VkDeviceSize bufferOffset;
4317 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
4318 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
4320 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
4321 0u, // deUint32 mipLevel;
4322 0u, // deUint32 arrayLayer;
4323 1u, // deUint32 arraySize;
4324 }, // VkImageSubresourceCopy imageSubresource;
4325 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
4326 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
4328 vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
4332 vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, ©Params);
4337 vector<VkBufferMemoryBarrier> cpFinishBarriers;
4338 VkBufferMemoryBarrier copyFinishBarrier =
4340 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
4341 DE_NULL, // const void* pNext;
4342 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
4343 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
4344 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
4345 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
4346 *readImageBuffer, // VkBuffer buffer;
4347 0u, // VkDeviceSize offset;
4348 imageSizeBytes // VkDeviceSize size;
4350 cpFinishBarriers.push_back(copyFinishBarrier);
4354 copyFinishBarrier.buffer = *fragOutputBuffer;
4355 copyFinishBarrier.size = VK_WHOLE_SIZE;
4356 cpFinishBarriers.push_back(copyFinishBarrier);
4358 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);
4362 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);
4366 endCommandBuffer(vk, *cmdBuf);
4368 // Upload vertex data
4370 void* vertexBufPtr = vertexBufferMemory->getHostPtr();
4371 deMemcpy(vertexBufPtr, &vertexData[0], vertexDataSize);
4372 flushAlloc(vk, device, *vertexBufferMemory);
4377 vector<deUint8> inputBufferBytes;
4378 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
4380 const deUint32 typNumBytes = instance.interfaces.getInputType().getNumBytes();
4381 const deUint32 bufNumBytes = static_cast<deUint32>(inputBufferBytes.size());
4383 // Require that the test instantation provides four output values.
4384 DE_ASSERT(bufNumBytes == 4 * typNumBytes);
4386 // We have four triangles. Because interpolation happens before executing the fragment shader,
4387 // we need to provide the same vertex attribute for the same triangle. That means, duplicate each
4388 // value three times for all four values.
4390 const deUint8* provided = static_cast<const deUint8*>(&inputBufferBytes.front());
4391 vector<deUint8> data;
4393 data.reserve(3 * bufNumBytes);
4395 for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes)
4396 for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
4397 for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx)
4398 data.push_back(provided[offset + byteNdx]);
4400 deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size());
4402 const VkMappedMemoryRange range =
4404 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
4405 DE_NULL, // const void* pNext;
4406 vertexInputMemory->getMemory(), // VkDeviceMemory mem;
4407 0, // VkDeviceSize offset;
4408 VK_WHOLE_SIZE, // VkDeviceSize size;
4411 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
4414 // Submit & wait for completion
4415 submitCommandsAndWait(vk, device, queue, cmdBuf.get());
4417 const void* imagePtr = readImageBufferMemory->getHostPtr();
4418 const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
4419 renderSize.x(), renderSize.y(), 1, imagePtr);
4421 invalidateAlloc(vk, device, *readImageBufferMemory);
4422 context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer);
4426 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
4427 const VkMappedMemoryRange range =
4429 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
4430 DE_NULL, // const void* pNext;
4431 fragOutputMemory->getMemory(), // VkDeviceMemory mem;
4432 0, // VkDeviceSize offset;
4433 fragOutputImgSize, // VkDeviceSize size;
4436 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
4439 { // Make sure all output resources are ready.
4440 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
4442 const VkMappedMemoryRange range =
4444 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
4445 DE_NULL, // const void* pNext;
4446 outResourceMemories[outputNdx]->getMemory(), // VkDeviceMemory mem;
4447 0, // VkDeviceSize offset;
4448 VK_WHOLE_SIZE, // VkDeviceSize size;
4451 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
4455 const RGBA threshold(1, 1, 1, 1);
4457 const RGBA upperLeft(pixelBuffer.getPixel(1, 1));
4458 if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold))
4459 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch"));
4461 const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1));
4462 if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold))
4463 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch"));
4465 const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1));
4466 if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold))
4467 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch"));
4469 const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1));
4470 if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold))
4471 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch"));
4473 // Check that the contents in the ouput variable matches expected.
4476 vector<deUint8> inputBufferBytes;
4477 vector<deUint8> outputBufferBytes;
4479 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
4480 instance.interfaces.getOutputBuffer()->getBytes(outputBufferBytes);
4482 const IFDataType& inputType = instance.interfaces.getInputType();
4483 const IFDataType& outputType = instance.interfaces.getOutputType();
4484 const void* inputData = &inputBufferBytes.front();
4485 const void* outputData = &outputBufferBytes.front();
4486 vector<std::pair<int, int> > positions;
4487 const tcu::ConstPixelBufferAccess fragOutputBufferAccess (outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr());
4489 positions.push_back(std::make_pair(1, 1));
4490 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1));
4491 positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1));
4492 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1));
4494 for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx)
4496 const int x = positions[posNdx].first;
4497 const int y = positions[posNdx].second;
4500 if (outputType.elementType == NUMBERTYPE_FLOAT32)
4502 const float* expected = static_cast<const float*>(outputData) + posNdx * outputType.numElements;
4503 const float* actual = static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y));
4505 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4506 if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
4509 else if (outputType.elementType == NUMBERTYPE_INT32)
4511 const deInt32* expected = static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements;
4512 const deInt32* actual = static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y));
4514 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4515 if (expected[eleNdx] != actual[eleNdx])
4518 else if (outputType.elementType == NUMBERTYPE_UINT32)
4520 const deUint32* expected = static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements;
4521 const deUint32* actual = static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y));
4523 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4524 if (expected[eleNdx] != actual[eleNdx])
4527 else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType == NUMBERTYPE_FLOAT64)
4529 const double* original = static_cast<const double*>(inputData) + posNdx * outputType.numElements;
4530 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4532 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4533 if (!compare16BitFloat64(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
4536 else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType != NUMBERTYPE_FLOAT64)
4538 if (inputType.elementType == NUMBERTYPE_FLOAT16)
4540 const deFloat16* original = static_cast<const deFloat16*>(inputData) + posNdx * outputType.numElements;
4541 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4543 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4544 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
4549 const float* original = static_cast<const float*>(inputData) + posNdx * outputType.numElements;
4550 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4552 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4553 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
4557 else if (outputType.elementType == NUMBERTYPE_INT16)
4559 const deInt16* expected = static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements;
4560 const deInt16* actual = static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4562 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4563 if (expected[eleNdx] != actual[eleNdx])
4566 else if (outputType.elementType == NUMBERTYPE_UINT16)
4568 const deUint16* expected = static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements;
4569 const deUint16* actual = static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4571 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4572 if (expected[eleNdx] != actual[eleNdx])
4575 else if (outputType.elementType == NUMBERTYPE_FLOAT64)
4577 const double* expected = static_cast<const double*>(outputData) + posNdx * outputType.numElements;
4578 const double* actual = static_cast<const double*>(fragOutputBufferAccess.getPixelPtr(x, y));
4580 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4581 if (!compare64BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
4585 DE_ASSERT(0 && "unhandled type");
4589 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch"));
4593 // Check the contents in output resources match with expected.
4594 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
4596 const BufferSp& expected = instance.resources.outputs[outputNdx].getBuffer();
4598 if (instance.resources.verifyIO != DE_NULL)
4600 if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog()))
4601 return tcu::TestStatus::fail("Resource returned doesn't match with expected");
4605 vector<deUint8> expectedBytes;
4606 expected->getBytes(expectedBytes);
4608 if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
4609 return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
4614 return TestStatus::pass("Rendered output matches input");
4617 const vector<ShaderElement>& getVertFragPipelineStages (void)
4619 static vector<ShaderElement> vertFragPipelineStages;
4620 if(vertFragPipelineStages.empty())
4622 vertFragPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4623 vertFragPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4625 return vertFragPipelineStages;
4628 const vector<ShaderElement>& getTessPipelineStages (void)
4630 static vector<ShaderElement> tessPipelineStages;
4631 if(tessPipelineStages.empty())
4633 tessPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4634 tessPipelineStages.push_back(ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
4635 tessPipelineStages.push_back(ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
4636 tessPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4638 return tessPipelineStages;
4641 const vector<ShaderElement>& getGeomPipelineStages (void)
4643 static vector<ShaderElement> geomPipelineStages;
4644 if(geomPipelineStages.empty())
4646 geomPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4647 geomPipelineStages.push_back(ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT));
4648 geomPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4650 return geomPipelineStages;
4653 // Helper structure used by addTestForStage function.
4656 typedef const vector<ShaderElement>& (*GetPipelineStagesFn)();
4657 typedef void (*AddShaderCodeCustomStageFn)(vk::SourceCollections&, InstanceContext);
4659 GetPipelineStagesFn getPipelineFn;
4660 AddShaderCodeCustomStageFn initProgramsFn;
4663 : getPipelineFn(DE_NULL)
4664 , initProgramsFn(DE_NULL)
4668 StageData(GetPipelineStagesFn pipelineGetter, AddShaderCodeCustomStageFn programsInitializer)
4669 : getPipelineFn(pipelineGetter)
4670 , initProgramsFn(programsInitializer)
4675 // Helper function used by addTestForStage function.
4676 const StageData& getStageData (vk::VkShaderStageFlagBits stage)
4679 static map<vk::VkShaderStageFlagBits, StageData> testedStageData;
4680 if(testedStageData.empty())
4682 testedStageData[VK_SHADER_STAGE_VERTEX_BIT] = StageData(getVertFragPipelineStages, addShaderCodeCustomVertex);
4683 testedStageData[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessControl);
4684 testedStageData[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessEval);
4685 testedStageData[VK_SHADER_STAGE_GEOMETRY_BIT] = StageData(getGeomPipelineStages, addShaderCodeCustomGeometry);
4686 testedStageData[VK_SHADER_STAGE_FRAGMENT_BIT] = StageData(getVertFragPipelineStages, addShaderCodeCustomFragment);
4689 return testedStageData[stage];
4692 void createTestForStage (vk::VkShaderStageFlagBits stage,
4693 const std::string& name,
4694 const RGBA (&inputColors)[4],
4695 const RGBA (&outputColors)[4],
4696 const map<string, string>& testCodeFragments,
4697 const SpecConstants& specConstants,
4698 const PushConstants& pushConstants,
4699 const GraphicsResources& resources,
4700 const GraphicsInterfaces& interfaces,
4701 const vector<string>& extensions,
4702 VulkanFeatures vulkanFeatures,
4703 tcu::TestCaseGroup* tests,
4704 const qpTestResult failResult,
4705 const string& failMessageTemplate,
4706 const bool renderFullSquare)
4708 const StageData& stageData = getStageData(stage);
4709 DE_ASSERT(stageData.getPipelineFn || stageData.initProgramsFn);
4710 const vector<ShaderElement>& pipeline = stageData.getPipelineFn();
4712 StageToSpecConstantMap specConstantMap;
4713 if (!specConstants.empty())
4714 specConstantMap[stage] = specConstants;
4716 InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstantMap, pushConstants, resources, interfaces, extensions, vulkanFeatures, stage);
4717 for (size_t i = 0; i < pipeline.size(); ++i)
4719 ctx.moduleMap[pipeline[i].moduleName].push_back(std::make_pair(pipeline[i].entryName, pipeline[i].stage));
4720 ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | pipeline[i].stage);
4723 ctx.failResult = failResult;
4724 if (!failMessageTemplate.empty())
4725 ctx.failMessageTemplate = failMessageTemplate;
4727 ctx.renderFullSquare = renderFullSquare;
4728 addFunctionCaseWithPrograms<InstanceContext>(tests, name, "", stageData.initProgramsFn, runAndVerifyDefaultPipeline, ctx);
4731 void createTestsForAllStages (const std::string& name,
4732 const RGBA (&inputColors)[4],
4733 const RGBA (&outputColors)[4],
4734 const map<string, string>& testCodeFragments,
4735 const SpecConstants& specConstants,
4736 const PushConstants& pushConstants,
4737 const GraphicsResources& resources,
4738 const GraphicsInterfaces& interfaces,
4739 const vector<string>& extensions,
4740 VulkanFeatures vulkanFeatures,
4741 tcu::TestCaseGroup* tests,
4742 const qpTestResult failResult,
4743 const string& failMessageTemplate)
4745 createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, name + "_vert",
4746 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4747 interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);
4749 createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name + "_tessc",
4750 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4751 interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);
4753 createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, name + "_tesse",
4754 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4755 interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);
4757 createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, name + "_geom",
4758 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4759 interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);
4761 createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, name + "_frag",
4762 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4763 interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate);
4766 void addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
4768 RGBA defaultColors[4];
4769 getDefaultColors(defaultColors);
4771 createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name,
4772 defaultColors, defaultColors, fragments, SpecConstants(), PushConstants(), GraphicsResources(),
4773 GraphicsInterfaces(), vector<string>(), VulkanFeatures(), group);