1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2017 Google Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Graphics pipeline for SPIR-V assembly tests 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "vktSpvAsmGraphicsShaderTestUtil.hpp" 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "tcuFloat.hpp" 27e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 28e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 29e5c31af7Sopenharmony_ci 30e5c31af7Sopenharmony_ci#include "vkDefs.hpp" 31e5c31af7Sopenharmony_ci#include "vkMemUtil.hpp" 32e5c31af7Sopenharmony_ci#include "vkPlatform.hpp" 33e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 34e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 35e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 36e5c31af7Sopenharmony_ci#include "vkImageUtil.hpp" 37e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#include "deRandom.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_cinamespace vkt 42e5c31af7Sopenharmony_ci{ 43e5c31af7Sopenharmony_cinamespace SpirVAssembly 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_ci 46e5c31af7Sopenharmony_ciusing namespace vk; 47e5c31af7Sopenharmony_ciusing std::map; 48e5c31af7Sopenharmony_ciusing std::string; 49e5c31af7Sopenharmony_ciusing std::vector; 50e5c31af7Sopenharmony_ciusing tcu::Float16; 51e5c31af7Sopenharmony_ciusing tcu::Float32; 52e5c31af7Sopenharmony_ciusing tcu::Float64; 53e5c31af7Sopenharmony_ciusing tcu::IVec3; 54e5c31af7Sopenharmony_ciusing tcu::IVec4; 55e5c31af7Sopenharmony_ciusing tcu::RGBA; 56e5c31af7Sopenharmony_ciusing tcu::TestLog; 57e5c31af7Sopenharmony_ciusing tcu::TestStatus; 58e5c31af7Sopenharmony_ciusing tcu::Vec4; 59e5c31af7Sopenharmony_ciusing de::UniquePtr; 60e5c31af7Sopenharmony_ciusing tcu::StringTemplate; 61e5c31af7Sopenharmony_ciusing tcu::Vec4; 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_cideUint32 IFDataType::getElementNumBytes (void) const 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci if (elementType < NUMBERTYPE_END32) 66e5c31af7Sopenharmony_ci return 4; 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ci if (elementType < NUMBERTYPE_END16) 69e5c31af7Sopenharmony_ci return 2; 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci return 8; 72e5c31af7Sopenharmony_ci} 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_ciVkFormat IFDataType::getVkFormat (void) const 75e5c31af7Sopenharmony_ci{ 76e5c31af7Sopenharmony_ci if (numElements == 1) 77e5c31af7Sopenharmony_ci { 78e5c31af7Sopenharmony_ci switch (elementType) 79e5c31af7Sopenharmony_ci { 80e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64_SFLOAT; 81e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32_SFLOAT; 82e5c31af7Sopenharmony_ci case NUMBERTYPE_INT32: return VK_FORMAT_R32_SINT; 83e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT32: return VK_FORMAT_R32_UINT; 84e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16_SFLOAT; 85e5c31af7Sopenharmony_ci case NUMBERTYPE_INT16: return VK_FORMAT_R16_SINT; 86e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT16: return VK_FORMAT_R16_UINT; 87e5c31af7Sopenharmony_ci default: break; 88e5c31af7Sopenharmony_ci } 89e5c31af7Sopenharmony_ci } 90e5c31af7Sopenharmony_ci else if (numElements == 2) 91e5c31af7Sopenharmony_ci { 92e5c31af7Sopenharmony_ci switch (elementType) 93e5c31af7Sopenharmony_ci { 94e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64G64_SFLOAT; 95e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32_SFLOAT; 96e5c31af7Sopenharmony_ci case NUMBERTYPE_INT32: return VK_FORMAT_R32G32_SINT; 97e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32_UINT; 98e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16_SFLOAT; 99e5c31af7Sopenharmony_ci case NUMBERTYPE_INT16: return VK_FORMAT_R16G16_SINT; 100e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16_UINT; 101e5c31af7Sopenharmony_ci default: break; 102e5c31af7Sopenharmony_ci } 103e5c31af7Sopenharmony_ci } 104e5c31af7Sopenharmony_ci else if (numElements == 3) 105e5c31af7Sopenharmony_ci { 106e5c31af7Sopenharmony_ci switch (elementType) 107e5c31af7Sopenharmony_ci { 108e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64G64B64_SFLOAT; 109e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32B32_SFLOAT; 110e5c31af7Sopenharmony_ci case NUMBERTYPE_INT32: return VK_FORMAT_R32G32B32_SINT; 111e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32B32_UINT; 112e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16B16_SFLOAT; 113e5c31af7Sopenharmony_ci case NUMBERTYPE_INT16: return VK_FORMAT_R16G16B16_SINT; 114e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16B16_UINT; 115e5c31af7Sopenharmony_ci default: break; 116e5c31af7Sopenharmony_ci } 117e5c31af7Sopenharmony_ci } 118e5c31af7Sopenharmony_ci else if (numElements == 4) 119e5c31af7Sopenharmony_ci { 120e5c31af7Sopenharmony_ci switch (elementType) 121e5c31af7Sopenharmony_ci { 122e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT64: return VK_FORMAT_R64G64B64A64_SFLOAT; 123e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT32: return VK_FORMAT_R32G32B32A32_SFLOAT; 124e5c31af7Sopenharmony_ci case NUMBERTYPE_INT32: return VK_FORMAT_R32G32B32A32_SINT; 125e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT32: return VK_FORMAT_R32G32B32A32_UINT; 126e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT16: return VK_FORMAT_R16G16B16A16_SFLOAT; 127e5c31af7Sopenharmony_ci case NUMBERTYPE_INT16: return VK_FORMAT_R16G16B16A16_SINT; 128e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT16: return VK_FORMAT_R16G16B16A16_UINT; 129e5c31af7Sopenharmony_ci default: break; 130e5c31af7Sopenharmony_ci } 131e5c31af7Sopenharmony_ci } 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci DE_ASSERT(false); 134e5c31af7Sopenharmony_ci return VK_FORMAT_UNDEFINED; 135e5c31af7Sopenharmony_ci} 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_citcu::TextureFormat IFDataType::getTextureFormat (void) const 138e5c31af7Sopenharmony_ci{ 139e5c31af7Sopenharmony_ci tcu::TextureFormat::ChannelType ct = tcu::TextureFormat::CHANNELTYPE_LAST; 140e5c31af7Sopenharmony_ci tcu::TextureFormat::ChannelOrder co = tcu::TextureFormat::CHANNELORDER_LAST; 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci switch (elementType) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT64: ct = tcu::TextureFormat::FLOAT64; break; 145e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT32: ct = tcu::TextureFormat::FLOAT; break; 146e5c31af7Sopenharmony_ci case NUMBERTYPE_INT32: ct = tcu::TextureFormat::SIGNED_INT32; break; 147e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT32: ct = tcu::TextureFormat::UNSIGNED_INT32; break; 148e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT16: ct = tcu::TextureFormat::HALF_FLOAT; break; 149e5c31af7Sopenharmony_ci case NUMBERTYPE_INT16: ct = tcu::TextureFormat::SIGNED_INT16; break; 150e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT16: ct = tcu::TextureFormat::UNSIGNED_INT16; break; 151e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 152e5c31af7Sopenharmony_ci } 153e5c31af7Sopenharmony_ci 154e5c31af7Sopenharmony_ci switch (numElements) 155e5c31af7Sopenharmony_ci { 156e5c31af7Sopenharmony_ci case 1: co = tcu::TextureFormat::R; break; 157e5c31af7Sopenharmony_ci case 2: co = tcu::TextureFormat::RG; break; 158e5c31af7Sopenharmony_ci case 3: co = tcu::TextureFormat::RGB; break; 159e5c31af7Sopenharmony_ci case 4: co = tcu::TextureFormat::RGBA; break; 160e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 161e5c31af7Sopenharmony_ci } 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci return tcu::TextureFormat(co, ct); 164e5c31af7Sopenharmony_ci} 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_cistring IFDataType::str (void) const 167e5c31af7Sopenharmony_ci{ 168e5c31af7Sopenharmony_ci string ret; 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci switch (elementType) 171e5c31af7Sopenharmony_ci { 172e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT64: ret = "f64"; break; 173e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT32: ret = "f32"; break; 174e5c31af7Sopenharmony_ci case NUMBERTYPE_INT32: ret = "i32"; break; 175e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT32: ret = "u32"; break; 176e5c31af7Sopenharmony_ci case NUMBERTYPE_FLOAT16: ret = "f16"; break; 177e5c31af7Sopenharmony_ci case NUMBERTYPE_INT16: ret = "i16"; break; 178e5c31af7Sopenharmony_ci case NUMBERTYPE_UINT16: ret = "u16"; break; 179e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 180e5c31af7Sopenharmony_ci } 181e5c31af7Sopenharmony_ci 182e5c31af7Sopenharmony_ci if (numElements == 1) 183e5c31af7Sopenharmony_ci return ret; 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci return string("v") + numberToString(numElements) + ret; 186e5c31af7Sopenharmony_ci} 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ciVkBufferUsageFlagBits getMatchingBufferUsageFlagBit (VkDescriptorType dType) 189e5c31af7Sopenharmony_ci{ 190e5c31af7Sopenharmony_ci switch (dType) 191e5c31af7Sopenharmony_ci { 192e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: return VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 193e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: return VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; 194e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 195e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 196e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT; 197e5c31af7Sopenharmony_ci default: DE_ASSERT(0 && "not implemented"); 198e5c31af7Sopenharmony_ci } 199e5c31af7Sopenharmony_ci return (VkBufferUsageFlagBits)0; 200e5c31af7Sopenharmony_ci} 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_ciVkImageUsageFlags getMatchingImageUsageFlags (VkDescriptorType dType) 203e5c31af7Sopenharmony_ci{ 204e5c31af7Sopenharmony_ci switch (dType) 205e5c31af7Sopenharmony_ci { 206e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: return VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 207e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 208e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: return VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 209e5c31af7Sopenharmony_ci default: DE_FATAL("Not implemented"); 210e5c31af7Sopenharmony_ci } 211e5c31af7Sopenharmony_ci return (VkImageUsageFlags)0; 212e5c31af7Sopenharmony_ci} 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_cistatic void requireFormatUsageSupport (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, VkFormat format, VkImageTiling imageTiling, VkImageUsageFlags requiredUsageFlags) 215e5c31af7Sopenharmony_ci{ 216e5c31af7Sopenharmony_ci VkFormatProperties properties; 217e5c31af7Sopenharmony_ci VkFormatFeatureFlags tilingFeatures = 0; 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci vki.getPhysicalDeviceFormatProperties(physicalDevice, format, &properties); 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci switch (imageTiling) 222e5c31af7Sopenharmony_ci { 223e5c31af7Sopenharmony_ci case VK_IMAGE_TILING_LINEAR: 224e5c31af7Sopenharmony_ci tilingFeatures = properties.linearTilingFeatures; 225e5c31af7Sopenharmony_ci break; 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci case VK_IMAGE_TILING_OPTIMAL: 228e5c31af7Sopenharmony_ci tilingFeatures = properties.optimalTilingFeatures; 229e5c31af7Sopenharmony_ci break; 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ci default: 232e5c31af7Sopenharmony_ci DE_ASSERT(false); 233e5c31af7Sopenharmony_ci break; 234e5c31af7Sopenharmony_ci } 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci if ((requiredUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) != 0) 237e5c31af7Sopenharmony_ci { 238e5c31af7Sopenharmony_ci if ((tilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) 239e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Image format cannot be used as color attachment"); 240e5c31af7Sopenharmony_ci requiredUsageFlags ^= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 241e5c31af7Sopenharmony_ci } 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci if ((requiredUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) != 0) 245e5c31af7Sopenharmony_ci { 246e5c31af7Sopenharmony_ci if ((tilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0) 247e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Image format cannot be used as transfer source"); 248e5c31af7Sopenharmony_ci requiredUsageFlags ^= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 249e5c31af7Sopenharmony_ci } 250e5c31af7Sopenharmony_ci 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci DE_ASSERT(!requiredUsageFlags && "checking other image usage bits not supported yet"); 253e5c31af7Sopenharmony_ci} 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_ciInstanceContext::InstanceContext (const RGBA (&inputs)[4], 256e5c31af7Sopenharmony_ci const RGBA (&outputs)[4], 257e5c31af7Sopenharmony_ci const map<string, string>& testCodeFragments_, 258e5c31af7Sopenharmony_ci const StageToSpecConstantMap& specConstants_, 259e5c31af7Sopenharmony_ci const PushConstants& pushConsants_, 260e5c31af7Sopenharmony_ci const GraphicsResources& resources_, 261e5c31af7Sopenharmony_ci const GraphicsInterfaces& interfaces_, 262e5c31af7Sopenharmony_ci const vector<string>& extensions_, 263e5c31af7Sopenharmony_ci VulkanFeatures vulkanFeatures_, 264e5c31af7Sopenharmony_ci VkShaderStageFlags customizedStages_) 265e5c31af7Sopenharmony_ci : testCodeFragments (testCodeFragments_) 266e5c31af7Sopenharmony_ci , specConstants (specConstants_) 267e5c31af7Sopenharmony_ci , hasTessellation (false) 268e5c31af7Sopenharmony_ci , requiredStages (static_cast<VkShaderStageFlagBits>(0)) 269e5c31af7Sopenharmony_ci , requiredDeviceExtensions (extensions_) 270e5c31af7Sopenharmony_ci , requestedFeatures (vulkanFeatures_) 271e5c31af7Sopenharmony_ci , pushConstants (pushConsants_) 272e5c31af7Sopenharmony_ci , customizedStages (customizedStages_) 273e5c31af7Sopenharmony_ci , resources (resources_) 274e5c31af7Sopenharmony_ci , interfaces (interfaces_) 275e5c31af7Sopenharmony_ci , failResult (QP_TEST_RESULT_FAIL) 276e5c31af7Sopenharmony_ci , failMessageTemplate ("${reason}") 277e5c31af7Sopenharmony_ci , renderFullSquare (false) 278e5c31af7Sopenharmony_ci , splitRenderArea (false) 279e5c31af7Sopenharmony_ci{ 280e5c31af7Sopenharmony_ci inputColors[0] = inputs[0]; 281e5c31af7Sopenharmony_ci inputColors[1] = inputs[1]; 282e5c31af7Sopenharmony_ci inputColors[2] = inputs[2]; 283e5c31af7Sopenharmony_ci inputColors[3] = inputs[3]; 284e5c31af7Sopenharmony_ci 285e5c31af7Sopenharmony_ci outputColors[0] = outputs[0]; 286e5c31af7Sopenharmony_ci outputColors[1] = outputs[1]; 287e5c31af7Sopenharmony_ci outputColors[2] = outputs[2]; 288e5c31af7Sopenharmony_ci outputColors[3] = outputs[3]; 289e5c31af7Sopenharmony_ci} 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ciInstanceContext::InstanceContext (const InstanceContext& other) 292e5c31af7Sopenharmony_ci : moduleMap (other.moduleMap) 293e5c31af7Sopenharmony_ci , testCodeFragments (other.testCodeFragments) 294e5c31af7Sopenharmony_ci , specConstants (other.specConstants) 295e5c31af7Sopenharmony_ci , hasTessellation (other.hasTessellation) 296e5c31af7Sopenharmony_ci , requiredStages (other.requiredStages) 297e5c31af7Sopenharmony_ci , requiredDeviceExtensions (other.requiredDeviceExtensions) 298e5c31af7Sopenharmony_ci , requestedFeatures (other.requestedFeatures) 299e5c31af7Sopenharmony_ci , pushConstants (other.pushConstants) 300e5c31af7Sopenharmony_ci , customizedStages (other.customizedStages) 301e5c31af7Sopenharmony_ci , resources (other.resources) 302e5c31af7Sopenharmony_ci , interfaces (other.interfaces) 303e5c31af7Sopenharmony_ci , failResult (other.failResult) 304e5c31af7Sopenharmony_ci , failMessageTemplate (other.failMessageTemplate) 305e5c31af7Sopenharmony_ci , renderFullSquare (other.renderFullSquare) 306e5c31af7Sopenharmony_ci , splitRenderArea (other.splitRenderArea) 307e5c31af7Sopenharmony_ci{ 308e5c31af7Sopenharmony_ci inputColors[0] = other.inputColors[0]; 309e5c31af7Sopenharmony_ci inputColors[1] = other.inputColors[1]; 310e5c31af7Sopenharmony_ci inputColors[2] = other.inputColors[2]; 311e5c31af7Sopenharmony_ci inputColors[3] = other.inputColors[3]; 312e5c31af7Sopenharmony_ci 313e5c31af7Sopenharmony_ci outputColors[0] = other.outputColors[0]; 314e5c31af7Sopenharmony_ci outputColors[1] = other.outputColors[1]; 315e5c31af7Sopenharmony_ci outputColors[2] = other.outputColors[2]; 316e5c31af7Sopenharmony_ci outputColors[3] = other.outputColors[3]; 317e5c31af7Sopenharmony_ci} 318e5c31af7Sopenharmony_ci 319e5c31af7Sopenharmony_cistring InstanceContext::getSpecializedFailMessage (const string& failureReason) 320e5c31af7Sopenharmony_ci{ 321e5c31af7Sopenharmony_ci map<string, string> parameters; 322e5c31af7Sopenharmony_ci parameters["reason"] = failureReason; 323e5c31af7Sopenharmony_ci return StringTemplate(failMessageTemplate).specialize(parameters); 324e5c31af7Sopenharmony_ci} 325e5c31af7Sopenharmony_ci 326e5c31af7Sopenharmony_ciInstanceContext createInstanceContext (const std::vector<ShaderElement>& elements, 327e5c31af7Sopenharmony_ci const tcu::RGBA (&inputColors)[4], 328e5c31af7Sopenharmony_ci const tcu::RGBA (&outputColors)[4], 329e5c31af7Sopenharmony_ci const std::map<std::string, std::string>& testCodeFragments, 330e5c31af7Sopenharmony_ci const StageToSpecConstantMap& specConstants, 331e5c31af7Sopenharmony_ci const PushConstants& pushConstants, 332e5c31af7Sopenharmony_ci const GraphicsResources& resources, 333e5c31af7Sopenharmony_ci const GraphicsInterfaces& interfaces, 334e5c31af7Sopenharmony_ci const std::vector<std::string>& extensions, 335e5c31af7Sopenharmony_ci VulkanFeatures vulkanFeatures, 336e5c31af7Sopenharmony_ci VkShaderStageFlags customizedStages, 337e5c31af7Sopenharmony_ci const qpTestResult failResult, 338e5c31af7Sopenharmony_ci const std::string& failMessageTemplate) 339e5c31af7Sopenharmony_ci{ 340e5c31af7Sopenharmony_ci InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, interfaces, extensions, vulkanFeatures, customizedStages); 341e5c31af7Sopenharmony_ci for (size_t i = 0; i < elements.size(); ++i) 342e5c31af7Sopenharmony_ci { 343e5c31af7Sopenharmony_ci ctx.moduleMap[elements[i].moduleName].push_back(std::make_pair(elements[i].entryName, elements[i].stage)); 344e5c31af7Sopenharmony_ci ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | elements[i].stage); 345e5c31af7Sopenharmony_ci } 346e5c31af7Sopenharmony_ci ctx.failResult = failResult; 347e5c31af7Sopenharmony_ci if (!failMessageTemplate.empty()) 348e5c31af7Sopenharmony_ci ctx.failMessageTemplate = failMessageTemplate; 349e5c31af7Sopenharmony_ci return ctx; 350e5c31af7Sopenharmony_ci} 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ciInstanceContext createInstanceContext (const std::vector<ShaderElement>& elements, 353e5c31af7Sopenharmony_ci tcu::RGBA (&inputColors)[4], 354e5c31af7Sopenharmony_ci const tcu::RGBA (&outputColors)[4], 355e5c31af7Sopenharmony_ci const std::map<std::string, std::string>& testCodeFragments) 356e5c31af7Sopenharmony_ci{ 357e5c31af7Sopenharmony_ci return createInstanceContext(elements, inputColors, outputColors, testCodeFragments, 358e5c31af7Sopenharmony_ci StageToSpecConstantMap(), PushConstants(), GraphicsResources(), 359e5c31af7Sopenharmony_ci GraphicsInterfaces(), std::vector<std::string>(), 360e5c31af7Sopenharmony_ci VulkanFeatures(), vk::VK_SHADER_STAGE_ALL); 361e5c31af7Sopenharmony_ci} 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ciInstanceContext createInstanceContext (const std::vector<ShaderElement>& elements, 364e5c31af7Sopenharmony_ci const std::map<std::string, std::string>& testCodeFragments) 365e5c31af7Sopenharmony_ci{ 366e5c31af7Sopenharmony_ci tcu::RGBA defaultColors[4]; 367e5c31af7Sopenharmony_ci getDefaultColors(defaultColors); 368e5c31af7Sopenharmony_ci return createInstanceContext(elements, defaultColors, defaultColors, testCodeFragments); 369e5c31af7Sopenharmony_ci} 370e5c31af7Sopenharmony_ci 371e5c31af7Sopenharmony_ciUnusedVariableContext createUnusedVariableContext(const ShaderTaskArray& shaderTasks, const VariableLocation& location) 372e5c31af7Sopenharmony_ci{ 373e5c31af7Sopenharmony_ci for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(shaderTasks); ++i) 374e5c31af7Sopenharmony_ci { 375e5c31af7Sopenharmony_ci DE_ASSERT(shaderTasks[i] >= 0 && shaderTasks[i] < SHADER_TASK_LAST); 376e5c31af7Sopenharmony_ci } 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ci std::vector<ShaderElement> elements; 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_ci DE_ASSERT(shaderTasks[SHADER_TASK_INDEX_VERTEX] != SHADER_TASK_NONE); 381e5c31af7Sopenharmony_ci DE_ASSERT(shaderTasks[SHADER_TASK_INDEX_FRAGMENT] != SHADER_TASK_NONE); 382e5c31af7Sopenharmony_ci elements.push_back(ShaderElement("vert", "main", vk::VK_SHADER_STAGE_VERTEX_BIT)); 383e5c31af7Sopenharmony_ci elements.push_back(ShaderElement("frag", "main", vk::VK_SHADER_STAGE_FRAGMENT_BIT)); 384e5c31af7Sopenharmony_ci 385e5c31af7Sopenharmony_ci if (shaderTasks[SHADER_TASK_INDEX_GEOMETRY] != SHADER_TASK_NONE) 386e5c31af7Sopenharmony_ci elements.push_back(ShaderElement("geom", "main", vk::VK_SHADER_STAGE_GEOMETRY_BIT)); 387e5c31af7Sopenharmony_ci 388e5c31af7Sopenharmony_ci if (shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL] != SHADER_TASK_NONE) 389e5c31af7Sopenharmony_ci elements.push_back(ShaderElement("tessc", "main", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)); 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_ci if (shaderTasks[SHADER_TASK_INDEX_TESS_EVAL] != SHADER_TASK_NONE) 392e5c31af7Sopenharmony_ci elements.push_back(ShaderElement("tesse", "main", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)); 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ci return UnusedVariableContext( 395e5c31af7Sopenharmony_ci createInstanceContext(elements, map<string, string>()), 396e5c31af7Sopenharmony_ci shaderTasks, 397e5c31af7Sopenharmony_ci location); 398e5c31af7Sopenharmony_ci} 399e5c31af7Sopenharmony_ci 400e5c31af7Sopenharmony_ciShaderElement::ShaderElement (const string& moduleName_, 401e5c31af7Sopenharmony_ci const string& entryPoint_, 402e5c31af7Sopenharmony_ci VkShaderStageFlagBits shaderStage_) 403e5c31af7Sopenharmony_ci : moduleName(moduleName_) 404e5c31af7Sopenharmony_ci , entryName(entryPoint_) 405e5c31af7Sopenharmony_ci , stage(shaderStage_) 406e5c31af7Sopenharmony_ci{ 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_civoid getDefaultColors (RGBA (&colors)[4]) 410e5c31af7Sopenharmony_ci{ 411e5c31af7Sopenharmony_ci colors[0] = RGBA::white(); 412e5c31af7Sopenharmony_ci colors[1] = RGBA::red(); 413e5c31af7Sopenharmony_ci colors[2] = RGBA::green(); 414e5c31af7Sopenharmony_ci colors[3] = RGBA::blue(); 415e5c31af7Sopenharmony_ci} 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_civoid getHalfColorsFullAlpha (RGBA (&colors)[4]) 418e5c31af7Sopenharmony_ci{ 419e5c31af7Sopenharmony_ci colors[0] = RGBA(127, 127, 127, 255); 420e5c31af7Sopenharmony_ci colors[1] = RGBA(127, 0, 0, 255); 421e5c31af7Sopenharmony_ci colors[2] = RGBA(0, 127, 0, 255); 422e5c31af7Sopenharmony_ci colors[3] = RGBA(0, 0, 127, 255); 423e5c31af7Sopenharmony_ci} 424e5c31af7Sopenharmony_ci 425e5c31af7Sopenharmony_civoid getInvertedDefaultColors (RGBA (&colors)[4]) 426e5c31af7Sopenharmony_ci{ 427e5c31af7Sopenharmony_ci colors[0] = RGBA(0, 0, 0, 255); 428e5c31af7Sopenharmony_ci colors[1] = RGBA(0, 255, 255, 255); 429e5c31af7Sopenharmony_ci colors[2] = RGBA(255, 0, 255, 255); 430e5c31af7Sopenharmony_ci colors[3] = RGBA(255, 255, 0, 255); 431e5c31af7Sopenharmony_ci} 432e5c31af7Sopenharmony_ci 433e5c31af7Sopenharmony_ci// For the current InstanceContext, constructs the required modules and shader stage create infos. 434e5c31af7Sopenharmony_civoid createPipelineShaderStages (const DeviceInterface& vk, 435e5c31af7Sopenharmony_ci const VkDevice vkDevice, 436e5c31af7Sopenharmony_ci InstanceContext& instance, 437e5c31af7Sopenharmony_ci Context& context, 438e5c31af7Sopenharmony_ci vector<ModuleHandleSp>& modules, 439e5c31af7Sopenharmony_ci vector<VkPipelineShaderStageCreateInfo>& createInfos) 440e5c31af7Sopenharmony_ci{ 441e5c31af7Sopenharmony_ci for (ModuleMap::const_iterator moduleNdx = instance.moduleMap.begin(); moduleNdx != instance.moduleMap.end(); ++moduleNdx) 442e5c31af7Sopenharmony_ci { 443e5c31af7Sopenharmony_ci const ModuleHandleSp mod(new Unique<VkShaderModule>(createShaderModule(vk, vkDevice, context.getBinaryCollection().get(moduleNdx->first), 0))); 444e5c31af7Sopenharmony_ci modules.push_back(ModuleHandleSp(mod)); 445e5c31af7Sopenharmony_ci for (vector<EntryToStage>::const_iterator shaderNdx = moduleNdx->second.begin(); shaderNdx != moduleNdx->second.end(); ++shaderNdx) 446e5c31af7Sopenharmony_ci { 447e5c31af7Sopenharmony_ci const EntryToStage& stage = *shaderNdx; 448e5c31af7Sopenharmony_ci const VkPipelineShaderStageCreateInfo shaderParam = 449e5c31af7Sopenharmony_ci { 450e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 451e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 452e5c31af7Sopenharmony_ci (VkPipelineShaderStageCreateFlags)0, 453e5c31af7Sopenharmony_ci stage.second, // VkShaderStageFlagBits stage; 454e5c31af7Sopenharmony_ci **modules.back(), // VkShaderModule module; 455e5c31af7Sopenharmony_ci stage.first.c_str(), // const char* pName; 456e5c31af7Sopenharmony_ci (const VkSpecializationInfo*)DE_NULL, 457e5c31af7Sopenharmony_ci }; 458e5c31af7Sopenharmony_ci createInfos.push_back(shaderParam); 459e5c31af7Sopenharmony_ci } 460e5c31af7Sopenharmony_ci } 461e5c31af7Sopenharmony_ci} 462e5c31af7Sopenharmony_ci 463e5c31af7Sopenharmony_ci// Creates vertex-shader assembly by specializing a boilerplate StringTemplate 464e5c31af7Sopenharmony_ci// on fragments, which must (at least) map "testfun" to an OpFunction definition 465e5c31af7Sopenharmony_ci// for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed 466e5c31af7Sopenharmony_ci// with "BP_" to avoid collisions with fragments. 467e5c31af7Sopenharmony_ci// 468e5c31af7Sopenharmony_ci// It corresponds roughly to this GLSL: 469e5c31af7Sopenharmony_ci//; 470e5c31af7Sopenharmony_ci// layout(location = 0) in vec4 position; 471e5c31af7Sopenharmony_ci// layout(location = 1) in vec4 color; 472e5c31af7Sopenharmony_ci// layout(location = 1) out highp vec4 vtxColor; 473e5c31af7Sopenharmony_ci// void main (void) { gl_Position = position; vtxColor = test_func(color); } 474e5c31af7Sopenharmony_cistring makeVertexShaderAssembly (const map<string, string>& fragments) 475e5c31af7Sopenharmony_ci{ 476e5c31af7Sopenharmony_ci static const char vertexShaderBoilerplate[] = 477e5c31af7Sopenharmony_ci "OpCapability Shader\n" 478e5c31af7Sopenharmony_ci "${capability:opt}\n" 479e5c31af7Sopenharmony_ci "${extension:opt}\n" 480e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 481e5c31af7Sopenharmony_ci "OpEntryPoint Vertex %BP_main \"main\" %BP_stream %BP_position %BP_vtx_color %BP_color %BP_gl_VertexIndex %BP_gl_InstanceIndex ${IF_entrypoint:opt} \n" 482e5c31af7Sopenharmony_ci "${execution_mode:opt}\n" 483e5c31af7Sopenharmony_ci "${debug:opt}\n" 484e5c31af7Sopenharmony_ci "${moduleprocessed:opt}\n" 485e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n" 486e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n" 487e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n" 488e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n" 489e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PerVertex Block\n" 490e5c31af7Sopenharmony_ci "OpDecorate %BP_position Location 0\n" 491e5c31af7Sopenharmony_ci "OpDecorate %BP_vtx_color Location 1\n" 492e5c31af7Sopenharmony_ci "OpDecorate %BP_color Location 1\n" 493e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_VertexIndex BuiltIn VertexIndex\n" 494e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_InstanceIndex BuiltIn InstanceIndex\n" 495e5c31af7Sopenharmony_ci "${IF_decoration:opt}\n" 496e5c31af7Sopenharmony_ci "${decoration:opt}\n" 497e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 498e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 499e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 500e5c31af7Sopenharmony_ci "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 501e5c31af7Sopenharmony_ci "%BP_op_gl_PerVertex = OpTypePointer Output %BP_gl_PerVertex\n" 502e5c31af7Sopenharmony_ci "%BP_stream = OpVariable %BP_op_gl_PerVertex Output\n" 503e5c31af7Sopenharmony_ci "%BP_position = OpVariable %ip_v4f32 Input\n" 504e5c31af7Sopenharmony_ci "%BP_vtx_color = OpVariable %op_v4f32 Output\n" 505e5c31af7Sopenharmony_ci "%BP_color = OpVariable %ip_v4f32 Input\n" 506e5c31af7Sopenharmony_ci "%BP_gl_VertexIndex = OpVariable %ip_i32 Input\n" 507e5c31af7Sopenharmony_ci "%BP_gl_InstanceIndex = OpVariable %ip_i32 Input\n" 508e5c31af7Sopenharmony_ci "${pre_main:opt}\n" 509e5c31af7Sopenharmony_ci "${IF_variable:opt}\n" 510e5c31af7Sopenharmony_ci "%BP_main = OpFunction %void None %voidf\n" 511e5c31af7Sopenharmony_ci "%BP_label = OpLabel\n" 512e5c31af7Sopenharmony_ci "${IF_carryforward:opt}\n" 513e5c31af7Sopenharmony_ci "${post_interface_op_vert:opt}\n" 514e5c31af7Sopenharmony_ci "%BP_pos = OpLoad %v4f32 %BP_position\n" 515e5c31af7Sopenharmony_ci "%BP_gl_pos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n" 516e5c31af7Sopenharmony_ci "OpStore %BP_gl_pos %BP_pos\n" 517e5c31af7Sopenharmony_ci "%BP_col = OpLoad %v4f32 %BP_color\n" 518e5c31af7Sopenharmony_ci "%BP_col_transformed = OpFunctionCall %v4f32 %test_code %BP_col\n" 519e5c31af7Sopenharmony_ci "OpStore %BP_vtx_color %BP_col_transformed\n" 520e5c31af7Sopenharmony_ci "OpReturn\n" 521e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 522e5c31af7Sopenharmony_ci "${interface_op_func:opt}\n" 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci "%isUniqueIdZero = OpFunction %bool None %bool_function\n" 525e5c31af7Sopenharmony_ci "%getId_label = OpLabel\n" 526e5c31af7Sopenharmony_ci "%vert_id = OpLoad %i32 %BP_gl_VertexIndex\n" 527e5c31af7Sopenharmony_ci "%is_id_0 = OpIEqual %bool %vert_id %c_i32_0\n" 528e5c31af7Sopenharmony_ci "OpReturnValue %is_id_0\n" 529e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 530e5c31af7Sopenharmony_ci 531e5c31af7Sopenharmony_ci "${testfun}\n"; 532e5c31af7Sopenharmony_ci return tcu::StringTemplate(vertexShaderBoilerplate).specialize(fragments); 533e5c31af7Sopenharmony_ci} 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_ci// Creates tess-control-shader assembly by specializing a boilerplate 536e5c31af7Sopenharmony_ci// StringTemplate on fragments, which must (at least) map "testfun" to an 537e5c31af7Sopenharmony_ci// OpFunction definition for %test_code that takes and returns a %v4f32. 538e5c31af7Sopenharmony_ci// Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments. 539e5c31af7Sopenharmony_ci// 540e5c31af7Sopenharmony_ci// It roughly corresponds to the following GLSL. 541e5c31af7Sopenharmony_ci// 542e5c31af7Sopenharmony_ci// #version 450 543e5c31af7Sopenharmony_ci// layout(vertices = 3) out; 544e5c31af7Sopenharmony_ci// layout(location = 1) in vec4 in_color[]; 545e5c31af7Sopenharmony_ci// layout(location = 1) out vec4 out_color[]; 546e5c31af7Sopenharmony_ci// 547e5c31af7Sopenharmony_ci// void main() { 548e5c31af7Sopenharmony_ci// out_color[gl_InvocationID] = testfun(in_color[gl_InvocationID]); 549e5c31af7Sopenharmony_ci// gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; 550e5c31af7Sopenharmony_ci// if (gl_InvocationID == 0) { 551e5c31af7Sopenharmony_ci// gl_TessLevelOuter[0] = 1.0; 552e5c31af7Sopenharmony_ci// gl_TessLevelOuter[1] = 1.0; 553e5c31af7Sopenharmony_ci// gl_TessLevelOuter[2] = 1.0; 554e5c31af7Sopenharmony_ci// gl_TessLevelInner[0] = 1.0; 555e5c31af7Sopenharmony_ci// } 556e5c31af7Sopenharmony_ci// } 557e5c31af7Sopenharmony_cistring makeTessControlShaderAssembly (const map<string, string>& fragments) 558e5c31af7Sopenharmony_ci{ 559e5c31af7Sopenharmony_ci static const char tessControlShaderBoilerplate[] = 560e5c31af7Sopenharmony_ci "OpCapability Tessellation\n" 561e5c31af7Sopenharmony_ci "${capability:opt}\n" 562e5c31af7Sopenharmony_ci "${extension:opt}\n" 563e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 564e5c31af7Sopenharmony_ci "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" 565e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main OutputVertices 3\n" 566e5c31af7Sopenharmony_ci "${execution_mode:opt}\n" 567e5c31af7Sopenharmony_ci "${debug:opt}\n" 568e5c31af7Sopenharmony_ci "${moduleprocessed:opt}\n" 569e5c31af7Sopenharmony_ci "OpDecorate %BP_out_color Location 1\n" 570e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_InvocationID BuiltIn InvocationId\n" 571e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n" 572e5c31af7Sopenharmony_ci "OpDecorate %BP_in_color Location 1\n" 573e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 0 BuiltIn Position\n" 574e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 1 BuiltIn PointSize\n" 575e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 2 BuiltIn ClipDistance\n" 576e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertex 3 BuiltIn CullDistance\n" 577e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PerVertex Block\n" 578e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PVOut 0 BuiltIn Position\n" 579e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PVOut 1 BuiltIn PointSize\n" 580e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PVOut 2 BuiltIn ClipDistance\n" 581e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PVOut 3 BuiltIn CullDistance\n" 582e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PVOut Block\n" 583e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_TessLevelOuter Patch\n" 584e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_TessLevelOuter BuiltIn TessLevelOuter\n" 585e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_TessLevelInner Patch\n" 586e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_TessLevelInner BuiltIn TessLevelInner\n" 587e5c31af7Sopenharmony_ci "${IF_decoration:opt}\n" 588e5c31af7Sopenharmony_ci "${decoration:opt}\n" 589e5c31af7Sopenharmony_ci "${decoration_tessc:opt}\n" 590e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 591e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 592e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 593e5c31af7Sopenharmony_ci "%BP_out_color = OpVariable %op_a3v4f32 Output\n" 594e5c31af7Sopenharmony_ci "%BP_gl_InvocationID = OpVariable %ip_i32 Input\n" 595e5c31af7Sopenharmony_ci "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n" 596e5c31af7Sopenharmony_ci "%BP_in_color = OpVariable %ip_a32v4f32 Input\n" 597e5c31af7Sopenharmony_ci "%BP_gl_PerVertex = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 598e5c31af7Sopenharmony_ci "%BP_a3_gl_PerVertex = OpTypeArray %BP_gl_PerVertex %c_u32_3\n" 599e5c31af7Sopenharmony_ci "%BP_op_a3_gl_PerVertex = OpTypePointer Output %BP_a3_gl_PerVertex\n" 600e5c31af7Sopenharmony_ci "%BP_gl_out = OpVariable %BP_op_a3_gl_PerVertex Output\n" 601e5c31af7Sopenharmony_ci "%BP_gl_PVOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 602e5c31af7Sopenharmony_ci "%BP_a32_gl_PVOut = OpTypeArray %BP_gl_PVOut %c_u32_32\n" 603e5c31af7Sopenharmony_ci "%BP_ip_a32_gl_PVOut = OpTypePointer Input %BP_a32_gl_PVOut\n" 604e5c31af7Sopenharmony_ci "%BP_gl_in = OpVariable %BP_ip_a32_gl_PVOut Input\n" 605e5c31af7Sopenharmony_ci "%BP_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n" 606e5c31af7Sopenharmony_ci "%BP_gl_TessLevelInner = OpVariable %op_a2f32 Output\n" 607e5c31af7Sopenharmony_ci "${pre_main:opt}\n" 608e5c31af7Sopenharmony_ci "${IF_variable:opt}\n" 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_ci "%BP_main = OpFunction %void None %voidf\n" 611e5c31af7Sopenharmony_ci "%BP_label = OpLabel\n" 612e5c31af7Sopenharmony_ci "%BP_gl_Invoc = OpLoad %i32 %BP_gl_InvocationID\n" 613e5c31af7Sopenharmony_ci "${IF_carryforward:opt}\n" 614e5c31af7Sopenharmony_ci "${post_interface_op_tessc:opt}\n" 615e5c31af7Sopenharmony_ci "%BP_in_col_loc = OpAccessChain %ip_v4f32 %BP_in_color %BP_gl_Invoc\n" 616e5c31af7Sopenharmony_ci "%BP_out_col_loc = OpAccessChain %op_v4f32 %BP_out_color %BP_gl_Invoc\n" 617e5c31af7Sopenharmony_ci "%BP_in_col_val = OpLoad %v4f32 %BP_in_col_loc\n" 618e5c31af7Sopenharmony_ci "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_in_col_val\n" 619e5c31af7Sopenharmony_ci "OpStore %BP_out_col_loc %BP_clr_transformed\n" 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci "%BP_in_pos_loc = OpAccessChain %ip_v4f32 %BP_gl_in %BP_gl_Invoc %c_i32_0\n" 622e5c31af7Sopenharmony_ci "%BP_out_pos_loc = OpAccessChain %op_v4f32 %BP_gl_out %BP_gl_Invoc %c_i32_0\n" 623e5c31af7Sopenharmony_ci "%BP_in_pos_val = OpLoad %v4f32 %BP_in_pos_loc\n" 624e5c31af7Sopenharmony_ci "OpStore %BP_out_pos_loc %BP_in_pos_val\n" 625e5c31af7Sopenharmony_ci 626e5c31af7Sopenharmony_ci "%BP_cmp = OpIEqual %bool %BP_gl_Invoc %c_i32_0\n" 627e5c31af7Sopenharmony_ci "OpSelectionMerge %BP_merge_label None\n" 628e5c31af7Sopenharmony_ci "OpBranchConditional %BP_cmp %BP_if_label %BP_merge_label\n" 629e5c31af7Sopenharmony_ci "%BP_if_label = OpLabel\n" 630e5c31af7Sopenharmony_ci "%BP_gl_TessLevelOuterPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_0\n" 631e5c31af7Sopenharmony_ci "%BP_gl_TessLevelOuterPos_1 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_1\n" 632e5c31af7Sopenharmony_ci "%BP_gl_TessLevelOuterPos_2 = OpAccessChain %op_f32 %BP_gl_TessLevelOuter %c_i32_2\n" 633e5c31af7Sopenharmony_ci "%BP_gl_TessLevelInnerPos_0 = OpAccessChain %op_f32 %BP_gl_TessLevelInner %c_i32_0\n" 634e5c31af7Sopenharmony_ci "OpStore %BP_gl_TessLevelOuterPos_0 %c_f32_1\n" 635e5c31af7Sopenharmony_ci "OpStore %BP_gl_TessLevelOuterPos_1 %c_f32_1\n" 636e5c31af7Sopenharmony_ci "OpStore %BP_gl_TessLevelOuterPos_2 %c_f32_1\n" 637e5c31af7Sopenharmony_ci "OpStore %BP_gl_TessLevelInnerPos_0 %c_f32_1\n" 638e5c31af7Sopenharmony_ci "OpBranch %BP_merge_label\n" 639e5c31af7Sopenharmony_ci "%BP_merge_label = OpLabel\n" 640e5c31af7Sopenharmony_ci "OpReturn\n" 641e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 642e5c31af7Sopenharmony_ci "${interface_op_func:opt}\n" 643e5c31af7Sopenharmony_ci 644e5c31af7Sopenharmony_ci "%isUniqueIdZero = OpFunction %bool None %bool_function\n" 645e5c31af7Sopenharmony_ci "%getId_label = OpLabel\n" 646e5c31af7Sopenharmony_ci "%invocation_id = OpLoad %i32 %BP_gl_InvocationID\n" 647e5c31af7Sopenharmony_ci "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n" 648e5c31af7Sopenharmony_ci "%is_invocation_0 = OpIEqual %bool %invocation_id %c_i32_0\n" 649e5c31af7Sopenharmony_ci "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n" 650e5c31af7Sopenharmony_ci "%is_id_0 = OpLogicalAnd %bool %is_invocation_0 %is_primitive_0\n" 651e5c31af7Sopenharmony_ci "OpReturnValue %is_id_0\n" 652e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci "${testfun}\n"; 655e5c31af7Sopenharmony_ci return tcu::StringTemplate(tessControlShaderBoilerplate).specialize(fragments); 656e5c31af7Sopenharmony_ci} 657e5c31af7Sopenharmony_ci 658e5c31af7Sopenharmony_ci// Creates tess-evaluation-shader assembly by specializing a boilerplate 659e5c31af7Sopenharmony_ci// StringTemplate on fragments, which must (at least) map "testfun" to an 660e5c31af7Sopenharmony_ci// OpFunction definition for %test_code that takes and returns a %v4f32. 661e5c31af7Sopenharmony_ci// Boilerplate IDs are prefixed with "BP_" to avoid collisions with fragments. 662e5c31af7Sopenharmony_ci// 663e5c31af7Sopenharmony_ci// It roughly corresponds to the following glsl. 664e5c31af7Sopenharmony_ci// 665e5c31af7Sopenharmony_ci// #version 450 666e5c31af7Sopenharmony_ci// 667e5c31af7Sopenharmony_ci// layout(triangles, equal_spacing, ccw) in; 668e5c31af7Sopenharmony_ci// layout(location = 1) in vec4 in_color[]; 669e5c31af7Sopenharmony_ci// layout(location = 1) out vec4 out_color; 670e5c31af7Sopenharmony_ci// 671e5c31af7Sopenharmony_ci// #define interpolate(val) 672e5c31af7Sopenharmony_ci// vec4(gl_TessCoord.x) * val[0] + vec4(gl_TessCoord.y) * val[1] + 673e5c31af7Sopenharmony_ci// vec4(gl_TessCoord.z) * val[2] 674e5c31af7Sopenharmony_ci// 675e5c31af7Sopenharmony_ci// void main() { 676e5c31af7Sopenharmony_ci// gl_Position = vec4(gl_TessCoord.x) * gl_in[0].gl_Position + 677e5c31af7Sopenharmony_ci// vec4(gl_TessCoord.y) * gl_in[1].gl_Position + 678e5c31af7Sopenharmony_ci// vec4(gl_TessCoord.z) * gl_in[2].gl_Position; 679e5c31af7Sopenharmony_ci// out_color = testfun(interpolate(in_color)); 680e5c31af7Sopenharmony_ci// } 681e5c31af7Sopenharmony_cistring makeTessEvalShaderAssembly (const map<string, string>& fragments) 682e5c31af7Sopenharmony_ci{ 683e5c31af7Sopenharmony_ci static const char tessEvalBoilerplate[] = 684e5c31af7Sopenharmony_ci "OpCapability Tessellation\n" 685e5c31af7Sopenharmony_ci "${capability:opt}\n" 686e5c31af7Sopenharmony_ci "${extension:opt}\n" 687e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 688e5c31af7Sopenharmony_ci "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" 689e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main Triangles\n" 690e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main SpacingEqual\n" 691e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main VertexOrderCcw\n" 692e5c31af7Sopenharmony_ci "${execution_mode:opt}\n" 693e5c31af7Sopenharmony_ci "${debug:opt}\n" 694e5c31af7Sopenharmony_ci "${moduleprocessed:opt}\n" 695e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexOut 0 BuiltIn Position\n" 696e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexOut 1 BuiltIn PointSize\n" 697e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexOut 2 BuiltIn ClipDistance\n" 698e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexOut 3 BuiltIn CullDistance\n" 699e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PerVertexOut Block\n" 700e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n" 701e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_TessCoord BuiltIn TessCoord\n" 702e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexIn 0 BuiltIn Position\n" 703e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexIn 1 BuiltIn PointSize\n" 704e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexIn 2 BuiltIn ClipDistance\n" 705e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_gl_PerVertexIn 3 BuiltIn CullDistance\n" 706e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PerVertexIn Block\n" 707e5c31af7Sopenharmony_ci "OpDecorate %BP_out_color Location 1\n" 708e5c31af7Sopenharmony_ci "OpDecorate %BP_in_color Location 1\n" 709e5c31af7Sopenharmony_ci "${IF_decoration:opt}\n" 710e5c31af7Sopenharmony_ci "${decoration:opt}\n" 711e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 712e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 713e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 714e5c31af7Sopenharmony_ci "%BP_gl_PerVertexOut = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 715e5c31af7Sopenharmony_ci "%BP_op_gl_PerVertexOut = OpTypePointer Output %BP_gl_PerVertexOut\n" 716e5c31af7Sopenharmony_ci "%BP_stream = OpVariable %BP_op_gl_PerVertexOut Output\n" 717e5c31af7Sopenharmony_ci "%BP_gl_TessCoord = OpVariable %ip_v3f32 Input\n" 718e5c31af7Sopenharmony_ci "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n" 719e5c31af7Sopenharmony_ci "%BP_gl_PerVertexIn = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 720e5c31af7Sopenharmony_ci "%BP_a32_gl_PerVertexIn = OpTypeArray %BP_gl_PerVertexIn %c_u32_32\n" 721e5c31af7Sopenharmony_ci "%BP_ip_a32_gl_PerVertexIn = OpTypePointer Input %BP_a32_gl_PerVertexIn\n" 722e5c31af7Sopenharmony_ci "%BP_gl_in = OpVariable %BP_ip_a32_gl_PerVertexIn Input\n" 723e5c31af7Sopenharmony_ci "%BP_out_color = OpVariable %op_v4f32 Output\n" 724e5c31af7Sopenharmony_ci "%BP_in_color = OpVariable %ip_a32v4f32 Input\n" 725e5c31af7Sopenharmony_ci "${pre_main:opt}\n" 726e5c31af7Sopenharmony_ci "${IF_variable:opt}\n" 727e5c31af7Sopenharmony_ci "%BP_main = OpFunction %void None %voidf\n" 728e5c31af7Sopenharmony_ci "%BP_label = OpLabel\n" 729e5c31af7Sopenharmony_ci "${IF_carryforward:opt}\n" 730e5c31af7Sopenharmony_ci "${post_interface_op_tesse:opt}\n" 731e5c31af7Sopenharmony_ci "%BP_gl_TC_0 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n" 732e5c31af7Sopenharmony_ci "%BP_gl_TC_1 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n" 733e5c31af7Sopenharmony_ci "%BP_gl_TC_2 = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n" 734e5c31af7Sopenharmony_ci "%BP_gl_in_gl_Pos_0 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n" 735e5c31af7Sopenharmony_ci "%BP_gl_in_gl_Pos_1 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n" 736e5c31af7Sopenharmony_ci "%BP_gl_in_gl_Pos_2 = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n" 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ci "%BP_gl_OPos = OpAccessChain %op_v4f32 %BP_stream %c_i32_0\n" 739e5c31af7Sopenharmony_ci "%BP_in_color_0 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n" 740e5c31af7Sopenharmony_ci "%BP_in_color_1 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n" 741e5c31af7Sopenharmony_ci "%BP_in_color_2 = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n" 742e5c31af7Sopenharmony_ci 743e5c31af7Sopenharmony_ci "%BP_TC_W_0 = OpLoad %f32 %BP_gl_TC_0\n" 744e5c31af7Sopenharmony_ci "%BP_TC_W_1 = OpLoad %f32 %BP_gl_TC_1\n" 745e5c31af7Sopenharmony_ci "%BP_TC_W_2 = OpLoad %f32 %BP_gl_TC_2\n" 746e5c31af7Sopenharmony_ci "%BP_v4f32_TC_0 = OpCompositeConstruct %v4f32 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0 %BP_TC_W_0\n" 747e5c31af7Sopenharmony_ci "%BP_v4f32_TC_1 = OpCompositeConstruct %v4f32 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1 %BP_TC_W_1\n" 748e5c31af7Sopenharmony_ci "%BP_v4f32_TC_2 = OpCompositeConstruct %v4f32 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2 %BP_TC_W_2\n" 749e5c31af7Sopenharmony_ci 750e5c31af7Sopenharmony_ci "%BP_gl_IP_0 = OpLoad %v4f32 %BP_gl_in_gl_Pos_0\n" 751e5c31af7Sopenharmony_ci "%BP_gl_IP_1 = OpLoad %v4f32 %BP_gl_in_gl_Pos_1\n" 752e5c31af7Sopenharmony_ci "%BP_gl_IP_2 = OpLoad %v4f32 %BP_gl_in_gl_Pos_2\n" 753e5c31af7Sopenharmony_ci 754e5c31af7Sopenharmony_ci "%BP_IP_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_gl_IP_0\n" 755e5c31af7Sopenharmony_ci "%BP_IP_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_gl_IP_1\n" 756e5c31af7Sopenharmony_ci "%BP_IP_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_gl_IP_2\n" 757e5c31af7Sopenharmony_ci 758e5c31af7Sopenharmony_ci "%BP_pos_sum_0 = OpFAdd %v4f32 %BP_IP_W_0 %BP_IP_W_1\n" 759e5c31af7Sopenharmony_ci "%BP_pos_sum_1 = OpFAdd %v4f32 %BP_pos_sum_0 %BP_IP_W_2\n" 760e5c31af7Sopenharmony_ci 761e5c31af7Sopenharmony_ci "OpStore %BP_gl_OPos %BP_pos_sum_1\n" 762e5c31af7Sopenharmony_ci 763e5c31af7Sopenharmony_ci "%BP_IC_0 = OpLoad %v4f32 %BP_in_color_0\n" 764e5c31af7Sopenharmony_ci "%BP_IC_1 = OpLoad %v4f32 %BP_in_color_1\n" 765e5c31af7Sopenharmony_ci "%BP_IC_2 = OpLoad %v4f32 %BP_in_color_2\n" 766e5c31af7Sopenharmony_ci 767e5c31af7Sopenharmony_ci "%BP_IC_W_0 = OpFMul %v4f32 %BP_v4f32_TC_0 %BP_IC_0\n" 768e5c31af7Sopenharmony_ci "%BP_IC_W_1 = OpFMul %v4f32 %BP_v4f32_TC_1 %BP_IC_1\n" 769e5c31af7Sopenharmony_ci "%BP_IC_W_2 = OpFMul %v4f32 %BP_v4f32_TC_2 %BP_IC_2\n" 770e5c31af7Sopenharmony_ci 771e5c31af7Sopenharmony_ci "%BP_col_sum_0 = OpFAdd %v4f32 %BP_IC_W_0 %BP_IC_W_1\n" 772e5c31af7Sopenharmony_ci "%BP_col_sum_1 = OpFAdd %v4f32 %BP_col_sum_0 %BP_IC_W_2\n" 773e5c31af7Sopenharmony_ci 774e5c31af7Sopenharmony_ci "%BP_clr_transformed = OpFunctionCall %v4f32 %test_code %BP_col_sum_1\n" 775e5c31af7Sopenharmony_ci 776e5c31af7Sopenharmony_ci "OpStore %BP_out_color %BP_clr_transformed\n" 777e5c31af7Sopenharmony_ci "OpReturn\n" 778e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 779e5c31af7Sopenharmony_ci "${interface_op_func:opt}\n" 780e5c31af7Sopenharmony_ci 781e5c31af7Sopenharmony_ci "%isUniqueIdZero = OpFunction %bool None %bool_function\n" 782e5c31af7Sopenharmony_ci "%getId_label = OpLabel\n" 783e5c31af7Sopenharmony_ci "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n" 784e5c31af7Sopenharmony_ci "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n" 785e5c31af7Sopenharmony_ci "%TC_0_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_0\n" 786e5c31af7Sopenharmony_ci "%TC_1_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_1\n" 787e5c31af7Sopenharmony_ci "%TC_2_loc = OpAccessChain %ip_f32 %BP_gl_TessCoord %c_u32_2\n" 788e5c31af7Sopenharmony_ci "%TC_W_0 = OpLoad %f32 %TC_0_loc\n" 789e5c31af7Sopenharmony_ci "%TC_W_1 = OpLoad %f32 %TC_1_loc\n" 790e5c31af7Sopenharmony_ci "%TC_W_2 = OpLoad %f32 %TC_2_loc\n" 791e5c31af7Sopenharmony_ci "%is_W_0_1 = OpFOrdEqual %bool %TC_W_0 %c_f32_1\n" 792e5c31af7Sopenharmony_ci "%is_W_1_0 = OpFOrdEqual %bool %TC_W_1 %c_f32_0\n" 793e5c31af7Sopenharmony_ci "%is_W_2_0 = OpFOrdEqual %bool %TC_W_2 %c_f32_0\n" 794e5c31af7Sopenharmony_ci "%is_tessCoord_1_0 = OpLogicalAnd %bool %is_W_0_1 %is_W_1_0\n" 795e5c31af7Sopenharmony_ci "%is_tessCoord_1_0_0 = OpLogicalAnd %bool %is_tessCoord_1_0 %is_W_2_0\n" 796e5c31af7Sopenharmony_ci "%is_unique_id_0 = OpLogicalAnd %bool %is_tessCoord_1_0_0 %is_primitive_0\n" 797e5c31af7Sopenharmony_ci "OpReturnValue %is_unique_id_0\n" 798e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_ci "${testfun}\n"; 801e5c31af7Sopenharmony_ci return tcu::StringTemplate(tessEvalBoilerplate).specialize(fragments); 802e5c31af7Sopenharmony_ci} 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci// Creates geometry-shader assembly by specializing a boilerplate StringTemplate 805e5c31af7Sopenharmony_ci// on fragments, which must (at least) map "testfun" to an OpFunction definition 806e5c31af7Sopenharmony_ci// for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed 807e5c31af7Sopenharmony_ci// with "BP_" to avoid collisions with fragments. 808e5c31af7Sopenharmony_ci// 809e5c31af7Sopenharmony_ci// Derived from this GLSL: 810e5c31af7Sopenharmony_ci// 811e5c31af7Sopenharmony_ci// #version 450 812e5c31af7Sopenharmony_ci// layout(triangles) in; 813e5c31af7Sopenharmony_ci// layout(triangle_strip, max_vertices = 3) out; 814e5c31af7Sopenharmony_ci// 815e5c31af7Sopenharmony_ci// layout(location = 1) in vec4 in_color[]; 816e5c31af7Sopenharmony_ci// layout(location = 1) out vec4 out_color; 817e5c31af7Sopenharmony_ci// 818e5c31af7Sopenharmony_ci// void main() { 819e5c31af7Sopenharmony_ci// gl_Position = gl_in[0].gl_Position; 820e5c31af7Sopenharmony_ci// out_color = test_fun(in_color[0]); 821e5c31af7Sopenharmony_ci// EmitVertex(); 822e5c31af7Sopenharmony_ci// gl_Position = gl_in[1].gl_Position; 823e5c31af7Sopenharmony_ci// out_color = test_fun(in_color[1]); 824e5c31af7Sopenharmony_ci// EmitVertex(); 825e5c31af7Sopenharmony_ci// gl_Position = gl_in[2].gl_Position; 826e5c31af7Sopenharmony_ci// out_color = test_fun(in_color[2]); 827e5c31af7Sopenharmony_ci// EmitVertex(); 828e5c31af7Sopenharmony_ci// EndPrimitive(); 829e5c31af7Sopenharmony_ci// } 830e5c31af7Sopenharmony_cistring makeGeometryShaderAssembly (const map<string, string>& fragments) 831e5c31af7Sopenharmony_ci{ 832e5c31af7Sopenharmony_ci static const char geometryShaderBoilerplate[] = 833e5c31af7Sopenharmony_ci "OpCapability Geometry\n" 834e5c31af7Sopenharmony_ci "${capability:opt}\n" 835e5c31af7Sopenharmony_ci "${extension:opt}\n" 836e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 837e5c31af7Sopenharmony_ci "OpEntryPoint Geometry %BP_main \"main\" %BP_out_gl_position %BP_gl_PrimitiveID %BP_gl_in %BP_out_color %BP_in_color ${IF_entrypoint:opt} ${GL_entrypoint:opt} \n" 838e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main Triangles\n" 839e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main Invocations 1\n" 840e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main OutputTriangleStrip\n" 841e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main OutputVertices 3\n" 842e5c31af7Sopenharmony_ci "${execution_mode:opt}\n" 843e5c31af7Sopenharmony_ci "${debug:opt}\n" 844e5c31af7Sopenharmony_ci "${moduleprocessed:opt}\n" 845e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_PrimitiveID BuiltIn PrimitiveId\n" 846e5c31af7Sopenharmony_ci "OpDecorate %BP_out_gl_position BuiltIn Position\n" 847e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_per_vertex_in 0 BuiltIn Position\n" 848e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_per_vertex_in 1 BuiltIn PointSize\n" 849e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_per_vertex_in 2 BuiltIn ClipDistance\n" 850e5c31af7Sopenharmony_ci "OpMemberDecorate %BP_per_vertex_in 3 BuiltIn CullDistance\n" 851e5c31af7Sopenharmony_ci "OpDecorate %BP_per_vertex_in Block\n" 852e5c31af7Sopenharmony_ci "OpDecorate %BP_out_color Location 1\n" 853e5c31af7Sopenharmony_ci "OpDecorate %BP_in_color Location 1\n" 854e5c31af7Sopenharmony_ci "${IF_decoration:opt}\n" 855e5c31af7Sopenharmony_ci "${decoration:opt}\n" 856e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 857e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 858e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 859e5c31af7Sopenharmony_ci "%BP_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 860e5c31af7Sopenharmony_ci "%BP_a3_per_vertex_in = OpTypeArray %BP_per_vertex_in %c_u32_3\n" 861e5c31af7Sopenharmony_ci "%BP_ip_a3_per_vertex_in = OpTypePointer Input %BP_a3_per_vertex_in\n" 862e5c31af7Sopenharmony_ci "%BP_pp_i32 = OpTypePointer Private %i32\n" 863e5c31af7Sopenharmony_ci "%BP_pp_v4i32 = OpTypePointer Private %v4i32\n" 864e5c31af7Sopenharmony_ci 865e5c31af7Sopenharmony_ci "%BP_gl_in = OpVariable %BP_ip_a3_per_vertex_in Input\n" 866e5c31af7Sopenharmony_ci "%BP_out_color = OpVariable %op_v4f32 Output\n" 867e5c31af7Sopenharmony_ci "%BP_in_color = OpVariable %ip_a3v4f32 Input\n" 868e5c31af7Sopenharmony_ci "%BP_gl_PrimitiveID = OpVariable %ip_i32 Input\n" 869e5c31af7Sopenharmony_ci "%BP_out_gl_position = OpVariable %op_v4f32 Output\n" 870e5c31af7Sopenharmony_ci "%BP_vertexIdInCurrentPatch = OpVariable %BP_pp_v4i32 Private\n" 871e5c31af7Sopenharmony_ci "${pre_main:opt}\n" 872e5c31af7Sopenharmony_ci "${IF_variable:opt}\n" 873e5c31af7Sopenharmony_ci 874e5c31af7Sopenharmony_ci "%BP_main = OpFunction %void None %voidf\n" 875e5c31af7Sopenharmony_ci "%BP_label = OpLabel\n" 876e5c31af7Sopenharmony_ci 877e5c31af7Sopenharmony_ci "${IF_carryforward:opt}\n" 878e5c31af7Sopenharmony_ci "${post_interface_op_geom:opt}\n" 879e5c31af7Sopenharmony_ci 880e5c31af7Sopenharmony_ci "%BP_primitiveId = OpLoad %i32 %BP_gl_PrimitiveID\n" 881e5c31af7Sopenharmony_ci "%BP_addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %BP_primitiveId\n" 882e5c31af7Sopenharmony_ci 883e5c31af7Sopenharmony_ci "%BP_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_0 %c_i32_0\n" 884e5c31af7Sopenharmony_ci "%BP_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_1 %c_i32_0\n" 885e5c31af7Sopenharmony_ci "%BP_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %BP_gl_in %c_i32_2 %c_i32_0\n" 886e5c31af7Sopenharmony_ci 887e5c31af7Sopenharmony_ci "%BP_in_position_0 = OpLoad %v4f32 %BP_gl_in_0_gl_position\n" 888e5c31af7Sopenharmony_ci "%BP_in_position_1 = OpLoad %v4f32 %BP_gl_in_1_gl_position\n" 889e5c31af7Sopenharmony_ci "%BP_in_position_2 = OpLoad %v4f32 %BP_gl_in_2_gl_position \n" 890e5c31af7Sopenharmony_ci 891e5c31af7Sopenharmony_ci "%BP_in_color_0_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_0\n" 892e5c31af7Sopenharmony_ci "%BP_in_color_1_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_1\n" 893e5c31af7Sopenharmony_ci "%BP_in_color_2_ptr = OpAccessChain %ip_v4f32 %BP_in_color %c_i32_2\n" 894e5c31af7Sopenharmony_ci 895e5c31af7Sopenharmony_ci "%BP_in_color_0 = OpLoad %v4f32 %BP_in_color_0_ptr\n" 896e5c31af7Sopenharmony_ci "%BP_in_color_1 = OpLoad %v4f32 %BP_in_color_1_ptr\n" 897e5c31af7Sopenharmony_ci "%BP_in_color_2 = OpLoad %v4f32 %BP_in_color_2_ptr\n" 898e5c31af7Sopenharmony_ci 899e5c31af7Sopenharmony_ci "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_0\n" 900e5c31af7Sopenharmony_ci "%BP_transformed_in_color_0 = OpFunctionCall %v4f32 %test_code %BP_in_color_0\n" 901e5c31af7Sopenharmony_ci "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_1\n" 902e5c31af7Sopenharmony_ci "%BP_transformed_in_color_1 = OpFunctionCall %v4f32 %test_code %BP_in_color_1\n" 903e5c31af7Sopenharmony_ci "OpStore %BP_addr_vertexIdInCurrentPatch %c_i32_2\n" 904e5c31af7Sopenharmony_ci "%BP_transformed_in_color_2 = OpFunctionCall %v4f32 %test_code %BP_in_color_2\n" 905e5c31af7Sopenharmony_ci 906e5c31af7Sopenharmony_ci 907e5c31af7Sopenharmony_ci "OpStore %BP_out_gl_position %BP_in_position_0\n" 908e5c31af7Sopenharmony_ci "OpStore %BP_out_color %BP_transformed_in_color_0\n" 909e5c31af7Sopenharmony_ci "OpEmitVertex\n" 910e5c31af7Sopenharmony_ci 911e5c31af7Sopenharmony_ci "OpStore %BP_out_gl_position %BP_in_position_1\n" 912e5c31af7Sopenharmony_ci "OpStore %BP_out_color %BP_transformed_in_color_1\n" 913e5c31af7Sopenharmony_ci "OpEmitVertex\n" 914e5c31af7Sopenharmony_ci 915e5c31af7Sopenharmony_ci "OpStore %BP_out_gl_position %BP_in_position_2\n" 916e5c31af7Sopenharmony_ci "OpStore %BP_out_color %BP_transformed_in_color_2\n" 917e5c31af7Sopenharmony_ci "OpEmitVertex\n" 918e5c31af7Sopenharmony_ci 919e5c31af7Sopenharmony_ci "OpEndPrimitive\n" 920e5c31af7Sopenharmony_ci "OpReturn\n" 921e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 922e5c31af7Sopenharmony_ci "${interface_op_func:opt}\n" 923e5c31af7Sopenharmony_ci 924e5c31af7Sopenharmony_ci "%isUniqueIdZero = OpFunction %bool None %bool_function\n" 925e5c31af7Sopenharmony_ci "%getId_label = OpLabel\n" 926e5c31af7Sopenharmony_ci "%primitive_id = OpLoad %i32 %BP_gl_PrimitiveID\n" 927e5c31af7Sopenharmony_ci "%addr_vertexIdInCurrentPatch = OpAccessChain %BP_pp_i32 %BP_vertexIdInCurrentPatch %primitive_id\n" 928e5c31af7Sopenharmony_ci "%vertexIdInCurrentPatch = OpLoad %i32 %addr_vertexIdInCurrentPatch\n" 929e5c31af7Sopenharmony_ci "%is_primitive_0 = OpIEqual %bool %primitive_id %c_i32_0\n" 930e5c31af7Sopenharmony_ci "%is_vertex_0 = OpIEqual %bool %vertexIdInCurrentPatch %c_i32_0\n" 931e5c31af7Sopenharmony_ci "%is_unique_id_0 = OpLogicalAnd %bool %is_primitive_0 %is_vertex_0\n" 932e5c31af7Sopenharmony_ci "OpReturnValue %is_unique_id_0\n" 933e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ci "${testfun}\n"; 936e5c31af7Sopenharmony_ci return tcu::StringTemplate(geometryShaderBoilerplate).specialize(fragments); 937e5c31af7Sopenharmony_ci} 938e5c31af7Sopenharmony_ci 939e5c31af7Sopenharmony_ci// Creates fragment-shader assembly by specializing a boilerplate StringTemplate 940e5c31af7Sopenharmony_ci// on fragments, which must (at least) map "testfun" to an OpFunction definition 941e5c31af7Sopenharmony_ci// for %test_code that takes and returns a %v4f32. Boilerplate IDs are prefixed 942e5c31af7Sopenharmony_ci// with "BP_" to avoid collisions with fragments. 943e5c31af7Sopenharmony_ci// 944e5c31af7Sopenharmony_ci// Derived from this GLSL: 945e5c31af7Sopenharmony_ci// 946e5c31af7Sopenharmony_ci// layout(location = 1) in highp vec4 vtxColor; 947e5c31af7Sopenharmony_ci// layout(location = 0) out highp vec4 fragColor; 948e5c31af7Sopenharmony_ci// highp vec4 testfun(highp vec4 x) { return x; } 949e5c31af7Sopenharmony_ci// void main(void) { fragColor = testfun(vtxColor); } 950e5c31af7Sopenharmony_ci// 951e5c31af7Sopenharmony_ci// with modifications including passing vtxColor by value and ripping out 952e5c31af7Sopenharmony_ci// testfun() definition. 953e5c31af7Sopenharmony_cistring makeFragmentShaderAssembly (const map<string, string>& fragments) 954e5c31af7Sopenharmony_ci{ 955e5c31af7Sopenharmony_ci static const char fragmentShaderBoilerplate[] = 956e5c31af7Sopenharmony_ci "OpCapability Shader\n" 957e5c31af7Sopenharmony_ci "${capability:opt}\n" 958e5c31af7Sopenharmony_ci "${extension:opt}\n" 959e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 960e5c31af7Sopenharmony_ci "OpEntryPoint Fragment %BP_main \"main\" %BP_vtxColor %BP_fragColor %BP_gl_FragCoord ${IF_entrypoint:opt} \n" 961e5c31af7Sopenharmony_ci "OpExecutionMode %BP_main OriginUpperLeft\n" 962e5c31af7Sopenharmony_ci "${execution_mode:opt}\n" 963e5c31af7Sopenharmony_ci "${debug:opt}\n" 964e5c31af7Sopenharmony_ci "${moduleprocessed:opt}\n" 965e5c31af7Sopenharmony_ci "OpDecorate %BP_fragColor Location 0\n" 966e5c31af7Sopenharmony_ci "OpDecorate %BP_vtxColor Location 1\n" 967e5c31af7Sopenharmony_ci "OpDecorate %BP_gl_FragCoord BuiltIn FragCoord\n" 968e5c31af7Sopenharmony_ci "${IF_decoration:opt}\n" 969e5c31af7Sopenharmony_ci "${decoration:opt}\n" 970e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 971e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 972e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 973e5c31af7Sopenharmony_ci "%BP_gl_FragCoord = OpVariable %ip_v4f32 Input\n" 974e5c31af7Sopenharmony_ci "%BP_fragColor = OpVariable %op_v4f32 Output\n" 975e5c31af7Sopenharmony_ci "%BP_vtxColor = OpVariable %ip_v4f32 Input\n" 976e5c31af7Sopenharmony_ci "${pre_main:opt}\n" 977e5c31af7Sopenharmony_ci "${IF_variable:opt}\n" 978e5c31af7Sopenharmony_ci "%BP_main = OpFunction %void None %voidf\n" 979e5c31af7Sopenharmony_ci "%BP_label_main = OpLabel\n" 980e5c31af7Sopenharmony_ci "${IF_carryforward:opt}\n" 981e5c31af7Sopenharmony_ci "${post_interface_op_frag:opt}\n" 982e5c31af7Sopenharmony_ci "%BP_tmp1 = OpLoad %v4f32 %BP_vtxColor\n" 983e5c31af7Sopenharmony_ci "%BP_tmp2 = OpFunctionCall %v4f32 %test_code %BP_tmp1\n" 984e5c31af7Sopenharmony_ci "OpStore %BP_fragColor %BP_tmp2\n" 985e5c31af7Sopenharmony_ci "OpReturn\n" 986e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 987e5c31af7Sopenharmony_ci "${interface_op_func:opt}\n" 988e5c31af7Sopenharmony_ci 989e5c31af7Sopenharmony_ci "%isUniqueIdZero = OpFunction %bool None %bool_function\n" 990e5c31af7Sopenharmony_ci "%getId_label = OpLabel\n" 991e5c31af7Sopenharmony_ci "%loc_x_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_0\n" 992e5c31af7Sopenharmony_ci "%loc_y_coord = OpAccessChain %ip_f32 %BP_gl_FragCoord %c_i32_1\n" 993e5c31af7Sopenharmony_ci "%x_coord = OpLoad %f32 %loc_x_coord\n" 994e5c31af7Sopenharmony_ci "%y_coord = OpLoad %f32 %loc_y_coord\n" 995e5c31af7Sopenharmony_ci "%is_x_idx0 = OpFOrdEqual %bool %x_coord %c_f32_0_5\n" 996e5c31af7Sopenharmony_ci "%is_y_idx0 = OpFOrdEqual %bool %y_coord %c_f32_0_5\n" 997e5c31af7Sopenharmony_ci "%is_frag_0 = OpLogicalAnd %bool %is_x_idx0 %is_y_idx0\n" 998e5c31af7Sopenharmony_ci "OpReturnValue %is_frag_0\n" 999e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 1000e5c31af7Sopenharmony_ci 1001e5c31af7Sopenharmony_ci "${testfun}\n"; 1002e5c31af7Sopenharmony_ci return tcu::StringTemplate(fragmentShaderBoilerplate).specialize(fragments); 1003e5c31af7Sopenharmony_ci} 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_ci// Creates mappings from placeholders to pass-through shader code which copies 1006e5c31af7Sopenharmony_ci// the input to the output faithfully. 1007e5c31af7Sopenharmony_cimap<string, string> passthruInterface (const IFDataType& data_type) 1008e5c31af7Sopenharmony_ci{ 1009e5c31af7Sopenharmony_ci const string var_type = data_type.str(); 1010e5c31af7Sopenharmony_ci map<string, string> fragments = passthruFragments(); 1011e5c31af7Sopenharmony_ci const string functype = string("%") + var_type + "_" + var_type + "_function"; 1012e5c31af7Sopenharmony_ci 1013e5c31af7Sopenharmony_ci fragments["interface_op_call"] = "OpCopyObject %" + var_type; 1014e5c31af7Sopenharmony_ci fragments["interface_op_func"] = ""; 1015e5c31af7Sopenharmony_ci fragments["input_type"] = var_type; 1016e5c31af7Sopenharmony_ci fragments["output_type"] = var_type; 1017e5c31af7Sopenharmony_ci fragments["pre_main"] = ""; 1018e5c31af7Sopenharmony_ci 1019e5c31af7Sopenharmony_ci if (!data_type.elementIs32bit()) 1020e5c31af7Sopenharmony_ci { 1021e5c31af7Sopenharmony_ci if (data_type.elementType == NUMBERTYPE_FLOAT64) 1022e5c31af7Sopenharmony_ci { 1023e5c31af7Sopenharmony_ci fragments["capability"] = "OpCapability Float64\n\n"; 1024e5c31af7Sopenharmony_ci fragments["pre_main"] += "%f64 = OpTypeFloat 64\n"; 1025e5c31af7Sopenharmony_ci } 1026e5c31af7Sopenharmony_ci else if (data_type.elementType == NUMBERTYPE_FLOAT16) 1027e5c31af7Sopenharmony_ci { 1028e5c31af7Sopenharmony_ci fragments["capability"] = "OpCapability StorageInputOutput16\n"; 1029e5c31af7Sopenharmony_ci fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n"; 1030e5c31af7Sopenharmony_ci fragments["pre_main"] += "%f16 = OpTypeFloat 16\n"; 1031e5c31af7Sopenharmony_ci } 1032e5c31af7Sopenharmony_ci else if (data_type.elementType == NUMBERTYPE_INT16) 1033e5c31af7Sopenharmony_ci { 1034e5c31af7Sopenharmony_ci fragments["capability"] = "OpCapability StorageInputOutput16\n"; 1035e5c31af7Sopenharmony_ci fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n"; 1036e5c31af7Sopenharmony_ci fragments["pre_main"] += "%i16 = OpTypeInt 16 1\n"; 1037e5c31af7Sopenharmony_ci } 1038e5c31af7Sopenharmony_ci else if (data_type.elementType == NUMBERTYPE_UINT16) 1039e5c31af7Sopenharmony_ci { 1040e5c31af7Sopenharmony_ci fragments["capability"] = "OpCapability StorageInputOutput16\n"; 1041e5c31af7Sopenharmony_ci fragments["extension"] = "OpExtension \"SPV_KHR_16bit_storage\"\n"; 1042e5c31af7Sopenharmony_ci fragments["pre_main"] += "%u16 = OpTypeInt 16 0\n"; 1043e5c31af7Sopenharmony_ci } 1044e5c31af7Sopenharmony_ci else 1045e5c31af7Sopenharmony_ci { 1046e5c31af7Sopenharmony_ci DE_ASSERT(0 && "unhandled type"); 1047e5c31af7Sopenharmony_ci } 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci if (data_type.isVector()) 1050e5c31af7Sopenharmony_ci { 1051e5c31af7Sopenharmony_ci fragments["pre_main"] += "%" + var_type + " = OpTypeVector %" + IFDataType(1, data_type.elementType).str() + " " + numberToString(data_type.numElements) + "\n"; 1052e5c31af7Sopenharmony_ci } 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_ci fragments["pre_main"] += 1055e5c31af7Sopenharmony_ci "%ip_" + var_type + " = OpTypePointer Input %" + var_type + "\n" 1056e5c31af7Sopenharmony_ci "%op_" + var_type + " = OpTypePointer Output %" + var_type + "\n"; 1057e5c31af7Sopenharmony_ci } 1058e5c31af7Sopenharmony_ci 1059e5c31af7Sopenharmony_ci if (strcmp(var_type.c_str(), "v4f32") != 0) 1060e5c31af7Sopenharmony_ci fragments["pre_main"] += 1061e5c31af7Sopenharmony_ci functype + " = OpTypeFunction %" + var_type + " %" + var_type + "\n" 1062e5c31af7Sopenharmony_ci "%a3" + var_type + " = OpTypeArray %" + var_type + " %c_i32_3\n" 1063e5c31af7Sopenharmony_ci "%ip_a3" + var_type + " = OpTypePointer Input %a3" + var_type + "\n" 1064e5c31af7Sopenharmony_ci "%op_a3" + var_type + " = OpTypePointer Output %a3" + var_type + "\n"; 1065e5c31af7Sopenharmony_ci 1066e5c31af7Sopenharmony_ci return fragments; 1067e5c31af7Sopenharmony_ci} 1068e5c31af7Sopenharmony_ci 1069e5c31af7Sopenharmony_ci// Returns mappings from interface placeholders to their concrete values. 1070e5c31af7Sopenharmony_ci// 1071e5c31af7Sopenharmony_ci// The concrete values should be specialized again to provide ${input_type} 1072e5c31af7Sopenharmony_ci// and ${output_type}. 1073e5c31af7Sopenharmony_ci// 1074e5c31af7Sopenharmony_ci// %ip_${input_type} and %op_${output_type} should also be defined in the final code. 1075e5c31af7Sopenharmony_cimap<string, string> fillInterfacePlaceholderVert (void) 1076e5c31af7Sopenharmony_ci{ 1077e5c31af7Sopenharmony_ci map<string, string> fragments; 1078e5c31af7Sopenharmony_ci 1079e5c31af7Sopenharmony_ci fragments["IF_entrypoint"] = "%IF_input %IF_output"; 1080e5c31af7Sopenharmony_ci fragments["IF_variable"] = 1081e5c31af7Sopenharmony_ci " %IF_input = OpVariable %ip_${input_type} Input\n" 1082e5c31af7Sopenharmony_ci "%IF_output = OpVariable %op_${output_type} Output\n"; 1083e5c31af7Sopenharmony_ci fragments["IF_decoration"] = 1084e5c31af7Sopenharmony_ci "OpDecorate %IF_input Location 2\n" 1085e5c31af7Sopenharmony_ci "OpDecorate %IF_output Location 2\n"; 1086e5c31af7Sopenharmony_ci fragments["IF_carryforward"] = 1087e5c31af7Sopenharmony_ci "%IF_input_val = OpLoad %${input_type} %IF_input\n" 1088e5c31af7Sopenharmony_ci " %IF_result = ${interface_op_call} %IF_input_val\n" 1089e5c31af7Sopenharmony_ci " OpStore %IF_output %IF_result\n"; 1090e5c31af7Sopenharmony_ci 1091e5c31af7Sopenharmony_ci // Make sure the rest still need to be instantialized. 1092e5c31af7Sopenharmony_ci fragments["capability"] = "${capability:opt}"; 1093e5c31af7Sopenharmony_ci fragments["extension"] = "${extension:opt}"; 1094e5c31af7Sopenharmony_ci fragments["execution_mode"] = "${execution_mode:opt}"; 1095e5c31af7Sopenharmony_ci fragments["debug"] = "${debug:opt}"; 1096e5c31af7Sopenharmony_ci fragments["decoration"] = "${decoration:opt}"; 1097e5c31af7Sopenharmony_ci fragments["pre_main"] = "${pre_main:opt}"; 1098e5c31af7Sopenharmony_ci fragments["testfun"] = "${testfun}"; 1099e5c31af7Sopenharmony_ci fragments["interface_op_call"] = "${interface_op_call}"; 1100e5c31af7Sopenharmony_ci fragments["interface_op_func"] = "${interface_op_func}"; 1101e5c31af7Sopenharmony_ci fragments["post_interface_op_vert"] = "${post_interface_op_vert:opt}"; 1102e5c31af7Sopenharmony_ci 1103e5c31af7Sopenharmony_ci return fragments; 1104e5c31af7Sopenharmony_ci} 1105e5c31af7Sopenharmony_ci 1106e5c31af7Sopenharmony_ci// Returns mappings from interface placeholders to their concrete values. 1107e5c31af7Sopenharmony_ci// 1108e5c31af7Sopenharmony_ci// The concrete values should be specialized again to provide ${input_type} 1109e5c31af7Sopenharmony_ci// and ${output_type}. 1110e5c31af7Sopenharmony_ci// 1111e5c31af7Sopenharmony_ci// %ip_${input_type} and %op_${output_type} should also be defined in the final code. 1112e5c31af7Sopenharmony_cimap<string, string> fillInterfacePlaceholderFrag (void) 1113e5c31af7Sopenharmony_ci{ 1114e5c31af7Sopenharmony_ci map<string, string> fragments; 1115e5c31af7Sopenharmony_ci 1116e5c31af7Sopenharmony_ci fragments["IF_entrypoint"] = "%IF_input %IF_output"; 1117e5c31af7Sopenharmony_ci fragments["IF_variable"] = 1118e5c31af7Sopenharmony_ci " %IF_input = OpVariable %ip_${input_type} Input\n" 1119e5c31af7Sopenharmony_ci "%IF_output = OpVariable %op_${output_type} Output\n"; 1120e5c31af7Sopenharmony_ci fragments["IF_decoration"] = 1121e5c31af7Sopenharmony_ci "OpDecorate %IF_input Flat\n" 1122e5c31af7Sopenharmony_ci "OpDecorate %IF_input Location 2\n" 1123e5c31af7Sopenharmony_ci "OpDecorate %IF_output Location 1\n"; // Fragment shader should write to location #1. 1124e5c31af7Sopenharmony_ci fragments["IF_carryforward"] = 1125e5c31af7Sopenharmony_ci "%IF_input_val = OpLoad %${input_type} %IF_input\n" 1126e5c31af7Sopenharmony_ci " %IF_result = ${interface_op_call} %IF_input_val\n" 1127e5c31af7Sopenharmony_ci " OpStore %IF_output %IF_result\n"; 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci // Make sure the rest still need to be instantialized. 1130e5c31af7Sopenharmony_ci fragments["capability"] = "${capability:opt}"; 1131e5c31af7Sopenharmony_ci fragments["extension"] = "${extension:opt}"; 1132e5c31af7Sopenharmony_ci fragments["execution_mode"] = "${execution_mode:opt}"; 1133e5c31af7Sopenharmony_ci fragments["debug"] = "${debug:opt}"; 1134e5c31af7Sopenharmony_ci fragments["decoration"] = "${decoration:opt}"; 1135e5c31af7Sopenharmony_ci fragments["pre_main"] = "${pre_main:opt}"; 1136e5c31af7Sopenharmony_ci fragments["testfun"] = "${testfun}"; 1137e5c31af7Sopenharmony_ci fragments["interface_op_call"] = "${interface_op_call}"; 1138e5c31af7Sopenharmony_ci fragments["interface_op_func"] = "${interface_op_func}"; 1139e5c31af7Sopenharmony_ci fragments["post_interface_op_frag"] = "${post_interface_op_frag:opt}"; 1140e5c31af7Sopenharmony_ci 1141e5c31af7Sopenharmony_ci return fragments; 1142e5c31af7Sopenharmony_ci} 1143e5c31af7Sopenharmony_ci 1144e5c31af7Sopenharmony_ci// Returns mappings from interface placeholders to their concrete values. 1145e5c31af7Sopenharmony_ci// 1146e5c31af7Sopenharmony_ci// The concrete values should be specialized again to provide ${input_type} 1147e5c31af7Sopenharmony_ci// and ${output_type}. 1148e5c31af7Sopenharmony_ci// 1149e5c31af7Sopenharmony_ci// %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type} 1150e5c31af7Sopenharmony_ci// should also be defined in the final code. 1151e5c31af7Sopenharmony_cimap<string, string> fillInterfacePlaceholderTessCtrl (void) 1152e5c31af7Sopenharmony_ci{ 1153e5c31af7Sopenharmony_ci map<string, string> fragments; 1154e5c31af7Sopenharmony_ci 1155e5c31af7Sopenharmony_ci fragments["IF_entrypoint"] = "%IF_input %IF_output"; 1156e5c31af7Sopenharmony_ci fragments["IF_variable"] = 1157e5c31af7Sopenharmony_ci " %IF_input = OpVariable %ip_a3${input_type} Input\n" 1158e5c31af7Sopenharmony_ci "%IF_output = OpVariable %op_a3${output_type} Output\n"; 1159e5c31af7Sopenharmony_ci fragments["IF_decoration"] = 1160e5c31af7Sopenharmony_ci "OpDecorate %IF_input Location 2\n" 1161e5c31af7Sopenharmony_ci "OpDecorate %IF_output Location 2\n"; 1162e5c31af7Sopenharmony_ci fragments["IF_carryforward"] = 1163e5c31af7Sopenharmony_ci " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n" 1164e5c31af7Sopenharmony_ci " %IF_input_ptr1 = OpAccessChain %ip_${input_type} %IF_input %c_i32_1\n" 1165e5c31af7Sopenharmony_ci " %IF_input_ptr2 = OpAccessChain %ip_${input_type} %IF_input %c_i32_2\n" 1166e5c31af7Sopenharmony_ci "%IF_output_ptr0 = OpAccessChain %op_${output_type} %IF_output %c_i32_0\n" 1167e5c31af7Sopenharmony_ci "%IF_output_ptr1 = OpAccessChain %op_${output_type} %IF_output %c_i32_1\n" 1168e5c31af7Sopenharmony_ci "%IF_output_ptr2 = OpAccessChain %op_${output_type} %IF_output %c_i32_2\n" 1169e5c31af7Sopenharmony_ci "%IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n" 1170e5c31af7Sopenharmony_ci "%IF_input_val1 = OpLoad %${input_type} %IF_input_ptr1\n" 1171e5c31af7Sopenharmony_ci "%IF_input_val2 = OpLoad %${input_type} %IF_input_ptr2\n" 1172e5c31af7Sopenharmony_ci "%IF_input_res0 = ${interface_op_call} %IF_input_val0\n" 1173e5c31af7Sopenharmony_ci "%IF_input_res1 = ${interface_op_call} %IF_input_val1\n" 1174e5c31af7Sopenharmony_ci "%IF_input_res2 = ${interface_op_call} %IF_input_val2\n" 1175e5c31af7Sopenharmony_ci "OpStore %IF_output_ptr0 %IF_input_res0\n" 1176e5c31af7Sopenharmony_ci "OpStore %IF_output_ptr1 %IF_input_res1\n" 1177e5c31af7Sopenharmony_ci "OpStore %IF_output_ptr2 %IF_input_res2\n"; 1178e5c31af7Sopenharmony_ci 1179e5c31af7Sopenharmony_ci // Make sure the rest still need to be instantialized. 1180e5c31af7Sopenharmony_ci fragments["capability"] = "${capability:opt}"; 1181e5c31af7Sopenharmony_ci fragments["extension"] = "${extension:opt}"; 1182e5c31af7Sopenharmony_ci fragments["execution_mode"] = "${execution_mode:opt}"; 1183e5c31af7Sopenharmony_ci fragments["debug"] = "${debug:opt}"; 1184e5c31af7Sopenharmony_ci fragments["decoration"] = "${decoration:opt}"; 1185e5c31af7Sopenharmony_ci fragments["decoration_tessc"] = "${decoration_tessc:opt}"; 1186e5c31af7Sopenharmony_ci fragments["pre_main"] = "${pre_main:opt}"; 1187e5c31af7Sopenharmony_ci fragments["testfun"] = "${testfun}"; 1188e5c31af7Sopenharmony_ci fragments["interface_op_call"] = "${interface_op_call}"; 1189e5c31af7Sopenharmony_ci fragments["interface_op_func"] = "${interface_op_func}"; 1190e5c31af7Sopenharmony_ci fragments["post_interface_op_tessc"] = "${post_interface_op_tessc:opt}"; 1191e5c31af7Sopenharmony_ci 1192e5c31af7Sopenharmony_ci return fragments; 1193e5c31af7Sopenharmony_ci} 1194e5c31af7Sopenharmony_ci 1195e5c31af7Sopenharmony_ci// Returns mappings from interface placeholders to their concrete values. 1196e5c31af7Sopenharmony_ci// 1197e5c31af7Sopenharmony_ci// The concrete values should be specialized again to provide ${input_type} 1198e5c31af7Sopenharmony_ci// and ${output_type}. 1199e5c31af7Sopenharmony_ci// 1200e5c31af7Sopenharmony_ci// %ip_${input_type}, %op_${output_type}, %ip_a3${input_type}, and $op_a3${output_type} 1201e5c31af7Sopenharmony_ci// should also be defined in the final code. 1202e5c31af7Sopenharmony_cimap<string, string> fillInterfacePlaceholderTessEvalGeom (void) 1203e5c31af7Sopenharmony_ci{ 1204e5c31af7Sopenharmony_ci map<string, string> fragments; 1205e5c31af7Sopenharmony_ci 1206e5c31af7Sopenharmony_ci fragments["IF_entrypoint"] = "%IF_input %IF_output"; 1207e5c31af7Sopenharmony_ci fragments["IF_variable"] = 1208e5c31af7Sopenharmony_ci " %IF_input = OpVariable %ip_a3${input_type} Input\n" 1209e5c31af7Sopenharmony_ci "%IF_output = OpVariable %op_${output_type} Output\n"; 1210e5c31af7Sopenharmony_ci fragments["IF_decoration"] = 1211e5c31af7Sopenharmony_ci "OpDecorate %IF_input Location 2\n" 1212e5c31af7Sopenharmony_ci "OpDecorate %IF_output Location 2\n"; 1213e5c31af7Sopenharmony_ci fragments["IF_carryforward"] = 1214e5c31af7Sopenharmony_ci // Only get the first value since all three values are the same anyway. 1215e5c31af7Sopenharmony_ci " %IF_input_ptr0 = OpAccessChain %ip_${input_type} %IF_input %c_i32_0\n" 1216e5c31af7Sopenharmony_ci " %IF_input_val0 = OpLoad %${input_type} %IF_input_ptr0\n" 1217e5c31af7Sopenharmony_ci " %IF_input_res0 = ${interface_op_call} %IF_input_val0\n" 1218e5c31af7Sopenharmony_ci "OpStore %IF_output %IF_input_res0\n"; 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_ci // Make sure the rest still need to be instantialized. 1221e5c31af7Sopenharmony_ci fragments["capability"] = "${capability:opt}"; 1222e5c31af7Sopenharmony_ci fragments["extension"] = "${extension:opt}"; 1223e5c31af7Sopenharmony_ci fragments["execution_mode"] = "${execution_mode:opt}"; 1224e5c31af7Sopenharmony_ci fragments["debug"] = "${debug:opt}"; 1225e5c31af7Sopenharmony_ci fragments["decoration"] = "${decoration:opt}"; 1226e5c31af7Sopenharmony_ci fragments["pre_main"] = "${pre_main:opt}"; 1227e5c31af7Sopenharmony_ci fragments["testfun"] = "${testfun}"; 1228e5c31af7Sopenharmony_ci fragments["interface_op_call"] = "${interface_op_call}"; 1229e5c31af7Sopenharmony_ci fragments["interface_op_func"] = "${interface_op_func}"; 1230e5c31af7Sopenharmony_ci fragments["post_interface_op_tesse"] = "${post_interface_op_tesse:opt}"; 1231e5c31af7Sopenharmony_ci fragments["post_interface_op_geom"] = "${post_interface_op_geom:opt}"; 1232e5c31af7Sopenharmony_ci 1233e5c31af7Sopenharmony_ci return fragments; 1234e5c31af7Sopenharmony_ci} 1235e5c31af7Sopenharmony_ci 1236e5c31af7Sopenharmony_cimap<string, string> passthruFragments (void) 1237e5c31af7Sopenharmony_ci{ 1238e5c31af7Sopenharmony_ci map<string, string> fragments; 1239e5c31af7Sopenharmony_ci fragments["testfun"] = 1240e5c31af7Sopenharmony_ci // A %test_code function that returns its argument unchanged. 1241e5c31af7Sopenharmony_ci "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n" 1242e5c31af7Sopenharmony_ci "%param1 = OpFunctionParameter %v4f32\n" 1243e5c31af7Sopenharmony_ci "%label_testfun = OpLabel\n" 1244e5c31af7Sopenharmony_ci "OpReturnValue %param1\n" 1245e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 1246e5c31af7Sopenharmony_ci return fragments; 1247e5c31af7Sopenharmony_ci} 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci// Adds shader assembly text to dst.spirvAsmSources for all shader kinds. 1250e5c31af7Sopenharmony_ci// Vertex shader gets custom code from context, the rest are pass-through. 1251e5c31af7Sopenharmony_civoid addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions) 1252e5c31af7Sopenharmony_ci{ 1253e5c31af7Sopenharmony_ci const deUint32 vulkanVersion = dst.usedVulkanVersion; 1254e5c31af7Sopenharmony_ci SpirvVersion targetSpirvVersion; 1255e5c31af7Sopenharmony_ci 1256e5c31af7Sopenharmony_ci if (spirVAsmBuildOptions == DE_NULL) 1257e5c31af7Sopenharmony_ci targetSpirvVersion = context.resources.spirvVersion; 1258e5c31af7Sopenharmony_ci else 1259e5c31af7Sopenharmony_ci targetSpirvVersion = spirVAsmBuildOptions->targetVersion; 1260e5c31af7Sopenharmony_ci 1261e5c31af7Sopenharmony_ci if (!context.interfaces.empty()) 1262e5c31af7Sopenharmony_ci { 1263e5c31af7Sopenharmony_ci // Inject boilerplate code to wire up additional input/output variables between stages. 1264e5c31af7Sopenharmony_ci // Just copy the contents in input variable to output variable in all stages except 1265e5c31af7Sopenharmony_ci // the customized stage. 1266e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1267e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1268e5c31af7Sopenharmony_ci } else { 1269e5c31af7Sopenharmony_ci map<string, string> passthru = passthruFragments(); 1270e5c31af7Sopenharmony_ci 1271e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1272e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1273e5c31af7Sopenharmony_ci } 1274e5c31af7Sopenharmony_ci} 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_civoid addShaderCodeCustomVertex (vk::SourceCollections& dst, InstanceContext context) 1277e5c31af7Sopenharmony_ci{ 1278e5c31af7Sopenharmony_ci addShaderCodeCustomVertex(dst, context, DE_NULL); 1279e5c31af7Sopenharmony_ci} 1280e5c31af7Sopenharmony_ci 1281e5c31af7Sopenharmony_ci// Adds shader assembly text to dst.spirvAsmSources for all shader kinds. 1282e5c31af7Sopenharmony_ci// Tessellation control shader gets custom code from context, the rest are 1283e5c31af7Sopenharmony_ci// pass-through. 1284e5c31af7Sopenharmony_civoid addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions) 1285e5c31af7Sopenharmony_ci{ 1286e5c31af7Sopenharmony_ci const deUint32 vulkanVersion = dst.usedVulkanVersion; 1287e5c31af7Sopenharmony_ci SpirvVersion targetSpirvVersion; 1288e5c31af7Sopenharmony_ci 1289e5c31af7Sopenharmony_ci if (spirVAsmBuildOptions == DE_NULL) 1290e5c31af7Sopenharmony_ci targetSpirvVersion = context.resources.spirvVersion; 1291e5c31af7Sopenharmony_ci else 1292e5c31af7Sopenharmony_ci targetSpirvVersion = spirVAsmBuildOptions->targetVersion; 1293e5c31af7Sopenharmony_ci 1294e5c31af7Sopenharmony_ci if (!context.interfaces.empty()) 1295e5c31af7Sopenharmony_ci { 1296e5c31af7Sopenharmony_ci // Inject boilerplate code to wire up additional input/output variables between stages. 1297e5c31af7Sopenharmony_ci // Just copy the contents in input variable to output variable in all stages except 1298e5c31af7Sopenharmony_ci // the customized stage. 1299e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1300e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1301e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1302e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1303e5c31af7Sopenharmony_ci } 1304e5c31af7Sopenharmony_ci else 1305e5c31af7Sopenharmony_ci { 1306e5c31af7Sopenharmony_ci map<string, string> passthru = passthruFragments(); 1307e5c31af7Sopenharmony_ci 1308e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1309e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1310e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1311e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1312e5c31af7Sopenharmony_ci } 1313e5c31af7Sopenharmony_ci} 1314e5c31af7Sopenharmony_ci 1315e5c31af7Sopenharmony_civoid addShaderCodeCustomTessControl (vk::SourceCollections& dst, InstanceContext context) 1316e5c31af7Sopenharmony_ci{ 1317e5c31af7Sopenharmony_ci addShaderCodeCustomTessControl(dst, context, DE_NULL); 1318e5c31af7Sopenharmony_ci} 1319e5c31af7Sopenharmony_ci 1320e5c31af7Sopenharmony_ci// Adds shader assembly text to dst.spirvAsmSources for all shader kinds. 1321e5c31af7Sopenharmony_ci// Tessellation evaluation shader gets custom code from context, the rest are 1322e5c31af7Sopenharmony_ci// pass-through. 1323e5c31af7Sopenharmony_civoid addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions) 1324e5c31af7Sopenharmony_ci{ 1325e5c31af7Sopenharmony_ci const deUint32 vulkanVersion = dst.usedVulkanVersion; 1326e5c31af7Sopenharmony_ci SpirvVersion targetSpirvVersion; 1327e5c31af7Sopenharmony_ci 1328e5c31af7Sopenharmony_ci if (spirVAsmBuildOptions == DE_NULL) 1329e5c31af7Sopenharmony_ci targetSpirvVersion = context.resources.spirvVersion; 1330e5c31af7Sopenharmony_ci else 1331e5c31af7Sopenharmony_ci targetSpirvVersion = spirVAsmBuildOptions->targetVersion; 1332e5c31af7Sopenharmony_ci 1333e5c31af7Sopenharmony_ci if (!context.interfaces.empty()) 1334e5c31af7Sopenharmony_ci { 1335e5c31af7Sopenharmony_ci // Inject boilerplate code to wire up additional input/output variables between stages. 1336e5c31af7Sopenharmony_ci // Just copy the contents in input variable to output variable in all stages except 1337e5c31af7Sopenharmony_ci // the customized stage. 1338e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1339e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << StringTemplate(makeTessControlShaderAssembly(fillInterfacePlaceholderTessCtrl())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1340e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << StringTemplate(makeTessEvalShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1341e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1342e5c31af7Sopenharmony_ci } 1343e5c31af7Sopenharmony_ci else 1344e5c31af7Sopenharmony_ci { 1345e5c31af7Sopenharmony_ci map<string, string> passthru = passthruFragments(); 1346e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1347e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tessc", spirVAsmBuildOptions) << makeTessControlShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1348e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tesse", spirVAsmBuildOptions) << makeTessEvalShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1349e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1350e5c31af7Sopenharmony_ci } 1351e5c31af7Sopenharmony_ci} 1352e5c31af7Sopenharmony_ci 1353e5c31af7Sopenharmony_civoid addShaderCodeCustomTessEval (vk::SourceCollections& dst, InstanceContext context) 1354e5c31af7Sopenharmony_ci{ 1355e5c31af7Sopenharmony_ci addShaderCodeCustomTessEval(dst, context, DE_NULL); 1356e5c31af7Sopenharmony_ci} 1357e5c31af7Sopenharmony_ci 1358e5c31af7Sopenharmony_ci// Adds shader assembly text to dst.spirvAsmSources for all shader kinds. 1359e5c31af7Sopenharmony_ci// Geometry shader gets custom code from context, the rest are pass-through. 1360e5c31af7Sopenharmony_civoid addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions) 1361e5c31af7Sopenharmony_ci{ 1362e5c31af7Sopenharmony_ci const deUint32 vulkanVersion = dst.usedVulkanVersion; 1363e5c31af7Sopenharmony_ci SpirvVersion targetSpirvVersion; 1364e5c31af7Sopenharmony_ci 1365e5c31af7Sopenharmony_ci if (spirVAsmBuildOptions == DE_NULL) 1366e5c31af7Sopenharmony_ci targetSpirvVersion = context.resources.spirvVersion; 1367e5c31af7Sopenharmony_ci else 1368e5c31af7Sopenharmony_ci targetSpirvVersion = spirVAsmBuildOptions->targetVersion; 1369e5c31af7Sopenharmony_ci 1370e5c31af7Sopenharmony_ci if (!context.interfaces.empty()) 1371e5c31af7Sopenharmony_ci { 1372e5c31af7Sopenharmony_ci // Inject boilerplate code to wire up additional input/output variables between stages. 1373e5c31af7Sopenharmony_ci // Just copy the contents in input variable to output variable in all stages except 1374e5c31af7Sopenharmony_ci // the customized stage. 1375e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1376e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << StringTemplate(makeGeometryShaderAssembly(fillInterfacePlaceholderTessEvalGeom())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1377e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(passthruInterface(context.interfaces.getOutputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1378e5c31af7Sopenharmony_ci } 1379e5c31af7Sopenharmony_ci else 1380e5c31af7Sopenharmony_ci { 1381e5c31af7Sopenharmony_ci map<string, string> passthru = passthruFragments(); 1382e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1383e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("geom", spirVAsmBuildOptions) << makeGeometryShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1384e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1385e5c31af7Sopenharmony_ci } 1386e5c31af7Sopenharmony_ci} 1387e5c31af7Sopenharmony_ci 1388e5c31af7Sopenharmony_civoid addShaderCodeCustomGeometry (vk::SourceCollections& dst, InstanceContext context) 1389e5c31af7Sopenharmony_ci{ 1390e5c31af7Sopenharmony_ci addShaderCodeCustomGeometry(dst, context, DE_NULL); 1391e5c31af7Sopenharmony_ci} 1392e5c31af7Sopenharmony_ci 1393e5c31af7Sopenharmony_ci// Adds shader assembly text to dst.spirvAsmSources for all shader kinds. 1394e5c31af7Sopenharmony_ci// Fragment shader gets custom code from context, the rest are pass-through. 1395e5c31af7Sopenharmony_civoid addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext& context, const SpirVAsmBuildOptions* spirVAsmBuildOptions) 1396e5c31af7Sopenharmony_ci{ 1397e5c31af7Sopenharmony_ci const deUint32 vulkanVersion = dst.usedVulkanVersion; 1398e5c31af7Sopenharmony_ci SpirvVersion targetSpirvVersion; 1399e5c31af7Sopenharmony_ci 1400e5c31af7Sopenharmony_ci if (spirVAsmBuildOptions == DE_NULL) 1401e5c31af7Sopenharmony_ci targetSpirvVersion = context.resources.spirvVersion; 1402e5c31af7Sopenharmony_ci else 1403e5c31af7Sopenharmony_ci targetSpirvVersion = spirVAsmBuildOptions->targetVersion; 1404e5c31af7Sopenharmony_ci 1405e5c31af7Sopenharmony_ci if (!context.interfaces.empty()) 1406e5c31af7Sopenharmony_ci { 1407e5c31af7Sopenharmony_ci // Inject boilerplate code to wire up additional input/output variables between stages. 1408e5c31af7Sopenharmony_ci // Just copy the contents in input variable to output variable in all stages except 1409e5c31af7Sopenharmony_ci // the customized stage. 1410e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << StringTemplate(makeVertexShaderAssembly(fillInterfacePlaceholderVert())).specialize(passthruInterface(context.interfaces.getInputType())) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1411e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << StringTemplate(makeFragmentShaderAssembly(fillInterfacePlaceholderFrag())).specialize(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1412e5c31af7Sopenharmony_ci } 1413e5c31af7Sopenharmony_ci else 1414e5c31af7Sopenharmony_ci { 1415e5c31af7Sopenharmony_ci map<string, string> passthru = passthruFragments(); 1416e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert", spirVAsmBuildOptions) << makeVertexShaderAssembly(passthru) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1417e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag", spirVAsmBuildOptions) << makeFragmentShaderAssembly(context.testCodeFragments) << SpirVAsmBuildOptions(vulkanVersion, targetSpirvVersion); 1418e5c31af7Sopenharmony_ci } 1419e5c31af7Sopenharmony_ci} 1420e5c31af7Sopenharmony_ci 1421e5c31af7Sopenharmony_civoid addShaderCodeCustomFragment (vk::SourceCollections& dst, InstanceContext context) 1422e5c31af7Sopenharmony_ci{ 1423e5c31af7Sopenharmony_ci addShaderCodeCustomFragment(dst, context, DE_NULL); 1424e5c31af7Sopenharmony_ci} 1425e5c31af7Sopenharmony_ci 1426e5c31af7Sopenharmony_civoid createCombinedModule (vk::SourceCollections& dst, InstanceContext ctx) 1427e5c31af7Sopenharmony_ci{ 1428e5c31af7Sopenharmony_ci const bool useTessellation (ctx.requiredStages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)); 1429e5c31af7Sopenharmony_ci const bool useGeometry (ctx.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT); 1430e5c31af7Sopenharmony_ci std::stringstream combinedModule; 1431e5c31af7Sopenharmony_ci std::stringstream opCapabilities; 1432e5c31af7Sopenharmony_ci std::stringstream opEntryPoints; 1433e5c31af7Sopenharmony_ci 1434e5c31af7Sopenharmony_ci // opCapabilities 1435e5c31af7Sopenharmony_ci { 1436e5c31af7Sopenharmony_ci opCapabilities << "OpCapability Shader\n"; 1437e5c31af7Sopenharmony_ci 1438e5c31af7Sopenharmony_ci if (useGeometry) 1439e5c31af7Sopenharmony_ci opCapabilities << "OpCapability Geometry\n"; 1440e5c31af7Sopenharmony_ci 1441e5c31af7Sopenharmony_ci if (useTessellation) 1442e5c31af7Sopenharmony_ci opCapabilities << "OpCapability Tessellation\n"; 1443e5c31af7Sopenharmony_ci } 1444e5c31af7Sopenharmony_ci 1445e5c31af7Sopenharmony_ci // opEntryPoints 1446e5c31af7Sopenharmony_ci { 1447e5c31af7Sopenharmony_ci if (useTessellation) 1448e5c31af7Sopenharmony_ci opEntryPoints << "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_vtxPosition %vert_vertex_id %vert_instance_id\n"; 1449e5c31af7Sopenharmony_ci else 1450e5c31af7Sopenharmony_ci opEntryPoints << "OpEntryPoint Vertex %vert_main \"main\" %vert_Position %vert_vtxColor %vert_color %vert_glPerVertex %vert_vertex_id %vert_instance_id\n"; 1451e5c31af7Sopenharmony_ci 1452e5c31af7Sopenharmony_ci if (useGeometry) 1453e5c31af7Sopenharmony_ci opEntryPoints << "OpEntryPoint Geometry %geom_main \"main\" %geom_out_gl_position %geom_gl_in %geom_out_color %geom_in_color\n"; 1454e5c31af7Sopenharmony_ci 1455e5c31af7Sopenharmony_ci if (useTessellation) 1456e5c31af7Sopenharmony_ci { 1457e5c31af7Sopenharmony_ci opEntryPoints << "OpEntryPoint TessellationControl %tessc_main \"main\" %tessc_out_color %tessc_gl_InvocationID %tessc_in_color %tessc_out_position %tessc_in_position %tessc_gl_TessLevelOuter %tessc_gl_TessLevelInner\n" 1458e5c31af7Sopenharmony_ci "OpEntryPoint TessellationEvaluation %tesse_main \"main\" %tesse_stream %tesse_gl_tessCoord %tesse_in_position %tesse_out_color %tesse_in_color \n"; 1459e5c31af7Sopenharmony_ci } 1460e5c31af7Sopenharmony_ci 1461e5c31af7Sopenharmony_ci opEntryPoints << "OpEntryPoint Fragment %frag_main \"main\" %frag_vtxColor %frag_fragColor\n"; 1462e5c31af7Sopenharmony_ci } 1463e5c31af7Sopenharmony_ci 1464e5c31af7Sopenharmony_ci combinedModule << opCapabilities.str() 1465e5c31af7Sopenharmony_ci << "OpMemoryModel Logical GLSL450\n" 1466e5c31af7Sopenharmony_ci << opEntryPoints.str(); 1467e5c31af7Sopenharmony_ci 1468e5c31af7Sopenharmony_ci if (useGeometry) 1469e5c31af7Sopenharmony_ci { 1470e5c31af7Sopenharmony_ci combinedModule << "OpExecutionMode %geom_main Triangles\n" 1471e5c31af7Sopenharmony_ci "OpExecutionMode %geom_main Invocations 1\n" 1472e5c31af7Sopenharmony_ci "OpExecutionMode %geom_main OutputTriangleStrip\n" 1473e5c31af7Sopenharmony_ci "OpExecutionMode %geom_main OutputVertices 3\n"; 1474e5c31af7Sopenharmony_ci } 1475e5c31af7Sopenharmony_ci 1476e5c31af7Sopenharmony_ci if (useTessellation) 1477e5c31af7Sopenharmony_ci { 1478e5c31af7Sopenharmony_ci combinedModule << "OpExecutionMode %tessc_main OutputVertices 3\n" 1479e5c31af7Sopenharmony_ci "OpExecutionMode %tesse_main Triangles\n" 1480e5c31af7Sopenharmony_ci "OpExecutionMode %tesse_main SpacingEqual\n" 1481e5c31af7Sopenharmony_ci "OpExecutionMode %tesse_main VertexOrderCcw\n"; 1482e5c31af7Sopenharmony_ci } 1483e5c31af7Sopenharmony_ci 1484e5c31af7Sopenharmony_ci combinedModule << "OpExecutionMode %frag_main OriginUpperLeft\n" 1485e5c31af7Sopenharmony_ci 1486e5c31af7Sopenharmony_ci "; Vertex decorations\n" 1487e5c31af7Sopenharmony_ci "OpDecorate %vert_Position Location 0\n" 1488e5c31af7Sopenharmony_ci "OpDecorate %vert_vtxColor Location 1\n" 1489e5c31af7Sopenharmony_ci "OpDecorate %vert_color Location 1\n" 1490e5c31af7Sopenharmony_ci "OpDecorate %vert_vertex_id BuiltIn VertexIndex\n" 1491e5c31af7Sopenharmony_ci "OpDecorate %vert_instance_id BuiltIn InstanceIndex\n"; 1492e5c31af7Sopenharmony_ci 1493e5c31af7Sopenharmony_ci // If tessellation is used, vertex position is written by tessellation stage. 1494e5c31af7Sopenharmony_ci // Otherwise it will be written by vertex stage. 1495e5c31af7Sopenharmony_ci if (useTessellation) 1496e5c31af7Sopenharmony_ci combinedModule << "OpDecorate %vert_vtxPosition Location 2\n"; 1497e5c31af7Sopenharmony_ci else 1498e5c31af7Sopenharmony_ci { 1499e5c31af7Sopenharmony_ci combinedModule << "OpMemberDecorate %vert_per_vertex_out 0 BuiltIn Position\n" 1500e5c31af7Sopenharmony_ci "OpMemberDecorate %vert_per_vertex_out 1 BuiltIn PointSize\n" 1501e5c31af7Sopenharmony_ci "OpMemberDecorate %vert_per_vertex_out 2 BuiltIn ClipDistance\n" 1502e5c31af7Sopenharmony_ci "OpMemberDecorate %vert_per_vertex_out 3 BuiltIn CullDistance\n" 1503e5c31af7Sopenharmony_ci "OpDecorate %vert_per_vertex_out Block\n"; 1504e5c31af7Sopenharmony_ci } 1505e5c31af7Sopenharmony_ci 1506e5c31af7Sopenharmony_ci if (useGeometry) 1507e5c31af7Sopenharmony_ci { 1508e5c31af7Sopenharmony_ci combinedModule << "; Geometry decorations\n" 1509e5c31af7Sopenharmony_ci "OpDecorate %geom_out_gl_position BuiltIn Position\n" 1510e5c31af7Sopenharmony_ci "OpMemberDecorate %geom_per_vertex_in 0 BuiltIn Position\n" 1511e5c31af7Sopenharmony_ci "OpMemberDecorate %geom_per_vertex_in 1 BuiltIn PointSize\n" 1512e5c31af7Sopenharmony_ci "OpMemberDecorate %geom_per_vertex_in 2 BuiltIn ClipDistance\n" 1513e5c31af7Sopenharmony_ci "OpMemberDecorate %geom_per_vertex_in 3 BuiltIn CullDistance\n" 1514e5c31af7Sopenharmony_ci "OpDecorate %geom_per_vertex_in Block\n" 1515e5c31af7Sopenharmony_ci "OpDecorate %geom_out_color Location 1\n" 1516e5c31af7Sopenharmony_ci "OpDecorate %geom_in_color Location 1\n"; 1517e5c31af7Sopenharmony_ci } 1518e5c31af7Sopenharmony_ci 1519e5c31af7Sopenharmony_ci if (useTessellation) 1520e5c31af7Sopenharmony_ci { 1521e5c31af7Sopenharmony_ci combinedModule << "; Tessellation Control decorations\n" 1522e5c31af7Sopenharmony_ci "OpDecorate %tessc_out_color Location 1\n" 1523e5c31af7Sopenharmony_ci "OpDecorate %tessc_gl_InvocationID BuiltIn InvocationId\n" 1524e5c31af7Sopenharmony_ci "OpDecorate %tessc_in_color Location 1\n" 1525e5c31af7Sopenharmony_ci "OpDecorate %tessc_out_position Location 2\n" 1526e5c31af7Sopenharmony_ci "OpDecorate %tessc_in_position Location 2\n" 1527e5c31af7Sopenharmony_ci "OpDecorate %tessc_gl_TessLevelOuter Patch\n" 1528e5c31af7Sopenharmony_ci "OpDecorate %tessc_gl_TessLevelOuter BuiltIn TessLevelOuter\n" 1529e5c31af7Sopenharmony_ci "OpDecorate %tessc_gl_TessLevelInner Patch\n" 1530e5c31af7Sopenharmony_ci "OpDecorate %tessc_gl_TessLevelInner BuiltIn TessLevelInner\n" 1531e5c31af7Sopenharmony_ci 1532e5c31af7Sopenharmony_ci "; Tessellation Evaluation decorations\n" 1533e5c31af7Sopenharmony_ci "OpMemberDecorate %tesse_per_vertex_out 0 BuiltIn Position\n" 1534e5c31af7Sopenharmony_ci "OpMemberDecorate %tesse_per_vertex_out 1 BuiltIn PointSize\n" 1535e5c31af7Sopenharmony_ci "OpMemberDecorate %tesse_per_vertex_out 2 BuiltIn ClipDistance\n" 1536e5c31af7Sopenharmony_ci "OpMemberDecorate %tesse_per_vertex_out 3 BuiltIn CullDistance\n" 1537e5c31af7Sopenharmony_ci "OpDecorate %tesse_per_vertex_out Block\n" 1538e5c31af7Sopenharmony_ci "OpDecorate %tesse_gl_tessCoord BuiltIn TessCoord\n" 1539e5c31af7Sopenharmony_ci "OpDecorate %tesse_in_position Location 2\n" 1540e5c31af7Sopenharmony_ci "OpDecorate %tesse_out_color Location 1\n" 1541e5c31af7Sopenharmony_ci "OpDecorate %tesse_in_color Location 1\n"; 1542e5c31af7Sopenharmony_ci } 1543e5c31af7Sopenharmony_ci 1544e5c31af7Sopenharmony_ci combinedModule << "; Fragment decorations\n" 1545e5c31af7Sopenharmony_ci "OpDecorate %frag_fragColor Location 0\n" 1546e5c31af7Sopenharmony_ci "OpDecorate %frag_vtxColor Location 1\n" 1547e5c31af7Sopenharmony_ci 1548e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 1549e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 1550e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 1551e5c31af7Sopenharmony_ci 1552e5c31af7Sopenharmony_ci "; Vertex Variables\n" 1553e5c31af7Sopenharmony_ci "%vert_Position = OpVariable %ip_v4f32 Input\n" 1554e5c31af7Sopenharmony_ci "%vert_vtxColor = OpVariable %op_v4f32 Output\n" 1555e5c31af7Sopenharmony_ci "%vert_color = OpVariable %ip_v4f32 Input\n" 1556e5c31af7Sopenharmony_ci "%vert_vertex_id = OpVariable %ip_i32 Input\n" 1557e5c31af7Sopenharmony_ci "%vert_instance_id = OpVariable %ip_i32 Input\n"; 1558e5c31af7Sopenharmony_ci 1559e5c31af7Sopenharmony_ci if (useTessellation) 1560e5c31af7Sopenharmony_ci combinedModule << "%vert_vtxPosition = OpVariable %op_v4f32 Output\n"; 1561e5c31af7Sopenharmony_ci else 1562e5c31af7Sopenharmony_ci { 1563e5c31af7Sopenharmony_ci combinedModule << "%vert_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 1564e5c31af7Sopenharmony_ci "%vert_op_per_vertex_out = OpTypePointer Output %vert_per_vertex_out\n" 1565e5c31af7Sopenharmony_ci "%vert_glPerVertex = OpVariable %vert_op_per_vertex_out Output\n"; 1566e5c31af7Sopenharmony_ci } 1567e5c31af7Sopenharmony_ci 1568e5c31af7Sopenharmony_ci if (useGeometry) 1569e5c31af7Sopenharmony_ci { 1570e5c31af7Sopenharmony_ci combinedModule << "; Geometry Variables\n" 1571e5c31af7Sopenharmony_ci "%geom_per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 1572e5c31af7Sopenharmony_ci "%geom_a3_per_vertex_in = OpTypeArray %geom_per_vertex_in %c_u32_3\n" 1573e5c31af7Sopenharmony_ci "%geom_ip_a3_per_vertex_in = OpTypePointer Input %geom_a3_per_vertex_in\n" 1574e5c31af7Sopenharmony_ci "%geom_gl_in = OpVariable %geom_ip_a3_per_vertex_in Input\n" 1575e5c31af7Sopenharmony_ci "%geom_out_color = OpVariable %op_v4f32 Output\n" 1576e5c31af7Sopenharmony_ci "%geom_in_color = OpVariable %ip_a3v4f32 Input\n" 1577e5c31af7Sopenharmony_ci "%geom_out_gl_position = OpVariable %op_v4f32 Output\n"; 1578e5c31af7Sopenharmony_ci } 1579e5c31af7Sopenharmony_ci 1580e5c31af7Sopenharmony_ci if (useTessellation) 1581e5c31af7Sopenharmony_ci { 1582e5c31af7Sopenharmony_ci combinedModule << "; Tessellation Control Variables\n" 1583e5c31af7Sopenharmony_ci "%tessc_out_color = OpVariable %op_a3v4f32 Output\n" 1584e5c31af7Sopenharmony_ci "%tessc_gl_InvocationID = OpVariable %ip_i32 Input\n" 1585e5c31af7Sopenharmony_ci "%tessc_in_color = OpVariable %ip_a32v4f32 Input\n" 1586e5c31af7Sopenharmony_ci "%tessc_out_position = OpVariable %op_a3v4f32 Output\n" 1587e5c31af7Sopenharmony_ci "%tessc_in_position = OpVariable %ip_a32v4f32 Input\n" 1588e5c31af7Sopenharmony_ci "%tessc_gl_TessLevelOuter = OpVariable %op_a4f32 Output\n" 1589e5c31af7Sopenharmony_ci "%tessc_gl_TessLevelInner = OpVariable %op_a2f32 Output\n" 1590e5c31af7Sopenharmony_ci 1591e5c31af7Sopenharmony_ci "; Tessellation Evaluation Decorations\n" 1592e5c31af7Sopenharmony_ci "%tesse_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 1593e5c31af7Sopenharmony_ci "%tesse_op_per_vertex_out = OpTypePointer Output %tesse_per_vertex_out\n" 1594e5c31af7Sopenharmony_ci "%tesse_stream = OpVariable %tesse_op_per_vertex_out Output\n" 1595e5c31af7Sopenharmony_ci "%tesse_gl_tessCoord = OpVariable %ip_v3f32 Input\n" 1596e5c31af7Sopenharmony_ci "%tesse_in_position = OpVariable %ip_a32v4f32 Input\n" 1597e5c31af7Sopenharmony_ci "%tesse_out_color = OpVariable %op_v4f32 Output\n" 1598e5c31af7Sopenharmony_ci "%tesse_in_color = OpVariable %ip_a32v4f32 Input\n"; 1599e5c31af7Sopenharmony_ci } 1600e5c31af7Sopenharmony_ci 1601e5c31af7Sopenharmony_ci combinedModule << "; Fragment Variables\n" 1602e5c31af7Sopenharmony_ci "%frag_fragColor = OpVariable %op_v4f32 Output\n" 1603e5c31af7Sopenharmony_ci "%frag_vtxColor = OpVariable %ip_v4f32 Input\n" 1604e5c31af7Sopenharmony_ci 1605e5c31af7Sopenharmony_ci "; Vertex Entry\n" 1606e5c31af7Sopenharmony_ci "%vert_main = OpFunction %void None %voidf\n" 1607e5c31af7Sopenharmony_ci "%vert_label = OpLabel\n" 1608e5c31af7Sopenharmony_ci "%vert_tmp_position = OpLoad %v4f32 %vert_Position\n"; 1609e5c31af7Sopenharmony_ci 1610e5c31af7Sopenharmony_ci if (useTessellation) 1611e5c31af7Sopenharmony_ci combinedModule << "OpStore %vert_vtxPosition %vert_tmp_position\n"; 1612e5c31af7Sopenharmony_ci else 1613e5c31af7Sopenharmony_ci { 1614e5c31af7Sopenharmony_ci combinedModule << "%vert_out_pos_ptr = OpAccessChain %op_v4f32 %vert_glPerVertex %c_i32_0\n" 1615e5c31af7Sopenharmony_ci "OpStore %vert_out_pos_ptr %vert_tmp_position\n"; 1616e5c31af7Sopenharmony_ci } 1617e5c31af7Sopenharmony_ci 1618e5c31af7Sopenharmony_ci combinedModule << "%vert_tmp_color = OpLoad %v4f32 %vert_color\n" 1619e5c31af7Sopenharmony_ci "OpStore %vert_vtxColor %vert_tmp_color\n" 1620e5c31af7Sopenharmony_ci "OpReturn\n" 1621e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 1622e5c31af7Sopenharmony_ci 1623e5c31af7Sopenharmony_ci if (useGeometry) 1624e5c31af7Sopenharmony_ci { 1625e5c31af7Sopenharmony_ci combinedModule << "; Geometry Entry\n" 1626e5c31af7Sopenharmony_ci "%geom_main = OpFunction %void None %voidf\n" 1627e5c31af7Sopenharmony_ci "%geom_label = OpLabel\n" 1628e5c31af7Sopenharmony_ci "%geom_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_0 %c_i32_0\n" 1629e5c31af7Sopenharmony_ci "%geom_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_1 %c_i32_0\n" 1630e5c31af7Sopenharmony_ci "%geom_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %geom_gl_in %c_i32_2 %c_i32_0\n" 1631e5c31af7Sopenharmony_ci "%geom_in_position_0 = OpLoad %v4f32 %geom_gl_in_0_gl_position\n" 1632e5c31af7Sopenharmony_ci "%geom_in_position_1 = OpLoad %v4f32 %geom_gl_in_1_gl_position\n" 1633e5c31af7Sopenharmony_ci "%geom_in_position_2 = OpLoad %v4f32 %geom_gl_in_2_gl_position \n" 1634e5c31af7Sopenharmony_ci "%geom_in_color_0_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_0\n" 1635e5c31af7Sopenharmony_ci "%geom_in_color_1_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_1\n" 1636e5c31af7Sopenharmony_ci "%geom_in_color_2_ptr = OpAccessChain %ip_v4f32 %geom_in_color %c_i32_2\n" 1637e5c31af7Sopenharmony_ci "%geom_in_color_0 = OpLoad %v4f32 %geom_in_color_0_ptr\n" 1638e5c31af7Sopenharmony_ci "%geom_in_color_1 = OpLoad %v4f32 %geom_in_color_1_ptr\n" 1639e5c31af7Sopenharmony_ci "%geom_in_color_2 = OpLoad %v4f32 %geom_in_color_2_ptr\n" 1640e5c31af7Sopenharmony_ci "OpStore %geom_out_gl_position %geom_in_position_0\n" 1641e5c31af7Sopenharmony_ci "OpStore %geom_out_color %geom_in_color_0\n" 1642e5c31af7Sopenharmony_ci "OpEmitVertex\n" 1643e5c31af7Sopenharmony_ci "OpStore %geom_out_gl_position %geom_in_position_1\n" 1644e5c31af7Sopenharmony_ci "OpStore %geom_out_color %geom_in_color_1\n" 1645e5c31af7Sopenharmony_ci "OpEmitVertex\n" 1646e5c31af7Sopenharmony_ci "OpStore %geom_out_gl_position %geom_in_position_2\n" 1647e5c31af7Sopenharmony_ci "OpStore %geom_out_color %geom_in_color_2\n" 1648e5c31af7Sopenharmony_ci "OpEmitVertex\n" 1649e5c31af7Sopenharmony_ci "OpEndPrimitive\n" 1650e5c31af7Sopenharmony_ci "OpReturn\n" 1651e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 1652e5c31af7Sopenharmony_ci } 1653e5c31af7Sopenharmony_ci 1654e5c31af7Sopenharmony_ci if (useTessellation) 1655e5c31af7Sopenharmony_ci { 1656e5c31af7Sopenharmony_ci combinedModule << "; Tessellation Control Entry\n" 1657e5c31af7Sopenharmony_ci "%tessc_main = OpFunction %void None %voidf\n" 1658e5c31af7Sopenharmony_ci "%tessc_label = OpLabel\n" 1659e5c31af7Sopenharmony_ci "%tessc_invocation_id = OpLoad %i32 %tessc_gl_InvocationID\n" 1660e5c31af7Sopenharmony_ci "%tessc_in_color_ptr = OpAccessChain %ip_v4f32 %tessc_in_color %tessc_invocation_id\n" 1661e5c31af7Sopenharmony_ci "%tessc_in_position_ptr = OpAccessChain %ip_v4f32 %tessc_in_position %tessc_invocation_id\n" 1662e5c31af7Sopenharmony_ci "%tessc_in_color_val = OpLoad %v4f32 %tessc_in_color_ptr\n" 1663e5c31af7Sopenharmony_ci "%tessc_in_position_val = OpLoad %v4f32 %tessc_in_position_ptr\n" 1664e5c31af7Sopenharmony_ci "%tessc_out_color_ptr = OpAccessChain %op_v4f32 %tessc_out_color %tessc_invocation_id\n" 1665e5c31af7Sopenharmony_ci "%tessc_out_position_ptr = OpAccessChain %op_v4f32 %tessc_out_position %tessc_invocation_id\n" 1666e5c31af7Sopenharmony_ci "OpStore %tessc_out_color_ptr %tessc_in_color_val\n" 1667e5c31af7Sopenharmony_ci "OpStore %tessc_out_position_ptr %tessc_in_position_val\n" 1668e5c31af7Sopenharmony_ci "%tessc_is_first_invocation = OpIEqual %bool %tessc_invocation_id %c_i32_0\n" 1669e5c31af7Sopenharmony_ci "OpSelectionMerge %tessc_merge_label None\n" 1670e5c31af7Sopenharmony_ci "OpBranchConditional %tessc_is_first_invocation %tessc_first_invocation %tessc_merge_label\n" 1671e5c31af7Sopenharmony_ci "%tessc_first_invocation = OpLabel\n" 1672e5c31af7Sopenharmony_ci "%tessc_tess_outer_0 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_0\n" 1673e5c31af7Sopenharmony_ci "%tessc_tess_outer_1 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_1\n" 1674e5c31af7Sopenharmony_ci "%tessc_tess_outer_2 = OpAccessChain %op_f32 %tessc_gl_TessLevelOuter %c_i32_2\n" 1675e5c31af7Sopenharmony_ci "%tessc_tess_inner = OpAccessChain %op_f32 %tessc_gl_TessLevelInner %c_i32_0\n" 1676e5c31af7Sopenharmony_ci "OpStore %tessc_tess_outer_0 %c_f32_1\n" 1677e5c31af7Sopenharmony_ci "OpStore %tessc_tess_outer_1 %c_f32_1\n" 1678e5c31af7Sopenharmony_ci "OpStore %tessc_tess_outer_2 %c_f32_1\n" 1679e5c31af7Sopenharmony_ci "OpStore %tessc_tess_inner %c_f32_1\n" 1680e5c31af7Sopenharmony_ci "OpBranch %tessc_merge_label\n" 1681e5c31af7Sopenharmony_ci "%tessc_merge_label = OpLabel\n" 1682e5c31af7Sopenharmony_ci "OpReturn\n" 1683e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 1684e5c31af7Sopenharmony_ci 1685e5c31af7Sopenharmony_ci "; Tessellation Evaluation Entry\n" 1686e5c31af7Sopenharmony_ci "%tesse_main = OpFunction %void None %voidf\n" 1687e5c31af7Sopenharmony_ci "%tesse_label = OpLabel\n" 1688e5c31af7Sopenharmony_ci "%tesse_tc_0_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_0\n" 1689e5c31af7Sopenharmony_ci "%tesse_tc_1_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_1\n" 1690e5c31af7Sopenharmony_ci "%tesse_tc_2_ptr = OpAccessChain %ip_f32 %tesse_gl_tessCoord %c_u32_2\n" 1691e5c31af7Sopenharmony_ci "%tesse_tc_0 = OpLoad %f32 %tesse_tc_0_ptr\n" 1692e5c31af7Sopenharmony_ci "%tesse_tc_1 = OpLoad %f32 %tesse_tc_1_ptr\n" 1693e5c31af7Sopenharmony_ci "%tesse_tc_2 = OpLoad %f32 %tesse_tc_2_ptr\n" 1694e5c31af7Sopenharmony_ci "%tesse_in_pos_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_0\n" 1695e5c31af7Sopenharmony_ci "%tesse_in_pos_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_1\n" 1696e5c31af7Sopenharmony_ci "%tesse_in_pos_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_position %c_i32_2\n" 1697e5c31af7Sopenharmony_ci "%tesse_in_pos_0 = OpLoad %v4f32 %tesse_in_pos_0_ptr\n" 1698e5c31af7Sopenharmony_ci "%tesse_in_pos_1 = OpLoad %v4f32 %tesse_in_pos_1_ptr\n" 1699e5c31af7Sopenharmony_ci "%tesse_in_pos_2 = OpLoad %v4f32 %tesse_in_pos_2_ptr\n" 1700e5c31af7Sopenharmony_ci "%tesse_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_0 %tesse_tc_0\n" 1701e5c31af7Sopenharmony_ci "%tesse_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_1 %tesse_tc_1\n" 1702e5c31af7Sopenharmony_ci "%tesse_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_pos_2 %tesse_tc_2\n" 1703e5c31af7Sopenharmony_ci "%tesse_out_pos_ptr = OpAccessChain %op_v4f32 %tesse_stream %c_i32_0\n" 1704e5c31af7Sopenharmony_ci "%tesse_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse_in_pos_0_weighted %tesse_in_pos_1_weighted\n" 1705e5c31af7Sopenharmony_ci "%tesse_computed_out = OpFAdd %v4f32 %tesse_in_pos_0_plus_pos_1 %tesse_in_pos_2_weighted\n" 1706e5c31af7Sopenharmony_ci "OpStore %tesse_out_pos_ptr %tesse_computed_out\n" 1707e5c31af7Sopenharmony_ci "%tesse_in_clr_0_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_0\n" 1708e5c31af7Sopenharmony_ci "%tesse_in_clr_1_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_1\n" 1709e5c31af7Sopenharmony_ci "%tesse_in_clr_2_ptr = OpAccessChain %ip_v4f32 %tesse_in_color %c_i32_2\n" 1710e5c31af7Sopenharmony_ci "%tesse_in_clr_0 = OpLoad %v4f32 %tesse_in_clr_0_ptr\n" 1711e5c31af7Sopenharmony_ci "%tesse_in_clr_1 = OpLoad %v4f32 %tesse_in_clr_1_ptr\n" 1712e5c31af7Sopenharmony_ci "%tesse_in_clr_2 = OpLoad %v4f32 %tesse_in_clr_2_ptr\n" 1713e5c31af7Sopenharmony_ci "%tesse_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_0 %tesse_tc_0\n" 1714e5c31af7Sopenharmony_ci "%tesse_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_1 %tesse_tc_1\n" 1715e5c31af7Sopenharmony_ci "%tesse_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse_in_clr_2 %tesse_tc_2\n" 1716e5c31af7Sopenharmony_ci "%tesse_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse_in_clr_0_weighted %tesse_in_clr_1_weighted\n" 1717e5c31af7Sopenharmony_ci "%tesse_computed_clr = OpFAdd %v4f32 %tesse_in_clr_0_plus_col_1 %tesse_in_clr_2_weighted\n" 1718e5c31af7Sopenharmony_ci "OpStore %tesse_out_color %tesse_computed_clr\n" 1719e5c31af7Sopenharmony_ci "OpReturn\n" 1720e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 1721e5c31af7Sopenharmony_ci } 1722e5c31af7Sopenharmony_ci 1723e5c31af7Sopenharmony_ci combinedModule << "; Fragment Entry\n" 1724e5c31af7Sopenharmony_ci "%frag_main = OpFunction %void None %voidf\n" 1725e5c31af7Sopenharmony_ci "%frag_label_main = OpLabel\n" 1726e5c31af7Sopenharmony_ci "%frag_tmp1 = OpLoad %v4f32 %frag_vtxColor\n" 1727e5c31af7Sopenharmony_ci "OpStore %frag_fragColor %frag_tmp1\n" 1728e5c31af7Sopenharmony_ci "OpReturn\n" 1729e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 1730e5c31af7Sopenharmony_ci 1731e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("module") << combinedModule.str(); 1732e5c31af7Sopenharmony_ci} 1733e5c31af7Sopenharmony_ci 1734e5c31af7Sopenharmony_civoid createUnusedVariableModules (vk::SourceCollections& dst, UnusedVariableContext ctx) 1735e5c31af7Sopenharmony_ci{ 1736e5c31af7Sopenharmony_ci if (ctx.shaderTasks[SHADER_TASK_INDEX_VERTEX] != SHADER_TASK_NONE) 1737e5c31af7Sopenharmony_ci { 1738e5c31af7Sopenharmony_ci std::ostringstream shader; 1739e5c31af7Sopenharmony_ci bool tessellation = (ctx.shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL] != SHADER_TASK_NONE 1740e5c31af7Sopenharmony_ci || ctx.shaderTasks[SHADER_TASK_INDEX_TESS_EVAL] != SHADER_TASK_NONE); 1741e5c31af7Sopenharmony_ci const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_VERTEX]; 1742e5c31af7Sopenharmony_ci 1743e5c31af7Sopenharmony_ci shader << "OpCapability Shader\n" 1744e5c31af7Sopenharmony_ci << "OpMemoryModel Logical GLSL450\n"; 1745e5c31af7Sopenharmony_ci 1746e5c31af7Sopenharmony_ci // Entry point depends on if tessellation is enabled or not to provide the vertex position. 1747e5c31af7Sopenharmony_ci shader << "OpEntryPoint Vertex %main \"main\" %Position %vtxColor %color " 1748e5c31af7Sopenharmony_ci << (tessellation ? "%vtxPosition" : "%vtx_glPerVertex") 1749e5c31af7Sopenharmony_ci << " %vertex_id %instance_id\n"; 1750e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 1751e5c31af7Sopenharmony_ci { 1752e5c31af7Sopenharmony_ci shader << getUnusedEntryPoint(); 1753e5c31af7Sopenharmony_ci } 1754e5c31af7Sopenharmony_ci 1755e5c31af7Sopenharmony_ci // Decorations. 1756e5c31af7Sopenharmony_ci shader << "OpDecorate %Position Location 0\n" 1757e5c31af7Sopenharmony_ci << "OpDecorate %vtxColor Location 1\n" 1758e5c31af7Sopenharmony_ci << "OpDecorate %color Location 1\n" 1759e5c31af7Sopenharmony_ci << "OpDecorate %vertex_id BuiltIn VertexIndex\n" 1760e5c31af7Sopenharmony_ci << "OpDecorate %instance_id BuiltIn InstanceIndex\n"; 1761e5c31af7Sopenharmony_ci if (tessellation) 1762e5c31af7Sopenharmony_ci { 1763e5c31af7Sopenharmony_ci shader << "OpDecorate %vtxPosition Location 2\n"; 1764e5c31af7Sopenharmony_ci } 1765e5c31af7Sopenharmony_ci else 1766e5c31af7Sopenharmony_ci { 1767e5c31af7Sopenharmony_ci shader << "OpMemberDecorate %vert_per_vertex_out 0 BuiltIn Position\n" 1768e5c31af7Sopenharmony_ci << "OpMemberDecorate %vert_per_vertex_out 1 BuiltIn PointSize\n" 1769e5c31af7Sopenharmony_ci << "OpMemberDecorate %vert_per_vertex_out 2 BuiltIn ClipDistance\n" 1770e5c31af7Sopenharmony_ci << "OpMemberDecorate %vert_per_vertex_out 3 BuiltIn CullDistance\n" 1771e5c31af7Sopenharmony_ci << "OpDecorate %vert_per_vertex_out Block\n"; 1772e5c31af7Sopenharmony_ci } 1773e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1774e5c31af7Sopenharmony_ci { 1775e5c31af7Sopenharmony_ci shader << getUnusedDecorations(ctx.variableLocation); 1776e5c31af7Sopenharmony_ci } 1777e5c31af7Sopenharmony_ci 1778e5c31af7Sopenharmony_ci // Standard types, constants and arrays. 1779e5c31af7Sopenharmony_ci shader << "; Start of standard types, constants and arrays\n" 1780e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_TYPES 1781e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_CONSTANTS 1782e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_ARRAYS 1783e5c31af7Sopenharmony_ci << "; End of standard types, constants and arrays\n"; 1784e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1785e5c31af7Sopenharmony_ci { 1786e5c31af7Sopenharmony_ci shader << getUnusedTypesAndConstants(); 1787e5c31af7Sopenharmony_ci } 1788e5c31af7Sopenharmony_ci 1789e5c31af7Sopenharmony_ci // Variables. 1790e5c31af7Sopenharmony_ci if (tessellation) 1791e5c31af7Sopenharmony_ci { 1792e5c31af7Sopenharmony_ci shader << "%vtxPosition = OpVariable %op_v4f32 Output\n"; 1793e5c31af7Sopenharmony_ci } 1794e5c31af7Sopenharmony_ci else 1795e5c31af7Sopenharmony_ci { 1796e5c31af7Sopenharmony_ci shader << "%vert_per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 1797e5c31af7Sopenharmony_ci << "%vert_op_per_vertex_out = OpTypePointer Output %vert_per_vertex_out\n" 1798e5c31af7Sopenharmony_ci << "%vtx_glPerVertex = OpVariable %vert_op_per_vertex_out Output\n"; 1799e5c31af7Sopenharmony_ci } 1800e5c31af7Sopenharmony_ci shader << "%Position = OpVariable %ip_v4f32 Input\n" 1801e5c31af7Sopenharmony_ci << "%vtxColor = OpVariable %op_v4f32 Output\n" 1802e5c31af7Sopenharmony_ci << "%color = OpVariable %ip_v4f32 Input\n" 1803e5c31af7Sopenharmony_ci << "%vertex_id = OpVariable %ip_i32 Input\n" 1804e5c31af7Sopenharmony_ci << "%instance_id = OpVariable %ip_i32 Input\n"; 1805e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1806e5c31af7Sopenharmony_ci { 1807e5c31af7Sopenharmony_ci shader << getUnusedBuffer(); 1808e5c31af7Sopenharmony_ci } 1809e5c31af7Sopenharmony_ci 1810e5c31af7Sopenharmony_ci // Vertex main function. 1811e5c31af7Sopenharmony_ci shader << "%main = OpFunction %void None %voidf\n" 1812e5c31af7Sopenharmony_ci << "%label = OpLabel\n" 1813e5c31af7Sopenharmony_ci << "%tmp_position = OpLoad %v4f32 %Position\n"; 1814e5c31af7Sopenharmony_ci if (tessellation) 1815e5c31af7Sopenharmony_ci { 1816e5c31af7Sopenharmony_ci shader << "OpStore %vtxPosition %tmp_position\n"; 1817e5c31af7Sopenharmony_ci } 1818e5c31af7Sopenharmony_ci else 1819e5c31af7Sopenharmony_ci { 1820e5c31af7Sopenharmony_ci shader << "%vert_out_pos_ptr = OpAccessChain %op_v4f32 %vtx_glPerVertex %c_i32_0\n" 1821e5c31af7Sopenharmony_ci << "OpStore %vert_out_pos_ptr %tmp_position\n"; 1822e5c31af7Sopenharmony_ci } 1823e5c31af7Sopenharmony_ci shader << "%tmp_color = OpLoad %v4f32 %color\n" 1824e5c31af7Sopenharmony_ci << "OpStore %vtxColor %tmp_color\n" 1825e5c31af7Sopenharmony_ci << "OpReturn\n" 1826e5c31af7Sopenharmony_ci << "OpFunctionEnd\n"; 1827e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 1828e5c31af7Sopenharmony_ci { 1829e5c31af7Sopenharmony_ci shader << getUnusedFunctionBody(); 1830e5c31af7Sopenharmony_ci } 1831e5c31af7Sopenharmony_ci 1832e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert") << shader.str(); 1833e5c31af7Sopenharmony_ci } 1834e5c31af7Sopenharmony_ci 1835e5c31af7Sopenharmony_ci if (ctx.shaderTasks[SHADER_TASK_INDEX_GEOMETRY] != SHADER_TASK_NONE) 1836e5c31af7Sopenharmony_ci { 1837e5c31af7Sopenharmony_ci const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_GEOMETRY]; 1838e5c31af7Sopenharmony_ci std::ostringstream shader; 1839e5c31af7Sopenharmony_ci 1840e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1841e5c31af7Sopenharmony_ci { 1842e5c31af7Sopenharmony_ci shader << getOpCapabilityShader(); 1843e5c31af7Sopenharmony_ci } 1844e5c31af7Sopenharmony_ci shader << "OpCapability Geometry\n" 1845e5c31af7Sopenharmony_ci << "OpMemoryModel Logical GLSL450\n"; 1846e5c31af7Sopenharmony_ci 1847e5c31af7Sopenharmony_ci // Entry points. 1848e5c31af7Sopenharmony_ci shader << "OpEntryPoint Geometry %geom1_main \"main\" %out_gl_position %gl_in %out_color %in_color\n"; 1849e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 1850e5c31af7Sopenharmony_ci { 1851e5c31af7Sopenharmony_ci shader << getUnusedEntryPoint(); 1852e5c31af7Sopenharmony_ci } 1853e5c31af7Sopenharmony_ci shader << "OpExecutionMode %geom1_main Triangles\n" 1854e5c31af7Sopenharmony_ci << "OpExecutionMode %geom1_main OutputTriangleStrip\n" 1855e5c31af7Sopenharmony_ci << "OpExecutionMode %geom1_main OutputVertices 3\n" 1856e5c31af7Sopenharmony_ci << "OpExecutionMode %geom1_main Invocations 1\n"; 1857e5c31af7Sopenharmony_ci 1858e5c31af7Sopenharmony_ci // Decorations. 1859e5c31af7Sopenharmony_ci shader << "OpDecorate %out_gl_position BuiltIn Position\n" 1860e5c31af7Sopenharmony_ci << "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n" 1861e5c31af7Sopenharmony_ci << "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n" 1862e5c31af7Sopenharmony_ci << "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n" 1863e5c31af7Sopenharmony_ci << "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n" 1864e5c31af7Sopenharmony_ci << "OpDecorate %per_vertex_in Block\n" 1865e5c31af7Sopenharmony_ci << "OpDecorate %out_color Location 1\n" 1866e5c31af7Sopenharmony_ci << "OpDecorate %in_color Location 1\n"; 1867e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1868e5c31af7Sopenharmony_ci { 1869e5c31af7Sopenharmony_ci shader << getUnusedDecorations(ctx.variableLocation); 1870e5c31af7Sopenharmony_ci } 1871e5c31af7Sopenharmony_ci 1872e5c31af7Sopenharmony_ci // Standard types, constants and arrays. 1873e5c31af7Sopenharmony_ci shader << "; Start of standard types, constants and arrays\n" 1874e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_TYPES 1875e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_CONSTANTS 1876e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_ARRAYS 1877e5c31af7Sopenharmony_ci << "; End of standard types, constants and arrays\n"; 1878e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1879e5c31af7Sopenharmony_ci { 1880e5c31af7Sopenharmony_ci shader << getUnusedTypesAndConstants(); 1881e5c31af7Sopenharmony_ci } 1882e5c31af7Sopenharmony_ci 1883e5c31af7Sopenharmony_ci // Variables. 1884e5c31af7Sopenharmony_ci shader << "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 1885e5c31af7Sopenharmony_ci << "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n" 1886e5c31af7Sopenharmony_ci << "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n" 1887e5c31af7Sopenharmony_ci << "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n" 1888e5c31af7Sopenharmony_ci << "%out_color = OpVariable %op_v4f32 Output\n" 1889e5c31af7Sopenharmony_ci << "%in_color = OpVariable %ip_a3v4f32 Input\n" 1890e5c31af7Sopenharmony_ci << "%out_gl_position = OpVariable %op_v4f32 Output\n"; 1891e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1892e5c31af7Sopenharmony_ci { 1893e5c31af7Sopenharmony_ci shader << getUnusedBuffer(); 1894e5c31af7Sopenharmony_ci } 1895e5c31af7Sopenharmony_ci 1896e5c31af7Sopenharmony_ci // Main function. 1897e5c31af7Sopenharmony_ci shader << "%geom1_main = OpFunction %void None %voidf\n" 1898e5c31af7Sopenharmony_ci << "%geom1_label = OpLabel\n" 1899e5c31af7Sopenharmony_ci << "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n" 1900e5c31af7Sopenharmony_ci << "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n" 1901e5c31af7Sopenharmony_ci << "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n" 1902e5c31af7Sopenharmony_ci << "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n" 1903e5c31af7Sopenharmony_ci << "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n" 1904e5c31af7Sopenharmony_ci << "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n" 1905e5c31af7Sopenharmony_ci << "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n" 1906e5c31af7Sopenharmony_ci << "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n" 1907e5c31af7Sopenharmony_ci << "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n" 1908e5c31af7Sopenharmony_ci << "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n" 1909e5c31af7Sopenharmony_ci << "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n" 1910e5c31af7Sopenharmony_ci << "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n" 1911e5c31af7Sopenharmony_ci << "OpStore %out_gl_position %geom1_in_position_0\n" 1912e5c31af7Sopenharmony_ci << "OpStore %out_color %geom1_in_color_0\n" 1913e5c31af7Sopenharmony_ci << "OpEmitVertex\n" 1914e5c31af7Sopenharmony_ci << "OpStore %out_gl_position %geom1_in_position_1\n" 1915e5c31af7Sopenharmony_ci << "OpStore %out_color %geom1_in_color_1\n" 1916e5c31af7Sopenharmony_ci << "OpEmitVertex\n" 1917e5c31af7Sopenharmony_ci << "OpStore %out_gl_position %geom1_in_position_2\n" 1918e5c31af7Sopenharmony_ci << "OpStore %out_color %geom1_in_color_2\n" 1919e5c31af7Sopenharmony_ci << "OpEmitVertex\n" 1920e5c31af7Sopenharmony_ci << "OpEndPrimitive\n" 1921e5c31af7Sopenharmony_ci << "OpReturn\n" 1922e5c31af7Sopenharmony_ci << "OpFunctionEnd\n"; 1923e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 1924e5c31af7Sopenharmony_ci { 1925e5c31af7Sopenharmony_ci shader << getUnusedFunctionBody(); 1926e5c31af7Sopenharmony_ci } 1927e5c31af7Sopenharmony_ci 1928e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("geom") << shader.str(); 1929e5c31af7Sopenharmony_ci } 1930e5c31af7Sopenharmony_ci 1931e5c31af7Sopenharmony_ci if (ctx.shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL] != SHADER_TASK_NONE) 1932e5c31af7Sopenharmony_ci { 1933e5c31af7Sopenharmony_ci const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_TESS_CONTROL]; 1934e5c31af7Sopenharmony_ci std::ostringstream shader; 1935e5c31af7Sopenharmony_ci 1936e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1937e5c31af7Sopenharmony_ci { 1938e5c31af7Sopenharmony_ci shader << getOpCapabilityShader(); 1939e5c31af7Sopenharmony_ci } 1940e5c31af7Sopenharmony_ci shader << "OpCapability Tessellation\n" 1941e5c31af7Sopenharmony_ci << "OpMemoryModel Logical GLSL450\n"; 1942e5c31af7Sopenharmony_ci 1943e5c31af7Sopenharmony_ci // Entry point. 1944e5c31af7Sopenharmony_ci shader << "OpEntryPoint TessellationControl %tessc1_main \"main\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n"; 1945e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 1946e5c31af7Sopenharmony_ci { 1947e5c31af7Sopenharmony_ci shader << getUnusedEntryPoint(); 1948e5c31af7Sopenharmony_ci } 1949e5c31af7Sopenharmony_ci shader << "OpExecutionMode %tessc1_main OutputVertices 3\n"; 1950e5c31af7Sopenharmony_ci 1951e5c31af7Sopenharmony_ci // Decorations. 1952e5c31af7Sopenharmony_ci shader << "OpDecorate %out_color Location 1\n" 1953e5c31af7Sopenharmony_ci << "OpDecorate %gl_InvocationID BuiltIn InvocationId\n" 1954e5c31af7Sopenharmony_ci << "OpDecorate %in_color Location 1\n" 1955e5c31af7Sopenharmony_ci << "OpDecorate %out_position Location 2\n" 1956e5c31af7Sopenharmony_ci << "OpDecorate %in_position Location 2\n" 1957e5c31af7Sopenharmony_ci << "OpDecorate %gl_TessLevelOuter Patch\n" 1958e5c31af7Sopenharmony_ci << "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n" 1959e5c31af7Sopenharmony_ci << "OpDecorate %gl_TessLevelInner Patch\n" 1960e5c31af7Sopenharmony_ci << "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n"; 1961e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1962e5c31af7Sopenharmony_ci { 1963e5c31af7Sopenharmony_ci shader << getUnusedDecorations(ctx.variableLocation); 1964e5c31af7Sopenharmony_ci } 1965e5c31af7Sopenharmony_ci 1966e5c31af7Sopenharmony_ci // Standard types, constants and arrays. 1967e5c31af7Sopenharmony_ci shader << "; Start of standard types, constants and arrays\n" 1968e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_TYPES 1969e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_CONSTANTS 1970e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_ARRAYS 1971e5c31af7Sopenharmony_ci << "; End of standard types, constants and arrays\n"; 1972e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1973e5c31af7Sopenharmony_ci { 1974e5c31af7Sopenharmony_ci shader << getUnusedTypesAndConstants(); 1975e5c31af7Sopenharmony_ci } 1976e5c31af7Sopenharmony_ci 1977e5c31af7Sopenharmony_ci // Variables. 1978e5c31af7Sopenharmony_ci shader << "%out_color = OpVariable %op_a3v4f32 Output\n" 1979e5c31af7Sopenharmony_ci << "%gl_InvocationID = OpVariable %ip_i32 Input\n" 1980e5c31af7Sopenharmony_ci << "%in_color = OpVariable %ip_a32v4f32 Input\n" 1981e5c31af7Sopenharmony_ci << "%out_position = OpVariable %op_a3v4f32 Output\n" 1982e5c31af7Sopenharmony_ci << "%in_position = OpVariable %ip_a32v4f32 Input\n" 1983e5c31af7Sopenharmony_ci << "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n" 1984e5c31af7Sopenharmony_ci << "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n"; 1985e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 1986e5c31af7Sopenharmony_ci { 1987e5c31af7Sopenharmony_ci shader << getUnusedBuffer(); 1988e5c31af7Sopenharmony_ci } 1989e5c31af7Sopenharmony_ci 1990e5c31af7Sopenharmony_ci // Main entry point. 1991e5c31af7Sopenharmony_ci shader << "%tessc1_main = OpFunction %void None %voidf\n" 1992e5c31af7Sopenharmony_ci << "%tessc1_label = OpLabel\n" 1993e5c31af7Sopenharmony_ci << "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n" 1994e5c31af7Sopenharmony_ci << "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n" 1995e5c31af7Sopenharmony_ci << "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n" 1996e5c31af7Sopenharmony_ci << "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n" 1997e5c31af7Sopenharmony_ci << "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n" 1998e5c31af7Sopenharmony_ci << "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n" 1999e5c31af7Sopenharmony_ci << "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n" 2000e5c31af7Sopenharmony_ci << "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n" 2001e5c31af7Sopenharmony_ci << "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n" 2002e5c31af7Sopenharmony_ci << "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n" 2003e5c31af7Sopenharmony_ci << "OpSelectionMerge %tessc1_merge_label None\n" 2004e5c31af7Sopenharmony_ci << "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n" 2005e5c31af7Sopenharmony_ci << "%tessc1_first_invocation = OpLabel\n" 2006e5c31af7Sopenharmony_ci << "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n" 2007e5c31af7Sopenharmony_ci << "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n" 2008e5c31af7Sopenharmony_ci << "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n" 2009e5c31af7Sopenharmony_ci << "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n" 2010e5c31af7Sopenharmony_ci << "OpStore %tessc1_tess_outer_0 %c_f32_1\n" 2011e5c31af7Sopenharmony_ci << "OpStore %tessc1_tess_outer_1 %c_f32_1\n" 2012e5c31af7Sopenharmony_ci << "OpStore %tessc1_tess_outer_2 %c_f32_1\n" 2013e5c31af7Sopenharmony_ci << "OpStore %tessc1_tess_inner %c_f32_1\n" 2014e5c31af7Sopenharmony_ci << "OpBranch %tessc1_merge_label\n" 2015e5c31af7Sopenharmony_ci << "%tessc1_merge_label = OpLabel\n" 2016e5c31af7Sopenharmony_ci << "OpReturn\n" 2017e5c31af7Sopenharmony_ci << "OpFunctionEnd\n"; 2018e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 2019e5c31af7Sopenharmony_ci { 2020e5c31af7Sopenharmony_ci shader << getUnusedFunctionBody(); 2021e5c31af7Sopenharmony_ci } 2022e5c31af7Sopenharmony_ci 2023e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tessc") << shader.str(); 2024e5c31af7Sopenharmony_ci } 2025e5c31af7Sopenharmony_ci 2026e5c31af7Sopenharmony_ci if (ctx.shaderTasks[SHADER_TASK_INDEX_TESS_EVAL] != SHADER_TASK_NONE) 2027e5c31af7Sopenharmony_ci { 2028e5c31af7Sopenharmony_ci const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_TESS_EVAL]; 2029e5c31af7Sopenharmony_ci std::ostringstream shader; 2030e5c31af7Sopenharmony_ci 2031e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 2032e5c31af7Sopenharmony_ci { 2033e5c31af7Sopenharmony_ci shader << getOpCapabilityShader(); 2034e5c31af7Sopenharmony_ci } 2035e5c31af7Sopenharmony_ci shader << "OpCapability Tessellation\n" 2036e5c31af7Sopenharmony_ci << "OpMemoryModel Logical GLSL450\n"; 2037e5c31af7Sopenharmony_ci 2038e5c31af7Sopenharmony_ci // Entry point. 2039e5c31af7Sopenharmony_ci shader << "OpEntryPoint TessellationEvaluation %tesse1_main \"main\" %stream %gl_tessCoord %in_position %out_color %in_color \n"; 2040e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 2041e5c31af7Sopenharmony_ci { 2042e5c31af7Sopenharmony_ci shader << getUnusedEntryPoint(); 2043e5c31af7Sopenharmony_ci } 2044e5c31af7Sopenharmony_ci shader << "OpExecutionMode %tesse1_main Triangles\n" 2045e5c31af7Sopenharmony_ci << "OpExecutionMode %tesse1_main SpacingEqual\n" 2046e5c31af7Sopenharmony_ci << "OpExecutionMode %tesse1_main VertexOrderCcw\n"; 2047e5c31af7Sopenharmony_ci 2048e5c31af7Sopenharmony_ci // Decorations. 2049e5c31af7Sopenharmony_ci shader << "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n" 2050e5c31af7Sopenharmony_ci << "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n" 2051e5c31af7Sopenharmony_ci << "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n" 2052e5c31af7Sopenharmony_ci << "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n" 2053e5c31af7Sopenharmony_ci << "OpDecorate %per_vertex_out Block\n" 2054e5c31af7Sopenharmony_ci << "OpDecorate %gl_tessCoord BuiltIn TessCoord\n" 2055e5c31af7Sopenharmony_ci << "OpDecorate %in_position Location 2\n" 2056e5c31af7Sopenharmony_ci << "OpDecorate %out_color Location 1\n" 2057e5c31af7Sopenharmony_ci << "OpDecorate %in_color Location 1\n"; 2058e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 2059e5c31af7Sopenharmony_ci { 2060e5c31af7Sopenharmony_ci shader << getUnusedDecorations(ctx.variableLocation); 2061e5c31af7Sopenharmony_ci } 2062e5c31af7Sopenharmony_ci 2063e5c31af7Sopenharmony_ci // Standard types, constants and arrays. 2064e5c31af7Sopenharmony_ci shader << "; Start of standard types, constants and arrays\n" 2065e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_TYPES 2066e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_CONSTANTS 2067e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_ARRAYS 2068e5c31af7Sopenharmony_ci << "; End of standard types, constants and arrays\n"; 2069e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 2070e5c31af7Sopenharmony_ci { 2071e5c31af7Sopenharmony_ci shader << getUnusedTypesAndConstants(); 2072e5c31af7Sopenharmony_ci } 2073e5c31af7Sopenharmony_ci 2074e5c31af7Sopenharmony_ci // Variables. 2075e5c31af7Sopenharmony_ci shader << "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 2076e5c31af7Sopenharmony_ci << "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n" 2077e5c31af7Sopenharmony_ci << "%stream = OpVariable %op_per_vertex_out Output\n" 2078e5c31af7Sopenharmony_ci << "%gl_tessCoord = OpVariable %ip_v3f32 Input\n" 2079e5c31af7Sopenharmony_ci << "%in_position = OpVariable %ip_a32v4f32 Input\n" 2080e5c31af7Sopenharmony_ci << "%out_color = OpVariable %op_v4f32 Output\n" 2081e5c31af7Sopenharmony_ci << "%in_color = OpVariable %ip_a32v4f32 Input\n"; 2082e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 2083e5c31af7Sopenharmony_ci { 2084e5c31af7Sopenharmony_ci shader << getUnusedBuffer(); 2085e5c31af7Sopenharmony_ci } 2086e5c31af7Sopenharmony_ci 2087e5c31af7Sopenharmony_ci // Main entry point. 2088e5c31af7Sopenharmony_ci shader << "%tesse1_main = OpFunction %void None %voidf\n" 2089e5c31af7Sopenharmony_ci << "%tesse1_label = OpLabel\n" 2090e5c31af7Sopenharmony_ci << "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n" 2091e5c31af7Sopenharmony_ci << "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n" 2092e5c31af7Sopenharmony_ci << "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n" 2093e5c31af7Sopenharmony_ci << "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n" 2094e5c31af7Sopenharmony_ci << "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n" 2095e5c31af7Sopenharmony_ci << "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n" 2096e5c31af7Sopenharmony_ci << "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n" 2097e5c31af7Sopenharmony_ci << "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n" 2098e5c31af7Sopenharmony_ci << "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n" 2099e5c31af7Sopenharmony_ci << "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n" 2100e5c31af7Sopenharmony_ci << "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n" 2101e5c31af7Sopenharmony_ci << "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n" 2102e5c31af7Sopenharmony_ci << "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n" 2103e5c31af7Sopenharmony_ci << "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n" 2104e5c31af7Sopenharmony_ci << "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n" 2105e5c31af7Sopenharmony_ci << "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n" 2106e5c31af7Sopenharmony_ci << "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n" 2107e5c31af7Sopenharmony_ci << "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n" 2108e5c31af7Sopenharmony_ci << "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n" 2109e5c31af7Sopenharmony_ci << "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n" 2110e5c31af7Sopenharmony_ci << "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n" 2111e5c31af7Sopenharmony_ci << "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n" 2112e5c31af7Sopenharmony_ci << "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n" 2113e5c31af7Sopenharmony_ci << "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n" 2114e5c31af7Sopenharmony_ci << "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n" 2115e5c31af7Sopenharmony_ci << "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n" 2116e5c31af7Sopenharmony_ci << "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n" 2117e5c31af7Sopenharmony_ci << "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n" 2118e5c31af7Sopenharmony_ci << "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n" 2119e5c31af7Sopenharmony_ci << "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n" 2120e5c31af7Sopenharmony_ci << "OpStore %out_color %tesse1_computed_clr\n" 2121e5c31af7Sopenharmony_ci << "OpReturn\n" 2122e5c31af7Sopenharmony_ci << "OpFunctionEnd\n"; 2123e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 2124e5c31af7Sopenharmony_ci { 2125e5c31af7Sopenharmony_ci shader << getUnusedFunctionBody(); 2126e5c31af7Sopenharmony_ci } 2127e5c31af7Sopenharmony_ci 2128e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tesse") << shader.str(); 2129e5c31af7Sopenharmony_ci } 2130e5c31af7Sopenharmony_ci 2131e5c31af7Sopenharmony_ci if (ctx.shaderTasks[SHADER_TASK_INDEX_FRAGMENT] != SHADER_TASK_NONE) 2132e5c31af7Sopenharmony_ci { 2133e5c31af7Sopenharmony_ci const ShaderTask& task = ctx.shaderTasks[SHADER_TASK_INDEX_FRAGMENT]; 2134e5c31af7Sopenharmony_ci std::ostringstream shader; 2135e5c31af7Sopenharmony_ci 2136e5c31af7Sopenharmony_ci shader << "OpCapability Shader\n" 2137e5c31af7Sopenharmony_ci << "OpMemoryModel Logical GLSL450\n"; 2138e5c31af7Sopenharmony_ci 2139e5c31af7Sopenharmony_ci // Entry point. 2140e5c31af7Sopenharmony_ci shader << "OpEntryPoint Fragment %main \"main\" %vtxColor %fragColor\n"; 2141e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 2142e5c31af7Sopenharmony_ci { 2143e5c31af7Sopenharmony_ci shader << getUnusedEntryPoint(); 2144e5c31af7Sopenharmony_ci } 2145e5c31af7Sopenharmony_ci shader << "OpExecutionMode %main OriginUpperLeft\n"; 2146e5c31af7Sopenharmony_ci 2147e5c31af7Sopenharmony_ci // Decorations. 2148e5c31af7Sopenharmony_ci shader << "OpDecorate %fragColor Location 0\n" 2149e5c31af7Sopenharmony_ci << "OpDecorate %vtxColor Location 1\n"; 2150e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 2151e5c31af7Sopenharmony_ci { 2152e5c31af7Sopenharmony_ci shader << getUnusedDecorations(ctx.variableLocation); 2153e5c31af7Sopenharmony_ci } 2154e5c31af7Sopenharmony_ci 2155e5c31af7Sopenharmony_ci // Standard types, constants and arrays. 2156e5c31af7Sopenharmony_ci shader << "; Start of standard types, constants and arrays\n" 2157e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_TYPES 2158e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_CONSTANTS 2159e5c31af7Sopenharmony_ci << SPIRV_ASSEMBLY_ARRAYS 2160e5c31af7Sopenharmony_ci << "; End of standard types, constants and arrays\n"; 2161e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 2162e5c31af7Sopenharmony_ci { 2163e5c31af7Sopenharmony_ci shader << getUnusedTypesAndConstants(); 2164e5c31af7Sopenharmony_ci } 2165e5c31af7Sopenharmony_ci 2166e5c31af7Sopenharmony_ci // Variables. 2167e5c31af7Sopenharmony_ci shader << "%fragColor = OpVariable %op_v4f32 Output\n" 2168e5c31af7Sopenharmony_ci << "%vtxColor = OpVariable %ip_v4f32 Input\n"; 2169e5c31af7Sopenharmony_ci if (task != SHADER_TASK_NORMAL) 2170e5c31af7Sopenharmony_ci { 2171e5c31af7Sopenharmony_ci shader << getUnusedBuffer(); 2172e5c31af7Sopenharmony_ci } 2173e5c31af7Sopenharmony_ci 2174e5c31af7Sopenharmony_ci // Main entry point. 2175e5c31af7Sopenharmony_ci shader << "%main = OpFunction %void None %voidf\n" 2176e5c31af7Sopenharmony_ci << "%label_main = OpLabel\n" 2177e5c31af7Sopenharmony_ci << "%tmp1 = OpLoad %v4f32 %vtxColor\n" 2178e5c31af7Sopenharmony_ci << "OpStore %fragColor %tmp1\n" 2179e5c31af7Sopenharmony_ci << "OpReturn\n" 2180e5c31af7Sopenharmony_ci << "OpFunctionEnd\n"; 2181e5c31af7Sopenharmony_ci if (task == SHADER_TASK_UNUSED_FUNC) 2182e5c31af7Sopenharmony_ci { 2183e5c31af7Sopenharmony_ci shader << getUnusedFunctionBody(); 2184e5c31af7Sopenharmony_ci } 2185e5c31af7Sopenharmony_ci 2186e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag") << shader.str(); 2187e5c31af7Sopenharmony_ci } 2188e5c31af7Sopenharmony_ci} 2189e5c31af7Sopenharmony_ci 2190e5c31af7Sopenharmony_civoid createMultipleEntries (vk::SourceCollections& dst, InstanceContext) 2191e5c31af7Sopenharmony_ci{ 2192e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("vert") << 2193e5c31af7Sopenharmony_ci // This module contains 2 vertex shaders. One that is a passthrough 2194e5c31af7Sopenharmony_ci // and a second that inverts the color of the output (1.0 - color). 2195e5c31af7Sopenharmony_ci "OpCapability Shader\n" 2196e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 2197e5c31af7Sopenharmony_ci "OpEntryPoint Vertex %main \"vert1\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n" 2198e5c31af7Sopenharmony_ci "OpEntryPoint Vertex %main2 \"vert2\" %Position %vtxColor %color %vtxPosition %vertex_id %instance_id\n" 2199e5c31af7Sopenharmony_ci 2200e5c31af7Sopenharmony_ci "OpDecorate %vtxPosition Location 2\n" 2201e5c31af7Sopenharmony_ci "OpDecorate %Position Location 0\n" 2202e5c31af7Sopenharmony_ci "OpDecorate %vtxColor Location 1\n" 2203e5c31af7Sopenharmony_ci "OpDecorate %color Location 1\n" 2204e5c31af7Sopenharmony_ci "OpDecorate %vertex_id BuiltIn VertexIndex\n" 2205e5c31af7Sopenharmony_ci "OpDecorate %instance_id BuiltIn InstanceIndex\n" 2206e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 2207e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 2208e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 2209e5c31af7Sopenharmony_ci "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n" 2210e5c31af7Sopenharmony_ci "%vtxPosition = OpVariable %op_v4f32 Output\n" 2211e5c31af7Sopenharmony_ci "%Position = OpVariable %ip_v4f32 Input\n" 2212e5c31af7Sopenharmony_ci "%vtxColor = OpVariable %op_v4f32 Output\n" 2213e5c31af7Sopenharmony_ci "%color = OpVariable %ip_v4f32 Input\n" 2214e5c31af7Sopenharmony_ci "%vertex_id = OpVariable %ip_i32 Input\n" 2215e5c31af7Sopenharmony_ci "%instance_id = OpVariable %ip_i32 Input\n" 2216e5c31af7Sopenharmony_ci 2217e5c31af7Sopenharmony_ci "%main = OpFunction %void None %voidf\n" 2218e5c31af7Sopenharmony_ci "%label = OpLabel\n" 2219e5c31af7Sopenharmony_ci "%tmp_position = OpLoad %v4f32 %Position\n" 2220e5c31af7Sopenharmony_ci "OpStore %vtxPosition %tmp_position\n" 2221e5c31af7Sopenharmony_ci "%tmp_color = OpLoad %v4f32 %color\n" 2222e5c31af7Sopenharmony_ci "OpStore %vtxColor %tmp_color\n" 2223e5c31af7Sopenharmony_ci "OpReturn\n" 2224e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 2225e5c31af7Sopenharmony_ci 2226e5c31af7Sopenharmony_ci "%main2 = OpFunction %void None %voidf\n" 2227e5c31af7Sopenharmony_ci "%label2 = OpLabel\n" 2228e5c31af7Sopenharmony_ci "%tmp_position2 = OpLoad %v4f32 %Position\n" 2229e5c31af7Sopenharmony_ci "OpStore %vtxPosition %tmp_position2\n" 2230e5c31af7Sopenharmony_ci "%tmp_color2 = OpLoad %v4f32 %color\n" 2231e5c31af7Sopenharmony_ci "%tmp_color3 = OpFSub %v4f32 %cval %tmp_color2\n" 2232e5c31af7Sopenharmony_ci "%tmp_color4 = OpVectorInsertDynamic %v4f32 %tmp_color3 %c_f32_1 %c_i32_3\n" 2233e5c31af7Sopenharmony_ci "OpStore %vtxColor %tmp_color4\n" 2234e5c31af7Sopenharmony_ci "OpReturn\n" 2235e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 2236e5c31af7Sopenharmony_ci 2237e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("frag") << 2238e5c31af7Sopenharmony_ci // This is a single module that contains 2 fragment shaders. 2239e5c31af7Sopenharmony_ci // One that passes color through and the other that inverts the output 2240e5c31af7Sopenharmony_ci // color (1.0 - color). 2241e5c31af7Sopenharmony_ci "OpCapability Shader\n" 2242e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 2243e5c31af7Sopenharmony_ci "OpEntryPoint Fragment %main \"frag1\" %vtxColor %fragColor\n" 2244e5c31af7Sopenharmony_ci "OpEntryPoint Fragment %main2 \"frag2\" %vtxColor %fragColor\n" 2245e5c31af7Sopenharmony_ci "OpExecutionMode %main OriginUpperLeft\n" 2246e5c31af7Sopenharmony_ci "OpExecutionMode %main2 OriginUpperLeft\n" 2247e5c31af7Sopenharmony_ci 2248e5c31af7Sopenharmony_ci "OpDecorate %fragColor Location 0\n" 2249e5c31af7Sopenharmony_ci "OpDecorate %vtxColor Location 1\n" 2250e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 2251e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 2252e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 2253e5c31af7Sopenharmony_ci "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n" 2254e5c31af7Sopenharmony_ci "%fragColor = OpVariable %op_v4f32 Output\n" 2255e5c31af7Sopenharmony_ci "%vtxColor = OpVariable %ip_v4f32 Input\n" 2256e5c31af7Sopenharmony_ci 2257e5c31af7Sopenharmony_ci "%main = OpFunction %void None %voidf\n" 2258e5c31af7Sopenharmony_ci "%label_main = OpLabel\n" 2259e5c31af7Sopenharmony_ci "%tmp1 = OpLoad %v4f32 %vtxColor\n" 2260e5c31af7Sopenharmony_ci "OpStore %fragColor %tmp1\n" 2261e5c31af7Sopenharmony_ci "OpReturn\n" 2262e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 2263e5c31af7Sopenharmony_ci 2264e5c31af7Sopenharmony_ci "%main2 = OpFunction %void None %voidf\n" 2265e5c31af7Sopenharmony_ci "%label_main2 = OpLabel\n" 2266e5c31af7Sopenharmony_ci "%tmp2 = OpLoad %v4f32 %vtxColor\n" 2267e5c31af7Sopenharmony_ci "%tmp3 = OpFSub %v4f32 %cval %tmp2\n" 2268e5c31af7Sopenharmony_ci "%tmp4 = OpVectorInsertDynamic %v4f32 %tmp3 %c_f32_1 %c_i32_3\n" 2269e5c31af7Sopenharmony_ci "OpStore %fragColor %tmp4\n" 2270e5c31af7Sopenharmony_ci "OpReturn\n" 2271e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 2272e5c31af7Sopenharmony_ci 2273e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("geom") << 2274e5c31af7Sopenharmony_ci "OpCapability Geometry\n" 2275e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 2276e5c31af7Sopenharmony_ci "OpEntryPoint Geometry %geom1_main \"geom1\" %out_gl_position %gl_in %out_color %in_color\n" 2277e5c31af7Sopenharmony_ci "OpEntryPoint Geometry %geom2_main \"geom2\" %out_gl_position %gl_in %out_color %in_color\n" 2278e5c31af7Sopenharmony_ci "OpExecutionMode %geom1_main Triangles\n" 2279e5c31af7Sopenharmony_ci "OpExecutionMode %geom2_main Triangles\n" 2280e5c31af7Sopenharmony_ci "OpExecutionMode %geom1_main OutputTriangleStrip\n" 2281e5c31af7Sopenharmony_ci "OpExecutionMode %geom2_main OutputTriangleStrip\n" 2282e5c31af7Sopenharmony_ci "OpExecutionMode %geom1_main OutputVertices 3\n" 2283e5c31af7Sopenharmony_ci "OpExecutionMode %geom2_main OutputVertices 3\n" 2284e5c31af7Sopenharmony_ci "OpExecutionMode %geom1_main Invocations 1\n" 2285e5c31af7Sopenharmony_ci "OpExecutionMode %geom2_main Invocations 1\n" 2286e5c31af7Sopenharmony_ci "OpDecorate %out_gl_position BuiltIn Position\n" 2287e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_in 0 BuiltIn Position\n" 2288e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_in 1 BuiltIn PointSize\n" 2289e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_in 2 BuiltIn ClipDistance\n" 2290e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_in 3 BuiltIn CullDistance\n" 2291e5c31af7Sopenharmony_ci "OpDecorate %per_vertex_in Block\n" 2292e5c31af7Sopenharmony_ci "OpDecorate %out_color Location 1\n" 2293e5c31af7Sopenharmony_ci "OpDecorate %in_color Location 1\n" 2294e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 2295e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 2296e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 2297e5c31af7Sopenharmony_ci "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n" 2298e5c31af7Sopenharmony_ci "%per_vertex_in = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 2299e5c31af7Sopenharmony_ci "%a3_per_vertex_in = OpTypeArray %per_vertex_in %c_u32_3\n" 2300e5c31af7Sopenharmony_ci "%ip_a3_per_vertex_in = OpTypePointer Input %a3_per_vertex_in\n" 2301e5c31af7Sopenharmony_ci "%gl_in = OpVariable %ip_a3_per_vertex_in Input\n" 2302e5c31af7Sopenharmony_ci "%out_color = OpVariable %op_v4f32 Output\n" 2303e5c31af7Sopenharmony_ci "%in_color = OpVariable %ip_a3v4f32 Input\n" 2304e5c31af7Sopenharmony_ci "%out_gl_position = OpVariable %op_v4f32 Output\n" 2305e5c31af7Sopenharmony_ci 2306e5c31af7Sopenharmony_ci "%geom1_main = OpFunction %void None %voidf\n" 2307e5c31af7Sopenharmony_ci "%geom1_label = OpLabel\n" 2308e5c31af7Sopenharmony_ci "%geom1_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n" 2309e5c31af7Sopenharmony_ci "%geom1_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n" 2310e5c31af7Sopenharmony_ci "%geom1_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n" 2311e5c31af7Sopenharmony_ci "%geom1_in_position_0 = OpLoad %v4f32 %geom1_gl_in_0_gl_position\n" 2312e5c31af7Sopenharmony_ci "%geom1_in_position_1 = OpLoad %v4f32 %geom1_gl_in_1_gl_position\n" 2313e5c31af7Sopenharmony_ci "%geom1_in_position_2 = OpLoad %v4f32 %geom1_gl_in_2_gl_position \n" 2314e5c31af7Sopenharmony_ci "%geom1_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n" 2315e5c31af7Sopenharmony_ci "%geom1_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n" 2316e5c31af7Sopenharmony_ci "%geom1_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n" 2317e5c31af7Sopenharmony_ci "%geom1_in_color_0 = OpLoad %v4f32 %geom1_in_color_0_ptr\n" 2318e5c31af7Sopenharmony_ci "%geom1_in_color_1 = OpLoad %v4f32 %geom1_in_color_1_ptr\n" 2319e5c31af7Sopenharmony_ci "%geom1_in_color_2 = OpLoad %v4f32 %geom1_in_color_2_ptr\n" 2320e5c31af7Sopenharmony_ci "OpStore %out_gl_position %geom1_in_position_0\n" 2321e5c31af7Sopenharmony_ci "OpStore %out_color %geom1_in_color_0\n" 2322e5c31af7Sopenharmony_ci "OpEmitVertex\n" 2323e5c31af7Sopenharmony_ci "OpStore %out_gl_position %geom1_in_position_1\n" 2324e5c31af7Sopenharmony_ci "OpStore %out_color %geom1_in_color_1\n" 2325e5c31af7Sopenharmony_ci "OpEmitVertex\n" 2326e5c31af7Sopenharmony_ci "OpStore %out_gl_position %geom1_in_position_2\n" 2327e5c31af7Sopenharmony_ci "OpStore %out_color %geom1_in_color_2\n" 2328e5c31af7Sopenharmony_ci "OpEmitVertex\n" 2329e5c31af7Sopenharmony_ci "OpEndPrimitive\n" 2330e5c31af7Sopenharmony_ci "OpReturn\n" 2331e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 2332e5c31af7Sopenharmony_ci 2333e5c31af7Sopenharmony_ci "%geom2_main = OpFunction %void None %voidf\n" 2334e5c31af7Sopenharmony_ci "%geom2_label = OpLabel\n" 2335e5c31af7Sopenharmony_ci "%geom2_gl_in_0_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_0 %c_i32_0\n" 2336e5c31af7Sopenharmony_ci "%geom2_gl_in_1_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_1 %c_i32_0\n" 2337e5c31af7Sopenharmony_ci "%geom2_gl_in_2_gl_position = OpAccessChain %ip_v4f32 %gl_in %c_i32_2 %c_i32_0\n" 2338e5c31af7Sopenharmony_ci "%geom2_in_position_0 = OpLoad %v4f32 %geom2_gl_in_0_gl_position\n" 2339e5c31af7Sopenharmony_ci "%geom2_in_position_1 = OpLoad %v4f32 %geom2_gl_in_1_gl_position\n" 2340e5c31af7Sopenharmony_ci "%geom2_in_position_2 = OpLoad %v4f32 %geom2_gl_in_2_gl_position \n" 2341e5c31af7Sopenharmony_ci "%geom2_in_color_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n" 2342e5c31af7Sopenharmony_ci "%geom2_in_color_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n" 2343e5c31af7Sopenharmony_ci "%geom2_in_color_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n" 2344e5c31af7Sopenharmony_ci "%geom2_in_color_0 = OpLoad %v4f32 %geom2_in_color_0_ptr\n" 2345e5c31af7Sopenharmony_ci "%geom2_in_color_1 = OpLoad %v4f32 %geom2_in_color_1_ptr\n" 2346e5c31af7Sopenharmony_ci "%geom2_in_color_2 = OpLoad %v4f32 %geom2_in_color_2_ptr\n" 2347e5c31af7Sopenharmony_ci "%geom2_transformed_in_color_0 = OpFSub %v4f32 %cval %geom2_in_color_0\n" 2348e5c31af7Sopenharmony_ci "%geom2_transformed_in_color_1 = OpFSub %v4f32 %cval %geom2_in_color_1\n" 2349e5c31af7Sopenharmony_ci "%geom2_transformed_in_color_2 = OpFSub %v4f32 %cval %geom2_in_color_2\n" 2350e5c31af7Sopenharmony_ci "%geom2_transformed_in_color_0_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_0 %c_f32_1 %c_i32_3\n" 2351e5c31af7Sopenharmony_ci "%geom2_transformed_in_color_1_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_1 %c_f32_1 %c_i32_3\n" 2352e5c31af7Sopenharmony_ci "%geom2_transformed_in_color_2_a = OpVectorInsertDynamic %v4f32 %geom2_transformed_in_color_2 %c_f32_1 %c_i32_3\n" 2353e5c31af7Sopenharmony_ci "OpStore %out_gl_position %geom2_in_position_0\n" 2354e5c31af7Sopenharmony_ci "OpStore %out_color %geom2_transformed_in_color_0_a\n" 2355e5c31af7Sopenharmony_ci "OpEmitVertex\n" 2356e5c31af7Sopenharmony_ci "OpStore %out_gl_position %geom2_in_position_1\n" 2357e5c31af7Sopenharmony_ci "OpStore %out_color %geom2_transformed_in_color_1_a\n" 2358e5c31af7Sopenharmony_ci "OpEmitVertex\n" 2359e5c31af7Sopenharmony_ci "OpStore %out_gl_position %geom2_in_position_2\n" 2360e5c31af7Sopenharmony_ci "OpStore %out_color %geom2_transformed_in_color_2_a\n" 2361e5c31af7Sopenharmony_ci "OpEmitVertex\n" 2362e5c31af7Sopenharmony_ci "OpEndPrimitive\n" 2363e5c31af7Sopenharmony_ci "OpReturn\n" 2364e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 2365e5c31af7Sopenharmony_ci 2366e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tessc") << 2367e5c31af7Sopenharmony_ci "OpCapability Tessellation\n" 2368e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 2369e5c31af7Sopenharmony_ci "OpEntryPoint TessellationControl %tessc1_main \"tessc1\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n" 2370e5c31af7Sopenharmony_ci "OpEntryPoint TessellationControl %tessc2_main \"tessc2\" %out_color %gl_InvocationID %in_color %out_position %in_position %gl_TessLevelOuter %gl_TessLevelInner\n" 2371e5c31af7Sopenharmony_ci "OpExecutionMode %tessc1_main OutputVertices 3\n" 2372e5c31af7Sopenharmony_ci "OpExecutionMode %tessc2_main OutputVertices 3\n" 2373e5c31af7Sopenharmony_ci "OpDecorate %out_color Location 1\n" 2374e5c31af7Sopenharmony_ci "OpDecorate %gl_InvocationID BuiltIn InvocationId\n" 2375e5c31af7Sopenharmony_ci "OpDecorate %in_color Location 1\n" 2376e5c31af7Sopenharmony_ci "OpDecorate %out_position Location 2\n" 2377e5c31af7Sopenharmony_ci "OpDecorate %in_position Location 2\n" 2378e5c31af7Sopenharmony_ci "OpDecorate %gl_TessLevelOuter Patch\n" 2379e5c31af7Sopenharmony_ci "OpDecorate %gl_TessLevelOuter BuiltIn TessLevelOuter\n" 2380e5c31af7Sopenharmony_ci "OpDecorate %gl_TessLevelInner Patch\n" 2381e5c31af7Sopenharmony_ci "OpDecorate %gl_TessLevelInner BuiltIn TessLevelInner\n" 2382e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 2383e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 2384e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 2385e5c31af7Sopenharmony_ci "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n" 2386e5c31af7Sopenharmony_ci "%out_color = OpVariable %op_a3v4f32 Output\n" 2387e5c31af7Sopenharmony_ci "%gl_InvocationID = OpVariable %ip_i32 Input\n" 2388e5c31af7Sopenharmony_ci "%in_color = OpVariable %ip_a32v4f32 Input\n" 2389e5c31af7Sopenharmony_ci "%out_position = OpVariable %op_a3v4f32 Output\n" 2390e5c31af7Sopenharmony_ci "%in_position = OpVariable %ip_a32v4f32 Input\n" 2391e5c31af7Sopenharmony_ci "%gl_TessLevelOuter = OpVariable %op_a4f32 Output\n" 2392e5c31af7Sopenharmony_ci "%gl_TessLevelInner = OpVariable %op_a2f32 Output\n" 2393e5c31af7Sopenharmony_ci 2394e5c31af7Sopenharmony_ci "%tessc1_main = OpFunction %void None %voidf\n" 2395e5c31af7Sopenharmony_ci "%tessc1_label = OpLabel\n" 2396e5c31af7Sopenharmony_ci "%tessc1_invocation_id = OpLoad %i32 %gl_InvocationID\n" 2397e5c31af7Sopenharmony_ci "%tessc1_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc1_invocation_id\n" 2398e5c31af7Sopenharmony_ci "%tessc1_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc1_invocation_id\n" 2399e5c31af7Sopenharmony_ci "%tessc1_in_color_val = OpLoad %v4f32 %tessc1_in_color_ptr\n" 2400e5c31af7Sopenharmony_ci "%tessc1_in_position_val = OpLoad %v4f32 %tessc1_in_position_ptr\n" 2401e5c31af7Sopenharmony_ci "%tessc1_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc1_invocation_id\n" 2402e5c31af7Sopenharmony_ci "%tessc1_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc1_invocation_id\n" 2403e5c31af7Sopenharmony_ci "OpStore %tessc1_out_color_ptr %tessc1_in_color_val\n" 2404e5c31af7Sopenharmony_ci "OpStore %tessc1_out_position_ptr %tessc1_in_position_val\n" 2405e5c31af7Sopenharmony_ci "%tessc1_is_first_invocation = OpIEqual %bool %tessc1_invocation_id %c_i32_0\n" 2406e5c31af7Sopenharmony_ci "OpSelectionMerge %tessc1_merge_label None\n" 2407e5c31af7Sopenharmony_ci "OpBranchConditional %tessc1_is_first_invocation %tessc1_first_invocation %tessc1_merge_label\n" 2408e5c31af7Sopenharmony_ci "%tessc1_first_invocation = OpLabel\n" 2409e5c31af7Sopenharmony_ci "%tessc1_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n" 2410e5c31af7Sopenharmony_ci "%tessc1_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n" 2411e5c31af7Sopenharmony_ci "%tessc1_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n" 2412e5c31af7Sopenharmony_ci "%tessc1_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n" 2413e5c31af7Sopenharmony_ci "OpStore %tessc1_tess_outer_0 %c_f32_1\n" 2414e5c31af7Sopenharmony_ci "OpStore %tessc1_tess_outer_1 %c_f32_1\n" 2415e5c31af7Sopenharmony_ci "OpStore %tessc1_tess_outer_2 %c_f32_1\n" 2416e5c31af7Sopenharmony_ci "OpStore %tessc1_tess_inner %c_f32_1\n" 2417e5c31af7Sopenharmony_ci "OpBranch %tessc1_merge_label\n" 2418e5c31af7Sopenharmony_ci "%tessc1_merge_label = OpLabel\n" 2419e5c31af7Sopenharmony_ci "OpReturn\n" 2420e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 2421e5c31af7Sopenharmony_ci 2422e5c31af7Sopenharmony_ci "%tessc2_main = OpFunction %void None %voidf\n" 2423e5c31af7Sopenharmony_ci "%tessc2_label = OpLabel\n" 2424e5c31af7Sopenharmony_ci "%tessc2_invocation_id = OpLoad %i32 %gl_InvocationID\n" 2425e5c31af7Sopenharmony_ci "%tessc2_in_color_ptr = OpAccessChain %ip_v4f32 %in_color %tessc2_invocation_id\n" 2426e5c31af7Sopenharmony_ci "%tessc2_in_position_ptr = OpAccessChain %ip_v4f32 %in_position %tessc2_invocation_id\n" 2427e5c31af7Sopenharmony_ci "%tessc2_in_color_val = OpLoad %v4f32 %tessc2_in_color_ptr\n" 2428e5c31af7Sopenharmony_ci "%tessc2_in_position_val = OpLoad %v4f32 %tessc2_in_position_ptr\n" 2429e5c31af7Sopenharmony_ci "%tessc2_out_color_ptr = OpAccessChain %op_v4f32 %out_color %tessc2_invocation_id\n" 2430e5c31af7Sopenharmony_ci "%tessc2_out_position_ptr = OpAccessChain %op_v4f32 %out_position %tessc2_invocation_id\n" 2431e5c31af7Sopenharmony_ci "%tessc2_transformed_color = OpFSub %v4f32 %cval %tessc2_in_color_val\n" 2432e5c31af7Sopenharmony_ci "%tessc2_transformed_color_a = OpVectorInsertDynamic %v4f32 %tessc2_transformed_color %c_f32_1 %c_i32_3\n" 2433e5c31af7Sopenharmony_ci "OpStore %tessc2_out_color_ptr %tessc2_transformed_color_a\n" 2434e5c31af7Sopenharmony_ci "OpStore %tessc2_out_position_ptr %tessc2_in_position_val\n" 2435e5c31af7Sopenharmony_ci "%tessc2_is_first_invocation = OpIEqual %bool %tessc2_invocation_id %c_i32_0\n" 2436e5c31af7Sopenharmony_ci "OpSelectionMerge %tessc2_merge_label None\n" 2437e5c31af7Sopenharmony_ci "OpBranchConditional %tessc2_is_first_invocation %tessc2_first_invocation %tessc2_merge_label\n" 2438e5c31af7Sopenharmony_ci "%tessc2_first_invocation = OpLabel\n" 2439e5c31af7Sopenharmony_ci "%tessc2_tess_outer_0 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_0\n" 2440e5c31af7Sopenharmony_ci "%tessc2_tess_outer_1 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_1\n" 2441e5c31af7Sopenharmony_ci "%tessc2_tess_outer_2 = OpAccessChain %op_f32 %gl_TessLevelOuter %c_i32_2\n" 2442e5c31af7Sopenharmony_ci "%tessc2_tess_inner = OpAccessChain %op_f32 %gl_TessLevelInner %c_i32_0\n" 2443e5c31af7Sopenharmony_ci "OpStore %tessc2_tess_outer_0 %c_f32_1\n" 2444e5c31af7Sopenharmony_ci "OpStore %tessc2_tess_outer_1 %c_f32_1\n" 2445e5c31af7Sopenharmony_ci "OpStore %tessc2_tess_outer_2 %c_f32_1\n" 2446e5c31af7Sopenharmony_ci "OpStore %tessc2_tess_inner %c_f32_1\n" 2447e5c31af7Sopenharmony_ci "OpBranch %tessc2_merge_label\n" 2448e5c31af7Sopenharmony_ci "%tessc2_merge_label = OpLabel\n" 2449e5c31af7Sopenharmony_ci "OpReturn\n" 2450e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 2451e5c31af7Sopenharmony_ci 2452e5c31af7Sopenharmony_ci dst.spirvAsmSources.add("tesse") << 2453e5c31af7Sopenharmony_ci "OpCapability Tessellation\n" 2454e5c31af7Sopenharmony_ci "OpMemoryModel Logical GLSL450\n" 2455e5c31af7Sopenharmony_ci "OpEntryPoint TessellationEvaluation %tesse1_main \"tesse1\" %stream %gl_tessCoord %in_position %out_color %in_color \n" 2456e5c31af7Sopenharmony_ci "OpEntryPoint TessellationEvaluation %tesse2_main \"tesse2\" %stream %gl_tessCoord %in_position %out_color %in_color \n" 2457e5c31af7Sopenharmony_ci "OpExecutionMode %tesse1_main Triangles\n" 2458e5c31af7Sopenharmony_ci "OpExecutionMode %tesse1_main SpacingEqual\n" 2459e5c31af7Sopenharmony_ci "OpExecutionMode %tesse1_main VertexOrderCcw\n" 2460e5c31af7Sopenharmony_ci "OpExecutionMode %tesse2_main Triangles\n" 2461e5c31af7Sopenharmony_ci "OpExecutionMode %tesse2_main SpacingEqual\n" 2462e5c31af7Sopenharmony_ci "OpExecutionMode %tesse2_main VertexOrderCcw\n" 2463e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_out 0 BuiltIn Position\n" 2464e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_out 1 BuiltIn PointSize\n" 2465e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_out 2 BuiltIn ClipDistance\n" 2466e5c31af7Sopenharmony_ci "OpMemberDecorate %per_vertex_out 3 BuiltIn CullDistance\n" 2467e5c31af7Sopenharmony_ci "OpDecorate %per_vertex_out Block\n" 2468e5c31af7Sopenharmony_ci "OpDecorate %gl_tessCoord BuiltIn TessCoord\n" 2469e5c31af7Sopenharmony_ci "OpDecorate %in_position Location 2\n" 2470e5c31af7Sopenharmony_ci "OpDecorate %out_color Location 1\n" 2471e5c31af7Sopenharmony_ci "OpDecorate %in_color Location 1\n" 2472e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_TYPES 2473e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_CONSTANTS 2474e5c31af7Sopenharmony_ci SPIRV_ASSEMBLY_ARRAYS 2475e5c31af7Sopenharmony_ci "%cval = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_0\n" 2476e5c31af7Sopenharmony_ci "%per_vertex_out = OpTypeStruct %v4f32 %f32 %a1f32 %a1f32\n" 2477e5c31af7Sopenharmony_ci "%op_per_vertex_out = OpTypePointer Output %per_vertex_out\n" 2478e5c31af7Sopenharmony_ci "%stream = OpVariable %op_per_vertex_out Output\n" 2479e5c31af7Sopenharmony_ci "%gl_tessCoord = OpVariable %ip_v3f32 Input\n" 2480e5c31af7Sopenharmony_ci "%in_position = OpVariable %ip_a32v4f32 Input\n" 2481e5c31af7Sopenharmony_ci "%out_color = OpVariable %op_v4f32 Output\n" 2482e5c31af7Sopenharmony_ci "%in_color = OpVariable %ip_a32v4f32 Input\n" 2483e5c31af7Sopenharmony_ci 2484e5c31af7Sopenharmony_ci "%tesse1_main = OpFunction %void None %voidf\n" 2485e5c31af7Sopenharmony_ci "%tesse1_label = OpLabel\n" 2486e5c31af7Sopenharmony_ci "%tesse1_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n" 2487e5c31af7Sopenharmony_ci "%tesse1_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n" 2488e5c31af7Sopenharmony_ci "%tesse1_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n" 2489e5c31af7Sopenharmony_ci "%tesse1_tc_0 = OpLoad %f32 %tesse1_tc_0_ptr\n" 2490e5c31af7Sopenharmony_ci "%tesse1_tc_1 = OpLoad %f32 %tesse1_tc_1_ptr\n" 2491e5c31af7Sopenharmony_ci "%tesse1_tc_2 = OpLoad %f32 %tesse1_tc_2_ptr\n" 2492e5c31af7Sopenharmony_ci "%tesse1_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n" 2493e5c31af7Sopenharmony_ci "%tesse1_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n" 2494e5c31af7Sopenharmony_ci "%tesse1_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n" 2495e5c31af7Sopenharmony_ci "%tesse1_in_pos_0 = OpLoad %v4f32 %tesse1_in_pos_0_ptr\n" 2496e5c31af7Sopenharmony_ci "%tesse1_in_pos_1 = OpLoad %v4f32 %tesse1_in_pos_1_ptr\n" 2497e5c31af7Sopenharmony_ci "%tesse1_in_pos_2 = OpLoad %v4f32 %tesse1_in_pos_2_ptr\n" 2498e5c31af7Sopenharmony_ci "%tesse1_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_0 %tesse1_tc_0\n" 2499e5c31af7Sopenharmony_ci "%tesse1_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_1 %tesse1_tc_1\n" 2500e5c31af7Sopenharmony_ci "%tesse1_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_pos_2 %tesse1_tc_2\n" 2501e5c31af7Sopenharmony_ci "%tesse1_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n" 2502e5c31af7Sopenharmony_ci "%tesse1_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse1_in_pos_0_weighted %tesse1_in_pos_1_weighted\n" 2503e5c31af7Sopenharmony_ci "%tesse1_computed_out = OpFAdd %v4f32 %tesse1_in_pos_0_plus_pos_1 %tesse1_in_pos_2_weighted\n" 2504e5c31af7Sopenharmony_ci "OpStore %tesse1_out_pos_ptr %tesse1_computed_out\n" 2505e5c31af7Sopenharmony_ci "%tesse1_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n" 2506e5c31af7Sopenharmony_ci "%tesse1_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n" 2507e5c31af7Sopenharmony_ci "%tesse1_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n" 2508e5c31af7Sopenharmony_ci "%tesse1_in_clr_0 = OpLoad %v4f32 %tesse1_in_clr_0_ptr\n" 2509e5c31af7Sopenharmony_ci "%tesse1_in_clr_1 = OpLoad %v4f32 %tesse1_in_clr_1_ptr\n" 2510e5c31af7Sopenharmony_ci "%tesse1_in_clr_2 = OpLoad %v4f32 %tesse1_in_clr_2_ptr\n" 2511e5c31af7Sopenharmony_ci "%tesse1_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_0 %tesse1_tc_0\n" 2512e5c31af7Sopenharmony_ci "%tesse1_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_1 %tesse1_tc_1\n" 2513e5c31af7Sopenharmony_ci "%tesse1_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse1_in_clr_2 %tesse1_tc_2\n" 2514e5c31af7Sopenharmony_ci "%tesse1_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse1_in_clr_0_weighted %tesse1_in_clr_1_weighted\n" 2515e5c31af7Sopenharmony_ci "%tesse1_computed_clr = OpFAdd %v4f32 %tesse1_in_clr_0_plus_col_1 %tesse1_in_clr_2_weighted\n" 2516e5c31af7Sopenharmony_ci "OpStore %out_color %tesse1_computed_clr\n" 2517e5c31af7Sopenharmony_ci "OpReturn\n" 2518e5c31af7Sopenharmony_ci "OpFunctionEnd\n" 2519e5c31af7Sopenharmony_ci 2520e5c31af7Sopenharmony_ci "%tesse2_main = OpFunction %void None %voidf\n" 2521e5c31af7Sopenharmony_ci "%tesse2_label = OpLabel\n" 2522e5c31af7Sopenharmony_ci "%tesse2_tc_0_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_0\n" 2523e5c31af7Sopenharmony_ci "%tesse2_tc_1_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_1\n" 2524e5c31af7Sopenharmony_ci "%tesse2_tc_2_ptr = OpAccessChain %ip_f32 %gl_tessCoord %c_u32_2\n" 2525e5c31af7Sopenharmony_ci "%tesse2_tc_0 = OpLoad %f32 %tesse2_tc_0_ptr\n" 2526e5c31af7Sopenharmony_ci "%tesse2_tc_1 = OpLoad %f32 %tesse2_tc_1_ptr\n" 2527e5c31af7Sopenharmony_ci "%tesse2_tc_2 = OpLoad %f32 %tesse2_tc_2_ptr\n" 2528e5c31af7Sopenharmony_ci "%tesse2_in_pos_0_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_0\n" 2529e5c31af7Sopenharmony_ci "%tesse2_in_pos_1_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_1\n" 2530e5c31af7Sopenharmony_ci "%tesse2_in_pos_2_ptr = OpAccessChain %ip_v4f32 %in_position %c_i32_2\n" 2531e5c31af7Sopenharmony_ci "%tesse2_in_pos_0 = OpLoad %v4f32 %tesse2_in_pos_0_ptr\n" 2532e5c31af7Sopenharmony_ci "%tesse2_in_pos_1 = OpLoad %v4f32 %tesse2_in_pos_1_ptr\n" 2533e5c31af7Sopenharmony_ci "%tesse2_in_pos_2 = OpLoad %v4f32 %tesse2_in_pos_2_ptr\n" 2534e5c31af7Sopenharmony_ci "%tesse2_in_pos_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_0 %tesse2_tc_0\n" 2535e5c31af7Sopenharmony_ci "%tesse2_in_pos_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_1 %tesse2_tc_1\n" 2536e5c31af7Sopenharmony_ci "%tesse2_in_pos_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_pos_2 %tesse2_tc_2\n" 2537e5c31af7Sopenharmony_ci "%tesse2_out_pos_ptr = OpAccessChain %op_v4f32 %stream %c_i32_0\n" 2538e5c31af7Sopenharmony_ci "%tesse2_in_pos_0_plus_pos_1 = OpFAdd %v4f32 %tesse2_in_pos_0_weighted %tesse2_in_pos_1_weighted\n" 2539e5c31af7Sopenharmony_ci "%tesse2_computed_out = OpFAdd %v4f32 %tesse2_in_pos_0_plus_pos_1 %tesse2_in_pos_2_weighted\n" 2540e5c31af7Sopenharmony_ci "OpStore %tesse2_out_pos_ptr %tesse2_computed_out\n" 2541e5c31af7Sopenharmony_ci "%tesse2_in_clr_0_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_0\n" 2542e5c31af7Sopenharmony_ci "%tesse2_in_clr_1_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_1\n" 2543e5c31af7Sopenharmony_ci "%tesse2_in_clr_2_ptr = OpAccessChain %ip_v4f32 %in_color %c_i32_2\n" 2544e5c31af7Sopenharmony_ci "%tesse2_in_clr_0 = OpLoad %v4f32 %tesse2_in_clr_0_ptr\n" 2545e5c31af7Sopenharmony_ci "%tesse2_in_clr_1 = OpLoad %v4f32 %tesse2_in_clr_1_ptr\n" 2546e5c31af7Sopenharmony_ci "%tesse2_in_clr_2 = OpLoad %v4f32 %tesse2_in_clr_2_ptr\n" 2547e5c31af7Sopenharmony_ci "%tesse2_in_clr_0_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_0 %tesse2_tc_0\n" 2548e5c31af7Sopenharmony_ci "%tesse2_in_clr_1_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_1 %tesse2_tc_1\n" 2549e5c31af7Sopenharmony_ci "%tesse2_in_clr_2_weighted = OpVectorTimesScalar %v4f32 %tesse2_in_clr_2 %tesse2_tc_2\n" 2550e5c31af7Sopenharmony_ci "%tesse2_in_clr_0_plus_col_1 = OpFAdd %v4f32 %tesse2_in_clr_0_weighted %tesse2_in_clr_1_weighted\n" 2551e5c31af7Sopenharmony_ci "%tesse2_computed_clr = OpFAdd %v4f32 %tesse2_in_clr_0_plus_col_1 %tesse2_in_clr_2_weighted\n" 2552e5c31af7Sopenharmony_ci "%tesse2_clr_transformed = OpFSub %v4f32 %cval %tesse2_computed_clr\n" 2553e5c31af7Sopenharmony_ci "%tesse2_clr_transformed_a = OpVectorInsertDynamic %v4f32 %tesse2_clr_transformed %c_f32_1 %c_i32_3\n" 2554e5c31af7Sopenharmony_ci "OpStore %out_color %tesse2_clr_transformed_a\n" 2555e5c31af7Sopenharmony_ci "OpReturn\n" 2556e5c31af7Sopenharmony_ci "OpFunctionEnd\n"; 2557e5c31af7Sopenharmony_ci} 2558e5c31af7Sopenharmony_ci 2559e5c31af7Sopenharmony_cibool compare16BitFloat (float original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log) 2560e5c31af7Sopenharmony_ci{ 2561e5c31af7Sopenharmony_ci // We only support RTE, RTZ, or both. 2562e5c31af7Sopenharmony_ci DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4); 2563e5c31af7Sopenharmony_ci 2564e5c31af7Sopenharmony_ci const Float32 originalFloat (original); 2565e5c31af7Sopenharmony_ci const Float16 returnedFloat (returned); 2566e5c31af7Sopenharmony_ci 2567e5c31af7Sopenharmony_ci // Zero are turned into zero under both RTE and RTZ. 2568e5c31af7Sopenharmony_ci if (originalFloat.isZero()) 2569e5c31af7Sopenharmony_ci { 2570e5c31af7Sopenharmony_ci if (returnedFloat.isZero()) 2571e5c31af7Sopenharmony_ci return true; 2572e5c31af7Sopenharmony_ci 2573e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage; 2574e5c31af7Sopenharmony_ci return false; 2575e5c31af7Sopenharmony_ci } 2576e5c31af7Sopenharmony_ci 2577e5c31af7Sopenharmony_ci // Any denormalized value input into a shader may be flushed to 0. 2578e5c31af7Sopenharmony_ci if (originalFloat.isDenorm() && returnedFloat.isZero()) 2579e5c31af7Sopenharmony_ci return true; 2580e5c31af7Sopenharmony_ci 2581e5c31af7Sopenharmony_ci // Inf are always turned into Inf with the same sign, too. 2582e5c31af7Sopenharmony_ci if (originalFloat.isInf()) 2583e5c31af7Sopenharmony_ci { 2584e5c31af7Sopenharmony_ci if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit()) 2585e5c31af7Sopenharmony_ci return true; 2586e5c31af7Sopenharmony_ci 2587e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage; 2588e5c31af7Sopenharmony_ci return false; 2589e5c31af7Sopenharmony_ci } 2590e5c31af7Sopenharmony_ci 2591e5c31af7Sopenharmony_ci // NaN are always turned into NaN, too. 2592e5c31af7Sopenharmony_ci if (originalFloat.isNaN()) 2593e5c31af7Sopenharmony_ci { 2594e5c31af7Sopenharmony_ci if (returnedFloat.isNaN()) 2595e5c31af7Sopenharmony_ci return true; 2596e5c31af7Sopenharmony_ci 2597e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage; 2598e5c31af7Sopenharmony_ci return false; 2599e5c31af7Sopenharmony_ci } 2600e5c31af7Sopenharmony_ci 2601e5c31af7Sopenharmony_ci // Check all rounding modes 2602e5c31af7Sopenharmony_ci for (int bitNdx = 0; bitNdx < 2; ++bitNdx) 2603e5c31af7Sopenharmony_ci { 2604e5c31af7Sopenharmony_ci if ((flags & (1u << bitNdx)) == 0) 2605e5c31af7Sopenharmony_ci continue; // This rounding mode is not selected. 2606e5c31af7Sopenharmony_ci 2607e5c31af7Sopenharmony_ci const Float16 expectedFloat (deFloat32To16Round(original, deRoundingMode(bitNdx))); 2608e5c31af7Sopenharmony_ci 2609e5c31af7Sopenharmony_ci // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0. 2610e5c31af7Sopenharmony_ci if (expectedFloat.isDenorm() && returnedFloat.isZero()) 2611e5c31af7Sopenharmony_ci return true; 2612e5c31af7Sopenharmony_ci 2613e5c31af7Sopenharmony_ci // If not matched in the above cases, they should have the same bit pattern. 2614e5c31af7Sopenharmony_ci if (expectedFloat.bits() == returnedFloat.bits()) 2615e5c31af7Sopenharmony_ci return true; 2616e5c31af7Sopenharmony_ci } 2617e5c31af7Sopenharmony_ci 2618e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: found unmatched 32-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage; 2619e5c31af7Sopenharmony_ci return false; 2620e5c31af7Sopenharmony_ci} 2621e5c31af7Sopenharmony_ci 2622e5c31af7Sopenharmony_cibool compare16BitFloat (deUint16 original, deUint16 returned, tcu::TestLog& log) 2623e5c31af7Sopenharmony_ci{ 2624e5c31af7Sopenharmony_ci const Float16 originalFloat (original); 2625e5c31af7Sopenharmony_ci const Float16 returnedFloat (returned); 2626e5c31af7Sopenharmony_ci 2627e5c31af7Sopenharmony_ci if (originalFloat.isZero()) 2628e5c31af7Sopenharmony_ci { 2629e5c31af7Sopenharmony_ci if (returnedFloat.isZero()) 2630e5c31af7Sopenharmony_ci return true; 2631e5c31af7Sopenharmony_ci 2632e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage; 2633e5c31af7Sopenharmony_ci return false; 2634e5c31af7Sopenharmony_ci } 2635e5c31af7Sopenharmony_ci 2636e5c31af7Sopenharmony_ci // Any denormalized value input into a shader or potentially generated by any instruction in a shader 2637e5c31af7Sopenharmony_ci // may be flushed to 0. 2638e5c31af7Sopenharmony_ci if (originalFloat.isDenorm() && returnedFloat.isZero()) 2639e5c31af7Sopenharmony_ci return true; 2640e5c31af7Sopenharmony_ci 2641e5c31af7Sopenharmony_ci // Inf are always turned into Inf with the same sign, too. 2642e5c31af7Sopenharmony_ci if (originalFloat.isInf()) 2643e5c31af7Sopenharmony_ci { 2644e5c31af7Sopenharmony_ci if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit()) 2645e5c31af7Sopenharmony_ci return true; 2646e5c31af7Sopenharmony_ci 2647e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage; 2648e5c31af7Sopenharmony_ci return false; 2649e5c31af7Sopenharmony_ci } 2650e5c31af7Sopenharmony_ci 2651e5c31af7Sopenharmony_ci // NaN are always turned into NaN, too. 2652e5c31af7Sopenharmony_ci if (originalFloat.isNaN()) 2653e5c31af7Sopenharmony_ci { 2654e5c31af7Sopenharmony_ci if (returnedFloat.isNaN()) 2655e5c31af7Sopenharmony_ci return true; 2656e5c31af7Sopenharmony_ci 2657e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage; 2658e5c31af7Sopenharmony_ci return false; 2659e5c31af7Sopenharmony_ci } 2660e5c31af7Sopenharmony_ci 2661e5c31af7Sopenharmony_ci // If not matched in the above cases, they should have the same bit pattern. 2662e5c31af7Sopenharmony_ci if (originalFloat.bits() == returnedFloat.bits()) 2663e5c31af7Sopenharmony_ci return true; 2664e5c31af7Sopenharmony_ci 2665e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: found unmatched 16-bit and 16-bit floats: " << original << " vs " << returned << TestLog::EndMessage; 2666e5c31af7Sopenharmony_ci return false; 2667e5c31af7Sopenharmony_ci} 2668e5c31af7Sopenharmony_ci 2669e5c31af7Sopenharmony_cibool compare16BitFloat(deUint16 original, float returned, tcu::TestLog & log) 2670e5c31af7Sopenharmony_ci{ 2671e5c31af7Sopenharmony_ci const Float16 originalFloat (original); 2672e5c31af7Sopenharmony_ci const Float32 returnedFloat (returned); 2673e5c31af7Sopenharmony_ci 2674e5c31af7Sopenharmony_ci // Zero are turned into zero under both RTE and RTZ. 2675e5c31af7Sopenharmony_ci if (originalFloat.isZero()) 2676e5c31af7Sopenharmony_ci { 2677e5c31af7Sopenharmony_ci if (returnedFloat.isZero()) 2678e5c31af7Sopenharmony_ci return true; 2679e5c31af7Sopenharmony_ci 2680e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage; 2681e5c31af7Sopenharmony_ci return false; 2682e5c31af7Sopenharmony_ci } 2683e5c31af7Sopenharmony_ci 2684e5c31af7Sopenharmony_ci // Any denormalized value input into a shader may be flushed to 0. 2685e5c31af7Sopenharmony_ci if (originalFloat.isDenorm() && returnedFloat.isZero()) 2686e5c31af7Sopenharmony_ci return true; 2687e5c31af7Sopenharmony_ci 2688e5c31af7Sopenharmony_ci // Inf are always turned into Inf with the same sign, too. 2689e5c31af7Sopenharmony_ci if (originalFloat.isInf()) 2690e5c31af7Sopenharmony_ci { 2691e5c31af7Sopenharmony_ci if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit()) 2692e5c31af7Sopenharmony_ci return true; 2693e5c31af7Sopenharmony_ci 2694e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage; 2695e5c31af7Sopenharmony_ci return false; 2696e5c31af7Sopenharmony_ci } 2697e5c31af7Sopenharmony_ci 2698e5c31af7Sopenharmony_ci // NaN are always turned into NaN, too. 2699e5c31af7Sopenharmony_ci if (originalFloat.isNaN()) 2700e5c31af7Sopenharmony_ci { 2701e5c31af7Sopenharmony_ci if (returnedFloat.isNaN()) 2702e5c31af7Sopenharmony_ci return true; 2703e5c31af7Sopenharmony_ci 2704e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage; 2705e5c31af7Sopenharmony_ci return false; 2706e5c31af7Sopenharmony_ci } 2707e5c31af7Sopenharmony_ci 2708e5c31af7Sopenharmony_ci // In all other cases, conversion should be exact. 2709e5c31af7Sopenharmony_ci const Float32 expectedFloat (deFloat16To32(original)); 2710e5c31af7Sopenharmony_ci if (expectedFloat.bits() == returnedFloat.bits()) 2711e5c31af7Sopenharmony_ci return true; 2712e5c31af7Sopenharmony_ci 2713e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: found unmatched 16-bit and 32-bit floats: " << original << " vs " << returnedFloat.bits() << TestLog::EndMessage; 2714e5c31af7Sopenharmony_ci return false; 2715e5c31af7Sopenharmony_ci} 2716e5c31af7Sopenharmony_ci 2717e5c31af7Sopenharmony_cibool compare16BitFloat (deFloat16 original, deFloat16 returned, std::string& error) 2718e5c31af7Sopenharmony_ci{ 2719e5c31af7Sopenharmony_ci std::ostringstream log; 2720e5c31af7Sopenharmony_ci const Float16 originalFloat (original); 2721e5c31af7Sopenharmony_ci const Float16 returnedFloat (returned); 2722e5c31af7Sopenharmony_ci 2723e5c31af7Sopenharmony_ci if (originalFloat.isZero()) 2724e5c31af7Sopenharmony_ci { 2725e5c31af7Sopenharmony_ci if (returnedFloat.isZero()) 2726e5c31af7Sopenharmony_ci return true; 2727e5c31af7Sopenharmony_ci 2728e5c31af7Sopenharmony_ci log << "Error: expected zero but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")"; 2729e5c31af7Sopenharmony_ci error = log.str(); 2730e5c31af7Sopenharmony_ci return false; 2731e5c31af7Sopenharmony_ci } 2732e5c31af7Sopenharmony_ci 2733e5c31af7Sopenharmony_ci // Any denormalized value input into a shader may be flushed to 0. 2734e5c31af7Sopenharmony_ci if (originalFloat.isDenorm() && returnedFloat.isZero()) 2735e5c31af7Sopenharmony_ci return true; 2736e5c31af7Sopenharmony_ci 2737e5c31af7Sopenharmony_ci // Inf are always turned into Inf with the same sign, too. 2738e5c31af7Sopenharmony_ci if (originalFloat.isInf()) 2739e5c31af7Sopenharmony_ci { 2740e5c31af7Sopenharmony_ci if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit()) 2741e5c31af7Sopenharmony_ci return true; 2742e5c31af7Sopenharmony_ci 2743e5c31af7Sopenharmony_ci log << "Error: expected Inf but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")"; 2744e5c31af7Sopenharmony_ci error = log.str(); 2745e5c31af7Sopenharmony_ci return false; 2746e5c31af7Sopenharmony_ci } 2747e5c31af7Sopenharmony_ci 2748e5c31af7Sopenharmony_ci // NaN are always turned into NaN, too. 2749e5c31af7Sopenharmony_ci if (originalFloat.isNaN()) 2750e5c31af7Sopenharmony_ci { 2751e5c31af7Sopenharmony_ci if (returnedFloat.isNaN()) 2752e5c31af7Sopenharmony_ci return true; 2753e5c31af7Sopenharmony_ci 2754e5c31af7Sopenharmony_ci log << "Error: expected NaN but returned " << std::hex << "0x" << returned << " (" << returnedFloat.asFloat() << ")"; 2755e5c31af7Sopenharmony_ci error = log.str(); 2756e5c31af7Sopenharmony_ci return false; 2757e5c31af7Sopenharmony_ci } 2758e5c31af7Sopenharmony_ci 2759e5c31af7Sopenharmony_ci // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0. 2760e5c31af7Sopenharmony_ci if (originalFloat.isDenorm() && returnedFloat.isZero()) 2761e5c31af7Sopenharmony_ci return true; 2762e5c31af7Sopenharmony_ci 2763e5c31af7Sopenharmony_ci // If not matched in the above cases, they should have the same bit pattern. 2764e5c31af7Sopenharmony_ci if (originalFloat.bits() == returnedFloat.bits()) 2765e5c31af7Sopenharmony_ci return true; 2766e5c31af7Sopenharmony_ci 2767e5c31af7Sopenharmony_ci log << "Error: found unmatched 16-bit and 16-bit floats: 0x" 2768e5c31af7Sopenharmony_ci << std::hex << original << " <=> 0x" << returned 2769e5c31af7Sopenharmony_ci << " (" << originalFloat.asFloat() << " <=> " << returnedFloat.asFloat() << ")"; 2770e5c31af7Sopenharmony_ci error = log.str(); 2771e5c31af7Sopenharmony_ci return false; 2772e5c31af7Sopenharmony_ci} 2773e5c31af7Sopenharmony_ci 2774e5c31af7Sopenharmony_cibool compare16BitFloat64 (double original, deUint16 returned, RoundingModeFlags flags, tcu::TestLog& log) 2775e5c31af7Sopenharmony_ci{ 2776e5c31af7Sopenharmony_ci // We only support RTE, RTZ, or both. 2777e5c31af7Sopenharmony_ci DE_ASSERT(static_cast<int>(flags) > 0 && static_cast<int>(flags) < 4); 2778e5c31af7Sopenharmony_ci 2779e5c31af7Sopenharmony_ci const Float64 originalFloat (original); 2780e5c31af7Sopenharmony_ci const Float16 returnedFloat (returned); 2781e5c31af7Sopenharmony_ci 2782e5c31af7Sopenharmony_ci // Zero are turned into zero under both RTE and RTZ. 2783e5c31af7Sopenharmony_ci if (originalFloat.isZero()) 2784e5c31af7Sopenharmony_ci { 2785e5c31af7Sopenharmony_ci if (returnedFloat.isZero()) 2786e5c31af7Sopenharmony_ci return true; 2787e5c31af7Sopenharmony_ci 2788e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected zero but returned " << returned << TestLog::EndMessage; 2789e5c31af7Sopenharmony_ci return false; 2790e5c31af7Sopenharmony_ci } 2791e5c31af7Sopenharmony_ci 2792e5c31af7Sopenharmony_ci // Any denormalized value input into a shader may be flushed to 0. 2793e5c31af7Sopenharmony_ci if (originalFloat.isDenorm() && returnedFloat.isZero()) 2794e5c31af7Sopenharmony_ci return true; 2795e5c31af7Sopenharmony_ci 2796e5c31af7Sopenharmony_ci // Inf are always turned into Inf with the same sign, too. 2797e5c31af7Sopenharmony_ci if (originalFloat.isInf()) 2798e5c31af7Sopenharmony_ci { 2799e5c31af7Sopenharmony_ci if (returnedFloat.isInf() && originalFloat.signBit() == returnedFloat.signBit()) 2800e5c31af7Sopenharmony_ci return true; 2801e5c31af7Sopenharmony_ci 2802e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected Inf but returned " << returned << TestLog::EndMessage; 2803e5c31af7Sopenharmony_ci return false; 2804e5c31af7Sopenharmony_ci } 2805e5c31af7Sopenharmony_ci 2806e5c31af7Sopenharmony_ci // NaN are always turned into NaN, too. 2807e5c31af7Sopenharmony_ci if (originalFloat.isNaN()) 2808e5c31af7Sopenharmony_ci { 2809e5c31af7Sopenharmony_ci if (returnedFloat.isNaN()) 2810e5c31af7Sopenharmony_ci return true; 2811e5c31af7Sopenharmony_ci 2812e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage; 2813e5c31af7Sopenharmony_ci return false; 2814e5c31af7Sopenharmony_ci } 2815e5c31af7Sopenharmony_ci 2816e5c31af7Sopenharmony_ci // Check all rounding modes 2817e5c31af7Sopenharmony_ci for (int bitNdx = 0; bitNdx < 2; ++bitNdx) 2818e5c31af7Sopenharmony_ci { 2819e5c31af7Sopenharmony_ci if ((flags & (1u << bitNdx)) == 0) 2820e5c31af7Sopenharmony_ci continue; // This rounding mode is not selected. 2821e5c31af7Sopenharmony_ci 2822e5c31af7Sopenharmony_ci const Float16 expectedFloat (deFloat64To16Round(original, deRoundingMode(bitNdx))); 2823e5c31af7Sopenharmony_ci 2824e5c31af7Sopenharmony_ci // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0. 2825e5c31af7Sopenharmony_ci if (expectedFloat.isDenorm() && returnedFloat.isZero()) 2826e5c31af7Sopenharmony_ci return true; 2827e5c31af7Sopenharmony_ci 2828e5c31af7Sopenharmony_ci // If not matched in the above cases, they should have the same bit pattern. 2829e5c31af7Sopenharmony_ci if (expectedFloat.bits() == returnedFloat.bits()) 2830e5c31af7Sopenharmony_ci return true; 2831e5c31af7Sopenharmony_ci } 2832e5c31af7Sopenharmony_ci 2833e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: found unmatched 64-bit and 16-bit floats: " << originalFloat.bits() << " vs " << returned << TestLog::EndMessage; 2834e5c31af7Sopenharmony_ci return false; 2835e5c31af7Sopenharmony_ci} 2836e5c31af7Sopenharmony_ci 2837e5c31af7Sopenharmony_cibool compare32BitFloat (float expected, float returned, tcu::TestLog& log) 2838e5c31af7Sopenharmony_ci{ 2839e5c31af7Sopenharmony_ci const Float32 expectedFloat (expected); 2840e5c31af7Sopenharmony_ci const Float32 returnedFloat (returned); 2841e5c31af7Sopenharmony_ci 2842e5c31af7Sopenharmony_ci // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0. 2843e5c31af7Sopenharmony_ci if (expectedFloat.isDenorm() && returnedFloat.isZero()) 2844e5c31af7Sopenharmony_ci return true; 2845e5c31af7Sopenharmony_ci 2846e5c31af7Sopenharmony_ci { 2847e5c31af7Sopenharmony_ci const Float16 originalFloat (deFloat32To16(expected)); 2848e5c31af7Sopenharmony_ci 2849e5c31af7Sopenharmony_ci // Any denormalized value input into a shader may be flushed to 0. 2850e5c31af7Sopenharmony_ci if (originalFloat.isDenorm() && returnedFloat.isZero()) 2851e5c31af7Sopenharmony_ci return true; 2852e5c31af7Sopenharmony_ci } 2853e5c31af7Sopenharmony_ci 2854e5c31af7Sopenharmony_ci if (expectedFloat.isNaN()) 2855e5c31af7Sopenharmony_ci { 2856e5c31af7Sopenharmony_ci if (returnedFloat.isNaN()) 2857e5c31af7Sopenharmony_ci return true; 2858e5c31af7Sopenharmony_ci 2859e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage; 2860e5c31af7Sopenharmony_ci return false; 2861e5c31af7Sopenharmony_ci } 2862e5c31af7Sopenharmony_ci 2863e5c31af7Sopenharmony_ci if (returned == expected) 2864e5c31af7Sopenharmony_ci return true; 2865e5c31af7Sopenharmony_ci 2866e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: found unmatched 32-bit float: expected " << expectedFloat.bits() << " vs. returned " << returnedFloat.bits() << TestLog::EndMessage; 2867e5c31af7Sopenharmony_ci return false; 2868e5c31af7Sopenharmony_ci} 2869e5c31af7Sopenharmony_ci 2870e5c31af7Sopenharmony_cibool compare64BitFloat (double expected, double returned, tcu::TestLog& log) 2871e5c31af7Sopenharmony_ci{ 2872e5c31af7Sopenharmony_ci const Float64 expectedDouble (expected); 2873e5c31af7Sopenharmony_ci const Float64 returnedDouble (returned); 2874e5c31af7Sopenharmony_ci 2875e5c31af7Sopenharmony_ci // Any denormalized value potentially generated by any instruction in a shader may be flushed to 0. 2876e5c31af7Sopenharmony_ci if (expectedDouble.isDenorm() && returnedDouble.isZero()) 2877e5c31af7Sopenharmony_ci return true; 2878e5c31af7Sopenharmony_ci 2879e5c31af7Sopenharmony_ci { 2880e5c31af7Sopenharmony_ci const Float16 originalDouble (deFloat64To16(expected)); 2881e5c31af7Sopenharmony_ci 2882e5c31af7Sopenharmony_ci // Any denormalized value input into a shader may be flushed to 0. 2883e5c31af7Sopenharmony_ci if (originalDouble.isDenorm() && returnedDouble.isZero()) 2884e5c31af7Sopenharmony_ci return true; 2885e5c31af7Sopenharmony_ci } 2886e5c31af7Sopenharmony_ci 2887e5c31af7Sopenharmony_ci if (expectedDouble.isNaN()) 2888e5c31af7Sopenharmony_ci { 2889e5c31af7Sopenharmony_ci if (returnedDouble.isNaN()) 2890e5c31af7Sopenharmony_ci return true; 2891e5c31af7Sopenharmony_ci 2892e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: expected NaN but returned " << returned << TestLog::EndMessage; 2893e5c31af7Sopenharmony_ci return false; 2894e5c31af7Sopenharmony_ci } 2895e5c31af7Sopenharmony_ci 2896e5c31af7Sopenharmony_ci if (returned == expected) 2897e5c31af7Sopenharmony_ci return true; 2898e5c31af7Sopenharmony_ci 2899e5c31af7Sopenharmony_ci log << TestLog::Message << "Error: found unmatched 64-bit float: expected " << expectedDouble.bits() << " vs. returned " << returnedDouble.bits() << TestLog::EndMessage; 2900e5c31af7Sopenharmony_ci return false; 2901e5c31af7Sopenharmony_ci} 2902e5c31af7Sopenharmony_ci 2903e5c31af7Sopenharmony_ciMove<VkBuffer> createBufferForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, deUint32 queueFamilyIndex) 2904e5c31af7Sopenharmony_ci{ 2905e5c31af7Sopenharmony_ci const vk::VkDescriptorType resourceType = resource.getDescriptorType(); 2906e5c31af7Sopenharmony_ci 2907e5c31af7Sopenharmony_ci vector<deUint8> resourceBytes; 2908e5c31af7Sopenharmony_ci resource.getBytes(resourceBytes); 2909e5c31af7Sopenharmony_ci 2910e5c31af7Sopenharmony_ci const VkBufferCreateInfo resourceBufferParams = 2911e5c31af7Sopenharmony_ci { 2912e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType 2913e5c31af7Sopenharmony_ci DE_NULL, // pNext 2914e5c31af7Sopenharmony_ci (VkBufferCreateFlags)0, // flags 2915e5c31af7Sopenharmony_ci (VkDeviceSize)resourceBytes.size(), // size 2916e5c31af7Sopenharmony_ci (VkBufferUsageFlags)getMatchingBufferUsageFlagBit(resourceType), // usage 2917e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // sharingMode 2918e5c31af7Sopenharmony_ci 1u, // queueFamilyCount 2919e5c31af7Sopenharmony_ci &queueFamilyIndex, // pQueueFamilyIndices 2920e5c31af7Sopenharmony_ci }; 2921e5c31af7Sopenharmony_ci 2922e5c31af7Sopenharmony_ci return createBuffer(vk, vkDevice, &resourceBufferParams); 2923e5c31af7Sopenharmony_ci} 2924e5c31af7Sopenharmony_ci 2925e5c31af7Sopenharmony_ciMove<VkImage> createImageForResource (const DeviceInterface& vk, const VkDevice vkDevice, const Resource& resource, VkFormat inputFormat, deUint32 queueFamilyIndex) 2926e5c31af7Sopenharmony_ci{ 2927e5c31af7Sopenharmony_ci const VkImageCreateInfo resourceImageParams = 2928e5c31af7Sopenharmony_ci { 2929e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 2930e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 2931e5c31af7Sopenharmony_ci 0u, // VkImageCreateFlags flags; 2932e5c31af7Sopenharmony_ci VK_IMAGE_TYPE_2D, // VkImageType imageType; 2933e5c31af7Sopenharmony_ci inputFormat, // VkFormat format; 2934e5c31af7Sopenharmony_ci { 8, 8, 1 }, // VkExtent3D extent; 2935e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 2936e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 2937e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 2938e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 2939e5c31af7Sopenharmony_ci getMatchingImageUsageFlags(resource.getDescriptorType()), // VkImageUsageFlags usage; 2940e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 2941e5c31af7Sopenharmony_ci 1u, // deUint32 queueFamilyCount; 2942e5c31af7Sopenharmony_ci &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 2943e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 2944e5c31af7Sopenharmony_ci }; 2945e5c31af7Sopenharmony_ci 2946e5c31af7Sopenharmony_ci return createImage(vk, vkDevice, &resourceImageParams); 2947e5c31af7Sopenharmony_ci} 2948e5c31af7Sopenharmony_ci 2949e5c31af7Sopenharmony_civoid copyBufferToImage (Context& context, const DeviceInterface& vk, const VkDevice& device, const VkQueue& queue, VkCommandPool cmdPool, VkCommandBuffer cmdBuffer, VkBuffer buffer, VkImage image, VkImageAspectFlags aspect) 2950e5c31af7Sopenharmony_ci{ 2951e5c31af7Sopenharmony_ci const VkBufferImageCopy copyRegion = 2952e5c31af7Sopenharmony_ci { 2953e5c31af7Sopenharmony_ci 0u, // VkDeviceSize bufferOffset; 2954e5c31af7Sopenharmony_ci 0u, // deUint32 bufferRowLength; 2955e5c31af7Sopenharmony_ci 0u, // deUint32 bufferImageHeight; 2956e5c31af7Sopenharmony_ci { 2957e5c31af7Sopenharmony_ci aspect, // VkImageAspectFlags aspect; 2958e5c31af7Sopenharmony_ci 0u, // deUint32 mipLevel; 2959e5c31af7Sopenharmony_ci 0u, // deUint32 baseArrayLayer; 2960e5c31af7Sopenharmony_ci 1u, // deUint32 layerCount; 2961e5c31af7Sopenharmony_ci }, // VkImageSubresourceLayers imageSubresource; 2962e5c31af7Sopenharmony_ci { 0, 0, 0 }, // VkOffset3D imageOffset; 2963e5c31af7Sopenharmony_ci { 8, 8, 1 } // VkExtent3D imageExtent; 2964e5c31af7Sopenharmony_ci }; 2965e5c31af7Sopenharmony_ci 2966e5c31af7Sopenharmony_ci // Copy buffer to image 2967e5c31af7Sopenharmony_ci beginCommandBuffer(vk, cmdBuffer); 2968e5c31af7Sopenharmony_ci 2969e5c31af7Sopenharmony_ci copyBufferToImage(vk, cmdBuffer, buffer, VK_WHOLE_SIZE, vector<VkBufferImageCopy>(1, copyRegion), aspect, 1u, 1u, image, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); 2970e5c31af7Sopenharmony_ci 2971e5c31af7Sopenharmony_ci endCommandBuffer(vk, cmdBuffer); 2972e5c31af7Sopenharmony_ci 2973e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, queue, cmdBuffer); 2974e5c31af7Sopenharmony_ci context.resetCommandPoolForVKSC(device, cmdPool); 2975e5c31af7Sopenharmony_ci} 2976e5c31af7Sopenharmony_ci 2977e5c31af7Sopenharmony_ciVkImageAspectFlags getImageAspectFlags (VkFormat format) 2978e5c31af7Sopenharmony_ci{ 2979e5c31af7Sopenharmony_ci const tcu::TextureFormat::ChannelOrder channelOrder = vk::mapVkFormat(format).order; 2980e5c31af7Sopenharmony_ci VkImageAspectFlags aspectFlags = (VkImageAspectFlags)0u; 2981e5c31af7Sopenharmony_ci 2982e5c31af7Sopenharmony_ci if (tcu::hasDepthComponent(channelOrder)) 2983e5c31af7Sopenharmony_ci aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT; 2984e5c31af7Sopenharmony_ci 2985e5c31af7Sopenharmony_ci if (tcu::hasStencilComponent(channelOrder)) 2986e5c31af7Sopenharmony_ci aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT; 2987e5c31af7Sopenharmony_ci 2988e5c31af7Sopenharmony_ci if (!aspectFlags) 2989e5c31af7Sopenharmony_ci aspectFlags |= VK_IMAGE_ASPECT_COLOR_BIT; 2990e5c31af7Sopenharmony_ci 2991e5c31af7Sopenharmony_ci return aspectFlags; 2992e5c31af7Sopenharmony_ci} 2993e5c31af7Sopenharmony_ci 2994e5c31af7Sopenharmony_ciTestStatus runAndVerifyUnusedVariablePipeline (Context &context, UnusedVariableContext unusedVariableContext) 2995e5c31af7Sopenharmony_ci{ 2996e5c31af7Sopenharmony_ci return runAndVerifyDefaultPipeline(context, unusedVariableContext.instanceContext); 2997e5c31af7Sopenharmony_ci} 2998e5c31af7Sopenharmony_ci 2999e5c31af7Sopenharmony_ciTestStatus runAndVerifyDefaultPipeline (Context& context, InstanceContext instance) 3000e5c31af7Sopenharmony_ci{ 3001e5c31af7Sopenharmony_ci if (getMinRequiredVulkanVersion(instance.resources.spirvVersion) > context.getUsedApiVersion()) 3002e5c31af7Sopenharmony_ci { 3003e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, string("Vulkan higher than or equal to " + getVulkanName(getMinRequiredVulkanVersion(instance.resources.spirvVersion)) + " is required for this test to run").c_str()); 3004e5c31af7Sopenharmony_ci } 3005e5c31af7Sopenharmony_ci 3006e5c31af7Sopenharmony_ci const DeviceInterface& vk = context.getDeviceInterface(); 3007e5c31af7Sopenharmony_ci const InstanceInterface& vkInstance = context.getInstanceInterface(); 3008e5c31af7Sopenharmony_ci const VkPhysicalDevice vkPhysicalDevice = context.getPhysicalDevice(); 3009e5c31af7Sopenharmony_ci const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 3010e5c31af7Sopenharmony_ci const VkQueue queue = context.getUniversalQueue(); 3011e5c31af7Sopenharmony_ci const VkDevice& device = context.getDevice(); 3012e5c31af7Sopenharmony_ci Allocator& allocator = context.getDefaultAllocator(); 3013e5c31af7Sopenharmony_ci vector<ModuleHandleSp> modules; 3014e5c31af7Sopenharmony_ci map<VkShaderStageFlagBits, VkShaderModule> moduleByStage; 3015e5c31af7Sopenharmony_ci const deUint32 fullRenderSize = 256; 3016e5c31af7Sopenharmony_ci const deUint32 quarterRenderSize = 64; 3017e5c31af7Sopenharmony_ci const tcu::UVec2 renderSize (fullRenderSize, fullRenderSize); 3018e5c31af7Sopenharmony_ci const int testSpecificSeed = 31354125; 3019e5c31af7Sopenharmony_ci const int seed = context.getTestContext().getCommandLine().getBaseSeed() ^ testSpecificSeed; 3020e5c31af7Sopenharmony_ci bool supportsGeometry = false; 3021e5c31af7Sopenharmony_ci bool supportsTessellation = false; 3022e5c31af7Sopenharmony_ci bool hasGeometry = false; 3023e5c31af7Sopenharmony_ci bool hasTessellation = false; 3024e5c31af7Sopenharmony_ci const bool hasPushConstants = !instance.pushConstants.empty(); 3025e5c31af7Sopenharmony_ci const deUint32 numInResources = static_cast<deUint32>(instance.resources.inputs.size()); 3026e5c31af7Sopenharmony_ci const deUint32 numOutResources = static_cast<deUint32>(instance.resources.outputs.size()); 3027e5c31af7Sopenharmony_ci const deUint32 numResources = numInResources + numOutResources; 3028e5c31af7Sopenharmony_ci const bool needInterface = !instance.interfaces.empty(); 3029e5c31af7Sopenharmony_ci const VkPhysicalDeviceFeatures& features = context.getDeviceFeatures(); 3030e5c31af7Sopenharmony_ci const Vec4 defaulClearColor (0.125f, 0.25f, 0.75f, 1.0f); 3031e5c31af7Sopenharmony_ci bool splitRenderArea = instance.splitRenderArea; 3032e5c31af7Sopenharmony_ci 3033e5c31af7Sopenharmony_ci const deUint32 renderDimension = splitRenderArea ? quarterRenderSize : fullRenderSize; 3034e5c31af7Sopenharmony_ci const int numRenderSegments = splitRenderArea ? 4 : 1; 3035e5c31af7Sopenharmony_ci 3036e5c31af7Sopenharmony_ci supportsGeometry = features.geometryShader == VK_TRUE; 3037e5c31af7Sopenharmony_ci supportsTessellation = features.tessellationShader == VK_TRUE; 3038e5c31af7Sopenharmony_ci hasGeometry = (instance.requiredStages & VK_SHADER_STAGE_GEOMETRY_BIT); 3039e5c31af7Sopenharmony_ci hasTessellation = (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) || 3040e5c31af7Sopenharmony_ci (instance.requiredStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT); 3041e5c31af7Sopenharmony_ci 3042e5c31af7Sopenharmony_ci if (hasGeometry && !supportsGeometry) 3043e5c31af7Sopenharmony_ci { 3044e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Geometry not supported"); 3045e5c31af7Sopenharmony_ci } 3046e5c31af7Sopenharmony_ci 3047e5c31af7Sopenharmony_ci if (hasTessellation && !supportsTessellation) 3048e5c31af7Sopenharmony_ci { 3049e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Tessellation not supported"); 3050e5c31af7Sopenharmony_ci } 3051e5c31af7Sopenharmony_ci 3052e5c31af7Sopenharmony_ci // Check all required extensions are supported 3053e5c31af7Sopenharmony_ci for (std::vector<std::string>::const_iterator i = instance.requiredDeviceExtensions.begin(); i != instance.requiredDeviceExtensions.end(); ++i) 3054e5c31af7Sopenharmony_ci { 3055e5c31af7Sopenharmony_ci if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), *i)) 3056e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, (std::string("Extension not supported: ") + *i).c_str()); 3057e5c31af7Sopenharmony_ci } 3058e5c31af7Sopenharmony_ci 3059e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 3060e5c31af7Sopenharmony_ci if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && 3061e5c31af7Sopenharmony_ci !context.getPortabilitySubsetFeatures().mutableComparisonSamplers) 3062e5c31af7Sopenharmony_ci { 3063e5c31af7Sopenharmony_ci // In portability when mutableComparisonSamplers is false then 3064e5c31af7Sopenharmony_ci // VkSamplerCreateInfo can't have compareEnable set to true 3065e5c31af7Sopenharmony_ci for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx) 3066e5c31af7Sopenharmony_ci { 3067e5c31af7Sopenharmony_ci const Resource& resource = instance.resources.inputs[inputNdx]; 3068e5c31af7Sopenharmony_ci const bool hasSampler = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || 3069e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER) || 3070e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 3071e5c31af7Sopenharmony_ci if (hasSampler && 3072e5c31af7Sopenharmony_ci tcu::hasDepthComponent(vk::mapVkFormat(instance.resources.inputFormat).order)) 3073e5c31af7Sopenharmony_ci { 3074e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: mutableComparisonSamplers are not supported by this implementation"); 3075e5c31af7Sopenharmony_ci } 3076e5c31af7Sopenharmony_ci } 3077e5c31af7Sopenharmony_ci } 3078e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 3079e5c31af7Sopenharmony_ci 3080e5c31af7Sopenharmony_ci { 3081e5c31af7Sopenharmony_ci VulkanFeatures localRequired = instance.requestedFeatures; 3082e5c31af7Sopenharmony_ci 3083e5c31af7Sopenharmony_ci const VkShaderStageFlags vertexPipelineStoresAndAtomicsAffected = vk::VK_SHADER_STAGE_VERTEX_BIT 3084e5c31af7Sopenharmony_ci | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT 3085e5c31af7Sopenharmony_ci | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT 3086e5c31af7Sopenharmony_ci | vk::VK_SHADER_STAGE_GEOMETRY_BIT; 3087e5c31af7Sopenharmony_ci 3088e5c31af7Sopenharmony_ci // reset fragment stores and atomics feature requirement 3089e5c31af7Sopenharmony_ci if ((localRequired.coreFeatures.fragmentStoresAndAtomics != DE_FALSE) && 3090e5c31af7Sopenharmony_ci (instance.customizedStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) == 0) 3091e5c31af7Sopenharmony_ci { 3092e5c31af7Sopenharmony_ci localRequired.coreFeatures.fragmentStoresAndAtomics = DE_FALSE; 3093e5c31af7Sopenharmony_ci } 3094e5c31af7Sopenharmony_ci 3095e5c31af7Sopenharmony_ci // reset vertex pipeline stores and atomics feature requirement 3096e5c31af7Sopenharmony_ci if (localRequired.coreFeatures.vertexPipelineStoresAndAtomics != DE_FALSE && 3097e5c31af7Sopenharmony_ci (instance.customizedStages & vertexPipelineStoresAndAtomicsAffected) == 0) 3098e5c31af7Sopenharmony_ci { 3099e5c31af7Sopenharmony_ci localRequired.coreFeatures.vertexPipelineStoresAndAtomics = DE_FALSE; 3100e5c31af7Sopenharmony_ci } 3101e5c31af7Sopenharmony_ci 3102e5c31af7Sopenharmony_ci const char* unsupportedFeature = DE_NULL; 3103e5c31af7Sopenharmony_ci if (!isVulkanFeaturesSupported(context, localRequired, &unsupportedFeature)) 3104e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, std::string("At least following requested feature not supported: ") + unsupportedFeature); 3105e5c31af7Sopenharmony_ci } 3106e5c31af7Sopenharmony_ci 3107e5c31af7Sopenharmony_ci // Check Interface Input/Output formats are supported 3108e5c31af7Sopenharmony_ci if (needInterface) 3109e5c31af7Sopenharmony_ci { 3110e5c31af7Sopenharmony_ci VkFormatProperties formatProperties; 3111e5c31af7Sopenharmony_ci vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getInputType().getVkFormat(), &formatProperties); 3112e5c31af7Sopenharmony_ci if ((formatProperties.bufferFeatures & VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0) 3113e5c31af7Sopenharmony_ci { 3114e5c31af7Sopenharmony_ci std::string error = "Interface Input format ("; 3115e5c31af7Sopenharmony_ci const std::string formatName = getFormatName(instance.interfaces.getInputType().getVkFormat()); 3116e5c31af7Sopenharmony_ci error += formatName + ") not supported"; 3117e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, error.c_str()); 3118e5c31af7Sopenharmony_ci } 3119e5c31af7Sopenharmony_ci 3120e5c31af7Sopenharmony_ci vkInstance.getPhysicalDeviceFormatProperties(vkPhysicalDevice, instance.interfaces.getOutputType().getVkFormat(), &formatProperties); 3121e5c31af7Sopenharmony_ci if (((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0) || 3122e5c31af7Sopenharmony_ci ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT) == 0)) 3123e5c31af7Sopenharmony_ci { 3124e5c31af7Sopenharmony_ci std::string error = "Interface Output format ("; 3125e5c31af7Sopenharmony_ci const std::string formatName = getFormatName(instance.interfaces.getInputType().getVkFormat()); 3126e5c31af7Sopenharmony_ci error += formatName + ") not supported"; 3127e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, error.c_str()); 3128e5c31af7Sopenharmony_ci } 3129e5c31af7Sopenharmony_ci } 3130e5c31af7Sopenharmony_ci 3131e5c31af7Sopenharmony_ci de::Random(seed).shuffle(instance.inputColors, instance.inputColors+4); 3132e5c31af7Sopenharmony_ci de::Random(seed).shuffle(instance.outputColors, instance.outputColors+4); 3133e5c31af7Sopenharmony_ci const Vec4 vertexData[] = 3134e5c31af7Sopenharmony_ci { 3135e5c31af7Sopenharmony_ci // Upper left corner: 3136e5c31af7Sopenharmony_ci Vec4(-1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //1 3137e5c31af7Sopenharmony_ci Vec4(-0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //2 3138e5c31af7Sopenharmony_ci Vec4(-1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[0].toVec(), //3 3139e5c31af7Sopenharmony_ci 3140e5c31af7Sopenharmony_ci // Upper right corner: 3141e5c31af7Sopenharmony_ci Vec4(+0.5f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //4 3142e5c31af7Sopenharmony_ci Vec4(+1.0f, -1.0f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //5 3143e5c31af7Sopenharmony_ci Vec4(+1.0f, -0.5f, 0.0f, 1.0f), instance.inputColors[1].toVec(), //6 3144e5c31af7Sopenharmony_ci 3145e5c31af7Sopenharmony_ci // Lower left corner: 3146e5c31af7Sopenharmony_ci Vec4(-1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //7 3147e5c31af7Sopenharmony_ci Vec4(-0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //8 3148e5c31af7Sopenharmony_ci Vec4(-1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[2].toVec(), //9 3149e5c31af7Sopenharmony_ci 3150e5c31af7Sopenharmony_ci // Lower right corner: 3151e5c31af7Sopenharmony_ci Vec4(+1.0f, +0.5f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //10 3152e5c31af7Sopenharmony_ci Vec4(+1.0f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //11 3153e5c31af7Sopenharmony_ci Vec4(+0.5f, +1.0f, 0.0f, 1.0f), instance.inputColors[3].toVec(), //12 3154e5c31af7Sopenharmony_ci 3155e5c31af7Sopenharmony_ci // The rest is used only renderFullSquare specified. Fills area already filled with clear color 3156e5c31af7Sopenharmony_ci // Left 1 3157e5c31af7Sopenharmony_ci Vec4(-1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //3 3158e5c31af7Sopenharmony_ci Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2 3159e5c31af7Sopenharmony_ci Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //7 3160e5c31af7Sopenharmony_ci 3161e5c31af7Sopenharmony_ci // Left 2 3162e5c31af7Sopenharmony_ci Vec4(-1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //7 3163e5c31af7Sopenharmony_ci Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2 3164e5c31af7Sopenharmony_ci Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8 3165e5c31af7Sopenharmony_ci 3166e5c31af7Sopenharmony_ci // Left-Center 3167e5c31af7Sopenharmony_ci Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8 3168e5c31af7Sopenharmony_ci Vec4(-0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //2 3169e5c31af7Sopenharmony_ci Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4 3170e5c31af7Sopenharmony_ci 3171e5c31af7Sopenharmony_ci // Right-Center 3172e5c31af7Sopenharmony_ci Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4 3173e5c31af7Sopenharmony_ci Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12 3174e5c31af7Sopenharmony_ci Vec4(-0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //8 3175e5c31af7Sopenharmony_ci 3176e5c31af7Sopenharmony_ci // Right 2 3177e5c31af7Sopenharmony_ci Vec4(+0.5f, -1.0f, 0.0f, 1.0f), defaulClearColor, //4 3178e5c31af7Sopenharmony_ci Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //6 3179e5c31af7Sopenharmony_ci Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12 3180e5c31af7Sopenharmony_ci 3181e5c31af7Sopenharmony_ci // Right 1 3182e5c31af7Sopenharmony_ci Vec4(+0.5f, +1.0f, 0.0f, 1.0f), defaulClearColor, //12 3183e5c31af7Sopenharmony_ci Vec4(+1.0f, -0.5f, 0.0f, 1.0f), defaulClearColor, //6 3184e5c31af7Sopenharmony_ci Vec4(+1.0f, +0.5f, 0.0f, 1.0f), defaulClearColor, //10 3185e5c31af7Sopenharmony_ci }; 3186e5c31af7Sopenharmony_ci 3187e5c31af7Sopenharmony_ci const size_t singleVertexDataSize = 2 * sizeof(Vec4); 3188e5c31af7Sopenharmony_ci const size_t vertexCount = instance.renderFullSquare ? sizeof(vertexData) / singleVertexDataSize : 4*3; 3189e5c31af7Sopenharmony_ci const size_t vertexDataSize = vertexCount * singleVertexDataSize; 3190e5c31af7Sopenharmony_ci 3191e5c31af7Sopenharmony_ci Move<VkBuffer> vertexInputBuffer; 3192e5c31af7Sopenharmony_ci de::MovePtr<Allocation> vertexInputMemory; 3193e5c31af7Sopenharmony_ci Move<VkBuffer> fragOutputBuffer; 3194e5c31af7Sopenharmony_ci de::MovePtr<Allocation> fragOutputMemory; 3195e5c31af7Sopenharmony_ci Move<VkImage> fragOutputImage; 3196e5c31af7Sopenharmony_ci de::MovePtr<Allocation> fragOutputImageMemory; 3197e5c31af7Sopenharmony_ci Move<VkImageView> fragOutputImageView; 3198e5c31af7Sopenharmony_ci 3199e5c31af7Sopenharmony_ci const VkBufferCreateInfo vertexBufferParams = 3200e5c31af7Sopenharmony_ci { 3201e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3202e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3203e5c31af7Sopenharmony_ci 0u, // VkBufferCreateFlags flags; 3204e5c31af7Sopenharmony_ci (VkDeviceSize)vertexDataSize, // VkDeviceSize size; 3205e5c31af7Sopenharmony_ci VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 3206e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3207e5c31af7Sopenharmony_ci 1u, // deUint32 queueFamilyCount; 3208e5c31af7Sopenharmony_ci &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3209e5c31af7Sopenharmony_ci }; 3210e5c31af7Sopenharmony_ci const Unique<VkBuffer> vertexBuffer (createBuffer(vk, device, &vertexBufferParams)); 3211e5c31af7Sopenharmony_ci const UniquePtr<Allocation> vertexBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexBuffer), MemoryRequirement::HostVisible)); 3212e5c31af7Sopenharmony_ci 3213e5c31af7Sopenharmony_ci VK_CHECK(vk.bindBufferMemory(device, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset())); 3214e5c31af7Sopenharmony_ci 3215e5c31af7Sopenharmony_ci const VkDeviceSize imageSizeBytes = (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y()); 3216e5c31af7Sopenharmony_ci const VkBufferCreateInfo readImageBufferParams = 3217e5c31af7Sopenharmony_ci { 3218e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3219e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3220e5c31af7Sopenharmony_ci 0u, // VkBufferCreateFlags flags; 3221e5c31af7Sopenharmony_ci imageSizeBytes, // VkDeviceSize size; 3222e5c31af7Sopenharmony_ci VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 3223e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3224e5c31af7Sopenharmony_ci 1u, // deUint32 queueFamilyCount; 3225e5c31af7Sopenharmony_ci &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3226e5c31af7Sopenharmony_ci }; 3227e5c31af7Sopenharmony_ci const Unique<VkBuffer> readImageBuffer (createBuffer(vk, device, &readImageBufferParams)); 3228e5c31af7Sopenharmony_ci const UniquePtr<Allocation> readImageBufferMemory (allocator.allocate(getBufferMemoryRequirements(vk, device, *readImageBuffer), MemoryRequirement::HostVisible)); 3229e5c31af7Sopenharmony_ci 3230e5c31af7Sopenharmony_ci VK_CHECK(vk.bindBufferMemory(device, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset())); 3231e5c31af7Sopenharmony_ci 3232e5c31af7Sopenharmony_ci VkImageCreateInfo imageParams = 3233e5c31af7Sopenharmony_ci { 3234e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 3235e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3236e5c31af7Sopenharmony_ci 0u, // VkImageCreateFlags flags; 3237e5c31af7Sopenharmony_ci VK_IMAGE_TYPE_2D, // VkImageType imageType; 3238e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format; 3239e5c31af7Sopenharmony_ci { renderSize.x(), renderSize.y(), 1 }, // VkExtent3D extent; 3240e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 3241e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 3242e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 3243e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 3244e5c31af7Sopenharmony_ci VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 3245e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3246e5c31af7Sopenharmony_ci 1u, // deUint32 queueFamilyCount; 3247e5c31af7Sopenharmony_ci &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3248e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 3249e5c31af7Sopenharmony_ci }; 3250e5c31af7Sopenharmony_ci 3251e5c31af7Sopenharmony_ci const Unique<VkImage> image (createImage(vk, device, &imageParams)); 3252e5c31af7Sopenharmony_ci const UniquePtr<Allocation> imageMemory (allocator.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any)); 3253e5c31af7Sopenharmony_ci 3254e5c31af7Sopenharmony_ci VK_CHECK(vk.bindImageMemory(device, *image, imageMemory->getMemory(), imageMemory->getOffset())); 3255e5c31af7Sopenharmony_ci 3256e5c31af7Sopenharmony_ci if (needInterface) 3257e5c31af7Sopenharmony_ci { 3258e5c31af7Sopenharmony_ci // The pipeline renders four triangles, each with three vertexes. 3259e5c31af7Sopenharmony_ci // Test instantialization only provides four data points, each 3260e5c31af7Sopenharmony_ci // for one triangle. So we need allocate space of three times of 3261e5c31af7Sopenharmony_ci // input buffer's size. 3262e5c31af7Sopenharmony_ci vector<deUint8> inputBufferBytes; 3263e5c31af7Sopenharmony_ci instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes); 3264e5c31af7Sopenharmony_ci 3265e5c31af7Sopenharmony_ci const deUint32 inputNumBytes = deUint32(inputBufferBytes.size() * 3); 3266e5c31af7Sopenharmony_ci // Create an additional buffer and backing memory for one input variable. 3267e5c31af7Sopenharmony_ci const VkBufferCreateInfo vertexInputParams = 3268e5c31af7Sopenharmony_ci { 3269e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3270e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3271e5c31af7Sopenharmony_ci 0u, // VkBufferCreateFlags flags; 3272e5c31af7Sopenharmony_ci inputNumBytes, // VkDeviceSize size; 3273e5c31af7Sopenharmony_ci VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 3274e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3275e5c31af7Sopenharmony_ci 1u, // deUint32 queueFamilyCount; 3276e5c31af7Sopenharmony_ci &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3277e5c31af7Sopenharmony_ci }; 3278e5c31af7Sopenharmony_ci 3279e5c31af7Sopenharmony_ci vertexInputBuffer = createBuffer(vk, device, &vertexInputParams); 3280e5c31af7Sopenharmony_ci vertexInputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *vertexInputBuffer), MemoryRequirement::HostVisible); 3281e5c31af7Sopenharmony_ci VK_CHECK(vk.bindBufferMemory(device, *vertexInputBuffer, vertexInputMemory->getMemory(), vertexInputMemory->getOffset())); 3282e5c31af7Sopenharmony_ci 3283e5c31af7Sopenharmony_ci // Create an additional buffer and backing memory for an output variable. 3284e5c31af7Sopenharmony_ci const VkDeviceSize fragOutputImgSize = (VkDeviceSize)(instance.interfaces.getOutputType().getNumBytes() * renderSize.x() * renderSize.y()); 3285e5c31af7Sopenharmony_ci const VkBufferCreateInfo fragOutputParams = 3286e5c31af7Sopenharmony_ci { 3287e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 3288e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3289e5c31af7Sopenharmony_ci 0u, // VkBufferCreateFlags flags; 3290e5c31af7Sopenharmony_ci fragOutputImgSize, // VkDeviceSize size; 3291e5c31af7Sopenharmony_ci VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 3292e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 3293e5c31af7Sopenharmony_ci 1u, // deUint32 queueFamilyCount; 3294e5c31af7Sopenharmony_ci &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 3295e5c31af7Sopenharmony_ci }; 3296e5c31af7Sopenharmony_ci fragOutputBuffer = createBuffer(vk, device, &fragOutputParams); 3297e5c31af7Sopenharmony_ci fragOutputMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *fragOutputBuffer), MemoryRequirement::HostVisible); 3298e5c31af7Sopenharmony_ci VK_CHECK(vk.bindBufferMemory(device, *fragOutputBuffer, fragOutputMemory->getMemory(), fragOutputMemory->getOffset())); 3299e5c31af7Sopenharmony_ci 3300e5c31af7Sopenharmony_ci // Create an additional image and backing memory for attachment. 3301e5c31af7Sopenharmony_ci // Reuse the previous imageParams since we only need to change the image format. 3302e5c31af7Sopenharmony_ci imageParams.format = instance.interfaces.getOutputType().getVkFormat(); 3303e5c31af7Sopenharmony_ci 3304e5c31af7Sopenharmony_ci // Check the usage bits on the given image format are supported. 3305e5c31af7Sopenharmony_ci requireFormatUsageSupport(vkInstance, vkPhysicalDevice, imageParams.format, imageParams.tiling, imageParams.usage); 3306e5c31af7Sopenharmony_ci 3307e5c31af7Sopenharmony_ci fragOutputImage = createImage(vk, device, &imageParams); 3308e5c31af7Sopenharmony_ci fragOutputImageMemory = allocator.allocate(getImageMemoryRequirements(vk, device, *fragOutputImage), MemoryRequirement::Any); 3309e5c31af7Sopenharmony_ci 3310e5c31af7Sopenharmony_ci VK_CHECK(vk.bindImageMemory(device, *fragOutputImage, fragOutputImageMemory->getMemory(), fragOutputImageMemory->getOffset())); 3311e5c31af7Sopenharmony_ci } 3312e5c31af7Sopenharmony_ci 3313e5c31af7Sopenharmony_ci vector<VkAttachmentDescription> colorAttDescs; 3314e5c31af7Sopenharmony_ci vector<VkAttachmentReference> colorAttRefs; 3315e5c31af7Sopenharmony_ci { 3316e5c31af7Sopenharmony_ci const VkAttachmentDescription attDesc = 3317e5c31af7Sopenharmony_ci { 3318e5c31af7Sopenharmony_ci 0u, // VkAttachmentDescriptionFlags flags; 3319e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format; 3320e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 3321e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 3322e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 3323e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 3324e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 3325e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 3326e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 3327e5c31af7Sopenharmony_ci }; 3328e5c31af7Sopenharmony_ci colorAttDescs.push_back(attDesc); 3329e5c31af7Sopenharmony_ci 3330e5c31af7Sopenharmony_ci const VkAttachmentReference attRef = 3331e5c31af7Sopenharmony_ci { 3332e5c31af7Sopenharmony_ci 0u, // deUint32 attachment; 3333e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; 3334e5c31af7Sopenharmony_ci }; 3335e5c31af7Sopenharmony_ci colorAttRefs.push_back(attRef); 3336e5c31af7Sopenharmony_ci } 3337e5c31af7Sopenharmony_ci 3338e5c31af7Sopenharmony_ci if (needInterface) 3339e5c31af7Sopenharmony_ci { 3340e5c31af7Sopenharmony_ci const VkAttachmentDescription attDesc = 3341e5c31af7Sopenharmony_ci { 3342e5c31af7Sopenharmony_ci 0u, // VkAttachmentDescriptionFlags flags; 3343e5c31af7Sopenharmony_ci instance.interfaces.getOutputType().getVkFormat(), // VkFormat format; 3344e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // deUint32 samples; 3345e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 3346e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 3347e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 3348e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 3349e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 3350e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 3351e5c31af7Sopenharmony_ci }; 3352e5c31af7Sopenharmony_ci colorAttDescs.push_back(attDesc); 3353e5c31af7Sopenharmony_ci 3354e5c31af7Sopenharmony_ci const VkAttachmentReference attRef = 3355e5c31af7Sopenharmony_ci { 3356e5c31af7Sopenharmony_ci 1u, // deUint32 attachment; 3357e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; 3358e5c31af7Sopenharmony_ci }; 3359e5c31af7Sopenharmony_ci colorAttRefs.push_back(attRef); 3360e5c31af7Sopenharmony_ci } 3361e5c31af7Sopenharmony_ci 3362e5c31af7Sopenharmony_ci VkSubpassDescription subpassDesc = 3363e5c31af7Sopenharmony_ci { 3364e5c31af7Sopenharmony_ci 0u, // VkSubpassDescriptionFlags flags; 3365e5c31af7Sopenharmony_ci VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 3366e5c31af7Sopenharmony_ci 0u, // deUint32 inputCount; 3367e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pInputAttachments; 3368e5c31af7Sopenharmony_ci 1u, // deUint32 colorCount; 3369e5c31af7Sopenharmony_ci colorAttRefs.data(), // const VkAttachmentReference* pColorAttachments; 3370e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pResolveAttachments; 3371e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 3372e5c31af7Sopenharmony_ci 0u, // deUint32 preserveCount; 3373e5c31af7Sopenharmony_ci DE_NULL, // const VkAttachmentReference* pPreserveAttachments; 3374e5c31af7Sopenharmony_ci 3375e5c31af7Sopenharmony_ci }; 3376e5c31af7Sopenharmony_ci VkRenderPassCreateInfo renderPassParams = 3377e5c31af7Sopenharmony_ci { 3378e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 3379e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3380e5c31af7Sopenharmony_ci (VkRenderPassCreateFlags)0, 3381e5c31af7Sopenharmony_ci 1u, // deUint32 attachmentCount; 3382e5c31af7Sopenharmony_ci colorAttDescs.data(), // const VkAttachmentDescription* pAttachments; 3383e5c31af7Sopenharmony_ci 1u, // deUint32 subpassCount; 3384e5c31af7Sopenharmony_ci &subpassDesc, // const VkSubpassDescription* pSubpasses; 3385e5c31af7Sopenharmony_ci 0u, // deUint32 dependencyCount; 3386e5c31af7Sopenharmony_ci DE_NULL, // const VkSubpassDependency* pDependencies; 3387e5c31af7Sopenharmony_ci }; 3388e5c31af7Sopenharmony_ci 3389e5c31af7Sopenharmony_ci if (needInterface) 3390e5c31af7Sopenharmony_ci { 3391e5c31af7Sopenharmony_ci subpassDesc.colorAttachmentCount += 1; 3392e5c31af7Sopenharmony_ci renderPassParams.attachmentCount += 1; 3393e5c31af7Sopenharmony_ci } 3394e5c31af7Sopenharmony_ci 3395e5c31af7Sopenharmony_ci const Unique<VkRenderPass> renderPass (createRenderPass(vk, device, &renderPassParams)); 3396e5c31af7Sopenharmony_ci 3397e5c31af7Sopenharmony_ci const VkImageViewCreateInfo colorAttViewParams = 3398e5c31af7Sopenharmony_ci { 3399e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3400e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3401e5c31af7Sopenharmony_ci 0u, // VkImageViewCreateFlags flags; 3402e5c31af7Sopenharmony_ci *image, // VkImage image; 3403e5c31af7Sopenharmony_ci VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 3404e5c31af7Sopenharmony_ci VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format; 3405e5c31af7Sopenharmony_ci { 3406e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_R, 3407e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_G, 3408e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_B, 3409e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_A 3410e5c31af7Sopenharmony_ci }, // VkChannelMapping channels; 3411e5c31af7Sopenharmony_ci { 3412e5c31af7Sopenharmony_ci VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 3413e5c31af7Sopenharmony_ci 0u, // deUint32 baseMipLevel; 3414e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 3415e5c31af7Sopenharmony_ci 0u, // deUint32 baseArrayLayer; 3416e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 3417e5c31af7Sopenharmony_ci }, // VkImageSubresourceRange subresourceRange; 3418e5c31af7Sopenharmony_ci }; 3419e5c31af7Sopenharmony_ci const Unique<VkImageView> colorAttView (createImageView(vk, device, &colorAttViewParams)); 3420e5c31af7Sopenharmony_ci const VkImageAspectFlags inputImageAspect = getImageAspectFlags(instance.resources.inputFormat); 3421e5c31af7Sopenharmony_ci 3422e5c31af7Sopenharmony_ci vector<VkImageView> attViews; 3423e5c31af7Sopenharmony_ci attViews.push_back(*colorAttView); 3424e5c31af7Sopenharmony_ci 3425e5c31af7Sopenharmony_ci // Handle resources requested by the test instantiation. 3426e5c31af7Sopenharmony_ci // These variables should be placed out of the following if block to avoid deallocation after out of scope. 3427e5c31af7Sopenharmony_ci vector<AllocationSp> inResourceMemories; 3428e5c31af7Sopenharmony_ci vector<AllocationSp> outResourceMemories; 3429e5c31af7Sopenharmony_ci vector<BufferHandleSp> inResourceBuffers; 3430e5c31af7Sopenharmony_ci vector<BufferHandleSp> outResourceBuffers; 3431e5c31af7Sopenharmony_ci vector<ImageHandleSp> inResourceImages; 3432e5c31af7Sopenharmony_ci vector<ImageViewHandleSp> inResourceImageViews; 3433e5c31af7Sopenharmony_ci vector<SamplerHandleSp> inResourceSamplers; 3434e5c31af7Sopenharmony_ci Move<VkDescriptorPool> descriptorPool; 3435e5c31af7Sopenharmony_ci Move<VkDescriptorSetLayout> setLayout; 3436e5c31af7Sopenharmony_ci VkDescriptorSetLayout rawSetLayout = DE_NULL; 3437e5c31af7Sopenharmony_ci VkDescriptorSet rawSet = DE_NULL; 3438e5c31af7Sopenharmony_ci 3439e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex)); 3440e5c31af7Sopenharmony_ci 3441e5c31af7Sopenharmony_ci // Command buffer 3442e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuf (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 3443e5c31af7Sopenharmony_ci 3444e5c31af7Sopenharmony_ci if (numResources != 0) 3445e5c31af7Sopenharmony_ci { 3446e5c31af7Sopenharmony_ci vector<VkDescriptorSetLayoutBinding> setLayoutBindings; 3447e5c31af7Sopenharmony_ci vector<VkDescriptorPoolSize> poolSizes; 3448e5c31af7Sopenharmony_ci 3449e5c31af7Sopenharmony_ci setLayoutBindings.reserve(numResources); 3450e5c31af7Sopenharmony_ci poolSizes.reserve(numResources); 3451e5c31af7Sopenharmony_ci 3452e5c31af7Sopenharmony_ci // Process all input resources. 3453e5c31af7Sopenharmony_ci for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx) 3454e5c31af7Sopenharmony_ci { 3455e5c31af7Sopenharmony_ci const Resource& resource = instance.resources.inputs[inputNdx]; 3456e5c31af7Sopenharmony_ci 3457e5c31af7Sopenharmony_ci const bool hasImage = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) || 3458e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || 3459e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 3460e5c31af7Sopenharmony_ci 3461e5c31af7Sopenharmony_ci const bool hasSampler = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || 3462e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER) || 3463e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 3464e5c31af7Sopenharmony_ci 3465e5c31af7Sopenharmony_ci // Resource is a buffer 3466e5c31af7Sopenharmony_ci if (!hasImage && !hasSampler) 3467e5c31af7Sopenharmony_ci { 3468e5c31af7Sopenharmony_ci Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex); 3469e5c31af7Sopenharmony_ci de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible); 3470e5c31af7Sopenharmony_ci 3471e5c31af7Sopenharmony_ci VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset())); 3472e5c31af7Sopenharmony_ci 3473e5c31af7Sopenharmony_ci // Copy data to memory. 3474e5c31af7Sopenharmony_ci { 3475e5c31af7Sopenharmony_ci vector<deUint8> resourceBytes; 3476e5c31af7Sopenharmony_ci resource.getBytes(resourceBytes); 3477e5c31af7Sopenharmony_ci 3478e5c31af7Sopenharmony_ci deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size()); 3479e5c31af7Sopenharmony_ci flushAlloc(vk, device, *resourceMemory); 3480e5c31af7Sopenharmony_ci } 3481e5c31af7Sopenharmony_ci 3482e5c31af7Sopenharmony_ci inResourceMemories.push_back(AllocationSp(resourceMemory.release())); 3483e5c31af7Sopenharmony_ci inResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer))); 3484e5c31af7Sopenharmony_ci } 3485e5c31af7Sopenharmony_ci // Resource is an image 3486e5c31af7Sopenharmony_ci else if (hasImage) 3487e5c31af7Sopenharmony_ci { 3488e5c31af7Sopenharmony_ci Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex); 3489e5c31af7Sopenharmony_ci de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible); 3490e5c31af7Sopenharmony_ci 3491e5c31af7Sopenharmony_ci VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset())); 3492e5c31af7Sopenharmony_ci 3493e5c31af7Sopenharmony_ci // Copy data to memory. 3494e5c31af7Sopenharmony_ci { 3495e5c31af7Sopenharmony_ci vector<deUint8> resourceBytes; 3496e5c31af7Sopenharmony_ci resource.getBytes(resourceBytes); 3497e5c31af7Sopenharmony_ci 3498e5c31af7Sopenharmony_ci deMemcpy(resourceMemory->getHostPtr(), &resourceBytes.front(), resourceBytes.size()); 3499e5c31af7Sopenharmony_ci flushAlloc(vk, device, *resourceMemory); 3500e5c31af7Sopenharmony_ci } 3501e5c31af7Sopenharmony_ci 3502e5c31af7Sopenharmony_ci Move<VkImage> resourceImage = createImageForResource(vk, device, resource, instance.resources.inputFormat, queueFamilyIndex); 3503e5c31af7Sopenharmony_ci de::MovePtr<Allocation> resourceImageMemory = allocator.allocate(getImageMemoryRequirements(vk, device, *resourceImage), MemoryRequirement::Any); 3504e5c31af7Sopenharmony_ci 3505e5c31af7Sopenharmony_ci VK_CHECK(vk.bindImageMemory(device, *resourceImage, resourceImageMemory->getMemory(), resourceImageMemory->getOffset())); 3506e5c31af7Sopenharmony_ci 3507e5c31af7Sopenharmony_ci copyBufferToImage(context, vk, device, queue, *cmdPool, *cmdBuf, resourceBuffer.get(), resourceImage.get(), inputImageAspect); 3508e5c31af7Sopenharmony_ci 3509e5c31af7Sopenharmony_ci inResourceMemories.push_back(AllocationSp(resourceImageMemory.release())); 3510e5c31af7Sopenharmony_ci inResourceImages.push_back(ImageHandleSp(new ImageHandleUp(resourceImage))); 3511e5c31af7Sopenharmony_ci } 3512e5c31af7Sopenharmony_ci 3513e5c31af7Sopenharmony_ci // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool. 3514e5c31af7Sopenharmony_ci const VkDescriptorSetLayoutBinding binding = 3515e5c31af7Sopenharmony_ci { 3516e5c31af7Sopenharmony_ci inputNdx, // binding 3517e5c31af7Sopenharmony_ci resource.getDescriptorType(), // descriptorType 3518e5c31af7Sopenharmony_ci 1u, // descriptorCount 3519e5c31af7Sopenharmony_ci VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags 3520e5c31af7Sopenharmony_ci DE_NULL, // pImmutableSamplers 3521e5c31af7Sopenharmony_ci }; 3522e5c31af7Sopenharmony_ci setLayoutBindings.push_back(binding); 3523e5c31af7Sopenharmony_ci 3524e5c31af7Sopenharmony_ci // Note: the following code doesn't check and unify descriptors of the same type. 3525e5c31af7Sopenharmony_ci const VkDescriptorPoolSize poolSize = 3526e5c31af7Sopenharmony_ci { 3527e5c31af7Sopenharmony_ci resource.getDescriptorType(), // type 3528e5c31af7Sopenharmony_ci 1u, // descriptorCount 3529e5c31af7Sopenharmony_ci }; 3530e5c31af7Sopenharmony_ci poolSizes.push_back(poolSize); 3531e5c31af7Sopenharmony_ci } 3532e5c31af7Sopenharmony_ci 3533e5c31af7Sopenharmony_ci // Process all output resources. 3534e5c31af7Sopenharmony_ci for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx) 3535e5c31af7Sopenharmony_ci { 3536e5c31af7Sopenharmony_ci const Resource& resource = instance.resources.outputs[outputNdx]; 3537e5c31af7Sopenharmony_ci // Create buffer and allocate memory. 3538e5c31af7Sopenharmony_ci Move<VkBuffer> resourceBuffer = createBufferForResource(vk, device, resource, queueFamilyIndex); 3539e5c31af7Sopenharmony_ci de::MovePtr<Allocation> resourceMemory = allocator.allocate(getBufferMemoryRequirements(vk, device, *resourceBuffer), MemoryRequirement::HostVisible); 3540e5c31af7Sopenharmony_ci vector<deUint8> resourceBytes; 3541e5c31af7Sopenharmony_ci 3542e5c31af7Sopenharmony_ci VK_CHECK(vk.bindBufferMemory(device, *resourceBuffer, resourceMemory->getMemory(), resourceMemory->getOffset())); 3543e5c31af7Sopenharmony_ci 3544e5c31af7Sopenharmony_ci // Fill memory with all ones. 3545e5c31af7Sopenharmony_ci resource.getBytes(resourceBytes); 3546e5c31af7Sopenharmony_ci deMemset((deUint8*)resourceMemory->getHostPtr(), 0xff, resourceBytes.size()); 3547e5c31af7Sopenharmony_ci flushAlloc(vk, device, *resourceMemory); 3548e5c31af7Sopenharmony_ci 3549e5c31af7Sopenharmony_ci outResourceMemories.push_back(AllocationSp(resourceMemory.release())); 3550e5c31af7Sopenharmony_ci outResourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(resourceBuffer))); 3551e5c31af7Sopenharmony_ci 3552e5c31af7Sopenharmony_ci // Prepare descriptor bindings and pool sizes for creating descriptor set layout and pool. 3553e5c31af7Sopenharmony_ci const VkDescriptorSetLayoutBinding binding = 3554e5c31af7Sopenharmony_ci { 3555e5c31af7Sopenharmony_ci numInResources + outputNdx, // binding 3556e5c31af7Sopenharmony_ci resource.getDescriptorType(), // descriptorType 3557e5c31af7Sopenharmony_ci 1u, // descriptorCount 3558e5c31af7Sopenharmony_ci VK_SHADER_STAGE_ALL_GRAPHICS, // stageFlags 3559e5c31af7Sopenharmony_ci DE_NULL, // pImmutableSamplers 3560e5c31af7Sopenharmony_ci }; 3561e5c31af7Sopenharmony_ci setLayoutBindings.push_back(binding); 3562e5c31af7Sopenharmony_ci 3563e5c31af7Sopenharmony_ci // Note: the following code doesn't check and unify descriptors of the same type. 3564e5c31af7Sopenharmony_ci const VkDescriptorPoolSize poolSize = 3565e5c31af7Sopenharmony_ci { 3566e5c31af7Sopenharmony_ci resource.getDescriptorType(), // type 3567e5c31af7Sopenharmony_ci 1u, // descriptorCount 3568e5c31af7Sopenharmony_ci }; 3569e5c31af7Sopenharmony_ci poolSizes.push_back(poolSize); 3570e5c31af7Sopenharmony_ci } 3571e5c31af7Sopenharmony_ci 3572e5c31af7Sopenharmony_ci // Create descriptor set layout, descriptor pool, and allocate descriptor set. 3573e5c31af7Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo setLayoutParams = 3574e5c31af7Sopenharmony_ci { 3575e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType 3576e5c31af7Sopenharmony_ci DE_NULL, // pNext 3577e5c31af7Sopenharmony_ci (VkDescriptorSetLayoutCreateFlags)0, // flags 3578e5c31af7Sopenharmony_ci numResources, // bindingCount 3579e5c31af7Sopenharmony_ci setLayoutBindings.data(), // pBindings 3580e5c31af7Sopenharmony_ci }; 3581e5c31af7Sopenharmony_ci setLayout = createDescriptorSetLayout(vk, device, &setLayoutParams); 3582e5c31af7Sopenharmony_ci rawSetLayout = *setLayout; 3583e5c31af7Sopenharmony_ci 3584e5c31af7Sopenharmony_ci const VkDescriptorPoolCreateInfo poolParams = 3585e5c31af7Sopenharmony_ci { 3586e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // sType 3587e5c31af7Sopenharmony_ci DE_NULL, // pNext 3588e5c31af7Sopenharmony_ci (VkDescriptorPoolCreateFlags)0, // flags 3589e5c31af7Sopenharmony_ci 1u, // maxSets 3590e5c31af7Sopenharmony_ci numResources, // poolSizeCount 3591e5c31af7Sopenharmony_ci poolSizes.data(), // pPoolSizes 3592e5c31af7Sopenharmony_ci }; 3593e5c31af7Sopenharmony_ci descriptorPool = createDescriptorPool(vk, device, &poolParams); 3594e5c31af7Sopenharmony_ci 3595e5c31af7Sopenharmony_ci const VkDescriptorSetAllocateInfo setAllocParams = 3596e5c31af7Sopenharmony_ci { 3597e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // sType 3598e5c31af7Sopenharmony_ci DE_NULL, // pNext 3599e5c31af7Sopenharmony_ci *descriptorPool, // descriptorPool 3600e5c31af7Sopenharmony_ci 1u, // descriptorSetCount 3601e5c31af7Sopenharmony_ci &rawSetLayout, // pSetLayouts 3602e5c31af7Sopenharmony_ci }; 3603e5c31af7Sopenharmony_ci VK_CHECK(vk.allocateDescriptorSets(device, &setAllocParams, &rawSet)); 3604e5c31af7Sopenharmony_ci 3605e5c31af7Sopenharmony_ci // Update descriptor set. 3606e5c31af7Sopenharmony_ci vector<VkWriteDescriptorSet> writeSpecs; 3607e5c31af7Sopenharmony_ci vector<VkDescriptorBufferInfo> dBufferInfos; 3608e5c31af7Sopenharmony_ci vector<VkDescriptorImageInfo> dImageInfos; 3609e5c31af7Sopenharmony_ci 3610e5c31af7Sopenharmony_ci writeSpecs.reserve(numResources); 3611e5c31af7Sopenharmony_ci dBufferInfos.reserve(numResources); 3612e5c31af7Sopenharmony_ci dImageInfos.reserve(numResources); 3613e5c31af7Sopenharmony_ci 3614e5c31af7Sopenharmony_ci deUint32 imgResourceNdx = 0u; 3615e5c31af7Sopenharmony_ci deUint32 bufResourceNdx = 0u; 3616e5c31af7Sopenharmony_ci 3617e5c31af7Sopenharmony_ci for (deUint32 inputNdx = 0; inputNdx < numInResources; ++inputNdx) 3618e5c31af7Sopenharmony_ci { 3619e5c31af7Sopenharmony_ci const Resource& resource = instance.resources.inputs[inputNdx]; 3620e5c31af7Sopenharmony_ci 3621e5c31af7Sopenharmony_ci const bool hasImage = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE) || 3622e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || 3623e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 3624e5c31af7Sopenharmony_ci 3625e5c31af7Sopenharmony_ci const bool hasSampler = (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE) || 3626e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_SAMPLER) || 3627e5c31af7Sopenharmony_ci (resource.getDescriptorType() == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); 3628e5c31af7Sopenharmony_ci 3629e5c31af7Sopenharmony_ci // Create image view and sampler 3630e5c31af7Sopenharmony_ci if (hasImage || hasSampler) 3631e5c31af7Sopenharmony_ci { 3632e5c31af7Sopenharmony_ci if (resource.getDescriptorType() != VK_DESCRIPTOR_TYPE_SAMPLER) 3633e5c31af7Sopenharmony_ci { 3634e5c31af7Sopenharmony_ci const VkImageViewCreateInfo imgViewParams = 3635e5c31af7Sopenharmony_ci { 3636e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 3637e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3638e5c31af7Sopenharmony_ci 0u, // VkImageViewCreateFlags flags; 3639e5c31af7Sopenharmony_ci **inResourceImages[imgResourceNdx++], // VkImage image; 3640e5c31af7Sopenharmony_ci VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 3641e5c31af7Sopenharmony_ci instance.resources.inputFormat, // VkFormat format; 3642e5c31af7Sopenharmony_ci { 3643e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_R, 3644e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_G, 3645e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_B, 3646e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_A 3647e5c31af7Sopenharmony_ci }, // VkComponentMapping channels; 3648e5c31af7Sopenharmony_ci { 3649e5c31af7Sopenharmony_ci inputImageAspect, // VkImageAspectFlags aspectMask; 3650e5c31af7Sopenharmony_ci 0u, // deUint32 baseMipLevel; 3651e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 3652e5c31af7Sopenharmony_ci 0u, // deUint32 baseArrayLayer; 3653e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 3654e5c31af7Sopenharmony_ci }, // VkImageSubresourceRange subresourceRange; 3655e5c31af7Sopenharmony_ci }; 3656e5c31af7Sopenharmony_ci 3657e5c31af7Sopenharmony_ci Move<VkImageView> imgView (createImageView(vk, device, &imgViewParams)); 3658e5c31af7Sopenharmony_ci inResourceImageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imgView))); 3659e5c31af7Sopenharmony_ci } 3660e5c31af7Sopenharmony_ci 3661e5c31af7Sopenharmony_ci if (hasSampler) 3662e5c31af7Sopenharmony_ci { 3663e5c31af7Sopenharmony_ci const bool hasDepthComponent = tcu::hasDepthComponent(vk::mapVkFormat(instance.resources.inputFormat).order); 3664e5c31af7Sopenharmony_ci const VkSamplerCreateInfo samplerParams 3665e5c31af7Sopenharmony_ci { 3666e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 3667e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3668e5c31af7Sopenharmony_ci 0, // VkSamplerCreateFlags flags; 3669e5c31af7Sopenharmony_ci VK_FILTER_NEAREST, // VkFilter magFilter: 3670e5c31af7Sopenharmony_ci VK_FILTER_NEAREST, // VkFilter minFilter; 3671e5c31af7Sopenharmony_ci VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode; 3672e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU; 3673e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV; 3674e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW; 3675e5c31af7Sopenharmony_ci 0.0f, // float mipLodBias; 3676e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 anistoropyEnable; 3677e5c31af7Sopenharmony_ci 1.0f, // float maxAnisotropy; 3678e5c31af7Sopenharmony_ci (hasDepthComponent) ? VK_TRUE : VK_FALSE, // VkBool32 compareEnable; 3679e5c31af7Sopenharmony_ci VK_COMPARE_OP_LESS, // VkCompareOp compareOp; 3680e5c31af7Sopenharmony_ci 0.0f, // float minLod; 3681e5c31af7Sopenharmony_ci 0.0f, // float maxLod; 3682e5c31af7Sopenharmony_ci VK_BORDER_COLOR_INT_OPAQUE_BLACK, // VkBorderColor borderColor; 3683e5c31af7Sopenharmony_ci VK_FALSE // VkBool32 unnormalizedCoordinates; 3684e5c31af7Sopenharmony_ci }; 3685e5c31af7Sopenharmony_ci 3686e5c31af7Sopenharmony_ci Move<VkSampler> sampler (createSampler(vk, device, &samplerParams)); 3687e5c31af7Sopenharmony_ci inResourceSamplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler))); 3688e5c31af7Sopenharmony_ci } 3689e5c31af7Sopenharmony_ci } 3690e5c31af7Sopenharmony_ci 3691e5c31af7Sopenharmony_ci // Create descriptor buffer and image infos 3692e5c31af7Sopenharmony_ci switch (resource.getDescriptorType()) 3693e5c31af7Sopenharmony_ci { 3694e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 3695e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 3696e5c31af7Sopenharmony_ci { 3697e5c31af7Sopenharmony_ci const VkDescriptorBufferInfo bufInfo = 3698e5c31af7Sopenharmony_ci { 3699e5c31af7Sopenharmony_ci **inResourceBuffers[bufResourceNdx++], // buffer 3700e5c31af7Sopenharmony_ci 0, // offset 3701e5c31af7Sopenharmony_ci VK_WHOLE_SIZE, // size 3702e5c31af7Sopenharmony_ci }; 3703e5c31af7Sopenharmony_ci dBufferInfos.push_back(bufInfo); 3704e5c31af7Sopenharmony_ci break; 3705e5c31af7Sopenharmony_ci } 3706e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 3707e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 3708e5c31af7Sopenharmony_ci { 3709e5c31af7Sopenharmony_ci const VkDescriptorImageInfo imgInfo = 3710e5c31af7Sopenharmony_ci { 3711e5c31af7Sopenharmony_ci DE_NULL, // sampler 3712e5c31af7Sopenharmony_ci **inResourceImageViews.back(), // imageView 3713e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL // imageLayout 3714e5c31af7Sopenharmony_ci }; 3715e5c31af7Sopenharmony_ci dImageInfos.push_back(imgInfo); 3716e5c31af7Sopenharmony_ci break; 3717e5c31af7Sopenharmony_ci } 3718e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 3719e5c31af7Sopenharmony_ci { 3720e5c31af7Sopenharmony_ci const VkDescriptorImageInfo imgInfo = 3721e5c31af7Sopenharmony_ci { 3722e5c31af7Sopenharmony_ci **inResourceSamplers.back(), // sampler 3723e5c31af7Sopenharmony_ci DE_NULL, // imageView 3724e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL // imageLayout 3725e5c31af7Sopenharmony_ci }; 3726e5c31af7Sopenharmony_ci dImageInfos.push_back(imgInfo); 3727e5c31af7Sopenharmony_ci break; 3728e5c31af7Sopenharmony_ci } 3729e5c31af7Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 3730e5c31af7Sopenharmony_ci { 3731e5c31af7Sopenharmony_ci 3732e5c31af7Sopenharmony_ci const VkDescriptorImageInfo imgInfo = 3733e5c31af7Sopenharmony_ci { 3734e5c31af7Sopenharmony_ci **inResourceSamplers.back(), // sampler 3735e5c31af7Sopenharmony_ci **inResourceImageViews.back(), // imageView 3736e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL // imageLayout 3737e5c31af7Sopenharmony_ci }; 3738e5c31af7Sopenharmony_ci dImageInfos.push_back(imgInfo); 3739e5c31af7Sopenharmony_ci break; 3740e5c31af7Sopenharmony_ci } 3741e5c31af7Sopenharmony_ci default: 3742e5c31af7Sopenharmony_ci DE_FATAL("Not implemented"); 3743e5c31af7Sopenharmony_ci } 3744e5c31af7Sopenharmony_ci 3745e5c31af7Sopenharmony_ci const VkWriteDescriptorSet writeSpec = { 3746e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType 3747e5c31af7Sopenharmony_ci DE_NULL, // pNext 3748e5c31af7Sopenharmony_ci rawSet, // dstSet 3749e5c31af7Sopenharmony_ci inputNdx, // binding 3750e5c31af7Sopenharmony_ci 0, // dstArrayElement 3751e5c31af7Sopenharmony_ci 1u, // descriptorCount 3752e5c31af7Sopenharmony_ci instance.resources.inputs[inputNdx].getDescriptorType(), // descriptorType 3753e5c31af7Sopenharmony_ci ( (hasImage | hasSampler) ? &dImageInfos.back() : DE_NULL), // pImageInfo 3754e5c31af7Sopenharmony_ci (!(hasImage | hasSampler) ? &dBufferInfos.back() : DE_NULL), // pBufferInfo 3755e5c31af7Sopenharmony_ci DE_NULL, // pTexelBufferView 3756e5c31af7Sopenharmony_ci }; 3757e5c31af7Sopenharmony_ci writeSpecs.push_back(writeSpec); 3758e5c31af7Sopenharmony_ci } 3759e5c31af7Sopenharmony_ci 3760e5c31af7Sopenharmony_ci for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx) 3761e5c31af7Sopenharmony_ci { 3762e5c31af7Sopenharmony_ci const VkDescriptorBufferInfo bufInfo = 3763e5c31af7Sopenharmony_ci { 3764e5c31af7Sopenharmony_ci **outResourceBuffers[outputNdx], // buffer 3765e5c31af7Sopenharmony_ci 0, // offset 3766e5c31af7Sopenharmony_ci VK_WHOLE_SIZE, // size 3767e5c31af7Sopenharmony_ci }; 3768e5c31af7Sopenharmony_ci dBufferInfos.push_back(bufInfo); 3769e5c31af7Sopenharmony_ci 3770e5c31af7Sopenharmony_ci const VkWriteDescriptorSet writeSpec = { 3771e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType 3772e5c31af7Sopenharmony_ci DE_NULL, // pNext 3773e5c31af7Sopenharmony_ci rawSet, // dstSet 3774e5c31af7Sopenharmony_ci numInResources + outputNdx, // binding 3775e5c31af7Sopenharmony_ci 0, // dstArrayElement 3776e5c31af7Sopenharmony_ci 1u, // descriptorCount 3777e5c31af7Sopenharmony_ci instance.resources.outputs[outputNdx].getDescriptorType(), // descriptorType 3778e5c31af7Sopenharmony_ci DE_NULL, // pImageInfo 3779e5c31af7Sopenharmony_ci &dBufferInfos.back(), // pBufferInfo 3780e5c31af7Sopenharmony_ci DE_NULL, // pTexelBufferView 3781e5c31af7Sopenharmony_ci }; 3782e5c31af7Sopenharmony_ci writeSpecs.push_back(writeSpec); 3783e5c31af7Sopenharmony_ci } 3784e5c31af7Sopenharmony_ci vk.updateDescriptorSets(device, numResources, writeSpecs.data(), 0, DE_NULL); 3785e5c31af7Sopenharmony_ci } 3786e5c31af7Sopenharmony_ci 3787e5c31af7Sopenharmony_ci // Pipeline layout 3788e5c31af7Sopenharmony_ci VkPipelineLayoutCreateInfo pipelineLayoutParams = 3789e5c31af7Sopenharmony_ci { 3790e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 3791e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3792e5c31af7Sopenharmony_ci (VkPipelineLayoutCreateFlags)0, 3793e5c31af7Sopenharmony_ci 0u, // deUint32 descriptorSetCount; 3794e5c31af7Sopenharmony_ci DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 3795e5c31af7Sopenharmony_ci 0u, // deUint32 pushConstantRangeCount; 3796e5c31af7Sopenharmony_ci DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 3797e5c31af7Sopenharmony_ci }; 3798e5c31af7Sopenharmony_ci 3799e5c31af7Sopenharmony_ci VkPushConstantRange pushConstantRange = 3800e5c31af7Sopenharmony_ci { 3801e5c31af7Sopenharmony_ci VK_SHADER_STAGE_ALL_GRAPHICS, // VkShaderStageFlags stageFlags; 3802e5c31af7Sopenharmony_ci 0, // uint32_t offset; 3803e5c31af7Sopenharmony_ci 0, // uint32_t size; 3804e5c31af7Sopenharmony_ci }; 3805e5c31af7Sopenharmony_ci if (hasPushConstants) 3806e5c31af7Sopenharmony_ci { 3807e5c31af7Sopenharmony_ci vector<deUint8> pushConstantsBytes; 3808e5c31af7Sopenharmony_ci instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes); 3809e5c31af7Sopenharmony_ci 3810e5c31af7Sopenharmony_ci pushConstantRange.size = static_cast<deUint32>(pushConstantsBytes.size()); 3811e5c31af7Sopenharmony_ci pipelineLayoutParams.pushConstantRangeCount = 1; 3812e5c31af7Sopenharmony_ci pipelineLayoutParams.pPushConstantRanges = &pushConstantRange; 3813e5c31af7Sopenharmony_ci } 3814e5c31af7Sopenharmony_ci if (numResources != 0) 3815e5c31af7Sopenharmony_ci { 3816e5c31af7Sopenharmony_ci // Update pipeline layout with the descriptor set layout. 3817e5c31af7Sopenharmony_ci pipelineLayoutParams.setLayoutCount = 1; 3818e5c31af7Sopenharmony_ci pipelineLayoutParams.pSetLayouts = &rawSetLayout; 3819e5c31af7Sopenharmony_ci } 3820e5c31af7Sopenharmony_ci const Unique<VkPipelineLayout> pipelineLayout (createPipelineLayout(vk, device, &pipelineLayoutParams)); 3821e5c31af7Sopenharmony_ci 3822e5c31af7Sopenharmony_ci // Pipeline 3823e5c31af7Sopenharmony_ci vector<VkPipelineShaderStageCreateInfo> shaderStageParams; 3824e5c31af7Sopenharmony_ci // We need these vectors to make sure that information about specialization constants for each stage can outlive createGraphicsPipeline(). 3825e5c31af7Sopenharmony_ci vector<vector<VkSpecializationMapEntry> > specConstantEntries; 3826e5c31af7Sopenharmony_ci vector<VkSpecializationInfo> specializationInfos; 3827e5c31af7Sopenharmony_ci if (DE_NULL != instance.resources.verifyBinary) 3828e5c31af7Sopenharmony_ci { 3829e5c31af7Sopenharmony_ci std::string shaderName; 3830e5c31af7Sopenharmony_ci switch(instance.customizedStages) 3831e5c31af7Sopenharmony_ci { 3832e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_VERTEX_BIT: 3833e5c31af7Sopenharmony_ci shaderName= "vert"; 3834e5c31af7Sopenharmony_ci break; 3835e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: 3836e5c31af7Sopenharmony_ci shaderName= "tessc"; 3837e5c31af7Sopenharmony_ci break; 3838e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: 3839e5c31af7Sopenharmony_ci shaderName= "tesse"; 3840e5c31af7Sopenharmony_ci break; 3841e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_GEOMETRY_BIT: 3842e5c31af7Sopenharmony_ci shaderName= "geom"; 3843e5c31af7Sopenharmony_ci break; 3844e5c31af7Sopenharmony_ci case VK_SHADER_STAGE_FRAGMENT_BIT: 3845e5c31af7Sopenharmony_ci shaderName= "frag"; 3846e5c31af7Sopenharmony_ci break; 3847e5c31af7Sopenharmony_ci default: 3848e5c31af7Sopenharmony_ci DE_ASSERT(0); 3849e5c31af7Sopenharmony_ci break; 3850e5c31af7Sopenharmony_ci } 3851e5c31af7Sopenharmony_ci const ProgramBinary& binary = context.getBinaryCollection().get(shaderName); 3852e5c31af7Sopenharmony_ci if (!instance.resources.verifyBinary(binary)) 3853e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Binary verification of SPIR-V in the test failed"); 3854e5c31af7Sopenharmony_ci 3855e5c31af7Sopenharmony_ci } 3856e5c31af7Sopenharmony_ci createPipelineShaderStages(vk, device, instance, context, modules, shaderStageParams); 3857e5c31af7Sopenharmony_ci 3858e5c31af7Sopenharmony_ci // And we don't want the reallocation of these vectors to invalidate pointers pointing to their contents. 3859e5c31af7Sopenharmony_ci specConstantEntries.reserve(shaderStageParams.size()); 3860e5c31af7Sopenharmony_ci specializationInfos.reserve(shaderStageParams.size()); 3861e5c31af7Sopenharmony_ci 3862e5c31af7Sopenharmony_ci // Patch the specialization info field in PipelineShaderStageCreateInfos. 3863e5c31af7Sopenharmony_ci for (vector<VkPipelineShaderStageCreateInfo>::iterator stageInfo = shaderStageParams.begin(); stageInfo != shaderStageParams.end(); ++stageInfo) 3864e5c31af7Sopenharmony_ci { 3865e5c31af7Sopenharmony_ci const StageToSpecConstantMap::const_iterator stageIt = instance.specConstants.find(stageInfo->stage); 3866e5c31af7Sopenharmony_ci 3867e5c31af7Sopenharmony_ci if (stageIt != instance.specConstants.end()) 3868e5c31af7Sopenharmony_ci { 3869e5c31af7Sopenharmony_ci const size_t numSpecConstants = stageIt->second.getValuesCount(); 3870e5c31af7Sopenharmony_ci vector<VkSpecializationMapEntry> entries; 3871e5c31af7Sopenharmony_ci VkSpecializationInfo specInfo; 3872e5c31af7Sopenharmony_ci size_t offset = 0; 3873e5c31af7Sopenharmony_ci 3874e5c31af7Sopenharmony_ci entries.resize(numSpecConstants); 3875e5c31af7Sopenharmony_ci 3876e5c31af7Sopenharmony_ci // Constant IDs are numbered sequentially starting from 0. 3877e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < numSpecConstants; ++ndx) 3878e5c31af7Sopenharmony_ci { 3879e5c31af7Sopenharmony_ci const size_t valueSize = stageIt->second.getValueSize(ndx); 3880e5c31af7Sopenharmony_ci 3881e5c31af7Sopenharmony_ci entries[ndx].constantID = (deUint32)ndx; 3882e5c31af7Sopenharmony_ci entries[ndx].offset = static_cast<deUint32>(offset); 3883e5c31af7Sopenharmony_ci entries[ndx].size = valueSize; 3884e5c31af7Sopenharmony_ci 3885e5c31af7Sopenharmony_ci offset += valueSize; 3886e5c31af7Sopenharmony_ci } 3887e5c31af7Sopenharmony_ci 3888e5c31af7Sopenharmony_ci specConstantEntries.push_back(entries); 3889e5c31af7Sopenharmony_ci 3890e5c31af7Sopenharmony_ci specInfo.mapEntryCount = (deUint32)numSpecConstants; 3891e5c31af7Sopenharmony_ci specInfo.pMapEntries = specConstantEntries.back().data(); 3892e5c31af7Sopenharmony_ci specInfo.dataSize = offset; 3893e5c31af7Sopenharmony_ci specInfo.pData = stageIt->second.getValuesBuffer(); 3894e5c31af7Sopenharmony_ci specializationInfos.push_back(specInfo); 3895e5c31af7Sopenharmony_ci 3896e5c31af7Sopenharmony_ci stageInfo->pSpecializationInfo = &specializationInfos.back(); 3897e5c31af7Sopenharmony_ci } 3898e5c31af7Sopenharmony_ci } 3899e5c31af7Sopenharmony_ci const VkPipelineDepthStencilStateCreateInfo depthStencilParams = 3900e5c31af7Sopenharmony_ci { 3901e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 3902e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3903e5c31af7Sopenharmony_ci (VkPipelineDepthStencilStateCreateFlags)0, 3904e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 depthTestEnable; 3905e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 depthWriteEnable; 3906e5c31af7Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp; 3907e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 depthBoundsTestEnable; 3908e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 stencilTestEnable; 3909e5c31af7Sopenharmony_ci { 3910e5c31af7Sopenharmony_ci VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp; 3911e5c31af7Sopenharmony_ci VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp; 3912e5c31af7Sopenharmony_ci VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp; 3913e5c31af7Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp; 3914e5c31af7Sopenharmony_ci 0u, // deUint32 stencilCompareMask; 3915e5c31af7Sopenharmony_ci 0u, // deUint32 stencilWriteMask; 3916e5c31af7Sopenharmony_ci 0u, // deUint32 stencilReference; 3917e5c31af7Sopenharmony_ci }, // VkStencilOpState front; 3918e5c31af7Sopenharmony_ci { 3919e5c31af7Sopenharmony_ci VK_STENCIL_OP_KEEP, // VkStencilOp stencilFailOp; 3920e5c31af7Sopenharmony_ci VK_STENCIL_OP_KEEP, // VkStencilOp stencilPassOp; 3921e5c31af7Sopenharmony_ci VK_STENCIL_OP_KEEP, // VkStencilOp stencilDepthFailOp; 3922e5c31af7Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // VkCompareOp stencilCompareOp; 3923e5c31af7Sopenharmony_ci 0u, // deUint32 stencilCompareMask; 3924e5c31af7Sopenharmony_ci 0u, // deUint32 stencilWriteMask; 3925e5c31af7Sopenharmony_ci 0u, // deUint32 stencilReference; 3926e5c31af7Sopenharmony_ci }, // VkStencilOpState back; 3927e5c31af7Sopenharmony_ci -1.0f, // float minDepthBounds; 3928e5c31af7Sopenharmony_ci +1.0f, // float maxDepthBounds; 3929e5c31af7Sopenharmony_ci }; 3930e5c31af7Sopenharmony_ci const VkViewport viewport0 = makeViewport(renderSize); 3931e5c31af7Sopenharmony_ci const VkRect2D scissor0 = makeRect2D(0u, 0u); 3932e5c31af7Sopenharmony_ci const VkPipelineViewportStateCreateInfo viewportParams = 3933e5c31af7Sopenharmony_ci { 3934e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 3935e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3936e5c31af7Sopenharmony_ci (VkPipelineViewportStateCreateFlags)0, 3937e5c31af7Sopenharmony_ci 1u, // deUint32 viewportCount; 3938e5c31af7Sopenharmony_ci &viewport0, 3939e5c31af7Sopenharmony_ci 1u, 3940e5c31af7Sopenharmony_ci &scissor0 3941e5c31af7Sopenharmony_ci }; 3942e5c31af7Sopenharmony_ci const VkSampleMask sampleMask = ~0u; 3943e5c31af7Sopenharmony_ci const VkPipelineMultisampleStateCreateInfo multisampleParams = 3944e5c31af7Sopenharmony_ci { 3945e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 3946e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3947e5c31af7Sopenharmony_ci (VkPipelineMultisampleStateCreateFlags)0, 3948e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterSamples; 3949e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 sampleShadingEnable; 3950e5c31af7Sopenharmony_ci 0.0f, // float minSampleShading; 3951e5c31af7Sopenharmony_ci &sampleMask, // const VkSampleMask* pSampleMask; 3952e5c31af7Sopenharmony_ci DE_FALSE, // VkBool32 alphaToCoverageEnable; 3953e5c31af7Sopenharmony_ci DE_FALSE, // VkBool32 alphaToOneEnable; 3954e5c31af7Sopenharmony_ci }; 3955e5c31af7Sopenharmony_ci const VkPipelineRasterizationStateCreateInfo rasterParams = 3956e5c31af7Sopenharmony_ci { 3957e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 3958e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3959e5c31af7Sopenharmony_ci (VkPipelineRasterizationStateCreateFlags)0, 3960e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 depthClampEnable; 3961e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 rasterizerDiscardEnable; 3962e5c31af7Sopenharmony_ci VK_POLYGON_MODE_FILL, // VkFillMode fillMode; 3963e5c31af7Sopenharmony_ci VK_CULL_MODE_NONE, // VkCullMode cullMode; 3964e5c31af7Sopenharmony_ci VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 3965e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 depthBiasEnable; 3966e5c31af7Sopenharmony_ci 0.0f, // float depthBias; 3967e5c31af7Sopenharmony_ci 0.0f, // float depthBiasClamp; 3968e5c31af7Sopenharmony_ci 0.0f, // float slopeScaledDepthBias; 3969e5c31af7Sopenharmony_ci 1.0f, // float lineWidth; 3970e5c31af7Sopenharmony_ci }; 3971e5c31af7Sopenharmony_ci const VkPrimitiveTopology topology = hasTessellation? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST: VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 3972e5c31af7Sopenharmony_ci const VkPipelineInputAssemblyStateCreateInfo inputAssemblyParams = 3973e5c31af7Sopenharmony_ci { 3974e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 3975e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 3976e5c31af7Sopenharmony_ci (VkPipelineInputAssemblyStateCreateFlags)0, 3977e5c31af7Sopenharmony_ci topology, // VkPrimitiveTopology topology; 3978e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 primitiveRestartEnable; 3979e5c31af7Sopenharmony_ci }; 3980e5c31af7Sopenharmony_ci 3981e5c31af7Sopenharmony_ci vector<VkVertexInputBindingDescription> vertexBindings; 3982e5c31af7Sopenharmony_ci vector<VkVertexInputAttributeDescription> vertexAttribs; 3983e5c31af7Sopenharmony_ci 3984e5c31af7Sopenharmony_ci const VkVertexInputBindingDescription vertexBinding0 = 3985e5c31af7Sopenharmony_ci { 3986e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 3987e5c31af7Sopenharmony_ci deUint32(singleVertexDataSize), // deUint32 strideInBytes; 3988e5c31af7Sopenharmony_ci VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; 3989e5c31af7Sopenharmony_ci }; 3990e5c31af7Sopenharmony_ci vertexBindings.push_back(vertexBinding0); 3991e5c31af7Sopenharmony_ci 3992e5c31af7Sopenharmony_ci { 3993e5c31af7Sopenharmony_ci VkVertexInputAttributeDescription attr0 = 3994e5c31af7Sopenharmony_ci { 3995e5c31af7Sopenharmony_ci 0u, // deUint32 location; 3996e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 3997e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 3998e5c31af7Sopenharmony_ci 0u // deUint32 offsetInBytes; 3999e5c31af7Sopenharmony_ci }; 4000e5c31af7Sopenharmony_ci vertexAttribs.push_back(attr0); 4001e5c31af7Sopenharmony_ci 4002e5c31af7Sopenharmony_ci VkVertexInputAttributeDescription attr1 = 4003e5c31af7Sopenharmony_ci { 4004e5c31af7Sopenharmony_ci 1u, // deUint32 location; 4005e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 4006e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 4007e5c31af7Sopenharmony_ci sizeof(Vec4), // deUint32 offsetInBytes; 4008e5c31af7Sopenharmony_ci }; 4009e5c31af7Sopenharmony_ci vertexAttribs.push_back(attr1); 4010e5c31af7Sopenharmony_ci } 4011e5c31af7Sopenharmony_ci 4012e5c31af7Sopenharmony_ci // If the test instantiation has additional input/output interface variables, we need to create additional bindings. 4013e5c31af7Sopenharmony_ci // Right now we only support one additional input varible for the vertex stage, and that will be bound to binding #1 4014e5c31af7Sopenharmony_ci // with location #2. 4015e5c31af7Sopenharmony_ci if (needInterface) 4016e5c31af7Sopenharmony_ci { 4017e5c31af7Sopenharmony_ci // Portability requires stride to be multiply of minVertexInputBindingStrideAlignment 4018e5c31af7Sopenharmony_ci // this value is usually 4 and current tests meet this requirement but 4019e5c31af7Sopenharmony_ci // if this changes in future then this limit should be verified in checkSupport 4020e5c31af7Sopenharmony_ci const deUint32 stride = instance.interfaces.getInputType().getNumBytes(); 4021e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 4022e5c31af7Sopenharmony_ci if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && 4023e5c31af7Sopenharmony_ci ((stride % context.getPortabilitySubsetProperties().minVertexInputBindingStrideAlignment) != 0)) 4024e5c31af7Sopenharmony_ci { 4025e5c31af7Sopenharmony_ci DE_FATAL("stride is not multiply of minVertexInputBindingStrideAlignment"); 4026e5c31af7Sopenharmony_ci } 4027e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 4028e5c31af7Sopenharmony_ci 4029e5c31af7Sopenharmony_ci const VkVertexInputBindingDescription vertexBinding1 = 4030e5c31af7Sopenharmony_ci { 4031e5c31af7Sopenharmony_ci 1u, // deUint32 binding; 4032e5c31af7Sopenharmony_ci stride, // deUint32 strideInBytes; 4033e5c31af7Sopenharmony_ci VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate stepRate; 4034e5c31af7Sopenharmony_ci }; 4035e5c31af7Sopenharmony_ci vertexBindings.push_back(vertexBinding1); 4036e5c31af7Sopenharmony_ci 4037e5c31af7Sopenharmony_ci VkVertexInputAttributeDescription attr = 4038e5c31af7Sopenharmony_ci { 4039e5c31af7Sopenharmony_ci 2u, // deUint32 location; 4040e5c31af7Sopenharmony_ci 1u, // deUint32 binding; 4041e5c31af7Sopenharmony_ci instance.interfaces.getInputType().getVkFormat(), // VkFormat format; 4042e5c31af7Sopenharmony_ci 0, // deUint32 offsetInBytes; 4043e5c31af7Sopenharmony_ci }; 4044e5c31af7Sopenharmony_ci vertexAttribs.push_back(attr); 4045e5c31af7Sopenharmony_ci } 4046e5c31af7Sopenharmony_ci 4047e5c31af7Sopenharmony_ci VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 4048e5c31af7Sopenharmony_ci { 4049e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 4050e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4051e5c31af7Sopenharmony_ci (VkPipelineVertexInputStateCreateFlags)0, 4052e5c31af7Sopenharmony_ci 1u, // deUint32 bindingCount; 4053e5c31af7Sopenharmony_ci vertexBindings.data(), // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 4054e5c31af7Sopenharmony_ci 2u, // deUint32 attributeCount; 4055e5c31af7Sopenharmony_ci vertexAttribs.data(), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 4056e5c31af7Sopenharmony_ci }; 4057e5c31af7Sopenharmony_ci 4058e5c31af7Sopenharmony_ci if (needInterface) 4059e5c31af7Sopenharmony_ci { 4060e5c31af7Sopenharmony_ci vertexInputStateParams.vertexBindingDescriptionCount += 1; 4061e5c31af7Sopenharmony_ci vertexInputStateParams.vertexAttributeDescriptionCount += 1; 4062e5c31af7Sopenharmony_ci } 4063e5c31af7Sopenharmony_ci 4064e5c31af7Sopenharmony_ci vector<VkPipelineColorBlendAttachmentState> attBlendStates; 4065e5c31af7Sopenharmony_ci const VkPipelineColorBlendAttachmentState attBlendState = 4066e5c31af7Sopenharmony_ci { 4067e5c31af7Sopenharmony_ci DE_FALSE, // deUint32 blendEnable; 4068e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // VkBlend srcBlendColor; 4069e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // VkBlend destBlendColor; 4070e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // VkBlendOp blendOpColor; 4071e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // VkBlend srcBlendAlpha; 4072e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // VkBlend destBlendAlpha; 4073e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // VkBlendOp blendOpAlpha; 4074e5c31af7Sopenharmony_ci (VK_COLOR_COMPONENT_R_BIT| 4075e5c31af7Sopenharmony_ci VK_COLOR_COMPONENT_G_BIT| 4076e5c31af7Sopenharmony_ci VK_COLOR_COMPONENT_B_BIT| 4077e5c31af7Sopenharmony_ci VK_COLOR_COMPONENT_A_BIT), // VkChannelFlags channelWriteMask; 4078e5c31af7Sopenharmony_ci }; 4079e5c31af7Sopenharmony_ci attBlendStates.push_back(attBlendState); 4080e5c31af7Sopenharmony_ci 4081e5c31af7Sopenharmony_ci if (needInterface) 4082e5c31af7Sopenharmony_ci attBlendStates.push_back(attBlendState); 4083e5c31af7Sopenharmony_ci 4084e5c31af7Sopenharmony_ci VkPipelineColorBlendStateCreateInfo blendParams = 4085e5c31af7Sopenharmony_ci { 4086e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 4087e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4088e5c31af7Sopenharmony_ci (VkPipelineColorBlendStateCreateFlags)0, 4089e5c31af7Sopenharmony_ci DE_FALSE, // VkBool32 logicOpEnable; 4090e5c31af7Sopenharmony_ci VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 4091e5c31af7Sopenharmony_ci 1u, // deUint32 attachmentCount; 4092e5c31af7Sopenharmony_ci attBlendStates.data(), // const VkPipelineColorBlendAttachmentState* pAttachments; 4093e5c31af7Sopenharmony_ci { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConst[4]; 4094e5c31af7Sopenharmony_ci }; 4095e5c31af7Sopenharmony_ci if (needInterface) 4096e5c31af7Sopenharmony_ci { 4097e5c31af7Sopenharmony_ci blendParams.attachmentCount += 1; 4098e5c31af7Sopenharmony_ci } 4099e5c31af7Sopenharmony_ci const VkPipelineTessellationStateCreateInfo tessellationState = 4100e5c31af7Sopenharmony_ci { 4101e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, 4102e5c31af7Sopenharmony_ci DE_NULL, 4103e5c31af7Sopenharmony_ci (VkPipelineTessellationStateCreateFlags)0, 4104e5c31af7Sopenharmony_ci 3u 4105e5c31af7Sopenharmony_ci }; 4106e5c31af7Sopenharmony_ci 4107e5c31af7Sopenharmony_ci const VkDynamicState dynamicStates[] = 4108e5c31af7Sopenharmony_ci { 4109e5c31af7Sopenharmony_ci VK_DYNAMIC_STATE_SCISSOR 4110e5c31af7Sopenharmony_ci }; 4111e5c31af7Sopenharmony_ci 4112e5c31af7Sopenharmony_ci const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo = 4113e5c31af7Sopenharmony_ci { 4114e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType 4115e5c31af7Sopenharmony_ci DE_NULL, // pNext 4116e5c31af7Sopenharmony_ci 0u, // flags 4117e5c31af7Sopenharmony_ci DE_LENGTH_OF_ARRAY(dynamicStates), // dynamicStateCount 4118e5c31af7Sopenharmony_ci dynamicStates // pDynamicStates 4119e5c31af7Sopenharmony_ci }; 4120e5c31af7Sopenharmony_ci 4121e5c31af7Sopenharmony_ci const VkPipelineTessellationStateCreateInfo* tessellationInfo = hasTessellation ? &tessellationState: DE_NULL; 4122e5c31af7Sopenharmony_ci const VkGraphicsPipelineCreateInfo pipelineParams = 4123e5c31af7Sopenharmony_ci { 4124e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 4125e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4126e5c31af7Sopenharmony_ci 0u, // VkPipelineCreateFlags flags; 4127e5c31af7Sopenharmony_ci (deUint32)shaderStageParams.size(), // deUint32 stageCount; 4128e5c31af7Sopenharmony_ci &shaderStageParams[0], // const VkPipelineShaderStageCreateInfo* pStages; 4129e5c31af7Sopenharmony_ci &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 4130e5c31af7Sopenharmony_ci &inputAssemblyParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 4131e5c31af7Sopenharmony_ci tessellationInfo, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 4132e5c31af7Sopenharmony_ci &viewportParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 4133e5c31af7Sopenharmony_ci &rasterParams, // const VkPipelineRasterStateCreateInfo* pRasterState; 4134e5c31af7Sopenharmony_ci &multisampleParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 4135e5c31af7Sopenharmony_ci &depthStencilParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 4136e5c31af7Sopenharmony_ci &blendParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 4137e5c31af7Sopenharmony_ci &dynamicStateCreateInfo, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 4138e5c31af7Sopenharmony_ci *pipelineLayout, // VkPipelineLayout layout; 4139e5c31af7Sopenharmony_ci *renderPass, // VkRenderPass renderPass; 4140e5c31af7Sopenharmony_ci 0u, // deUint32 subpass; 4141e5c31af7Sopenharmony_ci DE_NULL, // VkPipeline basePipelineHandle; 4142e5c31af7Sopenharmony_ci 0u, // deInt32 basePipelineIndex; 4143e5c31af7Sopenharmony_ci }; 4144e5c31af7Sopenharmony_ci 4145e5c31af7Sopenharmony_ci const Unique<VkPipeline> pipeline (createGraphicsPipeline(vk, device, DE_NULL, &pipelineParams)); 4146e5c31af7Sopenharmony_ci 4147e5c31af7Sopenharmony_ci if (needInterface) 4148e5c31af7Sopenharmony_ci { 4149e5c31af7Sopenharmony_ci const VkImageViewCreateInfo fragOutputViewParams = 4150e5c31af7Sopenharmony_ci { 4151e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 4152e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4153e5c31af7Sopenharmony_ci 0u, // VkImageViewCreateFlags flags; 4154e5c31af7Sopenharmony_ci *fragOutputImage, // VkImage image; 4155e5c31af7Sopenharmony_ci VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 4156e5c31af7Sopenharmony_ci instance.interfaces.getOutputType().getVkFormat(), // VkFormat format; 4157e5c31af7Sopenharmony_ci { 4158e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_R, 4159e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_G, 4160e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_B, 4161e5c31af7Sopenharmony_ci VK_COMPONENT_SWIZZLE_A 4162e5c31af7Sopenharmony_ci }, // VkChannelMapping channels; 4163e5c31af7Sopenharmony_ci { 4164e5c31af7Sopenharmony_ci VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4165e5c31af7Sopenharmony_ci 0u, // deUint32 baseMipLevel; 4166e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 4167e5c31af7Sopenharmony_ci 0u, // deUint32 baseArrayLayer; 4168e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 4169e5c31af7Sopenharmony_ci }, // VkImageSubresourceRange subresourceRange; 4170e5c31af7Sopenharmony_ci }; 4171e5c31af7Sopenharmony_ci fragOutputImageView = createImageView(vk, device, &fragOutputViewParams); 4172e5c31af7Sopenharmony_ci attViews.push_back(*fragOutputImageView); 4173e5c31af7Sopenharmony_ci } 4174e5c31af7Sopenharmony_ci 4175e5c31af7Sopenharmony_ci // Framebuffer 4176e5c31af7Sopenharmony_ci VkFramebufferCreateInfo framebufferParams = 4177e5c31af7Sopenharmony_ci { 4178e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 4179e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4180e5c31af7Sopenharmony_ci (VkFramebufferCreateFlags)0, 4181e5c31af7Sopenharmony_ci *renderPass, // VkRenderPass renderPass; 4182e5c31af7Sopenharmony_ci 1u, // deUint32 attachmentCount; 4183e5c31af7Sopenharmony_ci attViews.data(), // const VkImageView* pAttachments; 4184e5c31af7Sopenharmony_ci (deUint32)renderSize.x(), // deUint32 width; 4185e5c31af7Sopenharmony_ci (deUint32)renderSize.y(), // deUint32 height; 4186e5c31af7Sopenharmony_ci 1u, // deUint32 layers; 4187e5c31af7Sopenharmony_ci }; 4188e5c31af7Sopenharmony_ci 4189e5c31af7Sopenharmony_ci if (needInterface) 4190e5c31af7Sopenharmony_ci framebufferParams.attachmentCount += 1; 4191e5c31af7Sopenharmony_ci 4192e5c31af7Sopenharmony_ci const Unique<VkFramebuffer> framebuffer (createFramebuffer(vk, device, &framebufferParams)); 4193e5c31af7Sopenharmony_ci 4194e5c31af7Sopenharmony_ci bool firstPass = true; 4195e5c31af7Sopenharmony_ci 4196e5c31af7Sopenharmony_ci for (int x = 0; x < numRenderSegments; x++) 4197e5c31af7Sopenharmony_ci { 4198e5c31af7Sopenharmony_ci for (int y = 0; y < numRenderSegments; y++) 4199e5c31af7Sopenharmony_ci { 4200e5c31af7Sopenharmony_ci // Record commands 4201e5c31af7Sopenharmony_ci beginCommandBuffer(vk, *cmdBuf); 4202e5c31af7Sopenharmony_ci 4203e5c31af7Sopenharmony_ci if (firstPass) 4204e5c31af7Sopenharmony_ci { 4205e5c31af7Sopenharmony_ci const VkMemoryBarrier vertFlushBarrier = 4206e5c31af7Sopenharmony_ci { 4207e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType; 4208e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4209e5c31af7Sopenharmony_ci VK_ACCESS_HOST_WRITE_BIT, // VkMemoryOutputFlags outputMask; 4210e5c31af7Sopenharmony_ci VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, // VkMemoryInputFlags inputMask; 4211e5c31af7Sopenharmony_ci }; 4212e5c31af7Sopenharmony_ci vector<VkImageMemoryBarrier> colorAttBarriers; 4213e5c31af7Sopenharmony_ci 4214e5c31af7Sopenharmony_ci VkImageMemoryBarrier imgBarrier = 4215e5c31af7Sopenharmony_ci { 4216e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4217e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4218e5c31af7Sopenharmony_ci 0u, // VkMemoryOutputFlags outputMask; 4219e5c31af7Sopenharmony_ci VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryInputFlags inputMask; 4220e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 4221e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 4222e5c31af7Sopenharmony_ci queueFamilyIndex, // deUint32 srcQueueFamilyIndex; 4223e5c31af7Sopenharmony_ci queueFamilyIndex, // deUint32 destQueueFamilyIndex; 4224e5c31af7Sopenharmony_ci *image, // VkImage image; 4225e5c31af7Sopenharmony_ci { 4226e5c31af7Sopenharmony_ci VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 4227e5c31af7Sopenharmony_ci 0u, // deUint32 baseMipLevel; 4228e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 4229e5c31af7Sopenharmony_ci 0u, // deUint32 baseArraySlice; 4230e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 4231e5c31af7Sopenharmony_ci } // VkImageSubresourceRange subresourceRange; 4232e5c31af7Sopenharmony_ci }; 4233e5c31af7Sopenharmony_ci colorAttBarriers.push_back(imgBarrier); 4234e5c31af7Sopenharmony_ci if (needInterface) 4235e5c31af7Sopenharmony_ci { 4236e5c31af7Sopenharmony_ci imgBarrier.image = *fragOutputImage; 4237e5c31af7Sopenharmony_ci colorAttBarriers.push_back(imgBarrier); 4238e5c31af7Sopenharmony_ci 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()); 4239e5c31af7Sopenharmony_ci } 4240e5c31af7Sopenharmony_ci else 4241e5c31af7Sopenharmony_ci { 4242e5c31af7Sopenharmony_ci 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()); 4243e5c31af7Sopenharmony_ci } 4244e5c31af7Sopenharmony_ci } 4245e5c31af7Sopenharmony_ci 4246e5c31af7Sopenharmony_ci { 4247e5c31af7Sopenharmony_ci vector<VkClearValue> clearValue; 4248e5c31af7Sopenharmony_ci clearValue.push_back(makeClearValueColorF32(defaulClearColor[0], defaulClearColor[1], defaulClearColor[2], defaulClearColor[3])); 4249e5c31af7Sopenharmony_ci if (needInterface) 4250e5c31af7Sopenharmony_ci { 4251e5c31af7Sopenharmony_ci clearValue.push_back(makeClearValueColorU32(0, 0, 0, 0)); 4252e5c31af7Sopenharmony_ci } 4253e5c31af7Sopenharmony_ci 4254e5c31af7Sopenharmony_ci 4255e5c31af7Sopenharmony_ci vk::VkRect2D scissor = makeRect2D(x * renderDimension, y * renderDimension, renderDimension, renderDimension); 4256e5c31af7Sopenharmony_ci vk.cmdSetScissor(*cmdBuf, 0u, 1u, &scissor); 4257e5c31af7Sopenharmony_ci 4258e5c31af7Sopenharmony_ci beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, scissor, (deUint32)clearValue.size(), clearValue.data()); 4259e5c31af7Sopenharmony_ci } 4260e5c31af7Sopenharmony_ci 4261e5c31af7Sopenharmony_ci vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 4262e5c31af7Sopenharmony_ci { 4263e5c31af7Sopenharmony_ci const VkDeviceSize bindingOffset = 0; 4264e5c31af7Sopenharmony_ci vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset); 4265e5c31af7Sopenharmony_ci } 4266e5c31af7Sopenharmony_ci if (needInterface) 4267e5c31af7Sopenharmony_ci { 4268e5c31af7Sopenharmony_ci const VkDeviceSize bindingOffset = 0; 4269e5c31af7Sopenharmony_ci vk.cmdBindVertexBuffers(*cmdBuf, 1u, 1u, &vertexInputBuffer.get(), &bindingOffset); 4270e5c31af7Sopenharmony_ci } 4271e5c31af7Sopenharmony_ci if (hasPushConstants) 4272e5c31af7Sopenharmony_ci { 4273e5c31af7Sopenharmony_ci vector<deUint8> pushConstantsBytes; 4274e5c31af7Sopenharmony_ci instance.pushConstants.getBuffer()->getBytes(pushConstantsBytes); 4275e5c31af7Sopenharmony_ci 4276e5c31af7Sopenharmony_ci const deUint32 size = static_cast<deUint32>(pushConstantsBytes.size()); 4277e5c31af7Sopenharmony_ci const void* data = &pushConstantsBytes.front(); 4278e5c31af7Sopenharmony_ci 4279e5c31af7Sopenharmony_ci vk.cmdPushConstants(*cmdBuf, *pipelineLayout, VK_SHADER_STAGE_ALL_GRAPHICS, 0, size, data); 4280e5c31af7Sopenharmony_ci } 4281e5c31af7Sopenharmony_ci if (numResources != 0) 4282e5c31af7Sopenharmony_ci { 4283e5c31af7Sopenharmony_ci // Bind to set number 0. 4284e5c31af7Sopenharmony_ci vk.cmdBindDescriptorSets(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &rawSet, 0, DE_NULL); 4285e5c31af7Sopenharmony_ci } 4286e5c31af7Sopenharmony_ci vk.cmdDraw(*cmdBuf, deUint32(vertexCount), 1u /*run pipeline once*/, 0u /*first vertex*/, 0u /*first instanceIndex*/); 4287e5c31af7Sopenharmony_ci endRenderPass(vk, *cmdBuf); 4288e5c31af7Sopenharmony_ci 4289e5c31af7Sopenharmony_ci if (x == numRenderSegments - 1 && y == numRenderSegments - 1) 4290e5c31af7Sopenharmony_ci { 4291e5c31af7Sopenharmony_ci { 4292e5c31af7Sopenharmony_ci vector<VkImageMemoryBarrier> renderFinishBarrier; 4293e5c31af7Sopenharmony_ci VkImageMemoryBarrier imgBarrier = 4294e5c31af7Sopenharmony_ci { 4295e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 4296e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4297e5c31af7Sopenharmony_ci VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkMemoryOutputFlags outputMask; 4298e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_READ_BIT, // VkMemoryInputFlags inputMask; 4299e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout oldLayout; 4300e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout; 4301e5c31af7Sopenharmony_ci queueFamilyIndex, // deUint32 srcQueueFamilyIndex; 4302e5c31af7Sopenharmony_ci queueFamilyIndex, // deUint32 destQueueFamilyIndex; 4303e5c31af7Sopenharmony_ci *image, // VkImage image; 4304e5c31af7Sopenharmony_ci { 4305e5c31af7Sopenharmony_ci VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 4306e5c31af7Sopenharmony_ci 0u, // deUint32 baseMipLevel; 4307e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 4308e5c31af7Sopenharmony_ci 0u, // deUint32 baseArraySlice; 4309e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 4310e5c31af7Sopenharmony_ci } // VkImageSubresourceRange subresourceRange; 4311e5c31af7Sopenharmony_ci }; 4312e5c31af7Sopenharmony_ci renderFinishBarrier.push_back(imgBarrier); 4313e5c31af7Sopenharmony_ci 4314e5c31af7Sopenharmony_ci if (needInterface) 4315e5c31af7Sopenharmony_ci { 4316e5c31af7Sopenharmony_ci imgBarrier.image = *fragOutputImage; 4317e5c31af7Sopenharmony_ci renderFinishBarrier.push_back(imgBarrier); 4318e5c31af7Sopenharmony_ci 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()); 4319e5c31af7Sopenharmony_ci } 4320e5c31af7Sopenharmony_ci else 4321e5c31af7Sopenharmony_ci { 4322e5c31af7Sopenharmony_ci 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()); 4323e5c31af7Sopenharmony_ci } 4324e5c31af7Sopenharmony_ci } 4325e5c31af7Sopenharmony_ci 4326e5c31af7Sopenharmony_ci { 4327e5c31af7Sopenharmony_ci const VkBufferImageCopy copyParams = 4328e5c31af7Sopenharmony_ci { 4329e5c31af7Sopenharmony_ci (VkDeviceSize)0u, // VkDeviceSize bufferOffset; 4330e5c31af7Sopenharmony_ci (deUint32)renderSize.x(), // deUint32 bufferRowLength; 4331e5c31af7Sopenharmony_ci (deUint32)renderSize.y(), // deUint32 bufferImageHeight; 4332e5c31af7Sopenharmony_ci { 4333e5c31af7Sopenharmony_ci VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspect aspect; 4334e5c31af7Sopenharmony_ci 0u, // deUint32 mipLevel; 4335e5c31af7Sopenharmony_ci 0u, // deUint32 arrayLayer; 4336e5c31af7Sopenharmony_ci 1u, // deUint32 arraySize; 4337e5c31af7Sopenharmony_ci }, // VkImageSubresourceCopy imageSubresource; 4338e5c31af7Sopenharmony_ci { 0u, 0u, 0u }, // VkOffset3D imageOffset; 4339e5c31af7Sopenharmony_ci { renderSize.x(), renderSize.y(), 1u } 4340e5c31af7Sopenharmony_ci }; 4341e5c31af7Sopenharmony_ci vk.cmdCopyImageToBuffer(*cmdBuf, *image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *readImageBuffer, 1u, ©Params); 4342e5c31af7Sopenharmony_ci 4343e5c31af7Sopenharmony_ci if (needInterface) 4344e5c31af7Sopenharmony_ci { 4345e5c31af7Sopenharmony_ci vk.cmdCopyImageToBuffer(*cmdBuf, *fragOutputImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *fragOutputBuffer, 1u, ©Params); 4346e5c31af7Sopenharmony_ci } 4347e5c31af7Sopenharmony_ci } 4348e5c31af7Sopenharmony_ci 4349e5c31af7Sopenharmony_ci { 4350e5c31af7Sopenharmony_ci vector<VkBufferMemoryBarrier> cpFinishBarriers; 4351e5c31af7Sopenharmony_ci VkBufferMemoryBarrier copyFinishBarrier = 4352e5c31af7Sopenharmony_ci { 4353e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 4354e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 4355e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, // VkMemoryOutputFlags outputMask; 4356e5c31af7Sopenharmony_ci VK_ACCESS_HOST_READ_BIT, // VkMemoryInputFlags inputMask; 4357e5c31af7Sopenharmony_ci queueFamilyIndex, // deUint32 srcQueueFamilyIndex; 4358e5c31af7Sopenharmony_ci queueFamilyIndex, // deUint32 destQueueFamilyIndex; 4359e5c31af7Sopenharmony_ci *readImageBuffer, // VkBuffer buffer; 4360e5c31af7Sopenharmony_ci 0u, // VkDeviceSize offset; 4361e5c31af7Sopenharmony_ci imageSizeBytes // VkDeviceSize size; 4362e5c31af7Sopenharmony_ci }; 4363e5c31af7Sopenharmony_ci cpFinishBarriers.push_back(copyFinishBarrier); 4364e5c31af7Sopenharmony_ci 4365e5c31af7Sopenharmony_ci if (needInterface) 4366e5c31af7Sopenharmony_ci { 4367e5c31af7Sopenharmony_ci copyFinishBarrier.buffer = *fragOutputBuffer; 4368e5c31af7Sopenharmony_ci copyFinishBarrier.size = VK_WHOLE_SIZE; 4369e5c31af7Sopenharmony_ci cpFinishBarriers.push_back(copyFinishBarrier); 4370e5c31af7Sopenharmony_ci 4371e5c31af7Sopenharmony_ci 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); 4372e5c31af7Sopenharmony_ci } 4373e5c31af7Sopenharmony_ci else 4374e5c31af7Sopenharmony_ci { 4375e5c31af7Sopenharmony_ci 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); 4376e5c31af7Sopenharmony_ci } 4377e5c31af7Sopenharmony_ci } 4378e5c31af7Sopenharmony_ci } 4379e5c31af7Sopenharmony_ci 4380e5c31af7Sopenharmony_ci endCommandBuffer(vk, *cmdBuf); 4381e5c31af7Sopenharmony_ci 4382e5c31af7Sopenharmony_ci if (firstPass) 4383e5c31af7Sopenharmony_ci { 4384e5c31af7Sopenharmony_ci // Upload vertex data 4385e5c31af7Sopenharmony_ci { 4386e5c31af7Sopenharmony_ci void* vertexBufPtr = vertexBufferMemory->getHostPtr(); 4387e5c31af7Sopenharmony_ci deMemcpy(vertexBufPtr, &vertexData[0], vertexDataSize); 4388e5c31af7Sopenharmony_ci flushAlloc(vk, device, *vertexBufferMemory); 4389e5c31af7Sopenharmony_ci } 4390e5c31af7Sopenharmony_ci 4391e5c31af7Sopenharmony_ci if (needInterface) 4392e5c31af7Sopenharmony_ci { 4393e5c31af7Sopenharmony_ci vector<deUint8> inputBufferBytes; 4394e5c31af7Sopenharmony_ci instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes); 4395e5c31af7Sopenharmony_ci 4396e5c31af7Sopenharmony_ci const deUint32 typNumBytes = instance.interfaces.getInputType().getNumBytes(); 4397e5c31af7Sopenharmony_ci const deUint32 bufNumBytes = static_cast<deUint32>(inputBufferBytes.size()); 4398e5c31af7Sopenharmony_ci 4399e5c31af7Sopenharmony_ci // Require that the test instantation provides four output values. 4400e5c31af7Sopenharmony_ci DE_ASSERT(bufNumBytes == 4 * typNumBytes); 4401e5c31af7Sopenharmony_ci 4402e5c31af7Sopenharmony_ci // We have four triangles. Because interpolation happens before executing the fragment shader, 4403e5c31af7Sopenharmony_ci // we need to provide the same vertex attribute for the same triangle. That means, duplicate each 4404e5c31af7Sopenharmony_ci // value three times for all four values. 4405e5c31af7Sopenharmony_ci 4406e5c31af7Sopenharmony_ci const deUint8* provided = static_cast<const deUint8*>(&inputBufferBytes.front()); 4407e5c31af7Sopenharmony_ci vector<deUint8> data; 4408e5c31af7Sopenharmony_ci 4409e5c31af7Sopenharmony_ci data.reserve(3 * bufNumBytes); 4410e5c31af7Sopenharmony_ci 4411e5c31af7Sopenharmony_ci for (deUint32 offset = 0; offset < bufNumBytes; offset += typNumBytes) 4412e5c31af7Sopenharmony_ci for (deUint32 vertexNdx = 0; vertexNdx < 3; ++vertexNdx) 4413e5c31af7Sopenharmony_ci for (deUint32 byteNdx = 0; byteNdx < typNumBytes; ++byteNdx) 4414e5c31af7Sopenharmony_ci data.push_back(provided[offset + byteNdx]); 4415e5c31af7Sopenharmony_ci 4416e5c31af7Sopenharmony_ci deMemcpy(vertexInputMemory->getHostPtr(), data.data(), data.size()); 4417e5c31af7Sopenharmony_ci 4418e5c31af7Sopenharmony_ci flushAlloc(vk, device, *vertexInputMemory); 4419e5c31af7Sopenharmony_ci 4420e5c31af7Sopenharmony_ci } 4421e5c31af7Sopenharmony_ci firstPass = false; 4422e5c31af7Sopenharmony_ci } 4423e5c31af7Sopenharmony_ci 4424e5c31af7Sopenharmony_ci // Submit & wait for completion 4425e5c31af7Sopenharmony_ci submitCommandsAndWait(vk, device, queue, cmdBuf.get()); 4426e5c31af7Sopenharmony_ci context.resetCommandPoolForVKSC(device, *cmdPool); 4427e5c31af7Sopenharmony_ci } 4428e5c31af7Sopenharmony_ci } 4429e5c31af7Sopenharmony_ci 4430e5c31af7Sopenharmony_ci const void* imagePtr = readImageBufferMemory->getHostPtr(); 4431e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess pixelBuffer(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 4432e5c31af7Sopenharmony_ci renderSize.x(), renderSize.y(), 1, imagePtr); 4433e5c31af7Sopenharmony_ci // Log image 4434e5c31af7Sopenharmony_ci invalidateAlloc(vk, device, *readImageBufferMemory); 4435e5c31af7Sopenharmony_ci context.getTestContext().getLog() << TestLog::Image("Result", "Result", pixelBuffer); 4436e5c31af7Sopenharmony_ci 4437e5c31af7Sopenharmony_ci if (needInterface) 4438e5c31af7Sopenharmony_ci invalidateAlloc(vk, device, *fragOutputMemory); 4439e5c31af7Sopenharmony_ci 4440e5c31af7Sopenharmony_ci // Make sure all output resources are ready. 4441e5c31af7Sopenharmony_ci for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx) 4442e5c31af7Sopenharmony_ci invalidateAlloc(vk, device, *outResourceMemories[outputNdx]); 4443e5c31af7Sopenharmony_ci 4444e5c31af7Sopenharmony_ci const RGBA threshold(1, 1, 1, 1); 4445e5c31af7Sopenharmony_ci 4446e5c31af7Sopenharmony_ci const RGBA upperLeft(pixelBuffer.getPixel(1, 1)); 4447e5c31af7Sopenharmony_ci if (!tcu::compareThreshold(upperLeft, instance.outputColors[0], threshold)) 4448e5c31af7Sopenharmony_ci return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper left corner mismatch")); 4449e5c31af7Sopenharmony_ci 4450e5c31af7Sopenharmony_ci const RGBA upperRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, 1)); 4451e5c31af7Sopenharmony_ci if (!tcu::compareThreshold(upperRight, instance.outputColors[1], threshold)) 4452e5c31af7Sopenharmony_ci return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Upper right corner mismatch")); 4453e5c31af7Sopenharmony_ci 4454e5c31af7Sopenharmony_ci const RGBA lowerLeft(pixelBuffer.getPixel(1, pixelBuffer.getHeight() - 1)); 4455e5c31af7Sopenharmony_ci if (!tcu::compareThreshold(lowerLeft, instance.outputColors[2], threshold)) 4456e5c31af7Sopenharmony_ci return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower left corner mismatch")); 4457e5c31af7Sopenharmony_ci 4458e5c31af7Sopenharmony_ci const RGBA lowerRight(pixelBuffer.getPixel(pixelBuffer.getWidth() - 1, pixelBuffer.getHeight() - 1)); 4459e5c31af7Sopenharmony_ci if (!tcu::compareThreshold(lowerRight, instance.outputColors[3], threshold)) 4460e5c31af7Sopenharmony_ci return TestStatus(instance.failResult, instance.getSpecializedFailMessage("Lower right corner mismatch")); 4461e5c31af7Sopenharmony_ci 4462e5c31af7Sopenharmony_ci // Check that the contents in the ouput variable matches expected. 4463e5c31af7Sopenharmony_ci if (needInterface) 4464e5c31af7Sopenharmony_ci { 4465e5c31af7Sopenharmony_ci vector<deUint8> inputBufferBytes; 4466e5c31af7Sopenharmony_ci vector<deUint8> outputBufferBytes; 4467e5c31af7Sopenharmony_ci 4468e5c31af7Sopenharmony_ci instance.interfaces.getInputBuffer()->getBytes(inputBufferBytes); 4469e5c31af7Sopenharmony_ci instance.interfaces.getOutputBuffer()->getBytes(outputBufferBytes); 4470e5c31af7Sopenharmony_ci 4471e5c31af7Sopenharmony_ci const IFDataType& inputType = instance.interfaces.getInputType(); 4472e5c31af7Sopenharmony_ci const IFDataType& outputType = instance.interfaces.getOutputType(); 4473e5c31af7Sopenharmony_ci const void* inputData = &inputBufferBytes.front(); 4474e5c31af7Sopenharmony_ci const void* outputData = &outputBufferBytes.front(); 4475e5c31af7Sopenharmony_ci vector<std::pair<int, int> > positions; 4476e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess fragOutputBufferAccess (outputType.getTextureFormat(), renderSize.x(), renderSize.y(), 1, fragOutputMemory->getHostPtr()); 4477e5c31af7Sopenharmony_ci 4478e5c31af7Sopenharmony_ci positions.push_back(std::make_pair(1, 1)); 4479e5c31af7Sopenharmony_ci positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, 1)); 4480e5c31af7Sopenharmony_ci positions.push_back(std::make_pair(1, fragOutputBufferAccess.getHeight() - 1)); 4481e5c31af7Sopenharmony_ci positions.push_back(std::make_pair(fragOutputBufferAccess.getWidth() - 1, fragOutputBufferAccess.getHeight() - 1)); 4482e5c31af7Sopenharmony_ci 4483e5c31af7Sopenharmony_ci for (deUint32 posNdx = 0; posNdx < positions.size(); ++posNdx) 4484e5c31af7Sopenharmony_ci { 4485e5c31af7Sopenharmony_ci const int x = positions[posNdx].first; 4486e5c31af7Sopenharmony_ci const int y = positions[posNdx].second; 4487e5c31af7Sopenharmony_ci bool equal = true; 4488e5c31af7Sopenharmony_ci 4489e5c31af7Sopenharmony_ci if (outputType.elementType == NUMBERTYPE_FLOAT32) 4490e5c31af7Sopenharmony_ci { 4491e5c31af7Sopenharmony_ci const float* expected = static_cast<const float*>(outputData) + posNdx * outputType.numElements; 4492e5c31af7Sopenharmony_ci const float* actual = static_cast<const float*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4493e5c31af7Sopenharmony_ci 4494e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4495e5c31af7Sopenharmony_ci if (!compare32BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog())) 4496e5c31af7Sopenharmony_ci equal = false; 4497e5c31af7Sopenharmony_ci } 4498e5c31af7Sopenharmony_ci else if (outputType.elementType == NUMBERTYPE_INT32) 4499e5c31af7Sopenharmony_ci { 4500e5c31af7Sopenharmony_ci const deInt32* expected = static_cast<const deInt32*>(outputData) + posNdx * outputType.numElements; 4501e5c31af7Sopenharmony_ci const deInt32* actual = static_cast<const deInt32*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4502e5c31af7Sopenharmony_ci 4503e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4504e5c31af7Sopenharmony_ci if (expected[eleNdx] != actual[eleNdx]) 4505e5c31af7Sopenharmony_ci equal = false; 4506e5c31af7Sopenharmony_ci } 4507e5c31af7Sopenharmony_ci else if (outputType.elementType == NUMBERTYPE_UINT32) 4508e5c31af7Sopenharmony_ci { 4509e5c31af7Sopenharmony_ci const deUint32* expected = static_cast<const deUint32*>(outputData) + posNdx * outputType.numElements; 4510e5c31af7Sopenharmony_ci const deUint32* actual = static_cast<const deUint32*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4511e5c31af7Sopenharmony_ci 4512e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4513e5c31af7Sopenharmony_ci if (expected[eleNdx] != actual[eleNdx]) 4514e5c31af7Sopenharmony_ci equal = false; 4515e5c31af7Sopenharmony_ci } 4516e5c31af7Sopenharmony_ci else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType == NUMBERTYPE_FLOAT64) 4517e5c31af7Sopenharmony_ci { 4518e5c31af7Sopenharmony_ci const double* original = static_cast<const double*>(inputData) + posNdx * outputType.numElements; 4519e5c31af7Sopenharmony_ci const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4520e5c31af7Sopenharmony_ci 4521e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4522e5c31af7Sopenharmony_ci if (!compare16BitFloat64(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog())) 4523e5c31af7Sopenharmony_ci equal = false; 4524e5c31af7Sopenharmony_ci } 4525e5c31af7Sopenharmony_ci else if (outputType.elementType == NUMBERTYPE_FLOAT16 && inputType.elementType != NUMBERTYPE_FLOAT64) 4526e5c31af7Sopenharmony_ci { 4527e5c31af7Sopenharmony_ci if (inputType.elementType == NUMBERTYPE_FLOAT16) 4528e5c31af7Sopenharmony_ci { 4529e5c31af7Sopenharmony_ci const deFloat16* original = static_cast<const deFloat16*>(inputData) + posNdx * outputType.numElements; 4530e5c31af7Sopenharmony_ci const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4531e5c31af7Sopenharmony_ci 4532e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4533e5c31af7Sopenharmony_ci if (!compare16BitFloat(original[eleNdx], actual[eleNdx], context.getTestContext().getLog())) 4534e5c31af7Sopenharmony_ci equal = false; 4535e5c31af7Sopenharmony_ci } 4536e5c31af7Sopenharmony_ci else 4537e5c31af7Sopenharmony_ci { 4538e5c31af7Sopenharmony_ci const float* original = static_cast<const float*>(inputData) + posNdx * outputType.numElements; 4539e5c31af7Sopenharmony_ci const deFloat16* actual = static_cast<const deFloat16*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4540e5c31af7Sopenharmony_ci 4541e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4542e5c31af7Sopenharmony_ci if (!compare16BitFloat(original[eleNdx], actual[eleNdx], instance.interfaces.getRoundingMode(), context.getTestContext().getLog())) 4543e5c31af7Sopenharmony_ci equal = false; 4544e5c31af7Sopenharmony_ci } 4545e5c31af7Sopenharmony_ci } 4546e5c31af7Sopenharmony_ci else if (outputType.elementType == NUMBERTYPE_INT16) 4547e5c31af7Sopenharmony_ci { 4548e5c31af7Sopenharmony_ci const deInt16* expected = static_cast<const deInt16*>(outputData) + posNdx * outputType.numElements; 4549e5c31af7Sopenharmony_ci const deInt16* actual = static_cast<const deInt16*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4550e5c31af7Sopenharmony_ci 4551e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4552e5c31af7Sopenharmony_ci if (expected[eleNdx] != actual[eleNdx]) 4553e5c31af7Sopenharmony_ci equal = false; 4554e5c31af7Sopenharmony_ci } 4555e5c31af7Sopenharmony_ci else if (outputType.elementType == NUMBERTYPE_UINT16) 4556e5c31af7Sopenharmony_ci { 4557e5c31af7Sopenharmony_ci const deUint16* expected = static_cast<const deUint16*>(outputData) + posNdx * outputType.numElements; 4558e5c31af7Sopenharmony_ci const deUint16* actual = static_cast<const deUint16*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4559e5c31af7Sopenharmony_ci 4560e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4561e5c31af7Sopenharmony_ci if (expected[eleNdx] != actual[eleNdx]) 4562e5c31af7Sopenharmony_ci equal = false; 4563e5c31af7Sopenharmony_ci } 4564e5c31af7Sopenharmony_ci else if (outputType.elementType == NUMBERTYPE_FLOAT64) 4565e5c31af7Sopenharmony_ci { 4566e5c31af7Sopenharmony_ci const double* expected = static_cast<const double*>(outputData) + posNdx * outputType.numElements; 4567e5c31af7Sopenharmony_ci const double* actual = static_cast<const double*>(fragOutputBufferAccess.getPixelPtr(x, y)); 4568e5c31af7Sopenharmony_ci 4569e5c31af7Sopenharmony_ci for (deUint32 eleNdx = 0; eleNdx < outputType.numElements; ++eleNdx) 4570e5c31af7Sopenharmony_ci if (!compare64BitFloat(expected[eleNdx], actual[eleNdx], context.getTestContext().getLog())) 4571e5c31af7Sopenharmony_ci equal = false; 4572e5c31af7Sopenharmony_ci } 4573e5c31af7Sopenharmony_ci else { 4574e5c31af7Sopenharmony_ci DE_ASSERT(0 && "unhandled type"); 4575e5c31af7Sopenharmony_ci } 4576e5c31af7Sopenharmony_ci 4577e5c31af7Sopenharmony_ci if (!equal) 4578e5c31af7Sopenharmony_ci return TestStatus(instance.failResult, instance.getSpecializedFailMessage("fragment output dat point #" + numberToString(posNdx) + " mismatch")); 4579e5c31af7Sopenharmony_ci } 4580e5c31af7Sopenharmony_ci } 4581e5c31af7Sopenharmony_ci 4582e5c31af7Sopenharmony_ci // Check the contents in output resources match with expected. 4583e5c31af7Sopenharmony_ci for (deUint32 outputNdx = 0; outputNdx < numOutResources; ++outputNdx) 4584e5c31af7Sopenharmony_ci { 4585e5c31af7Sopenharmony_ci const BufferSp& expected = instance.resources.outputs[outputNdx].getBuffer(); 4586e5c31af7Sopenharmony_ci 4587e5c31af7Sopenharmony_ci if (instance.resources.verifyIO != DE_NULL) 4588e5c31af7Sopenharmony_ci { 4589e5c31af7Sopenharmony_ci if (!(*instance.resources.verifyIO)(instance.resources.inputs, outResourceMemories, instance.resources.outputs, context.getTestContext().getLog())) 4590e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Resource returned doesn't match with expected"); 4591e5c31af7Sopenharmony_ci } 4592e5c31af7Sopenharmony_ci else 4593e5c31af7Sopenharmony_ci { 4594e5c31af7Sopenharmony_ci vector<deUint8> expectedBytes; 4595e5c31af7Sopenharmony_ci expected->getBytes(expectedBytes); 4596e5c31af7Sopenharmony_ci 4597e5c31af7Sopenharmony_ci if (deMemCmp(&expectedBytes.front(), outResourceMemories[outputNdx]->getHostPtr(), expectedBytes.size())) 4598e5c31af7Sopenharmony_ci { 4599e5c31af7Sopenharmony_ci const size_t numExpectedEntries = expectedBytes.size() / sizeof(float); 4600e5c31af7Sopenharmony_ci float* expectedFloats = reinterpret_cast<float*>(&expectedBytes.front()); 4601e5c31af7Sopenharmony_ci float* outputFloats = reinterpret_cast<float*>(outResourceMemories[outputNdx]->getHostPtr()); 4602e5c31af7Sopenharmony_ci float diff = 0.0f; 4603e5c31af7Sopenharmony_ci deUint32 bitDiff = 0; 4604e5c31af7Sopenharmony_ci 4605e5c31af7Sopenharmony_ci for (size_t expectedNdx = 0; expectedNdx < numExpectedEntries; ++expectedNdx) 4606e5c31af7Sopenharmony_ci { 4607e5c31af7Sopenharmony_ci // RTZ and RNE can introduce a difference of a single ULP 4608e5c31af7Sopenharmony_ci // The RTZ output will always be either equal or lower than the RNE expected, 4609e5c31af7Sopenharmony_ci // so perform a bitwise subtractraction and check for the ULP difference 4610e5c31af7Sopenharmony_ci bitDiff = *reinterpret_cast<deUint32*>(&expectedFloats[expectedNdx]) - *reinterpret_cast<deUint32*>(&outputFloats[expectedNdx]); 4611e5c31af7Sopenharmony_ci 4612e5c31af7Sopenharmony_ci // Allow a maximum of 1 ULP difference to account for RTZ rounding 4613e5c31af7Sopenharmony_ci if (bitDiff & (~0x1)) 4614e5c31af7Sopenharmony_ci { 4615e5c31af7Sopenharmony_ci // Note: RTZ/RNE rounding leniency isn't applied for the checks below: 4616e5c31af7Sopenharmony_ci 4617e5c31af7Sopenharmony_ci // Some *variable_pointers* tests store counters in buffer 4618e5c31af7Sopenharmony_ci // whose value may vary if the same shader may be executed for multiple times 4619e5c31af7Sopenharmony_ci // in this case the output value can be expected value + non-negative integer N 4620e5c31af7Sopenharmony_ci if (instance.customizedStages == VK_SHADER_STAGE_VERTEX_BIT || 4621e5c31af7Sopenharmony_ci instance.customizedStages == VK_SHADER_STAGE_GEOMETRY_BIT || 4622e5c31af7Sopenharmony_ci instance.customizedStages == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT || 4623e5c31af7Sopenharmony_ci instance.customizedStages == VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) 4624e5c31af7Sopenharmony_ci { 4625e5c31af7Sopenharmony_ci if (deFloatIsInf(outputFloats[expectedNdx]) || deFloatIsNaN(outputFloats[expectedNdx])) 4626e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Value returned is invalid"); 4627e5c31af7Sopenharmony_ci 4628e5c31af7Sopenharmony_ci diff = outputFloats[expectedNdx] - expectedFloats[expectedNdx]; 4629e5c31af7Sopenharmony_ci deUint32 intDiff = static_cast<deUint32>(diff); 4630e5c31af7Sopenharmony_ci 4631e5c31af7Sopenharmony_ci if ((diff < 0.0f) || (expectedFloats[expectedNdx] + static_cast<float>(intDiff)) != outputFloats[expectedNdx]) 4632e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Value returned should be equal to expected value plus non-negative integer"); 4633e5c31af7Sopenharmony_ci } 4634e5c31af7Sopenharmony_ci else 4635e5c31af7Sopenharmony_ci { 4636e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Resource returned should be equal to expected, allowing for RTZ/RNE rounding"); 4637e5c31af7Sopenharmony_ci } 4638e5c31af7Sopenharmony_ci } 4639e5c31af7Sopenharmony_ci } 4640e5c31af7Sopenharmony_ci } 4641e5c31af7Sopenharmony_ci 4642e5c31af7Sopenharmony_ci } 4643e5c31af7Sopenharmony_ci } 4644e5c31af7Sopenharmony_ci 4645e5c31af7Sopenharmony_ci return TestStatus::pass("Rendered output matches input"); 4646e5c31af7Sopenharmony_ci} 4647e5c31af7Sopenharmony_ci 4648e5c31af7Sopenharmony_ciconst vector<ShaderElement>& getVertFragPipelineStages (void) 4649e5c31af7Sopenharmony_ci{ 4650e5c31af7Sopenharmony_ci static vector<ShaderElement> vertFragPipelineStages; 4651e5c31af7Sopenharmony_ci if(vertFragPipelineStages.empty()) 4652e5c31af7Sopenharmony_ci { 4653e5c31af7Sopenharmony_ci vertFragPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT)); 4654e5c31af7Sopenharmony_ci vertFragPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT)); 4655e5c31af7Sopenharmony_ci } 4656e5c31af7Sopenharmony_ci return vertFragPipelineStages; 4657e5c31af7Sopenharmony_ci} 4658e5c31af7Sopenharmony_ci 4659e5c31af7Sopenharmony_ciconst vector<ShaderElement>& getTessPipelineStages (void) 4660e5c31af7Sopenharmony_ci{ 4661e5c31af7Sopenharmony_ci static vector<ShaderElement> tessPipelineStages; 4662e5c31af7Sopenharmony_ci if(tessPipelineStages.empty()) 4663e5c31af7Sopenharmony_ci { 4664e5c31af7Sopenharmony_ci tessPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT)); 4665e5c31af7Sopenharmony_ci tessPipelineStages.push_back(ShaderElement("tessc", "main", VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)); 4666e5c31af7Sopenharmony_ci tessPipelineStages.push_back(ShaderElement("tesse", "main", VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)); 4667e5c31af7Sopenharmony_ci tessPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT)); 4668e5c31af7Sopenharmony_ci } 4669e5c31af7Sopenharmony_ci return tessPipelineStages; 4670e5c31af7Sopenharmony_ci} 4671e5c31af7Sopenharmony_ci 4672e5c31af7Sopenharmony_ciconst vector<ShaderElement>& getGeomPipelineStages (void) 4673e5c31af7Sopenharmony_ci{ 4674e5c31af7Sopenharmony_ci static vector<ShaderElement> geomPipelineStages; 4675e5c31af7Sopenharmony_ci if(geomPipelineStages.empty()) 4676e5c31af7Sopenharmony_ci { 4677e5c31af7Sopenharmony_ci geomPipelineStages.push_back(ShaderElement("vert", "main", VK_SHADER_STAGE_VERTEX_BIT)); 4678e5c31af7Sopenharmony_ci geomPipelineStages.push_back(ShaderElement("geom", "main", VK_SHADER_STAGE_GEOMETRY_BIT)); 4679e5c31af7Sopenharmony_ci geomPipelineStages.push_back(ShaderElement("frag", "main", VK_SHADER_STAGE_FRAGMENT_BIT)); 4680e5c31af7Sopenharmony_ci } 4681e5c31af7Sopenharmony_ci return geomPipelineStages; 4682e5c31af7Sopenharmony_ci} 4683e5c31af7Sopenharmony_ci 4684e5c31af7Sopenharmony_ci// Helper structure used by addTestForStage function. 4685e5c31af7Sopenharmony_cistruct StageData 4686e5c31af7Sopenharmony_ci{ 4687e5c31af7Sopenharmony_ci typedef const vector<ShaderElement>& (*GetPipelineStagesFn)(); 4688e5c31af7Sopenharmony_ci typedef void (*AddShaderCodeCustomStageFn)(vk::SourceCollections&, InstanceContext); 4689e5c31af7Sopenharmony_ci 4690e5c31af7Sopenharmony_ci GetPipelineStagesFn getPipelineFn; 4691e5c31af7Sopenharmony_ci AddShaderCodeCustomStageFn initProgramsFn; 4692e5c31af7Sopenharmony_ci 4693e5c31af7Sopenharmony_ci StageData() 4694e5c31af7Sopenharmony_ci : getPipelineFn(DE_NULL) 4695e5c31af7Sopenharmony_ci , initProgramsFn(DE_NULL) 4696e5c31af7Sopenharmony_ci { 4697e5c31af7Sopenharmony_ci } 4698e5c31af7Sopenharmony_ci 4699e5c31af7Sopenharmony_ci StageData(GetPipelineStagesFn pipelineGetter, AddShaderCodeCustomStageFn programsInitializer) 4700e5c31af7Sopenharmony_ci : getPipelineFn(pipelineGetter) 4701e5c31af7Sopenharmony_ci , initProgramsFn(programsInitializer) 4702e5c31af7Sopenharmony_ci { 4703e5c31af7Sopenharmony_ci } 4704e5c31af7Sopenharmony_ci}; 4705e5c31af7Sopenharmony_ci 4706e5c31af7Sopenharmony_ci// Helper function used by addTestForStage function. 4707e5c31af7Sopenharmony_ciconst StageData& getStageData (vk::VkShaderStageFlagBits stage) 4708e5c31af7Sopenharmony_ci{ 4709e5c31af7Sopenharmony_ci // Construct map 4710e5c31af7Sopenharmony_ci static map<vk::VkShaderStageFlagBits, StageData> testedStageData; 4711e5c31af7Sopenharmony_ci if(testedStageData.empty()) 4712e5c31af7Sopenharmony_ci { 4713e5c31af7Sopenharmony_ci testedStageData[VK_SHADER_STAGE_VERTEX_BIT] = StageData(getVertFragPipelineStages, addShaderCodeCustomVertex); 4714e5c31af7Sopenharmony_ci testedStageData[VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessControl); 4715e5c31af7Sopenharmony_ci testedStageData[VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT] = StageData(getTessPipelineStages, addShaderCodeCustomTessEval); 4716e5c31af7Sopenharmony_ci testedStageData[VK_SHADER_STAGE_GEOMETRY_BIT] = StageData(getGeomPipelineStages, addShaderCodeCustomGeometry); 4717e5c31af7Sopenharmony_ci testedStageData[VK_SHADER_STAGE_FRAGMENT_BIT] = StageData(getVertFragPipelineStages, addShaderCodeCustomFragment); 4718e5c31af7Sopenharmony_ci } 4719e5c31af7Sopenharmony_ci 4720e5c31af7Sopenharmony_ci return testedStageData[stage]; 4721e5c31af7Sopenharmony_ci} 4722e5c31af7Sopenharmony_ci 4723e5c31af7Sopenharmony_civoid createTestForStage (vk::VkShaderStageFlagBits stage, 4724e5c31af7Sopenharmony_ci const std::string& name, 4725e5c31af7Sopenharmony_ci const RGBA (&inputColors)[4], 4726e5c31af7Sopenharmony_ci const RGBA (&outputColors)[4], 4727e5c31af7Sopenharmony_ci const map<string, string>& testCodeFragments, 4728e5c31af7Sopenharmony_ci const SpecConstants& specConstants, 4729e5c31af7Sopenharmony_ci const PushConstants& pushConstants, 4730e5c31af7Sopenharmony_ci const GraphicsResources& resources, 4731e5c31af7Sopenharmony_ci const GraphicsInterfaces& interfaces, 4732e5c31af7Sopenharmony_ci const vector<string>& extensions, 4733e5c31af7Sopenharmony_ci VulkanFeatures vulkanFeatures, 4734e5c31af7Sopenharmony_ci tcu::TestCaseGroup* tests, 4735e5c31af7Sopenharmony_ci const qpTestResult failResult, 4736e5c31af7Sopenharmony_ci const string& failMessageTemplate, 4737e5c31af7Sopenharmony_ci const bool renderFullSquare, 4738e5c31af7Sopenharmony_ci const bool splitRenderArea) 4739e5c31af7Sopenharmony_ci{ 4740e5c31af7Sopenharmony_ci const StageData& stageData = getStageData(stage); 4741e5c31af7Sopenharmony_ci DE_ASSERT(stageData.getPipelineFn || stageData.initProgramsFn); 4742e5c31af7Sopenharmony_ci const vector<ShaderElement>& pipeline = stageData.getPipelineFn(); 4743e5c31af7Sopenharmony_ci 4744e5c31af7Sopenharmony_ci StageToSpecConstantMap specConstantMap; 4745e5c31af7Sopenharmony_ci if (!specConstants.empty()) 4746e5c31af7Sopenharmony_ci specConstantMap[stage] = specConstants; 4747e5c31af7Sopenharmony_ci 4748e5c31af7Sopenharmony_ci InstanceContext ctx (inputColors, outputColors, testCodeFragments, specConstantMap, pushConstants, resources, interfaces, extensions, vulkanFeatures, stage); 4749e5c31af7Sopenharmony_ci ctx.splitRenderArea = splitRenderArea; 4750e5c31af7Sopenharmony_ci for (size_t i = 0; i < pipeline.size(); ++i) 4751e5c31af7Sopenharmony_ci { 4752e5c31af7Sopenharmony_ci ctx.moduleMap[pipeline[i].moduleName].push_back(std::make_pair(pipeline[i].entryName, pipeline[i].stage)); 4753e5c31af7Sopenharmony_ci ctx.requiredStages = static_cast<VkShaderStageFlagBits>(ctx.requiredStages | pipeline[i].stage); 4754e5c31af7Sopenharmony_ci } 4755e5c31af7Sopenharmony_ci 4756e5c31af7Sopenharmony_ci ctx.failResult = failResult; 4757e5c31af7Sopenharmony_ci if (!failMessageTemplate.empty()) 4758e5c31af7Sopenharmony_ci ctx.failMessageTemplate = failMessageTemplate; 4759e5c31af7Sopenharmony_ci 4760e5c31af7Sopenharmony_ci ctx.renderFullSquare = renderFullSquare; 4761e5c31af7Sopenharmony_ci ctx.splitRenderArea = splitRenderArea; 4762e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms<InstanceContext>(tests, name, stageData.initProgramsFn, runAndVerifyDefaultPipeline, ctx); 4763e5c31af7Sopenharmony_ci} 4764e5c31af7Sopenharmony_ci 4765e5c31af7Sopenharmony_civoid createTestsForAllStages (const std::string& name, 4766e5c31af7Sopenharmony_ci const RGBA (&inputColors)[4], 4767e5c31af7Sopenharmony_ci const RGBA (&outputColors)[4], 4768e5c31af7Sopenharmony_ci const map<string, string>& testCodeFragments, 4769e5c31af7Sopenharmony_ci const SpecConstants& specConstants, 4770e5c31af7Sopenharmony_ci const PushConstants& pushConstants, 4771e5c31af7Sopenharmony_ci const GraphicsResources& resources, 4772e5c31af7Sopenharmony_ci const GraphicsInterfaces& interfaces, 4773e5c31af7Sopenharmony_ci const vector<string>& extensions, 4774e5c31af7Sopenharmony_ci VulkanFeatures vulkanFeatures, 4775e5c31af7Sopenharmony_ci tcu::TestCaseGroup* tests, 4776e5c31af7Sopenharmony_ci const qpTestResult failResult, 4777e5c31af7Sopenharmony_ci const string& failMessageTemplate, 4778e5c31af7Sopenharmony_ci const bool splitRenderArea) 4779e5c31af7Sopenharmony_ci{ 4780e5c31af7Sopenharmony_ci createTestForStage(VK_SHADER_STAGE_VERTEX_BIT, name + "_vert", 4781e5c31af7Sopenharmony_ci inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, 4782e5c31af7Sopenharmony_ci interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate); 4783e5c31af7Sopenharmony_ci 4784e5c31af7Sopenharmony_ci createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name + "_tessc", 4785e5c31af7Sopenharmony_ci inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, 4786e5c31af7Sopenharmony_ci interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate); 4787e5c31af7Sopenharmony_ci 4788e5c31af7Sopenharmony_ci createTestForStage(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, name + "_tesse", 4789e5c31af7Sopenharmony_ci inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, 4790e5c31af7Sopenharmony_ci interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate); 4791e5c31af7Sopenharmony_ci 4792e5c31af7Sopenharmony_ci createTestForStage(VK_SHADER_STAGE_GEOMETRY_BIT, name + "_geom", 4793e5c31af7Sopenharmony_ci inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, 4794e5c31af7Sopenharmony_ci interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate); 4795e5c31af7Sopenharmony_ci 4796e5c31af7Sopenharmony_ci createTestForStage(VK_SHADER_STAGE_FRAGMENT_BIT, name + "_frag", 4797e5c31af7Sopenharmony_ci inputColors, outputColors, testCodeFragments, specConstants, pushConstants, resources, 4798e5c31af7Sopenharmony_ci interfaces, extensions, vulkanFeatures, tests, failResult, failMessageTemplate, false, splitRenderArea); 4799e5c31af7Sopenharmony_ci} 4800e5c31af7Sopenharmony_ci 4801e5c31af7Sopenharmony_civoid addTessCtrlTest (tcu::TestCaseGroup* group, const char* name, const map<string, string>& fragments) 4802e5c31af7Sopenharmony_ci{ 4803e5c31af7Sopenharmony_ci RGBA defaultColors[4]; 4804e5c31af7Sopenharmony_ci getDefaultColors(defaultColors); 4805e5c31af7Sopenharmony_ci 4806e5c31af7Sopenharmony_ci createTestForStage(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, name, 4807e5c31af7Sopenharmony_ci defaultColors, defaultColors, fragments, SpecConstants(), PushConstants(), GraphicsResources(), 4808e5c31af7Sopenharmony_ci GraphicsInterfaces(), vector<string>(), VulkanFeatures(), group); 4809e5c31af7Sopenharmony_ci} 4810e5c31af7Sopenharmony_ci 4811e5c31af7Sopenharmony_ci} // SpirVAssembly 4812e5c31af7Sopenharmony_ci} // vkt 4813