Home | History | Annotate | Download | only in synchronization
      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 <string>
     34 
     35 namespace vkt
     36 {
     37 namespace synchronization
     38 {
     39 
     40 enum OperationName
     41 {
     42 	// Write operations
     43 	OPERATION_NAME_WRITE_FILL_BUFFER,
     44 	OPERATION_NAME_WRITE_UPDATE_BUFFER,
     45 	OPERATION_NAME_WRITE_COPY_BUFFER,
     46 	OPERATION_NAME_WRITE_COPY_BUFFER_TO_IMAGE,
     47 	OPERATION_NAME_WRITE_COPY_IMAGE_TO_BUFFER,
     48 	OPERATION_NAME_WRITE_COPY_IMAGE,
     49 	OPERATION_NAME_WRITE_BLIT_IMAGE,
     50 	OPERATION_NAME_WRITE_SSBO_VERTEX,
     51 	OPERATION_NAME_WRITE_SSBO_TESSELLATION_CONTROL,
     52 	OPERATION_NAME_WRITE_SSBO_TESSELLATION_EVALUATION,
     53 	OPERATION_NAME_WRITE_SSBO_GEOMETRY,
     54 	OPERATION_NAME_WRITE_SSBO_FRAGMENT,
     55 	OPERATION_NAME_WRITE_SSBO_COMPUTE,
     56 	OPERATION_NAME_WRITE_SSBO_COMPUTE_INDIRECT,
     57 	OPERATION_NAME_WRITE_IMAGE_VERTEX,
     58 	OPERATION_NAME_WRITE_IMAGE_TESSELLATION_CONTROL,
     59 	OPERATION_NAME_WRITE_IMAGE_TESSELLATION_EVALUATION,
     60 	OPERATION_NAME_WRITE_IMAGE_GEOMETRY,
     61 	OPERATION_NAME_WRITE_IMAGE_FRAGMENT,
     62 	OPERATION_NAME_WRITE_IMAGE_COMPUTE,
     63 	OPERATION_NAME_WRITE_IMAGE_COMPUTE_INDIRECT,
     64 	OPERATION_NAME_WRITE_CLEAR_COLOR_IMAGE,
     65 	OPERATION_NAME_WRITE_CLEAR_DEPTH_STENCIL_IMAGE,
     66 	OPERATION_NAME_WRITE_DRAW,
     67 	OPERATION_NAME_WRITE_DRAW_INDEXED,
     68 	OPERATION_NAME_WRITE_DRAW_INDIRECT,
     69 	OPERATION_NAME_WRITE_DRAW_INDEXED_INDIRECT,
     70 	OPERATION_NAME_WRITE_CLEAR_ATTACHMENTS,
     71 	OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW,
     72 	OPERATION_NAME_WRITE_INDIRECT_BUFFER_DRAW_INDEXED,
     73 	OPERATION_NAME_WRITE_INDIRECT_BUFFER_DISPATCH,
     74 
     75 	// Read operations
     76 	OPERATION_NAME_READ_COPY_BUFFER,
     77 	OPERATION_NAME_READ_COPY_BUFFER_TO_IMAGE,
     78 	OPERATION_NAME_READ_COPY_IMAGE_TO_BUFFER,
     79 	OPERATION_NAME_READ_COPY_IMAGE,
     80 	OPERATION_NAME_READ_BLIT_IMAGE,
     81 	OPERATION_NAME_READ_UBO_VERTEX,
     82 	OPERATION_NAME_READ_UBO_TESSELLATION_CONTROL,
     83 	OPERATION_NAME_READ_UBO_TESSELLATION_EVALUATION,
     84 	OPERATION_NAME_READ_UBO_GEOMETRY,
     85 	OPERATION_NAME_READ_UBO_FRAGMENT,
     86 	OPERATION_NAME_READ_UBO_COMPUTE,
     87 	OPERATION_NAME_READ_UBO_COMPUTE_INDIRECT,
     88 	OPERATION_NAME_READ_SSBO_VERTEX,
     89 	OPERATION_NAME_READ_SSBO_TESSELLATION_CONTROL,
     90 	OPERATION_NAME_READ_SSBO_TESSELLATION_EVALUATION,
     91 	OPERATION_NAME_READ_SSBO_GEOMETRY,
     92 	OPERATION_NAME_READ_SSBO_FRAGMENT,
     93 	OPERATION_NAME_READ_SSBO_COMPUTE,
     94 	OPERATION_NAME_READ_SSBO_COMPUTE_INDIRECT,
     95 	OPERATION_NAME_READ_IMAGE_VERTEX,
     96 	OPERATION_NAME_READ_IMAGE_TESSELLATION_CONTROL,
     97 	OPERATION_NAME_READ_IMAGE_TESSELLATION_EVALUATION,
     98 	OPERATION_NAME_READ_IMAGE_GEOMETRY,
     99 	OPERATION_NAME_READ_IMAGE_FRAGMENT,
    100 	OPERATION_NAME_READ_IMAGE_COMPUTE,
    101 	OPERATION_NAME_READ_IMAGE_COMPUTE_INDIRECT,
    102 	OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW,
    103 	OPERATION_NAME_READ_INDIRECT_BUFFER_DRAW_INDEXED,
    104 	OPERATION_NAME_READ_INDIRECT_BUFFER_DISPATCH,
    105 	OPERATION_NAME_READ_VERTEX_INPUT,
    106 };
    107 
    108 // Similar to Context, but allows test instance to decide which resources are used by the operation.
    109 // E.g. this is needed when we want operation to work on a particular queue instead of the universal queue.
    110 class OperationContext
    111 {
    112 public:
    113 									OperationContext		(Context&			context,
    114 															 PipelineCacheData&	pipelineCacheData);
    115 
    116 									OperationContext		(Context&					context,
    117 															 PipelineCacheData&			pipelineCacheData,
    118 															 const vk::DeviceInterface&	vk,
    119 															 const vk::VkDevice			device,
    120 															 vk::Allocator&				allocator);
    121 
    122 									OperationContext		(const deUint32						apiVersion,
    123 															 const vk::InstanceInterface&		vki,
    124 															 const vk::DeviceInterface&			vkd,
    125 															 vk::VkPhysicalDevice				physicalDevice,
    126 															 vk::VkDevice						device,
    127 															 vk::Allocator&						allocator,
    128 															 const std::vector<std::string>&	deviceExtensions,
    129 															 vk::BinaryCollection&				programCollection,
    130 															 PipelineCacheData&					pipelineCacheData);
    131 
    132 	const vk::InstanceInterface&	getInstanceInterface	(void) const { return m_vki; }
    133 	const vk::DeviceInterface&		getDeviceInterface		(void) const { return m_vk; }
    134 	vk::VkPhysicalDevice			getPhysicalDevice		(void) const { return m_physicalDevice; }
    135 	vk::VkDevice					getDevice				(void) const { return m_device; }
    136 	vk::Allocator&					getAllocator			(void) const { return m_allocator; }
    137 	vk::BinaryCollection&			getBinaryCollection		(void) const { return m_progCollection; }
    138 	PipelineCacheData&				getPipelineCacheData	(void) const { return m_pipelineCacheData; }
    139 	const std::vector<std::string>&	getDeviceExtensions		(void) const { return m_deviceExtensions;}
    140 	deUint32						getUsedApiVersion		(void) const { return m_usedApiVersion; }
    141 
    142 
    143 private:
    144 	const vk::InstanceInterface&	m_vki;
    145 	const vk::DeviceInterface&		m_vk;
    146 	const vk::VkPhysicalDevice		m_physicalDevice;
    147 	const vk::VkDevice				m_device;
    148 	vk::Allocator&					m_allocator;
    149 	vk::BinaryCollection&			m_progCollection;
    150 	PipelineCacheData&				m_pipelineCacheData;
    151 	const std::vector<std::string>&	m_deviceExtensions;
    152 	const deUint32					m_usedApiVersion;
    153 
    154 	// Disabled
    155 									OperationContext		(const OperationContext&);
    156 	OperationContext&				operator=				(const OperationContext&);
    157 };
    158 
    159 // Common interface to images and buffers used by operations.
    160 class Resource
    161 {
    162 public:
    163 							Resource	(OperationContext&				context,
    164 										 const ResourceDescription&		desc,
    165 										 const deUint32					usage,
    166 										 const vk::VkSharingMode		sharingMode = vk::VK_SHARING_MODE_EXCLUSIVE,
    167 										 const std::vector<deUint32>&	queueFamilyIndex = std::vector<deUint32>());
    168 
    169 							Resource	(ResourceType					type,
    170 										 vk::Move<vk::VkBuffer>			buffer,
    171 										 de::MovePtr<vk::Allocation>	allocation,
    172 										 vk::VkDeviceSize				offset,
    173 										 vk::VkDeviceSize				size);
    174 
    175 							Resource	(vk::Move<vk::VkImage>			image,
    176 										 de::MovePtr<vk::Allocation>	allocation,
    177 										 const vk::VkExtent3D&			extent,
    178 										 vk::VkImageType				imageType,
    179 										 vk::VkFormat					format,
    180 										 vk::VkImageSubresourceRange	subresourceRange,
    181 										 vk::VkImageSubresourceLayers	subresourceLayers);
    182 
    183 	ResourceType			getType		(void) const { return m_type; }
    184 	const BufferResource&	getBuffer	(void) const { return m_bufferData; }
    185 	const ImageResource&	getImage	(void) const { return m_imageData; }
    186 
    187 	vk::VkDeviceMemory		getMemory	(void) const;
    188 
    189 private:
    190 	const ResourceType		m_type;
    191 	de::MovePtr<Buffer>		m_buffer;
    192 	BufferResource			m_bufferData;
    193 	de::MovePtr<Image>		m_image;
    194 	ImageResource			m_imageData;
    195 };
    196 
    197 // \note Meaning of image layout is different for read and write types of operations:
    198 //       read  - the layout image must be in before being passed to the read operation
    199 //       write - the layout image will be in after the write operation has finished
    200 struct SyncInfo
    201 {
    202 	vk::VkPipelineStageFlags	stageMask;		// pipeline stage where read/write takes place
    203 	vk::VkAccessFlags			accessMask;		// type of access that is performed
    204 	vk::VkImageLayout			imageLayout;	// src (for reads) or dst (for writes) image layout
    205 };
    206 
    207 struct Data
    208 {
    209 	std::size_t					size;
    210 	const deUint8*				data;
    211 };
    212 
    213 // Abstract operation on a resource
    214 // \note Meaning of getData is different for read and write operations:
    215 //       read  - data actually read by the operation
    216 //       write - expected data that operation was supposed to write
    217 // \note It's assumed that recordCommands is called only once (i.e. no multiple command buffers are using these commands).
    218 class Operation
    219 {
    220 public:
    221 						Operation		(void) {}
    222 	virtual				~Operation		(void) {}
    223 
    224 	virtual void		recordCommands	(const vk::VkCommandBuffer cmdBuffer) = 0;	// commands that carry out this operation
    225 	virtual SyncInfo	getSyncInfo		(void) const = 0;							// data required to properly synchronize this operation
    226 	virtual Data		getData			(void) const = 0;							// get raw data that was written to or read from actual resource
    227 
    228 private:
    229 						Operation		(const Operation&);
    230 	Operation&			operator=		(const Operation&);
    231 };
    232 
    233 // A helper class to init programs and create the operation when context becomes available.
    234 // Throws OperationInvalidResourceError when resource and operation combination is not possible (e.g. buffer-specific op on an image).
    235 class OperationSupport
    236 {
    237 public:
    238 									OperationSupport		(void) {}
    239 	virtual							~OperationSupport		(void) {}
    240 
    241 	virtual deUint32				getResourceUsageFlags	(void) const = 0;
    242 	virtual vk::VkQueueFlags		getQueueFlags			(const OperationContext& context) const = 0;
    243 	virtual void					initPrograms			(vk::SourceCollections&) const {}	//!< empty by default
    244 
    245 	virtual de::MovePtr<Operation>	build					(OperationContext& context, Resource& resource) const = 0;
    246 
    247 private:
    248 									OperationSupport		(const OperationSupport&);
    249 	OperationSupport&				operator=				(const OperationSupport&);
    250 };
    251 
    252 bool							isResourceSupported		(const OperationName opName, const ResourceDescription& resourceDesc);
    253 de::MovePtr<OperationSupport>	makeOperationSupport	(const OperationName opName, const ResourceDescription& resourceDesc);
    254 std::string						getOperationName		(const OperationName opName);
    255 
    256 } // synchronization
    257 } // vkt
    258 
    259 #endif // _VKTSYNCHRONIZATIONOPERATION_HPP
    260