• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Synchronization tests utilities
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSynchronizationUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include "deStringUtil.hpp"
27 
28 namespace vkt
29 {
30 namespace synchronization
31 {
32 using namespace vk;
33 
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)34 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize			bufferSize,
35 										 const VkBufferUsageFlags	usage)
36 {
37 	const VkBufferCreateInfo bufferCreateInfo =
38 	{
39 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
40 		DE_NULL,								// const void*			pNext;
41 		(VkBufferCreateFlags)0,					// VkBufferCreateFlags	flags;
42 		bufferSize,								// VkDeviceSize			size;
43 		usage,									// VkBufferUsageFlags	usage;
44 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
45 		0u,										// deUint32				queueFamilyIndexCount;
46 		DE_NULL,								// const deUint32*		pQueueFamilyIndices;
47 	};
48 	return bufferCreateInfo;
49 }
50 
makeMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask)51 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags	srcAccessMask,
52 								   const VkAccessFlags	dstAccessMask)
53 {
54 	const VkMemoryBarrier barrier =
55 	{
56 		VK_STRUCTURE_TYPE_MEMORY_BARRIER,	// VkStructureType    sType;
57 		DE_NULL,							// const void*        pNext;
58 		srcAccessMask,						// VkAccessFlags      srcAccessMask;
59 		dstAccessMask,						// VkAccessFlags      dstAccessMask;
60 	};
61 	return barrier;
62 }
63 
makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkBuffer buffer,const VkDeviceSize offset,const VkDeviceSize bufferSizeBytes)64 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags	srcAccessMask,
65 											   const VkAccessFlags	dstAccessMask,
66 											   const VkBuffer		buffer,
67 											   const VkDeviceSize	offset,
68 											   const VkDeviceSize	bufferSizeBytes)
69 {
70 	const VkBufferMemoryBarrier barrier =
71 	{
72 		VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,	// VkStructureType	sType;
73 		DE_NULL,									// const void*		pNext;
74 		srcAccessMask,								// VkAccessFlags	srcAccessMask;
75 		dstAccessMask,								// VkAccessFlags	dstAccessMask;
76 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			srcQueueFamilyIndex;
77 		VK_QUEUE_FAMILY_IGNORED,					// deUint32			destQueueFamilyIndex;
78 		buffer,										// VkBuffer			buffer;
79 		offset,										// VkDeviceSize		offset;
80 		bufferSizeBytes,							// VkDeviceSize		size;
81 	};
82 	return barrier;
83 }
84 
makeImageMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange subresourceRange)85 VkImageMemoryBarrier makeImageMemoryBarrier	(const VkAccessFlags			srcAccessMask,
86 											 const VkAccessFlags			dstAccessMask,
87 											 const VkImageLayout			oldLayout,
88 											 const VkImageLayout			newLayout,
89 											 const VkImage					image,
90 											 const VkImageSubresourceRange	subresourceRange)
91 {
92 	const VkImageMemoryBarrier barrier =
93 	{
94 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType			sType;
95 		DE_NULL,										// const void*				pNext;
96 		srcAccessMask,									// VkAccessFlags			outputMask;
97 		dstAccessMask,									// VkAccessFlags			inputMask;
98 		oldLayout,										// VkImageLayout			oldLayout;
99 		newLayout,										// VkImageLayout			newLayout;
100 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					srcQueueFamilyIndex;
101 		VK_QUEUE_FAMILY_IGNORED,						// deUint32					destQueueFamilyIndex;
102 		image,											// VkImage					image;
103 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
104 	};
105 	return barrier;
106 }
107 
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)108 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
109 {
110 	const VkCommandPoolCreateInfo info =
111 	{
112 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType;
113 		DE_NULL,											// const void*				pNext;
114 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags;
115 		queueFamilyIndex,									// deUint32					queueFamilyIndex;
116 	};
117 	return createCommandPool(vk, device, &info);
118 }
119 
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)120 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
121 {
122 	const VkCommandBufferAllocateInfo info =
123 	{
124 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
125 		DE_NULL,											// const void*			pNext;
126 		commandPool,										// VkCommandPool		commandPool;
127 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
128 		1u,													// deUint32				commandBufferCount;
129 	};
130 	return allocateCommandBuffer(vk, device, &info);
131 }
132 
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)133 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&			vk,
134 										 const VkDevice					device,
135 										 const VkDescriptorPool			descriptorPool,
136 										 const VkDescriptorSetLayout	setLayout)
137 {
138 	const VkDescriptorSetAllocateInfo info =
139 	{
140 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,		// VkStructureType				sType;
141 		DE_NULL,											// const void*					pNext;
142 		descriptorPool,										// VkDescriptorPool				descriptorPool;
143 		1u,													// deUint32						descriptorSetCount;
144 		&setLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
145 	};
146 	return allocateDescriptorSet(vk, device, &info);
147 }
148 
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)149 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&		vk,
150 										   const VkDevice				device,
151 										   const VkDescriptorSetLayout	descriptorSetLayout)
152 {
153 	const VkPipelineLayoutCreateInfo info =
154 	{
155 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
156 		DE_NULL,											// const void*					pNext;
157 		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
158 		1u,													// deUint32						setLayoutCount;
159 		&descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
160 		0u,													// deUint32						pushConstantRangeCount;
161 		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
162 	};
163 	return createPipelineLayout(vk, device, &info);
164 }
165 
makePipelineLayoutWithoutDescriptors(const DeviceInterface & vk,const VkDevice device)166 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&		vk,
167 															 const VkDevice				device)
168 {
169 	const VkPipelineLayoutCreateInfo info =
170 	{
171 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
172 		DE_NULL,											// const void*					pNext;
173 		(VkPipelineLayoutCreateFlags)0,						// VkPipelineLayoutCreateFlags	flags;
174 		0u,													// deUint32						setLayoutCount;
175 		DE_NULL,											// const VkDescriptorSetLayout*	pSetLayouts;
176 		0u,													// deUint32						pushConstantRangeCount;
177 		DE_NULL,											// const VkPushConstantRange*	pPushConstantRanges;
178 	};
179 	return createPipelineLayout(vk, device, &info);
180 }
181 
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specInfo,PipelineCacheData & pipelineCacheData)182 Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
183 									  const VkDevice				device,
184 									  const VkPipelineLayout		pipelineLayout,
185 									  const VkShaderModule			shaderModule,
186 									  const VkSpecializationInfo*	specInfo,
187 									  PipelineCacheData&			pipelineCacheData)
188 {
189 	const VkPipelineShaderStageCreateInfo shaderStageInfo =
190 	{
191 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
192 		DE_NULL,												// const void*						pNext;
193 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
194 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
195 		shaderModule,											// VkShaderModule					module;
196 		"main",													// const char*						pName;
197 		specInfo,												// const VkSpecializationInfo*		pSpecializationInfo;
198 	};
199 	const VkComputePipelineCreateInfo pipelineInfo =
200 	{
201 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
202 		DE_NULL,											// const void*						pNext;
203 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags			flags;
204 		shaderStageInfo,									// VkPipelineShaderStageCreateInfo	stage;
205 		pipelineLayout,										// VkPipelineLayout					layout;
206 		DE_NULL,											// VkPipeline						basePipelineHandle;
207 		0,													// deInt32							basePipelineIndex;
208 	};
209 
210 	{
211 		const vk::Unique<vk::VkPipelineCache>	pipelineCache	(pipelineCacheData.createPipelineCache(vk, device));
212 		vk::Move<vk::VkPipeline>				pipeline		(createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
213 
214 		// Refresh data from cache
215 		pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
216 
217 		return pipeline;
218 	}
219 }
220 
makeImageCreateInfo(const VkImageType imageType,const VkExtent3D & extent,const VkFormat format,const VkImageUsageFlags usage)221 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
222 {
223 	const VkImageCreateInfo imageInfo =
224 	{
225 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
226 		DE_NULL,									// const void*              pNext;
227 		(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
228 		imageType,									// VkImageType              imageType;
229 		format,										// VkFormat                 format;
230 		extent,										// VkExtent3D               extent;
231 		1u,											// uint32_t                 mipLevels;
232 		1u,											// uint32_t                 arrayLayers;
233 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits    samples;
234 		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
235 		usage,										// VkImageUsageFlags        usage;
236 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
237 		0u,											// uint32_t                 queueFamilyIndexCount;
238 		DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
239 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
240 	};
241 	return imageInfo;
242 }
243 
makeImageView(const DeviceInterface & vk,const VkDevice device,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)244 Move<VkImageView> makeImageView (const DeviceInterface&			vk,
245 								 const VkDevice					device,
246 								 const VkImage					image,
247 								 const VkImageViewType			viewType,
248 								 const VkFormat					format,
249 								 const VkImageSubresourceRange	subresourceRange)
250 {
251 	const VkImageViewCreateInfo imageViewParams =
252 	{
253 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
254 		DE_NULL,										// const void*				pNext;
255 		(VkImageViewCreateFlags)0,						// VkImageViewCreateFlags	flags;
256 		image,											// VkImage					image;
257 		viewType,										// VkImageViewType			viewType;
258 		format,											// VkFormat					format;
259 		makeComponentMappingRGBA(),						// VkComponentMapping		components;
260 		subresourceRange,								// VkImageSubresourceRange	subresourceRange;
261 	};
262 	return createImageView(vk, device, &imageViewParams);
263 }
264 
makeBufferImageCopy(const VkImageSubresourceLayers subresourceLayers,const VkExtent3D extent)265 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers	subresourceLayers,
266 									   const VkExtent3D					extent)
267 {
268 	const VkBufferImageCopy copyParams =
269 	{
270 		0ull,										//	VkDeviceSize				bufferOffset;
271 		0u,											//	deUint32					bufferRowLength;
272 		0u,											//	deUint32					bufferImageHeight;
273 		subresourceLayers,							//	VkImageSubresourceLayers	imageSubresource;
274 		makeOffset3D(0, 0, 0),						//	VkOffset3D					imageOffset;
275 		extent,										//	VkExtent3D					imageExtent;
276 	};
277 	return copyParams;
278 }
279 
makeEvent(const DeviceInterface & vk,const VkDevice device)280 Move<VkEvent> makeEvent (const DeviceInterface& vk, const VkDevice device)
281 {
282 	const VkEventCreateInfo eventParams =
283 	{
284 		VK_STRUCTURE_TYPE_EVENT_CREATE_INFO,	// VkStructureType       sType;
285 		DE_NULL,								// const void*           pNext;
286 		(VkEventCreateFlags)0,					// VkEventCreateFlags    flags;
287 	};
288 	return createEvent(vk, device, &eventParams);
289 }
290 
beginCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)291 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
292 {
293 	const VkCommandBufferBeginInfo info =
294 	{
295 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,	// VkStructureType                          sType;
296 		DE_NULL,										// const void*                              pNext;
297 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,	// VkCommandBufferUsageFlags                flags;
298 		DE_NULL,										// const VkCommandBufferInheritanceInfo*    pInheritanceInfo;
299 	};
300 	VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
301 }
302 
endCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)303 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
304 {
305 	VK_CHECK(vk.endCommandBuffer(commandBuffer));
306 }
307 
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer)308 void submitCommandsAndWait (const DeviceInterface&	vk,
309 							const VkDevice			device,
310 							const VkQueue			queue,
311 							const VkCommandBuffer	commandBuffer)
312 {
313 	const VkFenceCreateInfo fenceInfo =
314 	{
315 		VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,	// VkStructureType		sType;
316 		DE_NULL,								// const void*			pNext;
317 		(VkFenceCreateFlags)0,					// VkFenceCreateFlags	flags;
318 	};
319 	const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
320 
321 	const VkSubmitInfo submitInfo =
322 	{
323 		VK_STRUCTURE_TYPE_SUBMIT_INFO,		// VkStructureType                sType;
324 		DE_NULL,							// const void*                    pNext;
325 		0u,									// uint32_t                       waitSemaphoreCount;
326 		DE_NULL,							// const VkSemaphore*             pWaitSemaphores;
327 		DE_NULL,							// const VkPipelineStageFlags*    pWaitDstStageMask;
328 		1u,									// uint32_t                       commandBufferCount;
329 		&commandBuffer,						// const VkCommandBuffer*         pCommandBuffers;
330 		0u,									// uint32_t                       signalSemaphoreCount;
331 		DE_NULL,							// const VkSemaphore*             pSignalSemaphores;
332 	};
333 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
334 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
335 }
336 
beginRenderPass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor)337 void beginRenderPass (const DeviceInterface&	vk,
338 					  const VkCommandBuffer		commandBuffer,
339 					  const VkRenderPass		renderPass,
340 					  const VkFramebuffer		framebuffer,
341 					  const VkRect2D&			renderArea,
342 					  const tcu::Vec4&			clearColor)
343 {
344 	const VkClearValue clearValue = makeClearValueColor(clearColor);
345 
346 	const VkRenderPassBeginInfo renderPassBeginInfo = {
347 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
348 		DE_NULL,										// const void*             pNext;
349 		renderPass,										// VkRenderPass            renderPass;
350 		framebuffer,									// VkFramebuffer           framebuffer;
351 		renderArea,										// VkRect2D                renderArea;
352 		1u,												// uint32_t                clearValueCount;
353 		&clearValue,									// const VkClearValue*     pClearValues;
354 	};
355 
356 	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
357 }
358 
beginRenderPassWithRasterizationDisabled(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer)359 void beginRenderPassWithRasterizationDisabled (const DeviceInterface&	vk,
360 											   const VkCommandBuffer	commandBuffer,
361 											   const VkRenderPass		renderPass,
362 											   const VkFramebuffer		framebuffer)
363 {
364 	const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
365 
366 	const VkRenderPassBeginInfo renderPassBeginInfo = {
367 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,		// VkStructureType         sType;
368 		DE_NULL,										// const void*             pNext;
369 		renderPass,										// VkRenderPass            renderPass;
370 		framebuffer,									// VkFramebuffer           framebuffer;
371 		renderArea,										// VkRect2D                renderArea;
372 		0u,												// uint32_t                clearValueCount;
373 		DE_NULL,										// const VkClearValue*     pClearValues;
374 	};
375 
376 	vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
377 }
378 
endRenderPass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)379 void endRenderPass (const DeviceInterface&	vk,
380 					const VkCommandBuffer	commandBuffer)
381 {
382 	vk.cmdEndRenderPass(commandBuffer);
383 }
384 
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat)385 Move<VkRenderPass> makeRenderPass (const DeviceInterface&	vk,
386 								   const VkDevice			device,
387 								   const VkFormat			colorFormat)
388 {
389 	const VkAttachmentDescription colorAttachmentDescription =
390 	{
391 		(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags;
392 		colorFormat,										// VkFormat							format;
393 		VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples;
394 		VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp				loadOp;
395 		VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp				storeOp;
396 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// VkAttachmentLoadOp				stencilLoadOp;
397 		VK_ATTACHMENT_STORE_OP_DONT_CARE,					// VkAttachmentStoreOp				stencilStoreOp;
398 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout					initialLayout;
399 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout					finalLayout;
400 	};
401 
402 	const VkAttachmentReference colorAttachmentReference =
403 	{
404 		0u,													// deUint32			attachment;
405 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL			// VkImageLayout	layout;
406 	};
407 
408 	const VkAttachmentReference depthAttachmentReference =
409 	{
410 		VK_ATTACHMENT_UNUSED,								// deUint32			attachment;
411 		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout	layout;
412 	};
413 
414 	const VkSubpassDescription subpassDescription =
415 	{
416 		(VkSubpassDescriptionFlags)0,						// VkSubpassDescriptionFlags		flags;
417 		VK_PIPELINE_BIND_POINT_GRAPHICS,					// VkPipelineBindPoint				pipelineBindPoint;
418 		0u,													// deUint32							inputAttachmentCount;
419 		DE_NULL,											// const VkAttachmentReference*		pInputAttachments;
420 		1u,													// deUint32							colorAttachmentCount;
421 		&colorAttachmentReference,							// const VkAttachmentReference*		pColorAttachments;
422 		DE_NULL,											// const VkAttachmentReference*		pResolveAttachments;
423 		&depthAttachmentReference,							// const VkAttachmentReference*		pDepthStencilAttachment;
424 		0u,													// deUint32							preserveAttachmentCount;
425 		DE_NULL												// const deUint32*					pPreserveAttachments;
426 	};
427 
428 	const VkRenderPassCreateInfo renderPassInfo =
429 	{
430 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,			// VkStructureType					sType;
431 		DE_NULL,											// const void*						pNext;
432 		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags;
433 		1u,													// deUint32							attachmentCount;
434 		&colorAttachmentDescription,						// const VkAttachmentDescription*	pAttachments;
435 		1u,													// deUint32							subpassCount;
436 		&subpassDescription,								// const VkSubpassDescription*		pSubpasses;
437 		0u,													// deUint32							dependencyCount;
438 		DE_NULL												// const VkSubpassDependency*		pDependencies;
439 	};
440 
441 	return createRenderPass(vk, device, &renderPassInfo);
442 }
443 
makeFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const VkImageView colorAttachment,const deUint32 width,const deUint32 height,const deUint32 layers)444 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&		vk,
445 									 const VkDevice				device,
446 									 const VkRenderPass			renderPass,
447 									 const VkImageView			colorAttachment,
448 									 const deUint32				width,
449 									 const deUint32				height,
450 									 const deUint32				layers)
451 {
452 	const VkFramebufferCreateInfo framebufferInfo = {
453 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,		// VkStructureType                             sType;
454 		DE_NULL,										// const void*                                 pNext;
455 		(VkFramebufferCreateFlags)0,					// VkFramebufferCreateFlags                    flags;
456 		renderPass,										// VkRenderPass                                renderPass;
457 		1u,												// uint32_t                                    attachmentCount;
458 		&colorAttachment,								// const VkImageView*                          pAttachments;
459 		width,											// uint32_t                                    width;
460 		height,											// uint32_t                                    height;
461 		layers,											// uint32_t                                    layers;
462 	};
463 
464 	return createFramebuffer(vk, device, &framebufferInfo);
465 }
466 
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)467 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&			vk,
468 															 const VkDevice					device,
469 															 const VkShaderStageFlagBits	stage,
470 															 const ProgramBinary&			binary,
471 															 const VkSpecializationInfo*	specInfo)
472 {
473 	VkShaderModule module;
474 	switch (stage)
475 	{
476 		case (VK_SHADER_STAGE_VERTEX_BIT):
477 			DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
478 			m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
479 			module = *m_vertexShaderModule;
480 			break;
481 
482 		case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
483 			DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
484 			m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
485 			module = *m_tessControlShaderModule;
486 			break;
487 
488 		case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
489 			DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
490 			m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
491 			module = *m_tessEvaluationShaderModule;
492 			break;
493 
494 		case (VK_SHADER_STAGE_GEOMETRY_BIT):
495 			DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
496 			m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
497 			module = *m_geometryShaderModule;
498 			break;
499 
500 		case (VK_SHADER_STAGE_FRAGMENT_BIT):
501 			DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
502 			m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
503 			module = *m_fragmentShaderModule;
504 			break;
505 
506 		default:
507 			DE_FATAL("Invalid shader stage");
508 			return *this;
509 	}
510 
511 	const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
512 	{
513 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
514 		DE_NULL,												// const void*							pNext;
515 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
516 		stage,													// VkShaderStageFlagBits				stage;
517 		module,													// VkShaderModule						module;
518 		"main",													// const char*							pName;
519 		specInfo,												// const VkSpecializationInfo*			pSpecializationInfo;
520 	};
521 
522 	m_shaderStageFlags |= stage;
523 	m_shaderStages.push_back(pipelineShaderStageInfo);
524 
525 	return *this;
526 }
527 
setVertexInputSingleAttribute(const VkFormat vertexFormat,const deUint32 stride)528 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
529 {
530 	const VkVertexInputBindingDescription bindingDesc =
531 	{
532 		0u,									// uint32_t				binding;
533 		stride,								// uint32_t				stride;
534 		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
535 	};
536 	const VkVertexInputAttributeDescription attributeDesc =
537 	{
538 		0u,									// uint32_t			location;
539 		0u,									// uint32_t			binding;
540 		vertexFormat,						// VkFormat			format;
541 		0u,									// uint32_t			offset;
542 	};
543 
544 	m_vertexInputBindings.clear();
545 	m_vertexInputBindings.push_back(bindingDesc);
546 
547 	m_vertexInputAttributes.clear();
548 	m_vertexInputAttributes.push_back(attributeDesc);
549 
550 	return *this;
551 }
552 
553 template<typename T>
dataPointer(const std::vector<T> & vec)554 inline const T* dataPointer (const std::vector<T>& vec)
555 {
556 	return (vec.size() != 0 ? &vec[0] : DE_NULL);
557 }
558 
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,PipelineCacheData & pipelineCacheData)559 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&	vk,
560 												 const VkDevice			device,
561 												 const VkPipelineLayout	pipelineLayout,
562 												 const VkRenderPass		renderPass,
563 												 PipelineCacheData&		pipelineCacheData)
564 {
565 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
566 	{
567 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
568 		DE_NULL,														// const void*                                 pNext;
569 		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
570 		static_cast<deUint32>(m_vertexInputBindings.size()),			// uint32_t                                    vertexBindingDescriptionCount;
571 		dataPointer(m_vertexInputBindings),								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
572 		static_cast<deUint32>(m_vertexInputAttributes.size()),			// uint32_t                                    vertexAttributeDescriptionCount;
573 		dataPointer(m_vertexInputAttributes),							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
574 	};
575 
576 	const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
577 																										 : m_primitiveTopology;
578 	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
579 	{
580 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
581 		DE_NULL,														// const void*                                 pNext;
582 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
583 		topology,														// VkPrimitiveTopology                         topology;
584 		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
585 	};
586 
587 	const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
588 	{
589 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
590 		DE_NULL,														// const void*                                 pNext;
591 		(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
592 		m_patchControlPoints,											// uint32_t                                    patchControlPoints;
593 	};
594 
595 	const VkViewport viewport = makeViewport(
596 		0.0f, 0.0f,
597 		static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
598 		0.0f, 1.0f);
599 
600 	const VkRect2D scissor = {
601 		makeOffset2D(0, 0),
602 		makeExtent2D(m_renderSize.x(), m_renderSize.y()),
603 	};
604 
605 	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
606 	{
607 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
608 		DE_NULL,												// const void*                                 pNext;
609 		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
610 		1u,														// uint32_t                                    viewportCount;
611 		&viewport,												// const VkViewport*                           pViewports;
612 		1u,														// uint32_t                                    scissorCount;
613 		&scissor,												// const VkRect2D*                             pScissors;
614 	};
615 
616 	const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
617 	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
618 	{
619 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
620 		DE_NULL,														// const void*                              pNext;
621 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
622 		VK_FALSE,														// VkBool32                                 depthClampEnable;
623 		isRasterizationDisabled,										// VkBool32                                 rasterizerDiscardEnable;
624 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
625 		m_cullModeFlags,												// VkCullModeFlags							cullMode;
626 		m_frontFace,													// VkFrontFace								frontFace;
627 		VK_FALSE,														// VkBool32									depthBiasEnable;
628 		0.0f,															// float									depthBiasConstantFactor;
629 		0.0f,															// float									depthBiasClamp;
630 		0.0f,															// float									depthBiasSlopeFactor;
631 		1.0f,															// float									lineWidth;
632 	};
633 
634 	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
635 	{
636 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
637 		DE_NULL,													// const void*								pNext;
638 		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
639 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
640 		VK_FALSE,													// VkBool32									sampleShadingEnable;
641 		0.0f,														// float									minSampleShading;
642 		DE_NULL,													// const VkSampleMask*						pSampleMask;
643 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
644 		VK_FALSE													// VkBool32									alphaToOneEnable;
645 	};
646 
647 	const VkStencilOpState stencilOpState = makeStencilOpState(
648 		VK_STENCIL_OP_KEEP,		// stencil fail
649 		VK_STENCIL_OP_KEEP,		// depth & stencil pass
650 		VK_STENCIL_OP_KEEP,		// depth only fail
651 		VK_COMPARE_OP_NEVER,	// compare op
652 		0u,						// compare mask
653 		0u,						// write mask
654 		0u);					// reference
655 
656 	const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
657 	{
658 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
659 		DE_NULL,													// const void*								pNext;
660 		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
661 		VK_FALSE,													// VkBool32									depthTestEnable;
662 		VK_FALSE,													// VkBool32									depthWriteEnable;
663 		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
664 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
665 		VK_FALSE,													// VkBool32									stencilTestEnable;
666 		stencilOpState,												// VkStencilOpState							front;
667 		stencilOpState,												// VkStencilOpState							back;
668 		0.0f,														// float									minDepthBounds;
669 		1.0f,														// float									maxDepthBounds;
670 	};
671 
672 	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
673 	const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
674 	{
675 		m_blendEnable,						// VkBool32					blendEnable;
676 		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
677 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
678 		VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
679 		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
680 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
681 		VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
682 		colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
683 	};
684 
685 	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
686 	{
687 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
688 		DE_NULL,													// const void*									pNext;
689 		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
690 		VK_FALSE,													// VkBool32										logicOpEnable;
691 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
692 		1u,															// deUint32										attachmentCount;
693 		&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
694 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
695 	};
696 
697 	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
698 	{
699 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType									sType;
700 		DE_NULL,																// const void*										pNext;
701 		(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags							flags;
702 		static_cast<deUint32>(m_shaderStages.size()),							// deUint32											stageCount;
703 		&m_shaderStages[0],														// const VkPipelineShaderStageCreateInfo*			pStages;
704 		&vertexInputStateInfo,													// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
705 		&pipelineInputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
706 		(m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*		pTessellationState;
707 		(isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo),		// const VkPipelineViewportStateCreateInfo*			pViewportState;
708 		&pipelineRasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
709 		(isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo),	// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
710 		(isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo),	// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
711 		(isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo),		// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
712 		DE_NULL,																// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
713 		pipelineLayout,															// VkPipelineLayout									layout;
714 		renderPass,																// VkRenderPass										renderPass;
715 		0u,																		// deUint32											subpass;
716 		DE_NULL,																// VkPipeline										basePipelineHandle;
717 		0,																		// deInt32											basePipelineIndex;
718 	};
719 
720 	{
721 		const vk::Unique<vk::VkPipelineCache>	pipelineCache	(pipelineCacheData.createPipelineCache(vk, device));
722 		vk::Move<vk::VkPipeline>				pipeline		(createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
723 
724 		// Refresh data from cache
725 		pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
726 
727 		return pipeline;
728 	}
729 }
730 
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)731 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
732 {
733 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
734 
735 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
736 		throw tcu::NotSupportedError("Tessellation shader not supported");
737 
738 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
739 		throw tcu::NotSupportedError("Geometry shader not supported");
740 
741 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
742 		throw tcu::NotSupportedError("Double-precision floats not supported");
743 
744 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
745 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
746 
747 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
748 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
749 
750 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
751 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
752 
753 	if (((flags & FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS) != 0) && !features.shaderStorageImageExtendedFormats)
754 		throw tcu::NotSupportedError("Storage image extended formats not supported");
755 }
756 
getResourceName(const ResourceDescription & resource)757 std::string getResourceName (const ResourceDescription& resource)
758 {
759 	std::ostringstream str;
760 
761 	if (resource.type == RESOURCE_TYPE_BUFFER)
762 		str << "buffer_" << resource.size.x();
763 	else if (resource.type == RESOURCE_TYPE_IMAGE)
764 	{
765 		str << "image_" << resource.size.x()
766 						<< (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
767 						<< (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
768 			<< "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
769 	}
770 	else if (isIndirectBuffer(resource.type))
771 		str << "indirect_buffer";
772 	else
773 		DE_ASSERT(0);
774 
775 	return str.str();
776 }
777 
isIndirectBuffer(const ResourceType type)778 bool isIndirectBuffer (const ResourceType type)
779 {
780 	switch (type)
781 	{
782 		case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
783 		case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
784 		case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
785 			return true;
786 
787 		default:
788 			return false;
789 	}
790 }
791 
PipelineCacheData(void)792 PipelineCacheData::PipelineCacheData (void)
793 {
794 }
795 
~PipelineCacheData(void)796 PipelineCacheData::~PipelineCacheData (void)
797 {
798 }
799 
createPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device) const800 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
801 {
802 	const de::ScopedLock						dataLock	(m_lock);
803 	const struct vk::VkPipelineCacheCreateInfo	params	=
804 	{
805 		vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
806 		DE_NULL,
807 		(vk::VkPipelineCacheCreateFlags)0,
808 		(deUintptr)m_data.size(),
809 		(m_data.empty() ? DE_NULL : &m_data[0])
810 	};
811 
812 	return vk::createPipelineCache(vk, device, &params);
813 }
814 
setFromPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device,const vk::VkPipelineCache pipelineCache)815 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
816 {
817 	const de::ScopedLock		dataLock		(m_lock);
818 	deUintptr					dataSize		= 0;
819 
820 	VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
821 
822 	m_data.resize(dataSize);
823 
824 	if (dataSize > 0)
825 		VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));
826 }
827 
828 } // synchronization
829 } // vkt
830