1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2021 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 Query Direction Tests 23e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include "vktRayQueryDirectionTests.hpp" 26e5c31af7Sopenharmony_ci#include "vktTestCase.hpp" 27e5c31af7Sopenharmony_ci 28e5c31af7Sopenharmony_ci#include "vkObjUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 30e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 31e5c31af7Sopenharmony_ci#include "vkBuilderUtil.hpp" 32e5c31af7Sopenharmony_ci#include "vkRayTracingUtil.hpp" 33e5c31af7Sopenharmony_ci#include "vkBufferWithMemory.hpp" 34e5c31af7Sopenharmony_ci#include "vkBarrierUtil.hpp" 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 37e5c31af7Sopenharmony_ci#include "tcuMatrix.hpp" 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp" 40e5c31af7Sopenharmony_ci#include "deRandom.hpp" 41e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 42e5c31af7Sopenharmony_ci#include "deDefs.hpp" 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_ci#include <vector> 45e5c31af7Sopenharmony_ci#include <cmath> 46e5c31af7Sopenharmony_ci#include <sstream> 47e5c31af7Sopenharmony_ci#include <utility> 48e5c31af7Sopenharmony_ci#include <algorithm> 49e5c31af7Sopenharmony_ci#include <limits> 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_cinamespace vkt 52e5c31af7Sopenharmony_ci{ 53e5c31af7Sopenharmony_cinamespace RayQuery 54e5c31af7Sopenharmony_ci{ 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_cinamespace 57e5c31af7Sopenharmony_ci{ 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ciusing namespace vk; 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ciusing GeometryData = std::vector<tcu::Vec3>; 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci// Should rays be shot from inside the geometry or not? 64e5c31af7Sopenharmony_cienum class RayOriginType 65e5c31af7Sopenharmony_ci{ 66e5c31af7Sopenharmony_ci OUTSIDE = 0, // Works with AABBs and triangles. 67e5c31af7Sopenharmony_ci INSIDE, // Works with AABBs only. 68e5c31af7Sopenharmony_ci}; 69e5c31af7Sopenharmony_ci 70e5c31af7Sopenharmony_ci// When rays are shot from the outside, they are expected to cross the geometry. 71e5c31af7Sopenharmony_ci// When shot from the inside, they can end inside, at the edge or outside the geometry. 72e5c31af7Sopenharmony_cienum class RayEndType 73e5c31af7Sopenharmony_ci{ 74e5c31af7Sopenharmony_ci CROSS = 0, // For RayOriginType::OUTSIDE. 75e5c31af7Sopenharmony_ci ZERO, // For RayOriginType::INSIDE. 76e5c31af7Sopenharmony_ci INSIDE, // For RayOriginType::INSIDE. 77e5c31af7Sopenharmony_ci EDGE, // For RayOriginType::INSIDE. 78e5c31af7Sopenharmony_ci OUTSIDE, // For RayOriginType::INSIDE. 79e5c31af7Sopenharmony_ci}; 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_cistruct SpaceObjects 82e5c31af7Sopenharmony_ci{ 83e5c31af7Sopenharmony_ci tcu::Vec3 origin; 84e5c31af7Sopenharmony_ci tcu::Vec3 direction; 85e5c31af7Sopenharmony_ci GeometryData geometry; 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_ci SpaceObjects (RayOriginType rayOriginType, VkGeometryTypeKHR geometryType) 88e5c31af7Sopenharmony_ci : origin (0.0f, 0.0f, 1.0f) // Origin of the ray at (0, 0, 1). 89e5c31af7Sopenharmony_ci , direction (0.0f, 0.0f, 1.0f) // Shooting towards (0, 0, 1). 90e5c31af7Sopenharmony_ci , geometry () 91e5c31af7Sopenharmony_ci { 92e5c31af7Sopenharmony_ci DE_ASSERT(geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR || geometryType == VK_GEOMETRY_TYPE_AABBS_KHR); 93e5c31af7Sopenharmony_ci DE_ASSERT(rayOriginType == RayOriginType::OUTSIDE || geometryType == VK_GEOMETRY_TYPE_AABBS_KHR); 94e5c31af7Sopenharmony_ci 95e5c31af7Sopenharmony_ci if (geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR) 96e5c31af7Sopenharmony_ci { 97e5c31af7Sopenharmony_ci // Triangle around (0, 0, 5). 98e5c31af7Sopenharmony_ci geometry.reserve(3u); 99e5c31af7Sopenharmony_ci geometry.push_back(tcu::Vec3( 0.0f, 0.5f, 5.0f)); 100e5c31af7Sopenharmony_ci geometry.push_back(tcu::Vec3(-0.5f, -0.5f, 5.0f)); 101e5c31af7Sopenharmony_ci geometry.push_back(tcu::Vec3( 0.5f, -0.5f, 5.0f)); 102e5c31af7Sopenharmony_ci } 103e5c31af7Sopenharmony_ci else 104e5c31af7Sopenharmony_ci { 105e5c31af7Sopenharmony_ci // AABB around (0, 0, 5) or with its back side at that distance when shot from the inside. 106e5c31af7Sopenharmony_ci geometry.reserve(2u); 107e5c31af7Sopenharmony_ci geometry.push_back(tcu::Vec3(-0.5f, -0.5f, ((rayOriginType == RayOriginType::INSIDE) ? 0.0f : 5.0f))); 108e5c31af7Sopenharmony_ci geometry.push_back(tcu::Vec3( 0.5f, 0.5f, 5.0f)); 109e5c31af7Sopenharmony_ci } 110e5c31af7Sopenharmony_ci } 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ci static float getDefaultDistance (void) 113e5c31af7Sopenharmony_ci { 114e5c31af7Sopenharmony_ci // Consistent with the Z coordinates of the origin, direction and points in constructors. 115e5c31af7Sopenharmony_ci return 4.0f; 116e5c31af7Sopenharmony_ci } 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_ci // Calculates distance to geometry edge given the direction scaling factor. 119e5c31af7Sopenharmony_ci static float getDistanceToEdge (float directionScale) 120e5c31af7Sopenharmony_ci { 121e5c31af7Sopenharmony_ci return getDefaultDistance() / directionScale; 122e5c31af7Sopenharmony_ci } 123e5c31af7Sopenharmony_ci}; 124e5c31af7Sopenharmony_ci 125e5c31af7Sopenharmony_ci// Default test tolerance for distance values. 126e5c31af7Sopenharmony_ciconstexpr float kDefaultTolerance = 0.001f; 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci// Calculates appropriate values for Tmin/Tmax given the distance to the geometry edge. 129e5c31af7Sopenharmony_cistd::pair<float, float> calcTminTmax (RayOriginType rayOriginType, RayEndType rayEndType, float distanceToEdge) 130e5c31af7Sopenharmony_ci{ 131e5c31af7Sopenharmony_ci std::pair<float, float> result; 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ci if (rayOriginType == RayOriginType::OUTSIDE) 134e5c31af7Sopenharmony_ci { 135e5c31af7Sopenharmony_ci DE_ASSERT(rayEndType == RayEndType::CROSS); 136e5c31af7Sopenharmony_ci const auto margin = kDefaultTolerance / 2.0f; 137e5c31af7Sopenharmony_ci result = std::make_pair(de::max(distanceToEdge - margin, 0.0f), distanceToEdge + margin); 138e5c31af7Sopenharmony_ci } 139e5c31af7Sopenharmony_ci else 140e5c31af7Sopenharmony_ci { 141e5c31af7Sopenharmony_ci result.first = 0.0f; 142e5c31af7Sopenharmony_ci switch (rayEndType) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci case RayEndType::ZERO: result.second = 0.0f; break; 145e5c31af7Sopenharmony_ci case RayEndType::INSIDE: result.second = distanceToEdge / 2.0f; break; 146e5c31af7Sopenharmony_ci case RayEndType::EDGE: result.second = distanceToEdge; break; 147e5c31af7Sopenharmony_ci case RayEndType::OUTSIDE: result.second = distanceToEdge + 1.0f; break; 148e5c31af7Sopenharmony_ci default: DE_ASSERT(false); break; 149e5c31af7Sopenharmony_ci } 150e5c31af7Sopenharmony_ci } 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci return result; 153e5c31af7Sopenharmony_ci} 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci// Get matrix to scale a point with the given scale factor. 156e5c31af7Sopenharmony_citcu::Mat3 getScaleMatrix (float scaleFactor) 157e5c31af7Sopenharmony_ci{ 158e5c31af7Sopenharmony_ci const float scaleDirectionMatrixData[] = 159e5c31af7Sopenharmony_ci { 160e5c31af7Sopenharmony_ci scaleFactor, 0.f, 0.f, 161e5c31af7Sopenharmony_ci 0.f, scaleFactor, 0.f, 162e5c31af7Sopenharmony_ci 0.f, 0.f, scaleFactor, 163e5c31af7Sopenharmony_ci }; 164e5c31af7Sopenharmony_ci return tcu::Mat3(scaleDirectionMatrixData); 165e5c31af7Sopenharmony_ci} 166e5c31af7Sopenharmony_ci 167e5c31af7Sopenharmony_ci// Get a matrix to rotate a point around the X and Y axis by the given angles in radians. 168e5c31af7Sopenharmony_citcu::Mat3 getRotationMatrix (float rotationX, float rotationY) 169e5c31af7Sopenharmony_ci{ 170e5c31af7Sopenharmony_ci const float cosA = std::cos(rotationX); 171e5c31af7Sopenharmony_ci const float sinA = std::sin(rotationX); 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ci const float cosB = std::cos(rotationY); 174e5c31af7Sopenharmony_ci const float sinB = std::sin(rotationY); 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci const float rotationMatrixDataX[] = 177e5c31af7Sopenharmony_ci { 178e5c31af7Sopenharmony_ci 1.0f, 0.0f, 0.0f, 179e5c31af7Sopenharmony_ci 0.0f, cosA,-sinA, 180e5c31af7Sopenharmony_ci 0.0f, sinA, cosA, 181e5c31af7Sopenharmony_ci }; 182e5c31af7Sopenharmony_ci const tcu::Mat3 rotationMatrixX (rotationMatrixDataX); 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci const float rotationMatrixDataY[] = 185e5c31af7Sopenharmony_ci { 186e5c31af7Sopenharmony_ci cosB, 0.0f,-sinB, 187e5c31af7Sopenharmony_ci 0.0f, 1.0f, 0.0f, 188e5c31af7Sopenharmony_ci sinB, 0.0f, cosB, 189e5c31af7Sopenharmony_ci }; 190e5c31af7Sopenharmony_ci const tcu::Mat3 rotationMatrixY (rotationMatrixDataY); 191e5c31af7Sopenharmony_ci 192e5c31af7Sopenharmony_ci return rotationMatrixX * rotationMatrixY; 193e5c31af7Sopenharmony_ci} 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci// Converts transformation matrix to the expected KHR format. 196e5c31af7Sopenharmony_ciVkTransformMatrixKHR toTransformMatrixKHR (const tcu::Mat3& mat3) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci VkTransformMatrixKHR result; 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci deMemset(result.matrix, 0, sizeof(result.matrix)); 201e5c31af7Sopenharmony_ci for (int y = 0; y < 3; ++y) 202e5c31af7Sopenharmony_ci for (int x = 0; x < 3; ++x) 203e5c31af7Sopenharmony_ci result.matrix[x][y] = mat3[x][y]; 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci return result; 206e5c31af7Sopenharmony_ci} 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_cistruct TestParams 209e5c31af7Sopenharmony_ci{ 210e5c31af7Sopenharmony_ci SpaceObjects spaceObjects; 211e5c31af7Sopenharmony_ci float directionScale; 212e5c31af7Sopenharmony_ci float rotationX; 213e5c31af7Sopenharmony_ci float rotationY; 214e5c31af7Sopenharmony_ci VkGeometryTypeKHR geometryType; 215e5c31af7Sopenharmony_ci bool useArraysOfPointers; 216e5c31af7Sopenharmony_ci bool updateMatrixAfterBuild; 217e5c31af7Sopenharmony_ci RayOriginType rayOriginType; 218e5c31af7Sopenharmony_ci RayEndType rayEndtype; 219e5c31af7Sopenharmony_ci}; 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ciclass DirectionTestCase : public vkt::TestCase 222e5c31af7Sopenharmony_ci{ 223e5c31af7Sopenharmony_cipublic: 224e5c31af7Sopenharmony_ci DirectionTestCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params); 225e5c31af7Sopenharmony_ci virtual ~DirectionTestCase (void) {} 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci virtual void checkSupport (Context& context) const; 228e5c31af7Sopenharmony_ci virtual void initPrograms (vk::SourceCollections& programCollection) const; 229e5c31af7Sopenharmony_ci virtual TestInstance* createInstance (Context& context) const; 230e5c31af7Sopenharmony_ci 231e5c31af7Sopenharmony_ciprotected: 232e5c31af7Sopenharmony_ci TestParams m_params; 233e5c31af7Sopenharmony_ci}; 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ciclass DirectionTestInstance : public vkt::TestInstance 236e5c31af7Sopenharmony_ci{ 237e5c31af7Sopenharmony_cipublic: 238e5c31af7Sopenharmony_ci DirectionTestInstance (Context& context, const TestParams& params); 239e5c31af7Sopenharmony_ci virtual ~DirectionTestInstance (void) {} 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci virtual tcu::TestStatus iterate (void); 242e5c31af7Sopenharmony_ci 243e5c31af7Sopenharmony_ciprotected: 244e5c31af7Sopenharmony_ci TestParams m_params; 245e5c31af7Sopenharmony_ci}; 246e5c31af7Sopenharmony_ci 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ciDirectionTestCase::DirectionTestCase(tcu::TestContext& testCtx, const std::string& name, const TestParams& params) 249e5c31af7Sopenharmony_ci : vkt::TestCase (testCtx, name) 250e5c31af7Sopenharmony_ci , m_params (params) 251e5c31af7Sopenharmony_ci{} 252e5c31af7Sopenharmony_ci 253e5c31af7Sopenharmony_civoid DirectionTestCase::checkSupport (Context& context) const 254e5c31af7Sopenharmony_ci{ 255e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_acceleration_structure"); 256e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_ray_query"); 257e5c31af7Sopenharmony_ci} 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci// Push constants. They need to match the shaders. 260e5c31af7Sopenharmony_ci// Note: origin and direction will be used as a Vec3. Declaring them as Vec4 eases matching alignments. 261e5c31af7Sopenharmony_cistruct PushConstants 262e5c31af7Sopenharmony_ci{ 263e5c31af7Sopenharmony_ci tcu::Vec4 origin; 264e5c31af7Sopenharmony_ci tcu::Vec4 direction; 265e5c31af7Sopenharmony_ci float tmix; 266e5c31af7Sopenharmony_ci float tmax; 267e5c31af7Sopenharmony_ci}; 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_citcu::Vec4 toVec4 (const tcu::Vec3& vec3) 270e5c31af7Sopenharmony_ci{ 271e5c31af7Sopenharmony_ci return tcu::Vec4(vec3.x(), vec3.y(), vec3.z(), 0.0f); 272e5c31af7Sopenharmony_ci} 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_civoid DirectionTestCase::initPrograms (vk::SourceCollections& programCollection) const 275e5c31af7Sopenharmony_ci{ 276e5c31af7Sopenharmony_ci const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_4, 0u, true); 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci std::ostringstream comp; 279e5c31af7Sopenharmony_ci comp 280e5c31af7Sopenharmony_ci << "#version 460 core\n" 281e5c31af7Sopenharmony_ci << "#extension GL_EXT_ray_query : require\n" 282e5c31af7Sopenharmony_ci << "\n" 283e5c31af7Sopenharmony_ci << "layout(local_size_x=1, local_size_y=1, local_size_z=1) in;\n" 284e5c31af7Sopenharmony_ci << "\n" 285e5c31af7Sopenharmony_ci << "layout(set=0, binding=0) uniform accelerationStructureEXT topLevelAS;\n" 286e5c31af7Sopenharmony_ci << "layout(set=0, binding=1, std430) buffer OutBuffer { float val; } outBuffer;\n" 287e5c31af7Sopenharmony_ci // Needs to match the PushConstants struct above. 288e5c31af7Sopenharmony_ci << "layout(push_constant, std430) uniform PushConstants {\n" 289e5c31af7Sopenharmony_ci << " vec4 origin;\n" 290e5c31af7Sopenharmony_ci << " vec4 direction;\n" 291e5c31af7Sopenharmony_ci << " float tmin;\n" 292e5c31af7Sopenharmony_ci << " float tmax;\n" 293e5c31af7Sopenharmony_ci << "} pc;\n" 294e5c31af7Sopenharmony_ci << "\n" 295e5c31af7Sopenharmony_ci << "void main()\n" 296e5c31af7Sopenharmony_ci << "{\n" 297e5c31af7Sopenharmony_ci << " const uint cullMask = 0xFF;\n" 298e5c31af7Sopenharmony_ci << " float outVal = -10000.0f;\n" 299e5c31af7Sopenharmony_ci << " rayQueryEXT rq;\n" 300e5c31af7Sopenharmony_ci << " rayQueryInitializeEXT(rq, topLevelAS, gl_RayFlagsNoneEXT, cullMask, pc.origin.xyz, pc.tmin, pc.direction.xyz, pc.tmax);\n" 301e5c31af7Sopenharmony_ci << " while (rayQueryProceedEXT(rq)) {\n" 302e5c31af7Sopenharmony_ci << " const uint candidateType = rayQueryGetIntersectionTypeEXT(rq, false);\n" 303e5c31af7Sopenharmony_ci << " if (candidateType == gl_RayQueryCandidateIntersectionTriangleEXT) {\n" 304e5c31af7Sopenharmony_ci << " outVal = rayQueryGetIntersectionTEXT(rq, false);\n" 305e5c31af7Sopenharmony_ci << " }\n" 306e5c31af7Sopenharmony_ci << " else if (candidateType == gl_RayQueryCandidateIntersectionAABBEXT) {\n" 307e5c31af7Sopenharmony_ci << " outVal = pc.tmin;\n" 308e5c31af7Sopenharmony_ci << " }\n" 309e5c31af7Sopenharmony_ci << " }\n" 310e5c31af7Sopenharmony_ci << " outBuffer.val = outVal;\n" 311e5c31af7Sopenharmony_ci << "}\n" 312e5c31af7Sopenharmony_ci ; 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci programCollection.glslSources.add("comp") << glu::ComputeSource(updateRayTracingGLSL(comp.str())) << buildOptions; 315e5c31af7Sopenharmony_ci} 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ciTestInstance* DirectionTestCase::createInstance (Context& context) const 318e5c31af7Sopenharmony_ci{ 319e5c31af7Sopenharmony_ci return new DirectionTestInstance(context, m_params); 320e5c31af7Sopenharmony_ci} 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_ciDirectionTestInstance::DirectionTestInstance (Context& context, const TestParams& params) 323e5c31af7Sopenharmony_ci : vkt::TestInstance (context) 324e5c31af7Sopenharmony_ci , m_params (params) 325e5c31af7Sopenharmony_ci{} 326e5c31af7Sopenharmony_ci 327e5c31af7Sopenharmony_citcu::TestStatus DirectionTestInstance::iterate (void) 328e5c31af7Sopenharmony_ci{ 329e5c31af7Sopenharmony_ci const auto& vkd = m_context.getDeviceInterface(); 330e5c31af7Sopenharmony_ci const auto device = m_context.getDevice(); 331e5c31af7Sopenharmony_ci auto& alloc = m_context.getDefaultAllocator(); 332e5c31af7Sopenharmony_ci const auto qIndex = m_context.getUniversalQueueFamilyIndex(); 333e5c31af7Sopenharmony_ci const auto queue = m_context.getUniversalQueue(); 334e5c31af7Sopenharmony_ci const auto stages = VK_SHADER_STAGE_COMPUTE_BIT; 335e5c31af7Sopenharmony_ci const auto pcSize = static_cast<deUint32>(sizeof(PushConstants)); 336e5c31af7Sopenharmony_ci 337e5c31af7Sopenharmony_ci const auto scaleMatrix = getScaleMatrix(m_params.directionScale); 338e5c31af7Sopenharmony_ci const auto rotationMatrix = getRotationMatrix(m_params.rotationX, m_params.rotationY); 339e5c31af7Sopenharmony_ci const auto transformMatrix = toTransformMatrixKHR(rotationMatrix); 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci // Command pool and buffer. 342e5c31af7Sopenharmony_ci const auto cmdPool = makeCommandPool(vkd, device, qIndex); 343e5c31af7Sopenharmony_ci const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY); 344e5c31af7Sopenharmony_ci const auto cmdBuffer = cmdBufferPtr.get(); 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, cmdBuffer); 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci // Build acceleration structures. 349e5c31af7Sopenharmony_ci auto topLevelAS = makeTopLevelAccelerationStructure(); 350e5c31af7Sopenharmony_ci auto bottomLevelAS = makeBottomLevelAccelerationStructure(); 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci const bool isTriangles = (m_params.geometryType == VK_GEOMETRY_TYPE_TRIANGLES_KHR); 353e5c31af7Sopenharmony_ci const VkGeometryInstanceFlagsKHR instanceFlags = (isTriangles ? VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR : 0); 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_ci bottomLevelAS->addGeometry(m_params.spaceObjects.geometry, isTriangles, VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR); 356e5c31af7Sopenharmony_ci bottomLevelAS->createAndBuild(vkd, device, cmdBuffer, alloc); 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci de::SharedPtr<BottomLevelAccelerationStructure> blasSharedPtr (bottomLevelAS.release()); 359e5c31af7Sopenharmony_ci topLevelAS->setUseArrayOfPointers(m_params.useArraysOfPointers); 360e5c31af7Sopenharmony_ci topLevelAS->setUsePPGeometries(m_params.useArraysOfPointers); 361e5c31af7Sopenharmony_ci topLevelAS->setInstanceCount(1); 362e5c31af7Sopenharmony_ci { 363e5c31af7Sopenharmony_ci const auto& initialMatrix = (m_params.updateMatrixAfterBuild ? identityMatrix3x4 : transformMatrix); 364e5c31af7Sopenharmony_ci topLevelAS->addInstance(blasSharedPtr, initialMatrix, 0, 0xFFu, 0u, instanceFlags); 365e5c31af7Sopenharmony_ci } 366e5c31af7Sopenharmony_ci topLevelAS->createAndBuild(vkd, device, cmdBuffer, alloc); 367e5c31af7Sopenharmony_ci if (m_params.updateMatrixAfterBuild) 368e5c31af7Sopenharmony_ci topLevelAS->updateInstanceMatrix(vkd, device, 0u, transformMatrix); 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci // Create output buffer. 371e5c31af7Sopenharmony_ci const auto bufferSize = static_cast<VkDeviceSize>(sizeof(float)); 372e5c31af7Sopenharmony_ci const auto bufferCreateInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT); 373e5c31af7Sopenharmony_ci BufferWithMemory buffer (vkd, device, alloc, bufferCreateInfo, MemoryRequirement::HostVisible); 374e5c31af7Sopenharmony_ci auto& bufferAlloc = buffer.getAllocation(); 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_ci // Fill output buffer with an initial value. 377e5c31af7Sopenharmony_ci deMemset(bufferAlloc.getHostPtr(), 0, sizeof(float)); 378e5c31af7Sopenharmony_ci flushAlloc(vkd, device, bufferAlloc); 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_ci // Descriptor set layout and pipeline layout. 381e5c31af7Sopenharmony_ci DescriptorSetLayoutBuilder setLayoutBuilder; 382e5c31af7Sopenharmony_ci setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, stages); 383e5c31af7Sopenharmony_ci setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, stages); 384e5c31af7Sopenharmony_ci const auto setLayout = setLayoutBuilder.build(vkd, device); 385e5c31af7Sopenharmony_ci 386e5c31af7Sopenharmony_ci const auto pcRange = makePushConstantRange(stages, 0u, pcSize); 387e5c31af7Sopenharmony_ci const auto pipelineLayout = makePipelineLayout(vkd, device, 1u, &setLayout.get(), 1u, &pcRange); 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci // Descriptor pool and set. 390e5c31af7Sopenharmony_ci DescriptorPoolBuilder poolBuilder; 391e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR); 392e5c31af7Sopenharmony_ci poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u); 393e5c31af7Sopenharmony_ci const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u); 394e5c31af7Sopenharmony_ci const auto descriptorSet = makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get()); 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_ci // Update descriptor set. 397e5c31af7Sopenharmony_ci { 398e5c31af7Sopenharmony_ci const VkWriteDescriptorSetAccelerationStructureKHR accelDescInfo = 399e5c31af7Sopenharmony_ci { 400e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR, 401e5c31af7Sopenharmony_ci nullptr, 402e5c31af7Sopenharmony_ci 1u, 403e5c31af7Sopenharmony_ci topLevelAS.get()->getPtr(), 404e5c31af7Sopenharmony_ci }; 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci const auto bufferDescInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, VK_WHOLE_SIZE); 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci DescriptorSetUpdateBuilder updateBuilder; 409e5c31af7Sopenharmony_ci updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, &accelDescInfo); 410e5c31af7Sopenharmony_ci updateBuilder.writeSingle(descriptorSet.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferDescInfo); 411e5c31af7Sopenharmony_ci updateBuilder.update(vkd, device); 412e5c31af7Sopenharmony_ci } 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci // Shader module and pipeline. 415e5c31af7Sopenharmony_ci const auto compModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("comp"), 0); 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci const VkPipelineShaderStageCreateInfo shaderInfo = 418e5c31af7Sopenharmony_ci { 419e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 420e5c31af7Sopenharmony_ci nullptr, // const void* pNext; 421e5c31af7Sopenharmony_ci 0u, // VkPipelineShaderStageCreateFlags flags; 422e5c31af7Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 423e5c31af7Sopenharmony_ci compModule.get(), // VkShaderModule module; 424e5c31af7Sopenharmony_ci "main", // const char* pName; 425e5c31af7Sopenharmony_ci nullptr, // const VkSpecializationInfo* pSpecializationInfo; 426e5c31af7Sopenharmony_ci }; 427e5c31af7Sopenharmony_ci const VkComputePipelineCreateInfo pipelineInfo = 428e5c31af7Sopenharmony_ci { 429e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 430e5c31af7Sopenharmony_ci nullptr, // const void* pNext; 431e5c31af7Sopenharmony_ci 0u, // VkPipelineCreateFlags flags; 432e5c31af7Sopenharmony_ci shaderInfo, // VkPipelineShaderStageCreateInfo stage; 433e5c31af7Sopenharmony_ci pipelineLayout.get(), // VkPipelineLayout layout; 434e5c31af7Sopenharmony_ci DE_NULL, // VkPipeline basePipelineHandle; 435e5c31af7Sopenharmony_ci 0, // deInt32 basePipelineIndex; 436e5c31af7Sopenharmony_ci }; 437e5c31af7Sopenharmony_ci const auto pipeline = createComputePipeline(vkd, device, DE_NULL, &pipelineInfo); 438e5c31af7Sopenharmony_ci 439e5c31af7Sopenharmony_ci // Push constants. 440e5c31af7Sopenharmony_ci const auto rotatedOrigin = m_params.spaceObjects.origin * rotationMatrix; 441e5c31af7Sopenharmony_ci const auto finalDirection = m_params.spaceObjects.direction * scaleMatrix * rotationMatrix; 442e5c31af7Sopenharmony_ci const auto distanceToEdge = SpaceObjects::getDistanceToEdge(m_params.directionScale); 443e5c31af7Sopenharmony_ci const auto tMinMax = calcTminTmax(m_params.rayOriginType, m_params.rayEndtype, distanceToEdge); 444e5c31af7Sopenharmony_ci const PushConstants pcData = 445e5c31af7Sopenharmony_ci { 446e5c31af7Sopenharmony_ci toVec4(rotatedOrigin), // tcu::Vec4 origin; 447e5c31af7Sopenharmony_ci toVec4(finalDirection), // tcu::Vec4 direction; 448e5c31af7Sopenharmony_ci tMinMax.first, // float tmix; 449e5c31af7Sopenharmony_ci tMinMax.second, // float tmax; 450e5c31af7Sopenharmony_ci }; 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci // Trace rays. 453e5c31af7Sopenharmony_ci vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline.get()); 454e5c31af7Sopenharmony_ci vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.get(), 0u, 1u, &descriptorSet.get(), 0u, nullptr); 455e5c31af7Sopenharmony_ci vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), stages, 0u, pcSize, &pcData); 456e5c31af7Sopenharmony_ci vkd.cmdDispatch(cmdBuffer, 1u, 1u, 1u); 457e5c31af7Sopenharmony_ci 458e5c31af7Sopenharmony_ci // Barrier for the output buffer. 459e5c31af7Sopenharmony_ci const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT); 460e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr); 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ci endCommandBuffer(vkd, cmdBuffer); 463e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, cmdBuffer); 464e5c31af7Sopenharmony_ci 465e5c31af7Sopenharmony_ci // Read value back from the buffer. 466e5c31af7Sopenharmony_ci float bufferValue = 0.0f; 467e5c31af7Sopenharmony_ci invalidateAlloc(vkd, device, bufferAlloc); 468e5c31af7Sopenharmony_ci deMemcpy(&bufferValue, bufferAlloc.getHostPtr(), sizeof(bufferValue)); 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ci if (m_params.rayEndtype == RayEndType::CROSS) 471e5c31af7Sopenharmony_ci { 472e5c31af7Sopenharmony_ci // Shooting from the ouside. 473e5c31af7Sopenharmony_ci if (de::abs(bufferValue - distanceToEdge) > kDefaultTolerance) 474e5c31af7Sopenharmony_ci { 475e5c31af7Sopenharmony_ci std::ostringstream msg; 476e5c31af7Sopenharmony_ci msg << "Result distance (" << bufferValue << ") differs from expected distance (" << distanceToEdge << ", tolerance " << kDefaultTolerance << ")"; 477e5c31af7Sopenharmony_ci TCU_FAIL(msg.str()); 478e5c31af7Sopenharmony_ci } 479e5c31af7Sopenharmony_ci } 480e5c31af7Sopenharmony_ci else 481e5c31af7Sopenharmony_ci { 482e5c31af7Sopenharmony_ci // Rays are shot from inside AABBs, rayTMin should be zero and the reported hit distance. 483e5c31af7Sopenharmony_ci if (bufferValue != 0.0f) 484e5c31af7Sopenharmony_ci { 485e5c31af7Sopenharmony_ci std::ostringstream msg; 486e5c31af7Sopenharmony_ci msg << "Result distance nonzero (" << bufferValue << ")"; 487e5c31af7Sopenharmony_ci TCU_FAIL(msg.str()); 488e5c31af7Sopenharmony_ci } 489e5c31af7Sopenharmony_ci } 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Pass"); 492e5c31af7Sopenharmony_ci} 493e5c31af7Sopenharmony_ci 494e5c31af7Sopenharmony_ciusing GroupPtr = de::MovePtr<tcu::TestCaseGroup>; 495e5c31af7Sopenharmony_ci 496e5c31af7Sopenharmony_ci// Generate a list of scaling factors suitable for the tests. 497e5c31af7Sopenharmony_cistd::vector<float> generateScalingFactors (de::Random& rnd) 498e5c31af7Sopenharmony_ci{ 499e5c31af7Sopenharmony_ci const float kMinScalingFactor = 0.5f; 500e5c31af7Sopenharmony_ci const float kMaxScalingFactor = 10.0f; 501e5c31af7Sopenharmony_ci const int kNumRandomScalingFactors = 5; 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci // Scaling factors: 1.0 and some randomly-generated ones. 504e5c31af7Sopenharmony_ci std::vector<float> scalingFactors; 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_ci scalingFactors.reserve(kNumRandomScalingFactors + 1); 507e5c31af7Sopenharmony_ci scalingFactors.push_back(1.0f); 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci for (int i = 0; i < kNumRandomScalingFactors; ++i) 510e5c31af7Sopenharmony_ci scalingFactors.push_back(rnd.getFloat() * (kMaxScalingFactor - kMinScalingFactor) + kMinScalingFactor); 511e5c31af7Sopenharmony_ci 512e5c31af7Sopenharmony_ci return scalingFactors; 513e5c31af7Sopenharmony_ci} 514e5c31af7Sopenharmony_ci 515e5c31af7Sopenharmony_ci// Generate a list of rotation angles suitable for the tests. 516e5c31af7Sopenharmony_cistd::vector<std::pair<float, float>> generateRotationAngles (de::Random& rnd) 517e5c31af7Sopenharmony_ci{ 518e5c31af7Sopenharmony_ci const float kPi2 = DE_PI * 2.0f; 519e5c31af7Sopenharmony_ci const int kNumRandomRotations = 4; 520e5c31af7Sopenharmony_ci 521e5c31af7Sopenharmony_ci // Rotations: 0.0 on both axis and some randomly-generated ones. 522e5c31af7Sopenharmony_ci std::vector<std::pair<float, float>> rotationAngles; 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci rotationAngles.reserve(kNumRandomRotations + 1); 525e5c31af7Sopenharmony_ci rotationAngles.push_back(std::make_pair(0.0f, 0.0f)); 526e5c31af7Sopenharmony_ci 527e5c31af7Sopenharmony_ci for (int i = 0; i < kNumRandomRotations; ++i) 528e5c31af7Sopenharmony_ci rotationAngles.push_back(std::make_pair(rnd.getFloat() * kPi2, rnd.getFloat() * kPi2)); 529e5c31af7Sopenharmony_ci 530e5c31af7Sopenharmony_ci return rotationAngles; 531e5c31af7Sopenharmony_ci} 532e5c31af7Sopenharmony_ci 533e5c31af7Sopenharmony_ci} // anonymous 534e5c31af7Sopenharmony_ci 535e5c31af7Sopenharmony_citcu::TestCaseGroup* createDirectionLengthTests (tcu::TestContext& testCtx) 536e5c31af7Sopenharmony_ci{ 537e5c31af7Sopenharmony_ci // Test direction vector length when using ray queries 538e5c31af7Sopenharmony_ci GroupPtr directionGroup (new tcu::TestCaseGroup(testCtx, "direction_length")); 539e5c31af7Sopenharmony_ci 540e5c31af7Sopenharmony_ci struct 541e5c31af7Sopenharmony_ci { 542e5c31af7Sopenharmony_ci VkGeometryTypeKHR geometryType; 543e5c31af7Sopenharmony_ci const char* name; 544e5c31af7Sopenharmony_ci } geometryTypes[] = 545e5c31af7Sopenharmony_ci { 546e5c31af7Sopenharmony_ci { VK_GEOMETRY_TYPE_TRIANGLES_KHR, "triangles" }, 547e5c31af7Sopenharmony_ci { VK_GEOMETRY_TYPE_AABBS_KHR, "aabbs" }, 548e5c31af7Sopenharmony_ci }; 549e5c31af7Sopenharmony_ci 550e5c31af7Sopenharmony_ci de::Random rnd(1614686501u); 551e5c31af7Sopenharmony_ci deUint32 caseCounter = 0u; 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci // Scaling factors: 1.0 and some randomly-generated ones. 554e5c31af7Sopenharmony_ci // Scaling factors and rotation angles. 555e5c31af7Sopenharmony_ci const auto scalingFactors = generateScalingFactors(rnd); 556e5c31af7Sopenharmony_ci const auto rotationAngles = generateRotationAngles(rnd); 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci for (int geometryTypeIdx = 0; geometryTypeIdx < DE_LENGTH_OF_ARRAY(geometryTypes); ++geometryTypeIdx) 559e5c31af7Sopenharmony_ci { 560e5c31af7Sopenharmony_ci const auto& gType = geometryTypes[geometryTypeIdx]; 561e5c31af7Sopenharmony_ci 562e5c31af7Sopenharmony_ci GroupPtr geomGroup (new tcu::TestCaseGroup(testCtx, gType.name)); 563e5c31af7Sopenharmony_ci 564e5c31af7Sopenharmony_ci for (size_t scalingIdx = 0; scalingIdx < scalingFactors.size(); ++scalingIdx) 565e5c31af7Sopenharmony_ci { 566e5c31af7Sopenharmony_ci const auto scale = scalingFactors[scalingIdx]; 567e5c31af7Sopenharmony_ci const auto scaleName = "scaling_factor_" + de::toString(scalingIdx); 568e5c31af7Sopenharmony_ci GroupPtr factorGroup (new tcu::TestCaseGroup(testCtx, scaleName.c_str())); 569e5c31af7Sopenharmony_ci 570e5c31af7Sopenharmony_ci for (size_t rotationIdx = 0; rotationIdx < rotationAngles.size(); ++rotationIdx) 571e5c31af7Sopenharmony_ci { 572e5c31af7Sopenharmony_ci const auto angles = rotationAngles[rotationIdx]; 573e5c31af7Sopenharmony_ci const auto angleName = "rotation_" + de::toString(rotationIdx); 574e5c31af7Sopenharmony_ci const auto geometryType = gType.geometryType; 575e5c31af7Sopenharmony_ci const auto rayOrigType = RayOriginType::OUTSIDE; 576e5c31af7Sopenharmony_ci const auto rayEndType = RayEndType::CROSS; 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_ci SpaceObjects spaceObjects(rayOrigType, geometryType); 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci TestParams params = 581e5c31af7Sopenharmony_ci { 582e5c31af7Sopenharmony_ci spaceObjects, // SpaceObjects spaceObjects; 583e5c31af7Sopenharmony_ci scale, // float directionScale; 584e5c31af7Sopenharmony_ci angles.first, // float rotationX; 585e5c31af7Sopenharmony_ci angles.second, // float rotationY; 586e5c31af7Sopenharmony_ci geometryType, // VkGeometryTypeKHR geometryType; 587e5c31af7Sopenharmony_ci // Use arrays of pointers when building the TLAS in every other test. 588e5c31af7Sopenharmony_ci (caseCounter % 2u == 0u), // bool useArraysOfPointers; 589e5c31af7Sopenharmony_ci // Sometimes, update matrix after building the lop level AS and before submitting the command buffer. 590e5c31af7Sopenharmony_ci (caseCounter % 3u == 0u), // bool updateMatrixAfterBuild; 591e5c31af7Sopenharmony_ci rayOrigType, // RayOriginType rayOriginType; 592e5c31af7Sopenharmony_ci rayEndType, // RayEndType rayEndType; 593e5c31af7Sopenharmony_ci }; 594e5c31af7Sopenharmony_ci ++caseCounter; 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci factorGroup->addChild(new DirectionTestCase(testCtx, angleName, params)); 597e5c31af7Sopenharmony_ci } 598e5c31af7Sopenharmony_ci 599e5c31af7Sopenharmony_ci geomGroup->addChild(factorGroup.release()); 600e5c31af7Sopenharmony_ci } 601e5c31af7Sopenharmony_ci 602e5c31af7Sopenharmony_ci directionGroup->addChild(geomGroup.release()); 603e5c31af7Sopenharmony_ci } 604e5c31af7Sopenharmony_ci 605e5c31af7Sopenharmony_ci return directionGroup.release(); 606e5c31af7Sopenharmony_ci} 607e5c31af7Sopenharmony_ci 608e5c31af7Sopenharmony_citcu::TestCaseGroup* createInsideAABBsTests (tcu::TestContext& testCtx) 609e5c31af7Sopenharmony_ci{ 610e5c31af7Sopenharmony_ci GroupPtr insideAABBsGroup (new tcu::TestCaseGroup(testCtx, "inside_aabbs", "Test shooting rays that start inside AABBs")); 611e5c31af7Sopenharmony_ci 612e5c31af7Sopenharmony_ci struct 613e5c31af7Sopenharmony_ci { 614e5c31af7Sopenharmony_ci RayEndType rayEndType; 615e5c31af7Sopenharmony_ci const char* name; 616e5c31af7Sopenharmony_ci } rayEndCases[] = 617e5c31af7Sopenharmony_ci { 618e5c31af7Sopenharmony_ci { RayEndType::ZERO, "tmax_zero" }, 619e5c31af7Sopenharmony_ci { RayEndType::INSIDE, "inside" }, 620e5c31af7Sopenharmony_ci { RayEndType::EDGE, "edge" }, 621e5c31af7Sopenharmony_ci { RayEndType::OUTSIDE, "outside" }, 622e5c31af7Sopenharmony_ci }; 623e5c31af7Sopenharmony_ci 624e5c31af7Sopenharmony_ci de::Random rnd(1621948244u); 625e5c31af7Sopenharmony_ci 626e5c31af7Sopenharmony_ci // Scaling factors: 1.0 and some randomly-generated ones. 627e5c31af7Sopenharmony_ci // Scaling factors and rotation angles. 628e5c31af7Sopenharmony_ci const auto scalingFactors = generateScalingFactors(rnd); 629e5c31af7Sopenharmony_ci const auto rotationAngles = generateRotationAngles(rnd); 630e5c31af7Sopenharmony_ci 631e5c31af7Sopenharmony_ci for (int rayEndCaseIdx = 0; rayEndCaseIdx < DE_LENGTH_OF_ARRAY(rayEndCases); ++rayEndCaseIdx) 632e5c31af7Sopenharmony_ci { 633e5c31af7Sopenharmony_ci const auto& rayEndCase = rayEndCases[rayEndCaseIdx]; 634e5c31af7Sopenharmony_ci const std::string rayEndName = std::string("ray_end_") + rayEndCase.name; 635e5c31af7Sopenharmony_ci GroupPtr rayEndGroup (new tcu::TestCaseGroup(testCtx, rayEndName.c_str())); 636e5c31af7Sopenharmony_ci 637e5c31af7Sopenharmony_ci for (size_t scalingIdx = 0; scalingIdx < scalingFactors.size(); ++scalingIdx) 638e5c31af7Sopenharmony_ci { 639e5c31af7Sopenharmony_ci const auto scale = scalingFactors[scalingIdx]; 640e5c31af7Sopenharmony_ci const auto scaleName = "scaling_factor_" + de::toString(scalingIdx); 641e5c31af7Sopenharmony_ci GroupPtr factorGroup (new tcu::TestCaseGroup(testCtx, scaleName.c_str())); 642e5c31af7Sopenharmony_ci 643e5c31af7Sopenharmony_ci for (size_t rotationIdx = 0; rotationIdx < rotationAngles.size(); ++rotationIdx) 644e5c31af7Sopenharmony_ci { 645e5c31af7Sopenharmony_ci const auto angles = rotationAngles[rotationIdx]; 646e5c31af7Sopenharmony_ci const auto angleName = "rotation_" + de::toString(rotationIdx); 647e5c31af7Sopenharmony_ci const auto geometryType = VK_GEOMETRY_TYPE_AABBS_KHR; 648e5c31af7Sopenharmony_ci const auto rayOrigType = RayOriginType::INSIDE; 649e5c31af7Sopenharmony_ci 650e5c31af7Sopenharmony_ci SpaceObjects spaceObjects(rayOrigType, geometryType); 651e5c31af7Sopenharmony_ci 652e5c31af7Sopenharmony_ci TestParams params = 653e5c31af7Sopenharmony_ci { 654e5c31af7Sopenharmony_ci spaceObjects, // SpaceObjects spaceObjects; 655e5c31af7Sopenharmony_ci scale, // float directionScale; 656e5c31af7Sopenharmony_ci angles.first, // float rotationX; 657e5c31af7Sopenharmony_ci angles.second, // float rotationY; 658e5c31af7Sopenharmony_ci geometryType, // VkGeometryTypeKHR geometryType; 659e5c31af7Sopenharmony_ci false, // bool useArraysOfPointers; 660e5c31af7Sopenharmony_ci false, // bool updateMatrixAfterBuild; 661e5c31af7Sopenharmony_ci rayOrigType, // RayOriginType rayOriginType; 662e5c31af7Sopenharmony_ci rayEndCase.rayEndType, // RayEndType rayEndType; 663e5c31af7Sopenharmony_ci }; 664e5c31af7Sopenharmony_ci 665e5c31af7Sopenharmony_ci factorGroup->addChild(new DirectionTestCase(testCtx, angleName, params)); 666e5c31af7Sopenharmony_ci } 667e5c31af7Sopenharmony_ci 668e5c31af7Sopenharmony_ci rayEndGroup->addChild(factorGroup.release()); 669e5c31af7Sopenharmony_ci } 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci insideAABBsGroup->addChild(rayEndGroup.release()); 672e5c31af7Sopenharmony_ci } 673e5c31af7Sopenharmony_ci 674e5c31af7Sopenharmony_ci return insideAABBsGroup.release(); 675e5c31af7Sopenharmony_ci} 676e5c31af7Sopenharmony_ci 677e5c31af7Sopenharmony_ci} // RayQuery 678e5c31af7Sopenharmony_ci} // vkt 679