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 
getInstanceInterface(void) const132 	const vk::InstanceInterface&	getInstanceInterface	(void) const { return m_vki; }
getDeviceInterface(void) const133 	const vk::DeviceInterface&		getDeviceInterface		(void) const { return m_vk; }
getPhysicalDevice(void) const134 	vk::VkPhysicalDevice			getPhysicalDevice		(void) const { return m_physicalDevice; }
getDevice(void) const135 	vk::VkDevice					getDevice				(void) const { return m_device; }
getAllocator(void) const136 	vk::Allocator&					getAllocator			(void) const { return m_allocator; }
getBinaryCollection(void) const137 	vk::BinaryCollection&			getBinaryCollection		(void) const { return m_progCollection; }
getPipelineCacheData(void) const138 	PipelineCacheData&				getPipelineCacheData	(void) const { return m_pipelineCacheData; }
getDeviceExtensions(void) const139 	const std::vector<std::string>&	getDeviceExtensions		(void) const { return m_deviceExtensions;}
getUsedApiVersion(void) const140 	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 
getType(void) const183 	ResourceType			getType		(void) const { return m_type; }
getBuffer(void) const184 	const BufferResource&	getBuffer	(void) const { return m_bufferData; }
getImage(void) const185 	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:
Operation(void)221 						Operation		(void) {}
~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:
OperationSupport(void)238 									OperationSupport		(void) {}
~OperationSupport(void)239 	virtual							~OperationSupport		(void) {}
240 
241 	virtual deUint32				getResourceUsageFlags	(void) const = 0;
242 	virtual vk::VkQueueFlags		getQueueFlags			(const OperationContext& context) const = 0;
initPrograms(vk::SourceCollections &) const243 	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