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 "vktDrawImageObjectUtil.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 "vkCmdUtil.hpp"
34 #include "vktDrawCreateInfoUtil.hpp"
35 #include "vktDrawBufferObjectUtil.hpp"
36
37 #include "tcuTextureUtil.hpp"
38
39 namespace vkt
40 {
41 namespace Draw
42 {
43
pack(int pixelSize,int width,int height,int depth,vk::VkDeviceSize rowPitchOrZero,vk::VkDeviceSize depthPitchOrZero,const void * srcBuffer,void * destBuffer)44 void MemoryOp::pack(int pixelSize, int width, int height, int depth, vk::VkDeviceSize rowPitchOrZero,
45 vk::VkDeviceSize depthPitchOrZero, const void *srcBuffer, void *destBuffer)
46 {
47 vk::VkDeviceSize rowPitch = rowPitchOrZero;
48 vk::VkDeviceSize depthPitch = depthPitchOrZero;
49
50 if (rowPitch == 0)
51 rowPitch = width * pixelSize;
52
53 if (depthPitch == 0)
54 depthPitch = rowPitch * height;
55
56 const vk::VkDeviceSize size = depthPitch * depth;
57
58 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(srcBuffer);
59 const uint8_t *srcStart;
60 srcStart = srcRow;
61 uint8_t *dstRow = reinterpret_cast<uint8_t *>(destBuffer);
62 uint8_t *dstStart;
63 dstStart = dstRow;
64
65 if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
66 depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
67 {
68 // fast path
69 deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
70 }
71 else
72 {
73 // slower, per row path
74 for (int d = 0; d < depth; d++)
75 {
76 vk::VkDeviceSize offsetDepthDst = d * depthPitch;
77 vk::VkDeviceSize offsetDepthSrc = d * (pixelSize * width * height);
78 srcRow = srcStart + offsetDepthSrc;
79 dstRow = dstStart + offsetDepthDst;
80 for (int r = 0; r < height; ++r)
81 {
82 deMemcpy(dstRow, srcRow, static_cast<size_t>(rowPitch));
83 srcRow += pixelSize * width;
84 dstRow += rowPitch;
85 }
86 }
87 }
88 }
89
unpack(int pixelSize,int width,int height,int depth,vk::VkDeviceSize rowPitchOrZero,vk::VkDeviceSize depthPitchOrZero,const void * srcBuffer,void * destBuffer)90 void MemoryOp::unpack(int pixelSize, int width, int height, int depth, vk::VkDeviceSize rowPitchOrZero,
91 vk::VkDeviceSize depthPitchOrZero, const void *srcBuffer, void *destBuffer)
92 {
93 vk::VkDeviceSize rowPitch = rowPitchOrZero;
94 vk::VkDeviceSize depthPitch = depthPitchOrZero;
95
96 if (rowPitch == 0)
97 rowPitch = width * pixelSize;
98
99 if (depthPitch == 0)
100 depthPitch = rowPitch * height;
101
102 const vk::VkDeviceSize size = depthPitch * depth;
103
104 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(srcBuffer);
105 const uint8_t *srcStart;
106 srcStart = srcRow;
107 uint8_t *dstRow = reinterpret_cast<uint8_t *>(destBuffer);
108 uint8_t *dstStart;
109 dstStart = dstRow;
110
111 if (rowPitch == static_cast<vk::VkDeviceSize>(width * pixelSize) &&
112 depthPitch == static_cast<vk::VkDeviceSize>(rowPitch * height))
113 {
114 // fast path
115 deMemcpy(dstRow, srcRow, static_cast<size_t>(size));
116 }
117 else
118 {
119 // slower, per row path
120 for (size_t d = 0; d < (size_t)depth; d++)
121 {
122 vk::VkDeviceSize offsetDepthDst = d * (pixelSize * width * height);
123 vk::VkDeviceSize offsetDepthSrc = d * depthPitch;
124 srcRow = srcStart + offsetDepthSrc;
125 dstRow = dstStart + offsetDepthDst;
126 for (int r = 0; r < height; ++r)
127 {
128 deMemcpy(dstRow, srcRow, static_cast<size_t>(pixelSize * width));
129 srcRow += rowPitch;
130 dstRow += pixelSize * width;
131 }
132 }
133 }
134 }
135
Image(const vk::DeviceInterface & vk,vk::VkDevice device,uint32_t queueFamilyIndex,vk::VkFormat format,const vk::VkExtent3D & extend,uint32_t levelCount,uint32_t layerCount,vk::Move<vk::VkImage> object_)136 Image::Image(const vk::DeviceInterface &vk, vk::VkDevice device, uint32_t queueFamilyIndex, vk::VkFormat format,
137 const vk::VkExtent3D &extend, uint32_t levelCount, uint32_t layerCount, vk::Move<vk::VkImage> object_)
138 : m_allocation(DE_NULL)
139 , m_object(object_)
140 , m_queueFamilyIndex(queueFamilyIndex)
141 , m_format(format)
142 , m_extent(extend)
143 , m_levelCount(levelCount)
144 , m_layerCount(layerCount)
145 , m_vk(vk)
146 , m_device(device)
147 {
148 }
149
readSurface(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)150 tcu::ConstPixelBufferAccess Image::readSurface(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
151 vk::VkOffset3D offset, int width, int height,
152 vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
153 unsigned int arrayElement)
154 {
155 m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
156 deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
157 if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
158 {
159 read(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_2D,
160 m_pixelAccessData.data());
161 }
162 if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
163 {
164 readUsingBuffer(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect,
165 m_pixelAccessData.data());
166 }
167 return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
168 }
169
readDepth(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,int height,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)170 tcu::ConstPixelBufferAccess Image::readDepth(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
171 vk::VkOffset3D offset, int width, int height,
172 vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
173 unsigned int arrayElement)
174 {
175 DE_ASSERT(aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT);
176 const tcu::TextureFormat tcuFormat = getDepthCopyFormat(m_format);
177 m_pixelAccessData.resize(width * height * tcuFormat.getPixelSize());
178 deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
179
180 readUsingBuffer(queue, allocator, layout, offset, width, height, 1, mipLevel, arrayElement, aspect,
181 m_pixelAccessData.data());
182 return tcu::ConstPixelBufferAccess(tcuFormat, width, height, 1, m_pixelAccessData.data());
183 }
184
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)185 tcu::ConstPixelBufferAccess Image::readVolume(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
186 vk::VkOffset3D offset, int width, int height, int depth,
187 vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
188 unsigned int arrayElement)
189 {
190 m_pixelAccessData.resize(width * height * depth * vk::mapVkFormat(m_format).getPixelSize());
191 deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
192 if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
193 {
194 read(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect,
195 vk::VK_IMAGE_TYPE_3D, m_pixelAccessData.data());
196 }
197 if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
198 {
199 readUsingBuffer(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect,
200 m_pixelAccessData.data());
201 }
202 return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, depth, m_pixelAccessData.data());
203 }
204
readSurface1D(vk::VkQueue queue,vk::Allocator & allocator,vk::VkImageLayout layout,vk::VkOffset3D offset,int width,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)205 tcu::ConstPixelBufferAccess Image::readSurface1D(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
206 vk::VkOffset3D offset, int width, vk::VkImageAspectFlagBits aspect,
207 unsigned int mipLevel, unsigned int arrayElement)
208 {
209 m_pixelAccessData.resize(width * vk::mapVkFormat(m_format).getPixelSize());
210 deMemset(m_pixelAccessData.data(), 0, m_pixelAccessData.size());
211 if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
212 {
213 read(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect, vk::VK_IMAGE_TYPE_1D,
214 m_pixelAccessData.data());
215 }
216 if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
217 {
218 readUsingBuffer(queue, allocator, layout, offset, width, 1, 1, mipLevel, arrayElement, aspect,
219 m_pixelAccessData.data());
220 }
221 return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, 1, 1, m_pixelAccessData.data());
222 }
223
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)224 void Image::read(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout, vk::VkOffset3D offset,
225 int width, int height, int depth, unsigned int mipLevel, unsigned int arrayElement,
226 vk::VkImageAspectFlagBits aspect, vk::VkImageType type, void *data)
227 {
228 DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
229
230 de::SharedPtr<Image> stagingResource =
231 copyToLinearImage(queue, allocator, layout, offset, width, height, depth, mipLevel, arrayElement, aspect, type);
232 const vk::VkOffset3D zeroOffset = {0, 0, 0};
233 stagingResource->readLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
234 }
235
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)236 void Image::readUsingBuffer(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
237 vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
238 unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, void *data)
239 {
240 DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
241
242 de::SharedPtr<Buffer> stagingResource;
243
244 bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
245 vk::VkDeviceSize bufferSize = 0;
246
247 if (!isCombinedType)
248 bufferSize = vk::mapVkFormat(m_format).getPixelSize() * width * height * depth;
249
250 uint32_t pixelMask = 0xffffffff;
251 if (isCombinedType)
252 {
253 int pixelSize = 0;
254 switch (m_format)
255 {
256 case vk::VK_FORMAT_D16_UNORM_S8_UINT:
257 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
258 break;
259 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
260 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
261 break;
262 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
263 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
264 // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels.
265 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
266 pixelMask = 0x00ffffff;
267 break;
268
269 default:
270 DE_FATAL("Not implemented");
271 }
272 bufferSize = pixelSize * width * height * depth;
273 }
274
275 BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT |
276 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
277 stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator,
278 vk::MemoryRequirement::HostVisible);
279
280 {
281 CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
282 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
283 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
284 vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
285
286 beginCommandBuffer(m_vk, *copyCmdBuffer);
287
288 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
289 {
290 layout = vk::VK_IMAGE_LAYOUT_GENERAL;
291
292 vk::VkImageMemoryBarrier barrier;
293 barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
294 barrier.pNext = DE_NULL;
295 barrier.srcAccessMask = 0;
296 barrier.dstAccessMask = 0;
297 barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
298 barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
299 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
300 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
301 barrier.image = object();
302
303 barrier.subresourceRange.aspectMask = aspect;
304 barrier.subresourceRange.baseMipLevel = 0;
305 barrier.subresourceRange.levelCount = m_levelCount;
306 barrier.subresourceRange.baseArrayLayer = 0;
307 barrier.subresourceRange.layerCount = m_layerCount;
308
309 m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
310 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0, 0,
311 (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL,
312 1, &barrier);
313 }
314
315 vk::VkBufferImageCopy region = {0, 0,
316 0, {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
317 offset, {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
318
319 m_vk.cmdCopyImageToBuffer(*copyCmdBuffer, object(), layout, stagingResource->object(), 1, ®ion);
320
321 // pipeline barrier for accessing the staging buffer from HOST
322 {
323 const vk::VkBufferMemoryBarrier memoryBarrier = {vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
324 DE_NULL,
325 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
326 vk::VK_ACCESS_HOST_READ_BIT,
327 VK_QUEUE_FAMILY_IGNORED,
328 VK_QUEUE_FAMILY_IGNORED,
329 stagingResource->object(),
330 0u,
331 VK_WHOLE_SIZE};
332 m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
333 0u, 0u, DE_NULL, 1u, &memoryBarrier, 0u, DE_NULL);
334 }
335
336 endCommandBuffer(m_vk, *copyCmdBuffer);
337
338 submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
339 }
340
341 // Validate the results
342 const vk::Allocation &bufAllocation = stagingResource->getBoundMemory();
343 invalidateMappedMemoryRange(m_vk, m_device, bufAllocation.getMemory(), bufAllocation.getOffset(), VK_WHOLE_SIZE);
344
345 uint8_t *destPtr = reinterpret_cast<uint8_t *>(stagingResource->getBoundMemory().getHostPtr());
346 deMemcpy(data, destPtr, static_cast<size_t>(bufferSize));
347 if (pixelMask != 0xffffffff)
348 {
349 /* data copied to or from the depth aspect of a
350 VK_FORMAT_X8_D24_UNORM_PACK32 or VK_FORMAT_D24_UNORM_S8_UINT format
351 is packed with one 32-bit word per texel with the D24 value in the
352 LSBs of the word, and *undefined* values in the eight MSBs. */
353 uint32_t *const data32 = static_cast<uint32_t *>(data);
354 const vk::VkDeviceSize data32Count = bufferSize / sizeof(uint32_t);
355 for (vk::VkDeviceSize i = 0; i < data32Count; ++i)
356 data32[i] &= pixelMask;
357 }
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, int width, int height, int depth,
361 vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
362 unsigned int arrayElement)
363 {
364 m_pixelAccessData.resize(width * height * vk::mapVkFormat(m_format).getPixelSize());
365 readLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, m_pixelAccessData.data());
366 return tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_format), width, height, 1, m_pixelAccessData.data());
367 }
368
readLinear(vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,void * data)369 void Image::readLinear(vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
370 unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, void *data)
371 {
372 DE_ASSERT(mipLevel < m_levelCount);
373 DE_ASSERT(arrayElement < m_layerCount);
374
375 vk::VkImageSubresource imageSubResource = {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement};
376
377 vk::VkSubresourceLayout imageLayout;
378 deMemset(&imageLayout, 0, sizeof(imageLayout));
379
380 m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource, &imageLayout);
381
382 const uint8_t *srcPtr = reinterpret_cast<const uint8_t *>(getBoundMemory().getHostPtr());
383 srcPtr += imageLayout.offset;
384 srcPtr += offset.z * imageLayout.depthPitch;
385 srcPtr += offset.y * imageLayout.rowPitch;
386 srcPtr += offset.x;
387
388 MemoryOp::unpack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth, imageLayout.rowPitch,
389 imageLayout.depthPitch, srcPtr, data);
390 }
391
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)392 de::SharedPtr<Image> Image::copyToLinearImage(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
393 vk::VkOffset3D offset, int width, int height, int depth,
394 unsigned int mipLevel, unsigned int arrayElement,
395 vk::VkImageAspectFlagBits aspect, vk::VkImageType type)
396 {
397 de::SharedPtr<Image> stagingResource;
398 {
399 vk::VkExtent3D stagingExtent = {(uint32_t)width, (uint32_t)height, (uint32_t)depth};
400 ImageCreateInfo stagingResourceCreateInfo(type, m_format, stagingExtent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
401 vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
402
403 stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator,
404 m_queueFamilyIndex, vk::MemoryRequirement::HostVisible);
405
406 CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
407 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
408 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
409 vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
410
411 beginCommandBuffer(m_vk, *copyCmdBuffer);
412
413 transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED,
414 vk::VK_IMAGE_LAYOUT_GENERAL, 0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT,
415 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
416
417 const vk::VkOffset3D zeroOffset = {0, 0, 0};
418 vk::VkImageCopy region = {{(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
419 offset,
420 {(vk::VkImageAspectFlags)aspect, 0, 0, 1},
421 zeroOffset,
422 {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
423
424 m_vk.cmdCopyImage(*copyCmdBuffer, object(), layout, stagingResource->object(), vk::VK_IMAGE_LAYOUT_GENERAL, 1,
425 ®ion);
426
427 // pipeline barrier for accessing the staging image from HOST
428 {
429 const vk::VkImageMemoryBarrier memoryBarrier = {
430 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
431 DE_NULL,
432 vk::VK_ACCESS_TRANSFER_WRITE_BIT,
433 vk::VK_ACCESS_HOST_READ_BIT,
434 vk::VK_IMAGE_LAYOUT_GENERAL,
435 vk::VK_IMAGE_LAYOUT_GENERAL,
436 VK_QUEUE_FAMILY_IGNORED,
437 VK_QUEUE_FAMILY_IGNORED,
438 stagingResource->object(),
439 {static_cast<vk::VkImageAspectFlags>(aspect), 0u, 1u, 0u, 1u}};
440 m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT,
441 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &memoryBarrier);
442 }
443
444 endCommandBuffer(m_vk, *copyCmdBuffer);
445
446 submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
447
448 // Validate the results
449 const vk::Allocation &imgAllocation = stagingResource->getBoundMemory();
450 invalidateMappedMemoryRange(m_vk, m_device, imgAllocation.getMemory(), imgAllocation.getOffset(),
451 VK_WHOLE_SIZE);
452 }
453 return stagingResource;
454 }
455
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)456 void Image::uploadVolume(const tcu::ConstPixelBufferAccess &access, vk::VkQueue queue, vk::Allocator &allocator,
457 vk::VkImageLayout layout, vk::VkOffset3D offset, vk::VkImageAspectFlagBits aspect,
458 unsigned int mipLevel, unsigned int arrayElement)
459 {
460 if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
461 {
462 upload(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(), mipLevel,
463 arrayElement, aspect, vk::VK_IMAGE_TYPE_3D, access.getDataPtr());
464 }
465 if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
466 {
467 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(),
468 mipLevel, arrayElement, aspect, access.getDataPtr());
469 }
470 }
471
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)472 void Image::uploadSurface(const tcu::ConstPixelBufferAccess &access, vk::VkQueue queue, vk::Allocator &allocator,
473 vk::VkImageLayout layout, vk::VkOffset3D offset, vk::VkImageAspectFlagBits aspect,
474 unsigned int mipLevel, unsigned int arrayElement)
475 {
476 if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
477 {
478 upload(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(), mipLevel,
479 arrayElement, aspect, vk::VK_IMAGE_TYPE_2D, access.getDataPtr());
480 }
481 if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
482 {
483 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(),
484 mipLevel, arrayElement, aspect, access.getDataPtr());
485 }
486 }
487
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)488 void Image::uploadSurface1D(const tcu::ConstPixelBufferAccess &access, vk::VkQueue queue, vk::Allocator &allocator,
489 vk::VkImageLayout layout, vk::VkOffset3D offset, vk::VkImageAspectFlagBits aspect,
490 unsigned int mipLevel, unsigned int arrayElement)
491 {
492 if (aspect == vk::VK_IMAGE_ASPECT_COLOR_BIT)
493 {
494 upload(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(), mipLevel,
495 arrayElement, aspect, vk::VK_IMAGE_TYPE_1D, access.getDataPtr());
496 }
497 if (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT || aspect == vk::VK_IMAGE_ASPECT_STENCIL_BIT)
498 {
499 uploadUsingBuffer(queue, allocator, layout, offset, access.getWidth(), access.getHeight(), access.getDepth(),
500 mipLevel, arrayElement, aspect, access.getDataPtr());
501 }
502 }
503
uploadSurfaceLinear(const tcu::ConstPixelBufferAccess & access,vk::VkOffset3D offset,int width,int height,int depth,vk::VkImageAspectFlagBits aspect,unsigned int mipLevel,unsigned int arrayElement)504 void Image::uploadSurfaceLinear(const tcu::ConstPixelBufferAccess &access, vk::VkOffset3D offset, int width, int height,
505 int depth, vk::VkImageAspectFlagBits aspect, unsigned int mipLevel,
506 unsigned int arrayElement)
507 {
508 uploadLinear(offset, width, height, depth, mipLevel, arrayElement, aspect, access.getDataPtr());
509 }
510
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)511 void Image::upload(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout, vk::VkOffset3D offset,
512 int width, int height, int depth, unsigned int mipLevel, unsigned int arrayElement,
513 vk::VkImageAspectFlagBits aspect, vk::VkImageType type, const void *data)
514 {
515 DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED ||
516 layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
517
518 de::SharedPtr<Image> stagingResource;
519 vk::VkExtent3D extent = {(uint32_t)width, (uint32_t)height, (uint32_t)depth};
520 ImageCreateInfo stagingResourceCreateInfo(type, m_format, extent, 1, 1, vk::VK_SAMPLE_COUNT_1_BIT,
521 vk::VK_IMAGE_TILING_LINEAR, vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
522
523 stagingResource = Image::createAndAlloc(m_vk, m_device, stagingResourceCreateInfo, allocator, m_queueFamilyIndex,
524 vk::MemoryRequirement::HostVisible);
525
526 const vk::VkOffset3D zeroOffset = {0, 0, 0};
527 stagingResource->uploadLinear(zeroOffset, width, height, depth, 0, 0, aspect, data);
528
529 {
530 CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
531 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
532 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
533 vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
534
535 beginCommandBuffer(m_vk, *copyCmdBuffer);
536
537 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
538 {
539 layout = vk::VK_IMAGE_LAYOUT_GENERAL;
540
541 vk::VkImageMemoryBarrier barrier;
542 barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
543 barrier.pNext = DE_NULL;
544 barrier.srcAccessMask = 0;
545 barrier.dstAccessMask = 0;
546 barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
547 barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
548 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
549 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
550 barrier.image = object();
551
552 barrier.subresourceRange.aspectMask = aspect;
553 barrier.subresourceRange.baseMipLevel = 0;
554 barrier.subresourceRange.levelCount = m_levelCount;
555 barrier.subresourceRange.baseArrayLayer = 0;
556 barrier.subresourceRange.layerCount = m_layerCount;
557
558 m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
559 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0, 0,
560 (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL,
561 1, &barrier);
562 }
563
564 transition2DImage(m_vk, *copyCmdBuffer, stagingResource->object(), aspect, vk::VK_IMAGE_LAYOUT_UNDEFINED,
565 vk::VK_IMAGE_LAYOUT_GENERAL, 0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT,
566 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT);
567
568 vk::VkImageCopy region = {{(vk::VkImageAspectFlags)aspect, 0, 0, 1},
569 zeroOffset,
570 {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
571 offset,
572 {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
573
574 m_vk.cmdCopyImage(*copyCmdBuffer, stagingResource->object(), vk::VK_IMAGE_LAYOUT_GENERAL, object(), layout, 1,
575 ®ion);
576 endCommandBuffer(m_vk, *copyCmdBuffer);
577
578 submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
579 }
580 }
581
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)582 void Image::uploadUsingBuffer(vk::VkQueue queue, vk::Allocator &allocator, vk::VkImageLayout layout,
583 vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
584 unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, const void *data)
585 {
586 DE_ASSERT(layout == vk::VK_IMAGE_LAYOUT_GENERAL || layout == vk::VK_IMAGE_LAYOUT_UNDEFINED ||
587 layout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
588
589 de::SharedPtr<Buffer> stagingResource;
590 bool isCombinedType = isCombinedDepthStencilType(vk::mapVkFormat(m_format).type);
591 vk::VkDeviceSize bufferSize = 0;
592 if (!isCombinedType)
593 bufferSize = vk::mapVkFormat(m_format).getPixelSize() * width * height * depth;
594 if (isCombinedType)
595 {
596 int pixelSize = 0;
597 switch (m_format)
598 {
599 case vk::VK_FORMAT_D16_UNORM_S8_UINT:
600 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 2 : 1;
601 break;
602 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT:
603 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 4 : 1;
604 break;
605 case vk::VK_FORMAT_X8_D24_UNORM_PACK32:
606 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
607 pixelSize = (aspect == vk::VK_IMAGE_ASPECT_DEPTH_BIT) ? 3 : 1;
608 break;
609
610 default:
611 DE_FATAL("Not implemented");
612 }
613 bufferSize = pixelSize * width * height * depth;
614 }
615 BufferCreateInfo stagingBufferResourceCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT |
616 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
617 stagingResource = Buffer::createAndAlloc(m_vk, m_device, stagingBufferResourceCreateInfo, allocator,
618 vk::MemoryRequirement::HostVisible);
619 uint8_t *destPtr = reinterpret_cast<uint8_t *>(stagingResource->getBoundMemory().getHostPtr());
620 deMemcpy(destPtr, data, static_cast<size_t>(bufferSize));
621 vk::flushAlloc(m_vk, m_device, stagingResource->getBoundMemory());
622 {
623 CmdPoolCreateInfo copyCmdPoolCreateInfo(m_queueFamilyIndex);
624 vk::Unique<vk::VkCommandPool> copyCmdPool(vk::createCommandPool(m_vk, m_device, ©CmdPoolCreateInfo));
625 vk::Unique<vk::VkCommandBuffer> copyCmdBuffer(
626 vk::allocateCommandBuffer(m_vk, m_device, *copyCmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
627
628 beginCommandBuffer(m_vk, *copyCmdBuffer);
629
630 if (layout == vk::VK_IMAGE_LAYOUT_UNDEFINED)
631 {
632 layout = vk::VK_IMAGE_LAYOUT_GENERAL;
633
634 vk::VkImageMemoryBarrier barrier;
635 barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
636 barrier.pNext = DE_NULL;
637 barrier.srcAccessMask = 0;
638 barrier.dstAccessMask = 0;
639 barrier.oldLayout = vk::VK_IMAGE_LAYOUT_UNDEFINED;
640 barrier.newLayout = vk::VK_IMAGE_LAYOUT_GENERAL;
641 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
642 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
643 barrier.image = object();
644
645 barrier.subresourceRange.aspectMask = aspect;
646 barrier.subresourceRange.baseMipLevel = 0;
647 barrier.subresourceRange.levelCount = m_levelCount;
648 barrier.subresourceRange.baseArrayLayer = 0;
649 barrier.subresourceRange.layerCount = m_layerCount;
650
651 m_vk.cmdPipelineBarrier(*copyCmdBuffer, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
652 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0, 0,
653 (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL,
654 1, &barrier);
655 }
656
657 vk::VkBufferImageCopy region = {0, 0,
658 0, {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement, 1},
659 offset, {(uint32_t)width, (uint32_t)height, (uint32_t)depth}};
660
661 m_vk.cmdCopyBufferToImage(*copyCmdBuffer, stagingResource->object(), object(), layout, 1, ®ion);
662 endCommandBuffer(m_vk, *copyCmdBuffer);
663
664 submitCommandsAndWait(m_vk, m_device, queue, copyCmdBuffer.get());
665 }
666 }
667
uploadLinear(vk::VkOffset3D offset,int width,int height,int depth,unsigned int mipLevel,unsigned int arrayElement,vk::VkImageAspectFlagBits aspect,const void * data)668 void Image::uploadLinear(vk::VkOffset3D offset, int width, int height, int depth, unsigned int mipLevel,
669 unsigned int arrayElement, vk::VkImageAspectFlagBits aspect, const void *data)
670 {
671 DE_ASSERT(mipLevel < m_levelCount);
672 DE_ASSERT(arrayElement < m_layerCount);
673
674 vk::VkSubresourceLayout imageLayout;
675
676 vk::VkImageSubresource imageSubResource = {(vk::VkImageAspectFlags)aspect, mipLevel, arrayElement};
677
678 m_vk.getImageSubresourceLayout(m_device, object(), &imageSubResource, &imageLayout);
679
680 uint8_t *destPtr = reinterpret_cast<uint8_t *>(getBoundMemory().getHostPtr());
681 destPtr += imageLayout.offset;
682 destPtr += offset.z * imageLayout.depthPitch;
683 destPtr += offset.y * imageLayout.rowPitch;
684 destPtr += offset.x;
685
686 MemoryOp::pack(vk::mapVkFormat(m_format).getPixelSize(), width, height, depth, imageLayout.rowPitch,
687 imageLayout.depthPitch, data, destPtr);
688 }
689
bindMemory(de::MovePtr<vk::Allocation> allocation)690 void Image::bindMemory(de::MovePtr<vk::Allocation> allocation)
691 {
692 DE_ASSERT(allocation);
693 VK_CHECK(m_vk.bindImageMemory(m_device, *m_object, allocation->getMemory(), allocation->getOffset()));
694
695 DE_ASSERT(!m_allocation);
696 m_allocation = allocation;
697 }
698
createAndAlloc(const vk::DeviceInterface & vk,vk::VkDevice device,const vk::VkImageCreateInfo & createInfo,vk::Allocator & allocator,uint32_t queueFamilyIndex,vk::MemoryRequirement memoryRequirement)699 de::SharedPtr<Image> Image::createAndAlloc(const vk::DeviceInterface &vk, vk::VkDevice device,
700 const vk::VkImageCreateInfo &createInfo, vk::Allocator &allocator,
701 uint32_t queueFamilyIndex, vk::MemoryRequirement memoryRequirement)
702 {
703 de::SharedPtr<Image> ret = create(vk, device, createInfo, queueFamilyIndex);
704
705 vk::VkMemoryRequirements imageRequirements = vk::getImageMemoryRequirements(vk, device, ret->object());
706 ret->bindMemory(allocator.allocate(imageRequirements, memoryRequirement));
707 return ret;
708 }
709
create(const vk::DeviceInterface & vk,vk::VkDevice device,const vk::VkImageCreateInfo & createInfo,uint32_t queueFamilyIndex)710 de::SharedPtr<Image> Image::create(const vk::DeviceInterface &vk, vk::VkDevice device,
711 const vk::VkImageCreateInfo &createInfo, uint32_t queueFamilyIndex)
712 {
713 return de::SharedPtr<Image>(new Image(vk, device, queueFamilyIndex, createInfo.format, createInfo.extent,
714 createInfo.mipLevels, createInfo.arrayLayers,
715 vk::createImage(vk, device, &createInfo)));
716 }
717
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,vk::VkPipelineStageFlags srcStageMask,vk::VkPipelineStageFlags dstStageMask,uint32_t numLayers)718 void transition2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
719 vk::VkImageAspectFlags aspectMask, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout,
720 vk::VkAccessFlags srcAccessMask, vk::VkAccessFlags dstAccessMask,
721 vk::VkPipelineStageFlags srcStageMask, vk::VkPipelineStageFlags dstStageMask, uint32_t numLayers)
722 {
723 vk::VkImageMemoryBarrier barrier;
724 barrier.sType = vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
725 barrier.pNext = DE_NULL;
726 barrier.srcAccessMask = srcAccessMask;
727 barrier.dstAccessMask = dstAccessMask;
728 barrier.oldLayout = oldLayout;
729 barrier.newLayout = newLayout;
730 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
731 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
732 barrier.image = image;
733 barrier.subresourceRange.aspectMask = aspectMask;
734 barrier.subresourceRange.baseMipLevel = 0;
735 barrier.subresourceRange.levelCount = 1;
736 barrier.subresourceRange.baseArrayLayer = 0;
737 barrier.subresourceRange.layerCount = numLayers;
738
739 vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (vk::VkDependencyFlags)0, 0,
740 (const vk::VkMemoryBarrier *)DE_NULL, 0, (const vk::VkBufferMemoryBarrier *)DE_NULL, 1,
741 &barrier);
742 }
743
initialTransitionColor2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask,uint32_t numLayers)744 void initialTransitionColor2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
745 vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
746 vk::VkPipelineStageFlags dstStageMask, uint32_t numLayers)
747 {
748 transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_COLOR_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u,
749 dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, numLayers);
750 }
751
initialTransitionDepth2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask)752 void initialTransitionDepth2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
753 vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
754 vk::VkPipelineStageFlags dstStageMask)
755 {
756 transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u,
757 dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask);
758 }
759
initialTransitionStencil2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask)760 void initialTransitionStencil2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
761 vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
762 vk::VkPipelineStageFlags dstStageMask)
763 {
764 transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_STENCIL_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u,
765 dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask);
766 }
767
initialTransitionDepthStencil2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageLayout layout,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags dstStageMask)768 void initialTransitionDepthStencil2DImage(const vk::DeviceInterface &vk, vk::VkCommandBuffer cmdBuffer,
769 vk::VkImage image, vk::VkImageLayout layout, vk::VkAccessFlags dstAccessMask,
770 vk::VkPipelineStageFlags dstStageMask)
771 {
772 transition2DImage(vk, cmdBuffer, image, vk::VK_IMAGE_ASPECT_DEPTH_BIT | vk::VK_IMAGE_ASPECT_STENCIL_BIT,
773 vk::VK_IMAGE_LAYOUT_UNDEFINED, layout, 0u, dstAccessMask, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
774 dstStageMask);
775 }
776
777 } // namespace Draw
778 } // namespace vkt
779