• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Intel Corporation
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Image Object Util
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktQueryPoolImageObjectUtil.hpp"
26 
27 #include "tcuSurface.hpp"
28 #include "tcuVectorUtil.hpp"
29 
30 #include "vkRefUtil.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vktQueryPoolCreateInfoUtil.hpp"
34 #include "vktQueryPoolBufferObjectUtil.hpp"
35 
36 #include "tcuTextureUtil.hpp"
37 
38 namespace vkt
39 {
40 namespace QueryPool
41 {
42 
pack(int pixelSize,int width,int height,int depth,vk::VkDeviceSize rowPitchOrZero,vk::VkDeviceSize depthPitchOrZero,const void * srcBuffer,void * destBuffer)43 void MemoryOp::pack (int				pixelSize,
44 					 int				width,
45 					 int				height,
46 					 int				depth,
47 					 vk::VkDeviceSize	rowPitchOrZero,
48 					 vk::VkDeviceSize	depthPitchOrZero,
49 					 const void *		srcBuffer,
50 					 void *				destBuffer)
51 {
52 	vk::VkDeviceSize rowPitch	= rowPitchOrZero;
53 	vk::VkDeviceSize depthPitch	= depthPitchOrZero;
54 
55 	if (rowPitch == 0)
56 		rowPitch = width * pixelSize;
57 
58 	if (depthPitch == 0)
59 		depthPitch = rowPitch * height;
60 
61 	const vk::VkDeviceSize size = depthPitch * depth;
62 
63 	const char *srcRow = reinterpret_cast<const char *>(srcBuffer);
64 	const char *srcStart;
65 	srcStart = srcRow;
66 	char *dstRow = reinterpret_cast<char *>(destBuffer);
67 	char *dstStart;
68 	dstStart = dstRow;
69 
70 	if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
71 		depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
72 	{
73 		// fast path
74 		deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
75 	}
76 	else
77 	{
78 		// slower, per row path
79 		for (int d = 0; d < depth; d++)
80 		{
81 			vk::VkDeviceSize offsetDepthDst = d * depthPitch;
82 			vk::VkDeviceSize offsetDepthSrc = d * (pixelSize * width * height);
83 			srcRow = srcStart + offsetDepthSrc;
84 			dstRow = dstStart + offsetDepthDst;
85 			for (int r = 0; r < height; ++r)
86 			{
87 				deMemcpy(dstRow, srcRow, static_cast<size_t>(rowPitch));
88 				srcRow += pixelSize * width;
89 				dstRow += rowPitch;
90 			}
91 		}
92 	}
93 }
94 
unpack(int pixelSize,int width,int height,int depth,vk::VkDeviceSize rowPitchOrZero,vk::VkDeviceSize depthPitchOrZero,const void * srcBuffer,void * destBuffer)95 void MemoryOp::unpack (int					pixelSize,
96 					   int					width,
97 					   int					height,
98 					   int					depth,
99 					   vk::VkDeviceSize		rowPitchOrZero,
100 					   vk::VkDeviceSize		depthPitchOrZero,
101 					   const void *			srcBuffer,
102 					   void *				destBuffer)
103 {
104 	vk::VkDeviceSize rowPitch	= rowPitchOrZero;
105 	vk::VkDeviceSize depthPitch = depthPitchOrZero;
106 
107 	if (rowPitch == 0)
108 		rowPitch = width * pixelSize;
109 
110 	if (depthPitch == 0)
111 		depthPitch = rowPitch * height;
112 
113 	const vk::VkDeviceSize size = depthPitch * depth;
114 
115 	const char *srcRow = reinterpret_cast<const char *>(srcBuffer);
116 	const char *srcStart;
117 	srcStart = srcRow;
118 	char *dstRow = reinterpret_cast<char *>(destBuffer);
119 	char *dstStart;
120 	dstStart = dstRow;
121 
122 	if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
123 		depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
124 	{
125 		// fast path
126 		deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
127 	}
128 	else
129 	{
130 		// slower, per row path
131 		for (size_t d = 0; d < (size_t)depth; d++)
132 		{
133 			vk::VkDeviceSize offsetDepthDst = d * (pixelSize * width * height);
134 			vk::VkDeviceSize offsetDepthSrc = d * depthPitch;
135 			srcRow = srcStart + offsetDepthSrc;
136 			dstRow = dstStart + offsetDepthDst;
137 			for (int r = 0; r < height; ++r)
138 			{
139 				deMemcpy(dstRow, srcRow, static_cast<size_t>(pixelSize * width));
140 				srcRow += rowPitch;
141 				dstRow += pixelSize * width;
142 			}
143 		}
144 	}
145 }
146 
Image(const vk::DeviceInterface & vk,vk::VkDevice device,vk::VkFormat format,const vk::VkExtent3D & extend,deUint32 levelCount,deUint32 layerCount,vk::Move<vk::VkImage> object_)147 Image::Image (const vk::DeviceInterface& vk,
148 			  vk::VkDevice				device,
149 			  vk::VkFormat				format,
150 			  const vk::VkExtent3D&		extend,
151 			  deUint32					levelCount,
152 			  deUint32					layerCount,
153 			  vk::Move<vk::VkImage>		object_)
154 	: m_allocation		(DE_NULL)
155 	, m_object			(object_)
156 	, m_format			(format)
157 	, m_extent			(extend)
158 	, m_levelCount		(levelCount)
159 	, m_layerCount		(layerCount)
160 	, m_vk(vk)
161 	, m_device(device)
162 {
163 }
164 
readVolume(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)165 tcu::ConstPixelBufferAccess Image::readVolume (vk::VkQueue					queue,
166 											   vk::Allocator&				allocator,
167 											   vk::VkImageLayout			layout,
168 											   vk::VkOffset3D				offset,
169 											   int							width,
170 											   int							height,
171 											   int							depth,
172 											   vk::VkImageAspectFlagBits	aspect,
173 											   unsigned int					mipLevel,
174 											   unsigned int					arrayElement)
175 {
176 	m_pixelAccessData.resize(width * height * depth * vk::mapVkFormat(m_format).getPixelSize());
177 	deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
178 	if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
179 	{
180 		read(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_3D,
181 		m_pixelAccessData.data());
182 	}
183 	if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
184 	{
185 		readUsingBuffer(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
186 	}
187 	return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, depth, m_pixelAccessData.data());
188 }
189 
readSurface1D(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)190 tcu::ConstPixelBufferAccess Image::readSurface1D(vk::VkQueue				queue,
191 												 vk::Allocator&				allocator,
192 												 vk::VkImageLayout			layout,
193 												 vk::VkOffset3D				offset,
194 												 int						width,
195 												 vk::VkImageAspectFlagBits	aspect,
196 												 unsigned int				mipLevel,
197 												 unsigned int				arrayElement)
198 {
199 	m_pixelAccessData.resize(width * vk::mapVkFormat(m_format).getPixelSize());
200 	deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
201 	if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
202 	{
203 		read(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
204 		m_pixelAccessData.data());
205 	}
206 	if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
207 	{
208 		readUsingBuffer(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect,
209 		m_pixelAccessData.data());
210 	}
211 	return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, 1, 1, m_pixelAccessData.data());
212 }
213 
read(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,vk::VkImageType type,void * data)214 void Image::read (vk::VkQueue					queue,
215 				  vk::Allocator&				allocator,
216 				  vk::VkImageLayout				layout,
217 				  vk::VkOffset3D				offset,
218 				  int							width,
219 				  int							height,
220 				  int							depth,
221 				  unsigned int					mipLevel,
222 				  unsigned int					arrayElement,
223 				  vk::VkImageAspectFlagBits		aspect,
224 				  vk::VkImageType				type,
225 				  void *						data)
226 {
227 	DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
228 
229 	de::SharedPtr<Image> stagingResource = copyToLinearImage(queue, allocator, layout, offset, width,
230 															 height, depth, mipLevel, arrayElement, aspect, type);
231 	const vk::VkOffset3D zeroOffset = {0, 0, 0};
232 	stagingResource->readLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
233 }
234 
readUsingBuffer(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,void * data)235 void Image::readUsingBuffer (vk::VkQueue				queue,
236 							 vk::Allocator&				allocator,
237 							 vk::VkImageLayout			layout,
238 							 vk::VkOffset3D				offset,
239 							 int						width,
240 							 int						height,
241 							 int						depth,
242 							 unsigned int				mipLevel,
243 							 unsigned int				arrayElement,
244 							 vk::VkImageAspectFlagBits	aspect,
245 							 void *						data)
246 {
247 	DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);;
248 
249 	de::SharedPtr<Buffer> stagingResource;
250 
251 	bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
252 	vk::VkDeviceSize bufferSize = 0;
253 
254 	if (!isCombinedType)
255 		bufferSize = vk::mapVkFormat(m_format).getPixelSize() * width * height * depth;
256 
257 	if (isCombinedType)
258 	{
259 		int pixelSize = 0;
260 		switch (m_format)
261 		{
262 			case vk::VK_FORMAT_D16_UNORM_S8_UINT:
263 				pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
264 				break;
265 			case  vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
266 				pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
267 				break;
268 			case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
269 			case vk::VK_FORMAT_D24_UNORM_S8_UINT:
270 				pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 3 : 1;
271 				break;
272 
273 			default:
274 				DE_FATAL("Not implemented");
275 		}
276 		bufferSize = pixelSize*width*height*depth;
277 	}
278 
279 	BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
280 	stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator, vk::MemoryRequirement::HostVisible);
281 
282 	{
283 		//todo [scygan] get proper queueFamilyIndex
284 		CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
285 		vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
286 
287 		const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
288 		{
289 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
290 			DE_NULL,											// const void*				pNext;
291 			*copyCmdPool,										// VkCommandPool			commandPool;
292 			vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
293 			1u,													// deUint32					bufferCount;
294 		};
295 		vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
296 
297 		CmdBufferBeginInfo beginInfo;
298 		VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
299 
300 		if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
301 		{
302 			layout = vk::VK_IMAGE_LAYOUT_GENERAL;
303 
304 			vk::VkImageMemoryBarrier barrier;
305 			barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
306 			barrier.pNext = DE_NULL;
307 			barrier.srcAccessMask = 0;
308 			barrier.dstAccessMask = 0;
309 			barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
310 			barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
311 			barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
312 			barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
313 			barrier.image = object();
314 
315 			barrier.subresourceRange.aspectMask = aspect;
316 			barrier.subresourceRange.baseMipLevel = 0;
317 			barrier.subresourceRange.levelCount = m_levelCount;
318 			barrier.subresourceRange.baseArrayLayer = 0;
319 			barrier.subresourceRange.layerCount = m_layerCount;
320 
321 			m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
322 									0, (const vk::VkMemoryBarrier*)DE_NULL,
323 									0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
324 									1, &barrier);
325 		}
326 
327 		const vk::VkBufferImageCopy region =
328 		{
329 			0, 0, 0,
330 			{ aspect, mipLevel, arrayElement, 1 },
331 			offset,
332 			{ (deUint32)width, (deUint32)height, (deUint32)depth }
333 		};
334 
335 		m_vk.cmdCopyImageToBuffer(*copyCmdBuffer, object(), layout, stagingResource->object(), 1, &region);
336 		VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
337 
338 		const vk::VkSubmitInfo submitInfo =
339 		{
340 			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
341 			DE_NULL,							// const void*				pNext;
342 			0,									// deUint32					waitSemaphoreCount;
343 			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
344 			(const vk::VkPipelineStageFlags*)DE_NULL,
345 			1,									// deUint32					commandBufferCount;
346 			&copyCmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
347 			0,									// deUint32					signalSemaphoreCount;
348 			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
349 		};
350 		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
351 
352 		// TODO: make this less intrusive
353 		VK_CHECK(m_vk.queueWaitIdle(queue));
354 	}
355 
356 	char* destPtr = reinterpret_cast<char*>(stagingResource->getBoundMemory().getHostPtr());
357 	deMemcpy(data, destPtr, static_cast<size_t>(bufferSize));
358 }
359 
readSurfaceLinear(vk::VkOffset3D offset,int width,int height,int depth,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)360 tcu::ConstPixelBufferAccess Image::readSurfaceLinear (vk::VkOffset3D				offset,
361 													  int							width,
362 													  int							height,
363 													  int							depth,
364 													  vk::VkImageAspectFlagBits		aspect,
365 													  unsigned int					mipLevel,
366 													  unsigned int					arrayElement)
367 {
368 	m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
369 	readLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
370 	return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
371 }
372 
readLinear(vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,void * data)373 void Image::readLinear (vk::VkOffset3D				offset,
374 						int							width,
375 						int							height,
376 						int							depth,
377 						unsigned int				mipLevel,
378 						unsigned int				arrayElement,
379 						vk::VkImageAspectFlagBits	aspect,
380 						void *						data)
381 {
382 	vk::VkImageSubresource imageSubResource = { aspect, mipLevel, arrayElement };
383 
384 	vk::VkSubresourceLayout imageLayout;
385 	deMemset(&imageLayout, 0, sizeof(imageLayout));
386 
387 	m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource, &imageLayout);
388 
389 	const char* srcPtr = reinterpret_cast<const char*>(getBoundMemory().getHostPtr());
390 	srcPtr += imageLayout.offset + getPixelOffset(offset, imageLayout.rowPitch, imageLayout.depthPitch, mipLevel, arrayElement);
391 
392 	MemoryOp::unpack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth,
393 		imageLayout.rowPitch, imageLayout.depthPitch, srcPtr, data);
394 }
395 
copyToLinearImage(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,vk::VkImageType type)396 de::SharedPtr<Image> Image::copyToLinearImage (vk::VkQueue					queue,
397 											   vk::Allocator&				allocator,
398 											   vk::VkImageLayout			layout,
399 											   vk::VkOffset3D				offset,
400 											   int							width,
401 											   int							height,
402 											   int							depth,
403 											   unsigned int					mipLevel,
404 											   unsigned int					arrayElement,
405 											   vk::VkImageAspectFlagBits	aspect,
406 											   vk::VkImageType				type)
407 {
408 	de::SharedPtr<Image> stagingResource;
409 	{
410 		vk::VkExtent3D stagingExtent = {(deUint32)width, (deUint32)height, (deUint32)depth};
411 		ImageCreateInfo stagingResourceCreateInfo(type, m_format, stagingExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
412 												  vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
413 
414 		stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
415 												vk::MemoryRequirement::HostVisible);
416 
417 		//todo [scygan] get proper queueFamilyIndex
418 		CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
419 		vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
420 
421 		const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
422 		{
423 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
424 			DE_NULL,											// const void*				pNext;
425 			*copyCmdPool,										// VkCommandPool			commandPool;
426 			vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
427 			1u,													// deUint32					bufferCount;
428 		};
429 		vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
430 
431 		CmdBufferBeginInfo beginInfo;
432 		VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
433 
434 		transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, 0, vk::VK_ACCESS_TRANSFER_WRITE_BIT);
435 
436 		const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
437 		vk::VkImageCopy region = { {aspect, mipLevel, arrayElement, 1}, offset, {aspect, 0, 0, 1}, zeroOffset, {(deUint32)width, (deUint32)height, (deUint32)depth} };
438 
439 		m_vk.cmdCopyImage(*copyCmdBuffer, object(), layout, stagingResource->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1, &region);
440 		VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
441 
442 		const vk::VkSubmitInfo submitInfo =
443 		{
444 			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
445 			DE_NULL,							// const void*				pNext;
446 			0,									// deUint32					waitSemaphoreCount;
447 			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
448 			(const vk::VkPipelineStageFlags*)DE_NULL,
449 			1,									// deUint32					commandBufferCount;
450 			&copyCmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
451 			0,									// deUint32					signalSemaphoreCount;
452 			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
453 		};
454 		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
455 
456 		// TODO: make this less intrusive
457 		VK_CHECK(m_vk.queueWaitIdle(queue));
458 	}
459 	return stagingResource;
460 }
461 
uploadVolume(const tcu::ConstPixelBufferAccess & access,vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)462 void Image::uploadVolume(const tcu::ConstPixelBufferAccess&	access,
463 						 vk::VkQueue						queue,
464 						 vk::Allocator&						allocator,
465 						 vk::VkImageLayout					layout,
466 						 vk::VkOffset3D						offset,
467 						 vk::VkImageAspectFlagBits			aspect,
468 						 unsigned int						mipLevel,
469 						 unsigned int						arrayElement)
470 {
471 	if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
472 	{
473 		upload(queue, allocator, layout, offset, access.getWidth(),
474 		access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_3D,
475 		access.getDataPtr());
476 	}
477 	if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
478 	{
479 		uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
480 		access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
481 	}
482 }
483 
uploadSurface(const tcu::ConstPixelBufferAccess & access,vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)484 void Image::uploadSurface (const tcu::ConstPixelBufferAccess&	access,
485 						   vk::VkQueue							queue,
486 						   vk::Allocator&						allocator,
487 						   vk::VkImageLayout					layout,
488 						   vk::VkOffset3D						offset,
489 						   vk::VkImageAspectFlagBits			aspect,
490 						   unsigned int							mipLevel,
491 						   unsigned int							arrayElement)
492 {
493 	if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
494 	{
495 		upload(queue, allocator, layout, offset, access.getWidth(),
496 			access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
497 			access.getDataPtr());
498 	}
499 	if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
500 	{
501 		uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
502 			access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
503 	}
504 }
505 
uploadSurface1D(const tcu::ConstPixelBufferAccess & access,vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)506 void Image::uploadSurface1D (const tcu::ConstPixelBufferAccess&	access,
507 							 vk::VkQueue						queue,
508 							 vk::Allocator&						allocator,
509 							 vk::VkImageLayout					layout,
510 							 vk::VkOffset3D						offset,
511 							 vk::VkImageAspectFlagBits			aspect,
512 							 unsigned int						mipLevel,
513 							 unsigned int						arrayElement)
514 {
515 	if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
516 	{
517 		upload(queue, allocator, layout, offset, access.getWidth(),
518 			access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
519 			access.getDataPtr());
520 	}
521 	if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
522 	{
523 		uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(),
524 			access.getHeight(), access.getDepth(), mipLevel, arrayElement, aspect, access.getDataPtr());
525 	}
526 }
527 
uploadSurfaceLinear(const tcu::ConstPixelBufferAccess & access,vk::VkOffset3D offset,int width,int height,int depth,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)528 void Image::uploadSurfaceLinear (const tcu::ConstPixelBufferAccess&	access,
529 								 vk::VkOffset3D						offset,
530 								 int								width,
531 								 int								height,
532 								 int								depth,
533 								 vk::VkImageAspectFlagBits			aspect,
534 								 unsigned int						mipLevel,
535 								 unsigned int						arrayElement)
536 {
537 	uploadLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, access.getDataPtr());
538 }
539 
upload(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,vk::VkImageType type,const void * data)540 void Image::upload (vk::VkQueue					queue,
541 					vk::Allocator&				allocator,
542 					vk::VkImageLayout			layout,
543 					vk::VkOffset3D				offset,
544 					int							width,
545 					int							height,
546 					int							depth,
547 					unsigned int				mipLevel,
548 					unsigned int				arrayElement,
549 					vk::VkImageAspectFlagBits	aspect,
550 					vk::VkImageType				type,
551 					const void *				data)
552 {
553 	DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
554 
555 	de::SharedPtr<Image> stagingResource;
556 	vk::VkExtent3D extent = {(deUint32)width, (deUint32)height, (deUint32)depth};
557 	ImageCreateInfo stagingResourceCreateInfo(
558 		type, m_format, extent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
559 		vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
560 
561 	stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
562 								vk::MemoryRequirement::HostVisible);
563 
564 	const vk::VkOffset3D zeroOffset = { 0, 0, 0 };
565 	stagingResource->uploadLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
566 
567 	{
568 		//todo [scygan] get proper queueFamilyIndex
569 		CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
570 		vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
571 
572 		const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
573 		{
574 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
575 			DE_NULL,											// const void*				pNext;
576 			*copyCmdPool,										// VkCommandPool			commandPool;
577 			vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
578 			1u,													// deUint32					bufferCount;
579 		};
580 
581 		vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
582 
583 		CmdBufferBeginInfo beginInfo;
584 		VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
585 
586 		if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
587 		{
588 			layout = vk::VK_IMAGE_LAYOUT_GENERAL;
589 
590 			vk::VkImageMemoryBarrier barrier;
591 			barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
592 			barrier.pNext = DE_NULL;
593 			barrier.srcAccessMask = 0;
594 			barrier.dstAccessMask = 0;
595 			barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
596 			barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
597 			barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
598 			barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
599 			barrier.image = object();
600 
601 			barrier.subresourceRange.aspectMask = aspect;
602 			barrier.subresourceRange.baseMipLevel = 0;
603 			barrier.subresourceRange.levelCount = m_levelCount;
604 			barrier.subresourceRange.baseArrayLayer = 0;
605 			barrier.subresourceRange.layerCount = m_layerCount;
606 
607 			m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
608 									0, (const vk::VkMemoryBarrier*)DE_NULL,
609 									0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
610 									1, &barrier);
611 		}
612 
613 		transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL);
614 
615 		vk::VkImageCopy region = {{aspect, 0, 0, 1},
616 									zeroOffset,
617 									{aspect, mipLevel, arrayElement, 1},
618 									offset,
619 									{(deUint32)width, (deUint32)height, (deUint32)depth}};
620 
621 		m_vk.cmdCopyImage(*copyCmdBuffer, stagingResource->object(),
622 								vk::VK_IMAGE_LAYOUT_GENERAL, object(), layout, 1, &region);
623 		VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
624 
625 		const vk::VkSubmitInfo submitInfo =
626 		{
627 			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
628 			DE_NULL,							// const void*				pNext;
629 			0,									// deUint32					waitSemaphoreCount;
630 			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
631 			(const vk::VkPipelineStageFlags*)DE_NULL,
632 			1,									// deUint32					commandBufferCount;
633 			&copyCmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
634 			0,									// deUint32					signalSemaphoreCount;
635 			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
636 		};
637 		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
638 
639 		// TODO: make this less intrusive
640 		VK_CHECK(m_vk.queueWaitIdle(queue));
641 	}
642 }
643 
uploadUsingBuffer(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,const void * data)644 void Image::uploadUsingBuffer (vk::VkQueue					queue,
645 							   vk::Allocator&				allocator,
646 							   vk::VkImageLayout			layout,
647 							   vk::VkOffset3D				offset,
648 							   int							width,
649 							   int							height,
650 							   int							depth,
651 							   unsigned int					mipLevel,
652 							   unsigned int					arrayElement,
653 							   vk::VkImageAspectFlagBits	aspect,
654 							   const void *					data)
655 {
656 	DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
657 
658 	de::SharedPtr<Buffer> stagingResource;
659 	bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
660 	vk::VkDeviceSize bufferSize = 0;
661 	if (!isCombinedType)
662 		bufferSize = vk::mapVkFormat(m_format).getPixelSize() *width*height*depth;
663 	if (isCombinedType)
664 	{
665 		int pixelSize = 0;
666 		switch (m_format)
667 		{
668 			case vk::VK_FORMAT_D16_UNORM_S8_UINT:
669 				pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
670 				break;
671 			case  vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
672 				pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
673 				break;
674 			case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
675 			case vk::VK_FORMAT_D24_UNORM_S8_UINT:
676 				pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 3 : 1;
677 			break;
678 
679 			default:
680 				DE_FATAL("Not implemented");
681 		}
682 		bufferSize = pixelSize*width*height*depth;
683 	}
684 	BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
685 	stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator, vk::MemoryRequirement::HostVisible);
686 	char* destPtr = reinterpret_cast<char*>(stagingResource->getBoundMemory().getHostPtr());
687 	deMemcpy(destPtr, data, static_cast<size_t>(bufferSize));
688 	vk::flushMappedMemoryRange(m_vk, m_device, stagingResource->getBoundMemory().getMemory(), stagingResource->getBoundMemory().getOffset(), bufferSize);
689 	{
690 		//todo [scygan] get proper queueFamilyIndex
691 		CmdPoolCreateInfo copyCmdPoolCreateInfo(0);
692 		vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, &copyCmdPoolCreateInfo));
693 
694 		const vk::VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
695 		{
696 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
697 			DE_NULL,											// const void*				pNext;
698 			*copyCmdPool,										// VkCommandPool			commandPool;
699 			vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
700 			1u,													// deUint32					bufferCount;
701 		};
702 		vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(vk::allocateCommandBuffer(m_vk, m_device, &cmdBufferAllocateInfo));
703 
704 		CmdBufferBeginInfo beginInfo;
705 		VK_CHECK(m_vk.beginCommandBuffer(*copyCmdBuffer, &beginInfo));
706 
707 		if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
708 		{
709 			layout = vk::VK_IMAGE_LAYOUT_GENERAL;
710 
711 			vk::VkImageMemoryBarrier barrier;
712 			barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
713 			barrier.pNext = DE_NULL;
714 			barrier.srcAccessMask = 0;
715 			barrier.dstAccessMask = 0;
716 			barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
717 			barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
718 			barrier.srcQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
719 			barrier.dstQueueFamilyIndex = vk::VK_QUEUE_FAMILY_IGNORED;
720 			barrier.image = object();
721 
722 			barrier.subresourceRange.aspectMask = aspect;
723 			barrier.subresourceRange.baseMipLevel = 0;
724 			barrier.subresourceRange.levelCount = m_levelCount;
725 			barrier.subresourceRange.baseArrayLayer = 0;
726 			barrier.subresourceRange.layerCount = m_layerCount;
727 
728 			m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
729 									0, (const vk::VkMemoryBarrier*)DE_NULL,
730 									0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
731 									1, &barrier);
732 		}
733 
734 		vk::VkBufferImageCopy region =
735 		{
736 			0, 0, 0,
737 			{ aspect, mipLevel, arrayElement, 1 },
738 			offset,
739 			{ (deUint32)width, (deUint32)height, (deUint32)depth }
740 		};
741 
742 		m_vk.cmdCopyBufferToImage(*copyCmdBuffer, stagingResource->object(),
743 			object(), layout, 1, &region);
744 		VK_CHECK(m_vk.endCommandBuffer(*copyCmdBuffer));
745 
746 		vk::VkSubmitInfo submitInfo =
747 		{
748 			vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,	// VkStructureType			sType;
749 			DE_NULL,							// const void*				pNext;
750 			0,									// deUint32					waitSemaphoreCount;
751 			DE_NULL,							// const VkSemaphore*		pWaitSemaphores;
752 			(const vk::VkPipelineStageFlags*)DE_NULL,
753 			1,									// deUint32					commandBufferCount;
754 			&copyCmdBuffer.get(),				// const VkCommandBuffer*	pCommandBuffers;
755 			0,									// deUint32					signalSemaphoreCount;
756 			DE_NULL								// const VkSemaphore*		pSignalSemaphores;
757 		};
758 		m_vk.queueSubmit(queue, 1, &submitInfo, DE_NULL);
759 
760 		// TODO: make this less intrusive
761 		VK_CHECK(m_vk.queueWaitIdle(queue));
762 	}
763 }
764 
uploadLinear(vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,const void * data)765 void Image::uploadLinear (vk::VkOffset3D			offset,
766 						  int						width,
767 						  int						height,
768 						  int						depth,
769 						  unsigned int				mipLevel,
770 						  unsigned int				arrayElement,
771 						  vk::VkImageAspectFlagBits	aspect,
772 						  const void *				data)
773 {
774 	vk::VkSubresourceLayout imageLayout;
775 
776 	vk::VkImageSubresource imageSubResource = {aspect, mipLevel, arrayElement};
777 
778 	m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource,
779 													&imageLayout);
780 
781 	char* destPtr = reinterpret_cast<char*>(getBoundMemory().getHostPtr());
782 
783 	destPtr += imageLayout.offset + getPixelOffset(offset, imageLayout.rowPitch, imageLayout.depthPitch, mipLevel, arrayElement);
784 
785 	MemoryOp::pack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth,
786 		imageLayout.rowPitch, imageLayout.depthPitch, data, destPtr);
787 }
788 
getPixelOffset(vk::VkOffset3D offset,vk::VkDeviceSize rowPitch,vk::VkDeviceSize depthPitch,unsigned int level,unsigned int layer)789 vk::VkDeviceSize Image::getPixelOffset (vk::VkOffset3D		offset,
790 										vk::VkDeviceSize	rowPitch,
791 										vk::VkDeviceSize	depthPitch,
792 										unsigned int		level,
793 										unsigned int		layer)
794 {
795 	DE_ASSERT(level < m_levelCount);
796 	DE_ASSERT(layer < m_layerCount);
797 
798 	vk::VkDeviceSize mipLevelSizes[32];
799 	vk::VkDeviceSize mipLevelRectSizes[32];
800 	tcu::IVec3 mipExtend
801 	= tcu::IVec3(m_extent.width, m_extent.height, m_extent.depth);
802 
803 	vk::VkDeviceSize arrayElemSize = 0;
804 	for (unsigned int i = 0; i < m_levelCount && (mipExtend[0] > 1 || mipExtend[1] > 1 || mipExtend[2] > 1); ++i)
805 	{
806 		// Rect size is just a 3D image size;
807 		mipLevelSizes[i] = mipExtend[2] * depthPitch;
808 
809 		arrayElemSize += mipLevelSizes[0];
810 
811 		mipExtend = tcu::max(mipExtend / 2, tcu::IVec3(1));
812 	}
813 
814 	vk::VkDeviceSize pixelOffset = layer * arrayElemSize;
815 	for (size_t i = 0; i < level; ++i)
816 	{
817 		pixelOffset += mipLevelSizes[i];
818 	}
819 	pixelOffset += offset.z * mipLevelRectSizes[level];
820 	pixelOffset += offset.y * rowPitch;
821 	pixelOffset += offset.x;
822 
823 	return pixelOffset;
824 }
825 
bindMemory(de::MovePtr<vk::Allocation> allocation)826 void Image::bindMemory (de::MovePtr<vk::Allocation> allocation)
827 {
828 	DE_ASSERT(allocation);
829 	VK_CHECK(m_vk.bindImageMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
830 
831 	DE_ASSERT(!m_allocation);
832 	m_allocation = allocation;
833 }
834 
createAndAlloc(const vk::DeviceInterface & vk,vk::VkDevice device,const vk::VkImageCreateInfo & createInfo,vk::Allocator & allocator,vk::MemoryRequirement memoryRequirement)835 de::SharedPtr<Image> Image::createAndAlloc(const vk::DeviceInterface&	vk,
836 										   vk::VkDevice					device,
837 										   const vk::VkImageCreateInfo& createInfo,
838 										   vk::Allocator&				allocator,
839 										   vk::MemoryRequirement		memoryRequirement)
840 {
841 	de::SharedPtr<Image> ret = create(vk, device, createInfo);
842 
843 	vk::VkMemoryRequirements imageRequirements = vk::getImageMemoryRequirements(vk, device, ret->object());
844 	ret->bindMemory(allocator.allocate(imageRequirements, memoryRequirement));
845 	return ret;
846 }
847 
create(const vk::DeviceInterface & vk,vk::VkDevice device,const vk::VkImageCreateInfo & createInfo)848 de::SharedPtr<Image> Image::create(const vk::DeviceInterface&	vk,
849 								   vk::VkDevice					device,
850 								   const vk::VkImageCreateInfo	&createInfo)
851 {
852 	return de::SharedPtr<Image>(new Image(vk, device, createInfo.format, createInfo.extent,
853 								createInfo.mipLevels, createInfo.arrayLayers,
854 								vk::createImage(vk, device, &createInfo)));
855 }
856 
transition2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageAspectFlags aspectMask,vk::VkImageLayout oldLayout,vk::VkImageLayout newLayout,vk::VkAccessFlags srcAccessMask,vk::VkAccessFlags dstAccessMask)857 void transition2DImage (const vk::DeviceInterface&	vk,
858 						vk::VkCommandBuffer			cmdBuffer,
859 						vk::VkImage					image,
860 						vk::VkImageAspectFlags		aspectMask,
861 						vk::VkImageLayout			oldLayout,
862 						vk::VkImageLayout			newLayout,
863 						vk::VkAccessFlags			srcAccessMask,
864 						vk::VkAccessFlags			dstAccessMask)
865 {
866 	vk::VkImageMemoryBarrier barrier;
867 	barrier.sType							= vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
868 	barrier.pNext							= DE_NULL;
869 	barrier.srcAccessMask					= srcAccessMask;
870 	barrier.dstAccessMask					= dstAccessMask;
871 	barrier.oldLayout						= oldLayout;
872 	barrier.newLayout						= newLayout;
873 	barrier.srcQueueFamilyIndex				= vk::VK_QUEUE_FAMILY_IGNORED;
874 	barrier.dstQueueFamilyIndex				= vk::VK_QUEUE_FAMILY_IGNORED;
875 	barrier.image							= image;
876 	barrier.subresourceRange.aspectMask		= aspectMask;
877 	barrier.subresourceRange.baseMipLevel	= 0;
878 	barrier.subresourceRange.levelCount		= 1;
879 	barrier.subresourceRange.baseArrayLayer = 0;
880 	barrier.subresourceRange.layerCount		= 1;
881 
882 	vk.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
883 						  0, (const vk::VkMemoryBarrier*)DE_NULL,
884 						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
885 						  1, &barrier);
886 }
887 
initialTransitionColor2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout)888 void initialTransitionColor2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
889 {
890 	transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
891 }
892 
initialTransitionDepth2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout)893 void initialTransitionDepth2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
894 {
895 	transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
896 }
897 
initialTransitionStencil2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout)898 void initialTransitionStencil2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
899 {
900 	transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
901 }
902 
initialTransitionDepthStencil2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout)903 void initialTransitionDepthStencil2DImage (const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image, vk::VkImageLayout layout)
904 {
905 	transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout);
906 }
907 
908 } // QueryPool
909 } // vkt
910