1 #ifndef _VKTSYNCHRONIZATIONUTIL_HPP
2 #define _VKTSYNCHRONIZATIONUTIL_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 tests utilities
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vkDefs.hpp"
27 #include "vkQueryUtil.hpp"
28 #include "vkMemUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "tcuVector.hpp"
32 #include "deMutex.hpp"
33 
34 namespace vkt
35 {
36 namespace synchronization
37 {
38 
39 class Buffer
40 {
41 public:
Buffer(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkBufferCreateInfo & bufferCreateInfo,const vk::MemoryRequirement memoryRequirement)42 										Buffer			(const vk::DeviceInterface&		vk,
43 														 const vk::VkDevice				device,
44 														 vk::Allocator&					allocator,
45 														 const vk::VkBufferCreateInfo&	bufferCreateInfo,
46 														 const vk::MemoryRequirement	memoryRequirement)
47 		: m_buffer		(createBuffer(vk, device, &bufferCreateInfo))
48 		, m_allocation	(allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement))
49 	{
50 		VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset()));
51 	}
52 
Buffer(vk::Move<vk::VkBuffer> buffer,de::MovePtr<vk::Allocation> allocation)53 										Buffer			(vk::Move<vk::VkBuffer>			buffer,
54 														 de::MovePtr<vk::Allocation>	allocation)
55 		: m_buffer		(buffer)
56 		, m_allocation	(allocation)
57 	{
58 	}
59 
get(void) const60 	const vk::VkBuffer&					get				(void) const { return *m_buffer; }
operator *(void) const61 	const vk::VkBuffer&					operator*		(void) const { return get(); }
getAllocation(void) const62 	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }
63 
64 private:
65 	const vk::Unique<vk::VkBuffer>		m_buffer;
66 	const de::UniquePtr<vk::Allocation>	m_allocation;
67 
68 	// "deleted"
69 										Buffer			(const Buffer&);
70 	Buffer&								operator=		(const Buffer&);
71 };
72 
73 class Image
74 {
75 public:
Image(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkImageCreateInfo & imageCreateInfo,const vk::MemoryRequirement memoryRequirement)76 										Image			(const vk::DeviceInterface&		vk,
77 														 const vk::VkDevice				device,
78 														 vk::Allocator&					allocator,
79 														 const vk::VkImageCreateInfo&	imageCreateInfo,
80 														 const vk::MemoryRequirement	memoryRequirement)
81 		: m_image		(createImage(vk, device, &imageCreateInfo))
82 		, m_allocation	(allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement))
83 	{
84 		VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset()));
85 	}
Image(vk::Move<vk::VkImage> & image,de::MovePtr<vk::Allocation> & allocation)86 										Image			(vk::Move<vk::VkImage>&			image,
87 														 de::MovePtr<vk::Allocation>&	allocation)
88 		: m_image		(image)
89 		, m_allocation	(allocation)
90 	{
91 	}
92 
get(void) const93 	const vk::VkImage&					get				(void) const { return *m_image; }
operator *(void) const94 	const vk::VkImage&					operator*		(void) const { return get(); }
getAllocation(void) const95 	vk::Allocation&						getAllocation	(void) const { return *m_allocation; }
96 
97 private:
98 	const vk::Unique<vk::VkImage>		m_image;
99 	const de::UniquePtr<vk::Allocation>	m_allocation;
100 
101 	// "deleted"
102 										Image			(const Image&);
103 	Image&								operator=		(const Image&);
104 };
105 
106 class PipelineCacheData
107 {
108 public:
109 									PipelineCacheData		(void);
110 									~PipelineCacheData		(void);
111 
112 	vk::Move<vk::VkPipelineCache>	createPipelineCache		(const vk::DeviceInterface& vk, const vk::VkDevice device) const;
113 	void							setFromPipelineCache	(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache);
114 
115 private:
116 	mutable de::Mutex				m_lock;
117 	std::vector<deUint8>			m_data;
118 };
119 
120 class GraphicsPipelineBuilder
121 {
122 public:
GraphicsPipelineBuilder(void)123 								GraphicsPipelineBuilder	(void) : m_renderSize			(0, 0)
124 															   , m_shaderStageFlags		(0u)
125 															   , m_cullModeFlags		(vk::VK_CULL_MODE_NONE)
126 															   , m_frontFace			(vk::VK_FRONT_FACE_COUNTER_CLOCKWISE)
127 															   , m_patchControlPoints	(1u)
128 															   , m_blendEnable			(false)
129 															   , m_primitiveTopology	(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) {}
130 
setRenderSize(const tcu::IVec2 & size)131 	GraphicsPipelineBuilder&	setRenderSize					(const tcu::IVec2& size) { m_renderSize = size; return *this; }
132 	GraphicsPipelineBuilder&	setShader						(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkShaderStageFlagBits stage, const vk::ProgramBinary& binary, const vk::VkSpecializationInfo* specInfo);
setPatchControlPoints(const deUint32 controlPoints)133 	GraphicsPipelineBuilder&	setPatchControlPoints			(const deUint32 controlPoints) { m_patchControlPoints = controlPoints; return *this; }
setCullModeFlags(const vk::VkCullModeFlags cullModeFlags)134 	GraphicsPipelineBuilder&	setCullModeFlags				(const vk::VkCullModeFlags cullModeFlags) { m_cullModeFlags = cullModeFlags; return *this; }
setFrontFace(const vk::VkFrontFace frontFace)135 	GraphicsPipelineBuilder&	setFrontFace					(const vk::VkFrontFace frontFace) { m_frontFace = frontFace; return *this; }
setBlend(const bool enable)136 	GraphicsPipelineBuilder&	setBlend						(const bool enable) { m_blendEnable = enable; return *this; }
137 
138 	//! Applies only to pipelines without tessellation shaders.
setPrimitiveTopology(const vk::VkPrimitiveTopology topology)139 	GraphicsPipelineBuilder&	setPrimitiveTopology			(const vk::VkPrimitiveTopology topology) { m_primitiveTopology = topology; return *this; }
140 
addVertexBinding(const vk::VkVertexInputBindingDescription vertexBinding)141 	GraphicsPipelineBuilder&	addVertexBinding				(const vk::VkVertexInputBindingDescription vertexBinding) { m_vertexInputBindings.push_back(vertexBinding); return *this; }
addVertexAttribute(const vk::VkVertexInputAttributeDescription vertexAttribute)142 	GraphicsPipelineBuilder&	addVertexAttribute				(const vk::VkVertexInputAttributeDescription vertexAttribute) { m_vertexInputAttributes.push_back(vertexAttribute); return *this; }
143 
144 	//! Basic vertex input configuration (uses biding 0, location 0, etc.)
145 	GraphicsPipelineBuilder&	setVertexInputSingleAttribute	(const vk::VkFormat vertexFormat, const deUint32 stride);
146 
147 	vk::Move<vk::VkPipeline>	build							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkRenderPass renderPass, PipelineCacheData& pipelineCacheData);
148 
149 private:
150 	tcu::IVec2											m_renderSize;
151 	vk::Move<vk::VkShaderModule>						m_vertexShaderModule;
152 	vk::Move<vk::VkShaderModule>						m_fragmentShaderModule;
153 	vk::Move<vk::VkShaderModule>						m_geometryShaderModule;
154 	vk::Move<vk::VkShaderModule>						m_tessControlShaderModule;
155 	vk::Move<vk::VkShaderModule>						m_tessEvaluationShaderModule;
156 	std::vector<vk::VkPipelineShaderStageCreateInfo>	m_shaderStages;
157 	std::vector<vk::VkVertexInputBindingDescription>	m_vertexInputBindings;
158 	std::vector<vk::VkVertexInputAttributeDescription>	m_vertexInputAttributes;
159 	vk::VkShaderStageFlags								m_shaderStageFlags;
160 	vk::VkCullModeFlags									m_cullModeFlags;
161 	vk::VkFrontFace										m_frontFace;
162 	deUint32											m_patchControlPoints;
163 	bool												m_blendEnable;
164 	vk::VkPrimitiveTopology								m_primitiveTopology;
165 
166 	GraphicsPipelineBuilder (const GraphicsPipelineBuilder&); // "deleted"
167 	GraphicsPipelineBuilder& operator= (const GraphicsPipelineBuilder&);
168 };
169 
170 enum FeatureFlagBits
171 {
172 	FEATURE_TESSELLATION_SHADER							= 1u << 0,
173 	FEATURE_GEOMETRY_SHADER								= 1u << 1,
174 	FEATURE_SHADER_FLOAT_64								= 1u << 2,
175 	FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS			= 1u << 3,
176 	FEATURE_FRAGMENT_STORES_AND_ATOMICS					= 1u << 4,
177 	FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE	= 1u << 5,
178 	FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS		= 1u << 6,
179 };
180 typedef deUint32 FeatureFlags;
181 
182 enum SyncPrimitive
183 {
184 	SYNC_PRIMITIVE_FENCE,
185 	SYNC_PRIMITIVE_SEMAPHORE,
186 	SYNC_PRIMITIVE_BARRIER,
187 	SYNC_PRIMITIVE_EVENT,
188 };
189 
190 enum ResourceType
191 {
192 	RESOURCE_TYPE_BUFFER,
193 	RESOURCE_TYPE_IMAGE,
194 	RESOURCE_TYPE_INDIRECT_BUFFER_DRAW,
195 	RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED,
196 	RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH,
197 };
198 
199 struct ResourceDescription
200 {
201 	ResourceType					type;
202 	tcu::IVec4						size;			//!< unused components are 0, e.g. for buffers only x is meaningful
203 	vk::VkImageType					imageType;
204 	vk::VkFormat					imageFormat;
205 	vk::VkImageAspectFlags			imageAspect;
206 };
207 
208 struct BufferResource
209 {
210 	vk::VkBuffer					handle;
211 	vk::VkDeviceSize				offset;
212 	vk::VkDeviceSize				size;
213 };
214 
215 struct ImageResource
216 {
217 	vk::VkImage						handle;
218 	vk::VkExtent3D					extent;
219 	vk::VkImageType					imageType;
220 	vk::VkFormat					format;
221 	vk::VkImageSubresourceRange		subresourceRange;
222 	vk::VkImageSubresourceLayers	subresourceLayers;
223 };
224 
225 vk::VkBufferCreateInfo			makeBufferCreateInfo						(const vk::VkDeviceSize bufferSize, const vk::VkBufferUsageFlags usage);
226 vk::VkImageCreateInfo			makeImageCreateInfo							(const vk::VkImageType imageType, const vk::VkExtent3D& extent, const vk::VkFormat format, const vk::VkImageUsageFlags usage);
227 vk::Move<vk::VkCommandBuffer>	makeCommandBuffer							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkCommandPool commandPool);
228 vk::Move<vk::VkDescriptorSet>	makeDescriptorSet							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorPool descriptorPool, const vk::VkDescriptorSetLayout setLayout);
229 vk::Move<vk::VkPipelineLayout>	makePipelineLayout							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorSetLayout descriptorSetLayout);
230 vk::Move<vk::VkPipelineLayout>	makePipelineLayoutWithoutDescriptors		(const vk::DeviceInterface& vk, const vk::VkDevice device);
231 vk::Move<vk::VkPipeline>		makeComputePipeline							(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkShaderModule shaderModule, const vk::VkSpecializationInfo* specInfo, PipelineCacheData& pipelineCacheData);
232 vk::Move<vk::VkFramebuffer>		makeFramebuffer								(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkRenderPass renderPass, const vk::VkImageView colorAttachment, const deUint32 width, const deUint32 height, const deUint32 layers);
233 vk::Move<vk::VkImageView>		makeImageView								(const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkImage image, const vk::VkImageViewType viewType, const vk::VkFormat format, const vk::VkImageSubresourceRange subresourceRange);
234 vk::VkBufferImageCopy			makeBufferImageCopy							(const vk::VkImageSubresourceLayers subresourceLayers, const vk::VkExtent3D extent);
235 vk::VkMemoryBarrier				makeMemoryBarrier							(const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask);
236 void							beginRenderPassWithRasterizationDisabled	(const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer, const vk::VkRenderPass renderPass, const vk::VkFramebuffer framebuffer);
237 void							requireFeatures								(const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, const FeatureFlags flags);
238 std::string						getResourceName								(const ResourceDescription& resource);
239 bool							isIndirectBuffer							(const ResourceType type);
240 
241 } // synchronization
242 } // vkt
243 
244 #endif // _VKTSYNCHRONIZATIONUTIL_HPP
245