1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2015 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2018 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 * \file 22e5c31af7Sopenharmony_ci * \brief Test cases for VK_KHR_shader_clock. Ensure that values are 23e5c31af7Sopenharmony_ci being read from the OpReadClockKHR OpCode. 24e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "vktShaderClockTests.hpp" 27e5c31af7Sopenharmony_ci#include "vktTestCaseUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vktTestGroupUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vktShaderExecutor.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 32e5c31af7Sopenharmony_ci 33e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_ci#include "vktAtomicOperationTests.hpp" 36e5c31af7Sopenharmony_ci#include "vktShaderExecutor.hpp" 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 39e5c31af7Sopenharmony_ci#include "vkMemUtil.hpp" 40e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 41e5c31af7Sopenharmony_ci#include "vktTestGroupUtil.hpp" 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 44e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp" 45e5c31af7Sopenharmony_ci#include "tcuResultCollector.hpp" 46e5c31af7Sopenharmony_ci 47e5c31af7Sopenharmony_ci#include "deStringUtil.hpp" 48e5c31af7Sopenharmony_ci#include "deSharedPtr.hpp" 49e5c31af7Sopenharmony_ci#include "deRandom.hpp" 50e5c31af7Sopenharmony_ci#include "deArrayUtil.hpp" 51e5c31af7Sopenharmony_ci 52e5c31af7Sopenharmony_ci#include <cassert> 53e5c31af7Sopenharmony_ci#include <string> 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_cinamespace vkt 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_cinamespace shaderexecutor 58e5c31af7Sopenharmony_ci{ 59e5c31af7Sopenharmony_ci 60e5c31af7Sopenharmony_cinamespace 61e5c31af7Sopenharmony_ci{ 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_cienum 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci NUM_ELEMENTS = 32 66e5c31af7Sopenharmony_ci}; 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_cienum clockType 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci SUBGROUP = 0, 71e5c31af7Sopenharmony_ci DEVICE 72e5c31af7Sopenharmony_ci}; 73e5c31af7Sopenharmony_ci 74e5c31af7Sopenharmony_cienum bitType 75e5c31af7Sopenharmony_ci{ 76e5c31af7Sopenharmony_ci BIT_32 = 0, 77e5c31af7Sopenharmony_ci BIT_64 78e5c31af7Sopenharmony_ci}; 79e5c31af7Sopenharmony_ci 80e5c31af7Sopenharmony_cistruct testType 81e5c31af7Sopenharmony_ci{ 82e5c31af7Sopenharmony_ci clockType testClockType; 83e5c31af7Sopenharmony_ci bitType testBitType; 84e5c31af7Sopenharmony_ci const char* testName; 85e5c31af7Sopenharmony_ci}; 86e5c31af7Sopenharmony_ci 87e5c31af7Sopenharmony_cistatic inline void* getPtrOfVar(deUint64& var) 88e5c31af7Sopenharmony_ci{ 89e5c31af7Sopenharmony_ci return &var; 90e5c31af7Sopenharmony_ci} 91e5c31af7Sopenharmony_ci 92e5c31af7Sopenharmony_ciusing namespace vk; 93e5c31af7Sopenharmony_ci 94e5c31af7Sopenharmony_ciclass ShaderClockTestInstance : public TestInstance 95e5c31af7Sopenharmony_ci{ 96e5c31af7Sopenharmony_cipublic: 97e5c31af7Sopenharmony_ci ShaderClockTestInstance(Context& context, const ShaderSpec& shaderSpec, glu::ShaderType shaderType) 98e5c31af7Sopenharmony_ci : TestInstance(context) 99e5c31af7Sopenharmony_ci , m_executor(createExecutor(m_context, shaderType, shaderSpec)) 100e5c31af7Sopenharmony_ci { 101e5c31af7Sopenharmony_ci } 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ci virtual tcu::TestStatus iterate(void) 104e5c31af7Sopenharmony_ci { 105e5c31af7Sopenharmony_ci const deUint64 initValue = 0xcdcdcdcd; 106e5c31af7Sopenharmony_ci 107e5c31af7Sopenharmony_ci std::vector<deUint64> outputs (NUM_ELEMENTS, initValue); 108e5c31af7Sopenharmony_ci std::vector<void*> outputPtr (NUM_ELEMENTS, nullptr); 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci std::transform(std::begin(outputs), std::end(outputs), std::begin(outputPtr), getPtrOfVar); 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_ci m_executor->execute(NUM_ELEMENTS, nullptr, outputPtr.data()); 113e5c31af7Sopenharmony_ci 114e5c31af7Sopenharmony_ci if (validateOutput(outputs)) 115e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Pass"); 116e5c31af7Sopenharmony_ci else 117e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Result comparison failed"); 118e5c31af7Sopenharmony_ci } 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ciprivate: 121e5c31af7Sopenharmony_ci bool validateOutput(std::vector<deUint64>& outputs) 122e5c31af7Sopenharmony_ci { 123e5c31af7Sopenharmony_ci // The shader will write a 1 in the output if the clock did not increase 124e5c31af7Sopenharmony_ci return (outputs.size() == deUint64(std::count(std::begin(outputs), std::end(outputs), 0))); 125e5c31af7Sopenharmony_ci } 126e5c31af7Sopenharmony_ci 127e5c31af7Sopenharmony_ci de::UniquePtr<ShaderExecutor> m_executor; 128e5c31af7Sopenharmony_ci}; 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ciclass ShaderClockCase : public TestCase 131e5c31af7Sopenharmony_ci{ 132e5c31af7Sopenharmony_cipublic: 133e5c31af7Sopenharmony_ci ShaderClockCase(tcu::TestContext& testCtx, testType operation, glu::ShaderType shaderType) 134e5c31af7Sopenharmony_ci : TestCase(testCtx, operation.testName) 135e5c31af7Sopenharmony_ci , m_operation(operation) 136e5c31af7Sopenharmony_ci , m_shaderSpec() 137e5c31af7Sopenharmony_ci , m_shaderType(shaderType) 138e5c31af7Sopenharmony_ci { 139e5c31af7Sopenharmony_ci initShaderSpec(); 140e5c31af7Sopenharmony_ci } 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci TestInstance* createInstance (Context& ctx) const override 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci return new ShaderClockTestInstance(ctx, m_shaderSpec, m_shaderType); 145e5c31af7Sopenharmony_ci } 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_ci void initPrograms (vk::SourceCollections& programCollection) const override 148e5c31af7Sopenharmony_ci { 149e5c31af7Sopenharmony_ci generateSources(m_shaderType, m_shaderSpec, programCollection); 150e5c31af7Sopenharmony_ci } 151e5c31af7Sopenharmony_ci 152e5c31af7Sopenharmony_ci void checkSupport (Context& context) const override 153e5c31af7Sopenharmony_ci { 154e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_shader_clock"); 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci if (m_operation.testBitType == BIT_64) 157e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_INT64); 158e5c31af7Sopenharmony_ci 159e5c31af7Sopenharmony_ci const auto& shaderClockFeatures = context.getShaderClockFeatures(); 160e5c31af7Sopenharmony_ci const auto realTimeTest = (m_operation.testClockType == DEVICE); 161e5c31af7Sopenharmony_ci 162e5c31af7Sopenharmony_ci if (realTimeTest && !shaderClockFeatures.shaderDeviceClock) 163e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Shader device clock is not supported"); 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci if (!realTimeTest && !shaderClockFeatures.shaderSubgroupClock) 166e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Shader subgroup clock is not supported"); 167e5c31af7Sopenharmony_ci } 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ciprivate: 170e5c31af7Sopenharmony_ci void initShaderSpec() 171e5c31af7Sopenharmony_ci { 172e5c31af7Sopenharmony_ci std::stringstream extensions; 173e5c31af7Sopenharmony_ci std::stringstream source; 174e5c31af7Sopenharmony_ci 175e5c31af7Sopenharmony_ci if (m_operation.testBitType == BIT_64) 176e5c31af7Sopenharmony_ci { 177e5c31af7Sopenharmony_ci extensions << "#extension GL_ARB_gpu_shader_int64 : require \n"; 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci source << "uint64_t time1 = " << m_operation.testName << "(); \n"; 180e5c31af7Sopenharmony_ci source << "uint64_t time2 = " << m_operation.testName << "(); \n"; 181e5c31af7Sopenharmony_ci source << "out0 = uvec2(0, 0); \n"; 182e5c31af7Sopenharmony_ci source << "if (time1 > time2) { \n"; 183e5c31af7Sopenharmony_ci source << " out0.x = 1; \n"; 184e5c31af7Sopenharmony_ci source << "} \n"; 185e5c31af7Sopenharmony_ci } 186e5c31af7Sopenharmony_ci else 187e5c31af7Sopenharmony_ci { 188e5c31af7Sopenharmony_ci source << "uvec2 time1 = " << m_operation.testName << "(); \n"; 189e5c31af7Sopenharmony_ci source << "uvec2 time2 = " << m_operation.testName << "(); \n"; 190e5c31af7Sopenharmony_ci source << "out0 = uvec2(0, 0); \n"; 191e5c31af7Sopenharmony_ci source << "if (time1.y > time2.y || (time1.y == time2.y && time1.x > time2.x)){ \n"; 192e5c31af7Sopenharmony_ci source << " out0.x = 1; \n"; 193e5c31af7Sopenharmony_ci source << "} \n"; 194e5c31af7Sopenharmony_ci } 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_ci if (m_operation.testClockType == DEVICE) 197e5c31af7Sopenharmony_ci { 198e5c31af7Sopenharmony_ci extensions << "#extension GL_EXT_shader_realtime_clock : require \n"; 199e5c31af7Sopenharmony_ci } 200e5c31af7Sopenharmony_ci else 201e5c31af7Sopenharmony_ci { 202e5c31af7Sopenharmony_ci extensions << "#extension GL_ARB_shader_clock : enable \n"; 203e5c31af7Sopenharmony_ci } 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci std::map<std::string, std::string> specializations = { 206e5c31af7Sopenharmony_ci { "EXTENSIONS", extensions.str() }, 207e5c31af7Sopenharmony_ci { "SOURCE", source.str() } 208e5c31af7Sopenharmony_ci }; 209e5c31af7Sopenharmony_ci 210e5c31af7Sopenharmony_ci m_shaderSpec.globalDeclarations = tcu::StringTemplate("${EXTENSIONS}").specialize(specializations); 211e5c31af7Sopenharmony_ci m_shaderSpec.source = tcu::StringTemplate("${SOURCE} ").specialize(specializations); 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci m_shaderSpec.outputs.push_back(Symbol("out0", glu::VarType(glu::TYPE_UINT_VEC2, glu::PRECISION_HIGHP))); 214e5c31af7Sopenharmony_ci } 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ciprivate: 217e5c31af7Sopenharmony_ci ShaderClockCase (const ShaderClockCase&); 218e5c31af7Sopenharmony_ci ShaderClockCase& operator= (const ShaderClockCase&); 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_ci testType m_operation; 221e5c31af7Sopenharmony_ci ShaderSpec m_shaderSpec; 222e5c31af7Sopenharmony_ci glu::ShaderType m_shaderType; 223e5c31af7Sopenharmony_ci}; 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_civoid addShaderClockTests (tcu::TestCaseGroup* testGroup) 226e5c31af7Sopenharmony_ci{ 227e5c31af7Sopenharmony_ci static glu::ShaderType stages[] = 228e5c31af7Sopenharmony_ci { 229e5c31af7Sopenharmony_ci glu::SHADERTYPE_VERTEX, 230e5c31af7Sopenharmony_ci glu::SHADERTYPE_FRAGMENT, 231e5c31af7Sopenharmony_ci glu::SHADERTYPE_COMPUTE 232e5c31af7Sopenharmony_ci }; 233e5c31af7Sopenharmony_ci 234e5c31af7Sopenharmony_ci static testType operations[] = 235e5c31af7Sopenharmony_ci { 236e5c31af7Sopenharmony_ci {SUBGROUP, BIT_64, "clockARB"}, 237e5c31af7Sopenharmony_ci {SUBGROUP, BIT_32, "clock2x32ARB" }, 238e5c31af7Sopenharmony_ci {DEVICE, BIT_64, "clockRealtimeEXT"}, 239e5c31af7Sopenharmony_ci {DEVICE, BIT_32, "clockRealtime2x32EXT"} 240e5c31af7Sopenharmony_ci }; 241e5c31af7Sopenharmony_ci 242e5c31af7Sopenharmony_ci tcu::TestContext& testCtx = testGroup->getTestContext(); 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_ci for (size_t i = 0; i != DE_LENGTH_OF_ARRAY(stages); ++i) 245e5c31af7Sopenharmony_ci { 246e5c31af7Sopenharmony_ci const char* stageName = (stages[i] == glu::SHADERTYPE_VERTEX) ? ("vertex") 247e5c31af7Sopenharmony_ci : (stages[i] == glu::SHADERTYPE_FRAGMENT) ? ("fragment") 248e5c31af7Sopenharmony_ci : (stages[i] == glu::SHADERTYPE_COMPUTE) ? ("compute") 249e5c31af7Sopenharmony_ci : (DE_NULL); 250e5c31af7Sopenharmony_ci 251e5c31af7Sopenharmony_ci const std::string setName = std::string() + stageName; 252e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> stageGroupTest(new tcu::TestCaseGroup(testCtx, setName.c_str())); 253e5c31af7Sopenharmony_ci 254e5c31af7Sopenharmony_ci for (size_t j = 0; j != DE_LENGTH_OF_ARRAY(operations); ++j) 255e5c31af7Sopenharmony_ci { 256e5c31af7Sopenharmony_ci stageGroupTest->addChild(new ShaderClockCase(testCtx, operations[j], stages[i])); 257e5c31af7Sopenharmony_ci } 258e5c31af7Sopenharmony_ci 259e5c31af7Sopenharmony_ci testGroup->addChild(stageGroupTest.release()); 260e5c31af7Sopenharmony_ci } 261e5c31af7Sopenharmony_ci} 262e5c31af7Sopenharmony_ci 263e5c31af7Sopenharmony_ci} // anonymous 264e5c31af7Sopenharmony_ci 265e5c31af7Sopenharmony_citcu::TestCaseGroup* createShaderClockTests(tcu::TestContext& testCtx) 266e5c31af7Sopenharmony_ci{ 267e5c31af7Sopenharmony_ci return createTestGroup(testCtx, "shader_clock", addShaderClockTests); 268e5c31af7Sopenharmony_ci} 269e5c31af7Sopenharmony_ci 270e5c31af7Sopenharmony_ci} // shaderexecutor 271e5c31af7Sopenharmony_ci} // vkt 272