1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2020 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2020 Valve Corporation. 7e5c31af7Sopenharmony_ci * 8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 11e5c31af7Sopenharmony_ci * 12e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 18e5c31af7Sopenharmony_ci * limitations under the License. 19e5c31af7Sopenharmony_ci * 20e5c31af7Sopenharmony_ci *//*! 21e5c31af7Sopenharmony_ci * \file 22e5c31af7Sopenharmony_ci * \brief Ray Tracing Data Spill tests 23e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 24e5c31af7Sopenharmony_ci#include "vktRayTracingDataSpillTests.hpp" 25e5c31af7Sopenharmony_ci#include "vktTestCase.hpp" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "vkRayTracingUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vkBufferWithMemory.hpp" 30e5c31af7Sopenharmony_ci#include "vkImageWithMemory.hpp" 31e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp" 32e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 33e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 34e5c31af7Sopenharmony_ci#include "vkBarrierUtil.hpp" 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 37e5c31af7Sopenharmony_ci#include "tcuFloat.hpp" 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp" 40e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp" 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ci#include <sstream> 43e5c31af7Sopenharmony_ci#include <string> 44e5c31af7Sopenharmony_ci#include <map> 45e5c31af7Sopenharmony_ci#include <vector> 46e5c31af7Sopenharmony_ci#include <array> 47e5c31af7Sopenharmony_ci#include <utility> 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciusing namespace vk; 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_cinamespace vkt 52e5c31af7Sopenharmony_ci{ 53e5c31af7Sopenharmony_cinamespace RayTracing 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_cinamespace 57e5c31af7Sopenharmony_ci{ 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ci// The type of shader call that will be used. 60e5c31af7Sopenharmony_cienum class CallType 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_ci TRACE_RAY = 0, 63e5c31af7Sopenharmony_ci EXECUTE_CALLABLE, 64e5c31af7Sopenharmony_ci REPORT_INTERSECTION, 65e5c31af7Sopenharmony_ci}; 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ci// The type of data that will be checked. 68e5c31af7Sopenharmony_cienum class DataType 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci // These can be made an array or vector. 71e5c31af7Sopenharmony_ci INT32 = 0, 72e5c31af7Sopenharmony_ci UINT32, 73e5c31af7Sopenharmony_ci INT64, 74e5c31af7Sopenharmony_ci UINT64, 75e5c31af7Sopenharmony_ci INT16, 76e5c31af7Sopenharmony_ci UINT16, 77e5c31af7Sopenharmony_ci INT8, 78e5c31af7Sopenharmony_ci UINT8, 79e5c31af7Sopenharmony_ci FLOAT32, 80e5c31af7Sopenharmony_ci FLOAT64, 81e5c31af7Sopenharmony_ci FLOAT16, 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_ci // These are standalone, so the vector type should be scalar. 84e5c31af7Sopenharmony_ci STRUCT, 85e5c31af7Sopenharmony_ci IMAGE, 86e5c31af7Sopenharmony_ci SAMPLER, 87e5c31af7Sopenharmony_ci SAMPLED_IMAGE, 88e5c31af7Sopenharmony_ci PTR_IMAGE, 89e5c31af7Sopenharmony_ci PTR_SAMPLER, 90e5c31af7Sopenharmony_ci PTR_SAMPLED_IMAGE, 91e5c31af7Sopenharmony_ci PTR_TEXEL, 92e5c31af7Sopenharmony_ci OP_NULL, 93e5c31af7Sopenharmony_ci OP_UNDEF, 94e5c31af7Sopenharmony_ci}; 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ci// The type of vector in use. 97e5c31af7Sopenharmony_cienum class VectorType 98e5c31af7Sopenharmony_ci{ 99e5c31af7Sopenharmony_ci SCALAR = 1, 100e5c31af7Sopenharmony_ci V2 = 2, 101e5c31af7Sopenharmony_ci V3 = 3, 102e5c31af7Sopenharmony_ci V4 = 4, 103e5c31af7Sopenharmony_ci A5 = 5, 104e5c31af7Sopenharmony_ci}; 105e5c31af7Sopenharmony_ci 106e5c31af7Sopenharmony_cistruct InputStruct 107e5c31af7Sopenharmony_ci{ 108e5c31af7Sopenharmony_ci deUint32 uintPart; 109e5c31af7Sopenharmony_ci float floatPart; 110e5c31af7Sopenharmony_ci}; 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ciconstexpr auto kImageFormat = VK_FORMAT_R32_UINT; 113e5c31af7Sopenharmony_ciconst auto kImageExtent = makeExtent3D(1u, 1u, 1u); 114e5c31af7Sopenharmony_ci 115e5c31af7Sopenharmony_ci// For samplers. 116e5c31af7Sopenharmony_ciconst VkImageUsageFlags kSampledImageUsage = (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT); 117e5c31af7Sopenharmony_ciconstexpr size_t kNumImages = 4u; 118e5c31af7Sopenharmony_ciconstexpr size_t kNumSamplers = 4u; 119e5c31af7Sopenharmony_ciconstexpr size_t kNumCombined = 2u; 120e5c31af7Sopenharmony_ciconstexpr size_t kNumAloneImages = kNumImages - kNumCombined; 121e5c31af7Sopenharmony_ciconstexpr size_t kNumAloneSamplers = kNumSamplers - kNumCombined; 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_ci// For storage images. 124e5c31af7Sopenharmony_ciconst VkImageUsageFlags kStorageImageUsage = (VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_STORAGE_BIT); 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_ci// For the pipeline interface tests. 127e5c31af7Sopenharmony_ciconstexpr size_t kNumStorageValues = 6u; 128e5c31af7Sopenharmony_ciconstexpr deUint32 kShaderRecordSize = sizeof(tcu::UVec4); 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci// Get the effective vector length in memory. 131e5c31af7Sopenharmony_cisize_t getEffectiveVectorLength (VectorType vectorType) 132e5c31af7Sopenharmony_ci{ 133e5c31af7Sopenharmony_ci return ((vectorType == VectorType::V3) ? static_cast<size_t>(4) : static_cast<size_t>(vectorType)); 134e5c31af7Sopenharmony_ci} 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci// Get the corresponding element size. 137e5c31af7Sopenharmony_ciVkDeviceSize getElementSize(DataType dataType, VectorType vectorType) 138e5c31af7Sopenharmony_ci{ 139e5c31af7Sopenharmony_ci const size_t length = getEffectiveVectorLength(vectorType); 140e5c31af7Sopenharmony_ci size_t dataSize = 0u; 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci switch (dataType) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci case DataType::INT32: dataSize = sizeof(deInt32); break; 145e5c31af7Sopenharmony_ci case DataType::UINT32: dataSize = sizeof(deUint32); break; 146e5c31af7Sopenharmony_ci case DataType::INT64: dataSize = sizeof(deInt64); break; 147e5c31af7Sopenharmony_ci case DataType::UINT64: dataSize = sizeof(deUint64); break; 148e5c31af7Sopenharmony_ci case DataType::INT16: dataSize = sizeof(deInt16); break; 149e5c31af7Sopenharmony_ci case DataType::UINT16: dataSize = sizeof(deUint16); break; 150e5c31af7Sopenharmony_ci case DataType::INT8: dataSize = sizeof(deInt8); break; 151e5c31af7Sopenharmony_ci case DataType::UINT8: dataSize = sizeof(deUint8); break; 152e5c31af7Sopenharmony_ci case DataType::FLOAT32: dataSize = sizeof(tcu::Float32); break; 153e5c31af7Sopenharmony_ci case DataType::FLOAT64: dataSize = sizeof(tcu::Float64); break; 154e5c31af7Sopenharmony_ci case DataType::FLOAT16: dataSize = sizeof(tcu::Float16); break; 155e5c31af7Sopenharmony_ci case DataType::STRUCT: dataSize = sizeof(InputStruct); break; 156e5c31af7Sopenharmony_ci case DataType::IMAGE: // fallthrough. 157e5c31af7Sopenharmony_ci case DataType::SAMPLER: // fallthrough. 158e5c31af7Sopenharmony_ci case DataType::SAMPLED_IMAGE: // fallthrough. 159e5c31af7Sopenharmony_ci case DataType::PTR_IMAGE: // fallthrough. 160e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLER: // fallthrough. 161e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLED_IMAGE: // fallthrough. 162e5c31af7Sopenharmony_ci dataSize = sizeof(tcu::Float32); break; 163e5c31af7Sopenharmony_ci case DataType::PTR_TEXEL: dataSize = sizeof(deInt32); break; 164e5c31af7Sopenharmony_ci case DataType::OP_NULL: // fallthrough. 165e5c31af7Sopenharmony_ci case DataType::OP_UNDEF: // fallthrough. 166e5c31af7Sopenharmony_ci dataSize = sizeof(deUint32); break; 167e5c31af7Sopenharmony_ci default: DE_ASSERT(false); break; 168e5c31af7Sopenharmony_ci } 169e5c31af7Sopenharmony_ci 170e5c31af7Sopenharmony_ci return static_cast<VkDeviceSize>(dataSize * length); 171e5c31af7Sopenharmony_ci} 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci// Proper stage for generating default geometry. 174e5c31af7Sopenharmony_ciVkShaderStageFlagBits getShaderStageForGeometry (CallType type_) 175e5c31af7Sopenharmony_ci{ 176e5c31af7Sopenharmony_ci VkShaderStageFlagBits bits = VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM; 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci switch (type_) 179e5c31af7Sopenharmony_ci { 180e5c31af7Sopenharmony_ci case CallType::TRACE_RAY: bits = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; break; 181e5c31af7Sopenharmony_ci case CallType::EXECUTE_CALLABLE: bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR; break; 182e5c31af7Sopenharmony_ci case CallType::REPORT_INTERSECTION: bits = VK_SHADER_STAGE_INTERSECTION_BIT_KHR; break; 183e5c31af7Sopenharmony_ci default: DE_ASSERT(false); break; 184e5c31af7Sopenharmony_ci } 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ci DE_ASSERT(bits != VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM); 187e5c31af7Sopenharmony_ci return bits; 188e5c31af7Sopenharmony_ci} 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_ciVkShaderStageFlags getShaderStages (CallType type_) 191e5c31af7Sopenharmony_ci{ 192e5c31af7Sopenharmony_ci VkShaderStageFlags flags = VK_SHADER_STAGE_RAYGEN_BIT_KHR; 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ci switch (type_) 195e5c31af7Sopenharmony_ci { 196e5c31af7Sopenharmony_ci case CallType::EXECUTE_CALLABLE: 197e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR; 198e5c31af7Sopenharmony_ci break; 199e5c31af7Sopenharmony_ci case CallType::TRACE_RAY: 200e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; 201e5c31af7Sopenharmony_ci break; 202e5c31af7Sopenharmony_ci case CallType::REPORT_INTERSECTION: 203e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR; 204e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_ANY_HIT_BIT_KHR; 205e5c31af7Sopenharmony_ci break; 206e5c31af7Sopenharmony_ci default: 207e5c31af7Sopenharmony_ci DE_ASSERT(false); 208e5c31af7Sopenharmony_ci break; 209e5c31af7Sopenharmony_ci } 210e5c31af7Sopenharmony_ci 211e5c31af7Sopenharmony_ci return flags; 212e5c31af7Sopenharmony_ci} 213e5c31af7Sopenharmony_ci 214e5c31af7Sopenharmony_ci// Some test types need additional descriptors with samplers, images and combined image samplers. 215e5c31af7Sopenharmony_cibool samplersNeeded (DataType dataType) 216e5c31af7Sopenharmony_ci{ 217e5c31af7Sopenharmony_ci bool needed = false; 218e5c31af7Sopenharmony_ci 219e5c31af7Sopenharmony_ci switch (dataType) 220e5c31af7Sopenharmony_ci { 221e5c31af7Sopenharmony_ci case DataType::IMAGE: 222e5c31af7Sopenharmony_ci case DataType::SAMPLER: 223e5c31af7Sopenharmony_ci case DataType::SAMPLED_IMAGE: 224e5c31af7Sopenharmony_ci case DataType::PTR_IMAGE: 225e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLER: 226e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLED_IMAGE: 227e5c31af7Sopenharmony_ci needed = true; 228e5c31af7Sopenharmony_ci break; 229e5c31af7Sopenharmony_ci default: 230e5c31af7Sopenharmony_ci break; 231e5c31af7Sopenharmony_ci } 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci return needed; 234e5c31af7Sopenharmony_ci} 235e5c31af7Sopenharmony_ci 236e5c31af7Sopenharmony_ci// Some test types need an additional descriptor with a storage image. 237e5c31af7Sopenharmony_cibool storageImageNeeded (DataType dataType) 238e5c31af7Sopenharmony_ci{ 239e5c31af7Sopenharmony_ci return (dataType == DataType::PTR_TEXEL); 240e5c31af7Sopenharmony_ci} 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci// Returns two strings: 243e5c31af7Sopenharmony_ci// .first is an optional GLSL additional type declaration (for structs, basically). 244e5c31af7Sopenharmony_ci// .second is the value declaration inside the input block. 245e5c31af7Sopenharmony_cistd::pair<std::string, std::string> getGLSLInputValDecl (DataType dataType, VectorType vectorType) 246e5c31af7Sopenharmony_ci{ 247e5c31af7Sopenharmony_ci using TypePair = std::pair<DataType, VectorType>; 248e5c31af7Sopenharmony_ci using TypeMap = std::map<TypePair, std::string>; 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci const std::string varName = "val"; 251e5c31af7Sopenharmony_ci const auto dataTypeIdx = static_cast<int>(dataType); 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_ci if (dataTypeIdx >= static_cast<int>(DataType::INT32) && dataTypeIdx <= static_cast<int>(DataType::FLOAT16)) 254e5c31af7Sopenharmony_ci { 255e5c31af7Sopenharmony_ci // Note: A5 uses the same type as the scalar version. The array suffix will be added below. 256e5c31af7Sopenharmony_ci const TypeMap map = 257e5c31af7Sopenharmony_ci { 258e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT32, VectorType::SCALAR), "int32_t"), 259e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT32, VectorType::V2), "i32vec2"), 260e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT32, VectorType::V3), "i32vec3"), 261e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT32, VectorType::V4), "i32vec4"), 262e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT32, VectorType::A5), "int32_t"), 263e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT32, VectorType::SCALAR), "uint32_t"), 264e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT32, VectorType::V2), "u32vec2"), 265e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT32, VectorType::V3), "u32vec3"), 266e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT32, VectorType::V4), "u32vec4"), 267e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT32, VectorType::A5), "uint32_t"), 268e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT64, VectorType::SCALAR), "int64_t"), 269e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT64, VectorType::V2), "i64vec2"), 270e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT64, VectorType::V3), "i64vec3"), 271e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT64, VectorType::V4), "i64vec4"), 272e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT64, VectorType::A5), "int64_t"), 273e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT64, VectorType::SCALAR), "uint64_t"), 274e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT64, VectorType::V2), "u64vec2"), 275e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT64, VectorType::V3), "u64vec3"), 276e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT64, VectorType::V4), "u64vec4"), 277e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT64, VectorType::A5), "uint64_t"), 278e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT16, VectorType::SCALAR), "int16_t"), 279e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT16, VectorType::V2), "i16vec2"), 280e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT16, VectorType::V3), "i16vec3"), 281e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT16, VectorType::V4), "i16vec4"), 282e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT16, VectorType::A5), "int16_t"), 283e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT16, VectorType::SCALAR), "uint16_t"), 284e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT16, VectorType::V2), "u16vec2"), 285e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT16, VectorType::V3), "u16vec3"), 286e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT16, VectorType::V4), "u16vec4"), 287e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT16, VectorType::A5), "uint16_t"), 288e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT8, VectorType::SCALAR), "int8_t"), 289e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT8, VectorType::V2), "i8vec2"), 290e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT8, VectorType::V3), "i8vec3"), 291e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT8, VectorType::V4), "i8vec4"), 292e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::INT8, VectorType::A5), "int8_t"), 293e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT8, VectorType::SCALAR), "uint8_t"), 294e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT8, VectorType::V2), "u8vec2"), 295e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT8, VectorType::V3), "u8vec3"), 296e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT8, VectorType::V4), "u8vec4"), 297e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::UINT8, VectorType::A5), "uint8_t"), 298e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT32, VectorType::SCALAR), "float32_t"), 299e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT32, VectorType::V2), "f32vec2"), 300e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT32, VectorType::V3), "f32vec3"), 301e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT32, VectorType::V4), "f32vec4"), 302e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT32, VectorType::A5), "float32_t"), 303e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT64, VectorType::SCALAR), "float64_t"), 304e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT64, VectorType::V2), "f64vec2"), 305e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT64, VectorType::V3), "f64vec3"), 306e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT64, VectorType::V4), "f64vec4"), 307e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT64, VectorType::A5), "float64_t"), 308e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT16, VectorType::SCALAR), "float16_t"), 309e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT16, VectorType::V2), "f16vec2"), 310e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT16, VectorType::V3), "f16vec3"), 311e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT16, VectorType::V4), "f16vec4"), 312e5c31af7Sopenharmony_ci std::make_pair(std::make_pair(DataType::FLOAT16, VectorType::A5), "float16_t"), 313e5c31af7Sopenharmony_ci }; 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_ci const auto key = std::make_pair(dataType, vectorType); 316e5c31af7Sopenharmony_ci const auto found = map.find(key); 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ci DE_ASSERT(found != end(map)); 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ci const auto baseType = found->second; 321e5c31af7Sopenharmony_ci const std::string decl = baseType + " " + varName + ((vectorType == VectorType::A5) ? "[5]" : "") + ";"; 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_ci return std::make_pair(std::string(), decl); 324e5c31af7Sopenharmony_ci } 325e5c31af7Sopenharmony_ci else if (dataType == DataType::STRUCT) 326e5c31af7Sopenharmony_ci { 327e5c31af7Sopenharmony_ci return std::make_pair(std::string("struct InputStruct { uint val1; float val2; };\n"), std::string("InputStruct val;")); 328e5c31af7Sopenharmony_ci } 329e5c31af7Sopenharmony_ci else if (samplersNeeded(dataType)) 330e5c31af7Sopenharmony_ci { 331e5c31af7Sopenharmony_ci return std::make_pair(std::string(), std::string("float val;")); 332e5c31af7Sopenharmony_ci } 333e5c31af7Sopenharmony_ci else if (storageImageNeeded(dataType)) 334e5c31af7Sopenharmony_ci { 335e5c31af7Sopenharmony_ci return std::make_pair(std::string(), std::string("int val;")); 336e5c31af7Sopenharmony_ci } 337e5c31af7Sopenharmony_ci else if (dataType == DataType::OP_NULL || dataType == DataType::OP_UNDEF) 338e5c31af7Sopenharmony_ci { 339e5c31af7Sopenharmony_ci return std::make_pair(std::string(), std::string("uint val;")); 340e5c31af7Sopenharmony_ci } 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_ci // Unreachable. 343e5c31af7Sopenharmony_ci DE_ASSERT(false); 344e5c31af7Sopenharmony_ci return std::make_pair(std::string(), std::string()); 345e5c31af7Sopenharmony_ci} 346e5c31af7Sopenharmony_ci 347e5c31af7Sopenharmony_ciclass DataSpillTestCase : public vkt::TestCase 348e5c31af7Sopenharmony_ci{ 349e5c31af7Sopenharmony_cipublic: 350e5c31af7Sopenharmony_ci struct TestParams 351e5c31af7Sopenharmony_ci { 352e5c31af7Sopenharmony_ci CallType callType; 353e5c31af7Sopenharmony_ci DataType dataType; 354e5c31af7Sopenharmony_ci VectorType vectorType; 355e5c31af7Sopenharmony_ci }; 356e5c31af7Sopenharmony_ci 357e5c31af7Sopenharmony_ci DataSpillTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams); 358e5c31af7Sopenharmony_ci virtual ~DataSpillTestCase (void) {} 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci virtual void initPrograms (vk::SourceCollections& programCollection) const; 361e5c31af7Sopenharmony_ci virtual TestInstance* createInstance (Context& context) const; 362e5c31af7Sopenharmony_ci virtual void checkSupport (Context& context) const; 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ciprivate: 365e5c31af7Sopenharmony_ci TestParams m_params; 366e5c31af7Sopenharmony_ci}; 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ciclass DataSpillTestInstance : public vkt::TestInstance 369e5c31af7Sopenharmony_ci{ 370e5c31af7Sopenharmony_cipublic: 371e5c31af7Sopenharmony_ci using TestParams = DataSpillTestCase::TestParams; 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci DataSpillTestInstance (Context& context, const TestParams& testParams); 374e5c31af7Sopenharmony_ci virtual ~DataSpillTestInstance (void) {} 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_ci virtual tcu::TestStatus iterate (void); 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ciprivate: 379e5c31af7Sopenharmony_ci TestParams m_params; 380e5c31af7Sopenharmony_ci}; 381e5c31af7Sopenharmony_ci 382e5c31af7Sopenharmony_ci 383e5c31af7Sopenharmony_ciDataSpillTestCase::DataSpillTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams) 384e5c31af7Sopenharmony_ci : vkt::TestCase (testCtx, name) 385e5c31af7Sopenharmony_ci , m_params (testParams) 386e5c31af7Sopenharmony_ci{ 387e5c31af7Sopenharmony_ci switch (m_params.dataType) 388e5c31af7Sopenharmony_ci { 389e5c31af7Sopenharmony_ci case DataType::STRUCT: 390e5c31af7Sopenharmony_ci case DataType::IMAGE: 391e5c31af7Sopenharmony_ci case DataType::SAMPLER: 392e5c31af7Sopenharmony_ci case DataType::SAMPLED_IMAGE: 393e5c31af7Sopenharmony_ci case DataType::PTR_IMAGE: 394e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLER: 395e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLED_IMAGE: 396e5c31af7Sopenharmony_ci case DataType::PTR_TEXEL: 397e5c31af7Sopenharmony_ci case DataType::OP_NULL: 398e5c31af7Sopenharmony_ci case DataType::OP_UNDEF: 399e5c31af7Sopenharmony_ci DE_ASSERT(m_params.vectorType == VectorType::SCALAR); 400e5c31af7Sopenharmony_ci break; 401e5c31af7Sopenharmony_ci default: 402e5c31af7Sopenharmony_ci break; 403e5c31af7Sopenharmony_ci } 404e5c31af7Sopenharmony_ci 405e5c31af7Sopenharmony_ci // The code assumes at most one of these is needed. 406e5c31af7Sopenharmony_ci DE_ASSERT(!(samplersNeeded(m_params.dataType) && storageImageNeeded(m_params.dataType))); 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ciTestInstance* DataSpillTestCase::createInstance (Context& context) const 410e5c31af7Sopenharmony_ci{ 411e5c31af7Sopenharmony_ci return new DataSpillTestInstance(context, m_params); 412e5c31af7Sopenharmony_ci} 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ciDataSpillTestInstance::DataSpillTestInstance (Context& context, const TestParams& testParams) 415e5c31af7Sopenharmony_ci : vkt::TestInstance (context) 416e5c31af7Sopenharmony_ci , m_params (testParams) 417e5c31af7Sopenharmony_ci{ 418e5c31af7Sopenharmony_ci} 419e5c31af7Sopenharmony_ci 420e5c31af7Sopenharmony_ci// General checks for all tests. 421e5c31af7Sopenharmony_civoid commonCheckSupport (Context& context) 422e5c31af7Sopenharmony_ci{ 423e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_acceleration_structure"); 424e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_ray_tracing_pipeline"); 425e5c31af7Sopenharmony_ci 426e5c31af7Sopenharmony_ci const auto& rtFeatures = context.getRayTracingPipelineFeatures(); 427e5c31af7Sopenharmony_ci if (!rtFeatures.rayTracingPipeline) 428e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Ray Tracing pipelines not supported"); 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci const auto& asFeatures = context.getAccelerationStructureFeatures(); 431e5c31af7Sopenharmony_ci if (!asFeatures.accelerationStructure) 432e5c31af7Sopenharmony_ci TCU_FAIL("VK_KHR_acceleration_structure supported without accelerationStructure support"); 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci} 435e5c31af7Sopenharmony_ci 436e5c31af7Sopenharmony_civoid DataSpillTestCase::checkSupport (Context& context) const 437e5c31af7Sopenharmony_ci{ 438e5c31af7Sopenharmony_ci // General checks first. 439e5c31af7Sopenharmony_ci commonCheckSupport(context); 440e5c31af7Sopenharmony_ci 441e5c31af7Sopenharmony_ci const auto& features = context.getDeviceFeatures(); 442e5c31af7Sopenharmony_ci const auto& featuresStorage16 = context.get16BitStorageFeatures(); 443e5c31af7Sopenharmony_ci const auto& featuresF16I8 = context.getShaderFloat16Int8Features(); 444e5c31af7Sopenharmony_ci const auto& featuresStorage8 = context.get8BitStorageFeatures(); 445e5c31af7Sopenharmony_ci 446e5c31af7Sopenharmony_ci if (m_params.dataType == DataType::INT64 || m_params.dataType == DataType::UINT64) 447e5c31af7Sopenharmony_ci { 448e5c31af7Sopenharmony_ci if (!features.shaderInt64) 449e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "64-bit integers not supported"); 450e5c31af7Sopenharmony_ci } 451e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::INT16 || m_params.dataType == DataType::UINT16) 452e5c31af7Sopenharmony_ci { 453e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_16bit_storage"); 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci if (!features.shaderInt16) 456e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "16-bit integers not supported"); 457e5c31af7Sopenharmony_ci 458e5c31af7Sopenharmony_ci if (!featuresStorage16.storageBuffer16BitAccess) 459e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "16-bit storage buffer access not supported"); 460e5c31af7Sopenharmony_ci } 461e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::INT8 || m_params.dataType == DataType::UINT8) 462e5c31af7Sopenharmony_ci { 463e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_shader_float16_int8"); 464e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_8bit_storage"); 465e5c31af7Sopenharmony_ci 466e5c31af7Sopenharmony_ci if (!featuresF16I8.shaderInt8) 467e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "8-bit integers not supported"); 468e5c31af7Sopenharmony_ci 469e5c31af7Sopenharmony_ci if (!featuresStorage8.storageBuffer8BitAccess) 470e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "8-bit storage buffer access not supported"); 471e5c31af7Sopenharmony_ci } 472e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::FLOAT64) 473e5c31af7Sopenharmony_ci { 474e5c31af7Sopenharmony_ci if (!features.shaderFloat64) 475e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "64-bit floats not supported"); 476e5c31af7Sopenharmony_ci } 477e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::FLOAT16) 478e5c31af7Sopenharmony_ci { 479e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_shader_float16_int8"); 480e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_16bit_storage"); 481e5c31af7Sopenharmony_ci 482e5c31af7Sopenharmony_ci if (!featuresF16I8.shaderFloat16) 483e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "16-bit floats not supported"); 484e5c31af7Sopenharmony_ci 485e5c31af7Sopenharmony_ci if (!featuresStorage16.storageBuffer16BitAccess) 486e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "16-bit storage buffer access not supported"); 487e5c31af7Sopenharmony_ci } 488e5c31af7Sopenharmony_ci else if (samplersNeeded(m_params.dataType)) 489e5c31af7Sopenharmony_ci { 490e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_descriptor_indexing"); 491e5c31af7Sopenharmony_ci const auto indexingFeatures = context.getDescriptorIndexingFeatures(); 492e5c31af7Sopenharmony_ci if (!indexingFeatures.shaderSampledImageArrayNonUniformIndexing) 493e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "No support for non-uniform sampled image arrays"); 494e5c31af7Sopenharmony_ci } 495e5c31af7Sopenharmony_ci} 496e5c31af7Sopenharmony_ci 497e5c31af7Sopenharmony_civoid DataSpillTestCase::initPrograms (vk::SourceCollections& programCollection) const 498e5c31af7Sopenharmony_ci{ 499e5c31af7Sopenharmony_ci const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 500e5c31af7Sopenharmony_ci const vk::SpirVAsmBuildOptions spvBuildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, true); 501e5c31af7Sopenharmony_ci 502e5c31af7Sopenharmony_ci std::ostringstream spvTemplateStream; 503e5c31af7Sopenharmony_ci 504e5c31af7Sopenharmony_ci // This SPIR-V template will be used to generate shaders for different 505e5c31af7Sopenharmony_ci // stages (raygen, callable, etc). The basic mechanism uses 3 SSBOs: one 506e5c31af7Sopenharmony_ci // used strictly as an input, one to write the check result, and one to 507e5c31af7Sopenharmony_ci // verify the shader call has taken place. The latter two SSBOs contain just 508e5c31af7Sopenharmony_ci // a single uint, but the input SSBO typically contains other type of data 509e5c31af7Sopenharmony_ci // that will be filled from the test instance with predetermined values. The 510e5c31af7Sopenharmony_ci // shader will expect this data to have specific values that can be combined 511e5c31af7Sopenharmony_ci // some way to give an expected result (e.g. by adding the 4 components if 512e5c31af7Sopenharmony_ci // it's a vec4). This result will be used in the shader call to make sure 513e5c31af7Sopenharmony_ci // input values are read *before* the call. After the shader call has taken 514e5c31af7Sopenharmony_ci // place, the shader will attempt to read the input buffer again and verify 515e5c31af7Sopenharmony_ci // the value is still correct and matches the previous one. If the result 516e5c31af7Sopenharmony_ci // matches, it will write a confirmation value in the check buffer. In the 517e5c31af7Sopenharmony_ci // mean time, the callee will write a confirmation value in the callee 518e5c31af7Sopenharmony_ci // buffer to verify the shader call took place. 519e5c31af7Sopenharmony_ci // 520e5c31af7Sopenharmony_ci // Some test variants use samplers, images or sampled images. These need 521e5c31af7Sopenharmony_ci // additional bindings of different types and the interesting value is 522e5c31af7Sopenharmony_ci // typically placed in the image instead of the input buffer, while the 523e5c31af7Sopenharmony_ci // input buffer is used for sampling coordinates instead. 524e5c31af7Sopenharmony_ci // 525e5c31af7Sopenharmony_ci // Some important SPIR-V template variables: 526e5c31af7Sopenharmony_ci // 527e5c31af7Sopenharmony_ci // - INPUT_BUFFER_VALUE_TYPE will contain the type of input buffer data. 528e5c31af7Sopenharmony_ci // - CALC_ZERO_FOR_CALLABLE is expected to contain instructions that will 529e5c31af7Sopenharmony_ci // calculate a value of zero to be used in the shader call instruction. 530e5c31af7Sopenharmony_ci // This value should be derived from the input data. 531e5c31af7Sopenharmony_ci // - CALL_STATEMENTS will contain the shader call instructions. 532e5c31af7Sopenharmony_ci // - CALC_EQUAL_STATEMENT is expected to contain instructions that will 533e5c31af7Sopenharmony_ci // set %equal to true as a %bool if the before- and after- data match. 534e5c31af7Sopenharmony_ci // 535e5c31af7Sopenharmony_ci // - %input_val_ptr contains the pointer to the input value. 536e5c31af7Sopenharmony_ci // - %input_val_before contains the value read before the call. 537e5c31af7Sopenharmony_ci // - %input_val_after contains the value read after the call. 538e5c31af7Sopenharmony_ci 539e5c31af7Sopenharmony_ci spvTemplateStream 540e5c31af7Sopenharmony_ci << " OpCapability RayTracingKHR\n" 541e5c31af7Sopenharmony_ci << "${EXTRA_CAPABILITIES}" 542e5c31af7Sopenharmony_ci << " OpExtension \"SPV_KHR_ray_tracing\"\n" 543e5c31af7Sopenharmony_ci << "${EXTRA_EXTENSIONS}" 544e5c31af7Sopenharmony_ci << " OpMemoryModel Logical GLSL450\n" 545e5c31af7Sopenharmony_ci << " OpEntryPoint ${ENTRY_POINT} %main \"main\" %topLevelAS %calleeBuffer %outputBuffer %inputBuffer${MAIN_INTERFACE_EXTRAS}\n" 546e5c31af7Sopenharmony_ci << "${INTERFACE_DECORATIONS}" 547e5c31af7Sopenharmony_ci << " OpMemberDecorate %InputBlock 0 Offset 0\n" 548e5c31af7Sopenharmony_ci << " OpDecorate %InputBlock Block\n" 549e5c31af7Sopenharmony_ci << " OpDecorate %inputBuffer DescriptorSet 0\n" 550e5c31af7Sopenharmony_ci << " OpDecorate %inputBuffer Binding 3\n" 551e5c31af7Sopenharmony_ci << " OpMemberDecorate %OutputBlock 0 Offset 0\n" 552e5c31af7Sopenharmony_ci << " OpDecorate %OutputBlock Block\n" 553e5c31af7Sopenharmony_ci << " OpDecorate %outputBuffer DescriptorSet 0\n" 554e5c31af7Sopenharmony_ci << " OpDecorate %outputBuffer Binding 2\n" 555e5c31af7Sopenharmony_ci << " OpMemberDecorate %CalleeBlock 0 Offset 0\n" 556e5c31af7Sopenharmony_ci << " OpDecorate %CalleeBlock Block\n" 557e5c31af7Sopenharmony_ci << " OpDecorate %calleeBuffer DescriptorSet 0\n" 558e5c31af7Sopenharmony_ci << " OpDecorate %calleeBuffer Binding 1\n" 559e5c31af7Sopenharmony_ci << " OpDecorate %topLevelAS DescriptorSet 0\n" 560e5c31af7Sopenharmony_ci << " OpDecorate %topLevelAS Binding 0\n" 561e5c31af7Sopenharmony_ci << "${EXTRA_BINDINGS}" 562e5c31af7Sopenharmony_ci << " %void = OpTypeVoid\n" 563e5c31af7Sopenharmony_ci << " %void_func = OpTypeFunction %void\n" 564e5c31af7Sopenharmony_ci << " %int = OpTypeInt 32 1\n" 565e5c31af7Sopenharmony_ci << " %uint = OpTypeInt 32 0\n" 566e5c31af7Sopenharmony_ci << " %int_0 = OpConstant %int 0\n" 567e5c31af7Sopenharmony_ci << " %uint_0 = OpConstant %uint 0\n" 568e5c31af7Sopenharmony_ci << " %uint_1 = OpConstant %uint 1\n" 569e5c31af7Sopenharmony_ci << " %uint_2 = OpConstant %uint 2\n" 570e5c31af7Sopenharmony_ci << " %uint_3 = OpConstant %uint 3\n" 571e5c31af7Sopenharmony_ci << " %uint_4 = OpConstant %uint 4\n" 572e5c31af7Sopenharmony_ci << " %uint_5 = OpConstant %uint 5\n" 573e5c31af7Sopenharmony_ci << " %uint_255 = OpConstant %uint 255\n" 574e5c31af7Sopenharmony_ci << " %bool = OpTypeBool\n" 575e5c31af7Sopenharmony_ci << " %float = OpTypeFloat 32\n" 576e5c31af7Sopenharmony_ci << " %float_0 = OpConstant %float 0\n" 577e5c31af7Sopenharmony_ci << " %float_1 = OpConstant %float 1\n" 578e5c31af7Sopenharmony_ci << " %float_9 = OpConstant %float 9\n" 579e5c31af7Sopenharmony_ci << " %float_0_5 = OpConstant %float 0.5\n" 580e5c31af7Sopenharmony_ci << " %float_n1 = OpConstant %float -1\n" 581e5c31af7Sopenharmony_ci << " %v3float = OpTypeVector %float 3\n" 582e5c31af7Sopenharmony_ci << " %origin_const = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0\n" 583e5c31af7Sopenharmony_ci << " %direction_const = OpConstantComposite %v3float %float_0 %float_0 %float_n1\n" 584e5c31af7Sopenharmony_ci << "${EXTRA_TYPES_AND_CONSTANTS}" 585e5c31af7Sopenharmony_ci << " %data_func_ptr = OpTypePointer Function ${INPUT_BUFFER_VALUE_TYPE}\n" 586e5c31af7Sopenharmony_ci << "${INTERFACE_TYPES_AND_VARIABLES}" 587e5c31af7Sopenharmony_ci << " %InputBlock = OpTypeStruct ${INPUT_BUFFER_VALUE_TYPE}\n" 588e5c31af7Sopenharmony_ci << " %_ptr_StorageBuffer_InputBlock = OpTypePointer StorageBuffer %InputBlock\n" 589e5c31af7Sopenharmony_ci << " %inputBuffer = OpVariable %_ptr_StorageBuffer_InputBlock StorageBuffer\n" 590e5c31af7Sopenharmony_ci << " %data_storagebuffer_ptr = OpTypePointer StorageBuffer ${INPUT_BUFFER_VALUE_TYPE}\n" 591e5c31af7Sopenharmony_ci << " %OutputBlock = OpTypeStruct %uint\n" 592e5c31af7Sopenharmony_ci << "%_ptr_StorageBuffer_OutputBlock = OpTypePointer StorageBuffer %OutputBlock\n" 593e5c31af7Sopenharmony_ci << " %outputBuffer = OpVariable %_ptr_StorageBuffer_OutputBlock StorageBuffer\n" 594e5c31af7Sopenharmony_ci << " %_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint\n" 595e5c31af7Sopenharmony_ci << " %CalleeBlock = OpTypeStruct %uint\n" 596e5c31af7Sopenharmony_ci << "%_ptr_StorageBuffer_CalleeBlock = OpTypePointer StorageBuffer %CalleeBlock\n" 597e5c31af7Sopenharmony_ci << " %calleeBuffer = OpVariable %_ptr_StorageBuffer_CalleeBlock StorageBuffer\n" 598e5c31af7Sopenharmony_ci << " %as_type = OpTypeAccelerationStructureKHR\n" 599e5c31af7Sopenharmony_ci << " %as_uniformconstant_ptr = OpTypePointer UniformConstant %as_type\n" 600e5c31af7Sopenharmony_ci << " %topLevelAS = OpVariable %as_uniformconstant_ptr UniformConstant\n" 601e5c31af7Sopenharmony_ci << "${EXTRA_BINDING_VARIABLES}" 602e5c31af7Sopenharmony_ci << " %main = OpFunction %void None %void_func\n" 603e5c31af7Sopenharmony_ci << " %main_label = OpLabel\n" 604e5c31af7Sopenharmony_ci << "${EXTRA_FUNCTION_VARIABLES}" 605e5c31af7Sopenharmony_ci << " %input_val_ptr = OpAccessChain %data_storagebuffer_ptr %inputBuffer %int_0\n" 606e5c31af7Sopenharmony_ci << " %output_val_ptr = OpAccessChain %_ptr_StorageBuffer_uint %outputBuffer %int_0\n" 607e5c31af7Sopenharmony_ci // Note we use Volatile to load the input buffer value before and after the call statements. 608e5c31af7Sopenharmony_ci << " %input_val_before = OpLoad ${INPUT_BUFFER_VALUE_TYPE} %input_val_ptr Volatile\n" 609e5c31af7Sopenharmony_ci << "${CALC_ZERO_FOR_CALLABLE}" 610e5c31af7Sopenharmony_ci << "${CALL_STATEMENTS}" 611e5c31af7Sopenharmony_ci << " %input_val_after = OpLoad ${INPUT_BUFFER_VALUE_TYPE} %input_val_ptr Volatile\n" 612e5c31af7Sopenharmony_ci << "${CALC_EQUAL_STATEMENT}" 613e5c31af7Sopenharmony_ci << " %output_val = OpSelect %uint %equal %uint_1 %uint_0\n" 614e5c31af7Sopenharmony_ci << " OpStore %output_val_ptr %output_val\n" 615e5c31af7Sopenharmony_ci << " OpReturn\n" 616e5c31af7Sopenharmony_ci << " OpFunctionEnd\n" 617e5c31af7Sopenharmony_ci ; 618e5c31af7Sopenharmony_ci 619e5c31af7Sopenharmony_ci const tcu::StringTemplate spvTemplate (spvTemplateStream.str()); 620e5c31af7Sopenharmony_ci 621e5c31af7Sopenharmony_ci std::map<std::string, std::string> subs; 622e5c31af7Sopenharmony_ci std::string componentTypeName; 623e5c31af7Sopenharmony_ci std::string opEqual; 624e5c31af7Sopenharmony_ci const int numComponents = static_cast<int>(m_params.vectorType); 625e5c31af7Sopenharmony_ci const auto isArray = (numComponents > static_cast<int>(VectorType::V4)); 626e5c31af7Sopenharmony_ci const auto numComponentsStr = de::toString(numComponents); 627e5c31af7Sopenharmony_ci 628e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] = ""; 629e5c31af7Sopenharmony_ci subs["EXTRA_EXTENSIONS"] = ""; 630e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] = ""; 631e5c31af7Sopenharmony_ci subs["EXTRA_FUNCTION_VARIABLES"] = ""; 632e5c31af7Sopenharmony_ci subs["EXTRA_BINDINGS"] = ""; 633e5c31af7Sopenharmony_ci subs["EXTRA_BINDING_VARIABLES"] = ""; 634e5c31af7Sopenharmony_ci subs["EXTRA_FUNCTIONS"] = ""; 635e5c31af7Sopenharmony_ci 636e5c31af7Sopenharmony_ci // Take into account some of these substitutions will be updated after the if-block. 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci if (m_params.dataType == DataType::INT32) 639e5c31af7Sopenharmony_ci { 640e5c31af7Sopenharmony_ci componentTypeName = "int"; 641e5c31af7Sopenharmony_ci 642e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%int"; 643e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %int_37 = OpConstant %int 37\n"; 644e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_int = OpISub %int %input_val_before %int_37\n" 645e5c31af7Sopenharmony_ci " %zero_for_callable = OpBitcast %uint %zero_int\n"; 646e5c31af7Sopenharmony_ci } 647e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::UINT32) 648e5c31af7Sopenharmony_ci { 649e5c31af7Sopenharmony_ci componentTypeName = "uint"; 650e5c31af7Sopenharmony_ci 651e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%uint"; 652e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %uint_37 = OpConstant %uint 37\n"; 653e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_for_callable = OpISub %uint %input_val_before %uint_37\n"; 654e5c31af7Sopenharmony_ci } 655e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::INT64) 656e5c31af7Sopenharmony_ci { 657e5c31af7Sopenharmony_ci componentTypeName = "long"; 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Int64\n"; 660e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%long"; 661e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %long = OpTypeInt 64 1\n" 662e5c31af7Sopenharmony_ci " %long_37 = OpConstant %long 37\n"; 663e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_long = OpISub %long %input_val_before %long_37\n" 664e5c31af7Sopenharmony_ci " %zero_for_callable = OpSConvert %uint %zero_long\n"; 665e5c31af7Sopenharmony_ci } 666e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::UINT64) 667e5c31af7Sopenharmony_ci { 668e5c31af7Sopenharmony_ci componentTypeName = "ulong"; 669e5c31af7Sopenharmony_ci 670e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Int64\n"; 671e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%ulong"; 672e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %ulong = OpTypeInt 64 0\n" 673e5c31af7Sopenharmony_ci " %ulong_37 = OpConstant %ulong 37\n"; 674e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_ulong = OpISub %ulong %input_val_before %ulong_37\n" 675e5c31af7Sopenharmony_ci " %zero_for_callable = OpUConvert %uint %zero_ulong\n"; 676e5c31af7Sopenharmony_ci } 677e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::INT16) 678e5c31af7Sopenharmony_ci { 679e5c31af7Sopenharmony_ci componentTypeName = "short"; 680e5c31af7Sopenharmony_ci 681e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Int16\n" 682e5c31af7Sopenharmony_ci " OpCapability StorageBuffer16BitAccess\n"; 683e5c31af7Sopenharmony_ci subs["EXTRA_EXTENSIONS"] += " OpExtension \"SPV_KHR_16bit_storage\"\n"; 684e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%short"; 685e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %short = OpTypeInt 16 1\n" 686e5c31af7Sopenharmony_ci " %short_37 = OpConstant %short 37\n"; 687e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_short = OpISub %short %input_val_before %short_37\n" 688e5c31af7Sopenharmony_ci " %zero_for_callable = OpSConvert %uint %zero_short\n"; 689e5c31af7Sopenharmony_ci } 690e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::UINT16) 691e5c31af7Sopenharmony_ci { 692e5c31af7Sopenharmony_ci componentTypeName = "ushort"; 693e5c31af7Sopenharmony_ci 694e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Int16\n" 695e5c31af7Sopenharmony_ci " OpCapability StorageBuffer16BitAccess\n"; 696e5c31af7Sopenharmony_ci subs["EXTRA_EXTENSIONS"] += " OpExtension \"SPV_KHR_16bit_storage\"\n"; 697e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%ushort"; 698e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %ushort = OpTypeInt 16 0\n" 699e5c31af7Sopenharmony_ci " %ushort_37 = OpConstant %ushort 37\n"; 700e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_ushort = OpISub %ushort %input_val_before %ushort_37\n" 701e5c31af7Sopenharmony_ci " %zero_for_callable = OpUConvert %uint %zero_ushort\n"; 702e5c31af7Sopenharmony_ci } 703e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::INT8) 704e5c31af7Sopenharmony_ci { 705e5c31af7Sopenharmony_ci componentTypeName = "char"; 706e5c31af7Sopenharmony_ci 707e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Int8\n" 708e5c31af7Sopenharmony_ci " OpCapability StorageBuffer8BitAccess\n"; 709e5c31af7Sopenharmony_ci subs["EXTRA_EXTENSIONS"] += " OpExtension \"SPV_KHR_8bit_storage\"\n"; 710e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%char"; 711e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %char = OpTypeInt 8 1\n" 712e5c31af7Sopenharmony_ci " %char_37 = OpConstant %char 37\n"; 713e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_char = OpISub %char %input_val_before %char_37\n" 714e5c31af7Sopenharmony_ci " %zero_for_callable = OpSConvert %uint %zero_char\n"; 715e5c31af7Sopenharmony_ci } 716e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::UINT8) 717e5c31af7Sopenharmony_ci { 718e5c31af7Sopenharmony_ci componentTypeName = "uchar"; 719e5c31af7Sopenharmony_ci 720e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Int8\n" 721e5c31af7Sopenharmony_ci " OpCapability StorageBuffer8BitAccess\n"; 722e5c31af7Sopenharmony_ci subs["EXTRA_EXTENSIONS"] += " OpExtension \"SPV_KHR_8bit_storage\"\n"; 723e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%uchar"; 724e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %uchar = OpTypeInt 8 0\n" 725e5c31af7Sopenharmony_ci " %uchar_37 = OpConstant %uchar 37\n"; 726e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_uchar = OpISub %uchar %input_val_before %uchar_37\n" 727e5c31af7Sopenharmony_ci " %zero_for_callable = OpUConvert %uint %zero_uchar\n"; 728e5c31af7Sopenharmony_ci } 729e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::FLOAT32) 730e5c31af7Sopenharmony_ci { 731e5c31af7Sopenharmony_ci componentTypeName = "float"; 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%float"; 734e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %float_37 = OpConstant %float 37\n"; 735e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_float = OpFSub %float %input_val_before %float_37\n" 736e5c31af7Sopenharmony_ci " %zero_for_callable = OpConvertFToU %uint %zero_float\n"; 737e5c31af7Sopenharmony_ci } 738e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::FLOAT64) 739e5c31af7Sopenharmony_ci { 740e5c31af7Sopenharmony_ci componentTypeName = "double"; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Float64\n"; 743e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%double"; 744e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %double = OpTypeFloat 64\n" 745e5c31af7Sopenharmony_ci " %double_37 = OpConstant %double 37\n"; 746e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_double = OpFSub %double %input_val_before %double_37\n" 747e5c31af7Sopenharmony_ci " %zero_for_callable = OpConvertFToU %uint %zero_double\n"; 748e5c31af7Sopenharmony_ci } 749e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::FLOAT16) 750e5c31af7Sopenharmony_ci { 751e5c31af7Sopenharmony_ci componentTypeName = "half"; 752e5c31af7Sopenharmony_ci 753e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability Float16\n" 754e5c31af7Sopenharmony_ci " OpCapability StorageBuffer16BitAccess\n"; 755e5c31af7Sopenharmony_ci subs["EXTRA_EXTENSIONS"] += " OpExtension \"SPV_KHR_16bit_storage\"\n"; 756e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%half"; 757e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %half = OpTypeFloat 16\n" 758e5c31af7Sopenharmony_ci " %half_37 = OpConstant %half 37\n"; 759e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %zero_half = OpFSub %half %input_val_before %half_37\n" 760e5c31af7Sopenharmony_ci " %zero_for_callable = OpConvertFToU %uint %zero_half\n"; 761e5c31af7Sopenharmony_ci } 762e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::STRUCT) 763e5c31af7Sopenharmony_ci { 764e5c31af7Sopenharmony_ci componentTypeName = "InputStruct"; 765e5c31af7Sopenharmony_ci 766e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%InputStruct"; 767e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %InputStruct = OpTypeStruct %uint %float\n" 768e5c31af7Sopenharmony_ci " %float_37 = OpConstant %float 37\n" 769e5c31af7Sopenharmony_ci " %uint_part_ptr_type = OpTypePointer StorageBuffer %uint\n" 770e5c31af7Sopenharmony_ci " %float_part_ptr_type = OpTypePointer StorageBuffer %float\n" 771e5c31af7Sopenharmony_ci " %uint_part_func_ptr_type = OpTypePointer Function %uint\n" 772e5c31af7Sopenharmony_ci " %float_part_func_ptr_type = OpTypePointer Function %float\n" 773e5c31af7Sopenharmony_ci " %input_struct_func_ptr_type = OpTypePointer Function %InputStruct\n" 774e5c31af7Sopenharmony_ci ; 775e5c31af7Sopenharmony_ci subs["INTERFACE_DECORATIONS"] = " OpMemberDecorate %InputStruct 0 Offset 0\n" 776e5c31af7Sopenharmony_ci " OpMemberDecorate %InputStruct 1 Offset 4\n"; 777e5c31af7Sopenharmony_ci 778e5c31af7Sopenharmony_ci // Sum struct members, then substract constant and convert to uint. 779e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = " %uint_part_ptr = OpAccessChain %uint_part_ptr_type %input_val_ptr %uint_0\n" 780e5c31af7Sopenharmony_ci " %float_part_ptr = OpAccessChain %float_part_ptr_type %input_val_ptr %uint_1\n" 781e5c31af7Sopenharmony_ci " %uint_part = OpLoad %uint %uint_part_ptr\n" 782e5c31af7Sopenharmony_ci " %float_part = OpLoad %float %float_part_ptr\n" 783e5c31af7Sopenharmony_ci " %uint_as_float = OpConvertUToF %float %uint_part\n" 784e5c31af7Sopenharmony_ci " %member_sum = OpFAdd %float %float_part %uint_as_float\n" 785e5c31af7Sopenharmony_ci " %zero_float = OpFSub %float %member_sum %float_37\n" 786e5c31af7Sopenharmony_ci " %zero_for_callable = OpConvertFToU %uint %zero_float\n" 787e5c31af7Sopenharmony_ci ; 788e5c31af7Sopenharmony_ci } 789e5c31af7Sopenharmony_ci else if (samplersNeeded(m_params.dataType)) 790e5c31af7Sopenharmony_ci { 791e5c31af7Sopenharmony_ci // These tests will use additional bindings as arrays of 2 elements: 792e5c31af7Sopenharmony_ci // - 1 array of samplers. 793e5c31af7Sopenharmony_ci // - 1 array of images. 794e5c31af7Sopenharmony_ci // - 1 array of combined image samplers. 795e5c31af7Sopenharmony_ci // Input values are typically used as texture coordinates (normally zeros) 796e5c31af7Sopenharmony_ci // Pixels will contain the expected values instead of them being in the input buffer. 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%float"; 799e5c31af7Sopenharmony_ci subs["EXTRA_CAPABILITIES"] += " OpCapability SampledImageArrayNonUniformIndexing\n"; 800e5c31af7Sopenharmony_ci subs["EXTRA_EXTENSIONS"] += " OpExtension \"SPV_EXT_descriptor_indexing\"\n"; 801e5c31af7Sopenharmony_ci subs["MAIN_INTERFACE_EXTRAS"] += " %sampledTexture %textureSampler %combinedImageSampler"; 802e5c31af7Sopenharmony_ci subs["EXTRA_BINDINGS"] += " OpDecorate %sampledTexture DescriptorSet 0\n" 803e5c31af7Sopenharmony_ci " OpDecorate %sampledTexture Binding 4\n" 804e5c31af7Sopenharmony_ci " OpDecorate %textureSampler DescriptorSet 0\n" 805e5c31af7Sopenharmony_ci " OpDecorate %textureSampler Binding 5\n" 806e5c31af7Sopenharmony_ci " OpDecorate %combinedImageSampler DescriptorSet 0\n" 807e5c31af7Sopenharmony_ci " OpDecorate %combinedImageSampler Binding 6\n"; 808e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %uint_37 = OpConstant %uint 37\n" 809e5c31af7Sopenharmony_ci " %v4uint = OpTypeVector %uint 4\n" 810e5c31af7Sopenharmony_ci " %v2float = OpTypeVector %float 2\n" 811e5c31af7Sopenharmony_ci " %image_type = OpTypeImage %uint 2D 0 0 0 1 Unknown\n" 812e5c31af7Sopenharmony_ci " %image_array_type = OpTypeArray %image_type %uint_2\n" 813e5c31af7Sopenharmony_ci " %image_array_type_uniform_ptr = OpTypePointer UniformConstant %image_array_type\n" 814e5c31af7Sopenharmony_ci " %image_type_uniform_ptr = OpTypePointer UniformConstant %image_type\n" 815e5c31af7Sopenharmony_ci " %sampler_type = OpTypeSampler\n" 816e5c31af7Sopenharmony_ci " %sampler_array_type = OpTypeArray %sampler_type %uint_2\n" 817e5c31af7Sopenharmony_ci "%sampler_array_type_uniform_ptr = OpTypePointer UniformConstant %sampler_array_type\n" 818e5c31af7Sopenharmony_ci " %sampler_type_uniform_ptr = OpTypePointer UniformConstant %sampler_type\n" 819e5c31af7Sopenharmony_ci " %sampled_image_type = OpTypeSampledImage %image_type\n" 820e5c31af7Sopenharmony_ci " %sampled_image_array_type = OpTypeArray %sampled_image_type %uint_2\n" 821e5c31af7Sopenharmony_ci "%sampled_image_array_type_uniform_ptr = OpTypePointer UniformConstant %sampled_image_array_type\n" 822e5c31af7Sopenharmony_ci "%sampled_image_type_uniform_ptr = OpTypePointer UniformConstant %sampled_image_type\n" 823e5c31af7Sopenharmony_ci ; 824e5c31af7Sopenharmony_ci subs["EXTRA_BINDING_VARIABLES"] += " %sampledTexture = OpVariable %image_array_type_uniform_ptr UniformConstant\n" 825e5c31af7Sopenharmony_ci " %textureSampler = OpVariable %sampler_array_type_uniform_ptr UniformConstant\n" 826e5c31af7Sopenharmony_ci " %combinedImageSampler = OpVariable %sampled_image_array_type_uniform_ptr UniformConstant\n" 827e5c31af7Sopenharmony_ci ; 828e5c31af7Sopenharmony_ci 829e5c31af7Sopenharmony_ci if (m_params.dataType == DataType::IMAGE || m_params.dataType == DataType::SAMPLER) 830e5c31af7Sopenharmony_ci { 831e5c31af7Sopenharmony_ci // Use the first sampler and sample from the first image. 832e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%image_0_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_0\n" 833e5c31af7Sopenharmony_ci "%sampler_0_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_0\n" 834e5c31af7Sopenharmony_ci "%sampler_0 = OpLoad %sampler_type %sampler_0_ptr\n" 835e5c31af7Sopenharmony_ci "%image_0 = OpLoad %image_type %image_0_ptr\n" 836e5c31af7Sopenharmony_ci "%sampled_image_0 = OpSampledImage %sampled_image_type %image_0 %sampler_0\n" 837e5c31af7Sopenharmony_ci "%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n" 838e5c31af7Sopenharmony_ci "%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n" 839e5c31af7Sopenharmony_ci "%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n" 840e5c31af7Sopenharmony_ci "%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n" 841e5c31af7Sopenharmony_ci ; 842e5c31af7Sopenharmony_ci } 843e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::SAMPLED_IMAGE) 844e5c31af7Sopenharmony_ci { 845e5c31af7Sopenharmony_ci // Use the first combined image sampler. 846e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%sampled_image_0_ptr = OpAccessChain %sampled_image_type_uniform_ptr %combinedImageSampler %uint_0\n" 847e5c31af7Sopenharmony_ci "%sampled_image_0 = OpLoad %sampled_image_type %sampled_image_0_ptr\n" 848e5c31af7Sopenharmony_ci "%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n" 849e5c31af7Sopenharmony_ci "%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n" 850e5c31af7Sopenharmony_ci "%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n" 851e5c31af7Sopenharmony_ci "%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n" 852e5c31af7Sopenharmony_ci ; 853e5c31af7Sopenharmony_ci } 854e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::PTR_IMAGE) 855e5c31af7Sopenharmony_ci { 856e5c31af7Sopenharmony_ci // We attempt to create the second pointer before the call. 857e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%image_0_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_0\n" 858e5c31af7Sopenharmony_ci "%image_1_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_1\n" 859e5c31af7Sopenharmony_ci "%image_0 = OpLoad %image_type %image_0_ptr\n" 860e5c31af7Sopenharmony_ci "%sampler_0_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_0\n" 861e5c31af7Sopenharmony_ci "%sampler_0 = OpLoad %sampler_type %sampler_0_ptr\n" 862e5c31af7Sopenharmony_ci "%sampled_image_0 = OpSampledImage %sampled_image_type %image_0 %sampler_0\n" 863e5c31af7Sopenharmony_ci "%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n" 864e5c31af7Sopenharmony_ci "%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n" 865e5c31af7Sopenharmony_ci "%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n" 866e5c31af7Sopenharmony_ci "%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n" 867e5c31af7Sopenharmony_ci ; 868e5c31af7Sopenharmony_ci } 869e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::PTR_SAMPLER) 870e5c31af7Sopenharmony_ci { 871e5c31af7Sopenharmony_ci // We attempt to create the second pointer before the call. 872e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%sampler_0_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_0\n" 873e5c31af7Sopenharmony_ci "%sampler_1_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_1\n" 874e5c31af7Sopenharmony_ci "%sampler_0 = OpLoad %sampler_type %sampler_0_ptr\n" 875e5c31af7Sopenharmony_ci "%image_0_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_0\n" 876e5c31af7Sopenharmony_ci "%image_0 = OpLoad %image_type %image_0_ptr\n" 877e5c31af7Sopenharmony_ci "%sampled_image_0 = OpSampledImage %sampled_image_type %image_0 %sampler_0\n" 878e5c31af7Sopenharmony_ci "%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n" 879e5c31af7Sopenharmony_ci "%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n" 880e5c31af7Sopenharmony_ci "%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n" 881e5c31af7Sopenharmony_ci "%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n" 882e5c31af7Sopenharmony_ci ; 883e5c31af7Sopenharmony_ci } 884e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::PTR_SAMPLED_IMAGE) 885e5c31af7Sopenharmony_ci { 886e5c31af7Sopenharmony_ci // We attempt to create the second pointer before the call. 887e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%sampled_image_0_ptr = OpAccessChain %sampled_image_type_uniform_ptr %combinedImageSampler %uint_0\n" 888e5c31af7Sopenharmony_ci "%sampled_image_1_ptr = OpAccessChain %sampled_image_type_uniform_ptr %combinedImageSampler %uint_1\n" 889e5c31af7Sopenharmony_ci "%sampled_image_0 = OpLoad %sampled_image_type %sampled_image_0_ptr\n" 890e5c31af7Sopenharmony_ci "%texture_coords_0 = OpCompositeConstruct %v2float %input_val_before %input_val_before\n" 891e5c31af7Sopenharmony_ci "%pixel_vec_0 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_0 Lod|ZeroExtend %float_0\n" 892e5c31af7Sopenharmony_ci "%pixel_0 = OpCompositeExtract %uint %pixel_vec_0 0\n" 893e5c31af7Sopenharmony_ci "%zero_for_callable = OpISub %uint %pixel_0 %uint_37\n" 894e5c31af7Sopenharmony_ci ; 895e5c31af7Sopenharmony_ci } 896e5c31af7Sopenharmony_ci else 897e5c31af7Sopenharmony_ci { 898e5c31af7Sopenharmony_ci DE_ASSERT(false); 899e5c31af7Sopenharmony_ci } 900e5c31af7Sopenharmony_ci } 901e5c31af7Sopenharmony_ci else if (storageImageNeeded(m_params.dataType)) 902e5c31af7Sopenharmony_ci { 903e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%int"; 904e5c31af7Sopenharmony_ci subs["MAIN_INTERFACE_EXTRAS"] += " %storageImage"; 905e5c31af7Sopenharmony_ci subs["EXTRA_BINDINGS"] += " OpDecorate %storageImage DescriptorSet 0\n" 906e5c31af7Sopenharmony_ci " OpDecorate %storageImage Binding 4\n" 907e5c31af7Sopenharmony_ci ; 908e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %uint_37 = OpConstant %uint 37\n" 909e5c31af7Sopenharmony_ci " %v2int = OpTypeVector %int 2\n" 910e5c31af7Sopenharmony_ci " %image_type = OpTypeImage %uint 2D 0 0 0 2 R32ui\n" 911e5c31af7Sopenharmony_ci " %image_type_uniform_ptr = OpTypePointer UniformConstant %image_type\n" 912e5c31af7Sopenharmony_ci " %uint_img_ptr = OpTypePointer Image %uint\n" 913e5c31af7Sopenharmony_ci ; 914e5c31af7Sopenharmony_ci subs["EXTRA_BINDING_VARIABLES"] += " %storageImage = OpVariable %image_type_uniform_ptr UniformConstant\n" 915e5c31af7Sopenharmony_ci ; 916e5c31af7Sopenharmony_ci 917e5c31af7Sopenharmony_ci // Load value from the image, expecting it to be 37 and swapping it with 5. 918e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%coords = OpCompositeConstruct %v2int %input_val_before %input_val_before\n" 919e5c31af7Sopenharmony_ci "%texel_ptr = OpImageTexelPointer %uint_img_ptr %storageImage %coords %uint_0\n" 920e5c31af7Sopenharmony_ci "%texel_value = OpAtomicCompareExchange %uint %texel_ptr %uint_1 %uint_0 %uint_0 %uint_5 %uint_37\n" 921e5c31af7Sopenharmony_ci "%zero_for_callable = OpISub %uint %texel_value %uint_37\n" 922e5c31af7Sopenharmony_ci ; 923e5c31af7Sopenharmony_ci } 924e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::OP_NULL) 925e5c31af7Sopenharmony_ci { 926e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%uint"; 927e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %uint_37 = OpConstant %uint 37\n" 928e5c31af7Sopenharmony_ci " %constant_null = OpConstantNull %uint\n" 929e5c31af7Sopenharmony_ci ; 930e5c31af7Sopenharmony_ci 931e5c31af7Sopenharmony_ci // Create a local copy of the null constant global object to work with it. 932e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%constant_null_copy = OpCopyObject %uint %constant_null\n" 933e5c31af7Sopenharmony_ci "%is_37_before = OpIEqual %bool %input_val_before %uint_37\n" 934e5c31af7Sopenharmony_ci "%zero_for_callable = OpSelect %uint %is_37_before %constant_null_copy %uint_5\n" 935e5c31af7Sopenharmony_ci ; 936e5c31af7Sopenharmony_ci } 937e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::OP_UNDEF) 938e5c31af7Sopenharmony_ci { 939e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%uint"; 940e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += " %uint_37 = OpConstant %uint 37\n" 941e5c31af7Sopenharmony_ci ; 942e5c31af7Sopenharmony_ci 943e5c31af7Sopenharmony_ci // Extract an undef value and write it to the output buffer to make sure it's used before the call. The value will be overwritten later. 944e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] += "%undef_var = OpUndef %uint\n" 945e5c31af7Sopenharmony_ci "%undef_val_before = OpCopyObject %uint %undef_var\n" 946e5c31af7Sopenharmony_ci "OpStore %output_val_ptr %undef_val_before Volatile\n" 947e5c31af7Sopenharmony_ci "%zero_for_callable = OpISub %uint %uint_37 %input_val_before\n" 948e5c31af7Sopenharmony_ci ; 949e5c31af7Sopenharmony_ci } 950e5c31af7Sopenharmony_ci else 951e5c31af7Sopenharmony_ci { 952e5c31af7Sopenharmony_ci DE_ASSERT(false); 953e5c31af7Sopenharmony_ci } 954e5c31af7Sopenharmony_ci 955e5c31af7Sopenharmony_ci // Comparison statement for data before and after the call. 956e5c31af7Sopenharmony_ci switch (m_params.dataType) 957e5c31af7Sopenharmony_ci { 958e5c31af7Sopenharmony_ci case DataType::INT32: 959e5c31af7Sopenharmony_ci case DataType::UINT32: 960e5c31af7Sopenharmony_ci case DataType::INT64: 961e5c31af7Sopenharmony_ci case DataType::UINT64: 962e5c31af7Sopenharmony_ci case DataType::INT16: 963e5c31af7Sopenharmony_ci case DataType::UINT16: 964e5c31af7Sopenharmony_ci case DataType::INT8: 965e5c31af7Sopenharmony_ci case DataType::UINT8: 966e5c31af7Sopenharmony_ci opEqual = "OpIEqual"; 967e5c31af7Sopenharmony_ci break; 968e5c31af7Sopenharmony_ci case DataType::FLOAT32: 969e5c31af7Sopenharmony_ci case DataType::FLOAT64: 970e5c31af7Sopenharmony_ci case DataType::FLOAT16: 971e5c31af7Sopenharmony_ci opEqual = "OpFOrdEqual"; 972e5c31af7Sopenharmony_ci break; 973e5c31af7Sopenharmony_ci case DataType::STRUCT: 974e5c31af7Sopenharmony_ci case DataType::IMAGE: 975e5c31af7Sopenharmony_ci case DataType::SAMPLER: 976e5c31af7Sopenharmony_ci case DataType::SAMPLED_IMAGE: 977e5c31af7Sopenharmony_ci case DataType::PTR_IMAGE: 978e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLER: 979e5c31af7Sopenharmony_ci case DataType::PTR_SAMPLED_IMAGE: 980e5c31af7Sopenharmony_ci case DataType::PTR_TEXEL: 981e5c31af7Sopenharmony_ci case DataType::OP_NULL: 982e5c31af7Sopenharmony_ci case DataType::OP_UNDEF: 983e5c31af7Sopenharmony_ci // These needs special code for the comparison. 984e5c31af7Sopenharmony_ci opEqual = "INVALID"; 985e5c31af7Sopenharmony_ci break; 986e5c31af7Sopenharmony_ci default: 987e5c31af7Sopenharmony_ci DE_ASSERT(false); 988e5c31af7Sopenharmony_ci break; 989e5c31af7Sopenharmony_ci } 990e5c31af7Sopenharmony_ci 991e5c31af7Sopenharmony_ci if (m_params.dataType == DataType::STRUCT) 992e5c31af7Sopenharmony_ci { 993e5c31af7Sopenharmony_ci // We need to store the before and after values in a variable in order to be able to access each member individually without accessing the StorageBuffer again. 994e5c31af7Sopenharmony_ci subs["EXTRA_FUNCTION_VARIABLES"] = " %input_val_func_before = OpVariable %input_struct_func_ptr_type Function\n" 995e5c31af7Sopenharmony_ci " %input_val_func_after = OpVariable %input_struct_func_ptr_type Function\n" 996e5c31af7Sopenharmony_ci ; 997e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] = " OpStore %input_val_func_before %input_val_before\n" 998e5c31af7Sopenharmony_ci " OpStore %input_val_func_after %input_val_after\n" 999e5c31af7Sopenharmony_ci " %uint_part_func_before_ptr = OpAccessChain %uint_part_func_ptr_type %input_val_func_before %uint_0\n" 1000e5c31af7Sopenharmony_ci " %float_part_func_before_ptr = OpAccessChain %float_part_func_ptr_type %input_val_func_before %uint_1\n" 1001e5c31af7Sopenharmony_ci " %uint_part_func_after_ptr = OpAccessChain %uint_part_func_ptr_type %input_val_func_after %uint_0\n" 1002e5c31af7Sopenharmony_ci " %float_part_func_after_ptr = OpAccessChain %float_part_func_ptr_type %input_val_func_after %uint_1\n" 1003e5c31af7Sopenharmony_ci " %uint_part_before = OpLoad %uint %uint_part_func_before_ptr\n" 1004e5c31af7Sopenharmony_ci " %float_part_before = OpLoad %float %float_part_func_before_ptr\n" 1005e5c31af7Sopenharmony_ci " %uint_part_after = OpLoad %uint %uint_part_func_after_ptr\n" 1006e5c31af7Sopenharmony_ci " %float_part_after = OpLoad %float %float_part_func_after_ptr\n" 1007e5c31af7Sopenharmony_ci " %uint_equal = OpIEqual %bool %uint_part_before %uint_part_after\n" 1008e5c31af7Sopenharmony_ci " %float_equal = OpFOrdEqual %bool %float_part_before %float_part_after\n" 1009e5c31af7Sopenharmony_ci " %equal = OpLogicalAnd %bool %uint_equal %float_equal\n" 1010e5c31af7Sopenharmony_ci ; 1011e5c31af7Sopenharmony_ci } 1012e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::IMAGE) 1013e5c31af7Sopenharmony_ci { 1014e5c31af7Sopenharmony_ci // Use the same image and the second sampler with different coordinates (actually the same). 1015e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%sampler_1_ptr = OpAccessChain %sampler_type_uniform_ptr %textureSampler %uint_1\n" 1016e5c31af7Sopenharmony_ci "%sampler_1 = OpLoad %sampler_type %sampler_1_ptr\n" 1017e5c31af7Sopenharmony_ci "%sampled_image_1 = OpSampledImage %sampled_image_type %image_0 %sampler_1\n" 1018e5c31af7Sopenharmony_ci "%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n" 1019e5c31af7Sopenharmony_ci "%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n" 1020e5c31af7Sopenharmony_ci "%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n" 1021e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %pixel_0 %pixel_1\n" 1022e5c31af7Sopenharmony_ci ; 1023e5c31af7Sopenharmony_ci } 1024e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::SAMPLER) 1025e5c31af7Sopenharmony_ci { 1026e5c31af7Sopenharmony_ci // Use the same sampler and sample from the second image with different coordinates (but actually the same). 1027e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%image_1_ptr = OpAccessChain %image_type_uniform_ptr %sampledTexture %uint_1\n" 1028e5c31af7Sopenharmony_ci "%image_1 = OpLoad %image_type %image_1_ptr\n" 1029e5c31af7Sopenharmony_ci "%sampled_image_1 = OpSampledImage %sampled_image_type %image_1 %sampler_0\n" 1030e5c31af7Sopenharmony_ci "%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n" 1031e5c31af7Sopenharmony_ci "%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n" 1032e5c31af7Sopenharmony_ci "%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n" 1033e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %pixel_0 %pixel_1\n" 1034e5c31af7Sopenharmony_ci ; 1035e5c31af7Sopenharmony_ci } 1036e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::SAMPLED_IMAGE) 1037e5c31af7Sopenharmony_ci { 1038e5c31af7Sopenharmony_ci // Reuse the same combined image sampler with different coordinates (actually the same). 1039e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n" 1040e5c31af7Sopenharmony_ci "%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_0 %texture_coords_1 Lod|ZeroExtend %float_0\n" 1041e5c31af7Sopenharmony_ci "%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n" 1042e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %pixel_0 %pixel_1\n" 1043e5c31af7Sopenharmony_ci ; 1044e5c31af7Sopenharmony_ci } 1045e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::PTR_IMAGE) 1046e5c31af7Sopenharmony_ci { 1047e5c31af7Sopenharmony_ci // We attempt to use the second pointer only after the call. 1048e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%image_1 = OpLoad %image_type %image_1_ptr\n" 1049e5c31af7Sopenharmony_ci "%sampled_image_1 = OpSampledImage %sampled_image_type %image_1 %sampler_0\n" 1050e5c31af7Sopenharmony_ci "%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n" 1051e5c31af7Sopenharmony_ci "%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n" 1052e5c31af7Sopenharmony_ci "%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n" 1053e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %pixel_0 %pixel_1\n" 1054e5c31af7Sopenharmony_ci ; 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ci } 1057e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::PTR_SAMPLER) 1058e5c31af7Sopenharmony_ci { 1059e5c31af7Sopenharmony_ci // We attempt to use the second pointer only after the call. 1060e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%sampler_1 = OpLoad %sampler_type %sampler_1_ptr\n" 1061e5c31af7Sopenharmony_ci "%sampled_image_1 = OpSampledImage %sampled_image_type %image_0 %sampler_1\n" 1062e5c31af7Sopenharmony_ci "%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n" 1063e5c31af7Sopenharmony_ci "%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n" 1064e5c31af7Sopenharmony_ci "%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n" 1065e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %pixel_0 %pixel_1\n" 1066e5c31af7Sopenharmony_ci ; 1067e5c31af7Sopenharmony_ci } 1068e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::PTR_SAMPLED_IMAGE) 1069e5c31af7Sopenharmony_ci { 1070e5c31af7Sopenharmony_ci // We attempt to use the second pointer only after the call. 1071e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%sampled_image_1 = OpLoad %sampled_image_type %sampled_image_1_ptr\n" 1072e5c31af7Sopenharmony_ci "%texture_coords_1 = OpCompositeConstruct %v2float %input_val_after %input_val_after\n" 1073e5c31af7Sopenharmony_ci "%pixel_vec_1 = OpImageSampleExplicitLod %v4uint %sampled_image_1 %texture_coords_1 Lod|ZeroExtend %float_0\n" 1074e5c31af7Sopenharmony_ci "%pixel_1 = OpCompositeExtract %uint %pixel_vec_1 0\n" 1075e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %pixel_0 %pixel_1\n" 1076e5c31af7Sopenharmony_ci ; 1077e5c31af7Sopenharmony_ci } 1078e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::PTR_TEXEL) 1079e5c31af7Sopenharmony_ci { 1080e5c31af7Sopenharmony_ci // Check value 5 was stored properly. 1081e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%stored_val = OpAtomicLoad %uint %texel_ptr %uint_1 %uint_0\n" 1082e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %stored_val %uint_5\n" 1083e5c31af7Sopenharmony_ci ; 1084e5c31af7Sopenharmony_ci } 1085e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::OP_NULL) 1086e5c31af7Sopenharmony_ci { 1087e5c31af7Sopenharmony_ci // Reuse the null constant after the call. 1088e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%is_37_after = OpIEqual %bool %input_val_after %uint_37\n" 1089e5c31af7Sopenharmony_ci "%writeback_val = OpSelect %uint %is_37_after %constant_null_copy %uint_5\n" 1090e5c31af7Sopenharmony_ci "OpStore %input_val_ptr %writeback_val Volatile\n" 1091e5c31af7Sopenharmony_ci "%readback_val = OpLoad %uint %input_val_ptr Volatile\n" 1092e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %readback_val %uint_0\n" 1093e5c31af7Sopenharmony_ci ; 1094e5c31af7Sopenharmony_ci } 1095e5c31af7Sopenharmony_ci else if (m_params.dataType == DataType::OP_UNDEF) 1096e5c31af7Sopenharmony_ci { 1097e5c31af7Sopenharmony_ci // Extract another undef value and write it to the input buffer. It will not be checked later. 1098e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += "%undef_val_after = OpCopyObject %uint %undef_var\n" 1099e5c31af7Sopenharmony_ci "OpStore %input_val_ptr %undef_val_after Volatile\n" 1100e5c31af7Sopenharmony_ci "%equal = OpIEqual %bool %input_val_after %input_val_before\n" 1101e5c31af7Sopenharmony_ci ; 1102e5c31af7Sopenharmony_ci } 1103e5c31af7Sopenharmony_ci else 1104e5c31af7Sopenharmony_ci { 1105e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += " %equal = " + opEqual + " %bool %input_val_before %input_val_after\n"; 1106e5c31af7Sopenharmony_ci } 1107e5c31af7Sopenharmony_ci 1108e5c31af7Sopenharmony_ci // Modifications for vectors and arrays. 1109e5c31af7Sopenharmony_ci if (numComponents > 1) 1110e5c31af7Sopenharmony_ci { 1111e5c31af7Sopenharmony_ci const std::string vectorTypeName = "v" + numComponentsStr + componentTypeName; 1112e5c31af7Sopenharmony_ci const std::string opType = (isArray ? "OpTypeArray" : "OpTypeVector"); 1113e5c31af7Sopenharmony_ci const std::string componentCountStr = (isArray ? ("%uint_" + numComponentsStr) : numComponentsStr); 1114e5c31af7Sopenharmony_ci 1115e5c31af7Sopenharmony_ci // Some extra types are needed. 1116e5c31af7Sopenharmony_ci if (!(m_params.dataType == DataType::FLOAT32 && m_params.vectorType == VectorType::V3)) 1117e5c31af7Sopenharmony_ci { 1118e5c31af7Sopenharmony_ci // Note: v3float is already defined in the shader by default. 1119e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += "%" + vectorTypeName + " = " + opType + " %" + componentTypeName + " " + componentCountStr + "\n"; 1120e5c31af7Sopenharmony_ci } 1121e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += "%v" + numComponentsStr + "bool = " + opType + " %bool " + componentCountStr + "\n"; 1122e5c31af7Sopenharmony_ci subs["EXTRA_TYPES_AND_CONSTANTS"] += "%comp_ptr = OpTypePointer StorageBuffer %" + componentTypeName + "\n"; 1123e5c31af7Sopenharmony_ci 1124e5c31af7Sopenharmony_ci // The input value in the buffer has a different type. 1125e5c31af7Sopenharmony_ci subs["INPUT_BUFFER_VALUE_TYPE"] = "%" + vectorTypeName; 1126e5c31af7Sopenharmony_ci 1127e5c31af7Sopenharmony_ci // Overwrite the way we calculate the zero used in the call. 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci // Proper operations for adding, substracting and converting components. 1130e5c31af7Sopenharmony_ci std::string opAdd; 1131e5c31af7Sopenharmony_ci std::string opSub; 1132e5c31af7Sopenharmony_ci std::string opConvert; 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_ci switch (m_params.dataType) 1135e5c31af7Sopenharmony_ci { 1136e5c31af7Sopenharmony_ci case DataType::INT32: 1137e5c31af7Sopenharmony_ci case DataType::UINT32: 1138e5c31af7Sopenharmony_ci case DataType::INT64: 1139e5c31af7Sopenharmony_ci case DataType::UINT64: 1140e5c31af7Sopenharmony_ci case DataType::INT16: 1141e5c31af7Sopenharmony_ci case DataType::UINT16: 1142e5c31af7Sopenharmony_ci case DataType::INT8: 1143e5c31af7Sopenharmony_ci case DataType::UINT8: 1144e5c31af7Sopenharmony_ci opAdd = "OpIAdd"; 1145e5c31af7Sopenharmony_ci opSub = "OpISub"; 1146e5c31af7Sopenharmony_ci break; 1147e5c31af7Sopenharmony_ci case DataType::FLOAT32: 1148e5c31af7Sopenharmony_ci case DataType::FLOAT64: 1149e5c31af7Sopenharmony_ci case DataType::FLOAT16: 1150e5c31af7Sopenharmony_ci opAdd = "OpFAdd"; 1151e5c31af7Sopenharmony_ci opSub = "OpFSub"; 1152e5c31af7Sopenharmony_ci break; 1153e5c31af7Sopenharmony_ci default: 1154e5c31af7Sopenharmony_ci DE_ASSERT(false); 1155e5c31af7Sopenharmony_ci break; 1156e5c31af7Sopenharmony_ci } 1157e5c31af7Sopenharmony_ci 1158e5c31af7Sopenharmony_ci switch (m_params.dataType) 1159e5c31af7Sopenharmony_ci { 1160e5c31af7Sopenharmony_ci case DataType::UINT32: 1161e5c31af7Sopenharmony_ci opConvert = "OpCopyObject"; 1162e5c31af7Sopenharmony_ci break; 1163e5c31af7Sopenharmony_ci case DataType::INT32: 1164e5c31af7Sopenharmony_ci opConvert = "OpBitcast"; 1165e5c31af7Sopenharmony_ci break; 1166e5c31af7Sopenharmony_ci case DataType::INT64: 1167e5c31af7Sopenharmony_ci case DataType::INT16: 1168e5c31af7Sopenharmony_ci case DataType::INT8: 1169e5c31af7Sopenharmony_ci opConvert = "OpSConvert"; 1170e5c31af7Sopenharmony_ci break; 1171e5c31af7Sopenharmony_ci case DataType::UINT64: 1172e5c31af7Sopenharmony_ci case DataType::UINT16: 1173e5c31af7Sopenharmony_ci case DataType::UINT8: 1174e5c31af7Sopenharmony_ci opConvert = "OpUConvert"; 1175e5c31af7Sopenharmony_ci break; 1176e5c31af7Sopenharmony_ci case DataType::FLOAT32: 1177e5c31af7Sopenharmony_ci case DataType::FLOAT64: 1178e5c31af7Sopenharmony_ci case DataType::FLOAT16: 1179e5c31af7Sopenharmony_ci opConvert = "OpConvertFToU"; 1180e5c31af7Sopenharmony_ci break; 1181e5c31af7Sopenharmony_ci default: 1182e5c31af7Sopenharmony_ci DE_ASSERT(false); 1183e5c31af7Sopenharmony_ci break; 1184e5c31af7Sopenharmony_ci } 1185e5c31af7Sopenharmony_ci 1186e5c31af7Sopenharmony_ci std::ostringstream zeroForCallable; 1187e5c31af7Sopenharmony_ci 1188e5c31af7Sopenharmony_ci // Create pointers to components and load components. 1189e5c31af7Sopenharmony_ci for (int i = 0; i < numComponents; ++i) 1190e5c31af7Sopenharmony_ci { 1191e5c31af7Sopenharmony_ci zeroForCallable 1192e5c31af7Sopenharmony_ci << "%component_ptr_" << i << " = OpAccessChain %comp_ptr %input_val_ptr %uint_" << i << "\n" 1193e5c31af7Sopenharmony_ci << "%component_" << i << " = OpLoad %" << componentTypeName << " %component_ptr_" << i << "\n" 1194e5c31af7Sopenharmony_ci ; 1195e5c31af7Sopenharmony_ci } 1196e5c31af7Sopenharmony_ci 1197e5c31af7Sopenharmony_ci // Sum components together in %total_sum. 1198e5c31af7Sopenharmony_ci for (int i = 1; i < numComponents; ++i) 1199e5c31af7Sopenharmony_ci { 1200e5c31af7Sopenharmony_ci const std::string previous = ((i == 1) ? "%component_0" : ("%partial_" + de::toString(i-1))); 1201e5c31af7Sopenharmony_ci const std::string resultName = ((i == (numComponents - 1)) ? "%total_sum" : ("%partial_" + de::toString(i))); 1202e5c31af7Sopenharmony_ci zeroForCallable << resultName << " = " << opAdd << " %" << componentTypeName << " %component_" << i << " " << previous << "\n"; 1203e5c31af7Sopenharmony_ci } 1204e5c31af7Sopenharmony_ci 1205e5c31af7Sopenharmony_ci // Recalculate the zero. 1206e5c31af7Sopenharmony_ci zeroForCallable 1207e5c31af7Sopenharmony_ci << "%zero_" << componentTypeName << " = " << opSub << " %" << componentTypeName << " %total_sum %" << componentTypeName << "_37\n" 1208e5c31af7Sopenharmony_ci << "%zero_for_callable = " << opConvert << " %uint %zero_" << componentTypeName << "\n" 1209e5c31af7Sopenharmony_ci ; 1210e5c31af7Sopenharmony_ci 1211e5c31af7Sopenharmony_ci // Finally replace the zero_for_callable statements with the special version for vectors. 1212e5c31af7Sopenharmony_ci subs["CALC_ZERO_FOR_CALLABLE"] = zeroForCallable.str(); 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci // Rework comparison statements. 1215e5c31af7Sopenharmony_ci if (isArray) 1216e5c31af7Sopenharmony_ci { 1217e5c31af7Sopenharmony_ci // Arrays need to be compared per-component. 1218e5c31af7Sopenharmony_ci std::ostringstream calcEqual; 1219e5c31af7Sopenharmony_ci 1220e5c31af7Sopenharmony_ci for (int i = 0; i < numComponents; ++i) 1221e5c31af7Sopenharmony_ci { 1222e5c31af7Sopenharmony_ci calcEqual 1223e5c31af7Sopenharmony_ci << "%component_after_" << i << " = OpLoad %" << componentTypeName << " %component_ptr_" << i << "\n" 1224e5c31af7Sopenharmony_ci << "%equal_" << i << " = " << opEqual << " %bool %component_" << i << " %component_after_" << i << "\n"; 1225e5c31af7Sopenharmony_ci if (i > 0) 1226e5c31af7Sopenharmony_ci calcEqual << "%and_" << i << " = OpLogicalAnd %bool %equal_" << (i - 1) << " %equal_" << i << "\n"; 1227e5c31af7Sopenharmony_ci if (i == numComponents - 1) 1228e5c31af7Sopenharmony_ci calcEqual << "%equal = OpCopyObject %bool %and_" << i << "\n"; 1229e5c31af7Sopenharmony_ci } 1230e5c31af7Sopenharmony_ci 1231e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] = calcEqual.str(); 1232e5c31af7Sopenharmony_ci } 1233e5c31af7Sopenharmony_ci else 1234e5c31af7Sopenharmony_ci { 1235e5c31af7Sopenharmony_ci // Vectors can be compared using a bool vector and OpAll. 1236e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] = " %equal_vector = " + opEqual + " %v" + numComponentsStr + "bool %input_val_before %input_val_after\n"; 1237e5c31af7Sopenharmony_ci subs["CALC_EQUAL_STATEMENT"] += " %equal = OpAll %bool %equal_vector\n"; 1238e5c31af7Sopenharmony_ci } 1239e5c31af7Sopenharmony_ci } 1240e5c31af7Sopenharmony_ci 1241e5c31af7Sopenharmony_ci if (isArray) 1242e5c31af7Sopenharmony_ci { 1243e5c31af7Sopenharmony_ci // Arrays need an ArrayStride decoration. 1244e5c31af7Sopenharmony_ci std::ostringstream interfaceDecorations; 1245e5c31af7Sopenharmony_ci interfaceDecorations << "OpDecorate %v" << numComponentsStr << componentTypeName << " ArrayStride " << getElementSize(m_params.dataType, VectorType::SCALAR) << "\n"; 1246e5c31af7Sopenharmony_ci subs["INTERFACE_DECORATIONS"] = interfaceDecorations.str(); 1247e5c31af7Sopenharmony_ci } 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci const auto inputBlockDecls = getGLSLInputValDecl(m_params.dataType, m_params.vectorType); 1250e5c31af7Sopenharmony_ci 1251e5c31af7Sopenharmony_ci std::ostringstream glslBindings; 1252e5c31af7Sopenharmony_ci glslBindings 1253e5c31af7Sopenharmony_ci << inputBlockDecls.first // Additional data types needed. 1254e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n" 1255e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 1) buffer CalleeBlock { uint val; } calleeBuffer;\n" 1256e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 2) buffer OutputBlock { uint val; } outputBuffer;\n" 1257e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 3) buffer InputBlock { " << inputBlockDecls.second << " } inputBuffer;\n" 1258e5c31af7Sopenharmony_ci ; 1259e5c31af7Sopenharmony_ci 1260e5c31af7Sopenharmony_ci if (samplersNeeded(m_params.dataType)) 1261e5c31af7Sopenharmony_ci { 1262e5c31af7Sopenharmony_ci glslBindings 1263e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 4) uniform utexture2D sampledTexture[2];\n" 1264e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 5) uniform sampler textureSampler[2];\n" 1265e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 6) uniform usampler2D combinedImageSampler[2];\n" 1266e5c31af7Sopenharmony_ci ; 1267e5c31af7Sopenharmony_ci } 1268e5c31af7Sopenharmony_ci else if (storageImageNeeded(m_params.dataType)) 1269e5c31af7Sopenharmony_ci { 1270e5c31af7Sopenharmony_ci glslBindings 1271e5c31af7Sopenharmony_ci << "layout(set = 0, binding = 4, r32ui) uniform uimage2D storageImage;\n" 1272e5c31af7Sopenharmony_ci ; 1273e5c31af7Sopenharmony_ci } 1274e5c31af7Sopenharmony_ci 1275e5c31af7Sopenharmony_ci const auto glslBindingsStr = glslBindings.str(); 1276e5c31af7Sopenharmony_ci const auto glslHeaderStr = "#version 460 core\n" 1277e5c31af7Sopenharmony_ci "#extension GL_EXT_ray_tracing : require\n" 1278e5c31af7Sopenharmony_ci "#extension GL_EXT_shader_explicit_arithmetic_types : require\n"; 1279e5c31af7Sopenharmony_ci 1280e5c31af7Sopenharmony_ci 1281e5c31af7Sopenharmony_ci if (m_params.callType == CallType::TRACE_RAY) 1282e5c31af7Sopenharmony_ci { 1283e5c31af7Sopenharmony_ci subs["ENTRY_POINT"] = "RayGenerationKHR"; 1284e5c31af7Sopenharmony_ci subs["MAIN_INTERFACE_EXTRAS"] += " %hitValue"; 1285e5c31af7Sopenharmony_ci subs["INTERFACE_DECORATIONS"] += " OpDecorate %hitValue Location 0\n"; 1286e5c31af7Sopenharmony_ci subs["INTERFACE_TYPES_AND_VARIABLES"] = " %payload_ptr = OpTypePointer RayPayloadKHR %v3float\n" 1287e5c31af7Sopenharmony_ci " %hitValue = OpVariable %payload_ptr RayPayloadKHR\n"; 1288e5c31af7Sopenharmony_ci subs["CALL_STATEMENTS"] = " %as_value = OpLoad %as_type %topLevelAS\n" 1289e5c31af7Sopenharmony_ci " OpTraceRayKHR %as_value %uint_0 %uint_255 %zero_for_callable %zero_for_callable %zero_for_callable %origin_const %float_0 %direction_const %float_9 %hitValue\n"; 1290e5c31af7Sopenharmony_ci 1291e5c31af7Sopenharmony_ci const auto rgen = spvTemplate.specialize(subs); 1292e5c31af7Sopenharmony_ci programCollection.spirvAsmSources.add("rgen") << rgen << spvBuildOptions; 1293e5c31af7Sopenharmony_ci 1294e5c31af7Sopenharmony_ci std::stringstream chit; 1295e5c31af7Sopenharmony_ci chit 1296e5c31af7Sopenharmony_ci << glslHeaderStr 1297e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 1298e5c31af7Sopenharmony_ci << "hitAttributeEXT vec3 attribs;\n" 1299e5c31af7Sopenharmony_ci << glslBindingsStr 1300e5c31af7Sopenharmony_ci << "void main()\n" 1301e5c31af7Sopenharmony_ci << "{\n" 1302e5c31af7Sopenharmony_ci << " calleeBuffer.val = 1u;\n" 1303e5c31af7Sopenharmony_ci << "}\n" 1304e5c31af7Sopenharmony_ci ; 1305e5c31af7Sopenharmony_ci programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions; 1306e5c31af7Sopenharmony_ci } 1307e5c31af7Sopenharmony_ci else if (m_params.callType == CallType::EXECUTE_CALLABLE) 1308e5c31af7Sopenharmony_ci { 1309e5c31af7Sopenharmony_ci subs["ENTRY_POINT"] = "RayGenerationKHR"; 1310e5c31af7Sopenharmony_ci subs["MAIN_INTERFACE_EXTRAS"] += " %callableData"; 1311e5c31af7Sopenharmony_ci subs["INTERFACE_DECORATIONS"] += " OpDecorate %callableData Location 0\n"; 1312e5c31af7Sopenharmony_ci subs["INTERFACE_TYPES_AND_VARIABLES"] = " %callable_data_ptr = OpTypePointer CallableDataKHR %float\n" 1313e5c31af7Sopenharmony_ci " %callableData = OpVariable %callable_data_ptr CallableDataKHR\n"; 1314e5c31af7Sopenharmony_ci subs["CALL_STATEMENTS"] = " OpExecuteCallableKHR %zero_for_callable %callableData\n"; 1315e5c31af7Sopenharmony_ci 1316e5c31af7Sopenharmony_ci const auto rgen = spvTemplate.specialize(subs); 1317e5c31af7Sopenharmony_ci programCollection.spirvAsmSources.add("rgen") << rgen << spvBuildOptions; 1318e5c31af7Sopenharmony_ci 1319e5c31af7Sopenharmony_ci std::ostringstream call; 1320e5c31af7Sopenharmony_ci call 1321e5c31af7Sopenharmony_ci << glslHeaderStr 1322e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataInEXT float callableData;\n" 1323e5c31af7Sopenharmony_ci << glslBindingsStr 1324e5c31af7Sopenharmony_ci << "void main()\n" 1325e5c31af7Sopenharmony_ci << "{\n" 1326e5c31af7Sopenharmony_ci << " calleeBuffer.val = 1u;\n" 1327e5c31af7Sopenharmony_ci << "}\n" 1328e5c31af7Sopenharmony_ci ; 1329e5c31af7Sopenharmony_ci 1330e5c31af7Sopenharmony_ci programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions; 1331e5c31af7Sopenharmony_ci } 1332e5c31af7Sopenharmony_ci else if (m_params.callType == CallType::REPORT_INTERSECTION) 1333e5c31af7Sopenharmony_ci { 1334e5c31af7Sopenharmony_ci subs["ENTRY_POINT"] = "IntersectionKHR"; 1335e5c31af7Sopenharmony_ci subs["MAIN_INTERFACE_EXTRAS"] += " %attribs"; 1336e5c31af7Sopenharmony_ci subs["INTERFACE_DECORATIONS"] += ""; 1337e5c31af7Sopenharmony_ci subs["INTERFACE_TYPES_AND_VARIABLES"] = " %hit_attribute_ptr = OpTypePointer HitAttributeKHR %v3float\n" 1338e5c31af7Sopenharmony_ci " %attribs = OpVariable %hit_attribute_ptr HitAttributeKHR\n"; 1339e5c31af7Sopenharmony_ci subs["CALL_STATEMENTS"] = " %intersection_ret = OpReportIntersectionKHR %bool %float_1 %zero_for_callable\n"; 1340e5c31af7Sopenharmony_ci 1341e5c31af7Sopenharmony_ci const auto rint = spvTemplate.specialize(subs); 1342e5c31af7Sopenharmony_ci programCollection.spirvAsmSources.add("rint") << rint << spvBuildOptions; 1343e5c31af7Sopenharmony_ci 1344e5c31af7Sopenharmony_ci std::ostringstream rgen; 1345e5c31af7Sopenharmony_ci rgen 1346e5c31af7Sopenharmony_ci << glslHeaderStr 1347e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadEXT vec3 hitValue;\n" 1348e5c31af7Sopenharmony_ci << glslBindingsStr 1349e5c31af7Sopenharmony_ci << "void main()\n" 1350e5c31af7Sopenharmony_ci << "{\n" 1351e5c31af7Sopenharmony_ci << " traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n" 1352e5c31af7Sopenharmony_ci << "}\n" 1353e5c31af7Sopenharmony_ci ; 1354e5c31af7Sopenharmony_ci programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 1355e5c31af7Sopenharmony_ci 1356e5c31af7Sopenharmony_ci std::stringstream ahit; 1357e5c31af7Sopenharmony_ci ahit 1358e5c31af7Sopenharmony_ci << glslHeaderStr 1359e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 1360e5c31af7Sopenharmony_ci << "hitAttributeEXT vec3 attribs;\n" 1361e5c31af7Sopenharmony_ci << glslBindingsStr 1362e5c31af7Sopenharmony_ci << "void main()\n" 1363e5c31af7Sopenharmony_ci << "{\n" 1364e5c31af7Sopenharmony_ci << " calleeBuffer.val = 1u;\n" 1365e5c31af7Sopenharmony_ci << "}\n" 1366e5c31af7Sopenharmony_ci ; 1367e5c31af7Sopenharmony_ci programCollection.glslSources.add("ahit") << glu::AnyHitSource(updateRayTracingGLSL(ahit.str())) << buildOptions; 1368e5c31af7Sopenharmony_ci } 1369e5c31af7Sopenharmony_ci else 1370e5c31af7Sopenharmony_ci { 1371e5c31af7Sopenharmony_ci DE_ASSERT(false); 1372e5c31af7Sopenharmony_ci } 1373e5c31af7Sopenharmony_ci} 1374e5c31af7Sopenharmony_ci 1375e5c31af7Sopenharmony_ciusing v2i32 = tcu::Vector<deInt32, 2>; 1376e5c31af7Sopenharmony_ciusing v3i32 = tcu::Vector<deInt32, 3>; 1377e5c31af7Sopenharmony_ciusing v4i32 = tcu::Vector<deInt32, 4>; 1378e5c31af7Sopenharmony_ciusing a5i32 = std::array<deInt32, 5>; 1379e5c31af7Sopenharmony_ci 1380e5c31af7Sopenharmony_ciusing v2u32 = tcu::Vector<deUint32, 2>; 1381e5c31af7Sopenharmony_ciusing v3u32 = tcu::Vector<deUint32, 3>; 1382e5c31af7Sopenharmony_ciusing v4u32 = tcu::Vector<deUint32, 4>; 1383e5c31af7Sopenharmony_ciusing a5u32 = std::array<deUint32, 5>; 1384e5c31af7Sopenharmony_ci 1385e5c31af7Sopenharmony_ciusing v2i64 = tcu::Vector<deInt64, 2>; 1386e5c31af7Sopenharmony_ciusing v3i64 = tcu::Vector<deInt64, 3>; 1387e5c31af7Sopenharmony_ciusing v4i64 = tcu::Vector<deInt64, 4>; 1388e5c31af7Sopenharmony_ciusing a5i64 = std::array<deInt64, 5>; 1389e5c31af7Sopenharmony_ci 1390e5c31af7Sopenharmony_ciusing v2u64 = tcu::Vector<deUint64, 2>; 1391e5c31af7Sopenharmony_ciusing v3u64 = tcu::Vector<deUint64, 3>; 1392e5c31af7Sopenharmony_ciusing v4u64 = tcu::Vector<deUint64, 4>; 1393e5c31af7Sopenharmony_ciusing a5u64 = std::array<deUint64, 5>; 1394e5c31af7Sopenharmony_ci 1395e5c31af7Sopenharmony_ciusing v2i16 = tcu::Vector<deInt16, 2>; 1396e5c31af7Sopenharmony_ciusing v3i16 = tcu::Vector<deInt16, 3>; 1397e5c31af7Sopenharmony_ciusing v4i16 = tcu::Vector<deInt16, 4>; 1398e5c31af7Sopenharmony_ciusing a5i16 = std::array<deInt16, 5>; 1399e5c31af7Sopenharmony_ci 1400e5c31af7Sopenharmony_ciusing v2u16 = tcu::Vector<deUint16, 2>; 1401e5c31af7Sopenharmony_ciusing v3u16 = tcu::Vector<deUint16, 3>; 1402e5c31af7Sopenharmony_ciusing v4u16 = tcu::Vector<deUint16, 4>; 1403e5c31af7Sopenharmony_ciusing a5u16 = std::array<deUint16, 5>; 1404e5c31af7Sopenharmony_ci 1405e5c31af7Sopenharmony_ciusing v2i8 = tcu::Vector<deInt8, 2>; 1406e5c31af7Sopenharmony_ciusing v3i8 = tcu::Vector<deInt8, 3>; 1407e5c31af7Sopenharmony_ciusing v4i8 = tcu::Vector<deInt8, 4>; 1408e5c31af7Sopenharmony_ciusing a5i8 = std::array<deInt8, 5>; 1409e5c31af7Sopenharmony_ci 1410e5c31af7Sopenharmony_ciusing v2u8 = tcu::Vector<deUint8, 2>; 1411e5c31af7Sopenharmony_ciusing v3u8 = tcu::Vector<deUint8, 3>; 1412e5c31af7Sopenharmony_ciusing v4u8 = tcu::Vector<deUint8, 4>; 1413e5c31af7Sopenharmony_ciusing a5u8 = std::array<deUint8, 5>; 1414e5c31af7Sopenharmony_ci 1415e5c31af7Sopenharmony_ciusing v2f32 = tcu::Vector<tcu::Float32, 2>; 1416e5c31af7Sopenharmony_ciusing v3f32 = tcu::Vector<tcu::Float32, 3>; 1417e5c31af7Sopenharmony_ciusing v4f32 = tcu::Vector<tcu::Float32, 4>; 1418e5c31af7Sopenharmony_ciusing a5f32 = std::array<tcu::Float32, 5>; 1419e5c31af7Sopenharmony_ci 1420e5c31af7Sopenharmony_ciusing v2f64 = tcu::Vector<tcu::Float64, 2>; 1421e5c31af7Sopenharmony_ciusing v3f64 = tcu::Vector<tcu::Float64, 3>; 1422e5c31af7Sopenharmony_ciusing v4f64 = tcu::Vector<tcu::Float64, 4>; 1423e5c31af7Sopenharmony_ciusing a5f64 = std::array<tcu::Float64, 5>; 1424e5c31af7Sopenharmony_ci 1425e5c31af7Sopenharmony_ciusing v2f16 = tcu::Vector<tcu::Float16, 2>; 1426e5c31af7Sopenharmony_ciusing v3f16 = tcu::Vector<tcu::Float16, 3>; 1427e5c31af7Sopenharmony_ciusing v4f16 = tcu::Vector<tcu::Float16, 4>; 1428e5c31af7Sopenharmony_ciusing a5f16 = std::array<tcu::Float16, 5>; 1429e5c31af7Sopenharmony_ci 1430e5c31af7Sopenharmony_ci// Scalar types get filled with value 37, matching the value that will be substracted in the shader. 1431e5c31af7Sopenharmony_ci#define GEN_SCALAR_FILL(DATA_TYPE) \ 1432e5c31af7Sopenharmony_ci do { \ 1433e5c31af7Sopenharmony_ci const auto inputBufferValue = static_cast<DATA_TYPE>(37.0); \ 1434e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue)); \ 1435e5c31af7Sopenharmony_ci } while (0) 1436e5c31af7Sopenharmony_ci 1437e5c31af7Sopenharmony_ci// Vector types get filled with values that add up to 37, matching the value that will be substracted in the shader. 1438e5c31af7Sopenharmony_ci#define GEN_V2_FILL(DATA_TYPE) \ 1439e5c31af7Sopenharmony_ci do { \ 1440e5c31af7Sopenharmony_ci DATA_TYPE inputBufferValue; \ 1441e5c31af7Sopenharmony_ci inputBufferValue.x() = static_cast<DATA_TYPE::Element>(21.0); \ 1442e5c31af7Sopenharmony_ci inputBufferValue.y() = static_cast<DATA_TYPE::Element>(16.0); \ 1443e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue)); \ 1444e5c31af7Sopenharmony_ci } while (0) 1445e5c31af7Sopenharmony_ci 1446e5c31af7Sopenharmony_ci#define GEN_V3_FILL(DATA_TYPE) \ 1447e5c31af7Sopenharmony_ci do { \ 1448e5c31af7Sopenharmony_ci DATA_TYPE inputBufferValue; \ 1449e5c31af7Sopenharmony_ci inputBufferValue.x() = static_cast<DATA_TYPE::Element>(11.0); \ 1450e5c31af7Sopenharmony_ci inputBufferValue.y() = static_cast<DATA_TYPE::Element>(19.0); \ 1451e5c31af7Sopenharmony_ci inputBufferValue.z() = static_cast<DATA_TYPE::Element>(7.0); \ 1452e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue)); \ 1453e5c31af7Sopenharmony_ci } while (0) 1454e5c31af7Sopenharmony_ci 1455e5c31af7Sopenharmony_ci#define GEN_V4_FILL(DATA_TYPE) \ 1456e5c31af7Sopenharmony_ci do { \ 1457e5c31af7Sopenharmony_ci DATA_TYPE inputBufferValue; \ 1458e5c31af7Sopenharmony_ci inputBufferValue.x() = static_cast<DATA_TYPE::Element>(9.0); \ 1459e5c31af7Sopenharmony_ci inputBufferValue.y() = static_cast<DATA_TYPE::Element>(11.0); \ 1460e5c31af7Sopenharmony_ci inputBufferValue.z() = static_cast<DATA_TYPE::Element>(3.0); \ 1461e5c31af7Sopenharmony_ci inputBufferValue.w() = static_cast<DATA_TYPE::Element>(14.0); \ 1462e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &inputBufferValue, sizeof(inputBufferValue)); \ 1463e5c31af7Sopenharmony_ci } while (0) 1464e5c31af7Sopenharmony_ci 1465e5c31af7Sopenharmony_ci#define GEN_A5_FILL(DATA_TYPE) \ 1466e5c31af7Sopenharmony_ci do { \ 1467e5c31af7Sopenharmony_ci DATA_TYPE inputBufferValue; \ 1468e5c31af7Sopenharmony_ci inputBufferValue[0] = static_cast<DATA_TYPE::value_type>(13.0); \ 1469e5c31af7Sopenharmony_ci inputBufferValue[1] = static_cast<DATA_TYPE::value_type>(6.0); \ 1470e5c31af7Sopenharmony_ci inputBufferValue[2] = static_cast<DATA_TYPE::value_type>(2.0); \ 1471e5c31af7Sopenharmony_ci inputBufferValue[3] = static_cast<DATA_TYPE::value_type>(5.0); \ 1472e5c31af7Sopenharmony_ci inputBufferValue[4] = static_cast<DATA_TYPE::value_type>(11.0); \ 1473e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, inputBufferValue.data(), de::dataSize(inputBufferValue)); \ 1474e5c31af7Sopenharmony_ci } while (0) 1475e5c31af7Sopenharmony_ci 1476e5c31af7Sopenharmony_civoid fillInputBuffer (DataType dataType, VectorType vectorType, void* bufferPtr) 1477e5c31af7Sopenharmony_ci{ 1478e5c31af7Sopenharmony_ci if (vectorType == VectorType::SCALAR) 1479e5c31af7Sopenharmony_ci { 1480e5c31af7Sopenharmony_ci if (dataType == DataType::INT32) GEN_SCALAR_FILL(deInt32); 1481e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT32) GEN_SCALAR_FILL(deUint32); 1482e5c31af7Sopenharmony_ci else if (dataType == DataType::INT64) GEN_SCALAR_FILL(deInt64); 1483e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT64) GEN_SCALAR_FILL(deUint64); 1484e5c31af7Sopenharmony_ci else if (dataType == DataType::INT16) GEN_SCALAR_FILL(deInt16); 1485e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT16) GEN_SCALAR_FILL(deUint16); 1486e5c31af7Sopenharmony_ci else if (dataType == DataType::INT8) GEN_SCALAR_FILL(deInt8); 1487e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT8) GEN_SCALAR_FILL(deUint8); 1488e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT32) GEN_SCALAR_FILL(tcu::Float32); 1489e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT64) GEN_SCALAR_FILL(tcu::Float64); 1490e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT16) GEN_SCALAR_FILL(tcu::Float16); 1491e5c31af7Sopenharmony_ci else if (dataType == DataType::STRUCT) 1492e5c31af7Sopenharmony_ci { 1493e5c31af7Sopenharmony_ci InputStruct data = { 12u, 25.0f }; 1494e5c31af7Sopenharmony_ci deMemcpy(bufferPtr, &data, sizeof(data)); 1495e5c31af7Sopenharmony_ci } 1496e5c31af7Sopenharmony_ci else if (dataType == DataType::OP_NULL) GEN_SCALAR_FILL(deUint32); 1497e5c31af7Sopenharmony_ci else if (dataType == DataType::OP_UNDEF) GEN_SCALAR_FILL(deUint32); 1498e5c31af7Sopenharmony_ci else 1499e5c31af7Sopenharmony_ci { 1500e5c31af7Sopenharmony_ci DE_ASSERT(false); 1501e5c31af7Sopenharmony_ci } 1502e5c31af7Sopenharmony_ci } 1503e5c31af7Sopenharmony_ci else if (vectorType == VectorType::V2) 1504e5c31af7Sopenharmony_ci { 1505e5c31af7Sopenharmony_ci if (dataType == DataType::INT32) GEN_V2_FILL(v2i32); 1506e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT32) GEN_V2_FILL(v2u32); 1507e5c31af7Sopenharmony_ci else if (dataType == DataType::INT64) GEN_V2_FILL(v2i64); 1508e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT64) GEN_V2_FILL(v2u64); 1509e5c31af7Sopenharmony_ci else if (dataType == DataType::INT16) GEN_V2_FILL(v2i16); 1510e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT16) GEN_V2_FILL(v2u16); 1511e5c31af7Sopenharmony_ci else if (dataType == DataType::INT8) GEN_V2_FILL(v2i8); 1512e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT8) GEN_V2_FILL(v2u8); 1513e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT32) GEN_V2_FILL(v2f32); 1514e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT64) GEN_V2_FILL(v2f64); 1515e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT16) GEN_V2_FILL(v2f16); 1516e5c31af7Sopenharmony_ci else 1517e5c31af7Sopenharmony_ci { 1518e5c31af7Sopenharmony_ci DE_ASSERT(false); 1519e5c31af7Sopenharmony_ci } 1520e5c31af7Sopenharmony_ci } 1521e5c31af7Sopenharmony_ci else if (vectorType == VectorType::V3) 1522e5c31af7Sopenharmony_ci { 1523e5c31af7Sopenharmony_ci if (dataType == DataType::INT32) GEN_V3_FILL(v3i32); 1524e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT32) GEN_V3_FILL(v3u32); 1525e5c31af7Sopenharmony_ci else if (dataType == DataType::INT64) GEN_V3_FILL(v3i64); 1526e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT64) GEN_V3_FILL(v3u64); 1527e5c31af7Sopenharmony_ci else if (dataType == DataType::INT16) GEN_V3_FILL(v3i16); 1528e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT16) GEN_V3_FILL(v3u16); 1529e5c31af7Sopenharmony_ci else if (dataType == DataType::INT8) GEN_V3_FILL(v3i8); 1530e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT8) GEN_V3_FILL(v3u8); 1531e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT32) GEN_V3_FILL(v3f32); 1532e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT64) GEN_V3_FILL(v3f64); 1533e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT16) GEN_V3_FILL(v3f16); 1534e5c31af7Sopenharmony_ci else 1535e5c31af7Sopenharmony_ci { 1536e5c31af7Sopenharmony_ci DE_ASSERT(false); 1537e5c31af7Sopenharmony_ci } 1538e5c31af7Sopenharmony_ci } 1539e5c31af7Sopenharmony_ci else if (vectorType == VectorType::V4) 1540e5c31af7Sopenharmony_ci { 1541e5c31af7Sopenharmony_ci if (dataType == DataType::INT32) GEN_V4_FILL(v4i32); 1542e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT32) GEN_V4_FILL(v4u32); 1543e5c31af7Sopenharmony_ci else if (dataType == DataType::INT64) GEN_V4_FILL(v4i64); 1544e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT64) GEN_V4_FILL(v4u64); 1545e5c31af7Sopenharmony_ci else if (dataType == DataType::INT16) GEN_V4_FILL(v4i16); 1546e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT16) GEN_V4_FILL(v4u16); 1547e5c31af7Sopenharmony_ci else if (dataType == DataType::INT8) GEN_V4_FILL(v4i8); 1548e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT8) GEN_V4_FILL(v4u8); 1549e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT32) GEN_V4_FILL(v4f32); 1550e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT64) GEN_V4_FILL(v4f64); 1551e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT16) GEN_V4_FILL(v4f16); 1552e5c31af7Sopenharmony_ci else 1553e5c31af7Sopenharmony_ci { 1554e5c31af7Sopenharmony_ci DE_ASSERT(false); 1555e5c31af7Sopenharmony_ci } 1556e5c31af7Sopenharmony_ci } 1557e5c31af7Sopenharmony_ci else if (vectorType == VectorType::A5) 1558e5c31af7Sopenharmony_ci { 1559e5c31af7Sopenharmony_ci if (dataType == DataType::INT32) GEN_A5_FILL(a5i32); 1560e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT32) GEN_A5_FILL(a5u32); 1561e5c31af7Sopenharmony_ci else if (dataType == DataType::INT64) GEN_A5_FILL(a5i64); 1562e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT64) GEN_A5_FILL(a5u64); 1563e5c31af7Sopenharmony_ci else if (dataType == DataType::INT16) GEN_A5_FILL(a5i16); 1564e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT16) GEN_A5_FILL(a5u16); 1565e5c31af7Sopenharmony_ci else if (dataType == DataType::INT8) GEN_A5_FILL(a5i8); 1566e5c31af7Sopenharmony_ci else if (dataType == DataType::UINT8) GEN_A5_FILL(a5u8); 1567e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT32) GEN_A5_FILL(a5f32); 1568e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT64) GEN_A5_FILL(a5f64); 1569e5c31af7Sopenharmony_ci else if (dataType == DataType::FLOAT16) GEN_A5_FILL(a5f16); 1570e5c31af7Sopenharmony_ci else 1571e5c31af7Sopenharmony_ci { 1572e5c31af7Sopenharmony_ci DE_ASSERT(false); 1573e5c31af7Sopenharmony_ci } 1574e5c31af7Sopenharmony_ci } 1575e5c31af7Sopenharmony_ci else 1576e5c31af7Sopenharmony_ci { 1577e5c31af7Sopenharmony_ci DE_ASSERT(false); 1578e5c31af7Sopenharmony_ci } 1579e5c31af7Sopenharmony_ci} 1580e5c31af7Sopenharmony_ci 1581e5c31af7Sopenharmony_citcu::TestStatus DataSpillTestInstance::iterate (void) 1582e5c31af7Sopenharmony_ci{ 1583e5c31af7Sopenharmony_ci const auto& vki = m_context.getInstanceInterface(); 1584e5c31af7Sopenharmony_ci const auto physicalDevice = m_context.getPhysicalDevice(); 1585e5c31af7Sopenharmony_ci const auto& vkd = m_context.getDeviceInterface(); 1586e5c31af7Sopenharmony_ci const auto device = m_context.getDevice(); 1587e5c31af7Sopenharmony_ci const auto queue = m_context.getUniversalQueue(); 1588e5c31af7Sopenharmony_ci const auto familyIndex = m_context.getUniversalQueueFamilyIndex(); 1589e5c31af7Sopenharmony_ci auto& alloc = m_context.getDefaultAllocator(); 1590e5c31af7Sopenharmony_ci const auto shaderStages = getShaderStages(m_params.callType); 1591e5c31af7Sopenharmony_ci 1592e5c31af7Sopenharmony_ci // Command buffer. 1593e5c31af7Sopenharmony_ci const auto cmdPool = makeCommandPool(vkd, device, familyIndex); 1594e5c31af7Sopenharmony_ci const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY); 1595e5c31af7Sopenharmony_ci const auto cmdBuffer = cmdBufferPtr.get(); 1596e5c31af7Sopenharmony_ci 1597e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, cmdBuffer); 1598e5c31af7Sopenharmony_ci 1599e5c31af7Sopenharmony_ci // Callee, input and output buffers. 1600e5c31af7Sopenharmony_ci const auto calleeBufferSize = getElementSize(DataType::UINT32, VectorType::SCALAR); 1601e5c31af7Sopenharmony_ci const auto outputBufferSize = getElementSize(DataType::UINT32, VectorType::SCALAR); 1602e5c31af7Sopenharmony_ci const auto inputBufferSize = getElementSize(m_params.dataType, m_params.vectorType); 1603e5c31af7Sopenharmony_ci 1604e5c31af7Sopenharmony_ci const auto calleeBufferInfo = makeBufferCreateInfo(calleeBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 1605e5c31af7Sopenharmony_ci const auto outputBufferInfo = makeBufferCreateInfo(outputBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 1606e5c31af7Sopenharmony_ci const auto inputBufferInfo = makeBufferCreateInfo(inputBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 1607e5c31af7Sopenharmony_ci 1608e5c31af7Sopenharmony_ci BufferWithMemory calleeBuffer (vkd, device, alloc, calleeBufferInfo, MemoryRequirement::HostVisible); 1609e5c31af7Sopenharmony_ci BufferWithMemory outputBuffer (vkd, device, alloc, outputBufferInfo, MemoryRequirement::HostVisible); 1610e5c31af7Sopenharmony_ci BufferWithMemory inputBuffer (vkd, device, alloc, inputBufferInfo, MemoryRequirement::HostVisible); 1611e5c31af7Sopenharmony_ci 1612e5c31af7Sopenharmony_ci // Fill buffers with values. 1613e5c31af7Sopenharmony_ci auto& calleeBufferAlloc = calleeBuffer.getAllocation(); 1614e5c31af7Sopenharmony_ci auto* calleeBufferPtr = calleeBufferAlloc.getHostPtr(); 1615e5c31af7Sopenharmony_ci auto& outputBufferAlloc = outputBuffer.getAllocation(); 1616e5c31af7Sopenharmony_ci auto* outputBufferPtr = outputBufferAlloc.getHostPtr(); 1617e5c31af7Sopenharmony_ci auto& inputBufferAlloc = inputBuffer.getAllocation(); 1618e5c31af7Sopenharmony_ci auto* inputBufferPtr = inputBufferAlloc.getHostPtr(); 1619e5c31af7Sopenharmony_ci 1620e5c31af7Sopenharmony_ci deMemset(calleeBufferPtr, 0, static_cast<size_t>(calleeBufferSize)); 1621e5c31af7Sopenharmony_ci deMemset(outputBufferPtr, 0, static_cast<size_t>(outputBufferSize)); 1622e5c31af7Sopenharmony_ci 1623e5c31af7Sopenharmony_ci if (samplersNeeded(m_params.dataType) || storageImageNeeded(m_params.dataType)) 1624e5c31af7Sopenharmony_ci { 1625e5c31af7Sopenharmony_ci // The input buffer for these cases will be filled with zeros (sampling coordinates), and the input textures will contain the interesting input value. 1626e5c31af7Sopenharmony_ci deMemset(inputBufferPtr, 0, static_cast<size_t>(inputBufferSize)); 1627e5c31af7Sopenharmony_ci } 1628e5c31af7Sopenharmony_ci else 1629e5c31af7Sopenharmony_ci { 1630e5c31af7Sopenharmony_ci // We want to fill the input buffer with values that will be consistently used in the shader to obtain a result of zero. 1631e5c31af7Sopenharmony_ci fillInputBuffer(m_params.dataType, m_params.vectorType, inputBufferPtr); 1632e5c31af7Sopenharmony_ci } 1633e5c31af7Sopenharmony_ci 1634e5c31af7Sopenharmony_ci flushAlloc(vkd, device, calleeBufferAlloc); 1635e5c31af7Sopenharmony_ci flushAlloc(vkd, device, outputBufferAlloc); 1636e5c31af7Sopenharmony_ci flushAlloc(vkd, device, inputBufferAlloc); 1637e5c31af7Sopenharmony_ci 1638e5c31af7Sopenharmony_ci // Acceleration structures. 1639e5c31af7Sopenharmony_ci de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure; 1640e5c31af7Sopenharmony_ci de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure; 1641e5c31af7Sopenharmony_ci 1642e5c31af7Sopenharmony_ci bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure(); 1643e5c31af7Sopenharmony_ci bottomLevelAccelerationStructure->setDefaultGeometryData(getShaderStageForGeometry(m_params.callType), VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR); 1644e5c31af7Sopenharmony_ci bottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc); 1645e5c31af7Sopenharmony_ci 1646e5c31af7Sopenharmony_ci topLevelAccelerationStructure = makeTopLevelAccelerationStructure(); 1647e5c31af7Sopenharmony_ci topLevelAccelerationStructure->setInstanceCount(1); 1648e5c31af7Sopenharmony_ci topLevelAccelerationStructure->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release())); 1649e5c31af7Sopenharmony_ci topLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc); 1650e5c31af7Sopenharmony_ci 1651e5c31af7Sopenharmony_ci // Get some ray tracing properties. 1652e5c31af7Sopenharmony_ci deUint32 shaderGroupHandleSize = 0u; 1653e5c31af7Sopenharmony_ci deUint32 shaderGroupBaseAlignment = 1u; 1654e5c31af7Sopenharmony_ci { 1655e5c31af7Sopenharmony_ci const auto rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice); 1656e5c31af7Sopenharmony_ci shaderGroupHandleSize = rayTracingPropertiesKHR->getShaderGroupHandleSize(); 1657e5c31af7Sopenharmony_ci shaderGroupBaseAlignment = rayTracingPropertiesKHR->getShaderGroupBaseAlignment(); 1658e5c31af7Sopenharmony_ci } 1659e5c31af7Sopenharmony_ci 1660e5c31af7Sopenharmony_ci // Textures and samplers if needed. 1661e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> textureData; 1662e5c31af7Sopenharmony_ci std::vector<de::MovePtr<ImageWithMemory>> textures; 1663e5c31af7Sopenharmony_ci std::vector<Move<VkImageView>> textureViews; 1664e5c31af7Sopenharmony_ci std::vector<Move<VkSampler>> samplers; 1665e5c31af7Sopenharmony_ci 1666e5c31af7Sopenharmony_ci if (samplersNeeded(m_params.dataType) || storageImageNeeded(m_params.dataType)) 1667e5c31af7Sopenharmony_ci { 1668e5c31af7Sopenharmony_ci // Create texture data with the expected contents. 1669e5c31af7Sopenharmony_ci { 1670e5c31af7Sopenharmony_ci const auto textureDataSize = static_cast<VkDeviceSize>(sizeof(deUint32)); 1671e5c31af7Sopenharmony_ci const auto textureDataCreateInfo = makeBufferCreateInfo(textureDataSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT); 1672e5c31af7Sopenharmony_ci 1673e5c31af7Sopenharmony_ci textureData = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vkd, device, alloc, textureDataCreateInfo, MemoryRequirement::HostVisible)); 1674e5c31af7Sopenharmony_ci auto& textureDataAlloc = textureData->getAllocation(); 1675e5c31af7Sopenharmony_ci auto* textureDataPtr = textureDataAlloc.getHostPtr(); 1676e5c31af7Sopenharmony_ci 1677e5c31af7Sopenharmony_ci fillInputBuffer(DataType::UINT32, VectorType::SCALAR, textureDataPtr); 1678e5c31af7Sopenharmony_ci flushAlloc(vkd, device, textureDataAlloc); 1679e5c31af7Sopenharmony_ci } 1680e5c31af7Sopenharmony_ci 1681e5c31af7Sopenharmony_ci // Images will be created like this with different usages. 1682e5c31af7Sopenharmony_ci VkImageCreateInfo imageCreateInfo = 1683e5c31af7Sopenharmony_ci { 1684e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 1685e5c31af7Sopenharmony_ci nullptr, // const void* pNext; 1686e5c31af7Sopenharmony_ci 0u, // VkImageCreateFlags flags; 1687e5c31af7Sopenharmony_ci VK_IMAGE_TYPE_2D, // VkImageType imageType; 1688e5c31af7Sopenharmony_ci kImageFormat, // VkFormat format; 1689e5c31af7Sopenharmony_ci kImageExtent, // VkExtent3D extent; 1690e5c31af7Sopenharmony_ci 1u, // deUint32 mipLevels; 1691e5c31af7Sopenharmony_ci 1u, // deUint32 arrayLayers; 1692e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 1693e5c31af7Sopenharmony_ci VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 1694e5c31af7Sopenharmony_ci kSampledImageUsage, // VkImageUsageFlags usage; 1695e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 1696e5c31af7Sopenharmony_ci 0u, // deUint32 queueFamilyIndexCount; 1697e5c31af7Sopenharmony_ci nullptr, // const deUint32* pQueueFamilyIndices; 1698e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 1699e5c31af7Sopenharmony_ci }; 1700e5c31af7Sopenharmony_ci 1701e5c31af7Sopenharmony_ci const auto imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 1702e5c31af7Sopenharmony_ci const auto imageSubresourceLayers = makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u); 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci if (samplersNeeded(m_params.dataType)) 1705e5c31af7Sopenharmony_ci { 1706e5c31af7Sopenharmony_ci // All samplers will be created like this. 1707e5c31af7Sopenharmony_ci const VkSamplerCreateInfo samplerCreateInfo = 1708e5c31af7Sopenharmony_ci { 1709e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType; 1710e5c31af7Sopenharmony_ci nullptr, // const void* pNext; 1711e5c31af7Sopenharmony_ci 0u, // VkSamplerCreateFlags flags; 1712e5c31af7Sopenharmony_ci VK_FILTER_NEAREST, // VkFilter magFilter; 1713e5c31af7Sopenharmony_ci VK_FILTER_NEAREST, // VkFilter minFilter; 1714e5c31af7Sopenharmony_ci VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode; 1715e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeU; 1716e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeV; 1717e5c31af7Sopenharmony_ci VK_SAMPLER_ADDRESS_MODE_REPEAT, // VkSamplerAddressMode addressModeW; 1718e5c31af7Sopenharmony_ci 0.0, // float mipLodBias; 1719e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 anisotropyEnable; 1720e5c31af7Sopenharmony_ci 1.0f, // float maxAnisotropy; 1721e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 compareEnable; 1722e5c31af7Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp; 1723e5c31af7Sopenharmony_ci 0.0f, // float minLod; 1724e5c31af7Sopenharmony_ci 1.0f, // float maxLod; 1725e5c31af7Sopenharmony_ci VK_BORDER_COLOR_INT_OPAQUE_BLACK, // VkBorderColor borderColor; 1726e5c31af7Sopenharmony_ci VK_FALSE, // VkBool32 unnormalizedCoordinates; 1727e5c31af7Sopenharmony_ci }; 1728e5c31af7Sopenharmony_ci 1729e5c31af7Sopenharmony_ci // Create textures and samplers. 1730e5c31af7Sopenharmony_ci for (size_t i = 0; i < kNumImages; ++i) 1731e5c31af7Sopenharmony_ci { 1732e5c31af7Sopenharmony_ci textures.emplace_back(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any)); 1733e5c31af7Sopenharmony_ci textureViews.emplace_back(makeImageView(vkd, device, textures.back()->get(), VK_IMAGE_VIEW_TYPE_2D, kImageFormat, imageSubresourceRange)); 1734e5c31af7Sopenharmony_ci } 1735e5c31af7Sopenharmony_ci 1736e5c31af7Sopenharmony_ci for (size_t i = 0; i < kNumSamplers; ++i) 1737e5c31af7Sopenharmony_ci samplers.emplace_back(createSampler(vkd, device, &samplerCreateInfo)); 1738e5c31af7Sopenharmony_ci 1739e5c31af7Sopenharmony_ci // Make sure texture data is available in the transfer stage. 1740e5c31af7Sopenharmony_ci const auto textureDataBarrier = makeMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); 1741e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &textureDataBarrier, 0u, nullptr, 0u, nullptr); 1742e5c31af7Sopenharmony_ci 1743e5c31af7Sopenharmony_ci const auto bufferImageCopy = makeBufferImageCopy(kImageExtent, imageSubresourceLayers); 1744e5c31af7Sopenharmony_ci 1745e5c31af7Sopenharmony_ci // Fill textures with data and prepare them for the ray tracing pipeline stages. 1746e5c31af7Sopenharmony_ci for (size_t i = 0; i < kNumImages; ++i) 1747e5c31af7Sopenharmony_ci { 1748e5c31af7Sopenharmony_ci const auto texturePreCopyBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, textures[i]->get(), imageSubresourceRange); 1749e5c31af7Sopenharmony_ci const auto texturePostCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, textures[i]->get(), imageSubresourceRange); 1750e5c31af7Sopenharmony_ci 1751e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePreCopyBarrier); 1752e5c31af7Sopenharmony_ci vkd.cmdCopyBufferToImage(cmdBuffer, textureData->get(), textures[i]->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy); 1753e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePostCopyBarrier); 1754e5c31af7Sopenharmony_ci } 1755e5c31af7Sopenharmony_ci } 1756e5c31af7Sopenharmony_ci else if (storageImageNeeded(m_params.dataType)) 1757e5c31af7Sopenharmony_ci { 1758e5c31af7Sopenharmony_ci // Image will be used for storage. 1759e5c31af7Sopenharmony_ci imageCreateInfo.usage = kStorageImageUsage; 1760e5c31af7Sopenharmony_ci 1761e5c31af7Sopenharmony_ci textures.emplace_back(new ImageWithMemory(vkd, device, alloc, imageCreateInfo, MemoryRequirement::Any)); 1762e5c31af7Sopenharmony_ci textureViews.emplace_back(makeImageView(vkd, device, textures.back()->get(), VK_IMAGE_VIEW_TYPE_2D, kImageFormat, imageSubresourceRange)); 1763e5c31af7Sopenharmony_ci 1764e5c31af7Sopenharmony_ci // Make sure texture data is available in the transfer stage. 1765e5c31af7Sopenharmony_ci const auto textureDataBarrier = makeMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT); 1766e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 1u, &textureDataBarrier, 0u, nullptr, 0u, nullptr); 1767e5c31af7Sopenharmony_ci 1768e5c31af7Sopenharmony_ci const auto bufferImageCopy = makeBufferImageCopy(kImageExtent, imageSubresourceLayers); 1769e5c31af7Sopenharmony_ci const auto texturePreCopyBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, textures.back()->get(), imageSubresourceRange); 1770e5c31af7Sopenharmony_ci const auto texturePostCopyBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, (VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, textures.back()->get(), imageSubresourceRange); 1771e5c31af7Sopenharmony_ci 1772e5c31af7Sopenharmony_ci // Fill texture with data and prepare them for the ray tracing pipeline stages. 1773e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePreCopyBarrier); 1774e5c31af7Sopenharmony_ci vkd.cmdCopyBufferToImage(cmdBuffer, textureData->get(), textures.back()->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &bufferImageCopy); 1775e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, 0u, 0u, nullptr, 0u, nullptr, 1u, &texturePostCopyBarrier); 1776e5c31af7Sopenharmony_ci } 1777e5c31af7Sopenharmony_ci else 1778e5c31af7Sopenharmony_ci { 1779e5c31af7Sopenharmony_ci DE_ASSERT(false); 1780e5c31af7Sopenharmony_ci } 1781e5c31af7Sopenharmony_ci } 1782e5c31af7Sopenharmony_ci 1783e5c31af7Sopenharmony_ci // Descriptor set layout. 1784e5c31af7Sopenharmony_ci DescriptorSetLayoutBuilder dslBuilder; 1785e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u, shaderStages, nullptr); 1786e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr); // Callee buffer. 1787e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr); // Output buffer. 1788e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr); // Input buffer. 1789e5c31af7Sopenharmony_ci if (samplersNeeded(m_params.dataType)) 1790e5c31af7Sopenharmony_ci { 1791e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2u, shaderStages, nullptr); 1792e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_SAMPLER, 2u, shaderStages, nullptr); 1793e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, shaderStages, nullptr); 1794e5c31af7Sopenharmony_ci } 1795e5c31af7Sopenharmony_ci else if (storageImageNeeded(m_params.dataType)) 1796e5c31af7Sopenharmony_ci { 1797e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u, shaderStages, nullptr); 1798e5c31af7Sopenharmony_ci } 1799e5c31af7Sopenharmony_ci const auto descriptorSetLayout = dslBuilder.build(vkd, device); 1800e5c31af7Sopenharmony_ci 1801e5c31af7Sopenharmony_ci // Pipeline layout. 1802e5c31af7Sopenharmony_ci const auto pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get()); 1803e5c31af7Sopenharmony_ci 1804e5c31af7Sopenharmony_ci // Descriptor pool and set. 1805e5c31af7Sopenharmony_ci DescriptorPoolBuilder poolBuilder; 1806e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR); 1807e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3u); 1808e5c31af7Sopenharmony_ci if (samplersNeeded(m_params.dataType)) 1809e5c31af7Sopenharmony_ci { 1810e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 2u); 1811e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 2u); 1812e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u); 1813e5c31af7Sopenharmony_ci } 1814e5c31af7Sopenharmony_ci else if (storageImageNeeded(m_params.dataType)) 1815e5c31af7Sopenharmony_ci { 1816e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u); 1817e5c31af7Sopenharmony_ci } 1818e5c31af7Sopenharmony_ci const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 1819e5c31af7Sopenharmony_ci const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get()); 1820e5c31af7Sopenharmony_ci 1821e5c31af7Sopenharmony_ci // Update descriptor set. 1822e5c31af7Sopenharmony_ci { 1823e5c31af7Sopenharmony_ci const VkWriteDescriptorSetAccelerationStructureKHR writeASInfo = 1824e5c31af7Sopenharmony_ci { 1825e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, 1826e5c31af7Sopenharmony_ci nullptr, 1827e5c31af7Sopenharmony_ci 1u, 1828e5c31af7Sopenharmony_ci topLevelAccelerationStructure.get()->getPtr(), 1829e5c31af7Sopenharmony_ci }; 1830e5c31af7Sopenharmony_ci 1831e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder updateBuilder; 1832e5c31af7Sopenharmony_ci 1833e5c31af7Sopenharmony_ci const auto ds = descriptorSet.get(); 1834e5c31af7Sopenharmony_ci 1835e5c31af7Sopenharmony_ci const auto calleeBufferDescriptorInfo = makeDescriptorBufferInfo(calleeBuffer.get(), 0ull, VK_WHOLE_SIZE); 1836e5c31af7Sopenharmony_ci const auto outputBufferDescriptorInfo = makeDescriptorBufferInfo(outputBuffer.get(), 0ull, VK_WHOLE_SIZE); 1837e5c31af7Sopenharmony_ci const auto inputBufferDescriptorInfo = makeDescriptorBufferInfo(inputBuffer.get(), 0ull, VK_WHOLE_SIZE); 1838e5c31af7Sopenharmony_ci 1839e5c31af7Sopenharmony_ci updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeASInfo); 1840e5c31af7Sopenharmony_ci updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &calleeBufferDescriptorInfo); 1841e5c31af7Sopenharmony_ci updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(2u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo); 1842e5c31af7Sopenharmony_ci updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(3u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &inputBufferDescriptorInfo); 1843e5c31af7Sopenharmony_ci 1844e5c31af7Sopenharmony_ci if (samplersNeeded(m_params.dataType)) 1845e5c31af7Sopenharmony_ci { 1846e5c31af7Sopenharmony_ci // Update textures, samplers and combined image samplers. 1847e5c31af7Sopenharmony_ci std::vector<VkDescriptorImageInfo> textureDescInfos; 1848e5c31af7Sopenharmony_ci std::vector<VkDescriptorImageInfo> textureSamplerInfos; 1849e5c31af7Sopenharmony_ci std::vector<VkDescriptorImageInfo> combinedSamplerInfos; 1850e5c31af7Sopenharmony_ci 1851e5c31af7Sopenharmony_ci for (size_t i = 0; i < kNumAloneImages; ++i) 1852e5c31af7Sopenharmony_ci textureDescInfos.push_back(makeDescriptorImageInfo(DE_NULL, textureViews[i].get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); 1853e5c31af7Sopenharmony_ci for (size_t i = 0; i < kNumAloneSamplers; ++i) 1854e5c31af7Sopenharmony_ci textureSamplerInfos.push_back(makeDescriptorImageInfo(samplers[i].get(), DE_NULL, VK_IMAGE_LAYOUT_UNDEFINED)); 1855e5c31af7Sopenharmony_ci 1856e5c31af7Sopenharmony_ci for (size_t i = 0; i < kNumCombined; ++i) 1857e5c31af7Sopenharmony_ci combinedSamplerInfos.push_back(makeDescriptorImageInfo(samplers[i + kNumAloneSamplers].get(), textureViews[i + kNumAloneImages].get(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); 1858e5c31af7Sopenharmony_ci 1859e5c31af7Sopenharmony_ci updateBuilder.writeArray(ds, DescriptorSetUpdateBuilder::Location::binding(4u), VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, kNumAloneImages, textureDescInfos.data()); 1860e5c31af7Sopenharmony_ci updateBuilder.writeArray(ds, DescriptorSetUpdateBuilder::Location::binding(5u), VK_DESCRIPTOR_TYPE_SAMPLER, kNumAloneSamplers, textureSamplerInfos.data()); 1861e5c31af7Sopenharmony_ci updateBuilder.writeArray(ds, DescriptorSetUpdateBuilder::Location::binding(6u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, kNumCombined, combinedSamplerInfos.data()); 1862e5c31af7Sopenharmony_ci } 1863e5c31af7Sopenharmony_ci else if (storageImageNeeded(m_params.dataType)) 1864e5c31af7Sopenharmony_ci { 1865e5c31af7Sopenharmony_ci const auto storageImageDescriptorInfo = makeDescriptorImageInfo(DE_NULL, textureViews.back().get(), VK_IMAGE_LAYOUT_GENERAL); 1866e5c31af7Sopenharmony_ci updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(4u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &storageImageDescriptorInfo); 1867e5c31af7Sopenharmony_ci } 1868e5c31af7Sopenharmony_ci 1869e5c31af7Sopenharmony_ci updateBuilder.update(vkd, device); 1870e5c31af7Sopenharmony_ci } 1871e5c31af7Sopenharmony_ci 1872e5c31af7Sopenharmony_ci // Create raytracing pipeline and shader binding tables. 1873e5c31af7Sopenharmony_ci Move<VkPipeline> pipeline; 1874e5c31af7Sopenharmony_ci 1875e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> raygenShaderBindingTable; 1876e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> missShaderBindingTable; 1877e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> hitShaderBindingTable; 1878e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> callableShaderBindingTable; 1879e5c31af7Sopenharmony_ci 1880e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1881e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1882e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1883e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 1884e5c31af7Sopenharmony_ci 1885e5c31af7Sopenharmony_ci { 1886e5c31af7Sopenharmony_ci const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>(); 1887e5c31af7Sopenharmony_ci const auto callType = m_params.callType; 1888e5c31af7Sopenharmony_ci 1889e5c31af7Sopenharmony_ci // Every case uses a ray generation shader. 1890e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0), 0); 1891e5c31af7Sopenharmony_ci 1892e5c31af7Sopenharmony_ci if (callType == CallType::TRACE_RAY) 1893e5c31af7Sopenharmony_ci { 1894e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1); 1895e5c31af7Sopenharmony_ci } 1896e5c31af7Sopenharmony_ci else if (callType == CallType::EXECUTE_CALLABLE) 1897e5c31af7Sopenharmony_ci { 1898e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 1); 1899e5c31af7Sopenharmony_ci } 1900e5c31af7Sopenharmony_ci else if (callType == CallType::REPORT_INTERSECTION) 1901e5c31af7Sopenharmony_ci { 1902e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rint"), 0), 1); 1903e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_ANY_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("ahit"), 0), 1); 1904e5c31af7Sopenharmony_ci } 1905e5c31af7Sopenharmony_ci else 1906e5c31af7Sopenharmony_ci { 1907e5c31af7Sopenharmony_ci DE_ASSERT(false); 1908e5c31af7Sopenharmony_ci } 1909e5c31af7Sopenharmony_ci 1910e5c31af7Sopenharmony_ci pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout.get()); 1911e5c31af7Sopenharmony_ci 1912e5c31af7Sopenharmony_ci raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1); 1913e5c31af7Sopenharmony_ci raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 1914e5c31af7Sopenharmony_ci 1915e5c31af7Sopenharmony_ci if (callType == CallType::EXECUTE_CALLABLE) 1916e5c31af7Sopenharmony_ci { 1917e5c31af7Sopenharmony_ci callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1); 1918e5c31af7Sopenharmony_ci callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 1919e5c31af7Sopenharmony_ci } 1920e5c31af7Sopenharmony_ci else if (callType == CallType::TRACE_RAY || callType == CallType::REPORT_INTERSECTION) 1921e5c31af7Sopenharmony_ci { 1922e5c31af7Sopenharmony_ci hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1); 1923e5c31af7Sopenharmony_ci hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 1924e5c31af7Sopenharmony_ci } 1925e5c31af7Sopenharmony_ci else 1926e5c31af7Sopenharmony_ci { 1927e5c31af7Sopenharmony_ci DE_ASSERT(false); 1928e5c31af7Sopenharmony_ci } 1929e5c31af7Sopenharmony_ci } 1930e5c31af7Sopenharmony_ci 1931e5c31af7Sopenharmony_ci // Use ray tracing pipeline. 1932e5c31af7Sopenharmony_ci vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get()); 1933e5c31af7Sopenharmony_ci vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr); 1934e5c31af7Sopenharmony_ci vkd.cmdTraceRaysKHR(cmdBuffer, &raygenShaderBindingTableRegion, &missShaderBindingTableRegion, &hitShaderBindingTableRegion, &callableShaderBindingTableRegion, 1u, 1u, 1u); 1935e5c31af7Sopenharmony_ci 1936e5c31af7Sopenharmony_ci // Synchronize output and callee buffers. 1937e5c31af7Sopenharmony_ci const auto memBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 1938e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &memBarrier, 0u, nullptr, 0u, nullptr); 1939e5c31af7Sopenharmony_ci 1940e5c31af7Sopenharmony_ci endCommandBuffer(vkd, cmdBuffer); 1941e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, cmdBuffer); 1942e5c31af7Sopenharmony_ci 1943e5c31af7Sopenharmony_ci // Verify output and callee buffers. 1944e5c31af7Sopenharmony_ci invalidateAlloc(vkd, device, outputBufferAlloc); 1945e5c31af7Sopenharmony_ci invalidateAlloc(vkd, device, calleeBufferAlloc); 1946e5c31af7Sopenharmony_ci 1947e5c31af7Sopenharmony_ci std::map<std::string, void*> bufferPtrs; 1948e5c31af7Sopenharmony_ci bufferPtrs["output"] = outputBufferPtr; 1949e5c31af7Sopenharmony_ci bufferPtrs["callee"] = calleeBufferPtr; 1950e5c31af7Sopenharmony_ci 1951e5c31af7Sopenharmony_ci for (const auto& ptr : bufferPtrs) 1952e5c31af7Sopenharmony_ci { 1953e5c31af7Sopenharmony_ci const auto& bufferName = ptr.first; 1954e5c31af7Sopenharmony_ci const auto& bufferPtr = ptr.second; 1955e5c31af7Sopenharmony_ci 1956e5c31af7Sopenharmony_ci deUint32 outputVal; 1957e5c31af7Sopenharmony_ci deMemcpy(&outputVal, bufferPtr, sizeof(outputVal)); 1958e5c31af7Sopenharmony_ci 1959e5c31af7Sopenharmony_ci if (outputVal != 1u) 1960e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Unexpected value found in " + bufferName + " buffer: " + de::toString(outputVal)); 1961e5c31af7Sopenharmony_ci } 1962e5c31af7Sopenharmony_ci 1963e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Pass"); 1964e5c31af7Sopenharmony_ci} 1965e5c31af7Sopenharmony_ci 1966e5c31af7Sopenharmony_cienum class InterfaceType 1967e5c31af7Sopenharmony_ci{ 1968e5c31af7Sopenharmony_ci RAY_PAYLOAD = 0, 1969e5c31af7Sopenharmony_ci CALLABLE_DATA, 1970e5c31af7Sopenharmony_ci HIT_ATTRIBUTES, 1971e5c31af7Sopenharmony_ci SHADER_RECORD_BUFFER_RGEN, 1972e5c31af7Sopenharmony_ci SHADER_RECORD_BUFFER_CALL, 1973e5c31af7Sopenharmony_ci SHADER_RECORD_BUFFER_MISS, 1974e5c31af7Sopenharmony_ci SHADER_RECORD_BUFFER_HIT, 1975e5c31af7Sopenharmony_ci}; 1976e5c31af7Sopenharmony_ci 1977e5c31af7Sopenharmony_ci// Separate class to ease testing pipeline interface variables. 1978e5c31af7Sopenharmony_ciclass DataSpillPipelineInterfaceTestCase : public vkt::TestCase 1979e5c31af7Sopenharmony_ci{ 1980e5c31af7Sopenharmony_cipublic: 1981e5c31af7Sopenharmony_ci struct TestParams 1982e5c31af7Sopenharmony_ci { 1983e5c31af7Sopenharmony_ci InterfaceType interfaceType; 1984e5c31af7Sopenharmony_ci }; 1985e5c31af7Sopenharmony_ci 1986e5c31af7Sopenharmony_ci DataSpillPipelineInterfaceTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams); 1987e5c31af7Sopenharmony_ci virtual ~DataSpillPipelineInterfaceTestCase (void) {} 1988e5c31af7Sopenharmony_ci 1989e5c31af7Sopenharmony_ci virtual void initPrograms (vk::SourceCollections& programCollection) const; 1990e5c31af7Sopenharmony_ci virtual TestInstance* createInstance (Context& context) const; 1991e5c31af7Sopenharmony_ci virtual void checkSupport (Context& context) const; 1992e5c31af7Sopenharmony_ci 1993e5c31af7Sopenharmony_ciprivate: 1994e5c31af7Sopenharmony_ci TestParams m_params; 1995e5c31af7Sopenharmony_ci}; 1996e5c31af7Sopenharmony_ci 1997e5c31af7Sopenharmony_ciclass DataSpillPipelineInterfaceTestInstance : public vkt::TestInstance 1998e5c31af7Sopenharmony_ci{ 1999e5c31af7Sopenharmony_cipublic: 2000e5c31af7Sopenharmony_ci using TestParams = DataSpillPipelineInterfaceTestCase::TestParams; 2001e5c31af7Sopenharmony_ci 2002e5c31af7Sopenharmony_ci DataSpillPipelineInterfaceTestInstance (Context& context, const TestParams& testParams); 2003e5c31af7Sopenharmony_ci ~DataSpillPipelineInterfaceTestInstance (void) {} 2004e5c31af7Sopenharmony_ci 2005e5c31af7Sopenharmony_ci tcu::TestStatus iterate (void); 2006e5c31af7Sopenharmony_ci 2007e5c31af7Sopenharmony_ciprivate: 2008e5c31af7Sopenharmony_ci TestParams m_params; 2009e5c31af7Sopenharmony_ci}; 2010e5c31af7Sopenharmony_ci 2011e5c31af7Sopenharmony_ciDataSpillPipelineInterfaceTestCase::DataSpillPipelineInterfaceTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& testParams) 2012e5c31af7Sopenharmony_ci : vkt::TestCase (testCtx, name) 2013e5c31af7Sopenharmony_ci , m_params (testParams) 2014e5c31af7Sopenharmony_ci{ 2015e5c31af7Sopenharmony_ci} 2016e5c31af7Sopenharmony_ci 2017e5c31af7Sopenharmony_ciTestInstance* DataSpillPipelineInterfaceTestCase::createInstance (Context& context) const 2018e5c31af7Sopenharmony_ci{ 2019e5c31af7Sopenharmony_ci return new DataSpillPipelineInterfaceTestInstance (context, m_params); 2020e5c31af7Sopenharmony_ci} 2021e5c31af7Sopenharmony_ci 2022e5c31af7Sopenharmony_ciDataSpillPipelineInterfaceTestInstance::DataSpillPipelineInterfaceTestInstance (Context& context, const TestParams& testParams) 2023e5c31af7Sopenharmony_ci : vkt::TestInstance (context) 2024e5c31af7Sopenharmony_ci , m_params (testParams) 2025e5c31af7Sopenharmony_ci{ 2026e5c31af7Sopenharmony_ci} 2027e5c31af7Sopenharmony_ci 2028e5c31af7Sopenharmony_civoid DataSpillPipelineInterfaceTestCase::checkSupport (Context& context) const 2029e5c31af7Sopenharmony_ci{ 2030e5c31af7Sopenharmony_ci commonCheckSupport(context); 2031e5c31af7Sopenharmony_ci} 2032e5c31af7Sopenharmony_ci 2033e5c31af7Sopenharmony_civoid DataSpillPipelineInterfaceTestCase::initPrograms (vk::SourceCollections& programCollection) const 2034e5c31af7Sopenharmony_ci{ 2035e5c31af7Sopenharmony_ci const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 2036e5c31af7Sopenharmony_ci 2037e5c31af7Sopenharmony_ci const std::string glslHeader = 2038e5c31af7Sopenharmony_ci "#version 460 core\n" 2039e5c31af7Sopenharmony_ci "#extension GL_EXT_ray_tracing : require\n" 2040e5c31af7Sopenharmony_ci ; 2041e5c31af7Sopenharmony_ci 2042e5c31af7Sopenharmony_ci const std::string glslBindings = 2043e5c31af7Sopenharmony_ci "layout(set = 0, binding = 0) uniform accelerationStructureEXT topLevelAS;\n" 2044e5c31af7Sopenharmony_ci "layout(set = 0, binding = 1) buffer StorageBlock { uint val[" + std::to_string(kNumStorageValues) + "]; } storageBuffer;\n" 2045e5c31af7Sopenharmony_ci ; 2046e5c31af7Sopenharmony_ci 2047e5c31af7Sopenharmony_ci if (m_params.interfaceType == InterfaceType::RAY_PAYLOAD) 2048e5c31af7Sopenharmony_ci { 2049e5c31af7Sopenharmony_ci // The closest hit shader will store 100 in the second array position. 2050e5c31af7Sopenharmony_ci // The ray gen shader will store 103 in the first array position using the hitValue after the traceRayExt() call. 2051e5c31af7Sopenharmony_ci 2052e5c31af7Sopenharmony_ci std::ostringstream rgen; 2053e5c31af7Sopenharmony_ci rgen 2054e5c31af7Sopenharmony_ci << glslHeader 2055e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadEXT vec3 hitValue;\n" 2056e5c31af7Sopenharmony_ci << glslBindings 2057e5c31af7Sopenharmony_ci << "void main()\n" 2058e5c31af7Sopenharmony_ci << "{\n" 2059e5c31af7Sopenharmony_ci << " hitValue = vec3(10.0, 30.0, 60.0);\n" 2060e5c31af7Sopenharmony_ci << " traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n" 2061e5c31af7Sopenharmony_ci << " storageBuffer.val[0] = uint(hitValue.x + hitValue.y + hitValue.z);\n" 2062e5c31af7Sopenharmony_ci << "}\n" 2063e5c31af7Sopenharmony_ci ; 2064e5c31af7Sopenharmony_ci programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 2065e5c31af7Sopenharmony_ci 2066e5c31af7Sopenharmony_ci std::stringstream chit; 2067e5c31af7Sopenharmony_ci chit 2068e5c31af7Sopenharmony_ci << glslHeader 2069e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 2070e5c31af7Sopenharmony_ci << "hitAttributeEXT vec3 attribs;\n" 2071e5c31af7Sopenharmony_ci << glslBindings 2072e5c31af7Sopenharmony_ci << "void main()\n" 2073e5c31af7Sopenharmony_ci << "{\n" 2074e5c31af7Sopenharmony_ci << " storageBuffer.val[1] = uint(hitValue.x + hitValue.y + hitValue.z);\n" 2075e5c31af7Sopenharmony_ci << " hitValue = vec3(hitValue.x + 1.0, hitValue.y + 1.0, hitValue.z + 1.0);\n" 2076e5c31af7Sopenharmony_ci << "}\n" 2077e5c31af7Sopenharmony_ci ; 2078e5c31af7Sopenharmony_ci programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions; 2079e5c31af7Sopenharmony_ci } 2080e5c31af7Sopenharmony_ci else if (m_params.interfaceType == InterfaceType::CALLABLE_DATA) 2081e5c31af7Sopenharmony_ci { 2082e5c31af7Sopenharmony_ci // The callable shader shader will store 100 in the second array position. 2083e5c31af7Sopenharmony_ci // The ray gen shader will store 200 in the first array position using the callable data after the executeCallableEXT() call. 2084e5c31af7Sopenharmony_ci 2085e5c31af7Sopenharmony_ci std::ostringstream rgen; 2086e5c31af7Sopenharmony_ci rgen 2087e5c31af7Sopenharmony_ci << glslHeader 2088e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataEXT float callableData;\n" 2089e5c31af7Sopenharmony_ci << glslBindings 2090e5c31af7Sopenharmony_ci << "void main()\n" 2091e5c31af7Sopenharmony_ci << "{\n" 2092e5c31af7Sopenharmony_ci << " callableData = 100.0;\n" 2093e5c31af7Sopenharmony_ci << " executeCallableEXT(0, 0);\n" 2094e5c31af7Sopenharmony_ci << " storageBuffer.val[0] = uint(callableData);\n" 2095e5c31af7Sopenharmony_ci << "}\n" 2096e5c31af7Sopenharmony_ci ; 2097e5c31af7Sopenharmony_ci programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 2098e5c31af7Sopenharmony_ci 2099e5c31af7Sopenharmony_ci std::ostringstream call; 2100e5c31af7Sopenharmony_ci call 2101e5c31af7Sopenharmony_ci << glslHeader 2102e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataInEXT float callableData;\n" 2103e5c31af7Sopenharmony_ci << glslBindings 2104e5c31af7Sopenharmony_ci << "void main()\n" 2105e5c31af7Sopenharmony_ci << "{\n" 2106e5c31af7Sopenharmony_ci << " storageBuffer.val[1] = uint(callableData);\n" 2107e5c31af7Sopenharmony_ci << " callableData = callableData * 2.0;\n" 2108e5c31af7Sopenharmony_ci << "}\n" 2109e5c31af7Sopenharmony_ci ; 2110e5c31af7Sopenharmony_ci 2111e5c31af7Sopenharmony_ci programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions; 2112e5c31af7Sopenharmony_ci } 2113e5c31af7Sopenharmony_ci else if (m_params.interfaceType == InterfaceType::HIT_ATTRIBUTES) 2114e5c31af7Sopenharmony_ci { 2115e5c31af7Sopenharmony_ci // The ray gen shader will store value 300 in the first storage buffer position. 2116e5c31af7Sopenharmony_ci // The intersection shader will store value 315 in the second storage buffer position. 2117e5c31af7Sopenharmony_ci // The closes hit shader will store value 330 in the third storage buffer position using the hit attributes. 2118e5c31af7Sopenharmony_ci 2119e5c31af7Sopenharmony_ci std::ostringstream rgen; 2120e5c31af7Sopenharmony_ci rgen 2121e5c31af7Sopenharmony_ci << glslHeader 2122e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadEXT vec3 hitValue;\n" 2123e5c31af7Sopenharmony_ci << glslBindings 2124e5c31af7Sopenharmony_ci << "void main()\n" 2125e5c31af7Sopenharmony_ci << "{\n" 2126e5c31af7Sopenharmony_ci << " traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n" 2127e5c31af7Sopenharmony_ci << " storageBuffer.val[0] = 300u;\n" 2128e5c31af7Sopenharmony_ci << "}\n" 2129e5c31af7Sopenharmony_ci ; 2130e5c31af7Sopenharmony_ci programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 2131e5c31af7Sopenharmony_ci 2132e5c31af7Sopenharmony_ci std::stringstream rint; 2133e5c31af7Sopenharmony_ci rint 2134e5c31af7Sopenharmony_ci << glslHeader 2135e5c31af7Sopenharmony_ci << "hitAttributeEXT vec3 attribs;\n" 2136e5c31af7Sopenharmony_ci << glslBindings 2137e5c31af7Sopenharmony_ci << "void main()\n" 2138e5c31af7Sopenharmony_ci << "{\n" 2139e5c31af7Sopenharmony_ci << " attribs = vec3(140.0, 160.0, 30.0);\n" 2140e5c31af7Sopenharmony_ci << " storageBuffer.val[1] = 315u;\n" 2141e5c31af7Sopenharmony_ci << " reportIntersectionEXT(1.0f, 0);\n" 2142e5c31af7Sopenharmony_ci << "}\n" 2143e5c31af7Sopenharmony_ci ; 2144e5c31af7Sopenharmony_ci 2145e5c31af7Sopenharmony_ci programCollection.glslSources.add("rint") << glu::IntersectionSource(updateRayTracingGLSL(rint.str())) << buildOptions; 2146e5c31af7Sopenharmony_ci 2147e5c31af7Sopenharmony_ci std::stringstream chit; 2148e5c31af7Sopenharmony_ci chit 2149e5c31af7Sopenharmony_ci << glslHeader 2150e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadInEXT vec3 hitValue;\n" 2151e5c31af7Sopenharmony_ci << "hitAttributeEXT vec3 attribs;\n" 2152e5c31af7Sopenharmony_ci << glslBindings 2153e5c31af7Sopenharmony_ci << "void main()\n" 2154e5c31af7Sopenharmony_ci << "{\n" 2155e5c31af7Sopenharmony_ci << " storageBuffer.val[2] = uint(attribs.x + attribs.y + attribs.z);\n" 2156e5c31af7Sopenharmony_ci << "}\n" 2157e5c31af7Sopenharmony_ci ; 2158e5c31af7Sopenharmony_ci programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chit.str())) << buildOptions; 2159e5c31af7Sopenharmony_ci 2160e5c31af7Sopenharmony_ci } 2161e5c31af7Sopenharmony_ci else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN) 2162e5c31af7Sopenharmony_ci { 2163e5c31af7Sopenharmony_ci // The ray gen shader will have a uvec4 in the shader record buffer with contents 400, 401, 402, 403. 2164e5c31af7Sopenharmony_ci // The shader will call a callable shader indicating a position in that vec4 (0, 1, 2, 3). For example, let's use position 1. 2165e5c31af7Sopenharmony_ci // The callable shader will return the indicated position+1 modulo 4, so it will return 2 in our case. 2166e5c31af7Sopenharmony_ci // *After* returning from the callable shader, the raygen shader will use that reply to access position 2 and write a 402 in the first output buffer position. 2167e5c31af7Sopenharmony_ci // The callable shader will store 450 in the second output buffer position. 2168e5c31af7Sopenharmony_ci 2169e5c31af7Sopenharmony_ci std::ostringstream rgen; 2170e5c31af7Sopenharmony_ci rgen 2171e5c31af7Sopenharmony_ci << glslHeader 2172e5c31af7Sopenharmony_ci << "layout(shaderRecordEXT) buffer ShaderRecordStruct {\n" 2173e5c31af7Sopenharmony_ci << " uvec4 info;\n" 2174e5c31af7Sopenharmony_ci << "};\n" 2175e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataEXT uint callableData;\n" 2176e5c31af7Sopenharmony_ci << glslBindings 2177e5c31af7Sopenharmony_ci << "void main()\n" 2178e5c31af7Sopenharmony_ci << "{\n" 2179e5c31af7Sopenharmony_ci << " callableData = 1u;" 2180e5c31af7Sopenharmony_ci << " executeCallableEXT(0, 0);\n" 2181e5c31af7Sopenharmony_ci << " if (callableData == 0u) storageBuffer.val[0] = info.x;\n" 2182e5c31af7Sopenharmony_ci << " else if (callableData == 1u) storageBuffer.val[0] = info.y;\n" 2183e5c31af7Sopenharmony_ci << " else if (callableData == 2u) storageBuffer.val[0] = info.z;\n" 2184e5c31af7Sopenharmony_ci << " else if (callableData == 3u) storageBuffer.val[0] = info.w;\n" 2185e5c31af7Sopenharmony_ci << "}\n" 2186e5c31af7Sopenharmony_ci ; 2187e5c31af7Sopenharmony_ci programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 2188e5c31af7Sopenharmony_ci 2189e5c31af7Sopenharmony_ci std::ostringstream call; 2190e5c31af7Sopenharmony_ci call 2191e5c31af7Sopenharmony_ci << glslHeader 2192e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataInEXT uint callableData;\n" 2193e5c31af7Sopenharmony_ci << glslBindings 2194e5c31af7Sopenharmony_ci << "void main()\n" 2195e5c31af7Sopenharmony_ci << "{\n" 2196e5c31af7Sopenharmony_ci << " storageBuffer.val[1] = 450u;\n" 2197e5c31af7Sopenharmony_ci << " callableData = (callableData + 1u) % 4u;\n" 2198e5c31af7Sopenharmony_ci << "}\n" 2199e5c31af7Sopenharmony_ci ; 2200e5c31af7Sopenharmony_ci 2201e5c31af7Sopenharmony_ci programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions; 2202e5c31af7Sopenharmony_ci } 2203e5c31af7Sopenharmony_ci else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL) 2204e5c31af7Sopenharmony_ci { 2205e5c31af7Sopenharmony_ci // Similar to the previous case, with a twist: 2206e5c31af7Sopenharmony_ci // * rgen passes the vector position. 2207e5c31af7Sopenharmony_ci // * call increases that by one. 2208e5c31af7Sopenharmony_ci // * subcall increases again and does the modulo operation, also writing 450 in the third output buffer value. 2209e5c31af7Sopenharmony_ci // * call is the one accessing the vector at the returned position, writing 403 in this case to the second output buffer value. 2210e5c31af7Sopenharmony_ci // * call passes this value back doubled to rgen, which writes it to the first output buffer value (806). 2211e5c31af7Sopenharmony_ci 2212e5c31af7Sopenharmony_ci std::ostringstream rgen; 2213e5c31af7Sopenharmony_ci rgen 2214e5c31af7Sopenharmony_ci << glslHeader 2215e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataEXT uint callableData;\n" 2216e5c31af7Sopenharmony_ci << glslBindings 2217e5c31af7Sopenharmony_ci << "void main()\n" 2218e5c31af7Sopenharmony_ci << "{\n" 2219e5c31af7Sopenharmony_ci << " callableData = 1u;\n" 2220e5c31af7Sopenharmony_ci << " executeCallableEXT(0, 0);\n" 2221e5c31af7Sopenharmony_ci << " storageBuffer.val[0] = callableData;\n" 2222e5c31af7Sopenharmony_ci << "}\n" 2223e5c31af7Sopenharmony_ci ; 2224e5c31af7Sopenharmony_ci programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 2225e5c31af7Sopenharmony_ci 2226e5c31af7Sopenharmony_ci std::ostringstream call; 2227e5c31af7Sopenharmony_ci call 2228e5c31af7Sopenharmony_ci << glslHeader 2229e5c31af7Sopenharmony_ci << "layout(shaderRecordEXT) buffer ShaderRecordStruct {\n" 2230e5c31af7Sopenharmony_ci << " uvec4 info;\n" 2231e5c31af7Sopenharmony_ci << "};\n" 2232e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataInEXT uint callableDataIn;\n" 2233e5c31af7Sopenharmony_ci << "layout(location = 1) callableDataEXT uint callableDataOut;\n" 2234e5c31af7Sopenharmony_ci << glslBindings 2235e5c31af7Sopenharmony_ci << "void main()\n" 2236e5c31af7Sopenharmony_ci << "{\n" 2237e5c31af7Sopenharmony_ci << " callableDataOut = callableDataIn + 1u;\n" 2238e5c31af7Sopenharmony_ci << " executeCallableEXT(1, 1);\n" 2239e5c31af7Sopenharmony_ci << " uint outputBufferValue = 777u;\n" 2240e5c31af7Sopenharmony_ci << " if (callableDataOut == 0u) outputBufferValue = info.x;\n" 2241e5c31af7Sopenharmony_ci << " else if (callableDataOut == 1u) outputBufferValue = info.y;\n" 2242e5c31af7Sopenharmony_ci << " else if (callableDataOut == 2u) outputBufferValue = info.z;\n" 2243e5c31af7Sopenharmony_ci << " else if (callableDataOut == 3u) outputBufferValue = info.w;\n" 2244e5c31af7Sopenharmony_ci << " storageBuffer.val[1] = outputBufferValue;\n" 2245e5c31af7Sopenharmony_ci << " callableDataIn = outputBufferValue * 2u;\n" 2246e5c31af7Sopenharmony_ci << "}\n" 2247e5c31af7Sopenharmony_ci ; 2248e5c31af7Sopenharmony_ci 2249e5c31af7Sopenharmony_ci programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions; 2250e5c31af7Sopenharmony_ci 2251e5c31af7Sopenharmony_ci std::ostringstream subcall; 2252e5c31af7Sopenharmony_ci subcall 2253e5c31af7Sopenharmony_ci << glslHeader 2254e5c31af7Sopenharmony_ci << "layout(location = 1) callableDataInEXT uint callableData;\n" 2255e5c31af7Sopenharmony_ci << glslBindings 2256e5c31af7Sopenharmony_ci << "void main()\n" 2257e5c31af7Sopenharmony_ci << "{\n" 2258e5c31af7Sopenharmony_ci << " callableData = (callableData + 1u) % 4u;\n" 2259e5c31af7Sopenharmony_ci << " storageBuffer.val[2] = 450u;\n" 2260e5c31af7Sopenharmony_ci << "}\n" 2261e5c31af7Sopenharmony_ci ; 2262e5c31af7Sopenharmony_ci 2263e5c31af7Sopenharmony_ci programCollection.glslSources.add("subcall") << glu::CallableSource(updateRayTracingGLSL(subcall.str())) << buildOptions; 2264e5c31af7Sopenharmony_ci } 2265e5c31af7Sopenharmony_ci else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS || m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT) 2266e5c31af7Sopenharmony_ci { 2267e5c31af7Sopenharmony_ci // Similar to the previous one, but the intermediate call shader has been replaced with a miss or closest hit shader. 2268e5c31af7Sopenharmony_ci // The rgen shader will communicate with the miss/chit shader using the ray payload instead of the callable data. 2269e5c31af7Sopenharmony_ci // Also, the initial position will be 2, so it will wrap around in this case. The numbers will also change. 2270e5c31af7Sopenharmony_ci 2271e5c31af7Sopenharmony_ci std::ostringstream rgen; 2272e5c31af7Sopenharmony_ci rgen 2273e5c31af7Sopenharmony_ci << glslHeader 2274e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadEXT uint rayPayload;\n" 2275e5c31af7Sopenharmony_ci << glslBindings 2276e5c31af7Sopenharmony_ci << "void main()\n" 2277e5c31af7Sopenharmony_ci << "{\n" 2278e5c31af7Sopenharmony_ci << " rayPayload = 2u;\n" 2279e5c31af7Sopenharmony_ci << " traceRayEXT(topLevelAS, 0u, 0xFFu, 0, 0, 0, vec3(0.5, 0.5, 0.0), 0.0, vec3(0.0, 0.0, -1.0), 9.0, 0);\n" 2280e5c31af7Sopenharmony_ci << " storageBuffer.val[0] = rayPayload;\n" 2281e5c31af7Sopenharmony_ci << "}\n" 2282e5c31af7Sopenharmony_ci ; 2283e5c31af7Sopenharmony_ci programCollection.glslSources.add("rgen") << glu::RaygenSource(updateRayTracingGLSL(rgen.str())) << buildOptions; 2284e5c31af7Sopenharmony_ci 2285e5c31af7Sopenharmony_ci std::ostringstream chitOrMiss; 2286e5c31af7Sopenharmony_ci chitOrMiss 2287e5c31af7Sopenharmony_ci << glslHeader 2288e5c31af7Sopenharmony_ci << "layout(shaderRecordEXT) buffer ShaderRecordStruct {\n" 2289e5c31af7Sopenharmony_ci << " uvec4 info;\n" 2290e5c31af7Sopenharmony_ci << "};\n" 2291e5c31af7Sopenharmony_ci << "layout(location = 0) rayPayloadInEXT uint rayPayload;\n" 2292e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataEXT uint callableData;\n" 2293e5c31af7Sopenharmony_ci << glslBindings 2294e5c31af7Sopenharmony_ci << "void main()\n" 2295e5c31af7Sopenharmony_ci << "{\n" 2296e5c31af7Sopenharmony_ci << " callableData = rayPayload + 1u;\n" 2297e5c31af7Sopenharmony_ci << " executeCallableEXT(0, 0);\n" 2298e5c31af7Sopenharmony_ci << " uint outputBufferValue = 777u;\n" 2299e5c31af7Sopenharmony_ci << " if (callableData == 0u) outputBufferValue = info.x;\n" 2300e5c31af7Sopenharmony_ci << " else if (callableData == 1u) outputBufferValue = info.y;\n" 2301e5c31af7Sopenharmony_ci << " else if (callableData == 2u) outputBufferValue = info.z;\n" 2302e5c31af7Sopenharmony_ci << " else if (callableData == 3u) outputBufferValue = info.w;\n" 2303e5c31af7Sopenharmony_ci << " storageBuffer.val[1] = outputBufferValue;\n" 2304e5c31af7Sopenharmony_ci << " rayPayload = outputBufferValue * 3u;\n" 2305e5c31af7Sopenharmony_ci << "}\n" 2306e5c31af7Sopenharmony_ci ; 2307e5c31af7Sopenharmony_ci 2308e5c31af7Sopenharmony_ci if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS) 2309e5c31af7Sopenharmony_ci programCollection.glslSources.add("miss") << glu::MissSource(updateRayTracingGLSL(chitOrMiss.str())) << buildOptions; 2310e5c31af7Sopenharmony_ci else if (m_params.interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT) 2311e5c31af7Sopenharmony_ci programCollection.glslSources.add("chit") << glu::ClosestHitSource(updateRayTracingGLSL(chitOrMiss.str())) << buildOptions; 2312e5c31af7Sopenharmony_ci else 2313e5c31af7Sopenharmony_ci DE_ASSERT(false); 2314e5c31af7Sopenharmony_ci 2315e5c31af7Sopenharmony_ci std::ostringstream call; 2316e5c31af7Sopenharmony_ci call 2317e5c31af7Sopenharmony_ci << glslHeader 2318e5c31af7Sopenharmony_ci << "layout(location = 0) callableDataInEXT uint callableData;\n" 2319e5c31af7Sopenharmony_ci << glslBindings 2320e5c31af7Sopenharmony_ci << "void main()\n" 2321e5c31af7Sopenharmony_ci << "{\n" 2322e5c31af7Sopenharmony_ci << " storageBuffer.val[2] = 490u;\n" 2323e5c31af7Sopenharmony_ci << " callableData = (callableData + 1u) % 4u;\n" 2324e5c31af7Sopenharmony_ci << "}\n" 2325e5c31af7Sopenharmony_ci ; 2326e5c31af7Sopenharmony_ci 2327e5c31af7Sopenharmony_ci programCollection.glslSources.add("call") << glu::CallableSource(updateRayTracingGLSL(call.str())) << buildOptions; 2328e5c31af7Sopenharmony_ci } 2329e5c31af7Sopenharmony_ci else 2330e5c31af7Sopenharmony_ci { 2331e5c31af7Sopenharmony_ci DE_ASSERT(false); 2332e5c31af7Sopenharmony_ci } 2333e5c31af7Sopenharmony_ci} 2334e5c31af7Sopenharmony_ci 2335e5c31af7Sopenharmony_ciVkShaderStageFlags getShaderStages (InterfaceType type_) 2336e5c31af7Sopenharmony_ci{ 2337e5c31af7Sopenharmony_ci VkShaderStageFlags flags = VK_SHADER_STAGE_RAYGEN_BIT_KHR; 2338e5c31af7Sopenharmony_ci 2339e5c31af7Sopenharmony_ci switch (type_) 2340e5c31af7Sopenharmony_ci { 2341e5c31af7Sopenharmony_ci case InterfaceType::HIT_ATTRIBUTES: 2342e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_INTERSECTION_BIT_KHR; 2343e5c31af7Sopenharmony_ci // fallthrough. 2344e5c31af7Sopenharmony_ci case InterfaceType::RAY_PAYLOAD: 2345e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; 2346e5c31af7Sopenharmony_ci break; 2347e5c31af7Sopenharmony_ci case InterfaceType::CALLABLE_DATA: 2348e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_RGEN: 2349e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_CALL: 2350e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR; 2351e5c31af7Sopenharmony_ci break; 2352e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_MISS: 2353e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR; 2354e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_MISS_BIT_KHR; 2355e5c31af7Sopenharmony_ci break; 2356e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_HIT: 2357e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_CALLABLE_BIT_KHR; 2358e5c31af7Sopenharmony_ci flags |= VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; 2359e5c31af7Sopenharmony_ci break; 2360e5c31af7Sopenharmony_ci default: 2361e5c31af7Sopenharmony_ci DE_ASSERT(false); 2362e5c31af7Sopenharmony_ci break; 2363e5c31af7Sopenharmony_ci } 2364e5c31af7Sopenharmony_ci 2365e5c31af7Sopenharmony_ci return flags; 2366e5c31af7Sopenharmony_ci} 2367e5c31af7Sopenharmony_ci 2368e5c31af7Sopenharmony_ci// Proper stage for generating default geometry. 2369e5c31af7Sopenharmony_ciVkShaderStageFlagBits getShaderStageForGeometry (InterfaceType type_) 2370e5c31af7Sopenharmony_ci{ 2371e5c31af7Sopenharmony_ci VkShaderStageFlagBits bits = VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM; 2372e5c31af7Sopenharmony_ci 2373e5c31af7Sopenharmony_ci switch (type_) 2374e5c31af7Sopenharmony_ci { 2375e5c31af7Sopenharmony_ci case InterfaceType::HIT_ATTRIBUTES: bits = VK_SHADER_STAGE_INTERSECTION_BIT_KHR; break; 2376e5c31af7Sopenharmony_ci case InterfaceType::RAY_PAYLOAD: bits = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; break; 2377e5c31af7Sopenharmony_ci case InterfaceType::CALLABLE_DATA: bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR; break; 2378e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_RGEN: bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR; break; 2379e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_CALL: bits = VK_SHADER_STAGE_CALLABLE_BIT_KHR; break; 2380e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_MISS: bits = VK_SHADER_STAGE_MISS_BIT_KHR; break; 2381e5c31af7Sopenharmony_ci case InterfaceType::SHADER_RECORD_BUFFER_HIT: bits = VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR; break; 2382e5c31af7Sopenharmony_ci default: DE_ASSERT(false); break; 2383e5c31af7Sopenharmony_ci } 2384e5c31af7Sopenharmony_ci 2385e5c31af7Sopenharmony_ci DE_ASSERT(bits != VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM); 2386e5c31af7Sopenharmony_ci return bits; 2387e5c31af7Sopenharmony_ci} 2388e5c31af7Sopenharmony_ci 2389e5c31af7Sopenharmony_civoid createSBTWithShaderRecord (const DeviceInterface& vkd, VkDevice device, vk::Allocator &alloc, 2390e5c31af7Sopenharmony_ci VkPipeline pipeline, RayTracingPipeline* rayTracingPipeline, 2391e5c31af7Sopenharmony_ci deUint32 shaderGroupHandleSize, deUint32 shaderGroupBaseAlignment, 2392e5c31af7Sopenharmony_ci deUint32 firstGroup, deUint32 groupCount, 2393e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory>& shaderBindingTable, 2394e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR& shaderBindingTableRegion) 2395e5c31af7Sopenharmony_ci{ 2396e5c31af7Sopenharmony_ci const auto alignedSize = de::roundUp(shaderGroupHandleSize + kShaderRecordSize, shaderGroupHandleSize); 2397e5c31af7Sopenharmony_ci shaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline, alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, firstGroup, groupCount, 0u, 0u, MemoryRequirement::Any, 0u, 0u, kShaderRecordSize); 2398e5c31af7Sopenharmony_ci shaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, shaderBindingTable->get(), 0), alignedSize, groupCount * alignedSize); 2399e5c31af7Sopenharmony_ci 2400e5c31af7Sopenharmony_ci // Fill shader record buffer data. 2401e5c31af7Sopenharmony_ci // Note we will only fill the first shader record after the handle. 2402e5c31af7Sopenharmony_ci const tcu::UVec4 shaderRecordData (400u, 401u, 402u, 403u); 2403e5c31af7Sopenharmony_ci auto& sbtAlloc = shaderBindingTable->getAllocation(); 2404e5c31af7Sopenharmony_ci auto* dataPtr = reinterpret_cast<deUint8*>(sbtAlloc.getHostPtr()) + shaderGroupHandleSize; 2405e5c31af7Sopenharmony_ci 2406e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(shaderRecordData) == static_cast<size_t>(kShaderRecordSize)); 2407e5c31af7Sopenharmony_ci deMemcpy(dataPtr, &shaderRecordData, sizeof(shaderRecordData)); 2408e5c31af7Sopenharmony_ci} 2409e5c31af7Sopenharmony_ci 2410e5c31af7Sopenharmony_citcu::TestStatus DataSpillPipelineInterfaceTestInstance::iterate (void) 2411e5c31af7Sopenharmony_ci{ 2412e5c31af7Sopenharmony_ci const auto& vki = m_context.getInstanceInterface(); 2413e5c31af7Sopenharmony_ci const auto physicalDevice = m_context.getPhysicalDevice(); 2414e5c31af7Sopenharmony_ci const auto& vkd = m_context.getDeviceInterface(); 2415e5c31af7Sopenharmony_ci const auto device = m_context.getDevice(); 2416e5c31af7Sopenharmony_ci const auto queue = m_context.getUniversalQueue(); 2417e5c31af7Sopenharmony_ci const auto familyIndex = m_context.getUniversalQueueFamilyIndex(); 2418e5c31af7Sopenharmony_ci auto& alloc = m_context.getDefaultAllocator(); 2419e5c31af7Sopenharmony_ci const auto shaderStages = getShaderStages(m_params.interfaceType); 2420e5c31af7Sopenharmony_ci 2421e5c31af7Sopenharmony_ci // Command buffer. 2422e5c31af7Sopenharmony_ci const auto cmdPool = makeCommandPool(vkd, device, familyIndex); 2423e5c31af7Sopenharmony_ci const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY); 2424e5c31af7Sopenharmony_ci const auto cmdBuffer = cmdBufferPtr.get(); 2425e5c31af7Sopenharmony_ci 2426e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, cmdBuffer); 2427e5c31af7Sopenharmony_ci 2428e5c31af7Sopenharmony_ci // Storage buffer. 2429e5c31af7Sopenharmony_ci std::array<deUint32, kNumStorageValues> storageBufferData; 2430e5c31af7Sopenharmony_ci const auto storageBufferSize = de::dataSize(storageBufferData); 2431e5c31af7Sopenharmony_ci const auto storagebufferInfo = makeBufferCreateInfo(storageBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 2432e5c31af7Sopenharmony_ci BufferWithMemory storageBuffer (vkd, device, alloc, storagebufferInfo, MemoryRequirement::HostVisible); 2433e5c31af7Sopenharmony_ci 2434e5c31af7Sopenharmony_ci // Zero-out buffer. 2435e5c31af7Sopenharmony_ci auto& storageBufferAlloc = storageBuffer.getAllocation(); 2436e5c31af7Sopenharmony_ci auto* storageBufferPtr = storageBufferAlloc.getHostPtr(); 2437e5c31af7Sopenharmony_ci deMemset(storageBufferPtr, 0, storageBufferSize); 2438e5c31af7Sopenharmony_ci flushAlloc(vkd, device, storageBufferAlloc); 2439e5c31af7Sopenharmony_ci 2440e5c31af7Sopenharmony_ci // Acceleration structures. 2441e5c31af7Sopenharmony_ci de::MovePtr<BottomLevelAccelerationStructure> bottomLevelAccelerationStructure; 2442e5c31af7Sopenharmony_ci de::MovePtr<TopLevelAccelerationStructure> topLevelAccelerationStructure; 2443e5c31af7Sopenharmony_ci 2444e5c31af7Sopenharmony_ci bottomLevelAccelerationStructure = makeBottomLevelAccelerationStructure(); 2445e5c31af7Sopenharmony_ci bottomLevelAccelerationStructure->setDefaultGeometryData(getShaderStageForGeometry(m_params.interfaceType), VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR); 2446e5c31af7Sopenharmony_ci bottomLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc); 2447e5c31af7Sopenharmony_ci 2448e5c31af7Sopenharmony_ci topLevelAccelerationStructure = makeTopLevelAccelerationStructure(); 2449e5c31af7Sopenharmony_ci topLevelAccelerationStructure->setInstanceCount(1); 2450e5c31af7Sopenharmony_ci topLevelAccelerationStructure->addInstance(de::SharedPtr<BottomLevelAccelerationStructure>(bottomLevelAccelerationStructure.release())); 2451e5c31af7Sopenharmony_ci topLevelAccelerationStructure->createAndBuild(vkd, device, cmdBuffer, alloc); 2452e5c31af7Sopenharmony_ci 2453e5c31af7Sopenharmony_ci // Get some ray tracing properties. 2454e5c31af7Sopenharmony_ci deUint32 shaderGroupHandleSize = 0u; 2455e5c31af7Sopenharmony_ci deUint32 shaderGroupBaseAlignment = 1u; 2456e5c31af7Sopenharmony_ci { 2457e5c31af7Sopenharmony_ci const auto rayTracingPropertiesKHR = makeRayTracingProperties(vki, physicalDevice); 2458e5c31af7Sopenharmony_ci shaderGroupHandleSize = rayTracingPropertiesKHR->getShaderGroupHandleSize(); 2459e5c31af7Sopenharmony_ci shaderGroupBaseAlignment = rayTracingPropertiesKHR->getShaderGroupBaseAlignment(); 2460e5c31af7Sopenharmony_ci } 2461e5c31af7Sopenharmony_ci 2462e5c31af7Sopenharmony_ci // Descriptor set layout. 2463e5c31af7Sopenharmony_ci DescriptorSetLayoutBuilder dslBuilder; 2464e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 1u, shaderStages, nullptr); 2465e5c31af7Sopenharmony_ci dslBuilder.addBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, shaderStages, nullptr); // Callee buffer. 2466e5c31af7Sopenharmony_ci const auto descriptorSetLayout = dslBuilder.build(vkd, device); 2467e5c31af7Sopenharmony_ci 2468e5c31af7Sopenharmony_ci // Pipeline layout. 2469e5c31af7Sopenharmony_ci const auto pipelineLayout = makePipelineLayout(vkd, device, descriptorSetLayout.get()); 2470e5c31af7Sopenharmony_ci 2471e5c31af7Sopenharmony_ci // Descriptor pool and set. 2472e5c31af7Sopenharmony_ci DescriptorPoolBuilder poolBuilder; 2473e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR); 2474e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); 2475e5c31af7Sopenharmony_ci const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 2476e5c31af7Sopenharmony_ci const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get()); 2477e5c31af7Sopenharmony_ci 2478e5c31af7Sopenharmony_ci // Update descriptor set. 2479e5c31af7Sopenharmony_ci { 2480e5c31af7Sopenharmony_ci const VkWriteDescriptorSetAccelerationStructureKHR writeASInfo = 2481e5c31af7Sopenharmony_ci { 2482e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, 2483e5c31af7Sopenharmony_ci nullptr, 2484e5c31af7Sopenharmony_ci 1u, 2485e5c31af7Sopenharmony_ci topLevelAccelerationStructure.get()->getPtr(), 2486e5c31af7Sopenharmony_ci }; 2487e5c31af7Sopenharmony_ci 2488e5c31af7Sopenharmony_ci const auto ds = descriptorSet.get(); 2489e5c31af7Sopenharmony_ci const auto storageBufferDescriptorInfo = makeDescriptorBufferInfo(storageBuffer.get(), 0ull, VK_WHOLE_SIZE); 2490e5c31af7Sopenharmony_ci 2491e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder updateBuilder; 2492e5c31af7Sopenharmony_ci updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &writeASInfo); 2493e5c31af7Sopenharmony_ci updateBuilder.writeSingle(ds, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &storageBufferDescriptorInfo); 2494e5c31af7Sopenharmony_ci updateBuilder.update(vkd, device); 2495e5c31af7Sopenharmony_ci } 2496e5c31af7Sopenharmony_ci 2497e5c31af7Sopenharmony_ci // Create raytracing pipeline and shader binding tables. 2498e5c31af7Sopenharmony_ci const auto interfaceType = m_params.interfaceType; 2499e5c31af7Sopenharmony_ci Move<VkPipeline> pipeline; 2500e5c31af7Sopenharmony_ci 2501e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> raygenShaderBindingTable; 2502e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> missShaderBindingTable; 2503e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> hitShaderBindingTable; 2504e5c31af7Sopenharmony_ci de::MovePtr<BufferWithMemory> callableShaderBindingTable; 2505e5c31af7Sopenharmony_ci 2506e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 2507e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR missShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 2508e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 2509e5c31af7Sopenharmony_ci VkStridedDeviceAddressRegionKHR callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(DE_NULL, 0, 0); 2510e5c31af7Sopenharmony_ci 2511e5c31af7Sopenharmony_ci { 2512e5c31af7Sopenharmony_ci const auto rayTracingPipeline = de::newMovePtr<RayTracingPipeline>(); 2513e5c31af7Sopenharmony_ci 2514e5c31af7Sopenharmony_ci // Every case uses a ray generation shader. 2515e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_RAYGEN_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rgen"), 0), 0); 2516e5c31af7Sopenharmony_ci 2517e5c31af7Sopenharmony_ci if (interfaceType == InterfaceType::RAY_PAYLOAD) 2518e5c31af7Sopenharmony_ci { 2519e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1); 2520e5c31af7Sopenharmony_ci } 2521e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::CALLABLE_DATA || interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN) 2522e5c31af7Sopenharmony_ci { 2523e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 1); 2524e5c31af7Sopenharmony_ci } 2525e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::HIT_ATTRIBUTES) 2526e5c31af7Sopenharmony_ci { 2527e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_INTERSECTION_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("rint"), 0), 1); 2528e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1); 2529e5c31af7Sopenharmony_ci } 2530e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL) 2531e5c31af7Sopenharmony_ci { 2532e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 1); 2533e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("subcall"), 0), 2); 2534e5c31af7Sopenharmony_ci } 2535e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS) 2536e5c31af7Sopenharmony_ci { 2537e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_MISS_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("miss"), 0), 1); 2538e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 2); 2539e5c31af7Sopenharmony_ci } 2540e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT) 2541e5c31af7Sopenharmony_ci { 2542e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("chit"), 0), 1); 2543e5c31af7Sopenharmony_ci rayTracingPipeline->addShader(VK_SHADER_STAGE_CALLABLE_BIT_KHR, createShaderModule(vkd, device, m_context.getBinaryCollection().get("call"), 0), 2); 2544e5c31af7Sopenharmony_ci } 2545e5c31af7Sopenharmony_ci else 2546e5c31af7Sopenharmony_ci { 2547e5c31af7Sopenharmony_ci DE_ASSERT(false); 2548e5c31af7Sopenharmony_ci } 2549e5c31af7Sopenharmony_ci 2550e5c31af7Sopenharmony_ci pipeline = rayTracingPipeline->createPipeline(vkd, device, pipelineLayout.get()); 2551e5c31af7Sopenharmony_ci 2552e5c31af7Sopenharmony_ci if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN) 2553e5c31af7Sopenharmony_ci { 2554e5c31af7Sopenharmony_ci createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment, 2555e5c31af7Sopenharmony_ci 0u, 1u, raygenShaderBindingTable, raygenShaderBindingTableRegion); 2556e5c31af7Sopenharmony_ci } 2557e5c31af7Sopenharmony_ci else 2558e5c31af7Sopenharmony_ci { 2559e5c31af7Sopenharmony_ci raygenShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 0, 1); 2560e5c31af7Sopenharmony_ci raygenShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, raygenShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 2561e5c31af7Sopenharmony_ci } 2562e5c31af7Sopenharmony_ci 2563e5c31af7Sopenharmony_ci 2564e5c31af7Sopenharmony_ci if (interfaceType == InterfaceType::CALLABLE_DATA || interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN) 2565e5c31af7Sopenharmony_ci { 2566e5c31af7Sopenharmony_ci callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1); 2567e5c31af7Sopenharmony_ci callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 2568e5c31af7Sopenharmony_ci } 2569e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::RAY_PAYLOAD || interfaceType == InterfaceType::HIT_ATTRIBUTES) 2570e5c31af7Sopenharmony_ci { 2571e5c31af7Sopenharmony_ci hitShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 1, 1); 2572e5c31af7Sopenharmony_ci hitShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, hitShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 2573e5c31af7Sopenharmony_ci } 2574e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL) 2575e5c31af7Sopenharmony_ci { 2576e5c31af7Sopenharmony_ci createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment, 2577e5c31af7Sopenharmony_ci 1u, 2u, callableShaderBindingTable, callableShaderBindingTableRegion); 2578e5c31af7Sopenharmony_ci } 2579e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS) 2580e5c31af7Sopenharmony_ci { 2581e5c31af7Sopenharmony_ci createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment, 2582e5c31af7Sopenharmony_ci 1u, 1u, missShaderBindingTable, missShaderBindingTableRegion); 2583e5c31af7Sopenharmony_ci 2584e5c31af7Sopenharmony_ci // Callable shader table. 2585e5c31af7Sopenharmony_ci callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1); 2586e5c31af7Sopenharmony_ci callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 2587e5c31af7Sopenharmony_ci } 2588e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT) 2589e5c31af7Sopenharmony_ci { 2590e5c31af7Sopenharmony_ci createSBTWithShaderRecord (vkd, device, alloc, pipeline.get(), rayTracingPipeline.get(), shaderGroupHandleSize, shaderGroupBaseAlignment, 2591e5c31af7Sopenharmony_ci 1u, 1u, hitShaderBindingTable, hitShaderBindingTableRegion); 2592e5c31af7Sopenharmony_ci 2593e5c31af7Sopenharmony_ci // Callable shader table. 2594e5c31af7Sopenharmony_ci callableShaderBindingTable = rayTracingPipeline->createShaderBindingTable(vkd, device, pipeline.get(), alloc, shaderGroupHandleSize, shaderGroupBaseAlignment, 2, 1); 2595e5c31af7Sopenharmony_ci callableShaderBindingTableRegion = makeStridedDeviceAddressRegionKHR(getBufferDeviceAddress(vkd, device, callableShaderBindingTable->get(), 0), shaderGroupHandleSize, shaderGroupHandleSize); 2596e5c31af7Sopenharmony_ci } 2597e5c31af7Sopenharmony_ci else 2598e5c31af7Sopenharmony_ci { 2599e5c31af7Sopenharmony_ci DE_ASSERT(false); 2600e5c31af7Sopenharmony_ci } 2601e5c31af7Sopenharmony_ci } 2602e5c31af7Sopenharmony_ci 2603e5c31af7Sopenharmony_ci // Use ray tracing pipeline. 2604e5c31af7Sopenharmony_ci vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipeline.get()); 2605e5c31af7Sopenharmony_ci vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr); 2606e5c31af7Sopenharmony_ci vkd.cmdTraceRaysKHR(cmdBuffer, &raygenShaderBindingTableRegion, &missShaderBindingTableRegion, &hitShaderBindingTableRegion, &callableShaderBindingTableRegion, 1u, 1u, 1u); 2607e5c31af7Sopenharmony_ci 2608e5c31af7Sopenharmony_ci // Synchronize output and callee buffers. 2609e5c31af7Sopenharmony_ci const auto memBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 2610e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &memBarrier, 0u, nullptr, 0u, nullptr); 2611e5c31af7Sopenharmony_ci 2612e5c31af7Sopenharmony_ci endCommandBuffer(vkd, cmdBuffer); 2613e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, cmdBuffer); 2614e5c31af7Sopenharmony_ci 2615e5c31af7Sopenharmony_ci // Verify storage buffer. 2616e5c31af7Sopenharmony_ci invalidateAlloc(vkd, device, storageBufferAlloc); 2617e5c31af7Sopenharmony_ci deMemcpy(storageBufferData.data(), storageBufferPtr, storageBufferSize); 2618e5c31af7Sopenharmony_ci 2619e5c31af7Sopenharmony_ci // These values must match what the shaders store. 2620e5c31af7Sopenharmony_ci std::vector<deUint32> expectedData; 2621e5c31af7Sopenharmony_ci if (interfaceType == InterfaceType::RAY_PAYLOAD) 2622e5c31af7Sopenharmony_ci { 2623e5c31af7Sopenharmony_ci expectedData.push_back(103u); 2624e5c31af7Sopenharmony_ci expectedData.push_back(100u); 2625e5c31af7Sopenharmony_ci } 2626e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::CALLABLE_DATA) 2627e5c31af7Sopenharmony_ci { 2628e5c31af7Sopenharmony_ci expectedData.push_back(200u); 2629e5c31af7Sopenharmony_ci expectedData.push_back(100u); 2630e5c31af7Sopenharmony_ci } 2631e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::HIT_ATTRIBUTES) 2632e5c31af7Sopenharmony_ci { 2633e5c31af7Sopenharmony_ci expectedData.push_back(300u); 2634e5c31af7Sopenharmony_ci expectedData.push_back(315u); 2635e5c31af7Sopenharmony_ci expectedData.push_back(330u); 2636e5c31af7Sopenharmony_ci } 2637e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_RGEN) 2638e5c31af7Sopenharmony_ci { 2639e5c31af7Sopenharmony_ci expectedData.push_back(402u); 2640e5c31af7Sopenharmony_ci expectedData.push_back(450u); 2641e5c31af7Sopenharmony_ci } 2642e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_CALL) 2643e5c31af7Sopenharmony_ci { 2644e5c31af7Sopenharmony_ci expectedData.push_back(806u); 2645e5c31af7Sopenharmony_ci expectedData.push_back(403u); 2646e5c31af7Sopenharmony_ci expectedData.push_back(450u); 2647e5c31af7Sopenharmony_ci } 2648e5c31af7Sopenharmony_ci else if (interfaceType == InterfaceType::SHADER_RECORD_BUFFER_MISS || interfaceType == InterfaceType::SHADER_RECORD_BUFFER_HIT) 2649e5c31af7Sopenharmony_ci { 2650e5c31af7Sopenharmony_ci expectedData.push_back(1200u); 2651e5c31af7Sopenharmony_ci expectedData.push_back( 400u); 2652e5c31af7Sopenharmony_ci expectedData.push_back( 490u); 2653e5c31af7Sopenharmony_ci } 2654e5c31af7Sopenharmony_ci else 2655e5c31af7Sopenharmony_ci { 2656e5c31af7Sopenharmony_ci DE_ASSERT(false); 2657e5c31af7Sopenharmony_ci } 2658e5c31af7Sopenharmony_ci 2659e5c31af7Sopenharmony_ci size_t pos; 2660e5c31af7Sopenharmony_ci for (pos = 0u; pos < expectedData.size(); ++pos) 2661e5c31af7Sopenharmony_ci { 2662e5c31af7Sopenharmony_ci const auto& stored = storageBufferData.at(pos); 2663e5c31af7Sopenharmony_ci const auto& expected = expectedData.at(pos); 2664e5c31af7Sopenharmony_ci if (stored != expected) 2665e5c31af7Sopenharmony_ci { 2666e5c31af7Sopenharmony_ci std::ostringstream msg; 2667e5c31af7Sopenharmony_ci msg << "Unexpected output value found at position " << pos << " (expected " << expected << " but got " << stored << ")"; 2668e5c31af7Sopenharmony_ci return tcu::TestStatus::fail(msg.str()); 2669e5c31af7Sopenharmony_ci } 2670e5c31af7Sopenharmony_ci } 2671e5c31af7Sopenharmony_ci 2672e5c31af7Sopenharmony_ci // Expect zeros in unused positions, as filled on the host. 2673e5c31af7Sopenharmony_ci for (; pos < storageBufferData.size(); ++pos) 2674e5c31af7Sopenharmony_ci { 2675e5c31af7Sopenharmony_ci const auto& stored = storageBufferData.at(pos); 2676e5c31af7Sopenharmony_ci if (stored != 0u) 2677e5c31af7Sopenharmony_ci { 2678e5c31af7Sopenharmony_ci std::ostringstream msg; 2679e5c31af7Sopenharmony_ci msg << "Unexpected output value found at position " << pos << " (expected 0 but got " << stored << ")"; 2680e5c31af7Sopenharmony_ci return tcu::TestStatus::fail(msg.str()); 2681e5c31af7Sopenharmony_ci } 2682e5c31af7Sopenharmony_ci } 2683e5c31af7Sopenharmony_ci 2684e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Pass"); 2685e5c31af7Sopenharmony_ci} 2686e5c31af7Sopenharmony_ci 2687e5c31af7Sopenharmony_ci} // anonymous namespace 2688e5c31af7Sopenharmony_ci 2689e5c31af7Sopenharmony_citcu::TestCaseGroup* createDataSpillTests(tcu::TestContext& testCtx) 2690e5c31af7Sopenharmony_ci{ 2691e5c31af7Sopenharmony_ci // Ray tracing tests for data spilling and unspilling around shader calls 2692e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "data_spill")); 2693e5c31af7Sopenharmony_ci 2694e5c31af7Sopenharmony_ci struct 2695e5c31af7Sopenharmony_ci { 2696e5c31af7Sopenharmony_ci CallType callType; 2697e5c31af7Sopenharmony_ci const char* name; 2698e5c31af7Sopenharmony_ci } callTypes[] = 2699e5c31af7Sopenharmony_ci { 2700e5c31af7Sopenharmony_ci { CallType::EXECUTE_CALLABLE, "execute_callable" }, 2701e5c31af7Sopenharmony_ci { CallType::TRACE_RAY, "trace_ray" }, 2702e5c31af7Sopenharmony_ci { CallType::REPORT_INTERSECTION, "report_intersection" }, 2703e5c31af7Sopenharmony_ci }; 2704e5c31af7Sopenharmony_ci 2705e5c31af7Sopenharmony_ci struct 2706e5c31af7Sopenharmony_ci { 2707e5c31af7Sopenharmony_ci DataType dataType; 2708e5c31af7Sopenharmony_ci const char* name; 2709e5c31af7Sopenharmony_ci } dataTypes[] = 2710e5c31af7Sopenharmony_ci { 2711e5c31af7Sopenharmony_ci { DataType::INT32, "int32" }, 2712e5c31af7Sopenharmony_ci { DataType::UINT32, "uint32" }, 2713e5c31af7Sopenharmony_ci { DataType::INT64, "int64" }, 2714e5c31af7Sopenharmony_ci { DataType::UINT64, "uint64" }, 2715e5c31af7Sopenharmony_ci { DataType::INT16, "int16" }, 2716e5c31af7Sopenharmony_ci { DataType::UINT16, "uint16" }, 2717e5c31af7Sopenharmony_ci { DataType::INT8, "int8" }, 2718e5c31af7Sopenharmony_ci { DataType::UINT8, "uint8" }, 2719e5c31af7Sopenharmony_ci { DataType::FLOAT32, "float32" }, 2720e5c31af7Sopenharmony_ci { DataType::FLOAT64, "float64" }, 2721e5c31af7Sopenharmony_ci { DataType::FLOAT16, "float16" }, 2722e5c31af7Sopenharmony_ci { DataType::STRUCT, "struct" }, 2723e5c31af7Sopenharmony_ci { DataType::SAMPLER, "sampler" }, 2724e5c31af7Sopenharmony_ci { DataType::IMAGE, "image" }, 2725e5c31af7Sopenharmony_ci { DataType::SAMPLED_IMAGE, "combined" }, 2726e5c31af7Sopenharmony_ci { DataType::PTR_IMAGE, "ptr_image" }, 2727e5c31af7Sopenharmony_ci { DataType::PTR_SAMPLER, "ptr_sampler" }, 2728e5c31af7Sopenharmony_ci { DataType::PTR_SAMPLED_IMAGE, "ptr_combined" }, 2729e5c31af7Sopenharmony_ci { DataType::PTR_TEXEL, "ptr_texel" }, 2730e5c31af7Sopenharmony_ci { DataType::OP_NULL, "op_null" }, 2731e5c31af7Sopenharmony_ci { DataType::OP_UNDEF, "op_undef" }, 2732e5c31af7Sopenharmony_ci }; 2733e5c31af7Sopenharmony_ci 2734e5c31af7Sopenharmony_ci struct 2735e5c31af7Sopenharmony_ci { 2736e5c31af7Sopenharmony_ci VectorType vectorType; 2737e5c31af7Sopenharmony_ci const char* prefix; 2738e5c31af7Sopenharmony_ci } vectorTypes[] = 2739e5c31af7Sopenharmony_ci { 2740e5c31af7Sopenharmony_ci { VectorType::SCALAR, "" }, 2741e5c31af7Sopenharmony_ci { VectorType::V2, "v2" }, 2742e5c31af7Sopenharmony_ci { VectorType::V3, "v3" }, 2743e5c31af7Sopenharmony_ci { VectorType::V4, "v4" }, 2744e5c31af7Sopenharmony_ci { VectorType::A5, "a5" }, 2745e5c31af7Sopenharmony_ci }; 2746e5c31af7Sopenharmony_ci 2747e5c31af7Sopenharmony_ci for (int callTypeIdx = 0; callTypeIdx < DE_LENGTH_OF_ARRAY(callTypes); ++callTypeIdx) 2748e5c31af7Sopenharmony_ci { 2749e5c31af7Sopenharmony_ci const auto& entryCallTypes = callTypes[callTypeIdx]; 2750e5c31af7Sopenharmony_ci 2751e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> callTypeGroup(new tcu::TestCaseGroup(testCtx, entryCallTypes.name)); 2752e5c31af7Sopenharmony_ci for (int dataTypeIdx = 0; dataTypeIdx < DE_LENGTH_OF_ARRAY(dataTypes); ++dataTypeIdx) 2753e5c31af7Sopenharmony_ci { 2754e5c31af7Sopenharmony_ci const auto& entryDataTypes = dataTypes[dataTypeIdx]; 2755e5c31af7Sopenharmony_ci 2756e5c31af7Sopenharmony_ci for (int vectorTypeIdx = 0; vectorTypeIdx < DE_LENGTH_OF_ARRAY(vectorTypes); ++vectorTypeIdx) 2757e5c31af7Sopenharmony_ci { 2758e5c31af7Sopenharmony_ci const auto& entryVectorTypes = vectorTypes[vectorTypeIdx]; 2759e5c31af7Sopenharmony_ci 2760e5c31af7Sopenharmony_ci if ((samplersNeeded(entryDataTypes.dataType) 2761e5c31af7Sopenharmony_ci || storageImageNeeded(entryDataTypes.dataType) 2762e5c31af7Sopenharmony_ci || entryDataTypes.dataType == DataType::STRUCT 2763e5c31af7Sopenharmony_ci || entryDataTypes.dataType == DataType::OP_NULL 2764e5c31af7Sopenharmony_ci || entryDataTypes.dataType == DataType::OP_UNDEF) 2765e5c31af7Sopenharmony_ci && entryVectorTypes.vectorType != VectorType::SCALAR) 2766e5c31af7Sopenharmony_ci { 2767e5c31af7Sopenharmony_ci continue; 2768e5c31af7Sopenharmony_ci } 2769e5c31af7Sopenharmony_ci 2770e5c31af7Sopenharmony_ci DataSpillTestCase::TestParams params; 2771e5c31af7Sopenharmony_ci params.callType = entryCallTypes.callType; 2772e5c31af7Sopenharmony_ci params.dataType = entryDataTypes.dataType; 2773e5c31af7Sopenharmony_ci params.vectorType = entryVectorTypes.vectorType; 2774e5c31af7Sopenharmony_ci 2775e5c31af7Sopenharmony_ci const auto testName = std::string(entryVectorTypes.prefix) + entryDataTypes.name; 2776e5c31af7Sopenharmony_ci 2777e5c31af7Sopenharmony_ci callTypeGroup->addChild(new DataSpillTestCase(testCtx, testName, params)); 2778e5c31af7Sopenharmony_ci } 2779e5c31af7Sopenharmony_ci } 2780e5c31af7Sopenharmony_ci 2781e5c31af7Sopenharmony_ci group->addChild(callTypeGroup.release()); 2782e5c31af7Sopenharmony_ci } 2783e5c31af7Sopenharmony_ci 2784e5c31af7Sopenharmony_ci // Pipeline interface tests. 2785e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> pipelineInterfaceGroup(new tcu::TestCaseGroup(testCtx, "pipeline_interface", "Test data spilling and unspilling of pipeline interface variables")); 2786e5c31af7Sopenharmony_ci 2787e5c31af7Sopenharmony_ci struct 2788e5c31af7Sopenharmony_ci { 2789e5c31af7Sopenharmony_ci InterfaceType interfaceType; 2790e5c31af7Sopenharmony_ci const char* name; 2791e5c31af7Sopenharmony_ci } interfaceTypes[] = 2792e5c31af7Sopenharmony_ci { 2793e5c31af7Sopenharmony_ci { InterfaceType::RAY_PAYLOAD, "ray_payload" }, 2794e5c31af7Sopenharmony_ci { InterfaceType::CALLABLE_DATA, "callable_data" }, 2795e5c31af7Sopenharmony_ci { InterfaceType::HIT_ATTRIBUTES, "hit_attributes" }, 2796e5c31af7Sopenharmony_ci { InterfaceType::SHADER_RECORD_BUFFER_RGEN, "shader_record_buffer_rgen" }, 2797e5c31af7Sopenharmony_ci { InterfaceType::SHADER_RECORD_BUFFER_CALL, "shader_record_buffer_call" }, 2798e5c31af7Sopenharmony_ci { InterfaceType::SHADER_RECORD_BUFFER_MISS, "shader_record_buffer_miss" }, 2799e5c31af7Sopenharmony_ci { InterfaceType::SHADER_RECORD_BUFFER_HIT, "shader_record_buffer_hit" }, 2800e5c31af7Sopenharmony_ci }; 2801e5c31af7Sopenharmony_ci 2802e5c31af7Sopenharmony_ci for (int idx = 0; idx < DE_LENGTH_OF_ARRAY(interfaceTypes); ++idx) 2803e5c31af7Sopenharmony_ci { 2804e5c31af7Sopenharmony_ci const auto& entry = interfaceTypes[idx]; 2805e5c31af7Sopenharmony_ci DataSpillPipelineInterfaceTestCase::TestParams params; 2806e5c31af7Sopenharmony_ci 2807e5c31af7Sopenharmony_ci params.interfaceType = entry.interfaceType; 2808e5c31af7Sopenharmony_ci 2809e5c31af7Sopenharmony_ci pipelineInterfaceGroup->addChild(new DataSpillPipelineInterfaceTestCase(testCtx, entry.name, params)); 2810e5c31af7Sopenharmony_ci } 2811e5c31af7Sopenharmony_ci 2812e5c31af7Sopenharmony_ci group->addChild(pipelineInterfaceGroup.release()); 2813e5c31af7Sopenharmony_ci 2814e5c31af7Sopenharmony_ci return group.release(); 2815e5c31af7Sopenharmony_ci} 2816e5c31af7Sopenharmony_ci 2817e5c31af7Sopenharmony_ci} // RayTracing 2818e5c31af7Sopenharmony_ci} // vkt 2819e5c31af7Sopenharmony_ci 2820