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 const vector<string>& features_,
264 VulkanFeatures vulkanFeatures_,
265 VkShaderStageFlags customizedStages_)
266 : testCodeFragments (testCodeFragments_)
267 , specConstants (specConstants_)
268 , hasTessellation (false)
269 , requiredStages (static_cast<VkShaderStageFlagBits>(0))
270 , requiredDeviceExtensions (extensions_)
271 , requiredDeviceFeatures (features_)
272 , requestedFeatures (vulkanFeatures_)
273 , pushConstants (pushConsants_)
274 , customizedStages (customizedStages_)
275 , resources (resources_)
276 , interfaces (interfaces_)
277 , failResult (QP_TEST_RESULT_FAIL)
278 , failMessageTemplate ("${reason}")
279 , renderFullSquare (false)
281 inputColors[0] = inputs[0];
282 inputColors[1] = inputs[1];
283 inputColors[2] = inputs[2];
284 inputColors[3] = inputs[3];
286 outputColors[0] = outputs[0];
287 outputColors[1] = outputs[1];
288 outputColors[2] = outputs[2];
289 outputColors[3] = outputs[3];
292 InstanceContext::InstanceContext (const InstanceContext& other)
293 : moduleMap (other.moduleMap)
294 , testCodeFragments (other.testCodeFragments)
295 , specConstants (other.specConstants)
296 , hasTessellation (other.hasTessellation)
297 , requiredStages (other.requiredStages)
298 , requiredDeviceExtensions (other.requiredDeviceExtensions)
299 , requiredDeviceFeatures (other.requiredDeviceFeatures)
300 , requestedFeatures (other.requestedFeatures)
301 , pushConstants (other.pushConstants)
302 , customizedStages (other.customizedStages)
303 , resources (other.resources)
304 , interfaces (other.interfaces)
305 , failResult (other.failResult)
306 , failMessageTemplate (other.failMessageTemplate)
307 , renderFullSquare (other.renderFullSquare)
309 inputColors[0] = other.inputColors[0];
310 inputColors[1] = other.inputColors[1];
311 inputColors[2] = other.inputColors[2];
312 inputColors[3] = other.inputColors[3];
314 outputColors[0] = other.outputColors[0];
315 outputColors[1] = other.outputColors[1];
316 outputColors[2] = other.outputColors[2];
317 outputColors[3] = other.outputColors[3];
320 string InstanceContext::getSpecializedFailMessage (const string& failureReason)
322 map<string, string> parameters;
323 parameters["reason"] = failureReason;
324 return StringTemplate(failMessageTemplate).specialize(parameters);
327 ShaderElement::ShaderElement (const string& moduleName_,
328 const string& entryPoint_,
329 VkShaderStageFlagBits shaderStage_)
330 : moduleName(moduleName_)
331 , entryName(entryPoint_)
332 , stage(shaderStage_)
336 void getDefaultColors (RGBA (&colors)[4])
338 colors[0] = RGBA::white();
339 colors[1] = RGBA::red();
340 colors[2] = RGBA::green();
341 colors[3] = RGBA::blue();
344 void getHalfColorsFullAlpha (RGBA (&colors)[4])
346 colors[0] = RGBA(127, 127, 127, 255);
347 colors[1] = RGBA(127, 0, 0, 255);
348 colors[2] = RGBA(0, 127, 0, 255);
349 colors[3] = RGBA(0, 0, 127, 255);
352 void getInvertedDefaultColors (RGBA (&colors)[4])
354 colors[0] = RGBA(0, 0, 0, 255);
355 colors[1] = RGBA(0, 255, 255, 255);
356 colors[2] = RGBA(255, 0, 255, 255);
357 colors[3] = RGBA(255, 255, 0, 255);
360 // For the current InstanceContext, constructs the required modules and shader stage create infos.
361 void createPipelineShaderStages (const DeviceInterface& vk,
362 const VkDevice vkDevice,
363 InstanceContext& instance,
365 vector<ModuleHandleSp>& modules,
366 vector<VkPipelineShaderStageCreateInfo>& createInfos)
368 for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx)
370 const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0)));
371 modules.push_back(ModuleHandleSp(mod));
372 for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx)
374 const EntryToStage& stage = *shaderNdx;
375 const VkPipelineShaderStageCreateInfo shaderParam =
377 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
378 DE_NULL, // const void* pNext;
379 (VkPipelineShaderStageCreateFlags)0,
380 stage.second, // VkShaderStageFlagBits stage;
381 **modules.back(), // VkShaderModule module;
382 stage.first.c_str(), // const char* pName;
383 (const VkSpecializationInfo*)DE_NULL,
385 createInfos.push_back(shaderParam);
390 // Creates vertex-shader assembly by specializing a boilerplate StringTemplate
391 // on fragments, which must (at least) map "testfun" to an OpFunction definition
392 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
393 // with "BP_" to avoid collisions with fragments.
395 // It corresponds roughly to this GLSL:
397 // layout(location = 0) in vec4 position;
398 // layout(location = 1) in vec4 color;
399 // layout(location = 1) out highp vec4 vtxColor;
400 // void main (void) { gl_Position = position; vtxColor = test_func(color); }
401 string makeVertexShaderAssembly (const map<string, string>& fragments)
403 static const char vertexShaderBoilerplate[] =
404 "OpCapability Shader\n"
405 "OpCapability ClipDistance\n"
406 "OpCapability CullDistance\n"
407 "${capability:opt}\n"
409 "OpMemoryModel Logical GLSL450\n"
410 "OpEntryPoint Vertex %BP_main \"main\" %BP_stream %BP_position %BP_vtx_color %BP_color %BP_gl_VertexIndex %BP_gl_InstanceIndex ${IF_entrypoint:opt} \n"
412 "${moduleprocessed:opt}\n"
413 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
414 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
415 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
416 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
417 "OpDecorate %BP_gl_PerVertex Block\n"
418 "OpDecorate %BP_position Location 0\n"
419 "OpDecorate %BP_vtx_color Location 1\n"
420 "OpDecorate %BP_color Location 1\n"
421 "OpDecorate %BP_gl_VertexIndex BuiltIn VertexIndex\n"
422 "OpDecorate %BP_gl_InstanceIndex BuiltIn InstanceIndex\n"
423 "${IF_decoration:opt}\n"
424 "${decoration:opt}\n"
426 SPIRV_ASSEMBLY_CONSTANTS
427 SPIRV_ASSEMBLY_ARRAYS
428 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
429 "%BP_op_gl_PerVertex = OpTypePointer Output %BP_gl_PerVertex\n"
430 "%BP_stream = OpVariable %BP_op_gl_PerVertex Output\n"
431 "%BP_position = OpVariable %ip_v4f32 Input\n"
432 "%BP_vtx_color = OpVariable %op_v4f32 Output\n"
433 "%BP_color = OpVariable %ip_v4f32 Input\n"
434 "%BP_gl_VertexIndex = OpVariable %ip_i32 Input\n"
435 "%BP_gl_InstanceIndex = OpVariable %ip_i32 Input\n"
437 "${IF_variable:opt}\n"
438 "%BP_main = OpFunction %void None %fun\n"
439 "%BP_label = OpLabel\n"
440 "${IF_carryforward:opt}\n"
441 "${post_interface_op_vert:opt}\n"
442 "%BP_pos = OpLoad %v4f32 %BP_position\n"
443 "%BP_gl_pos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
444 "OpStore %BP_gl_pos %BP_pos\n"
445 "%BP_col = OpLoad %v4f32 %BP_color\n"
446 "%BP_col_transformed = OpFunctionCall %v4f32 %test_code %BP_col\n"
447 "OpStore %BP_vtx_color %BP_col_transformed\n"
450 "${interface_op_func:opt}\n"
452 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
453 "%getId_label = OpLabel\n"
454 "%vert_id = OpLoad %i32 %BP_gl_VertexIndex\n"
455 "%is_id_0 = OpIEqual %bool %vert_id %c_i32_0\n"
456 "OpReturnValue %is_id_0\n"
460 return tcu::StringTemplate(vertexShaderBoilerplate).specialize(fragments);
463 // Creates tess-control-shader assembly by specializing a boilerplate
464 // StringTemplate on fragments, which must (at least) map "testfun" to an
465 // OpFunction definition for %test_code that takes and returns a %v4f32.
466 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
468 // It roughly corresponds to the following GLSL.
471 // layout(vertices = 3) out;
472 // layout(location = 1) in vec4 in_color[];
473 // layout(location = 1) out vec4 out_color[];
476 // out_color[gl_InvocationID] = testfun(in_color[gl_InvocationID]);
477 // gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;
478 // if (gl_InvocationID == 0) {
479 // gl_TessLevelOuter[0] = 1.0;
480 // gl_TessLevelOuter[1] = 1.0;
481 // gl_TessLevelOuter[2] = 1.0;
482 // gl_TessLevelInner[0] = 1.0;
485 string makeTessControlShaderAssembly (const map<string, string>& fragments)
487 static const char tessControlShaderBoilerplate[] =
488 "OpCapability Tessellation\n"
489 "OpCapability ClipDistance\n"
490 "OpCapability CullDistance\n"
491 "${capability:opt}\n"
493 "OpMemoryModel Logical GLSL450\n"
494 "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"
495 "OpExecutionMode %BP_main OutputVertices 3\n"
497 "${moduleprocessed:opt}\n"
498 "OpDecorate %BP_out_color Location 1\n"
499 "OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n"
500 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
501 "OpDecorate %BP_in_color Location 1\n"
502 "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n"
503 "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n"
504 "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n"
505 "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n"
506 "OpDecorate %BP_gl_PerVertex Block\n"
507 "OpMemberDecorate %BP_gl_PVOut 0 BuiltIn Position\n"
508 "OpMemberDecorate %BP_gl_PVOut 1 BuiltIn PointSize\n"
509 "OpMemberDecorate %BP_gl_PVOut 2 BuiltIn ClipDistance\n"
510 "OpMemberDecorate %BP_gl_PVOut 3 BuiltIn CullDistance\n"
511 "OpDecorate %BP_gl_PVOut Block\n"
512 "OpDecorate %BP_gl_TessLevelOuter Patch\n"
513 "OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
514 "OpDecorate %BP_gl_TessLevelInner Patch\n"
515 "OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n"
516 "${IF_decoration:opt}\n"
517 "${decoration:opt}\n"
518 "${decoration_tessc:opt}\n"
520 SPIRV_ASSEMBLY_CONSTANTS
521 SPIRV_ASSEMBLY_ARRAYS
522 "%BP_out_color = OpVariable %op_a3v4f32 Output\n"
523 "%BP_gl_InvocationID = OpVariable %ip_i32 Input\n"
524 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
525 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
526 "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
527 "%BP_a3_gl_PerVertex = OpTypeArray %BP_gl_PerVertex %c_u32_3\n"
528 "%BP_op_a3_gl_PerVertex = OpTypePointer Output %BP_a3_gl_PerVertex\n"
529 "%BP_gl_out = OpVariable %BP_op_a3_gl_PerVertex Output\n"
530 "%BP_gl_PVOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
531 "%BP_a32_gl_PVOut = OpTypeArray %BP_gl_PVOut %c_u32_32\n"
532 "%BP_ip_a32_gl_PVOut = OpTypePointer Input %BP_a32_gl_PVOut\n"
533 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PVOut Input\n"
534 "%BP_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
535 "%BP_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
537 "${IF_variable:opt}\n"
539 "%BP_main = OpFunction %void None %fun\n"
540 "%BP_label = OpLabel\n"
541 "%BP_gl_Invoc = OpLoad %i32 %BP_gl_InvocationID\n"
542 "${IF_carryforward:opt}\n"
543 "${post_interface_op_tessc:opt}\n"
544 "%BP_in_col_loc = OpAccessChain %ip_v4f32 %BP_in_color %BP_gl_Invoc\n"
545 "%BP_out_col_loc = OpAccessChain %op_v4f32 %BP_out_color %BP_gl_Invoc\n"
546 "%BP_in_col_val = OpLoad %v4f32 %BP_in_col_loc\n"
547 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_in_col_val\n"
548 "OpStore %BP_out_col_loc %BP_clr_transformed\n"
550 "%BP_in_pos_loc = OpAccessChain %ip_v4f32 %BP_gl_in %BP_gl_Invoc %c_i32_0\n"
551 "%BP_out_pos_loc = OpAccessChain %op_v4f32 %BP_gl_out %BP_gl_Invoc %c_i32_0\n"
552 "%BP_in_pos_val = OpLoad %v4f32 %BP_in_pos_loc\n"
553 "OpStore %BP_out_pos_loc %BP_in_pos_val\n"
555 "%BP_cmp = OpIEqual %bool %BP_gl_Invoc %c_i32_0\n"
556 "OpSelectionMerge %BP_merge_label None\n"
557 "OpBranchConditional %BP_cmp %BP_if_label %BP_merge_label\n"
558 "%BP_if_label = OpLabel\n"
559 "%BP_gl_TessLevelOuterPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_0\n"
560 "%BP_gl_TessLevelOuterPos_1 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_1\n"
561 "%BP_gl_TessLevelOuterPos_2 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_2\n"
562 "%BP_gl_TessLevelInnerPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelInner %c_i32_0\n"
563 "OpStore %BP_gl_TessLevelOuterPos_0 %c_f32_1\n"
564 "OpStore %BP_gl_TessLevelOuterPos_1 %c_f32_1\n"
565 "OpStore %BP_gl_TessLevelOuterPos_2 %c_f32_1\n"
566 "OpStore %BP_gl_TessLevelInnerPos_0 %c_f32_1\n"
567 "OpBranch %BP_merge_label\n"
568 "%BP_merge_label = OpLabel\n"
571 "${interface_op_func:opt}\n"
573 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
574 "%getId_label = OpLabel\n"
575 "%invocation_id = OpLoad %i32 %BP_gl_InvocationID\n"
576 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
577 "%is_invocation_0 = OpIEqual %bool %invocation_id %c_i32_0\n"
578 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
579 "%is_id_0 = OpLogicalAnd %bool %is_invocation_0 %is_primitive_0\n"
580 "OpReturnValue %is_id_0\n"
584 return tcu::StringTemplate(tessControlShaderBoilerplate).specialize(fragments);
587 // Creates tess-evaluation-shader assembly by specializing a boilerplate
588 // StringTemplate on fragments, which must (at least) map "testfun" to an
589 // OpFunction definition for %test_code that takes and returns a %v4f32.
590 // Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments.
592 // It roughly corresponds to the following glsl.
596 // layout(triangles, equal_spacing, ccw) in;
597 // layout(location = 1) in vec4 in_color[];
598 // layout(location = 1) out vec4 out_color;
600 // #define interpolate(val)
601 // vec4(gl_TessCoord.x) * val[0] + vec4(gl_TessCoord.y) * val[1] +
602 // vec4(gl_TessCoord.z) * val[2]
605 // gl_Position = vec4(gl_TessCoord.x) * gl_in[0].gl_Position +
606 // vec4(gl_TessCoord.y) * gl_in[1].gl_Position +
607 // vec4(gl_TessCoord.z) * gl_in[2].gl_Position;
608 // out_color = testfun(interpolate(in_color));
610 string makeTessEvalShaderAssembly (const map<string, string>& fragments)
612 static const char tessEvalBoilerplate[] =
613 "OpCapability Tessellation\n"
614 "OpCapability ClipDistance\n"
615 "OpCapability CullDistance\n"
616 "${capability:opt}\n"
618 "OpMemoryModel Logical GLSL450\n"
619 "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"
620 "OpExecutionMode %BP_main Triangles\n"
621 "OpExecutionMode %BP_main SpacingEqual\n"
622 "OpExecutionMode %BP_main VertexOrderCcw\n"
624 "${moduleprocessed:opt}\n"
625 "OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n"
626 "OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n"
627 "OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n"
628 "OpMemberDecorate %BP_gl_PerVertexOut 3 BuiltIn CullDistance\n"
629 "OpDecorate %BP_gl_PerVertexOut Block\n"
630 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
631 "OpDecorate %BP_gl_TessCoord BuiltIn TessCoord\n"
632 "OpMemberDecorate %BP_gl_PerVertexIn 0 BuiltIn Position\n"
633 "OpMemberDecorate %BP_gl_PerVertexIn 1 BuiltIn PointSize\n"
634 "OpMemberDecorate %BP_gl_PerVertexIn 2 BuiltIn ClipDistance\n"
635 "OpMemberDecorate %BP_gl_PerVertexIn 3 BuiltIn CullDistance\n"
636 "OpDecorate %BP_gl_PerVertexIn Block\n"
637 "OpDecorate %BP_out_color Location 1\n"
638 "OpDecorate %BP_in_color Location 1\n"
639 "${IF_decoration:opt}\n"
640 "${decoration:opt}\n"
642 SPIRV_ASSEMBLY_CONSTANTS
643 SPIRV_ASSEMBLY_ARRAYS
644 "%BP_gl_PerVertexOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
645 "%BP_op_gl_PerVertexOut = OpTypePointer Output %BP_gl_PerVertexOut\n"
646 "%BP_stream = OpVariable %BP_op_gl_PerVertexOut Output\n"
647 "%BP_gl_TessCoord = OpVariable %ip_v3f32 Input\n"
648 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
649 "%BP_gl_PerVertexIn = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
650 "%BP_a32_gl_PerVertexIn = OpTypeArray %BP_gl_PerVertexIn %c_u32_32\n"
651 "%BP_ip_a32_gl_PerVertexIn = OpTypePointer Input %BP_a32_gl_PerVertexIn\n"
652 "%BP_gl_in = OpVariable %BP_ip_a32_gl_PerVertexIn Input\n"
653 "%BP_out_color = OpVariable %op_v4f32 Output\n"
654 "%BP_in_color = OpVariable %ip_a32v4f32 Input\n"
656 "${IF_variable:opt}\n"
657 "%BP_main = OpFunction %void None %fun\n"
658 "%BP_label = OpLabel\n"
659 "${IF_carryforward:opt}\n"
660 "${post_interface_op_tesse:opt}\n"
661 "%BP_gl_TC_0 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
662 "%BP_gl_TC_1 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
663 "%BP_gl_TC_2 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
664 "%BP_gl_in_gl_Pos_0 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
665 "%BP_gl_in_gl_Pos_1 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
666 "%BP_gl_in_gl_Pos_2 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
668 "%BP_gl_OPos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n"
669 "%BP_in_color_0 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
670 "%BP_in_color_1 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
671 "%BP_in_color_2 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
673 "%BP_TC_W_0 = OpLoad %f32 %BP_gl_TC_0\n"
674 "%BP_TC_W_1 = OpLoad %f32 %BP_gl_TC_1\n"
675 "%BP_TC_W_2 = OpLoad %f32 %BP_gl_TC_2\n"
676 "%BP_v4f32_TC_0 = OpCompositeConstruct %v4f32 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0\n"
677 "%BP_v4f32_TC_1 = OpCompositeConstruct %v4f32 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1\n"
678 "%BP_v4f32_TC_2 = OpCompositeConstruct %v4f32 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2\n"
680 "%BP_gl_IP_0 = OpLoad %v4f32 %BP_gl_in_gl_Pos_0\n"
681 "%BP_gl_IP_1 = OpLoad %v4f32 %BP_gl_in_gl_Pos_1\n"
682 "%BP_gl_IP_2 = OpLoad %v4f32 %BP_gl_in_gl_Pos_2\n"
684 "%BP_IP_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_gl_IP_0\n"
685 "%BP_IP_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_gl_IP_1\n"
686 "%BP_IP_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_gl_IP_2\n"
688 "%BP_pos_sum_0 = OpFAdd %v4f32 %BP_IP_W_0 %BP_IP_W_1\n"
689 "%BP_pos_sum_1 = OpFAdd %v4f32 %BP_pos_sum_0 %BP_IP_W_2\n"
691 "OpStore %BP_gl_OPos %BP_pos_sum_1\n"
693 "%BP_IC_0 = OpLoad %v4f32 %BP_in_color_0\n"
694 "%BP_IC_1 = OpLoad %v4f32 %BP_in_color_1\n"
695 "%BP_IC_2 = OpLoad %v4f32 %BP_in_color_2\n"
697 "%BP_IC_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_IC_0\n"
698 "%BP_IC_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_IC_1\n"
699 "%BP_IC_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_IC_2\n"
701 "%BP_col_sum_0 = OpFAdd %v4f32 %BP_IC_W_0 %BP_IC_W_1\n"
702 "%BP_col_sum_1 = OpFAdd %v4f32 %BP_col_sum_0 %BP_IC_W_2\n"
704 "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_col_sum_1\n"
706 "OpStore %BP_out_color %BP_clr_transformed\n"
709 "${interface_op_func:opt}\n"
711 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
712 "%getId_label = OpLabel\n"
713 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
714 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
715 "%TC_0_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n"
716 "%TC_1_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n"
717 "%TC_2_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n"
718 "%TC_W_0 = OpLoad %f32 %TC_0_loc\n"
719 "%TC_W_1 = OpLoad %f32 %TC_1_loc\n"
720 "%TC_W_2 = OpLoad %f32 %TC_2_loc\n"
721 "%is_W_0_1 = OpFOrdEqual %bool %TC_W_0 %c_f32_1\n"
722 "%is_W_1_0 = OpFOrdEqual %bool %TC_W_1 %c_f32_0\n"
723 "%is_W_2_0 = OpFOrdEqual %bool %TC_W_2 %c_f32_0\n"
724 "%is_tessCoord_1_0 = OpLogicalAnd %bool %is_W_0_1 %is_W_1_0\n"
725 "%is_tessCoord_1_0_0 = OpLogicalAnd %bool %is_tessCoord_1_0 %is_W_2_0\n"
726 "%is_unique_id_0 = OpLogicalAnd %bool %is_tessCoord_1_0_0 %is_primitive_0\n"
727 "OpReturnValue %is_unique_id_0\n"
731 return tcu::StringTemplate(tessEvalBoilerplate).specialize(fragments);
734 // Creates geometry-shader assembly by specializing a boilerplate StringTemplate
735 // on fragments, which must (at least) map "testfun" to an OpFunction definition
736 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
737 // with "BP_" to avoid collisions with fragments.
739 // Derived from this GLSL:
742 // layout(triangles) in;
743 // layout(triangle_strip, max_vertices = 3) out;
745 // layout(location = 1) in vec4 in_color[];
746 // layout(location = 1) out vec4 out_color;
749 // gl_Position = gl_in[0].gl_Position;
750 // out_color = test_fun(in_color[0]);
752 // gl_Position = gl_in[1].gl_Position;
753 // out_color = test_fun(in_color[1]);
755 // gl_Position = gl_in[2].gl_Position;
756 // out_color = test_fun(in_color[2]);
760 string makeGeometryShaderAssembly (const map<string, string>& fragments)
762 static const char geometryShaderBoilerplate[] =
763 "OpCapability Geometry\n"
764 "OpCapability ClipDistance\n"
765 "OpCapability CullDistance\n"
766 "${capability:opt}\n"
768 "OpMemoryModel Logical GLSL450\n"
769 "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"
770 "OpExecutionMode %BP_main Triangles\n"
771 "OpExecutionMode %BP_main OutputTriangleStrip\n"
772 "OpExecutionMode %BP_main OutputVertices 3\n"
774 "${moduleprocessed:opt}\n"
775 "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n"
776 "OpDecorate %BP_out_gl_position BuiltIn Position\n"
777 "OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n"
778 "OpMemberDecorate %BP_per_vertex_in 1 BuiltIn PointSize\n"
779 "OpMemberDecorate %BP_per_vertex_in 2 BuiltIn ClipDistance\n"
780 "OpMemberDecorate %BP_per_vertex_in 3 BuiltIn CullDistance\n"
781 "OpDecorate %BP_per_vertex_in Block\n"
782 "OpDecorate %BP_out_color Location 1\n"
783 "OpDecorate %BP_in_color Location 1\n"
784 "${IF_decoration:opt}\n"
785 "${decoration:opt}\n"
787 SPIRV_ASSEMBLY_CONSTANTS
788 SPIRV_ASSEMBLY_ARRAYS
789 "%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
790 "%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n"
791 "%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n"
792 "%BP_pp_i32 = OpTypePointer Private %i32\n"
793 "%BP_pp_v4i32 = OpTypePointer Private %v4i32\n"
795 "%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n"
796 "%BP_out_color = OpVariable %op_v4f32 Output\n"
797 "%BP_in_color = OpVariable %ip_a3v4f32 Input\n"
798 "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n"
799 "%BP_out_gl_position = OpVariable %op_v4f32 Output\n"
800 "%BP_vertexIdInCurrentPatch = OpVariable %BP_pp_v4i32 Private\n"
802 "${IF_variable:opt}\n"
804 "%BP_main = OpFunction %void None %fun\n"
805 "%BP_label = OpLabel\n"
807 "${IF_carryforward:opt}\n"
808 "${post_interface_op_geom:opt}\n"
810 "%BP_primitiveId = OpLoad %i32 %BP_gl_PrimitiveID\n"
811 "%BP_addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %BP_primitiveId\n"
813 "%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n"
814 "%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n"
815 "%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n"
817 "%BP_in_position_0 = OpLoad %v4f32 %BP_gl_in_0_gl_position\n"
818 "%BP_in_position_1 = OpLoad %v4f32 %BP_gl_in_1_gl_position\n"
819 "%BP_in_position_2 = OpLoad %v4f32 %BP_gl_in_2_gl_position \n"
821 "%BP_in_color_0_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n"
822 "%BP_in_color_1_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n"
823 "%BP_in_color_2_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n"
825 "%BP_in_color_0 = OpLoad %v4f32 %BP_in_color_0_ptr\n"
826 "%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n"
827 "%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n"
829 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_0\n"
830 "%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n"
831 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_1\n"
832 "%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n"
833 "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_2\n"
834 "%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n"
837 "OpStore %BP_out_gl_position %BP_in_position_0\n"
838 "OpStore %BP_out_color %BP_transformed_in_color_0\n"
841 "OpStore %BP_out_gl_position %BP_in_position_1\n"
842 "OpStore %BP_out_color %BP_transformed_in_color_1\n"
845 "OpStore %BP_out_gl_position %BP_in_position_2\n"
846 "OpStore %BP_out_color %BP_transformed_in_color_2\n"
852 "${interface_op_func:opt}\n"
854 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
855 "%getId_label = OpLabel\n"
856 "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n"
857 "%addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %primitive_id\n"
858 "%vertexIdInCurrentPatch = OpLoad %i32 %addr_vertexIdInCurrentPatch\n"
859 "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n"
860 "%is_vertex_0 = OpIEqual %bool %vertexIdInCurrentPatch %c_i32_0\n"
861 "%is_unique_id_0 = OpLogicalAnd %bool %is_primitive_0 %is_vertex_0\n"
862 "OpReturnValue %is_unique_id_0\n"
866 return tcu::StringTemplate(geometryShaderBoilerplate).specialize(fragments);
869 // Creates fragment-shader assembly by specializing a boilerplate StringTemplate
870 // on fragments, which must (at least) map "testfun" to an OpFunction definition
871 // for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed
872 // with "BP_" to avoid collisions with fragments.
874 // Derived from this GLSL:
876 // layout(location = 1) in highp vec4 vtxColor;
877 // layout(location = 0) out highp vec4 fragColor;
878 // highp vec4 testfun(highp vec4 x) { return x; }
879 // void main(void) { fragColor = testfun(vtxColor); }
881 // with modifications including passing vtxColor by value and ripping out
882 // testfun() definition.
883 string makeFragmentShaderAssembly (const map<string, string>& fragments)
885 static const char fragmentShaderBoilerplate[] =
886 "OpCapability Shader\n"
887 "${capability:opt}\n"
889 "OpMemoryModel Logical GLSL450\n"
890 "OpEntryPoint Fragment %BP_main \"main\" %BP_vtxColor %BP_fragColor %BP_gl_FragCoord ${IF_entrypoint:opt} \n"
891 "OpExecutionMode %BP_main OriginUpperLeft\n"
893 "${moduleprocessed:opt}\n"
894 "OpDecorate %BP_fragColor Location 0\n"
895 "OpDecorate %BP_vtxColor Location 1\n"
896 "OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n"
897 "${IF_decoration:opt}\n"
898 "${decoration:opt}\n"
900 SPIRV_ASSEMBLY_CONSTANTS
901 SPIRV_ASSEMBLY_ARRAYS
902 "%BP_gl_FragCoord = OpVariable %ip_v4f32 Input\n"
903 "%BP_fragColor = OpVariable %op_v4f32 Output\n"
904 "%BP_vtxColor = OpVariable %ip_v4f32 Input\n"
906 "${IF_variable:opt}\n"
907 "%BP_main = OpFunction %void None %fun\n"
908 "%BP_label_main = OpLabel\n"
909 "${IF_carryforward:opt}\n"
910 "${post_interface_op_frag:opt}\n"
911 "%BP_tmp1 = OpLoad %v4f32 %BP_vtxColor\n"
912 "%BP_tmp2 = OpFunctionCall %v4f32 %test_code %BP_tmp1\n"
913 "OpStore %BP_fragColor %BP_tmp2\n"
916 "${interface_op_func:opt}\n"
918 "%isUniqueIdZero = OpFunction %bool None %bool_function\n"
919 "%getId_label = OpLabel\n"
920 "%loc_x_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n"
921 "%loc_y_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n"
922 "%x_coord = OpLoad %f32 %loc_x_coord\n"
923 "%y_coord = OpLoad %f32 %loc_y_coord\n"
924 "%is_x_idx0 = OpFOrdEqual %bool %x_coord %c_f32_0_5\n"
925 "%is_y_idx0 = OpFOrdEqual %bool %y_coord %c_f32_0_5\n"
926 "%is_frag_0 = OpLogicalAnd %bool %is_x_idx0 %is_y_idx0\n"
927 "OpReturnValue %is_frag_0\n"
931 return tcu::StringTemplate(fragmentShaderBoilerplate).specialize(fragments);
934 // Creates mappings from placeholders to pass-through shader code which copies
935 // the input to the output faithfully.
936 map<string, string> passthruInterface (const IFDataType& data_type)
938 const string var_type = data_type.str();
939 map<string, string> fragments = passthruFragments();
940 const string functype = string("%") + var_type + "_" + var_type + "_function";
942 fragments["interface_op_func"] =
943 string("%interface_op_func = OpFunction %") + var_type + " None " + functype + "\n"
944 " %io_param1 = OpFunctionParameter %" + var_type + "\n"
945 " %IF_label = OpLabel\n"
946 " OpReturnValue %io_param1\n"
948 fragments["input_type"] = var_type;
949 fragments["output_type"] = var_type;
950 fragments["pre_main"] = "";
952 if (!data_type.elementIs32bit())
954 if (data_type.elementType == NUMBERTYPE_FLOAT64)
956 fragments["capability"] = "OpCapability Float64\n\n";
957 fragments["pre_main"] += "%f64 = OpTypeFloat 64\n";
959 else if (data_type.elementType == NUMBERTYPE_FLOAT16)
961 fragments["capability"] = "OpCapability StorageInputOutput16\n";
962 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
963 fragments["pre_main"] += "%f16 = OpTypeFloat 16\n";
965 else if (data_type.elementType == NUMBERTYPE_INT16)
967 fragments["capability"] = "OpCapability StorageInputOutput16\n";
968 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
969 fragments["pre_main"] += "%i16 = OpTypeInt 16 1\n";
971 else if (data_type.elementType == NUMBERTYPE_UINT16)
973 fragments["capability"] = "OpCapability StorageInputOutput16\n";
974 fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n";
975 fragments["pre_main"] += "%u16 = OpTypeInt 16 0\n";
979 DE_ASSERT(0 && "unhandled type");
982 if (data_type.isVector())
984 fragments["pre_main"] += "%" + var_type + " = OpTypeVector %" + IFDataType(1, data_type.elementType).str() + " " + numberToString(data_type.numElements) + "\n";
987 fragments["pre_main"] +=
988 "%ip_" + var_type + " = OpTypePointer Input %" + var_type + "\n"
989 "%op_" + var_type + " = OpTypePointer Output %" + var_type + "\n";
992 if (strcmp(var_type.c_str(), "v4f32") != 0)
993 fragments["pre_main"] +=
994 functype + " = OpTypeFunction %" + var_type + " %" + var_type + "\n"
995 "%a3" + var_type + " = OpTypeArray %" + var_type + " %c_i32_3\n"
996 "%ip_a3" + var_type + " = OpTypePointer Input %a3" + var_type + "\n"
997 "%op_a3" + var_type + " = OpTypePointer Output %a3" + var_type + "\n";
1002 // Returns mappings from interface placeholders to their concrete values.
1004 // The concrete values should be specialized again to provide ${input_type}
1005 // and ${output_type}.
1007 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1008 map<string, string> fillInterfacePlaceholderVert (void)
1010 map<string, string> fragments;
1012 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1013 fragments["IF_variable"] =
1014 " %IF_input = OpVariable %ip_${input_type} Input\n"
1015 "%IF_output = OpVariable %op_${output_type} Output\n";
1016 fragments["IF_decoration"] =
1017 "OpDecorate %IF_input Location 2\n"
1018 "OpDecorate %IF_output Location 2\n";
1019 fragments["IF_carryforward"] =
1020 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1021 " %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1022 " OpStore %IF_output %IF_result\n";
1024 // Make sure the rest still need to be instantialized.
1025 fragments["capability"] = "${capability:opt}";
1026 fragments["extension"] = "${extension:opt}";
1027 fragments["debug"] = "${debug:opt}";
1028 fragments["decoration"] = "${decoration:opt}";
1029 fragments["pre_main"] = "${pre_main:opt}";
1030 fragments["testfun"] = "${testfun}";
1031 fragments["interface_op_func"] = "${interface_op_func}";
1032 fragments["post_interface_op_vert"] = "${post_interface_op_vert:opt}";
1037 // Returns mappings from interface placeholders to their concrete values.
1039 // The concrete values should be specialized again to provide ${input_type}
1040 // and ${output_type}.
1042 // %ip_${input_type} and %op_${output_type} should also be defined in the final code.
1043 map<string, string> fillInterfacePlaceholderFrag (void)
1045 map<string, string> fragments;
1047 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1048 fragments["IF_variable"] =
1049 " %IF_input = OpVariable %ip_${input_type} Input\n"
1050 "%IF_output = OpVariable %op_${output_type} Output\n";
1051 fragments["IF_decoration"] =
1052 "OpDecorate %IF_input Flat\n"
1053 "OpDecorate %IF_input Location 2\n"
1054 "OpDecorate %IF_output Location 1\n"; // Fragment shader should write to location #1.
1055 fragments["IF_carryforward"] =
1056 "%IF_input_val = OpLoad %${input_type} %IF_input\n"
1057 " %IF_result = OpFunctionCall %${output_type} %interface_op_func %IF_input_val\n"
1058 " OpStore %IF_output %IF_result\n";
1060 // Make sure the rest still need to be instantialized.
1061 fragments["capability"] = "${capability:opt}";
1062 fragments["extension"] = "${extension:opt}";
1063 fragments["debug"] = "${debug:opt}";
1064 fragments["decoration"] = "${decoration:opt}";
1065 fragments["pre_main"] = "${pre_main:opt}";
1066 fragments["testfun"] = "${testfun}";
1067 fragments["interface_op_func"] = "${interface_op_func}";
1068 fragments["post_interface_op_frag"] = "${post_interface_op_frag:opt}";
1073 // Returns mappings from interface placeholders to their concrete values.
1075 // The concrete values should be specialized again to provide ${input_type}
1076 // and ${output_type}.
1078 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1079 // should also be defined in the final code.
1080 map<string, string> fillInterfacePlaceholderTessCtrl (void)
1082 map<string, string> fragments;
1084 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1085 fragments["IF_variable"] =
1086 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1087 "%IF_output = OpVariable %op_a3${output_type} Output\n";
1088 fragments["IF_decoration"] =
1089 "OpDecorate %IF_input Location 2\n"
1090 "OpDecorate %IF_output Location 2\n";
1091 fragments["IF_carryforward"] =
1092 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1093 " %IF_input_ptr1 = OpAccessChain %ip_${input_type} %IF_input %c_i32_1\n"
1094 " %IF_input_ptr2 = OpAccessChain %ip_${input_type} %IF_input %c_i32_2\n"
1095 "%IF_output_ptr0 = OpAccessChain %op_${output_type} %IF_output %c_i32_0\n"
1096 "%IF_output_ptr1 = OpAccessChain %op_${output_type} %IF_output %c_i32_1\n"
1097 "%IF_output_ptr2 = OpAccessChain %op_${output_type} %IF_output %c_i32_2\n"
1098 "%IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1099 "%IF_input_val1 = OpLoad %${input_type} %IF_input_ptr1\n"
1100 "%IF_input_val2 = OpLoad %${input_type} %IF_input_ptr2\n"
1101 "%IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1102 "%IF_input_res1 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val1\n"
1103 "%IF_input_res2 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val2\n"
1104 "OpStore %IF_output_ptr0 %IF_input_res0\n"
1105 "OpStore %IF_output_ptr1 %IF_input_res1\n"
1106 "OpStore %IF_output_ptr2 %IF_input_res2\n";
1108 // Make sure the rest still need to be instantialized.
1109 fragments["capability"] = "${capability:opt}";
1110 fragments["extension"] = "${extension:opt}";
1111 fragments["debug"] = "${debug:opt}";
1112 fragments["decoration"] = "${decoration:opt}";
1113 fragments["decoration_tessc"] = "${decoration_tessc:opt}";
1114 fragments["pre_main"] = "${pre_main:opt}";
1115 fragments["testfun"] = "${testfun}";
1116 fragments["interface_op_func"] = "${interface_op_func}";
1117 fragments["post_interface_op_tessc"] = "${post_interface_op_tessc:opt}";
1122 // Returns mappings from interface placeholders to their concrete values.
1124 // The concrete values should be specialized again to provide ${input_type}
1125 // and ${output_type}.
1127 // %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type}
1128 // should also be defined in the final code.
1129 map<string, string> fillInterfacePlaceholderTessEvalGeom (void)
1131 map<string, string> fragments;
1133 fragments["IF_entrypoint"] = "%IF_input %IF_output";
1134 fragments["IF_variable"] =
1135 " %IF_input = OpVariable %ip_a3${input_type} Input\n"
1136 "%IF_output = OpVariable %op_${output_type} Output\n";
1137 fragments["IF_decoration"] =
1138 "OpDecorate %IF_input Location 2\n"
1139 "OpDecorate %IF_output Location 2\n";
1140 fragments["IF_carryforward"] =
1141 // Only get the first value since all three values are the same anyway.
1142 " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n"
1143 " %IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n"
1144 " %IF_input_res0 = OpFunctionCall %${output_type} %interface_op_func %IF_input_val0\n"
1145 "OpStore %IF_output %IF_input_res0\n";
1147 // Make sure the rest still need to be instantialized.
1148 fragments["capability"] = "${capability:opt}";
1149 fragments["extension"] = "${extension:opt}";
1150 fragments["debug"] = "${debug:opt}";
1151 fragments["decoration"] = "${decoration:opt}";
1152 fragments["pre_main"] = "${pre_main:opt}";
1153 fragments["testfun"] = "${testfun}";
1154 fragments["interface_op_func"] = "${interface_op_func}";
1155 fragments["post_interface_op_tesse"] = "${post_interface_op_tesse:opt}";
1156 fragments["post_interface_op_geom"] = "${post_interface_op_geom:opt}";
1161 map<string, string> passthruFragments (void)
1163 map<string, string> fragments;
1164 fragments["testfun"] =
1165 // A %test_code function that returns its argument unchanged.
1166 "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
1167 "%param1 = OpFunctionParameter %v4f32\n"
1168 "%label_testfun = OpLabel\n"
1169 "OpReturnValue %param1\n"
1174 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1175 // Vertex shader gets custom code from context, the rest are pass-through.
1176 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1178 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1179 SpirvVersion targetSpirvVersion;
1181 if (spirVAsmBuildOptions == DE_NULL)
1182 targetSpirvVersion = context.resources.spirvVersion;
1184 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1186 if (!context.interfaces.empty())
1188 // Inject boilerplate code to wire up additional input/output variables between stages.
1189 // Just copy the contents in input variable to output variable in all stages except
1190 // the customized stage.
1191 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1192 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1194 map<string, string> passthru = passthruFragments();
1196 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1197 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1201 void addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext context)
1203 addShaderCodeCustomVertex(dst, context, DE_NULL);
1206 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1207 // Tessellation control shader gets custom code from context, the rest are
1209 void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1211 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1212 SpirvVersion targetSpirvVersion;
1214 if (spirVAsmBuildOptions == DE_NULL)
1215 targetSpirvVersion = context.resources.spirvVersion;
1217 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1219 if (!context.interfaces.empty())
1221 // Inject boilerplate code to wire up additional input/output variables between stages.
1222 // Just copy the contents in input variable to output variable in all stages except
1223 // the customized stage.
1224 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1225 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1226 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1227 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1231 map<string, string> passthru = passthruFragments();
1233 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1234 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1235 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1236 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1240 void addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext context)
1242 addShaderCodeCustomTessControl(dst, context, DE_NULL);
1245 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1246 // Tessellation evaluation shader gets custom code from context, the rest are
1248 void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1250 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1251 SpirvVersion targetSpirvVersion;
1253 if (spirVAsmBuildOptions == DE_NULL)
1254 targetSpirvVersion = context.resources.spirvVersion;
1256 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1258 if (!context.interfaces.empty())
1260 // Inject boilerplate code to wire up additional input/output variables between stages.
1261 // Just copy the contents in input variable to output variable in all stages except
1262 // the customized stage.
1263 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1264 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1265 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1266 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1270 map<string, string> passthru = passthruFragments();
1271 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1272 dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1273 dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1274 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1278 void addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext context)
1280 addShaderCodeCustomTessEval(dst, context, DE_NULL);
1283 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1284 // Geometry shader gets custom code from context, the rest are pass-through.
1285 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1287 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1288 SpirvVersion targetSpirvVersion;
1290 if (spirVAsmBuildOptions == DE_NULL)
1291 targetSpirvVersion = context.resources.spirvVersion;
1293 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1295 if (!context.interfaces.empty())
1297 // Inject boilerplate code to wire up additional input/output variables between stages.
1298 // Just copy the contents in input variable to output variable in all stages except
1299 // the customized stage.
1300 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1301 dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1302 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1306 map<string, string> passthru = passthruFragments();
1307 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1308 dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << makeGeometryShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1309 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1313 void addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext context)
1315 addShaderCodeCustomGeometry(dst, context, DE_NULL);
1318 // Adds shader assembly text to dst.spirvAsmSources for all shader kinds.
1319 // Fragment shader gets custom code from context, the rest are pass-through.
1320 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions)
1322 const deUint32 vulkanVersion = dst.usedVulkanVersion;
1323 SpirvVersion targetSpirvVersion;
1325 if (spirVAsmBuildOptions == DE_NULL)
1326 targetSpirvVersion = context.resources.spirvVersion;
1328 targetSpirvVersion = spirVAsmBuildOptions->targetVersion;
1330 if (!context.interfaces.empty())
1332 // Inject boilerplate code to wire up additional input/output variables between stages.
1333 // Just copy the contents in input variable to output variable in all stages except
1334 // the customized stage.
1335 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1336 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1340 map<string, string> passthru = passthruFragments();
1341 dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1342 dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion);
1346 void addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext context)
1348 addShaderCodeCustomFragment(dst, context, DE_NULL);
1351 void createCombinedModule (vk::SourceCollections& dst, InstanceContext)
1353 // \todo [2015-12-07 awoloszyn] Make tessellation / geometry conditional
1354 dst.spirvAsmSources.add("module") <<
1355 "OpCapability Shader\n"
1356 "OpCapability ClipDistance\n"
1357 "OpCapability CullDistance\n"
1358 "OpCapability Geometry\n"
1359 "OpCapability Tessellation\n"
1360 "OpMemoryModel Logical GLSL450\n"
1362 "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_vtxPosition %vert_vertex_id %vert_instance_id\n"
1363 "OpEntryPoint Geometry %geom_main \"main\" %geom_out_gl_position %geom_gl_in %geom_out_color %geom_in_color\n"
1364 "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"
1365 "OpEntryPoint TessellationEvaluation %tesse_main \"main\" %tesse_stream %tesse_gl_tessCoord %tesse_in_position %tesse_out_color %tesse_in_color \n"
1366 "OpEntryPoint Fragment %frag_main \"main\" %frag_vtxColor %frag_fragColor\n"
1368 "OpExecutionMode %geom_main Triangles\n"
1369 "OpExecutionMode %geom_main OutputTriangleStrip\n"
1370 "OpExecutionMode %geom_main OutputVertices 3\n"
1372 "OpExecutionMode %tessc_main OutputVertices 3\n"
1374 "OpExecutionMode %tesse_main Triangles\n"
1375 "OpExecutionMode %tesse_main SpacingEqual\n"
1376 "OpExecutionMode %tesse_main VertexOrderCcw\n"
1378 "OpExecutionMode %frag_main OriginUpperLeft\n"
1380 "; Vertex decorations\n"
1381 "OpDecorate %vert_vtxPosition Location 2\n"
1382 "OpDecorate %vert_Position Location 0\n"
1383 "OpDecorate %vert_vtxColor Location 1\n"
1384 "OpDecorate %vert_color Location 1\n"
1385 "OpDecorate %vert_vertex_id BuiltIn VertexIndex\n"
1386 "OpDecorate %vert_instance_id BuiltIn InstanceIndex\n"
1388 "; Geometry decorations\n"
1389 "OpDecorate %geom_out_gl_position BuiltIn Position\n"
1390 "OpMemberDecorate %geom_per_vertex_in 0 BuiltIn Position\n"
1391 "OpMemberDecorate %geom_per_vertex_in 1 BuiltIn PointSize\n"
1392 "OpMemberDecorate %geom_per_vertex_in 2 BuiltIn ClipDistance\n"
1393 "OpMemberDecorate %geom_per_vertex_in 3 BuiltIn CullDistance\n"
1394 "OpDecorate %geom_per_vertex_in Block\n"
1395 "OpDecorate %geom_out_color Location 1\n"
1396 "OpDecorate %geom_in_color Location 1\n"
1398 "; Tessellation Control decorations\n"
1399 "OpDecorate %tessc_out_color Location 1\n"
1400 "OpDecorate %tessc_gl_InvocationID BuiltIn InvocationId\n"
1401 "OpDecorate %tessc_in_color Location 1\n"
1402 "OpDecorate %tessc_out_position Location 2\n"
1403 "OpDecorate %tessc_in_position Location 2\n"
1404 "OpDecorate %tessc_gl_TessLevelOuter Patch\n"
1405 "OpDecorate %tessc_gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1406 "OpDecorate %tessc_gl_TessLevelInner Patch\n"
1407 "OpDecorate %tessc_gl_TessLevelInner BuiltIn TessLevelInner\n"
1409 "; Tessellation Evaluation decorations\n"
1410 "OpMemberDecorate %tesse_per_vertex_out 0 BuiltIn Position\n"
1411 "OpMemberDecorate %tesse_per_vertex_out 1 BuiltIn PointSize\n"
1412 "OpMemberDecorate %tesse_per_vertex_out 2 BuiltIn ClipDistance\n"
1413 "OpMemberDecorate %tesse_per_vertex_out 3 BuiltIn CullDistance\n"
1414 "OpDecorate %tesse_per_vertex_out Block\n"
1415 "OpDecorate %tesse_gl_tessCoord BuiltIn TessCoord\n"
1416 "OpDecorate %tesse_in_position Location 2\n"
1417 "OpDecorate %tesse_out_color Location 1\n"
1418 "OpDecorate %tesse_in_color Location 1\n"
1420 "; Fragment decorations\n"
1421 "OpDecorate %frag_fragColor Location 0\n"
1422 "OpDecorate %frag_vtxColor Location 1\n"
1424 SPIRV_ASSEMBLY_TYPES
1425 SPIRV_ASSEMBLY_CONSTANTS
1426 SPIRV_ASSEMBLY_ARRAYS
1428 "; Vertex Variables\n"
1429 "%vert_vtxPosition = OpVariable %op_v4f32 Output\n"
1430 "%vert_Position = OpVariable %ip_v4f32 Input\n"
1431 "%vert_vtxColor = OpVariable %op_v4f32 Output\n"
1432 "%vert_color = OpVariable %ip_v4f32 Input\n"
1433 "%vert_vertex_id = OpVariable %ip_i32 Input\n"
1434 "%vert_instance_id = OpVariable %ip_i32 Input\n"
1436 "; Geometry Variables\n"
1437 "%geom_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1438 "%geom_a3_per_vertex_in = OpTypeArray %geom_per_vertex_in %c_u32_3\n"
1439 "%geom_ip_a3_per_vertex_in = OpTypePointer Input %geom_a3_per_vertex_in\n"
1440 "%geom_gl_in = OpVariable %geom_ip_a3_per_vertex_in Input\n"
1441 "%geom_out_color = OpVariable %op_v4f32 Output\n"
1442 "%geom_in_color = OpVariable %ip_a3v4f32 Input\n"
1443 "%geom_out_gl_position = OpVariable %op_v4f32 Output\n"
1445 "; Tessellation Control Variables\n"
1446 "%tessc_out_color = OpVariable %op_a3v4f32 Output\n"
1447 "%tessc_gl_InvocationID = OpVariable %ip_i32 Input\n"
1448 "%tessc_in_color = OpVariable %ip_a32v4f32 Input\n"
1449 "%tessc_out_position = OpVariable %op_a3v4f32 Output\n"
1450 "%tessc_in_position = OpVariable %ip_a32v4f32 Input\n"
1451 "%tessc_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1452 "%tessc_gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1454 "; Tessellation Evaluation Decorations\n"
1455 "%tesse_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1456 "%tesse_op_per_vertex_out = OpTypePointer Output %tesse_per_vertex_out\n"
1457 "%tesse_stream = OpVariable %tesse_op_per_vertex_out Output\n"
1458 "%tesse_gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1459 "%tesse_in_position = OpVariable %ip_a32v4f32 Input\n"
1460 "%tesse_out_color = OpVariable %op_v4f32 Output\n"
1461 "%tesse_in_color = OpVariable %ip_a32v4f32 Input\n"
1463 "; Fragment Variables\n"
1464 "%frag_fragColor = OpVariable %op_v4f32 Output\n"
1465 "%frag_vtxColor = OpVariable %ip_v4f32 Input\n"
1468 "%vert_main = OpFunction %void None %fun\n"
1469 "%vert_label = OpLabel\n"
1470 "%vert_tmp_position = OpLoad %v4f32 %vert_Position\n"
1471 "OpStore %vert_vtxPosition %vert_tmp_position\n"
1472 "%vert_tmp_color = OpLoad %v4f32 %vert_color\n"
1473 "OpStore %vert_vtxColor %vert_tmp_color\n"
1477 "; Geometry Entry\n"
1478 "%geom_main = OpFunction %void None %fun\n"
1479 "%geom_label = OpLabel\n"
1480 "%geom_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_0 %c_i32_0\n"
1481 "%geom_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_1 %c_i32_0\n"
1482 "%geom_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_2 %c_i32_0\n"
1483 "%geom_in_position_0 = OpLoad %v4f32 %geom_gl_in_0_gl_position\n"
1484 "%geom_in_position_1 = OpLoad %v4f32 %geom_gl_in_1_gl_position\n"
1485 "%geom_in_position_2 = OpLoad %v4f32 %geom_gl_in_2_gl_position \n"
1486 "%geom_in_color_0_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_0\n"
1487 "%geom_in_color_1_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_1\n"
1488 "%geom_in_color_2_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_2\n"
1489 "%geom_in_color_0 = OpLoad %v4f32 %geom_in_color_0_ptr\n"
1490 "%geom_in_color_1 = OpLoad %v4f32 %geom_in_color_1_ptr\n"
1491 "%geom_in_color_2 = OpLoad %v4f32 %geom_in_color_2_ptr\n"
1492 "OpStore %geom_out_gl_position %geom_in_position_0\n"
1493 "OpStore %geom_out_color %geom_in_color_0\n"
1495 "OpStore %geom_out_gl_position %geom_in_position_1\n"
1496 "OpStore %geom_out_color %geom_in_color_1\n"
1498 "OpStore %geom_out_gl_position %geom_in_position_2\n"
1499 "OpStore %geom_out_color %geom_in_color_2\n"
1505 "; Tessellation Control Entry\n"
1506 "%tessc_main = OpFunction %void None %fun\n"
1507 "%tessc_label = OpLabel\n"
1508 "%tessc_invocation_id = OpLoad %i32 %tessc_gl_InvocationID\n"
1509 "%tessc_in_color_ptr = OpAccessChain %ip_v4f32 %tessc_in_color %tessc_invocation_id\n"
1510 "%tessc_in_position_ptr = OpAccessChain %ip_v4f32 %tessc_in_position %tessc_invocation_id\n"
1511 "%tessc_in_color_val = OpLoad %v4f32 %tessc_in_color_ptr\n"
1512 "%tessc_in_position_val = OpLoad %v4f32 %tessc_in_position_ptr\n"
1513 "%tessc_out_color_ptr = OpAccessChain %op_v4f32 %tessc_out_color %tessc_invocation_id\n"
1514 "%tessc_out_position_ptr = OpAccessChain %op_v4f32 %tessc_out_position %tessc_invocation_id\n"
1515 "OpStore %tessc_out_color_ptr %tessc_in_color_val\n"
1516 "OpStore %tessc_out_position_ptr %tessc_in_position_val\n"
1517 "%tessc_is_first_invocation = OpIEqual %bool %tessc_invocation_id %c_i32_0\n"
1518 "OpSelectionMerge %tessc_merge_label None\n"
1519 "OpBranchConditional %tessc_is_first_invocation %tessc_first_invocation %tessc_merge_label\n"
1520 "%tessc_first_invocation = OpLabel\n"
1521 "%tessc_tess_outer_0 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_0\n"
1522 "%tessc_tess_outer_1 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_1\n"
1523 "%tessc_tess_outer_2 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_2\n"
1524 "%tessc_tess_inner = OpAccessChain %op_f32 %tessc_gl_TessLevelInner %c_i32_0\n"
1525 "OpStore %tessc_tess_outer_0 %c_f32_1\n"
1526 "OpStore %tessc_tess_outer_1 %c_f32_1\n"
1527 "OpStore %tessc_tess_outer_2 %c_f32_1\n"
1528 "OpStore %tessc_tess_inner %c_f32_1\n"
1529 "OpBranch %tessc_merge_label\n"
1530 "%tessc_merge_label = OpLabel\n"
1534 "; Tessellation Evaluation Entry\n"
1535 "%tesse_main = OpFunction %void None %fun\n"
1536 "%tesse_label = OpLabel\n"
1537 "%tesse_tc_0_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_0\n"
1538 "%tesse_tc_1_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_1\n"
1539 "%tesse_tc_2_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_2\n"
1540 "%tesse_tc_0 = OpLoad %f32 %tesse_tc_0_ptr\n"
1541 "%tesse_tc_1 = OpLoad %f32 %tesse_tc_1_ptr\n"
1542 "%tesse_tc_2 = OpLoad %f32 %tesse_tc_2_ptr\n"
1543 "%tesse_in_pos_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_0\n"
1544 "%tesse_in_pos_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_1\n"
1545 "%tesse_in_pos_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_2\n"
1546 "%tesse_in_pos_0 = OpLoad %v4f32 %tesse_in_pos_0_ptr\n"
1547 "%tesse_in_pos_1 = OpLoad %v4f32 %tesse_in_pos_1_ptr\n"
1548 "%tesse_in_pos_2 = OpLoad %v4f32 %tesse_in_pos_2_ptr\n"
1549 "%tesse_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_0 %tesse_tc_0\n"
1550 "%tesse_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_1 %tesse_tc_1\n"
1551 "%tesse_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_2 %tesse_tc_2\n"
1552 "%tesse_out_pos_ptr = OpAccessChain %op_v4f32 %tesse_stream %c_i32_0\n"
1553 "%tesse_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse_in_pos_0_weighted %tesse_in_pos_1_weighted\n"
1554 "%tesse_computed_out = OpFAdd %v4f32 %tesse_in_pos_0_plus_pos_1 %tesse_in_pos_2_weighted\n"
1555 "OpStore %tesse_out_pos_ptr %tesse_computed_out\n"
1556 "%tesse_in_clr_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_0\n"
1557 "%tesse_in_clr_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_1\n"
1558 "%tesse_in_clr_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_2\n"
1559 "%tesse_in_clr_0 = OpLoad %v4f32 %tesse_in_clr_0_ptr\n"
1560 "%tesse_in_clr_1 = OpLoad %v4f32 %tesse_in_clr_1_ptr\n"
1561 "%tesse_in_clr_2 = OpLoad %v4f32 %tesse_in_clr_2_ptr\n"
1562 "%tesse_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_0 %tesse_tc_0\n"
1563 "%tesse_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_1 %tesse_tc_1\n"
1564 "%tesse_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_2 %tesse_tc_2\n"
1565 "%tesse_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse_in_clr_0_weighted %tesse_in_clr_1_weighted\n"
1566 "%tesse_computed_clr = OpFAdd %v4f32 %tesse_in_clr_0_plus_col_1 %tesse_in_clr_2_weighted\n"
1567 "OpStore %tesse_out_color %tesse_computed_clr\n"
1571 "; Fragment Entry\n"
1572 "%frag_main = OpFunction %void None %fun\n"
1573 "%frag_label_main = OpLabel\n"
1574 "%frag_tmp1 = OpLoad %v4f32 %frag_vtxColor\n"
1575 "OpStore %frag_fragColor %frag_tmp1\n"
1580 void createMultipleEntries (vk::SourceCollections& dst, InstanceContext)
1582 dst.spirvAsmSources.add("vert") <<
1583 // This module contains 2 vertex shaders. One that is a passthrough
1584 // and a second that inverts the color of the output (1.0 - color).
1585 "OpCapability Shader\n"
1586 "OpMemoryModel Logical GLSL450\n"
1587 "OpEntryPoint Vertex %main \"vert1\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1588 "OpEntryPoint Vertex %main2 \"vert2\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n"
1590 "OpDecorate %vtxPosition Location 2\n"
1591 "OpDecorate %Position Location 0\n"
1592 "OpDecorate %vtxColor Location 1\n"
1593 "OpDecorate %color Location 1\n"
1594 "OpDecorate %vertex_id BuiltIn VertexIndex\n"
1595 "OpDecorate %instance_id BuiltIn InstanceIndex\n"
1596 SPIRV_ASSEMBLY_TYPES
1597 SPIRV_ASSEMBLY_CONSTANTS
1598 SPIRV_ASSEMBLY_ARRAYS
1599 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1600 "%vtxPosition = OpVariable %op_v4f32 Output\n"
1601 "%Position = OpVariable %ip_v4f32 Input\n"
1602 "%vtxColor = OpVariable %op_v4f32 Output\n"
1603 "%color = OpVariable %ip_v4f32 Input\n"
1604 "%vertex_id = OpVariable %ip_i32 Input\n"
1605 "%instance_id = OpVariable %ip_i32 Input\n"
1607 "%main = OpFunction %void None %fun\n"
1608 "%label = OpLabel\n"
1609 "%tmp_position = OpLoad %v4f32 %Position\n"
1610 "OpStore %vtxPosition %tmp_position\n"
1611 "%tmp_color = OpLoad %v4f32 %color\n"
1612 "OpStore %vtxColor %tmp_color\n"
1616 "%main2 = OpFunction %void None %fun\n"
1617 "%label2 = OpLabel\n"
1618 "%tmp_position2 = OpLoad %v4f32 %Position\n"
1619 "OpStore %vtxPosition %tmp_position2\n"
1620 "%tmp_color2 = OpLoad %v4f32 %color\n"
1621 "%tmp_color3 = OpFSub %v4f32 %cval %tmp_color2\n"
1622 "%tmp_color4 = OpVectorInsertDynamic %v4f32 %tmp_color3 %c_f32_1 %c_i32_3\n"
1623 "OpStore %vtxColor %tmp_color4\n"
1627 dst.spirvAsmSources.add("frag") <<
1628 // This is a single module that contains 2 fragment shaders.
1629 // One that passes color through and the other that inverts the output
1630 // color (1.0 - color).
1631 "OpCapability Shader\n"
1632 "OpMemoryModel Logical GLSL450\n"
1633 "OpEntryPoint Fragment %main \"frag1\" %vtxColor %fragColor\n"
1634 "OpEntryPoint Fragment %main2 \"frag2\" %vtxColor %fragColor\n"
1635 "OpExecutionMode %main OriginUpperLeft\n"
1636 "OpExecutionMode %main2 OriginUpperLeft\n"
1638 "OpDecorate %fragColor Location 0\n"
1639 "OpDecorate %vtxColor Location 1\n"
1640 SPIRV_ASSEMBLY_TYPES
1641 SPIRV_ASSEMBLY_CONSTANTS
1642 SPIRV_ASSEMBLY_ARRAYS
1643 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1644 "%fragColor = OpVariable %op_v4f32 Output\n"
1645 "%vtxColor = OpVariable %ip_v4f32 Input\n"
1647 "%main = OpFunction %void None %fun\n"
1648 "%label_main = OpLabel\n"
1649 "%tmp1 = OpLoad %v4f32 %vtxColor\n"
1650 "OpStore %fragColor %tmp1\n"
1654 "%main2 = OpFunction %void None %fun\n"
1655 "%label_main2 = OpLabel\n"
1656 "%tmp2 = OpLoad %v4f32 %vtxColor\n"
1657 "%tmp3 = OpFSub %v4f32 %cval %tmp2\n"
1658 "%tmp4 = OpVectorInsertDynamic %v4f32 %tmp3 %c_f32_1 %c_i32_3\n"
1659 "OpStore %fragColor %tmp4\n"
1663 dst.spirvAsmSources.add("geom") <<
1664 "OpCapability Geometry\n"
1665 "OpCapability ClipDistance\n"
1666 "OpCapability CullDistance\n"
1667 "OpMemoryModel Logical GLSL450\n"
1668 "OpEntryPoint Geometry %geom1_main \"geom1\" %out_gl_position %gl_in %out_color %in_color\n"
1669 "OpEntryPoint Geometry %geom2_main \"geom2\" %out_gl_position %gl_in %out_color %in_color\n"
1670 "OpExecutionMode %geom1_main Triangles\n"
1671 "OpExecutionMode %geom2_main Triangles\n"
1672 "OpExecutionMode %geom1_main OutputTriangleStrip\n"
1673 "OpExecutionMode %geom2_main OutputTriangleStrip\n"
1674 "OpExecutionMode %geom1_main OutputVertices 3\n"
1675 "OpExecutionMode %geom2_main OutputVertices 3\n"
1676 "OpDecorate %out_gl_position BuiltIn Position\n"
1677 "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n"
1678 "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n"
1679 "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n"
1680 "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n"
1681 "OpDecorate %per_vertex_in Block\n"
1682 "OpDecorate %out_color Location 1\n"
1683 "OpDecorate %in_color Location 1\n"
1684 SPIRV_ASSEMBLY_TYPES
1685 SPIRV_ASSEMBLY_CONSTANTS
1686 SPIRV_ASSEMBLY_ARRAYS
1687 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1688 "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1689 "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n"
1690 "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n"
1691 "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n"
1692 "%out_color = OpVariable %op_v4f32 Output\n"
1693 "%in_color = OpVariable %ip_a3v4f32 Input\n"
1694 "%out_gl_position = OpVariable %op_v4f32 Output\n"
1696 "%geom1_main = OpFunction %void None %fun\n"
1697 "%geom1_label = OpLabel\n"
1698 "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1699 "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1700 "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1701 "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n"
1702 "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n"
1703 "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n"
1704 "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1705 "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1706 "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1707 "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n"
1708 "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n"
1709 "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n"
1710 "OpStore %out_gl_position %geom1_in_position_0\n"
1711 "OpStore %out_color %geom1_in_color_0\n"
1713 "OpStore %out_gl_position %geom1_in_position_1\n"
1714 "OpStore %out_color %geom1_in_color_1\n"
1716 "OpStore %out_gl_position %geom1_in_position_2\n"
1717 "OpStore %out_color %geom1_in_color_2\n"
1723 "%geom2_main = OpFunction %void None %fun\n"
1724 "%geom2_label = OpLabel\n"
1725 "%geom2_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n"
1726 "%geom2_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n"
1727 "%geom2_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n"
1728 "%geom2_in_position_0 = OpLoad %v4f32 %geom2_gl_in_0_gl_position\n"
1729 "%geom2_in_position_1 = OpLoad %v4f32 %geom2_gl_in_1_gl_position\n"
1730 "%geom2_in_position_2 = OpLoad %v4f32 %geom2_gl_in_2_gl_position \n"
1731 "%geom2_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1732 "%geom2_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1733 "%geom2_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1734 "%geom2_in_color_0 = OpLoad %v4f32 %geom2_in_color_0_ptr\n"
1735 "%geom2_in_color_1 = OpLoad %v4f32 %geom2_in_color_1_ptr\n"
1736 "%geom2_in_color_2 = OpLoad %v4f32 %geom2_in_color_2_ptr\n"
1737 "%geom2_transformed_in_color_0 = OpFSub %v4f32 %cval %geom2_in_color_0\n"
1738 "%geom2_transformed_in_color_1 = OpFSub %v4f32 %cval %geom2_in_color_1\n"
1739 "%geom2_transformed_in_color_2 = OpFSub %v4f32 %cval %geom2_in_color_2\n"
1740 "%geom2_transformed_in_color_0_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_0 %c_f32_1 %c_i32_3\n"
1741 "%geom2_transformed_in_color_1_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_1 %c_f32_1 %c_i32_3\n"
1742 "%geom2_transformed_in_color_2_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_2 %c_f32_1 %c_i32_3\n"
1743 "OpStore %out_gl_position %geom2_in_position_0\n"
1744 "OpStore %out_color %geom2_transformed_in_color_0_a\n"
1746 "OpStore %out_gl_position %geom2_in_position_1\n"
1747 "OpStore %out_color %geom2_transformed_in_color_1_a\n"
1749 "OpStore %out_gl_position %geom2_in_position_2\n"
1750 "OpStore %out_color %geom2_transformed_in_color_2_a\n"
1756 dst.spirvAsmSources.add("tessc") <<
1757 "OpCapability Tessellation\n"
1758 "OpMemoryModel Logical GLSL450\n"
1759 "OpEntryPoint TessellationControl %tessc1_main \"tessc1\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1760 "OpEntryPoint TessellationControl %tessc2_main \"tessc2\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"
1761 "OpExecutionMode %tessc1_main OutputVertices 3\n"
1762 "OpExecutionMode %tessc2_main OutputVertices 3\n"
1763 "OpDecorate %out_color Location 1\n"
1764 "OpDecorate %gl_InvocationID BuiltIn InvocationId\n"
1765 "OpDecorate %in_color Location 1\n"
1766 "OpDecorate %out_position Location 2\n"
1767 "OpDecorate %in_position Location 2\n"
1768 "OpDecorate %gl_TessLevelOuter Patch\n"
1769 "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n"
1770 "OpDecorate %gl_TessLevelInner Patch\n"
1771 "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n"
1772 SPIRV_ASSEMBLY_TYPES
1773 SPIRV_ASSEMBLY_CONSTANTS
1774 SPIRV_ASSEMBLY_ARRAYS
1775 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1776 "%out_color = OpVariable %op_a3v4f32 Output\n"
1777 "%gl_InvocationID = OpVariable %ip_i32 Input\n"
1778 "%in_color = OpVariable %ip_a32v4f32 Input\n"
1779 "%out_position = OpVariable %op_a3v4f32 Output\n"
1780 "%in_position = OpVariable %ip_a32v4f32 Input\n"
1781 "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n"
1782 "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n"
1784 "%tessc1_main = OpFunction %void None %fun\n"
1785 "%tessc1_label = OpLabel\n"
1786 "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1787 "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n"
1788 "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n"
1789 "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n"
1790 "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n"
1791 "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n"
1792 "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n"
1793 "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n"
1794 "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n"
1795 "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n"
1796 "OpSelectionMerge %tessc1_merge_label None\n"
1797 "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n"
1798 "%tessc1_first_invocation = OpLabel\n"
1799 "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1800 "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1801 "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1802 "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1803 "OpStore %tessc1_tess_outer_0 %c_f32_1\n"
1804 "OpStore %tessc1_tess_outer_1 %c_f32_1\n"
1805 "OpStore %tessc1_tess_outer_2 %c_f32_1\n"
1806 "OpStore %tessc1_tess_inner %c_f32_1\n"
1807 "OpBranch %tessc1_merge_label\n"
1808 "%tessc1_merge_label = OpLabel\n"
1812 "%tessc2_main = OpFunction %void None %fun\n"
1813 "%tessc2_label = OpLabel\n"
1814 "%tessc2_invocation_id = OpLoad %i32 %gl_InvocationID\n"
1815 "%tessc2_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc2_invocation_id\n"
1816 "%tessc2_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc2_invocation_id\n"
1817 "%tessc2_in_color_val = OpLoad %v4f32 %tessc2_in_color_ptr\n"
1818 "%tessc2_in_position_val = OpLoad %v4f32 %tessc2_in_position_ptr\n"
1819 "%tessc2_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc2_invocation_id\n"
1820 "%tessc2_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc2_invocation_id\n"
1821 "%tessc2_transformed_color = OpFSub %v4f32 %cval %tessc2_in_color_val\n"
1822 "%tessc2_transformed_color_a = OpVectorInsertDynamic %v4f32 %tessc2_transformed_color %c_f32_1 %c_i32_3\n"
1823 "OpStore %tessc2_out_color_ptr %tessc2_transformed_color_a\n"
1824 "OpStore %tessc2_out_position_ptr %tessc2_in_position_val\n"
1825 "%tessc2_is_first_invocation = OpIEqual %bool %tessc2_invocation_id %c_i32_0\n"
1826 "OpSelectionMerge %tessc2_merge_label None\n"
1827 "OpBranchConditional %tessc2_is_first_invocation %tessc2_first_invocation %tessc2_merge_label\n"
1828 "%tessc2_first_invocation = OpLabel\n"
1829 "%tessc2_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n"
1830 "%tessc2_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n"
1831 "%tessc2_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n"
1832 "%tessc2_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n"
1833 "OpStore %tessc2_tess_outer_0 %c_f32_1\n"
1834 "OpStore %tessc2_tess_outer_1 %c_f32_1\n"
1835 "OpStore %tessc2_tess_outer_2 %c_f32_1\n"
1836 "OpStore %tessc2_tess_inner %c_f32_1\n"
1837 "OpBranch %tessc2_merge_label\n"
1838 "%tessc2_merge_label = OpLabel\n"
1842 dst.spirvAsmSources.add("tesse") <<
1843 "OpCapability Tessellation\n"
1844 "OpCapability ClipDistance\n"
1845 "OpCapability CullDistance\n"
1846 "OpMemoryModel Logical GLSL450\n"
1847 "OpEntryPoint TessellationEvaluation %tesse1_main \"tesse1\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
1848 "OpEntryPoint TessellationEvaluation %tesse2_main \"tesse2\" %stream %gl_tessCoord %in_position %out_color %in_color \n"
1849 "OpExecutionMode %tesse1_main Triangles\n"
1850 "OpExecutionMode %tesse1_main SpacingEqual\n"
1851 "OpExecutionMode %tesse1_main VertexOrderCcw\n"
1852 "OpExecutionMode %tesse2_main Triangles\n"
1853 "OpExecutionMode %tesse2_main SpacingEqual\n"
1854 "OpExecutionMode %tesse2_main VertexOrderCcw\n"
1855 "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n"
1856 "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n"
1857 "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n"
1858 "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n"
1859 "OpDecorate %per_vertex_out Block\n"
1860 "OpDecorate %gl_tessCoord BuiltIn TessCoord\n"
1861 "OpDecorate %in_position Location 2\n"
1862 "OpDecorate %out_color Location 1\n"
1863 "OpDecorate %in_color Location 1\n"
1864 SPIRV_ASSEMBLY_TYPES
1865 SPIRV_ASSEMBLY_CONSTANTS
1866 SPIRV_ASSEMBLY_ARRAYS
1867 "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n"
1868 "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n"
1869 "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n"
1870 "%stream = OpVariable %op_per_vertex_out Output\n"
1871 "%gl_tessCoord = OpVariable %ip_v3f32 Input\n"
1872 "%in_position = OpVariable %ip_a32v4f32 Input\n"
1873 "%out_color = OpVariable %op_v4f32 Output\n"
1874 "%in_color = OpVariable %ip_a32v4f32 Input\n"
1876 "%tesse1_main = OpFunction %void None %fun\n"
1877 "%tesse1_label = OpLabel\n"
1878 "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
1879 "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
1880 "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
1881 "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n"
1882 "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n"
1883 "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n"
1884 "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
1885 "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
1886 "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
1887 "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n"
1888 "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n"
1889 "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n"
1890 "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n"
1891 "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n"
1892 "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n"
1893 "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
1894 "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n"
1895 "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n"
1896 "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n"
1897 "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1898 "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1899 "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1900 "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n"
1901 "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n"
1902 "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n"
1903 "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n"
1904 "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n"
1905 "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n"
1906 "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n"
1907 "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n"
1908 "OpStore %out_color %tesse1_computed_clr\n"
1912 "%tesse2_main = OpFunction %void None %fun\n"
1913 "%tesse2_label = OpLabel\n"
1914 "%tesse2_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n"
1915 "%tesse2_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n"
1916 "%tesse2_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n"
1917 "%tesse2_tc_0 = OpLoad %f32 %tesse2_tc_0_ptr\n"
1918 "%tesse2_tc_1 = OpLoad %f32 %tesse2_tc_1_ptr\n"
1919 "%tesse2_tc_2 = OpLoad %f32 %tesse2_tc_2_ptr\n"
1920 "%tesse2_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n"
1921 "%tesse2_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n"
1922 "%tesse2_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n"
1923 "%tesse2_in_pos_0 = OpLoad %v4f32 %tesse2_in_pos_0_ptr\n"
1924 "%tesse2_in_pos_1 = OpLoad %v4f32 %tesse2_in_pos_1_ptr\n"
1925 "%tesse2_in_pos_2 = OpLoad %v4f32 %tesse2_in_pos_2_ptr\n"
1926 "%tesse2_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_0 %tesse2_tc_0\n"
1927 "%tesse2_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_1 %tesse2_tc_1\n"
1928 "%tesse2_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_2 %tesse2_tc_2\n"
1929 "%tesse2_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n"
1930 "%tesse2_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse2_in_pos_0_weighted %tesse2_in_pos_1_weighted\n"
1931 "%tesse2_computed_out = OpFAdd %v4f32 %tesse2_in_pos_0_plus_pos_1 %tesse2_in_pos_2_weighted\n"
1932 "OpStore %tesse2_out_pos_ptr %tesse2_computed_out\n"
1933 "%tesse2_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n"
1934 "%tesse2_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n"
1935 "%tesse2_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n"
1936 "%tesse2_in_clr_0 = OpLoad %v4f32 %tesse2_in_clr_0_ptr\n"
1937 "%tesse2_in_clr_1 = OpLoad %v4f32 %tesse2_in_clr_1_ptr\n"
1938 "%tesse2_in_clr_2 = OpLoad %v4f32 %tesse2_in_clr_2_ptr\n"
1939 "%tesse2_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_0 %tesse2_tc_0\n"
1940 "%tesse2_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_1 %tesse2_tc_1\n"
1941 "%tesse2_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_2 %tesse2_tc_2\n"
1942 "%tesse2_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse2_in_clr_0_weighted %tesse2_in_clr_1_weighted\n"
1943 "%tesse2_computed_clr = OpFAdd %v4f32 %tesse2_in_clr_0_plus_col_1 %tesse2_in_clr_2_weighted\n"
1944 "%tesse2_clr_transformed = OpFSub %v4f32 %cval %tesse2_computed_clr\n"
1945 "%tesse2_clr_transformed_a = OpVectorInsertDynamic %v4f32 %tesse2_clr_transformed %c_f32_1 %c_i32_3\n"
1946 "OpStore %out_color %tesse2_clr_transformed_a\n"
1951 bool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
1953 // We only support RTE, RTZ, or both.
1954 DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);
1956 const Float32 originalFloat (original);
1957 const Float16 returnedFloat (returned);
1959 // Zero are turned into zero under both RTE and RTZ.
1960 if (originalFloat.isZero())
1962 if (returnedFloat.isZero())
1965 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
1969 // Any denormalized value input into a shader may be flushed to 0.
1970 if (originalFloat.isDenorm() && returnedFloat.isZero())
1973 // Inf are always turned into Inf with the same sign, too.
1974 if (originalFloat.isInf())
1976 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
1979 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
1983 // NaN are always turned into NaN, too.
1984 if (originalFloat.isNaN())
1986 if (returnedFloat.isNaN())
1989 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
1993 // Check all rounding modes
1994 for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
1996 if ((flags & (1u << bitNdx)) == 0)
1997 continue; // This rounding mode is not selected.
1999 const Float16 expectedFloat (deFloat32To16Round(original, deRoundingMode(bitNdx)));
2001 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2002 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2005 // If not matched in the above cases, they should have the same bit pattern.
2006 if (expectedFloat.bits() == returnedFloat.bits())
2010 log << TestLog::Message << "Error: found unmatched 32-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
2014 bool compare16BitFloat (deUint16 original, deUint16 returned, tcu::TestLog& log)
2016 const Float16 originalFloat (original);
2017 const Float16 returnedFloat (returned);
2019 if (originalFloat.isZero())
2021 if (returnedFloat.isZero())
2024 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2028 // Any denormalized value input into a shader or potentially generated by any instruction in a shader
2029 // may be flushed to 0.
2030 if (originalFloat.isDenorm() && returnedFloat.isZero())
2033 // Inf are always turned into Inf with the same sign, too.
2034 if (originalFloat.isInf())
2036 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2039 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2043 // NaN are always turned into NaN, too.
2044 if (originalFloat.isNaN())
2046 if (returnedFloat.isNaN())
2049 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2053 // If not matched in the above cases, they should have the same bit pattern.
2054 if (originalFloat.bits() == returnedFloat.bits())
2057 log << TestLog::Message << "Error: found unmatched 16-bit and 16-bit floats: " << original << " vs " << returned << TestLog::EndMessage;
2061 bool compare16BitFloat(deUint16 original, float returned, tcu::TestLog & log)
2063 const Float16 originalFloat (original);
2064 const Float32 returnedFloat (returned);
2066 // Zero are turned into zero under both RTE and RTZ.
2067 if (originalFloat.isZero())
2069 if (returnedFloat.isZero())
2072 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2076 // Any denormalized value input into a shader may be flushed to 0.
2077 if (originalFloat.isDenorm() && returnedFloat.isZero())
2080 // Inf are always turned into Inf with the same sign, too.
2081 if (originalFloat.isInf())
2083 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2086 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2090 // NaN are always turned into NaN, too.
2091 if (originalFloat.isNaN())
2093 if (returnedFloat.isNaN())
2096 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2100 // In all other cases, conversion should be exact.
2101 const Float32 expectedFloat (deFloat16To32(original));
2102 if (expectedFloat.bits() == returnedFloat.bits())
2105 log << TestLog::Message << "Error: found unmatched 16-bit and 32-bit floats: " << original << " vs " << returnedFloat.bits() << TestLog::EndMessage;
2109 bool compare16BitFloat (deFloat16 original, deFloat16 returned, std::string& error)
2111 std::ostringstream log;
2112 const Float16 originalFloat (original);
2113 const Float16 returnedFloat (returned);
2115 if (originalFloat.isZero())
2117 if (returnedFloat.isZero())
2120 log << "Error: expected zero but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
2125 // Any denormalized value input into a shader may be flushed to 0.
2126 if (originalFloat.isDenorm() && returnedFloat.isZero())
2129 // Inf are always turned into Inf with the same sign, too.
2130 if (originalFloat.isInf())
2132 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2135 log << "Error: expected Inf but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
2140 // NaN are always turned into NaN, too.
2141 if (originalFloat.isNaN())
2143 if (returnedFloat.isNaN())
2146 log << "Error: expected NaN but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")";
2151 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2152 if (originalFloat.isDenorm() && returnedFloat.isZero())
2155 // If not matched in the above cases, they should have the same bit pattern.
2156 if (originalFloat.bits() == returnedFloat.bits())
2159 log << "Error: found unmatched 16-bit and 16-bit floats: 0x"
2160 << std::hex << original << " <=> 0x" << returned
2161 << " (" << originalFloat.asFloat() << " <=> " << returnedFloat.asFloat() << ")";
2166 bool compare16BitFloat64 (double original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log)
2168 // We only support RTE, RTZ, or both.
2169 DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4);
2171 const Float64 originalFloat (original);
2172 const Float16 returnedFloat (returned);
2174 // Zero are turned into zero under both RTE and RTZ.
2175 if (originalFloat.isZero())
2177 if (returnedFloat.isZero())
2180 log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage;
2184 // Any denormalized value input into a shader may be flushed to 0.
2185 if (originalFloat.isDenorm() && returnedFloat.isZero())
2188 // Inf are always turned into Inf with the same sign, too.
2189 if (originalFloat.isInf())
2191 if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit())
2194 log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage;
2198 // NaN are always turned into NaN, too.
2199 if (originalFloat.isNaN())
2201 if (returnedFloat.isNaN())
2204 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2208 // Check all rounding modes
2209 for (int bitNdx = 0; bitNdx < 2; ++bitNdx)
2211 if ((flags & (1u << bitNdx)) == 0)
2212 continue; // This rounding mode is not selected.
2214 const Float16 expectedFloat (deFloat64To16Round(original, deRoundingMode(bitNdx)));
2216 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2217 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2220 // If not matched in the above cases, they should have the same bit pattern.
2221 if (expectedFloat.bits() == returnedFloat.bits())
2225 log << TestLog::Message << "Error: found unmatched 64-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage;
2229 bool compare32BitFloat (float expected, float returned, tcu::TestLog& log)
2231 const Float32 expectedFloat (expected);
2232 const Float32 returnedFloat (returned);
2234 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2235 if (expectedFloat.isDenorm() && returnedFloat.isZero())
2239 const Float16 originalFloat (deFloat32To16(expected));
2241 // Any denormalized value input into a shader may be flushed to 0.
2242 if (originalFloat.isDenorm() && returnedFloat.isZero())
2246 if (expectedFloat.isNaN())
2248 if (returnedFloat.isNaN())
2251 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2255 if (returned == expected)
2258 log << TestLog::Message << "Error: found unmatched 32-bit float: expected " << expectedFloat.bits() << " vs. returned " << returnedFloat.bits() << TestLog::EndMessage;
2262 bool compare64BitFloat (double expected, double returned, tcu::TestLog& log)
2264 const Float64 expectedDouble (expected);
2265 const Float64 returnedDouble (returned);
2267 // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0.
2268 if (expectedDouble.isDenorm() && returnedDouble.isZero())
2272 const Float16 originalDouble (deFloat64To16(expected));
2274 // Any denormalized value input into a shader may be flushed to 0.
2275 if (originalDouble.isDenorm() && returnedDouble.isZero())
2279 if (expectedDouble.isNaN())
2281 if (returnedDouble.isNaN())
2284 log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage;
2288 if (returned == expected)
2291 log << TestLog::Message << "Error: found unmatched 64-bit float: expected " << expectedDouble.bits() << " vs. returned " << returnedDouble.bits() << TestLog::EndMessage;
2295 Move<VkBuffer> createBufferForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex)
2297 const vk::VkDescriptorType resourceType = resource.getDescriptorType();
2299 vector<deUint8> resourceBytes;
2300 resource.getBytes(resourceBytes);
2302 const VkBufferCreateInfo resourceBufferParams =
2304 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
2306 (VkBufferCreateFlags)0, // flags
2307 (VkDeviceSize)resourceBytes.size(), // size
2308 (VkBufferUsageFlags)getMatchingBufferUsageFlagBit(resourceType), // usage
2309 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2310 1u, // queueFamilyCount
2311 &queueFamilyIndex, // pQueueFamilyIndices
2314 return createBuffer(vk, vkDevice, &resourceBufferParams);
2317 Move<VkImage> createImageForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, VkFormat inputFormat, deUint32 queueFamilyIndex)
2319 const VkImageCreateInfo resourceImageParams =
2321 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2322 DE_NULL, // const void* pNext;
2323 0u, // VkImageCreateFlags flags;
2324 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2325 inputFormat, // VkFormat format;
2326 { 8, 8, 1 }, // VkExtent3D extent;
2327 1u, // deUint32 mipLevels;
2328 1u, // deUint32 arraySize;
2329 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2330 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2331 getMatchingImageUsageFlags(resource.getDescriptorType()), // VkImageUsageFlags usage;
2332 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2333 1u, // deUint32 queueFamilyCount;
2334 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2335 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
2338 return createImage(vk, vkDevice, &resourceImageParams);
2341 void copyBufferToImage (const DeviceInterface& vk, const VkDevice& device, const VkQueue& queue, VkCommandBuffer cmdBuffer, VkBuffer buffer, VkImage image, VkImageAspectFlags aspect)
2343 const VkBufferImageCopy copyRegion =
2345 0u, // VkDeviceSize bufferOffset;
2346 0u, // deUint32 bufferRowLength;
2347 0u, // deUint32 bufferImageHeight;
2349 aspect, // VkImageAspectFlags aspect;
2350 0u, // deUint32 mipLevel;
2351 0u, // deUint32 baseArrayLayer;
2352 1u, // deUint32 layerCount;
2353 }, // VkImageSubresourceLayers imageSubresource;
2354 { 0, 0, 0 }, // VkOffset3D imageOffset;
2355 { 8, 8, 1 } // VkExtent3D imageExtent;
2358 // Copy buffer to image
2360 const VkImageMemoryBarrier imageBarriers[] =
2363 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2364 DE_NULL, // const void* pNext;
2365 DE_NULL, // VkAccessFlags srcAccessMask;
2366 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2367 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
2368 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2369 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2370 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2371 image, // VkImage image;
2372 { // VkImageSubresourceRange subresourceRange;
2373 aspect, // VkImageAspectFlags aspectMask;
2374 0u, // deUint32 baseMipLevel;
2375 1u, // deUint32 mipLevels;
2376 0u, // deUint32 baseArraySlice;
2377 1u // deUint32 arraySize;
2381 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2382 DE_NULL, // const void* pNext;
2383 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2384 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
2385 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2386 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
2387 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2388 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2389 image, // VkImage image;
2390 { // VkImageSubresourceRange subresourceRange;
2391 aspect, // VkImageAspectFlags aspectMask;
2392 0u, // deUint32 baseMipLevel;
2393 1u, // deUint32 mipLevels;
2394 0u, // deUint32 baseArraySlice;
2395 1u // deUint32 arraySize;
2400 beginCommandBuffer(vk, cmdBuffer);
2401 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
2402 0u, DE_NULL, 1u, &imageBarriers[0]);
2403 vk.cmdCopyBufferToImage(cmdBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
2404 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
2405 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarriers[1]);
2407 endCommandBuffer(vk, cmdBuffer);
2409 submitCommandsAndWait(vk, device, queue, cmdBuffer);
2412 VkImageAspectFlags getImageAspectFlags (VkFormat format)
2414 const tcu::TextureFormat::ChannelOrder channelOrder = vk::mapVkFormat(format).order;
2415 VkImageAspectFlags aspectFlags = (VkImageAspectFlags)0u;
2417 if (tcu::hasDepthComponent(channelOrder))
2418 aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
2420 if (tcu::hasStencilComponent(channelOrder))
2421 aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
2424 aspectFlags |= VK_IMAGE_ASPECT_COLOR_BIT;
2429 TestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance)
2431 if (getMinRequiredVulkanVersion(instance.resources.spirvVersion) > context.getUsedApiVersion())
2433 TCU_THROW(NotSupportedError, string("Vulkan higher than or equal to " + getVulkanName(getMinRequiredVulkanVersion(instance.resources.spirvVersion)) + " is required for this test to run").c_str());
2436 const DeviceInterface& vk = context.getDeviceInterface();
2437 const InstanceInterface& vkInstance = context.getInstanceInterface();
2438 const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice();
2439 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2440 const VkQueue queue = context.getUniversalQueue();
2441 const VkDevice& device = context.getDevice();
2442 Allocator& allocator = context.getDefaultAllocator();
2443 vector<ModuleHandleSp> modules;
2444 map<VkShaderStageFlagBits, VkShaderModule> moduleByStage;
2445 const tcu::UVec2 renderSize (256, 256);
2446 const int testSpecificSeed = 31354125;
2447 const int seed = context.getTestContext().getCommandLine().getBaseSeed() ^ testSpecificSeed;
2448 bool supportsGeometry = false;
2449 bool supportsTessellation = false;
2450 bool hasTessellation = false;
2451 const bool hasPushConstants = !instance.pushConstants.empty();
2452 const deUint32 numResources = static_cast<deUint32>(instance.resources.inputs.size() + instance.resources.outputs.size());
2453 const bool needInterface = !instance.interfaces.empty();
2454 const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures();
2455 const Vec4 defaulClearColor (0.125f, 0.25f, 0.75f, 1.0f);
2457 supportsGeometry = features.geometryShader == VK_TRUE;
2458 supportsTessellation = features.tessellationShader == VK_TRUE;
2459 hasTessellation = (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) ||
2460 (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2462 if (hasTessellation && !supportsTessellation)
2464 TCU_THROW(NotSupportedError, "Tessellation not supported");
2467 if ((instance.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT) &&
2470 TCU_THROW(NotSupportedError, "Geometry not supported");
2473 // Check all required extensions are supported
2474 for (std::vector<std::string>::const_iterator i = instance.requiredDeviceExtensions.begin(); i != instance.requiredDeviceExtensions.end(); ++i)
2476 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), *i))
2477 TCU_THROW(NotSupportedError, (std::string("Extension not supported: ") + *i).c_str());
2481 for (deUint32 featureNdx = 0; featureNdx < instance.requiredDeviceFeatures.size(); ++featureNdx)
2483 const string& feature = instance.requiredDeviceFeatures[featureNdx];
2485 if (feature == "shaderInt16")
2487 if (features.shaderInt16 != VK_TRUE)
2488 TCU_THROW(NotSupportedError, "Device feature not supported: shaderInt16");
2490 else if (feature == "shaderInt64")
2492 if (features.shaderInt64 != VK_TRUE)
2493 TCU_THROW(NotSupportedError, "Device feature not supported: shaderInt64");
2495 else if (feature == "shaderFloat64")
2497 if (features.shaderFloat64 != VK_TRUE)
2498 TCU_THROW(NotSupportedError, "Device feature not supported: shaderFloat64");
2500 else if (feature == "fragmentStoresAndAtomics")
2502 if (features.fragmentStoresAndAtomics != VK_TRUE)
2503 TCU_THROW(NotSupportedError, "Device feature not supported: fragmentStoresAndAtomics");
2507 TCU_THROW(InternalError, (std::string("Unimplemented physical device feature: ") + feature).c_str());
2514 const VkShaderStageFlags vertexPipelineStoresAndAtomicsAffected = vk::VK_SHADER_STAGE_VERTEX_BIT
2515 | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT
2516 | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT
2517 | vk::VK_SHADER_STAGE_GEOMETRY_BIT;
2518 const char* unsupportedFeature = DE_NULL;
2519 vk::VkPhysicalDeviceFeatures localRequiredCoreFeatures = instance.requestedFeatures.coreFeatures;
2521 // reset fragment stores and atomics feature requirement
2522 if ((localRequiredCoreFeatures.fragmentStoresAndAtomics != DE_FALSE) &&
2523 (instance.customizedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) == 0)
2525 localRequiredCoreFeatures.fragmentStoresAndAtomics = DE_FALSE;
2528 // reset vertex pipeline stores and atomics feature requirement
2529 if (localRequiredCoreFeatures.vertexPipelineStoresAndAtomics != DE_FALSE &&
2530 (instance.customizedStages & vertexPipelineStoresAndAtomicsAffected) == 0)
2532 localRequiredCoreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE;
2535 if (!isCoreFeaturesSupported(context, localRequiredCoreFeatures, &unsupportedFeature))
2536 TCU_THROW(NotSupportedError, std::string("At least following requested core feature is not supported: ") + unsupportedFeature);
2539 // Extension features
2541 // 8bit storage features
2543 if (!is8BitStorageFeaturesSupported(context, instance.requestedFeatures.ext8BitStorage))
2544 TCU_THROW(NotSupportedError, "Requested 8bit storage features not supported");
2547 // 16bit storage features
2549 if (!is16BitStorageFeaturesSupported(context, instance.requestedFeatures.ext16BitStorage))
2550 TCU_THROW(NotSupportedError, "Requested 16bit storage features not supported");
2553 // Variable Pointers features
2555 if (!isVariablePointersFeaturesSupported(context, instance.requestedFeatures.extVariablePointers))
2556 TCU_THROW(NotSupportedError, "Requested Variable Pointer features not supported");
2559 // Float16/Int8 shader features
2561 if (!isFloat16Int8FeaturesSupported(context, instance.requestedFeatures.extFloat16Int8))
2562 TCU_THROW(NotSupportedError, "Requested 16bit float or 8bit int feature not supported");
2566 // FloatControls features
2568 if (!isFloatControlsFeaturesSupported(context, instance.requestedFeatures.floatControlsProperties))
2569 TCU_THROW(NotSupportedError, "Requested Float Controls features not supported");
2572 // Check Interface Input/Output formats are supported
2575 VkFormatProperties formatProperties;
2576 vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getInputType().getVkFormat(), &formatProperties);
2577 if ((formatProperties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0)
2579 std::string error = "Interface Input format (";
2580 const std::string formatName = getFormatName(instance.interfaces.getInputType().getVkFormat());
2581 error += formatName + ") not supported";
2582 TCU_THROW(NotSupportedError, error.c_str());
2585 vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getOutputType().getVkFormat(), &formatProperties);
2586 if (((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) ||
2587 ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0))
2589 std::string error = "Interface Output format (";
2590 const std::string formatName = getFormatName(instance.interfaces.getInputType().getVkFormat());
2591 error += formatName + ") not supported";
2592 TCU_THROW(NotSupportedError, error.c_str());
2596 de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4);
2597 de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4);
2598 const Vec4 vertexData[] =
2600 // Upper left corner:
2601 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //1
2602 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //2
2603 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //3
2605 // Upper right corner:
2606 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //4
2607 Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //5
2608 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //6
2610 // Lower left corner:
2611 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //7
2612 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //8
2613 Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //9
2615 // Lower right corner:
2616 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //10
2617 Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //11
2618 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //12
2620 // The rest is used only renderFullSquare specified. Fills area already filled with clear color
2622 Vec4(-1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //3
2623 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2
2624 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //7
2627 Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //7
2628 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2
2629 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8
2632 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8
2633 Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2
2634 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4
2637 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4
2638 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12
2639 Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8
2642 Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4
2643 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //6
2644 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12
2647 Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12
2648 Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //6
2649 Vec4(+1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //10
2652 const size_t singleVertexDataSize = 2 * sizeof(Vec4);
2653 const size_t vertexCount = instance.renderFullSquare ? sizeof(vertexData) / singleVertexDataSize : 4*3;
2654 const size_t vertexDataSize = vertexCount * singleVertexDataSize;
2656 Move<VkBuffer> vertexInputBuffer;
2657 de::MovePtr<Allocation> vertexInputMemory;
2658 Move<VkBuffer> fragOutputBuffer;
2659 de::MovePtr<Allocation> fragOutputMemory;
2660 Move<VkImage> fragOutputImage;
2661 de::MovePtr<Allocation> fragOutputImageMemory;
2662 Move<VkImageView> fragOutputImageView;
2664 const VkBufferCreateInfo vertexBufferParams =
2666 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2667 DE_NULL, // const void* pNext;
2668 0u, // VkBufferCreateFlags flags;
2669 (VkDeviceSize)vertexDataSize, // VkDeviceSize size;
2670 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2671 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2672 1u, // deUint32 queueFamilyCount;
2673 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2675 const Unique<VkBuffer> vertexBuffer (createBuffer(vk, device, &vertexBufferParams));
2676 const UniquePtr<Allocation> vertexBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexBuffer), MemoryRequirement::HostVisible));
2678 VK_CHECK(vk.bindBufferMemory(device, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
2680 const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
2681 const VkBufferCreateInfo readImageBufferParams =
2683 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2684 DE_NULL, // const void* pNext;
2685 0u, // VkBufferCreateFlags flags;
2686 imageSizeBytes, // VkDeviceSize size;
2687 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2688 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2689 1u, // deUint32 queueFamilyCount;
2690 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2692 const Unique<VkBuffer> readImageBuffer (createBuffer(vk, device, &readImageBufferParams));
2693 const UniquePtr<Allocation> readImageBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible));
2695 VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
2697 VkImageCreateInfo imageParams =
2699 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2700 DE_NULL, // const void* pNext;
2701 0u, // VkImageCreateFlags flags;
2702 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2703 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2704 { renderSize.x(), renderSize.y(), 1 }, // VkExtent3D extent;
2705 1u, // deUint32 mipLevels;
2706 1u, // deUint32 arraySize;
2707 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2708 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2709 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
2710 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2711 1u, // deUint32 queueFamilyCount;
2712 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2713 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2716 const Unique<VkImage> image (createImage(vk, device, &imageParams));
2717 const UniquePtr<Allocation> imageMemory (allocator.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any));
2719 VK_CHECK(vk.bindImageMemory(device, *image, imageMemory->getMemory(), imageMemory->getOffset()));
2723 // The pipeline renders four triangles, each with three vertexes.
2724 // Test instantialization only provides four data points, each
2725 // for one triangle. So we need allocate space of three times of
2726 // input buffer's size.
2727 vector<deUint8> inputBufferBytes;
2728 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
2730 const deUint32 inputNumBytes = deUint32(inputBufferBytes.size() * 3);
2731 // Create an additional buffer and backing memory for one input variable.
2732 const VkBufferCreateInfo vertexInputParams =
2734 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2735 DE_NULL, // const void* pNext;
2736 0u, // VkBufferCreateFlags flags;
2737 inputNumBytes, // VkDeviceSize size;
2738 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
2739 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2740 1u, // deUint32 queueFamilyCount;
2741 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2744 vertexInputBuffer = createBuffer(vk, device, &vertexInputParams);
2745 vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexInputBuffer), MemoryRequirement::HostVisible);
2746 VK_CHECK(vk.bindBufferMemory(device, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset()));
2748 // Create an additional buffer and backing memory for an output variable.
2749 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
2750 const VkBufferCreateInfo fragOutputParams =
2752 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2753 DE_NULL, // const void* pNext;
2754 0u, // VkBufferCreateFlags flags;
2755 fragOutputImgSize, // VkDeviceSize size;
2756 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2757 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2758 1u, // deUint32 queueFamilyCount;
2759 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2761 fragOutputBuffer = createBuffer(vk, device, &fragOutputParams);
2762 fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *fragOutputBuffer), MemoryRequirement::HostVisible);
2763 VK_CHECK(vk.bindBufferMemory(device, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset()));
2765 // Create an additional image and backing memory for attachment.
2766 // Reuse the previous imageParams since we only need to change the image format.
2767 imageParams.format = instance.interfaces.getOutputType().getVkFormat();
2769 // Check the usage bits on the given image format are supported.
2770 requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.tiling, imageParams.usage);
2772 fragOutputImage = createImage(vk, device, &imageParams);
2773 fragOutputImageMemory = allocator.allocate(getImageMemoryRequirements(vk, device, *fragOutputImage), MemoryRequirement::Any);
2775 VK_CHECK(vk.bindImageMemory(device, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset()));
2778 vector<VkAttachmentDescription> colorAttDescs;
2779 vector<VkAttachmentReference> colorAttRefs;
2781 const VkAttachmentDescription attDesc =
2783 0u, // VkAttachmentDescriptionFlags flags;
2784 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2785 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2786 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2787 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2788 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2789 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2790 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2791 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2793 colorAttDescs.push_back(attDesc);
2795 const VkAttachmentReference attRef =
2797 0u, // deUint32 attachment;
2798 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
2800 colorAttRefs.push_back(attRef);
2805 const VkAttachmentDescription attDesc =
2807 0u, // VkAttachmentDescriptionFlags flags;
2808 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
2809 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2810 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
2811 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
2812 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
2813 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
2814 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
2815 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
2817 colorAttDescs.push_back(attDesc);
2819 const VkAttachmentReference attRef =
2821 1u, // deUint32 attachment;
2822 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
2824 colorAttRefs.push_back(attRef);
2827 VkSubpassDescription subpassDesc =
2829 0u, // VkSubpassDescriptionFlags flags;
2830 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
2831 0u, // deUint32 inputCount;
2832 DE_NULL, // const VkAttachmentReference* pInputAttachments;
2833 1u, // deUint32 colorCount;
2834 colorAttRefs.data(), // const VkAttachmentReference* pColorAttachments;
2835 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
2836 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
2837 0u, // deUint32 preserveCount;
2838 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
2841 VkRenderPassCreateInfo renderPassParams =
2843 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
2844 DE_NULL, // const void* pNext;
2845 (VkRenderPassCreateFlags)0,
2846 1u, // deUint32 attachmentCount;
2847 colorAttDescs.data(), // const VkAttachmentDescription* pAttachments;
2848 1u, // deUint32 subpassCount;
2849 &subpassDesc, // const VkSubpassDescription* pSubpasses;
2850 0u, // deUint32 dependencyCount;
2851 DE_NULL, // const VkSubpassDependency* pDependencies;
2856 subpassDesc.colorAttachmentCount += 1;
2857 renderPassParams.attachmentCount += 1;
2860 const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, &renderPassParams));
2862 const VkImageViewCreateInfo colorAttViewParams =
2864 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
2865 DE_NULL, // const void* pNext;
2866 0u, // VkImageViewCreateFlags flags;
2867 *image, // VkImage image;
2868 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
2869 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
2871 VK_COMPONENT_SWIZZLE_R,
2872 VK_COMPONENT_SWIZZLE_G,
2873 VK_COMPONENT_SWIZZLE_B,
2874 VK_COMPONENT_SWIZZLE_A
2875 }, // VkChannelMapping channels;
2877 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
2878 0u, // deUint32 baseMipLevel;
2879 1u, // deUint32 mipLevels;
2880 0u, // deUint32 baseArrayLayer;
2881 1u, // deUint32 arraySize;
2882 }, // VkImageSubresourceRange subresourceRange;
2884 const Unique<VkImageView> colorAttView (createImageView(vk, device, &colorAttViewParams));
2885 const VkImageAspectFlags inputImageAspect = getImageAspectFlags(instance.resources.inputFormat);
2887 vector<VkImageView> attViews;
2888 attViews.push_back(*colorAttView);
2890 // Handle resources requested by the test instantiation.
2891 const deUint32 numInResources = static_cast<deUint32>(instance.resources.inputs.size());
2892 const deUint32 numOutResources = static_cast<deUint32>(instance.resources.outputs.size());
2893 // These variables should be placed out of the following if block to avoid deallocation after out of scope.
2894 vector<AllocationSp> inResourceMemories;
2895 vector<AllocationSp> outResourceMemories;
2896 vector<BufferHandleSp> inResourceBuffers;
2897 vector<BufferHandleSp> outResourceBuffers;
2898 vector<ImageHandleSp> inResourceImages;
2899 vector<ImageViewHandleSp> inResourceImageViews;
2900 vector<SamplerHandleSp> inResourceSamplers;
2901 Move<VkDescriptorPool> descriptorPool;
2902 Move<VkDescriptorSetLayout> setLayout;
2903 VkDescriptorSetLayout rawSetLayout = DE_NULL;
2904 VkDescriptorSet rawSet = DE_NULL;
2906 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
2909 const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2911 if (numResources != 0)
2913 vector<VkDescriptorSetLayoutBinding> setLayoutBindings;
2914 vector<VkDescriptorPoolSize> poolSizes;
2916 setLayoutBindings.reserve(numResources);
2917 poolSizes.reserve(numResources);
2919 // Process all input resources.
2920 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
2922 const Resource& resource = instance.resources.inputs[inputNdx];
2924 const bool hasImage = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
2925 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2926 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2928 const bool hasSampler = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
2929 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER) ||
2930 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
2932 // Resource is a buffer
2933 if (!hasImage && !hasSampler)
2935 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex);
2936 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
2938 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2940 // Copy data to memory.
2942 const VkMappedMemoryRange range =
2944 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
2945 DE_NULL, // const void* pNext;
2946 resourceMemory->getMemory(), // VkDeviceMemory mem;
2947 0, // VkDeviceSize offset;
2948 VK_WHOLE_SIZE, // VkDeviceSize size;
2951 vector<deUint8> resourceBytes;
2952 resource.getBytes(resourceBytes);
2954 deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
2955 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
2958 inResourceMemories.push_back(AllocationSp(resourceMemory.release()));
2959 inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
2961 // Resource is an image
2964 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex);
2965 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
2967 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
2969 // Copy data to memory.
2971 const VkMappedMemoryRange range =
2973 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
2974 DE_NULL, // const void* pNext;
2975 resourceMemory->getMemory(), // VkDeviceMemory mem;
2976 0, // VkDeviceSize offset;
2977 VK_WHOLE_SIZE, // VkDeviceSize size;
2980 vector<deUint8> resourceBytes;
2981 resource.getBytes(resourceBytes);
2983 deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size());
2984 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
2987 Move<VkImage> resourceImage = createImageForResource(vk, device, resource, instance.resources.inputFormat, queueFamilyIndex);
2988 de::MovePtr<Allocation> resourceImageMemory = allocator.allocate(getImageMemoryRequirements(vk, device, *resourceImage), MemoryRequirement::Any);
2990 VK_CHECK(vk.bindImageMemory(device, *resourceImage, resourceImageMemory->getMemory(), resourceImageMemory->getOffset()));
2992 copyBufferToImage(vk, device, queue, *cmdBuf, resourceBuffer.get(), resourceImage.get(), inputImageAspect);
2994 inResourceMemories.push_back(AllocationSp(resourceImageMemory.release()));
2995 inResourceImages.push_back(ImageHandleSp(new ImageHandleUp(resourceImage)));
2998 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
2999 const VkDescriptorSetLayoutBinding binding =
3001 inputNdx, // binding
3002 resource.getDescriptorType(), // descriptorType
3003 1u, // descriptorCount
3004 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
3005 DE_NULL, // pImmutableSamplers
3007 setLayoutBindings.push_back(binding);
3009 // Note: the following code doesn't check and unify descriptors of the same type.
3010 const VkDescriptorPoolSize poolSize =
3012 resource.getDescriptorType(), // type
3013 1u, // descriptorCount
3015 poolSizes.push_back(poolSize);
3018 // Process all output resources.
3019 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3021 const Resource& resource = instance.resources.outputs[outputNdx];
3022 // Create buffer and allocate memory.
3023 Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex);
3024 de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible);
3025 vector<deUint8> resourceBytes;
3027 VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset()));
3029 // Fill memory with all ones.
3030 const VkMappedMemoryRange range =
3032 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3033 DE_NULL, // const void* pNext;
3034 resourceMemory->getMemory(), // VkDeviceMemory mem;
3035 0, // VkDeviceSize offset;
3036 VK_WHOLE_SIZE, // VkDeviceSize size;
3039 resource.getBytes(resourceBytes);
3040 deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resourceBytes.size());
3041 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3043 outResourceMemories.push_back(AllocationSp(resourceMemory.release()));
3044 outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer)));
3046 // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool.
3047 const VkDescriptorSetLayoutBinding binding =
3049 numInResources + outputNdx, // binding
3050 resource.getDescriptorType(), // descriptorType
3051 1u, // descriptorCount
3052 VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags
3053 DE_NULL, // pImmutableSamplers
3055 setLayoutBindings.push_back(binding);
3057 // Note: the following code doesn't check and unify descriptors of the same type.
3058 const VkDescriptorPoolSize poolSize =
3060 resource.getDescriptorType(), // type
3061 1u, // descriptorCount
3063 poolSizes.push_back(poolSize);
3066 // Create descriptor set layout, descriptor pool, and allocate descriptor set.
3067 const VkDescriptorSetLayoutCreateInfo setLayoutParams =
3069 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
3071 (VkDescriptorSetLayoutCreateFlags)0, // flags
3072 numResources, // bindingCount
3073 setLayoutBindings.data(), // pBindings
3075 setLayout = createDescriptorSetLayout(vk, device, &setLayoutParams);
3076 rawSetLayout = *setLayout;
3078 const VkDescriptorPoolCreateInfo poolParams =
3080 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType
3082 (VkDescriptorPoolCreateFlags)0, // flags
3084 numResources, // poolSizeCount
3085 poolSizes.data(), // pPoolSizes
3087 descriptorPool = createDescriptorPool(vk, device, &poolParams);
3089 const VkDescriptorSetAllocateInfo setAllocParams =
3091 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType
3093 *descriptorPool, // descriptorPool
3094 1u, // descriptorSetCount
3095 &rawSetLayout, // pSetLayouts
3097 VK_CHECK(vk.allocateDescriptorSets(device, &setAllocParams, &rawSet));
3099 // Update descriptor set.
3100 vector<VkWriteDescriptorSet> writeSpecs;
3101 vector<VkDescriptorBufferInfo> dBufferInfos;
3102 vector<VkDescriptorImageInfo> dImageInfos;
3104 writeSpecs.reserve(numResources);
3105 dBufferInfos.reserve(numResources);
3106 dImageInfos.reserve(numResources);
3108 deUint32 imgResourceNdx = 0u;
3109 deUint32 bufResourceNdx = 0u;
3111 for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx)
3113 const Resource& resource = instance.resources.inputs[inputNdx];
3115 const bool hasImage = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) ||
3116 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
3117 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3119 const bool hasSampler = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) ||
3120 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER) ||
3121 (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
3123 // Create image view and sampler
3124 if (hasImage || hasSampler)
3126 if (resource.getDescriptorType() != VK_DESCRIPTOR_TYPE_SAMPLER)
3128 const VkImageViewCreateInfo imgViewParams =
3130 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3131 DE_NULL, // const void* pNext;
3132 0u, // VkImageViewCreateFlags flags;
3133 **inResourceImages[imgResourceNdx++], // VkImage image;
3134 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3135 instance.resources.inputFormat, // VkFormat format;
3137 VK_COMPONENT_SWIZZLE_R,
3138 VK_COMPONENT_SWIZZLE_G,
3139 VK_COMPONENT_SWIZZLE_B,
3140 VK_COMPONENT_SWIZZLE_A
3141 }, // VkComponentMapping channels;
3143 inputImageAspect, // VkImageAspectFlags aspectMask;
3144 0u, // deUint32 baseMipLevel;
3145 1u, // deUint32 mipLevels;
3146 0u, // deUint32 baseArrayLayer;
3147 1u, // deUint32 arraySize;
3148 }, // VkImageSubresourceRange subresourceRange;
3151 Move<VkImageView> imgView (createImageView(vk, device, &imgViewParams));
3152 inResourceImageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imgView)));
3157 const bool hasDepthComponent = tcu::hasDepthComponent(vk::mapVkFormat(instance.resources.inputFormat).order);
3158 const VkSamplerCreateInfo samplerParams =
3160 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
3161 DE_NULL, // const void* pNext;
3162 0, // VkSamplerCreateFlags flags;
3163 VK_FILTER_NEAREST, // VkFilter magFilter:
3164 VK_FILTER_NEAREST, // VkFilter minFilter;
3165 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
3166 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
3167 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
3168 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
3169 0.0f, // float mipLodBias;
3170 VK_FALSE, // VkBool32 anistoropyÉnable;
3171 1.0f, // float maxAnisotropy;
3172 (hasDepthComponent) ? VK_TRUE : VK_FALSE, // VkBool32 compareEnable;
3173 VK_COMPARE_OP_LESS, // VkCompareOp compareOp;
3174 0.0f, // float minLod;
3175 0.0f, // float maxLod;
3176 VK_BORDER_COLOR_INT_OPAQUE_BLACK, // VkBorderColor borderColor;
3177 VK_FALSE // VkBool32 unnormalizedCoordinates;
3180 Move<VkSampler> sampler (createSampler(vk, device, &samplerParams));
3181 inResourceSamplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler)));
3185 // Create descriptor buffer and image infos
3186 switch (resource.getDescriptorType())
3188 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
3189 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
3191 const VkDescriptorBufferInfo bufInfo =
3193 **inResourceBuffers[bufResourceNdx++], // buffer
3195 VK_WHOLE_SIZE, // size
3197 dBufferInfos.push_back(bufInfo);
3200 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
3201 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
3203 const VkDescriptorImageInfo imgInfo =
3206 **inResourceImageViews.back(), // imageView
3207 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3209 dImageInfos.push_back(imgInfo);
3212 case VK_DESCRIPTOR_TYPE_SAMPLER:
3214 const VkDescriptorImageInfo imgInfo =
3216 **inResourceSamplers.back(), // sampler
3217 DE_NULL, // imageView
3218 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3220 dImageInfos.push_back(imgInfo);
3223 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
3226 const VkDescriptorImageInfo imgInfo =
3228 **inResourceSamplers.back(), // sampler
3229 **inResourceImageViews.back(), // imageView
3230 VK_IMAGE_LAYOUT_GENERAL // imageLayout
3232 dImageInfos.push_back(imgInfo);
3236 DE_FATAL("Not implemented");
3239 const VkWriteDescriptorSet writeSpec = {
3240 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3243 inputNdx, // binding
3244 0, // dstArrayElement
3245 1u, // descriptorCount
3246 instance.resources.inputs[inputNdx].getDescriptorType(), // descriptorType
3247 ( (hasImage | hasSampler) ? &dImageInfos.back() : DE_NULL), // pImageInfo
3248 (!(hasImage | hasSampler) ? &dBufferInfos.back() : DE_NULL), // pBufferInfo
3249 DE_NULL, // pTexelBufferView
3251 writeSpecs.push_back(writeSpec);
3254 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3256 const VkDescriptorBufferInfo bufInfo =
3258 **outResourceBuffers[outputNdx], // buffer
3260 VK_WHOLE_SIZE, // size
3262 dBufferInfos.push_back(bufInfo);
3264 const VkWriteDescriptorSet writeSpec = {
3265 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
3268 numInResources + outputNdx, // binding
3269 0, // dstArrayElement
3270 1u, // descriptorCount
3271 instance.resources.outputs[outputNdx].getDescriptorType(), // descriptorType
3272 DE_NULL, // pImageInfo
3273 &dBufferInfos.back(), // pBufferInfo
3274 DE_NULL, // pTexelBufferView
3276 writeSpecs.push_back(writeSpec);
3278 vk.updateDescriptorSets(device, numResources, writeSpecs.data(), 0, DE_NULL);
3282 VkPipelineLayoutCreateInfo pipelineLayoutParams =
3284 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3285 DE_NULL, // const void* pNext;
3286 (VkPipelineLayoutCreateFlags)0,
3287 0u, // deUint32 descriptorSetCount;
3288 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
3289 0u, // deUint32 pushConstantRangeCount;
3290 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
3293 VkPushConstantRange pushConstantRange =
3295 VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags stageFlags;
3296 0, // uint32_t offset;
3297 0, // uint32_t size;
3299 if (hasPushConstants)
3301 vector<deUint8> pushConstantsBytes;
3302 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3304 pushConstantRange.size = static_cast<deUint32>(pushConstantsBytes.size());
3305 pipelineLayoutParams.pushConstantRangeCount = 1;
3306 pipelineLayoutParams.pPushConstantRanges = &pushConstantRange;
3308 if (numResources != 0)
3310 // Update pipeline layout with the descriptor set layout.
3311 pipelineLayoutParams.setLayoutCount = 1;
3312 pipelineLayoutParams.pSetLayouts = &rawSetLayout;
3314 const Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, device, &pipelineLayoutParams));
3317 vector<VkPipelineShaderStageCreateInfo> shaderStageParams;
3318 // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline().
3319 vector<vector<VkSpecializationMapEntry> > specConstantEntries;
3320 vector<VkSpecializationInfo> specializationInfos;
3321 if (DE_NULL != instance.resources.verifyBinary)
3323 std::string shaderName;
3324 switch(instance.customizedStages)
3326 case VK_SHADER_STAGE_VERTEX_BIT:
3329 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
3330 shaderName= "tessc";
3332 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
3333 shaderName= "tesse";
3335 case VK_SHADER_STAGE_GEOMETRY_BIT:
3338 case VK_SHADER_STAGE_FRAGMENT_BIT:
3345 const ProgramBinary& binary = context.getBinaryCollection().get(shaderName);
3346 if (!instance.resources.verifyBinary(binary))
3347 return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed");
3350 createPipelineShaderStages(vk, device, instance, context, modules, shaderStageParams);
3352 // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents.
3353 specConstantEntries.reserve(shaderStageParams.size());
3354 specializationInfos.reserve(shaderStageParams.size());
3356 // Patch the specialization info field in PipelineShaderStageCreateInfos.
3357 for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo)
3359 const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage);
3361 if (stageIt != instance.specConstants.end())
3363 const size_t numSpecConstants = stageIt->second.getValuesCount();
3364 vector<VkSpecializationMapEntry> entries;
3365 VkSpecializationInfo specInfo;
3368 entries.resize(numSpecConstants);
3370 // Constant IDs are numbered sequentially starting from 0.
3371 for (size_t ndx = 0; ndx < numSpecConstants; ++ndx)
3373 const size_t valueSize = stageIt->second.getValueSize(ndx);
3375 entries[ndx].constantID = (deUint32)ndx;
3376 entries[ndx].offset = static_cast<deUint32>(offset);
3377 entries[ndx].size = valueSize;
3379 offset += valueSize;
3382 specConstantEntries.push_back(entries);
3384 specInfo.mapEntryCount = (deUint32)numSpecConstants;
3385 specInfo.pMapEntries = specConstantEntries.back().data();
3386 specInfo.dataSize = offset;
3387 specInfo.pData = stageIt->second.getValuesBuffer();
3388 specializationInfos.push_back(specInfo);
3390 stageInfo->pSpecializationInfo = &specializationInfos.back();
3393 const VkPipelineDepthStencilStateCreateInfo depthStencilParams =
3395 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
3396 DE_NULL, // const void* pNext;
3397 (VkPipelineDepthStencilStateCreateFlags)0,
3398 DE_FALSE, // deUint32 depthTestEnable;
3399 DE_FALSE, // deUint32 depthWriteEnable;
3400 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
3401 DE_FALSE, // deUint32 depthBoundsTestEnable;
3402 DE_FALSE, // deUint32 stencilTestEnable;
3404 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
3405 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
3406 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
3407 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
3408 0u, // deUint32 stencilCompareMask;
3409 0u, // deUint32 stencilWriteMask;
3410 0u, // deUint32 stencilReference;
3411 }, // VkStencilOpState front;
3413 VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp;
3414 VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp;
3415 VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp;
3416 VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp;
3417 0u, // deUint32 stencilCompareMask;
3418 0u, // deUint32 stencilWriteMask;
3419 0u, // deUint32 stencilReference;
3420 }, // VkStencilOpState back;
3421 -1.0f, // float minDepthBounds;
3422 +1.0f, // float maxDepthBounds;
3424 const VkViewport viewport0 = makeViewport(renderSize);
3425 const VkRect2D scissor0 = makeRect2D(renderSize);
3426 const VkPipelineViewportStateCreateInfo viewportParams =
3428 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
3429 DE_NULL, // const void* pNext;
3430 (VkPipelineViewportStateCreateFlags)0,
3431 1u, // deUint32 viewportCount;
3436 const VkSampleMask sampleMask = ~0u;
3437 const VkPipelineMultisampleStateCreateInfo multisampleParams =
3439 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
3440 DE_NULL, // const void* pNext;
3441 (VkPipelineMultisampleStateCreateFlags)0,
3442 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterSamples;
3443 DE_FALSE, // deUint32 sampleShadingEnable;
3444 0.0f, // float minSampleShading;
3445 &sampleMask, // const VkSampleMask* pSampleMask;
3446 DE_FALSE, // VkBool32 alphaToCoverageEnable;
3447 DE_FALSE, // VkBool32 alphaToOneEnable;
3449 const VkPipelineRasterizationStateCreateInfo rasterParams =
3451 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
3452 DE_NULL, // const void* pNext;
3453 (VkPipelineRasterizationStateCreateFlags)0,
3454 DE_FALSE, // deUint32 depthClampEnable;
3455 DE_FALSE, // deUint32 rasterizerDiscardEnable;
3456 VK_POLYGON_MODE_FILL, // VkFillMode fillMode;
3457 VK_CULL_MODE_NONE, // VkCullMode cullMode;
3458 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
3459 VK_FALSE, // VkBool32 depthBiasEnable;
3460 0.0f, // float depthBias;
3461 0.0f, // float depthBiasClamp;
3462 0.0f, // float slopeScaledDepthBias;
3463 1.0f, // float lineWidth;
3465 const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
3466 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyParams =
3468 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
3469 DE_NULL, // const void* pNext;
3470 (VkPipelineInputAssemblyStateCreateFlags)0,
3471 topology, // VkPrimitiveTopology topology;
3472 DE_FALSE, // deUint32 primitiveRestartEnable;
3475 vector<VkVertexInputBindingDescription> vertexBindings;
3476 vector<VkVertexInputAttributeDescription> vertexAttribs;
3478 const VkVertexInputBindingDescription vertexBinding0 =
3480 0u, // deUint32 binding;
3481 deUint32(singleVertexDataSize), // deUint32 strideInBytes;
3482 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
3484 vertexBindings.push_back(vertexBinding0);
3487 VkVertexInputAttributeDescription attr0 =
3489 0u, // deUint32 location;
3490 0u, // deUint32 binding;
3491 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3492 0u // deUint32 offsetInBytes;
3494 vertexAttribs.push_back(attr0);
3496 VkVertexInputAttributeDescription attr1 =
3498 1u, // deUint32 location;
3499 0u, // deUint32 binding;
3500 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
3501 sizeof(Vec4), // deUint32 offsetInBytes;
3503 vertexAttribs.push_back(attr1);
3506 // If the test instantiation has additional input/output interface variables, we need to create additional bindings.
3507 // Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1
3508 // with location #2.
3511 const VkVertexInputBindingDescription vertexBinding1 =
3513 1u, // deUint32 binding;
3514 instance.interfaces.getInputType().getNumBytes(), // deUint32 strideInBytes;
3515 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate;
3517 vertexBindings.push_back(vertexBinding1);
3519 VkVertexInputAttributeDescription attr =
3521 2u, // deUint32 location;
3522 1u, // deUint32 binding;
3523 instance.interfaces.getInputType().getVkFormat(), // VkFormat format;
3524 0, // deUint32 offsetInBytes;
3526 vertexAttribs.push_back(attr);
3529 VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
3531 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
3532 DE_NULL, // const void* pNext;
3533 (VkPipelineVertexInputStateCreateFlags)0,
3534 1u, // deUint32 bindingCount;
3535 vertexBindings.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
3536 2u, // deUint32 attributeCount;
3537 vertexAttribs.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
3542 vertexInputStateParams.vertexBindingDescriptionCount += 1;
3543 vertexInputStateParams.vertexAttributeDescriptionCount += 1;
3546 vector<VkPipelineColorBlendAttachmentState> attBlendStates;
3547 const VkPipelineColorBlendAttachmentState attBlendState =
3549 DE_FALSE, // deUint32 blendEnable;
3550 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor;
3551 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor;
3552 VK_BLEND_OP_ADD, // VkBlendOp blendOpColor;
3553 VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha;
3554 VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha;
3555 VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha;
3556 (VK_COLOR_COMPONENT_R_BIT|
3557 VK_COLOR_COMPONENT_G_BIT|
3558 VK_COLOR_COMPONENT_B_BIT|
3559 VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask;
3561 attBlendStates.push_back(attBlendState);
3564 attBlendStates.push_back(attBlendState);
3566 VkPipelineColorBlendStateCreateInfo blendParams =
3568 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
3569 DE_NULL, // const void* pNext;
3570 (VkPipelineColorBlendStateCreateFlags)0,
3571 DE_FALSE, // VkBool32 logicOpEnable;
3572 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
3573 1u, // deUint32 attachmentCount;
3574 attBlendStates.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
3575 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4];
3579 blendParams.attachmentCount += 1;
3581 const VkPipelineTessellationStateCreateInfo tessellationState =
3583 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
3585 (VkPipelineTessellationStateCreateFlags)0,
3589 const VkPipelineTessellationStateCreateInfo* tessellationInfo = hasTessellation ? &tessellationState: DE_NULL;
3590 const VkGraphicsPipelineCreateInfo pipelineParams =
3592 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
3593 DE_NULL, // const void* pNext;
3594 0u, // VkPipelineCreateFlags flags;
3595 (deUint32)shaderStageParams.size(), // deUint32 stageCount;
3596 &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages;
3597 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
3598 &inputAssemblyParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
3599 tessellationInfo, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
3600 &viewportParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
3601 &rasterParams, // const VkPipelineRasterStateCreateInfo* pRasterState;
3602 &multisampleParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
3603 &depthStencilParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
3604 &blendParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
3605 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
3606 *pipelineLayout, // VkPipelineLayout layout;
3607 *renderPass, // VkRenderPass renderPass;
3608 0u, // deUint32 subpass;
3609 DE_NULL, // VkPipeline basePipelineHandle;
3610 0u, // deInt32 basePipelineIndex;
3613 const Unique<VkPipeline> pipeline (createGraphicsPipeline(vk, device, DE_NULL, &pipelineParams));
3617 const VkImageViewCreateInfo fragOutputViewParams =
3619 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3620 DE_NULL, // const void* pNext;
3621 0u, // VkImageViewCreateFlags flags;
3622 *fragOutputImage, // VkImage image;
3623 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3624 instance.interfaces.getOutputType().getVkFormat(), // VkFormat format;
3626 VK_COMPONENT_SWIZZLE_R,
3627 VK_COMPONENT_SWIZZLE_G,
3628 VK_COMPONENT_SWIZZLE_B,
3629 VK_COMPONENT_SWIZZLE_A
3630 }, // VkChannelMapping channels;
3632 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
3633 0u, // deUint32 baseMipLevel;
3634 1u, // deUint32 mipLevels;
3635 0u, // deUint32 baseArrayLayer;
3636 1u, // deUint32 arraySize;
3637 }, // VkImageSubresourceRange subresourceRange;
3639 fragOutputImageView = createImageView(vk, device, &fragOutputViewParams);
3640 attViews.push_back(*fragOutputImageView);
3644 VkFramebufferCreateInfo framebufferParams =
3646 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
3647 DE_NULL, // const void* pNext;
3648 (VkFramebufferCreateFlags)0,
3649 *renderPass, // VkRenderPass renderPass;
3650 1u, // deUint32 attachmentCount;
3651 attViews.data(), // const VkImageView* pAttachments;
3652 (deUint32)renderSize.x(), // deUint32 width;
3653 (deUint32)renderSize.y(), // deUint32 height;
3654 1u, // deUint32 layers;
3658 framebufferParams.attachmentCount += 1;
3660 const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, &framebufferParams));
3663 beginCommandBuffer(vk, *cmdBuf);
3666 const VkMemoryBarrier vertFlushBarrier =
3668 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
3669 DE_NULL, // const void* pNext;
3670 VK_ACCESS_HOST_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3671 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkMemoryInputFlags inputMask;
3673 vector<VkImageMemoryBarrier> colorAttBarriers;
3675 VkImageMemoryBarrier imgBarrier =
3677 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3678 DE_NULL, // const void* pNext;
3679 0u, // VkMemoryOutputFlags outputMask;
3680 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryInputFlags inputMask;
3681 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
3682 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
3683 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3684 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3685 *image, // VkImage image;
3687 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
3688 0u, // deUint32 baseMipLevel;
3689 1u, // deUint32 mipLevels;
3690 0u, // deUint32 baseArraySlice;
3691 1u, // deUint32 arraySize;
3692 } // VkImageSubresourceRange subresourceRange;
3694 colorAttBarriers.push_back(imgBarrier);
3697 imgBarrier.image = *fragOutputImage;
3698 colorAttBarriers.push_back(imgBarrier);
3699 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());
3703 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());
3708 vector<VkClearValue> clearValue;
3709 clearValue.push_back(makeClearValueColorF32(defaulClearColor[0], defaulClearColor[1], defaulClearColor[2], defaulClearColor[3]));
3712 clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0));
3714 beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), (deUint32)clearValue.size(), clearValue.data());
3717 vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
3719 const VkDeviceSize bindingOffset = 0;
3720 vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
3724 const VkDeviceSize bindingOffset = 0;
3725 vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset);
3727 if (hasPushConstants)
3729 vector<deUint8> pushConstantsBytes;
3730 instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes);
3732 const deUint32 size = static_cast<deUint32>(pushConstantsBytes.size());
3733 const void* data = &pushConstantsBytes.front();
3735 vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data);
3737 if (numResources != 0)
3739 // Bind to set number 0.
3740 vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL);
3742 vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/);
3743 endRenderPass(vk, *cmdBuf);
3746 vector<VkImageMemoryBarrier> renderFinishBarrier;
3747 VkImageMemoryBarrier imgBarrier =
3749 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3750 DE_NULL, // const void* pNext;
3751 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3752 VK_ACCESS_TRANSFER_READ_BIT, // VkMemoryInputFlags inputMask;
3753 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout;
3754 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
3755 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3756 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3757 *image, // VkImage image;
3759 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
3760 0u, // deUint32 baseMipLevel;
3761 1u, // deUint32 mipLevels;
3762 0u, // deUint32 baseArraySlice;
3763 1u, // deUint32 arraySize;
3764 } // VkImageSubresourceRange subresourceRange;
3766 renderFinishBarrier.push_back(imgBarrier);
3770 imgBarrier.image = *fragOutputImage;
3771 renderFinishBarrier.push_back(imgBarrier);
3772 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());
3776 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());
3781 const VkBufferImageCopy copyParams =
3783 (VkDeviceSize)0u, // VkDeviceSize bufferOffset;
3784 (deUint32)renderSize.x(), // deUint32 bufferRowLength;
3785 (deUint32)renderSize.y(), // deUint32 bufferImageHeight;
3787 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect;
3788 0u, // deUint32 mipLevel;
3789 0u, // deUint32 arrayLayer;
3790 1u, // deUint32 arraySize;
3791 }, // VkImageSubresourceCopy imageSubresource;
3792 { 0u, 0u, 0u }, // VkOffset3D imageOffset;
3793 { renderSize.x(), renderSize.y(), 1u } // VkExtent3D imageExtent;
3795 vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params);
3799 vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, ©Params);
3804 vector<VkBufferMemoryBarrier> cpFinishBarriers;
3805 VkBufferMemoryBarrier copyFinishBarrier =
3807 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
3808 DE_NULL, // const void* pNext;
3809 VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask;
3810 VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask;
3811 queueFamilyIndex, // deUint32 srcQueueFamilyIndex;
3812 queueFamilyIndex, // deUint32 destQueueFamilyIndex;
3813 *readImageBuffer, // VkBuffer buffer;
3814 0u, // VkDeviceSize offset;
3815 imageSizeBytes // VkDeviceSize size;
3817 cpFinishBarriers.push_back(copyFinishBarrier);
3821 copyFinishBarrier.buffer = *fragOutputBuffer;
3822 copyFinishBarrier.size = VK_WHOLE_SIZE;
3823 cpFinishBarriers.push_back(copyFinishBarrier);
3825 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);
3829 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);
3833 endCommandBuffer(vk, *cmdBuf);
3835 // Upload vertex data
3837 const VkMappedMemoryRange range =
3839 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3840 DE_NULL, // const void* pNext;
3841 vertexBufferMemory->getMemory(), // VkDeviceMemory mem;
3842 0, // VkDeviceSize offset;
3843 (VkDeviceSize)vertexDataSize, // VkDeviceSize size;
3845 void* vertexBufPtr = vertexBufferMemory->getHostPtr();
3847 deMemcpy(vertexBufPtr, &vertexData[0], vertexDataSize);
3848 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3853 vector<deUint8> inputBufferBytes;
3854 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3856 const deUint32 typNumBytes = instance.interfaces.getInputType().getNumBytes();
3857 const deUint32 bufNumBytes = static_cast<deUint32>(inputBufferBytes.size());
3859 // Require that the test instantation provides four output values.
3860 DE_ASSERT(bufNumBytes == 4 * typNumBytes);
3862 // We have four triangles. Because interpolation happens before executing the fragment shader,
3863 // we need to provide the same vertex attribute for the same triangle. That means, duplicate each
3864 // value three times for all four values.
3866 const deUint8* provided = static_cast<const deUint8*>(&inputBufferBytes.front());
3867 vector<deUint8> data;
3869 data.reserve(3 * bufNumBytes);
3871 for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes)
3872 for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx)
3873 for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx)
3874 data.push_back(provided[offset + byteNdx]);
3876 deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size());
3878 const VkMappedMemoryRange range =
3880 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3881 DE_NULL, // const void* pNext;
3882 vertexInputMemory->getMemory(), // VkDeviceMemory mem;
3883 0, // VkDeviceSize offset;
3884 VK_WHOLE_SIZE, // VkDeviceSize size;
3887 VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
3890 // Submit & wait for completion
3891 submitCommandsAndWait(vk, device, queue, cmdBuf.get());
3893 const void* imagePtr = readImageBufferMemory->getHostPtr();
3894 const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
3895 renderSize.x(), renderSize.y(), 1, imagePtr);
3898 const VkMappedMemoryRange range =
3900 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3901 DE_NULL, // const void* pNext;
3902 readImageBufferMemory->getMemory(), // VkDeviceMemory mem;
3903 0, // VkDeviceSize offset;
3904 imageSizeBytes, // VkDeviceSize size;
3907 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3908 context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer);
3913 const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y());
3914 const VkMappedMemoryRange range =
3916 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3917 DE_NULL, // const void* pNext;
3918 fragOutputMemory->getMemory(), // VkDeviceMemory mem;
3919 0, // VkDeviceSize offset;
3920 fragOutputImgSize, // VkDeviceSize size;
3923 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3926 { // Make sure all output resources are ready.
3927 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
3929 const VkMappedMemoryRange range =
3931 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
3932 DE_NULL, // const void* pNext;
3933 outResourceMemories[outputNdx]->getMemory(), // VkDeviceMemory mem;
3934 0, // VkDeviceSize offset;
3935 VK_WHOLE_SIZE, // VkDeviceSize size;
3938 VK_CHECK(vk.invalidateMappedMemoryRanges(device, 1u, &range));
3942 const RGBA threshold(1, 1, 1, 1);
3944 const RGBA upperLeft(pixelBuffer.getPixel(1, 1));
3945 if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold))
3946 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch"));
3948 const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1));
3949 if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold))
3950 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch"));
3952 const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1));
3953 if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold))
3954 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch"));
3956 const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1));
3957 if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold))
3958 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch"));
3960 // Check that the contents in the ouput variable matches expected.
3963 vector<deUint8> inputBufferBytes;
3964 vector<deUint8> outputBufferBytes;
3966 instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes);
3967 instance.interfaces.getOutputBuffer()->getBytes(outputBufferBytes);
3969 const IFDataType& inputType = instance.interfaces.getInputType();
3970 const IFDataType& outputType = instance.interfaces.getOutputType();
3971 const void* inputData = &inputBufferBytes.front();
3972 const void* outputData = &outputBufferBytes.front();
3973 vector<std::pair<int, int> > positions;
3974 const tcu::ConstPixelBufferAccess fragOutputBufferAccess (outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr());
3976 positions.push_back(std::make_pair(1, 1));
3977 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1));
3978 positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1));
3979 positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1));
3981 for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx)
3983 const int x = positions[posNdx].first;
3984 const int y = positions[posNdx].second;
3987 if (outputType.elementType == NUMBERTYPE_FLOAT32)
3989 const float* expected = static_cast<const float*>(outputData) + posNdx * outputType.numElements;
3990 const float* actual = static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y));
3992 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
3993 if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
3996 else if (outputType.elementType == NUMBERTYPE_INT32)
3998 const deInt32* expected = static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements;
3999 const deInt32* actual = static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y));
4001 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4002 if (expected[eleNdx] != actual[eleNdx])
4005 else if (outputType.elementType == NUMBERTYPE_UINT32)
4007 const deUint32* expected = static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements;
4008 const deUint32* actual = static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y));
4010 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4011 if (expected[eleNdx] != actual[eleNdx])
4014 else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType == NUMBERTYPE_FLOAT64)
4016 const double* original = static_cast<const double*>(inputData) + posNdx * outputType.numElements;
4017 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4019 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4020 if (!compare16BitFloat64(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
4023 else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType != NUMBERTYPE_FLOAT64)
4025 if (inputType.elementType == NUMBERTYPE_FLOAT16)
4027 const deFloat16* original = static_cast<const deFloat16*>(inputData) + posNdx * outputType.numElements;
4028 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4030 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4031 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
4036 const float* original = static_cast<const float*>(inputData) + posNdx * outputType.numElements;
4037 const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4039 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4040 if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog()))
4044 else if (outputType.elementType == NUMBERTYPE_INT16)
4046 const deInt16* expected = static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements;
4047 const deInt16* actual = static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4049 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4050 if (expected[eleNdx] != actual[eleNdx])
4053 else if (outputType.elementType == NUMBERTYPE_UINT16)
4055 const deUint16* expected = static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements;
4056 const deUint16* actual = static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y));
4058 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4059 if (expected[eleNdx] != actual[eleNdx])
4062 else if (outputType.elementType == NUMBERTYPE_FLOAT64)
4064 const double* expected = static_cast<const double*>(outputData) + posNdx * outputType.numElements;
4065 const double* actual = static_cast<const double*>(fragOutputBufferAccess.getPixelPtr(x, y));
4067 for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx)
4068 if (!compare64BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog()))
4072 DE_ASSERT(0 && "unhandled type");
4076 return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch"));
4080 // Check the contents in output resources match with expected.
4081 for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx)
4083 const BufferSp& expected = instance.resources.outputs[outputNdx].getBuffer();
4085 if (instance.resources.verifyIO != DE_NULL)
4087 if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog()))
4088 return tcu::TestStatus::fail("Resource returned doesn't match with expected");
4092 vector<deUint8> expectedBytes;
4093 expected->getBytes(expectedBytes);
4095 if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size()))
4096 return tcu::TestStatus::fail("Resource returned doesn't match bitwisely with expected");
4101 return TestStatus::pass("Rendered output matches input");
4104 const vector<ShaderElement>& getVertFragPipelineStages (void)
4106 static vector<ShaderElement> vertFragPipelineStages;
4107 if(vertFragPipelineStages.empty())
4109 vertFragPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4110 vertFragPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4112 return vertFragPipelineStages;
4115 const vector<ShaderElement>& getTessPipelineStages (void)
4117 static vector<ShaderElement> tessPipelineStages;
4118 if(tessPipelineStages.empty())
4120 tessPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4121 tessPipelineStages.push_back(ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT));
4122 tessPipelineStages.push_back(ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT));
4123 tessPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4125 return tessPipelineStages;
4128 const vector<ShaderElement>& getGeomPipelineStages (void)
4130 static vector<ShaderElement> geomPipelineStages;
4131 if(geomPipelineStages.empty())
4133 geomPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT));
4134 geomPipelineStages.push_back(ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT));
4135 geomPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT));
4137 return geomPipelineStages;
4140 // Helper structure used by addTestForStage function.
4143 typedef const vector<ShaderElement>& (*GetPipelineStagesFn)();
4144 typedef void (*AddShaderCodeCustomStageFn)(vk::SourceCollections&, InstanceContext);
4146 GetPipelineStagesFn getPipelineFn;
4147 AddShaderCodeCustomStageFn initProgramsFn;
4150 : getPipelineFn(DE_NULL)
4151 , initProgramsFn(DE_NULL)
4155 StageData(GetPipelineStagesFn pipelineGetter, AddShaderCodeCustomStageFn programsInitializer)
4156 : getPipelineFn(pipelineGetter)
4157 , initProgramsFn(programsInitializer)
4162 // Helper function used by addTestForStage function.
4163 const StageData& getStageData (vk::VkShaderStageFlagBits stage)
4166 static map<vk::VkShaderStageFlagBits, StageData> testedStageData;
4167 if(testedStageData.empty())
4169 testedStageData[VK_SHADER_STAGE_VERTEX_BIT] = StageData(getVertFragPipelineStages, addShaderCodeCustomVertex);
4170 testedStageData[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessControl);
4171 testedStageData[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessEval);
4172 testedStageData[VK_SHADER_STAGE_GEOMETRY_BIT] = StageData(getGeomPipelineStages, addShaderCodeCustomGeometry);
4173 testedStageData[VK_SHADER_STAGE_FRAGMENT_BIT] = StageData(getVertFragPipelineStages, addShaderCodeCustomFragment);
4176 return testedStageData[stage];
4179 void createTestForStage (vk::VkShaderStageFlagBits stage,
4180 const std::string& name,
4181 const RGBA (&inputColors)[4],
4182 const RGBA (&outputColors)[4],
4183 const map<string, string>& testCodeFragments,
4184 const SpecConstants& specConstants,
4185 const PushConstants& pushConstants,
4186 const GraphicsResources& resources,
4187 const GraphicsInterfaces& interfaces,
4188 const vector<string>& extensions,
4189 const vector<string>& features,
4190 VulkanFeatures vulkanFeatures,
4191 tcu::TestCaseGroup* tests,
4192 const qpTestResult failResult,
4193 const string& failMessageTemplate,
4194 const bool renderFullSquare)
4196 const StageData& stageData = getStageData(stage);
4197 DE_ASSERT(stageData.getPipelineFn || stageData.initProgramsFn);
4198 const vector<ShaderElement>& pipeline = stageData.getPipelineFn();
4200 StageToSpecConstantMap specConstantMap;
4201 if (!specConstants.empty())
4202 specConstantMap[stage] = specConstants;
4204 InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstantMap, pushConstants, resources, interfaces, extensions, features, vulkanFeatures, stage);
4205 for (size_t i = 0; i < pipeline.size(); ++i)
4207 ctx.moduleMap[pipeline[i].moduleName].push_back(std::make_pair(pipeline[i].entryName, pipeline[i].stage));
4208 ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | pipeline[i].stage);
4211 ctx.failResult = failResult;
4212 if (!failMessageTemplate.empty())
4213 ctx.failMessageTemplate = failMessageTemplate;
4215 ctx.renderFullSquare = renderFullSquare;
4216 addFunctionCaseWithPrograms<InstanceContext>(tests, name, "", stageData.initProgramsFn, runAndVerifyDefaultPipeline, ctx);
4219 void createTestsForAllStages (const std::string& name,
4220 const RGBA (&inputColors)[4],
4221 const RGBA (&outputColors)[4],
4222 const map<string, string>& testCodeFragments,
4223 const SpecConstants& specConstants,
4224 const PushConstants& pushConstants,
4225 const GraphicsResources& resources,
4226 const GraphicsInterfaces& interfaces,
4227 const vector<string>& extensions,
4228 const vector<string>& features,
4229 VulkanFeatures vulkanFeatures,
4230 tcu::TestCaseGroup* tests,
4231 const qpTestResult failResult,
4232 const string& failMessageTemplate)
4234 createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, name + "_vert",
4235 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4236 interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4238 createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name + "_tessc",
4239 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4240 interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4242 createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, name + "_tesse",
4243 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4244 interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4246 createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, name + "_geom",
4247 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4248 interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4250 createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, name + "_frag",
4251 inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources,
4252 interfaces, extensions, features, vulkanFeatures, tests, failResult, failMessageTemplate);
4255 void addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments)
4257 RGBA defaultColors[4];
4258 getDefaultColors(defaultColors);
4260 createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name,
4261 defaultColors, defaultColors, fragments, SpecConstants(), PushConstants(), GraphicsResources(),
4262 GraphicsInterfaces(), vector<string>(), vector<string>(), VulkanFeatures(), group);