1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2018 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2018 Danylo Piliaiev <danylo.piliaiev@gmail.com> 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 Conditional Rendering Test Utils 23e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include "vktConditionalRenderingTestUtil.hpp" 26e5c31af7Sopenharmony_ci#include "vktDrawCreateInfoUtil.hpp" 27e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_cinamespace vkt 32e5c31af7Sopenharmony_ci{ 33e5c31af7Sopenharmony_cinamespace conditional 34e5c31af7Sopenharmony_ci{ 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_civoid checkConditionalRenderingCapabilities (vkt::Context& context, const ConditionalData& data) 37e5c31af7Sopenharmony_ci{ 38e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_EXT_conditional_rendering"); 39e5c31af7Sopenharmony_ci 40e5c31af7Sopenharmony_ci const auto& conditionalRenderingFeatures = context.getConditionalRenderingFeaturesEXT(); 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ci if (conditionalRenderingFeatures.conditionalRendering == VK_FALSE) 43e5c31af7Sopenharmony_ci TCU_FAIL("conditionalRendering feature not supported but VK_EXT_conditional_rendering present"); 44e5c31af7Sopenharmony_ci 45e5c31af7Sopenharmony_ci if (data.conditionInherited && !conditionalRenderingFeatures.inheritedConditionalRendering) 46e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Device does not support inherited conditional rendering"); 47e5c31af7Sopenharmony_ci} 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_cide::SharedPtr<Draw::Buffer> createConditionalRenderingBuffer (vkt::Context& context, const ConditionalData& data) 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci const auto& vk = context.getDeviceInterface(); 52e5c31af7Sopenharmony_ci const auto device = context.getDevice(); 53e5c31af7Sopenharmony_ci const auto queueIndex = context.getUniversalQueueFamilyIndex(); 54e5c31af7Sopenharmony_ci const auto queue = context.getUniversalQueue(); 55e5c31af7Sopenharmony_ci auto& alloc = context.getDefaultAllocator(); 56e5c31af7Sopenharmony_ci 57e5c31af7Sopenharmony_ci // When padding the condition value, it will be surounded by two additional values with nonzero bytes in them. 58e5c31af7Sopenharmony_ci // When choosing to apply an offset to the allocation, the offset will be four times the size of the condition variable. 59e5c31af7Sopenharmony_ci const auto bufferSize = static_cast<vk::VkDeviceSize>(sizeof(data.conditionValue)) * (data.padConditionValue ? 3ull : 1ull); 60e5c31af7Sopenharmony_ci const auto dataOffset = static_cast<vk::VkDeviceSize>(data.padConditionValue ? sizeof(data.conditionValue) : 0); 61e5c31af7Sopenharmony_ci const auto allocOffset = static_cast<vk::VkDeviceSize>(sizeof(data.conditionValue) * (data.allocationOffset ? 4u : 0u)); 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci // Create host-visible buffer. This may be the final buffer or only a staging buffer. 64e5c31af7Sopenharmony_ci const auto hostUsage = ((data.memoryType == HOST) ? vk::VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT : vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT); 65e5c31af7Sopenharmony_ci de::SharedPtr<Draw::Buffer> hostBuffer = Draw::Buffer::createAndAlloc(vk, device, 66e5c31af7Sopenharmony_ci Draw::BufferCreateInfo(bufferSize, hostUsage), 67e5c31af7Sopenharmony_ci alloc, 68e5c31af7Sopenharmony_ci vk::MemoryRequirement::HostVisible, 69e5c31af7Sopenharmony_ci allocOffset); 70e5c31af7Sopenharmony_ci 71e5c31af7Sopenharmony_ci // Copy data to host buffer. 72e5c31af7Sopenharmony_ci deUint8* conditionBufferPtr = reinterpret_cast<deUint8*>(hostBuffer->getHostPtr()); 73e5c31af7Sopenharmony_ci deMemset(conditionBufferPtr, 1, static_cast<size_t>(bufferSize)); 74e5c31af7Sopenharmony_ci deMemcpy(conditionBufferPtr + dataOffset, &data.conditionValue, sizeof(data.conditionValue)); 75e5c31af7Sopenharmony_ci vk::flushAlloc(vk, context.getDevice(), hostBuffer->getBoundMemory()); 76e5c31af7Sopenharmony_ci 77e5c31af7Sopenharmony_ci // Return host buffer if appropriate. 78e5c31af7Sopenharmony_ci if (data.memoryType == HOST) 79e5c31af7Sopenharmony_ci return hostBuffer; 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ci // Create and return device-local buffer otherwise, after copying host-visible buffer contents to it. 82e5c31af7Sopenharmony_ci const auto deviceLocalUsage = (vk::VK_BUFFER_USAGE_CONDITIONAL_RENDERING_BIT_EXT | vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT); 83e5c31af7Sopenharmony_ci de::SharedPtr<Draw::Buffer> deviceLocalBuffer = Draw::Buffer::createAndAlloc(vk, device, 84e5c31af7Sopenharmony_ci Draw::BufferCreateInfo(bufferSize, deviceLocalUsage), 85e5c31af7Sopenharmony_ci alloc, 86e5c31af7Sopenharmony_ci vk::MemoryRequirement::Local, 87e5c31af7Sopenharmony_ci allocOffset); 88e5c31af7Sopenharmony_ci 89e5c31af7Sopenharmony_ci const auto cmdPool = vk::makeCommandPool(vk, device, queueIndex); 90e5c31af7Sopenharmony_ci const auto cmdBuffer = vk::allocateCommandBuffer (vk, device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY); 91e5c31af7Sopenharmony_ci const auto copyInfo = vk::makeBufferCopy(0ull, 0ull, bufferSize); 92e5c31af7Sopenharmony_ci 93e5c31af7Sopenharmony_ci vk::beginCommandBuffer(vk, *cmdBuffer); 94e5c31af7Sopenharmony_ci vk.cmdCopyBuffer(*cmdBuffer, hostBuffer->object(), deviceLocalBuffer->object(), 1, ©Info); 95e5c31af7Sopenharmony_ci vk::endCommandBuffer(vk, *cmdBuffer); 96e5c31af7Sopenharmony_ci vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer); 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci return deviceLocalBuffer; 99e5c31af7Sopenharmony_ci} 100e5c31af7Sopenharmony_ci 101e5c31af7Sopenharmony_civoid beginConditionalRendering (const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, Draw::Buffer& buffer, const ConditionalData& data) 102e5c31af7Sopenharmony_ci{ 103e5c31af7Sopenharmony_ci vk::VkConditionalRenderingBeginInfoEXT conditionalRenderingBeginInfo; 104e5c31af7Sopenharmony_ci conditionalRenderingBeginInfo.sType = vk::VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT; 105e5c31af7Sopenharmony_ci conditionalRenderingBeginInfo.pNext = nullptr; 106e5c31af7Sopenharmony_ci conditionalRenderingBeginInfo.buffer = buffer.object(); 107e5c31af7Sopenharmony_ci conditionalRenderingBeginInfo.offset = static_cast<vk::VkDeviceSize>(data.padConditionValue ? sizeof(data.conditionValue) : 0u); 108e5c31af7Sopenharmony_ci conditionalRenderingBeginInfo.flags = data.conditionInverted ? vk::VK_CONDITIONAL_RENDERING_INVERTED_BIT_EXT : 0; 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci vk.cmdBeginConditionalRenderingEXT(cmdBuffer, &conditionalRenderingBeginInfo); 111e5c31af7Sopenharmony_ci} 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_cistd::ostream& operator<< (std::ostream& str, ConditionalData const& c) 114e5c31af7Sopenharmony_ci{ 115e5c31af7Sopenharmony_ci const bool conditionEnabled = c.conditionInPrimaryCommandBuffer || c.conditionInSecondaryCommandBuffer; 116e5c31af7Sopenharmony_ci str << (conditionEnabled ? "condition" : "no_condition"); 117e5c31af7Sopenharmony_ci str << (c.memoryType ? "_host_memory" : "_local_memory"); 118e5c31af7Sopenharmony_ci 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ci if (c.conditionInSecondaryCommandBuffer || !conditionEnabled) 121e5c31af7Sopenharmony_ci { 122e5c31af7Sopenharmony_ci str << "_secondary_buffer"; 123e5c31af7Sopenharmony_ci } 124e5c31af7Sopenharmony_ci 125e5c31af7Sopenharmony_ci if (c.conditionInherited) 126e5c31af7Sopenharmony_ci { 127e5c31af7Sopenharmony_ci str << "_inherited"; 128e5c31af7Sopenharmony_ci } 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci str << "_" << (c.expectCommandExecution ? "expect_execution" : "expect_noop"); 131e5c31af7Sopenharmony_ci 132e5c31af7Sopenharmony_ci if (c.conditionInverted) 133e5c31af7Sopenharmony_ci { 134e5c31af7Sopenharmony_ci str << "_inverted"; 135e5c31af7Sopenharmony_ci } 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ci if (c.padConditionValue) 138e5c31af7Sopenharmony_ci { 139e5c31af7Sopenharmony_ci str << "_padded"; 140e5c31af7Sopenharmony_ci } 141e5c31af7Sopenharmony_ci 142e5c31af7Sopenharmony_ci if (c.clearInRenderPass) 143e5c31af7Sopenharmony_ci { 144e5c31af7Sopenharmony_ci str << "_rp_clear"; 145e5c31af7Sopenharmony_ci } 146e5c31af7Sopenharmony_ci 147e5c31af7Sopenharmony_ci return str; 148e5c31af7Sopenharmony_ci} 149e5c31af7Sopenharmony_ci 150e5c31af7Sopenharmony_ci} // conditional 151e5c31af7Sopenharmony_ci} // vkt 152