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