1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan CTS Framework 3e5c31af7Sopenharmony_ci * -------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2021 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief Defines class for handling resources ( programs, pipelines, files, etc. ) 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "vkResourceInterface.hpp" 25e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 28e5c31af7Sopenharmony_ci #include <functional> 29e5c31af7Sopenharmony_ci #include <fstream> 30e5c31af7Sopenharmony_ci #include "vkSafetyCriticalUtil.hpp" 31e5c31af7Sopenharmony_ci #include "vkRefUtil.hpp" 32e5c31af7Sopenharmony_ci #include "tcuCommandLine.hpp" 33e5c31af7Sopenharmony_ci #include "vksCacheBuilder.hpp" 34e5c31af7Sopenharmony_ci #include "vksSerializer.hpp" 35e5c31af7Sopenharmony_ci #include "vkApiVersion.hpp" 36e5c31af7Sopenharmony_ci using namespace vksc_server::json; 37e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 38e5c31af7Sopenharmony_ci 39e5c31af7Sopenharmony_cinamespace vk 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ciResourceInterface::ResourceInterface (tcu::TestContext& testCtx) 43e5c31af7Sopenharmony_ci : m_testCtx (testCtx) 44e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 45e5c31af7Sopenharmony_ci , m_commandPoolIndex (0u) 46e5c31af7Sopenharmony_ci , m_resourceCounter (0u) 47e5c31af7Sopenharmony_ci , m_statCurrent (resetDeviceObjectReservationCreateInfo()) 48e5c31af7Sopenharmony_ci , m_statMax (resetDeviceObjectReservationCreateInfo()) 49e5c31af7Sopenharmony_ci , m_enabledHandleDestroy (true) 50e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 51e5c31af7Sopenharmony_ci{ 52e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 53e5c31af7Sopenharmony_ci // pipelineCacheRequestCount does not contain one instance of createPipelineCache call that happens only in subprocess 54e5c31af7Sopenharmony_ci m_statCurrent.pipelineCacheRequestCount = 1u; 55e5c31af7Sopenharmony_ci m_statMax.pipelineCacheRequestCount = 1u; 56e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 57e5c31af7Sopenharmony_ci} 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ciResourceInterface::~ResourceInterface () 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_ci} 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_civoid ResourceInterface::initTestCase (const std::string& casePath) 64e5c31af7Sopenharmony_ci{ 65e5c31af7Sopenharmony_ci m_currentTestPath = casePath; 66e5c31af7Sopenharmony_ci} 67e5c31af7Sopenharmony_ci 68e5c31af7Sopenharmony_ciconst std::string& ResourceInterface::getCasePath() const 69e5c31af7Sopenharmony_ci{ 70e5c31af7Sopenharmony_ci return m_currentTestPath; 71e5c31af7Sopenharmony_ci} 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 74e5c31af7Sopenharmony_civoid ResourceInterface::initApiVersion (const deUint32 version) 75e5c31af7Sopenharmony_ci{ 76e5c31af7Sopenharmony_ci const ApiVersion apiVersion = unpackVersion(version); 77e5c31af7Sopenharmony_ci const bool vulkanSC = (apiVersion.variantNum == 1); 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci m_version = tcu::Maybe<deUint32>(version); 80e5c31af7Sopenharmony_ci m_vulkanSC = vulkanSC; 81e5c31af7Sopenharmony_ci} 82e5c31af7Sopenharmony_ci 83e5c31af7Sopenharmony_cibool ResourceInterface::isVulkanSC (void) const 84e5c31af7Sopenharmony_ci{ 85e5c31af7Sopenharmony_ci return m_vulkanSC.get(); 86e5c31af7Sopenharmony_ci} 87e5c31af7Sopenharmony_ci 88e5c31af7Sopenharmony_cideUint64 ResourceInterface::incResourceCounter () 89e5c31af7Sopenharmony_ci{ 90e5c31af7Sopenharmony_ci return ++m_resourceCounter; 91e5c31af7Sopenharmony_ci} 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_cistd::mutex& ResourceInterface::getStatMutex () 94e5c31af7Sopenharmony_ci{ 95e5c31af7Sopenharmony_ci return m_mutex; 96e5c31af7Sopenharmony_ci} 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ciVkDeviceObjectReservationCreateInfo& ResourceInterface::getStatCurrent () 99e5c31af7Sopenharmony_ci{ 100e5c31af7Sopenharmony_ci return m_statCurrent; 101e5c31af7Sopenharmony_ci} 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_ciVkDeviceObjectReservationCreateInfo& ResourceInterface::getStatMax () 104e5c31af7Sopenharmony_ci{ 105e5c31af7Sopenharmony_ci return m_statMax; 106e5c31af7Sopenharmony_ci} 107e5c31af7Sopenharmony_ci 108e5c31af7Sopenharmony_ciconst VkDeviceObjectReservationCreateInfo& ResourceInterface::getStatMax () const 109e5c31af7Sopenharmony_ci{ 110e5c31af7Sopenharmony_ci return m_statMax; 111e5c31af7Sopenharmony_ci} 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_civoid ResourceInterface::setHandleDestroy(bool value) 114e5c31af7Sopenharmony_ci{ 115e5c31af7Sopenharmony_ci m_enabledHandleDestroy = value; 116e5c31af7Sopenharmony_ci} 117e5c31af7Sopenharmony_ci 118e5c31af7Sopenharmony_cibool ResourceInterface::isEnabledHandleDestroy() const 119e5c31af7Sopenharmony_ci{ 120e5c31af7Sopenharmony_ci return m_enabledHandleDestroy; 121e5c31af7Sopenharmony_ci} 122e5c31af7Sopenharmony_ci 123e5c31af7Sopenharmony_civoid ResourceInterface::removeRedundantObjects () 124e5c31af7Sopenharmony_ci{ 125e5c31af7Sopenharmony_ci // At the end of the day we only need to export objects used in pipelines. 126e5c31af7Sopenharmony_ci // Rest of the objects may be removed from m_json* structures as redundant 127e5c31af7Sopenharmony_ci std::set<VkSamplerYcbcrConversion> samplerYcbcrConversionsInPipeline; 128e5c31af7Sopenharmony_ci std::set<VkSampler> samplersInPipeline; 129e5c31af7Sopenharmony_ci std::set<VkShaderModule> shadersInPipeline; 130e5c31af7Sopenharmony_ci std::set<VkRenderPass> renderPassesInPipeline; 131e5c31af7Sopenharmony_ci std::set<VkPipelineLayout> pipelineLayoutsInPipeline; 132e5c31af7Sopenharmony_ci std::set<VkDescriptorSetLayout> descriptorSetLayoutsInPipeline; 133e5c31af7Sopenharmony_ci 134e5c31af7Sopenharmony_ci Context jsonReader; 135e5c31af7Sopenharmony_ci 136e5c31af7Sopenharmony_ci for (auto it = begin(m_pipelineInput.pipelines); it != end(m_pipelineInput.pipelines); ++it) 137e5c31af7Sopenharmony_ci { 138e5c31af7Sopenharmony_ci if (it->pipelineContents.find("VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO") != std::string::npos) 139e5c31af7Sopenharmony_ci { 140e5c31af7Sopenharmony_ci VkGraphicsPipelineCreateInfo gpCI; 141e5c31af7Sopenharmony_ci deMemset(&gpCI, 0, sizeof(gpCI)); 142e5c31af7Sopenharmony_ci readJSON_VkGraphicsPipelineCreateInfo(jsonReader, it->pipelineContents, gpCI); 143e5c31af7Sopenharmony_ci 144e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < gpCI.stageCount; ++i) 145e5c31af7Sopenharmony_ci shadersInPipeline.insert(gpCI.pStages[i].module); 146e5c31af7Sopenharmony_ci renderPassesInPipeline.insert(gpCI.renderPass); 147e5c31af7Sopenharmony_ci pipelineLayoutsInPipeline.insert(gpCI.layout); 148e5c31af7Sopenharmony_ci } 149e5c31af7Sopenharmony_ci else if (it->pipelineContents.find("VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO") != std::string::npos) 150e5c31af7Sopenharmony_ci { 151e5c31af7Sopenharmony_ci VkComputePipelineCreateInfo cpCI; 152e5c31af7Sopenharmony_ci deMemset(&cpCI, 0, sizeof(cpCI)); 153e5c31af7Sopenharmony_ci readJSON_VkComputePipelineCreateInfo(jsonReader, it->pipelineContents, cpCI); 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci shadersInPipeline.insert(cpCI.stage.module); 156e5c31af7Sopenharmony_ci pipelineLayoutsInPipeline.insert(cpCI.layout); 157e5c31af7Sopenharmony_ci } 158e5c31af7Sopenharmony_ci else 159e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Could not recognize pipeline type"); 160e5c31af7Sopenharmony_ci } 161e5c31af7Sopenharmony_ci for (auto it = begin(m_pipelineInput.shaderModules); it != end(m_pipelineInput.shaderModules); ) 162e5c31af7Sopenharmony_ci { 163e5c31af7Sopenharmony_ci if (shadersInPipeline.find(it->first) == end(shadersInPipeline)) 164e5c31af7Sopenharmony_ci it = m_pipelineInput.shaderModules.erase(it); 165e5c31af7Sopenharmony_ci else 166e5c31af7Sopenharmony_ci ++it; 167e5c31af7Sopenharmony_ci } 168e5c31af7Sopenharmony_ci for (auto it = begin(m_pipelineInput.renderPasses); it != end(m_pipelineInput.renderPasses); ) 169e5c31af7Sopenharmony_ci { 170e5c31af7Sopenharmony_ci if (renderPassesInPipeline.find(it->first) == end(renderPassesInPipeline)) 171e5c31af7Sopenharmony_ci it = m_pipelineInput.renderPasses.erase(it); 172e5c31af7Sopenharmony_ci else 173e5c31af7Sopenharmony_ci ++it; 174e5c31af7Sopenharmony_ci } 175e5c31af7Sopenharmony_ci for (auto it = begin(m_pipelineInput.pipelineLayouts); it != end(m_pipelineInput.pipelineLayouts); ) 176e5c31af7Sopenharmony_ci { 177e5c31af7Sopenharmony_ci if (pipelineLayoutsInPipeline.find(it->first) == end(pipelineLayoutsInPipeline)) 178e5c31af7Sopenharmony_ci { 179e5c31af7Sopenharmony_ci it = m_pipelineInput.pipelineLayouts.erase(it); 180e5c31af7Sopenharmony_ci } 181e5c31af7Sopenharmony_ci else 182e5c31af7Sopenharmony_ci { 183e5c31af7Sopenharmony_ci VkPipelineLayoutCreateInfo plCI; 184e5c31af7Sopenharmony_ci deMemset(&plCI, 0, sizeof(plCI)); 185e5c31af7Sopenharmony_ci readJSON_VkPipelineLayoutCreateInfo(jsonReader, it->second, plCI); 186e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < plCI.setLayoutCount; ++i) 187e5c31af7Sopenharmony_ci descriptorSetLayoutsInPipeline.insert(plCI.pSetLayouts[i]); 188e5c31af7Sopenharmony_ci ++it; 189e5c31af7Sopenharmony_ci } 190e5c31af7Sopenharmony_ci } 191e5c31af7Sopenharmony_ci for (auto it = begin(m_pipelineInput.descriptorSetLayouts); it != end(m_pipelineInput.descriptorSetLayouts); ) 192e5c31af7Sopenharmony_ci { 193e5c31af7Sopenharmony_ci if (descriptorSetLayoutsInPipeline.find(it->first) == end(descriptorSetLayoutsInPipeline)) 194e5c31af7Sopenharmony_ci it = m_pipelineInput.descriptorSetLayouts.erase(it); 195e5c31af7Sopenharmony_ci else 196e5c31af7Sopenharmony_ci { 197e5c31af7Sopenharmony_ci VkDescriptorSetLayoutCreateInfo dsCI; 198e5c31af7Sopenharmony_ci deMemset(&dsCI, 0, sizeof(dsCI)); 199e5c31af7Sopenharmony_ci readJSON_VkDescriptorSetLayoutCreateInfo(jsonReader, it->second, dsCI); 200e5c31af7Sopenharmony_ci 201e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < dsCI.bindingCount; ++i) 202e5c31af7Sopenharmony_ci { 203e5c31af7Sopenharmony_ci if (dsCI.pBindings[i].pImmutableSamplers == NULL) 204e5c31af7Sopenharmony_ci continue; 205e5c31af7Sopenharmony_ci for (deUint32 j = 0; j < dsCI.pBindings[i].descriptorCount; ++j) 206e5c31af7Sopenharmony_ci { 207e5c31af7Sopenharmony_ci if (dsCI.pBindings[i].pImmutableSamplers[j] == DE_NULL) 208e5c31af7Sopenharmony_ci continue; 209e5c31af7Sopenharmony_ci samplersInPipeline.insert(dsCI.pBindings[i].pImmutableSamplers[j]); 210e5c31af7Sopenharmony_ci } 211e5c31af7Sopenharmony_ci } 212e5c31af7Sopenharmony_ci ++it; 213e5c31af7Sopenharmony_ci } 214e5c31af7Sopenharmony_ci } 215e5c31af7Sopenharmony_ci 216e5c31af7Sopenharmony_ci for (auto it = begin(m_pipelineInput.samplers); it != end(m_pipelineInput.samplers); ) 217e5c31af7Sopenharmony_ci { 218e5c31af7Sopenharmony_ci if (samplersInPipeline.find(it->first) == end(samplersInPipeline)) 219e5c31af7Sopenharmony_ci it = m_pipelineInput.samplers.erase(it); 220e5c31af7Sopenharmony_ci else 221e5c31af7Sopenharmony_ci { 222e5c31af7Sopenharmony_ci VkSamplerCreateInfo sCI; 223e5c31af7Sopenharmony_ci deMemset(&sCI, 0, sizeof(sCI)); 224e5c31af7Sopenharmony_ci readJSON_VkSamplerCreateInfo(jsonReader, it->second, sCI); 225e5c31af7Sopenharmony_ci 226e5c31af7Sopenharmony_ci if (sCI.pNext != DE_NULL) 227e5c31af7Sopenharmony_ci { 228e5c31af7Sopenharmony_ci VkSamplerYcbcrConversionInfo* info = (VkSamplerYcbcrConversionInfo*)(sCI.pNext); 229e5c31af7Sopenharmony_ci if (info->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO) 230e5c31af7Sopenharmony_ci samplerYcbcrConversionsInPipeline.insert(info->conversion); 231e5c31af7Sopenharmony_ci } 232e5c31af7Sopenharmony_ci ++it; 233e5c31af7Sopenharmony_ci } 234e5c31af7Sopenharmony_ci } 235e5c31af7Sopenharmony_ci for (auto it = begin(m_pipelineInput.samplerYcbcrConversions); it != end(m_pipelineInput.samplerYcbcrConversions); ) 236e5c31af7Sopenharmony_ci { 237e5c31af7Sopenharmony_ci if (samplerYcbcrConversionsInPipeline.find(it->first) == end(samplerYcbcrConversionsInPipeline)) 238e5c31af7Sopenharmony_ci it = m_pipelineInput.samplerYcbcrConversions.erase(it); 239e5c31af7Sopenharmony_ci else 240e5c31af7Sopenharmony_ci ++it; 241e5c31af7Sopenharmony_ci } 242e5c31af7Sopenharmony_ci} 243e5c31af7Sopenharmony_ci 244e5c31af7Sopenharmony_civoid ResourceInterface::finalizeCommandBuffers () 245e5c31af7Sopenharmony_ci{ 246e5c31af7Sopenharmony_ci // We have information about command buffer sizes 247e5c31af7Sopenharmony_ci // Now we have to convert it into command pool sizes 248e5c31af7Sopenharmony_ci std::map<deUint64, std::size_t> cpToIndex; 249e5c31af7Sopenharmony_ci for (std::size_t i = 0; i < m_commandPoolMemoryConsumption.size(); ++i) 250e5c31af7Sopenharmony_ci cpToIndex.insert({ m_commandPoolMemoryConsumption[i].commandPool, i }); 251e5c31af7Sopenharmony_ci for (const auto& memC : m_commandBufferMemoryConsumption) 252e5c31af7Sopenharmony_ci { 253e5c31af7Sopenharmony_ci std::size_t j = cpToIndex[memC.second.commandPool]; 254e5c31af7Sopenharmony_ci m_commandPoolMemoryConsumption[j].updateValues 255e5c31af7Sopenharmony_ci ( 256e5c31af7Sopenharmony_ci memC.second.maxCommandPoolAllocated, 257e5c31af7Sopenharmony_ci memC.second.maxCommandPoolReservedSize, 258e5c31af7Sopenharmony_ci memC.second.maxCommandBufferAllocated 259e5c31af7Sopenharmony_ci ); 260e5c31af7Sopenharmony_ci m_commandPoolMemoryConsumption[j].commandBufferCount++; 261e5c31af7Sopenharmony_ci } 262e5c31af7Sopenharmony_ci // Each m_commandPoolMemoryConsumption element must have at least one command buffer ( see DeviceDriverSC::createCommandPoolHandlerNorm() ) 263e5c31af7Sopenharmony_ci // As a result we have to ensure that commandBufferRequestCount is not less than the number of command pools 264e5c31af7Sopenharmony_ci m_statMax.commandBufferRequestCount = de::max(deUint32(m_commandPoolMemoryConsumption.size()), m_statMax.commandBufferRequestCount); 265e5c31af7Sopenharmony_ci} 266e5c31af7Sopenharmony_ci 267e5c31af7Sopenharmony_cistd::vector<deUint8> ResourceInterface::exportData () const 268e5c31af7Sopenharmony_ci{ 269e5c31af7Sopenharmony_ci vksc_server::VulkanDataTransmittedFromMainToSubprocess vdtfmtsp(m_pipelineInput, m_statMax, m_commandPoolMemoryConsumption, m_pipelineSizes); 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci return vksc_server::Serialize(vdtfmtsp); 272e5c31af7Sopenharmony_ci} 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_civoid ResourceInterface::importData (std::vector<deUint8>& importText) const 275e5c31af7Sopenharmony_ci{ 276e5c31af7Sopenharmony_ci vksc_server::VulkanDataTransmittedFromMainToSubprocess vdtfmtsp = vksc_server::Deserialize<vksc_server::VulkanDataTransmittedFromMainToSubprocess>(importText); 277e5c31af7Sopenharmony_ci 278e5c31af7Sopenharmony_ci m_pipelineInput = vdtfmtsp.pipelineCacheInput; 279e5c31af7Sopenharmony_ci m_statMax = vdtfmtsp.memoryReservation; 280e5c31af7Sopenharmony_ci m_commandPoolMemoryConsumption = vdtfmtsp.commandPoolMemoryConsumption; 281e5c31af7Sopenharmony_ci m_pipelineSizes = vdtfmtsp.pipelineSizes; 282e5c31af7Sopenharmony_ci} 283e5c31af7Sopenharmony_ci 284e5c31af7Sopenharmony_civoid ResourceInterface::registerObjectHash (deUint64 handle, std::size_t hashValue) const 285e5c31af7Sopenharmony_ci{ 286e5c31af7Sopenharmony_ci m_objectHashes[handle] = hashValue; 287e5c31af7Sopenharmony_ci} 288e5c31af7Sopenharmony_ci 289e5c31af7Sopenharmony_ciconst std::map<deUint64,std::size_t>& ResourceInterface::getObjectHashes () const 290e5c31af7Sopenharmony_ci{ 291e5c31af7Sopenharmony_ci return m_objectHashes; 292e5c31af7Sopenharmony_ci} 293e5c31af7Sopenharmony_ci 294e5c31af7Sopenharmony_cistruct PipelinePoolSizeInfo 295e5c31af7Sopenharmony_ci{ 296e5c31af7Sopenharmony_ci deUint32 maxTestCount; 297e5c31af7Sopenharmony_ci deUint32 size; 298e5c31af7Sopenharmony_ci}; 299e5c31af7Sopenharmony_ci 300e5c31af7Sopenharmony_civoid ResourceInterface::preparePipelinePoolSizes() 301e5c31af7Sopenharmony_ci{ 302e5c31af7Sopenharmony_ci std::map<std::string, std::vector<PipelinePoolSizeInfo>> pipelineInfoPerTest; 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci // Step 1: collect information about all pipelines in each test, group by size 305e5c31af7Sopenharmony_ci for (const auto& pipeline : m_pipelineInput.pipelines) 306e5c31af7Sopenharmony_ci { 307e5c31af7Sopenharmony_ci auto it = std::find_if(begin(m_pipelineSizes), end(m_pipelineSizes), vksc_server::PipelineIdentifierEqual(pipeline.id)); 308e5c31af7Sopenharmony_ci if (it == end(m_pipelineSizes)) 309e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "VkPipelinePoolEntrySizeCreateInfo not created for pipelineIdentifier"); 310e5c31af7Sopenharmony_ci 311e5c31af7Sopenharmony_ci PipelinePoolSizeInfo ppsi 312e5c31af7Sopenharmony_ci { 313e5c31af7Sopenharmony_ci it->count, 314e5c31af7Sopenharmony_ci it->size 315e5c31af7Sopenharmony_ci }; 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_ci for (const auto& test : pipeline.tests) 318e5c31af7Sopenharmony_ci { 319e5c31af7Sopenharmony_ci auto pit = pipelineInfoPerTest.find(test); 320e5c31af7Sopenharmony_ci if (pit == end(pipelineInfoPerTest)) 321e5c31af7Sopenharmony_ci pit = pipelineInfoPerTest.insert({ test, std::vector<PipelinePoolSizeInfo>() }).first; 322e5c31af7Sopenharmony_ci // group by the same sizes in a test 323e5c31af7Sopenharmony_ci bool found = false; 324e5c31af7Sopenharmony_ci for (size_t i = 0; i<pit->second.size(); ++i) 325e5c31af7Sopenharmony_ci { 326e5c31af7Sopenharmony_ci if (pit->second[i].size == ppsi.size) 327e5c31af7Sopenharmony_ci { 328e5c31af7Sopenharmony_ci pit->second[i].maxTestCount += ppsi.maxTestCount; 329e5c31af7Sopenharmony_ci found = true; 330e5c31af7Sopenharmony_ci break; 331e5c31af7Sopenharmony_ci } 332e5c31af7Sopenharmony_ci } 333e5c31af7Sopenharmony_ci if(!found) 334e5c31af7Sopenharmony_ci pit->second.push_back(ppsi); 335e5c31af7Sopenharmony_ci } 336e5c31af7Sopenharmony_ci } 337e5c31af7Sopenharmony_ci 338e5c31af7Sopenharmony_ci // Step 2: choose pipeline pool sizes 339e5c31af7Sopenharmony_ci std::vector<PipelinePoolSizeInfo> finalPoolSizes; 340e5c31af7Sopenharmony_ci for (const auto& pInfo : pipelineInfoPerTest) 341e5c31af7Sopenharmony_ci { 342e5c31af7Sopenharmony_ci for (const auto& ppsi1 : pInfo.second) 343e5c31af7Sopenharmony_ci { 344e5c31af7Sopenharmony_ci auto it = std::find_if(begin(finalPoolSizes), end(finalPoolSizes), [&ppsi1](const PipelinePoolSizeInfo& x) { return (x.size == ppsi1.size); }); 345e5c31af7Sopenharmony_ci if (it != end(finalPoolSizes)) 346e5c31af7Sopenharmony_ci it->maxTestCount = de::max(it->maxTestCount, ppsi1.maxTestCount); 347e5c31af7Sopenharmony_ci else 348e5c31af7Sopenharmony_ci finalPoolSizes.push_back(ppsi1); 349e5c31af7Sopenharmony_ci } 350e5c31af7Sopenharmony_ci } 351e5c31af7Sopenharmony_ci 352e5c31af7Sopenharmony_ci // Step 3: convert results to VkPipelinePoolSize 353e5c31af7Sopenharmony_ci m_pipelinePoolSizes.clear(); 354e5c31af7Sopenharmony_ci for (const auto& ppsi : finalPoolSizes) 355e5c31af7Sopenharmony_ci { 356e5c31af7Sopenharmony_ci VkPipelinePoolSize poolSize = 357e5c31af7Sopenharmony_ci { 358e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_POOL_SIZE, // VkStructureType sType; 359e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 360e5c31af7Sopenharmony_ci ppsi.size, // VkDeviceSize poolEntrySize; 361e5c31af7Sopenharmony_ci ppsi.maxTestCount // deUint32 poolEntryCount; 362e5c31af7Sopenharmony_ci }; 363e5c31af7Sopenharmony_ci m_pipelinePoolSizes.emplace_back(poolSize); 364e5c31af7Sopenharmony_ci } 365e5c31af7Sopenharmony_ci} 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_cistd::vector<VkPipelinePoolSize> ResourceInterface::getPipelinePoolSizes () const 368e5c31af7Sopenharmony_ci{ 369e5c31af7Sopenharmony_ci return m_pipelinePoolSizes; 370e5c31af7Sopenharmony_ci} 371e5c31af7Sopenharmony_ci 372e5c31af7Sopenharmony_civoid ResourceInterface::fillPoolEntrySize (vk::VkPipelineOfflineCreateInfo& pipelineIdentifier) const 373e5c31af7Sopenharmony_ci{ 374e5c31af7Sopenharmony_ci auto it = std::find_if(begin(m_pipelineSizes), end(m_pipelineSizes), vksc_server::PipelineIdentifierEqual(pipelineIdentifier)); 375e5c31af7Sopenharmony_ci if( it == end(m_pipelineSizes) ) 376e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "VkPipelinePoolEntrySizeCreateInfo not created for pipelineIdentifier"); 377e5c31af7Sopenharmony_ci pipelineIdentifier.poolEntrySize = it->size; 378e5c31af7Sopenharmony_ci} 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_civksc_server::VulkanCommandMemoryConsumption ResourceInterface::getNextCommandPoolSize () 381e5c31af7Sopenharmony_ci{ 382e5c31af7Sopenharmony_ci if (m_commandPoolMemoryConsumption.empty()) 383e5c31af7Sopenharmony_ci return vksc_server::VulkanCommandMemoryConsumption(); 384e5c31af7Sopenharmony_ci 385e5c31af7Sopenharmony_ci vksc_server::VulkanCommandMemoryConsumption result = m_commandPoolMemoryConsumption[m_commandPoolIndex]; 386e5c31af7Sopenharmony_ci // modulo operation is just a safeguard against excessive number of requests 387e5c31af7Sopenharmony_ci m_commandPoolIndex = (m_commandPoolIndex + 1) % deUint32(m_commandPoolMemoryConsumption.size()); 388e5c31af7Sopenharmony_ci return result; 389e5c31af7Sopenharmony_ci} 390e5c31af7Sopenharmony_ci 391e5c31af7Sopenharmony_cistd::size_t ResourceInterface::getCacheDataSize () const 392e5c31af7Sopenharmony_ci{ 393e5c31af7Sopenharmony_ci return m_cacheData.size(); 394e5c31af7Sopenharmony_ci} 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_ciconst deUint8* ResourceInterface::getCacheData () const 397e5c31af7Sopenharmony_ci{ 398e5c31af7Sopenharmony_ci return m_cacheData.data(); 399e5c31af7Sopenharmony_ci} 400e5c31af7Sopenharmony_ci 401e5c31af7Sopenharmony_ciVkPipelineCache ResourceInterface::getPipelineCache(VkDevice device) const 402e5c31af7Sopenharmony_ci{ 403e5c31af7Sopenharmony_ci auto pit = m_pipelineCache.find(device); 404e5c31af7Sopenharmony_ci if (pit == end(m_pipelineCache)) 405e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "m_pipelineCache not found for this device"); 406e5c31af7Sopenharmony_ci return pit->second.get()->get(); 407e5c31af7Sopenharmony_ci} 408e5c31af7Sopenharmony_ci 409e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 410e5c31af7Sopenharmony_ci 411e5c31af7Sopenharmony_ciResourceInterfaceStandard::ResourceInterfaceStandard (tcu::TestContext& testCtx) 412e5c31af7Sopenharmony_ci : ResourceInterface(testCtx) 413e5c31af7Sopenharmony_ci{ 414e5c31af7Sopenharmony_ci} 415e5c31af7Sopenharmony_ci 416e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::initDevice (DeviceInterface& deviceInterface, VkDevice device) 417e5c31af7Sopenharmony_ci{ 418e5c31af7Sopenharmony_ci // ResourceInterfaceStandard is a class for running VulkanSC tests on normal Vulkan driver. 419e5c31af7Sopenharmony_ci // CTS does not have vkCreateShaderModule function defined for Vulkan SC driver, but we need this function 420e5c31af7Sopenharmony_ci // So ResourceInterfaceStandard class must have its own vkCreateShaderModule function pointer 421e5c31af7Sopenharmony_ci // Moreover - we create additional function pointers for vkCreateGraphicsPipelines, vkCreateComputePipelines, etc. 422e5c31af7Sopenharmony_ci // BTW: although ResourceInterfaceStandard exists in normal Vulkan tests - only initDevice and buildProgram functions are used by Vulkan tests 423e5c31af7Sopenharmony_ci // Other functions are called from within DeviceDriverSC which does not exist in these tests ( DeviceDriver class is used instead ) 424e5c31af7Sopenharmony_ci m_createShaderModuleFunc[device] = (CreateShaderModuleFunc) deviceInterface.getDeviceProcAddr(device, "vkCreateShaderModule"); 425e5c31af7Sopenharmony_ci m_createGraphicsPipelinesFunc[device] = (CreateGraphicsPipelinesFunc) deviceInterface.getDeviceProcAddr(device, "vkCreateGraphicsPipelines"); 426e5c31af7Sopenharmony_ci m_createComputePipelinesFunc[device] = (CreateComputePipelinesFunc) deviceInterface.getDeviceProcAddr(device, "vkCreateComputePipelines"); 427e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 428e5c31af7Sopenharmony_ci if (m_testCtx.getCommandLine().isSubProcess()) 429e5c31af7Sopenharmony_ci { 430e5c31af7Sopenharmony_ci if (m_cacheData.size() > 0) 431e5c31af7Sopenharmony_ci { 432e5c31af7Sopenharmony_ci VkPipelineCacheCreateInfo pCreateInfo = 433e5c31af7Sopenharmony_ci { 434e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType; 435e5c31af7Sopenharmony_ci DE_NULL, // const void* pNext; 436e5c31af7Sopenharmony_ci VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT | 437e5c31af7Sopenharmony_ci VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags; 438e5c31af7Sopenharmony_ci m_cacheData.size(), // deUintptr initialDataSize; 439e5c31af7Sopenharmony_ci m_cacheData.data() // const void* pInitialData; 440e5c31af7Sopenharmony_ci }; 441e5c31af7Sopenharmony_ci m_pipelineCache[device] = de::SharedPtr<Move<VkPipelineCache>>(new Move<VkPipelineCache>(createPipelineCache(deviceInterface, device, &pCreateInfo, DE_NULL))); 442e5c31af7Sopenharmony_ci } 443e5c31af7Sopenharmony_ci } 444e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 445e5c31af7Sopenharmony_ci} 446e5c31af7Sopenharmony_ci 447e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::deinitDevice (VkDevice device) 448e5c31af7Sopenharmony_ci{ 449e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 450e5c31af7Sopenharmony_ci if (m_testCtx.getCommandLine().isSubProcess()) 451e5c31af7Sopenharmony_ci { 452e5c31af7Sopenharmony_ci m_pipelineCache.erase(device); 453e5c31af7Sopenharmony_ci } 454e5c31af7Sopenharmony_ci#else 455e5c31af7Sopenharmony_ci DE_UNREF(device); 456e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 457e5c31af7Sopenharmony_ci} 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::registerDeviceFeatures (VkDevice device, 462e5c31af7Sopenharmony_ci const VkDeviceCreateInfo* pCreateInfo) const 463e5c31af7Sopenharmony_ci{ 464e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2* chainedFeatures = (VkPhysicalDeviceFeatures2*)findStructureInChain(pCreateInfo->pNext, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2); 465e5c31af7Sopenharmony_ci if (chainedFeatures != NULL) 466e5c31af7Sopenharmony_ci { 467e5c31af7Sopenharmony_ci m_deviceFeatures[device] = writeJSON_pNextChain(pCreateInfo->pNext); 468e5c31af7Sopenharmony_ci } 469e5c31af7Sopenharmony_ci else 470e5c31af7Sopenharmony_ci { 471e5c31af7Sopenharmony_ci VkPhysicalDeviceFeatures2 deviceFeatures2 = initVulkanStructure(); 472e5c31af7Sopenharmony_ci if (pCreateInfo->pEnabledFeatures != NULL) 473e5c31af7Sopenharmony_ci deviceFeatures2.features = *(pCreateInfo->pEnabledFeatures); 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_ci deviceFeatures2.pNext = (void *)pCreateInfo->pNext; 476e5c31af7Sopenharmony_ci m_deviceFeatures[device] = writeJSON_VkPhysicalDeviceFeatures2(deviceFeatures2); 477e5c31af7Sopenharmony_ci } 478e5c31af7Sopenharmony_ci 479e5c31af7Sopenharmony_ci std::vector<std::string> extensions; 480e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < pCreateInfo->enabledExtensionCount; ++i) 481e5c31af7Sopenharmony_ci extensions.push_back(pCreateInfo->ppEnabledExtensionNames[i]); 482e5c31af7Sopenharmony_ci m_deviceExtensions[device] = extensions; 483e5c31af7Sopenharmony_ci} 484e5c31af7Sopenharmony_ci 485e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::unregisterDeviceFeatures(VkDevice device) const 486e5c31af7Sopenharmony_ci{ 487e5c31af7Sopenharmony_ci m_deviceFeatures.erase(device); 488e5c31af7Sopenharmony_ci m_deviceExtensions.erase(device); 489e5c31af7Sopenharmony_ci} 490e5c31af7Sopenharmony_ci 491e5c31af7Sopenharmony_ciVkResult ResourceInterfaceStandard::createShaderModule (VkDevice device, 492e5c31af7Sopenharmony_ci const VkShaderModuleCreateInfo* pCreateInfo, 493e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 494e5c31af7Sopenharmony_ci VkShaderModule* pShaderModule, 495e5c31af7Sopenharmony_ci bool normalMode) const 496e5c31af7Sopenharmony_ci{ 497e5c31af7Sopenharmony_ci if (normalMode) 498e5c31af7Sopenharmony_ci { 499e5c31af7Sopenharmony_ci if (isVulkanSC()) 500e5c31af7Sopenharmony_ci { 501e5c31af7Sopenharmony_ci *pShaderModule = VkShaderModule(++m_resourceCounter); 502e5c31af7Sopenharmony_ci registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes())); 503e5c31af7Sopenharmony_ci return VK_SUCCESS; 504e5c31af7Sopenharmony_ci } 505e5c31af7Sopenharmony_ci else 506e5c31af7Sopenharmony_ci { 507e5c31af7Sopenharmony_ci const auto it = m_createShaderModuleFunc.find(device); 508e5c31af7Sopenharmony_ci if (it != end(m_createShaderModuleFunc)) 509e5c31af7Sopenharmony_ci { 510e5c31af7Sopenharmony_ci VkResult result = it->second(device, pCreateInfo, pAllocator, pShaderModule); 511e5c31af7Sopenharmony_ci registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes())); 512e5c31af7Sopenharmony_ci return result; 513e5c31af7Sopenharmony_ci } 514e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "vkCreateShaderModule not defined"); 515e5c31af7Sopenharmony_ci } 516e5c31af7Sopenharmony_ci } 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci // main process: store VkShaderModuleCreateInfo in JSON format. Shaders will be sent later for m_pipelineCache creation ( and sent through file to another process ) 519e5c31af7Sopenharmony_ci *pShaderModule = VkShaderModule(++m_resourceCounter); 520e5c31af7Sopenharmony_ci registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes())); 521e5c31af7Sopenharmony_ci m_pipelineInput.shaderModules.insert({ *pShaderModule, writeJSON_VkShaderModuleCreateInfo(*pCreateInfo) }); 522e5c31af7Sopenharmony_ci return VK_SUCCESS; 523e5c31af7Sopenharmony_ci} 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ciVkPipelineOfflineCreateInfo makeGraphicsPipelineIdentifier (const std::string& testPath, const VkGraphicsPipelineCreateInfo& gpCI, const std::map<deUint64, std::size_t>& objectHashes) 526e5c31af7Sopenharmony_ci{ 527e5c31af7Sopenharmony_ci DE_UNREF(testPath); 528e5c31af7Sopenharmony_ci VkPipelineOfflineCreateInfo pipelineID = resetPipelineOfflineCreateInfo(); 529e5c31af7Sopenharmony_ci std::size_t hashValue = calculateGraphicsPipelineHash(gpCI, objectHashes); 530e5c31af7Sopenharmony_ci memcpy(pipelineID.pipelineIdentifier, &hashValue, sizeof(std::size_t)); 531e5c31af7Sopenharmony_ci return pipelineID; 532e5c31af7Sopenharmony_ci} 533e5c31af7Sopenharmony_ci 534e5c31af7Sopenharmony_ciVkPipelineOfflineCreateInfo makeComputePipelineIdentifier (const std::string& testPath, const VkComputePipelineCreateInfo& cpCI, const std::map<deUint64, std::size_t>& objectHashes) 535e5c31af7Sopenharmony_ci{ 536e5c31af7Sopenharmony_ci DE_UNREF(testPath); 537e5c31af7Sopenharmony_ci VkPipelineOfflineCreateInfo pipelineID = resetPipelineOfflineCreateInfo(); 538e5c31af7Sopenharmony_ci std::size_t hashValue = calculateComputePipelineHash(cpCI, objectHashes); 539e5c31af7Sopenharmony_ci memcpy(pipelineID.pipelineIdentifier, &hashValue, sizeof(std::size_t)); 540e5c31af7Sopenharmony_ci return pipelineID; 541e5c31af7Sopenharmony_ci} 542e5c31af7Sopenharmony_ci 543e5c31af7Sopenharmony_ciVkResult ResourceInterfaceStandard::createGraphicsPipelines (VkDevice device, 544e5c31af7Sopenharmony_ci VkPipelineCache pipelineCache, 545e5c31af7Sopenharmony_ci deUint32 createInfoCount, 546e5c31af7Sopenharmony_ci const VkGraphicsPipelineCreateInfo* pCreateInfos, 547e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 548e5c31af7Sopenharmony_ci VkPipeline* pPipelines, 549e5c31af7Sopenharmony_ci bool normalMode) const 550e5c31af7Sopenharmony_ci{ 551e5c31af7Sopenharmony_ci DE_UNREF(pipelineCache); 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci // build pipeline identifiers (if required), make a copy of pCreateInfos 554e5c31af7Sopenharmony_ci std::vector<VkPipelineOfflineCreateInfo> pipelineIDs; 555e5c31af7Sopenharmony_ci std::vector<deUint8> idInPNextChain; 556e5c31af7Sopenharmony_ci std::vector<VkGraphicsPipelineCreateInfo> pCreateInfoCopies; 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < createInfoCount; ++i) 559e5c31af7Sopenharmony_ci { 560e5c31af7Sopenharmony_ci pCreateInfoCopies.push_back(pCreateInfos[i]); 561e5c31af7Sopenharmony_ci 562e5c31af7Sopenharmony_ci // Check if test added pipeline identifier on its own 563e5c31af7Sopenharmony_ci VkPipelineOfflineCreateInfo* idInfo = (VkPipelineOfflineCreateInfo*)findStructureInChain(pCreateInfos[i].pNext, VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO); 564e5c31af7Sopenharmony_ci if (idInfo == DE_NULL) 565e5c31af7Sopenharmony_ci { 566e5c31af7Sopenharmony_ci pipelineIDs.push_back(makeGraphicsPipelineIdentifier(m_currentTestPath, pCreateInfos[i], getObjectHashes())); 567e5c31af7Sopenharmony_ci idInPNextChain.push_back(0); 568e5c31af7Sopenharmony_ci } 569e5c31af7Sopenharmony_ci else 570e5c31af7Sopenharmony_ci { 571e5c31af7Sopenharmony_ci pipelineIDs.push_back(*idInfo); 572e5c31af7Sopenharmony_ci idInPNextChain.push_back(1); 573e5c31af7Sopenharmony_ci } 574e5c31af7Sopenharmony_ci 575e5c31af7Sopenharmony_ci if (normalMode) 576e5c31af7Sopenharmony_ci fillPoolEntrySize(pipelineIDs.back()); 577e5c31af7Sopenharmony_ci } 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_ci // reset not used pointers, so that JSON generation does not crash 580e5c31af7Sopenharmony_ci std::vector<VkPipelineViewportStateCreateInfo> viewportStateCopies (createInfoCount); 581e5c31af7Sopenharmony_ci if (!normalMode) 582e5c31af7Sopenharmony_ci { 583e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < createInfoCount; ++i) 584e5c31af7Sopenharmony_ci { 585e5c31af7Sopenharmony_ci bool vertexInputStateRequired = false; 586e5c31af7Sopenharmony_ci bool inputAssemblyStateRequired = false; 587e5c31af7Sopenharmony_ci bool tessellationStateRequired = false; 588e5c31af7Sopenharmony_ci bool viewportStateRequired = false; 589e5c31af7Sopenharmony_ci bool viewportStateViewportsRequired = false; 590e5c31af7Sopenharmony_ci bool viewportStateScissorsRequired = false; 591e5c31af7Sopenharmony_ci bool multiSampleStateRequired = false; 592e5c31af7Sopenharmony_ci bool depthStencilStateRequired = false; 593e5c31af7Sopenharmony_ci bool colorBlendStateRequired = false; 594e5c31af7Sopenharmony_ci 595e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pStages != DE_NULL) 596e5c31af7Sopenharmony_ci { 597e5c31af7Sopenharmony_ci for (deUint32 j = 0; j < pCreateInfoCopies[i].stageCount; ++j) 598e5c31af7Sopenharmony_ci { 599e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pStages[j].stage == VK_SHADER_STAGE_VERTEX_BIT) 600e5c31af7Sopenharmony_ci { 601e5c31af7Sopenharmony_ci vertexInputStateRequired = true; 602e5c31af7Sopenharmony_ci inputAssemblyStateRequired = true; 603e5c31af7Sopenharmony_ci } 604e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pStages[j].stage == VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) 605e5c31af7Sopenharmony_ci { 606e5c31af7Sopenharmony_ci tessellationStateRequired = true; 607e5c31af7Sopenharmony_ci } 608e5c31af7Sopenharmony_ci } 609e5c31af7Sopenharmony_ci } 610e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pDynamicState != DE_NULL) 611e5c31af7Sopenharmony_ci { 612e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pDynamicState->pDynamicStates != DE_NULL) 613e5c31af7Sopenharmony_ci for (deUint32 j = 0; j < pCreateInfoCopies[i].pDynamicState->dynamicStateCount; ++j) 614e5c31af7Sopenharmony_ci { 615e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_VIEWPORT || pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT) 616e5c31af7Sopenharmony_ci { 617e5c31af7Sopenharmony_ci viewportStateRequired = true; 618e5c31af7Sopenharmony_ci viewportStateViewportsRequired = true; 619e5c31af7Sopenharmony_ci } 620e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_SCISSOR || pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT) 621e5c31af7Sopenharmony_ci { 622e5c31af7Sopenharmony_ci viewportStateRequired = true; 623e5c31af7Sopenharmony_ci viewportStateScissorsRequired = true; 624e5c31af7Sopenharmony_ci } 625e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pDynamicState->pDynamicStates[j] == VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT) 626e5c31af7Sopenharmony_ci viewportStateRequired = true; 627e5c31af7Sopenharmony_ci } 628e5c31af7Sopenharmony_ci } 629e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pRasterizationState != DE_NULL) 630e5c31af7Sopenharmony_ci { 631e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pRasterizationState->rasterizerDiscardEnable == VK_FALSE) 632e5c31af7Sopenharmony_ci { 633e5c31af7Sopenharmony_ci viewportStateRequired = true; 634e5c31af7Sopenharmony_ci viewportStateViewportsRequired = true; 635e5c31af7Sopenharmony_ci viewportStateScissorsRequired = true; 636e5c31af7Sopenharmony_ci multiSampleStateRequired = true; 637e5c31af7Sopenharmony_ci depthStencilStateRequired = true; 638e5c31af7Sopenharmony_ci colorBlendStateRequired = true; 639e5c31af7Sopenharmony_ci } 640e5c31af7Sopenharmony_ci } 641e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pVertexInputState != DE_NULL && !vertexInputStateRequired) 642e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pVertexInputState = DE_NULL; 643e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pInputAssemblyState != DE_NULL && !inputAssemblyStateRequired) 644e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pInputAssemblyState = DE_NULL; 645e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pTessellationState != DE_NULL && !tessellationStateRequired) 646e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pTessellationState = DE_NULL; 647e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pViewportState != DE_NULL) 648e5c31af7Sopenharmony_ci { 649e5c31af7Sopenharmony_ci if (viewportStateRequired) 650e5c31af7Sopenharmony_ci { 651e5c31af7Sopenharmony_ci viewportStateCopies[i] = *(pCreateInfoCopies[i].pViewportState); 652e5c31af7Sopenharmony_ci bool exchangeVP = false; 653e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pViewportState->pViewports != DE_NULL && !viewportStateViewportsRequired) 654e5c31af7Sopenharmony_ci { 655e5c31af7Sopenharmony_ci viewportStateCopies[i].pViewports = DE_NULL; 656e5c31af7Sopenharmony_ci viewportStateCopies[i].viewportCount = 0u; 657e5c31af7Sopenharmony_ci exchangeVP = true; 658e5c31af7Sopenharmony_ci } 659e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pViewportState->pScissors != DE_NULL && !viewportStateScissorsRequired) 660e5c31af7Sopenharmony_ci { 661e5c31af7Sopenharmony_ci viewportStateCopies[i].pScissors = DE_NULL; 662e5c31af7Sopenharmony_ci viewportStateCopies[i].scissorCount = 0u; 663e5c31af7Sopenharmony_ci exchangeVP = true; 664e5c31af7Sopenharmony_ci } 665e5c31af7Sopenharmony_ci if (exchangeVP) 666e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pViewportState = &(viewportStateCopies[i]); 667e5c31af7Sopenharmony_ci } 668e5c31af7Sopenharmony_ci else 669e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pViewportState = DE_NULL; 670e5c31af7Sopenharmony_ci } 671e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pMultisampleState != DE_NULL && !multiSampleStateRequired) 672e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pMultisampleState = DE_NULL; 673e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pDepthStencilState != DE_NULL && !depthStencilStateRequired) 674e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pDepthStencilState = DE_NULL; 675e5c31af7Sopenharmony_ci if (pCreateInfoCopies[i].pColorBlendState != DE_NULL && !colorBlendStateRequired) 676e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pColorBlendState = DE_NULL; 677e5c31af7Sopenharmony_ci } 678e5c31af7Sopenharmony_ci } 679e5c31af7Sopenharmony_ci 680e5c31af7Sopenharmony_ci // Include pipelineIdentifiers into pNext chain of pCreateInfoCopies - skip this operation if pipeline identifier was created inside test 681e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < createInfoCount; ++i) 682e5c31af7Sopenharmony_ci { 683e5c31af7Sopenharmony_ci if (idInPNextChain[i] == 0) 684e5c31af7Sopenharmony_ci { 685e5c31af7Sopenharmony_ci pipelineIDs[i].pNext = pCreateInfoCopies[i].pNext; 686e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pNext = &pipelineIDs[i]; 687e5c31af7Sopenharmony_ci } 688e5c31af7Sopenharmony_ci } 689e5c31af7Sopenharmony_ci 690e5c31af7Sopenharmony_ci // subprocess: load graphics pipelines from OUR m_pipelineCache cache 691e5c31af7Sopenharmony_ci if (normalMode) 692e5c31af7Sopenharmony_ci { 693e5c31af7Sopenharmony_ci const auto it = m_createGraphicsPipelinesFunc.find(device); 694e5c31af7Sopenharmony_ci if (it != end(m_createGraphicsPipelinesFunc)) 695e5c31af7Sopenharmony_ci { 696e5c31af7Sopenharmony_ci auto pit = m_pipelineCache.find(device); 697e5c31af7Sopenharmony_ci if ( pit != end(m_pipelineCache) ) 698e5c31af7Sopenharmony_ci { 699e5c31af7Sopenharmony_ci VkPipelineCache pCache = pit->second->get(); 700e5c31af7Sopenharmony_ci return it->second(device, pCache, createInfoCount, pCreateInfoCopies.data(), pAllocator, pPipelines); 701e5c31af7Sopenharmony_ci } 702e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "m_pipelineCache not initialized for this device"); 703e5c31af7Sopenharmony_ci } 704e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "vkCreateGraphicsPipelines not defined"); 705e5c31af7Sopenharmony_ci } 706e5c31af7Sopenharmony_ci 707e5c31af7Sopenharmony_ci // main process: store pipelines in JSON format. Pipelines will be sent later for m_pipelineCache creation ( and sent through file to another process ) 708e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < createInfoCount; ++i) 709e5c31af7Sopenharmony_ci { 710e5c31af7Sopenharmony_ci m_pipelineIdentifiers.insert({ pPipelines[i], pipelineIDs[i] }); 711e5c31af7Sopenharmony_ci 712e5c31af7Sopenharmony_ci auto it = std::find_if(begin(m_pipelineInput.pipelines), end(m_pipelineInput.pipelines), vksc_server::PipelineIdentifierEqual(pipelineIDs[i])); 713e5c31af7Sopenharmony_ci pipelineIDs[i].pNext = DE_NULL; 714e5c31af7Sopenharmony_ci if (it == end(m_pipelineInput.pipelines)) 715e5c31af7Sopenharmony_ci { 716e5c31af7Sopenharmony_ci const auto& featIt = m_deviceFeatures.find(device); 717e5c31af7Sopenharmony_ci if(featIt == end(m_deviceFeatures)) 718e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Can't find device features for this pipeline"); 719e5c31af7Sopenharmony_ci const auto& extIt = m_deviceExtensions.find(device); 720e5c31af7Sopenharmony_ci if (extIt == end(m_deviceExtensions)) 721e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Can't find device extensions for this pipeline"); 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_ci m_pipelineInput.pipelines.push_back(vksc_server::VulkanJsonPipelineDescription( 724e5c31af7Sopenharmony_ci pipelineIDs[i], 725e5c31af7Sopenharmony_ci writeJSON_VkGraphicsPipelineCreateInfo(pCreateInfoCopies[i]), 726e5c31af7Sopenharmony_ci featIt->second, 727e5c31af7Sopenharmony_ci extIt->second, 728e5c31af7Sopenharmony_ci m_currentTestPath)); 729e5c31af7Sopenharmony_ci } 730e5c31af7Sopenharmony_ci else 731e5c31af7Sopenharmony_ci it->add(m_currentTestPath); 732e5c31af7Sopenharmony_ci } 733e5c31af7Sopenharmony_ci return VK_SUCCESS; 734e5c31af7Sopenharmony_ci} 735e5c31af7Sopenharmony_ci 736e5c31af7Sopenharmony_ciVkResult ResourceInterfaceStandard::createComputePipelines (VkDevice device, 737e5c31af7Sopenharmony_ci VkPipelineCache pipelineCache, 738e5c31af7Sopenharmony_ci deUint32 createInfoCount, 739e5c31af7Sopenharmony_ci const VkComputePipelineCreateInfo* pCreateInfos, 740e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 741e5c31af7Sopenharmony_ci VkPipeline* pPipelines, 742e5c31af7Sopenharmony_ci bool normalMode) const 743e5c31af7Sopenharmony_ci{ 744e5c31af7Sopenharmony_ci DE_UNREF(pipelineCache); 745e5c31af7Sopenharmony_ci 746e5c31af7Sopenharmony_ci // build pipeline identifiers (if required), make a copy of pCreateInfos 747e5c31af7Sopenharmony_ci std::vector<VkPipelineOfflineCreateInfo> pipelineIDs; 748e5c31af7Sopenharmony_ci std::vector<deUint8> idInPNextChain; 749e5c31af7Sopenharmony_ci std::vector<VkComputePipelineCreateInfo> pCreateInfoCopies; 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < createInfoCount; ++i) 752e5c31af7Sopenharmony_ci { 753e5c31af7Sopenharmony_ci pCreateInfoCopies.push_back(pCreateInfos[i]); 754e5c31af7Sopenharmony_ci 755e5c31af7Sopenharmony_ci // Check if test added pipeline identifier on its own 756e5c31af7Sopenharmony_ci VkPipelineOfflineCreateInfo* idInfo = (VkPipelineOfflineCreateInfo*)findStructureInChain(pCreateInfos[i].pNext, VK_STRUCTURE_TYPE_PIPELINE_OFFLINE_CREATE_INFO); 757e5c31af7Sopenharmony_ci if (idInfo == DE_NULL) 758e5c31af7Sopenharmony_ci { 759e5c31af7Sopenharmony_ci pipelineIDs.push_back(makeComputePipelineIdentifier(m_currentTestPath, pCreateInfos[i], getObjectHashes())); 760e5c31af7Sopenharmony_ci idInPNextChain.push_back(0); 761e5c31af7Sopenharmony_ci } 762e5c31af7Sopenharmony_ci else 763e5c31af7Sopenharmony_ci { 764e5c31af7Sopenharmony_ci pipelineIDs.push_back(*idInfo); 765e5c31af7Sopenharmony_ci idInPNextChain.push_back(1); 766e5c31af7Sopenharmony_ci } 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci if (normalMode) 769e5c31af7Sopenharmony_ci fillPoolEntrySize(pipelineIDs.back()); 770e5c31af7Sopenharmony_ci } 771e5c31af7Sopenharmony_ci 772e5c31af7Sopenharmony_ci // Include pipelineIdentifiers into pNext chain of pCreateInfoCopies - skip this operation if pipeline identifier was created inside test 773e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < createInfoCount; ++i) 774e5c31af7Sopenharmony_ci { 775e5c31af7Sopenharmony_ci if (idInPNextChain[i] == 0) 776e5c31af7Sopenharmony_ci { 777e5c31af7Sopenharmony_ci pipelineIDs[i].pNext = pCreateInfoCopies[i].pNext; 778e5c31af7Sopenharmony_ci pCreateInfoCopies[i].pNext = &pipelineIDs[i]; 779e5c31af7Sopenharmony_ci } 780e5c31af7Sopenharmony_ci } 781e5c31af7Sopenharmony_ci 782e5c31af7Sopenharmony_ci // subprocess: load compute pipelines from OUR pipeline cache 783e5c31af7Sopenharmony_ci if (normalMode) 784e5c31af7Sopenharmony_ci { 785e5c31af7Sopenharmony_ci const auto it = m_createComputePipelinesFunc.find(device); 786e5c31af7Sopenharmony_ci if (it != end(m_createComputePipelinesFunc)) 787e5c31af7Sopenharmony_ci { 788e5c31af7Sopenharmony_ci auto pit = m_pipelineCache.find(device); 789e5c31af7Sopenharmony_ci if ( pit != end(m_pipelineCache) ) 790e5c31af7Sopenharmony_ci { 791e5c31af7Sopenharmony_ci VkPipelineCache pCache = pit->second->get(); 792e5c31af7Sopenharmony_ci return it->second(device, pCache, createInfoCount, pCreateInfoCopies.data(), pAllocator, pPipelines); 793e5c31af7Sopenharmony_ci } 794e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "m_pipelineCache not initialized for this device"); 795e5c31af7Sopenharmony_ci } 796e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "vkCreateComputePipelines not defined"); 797e5c31af7Sopenharmony_ci } 798e5c31af7Sopenharmony_ci 799e5c31af7Sopenharmony_ci // main process: store pipelines in JSON format. Pipelines will be sent later for m_pipelineCache creation ( and sent through file to another process ) 800e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < createInfoCount; ++i) 801e5c31af7Sopenharmony_ci { 802e5c31af7Sopenharmony_ci m_pipelineIdentifiers.insert({ pPipelines[i], pipelineIDs[i] }); 803e5c31af7Sopenharmony_ci 804e5c31af7Sopenharmony_ci auto it = std::find_if(begin(m_pipelineInput.pipelines), end(m_pipelineInput.pipelines), vksc_server::PipelineIdentifierEqual(pipelineIDs[i])); 805e5c31af7Sopenharmony_ci pipelineIDs[i].pNext = DE_NULL; 806e5c31af7Sopenharmony_ci if (it == end(m_pipelineInput.pipelines)) 807e5c31af7Sopenharmony_ci { 808e5c31af7Sopenharmony_ci const auto& featIt = m_deviceFeatures.find(device); 809e5c31af7Sopenharmony_ci if (featIt == end(m_deviceFeatures)) 810e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Can't find device features for this pipeline"); 811e5c31af7Sopenharmony_ci const auto& extIt = m_deviceExtensions.find(device); 812e5c31af7Sopenharmony_ci if (extIt == end(m_deviceExtensions)) 813e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Can't find device extensions for this pipeline"); 814e5c31af7Sopenharmony_ci 815e5c31af7Sopenharmony_ci m_pipelineInput.pipelines.push_back(vksc_server::VulkanJsonPipelineDescription( 816e5c31af7Sopenharmony_ci pipelineIDs[i], 817e5c31af7Sopenharmony_ci writeJSON_VkComputePipelineCreateInfo(pCreateInfoCopies[i]), 818e5c31af7Sopenharmony_ci featIt->second, 819e5c31af7Sopenharmony_ci extIt->second, 820e5c31af7Sopenharmony_ci m_currentTestPath)); 821e5c31af7Sopenharmony_ci } 822e5c31af7Sopenharmony_ci else 823e5c31af7Sopenharmony_ci it->add(m_currentTestPath); 824e5c31af7Sopenharmony_ci } 825e5c31af7Sopenharmony_ci return VK_SUCCESS; 826e5c31af7Sopenharmony_ci} 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::destroyPipeline (VkDevice device, 829e5c31af7Sopenharmony_ci VkPipeline pipeline, 830e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator) const 831e5c31af7Sopenharmony_ci{ 832e5c31af7Sopenharmony_ci DE_UNREF(device); 833e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 834e5c31af7Sopenharmony_ci 835e5c31af7Sopenharmony_ci auto it = m_pipelineIdentifiers.find(pipeline); 836e5c31af7Sopenharmony_ci if(it==end(m_pipelineIdentifiers)) 837e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Can't find pipeline"); 838e5c31af7Sopenharmony_ci 839e5c31af7Sopenharmony_ci auto pit = std::find_if(begin(m_pipelineInput.pipelines), end(m_pipelineInput.pipelines), vksc_server::PipelineIdentifierEqual(it->second)); 840e5c31af7Sopenharmony_ci if (pit == end(m_pipelineInput.pipelines)) 841e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Can't find pipeline identifier"); 842e5c31af7Sopenharmony_ci pit->remove(); 843e5c31af7Sopenharmony_ci} 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createRenderPass (VkDevice device, 846e5c31af7Sopenharmony_ci const VkRenderPassCreateInfo* pCreateInfo, 847e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 848e5c31af7Sopenharmony_ci VkRenderPass* pRenderPass) const 849e5c31af7Sopenharmony_ci{ 850e5c31af7Sopenharmony_ci DE_UNREF(device); 851e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 852e5c31af7Sopenharmony_ci m_pipelineInput.renderPasses.insert({ *pRenderPass, writeJSON_VkRenderPassCreateInfo(*pCreateInfo) }); 853e5c31af7Sopenharmony_ci} 854e5c31af7Sopenharmony_ci 855e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createRenderPass2 (VkDevice device, 856e5c31af7Sopenharmony_ci const VkRenderPassCreateInfo2* pCreateInfo, 857e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 858e5c31af7Sopenharmony_ci VkRenderPass* pRenderPass) const 859e5c31af7Sopenharmony_ci{ 860e5c31af7Sopenharmony_ci DE_UNREF(device); 861e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 862e5c31af7Sopenharmony_ci m_pipelineInput.renderPasses.insert({ *pRenderPass, writeJSON_VkRenderPassCreateInfo2(*pCreateInfo) }); 863e5c31af7Sopenharmony_ci} 864e5c31af7Sopenharmony_ci 865e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createPipelineLayout (VkDevice device, 866e5c31af7Sopenharmony_ci const VkPipelineLayoutCreateInfo* pCreateInfo, 867e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 868e5c31af7Sopenharmony_ci VkPipelineLayout* pPipelineLayout) const 869e5c31af7Sopenharmony_ci{ 870e5c31af7Sopenharmony_ci DE_UNREF(device); 871e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 872e5c31af7Sopenharmony_ci m_pipelineInput.pipelineLayouts.insert({*pPipelineLayout, writeJSON_VkPipelineLayoutCreateInfo(*pCreateInfo) }); 873e5c31af7Sopenharmony_ci} 874e5c31af7Sopenharmony_ci 875e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createDescriptorSetLayout (VkDevice device, 876e5c31af7Sopenharmony_ci const VkDescriptorSetLayoutCreateInfo* pCreateInfo, 877e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 878e5c31af7Sopenharmony_ci VkDescriptorSetLayout* pSetLayout) const 879e5c31af7Sopenharmony_ci{ 880e5c31af7Sopenharmony_ci DE_UNREF(device); 881e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 882e5c31af7Sopenharmony_ci m_pipelineInput.descriptorSetLayouts.insert({ *pSetLayout, writeJSON_VkDescriptorSetLayoutCreateInfo(*pCreateInfo) }); 883e5c31af7Sopenharmony_ci} 884e5c31af7Sopenharmony_ci 885e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createSampler (VkDevice device, 886e5c31af7Sopenharmony_ci const VkSamplerCreateInfo* pCreateInfo, 887e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 888e5c31af7Sopenharmony_ci VkSampler* pSampler) const 889e5c31af7Sopenharmony_ci{ 890e5c31af7Sopenharmony_ci DE_UNREF(device); 891e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 892e5c31af7Sopenharmony_ci m_pipelineInput.samplers.insert({ *pSampler, writeJSON_VkSamplerCreateInfo(*pCreateInfo) }); 893e5c31af7Sopenharmony_ci} 894e5c31af7Sopenharmony_ci 895e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createSamplerYcbcrConversion (VkDevice device, 896e5c31af7Sopenharmony_ci const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, 897e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 898e5c31af7Sopenharmony_ci VkSamplerYcbcrConversion* pYcbcrConversion) const 899e5c31af7Sopenharmony_ci{ 900e5c31af7Sopenharmony_ci DE_UNREF(device); 901e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 902e5c31af7Sopenharmony_ci m_pipelineInput.samplerYcbcrConversions.insert({ *pYcbcrConversion, writeJSON_VkSamplerYcbcrConversionCreateInfo(*pCreateInfo) }); 903e5c31af7Sopenharmony_ci} 904e5c31af7Sopenharmony_ci 905e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::createCommandPool (VkDevice device, 906e5c31af7Sopenharmony_ci const VkCommandPoolCreateInfo* pCreateInfo, 907e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 908e5c31af7Sopenharmony_ci VkCommandPool* pCommandPool) const 909e5c31af7Sopenharmony_ci{ 910e5c31af7Sopenharmony_ci DE_UNREF(device); 911e5c31af7Sopenharmony_ci DE_UNREF(pCreateInfo); 912e5c31af7Sopenharmony_ci DE_UNREF(pAllocator); 913e5c31af7Sopenharmony_ci m_commandPoolMemoryConsumption.push_back(vksc_server::VulkanCommandMemoryConsumption(pCommandPool->getInternal())); 914e5c31af7Sopenharmony_ci} 915e5c31af7Sopenharmony_ci 916e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::allocateCommandBuffers (VkDevice device, 917e5c31af7Sopenharmony_ci const VkCommandBufferAllocateInfo* pAllocateInfo, 918e5c31af7Sopenharmony_ci VkCommandBuffer* pCommandBuffers) const 919e5c31af7Sopenharmony_ci{ 920e5c31af7Sopenharmony_ci DE_UNREF(device); 921e5c31af7Sopenharmony_ci for (deUint32 i = 0; i < pAllocateInfo->commandBufferCount; ++i) 922e5c31af7Sopenharmony_ci { 923e5c31af7Sopenharmony_ci m_commandBufferMemoryConsumption.insert({ pCommandBuffers[i], vksc_server::VulkanCommandMemoryConsumption(pAllocateInfo->commandPool.getInternal()) }); 924e5c31af7Sopenharmony_ci } 925e5c31af7Sopenharmony_ci} 926e5c31af7Sopenharmony_ci 927e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::increaseCommandBufferSize (VkCommandBuffer commandBuffer, 928e5c31af7Sopenharmony_ci VkDeviceSize commandSize) const 929e5c31af7Sopenharmony_ci{ 930e5c31af7Sopenharmony_ci auto it = m_commandBufferMemoryConsumption.find(commandBuffer); 931e5c31af7Sopenharmony_ci if (it == end(m_commandBufferMemoryConsumption)) 932e5c31af7Sopenharmony_ci TCU_THROW(InternalError, "Unregistered command buffer"); 933e5c31af7Sopenharmony_ci 934e5c31af7Sopenharmony_ci it->second.updateValues(commandSize, commandSize, commandSize); 935e5c31af7Sopenharmony_ci} 936e5c31af7Sopenharmony_ci 937e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::resetCommandPool (VkDevice device, 938e5c31af7Sopenharmony_ci VkCommandPool commandPool, 939e5c31af7Sopenharmony_ci VkCommandPoolResetFlags flags) const 940e5c31af7Sopenharmony_ci{ 941e5c31af7Sopenharmony_ci DE_UNREF(device); 942e5c31af7Sopenharmony_ci DE_UNREF(flags); 943e5c31af7Sopenharmony_ci 944e5c31af7Sopenharmony_ci for (auto& memC : m_commandBufferMemoryConsumption) 945e5c31af7Sopenharmony_ci { 946e5c31af7Sopenharmony_ci if (memC.second.commandPool == commandPool.getInternal()) 947e5c31af7Sopenharmony_ci memC.second.resetValues(); 948e5c31af7Sopenharmony_ci } 949e5c31af7Sopenharmony_ci} 950e5c31af7Sopenharmony_ci 951e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::importPipelineCacheData (const PlatformInterface& vkp, 952e5c31af7Sopenharmony_ci VkInstance instance, 953e5c31af7Sopenharmony_ci const InstanceInterface& vki, 954e5c31af7Sopenharmony_ci VkPhysicalDevice physicalDevice, 955e5c31af7Sopenharmony_ci deUint32 queueIndex) 956e5c31af7Sopenharmony_ci{ 957e5c31af7Sopenharmony_ci if(!std::string(m_testCtx.getCommandLine().getPipelineCompilerPath()).empty()) 958e5c31af7Sopenharmony_ci { 959e5c31af7Sopenharmony_ci m_cacheData = vksc_server::buildOfflinePipelineCache(m_pipelineInput, 960e5c31af7Sopenharmony_ci std::string( m_testCtx.getCommandLine().getPipelineCompilerPath()), 961e5c31af7Sopenharmony_ci std::string( m_testCtx.getCommandLine().getPipelineCompilerDataDir()), 962e5c31af7Sopenharmony_ci std::string( m_testCtx.getCommandLine().getPipelineCompilerArgs()), 963e5c31af7Sopenharmony_ci std::string( m_testCtx.getCommandLine().getPipelineCompilerOutputFile()), 964e5c31af7Sopenharmony_ci std::string( m_testCtx.getCommandLine().getPipelineCompilerLogFile()), 965e5c31af7Sopenharmony_ci std::string( m_testCtx.getCommandLine().getPipelineCompilerFilePrefix()) ); 966e5c31af7Sopenharmony_ci } 967e5c31af7Sopenharmony_ci else 968e5c31af7Sopenharmony_ci { 969e5c31af7Sopenharmony_ci m_cacheData = vksc_server::buildPipelineCache(m_pipelineInput, vkp, instance, vki, physicalDevice, queueIndex); 970e5c31af7Sopenharmony_ci } 971e5c31af7Sopenharmony_ci 972e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkanSC10Properties vulkanSC10Properties = initVulkanStructure(); 973e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties2 deviceProperties2 = initVulkanStructure(&vulkanSC10Properties); 974e5c31af7Sopenharmony_ci vki.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2); 975e5c31af7Sopenharmony_ci 976e5c31af7Sopenharmony_ci m_pipelineSizes = vksc_server::extractSizesFromPipelineCache( m_pipelineInput, m_cacheData, deUint32(m_testCtx.getCommandLine().getPipelineDefaultSize()), vulkanSC10Properties.recyclePipelineMemory == VK_TRUE); 977e5c31af7Sopenharmony_ci preparePipelinePoolSizes(); 978e5c31af7Sopenharmony_ci} 979e5c31af7Sopenharmony_ci 980e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::resetObjects () 981e5c31af7Sopenharmony_ci{ 982e5c31af7Sopenharmony_ci m_pipelineInput = {}; 983e5c31af7Sopenharmony_ci m_objectHashes.clear(); 984e5c31af7Sopenharmony_ci m_commandPoolMemoryConsumption.clear(); 985e5c31af7Sopenharmony_ci m_commandPoolIndex = 0u; 986e5c31af7Sopenharmony_ci m_commandBufferMemoryConsumption.clear(); 987e5c31af7Sopenharmony_ci m_resourceCounter = 0u; 988e5c31af7Sopenharmony_ci m_statCurrent = resetDeviceObjectReservationCreateInfo(); 989e5c31af7Sopenharmony_ci m_statMax = resetDeviceObjectReservationCreateInfo(); 990e5c31af7Sopenharmony_ci // pipelineCacheRequestCount does not contain one instance of createPipelineCache call that happens only in subprocess 991e5c31af7Sopenharmony_ci m_statCurrent.pipelineCacheRequestCount = 1u; 992e5c31af7Sopenharmony_ci m_statMax.pipelineCacheRequestCount = 1u; 993e5c31af7Sopenharmony_ci m_cacheData.clear(); 994e5c31af7Sopenharmony_ci m_pipelineIdentifiers.clear(); 995e5c31af7Sopenharmony_ci m_pipelineSizes.clear(); 996e5c31af7Sopenharmony_ci m_pipelinePoolSizes.clear(); 997e5c31af7Sopenharmony_ci runGarbageCollection(); 998e5c31af7Sopenharmony_ci} 999e5c31af7Sopenharmony_ci 1000e5c31af7Sopenharmony_civoid ResourceInterfaceStandard::resetPipelineCaches () 1001e5c31af7Sopenharmony_ci{ 1002e5c31af7Sopenharmony_ci if (m_testCtx.getCommandLine().isSubProcess()) 1003e5c31af7Sopenharmony_ci { 1004e5c31af7Sopenharmony_ci m_pipelineCache.clear(); 1005e5c31af7Sopenharmony_ci } 1006e5c31af7Sopenharmony_ci} 1007e5c31af7Sopenharmony_ci 1008e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 1009e5c31af7Sopenharmony_ci 1010e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceStandard::compileProgram (const vk::ProgramIdentifier& progId, 1011e5c31af7Sopenharmony_ci const vk::GlslSource& source, 1012e5c31af7Sopenharmony_ci glu::ShaderProgramInfo* buildInfo, 1013e5c31af7Sopenharmony_ci const tcu::CommandLine& commandLine) 1014e5c31af7Sopenharmony_ci{ 1015e5c31af7Sopenharmony_ci DE_UNREF(progId); 1016e5c31af7Sopenharmony_ci return vk::buildProgram(source, buildInfo, commandLine); 1017e5c31af7Sopenharmony_ci} 1018e5c31af7Sopenharmony_ci 1019e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceStandard::compileProgram (const vk::ProgramIdentifier& progId, 1020e5c31af7Sopenharmony_ci const vk::HlslSource& source, 1021e5c31af7Sopenharmony_ci glu::ShaderProgramInfo* buildInfo, 1022e5c31af7Sopenharmony_ci const tcu::CommandLine& commandLine) 1023e5c31af7Sopenharmony_ci{ 1024e5c31af7Sopenharmony_ci DE_UNREF(progId); 1025e5c31af7Sopenharmony_ci return vk::buildProgram(source, buildInfo, commandLine); 1026e5c31af7Sopenharmony_ci} 1027e5c31af7Sopenharmony_ci 1028e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceStandard::compileProgram (const vk::ProgramIdentifier& progId, 1029e5c31af7Sopenharmony_ci const vk::SpirVAsmSource& source, 1030e5c31af7Sopenharmony_ci vk::SpirVProgramInfo* buildInfo, 1031e5c31af7Sopenharmony_ci const tcu::CommandLine& commandLine) 1032e5c31af7Sopenharmony_ci{ 1033e5c31af7Sopenharmony_ci DE_UNREF(progId); 1034e5c31af7Sopenharmony_ci return vk::assembleProgram(source, buildInfo, commandLine); 1035e5c31af7Sopenharmony_ci} 1036e5c31af7Sopenharmony_ci 1037e5c31af7Sopenharmony_ci#ifdef CTS_USES_VULKANSC 1038e5c31af7Sopenharmony_ci 1039e5c31af7Sopenharmony_ciResourceInterfaceVKSC::ResourceInterfaceVKSC (tcu::TestContext& testCtx) 1040e5c31af7Sopenharmony_ci : ResourceInterfaceStandard(testCtx) 1041e5c31af7Sopenharmony_ci{ 1042e5c31af7Sopenharmony_ci m_address = std::string(testCtx.getCommandLine().getServerAddress()); 1043e5c31af7Sopenharmony_ci} 1044e5c31af7Sopenharmony_ci 1045e5c31af7Sopenharmony_civksc_server::Server* ResourceInterfaceVKSC::getServer () 1046e5c31af7Sopenharmony_ci{ 1047e5c31af7Sopenharmony_ci if (!m_server) 1048e5c31af7Sopenharmony_ci { 1049e5c31af7Sopenharmony_ci m_server = std::make_shared<vksc_server::Server>(m_address); 1050e5c31af7Sopenharmony_ci } 1051e5c31af7Sopenharmony_ci return m_server.get(); 1052e5c31af7Sopenharmony_ci} 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_cibool ResourceInterfaceVKSC::noServer () const 1055e5c31af7Sopenharmony_ci{ 1056e5c31af7Sopenharmony_ci return m_address.empty(); 1057e5c31af7Sopenharmony_ci} 1058e5c31af7Sopenharmony_ci 1059e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceVKSC::compileProgram (const vk::ProgramIdentifier& progId, 1060e5c31af7Sopenharmony_ci const vk::GlslSource& source, 1061e5c31af7Sopenharmony_ci glu::ShaderProgramInfo* buildInfo, 1062e5c31af7Sopenharmony_ci const tcu::CommandLine& commandLine) 1063e5c31af7Sopenharmony_ci{ 1064e5c31af7Sopenharmony_ci if (noServer()) return ResourceInterfaceStandard::compileProgram(progId, source, buildInfo, commandLine); 1065e5c31af7Sopenharmony_ci 1066e5c31af7Sopenharmony_ci DE_UNREF(progId); 1067e5c31af7Sopenharmony_ci DE_UNREF(buildInfo); 1068e5c31af7Sopenharmony_ci 1069e5c31af7Sopenharmony_ci vksc_server::CompileShaderRequest request; 1070e5c31af7Sopenharmony_ci request.source.active = "glsl"; 1071e5c31af7Sopenharmony_ci request.source.glsl = source; 1072e5c31af7Sopenharmony_ci request.commandLine = commandLine.getInitialCmdLine(); 1073e5c31af7Sopenharmony_ci vksc_server::CompileShaderResponse response; 1074e5c31af7Sopenharmony_ci getServer()->SendRequest(request, response); 1075e5c31af7Sopenharmony_ci 1076e5c31af7Sopenharmony_ci return new ProgramBinary(PROGRAM_FORMAT_SPIRV, response.binary.size(), response.binary.data()); 1077e5c31af7Sopenharmony_ci} 1078e5c31af7Sopenharmony_ci 1079e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceVKSC::compileProgram (const vk::ProgramIdentifier& progId, 1080e5c31af7Sopenharmony_ci const vk::HlslSource& source, 1081e5c31af7Sopenharmony_ci glu::ShaderProgramInfo* buildInfo, 1082e5c31af7Sopenharmony_ci const tcu::CommandLine& commandLine) 1083e5c31af7Sopenharmony_ci{ 1084e5c31af7Sopenharmony_ci if (noServer()) return ResourceInterfaceStandard::compileProgram(progId, source, buildInfo, commandLine); 1085e5c31af7Sopenharmony_ci 1086e5c31af7Sopenharmony_ci DE_UNREF(progId); 1087e5c31af7Sopenharmony_ci DE_UNREF(buildInfo); 1088e5c31af7Sopenharmony_ci 1089e5c31af7Sopenharmony_ci vksc_server::CompileShaderRequest request; 1090e5c31af7Sopenharmony_ci request.source.active = "hlsl"; 1091e5c31af7Sopenharmony_ci request.source.hlsl = source; 1092e5c31af7Sopenharmony_ci request.commandLine = commandLine.getInitialCmdLine(); 1093e5c31af7Sopenharmony_ci vksc_server::CompileShaderResponse response; 1094e5c31af7Sopenharmony_ci getServer()->SendRequest(request, response); 1095e5c31af7Sopenharmony_ci 1096e5c31af7Sopenharmony_ci return new ProgramBinary(PROGRAM_FORMAT_SPIRV, response.binary.size(), response.binary.data()); 1097e5c31af7Sopenharmony_ci} 1098e5c31af7Sopenharmony_ci 1099e5c31af7Sopenharmony_civk::ProgramBinary* ResourceInterfaceVKSC::compileProgram (const vk::ProgramIdentifier& progId, 1100e5c31af7Sopenharmony_ci const vk::SpirVAsmSource& source, 1101e5c31af7Sopenharmony_ci vk::SpirVProgramInfo* buildInfo, 1102e5c31af7Sopenharmony_ci const tcu::CommandLine& commandLine) 1103e5c31af7Sopenharmony_ci{ 1104e5c31af7Sopenharmony_ci if (noServer()) return ResourceInterfaceStandard::compileProgram(progId, source, buildInfo, commandLine); 1105e5c31af7Sopenharmony_ci 1106e5c31af7Sopenharmony_ci DE_UNREF(progId); 1107e5c31af7Sopenharmony_ci DE_UNREF(buildInfo); 1108e5c31af7Sopenharmony_ci 1109e5c31af7Sopenharmony_ci vksc_server::CompileShaderRequest request; 1110e5c31af7Sopenharmony_ci request.source.active = "spirv"; 1111e5c31af7Sopenharmony_ci request.source.spirv = source; 1112e5c31af7Sopenharmony_ci request.commandLine = commandLine.getInitialCmdLine(); 1113e5c31af7Sopenharmony_ci vksc_server::CompileShaderResponse response; 1114e5c31af7Sopenharmony_ci getServer()->SendRequest(request, response); 1115e5c31af7Sopenharmony_ci 1116e5c31af7Sopenharmony_ci return new ProgramBinary(PROGRAM_FORMAT_SPIRV, response.binary.size(), response.binary.data()); 1117e5c31af7Sopenharmony_ci} 1118e5c31af7Sopenharmony_ci 1119e5c31af7Sopenharmony_ciVkResult ResourceInterfaceVKSC::createShaderModule (VkDevice device, 1120e5c31af7Sopenharmony_ci const VkShaderModuleCreateInfo* pCreateInfo, 1121e5c31af7Sopenharmony_ci const VkAllocationCallbacks* pAllocator, 1122e5c31af7Sopenharmony_ci VkShaderModule* pShaderModule, 1123e5c31af7Sopenharmony_ci bool normalMode) const 1124e5c31af7Sopenharmony_ci{ 1125e5c31af7Sopenharmony_ci if (noServer() || !normalMode || !isVulkanSC()) 1126e5c31af7Sopenharmony_ci return ResourceInterfaceStandard::createShaderModule(device, pCreateInfo, pAllocator, pShaderModule, normalMode); 1127e5c31af7Sopenharmony_ci 1128e5c31af7Sopenharmony_ci // We will reach this place only in one case: 1129e5c31af7Sopenharmony_ci // - server exists 1130e5c31af7Sopenharmony_ci // - subprocess asks for creation of VkShaderModule which will be later ignored, because it will receive the whole pipeline from server 1131e5c31af7Sopenharmony_ci // ( Are there any tests which receive VkShaderModule and do not use it in any pipeline ? ) 1132e5c31af7Sopenharmony_ci *pShaderModule = VkShaderModule(++m_resourceCounter); 1133e5c31af7Sopenharmony_ci registerObjectHash(pShaderModule->getInternal(), calculateShaderModuleHash(*pCreateInfo, getObjectHashes())); 1134e5c31af7Sopenharmony_ci return VK_SUCCESS; 1135e5c31af7Sopenharmony_ci} 1136e5c31af7Sopenharmony_ci 1137e5c31af7Sopenharmony_ci 1138e5c31af7Sopenharmony_civoid ResourceInterfaceVKSC::importPipelineCacheData (const PlatformInterface& vkp, 1139e5c31af7Sopenharmony_ci VkInstance instance, 1140e5c31af7Sopenharmony_ci const InstanceInterface& vki, 1141e5c31af7Sopenharmony_ci VkPhysicalDevice physicalDevice, 1142e5c31af7Sopenharmony_ci deUint32 queueIndex) 1143e5c31af7Sopenharmony_ci{ 1144e5c31af7Sopenharmony_ci if (noServer()) 1145e5c31af7Sopenharmony_ci { 1146e5c31af7Sopenharmony_ci ResourceInterfaceStandard::importPipelineCacheData(vkp, instance, vki, physicalDevice, queueIndex); 1147e5c31af7Sopenharmony_ci return; 1148e5c31af7Sopenharmony_ci } 1149e5c31af7Sopenharmony_ci 1150e5c31af7Sopenharmony_ci vksc_server::CreateCacheRequest request; 1151e5c31af7Sopenharmony_ci request.input = m_pipelineInput; 1152e5c31af7Sopenharmony_ci std::vector<int> caseFraction = m_testCtx.getCommandLine().getCaseFraction(); 1153e5c31af7Sopenharmony_ci request.caseFraction = caseFraction.empty() ? -1 : caseFraction[0]; 1154e5c31af7Sopenharmony_ci 1155e5c31af7Sopenharmony_ci vksc_server::CreateCacheResponse response; 1156e5c31af7Sopenharmony_ci getServer()->SendRequest(request, response); 1157e5c31af7Sopenharmony_ci 1158e5c31af7Sopenharmony_ci if (response.status) 1159e5c31af7Sopenharmony_ci { 1160e5c31af7Sopenharmony_ci m_cacheData = std::move(response.binary); 1161e5c31af7Sopenharmony_ci 1162e5c31af7Sopenharmony_ci VkPhysicalDeviceVulkanSC10Properties vulkanSC10Properties = initVulkanStructure(); 1163e5c31af7Sopenharmony_ci VkPhysicalDeviceProperties2 deviceProperties2 = initVulkanStructure(&vulkanSC10Properties); 1164e5c31af7Sopenharmony_ci vki.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties2); 1165e5c31af7Sopenharmony_ci 1166e5c31af7Sopenharmony_ci m_pipelineSizes = vksc_server::extractSizesFromPipelineCache( m_pipelineInput, m_cacheData, deUint32(m_testCtx.getCommandLine().getPipelineDefaultSize()), vulkanSC10Properties.recyclePipelineMemory == VK_TRUE); 1167e5c31af7Sopenharmony_ci preparePipelinePoolSizes(); 1168e5c31af7Sopenharmony_ci } 1169e5c31af7Sopenharmony_ci else { TCU_THROW(InternalError, "Server did not return pipeline cache data when requested (check server log for details)"); } 1170e5c31af7Sopenharmony_ci} 1171e5c31af7Sopenharmony_ci 1172e5c31af7Sopenharmony_ciMultithreadedDestroyGuard::MultithreadedDestroyGuard (de::SharedPtr<vk::ResourceInterface> resourceInterface) 1173e5c31af7Sopenharmony_ci : m_resourceInterface{ resourceInterface } 1174e5c31af7Sopenharmony_ci{ 1175e5c31af7Sopenharmony_ci if (m_resourceInterface.get() != DE_NULL) 1176e5c31af7Sopenharmony_ci m_resourceInterface->setHandleDestroy(false); 1177e5c31af7Sopenharmony_ci} 1178e5c31af7Sopenharmony_ci 1179e5c31af7Sopenharmony_ciMultithreadedDestroyGuard::~MultithreadedDestroyGuard () 1180e5c31af7Sopenharmony_ci{ 1181e5c31af7Sopenharmony_ci if (m_resourceInterface.get() != DE_NULL) 1182e5c31af7Sopenharmony_ci m_resourceInterface->setHandleDestroy(true); 1183e5c31af7Sopenharmony_ci} 1184e5c31af7Sopenharmony_ci 1185e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 1186e5c31af7Sopenharmony_ci 1187e5c31af7Sopenharmony_ci 1188e5c31af7Sopenharmony_ci} // namespace vk 1189