1 #ifndef _VKTSYNCHRONIZATIONOPERATION_HPP 2 #define _VKTSYNCHRONIZATIONOPERATION_HPP 3 /*------------------------------------------------------------------------ 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Synchronization operation abstraction 24 *//*--------------------------------------------------------------------*/ 25 26 #include "tcuDefs.hpp" 27 #include "vkDefs.hpp" 28 #include "vkPrograms.hpp" 29 #include "vktTestCase.hpp" 30 #include "vktSynchronizationUtil.hpp" 31 #include "tcuVector.hpp" 32 #include "deUniquePtr.hpp" 33 #include "vkResourceInterface.hpp" 34 #include <string> 35 36 namespace vkt 37 { 38 namespace synchronization 39 { 40 41 enum OperationName 42 { 43 // Write operations 44 OPERATION_NAME_WRITE_FILL_BUFFER, 45 OPERATION_NAME_WRITE_UPDATE_BUFFER, 46 OPERATION_NAME_WRITE_COPY_BUFFER, 47 OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE, 48 OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER, 49 OPERATION_NAME_WRITE_COPY_IMAGE, 50 OPERATION_NAME_WRITE_BLIT_IMAGE, 51 OPERATION_NAME_WRITE_SSBO_VERTEX, 52 OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL, 53 OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION, 54 OPERATION_NAME_WRITE_SSBO_GEOMETRY, 55 OPERATION_NAME_WRITE_SSBO_FRAGMENT, 56 OPERATION_NAME_WRITE_SSBO_COMPUTE, 57 OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT, 58 OPERATION_NAME_WRITE_IMAGE_VERTEX, 59 OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL, 60 OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION, 61 OPERATION_NAME_WRITE_IMAGE_GEOMETRY, 62 OPERATION_NAME_WRITE_IMAGE_FRAGMENT, 63 OPERATION_NAME_WRITE_IMAGE_COMPUTE, 64 OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT, 65 OPERATION_NAME_WRITE_IMAGE_COMPUTE_MULTISAMPLE, 66 OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE, 67 OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE, 68 OPERATION_NAME_WRITE_DRAW, 69 OPERATION_NAME_WRITE_DRAW_INDEXED, 70 OPERATION_NAME_WRITE_DRAW_INDIRECT, 71 OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT, 72 OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS, 73 OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW, 74 OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED, 75 OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH, 76 OPERATION_NAME_WRITE_UPDATE_INDEX_BUFFER, 77 78 // Read operations 79 OPERATION_NAME_READ_COPY_BUFFER, 80 OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE, 81 OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER, 82 OPERATION_NAME_READ_COPY_IMAGE, 83 OPERATION_NAME_READ_BLIT_IMAGE, 84 OPERATION_NAME_READ_RESOLVE_IMAGE, 85 OPERATION_NAME_READ_UBO_VERTEX, 86 OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL, 87 OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION, 88 OPERATION_NAME_READ_UBO_GEOMETRY, 89 OPERATION_NAME_READ_UBO_FRAGMENT, 90 OPERATION_NAME_READ_UBO_COMPUTE, 91 OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT, 92 OPERATION_NAME_READ_UBO_TEXEL_VERTEX, 93 OPERATION_NAME_READ_UBO_TEXEL_TESSELLATION_CONTROL, 94 OPERATION_NAME_READ_UBO_TEXEL_TESSELLATION_EVALUATION, 95 OPERATION_NAME_READ_UBO_TEXEL_GEOMETRY, 96 OPERATION_NAME_READ_UBO_TEXEL_FRAGMENT, 97 OPERATION_NAME_READ_UBO_TEXEL_COMPUTE, 98 OPERATION_NAME_READ_UBO_TEXEL_COMPUTE_INDIRECT, 99 OPERATION_NAME_READ_SSBO_VERTEX, 100 OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL, 101 OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION, 102 OPERATION_NAME_READ_SSBO_GEOMETRY, 103 OPERATION_NAME_READ_SSBO_FRAGMENT, 104 OPERATION_NAME_READ_SSBO_COMPUTE, 105 OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT, 106 OPERATION_NAME_READ_IMAGE_VERTEX, 107 OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL, 108 OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION, 109 OPERATION_NAME_READ_IMAGE_GEOMETRY, 110 OPERATION_NAME_READ_IMAGE_FRAGMENT, 111 OPERATION_NAME_READ_IMAGE_COMPUTE, 112 OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT, 113 OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW, 114 OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED, 115 OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH, 116 OPERATION_NAME_READ_VERTEX_INPUT, 117 OPERATION_NAME_READ_INDEX_INPUT, 118 119 // Copy operations 120 OPERATION_NAME_COPY_BUFFER, 121 OPERATION_NAME_COPY_IMAGE, 122 OPERATION_NAME_BLIT_IMAGE, 123 OPERATION_NAME_COPY_SSBO_VERTEX, 124 OPERATION_NAME_COPY_SSBO_TESSELLATION_CONTROL, 125 OPERATION_NAME_COPY_SSBO_TESSELLATION_EVALUATION, 126 OPERATION_NAME_COPY_SSBO_GEOMETRY, 127 OPERATION_NAME_COPY_SSBO_FRAGMENT, 128 OPERATION_NAME_COPY_SSBO_COMPUTE, 129 OPERATION_NAME_COPY_SSBO_COMPUTE_INDIRECT, 130 OPERATION_NAME_COPY_IMAGE_VERTEX, 131 OPERATION_NAME_COPY_IMAGE_TESSELLATION_CONTROL, 132 OPERATION_NAME_COPY_IMAGE_TESSELLATION_EVALUATION, 133 OPERATION_NAME_COPY_IMAGE_GEOMETRY, 134 OPERATION_NAME_COPY_IMAGE_FRAGMENT, 135 OPERATION_NAME_COPY_IMAGE_COMPUTE, 136 OPERATION_NAME_COPY_IMAGE_COMPUTE_INDIRECT, 137 }; 138 139 // Similar to Context, but allows test instance to decide which resources are used by the operation. 140 // E.g. this is needed when we want operation to work on a particular queue instead of the universal queue. 141 class OperationContext 142 { 143 public: 144 OperationContext (Context& context, 145 SynchronizationType syncType, 146 PipelineCacheData& pipelineCacheData); 147 148 OperationContext (Context& context, 149 SynchronizationType syncType, 150 const vk::DeviceInterface& vkd, 151 const vk::VkDevice device, 152 vk::Allocator& allocator, 153 PipelineCacheData& pipelineCacheData); 154 155 OperationContext (Context& context, 156 SynchronizationType syncType, 157 const vk::InstanceInterface& vki, 158 const vk::DeviceInterface& vkd, 159 vk::VkPhysicalDevice physicalDevice, 160 vk::VkDevice device, 161 vk::Allocator& allocator, 162 vk::BinaryCollection& programCollection, 163 PipelineCacheData& pipelineCacheData); 164 getSynchronizationType(void) const165 SynchronizationType getSynchronizationType (void) const { return m_syncType; } getInstanceInterface(void) const166 const vk::InstanceInterface& getInstanceInterface (void) const { return m_vki; } getDeviceInterface(void) const167 const vk::DeviceInterface& getDeviceInterface (void) const { return m_vk; } getPhysicalDevice(void) const168 vk::VkPhysicalDevice getPhysicalDevice (void) const { return m_physicalDevice; } getDevice(void) const169 vk::VkDevice getDevice (void) const { return m_device; } getAllocator(void) const170 vk::Allocator& getAllocator (void) const { return m_allocator; } getBinaryCollection(void) const171 vk::BinaryCollection& getBinaryCollection (void) const { return m_progCollection; } getPipelineCacheData(void) const172 PipelineCacheData& getPipelineCacheData (void) const { return m_pipelineCacheData; } 173 isDeviceFunctionalitySupported(const std::string & extension) const174 bool isDeviceFunctionalitySupported(const std::string& extension) const 175 { 176 return m_context.isDeviceFunctionalitySupported(extension); 177 } getResourceInterface(void) const178 de::SharedPtr<vk::ResourceInterface> getResourceInterface (void) const { return m_context.getResourceInterface(); } 179 private: 180 const vkt::Context& m_context; 181 const SynchronizationType m_syncType; 182 const vk::InstanceInterface& m_vki; 183 const vk::DeviceInterface& m_vk; 184 const vk::VkPhysicalDevice m_physicalDevice; 185 const vk::VkDevice m_device; 186 vk::Allocator& m_allocator; 187 vk::BinaryCollection& m_progCollection; 188 PipelineCacheData& m_pipelineCacheData; 189 190 // Disabled 191 OperationContext (const OperationContext&); 192 OperationContext& operator= (const OperationContext&); 193 }; 194 195 // Common interface to images and buffers used by operations. 196 class Resource 197 { 198 public: 199 Resource (OperationContext& context, 200 const ResourceDescription& desc, 201 const deUint32 usage, 202 const vk::VkSharingMode sharingMode = vk::VK_SHARING_MODE_EXCLUSIVE, 203 const std::vector<deUint32>& queueFamilyIndex = std::vector<deUint32>()); 204 205 Resource (ResourceType type, 206 vk::Move<vk::VkBuffer> buffer, 207 de::MovePtr<vk::Allocation> allocation, 208 vk::VkDeviceSize offset, 209 vk::VkDeviceSize size); 210 211 Resource (vk::Move<vk::VkImage> image, 212 de::MovePtr<vk::Allocation> allocation, 213 const vk::VkExtent3D& extent, 214 vk::VkImageType imageType, 215 vk::VkFormat format, 216 vk::VkImageSubresourceRange subresourceRange, 217 vk::VkImageSubresourceLayers subresourceLayers, 218 vk::VkImageTiling tiling); 219 getType(void) const220 ResourceType getType (void) const { return m_type; } getBuffer(void) const221 const BufferResource& getBuffer (void) const { DE_ASSERT(m_bufferData.get()); return *m_bufferData; } getImage(void) const222 const ImageResource& getImage (void) const { DE_ASSERT(m_imageData.get()); return *m_imageData; } 223 224 vk::VkDeviceMemory getMemory (void) const; 225 226 private: 227 const ResourceType m_type; 228 de::MovePtr<Buffer> m_buffer; 229 de::MovePtr<BufferResource> m_bufferData; 230 de::MovePtr<Image> m_image; 231 de::MovePtr<ImageResource> m_imageData; 232 }; 233 234 // \note Meaning of image layout is different for read and write types of operations: 235 // read - the layout image must be in before being passed to the read operation 236 // write - the layout image will be in after the write operation has finished 237 struct SyncInfo 238 { 239 vk::VkPipelineStageFlags2KHR stageMask; // pipeline stage where read/write takes place 240 vk::VkAccessFlags2KHR accessMask; // type of access that is performed 241 vk::VkImageLayout imageLayout; // src (for reads) or dst (for writes) image layout 242 }; 243 244 struct Data 245 { 246 std::size_t size; 247 const deUint8* data; 248 }; 249 250 // Abstract operation on a resource 251 // \note Meaning of getData is different for read and write operations: 252 // read - data actually read by the operation 253 // write - expected data that operation was supposed to write 254 // \note It's assumed that recordCommands is called only once (i.e. no multiple command buffers are using these commands). 255 class Operation 256 { 257 public: Operation(void)258 Operation (void) 259 : m_specializedAccess (false) 260 {} Operation(const bool specializedAccess)261 Operation (const bool specializedAccess) 262 : m_specializedAccess (specializedAccess) 263 {} ~Operation(void)264 virtual ~Operation (void) {} 265 266 virtual void recordCommands (const vk::VkCommandBuffer cmdBuffer) = 0; // commands that carry out this operation 267 virtual SyncInfo getInSyncInfo (void) const = 0; // data required to properly synchronize this operation 268 virtual SyncInfo getOutSyncInfo (void) const = 0; // data required to properly synchronize this operation 269 virtual Data getData (void) const = 0; // get raw data that was written to or read from actual resource 270 virtual void setData (const Data& data) = 0; // set raw data to be read from actual resource 271 272 private: 273 Operation (const Operation&); 274 Operation& operator= (const Operation&); 275 276 protected: 277 bool m_specializedAccess; 278 }; 279 280 // A helper class to init programs and create the operation when context becomes available. 281 // Throws OperationInvalidResourceError when resource and operation combination is not possible (e.g. buffer-specific op on an image). 282 class OperationSupport 283 { 284 public: OperationSupport(void)285 OperationSupport (void) 286 : m_specializedAccess (false) 287 {} OperationSupport(const bool specializedAccess)288 OperationSupport (const bool specializedAccess) 289 : m_specializedAccess (specializedAccess) 290 {} ~OperationSupport(void)291 virtual ~OperationSupport (void) {} 292 293 virtual deUint32 getInResourceUsageFlags (void) const = 0; 294 virtual deUint32 getOutResourceUsageFlags (void) const = 0; 295 virtual vk::VkQueueFlags getQueueFlags (const OperationContext& context) const = 0; initPrograms(vk::SourceCollections &) const296 virtual void initPrograms (vk::SourceCollections&) const {} //!< empty by default 297 298 virtual de::MovePtr<Operation> build (OperationContext& context, Resource& resource) const = 0; 299 virtual de::MovePtr<Operation> build (OperationContext& context, Resource& inResource, Resource& outResource) const = 0; 300 getShaderStage(void)301 virtual vk::VkShaderStageFlagBits getShaderStage (void) { return vk::VK_SHADER_STAGE_FLAG_BITS_MAX_ENUM; } 302 303 private: 304 OperationSupport (const OperationSupport&); 305 OperationSupport& operator= (const OperationSupport&); 306 307 protected: 308 bool m_specializedAccess; 309 }; 310 311 bool isResourceSupported (const OperationName opName, const ResourceDescription& resourceDesc); 312 bool isSpecializedAccessFlagSupported (const OperationName opName); 313 de::MovePtr<OperationSupport> makeOperationSupport (const OperationName opName, const ResourceDescription& resourceDesc, const bool specializedAccess = false); 314 std::string getOperationName (const OperationName opName); 315 bool isStageSupported (const vk::VkShaderStageFlagBits stage, const vk::VkQueueFlags queueFlags); 316 317 } // synchronization 318 } // vkt 319 320 #endif // _VKTSYNCHRONIZATIONOPERATION_HPP 321