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 Advanced Micro Devices, Inc. 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/*! 22e5c31af7Sopenharmony_ci * \file 23e5c31af7Sopenharmony_ci * \brief Pipeline Cache Tests 24e5c31af7Sopenharmony_ci */ 25e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*/ 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "vktPipelineCreationCacheControlTests.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include "deRandom.hpp" 30e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp" 31e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 32e5c31af7Sopenharmony_ci#include "vkDeviceUtil.hpp" 33e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 34e5c31af7Sopenharmony_ci#include "vktConstexprVectorUtil.hpp" 35e5c31af7Sopenharmony_ci#include "vktTestCase.hpp" 36e5c31af7Sopenharmony_ci#include "vktTestCaseUtil.hpp" 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci#include <chrono> 39e5c31af7Sopenharmony_ci#include <random> 40e5c31af7Sopenharmony_ci#include <string> 41e5c31af7Sopenharmony_ci#include <vector> 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_cinamespace vkt 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_cinamespace pipeline 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_cinamespace 48e5c31af7Sopenharmony_ci{ 49e5c31af7Sopenharmony_ciusing namespace vk; 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_ciusing tcu::StringTemplate; 52e5c31af7Sopenharmony_ciusing tcu::TestCaseGroup; 53e5c31af7Sopenharmony_ciusing tcu::TestContext; 54e5c31af7Sopenharmony_ciusing tcu::TestStatus; 55e5c31af7Sopenharmony_ci 56e5c31af7Sopenharmony_ciusing ::std::array; 57e5c31af7Sopenharmony_ciusing ::std::string; 58e5c31af7Sopenharmony_ciusing ::std::vector; 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 61e5c31af7Sopenharmony_ci * Elements common to all test types 62e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 63e5c31af7Sopenharmony_cinamespace test_common 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ciusing ::std::chrono::high_resolution_clock; 66e5c31af7Sopenharmony_ciusing ::std::chrono::microseconds; 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ciusing duration = high_resolution_clock::duration; 69e5c31af7Sopenharmony_ciusing UniquePipeline = Move<VkPipeline>; 70e5c31af7Sopenharmony_ciusing UniqueShaderModule = Move<VkShaderModule>; 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 73e5c31af7Sopenharmony_ci * \brief Paired Vulkan API result with elapsed duration 74e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 75e5c31af7Sopenharmony_cistruct TimedResult 76e5c31af7Sopenharmony_ci{ 77e5c31af7Sopenharmony_ci VkResult result; 78e5c31af7Sopenharmony_ci duration elapsed; 79e5c31af7Sopenharmony_ci}; 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 82e5c31af7Sopenharmony_ci * \brief Validation function type output from vkCreate*Pipelines() 83e5c31af7Sopenharmony_ci * 84e5c31af7Sopenharmony_ci * \param result - VkResult returned from API call 85e5c31af7Sopenharmony_ci * \param pipeliens - vector of pipelines created 86e5c31af7Sopenharmony_ci * \param elapsed - high_resolution_clock::duration of time elapsed in API 87e5c31af7Sopenharmony_ci * \param reason - output string to give the reason for failure 88e5c31af7Sopenharmony_ci * 89e5c31af7Sopenharmony_ci * \return QP_TEST_RESULT_PASS on success QP_TEST_RESULT_FAIL otherwise 90e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 91e5c31af7Sopenharmony_ciusing Validator = qpTestResult (*)(VkResult, const vector<UniquePipeline>&, duration, string&); 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_cistatic constexpr size_t VALIDATOR_ARRAY_MAX = 4; 94e5c31af7Sopenharmony_ciusing ValidatorArray = ConstexprVector<Validator, VALIDATOR_ARRAY_MAX>; 95e5c31af7Sopenharmony_ci 96e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 97e5c31af7Sopenharmony_ci * \brief Run a loop of validation tests and return the result 98e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 99e5c31af7Sopenharmony_citemplate <typename pipelines_t, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL> 100e5c31af7Sopenharmony_ciTestStatus validateResults(VkResult result, 101e5c31af7Sopenharmony_ci const pipelines_t& pipelines, 102e5c31af7Sopenharmony_ci duration elapsed, 103e5c31af7Sopenharmony_ci const ValidatorArray& validators) 104e5c31af7Sopenharmony_ci{ 105e5c31af7Sopenharmony_ci using de::contains; 106e5c31af7Sopenharmony_ci static constexpr VkResult ALLOWED_RESULTS[] = {VK_SUCCESS, VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT}; 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ci string reason; 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci if (contains(DE_ARRAY_BEGIN(ALLOWED_RESULTS), DE_ARRAY_END(ALLOWED_RESULTS), result) == DE_FALSE) 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"Pipeline creation returned an error result: ${0}"}; 113e5c31af7Sopenharmony_ci TCU_THROW(InternalError, ERROR_MSG.format(result).c_str()); 114e5c31af7Sopenharmony_ci } 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_ci for (const auto& validator : validators) 117e5c31af7Sopenharmony_ci { 118e5c31af7Sopenharmony_ci const auto qpResult = validator(result, pipelines, elapsed, reason); 119e5c31af7Sopenharmony_ci if (qpResult != QP_TEST_RESULT_PASS) 120e5c31af7Sopenharmony_ci { 121e5c31af7Sopenharmony_ci return {qpResult, reason}; 122e5c31af7Sopenharmony_ci } 123e5c31af7Sopenharmony_ci } 124e5c31af7Sopenharmony_ci 125e5c31af7Sopenharmony_ci return TestStatus::pass("Test passed."); 126e5c31af7Sopenharmony_ci} 127e5c31af7Sopenharmony_ci 128e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 129e5c31af7Sopenharmony_ci * \brief Generate an error if result does not match VK_RESULT 130e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 131e5c31af7Sopenharmony_citemplate <VkResult VK_RESULT, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL> 132e5c31af7Sopenharmony_ciqpTestResult checkResult(VkResult result, const vector<UniquePipeline>&, duration, string& reason) 133e5c31af7Sopenharmony_ci{ 134e5c31af7Sopenharmony_ci if (VK_RESULT != result) 135e5c31af7Sopenharmony_ci { 136e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"Got ${0}, Expected ${1}"}; 137e5c31af7Sopenharmony_ci reason = ERROR_MSG.format(result, VK_RESULT); 138e5c31af7Sopenharmony_ci return FAIL_RESULT; 139e5c31af7Sopenharmony_ci } 140e5c31af7Sopenharmony_ci 141e5c31af7Sopenharmony_ci return QP_TEST_RESULT_PASS; 142e5c31af7Sopenharmony_ci} 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 145e5c31af7Sopenharmony_ci * \brief Generate an error if pipeline[INDEX] is not valid 146e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 147e5c31af7Sopenharmony_citemplate <size_t INDEX, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL> 148e5c31af7Sopenharmony_ciqpTestResult checkPipelineMustBeValid(VkResult, const vector<UniquePipeline>& pipelines, duration, string& reason) 149e5c31af7Sopenharmony_ci{ 150e5c31af7Sopenharmony_ci if (pipelines.size() <= INDEX) 151e5c31af7Sopenharmony_ci { 152e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"Index ${0} is not in created pipelines (pipelines.size(): ${1})"}; 153e5c31af7Sopenharmony_ci TCU_THROW(TestError, ERROR_MSG.format(INDEX, pipelines.size())); 154e5c31af7Sopenharmony_ci } 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci if (*pipelines[INDEX] == VK_NULL_HANDLE) 157e5c31af7Sopenharmony_ci { 158e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"pipelines[${0}] is not a valid VkPipeline object"}; 159e5c31af7Sopenharmony_ci reason = ERROR_MSG.format(INDEX); 160e5c31af7Sopenharmony_ci return FAIL_RESULT; 161e5c31af7Sopenharmony_ci } 162e5c31af7Sopenharmony_ci 163e5c31af7Sopenharmony_ci return QP_TEST_RESULT_PASS; 164e5c31af7Sopenharmony_ci} 165e5c31af7Sopenharmony_ci 166e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 167e5c31af7Sopenharmony_ci * \brief Generate an error if pipeline[INDEX] is not VK_NULL_HANDLE 168e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 169e5c31af7Sopenharmony_citemplate <size_t INDEX, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL> 170e5c31af7Sopenharmony_ciqpTestResult checkPipelineMustBeNull(VkResult, const vector<UniquePipeline>& pipelines, duration, string& reason) 171e5c31af7Sopenharmony_ci{ 172e5c31af7Sopenharmony_ci if (pipelines.size() <= INDEX) 173e5c31af7Sopenharmony_ci { 174e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"Index ${0} is not in created pipelines (pipelines.size(): ${1})"}; 175e5c31af7Sopenharmony_ci TCU_THROW(TestError, ERROR_MSG.format(INDEX, pipelines.size())); 176e5c31af7Sopenharmony_ci } 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci if (*pipelines[INDEX] != VK_NULL_HANDLE) 179e5c31af7Sopenharmony_ci { 180e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"pipelines[${0}] is not VK_NULL_HANDLE"}; 181e5c31af7Sopenharmony_ci reason = ERROR_MSG.format(INDEX); 182e5c31af7Sopenharmony_ci return FAIL_RESULT; 183e5c31af7Sopenharmony_ci } 184e5c31af7Sopenharmony_ci 185e5c31af7Sopenharmony_ci return QP_TEST_RESULT_PASS; 186e5c31af7Sopenharmony_ci} 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 189e5c31af7Sopenharmony_ci * \brief Generate an error if any pipeline is valid after an early-return failure 190e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 191e5c31af7Sopenharmony_citemplate <size_t INDEX, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL> 192e5c31af7Sopenharmony_ciqpTestResult checkPipelineNullAfterIndex(VkResult, const vector<UniquePipeline>& pipelines, duration, string& reason) 193e5c31af7Sopenharmony_ci{ 194e5c31af7Sopenharmony_ci if (pipelines.size() <= INDEX) 195e5c31af7Sopenharmony_ci { 196e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"Index ${0} is not in created pipelines (pipelines.size(): ${1})"}; 197e5c31af7Sopenharmony_ci TCU_THROW(TestError, ERROR_MSG.format(INDEX, pipelines.size())); 198e5c31af7Sopenharmony_ci } 199e5c31af7Sopenharmony_ci 200e5c31af7Sopenharmony_ci if (pipelines.size() - 1 == INDEX) 201e5c31af7Sopenharmony_ci { 202e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"Index ${0} is the last pipeline, likely a malformed test case"}; 203e5c31af7Sopenharmony_ci TCU_THROW(TestError, ERROR_MSG.format(INDEX)); 204e5c31af7Sopenharmony_ci } 205e5c31af7Sopenharmony_ci 206e5c31af7Sopenharmony_ci // Only have to iterate through if the requested index is null 207e5c31af7Sopenharmony_ci if (*pipelines[INDEX] == VK_NULL_HANDLE) 208e5c31af7Sopenharmony_ci { 209e5c31af7Sopenharmony_ci for (size_t i = INDEX + 1; i < pipelines.size(); ++i) 210e5c31af7Sopenharmony_ci { 211e5c31af7Sopenharmony_ci if (*pipelines[i] != VK_NULL_HANDLE) 212e5c31af7Sopenharmony_ci { 213e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = { 214e5c31af7Sopenharmony_ci "pipelines[${0}] is not VK_NULL_HANDLE after a explicit early return index"}; 215e5c31af7Sopenharmony_ci reason = ERROR_MSG.format(i); 216e5c31af7Sopenharmony_ci return FAIL_RESULT; 217e5c31af7Sopenharmony_ci } 218e5c31af7Sopenharmony_ci } 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci return QP_TEST_RESULT_PASS; 222e5c31af7Sopenharmony_ci} 223e5c31af7Sopenharmony_ci 224e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 225e5c31af7Sopenharmony_ci * Time limit constants 226e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 227e5c31af7Sopenharmony_cienum ElapsedTime 228e5c31af7Sopenharmony_ci{ 229e5c31af7Sopenharmony_ci ELAPSED_TIME_INFINITE = microseconds{-1}.count(), 230e5c31af7Sopenharmony_ci ELAPSED_TIME_IMMEDIATE = microseconds{500}.count(), 231e5c31af7Sopenharmony_ci ELAPSED_TIME_FAST = microseconds{1000}.count() 232e5c31af7Sopenharmony_ci}; 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 235e5c31af7Sopenharmony_ci * \brief Generate an error if elapsed time exceeds MAX_TIME 236e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 237e5c31af7Sopenharmony_citemplate <ElapsedTime MAX_TIME, qpTestResult FAIL_RESULT = QP_TEST_RESULT_FAIL> 238e5c31af7Sopenharmony_ciqpTestResult checkElapsedTime(VkResult, const vector<UniquePipeline>&, duration elapsed, string& reason) 239e5c31af7Sopenharmony_ci{ 240e5c31af7Sopenharmony_ci#if defined(DE_DEBUG) 241e5c31af7Sopenharmony_ci DE_UNREF(elapsed); 242e5c31af7Sopenharmony_ci DE_UNREF(reason); 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci // In debug mode timing is not likely to be accurate 245e5c31af7Sopenharmony_ci return QP_TEST_RESULT_PASS; 246e5c31af7Sopenharmony_ci#else 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_ci using ::std::chrono::duration_cast; 249e5c31af7Sopenharmony_ci 250e5c31af7Sopenharmony_ci static constexpr microseconds ALLOWED_TIME = microseconds{MAX_TIME}; 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci if (elapsed > ALLOWED_TIME) 253e5c31af7Sopenharmony_ci { 254e5c31af7Sopenharmony_ci static const StringTemplate ERROR_MSG = {"pipeline creation took longer than ${0}us (actual time: ${1}us)"}; 255e5c31af7Sopenharmony_ci reason = ERROR_MSG.format(ALLOWED_TIME.count(), duration_cast<microseconds>(elapsed).count()); 256e5c31af7Sopenharmony_ci return FAIL_RESULT; 257e5c31af7Sopenharmony_ci } 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci return QP_TEST_RESULT_PASS; 260e5c31af7Sopenharmony_ci#endif 261e5c31af7Sopenharmony_ci} 262e5c31af7Sopenharmony_ci 263e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 264e5c31af7Sopenharmony_ci * \brief Test case parameters 265e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 266e5c31af7Sopenharmony_cistruct TestParams 267e5c31af7Sopenharmony_ci{ 268e5c31af7Sopenharmony_ci enum CacheType 269e5c31af7Sopenharmony_ci { 270e5c31af7Sopenharmony_ci NO_CACHE = 0, 271e5c31af7Sopenharmony_ci EXPLICIT_CACHE, 272e5c31af7Sopenharmony_ci DERIVATIVE_HANDLE, 273e5c31af7Sopenharmony_ci DERIVATIVE_INDEX 274e5c31af7Sopenharmony_ci }; 275e5c31af7Sopenharmony_ci 276e5c31af7Sopenharmony_ci struct Iteration 277e5c31af7Sopenharmony_ci { 278e5c31af7Sopenharmony_ci static constexpr size_t MAX_VARIANTS = 4; 279e5c31af7Sopenharmony_ci using Variant = VkPipelineCreateFlags; 280e5c31af7Sopenharmony_ci using VariantArray = ConstexprVector<Variant, MAX_VARIANTS>; 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci static constexpr Variant NORMAL = 0; 283e5c31af7Sopenharmony_ci static constexpr Variant NO_COMPILE = VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT; 284e5c31af7Sopenharmony_ci static constexpr Variant EARLY_RETURN = NO_COMPILE | VK_PIPELINE_CREATE_EARLY_RETURN_ON_FAILURE_BIT_EXT; 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ci static constexpr VariantArray SINGLE_NORMAL = VariantArray{NORMAL}; 287e5c31af7Sopenharmony_ci static constexpr VariantArray SINGLE_NOCOMPILE = VariantArray{NO_COMPILE}; 288e5c31af7Sopenharmony_ci static constexpr VariantArray BATCH_NOCOMPILE_COMPILE_NOCOMPILE = VariantArray{NO_COMPILE, NORMAL, NO_COMPILE}; 289e5c31af7Sopenharmony_ci static constexpr VariantArray BATCH_RETURN_COMPILE_NOCOMPILE = VariantArray{EARLY_RETURN, NORMAL, NO_COMPILE}; 290e5c31af7Sopenharmony_ci 291e5c31af7Sopenharmony_ci inline constexpr Iteration() : variants{}, validators{} {} 292e5c31af7Sopenharmony_ci inline constexpr Iteration(const VariantArray& v, const ValidatorArray& f) : variants{v}, validators{f} {} 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_ci VariantArray variants; 295e5c31af7Sopenharmony_ci ValidatorArray validators; 296e5c31af7Sopenharmony_ci }; 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci static constexpr size_t MAX_ITERATIONS = 4; 299e5c31af7Sopenharmony_ci using IterationArray = ConstexprVector<Iteration, MAX_ITERATIONS>; 300e5c31af7Sopenharmony_ci 301e5c31af7Sopenharmony_ci const char* name; 302e5c31af7Sopenharmony_ci CacheType cacheType; 303e5c31af7Sopenharmony_ci IterationArray iterations; 304e5c31af7Sopenharmony_ci bool useMaintenance5; 305e5c31af7Sopenharmony_ci}; 306e5c31af7Sopenharmony_ci 307e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 308e5c31af7Sopenharmony_ci * \brief Verify extension and feature support 309e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 310e5c31af7Sopenharmony_civoid checkSupport(Context& context, const TestParams& params) 311e5c31af7Sopenharmony_ci{ 312e5c31af7Sopenharmony_ci static constexpr char EXT_NAME[] = "VK_EXT_pipeline_creation_cache_control"; 313e5c31af7Sopenharmony_ci if (!context.requireDeviceFunctionality(EXT_NAME)) 314e5c31af7Sopenharmony_ci { 315e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Extension 'VK_EXT_pipeline_creation_cache_control' is not supported"); 316e5c31af7Sopenharmony_ci } 317e5c31af7Sopenharmony_ci 318e5c31af7Sopenharmony_ci const auto features = context.getPipelineCreationCacheControlFeatures(); 319e5c31af7Sopenharmony_ci if (features.pipelineCreationCacheControl == DE_FALSE) 320e5c31af7Sopenharmony_ci { 321e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Feature 'pipelineCreationCacheControl' is not enabled"); 322e5c31af7Sopenharmony_ci } 323e5c31af7Sopenharmony_ci 324e5c31af7Sopenharmony_ci if (params.useMaintenance5) 325e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_maintenance5"); 326e5c31af7Sopenharmony_ci} 327e5c31af7Sopenharmony_ci 328e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 329e5c31af7Sopenharmony_ci * \brief Generate a random floating point number as a string 330e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 331e5c31af7Sopenharmony_cifloat randomFloat() 332e5c31af7Sopenharmony_ci{ 333e5c31af7Sopenharmony_ci#if !defined(DE_DEBUG) 334e5c31af7Sopenharmony_ci static de::Random state = {::std::random_device{}()}; 335e5c31af7Sopenharmony_ci#else 336e5c31af7Sopenharmony_ci static de::Random state = {0xDEADBEEF}; 337e5c31af7Sopenharmony_ci#endif 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_ci return state.getFloat(); 340e5c31af7Sopenharmony_ci} 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 343e5c31af7Sopenharmony_ci * \brief Get a string of VkResults from a vector 344e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 345e5c31af7Sopenharmony_cistring getResultsString(const vector<VkResult>& results) 346e5c31af7Sopenharmony_ci{ 347e5c31af7Sopenharmony_ci using ::std::ostringstream; 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci ostringstream output; 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci output << "results[" << results.size() << "]={ "; 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci if (!results.empty()) 354e5c31af7Sopenharmony_ci { 355e5c31af7Sopenharmony_ci output << results[0]; 356e5c31af7Sopenharmony_ci } 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci for (size_t i = 1; i < results.size(); ++i) 359e5c31af7Sopenharmony_ci { 360e5c31af7Sopenharmony_ci output << ", " << results[i]; 361e5c31af7Sopenharmony_ci } 362e5c31af7Sopenharmony_ci 363e5c31af7Sopenharmony_ci output << " }"; 364e5c31af7Sopenharmony_ci 365e5c31af7Sopenharmony_ci return output.str(); 366e5c31af7Sopenharmony_ci} 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 369e5c31af7Sopenharmony_ci * \brief Cast a pointer to an the expected SPIRV type 370e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 371e5c31af7Sopenharmony_citemplate <typename _t> 372e5c31af7Sopenharmony_ciinline const deUint32* shader_cast(const _t* ptr) 373e5c31af7Sopenharmony_ci{ 374e5c31af7Sopenharmony_ci return reinterpret_cast<const deUint32*>(ptr); 375e5c31af7Sopenharmony_ci} 376e5c31af7Sopenharmony_ci 377e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 378e5c31af7Sopenharmony_ci * \brief Capture a container of Vulkan handles into Move<> types 379e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 380e5c31af7Sopenharmony_citemplate <typename input_container_t, 381e5c31af7Sopenharmony_ci typename handle_t = typename input_container_t::value_type, 382e5c31af7Sopenharmony_ci typename move_t = Move<handle_t>, 383e5c31af7Sopenharmony_ci typename deleter_t = Deleter<handle_t>, 384e5c31af7Sopenharmony_ci typename output_t = vector<move_t>> 385e5c31af7Sopenharmony_cioutput_t wrapHandles(const DeviceInterface& vk, 386e5c31af7Sopenharmony_ci VkDevice device, 387e5c31af7Sopenharmony_ci const input_container_t& input, 388e5c31af7Sopenharmony_ci const VkAllocationCallbacks* allocator = DE_NULL) 389e5c31af7Sopenharmony_ci{ 390e5c31af7Sopenharmony_ci using ::std::begin; 391e5c31af7Sopenharmony_ci using ::std::end; 392e5c31af7Sopenharmony_ci using ::std::transform; 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ci auto output = output_t{}; 395e5c31af7Sopenharmony_ci output.resize(input.size()); 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci struct Predicate 398e5c31af7Sopenharmony_ci { 399e5c31af7Sopenharmony_ci deleter_t deleter; 400e5c31af7Sopenharmony_ci move_t operator()(handle_t v) 401e5c31af7Sopenharmony_ci { 402e5c31af7Sopenharmony_ci return (v != VK_NULL_HANDLE) ? move_t{check(v), deleter} : move_t{}; 403e5c31af7Sopenharmony_ci } 404e5c31af7Sopenharmony_ci }; 405e5c31af7Sopenharmony_ci 406e5c31af7Sopenharmony_ci const auto wrapHandle = Predicate{deleter_t{vk, device, allocator}}; 407e5c31af7Sopenharmony_ci 408e5c31af7Sopenharmony_ci transform(begin(input), end(input), begin(output), wrapHandle); 409e5c31af7Sopenharmony_ci 410e5c31af7Sopenharmony_ci return output; 411e5c31af7Sopenharmony_ci} 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 414e5c31af7Sopenharmony_ci * \brief create vkPipelineCache for test params 415e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 416e5c31af7Sopenharmony_ciMove<VkPipelineCache> createPipelineCache(const DeviceInterface& vk, VkDevice device, const TestParams& params) 417e5c31af7Sopenharmony_ci{ 418e5c31af7Sopenharmony_ci if (params.cacheType != TestParams::EXPLICIT_CACHE) 419e5c31af7Sopenharmony_ci { 420e5c31af7Sopenharmony_ci return {}; 421e5c31af7Sopenharmony_ci } 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci static constexpr auto cacheInfo = VkPipelineCacheCreateInfo{ 424e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, //sType 425e5c31af7Sopenharmony_ci DE_NULL, //pNext 426e5c31af7Sopenharmony_ci VkPipelineCacheCreateFlags{}, //flags 427e5c31af7Sopenharmony_ci deUintptr{0}, //initialDataSize 428e5c31af7Sopenharmony_ci DE_NULL //pInitialData 429e5c31af7Sopenharmony_ci }; 430e5c31af7Sopenharmony_ci 431e5c31af7Sopenharmony_ci return createPipelineCache(vk, device, &cacheInfo); 432e5c31af7Sopenharmony_ci} 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 435e5c31af7Sopenharmony_ci * \brief create VkPipelineLayout with descriptor sets from test parameters 436e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 437e5c31af7Sopenharmony_ciMove<VkPipelineLayout> createPipelineLayout(const DeviceInterface& vk, 438e5c31af7Sopenharmony_ci VkDevice device, 439e5c31af7Sopenharmony_ci const vector<VkDescriptorSetLayout>& setLayouts, 440e5c31af7Sopenharmony_ci const TestParams&) 441e5c31af7Sopenharmony_ci{ 442e5c31af7Sopenharmony_ci const auto layoutCreateInfo = VkPipelineLayoutCreateInfo{ 443e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType 444e5c31af7Sopenharmony_ci DE_NULL, // pNext 445e5c31af7Sopenharmony_ci VkPipelineLayoutCreateFlags{}, // flags 446e5c31af7Sopenharmony_ci static_cast<deUint32>(setLayouts.size()), // setLayoutCount 447e5c31af7Sopenharmony_ci setLayouts.data(), // pSetLayouts 448e5c31af7Sopenharmony_ci deUint32{0u}, // pushConstantRangeCount 449e5c31af7Sopenharmony_ci DE_NULL, // pPushConstantRanges 450e5c31af7Sopenharmony_ci }; 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci return createPipelineLayout(vk, device, &layoutCreateInfo); 453e5c31af7Sopenharmony_ci} 454e5c31af7Sopenharmony_ci 455e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 456e5c31af7Sopenharmony_ci * \brief create basic VkPipelineLayout from test parameters 457e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 458e5c31af7Sopenharmony_ciMove<VkPipelineLayout> createPipelineLayout(const DeviceInterface& vk, VkDevice device, const TestParams&) 459e5c31af7Sopenharmony_ci{ 460e5c31af7Sopenharmony_ci static constexpr auto layoutCreateInfo = VkPipelineLayoutCreateInfo{ 461e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType 462e5c31af7Sopenharmony_ci DE_NULL, // pNext 463e5c31af7Sopenharmony_ci VkPipelineLayoutCreateFlags{}, // flags 464e5c31af7Sopenharmony_ci deUint32{0u}, // setLayoutCount 465e5c31af7Sopenharmony_ci DE_NULL, // pSetLayouts 466e5c31af7Sopenharmony_ci deUint32{0u}, // pushConstantRangeCount 467e5c31af7Sopenharmony_ci DE_NULL, // pPushConstantRanges 468e5c31af7Sopenharmony_ci }; 469e5c31af7Sopenharmony_ci 470e5c31af7Sopenharmony_ci return createPipelineLayout(vk, device, &layoutCreateInfo); 471e5c31af7Sopenharmony_ci} 472e5c31af7Sopenharmony_ci 473e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 474e5c31af7Sopenharmony_ci * \brief Create array of shader modules 475e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 476e5c31af7Sopenharmony_civector<UniqueShaderModule> createShaderModules(const DeviceInterface& vk, 477e5c31af7Sopenharmony_ci VkDevice device, 478e5c31af7Sopenharmony_ci const BinaryCollection& collection, 479e5c31af7Sopenharmony_ci const vector<const char*>& names) 480e5c31af7Sopenharmony_ci{ 481e5c31af7Sopenharmony_ci auto output = vector<UniqueShaderModule>{}; 482e5c31af7Sopenharmony_ci output.reserve(names.size()); 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ci for (const auto& name : names) 485e5c31af7Sopenharmony_ci { 486e5c31af7Sopenharmony_ci const auto& binary = collection.get(name); 487e5c31af7Sopenharmony_ci const auto createInfo = VkShaderModuleCreateInfo{ 488e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // sType 489e5c31af7Sopenharmony_ci DE_NULL, // pNext 490e5c31af7Sopenharmony_ci VkShaderModuleCreateFlags{}, // flags 491e5c31af7Sopenharmony_ci binary.getSize(), // codeSize 492e5c31af7Sopenharmony_ci shader_cast(binary.getBinary()) // pCode 493e5c31af7Sopenharmony_ci }; 494e5c31af7Sopenharmony_ci 495e5c31af7Sopenharmony_ci output.push_back(createShaderModule(vk, device, &createInfo)); 496e5c31af7Sopenharmony_ci } 497e5c31af7Sopenharmony_ci 498e5c31af7Sopenharmony_ci return output; 499e5c31af7Sopenharmony_ci} 500e5c31af7Sopenharmony_ci 501e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 502e5c31af7Sopenharmony_ci * \brief Create array of shader binding stages 503e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 504e5c31af7Sopenharmony_civector<VkPipelineShaderStageCreateInfo> createShaderStages(const vector<Move<VkShaderModule>>& modules, 505e5c31af7Sopenharmony_ci const vector<VkShaderStageFlagBits>& stages) 506e5c31af7Sopenharmony_ci{ 507e5c31af7Sopenharmony_ci DE_ASSERT(modules.size() == stages.size()); 508e5c31af7Sopenharmony_ci 509e5c31af7Sopenharmony_ci auto output = vector<VkPipelineShaderStageCreateInfo>{}; 510e5c31af7Sopenharmony_ci output.reserve(modules.size()); 511e5c31af7Sopenharmony_ci 512e5c31af7Sopenharmony_ci int i = 0; 513e5c31af7Sopenharmony_ci 514e5c31af7Sopenharmony_ci for (const auto& module : modules) 515e5c31af7Sopenharmony_ci { 516e5c31af7Sopenharmony_ci const auto stageInfo = VkPipelineShaderStageCreateInfo{ 517e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType 518e5c31af7Sopenharmony_ci DE_NULL, // pNext 519e5c31af7Sopenharmony_ci VkPipelineShaderStageCreateFlags{}, // flags 520e5c31af7Sopenharmony_ci stages[i++], // stage 521e5c31af7Sopenharmony_ci *module, // module 522e5c31af7Sopenharmony_ci "main", // pName 523e5c31af7Sopenharmony_ci DE_NULL // pSpecializationInfo 524e5c31af7Sopenharmony_ci }; 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci output.push_back(stageInfo); 527e5c31af7Sopenharmony_ci } 528e5c31af7Sopenharmony_ci 529e5c31af7Sopenharmony_ci return output; 530e5c31af7Sopenharmony_ci} 531e5c31af7Sopenharmony_ci 532e5c31af7Sopenharmony_ci} // namespace test_common 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 535e5c31af7Sopenharmony_ci * \brief Graphics pipeline specific testing 536e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 537e5c31af7Sopenharmony_cinamespace graphics_tests 538e5c31af7Sopenharmony_ci{ 539e5c31af7Sopenharmony_ciusing namespace test_common; 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 542e5c31af7Sopenharmony_ci * \brief Common graphics pipeline create info initialization 543e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 544e5c31af7Sopenharmony_ciVkGraphicsPipelineCreateInfo getPipelineCreateInfoCommon() 545e5c31af7Sopenharmony_ci{ 546e5c31af7Sopenharmony_ci static constexpr auto VERTEX_BINDING = VkVertexInputBindingDescription{ 547e5c31af7Sopenharmony_ci deUint32{0u}, // binding 548e5c31af7Sopenharmony_ci sizeof(float[4]), // stride 549e5c31af7Sopenharmony_ci VK_VERTEX_INPUT_RATE_VERTEX // inputRate 550e5c31af7Sopenharmony_ci }; 551e5c31af7Sopenharmony_ci 552e5c31af7Sopenharmony_ci static constexpr auto VERTEX_ATTRIBUTE = VkVertexInputAttributeDescription{ 553e5c31af7Sopenharmony_ci deUint32{0u}, // location 554e5c31af7Sopenharmony_ci deUint32{0u}, // binding 555e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SFLOAT, // format 556e5c31af7Sopenharmony_ci deUint32{0u} // offset 557e5c31af7Sopenharmony_ci }; 558e5c31af7Sopenharmony_ci 559e5c31af7Sopenharmony_ci static constexpr auto VERTEX_INPUT_STATE = VkPipelineVertexInputStateCreateInfo{ 560e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // sType 561e5c31af7Sopenharmony_ci DE_NULL, // pNext 562e5c31af7Sopenharmony_ci VkPipelineVertexInputStateCreateFlags{}, // flags 563e5c31af7Sopenharmony_ci deUint32{1u}, // vertexBindingDescriptionCount 564e5c31af7Sopenharmony_ci &VERTEX_BINDING, // pVertexBindingDescriptions 565e5c31af7Sopenharmony_ci deUint32{1u}, // vertexAttributeDescriptionCount 566e5c31af7Sopenharmony_ci &VERTEX_ATTRIBUTE // pVertexAttributeDescriptions 567e5c31af7Sopenharmony_ci }; 568e5c31af7Sopenharmony_ci 569e5c31af7Sopenharmony_ci static constexpr auto IA_STATE = VkPipelineInputAssemblyStateCreateInfo{ 570e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // sType 571e5c31af7Sopenharmony_ci DE_NULL, // pNext 572e5c31af7Sopenharmony_ci VkPipelineInputAssemblyStateCreateFlags{}, // flags 573e5c31af7Sopenharmony_ci VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // topology 574e5c31af7Sopenharmony_ci VK_TRUE // primitiveRestartEnable 575e5c31af7Sopenharmony_ci }; 576e5c31af7Sopenharmony_ci 577e5c31af7Sopenharmony_ci static constexpr auto TESSALATION_STATE = VkPipelineTessellationStateCreateInfo{ 578e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO, // sType 579e5c31af7Sopenharmony_ci DE_NULL, // pNext 580e5c31af7Sopenharmony_ci VkPipelineTessellationStateCreateFlags{}, // flags 581e5c31af7Sopenharmony_ci deUint32{0u} // patchControlPoints 582e5c31af7Sopenharmony_ci }; 583e5c31af7Sopenharmony_ci 584e5c31af7Sopenharmony_ci static constexpr auto VIEWPORT = VkViewport{ 585e5c31af7Sopenharmony_ci 0.f, // x 586e5c31af7Sopenharmony_ci 0.f, // y 587e5c31af7Sopenharmony_ci 1.f, // width 588e5c31af7Sopenharmony_ci 1.f, // height 589e5c31af7Sopenharmony_ci 0.f, // minDepth 590e5c31af7Sopenharmony_ci 1.f // maxDept 591e5c31af7Sopenharmony_ci }; 592e5c31af7Sopenharmony_ci 593e5c31af7Sopenharmony_ci static constexpr auto SCISSOR_RECT = VkRect2D{ 594e5c31af7Sopenharmony_ci {0, 0}, // offset 595e5c31af7Sopenharmony_ci {256, 256} // extent 596e5c31af7Sopenharmony_ci }; 597e5c31af7Sopenharmony_ci 598e5c31af7Sopenharmony_ci static constexpr auto VIEWPORT_STATE = VkPipelineViewportStateCreateInfo{ 599e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // sType 600e5c31af7Sopenharmony_ci DE_NULL, // pNext 601e5c31af7Sopenharmony_ci VkPipelineViewportStateCreateFlags{}, // flags 602e5c31af7Sopenharmony_ci deUint32{1u}, // viewportCount 603e5c31af7Sopenharmony_ci &VIEWPORT, // pViewports 604e5c31af7Sopenharmony_ci deUint32{1u}, // scissorCount 605e5c31af7Sopenharmony_ci &SCISSOR_RECT // pScissors 606e5c31af7Sopenharmony_ci }; 607e5c31af7Sopenharmony_ci 608e5c31af7Sopenharmony_ci static constexpr auto RASTERIZATION_STATE = VkPipelineRasterizationStateCreateInfo{ 609e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // sType 610e5c31af7Sopenharmony_ci DE_NULL, // pNext 611e5c31af7Sopenharmony_ci VkPipelineRasterizationStateCreateFlags{}, // flags 612e5c31af7Sopenharmony_ci VK_FALSE, // depthClampEnable 613e5c31af7Sopenharmony_ci VK_TRUE, // rasterizerDiscardEnable 614e5c31af7Sopenharmony_ci VK_POLYGON_MODE_FILL, // polygonMode 615e5c31af7Sopenharmony_ci VK_CULL_MODE_NONE, // cullMode 616e5c31af7Sopenharmony_ci VK_FRONT_FACE_CLOCKWISE, // frontFace 617e5c31af7Sopenharmony_ci VK_FALSE, // depthBiasEnable 618e5c31af7Sopenharmony_ci 0.f, // depthBiasConstantFactor 619e5c31af7Sopenharmony_ci 0.f, // depthBiasClamp 620e5c31af7Sopenharmony_ci 0.f, // depthBiasSlopeFactor 621e5c31af7Sopenharmony_ci 1.f // lineWidth 622e5c31af7Sopenharmony_ci }; 623e5c31af7Sopenharmony_ci 624e5c31af7Sopenharmony_ci static constexpr auto SAMPLE_MASK = VkSampleMask{}; 625e5c31af7Sopenharmony_ci 626e5c31af7Sopenharmony_ci static constexpr auto MULTISAMPLE_STATE = VkPipelineMultisampleStateCreateInfo{ 627e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // sType 628e5c31af7Sopenharmony_ci DE_NULL, // pNext 629e5c31af7Sopenharmony_ci VkPipelineMultisampleStateCreateFlags{}, // flags 630e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // rasterizationSamples 631e5c31af7Sopenharmony_ci VK_FALSE, // sampleShadingEnable 632e5c31af7Sopenharmony_ci 0.f, // minSampleShading 633e5c31af7Sopenharmony_ci &SAMPLE_MASK, // pSampleMask 634e5c31af7Sopenharmony_ci VK_FALSE, // alphaToCoverageEnable 635e5c31af7Sopenharmony_ci VK_FALSE // alphaToOneEnable 636e5c31af7Sopenharmony_ci }; 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci static constexpr auto STENCIL_OP_STATE = VkStencilOpState{ 639e5c31af7Sopenharmony_ci VK_STENCIL_OP_ZERO, // failOp 640e5c31af7Sopenharmony_ci VK_STENCIL_OP_ZERO, // passOp 641e5c31af7Sopenharmony_ci VK_STENCIL_OP_ZERO, // depthFailOp 642e5c31af7Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // compareOp 643e5c31af7Sopenharmony_ci deUint32{0u}, // compareMask 644e5c31af7Sopenharmony_ci deUint32{0u}, // writeMask 645e5c31af7Sopenharmony_ci deUint32{0u} // reference 646e5c31af7Sopenharmony_ci }; 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_ci static constexpr auto DEPTH_STENCIL_STATE = VkPipelineDepthStencilStateCreateInfo{ 649e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // sType 650e5c31af7Sopenharmony_ci DE_NULL, // pNext 651e5c31af7Sopenharmony_ci VkPipelineDepthStencilStateCreateFlags{}, // flags 652e5c31af7Sopenharmony_ci VK_FALSE, // depthTestEnable 653e5c31af7Sopenharmony_ci VK_FALSE, // depthWriteEnable 654e5c31af7Sopenharmony_ci VK_COMPARE_OP_ALWAYS, // depthCompareOp 655e5c31af7Sopenharmony_ci VK_FALSE, // depthBoundsTestEnable 656e5c31af7Sopenharmony_ci VK_FALSE, // stencilTestEnable 657e5c31af7Sopenharmony_ci STENCIL_OP_STATE, // front 658e5c31af7Sopenharmony_ci STENCIL_OP_STATE, // back 659e5c31af7Sopenharmony_ci 0.f, // minDepthBounds 660e5c31af7Sopenharmony_ci 1.f // maxDepthBounds 661e5c31af7Sopenharmony_ci }; 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci static constexpr auto COLOR_FLAGS_ALL = VkColorComponentFlags{VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | 664e5c31af7Sopenharmony_ci VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT}; 665e5c31af7Sopenharmony_ci 666e5c31af7Sopenharmony_ci static constexpr auto COLOR_BLEND_ATTACH_STATE = VkPipelineColorBlendAttachmentState{ 667e5c31af7Sopenharmony_ci VK_FALSE, // blendEnable 668e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // srcColorBlendFactor 669e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // dstColorBlendFactor 670e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // colorBlendOp 671e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ONE, // srcAlphaBlendFactor 672e5c31af7Sopenharmony_ci VK_BLEND_FACTOR_ZERO, // dstAlphaBlendFactor 673e5c31af7Sopenharmony_ci VK_BLEND_OP_ADD, // alphaBlendOp 674e5c31af7Sopenharmony_ci COLOR_FLAGS_ALL // colorWriteMask 675e5c31af7Sopenharmony_ci }; 676e5c31af7Sopenharmony_ci 677e5c31af7Sopenharmony_ci static constexpr auto COLOR_BLEND_STATE = VkPipelineColorBlendStateCreateInfo{ 678e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // sType 679e5c31af7Sopenharmony_ci DE_NULL, // pNext 680e5c31af7Sopenharmony_ci VkPipelineColorBlendStateCreateFlags{}, // flags 681e5c31af7Sopenharmony_ci VK_FALSE, // logicOpEnable 682e5c31af7Sopenharmony_ci VK_LOGIC_OP_SET, // logicOp 683e5c31af7Sopenharmony_ci deUint32{1u}, // attachmentCount 684e5c31af7Sopenharmony_ci &COLOR_BLEND_ATTACH_STATE, // pAttachments 685e5c31af7Sopenharmony_ci {0.f, 0.f, 0.f, 0.f} // blendConstants[4] 686e5c31af7Sopenharmony_ci }; 687e5c31af7Sopenharmony_ci 688e5c31af7Sopenharmony_ci static constexpr auto DYNAMIC_STATE = VkPipelineDynamicStateCreateInfo{ 689e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // sType; 690e5c31af7Sopenharmony_ci DE_NULL, // pNext; 691e5c31af7Sopenharmony_ci VkPipelineDynamicStateCreateFlags{}, // flags; 692e5c31af7Sopenharmony_ci deUint32{0u}, // dynamicStateCount; 693e5c31af7Sopenharmony_ci DE_NULL // pDynamicStates; 694e5c31af7Sopenharmony_ci }; 695e5c31af7Sopenharmony_ci 696e5c31af7Sopenharmony_ci return VkGraphicsPipelineCreateInfo{ 697e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // sType 698e5c31af7Sopenharmony_ci DE_NULL, // pNext 699e5c31af7Sopenharmony_ci VkPipelineCreateFlags{}, // flags 700e5c31af7Sopenharmony_ci deUint32{0u}, // stageCount 701e5c31af7Sopenharmony_ci DE_NULL, // pStages 702e5c31af7Sopenharmony_ci &VERTEX_INPUT_STATE, // pVertexInputState 703e5c31af7Sopenharmony_ci &IA_STATE, // pInputAssemblyState 704e5c31af7Sopenharmony_ci &TESSALATION_STATE, // pTessellationState 705e5c31af7Sopenharmony_ci &VIEWPORT_STATE, // pViewportState 706e5c31af7Sopenharmony_ci &RASTERIZATION_STATE, // pRasterizationState 707e5c31af7Sopenharmony_ci &MULTISAMPLE_STATE, // pMultisampleState 708e5c31af7Sopenharmony_ci &DEPTH_STENCIL_STATE, // pDepthStencilState 709e5c31af7Sopenharmony_ci &COLOR_BLEND_STATE, // pColorBlendState 710e5c31af7Sopenharmony_ci &DYNAMIC_STATE, // pDynamicState 711e5c31af7Sopenharmony_ci VK_NULL_HANDLE, // layout 712e5c31af7Sopenharmony_ci VK_NULL_HANDLE, // renderPass 713e5c31af7Sopenharmony_ci deUint32{0u}, // subpass 714e5c31af7Sopenharmony_ci VK_NULL_HANDLE, // basePipelineHandle 715e5c31af7Sopenharmony_ci deInt32{-1} // basePipelineIndex 716e5c31af7Sopenharmony_ci }; 717e5c31af7Sopenharmony_ci} 718e5c31af7Sopenharmony_ci 719e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 720e5c31af7Sopenharmony_ci * \brief create VkGraphicsPipelineCreateInfo structs from test iteration 721e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 722e5c31af7Sopenharmony_civector<VkGraphicsPipelineCreateInfo> createPipelineCreateInfos(const TestParams::Iteration& iteration, 723e5c31af7Sopenharmony_ci const VkGraphicsPipelineCreateInfo& base, 724e5c31af7Sopenharmony_ci VkPipeline basePipeline, 725e5c31af7Sopenharmony_ci const TestParams& testParameter) 726e5c31af7Sopenharmony_ci{ 727e5c31af7Sopenharmony_ci auto output = vector<VkGraphicsPipelineCreateInfo>{}; 728e5c31af7Sopenharmony_ci output.reserve(iteration.variants.size()); 729e5c31af7Sopenharmony_ci 730e5c31af7Sopenharmony_ci deInt32 count = 0; 731e5c31af7Sopenharmony_ci deInt32 basePipelineIndex = -1; 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ci for (VkPipelineCreateFlags flags : iteration.variants) 734e5c31af7Sopenharmony_ci { 735e5c31af7Sopenharmony_ci const auto curIndex = count++; 736e5c31af7Sopenharmony_ci auto createInfo = base; 737e5c31af7Sopenharmony_ci 738e5c31af7Sopenharmony_ci if (testParameter.cacheType == TestParams::DERIVATIVE_INDEX) 739e5c31af7Sopenharmony_ci { 740e5c31af7Sopenharmony_ci if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT) 741e5c31af7Sopenharmony_ci { 742e5c31af7Sopenharmony_ci if (basePipelineIndex != -1) 743e5c31af7Sopenharmony_ci { 744e5c31af7Sopenharmony_ci flags |= VK_PIPELINE_CREATE_DERIVATIVE_BIT; 745e5c31af7Sopenharmony_ci } 746e5c31af7Sopenharmony_ci } 747e5c31af7Sopenharmony_ci else 748e5c31af7Sopenharmony_ci { 749e5c31af7Sopenharmony_ci flags |= VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT; 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_ci if (basePipelineIndex == -1) 752e5c31af7Sopenharmony_ci { 753e5c31af7Sopenharmony_ci basePipelineIndex = curIndex; 754e5c31af7Sopenharmony_ci } 755e5c31af7Sopenharmony_ci } 756e5c31af7Sopenharmony_ci } 757e5c31af7Sopenharmony_ci 758e5c31af7Sopenharmony_ci createInfo.flags = flags; 759e5c31af7Sopenharmony_ci createInfo.basePipelineHandle = basePipeline; 760e5c31af7Sopenharmony_ci createInfo.basePipelineIndex = basePipelineIndex; 761e5c31af7Sopenharmony_ci 762e5c31af7Sopenharmony_ci output.push_back(createInfo); 763e5c31af7Sopenharmony_ci } 764e5c31af7Sopenharmony_ci 765e5c31af7Sopenharmony_ci return output; 766e5c31af7Sopenharmony_ci} 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 769e5c31af7Sopenharmony_ci * \brief create VkRenderPass object for Graphics test 770e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 771e5c31af7Sopenharmony_ciMove<VkRenderPass> createRenderPass(const DeviceInterface& vk, VkDevice device, const TestParams&) 772e5c31af7Sopenharmony_ci{ 773e5c31af7Sopenharmony_ci static constexpr auto COLOR_FORMAT = VK_FORMAT_R8G8B8A8_UNORM; 774e5c31af7Sopenharmony_ci 775e5c31af7Sopenharmony_ci static constexpr auto COLOR_ATTACHMENT_REF = VkAttachmentReference{ 776e5c31af7Sopenharmony_ci deUint32{0u}, // attachment 777e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout 778e5c31af7Sopenharmony_ci }; 779e5c31af7Sopenharmony_ci 780e5c31af7Sopenharmony_ci static constexpr auto SUBPASS = VkSubpassDescription{ 781e5c31af7Sopenharmony_ci VkSubpassDescriptionFlags{}, // flags 782e5c31af7Sopenharmony_ci VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint 783e5c31af7Sopenharmony_ci deUint32{0u}, // inputAttachmentCount 784e5c31af7Sopenharmony_ci DE_NULL, // pInputAttachments 785e5c31af7Sopenharmony_ci deUint32{1u}, // colorAttachmentCount 786e5c31af7Sopenharmony_ci &COLOR_ATTACHMENT_REF, // pColorAttachments 787e5c31af7Sopenharmony_ci DE_NULL, // pResolveAttachments 788e5c31af7Sopenharmony_ci DE_NULL, // pDepthStencilAttachment 789e5c31af7Sopenharmony_ci deUint32{0u}, // preserveAttachmentCount 790e5c31af7Sopenharmony_ci DE_NULL // pPreserveAttachments 791e5c31af7Sopenharmony_ci }; 792e5c31af7Sopenharmony_ci 793e5c31af7Sopenharmony_ci static constexpr auto COLOR_ATTACHMENT = VkAttachmentDescription{ 794e5c31af7Sopenharmony_ci VkAttachmentDescriptionFlags{}, // flags 795e5c31af7Sopenharmony_ci COLOR_FORMAT, // format 796e5c31af7Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT, // samples 797e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp 798e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_STORE, // storeOp 799e5c31af7Sopenharmony_ci VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp 800e5c31af7Sopenharmony_ci VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp 801e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout 802e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_PRESENT_SRC_KHR // finalLayout 803e5c31af7Sopenharmony_ci }; 804e5c31af7Sopenharmony_ci 805e5c31af7Sopenharmony_ci static constexpr auto RENDER_PASS_CREATE_INFO = VkRenderPassCreateInfo{ 806e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // sType 807e5c31af7Sopenharmony_ci DE_NULL, // pNext 808e5c31af7Sopenharmony_ci VkRenderPassCreateFlags{}, // flags 809e5c31af7Sopenharmony_ci deUint32{1u}, // attachmentCount 810e5c31af7Sopenharmony_ci &COLOR_ATTACHMENT, // pAttachments 811e5c31af7Sopenharmony_ci deUint32{1u}, // subpassCount 812e5c31af7Sopenharmony_ci &SUBPASS, // pSubpasses 813e5c31af7Sopenharmony_ci deUint32{0u}, // dependencyCount 814e5c31af7Sopenharmony_ci DE_NULL // pDependencies 815e5c31af7Sopenharmony_ci }; 816e5c31af7Sopenharmony_ci 817e5c31af7Sopenharmony_ci return createRenderPass(vk, device, &RENDER_PASS_CREATE_INFO); 818e5c31af7Sopenharmony_ci} 819e5c31af7Sopenharmony_ci 820e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 821e5c31af7Sopenharmony_ci * \brief Initialize shader programs 822e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 823e5c31af7Sopenharmony_civoid initPrograms(SourceCollections& dst, const TestParams&) 824e5c31af7Sopenharmony_ci{ 825e5c31af7Sopenharmony_ci using ::glu::FragmentSource; 826e5c31af7Sopenharmony_ci using ::glu::VertexSource; 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci // Vertex Shader 829e5c31af7Sopenharmony_ci static const StringTemplate VS_TEXT = {"#version 310 es\n" 830e5c31af7Sopenharmony_ci "layout(location = 0) in vec4 position;\n" 831e5c31af7Sopenharmony_ci "layout(location = 0) out vec3 vertColor;\n" 832e5c31af7Sopenharmony_ci "void main (void)\n" 833e5c31af7Sopenharmony_ci "{\n" 834e5c31af7Sopenharmony_ci " gl_Position = position;\n" 835e5c31af7Sopenharmony_ci " vertColor = vec3(${0}, ${1}, ${2});\n" 836e5c31af7Sopenharmony_ci "}\n"}; 837e5c31af7Sopenharmony_ci 838e5c31af7Sopenharmony_ci // Fragment Shader 839e5c31af7Sopenharmony_ci static const StringTemplate FS_TEXT = {"#version 310 es\n" 840e5c31af7Sopenharmony_ci "precision highp float;\n" 841e5c31af7Sopenharmony_ci "layout(location = 0) in vec3 vertColor;\n" 842e5c31af7Sopenharmony_ci "layout(location = 0) out vec4 outColor;\n" 843e5c31af7Sopenharmony_ci "void main (void)\n" 844e5c31af7Sopenharmony_ci "{\n" 845e5c31af7Sopenharmony_ci " const vec3 fragColor = vec3(${0}, ${1}, ${2});\n" 846e5c31af7Sopenharmony_ci " outColor = vec4((fragColor + vertColor) * 0.5, 1.0);\n" 847e5c31af7Sopenharmony_ci "}\n"}; 848e5c31af7Sopenharmony_ci 849e5c31af7Sopenharmony_ci dst.glslSources.add("vertex") << VertexSource{VS_TEXT.format(randomFloat(), randomFloat(), randomFloat())}; 850e5c31af7Sopenharmony_ci dst.glslSources.add("fragment") << FragmentSource{FS_TEXT.format(randomFloat(), randomFloat(), randomFloat())}; 851e5c31af7Sopenharmony_ci} 852e5c31af7Sopenharmony_ci 853e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 854e5c31af7Sopenharmony_ci * \brief return both result and elapsed time from pipeline creation 855e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 856e5c31af7Sopenharmony_citemplate <typename create_infos_t, typename pipelines_t> 857e5c31af7Sopenharmony_ciTimedResult timePipelineCreation(const DeviceInterface& vk, 858e5c31af7Sopenharmony_ci const VkDevice device, 859e5c31af7Sopenharmony_ci const VkPipelineCache cache, 860e5c31af7Sopenharmony_ci const create_infos_t& createInfos, 861e5c31af7Sopenharmony_ci pipelines_t& pipelines, 862e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator = DE_NULL) 863e5c31af7Sopenharmony_ci{ 864e5c31af7Sopenharmony_ci DE_ASSERT(createInfos.size() <= pipelines.size()); 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci const auto timeStart = high_resolution_clock::now(); 867e5c31af7Sopenharmony_ci const auto result = vk.createGraphicsPipelines( 868e5c31af7Sopenharmony_ci device, cache, static_cast<deUint32>(createInfos.size()), createInfos.data(), pAllocator, pipelines.data()); 869e5c31af7Sopenharmony_ci const auto elapsed = high_resolution_clock::now() - timeStart; 870e5c31af7Sopenharmony_ci return {result, elapsed}; 871e5c31af7Sopenharmony_ci} 872e5c31af7Sopenharmony_ci 873e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 874e5c31af7Sopenharmony_ci * \brief Test instance function 875e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 876e5c31af7Sopenharmony_ciTestStatus testInstance(Context& context, const TestParams& testParameter) 877e5c31af7Sopenharmony_ci{ 878e5c31af7Sopenharmony_ci const auto& vk = context.getDeviceInterface(); 879e5c31af7Sopenharmony_ci const auto device = context.getDevice(); 880e5c31af7Sopenharmony_ci const auto pipelineCache = createPipelineCache(vk, device, testParameter); 881e5c31af7Sopenharmony_ci const auto layout = createPipelineLayout(vk, device, testParameter); 882e5c31af7Sopenharmony_ci const auto renderPass = createRenderPass(vk, device, testParameter); 883e5c31af7Sopenharmony_ci // No fragment due to rasterizationDiscardEnabled 884e5c31af7Sopenharmony_ci const auto modules = createShaderModules(vk, device, context.getBinaryCollection(), std::vector<const char*>{"vertex"}); 885e5c31af7Sopenharmony_ci const auto shaderStages = createShaderStages(modules, std::vector<VkShaderStageFlagBits>{VK_SHADER_STAGE_VERTEX_BIT}); 886e5c31af7Sopenharmony_ci 887e5c31af7Sopenharmony_ci // Placeholder for base pipeline if using cacheType == DERIVATIVE_HANDLE 888e5c31af7Sopenharmony_ci auto basePipeline = UniquePipeline{}; 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_ci auto baseCreateInfo = getPipelineCreateInfoCommon(); 891e5c31af7Sopenharmony_ci baseCreateInfo.layout = layout.get(); 892e5c31af7Sopenharmony_ci baseCreateInfo.renderPass = renderPass.get(); 893e5c31af7Sopenharmony_ci baseCreateInfo.stageCount = static_cast<deUint32>(shaderStages.size()); 894e5c31af7Sopenharmony_ci baseCreateInfo.pStages = shaderStages.data(); 895e5c31af7Sopenharmony_ci 896e5c31af7Sopenharmony_ci auto results = vector<VkResult>{}; 897e5c31af7Sopenharmony_ci results.reserve(testParameter.iterations.size()); 898e5c31af7Sopenharmony_ci 899e5c31af7Sopenharmony_ci for (const auto& i : testParameter.iterations) 900e5c31af7Sopenharmony_ci { 901e5c31af7Sopenharmony_ci auto createInfos = createPipelineCreateInfos(i, baseCreateInfo, basePipeline.get(), testParameter); 902e5c31af7Sopenharmony_ci auto created = vector<VkPipeline>{}; 903e5c31af7Sopenharmony_ci created.resize(createInfos.size()); 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 906e5c31af7Sopenharmony_ci std::vector<VkPipelineCreateFlags2CreateInfoKHR> flags2CreateInfo(created.size(), { VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO_KHR, 0, 0 }); 907e5c31af7Sopenharmony_ci if (testParameter.useMaintenance5) 908e5c31af7Sopenharmony_ci { 909e5c31af7Sopenharmony_ci for (deUint32 ci = 0; ci < createInfos.size(); ++ci) 910e5c31af7Sopenharmony_ci { 911e5c31af7Sopenharmony_ci flags2CreateInfo[ci].flags = translateCreateFlag(createInfos[ci].flags); 912e5c31af7Sopenharmony_ci flags2CreateInfo[ci].pNext = createInfos[ci].pNext; 913e5c31af7Sopenharmony_ci createInfos[ci].flags = 0; 914e5c31af7Sopenharmony_ci createInfos[ci].pNext = &flags2CreateInfo[ci]; 915e5c31af7Sopenharmony_ci } 916e5c31af7Sopenharmony_ci } 917e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 918e5c31af7Sopenharmony_ci 919e5c31af7Sopenharmony_ci const auto timedResult = timePipelineCreation(vk, device, pipelineCache.get(), createInfos, created); 920e5c31af7Sopenharmony_ci auto pipelines = wrapHandles(vk, device, created); 921e5c31af7Sopenharmony_ci 922e5c31af7Sopenharmony_ci const auto status = validateResults(timedResult.result, pipelines, timedResult.elapsed, i.validators); 923e5c31af7Sopenharmony_ci if (status.getCode() != QP_TEST_RESULT_PASS) 924e5c31af7Sopenharmony_ci { 925e5c31af7Sopenharmony_ci return status; 926e5c31af7Sopenharmony_ci } 927e5c31af7Sopenharmony_ci 928e5c31af7Sopenharmony_ci if ((testParameter.cacheType == TestParams::DERIVATIVE_HANDLE) && (*basePipeline == VK_NULL_HANDLE)) 929e5c31af7Sopenharmony_ci { 930e5c31af7Sopenharmony_ci for (auto& pipeline : pipelines) 931e5c31af7Sopenharmony_ci { 932e5c31af7Sopenharmony_ci if (*pipeline != VK_NULL_HANDLE) 933e5c31af7Sopenharmony_ci { 934e5c31af7Sopenharmony_ci basePipeline = pipeline; 935e5c31af7Sopenharmony_ci break; 936e5c31af7Sopenharmony_ci } 937e5c31af7Sopenharmony_ci } 938e5c31af7Sopenharmony_ci } 939e5c31af7Sopenharmony_ci 940e5c31af7Sopenharmony_ci results.push_back(timedResult.result); 941e5c31af7Sopenharmony_ci } 942e5c31af7Sopenharmony_ci 943e5c31af7Sopenharmony_ci static const StringTemplate PASS_MSG = {"Test Passed. ${0}"}; 944e5c31af7Sopenharmony_ci return TestStatus::pass(PASS_MSG.format(getResultsString(results))); 945e5c31af7Sopenharmony_ci} 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_ci} // namespace graphics_tests 948e5c31af7Sopenharmony_ci 949e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 950e5c31af7Sopenharmony_ci * \brief Compute pipeline specific testing 951e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 952e5c31af7Sopenharmony_cinamespace compute_tests 953e5c31af7Sopenharmony_ci{ 954e5c31af7Sopenharmony_ciusing namespace test_common; 955e5c31af7Sopenharmony_ci 956e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 957e5c31af7Sopenharmony_ci * \brief create VkComputePipelineCreateInfo structs from test iteration 958e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 959e5c31af7Sopenharmony_civector<VkComputePipelineCreateInfo> createPipelineCreateInfos(const TestParams::Iteration& iteration, 960e5c31af7Sopenharmony_ci const VkComputePipelineCreateInfo& base, 961e5c31af7Sopenharmony_ci VkPipeline basePipeline, 962e5c31af7Sopenharmony_ci const TestParams& testParameter) 963e5c31af7Sopenharmony_ci{ 964e5c31af7Sopenharmony_ci auto output = vector<VkComputePipelineCreateInfo>{}; 965e5c31af7Sopenharmony_ci output.reserve(iteration.variants.size()); 966e5c31af7Sopenharmony_ci 967e5c31af7Sopenharmony_ci deInt32 count = 0; 968e5c31af7Sopenharmony_ci deInt32 basePipelineIndex = -1; 969e5c31af7Sopenharmony_ci 970e5c31af7Sopenharmony_ci for (VkPipelineCreateFlags flags : iteration.variants) 971e5c31af7Sopenharmony_ci { 972e5c31af7Sopenharmony_ci const auto curIndex = count++; 973e5c31af7Sopenharmony_ci auto createInfo = base; 974e5c31af7Sopenharmony_ci 975e5c31af7Sopenharmony_ci if (testParameter.cacheType == TestParams::DERIVATIVE_INDEX) 976e5c31af7Sopenharmony_ci { 977e5c31af7Sopenharmony_ci if (flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_EXT) 978e5c31af7Sopenharmony_ci { 979e5c31af7Sopenharmony_ci if (basePipelineIndex != -1) 980e5c31af7Sopenharmony_ci { 981e5c31af7Sopenharmony_ci flags |= VK_PIPELINE_CREATE_DERIVATIVE_BIT; 982e5c31af7Sopenharmony_ci } 983e5c31af7Sopenharmony_ci } 984e5c31af7Sopenharmony_ci else 985e5c31af7Sopenharmony_ci { 986e5c31af7Sopenharmony_ci flags |= VK_PIPELINE_CREATE_ALLOW_DERIVATIVES_BIT; 987e5c31af7Sopenharmony_ci 988e5c31af7Sopenharmony_ci if (basePipelineIndex == -1) 989e5c31af7Sopenharmony_ci { 990e5c31af7Sopenharmony_ci basePipelineIndex = curIndex; 991e5c31af7Sopenharmony_ci } 992e5c31af7Sopenharmony_ci } 993e5c31af7Sopenharmony_ci } 994e5c31af7Sopenharmony_ci 995e5c31af7Sopenharmony_ci createInfo.flags = flags; 996e5c31af7Sopenharmony_ci createInfo.basePipelineHandle = basePipeline; 997e5c31af7Sopenharmony_ci createInfo.basePipelineIndex = basePipelineIndex; 998e5c31af7Sopenharmony_ci 999e5c31af7Sopenharmony_ci output.push_back(createInfo); 1000e5c31af7Sopenharmony_ci } 1001e5c31af7Sopenharmony_ci 1002e5c31af7Sopenharmony_ci return output; 1003e5c31af7Sopenharmony_ci} 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1006e5c31af7Sopenharmony_ci * \brief create compute descriptor set layout 1007e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1008e5c31af7Sopenharmony_ciMove<VkDescriptorSetLayout> createDescriptorSetLayout(const DeviceInterface& vk, VkDevice device, const TestParams&) 1009e5c31af7Sopenharmony_ci{ 1010e5c31af7Sopenharmony_ci static constexpr auto DESCRIPTOR_SET_LAYOUT_BINDING = VkDescriptorSetLayoutBinding{ 1011e5c31af7Sopenharmony_ci deUint32{0u}, // binding 1012e5c31af7Sopenharmony_ci VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType 1013e5c31af7Sopenharmony_ci deUint32{1u}, // descriptorCount 1014e5c31af7Sopenharmony_ci VK_SHADER_STAGE_COMPUTE_BIT, // stageFlags 1015e5c31af7Sopenharmony_ci DE_NULL // pImmutableSamplers 1016e5c31af7Sopenharmony_ci }; 1017e5c31af7Sopenharmony_ci 1018e5c31af7Sopenharmony_ci static constexpr auto DESCRIPTOR_SET_LAYOUT_CREATE_INFO = VkDescriptorSetLayoutCreateInfo{ 1019e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType 1020e5c31af7Sopenharmony_ci DE_NULL, // pNext 1021e5c31af7Sopenharmony_ci VkDescriptorSetLayoutCreateFlags{}, // flags 1022e5c31af7Sopenharmony_ci deUint32{1u}, // bindingCount 1023e5c31af7Sopenharmony_ci &DESCRIPTOR_SET_LAYOUT_BINDING // pBindings 1024e5c31af7Sopenharmony_ci }; 1025e5c31af7Sopenharmony_ci 1026e5c31af7Sopenharmony_ci return createDescriptorSetLayout(vk, device, &DESCRIPTOR_SET_LAYOUT_CREATE_INFO); 1027e5c31af7Sopenharmony_ci} 1028e5c31af7Sopenharmony_ci 1029e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1030e5c31af7Sopenharmony_ci * \brief Initialize shader programs 1031e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1032e5c31af7Sopenharmony_civoid initPrograms(SourceCollections& dst, const TestParams&) 1033e5c31af7Sopenharmony_ci{ 1034e5c31af7Sopenharmony_ci using ::glu::ComputeSource; 1035e5c31af7Sopenharmony_ci 1036e5c31af7Sopenharmony_ci static const StringTemplate CS_TEXT = {"#version 450\n" 1037e5c31af7Sopenharmony_ci "precision highp float;\n" 1038e5c31af7Sopenharmony_ci "layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;\n" 1039e5c31af7Sopenharmony_ci "layout (std140, binding = 0) buffer buf { vec3 data[]; };\n" 1040e5c31af7Sopenharmony_ci "void main (void)\n" 1041e5c31af7Sopenharmony_ci "{\n" 1042e5c31af7Sopenharmony_ci " data[gl_GlobalInvocationID.x] = vec3(${0}, ${1}, ${2});\n" 1043e5c31af7Sopenharmony_ci "}\n"}; 1044e5c31af7Sopenharmony_ci 1045e5c31af7Sopenharmony_ci dst.glslSources.add("compute") 1046e5c31af7Sopenharmony_ci << ComputeSource{CS_TEXT.format(randomFloat(), randomFloat(), randomFloat())}; 1047e5c31af7Sopenharmony_ci} 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1050e5c31af7Sopenharmony_ci * \brief return both result and elapsed time from pipeline creation 1051e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1052e5c31af7Sopenharmony_citemplate <typename create_infos_t, typename pipelines_t> 1053e5c31af7Sopenharmony_ciTimedResult timePipelineCreation(const DeviceInterface& vk, 1054e5c31af7Sopenharmony_ci const VkDevice device, 1055e5c31af7Sopenharmony_ci const VkPipelineCache cache, 1056e5c31af7Sopenharmony_ci const create_infos_t& createInfos, 1057e5c31af7Sopenharmony_ci pipelines_t& pipelines, 1058e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator = DE_NULL) 1059e5c31af7Sopenharmony_ci{ 1060e5c31af7Sopenharmony_ci DE_ASSERT(createInfos.size() <= pipelines.size()); 1061e5c31af7Sopenharmony_ci 1062e5c31af7Sopenharmony_ci const auto timeStart = high_resolution_clock::now(); 1063e5c31af7Sopenharmony_ci const auto result = vk.createComputePipelines( 1064e5c31af7Sopenharmony_ci device, cache, static_cast<deUint32>(createInfos.size()), createInfos.data(), pAllocator, pipelines.data()); 1065e5c31af7Sopenharmony_ci const auto elapsed = high_resolution_clock::now() - timeStart; 1066e5c31af7Sopenharmony_ci return {result, elapsed}; 1067e5c31af7Sopenharmony_ci} 1068e5c31af7Sopenharmony_ci 1069e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1070e5c31af7Sopenharmony_ci * \brief Test instance function 1071e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1072e5c31af7Sopenharmony_ciTestStatus testInstance(Context& context, const TestParams& testParameter) 1073e5c31af7Sopenharmony_ci{ 1074e5c31af7Sopenharmony_ci const auto& vk = context.getDeviceInterface(); 1075e5c31af7Sopenharmony_ci const auto device = context.getDevice(); 1076e5c31af7Sopenharmony_ci const auto pipelineCache = createPipelineCache(vk, device, testParameter); 1077e5c31af7Sopenharmony_ci const auto descriptorSetLayout = createDescriptorSetLayout(vk, device, testParameter); 1078e5c31af7Sopenharmony_ci const auto pipelineLayout = createPipelineLayout(vk, device, {descriptorSetLayout.get()}, testParameter); 1079e5c31af7Sopenharmony_ci const auto modules = createShaderModules(vk, device, context.getBinaryCollection(), {"compute"}); 1080e5c31af7Sopenharmony_ci const auto shaderStages = createShaderStages(modules, {VK_SHADER_STAGE_COMPUTE_BIT}); 1081e5c31af7Sopenharmony_ci 1082e5c31af7Sopenharmony_ci // Placeholder for base pipeline if using cacheType == DERIVATIVE_HANDLE 1083e5c31af7Sopenharmony_ci auto basePipeline = UniquePipeline{}; 1084e5c31af7Sopenharmony_ci 1085e5c31af7Sopenharmony_ci const auto baseCreateInfo = VkComputePipelineCreateInfo{ 1086e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // sType 1087e5c31af7Sopenharmony_ci DE_NULL, // pNext 1088e5c31af7Sopenharmony_ci VkPipelineCreateFlags{}, // flags 1089e5c31af7Sopenharmony_ci shaderStages[0], // stage 1090e5c31af7Sopenharmony_ci pipelineLayout.get(), // layout 1091e5c31af7Sopenharmony_ci VK_NULL_HANDLE, // basePipelineHandle 1092e5c31af7Sopenharmony_ci deInt32{-1} // basePipelineIndex 1093e5c31af7Sopenharmony_ci }; 1094e5c31af7Sopenharmony_ci 1095e5c31af7Sopenharmony_ci auto results = vector<VkResult>{}; 1096e5c31af7Sopenharmony_ci results.reserve(testParameter.iterations.size()); 1097e5c31af7Sopenharmony_ci 1098e5c31af7Sopenharmony_ci for (const auto& i : testParameter.iterations) 1099e5c31af7Sopenharmony_ci { 1100e5c31af7Sopenharmony_ci const auto createInfos = createPipelineCreateInfos(i, baseCreateInfo, basePipeline.get(), testParameter); 1101e5c31af7Sopenharmony_ci auto created = vector<VkPipeline>{}; 1102e5c31af7Sopenharmony_ci created.resize(createInfos.size()); 1103e5c31af7Sopenharmony_ci 1104e5c31af7Sopenharmony_ci const auto timedResult = timePipelineCreation(vk, device, pipelineCache.get(), createInfos, created); 1105e5c31af7Sopenharmony_ci auto pipelines = wrapHandles(vk, device, created); 1106e5c31af7Sopenharmony_ci 1107e5c31af7Sopenharmony_ci const auto status = validateResults(timedResult.result, pipelines, timedResult.elapsed, i.validators); 1108e5c31af7Sopenharmony_ci if (status.getCode() != QP_TEST_RESULT_PASS) 1109e5c31af7Sopenharmony_ci { 1110e5c31af7Sopenharmony_ci return status; 1111e5c31af7Sopenharmony_ci } 1112e5c31af7Sopenharmony_ci 1113e5c31af7Sopenharmony_ci if ((testParameter.cacheType == TestParams::DERIVATIVE_HANDLE) && (*basePipeline == VK_NULL_HANDLE)) 1114e5c31af7Sopenharmony_ci { 1115e5c31af7Sopenharmony_ci for (auto& pipeline : pipelines) 1116e5c31af7Sopenharmony_ci { 1117e5c31af7Sopenharmony_ci if (*pipeline != VK_NULL_HANDLE) 1118e5c31af7Sopenharmony_ci { 1119e5c31af7Sopenharmony_ci basePipeline = pipeline; 1120e5c31af7Sopenharmony_ci break; 1121e5c31af7Sopenharmony_ci } 1122e5c31af7Sopenharmony_ci } 1123e5c31af7Sopenharmony_ci } 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_ci results.push_back(timedResult.result); 1126e5c31af7Sopenharmony_ci } 1127e5c31af7Sopenharmony_ci 1128e5c31af7Sopenharmony_ci static const StringTemplate PASS_MSG = {"Test Passed. ${0}"}; 1129e5c31af7Sopenharmony_ci return TestStatus::pass(PASS_MSG.format(getResultsString(results))); 1130e5c31af7Sopenharmony_ci} 1131e5c31af7Sopenharmony_ci 1132e5c31af7Sopenharmony_ci} // namespace compute_tests 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_ciusing namespace test_common; 1135e5c31af7Sopenharmony_ci 1136e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1137e5c31af7Sopenharmony_ci * \brief Duplicate single pipeline recreation with explicit caching 1138e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1139e5c31af7Sopenharmony_cistatic constexpr TestParams DUPLICATE_SINGLE_RECREATE_EXPLICIT_CACHING = 1140e5c31af7Sopenharmony_ci{ 1141e5c31af7Sopenharmony_ci "duplicate_single_recreate_explicit_caching", 1142e5c31af7Sopenharmony_ci TestParams::EXPLICIT_CACHE, 1143e5c31af7Sopenharmony_ci TestParams::IterationArray 1144e5c31af7Sopenharmony_ci { 1145e5c31af7Sopenharmony_ci TestParams::Iteration{ 1146e5c31af7Sopenharmony_ci // Iteration [0]: Force compilation of pipeline 1147e5c31af7Sopenharmony_ci TestParams::Iteration::SINGLE_NORMAL, 1148e5c31af7Sopenharmony_ci ValidatorArray{ 1149e5c31af7Sopenharmony_ci // Fail if result is not VK_SUCCESS 1150e5c31af7Sopenharmony_ci checkResult<VK_SUCCESS>, 1151e5c31af7Sopenharmony_ci // Fail if pipeline is not valid 1152e5c31af7Sopenharmony_ci checkPipelineMustBeValid<0> 1153e5c31af7Sopenharmony_ci } 1154e5c31af7Sopenharmony_ci }, 1155e5c31af7Sopenharmony_ci TestParams::Iteration{ 1156e5c31af7Sopenharmony_ci // Iteration [1]: Request compilation of same pipeline without compile 1157e5c31af7Sopenharmony_ci TestParams::Iteration::SINGLE_NOCOMPILE, 1158e5c31af7Sopenharmony_ci ValidatorArray{ 1159e5c31af7Sopenharmony_ci // Warn if result is not VK_SUCCESS 1160e5c31af7Sopenharmony_ci checkResult<VK_SUCCESS, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1161e5c31af7Sopenharmony_ci // Warn if pipeline is not valid 1162e5c31af7Sopenharmony_ci checkPipelineMustBeValid<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1163e5c31af7Sopenharmony_ci // Warn if pipeline took too long 1164e5c31af7Sopenharmony_ci checkElapsedTime<ELAPSED_TIME_FAST, QP_TEST_RESULT_QUALITY_WARNING> 1165e5c31af7Sopenharmony_ci } 1166e5c31af7Sopenharmony_ci } 1167e5c31af7Sopenharmony_ci }, 1168e5c31af7Sopenharmony_ci false 1169e5c31af7Sopenharmony_ci}; 1170e5c31af7Sopenharmony_ci 1171e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1172e5c31af7Sopenharmony_ci * \brief Duplicate single pipeline recreation with no explicit cache 1173e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1174e5c31af7Sopenharmony_cistatic constexpr TestParams DUPLICATE_SINGLE_RECREATE_NO_CACHING = 1175e5c31af7Sopenharmony_ci{ 1176e5c31af7Sopenharmony_ci "duplicate_single_recreate_no_caching", 1177e5c31af7Sopenharmony_ci TestParams::NO_CACHE, 1178e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1179e5c31af7Sopenharmony_ci TestParams::Iteration{ 1180e5c31af7Sopenharmony_ci // Iteration [0]: Force compilation of pipeline 1181e5c31af7Sopenharmony_ci TestParams::Iteration::SINGLE_NORMAL, 1182e5c31af7Sopenharmony_ci ValidatorArray{ 1183e5c31af7Sopenharmony_ci // Fail if result is not VK_SUCCESS 1184e5c31af7Sopenharmony_ci checkResult<VK_SUCCESS>, 1185e5c31af7Sopenharmony_ci // Fail if pipeline is not valid 1186e5c31af7Sopenharmony_ci checkPipelineMustBeValid<0> 1187e5c31af7Sopenharmony_ci } 1188e5c31af7Sopenharmony_ci }, 1189e5c31af7Sopenharmony_ci TestParams::Iteration{ 1190e5c31af7Sopenharmony_ci // Iteration [1]: Request compilation of same pipeline without compile 1191e5c31af7Sopenharmony_ci TestParams::Iteration::SINGLE_NOCOMPILE, 1192e5c31af7Sopenharmony_ci ValidatorArray{ 1193e5c31af7Sopenharmony_ci // Warn if pipeline took too long 1194e5c31af7Sopenharmony_ci checkElapsedTime<ELAPSED_TIME_FAST, QP_TEST_RESULT_QUALITY_WARNING> 1195e5c31af7Sopenharmony_ci } 1196e5c31af7Sopenharmony_ci } 1197e5c31af7Sopenharmony_ci }, 1198e5c31af7Sopenharmony_ci false 1199e5c31af7Sopenharmony_ci}; 1200e5c31af7Sopenharmony_ci 1201e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1202e5c31af7Sopenharmony_ci * \brief Duplicate single pipeline recreation using derivative pipelines 1203e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1204e5c31af7Sopenharmony_cistatic constexpr TestParams DUPLICATE_SINGLE_RECREATE_DERIVATIVE = 1205e5c31af7Sopenharmony_ci{ 1206e5c31af7Sopenharmony_ci "duplicate_single_recreate_derivative", 1207e5c31af7Sopenharmony_ci TestParams::DERIVATIVE_HANDLE, 1208e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1209e5c31af7Sopenharmony_ci TestParams::Iteration{ 1210e5c31af7Sopenharmony_ci // Iteration [0]: Force compilation of pipeline 1211e5c31af7Sopenharmony_ci TestParams::Iteration::SINGLE_NORMAL, 1212e5c31af7Sopenharmony_ci ValidatorArray{ 1213e5c31af7Sopenharmony_ci // Fail if result is not VK_SUCCESS 1214e5c31af7Sopenharmony_ci checkResult<VK_SUCCESS>, 1215e5c31af7Sopenharmony_ci // Fail if pipeline is not valid 1216e5c31af7Sopenharmony_ci checkPipelineMustBeValid<0> 1217e5c31af7Sopenharmony_ci } 1218e5c31af7Sopenharmony_ci }, 1219e5c31af7Sopenharmony_ci TestParams::Iteration{ 1220e5c31af7Sopenharmony_ci // Iteration [1]: Request compilation of same pipeline without compile 1221e5c31af7Sopenharmony_ci TestParams::Iteration::SINGLE_NOCOMPILE, 1222e5c31af7Sopenharmony_ci ValidatorArray{ 1223e5c31af7Sopenharmony_ci // Warn if pipeline took too long 1224e5c31af7Sopenharmony_ci checkElapsedTime<ELAPSED_TIME_FAST, QP_TEST_RESULT_QUALITY_WARNING> 1225e5c31af7Sopenharmony_ci } 1226e5c31af7Sopenharmony_ci } 1227e5c31af7Sopenharmony_ci }, 1228e5c31af7Sopenharmony_ci false 1229e5c31af7Sopenharmony_ci}; 1230e5c31af7Sopenharmony_ci 1231e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1232e5c31af7Sopenharmony_ci * \brief Single creation of never before seen pipeline without compile 1233e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1234e5c31af7Sopenharmony_cistatic constexpr TestParams SINGLE_PIPELINE_NO_COMPILE = 1235e5c31af7Sopenharmony_ci{ 1236e5c31af7Sopenharmony_ci "single_pipeline_no_compile", 1237e5c31af7Sopenharmony_ci TestParams::NO_CACHE, 1238e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1239e5c31af7Sopenharmony_ci TestParams::Iteration{ 1240e5c31af7Sopenharmony_ci TestParams::Iteration::SINGLE_NOCOMPILE, 1241e5c31af7Sopenharmony_ci ValidatorArray{ 1242e5c31af7Sopenharmony_ci // Warn if pipeline took too long 1243e5c31af7Sopenharmony_ci checkElapsedTime<ELAPSED_TIME_IMMEDIATE, QP_TEST_RESULT_QUALITY_WARNING> 1244e5c31af7Sopenharmony_ci } 1245e5c31af7Sopenharmony_ci } 1246e5c31af7Sopenharmony_ci }, 1247e5c31af7Sopenharmony_ci false 1248e5c31af7Sopenharmony_ci}; 1249e5c31af7Sopenharmony_ci 1250e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1251e5c31af7Sopenharmony_ci * \brief Batch creation of duplicate pipelines with explicit caching 1252e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1253e5c31af7Sopenharmony_cistatic constexpr TestParams DUPLICATE_BATCH_PIPELINES_EXPLICIT_CACHE = 1254e5c31af7Sopenharmony_ci{ 1255e5c31af7Sopenharmony_ci "duplicate_batch_pipelines_explicit_cache", 1256e5c31af7Sopenharmony_ci TestParams::EXPLICIT_CACHE, 1257e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1258e5c31af7Sopenharmony_ci TestParams::Iteration{ 1259e5c31af7Sopenharmony_ci TestParams::Iteration::BATCH_NOCOMPILE_COMPILE_NOCOMPILE, 1260e5c31af7Sopenharmony_ci ValidatorArray{ 1261e5c31af7Sopenharmony_ci // Fail if pipeline[1] is not valid 1262e5c31af7Sopenharmony_ci checkPipelineMustBeValid<1>, 1263e5c31af7Sopenharmony_ci // Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT 1264e5c31af7Sopenharmony_ci checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1265e5c31af7Sopenharmony_ci // Warn if pipelines[0] is not VK_NULL_HANDLE 1266e5c31af7Sopenharmony_ci checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1267e5c31af7Sopenharmony_ci // Warn if pipelines[2] is not valid 1268e5c31af7Sopenharmony_ci checkPipelineMustBeValid<2, QP_TEST_RESULT_COMPATIBILITY_WARNING> 1269e5c31af7Sopenharmony_ci } 1270e5c31af7Sopenharmony_ci } 1271e5c31af7Sopenharmony_ci }, 1272e5c31af7Sopenharmony_ci false 1273e5c31af7Sopenharmony_ci}; 1274e5c31af7Sopenharmony_ci 1275e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1276e5c31af7Sopenharmony_ci * \brief Batch creation of duplicate pipelines with no caching 1277e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1278e5c31af7Sopenharmony_cistatic constexpr TestParams DUPLICATE_BATCH_PIPELINES_NO_CACHE = 1279e5c31af7Sopenharmony_ci{ 1280e5c31af7Sopenharmony_ci "duplicate_batch_pipelines_no_cache", 1281e5c31af7Sopenharmony_ci TestParams::NO_CACHE, 1282e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1283e5c31af7Sopenharmony_ci TestParams::Iteration{ 1284e5c31af7Sopenharmony_ci TestParams::Iteration::BATCH_NOCOMPILE_COMPILE_NOCOMPILE, 1285e5c31af7Sopenharmony_ci ValidatorArray{ 1286e5c31af7Sopenharmony_ci // Fail if pipeline[1] is not valid 1287e5c31af7Sopenharmony_ci checkPipelineMustBeValid<1>, 1288e5c31af7Sopenharmony_ci // Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT 1289e5c31af7Sopenharmony_ci checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1290e5c31af7Sopenharmony_ci // Warn if pipelines[0] is not VK_NULL_HANDLE 1291e5c31af7Sopenharmony_ci checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING> 1292e5c31af7Sopenharmony_ci } 1293e5c31af7Sopenharmony_ci } 1294e5c31af7Sopenharmony_ci }, 1295e5c31af7Sopenharmony_ci false 1296e5c31af7Sopenharmony_ci}; 1297e5c31af7Sopenharmony_ci 1298e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1299e5c31af7Sopenharmony_ci * \brief Batch creation of duplicate pipelines with derivative pipeline index 1300e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1301e5c31af7Sopenharmony_cistatic constexpr TestParams DUPLICATE_BATCH_PIPELINES_DERIVATIVE_INDEX = 1302e5c31af7Sopenharmony_ci{ 1303e5c31af7Sopenharmony_ci "duplicate_batch_pipelines_derivative_index", 1304e5c31af7Sopenharmony_ci TestParams::DERIVATIVE_INDEX, 1305e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1306e5c31af7Sopenharmony_ci TestParams::Iteration{ 1307e5c31af7Sopenharmony_ci TestParams::Iteration::BATCH_NOCOMPILE_COMPILE_NOCOMPILE, 1308e5c31af7Sopenharmony_ci ValidatorArray{ 1309e5c31af7Sopenharmony_ci // Fail if pipeline[1] is not valid 1310e5c31af7Sopenharmony_ci checkPipelineMustBeValid<1>, 1311e5c31af7Sopenharmony_ci // Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT 1312e5c31af7Sopenharmony_ci checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1313e5c31af7Sopenharmony_ci // Warn if pipelines[0] is not VK_NULL_HANDLE 1314e5c31af7Sopenharmony_ci checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING> 1315e5c31af7Sopenharmony_ci } 1316e5c31af7Sopenharmony_ci } 1317e5c31af7Sopenharmony_ci }, 1318e5c31af7Sopenharmony_ci false 1319e5c31af7Sopenharmony_ci}; 1320e5c31af7Sopenharmony_ci 1321e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1322e5c31af7Sopenharmony_ci * \brief Batch creation of pipelines with early return 1323e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1324e5c31af7Sopenharmony_cistatic constexpr TestParams BATCH_PIPELINES_EARLY_RETURN = 1325e5c31af7Sopenharmony_ci{ 1326e5c31af7Sopenharmony_ci "batch_pipelines_early_return", 1327e5c31af7Sopenharmony_ci TestParams::NO_CACHE, 1328e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1329e5c31af7Sopenharmony_ci TestParams::Iteration{ 1330e5c31af7Sopenharmony_ci TestParams::Iteration::BATCH_RETURN_COMPILE_NOCOMPILE, 1331e5c31af7Sopenharmony_ci ValidatorArray{ 1332e5c31af7Sopenharmony_ci // fail if a valid pipeline follows the early-return failure 1333e5c31af7Sopenharmony_ci checkPipelineNullAfterIndex<0>, 1334e5c31af7Sopenharmony_ci // Warn if return was not immediate 1335e5c31af7Sopenharmony_ci checkElapsedTime<ELAPSED_TIME_IMMEDIATE, QP_TEST_RESULT_QUALITY_WARNING>, 1336e5c31af7Sopenharmony_ci // Warn if pipelines[0] is not VK_NULL_HANDLE 1337e5c31af7Sopenharmony_ci checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1338e5c31af7Sopenharmony_ci // Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT 1339e5c31af7Sopenharmony_ci checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING> 1340e5c31af7Sopenharmony_ci } 1341e5c31af7Sopenharmony_ci } 1342e5c31af7Sopenharmony_ci }, 1343e5c31af7Sopenharmony_ci false 1344e5c31af7Sopenharmony_ci}; 1345e5c31af7Sopenharmony_ci 1346e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1347e5c31af7Sopenharmony_ci * \brief Batch creation of pipelines with early return using VkPipelineCreateFlagBits2KHR from maintenance5 1348e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1349e5c31af7Sopenharmony_cistatic constexpr TestParams BATCH_PIPELINES_EARLY_RETURN_MAINTENANCE_5 1350e5c31af7Sopenharmony_ci{ 1351e5c31af7Sopenharmony_ci "batch_pipelines_early_return_maintenance5", 1352e5c31af7Sopenharmony_ci TestParams::NO_CACHE, 1353e5c31af7Sopenharmony_ci TestParams::IterationArray{ 1354e5c31af7Sopenharmony_ci TestParams::Iteration{ 1355e5c31af7Sopenharmony_ci TestParams::Iteration::BATCH_RETURN_COMPILE_NOCOMPILE, 1356e5c31af7Sopenharmony_ci ValidatorArray{ 1357e5c31af7Sopenharmony_ci // fail if a valid pipeline follows the early-return failure 1358e5c31af7Sopenharmony_ci checkPipelineNullAfterIndex<0>, 1359e5c31af7Sopenharmony_ci // Warn if return was not immediate 1360e5c31af7Sopenharmony_ci checkElapsedTime<ELAPSED_TIME_IMMEDIATE, QP_TEST_RESULT_QUALITY_WARNING>, 1361e5c31af7Sopenharmony_ci // Warn if pipelines[0] is not VK_NULL_HANDLE 1362e5c31af7Sopenharmony_ci checkPipelineMustBeNull<0, QP_TEST_RESULT_COMPATIBILITY_WARNING>, 1363e5c31af7Sopenharmony_ci // Warn if result is not VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT 1364e5c31af7Sopenharmony_ci checkResult<VK_ERROR_PIPELINE_COMPILE_REQUIRED_EXT, QP_TEST_RESULT_COMPATIBILITY_WARNING> 1365e5c31af7Sopenharmony_ci } 1366e5c31af7Sopenharmony_ci } 1367e5c31af7Sopenharmony_ci }, 1368e5c31af7Sopenharmony_ci true, 1369e5c31af7Sopenharmony_ci}; 1370e5c31af7Sopenharmony_ci 1371e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1372e5c31af7Sopenharmony_ci * \brief Full array of test cases 1373e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1374e5c31af7Sopenharmony_cistatic constexpr TestParams TEST_CASES[] = 1375e5c31af7Sopenharmony_ci{ 1376e5c31af7Sopenharmony_ci SINGLE_PIPELINE_NO_COMPILE, 1377e5c31af7Sopenharmony_ci BATCH_PIPELINES_EARLY_RETURN, 1378e5c31af7Sopenharmony_ci DUPLICATE_SINGLE_RECREATE_EXPLICIT_CACHING, 1379e5c31af7Sopenharmony_ci DUPLICATE_SINGLE_RECREATE_NO_CACHING, 1380e5c31af7Sopenharmony_ci DUPLICATE_SINGLE_RECREATE_DERIVATIVE, 1381e5c31af7Sopenharmony_ci DUPLICATE_BATCH_PIPELINES_EXPLICIT_CACHE, 1382e5c31af7Sopenharmony_ci DUPLICATE_BATCH_PIPELINES_NO_CACHE, 1383e5c31af7Sopenharmony_ci DUPLICATE_BATCH_PIPELINES_DERIVATIVE_INDEX, 1384e5c31af7Sopenharmony_ci 1385e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 1386e5c31af7Sopenharmony_ci BATCH_PIPELINES_EARLY_RETURN_MAINTENANCE_5, 1387e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 1388e5c31af7Sopenharmony_ci 1389e5c31af7Sopenharmony_ci}; 1390e5c31af7Sopenharmony_ci 1391e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1392e5c31af7Sopenharmony_ci * \brief Variadic version of de::newMovePtr 1393e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1394e5c31af7Sopenharmony_citemplate <typename T, typename... args_t> 1395e5c31af7Sopenharmony_ciinline de::MovePtr<T> newMovePtr(args_t&&... args) 1396e5c31af7Sopenharmony_ci{ 1397e5c31af7Sopenharmony_ci return de::MovePtr<T>(new T(::std::forward<args_t>(args)...)); 1398e5c31af7Sopenharmony_ci} 1399e5c31af7Sopenharmony_ci 1400e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1401e5c31af7Sopenharmony_ci * \brief Make test group consisting of graphics pipeline tests 1402e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1403e5c31af7Sopenharmony_civoid addGraphicsPipelineTests(TestCaseGroup& group) 1404e5c31af7Sopenharmony_ci{ 1405e5c31af7Sopenharmony_ci using namespace graphics_tests; 1406e5c31af7Sopenharmony_ci 1407e5c31af7Sopenharmony_ci auto tests = newMovePtr<TestCaseGroup>( 1408e5c31af7Sopenharmony_ci group.getTestContext(), "graphics_pipelines", "Test pipeline creation cache control with graphics pipelines"); 1409e5c31af7Sopenharmony_ci 1410e5c31af7Sopenharmony_ci for (const auto& params : TEST_CASES) 1411e5c31af7Sopenharmony_ci { 1412e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms<const TestParams&>( 1413e5c31af7Sopenharmony_ci tests.get(), params.name, checkSupport, initPrograms, testInstance, params); 1414e5c31af7Sopenharmony_ci } 1415e5c31af7Sopenharmony_ci 1416e5c31af7Sopenharmony_ci group.addChild(tests.release()); 1417e5c31af7Sopenharmony_ci} 1418e5c31af7Sopenharmony_ci 1419e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1420e5c31af7Sopenharmony_ci * \brief Make test group consisting of compute pipeline tests 1421e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1422e5c31af7Sopenharmony_civoid addComputePipelineTests(TestCaseGroup& group) 1423e5c31af7Sopenharmony_ci{ 1424e5c31af7Sopenharmony_ci using namespace compute_tests; 1425e5c31af7Sopenharmony_ci 1426e5c31af7Sopenharmony_ci auto tests = newMovePtr<TestCaseGroup>( 1427e5c31af7Sopenharmony_ci group.getTestContext(), "compute_pipelines", "Test pipeline creation cache control with compute pipelines"); 1428e5c31af7Sopenharmony_ci 1429e5c31af7Sopenharmony_ci for (const auto& params : TEST_CASES) 1430e5c31af7Sopenharmony_ci { 1431e5c31af7Sopenharmony_ci addFunctionCaseWithPrograms<const TestParams&>( 1432e5c31af7Sopenharmony_ci tests.get(), params.name, checkSupport, initPrograms, testInstance, params); 1433e5c31af7Sopenharmony_ci } 1434e5c31af7Sopenharmony_ci 1435e5c31af7Sopenharmony_ci group.addChild(tests.release()); 1436e5c31af7Sopenharmony_ci} 1437e5c31af7Sopenharmony_ci 1438e5c31af7Sopenharmony_ci} // namespace 1439e5c31af7Sopenharmony_ci 1440e5c31af7Sopenharmony_ci/*--------------------------------------------------------------------*//*! 1441e5c31af7Sopenharmony_ci * \brief Make pipeline creation cache control test group 1442e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 1443e5c31af7Sopenharmony_ciTestCaseGroup* createCacheControlTests(TestContext& testCtx) 1444e5c31af7Sopenharmony_ci{ 1445e5c31af7Sopenharmony_ci auto tests = newMovePtr<TestCaseGroup>(testCtx, "creation_cache_control"); 1446e5c31af7Sopenharmony_ci 1447e5c31af7Sopenharmony_ci addGraphicsPipelineTests(*tests); 1448e5c31af7Sopenharmony_ci addComputePipelineTests(*tests); 1449e5c31af7Sopenharmony_ci 1450e5c31af7Sopenharmony_ci return tests.release(); 1451e5c31af7Sopenharmony_ci} 1452e5c31af7Sopenharmony_ci 1453e5c31af7Sopenharmony_ci} // namespace pipeline 1454e5c31af7Sopenharmony_ci 1455e5c31af7Sopenharmony_ci} // namespace vkt 1456