• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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