1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2022 The Khronos Group Inc.
6 * Copyright (c) 2022 Google LLC.
7 * Copyright (c) 2022 LunarG, Inc.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Tests for VK_EXT_host_image_copy
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktImageHostImageCopyTests.hpp"
27
28 #include "vktTestCase.hpp"
29 #include "vktTestGroupUtil.hpp"
30
31 #include "vkCmdUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkBarrierUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkBuilderUtil.hpp"
39 #include "vkImageWithMemory.hpp"
40 #include "vkBufferWithMemory.hpp"
41 #include "vktImageTestsUtil.hpp"
42 #include "ycbcr/vktYCbCrUtil.hpp"
43
44 #include "tcuTestLog.hpp"
45
46 namespace vkt
47 {
48 namespace image
49 {
50 namespace
51 {
52
53 using namespace vk;
54
getAspectFlags(vk::VkFormat format)55 vk::VkImageAspectFlags getAspectFlags (vk::VkFormat format)
56 {
57 if (isCompressedFormat(format))
58 {
59 return vk::VK_IMAGE_ASPECT_COLOR_BIT;
60 }
61
62 const auto sampledFormat = mapVkFormat(format);
63 if (sampledFormat.order == tcu::TextureFormat::S)
64 {
65 return vk::VK_IMAGE_ASPECT_STENCIL_BIT;
66 }
67 if (sampledFormat.order == tcu::TextureFormat::D || sampledFormat.order == tcu::TextureFormat::DS)
68 {
69 return vk::VK_IMAGE_ASPECT_DEPTH_BIT;
70 }
71 return vk::VK_IMAGE_ASPECT_COLOR_BIT;
72 }
73
getChannelSize(vk::VkFormat format)74 deUint32 getChannelSize (vk::VkFormat format)
75 {
76 const auto tcuFormat = isCompressedFormat(format) ? tcu::getUncompressedFormat(mapVkCompressedFormat(format)) : mapVkFormat(format);
77 if (tcuFormat.order != tcu::TextureFormat::D && tcuFormat.order != tcu::TextureFormat::S && tcuFormat.order != tcu::TextureFormat::DS)
78 {
79 return tcu::getChannelSize(tcuFormat.type);
80 }
81 switch (format)
82 {
83 case vk::VK_FORMAT_D24_UNORM_S8_UINT:
84 return 4;
85 case vk::VK_FORMAT_D32_SFLOAT:
86 return 4;
87 case vk::VK_FORMAT_D16_UNORM:
88 return 2;
89 case vk::VK_FORMAT_S8_UINT:
90 return 1;
91 default:
92 break;
93 }
94 DE_ASSERT(0);
95 return 0;
96 }
97
getNumChannels(vk::VkFormat format)98 deUint32 getNumChannels (vk::VkFormat format)
99 {
100 const auto tcuFormat = isCompressedFormat(format) ? tcu::getUncompressedFormat(mapVkCompressedFormat(format)) : mapVkFormat(format);
101 if (tcuFormat.order != tcu::TextureFormat::D && tcuFormat.order != tcu::TextureFormat::S && tcuFormat.order != tcu::TextureFormat::DS)
102 {
103 return tcu::getNumUsedChannels(tcuFormat.order);
104 }
105 return 1;
106 }
107
generateData(void * ptr,deUint32 size,vk::VkFormat format)108 void generateData(void* ptr, deUint32 size, vk::VkFormat format) {
109 if (isDepthStencilFormat(format))
110 {
111 de::Random randomGen(deInt32Hash((deUint32)format) ^
112 deInt32Hash((deUint32)size));
113 if (format == VK_FORMAT_D16_UNORM) {
114 ycbcr::fillRandomNoNaN(&randomGen, (deUint8*)ptr, size, VK_FORMAT_R16_UNORM);
115 } else {
116 ycbcr::fillRandomNoNaN(&randomGen, (deUint8*)ptr, size, VK_FORMAT_R32_SFLOAT);
117 }
118 }
119 else if (isCompressedFormat(format))
120 {
121 memset(ptr, 255, size);
122 }
123 else
124 {
125 de::Random randomGen(deInt32Hash((deUint32)format) ^
126 deInt32Hash((deUint32)size));
127 ycbcr::fillRandomNoNaN(&randomGen, (deUint8*)ptr, size, format);
128 }
129 }
130
getHostImageCopyProperties(const vk::InstanceDriver & instanceDriver,VkPhysicalDevice physicalDevice,vk::VkPhysicalDeviceHostImageCopyPropertiesEXT * hostImageCopyProperties)131 void getHostImageCopyProperties(const vk::InstanceDriver& instanceDriver, VkPhysicalDevice physicalDevice, vk::VkPhysicalDeviceHostImageCopyPropertiesEXT* hostImageCopyProperties) {
132 vk::VkPhysicalDeviceProperties properties;
133 deMemset(&properties, 0, sizeof(vk::VkPhysicalDeviceProperties));
134 vk::VkPhysicalDeviceProperties2 properties2 =
135 {
136 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, // VkStructureType sType
137 hostImageCopyProperties, // const void* pNext
138 properties // VkPhysicalDeviceProperties properties
139 };
140 instanceDriver.getPhysicalDeviceProperties2(physicalDevice, &properties2);
141 }
142
isBlockCompressedFormat(vk::VkFormat format)143 bool isBlockCompressedFormat (vk::VkFormat format)
144 {
145 switch (format)
146 {
147 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
148 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
149 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
150 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
151 case VK_FORMAT_BC2_UNORM_BLOCK:
152 case VK_FORMAT_BC2_SRGB_BLOCK:
153 case VK_FORMAT_BC3_UNORM_BLOCK:
154 case VK_FORMAT_BC3_SRGB_BLOCK:
155 case VK_FORMAT_BC4_UNORM_BLOCK:
156 case VK_FORMAT_BC4_SNORM_BLOCK:
157 case VK_FORMAT_BC5_UNORM_BLOCK:
158 case VK_FORMAT_BC5_SNORM_BLOCK:
159 case VK_FORMAT_BC6H_UFLOAT_BLOCK:
160 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
161 case VK_FORMAT_BC7_UNORM_BLOCK:
162 case VK_FORMAT_BC7_SRGB_BLOCK:
163 return true;
164 default:
165 break;
166 }
167 return false;
168 }
169
checkSupportedFormatFeatures(const vk::InstanceDriver & vki,VkPhysicalDevice physicalDevice,vk::VkFormat format,vk::VkImageTiling tiling,deUint64 * outDrmModifier)170 void checkSupportedFormatFeatures(const vk::InstanceDriver& vki, VkPhysicalDevice physicalDevice, vk::VkFormat format, vk::VkImageTiling tiling, deUint64 *outDrmModifier)
171 {
172 vk::VkDrmFormatModifierPropertiesList2EXT drmList = vk::initVulkanStructure();
173 vk::VkFormatProperties3 formatProperties3 = tiling == vk::VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ?
174 vk::initVulkanStructure(&drmList) :
175 vk::initVulkanStructure();
176 vk::VkFormatProperties2 formatProperties2 = vk::initVulkanStructure(&formatProperties3);
177 vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties2);
178 std::vector<vk::VkDrmFormatModifierProperties2EXT> modifiers(drmList.drmFormatModifierCount);
179
180 if (tiling == vk::VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
181 {
182 if (drmList.drmFormatModifierCount == 0)
183 TCU_THROW(NotSupportedError, "Format feature host image transfer not supported for drm format modifier.");
184 drmList.pDrmFormatModifierProperties = modifiers.data();
185 vki.getPhysicalDeviceFormatProperties2(physicalDevice, format, &formatProperties2);
186
187 bool modifierFound = false;
188 for (deUint32 i = 0; i < drmList.drmFormatModifierCount; ++i)
189 {
190 if (drmList.pDrmFormatModifierProperties[i].drmFormatModifierTilingFeatures & vk::VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT)
191 {
192 *outDrmModifier = drmList.pDrmFormatModifierProperties[i].drmFormatModifier;
193 return;
194 }
195 }
196
197 if (!modifierFound)
198 TCU_THROW(NotSupportedError, "Format feature host image transfer not supported for drm format modifier.");
199 }
200 else
201 {
202 if (tiling == vk::VK_IMAGE_TILING_LINEAR &&
203 (formatProperties3.linearTilingFeatures & vk::VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0)
204 TCU_THROW(NotSupportedError, "Format feature host image transfer not supported for optimal tiling.");
205 if (tiling == vk::VK_IMAGE_TILING_OPTIMAL &&
206 (formatProperties3.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0)
207 TCU_THROW(NotSupportedError, "Format feature host image transfer not supported for optimal tiling.");
208 }
209 }
210
211 enum Command {
212 DRAW,
213 DISPATCH,
214 };
215
216 struct TestParameters
217 {
218 bool hostCopyMemoryToImage;
219 bool hostCopyImageToMemory;
220 bool hostTransferLayout;
221 bool outputImageHostTransition;
222 bool memcpyFlag;
223 bool dynamicRendering;
224 Command command;
225 vk::VkFormat imageSampledFormat;
226 vk::VkImageLayout srcLayout;
227 vk::VkImageLayout dstLayout;
228 vk::VkImageLayout intermediateLayout;
229 vk::VkImageTiling sampledTiling;
230 vk::VkFormat imageOutputFormat;
231 vk::VkExtent3D imageSize;
232 bool sparse;
233 deUint32 mipLevel;
234 deUint32 regionsCount;
235 deUint32 padding;
236 };
237
238 class HostImageCopyTestInstance : public vkt::TestInstance
239 {
240 public:
HostImageCopyTestInstance(vkt::Context & context,const TestParameters & parameters)241 HostImageCopyTestInstance (vkt::Context& context, const TestParameters& parameters)
242 : vkt::TestInstance (context)
243 , m_parameters (parameters)
244 {
245 }
246 void transitionImageLayout (const Move<vk::VkCommandBuffer>* cmdBuffer, vk::VkImage image, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout, vk::VkImageSubresourceRange subresourceRange);
247 void copyMemoryToImage (const std::vector<deUint8> testData, vk::VkImage image, deUint32 texelSize, const vk::VkImageSubresourceLayers subresourceLayers, deInt32 xOffset, deInt32 yOffset, deUint32 width, deUint32 height);
248
249 private:
250 tcu::TestStatus iterate (void);
251
252 const TestParameters m_parameters;
253 };
254
transitionImageLayout(const Move<vk::VkCommandBuffer> * cmdBuffer,vk::VkImage image,vk::VkImageLayout oldLayout,vk::VkImageLayout newLayout,vk::VkImageSubresourceRange subresourceRange)255 void HostImageCopyTestInstance::transitionImageLayout (const Move<vk::VkCommandBuffer>* cmdBuffer, vk::VkImage image, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout, vk::VkImageSubresourceRange subresourceRange)
256 {
257 const DeviceInterface& vk = m_context.getDeviceInterface();
258 const vk::VkDevice device = m_context.getDevice();
259 const vk::VkQueue queue = m_context.getUniversalQueue();
260
261 if (m_parameters.hostTransferLayout)
262 {
263 vk::VkHostImageLayoutTransitionInfoEXT transition =
264 {
265 vk::VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT, // VkStructureType sType;
266 DE_NULL, // const void* pNext;
267 image, // VkImage image;
268 oldLayout, // VkImageLayout oldLayout;
269 newLayout, // VkImageLayout newLayout;
270 subresourceRange // VkImageSubresourceRange subresourceRange;
271 };
272 vk.transitionImageLayoutEXT(device, 1, &transition);
273 }
274 else
275 {
276 vk::beginCommandBuffer(vk, **cmdBuffer, 0u);
277 auto imageMemoryBarrier = makeImageMemoryBarrier(0u, vk::VK_ACCESS_TRANSFER_WRITE_BIT, oldLayout, newLayout, image, subresourceRange);
278 vk.cmdPipelineBarrier(**cmdBuffer, vk::VK_PIPELINE_STAGE_NONE, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1, &imageMemoryBarrier);
279 vk::endCommandBuffer(vk, **cmdBuffer);
280 vk::submitCommandsAndWait(vk, device, queue, **cmdBuffer);
281 }
282 }
283
copyMemoryToImage(const std::vector<deUint8> testData,vk::VkImage image,deUint32 texelSize,const vk::VkImageSubresourceLayers subresourceLayers,deInt32 xOffset,deInt32 yOffset,deUint32 width,deUint32 height)284 void HostImageCopyTestInstance::copyMemoryToImage (const std::vector<deUint8> testData, vk::VkImage image, deUint32 texelSize, const vk::VkImageSubresourceLayers subresourceLayers, deInt32 xOffset, deInt32 yOffset, deUint32 width, deUint32 height)
285 {
286 const DeviceInterface& vk = m_context.getDeviceInterface();
287 const vk::VkDevice device = m_context.getDevice();
288 std::vector<deUint8> data (texelSize * width * height);
289 const deUint32 imageWidth = m_parameters.imageSize.width;
290 for (deUint32 i = 0; i < height; ++i) {
291 memcpy(&data[i * width * texelSize], &testData[((yOffset + i) * imageWidth + xOffset) * texelSize], width * texelSize);
292 }
293
294 const deUint32 regionsCount = m_parameters.regionsCount > height ? m_parameters.regionsCount : 1u;
295 std::vector<vk::VkMemoryToImageCopyEXT> regions;
296
297 for (deUint32 i = 0; i < regionsCount; ++i)
298 {
299 vk::VkOffset3D offset = { xOffset, (deInt32)(yOffset + height / regionsCount * i), 0 };
300 vk::VkExtent3D extent = { width, height / regionsCount, 1 };
301 if (i == regionsCount - 1)
302 extent.height = height - height / regionsCount * i;
303
304 if (extent.height == 0)
305 continue;
306
307 deUint32 dataOffset = width * (height / regionsCount * i) * texelSize;
308
309 const vk::VkMemoryToImageCopyEXT region = {
310 vk::VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT, // VkStructureType sType;
311 DE_NULL, // const void* pNext;
312 &data[dataOffset], // const void* memoryHostPointer;
313 0, // uint32_t memoryRowLength;
314 0, // uint32_t memoryImageHeight;
315 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
316 offset, // VkOffset3D imageOffset;
317 extent // VkExtent3D imageExtent;
318 };
319 regions.push_back(region);
320 }
321
322 vk::VkCopyMemoryToImageInfoEXT copyMemoryToImageInfo =
323 {
324 vk::VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT, // VkStructureType sType;
325 DE_NULL, // const void* pNext;
326 0u, // VkMemoryImageCopyFlagsEXT flags;
327 image, // VkImage dstImage;
328 m_parameters.dstLayout, // VkImageLayout dstImageLayout;
329 (deUint32)regions.size(), // uint32_t regionCount;
330 regions.data(), // const VkMemoryToImageCopyEXT* pRegions;
331 };
332
333 vk.copyMemoryToImageEXT(device, ©MemoryToImageInfo);
334 }
335
iterate(void)336 tcu::TestStatus HostImageCopyTestInstance::iterate (void)
337 {
338 const InstanceInterface& vki = m_context.getInstanceInterface();
339 const DeviceInterface& vk = m_context.getDeviceInterface();
340 const vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
341 const vk::VkDevice device = m_context.getDevice();
342 const auto& deviceExtensions = m_context.getDeviceExtensions();
343 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
344 const vk::VkQueue queue = m_context.getUniversalQueue();
345 auto& alloc = m_context.getDefaultAllocator();
346 tcu::TestLog& log = m_context.getTestContext().getLog();
347
348 std::stringstream commandsLog;
349
350 const Move<vk::VkCommandPool> cmdPool (createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
351 const Move<vk::VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
352
353 const vk::VkExtent3D imageSize = { m_parameters.imageSize.width * (deUint32)dePow(2, m_parameters.mipLevel), m_parameters.imageSize.height * (deUint32)dePow(2, m_parameters.mipLevel), 1 };
354 const vk::VkExtent3D mipImageSize = { m_parameters.imageSize.width, m_parameters.imageSize.height, 1 };
355
356 const vk::VkRect2D renderArea = vk::makeRect2D(0, 0, mipImageSize.width, mipImageSize.height);
357
358 const auto sampledChannelSize = getChannelSize(m_parameters.imageSampledFormat);
359 const auto sampledNumChannels = getNumChannels(m_parameters.imageSampledFormat);
360 const auto sampledBufferCount = mipImageSize.width * mipImageSize.height * sampledNumChannels;
361 const auto sampledBufferSize = sampledBufferCount * sampledChannelSize;
362
363 const auto outputFormat = mapVkFormat(m_parameters.imageOutputFormat);
364 const auto outputChannelSize = getChannelSize(m_parameters.imageOutputFormat);
365 const auto outputNumChannels = getNumUsedChannels(m_parameters.imageOutputFormat);
366 const auto outputBufferCount = mipImageSize.width * mipImageSize.height * outputNumChannels;
367 const auto outputBufferSize = outputBufferCount * outputChannelSize;
368
369 vk::VkImage sampledImage;
370 de::MovePtr<ImageWithMemory> sampledImageWithMemory;
371 de::MovePtr<SparseImage> sparseSampledImage;
372 de::MovePtr<ImageWithMemory> sampledImageWithMemoryCopy;
373 de::MovePtr<ImageWithMemory> outputImage;
374 Move<vk::VkImageView> sampledImageView;
375 Move<vk::VkImageView> sampledImageViewCopy;
376 Move<vk::VkImageView> outputImageView;
377
378 const vk::VkImageAspectFlags sampledAspect = getAspectFlags(m_parameters.imageSampledFormat);
379 const vk::VkComponentMapping componentMapping = makeComponentMappingRGBA();
380 const vk::VkOffset3D imageOffset = makeOffset3D(0, 0, 0);
381 const vk::VkImageSubresource sampledSubresource = makeImageSubresource(sampledAspect, m_parameters.mipLevel, 0u);
382 const vk::VkImageSubresourceRange sampledSubresourceRange = makeImageSubresourceRange(sampledAspect, m_parameters.mipLevel, 1u, 0u, 1u);
383 const vk::VkImageSubresourceLayers sampledSubresourceLayers = makeImageSubresourceLayers(sampledAspect, m_parameters.mipLevel, 0u, 1u);
384 const auto outputSubresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, m_parameters.mipLevel, 1u, 0u, 1u);
385 const vk::VkImageSubresourceLayers outputSubresourceLayers = makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, m_parameters.mipLevel, 0u, 1u);
386
387 std::vector<deUint8> testData (sampledBufferSize);
388 generateData(testData.data(), sampledBufferSize, m_parameters.imageSampledFormat);
389
390 // Create sampled image
391 {
392 vk::VkImageUsageFlags usage = vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT;
393 if (m_parameters.hostCopyMemoryToImage || m_parameters.hostCopyImageToMemory || m_parameters.memcpyFlag || m_parameters.hostTransferLayout)
394 usage |= vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
395 if (m_parameters.intermediateLayout == vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
396 usage |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
397 else if (m_parameters.intermediateLayout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
398 usage |= vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
399 else if (m_parameters.intermediateLayout == vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
400 usage |= vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT;
401
402 vk::VkImageCreateInfo createInfo =
403 {
404 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
405 DE_NULL, // const void* pNext
406 0u, // VkImageCreateFlags flags
407 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
408 m_parameters.imageSampledFormat, // VkFormat format
409 imageSize, // VkExtent3D extent
410 m_parameters.mipLevel + 1, // uint32_t mipLevels
411 1u, // uint32_t arrayLayers
412 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
413 m_parameters.sampledTiling, // VkImageTiling tiling
414 usage, // VkImageUsageFlags usage
415 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
416 0, // uint32_t queueFamilyIndexCount
417 DE_NULL, // const uint32_t* pQueueFamilyIndices
418 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
419 };
420
421 if (m_parameters.sparse)
422 {
423 createInfo.flags |= (vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT);
424 sparseSampledImage = de::MovePtr<SparseImage>(new SparseImage(vk, device, physicalDevice, vki, createInfo, m_context.getSparseQueue(), alloc, mapVkFormat(createInfo.format)));
425 sampledImage = **sparseSampledImage;
426 }
427 else
428 {
429 sampledImageWithMemory = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
430 if (m_parameters.memcpyFlag)
431 sampledImageWithMemoryCopy = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
432 sampledImage = **sampledImageWithMemory;
433 }
434
435 vk::VkImageViewCreateInfo imageViewCreateInfo =
436 {
437 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
438 DE_NULL, // const void* pNext;
439 (vk::VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
440 sampledImage, // VkImage image;
441 vk::VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
442 m_parameters.imageSampledFormat, // VkFormat format;
443 componentMapping, // VkComponentMapping components;
444 sampledSubresourceRange // VkImageSubresourceRange subresourceRange;
445 };
446 sampledImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
447 if (m_parameters.memcpyFlag)
448 {
449 imageViewCreateInfo.image = **sampledImageWithMemoryCopy;
450 sampledImageViewCopy = createImageView(vk, device, &imageViewCreateInfo, NULL);;
451 }
452 }
453
454 // Create output image
455 {
456 vk::VkImageUsageFlags usage = vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
457 if (m_parameters.outputImageHostTransition || m_parameters.hostCopyImageToMemory || m_parameters.hostTransferLayout)
458 usage |= vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
459 if (m_parameters.command == DISPATCH)
460 usage |= vk::VK_IMAGE_USAGE_STORAGE_BIT;
461
462 const vk::VkImageCreateInfo createInfo =
463 {
464 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
465 DE_NULL, // const void* pNext
466 0u, // VkImageCreateFlags flags
467 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType
468 m_parameters.imageOutputFormat, // VkFormat format
469 imageSize, // VkExtent3D extent
470 m_parameters.mipLevel + 1, // uint32_t mipLevels
471 1u, // uint32_t arrayLayers
472 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
473 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
474 usage, // VkImageUsageFlags usage
475 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
476 0, // uint32_t queueFamilyIndexCount
477 DE_NULL, // const uint32_t* pQueueFamilyIndices
478 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
479 };
480
481 outputImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
482
483 vk::VkImageViewCreateInfo imageViewCreateInfo =
484 {
485 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
486 DE_NULL, // const void* pNext;
487 (VkImageViewCreateFlags)0u, // VkImageViewCreateFlags flags;
488 **outputImage, // VkImage image;
489 vk::VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
490 m_parameters.imageOutputFormat, // VkFormat format;
491 componentMapping, // VkComponentMapping components;
492 outputSubresourceRange // VkImageSubresourceRange subresourceRange;
493 };
494 outputImageView = createImageView(vk, device, &imageViewCreateInfo, NULL);
495 }
496
497 const vk::VkAttachmentDescription colorAttachmentDescription =
498 {
499 (vk::VkAttachmentDescriptionFlags)0u, // VkAttachmentDescriptionFlags flags
500 m_parameters.imageOutputFormat, // VkFormat format
501 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
502 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp
503 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
504 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
505 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
506 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout
507 vk::VK_IMAGE_LAYOUT_GENERAL // VkImageLayout finalLayout
508 };
509
510 const vk::VkAttachmentReference colorAttachmentRef =
511 {
512 0u, // deUint32 attachment
513 vk::VK_IMAGE_LAYOUT_GENERAL // VkImageLayout layout
514 };
515
516 const vk::VkSubpassDescription subpassDescription =
517 {
518 (vk::VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags
519 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
520 0u, // deUint32 inputAttachmentCount
521 DE_NULL, // const VkAttachmentReference* pInputAttachments
522 1u, // deUint32 colorAttachmentCount
523 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments
524 DE_NULL, // const VkAttachmentReference* pResolveAttachments
525 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
526 0u, // deUint32 preserveAttachmentCount
527 DE_NULL // const deUint32* pPreserveAttachments
528 };
529
530 Move<vk::VkRenderPass> renderPass;
531 Move<vk::VkFramebuffer> framebuffer;
532 if (!m_parameters.dynamicRendering && m_parameters.command == DRAW)
533 {
534 const vk::VkRenderPassCreateInfo renderPassInfo =
535 {
536 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
537 nullptr, // const void* pNext;
538 0u, // VkRenderPassCreateFlags flags;
539 1u, // deUint32 attachmentCount;
540 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
541 1u, // deUint32 subpassCount;
542 &subpassDescription, // const VkSubpassDescription* pSubpasses;
543 0u, // deUint32 dependencyCount;
544 nullptr, // const VkSubpassDependency* pDependencies;
545 };
546 renderPass = createRenderPass(vk, device, &renderPassInfo);
547 framebuffer = makeFramebuffer(vk, device, *renderPass, *outputImageView, renderArea.extent.width, renderArea.extent.height);
548 }
549
550 const std::vector<vk::VkViewport> viewports { makeViewport(renderArea.extent) };
551 const std::vector<vk::VkRect2D> scissors { makeRect2D(renderArea.extent) };
552
553 vk::ShaderWrapper vert = vk::ShaderWrapper(vk, device, m_context.getBinaryCollection().get("vert"));
554 vk::ShaderWrapper frag = vk::ShaderWrapper(vk, device, m_context.getBinaryCollection().get("frag"));
555
556 DescriptorSetLayoutBuilder descriptorBuilder;
557 descriptorBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, vk::VK_SHADER_STAGE_FRAGMENT_BIT | vk::VK_SHADER_STAGE_COMPUTE_BIT);
558 if (m_parameters.command == DISPATCH)
559 descriptorBuilder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
560
561 const auto descriptorSetLayout (descriptorBuilder.build(vk, device));
562 const vk::PipelineLayoutWrapper pipelineLayout (PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC, vk, device, *descriptorSetLayout);
563
564 DescriptorPoolBuilder poolBuilder;
565 poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
566 if (m_parameters.command == DISPATCH)
567 poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
568 const Move<vk::VkDescriptorPool> descriptorPool = poolBuilder.build(vk, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
569 const Move<vk::VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
570
571 vk::VkSamplerCreateInfo samplerParams =
572 {
573 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
574 DE_NULL, // const void* pNext;
575 0u, // VkSamplerCreateFlags flags;
576 vk::VK_FILTER_NEAREST, // VkFilter magFilter;
577 vk::VK_FILTER_NEAREST, // VkFilter minFilter;
578 vk::VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
579 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeU;
580 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeV;
581 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, // VkSamplerAddressMode addressModeW;
582 0.0f, // float mipLodBias;
583 VK_FALSE, // VkBool32 anisotropyEnable;
584 0.0f, // float maxAnisotropy;
585 VK_FALSE, // VkBool32 compareEnable;
586 vk::VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
587 0.0f, // float minLod;
588 VK_LOD_CLAMP_NONE, // float maxLod;
589 vk::VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, // VkBorderColor borderColor;
590 VK_FALSE // VkBool32 unnormalizedCoordinates;
591 };
592 const vk::Move<vk::VkSampler> sampler = createSampler(vk, device, &samplerParams);
593 vk::VkDescriptorImageInfo descriptorSrcImageInfo (makeDescriptorImageInfo(*sampler, *sampledImageView, vk::VK_IMAGE_LAYOUT_GENERAL));
594 const vk::VkDescriptorImageInfo descriptorDstImageInfo (makeDescriptorImageInfo(*sampler, *outputImageView, vk::VK_IMAGE_LAYOUT_GENERAL));
595
596 const vk::VkPipelineVertexInputStateCreateInfo vertexInput =
597 {
598 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
599 nullptr, // const void* pNext;
600 0u, // VkPipelineVertexInputStateCreateFlags flags;
601 0u, // deUint32 vertexBindingDescriptionCount;
602 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
603 0u, // deUint32 vertexAttributeDescriptionCount;
604 DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
605 };
606
607 GraphicsPipelineWrapper pipeline(vki, vk, physicalDevice, device, deviceExtensions, vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC);
608 Move<vk::VkPipeline> computePipeline;
609
610 if (m_parameters.command == DRAW)
611 {
612 vk::VkPipelineRenderingCreateInfo pipelineRenderingCreateInfo;
613 if (m_parameters.dynamicRendering)
614 {
615 pipelineRenderingCreateInfo = {
616 vk::VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, // VkStructureType sType
617 DE_NULL, // const void* pNext
618 0u, // uint32_t viewMask
619 1u, // uint32_t colorAttachmentCount
620 &m_parameters.imageOutputFormat, // const VkFormat* pColorAttachmentFormats
621 vk::VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat
622 vk::VK_FORMAT_UNDEFINED // VkFormat stencilAttachmentFormat
623 };
624 }
625
626 vk::PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
627 renderingCreateInfoWrapper.ptr = m_parameters.dynamicRendering ? &pipelineRenderingCreateInfo : DE_NULL;
628
629 pipeline.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
630 .setDefaultRasterizationState()
631 .setDefaultMultisampleState()
632 .setDefaultDepthStencilState()
633 .setDefaultColorBlendState()
634 .setupVertexInputState(&vertexInput)
635 .setupPreRasterizationShaderState(viewports,
636 scissors,
637 pipelineLayout,
638 *renderPass,
639 0u,
640 vert,
641 DE_NULL,
642 {},
643 {},
644 {},
645 DE_NULL,
646 DE_NULL,
647 renderingCreateInfoWrapper)
648 .setupFragmentShaderState(pipelineLayout, *renderPass, 0u, frag)
649 .setupFragmentOutputState(*renderPass)
650 .setMonolithicPipelineLayout(pipelineLayout)
651 .buildPipeline();
652 }
653 else
654 {
655 const Unique<vk::VkShaderModule> cs(vk::createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0u));
656 const vk::VkPipelineShaderStageCreateInfo pipelineShaderStageParams =
657 {
658 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // sType
659 DE_NULL, // pNext
660 (VkPipelineShaderStageCreateFlags)0u, // flags
661 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
662 *cs, // module
663 "main", // pName
664 DE_NULL, // pSpecializationInfo
665 };
666 const vk::VkComputePipelineCreateInfo pipelineCreateInfo =
667 {
668 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // sType
669 DE_NULL, // pNext
670 (VkPipelineCreateFlags)0u, // flags
671 pipelineShaderStageParams, // stage
672 *pipelineLayout, // layout
673 DE_NULL, // basePipelineHandle
674 0, // basePipelineIndex
675 };
676 computePipeline = createComputePipeline(vk, device, DE_NULL, &pipelineCreateInfo);
677 }
678
679 de::MovePtr<BufferWithMemory> colorOutputBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
680 vk, device, alloc, makeBufferCreateInfo(outputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
681
682 // Load sampled image
683 if (m_parameters.hostCopyMemoryToImage)
684 {
685 transitionImageLayout(&cmdBuffer, sampledImage, vk::VK_IMAGE_LAYOUT_UNDEFINED, m_parameters.dstLayout, sampledSubresourceRange);
686 commandsLog << "vkTransitionImageLayoutEXT() image " << sampledImage << " to layout " << getImageLayoutStr(m_parameters.dstLayout).toString() << "\n";
687
688 copyMemoryToImage(testData, sampledImage, sampledChannelSize * sampledNumChannels, sampledSubresourceLayers, 0, 0, mipImageSize.width, mipImageSize.height);
689 commandsLog << "vkCopyMemoryToImageEXT() with image " << sampledImage << ", xOffset (0), yOffset (0), width (" << mipImageSize.width << "), height (" << mipImageSize.height << ")\n";
690
691 de::Random randomGen(deInt32Hash((deUint32)m_parameters.imageSampledFormat) ^
692 deInt32Hash((deUint32)mipImageSize.width) ^
693 deInt32Hash((deUint32)mipImageSize.height) ^
694 deInt32Hash((deUint32)mipImageSize.depth));
695 for (int i = 0; i < 20; ++i)
696 {
697 deInt32 xOffset = randomGen.getInt32() % (mipImageSize.width / 2);
698 deInt32 yOffset = randomGen.getInt32() % (mipImageSize.height / 2);
699 deUint32 width = deMaxu32(randomGen.getUint32() % (mipImageSize.width / 2), 1u);
700 deUint32 height = deMaxu32(randomGen.getUint32() % (mipImageSize.height / 2), 1u);
701
702 if (isCompressedFormat(m_parameters.imageSampledFormat)) {
703 deUint32 blockWidth = getBlockWidth(m_parameters.imageSampledFormat);
704 deUint32 blockHeight = getBlockHeight(m_parameters.imageSampledFormat);
705 xOffset = (xOffset / blockWidth) * blockWidth;
706 yOffset = (yOffset / blockHeight) * blockHeight;
707 width = deMaxu32((width / blockWidth) * blockWidth, blockWidth);
708 height = deMaxu32((height / blockHeight) * blockHeight, blockHeight);
709 }
710
711 copyMemoryToImage(testData, sampledImage, sampledChannelSize * sampledNumChannels, sampledSubresourceLayers, xOffset, yOffset, width, height);
712 commandsLog << "vkCopyMemoryToImageEXT() with image " << sampledImage << ", xOffset (" << xOffset << "), yOffset (" << yOffset << "), width (" << width << "), height (" << height << ")\n";
713 }
714
715 if (m_parameters.dstLayout != vk::VK_IMAGE_LAYOUT_GENERAL)
716 {
717 transitionImageLayout(&cmdBuffer, sampledImage, m_parameters.dstLayout, vk::VK_IMAGE_LAYOUT_GENERAL, sampledSubresourceRange);
718 commandsLog << "vkTransitionImageLayoutEXT() image " << sampledImage << " to layout VK_IMAGE_LAYOUT_GENERAL\n";
719 }
720 }
721 else
722 {
723 de::MovePtr<BufferWithMemory> sampledBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, alloc, makeBufferCreateInfo(sampledBufferSize, vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::HostVisible));
724
725 auto& bufferAlloc = sampledBuffer->getAllocation();
726 memcpy(bufferAlloc.getHostPtr(), testData.data(), sampledBufferSize);
727 flushAlloc(vk, device, bufferAlloc);
728
729 transitionImageLayout(&cmdBuffer, sampledImage, vk::VK_IMAGE_LAYOUT_UNDEFINED, m_parameters.dstLayout, sampledSubresourceRange);
730 commandsLog << "vkTransitionImageLayoutEXT() image " << sampledImage << " to layout" << getImageLayoutStr(m_parameters.dstLayout).toString() << "\n";
731
732 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
733 const vk::VkBufferImageCopy copyRegion =
734 {
735 0,
736 0,
737 0,
738 sampledSubresourceLayers,
739 imageOffset,
740 {
741 mipImageSize.width,
742 mipImageSize.height,
743 mipImageSize.depth,
744 },
745 };
746 vk.cmdCopyBufferToImage(*cmdBuffer, sampledBuffer->get(), sampledImage, m_parameters.dstLayout, 1u, ©Region);
747 commandsLog << "vkCmdCopyBufferToImage() with image " << sampledImage << ", xOffset (" << copyRegion.imageOffset.x << "), yOffset (" << copyRegion.imageOffset.y << "), width (" << mipImageSize.width << "), height (" << mipImageSize.height << ")\n";
748
749 {
750 auto imageMemoryBarrier = makeImageMemoryBarrier(vk::VK_ACCESS_TRANSFER_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, m_parameters.dstLayout, m_parameters.intermediateLayout, sampledImage, sampledSubresourceRange);
751 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1, &imageMemoryBarrier);
752 }
753
754 vk::endCommandBuffer(vk, *cmdBuffer);
755 deUint32 semaphoreCount = 0;
756 vk::VkSemaphore semaphore = DE_NULL;
757 VkPipelineStageFlags waitStages = 0;
758 if (m_parameters.sparse)
759 {
760 semaphoreCount = 1;
761 semaphore = sparseSampledImage->getSemaphore();
762 waitStages = vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
763 }
764 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer, false, 1u, semaphoreCount, &semaphore, &waitStages);
765
766 if (m_parameters.intermediateLayout != vk::VK_IMAGE_LAYOUT_GENERAL)
767 {
768 transitionImageLayout(&cmdBuffer, sampledImage, m_parameters.intermediateLayout, vk::VK_IMAGE_LAYOUT_GENERAL, sampledSubresourceRange);
769 commandsLog << "vkTransitionImageLayoutEXT() image " << sampledImage << " to layout VK_IMAGE_LAYOUT_GENERAL\n";
770 }
771 }
772
773 if (m_parameters.memcpyFlag)
774 {
775 vk::VkImageSubresource2EXT subresource2 =
776 {
777 vk::VK_STRUCTURE_TYPE_IMAGE_SUBRESOURCE_2_EXT, // VkStructureType sType;
778 DE_NULL, // void* pNext;
779 sampledSubresource // VkImageSubresource imageSubresource;
780 };
781
782 vk::VkSubresourceHostMemcpySizeEXT subresourceHostMemcpySize = vk::initVulkanStructure();
783 vk::VkSubresourceLayout2EXT subresourceLayout = vk::initVulkanStructure(&subresourceHostMemcpySize);
784 vk.getImageSubresourceLayout2KHR(device, sampledImage, &subresource2, &subresourceLayout);
785
786 std::vector<deUint8> data((size_t)subresourceHostMemcpySize.size);
787
788 const vk::VkImageToMemoryCopyEXT region =
789 {
790 vk::VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT, // VkStructureType sType;
791 DE_NULL, // const void* pNext;
792 data.data(), // void* memoryHostPointer;
793 0u, // uint32_t memoryRowLength;
794 0u, // uint32_t memoryImageHeight;
795 sampledSubresourceLayers, // VkImageSubresourceLayers imageSubresource;
796 imageOffset, // VkOffset3D imageOffset;
797 mipImageSize, // VkExtent3D imageExtent;
798 };
799
800 const vk::VkCopyImageToMemoryInfoEXT copyImageToMemoryInfo =
801 {
802 vk::VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT, // VkStructureType sType;
803 DE_NULL, // const void* pNext;
804 vk::VK_HOST_IMAGE_COPY_MEMCPY_EXT, // VkMemoryImageCopyFlagsEXT flags;
805 sampledImage, // VkImage srcImage;
806 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout srcImageLayout;
807 1, // uint32_t regionCount;
808 ®ion, // const VkImageToMemoryCopyEXT* pRegions;
809 };
810 vk.copyImageToMemoryEXT(device, ©ImageToMemoryInfo);
811 commandsLog << "vkCopyImageToMemoryEXT() with image " << sampledImage << ", xOffset (" << region.imageOffset.x << "), yOffset (" << region.imageOffset.y << "), width (" << mipImageSize.width << "), height (" << mipImageSize.height << ")\n";
812
813 transitionImageLayout(&cmdBuffer, **sampledImageWithMemoryCopy, vk::VK_IMAGE_LAYOUT_UNDEFINED, m_parameters.dstLayout, sampledSubresourceRange);
814
815 const vk::VkMemoryToImageCopyEXT toImageRegion = {
816 vk::VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY_EXT, // VkStructureType sType;
817 DE_NULL, // const void* pNext;
818 data.data(), // const void* memoryHostPointer;
819 0, // uint32_t memoryRowLength;
820 0, // uint32_t memoryImageHeight;
821 sampledSubresourceLayers, // VkImageSubresourceLayers imageSubresource;
822 imageOffset, // VkOffset3D imageOffset;
823 mipImageSize // VkExtent3D imageExtent;
824 };
825
826 vk::VkCopyMemoryToImageInfoEXT copyMemoryToImageInfo =
827 {
828 vk::VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO_EXT, // VkStructureType sType;
829 DE_NULL, // const void* pNext;
830 vk::VK_HOST_IMAGE_COPY_MEMCPY_EXT, // VkMemoryImageCopyFlagsEXT flags;
831 **sampledImageWithMemoryCopy, // VkImage dstImage;
832 m_parameters.dstLayout, // VkImageLayout dstImageLayout;
833 1u, // uint32_t regionCount;
834 &toImageRegion, // const VkMemoryToImageCopyEXT* pRegions;
835 };
836 vk.copyMemoryToImageEXT(device, ©MemoryToImageInfo);
837 commandsLog << "vkCopyMemoryToImageEXT() with image " << **sampledImageWithMemoryCopy << ", xOffset (" << toImageRegion.imageOffset.x << "), yOffset (" << toImageRegion.imageOffset.y << "), width (" << toImageRegion.imageExtent.width << "), height (" << toImageRegion.imageExtent.height << ")\n";
838 descriptorSrcImageInfo.imageView = *sampledImageViewCopy;
839
840 transitionImageLayout(&cmdBuffer, **sampledImageWithMemoryCopy, m_parameters.dstLayout, vk::VK_IMAGE_LAYOUT_GENERAL, sampledSubresourceRange);
841 }
842
843 // Transition output image
844 transitionImageLayout(&cmdBuffer, **outputImage, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, outputSubresourceRange);
845 commandsLog << "vkTransitionImageLayoutEXT() image " << **outputImage << " to layout VK_IMAGE_LAYOUT_GENERAL\n";
846 vk::beginCommandBuffer(vk, *cmdBuffer, 0u);
847
848 vk::DescriptorSetUpdateBuilder updateBuilder;
849 updateBuilder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImageInfo);
850 if (m_parameters.command == DISPATCH)
851 updateBuilder.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImageInfo);
852 updateBuilder.update(vk, device);
853
854 if (m_parameters.command == DRAW)
855 {
856 if (m_parameters.dynamicRendering)
857 beginRendering(vk, *cmdBuffer, *outputImageView, renderArea, vk::VkClearValue(), vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE);
858 else
859 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea);
860
861 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.getPipeline());
862 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0, 1, &*descriptorSet, 0, DE_NULL);
863 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0);
864 commandsLog << "vkCmdDraw()\n";
865
866 if (m_parameters.dynamicRendering)
867 endRendering(vk, *cmdBuffer);
868 else
869 endRenderPass(vk, *cmdBuffer);
870
871 const auto postImageBarrier = makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, m_parameters.srcLayout, **outputImage, outputSubresourceRange);
872 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
873 }
874 else
875 {
876 const auto imageMemoryBarrier = makeImageMemoryBarrier(0u, vk::VK_ACCESS_SHADER_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **outputImage, outputSubresourceRange);
877 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageMemoryBarrier);
878 vk.cmdBindPipeline(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *computePipeline);
879 vk.cmdBindDescriptorSets(*cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0, 1, &*descriptorSet, 0, DE_NULL);
880 vk.cmdDispatch(*cmdBuffer, renderArea.extent.width, renderArea.extent.height, 1);
881 commandsLog << "vkCmdDispatch()\n";
882
883 vk::VkImageMemoryBarrier postImageBarrier =
884 {
885 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
886 DE_NULL, // const void* pNext
887 vk::VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask
888 vk::VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
889 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout
890 m_parameters.srcLayout, // VkImageLayout newLayout
891 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
892 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
893 **outputImage, // VkImage image
894 outputSubresourceRange // VkImageSubresourceRange subresourceRange
895 };
896
897 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
898 }
899
900 const vk::VkBufferImageCopy copyRegion =
901 {
902 0u, // VkDeviceSize bufferOffset;
903 0u, // deUint32 bufferRowLength;
904 0u, // deUint32 bufferImageHeight;
905 outputSubresourceLayers, // VkImageSubresourceLayers imageSubresource;
906 imageOffset, // VkOffset3D imageOffset;
907 {renderArea.extent.width, renderArea.extent.height, 1} // VkExtent3D imageExtent;
908 };
909 vk.cmdCopyImageToBuffer(*cmdBuffer, **outputImage, m_parameters.srcLayout, **colorOutputBuffer, 1u, ©Region);
910 commandsLog << "vkCmdCopyImageToBuffer() with image " << **outputImage << ", xOffset (" << imageOffset.x << "), yOffset (" << imageOffset.y << "), width (" << renderArea.extent.width << "), height (" << renderArea.extent.height << "\n";
911 vk::endCommandBuffer(vk, *cmdBuffer);
912
913 vk::submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
914
915 // Verify image
916 tcu::ConstPixelBufferAccess resultBuffer = tcu::ConstPixelBufferAccess(outputFormat, renderArea.extent.width, renderArea.extent.height, 1, (const void*)colorOutputBuffer->getAllocation().getHostPtr());
917
918 if (m_parameters.hostCopyImageToMemory)
919 {
920 const deUint32 paddedBufferSize = (mipImageSize.width + m_parameters.padding) * (mipImageSize.height + m_parameters.padding) * outputNumChannels * outputChannelSize;
921 const deUint32 memoryRowLength = (mipImageSize.width + m_parameters.padding);
922 const deUint32 memoryImageHeight = (mipImageSize.height + m_parameters.padding);
923 std::vector<deUint8> paddedData (paddedBufferSize);
924 std::vector<deUint8> data (outputBufferSize);
925
926 std::vector<vk::VkImageToMemoryCopyEXT> regions(m_parameters.regionsCount);
927
928 for (deUint32 i = 0; i < m_parameters.regionsCount; ++i)
929 {
930 vk::VkOffset3D offset = { 0, (deInt32)(mipImageSize.height / m_parameters.regionsCount * i), 0 };
931 vk::VkExtent3D extent = { mipImageSize.width, mipImageSize.height / m_parameters.regionsCount, 1 };
932 if (i == m_parameters.regionsCount - 1)
933 extent.height = mipImageSize.height - mipImageSize.height / m_parameters.regionsCount * i;
934
935 deUint32 dataOffset = (mipImageSize.width + m_parameters.padding) * offset.y * outputNumChannels * outputChannelSize;
936
937 const vk::VkImageToMemoryCopyEXT region =
938 {
939 vk::VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT, // VkStructureType sType;
940 DE_NULL, // const void* pNext;
941 &paddedData[dataOffset], // void* memoryHostPointer;
942 memoryRowLength, // uint32_t memoryRowLength;
943 memoryImageHeight, // uint32_t memoryImageHeight;
944 outputSubresourceLayers, // VkImageSubresourceLayers imageSubresource;
945 offset, // VkOffset3D imageOffset;
946 extent, // VkExtent3D imageExtent;
947 };
948
949 regions[i] = region;
950 }
951
952 const vk::VkCopyImageToMemoryInfoEXT copyImageToMemoryInfo =
953 {
954 vk::VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT, // VkStructureType sType;
955 DE_NULL, // const void* pNext;
956 0u, // VkMemoryImageCopyFlagsEXT flags;
957 **outputImage, // VkImage srcImage;
958 m_parameters.srcLayout, // VkImageLayout srcImageLayout;
959 (deUint32)regions.size(), // uint32_t regionCount;
960 regions.data(), // const VkImageToMemoryCopyEXT* pRegions;
961 };
962 vk.copyImageToMemoryEXT(device, ©ImageToMemoryInfo);
963 commandsLog << "vkCopyImageToMemoryEXT() with image " << **outputImage << "\n";
964
965 for (deUint32 j = 0; j < mipImageSize.height; ++j)
966 {
967 for (deUint32 i = 0; i < mipImageSize.width; ++i)
968 {
969 for (deUint32 k = 0; k < outputNumChannels * outputChannelSize; ++k)
970 {
971 deUint32 dstIndex = j * mipImageSize.width * (outputNumChannels * outputChannelSize) + i * (outputNumChannels * outputChannelSize) + k;
972 deUint32 srcIndex = j * (mipImageSize.width + m_parameters.padding) * (outputNumChannels * outputChannelSize) + i * (outputNumChannels * outputChannelSize) + k;
973 data[dstIndex] = paddedData[srcIndex];
974 }
975 }
976 }
977
978 bool match = memcmp(data.data(), resultBuffer.getDataPtr(), outputBufferSize) == 0;
979 if (!match)
980 {
981 log << tcu::TestLog::Message << commandsLog.str() << tcu::TestLog::EndMessage;
982 for (deUint32 i = 0; i < outputBufferSize; ++i) {
983 if (data[i] != ((deUint8*)resultBuffer.getDataPtr())[i])
984 {
985 log << tcu::TestLog::Message << "At byte " << i << " data from vkCopyImageToMemoryEXT() is " << data[i] << ", but data from vkCmdCopyImageToBuffer() (after padding) is " << ((deUint8*)resultBuffer.getDataPtr())[i] << tcu::TestLog::EndMessage;
986 break;
987 }
988 }
989 return tcu::TestStatus::fail("copyImageToMemoryEXT failed");
990 }
991 }
992
993 if (m_parameters.imageOutputFormat == m_parameters.imageSampledFormat) {
994 std::vector<deUint8> resultData(sampledBufferSize);
995 const Allocation& outputAlloc = colorOutputBuffer->getAllocation();
996 deMemcpy(resultData.data(), outputAlloc.getHostPtr(), sampledBufferSize);
997
998 for (uint32_t i = 0; i < sampledBufferSize; ++i) {
999 if (resultData[i] != testData[i]) {
1000
1001 if (!isCompressedFormat(m_parameters.imageSampledFormat))
1002 {
1003 const tcu::ConstPixelBufferAccess bufferData(mapVkFormat(m_parameters.imageSampledFormat),
1004 m_parameters.imageSize.width,
1005 m_parameters.imageSize.height,
1006 m_parameters.imageSize.depth,
1007 outputAlloc.getHostPtr());
1008
1009 m_context.getTestContext().getLog()
1010 << tcu::TestLog::Section("host_copy_result", "host_copy_result")
1011 << tcu::LogImage("image", "", bufferData)
1012 << tcu::TestLog::EndSection;
1013 }
1014
1015 return tcu::TestStatus::fail("Image verification failed");
1016 }
1017 }
1018 }
1019 return tcu::TestStatus::pass("Pass");
1020 }
1021
1022 class HostImageCopyTestCase : public vkt::TestCase
1023 {
1024 public:
HostImageCopyTestCase(tcu::TestContext & context,const char * name,const TestParameters & parameters)1025 HostImageCopyTestCase (tcu::TestContext& context, const char* name, const TestParameters& parameters)
1026 : TestCase (context, name)
1027 , m_parameters (parameters)
1028 {
1029 }
1030 private:
1031 void checkSupport (vkt::Context& context) const;
1032 void initPrograms (vk::SourceCollections& programCollection) const;
createInstance(vkt::Context & context) const1033 vkt::TestInstance* createInstance (vkt::Context& context) const { return new HostImageCopyTestInstance(context, m_parameters); }
1034
1035 const TestParameters m_parameters;
1036 };
1037
checkSupport(vkt::Context & context) const1038 void HostImageCopyTestCase::checkSupport (vkt::Context& context) const
1039 {
1040 vk::VkInstance instance (context.getInstance());
1041 vk::InstanceDriver instanceDriver (context.getPlatformInterface(), instance);
1042 const vk::InstanceInterface& vki = context.getInstanceInterface();
1043 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1044
1045 context.requireDeviceFunctionality("VK_EXT_host_image_copy");
1046
1047 if (m_parameters.dynamicRendering)
1048 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
1049
1050 if (m_parameters.sparse)
1051 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SPARSE_BINDING);
1052
1053 vk::VkPhysicalDeviceHostImageCopyFeaturesEXT hostImageCopyFeatures =
1054 {
1055 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT, // VkStructureType sType
1056 DE_NULL, // const void* pNext
1057 VK_FALSE, // VkBool32 hostImageCopy;
1058 };
1059
1060 vk::VkPhysicalDeviceFeatures features;
1061 deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
1062 vk::VkPhysicalDeviceFeatures2 features2 =
1063 {
1064 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // VkStructureType sType
1065 &hostImageCopyFeatures, // const void* pNext
1066 features // VkPhysicalDeviceFeatures features
1067 };
1068
1069 instanceDriver.getPhysicalDeviceFeatures2(physicalDevice, &features2);
1070
1071 vk::VkPhysicalDeviceHostImageCopyPropertiesEXT hostImageCopyProperties =
1072 {
1073 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT, // VkStructureType sType;
1074 DE_NULL, // void* pNext;
1075 0u, // uint32_t copySrcLayoutCount;
1076 DE_NULL, // VkImageLayout* pCopySrcLayouts;
1077 0u, // uint32_t copyDstLayoutCount;
1078 DE_NULL, // VkImageLayout* pCopyDstLayouts;
1079 {}, // uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE];
1080 DE_FALSE // VkBool32 identicalMemoryTypeRequirements;
1081 };
1082 getHostImageCopyProperties(instanceDriver, physicalDevice, &hostImageCopyProperties);
1083 std::vector<vk::VkImageLayout> srcLayouts(hostImageCopyProperties.copySrcLayoutCount);
1084 std::vector<vk::VkImageLayout> dstLayouts(hostImageCopyProperties.copyDstLayoutCount);
1085 hostImageCopyProperties.pCopySrcLayouts = srcLayouts.data();
1086 hostImageCopyProperties.pCopyDstLayouts = dstLayouts.data();
1087 getHostImageCopyProperties(instanceDriver, physicalDevice, &hostImageCopyProperties);
1088 bool layoutSupported = false;
1089 bool intermediateLayoutSupported = false;
1090 for (deUint32 i = 0; i < hostImageCopyProperties.copySrcLayoutCount; ++i)
1091 {
1092 if (hostImageCopyProperties.pCopySrcLayouts[i] == m_parameters.srcLayout)
1093 layoutSupported = true;
1094 if (hostImageCopyProperties.pCopySrcLayouts[i] == m_parameters.intermediateLayout)
1095 intermediateLayoutSupported = true;
1096 }
1097 if (layoutSupported == false || intermediateLayoutSupported == false)
1098 TCU_THROW(NotSupportedError, "Layout not supported for src host copy");
1099 layoutSupported = false;
1100 for (deUint32 i = 0; i < hostImageCopyProperties.copyDstLayoutCount; ++i)
1101 {
1102 if (hostImageCopyProperties.pCopyDstLayouts[i] == m_parameters.dstLayout)
1103 {
1104 layoutSupported = true;
1105 break;
1106 }
1107 }
1108 if (layoutSupported == false)
1109 TCU_THROW(NotSupportedError, "Layout not supported for dst host copy");
1110
1111 vk::VkImageUsageFlags usage = vk::VK_IMAGE_USAGE_SAMPLED_BIT | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1112 if (m_parameters.hostCopyMemoryToImage || m_parameters.hostCopyImageToMemory || m_parameters.memcpyFlag || m_parameters.hostTransferLayout)
1113 usage |= vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
1114 if (m_parameters.intermediateLayout == vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
1115 usage |= vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1116 else if (m_parameters.intermediateLayout == vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
1117 usage |= vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1118 else if (m_parameters.intermediateLayout == vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
1119 usage |= vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1120
1121 vk::VkImageCreateFlags flags = 0u;
1122 if (m_parameters.sparse)
1123 flags |= vk::VK_IMAGE_CREATE_SPARSE_BINDING_BIT | vk::VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
1124 vk::VkImageFormatProperties imageFormatProperties;
1125 if (vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.imageSampledFormat, vk::VK_IMAGE_TYPE_2D,
1126 m_parameters.sampledTiling, usage, flags,
1127 &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1128 TCU_THROW(NotSupportedError, "Image format not supported.");
1129
1130 vk::VkImageUsageFlags outputUsage = vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1131 if (m_parameters.outputImageHostTransition || m_parameters.hostCopyImageToMemory)
1132 outputUsage |= vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT;
1133 if (m_parameters.command == DISPATCH)
1134 outputUsage |= vk::VK_IMAGE_USAGE_STORAGE_BIT;
1135 vk::VkImageFormatProperties outputImageFormatProperties;
1136 if (vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_parameters.imageOutputFormat, vk::VK_IMAGE_TYPE_2D,
1137 vk::VK_IMAGE_TILING_OPTIMAL, outputUsage, flags,
1138 &outputImageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1139 TCU_THROW(NotSupportedError, "Image format not supported.");
1140
1141 vk::VkFormatProperties3 formatProperties3 = vk::initVulkanStructure();
1142 vk::VkFormatProperties2 formatProperties2 = vk::initVulkanStructure(&formatProperties3);
1143 vki.getPhysicalDeviceFormatProperties2(context.getPhysicalDevice(), m_parameters.imageSampledFormat, &formatProperties2);
1144 if (m_parameters.sampledTiling == vk::VK_IMAGE_TILING_LINEAR && (formatProperties3.linearTilingFeatures & vk::VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0)
1145 TCU_THROW(NotSupportedError, "Format feature host image transfer not supported for linear tiling.");
1146 if (m_parameters.sampledTiling == vk::VK_IMAGE_TILING_OPTIMAL && (formatProperties3.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0)
1147 TCU_THROW(NotSupportedError, "Format feature host image transfer not supported for optimal tiling.");
1148
1149 if (hostImageCopyFeatures.hostImageCopy != VK_TRUE)
1150 TCU_THROW(NotSupportedError, "hostImageCopy not supported");
1151 if (imageFormatProperties.maxMipLevels <= m_parameters.mipLevel)
1152 TCU_THROW(NotSupportedError, "Required image mip levels not supported.");
1153
1154 if (m_parameters.command == DISPATCH)
1155 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT);
1156 }
1157
initPrograms(vk::SourceCollections & programCollection) const1158 void HostImageCopyTestCase::initPrograms (vk::SourceCollections& programCollection) const
1159 {
1160 {
1161 std::ostringstream vert;
1162 vert
1163 << "#version 450\n"
1164 << "layout (location=0) out vec2 texCoord;\n"
1165 << "void main()\n"
1166 << "{\n"
1167 << " texCoord = vec2(gl_VertexIndex & 1u, (gl_VertexIndex >> 1u) & 1u);"
1168 << " gl_Position = vec4(texCoord * 2.0f - 1.0f, 0.0f, 1.0f);\n"
1169 << "}\n"
1170 ;
1171
1172 programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
1173 }
1174 {
1175 std::string output;
1176 if (isDepthStencilFormat(m_parameters.imageSampledFormat))
1177 output = " out_color = vec4(texture(combinedSampler, texCoord).r, 0, 0, 0);\n";
1178 else
1179 output = " out_color = texture(combinedSampler, texCoord);\n";
1180
1181 std::ostringstream frag;
1182 frag
1183 << "#version 450\n"
1184 << "layout (location=0) out vec4 out_color;\n"
1185 << "layout (location=0) in vec2 texCoord;\n"
1186 << "layout (set=0, binding=0) uniform sampler2D combinedSampler;\n"
1187 << "void main()\n"
1188 << "{\n"
1189 << output
1190 << "}\n"
1191 ;
1192
1193 programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
1194 }
1195 {
1196 std::string image;
1197 std::string output;
1198 if (m_parameters.imageOutputFormat == vk::VK_FORMAT_R8G8B8A8_UINT)
1199 {
1200 image = "uimage2D";
1201 output = "uvec4(texture(combinedSampler, vec2(pixelCoord) / (textureSize(combinedSampler, 0) - vec2(0.001f))) * 255)";
1202 }
1203 else
1204 {
1205 image = "image2D";
1206 output = "texture(combinedSampler, vec2(pixelCoord) / (textureSize(combinedSampler, 0) - vec2(0.001f)))";
1207 }
1208
1209 std::ostringstream comp;
1210 comp
1211 << "#version 450\n"
1212 << "layout (local_size_x=1, local_size_y=1, local_size_z=1) in;\n"
1213 << "layout (set=0, binding=0) uniform sampler2D combinedSampler;\n"
1214 << "layout (set=0, binding=1) uniform writeonly " << image << " outImage;\n"
1215 << "void main()\n"
1216 << "{\n"
1217 << " ivec2 pixelCoord = ivec2(gl_GlobalInvocationID.xy);\n"
1218 << " imageStore(outImage, pixelCoord, " << output << ");\n"
1219 << "}\n"
1220 ;
1221
1222 programCollection.glslSources.add("comp") << glu::ComputeSource(comp.str());
1223 }
1224 }
1225
1226 class PreinitializedTestInstance : public vkt::TestInstance
1227 {
1228 public:
PreinitializedTestInstance(vkt::Context & context,const vk::VkFormat format,vk::VkImageLayout srcLayout,vk::VkImageLayout dstLayout,vk::VkExtent3D size,deUint32 arrayLayers,bool imageToImageCopy,bool memcpy,vk::VkImageTiling tiling)1229 PreinitializedTestInstance (vkt::Context& context, const vk::VkFormat format, vk::VkImageLayout srcLayout, vk::VkImageLayout dstLayout, vk::VkExtent3D size, deUint32 arrayLayers, bool imageToImageCopy, bool memcpy, vk::VkImageTiling tiling)
1230 : vkt::TestInstance (context)
1231 , m_format (format)
1232 , m_srcLayout (srcLayout)
1233 , m_dstLayout (dstLayout)
1234 , m_size (size)
1235 , m_arrayLayers (arrayLayers)
1236 , m_imageToImageCopy (imageToImageCopy)
1237 , m_memcpy (memcpy)
1238 , m_tiling (tiling)
1239 {
1240 }
1241
1242 private:
1243 tcu::TestStatus iterate (void);
1244
1245 const vk::VkFormat m_format;
1246 const vk::VkImageLayout m_srcLayout;
1247 const vk::VkImageLayout m_dstLayout;
1248 const vk::VkExtent3D m_size;
1249 const deUint32 m_arrayLayers;
1250 const bool m_imageToImageCopy;
1251 const bool m_memcpy;
1252 const vk::VkImageTiling m_tiling;
1253 };
1254
iterate(void)1255 tcu::TestStatus PreinitializedTestInstance::iterate (void)
1256 {
1257 vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), m_context.getInstance());
1258 vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1259 const DeviceInterface& vk = m_context.getDeviceInterface();
1260 const vk::VkDevice device = m_context.getDevice();
1261 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1262 const vk::VkQueue queue = m_context.getUniversalQueue();
1263 auto& alloc = m_context.getDefaultAllocator();
1264 tcu::TestLog& log = m_context.getTestContext().getLog();
1265
1266 const auto subresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_arrayLayers);
1267 const auto subresourceLayers = makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, m_arrayLayers);
1268 const vk::VkOffset3D offset = { 0u, 0u, 0u };
1269
1270 const auto channelSize = getChannelSize(m_format);
1271 const auto numChannels = getNumChannels(m_format);
1272 const auto bufferCount = m_size.width * m_size.height * m_size.depth * m_arrayLayers * numChannels;
1273 const auto bufferSize = bufferCount * channelSize;
1274
1275 const vk::VkCommandPoolCreateInfo cmdPoolInfo =
1276 {
1277 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // sType
1278 DE_NULL, // pNext
1279 vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // flags
1280 queueFamilyIndex, // queuefamilyindex
1281 };
1282 const Move <vk::VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolInfo));
1283 const Move <vk::VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1284
1285 const vk::VkImageType imageType = m_size.depth > 1 ? vk::VK_IMAGE_TYPE_3D : vk::VK_IMAGE_TYPE_2D;
1286
1287 deUint64 modifier = 0;
1288 checkSupportedFormatFeatures(instanceDriver, physicalDevice, m_format, m_tiling, &modifier);
1289
1290 vk::VkImageDrmFormatModifierListCreateInfoEXT drmCreateInfo = vk::initVulkanStructure();
1291 drmCreateInfo.drmFormatModifierCount = 1;
1292 drmCreateInfo.pDrmFormatModifiers = &modifier;
1293
1294 vk::VkImageCreateInfo createInfo =
1295 {
1296 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
1297 m_tiling == vk::VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ? &drmCreateInfo : DE_NULL,
1298 // const void* pNext
1299 0u, // VkImageCreateFlags flags
1300 imageType, // VkImageType imageType
1301 m_format, // VkFormat format
1302 m_size, // VkExtent3D extent
1303 1u, // uint32_t mipLevels
1304 m_arrayLayers, // uint32_t arrayLayers
1305 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
1306 m_tiling, // VkImageTiling tiling
1307 vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1308 // VkImageUsageFlags usage
1309 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1310 0, // uint32_t queueFamilyIndexCount
1311 DE_NULL, // const uint32_t* pQueueFamilyIndices
1312 vk::VK_IMAGE_LAYOUT_PREINITIALIZED // VkImageLayout initialLayout
1313 };
1314
1315 de::MovePtr<ImageWithMemory> image = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::HostVisible));
1316 de::MovePtr<ImageWithMemory> copyImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any));
1317 const vk::VkImage endImage = m_imageToImageCopy ? **copyImage : **image;
1318 de::MovePtr<BufferWithMemory> outputBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, alloc, makeBufferCreateInfo(bufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible));
1319
1320 vk::Allocation& allocation = image->getAllocation();
1321 void* ptr = allocation.getHostPtr();
1322 generateData(ptr, bufferSize, m_format);
1323
1324 vk::VkPhysicalDeviceHostImageCopyPropertiesEXT hostImageCopyProperties =
1325 {
1326 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT, // VkStructureType sType;
1327 DE_NULL, // void* pNext;
1328 0u, // uint32_t copySrcLayoutCount;
1329 DE_NULL, // VkImageLayout* pCopySrcLayouts;
1330 0u, // uint32_t copyDstLayoutCount;
1331 DE_NULL, // VkImageLayout* pCopyDstLayouts;
1332 {}, // uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE];
1333 DE_FALSE, // VkBool32 identicalMemoryTypeRequirements;
1334 };
1335 getHostImageCopyProperties(instanceDriver, physicalDevice, &hostImageCopyProperties);
1336 if (hostImageCopyProperties.identicalMemoryTypeRequirements)
1337 {
1338 createInfo.flags &= ~(vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT);
1339 de::MovePtr<ImageWithMemory> imageWithoutHostCopy = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::HostVisible));
1340 vk::VkMemoryRequirements hostImageMemoryRequirements;
1341 vk::VkMemoryRequirements memoryRequirements;
1342 vk.getImageMemoryRequirements(device, **image, &hostImageMemoryRequirements);
1343 vk.getImageMemoryRequirements(device, **imageWithoutHostCopy, &memoryRequirements);
1344
1345 if (hostImageMemoryRequirements.memoryTypeBits != memoryRequirements.memoryTypeBits)
1346 TCU_THROW(NotSupportedError, "Layout not supported for src host copy");
1347 }
1348
1349 // map device memory and initialize
1350 {
1351 const vk::VkHostImageLayoutTransitionInfoEXT transition =
1352 {
1353 vk::VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT, // VkStructureType sType;
1354 DE_NULL, // const void* pNext;
1355 image->get(), // VkImage image;
1356 vk::VK_IMAGE_LAYOUT_PREINITIALIZED, // VkImageLayout oldLayout;
1357 m_srcLayout, // VkImageLayout newLayout;
1358 subresourceRange // VkImageSubresourceRange subresourceRange;
1359 };
1360 vk.transitionImageLayoutEXT(device, 1, &transition);
1361 }
1362
1363 if (m_imageToImageCopy)
1364 {
1365 vk::VkHostImageLayoutTransitionInfoEXT transition =
1366 {
1367 vk::VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT, // VkStructureType sType;
1368 DE_NULL, // const void* pNext;
1369 copyImage->get(), // VkImage image;
1370 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1371 m_dstLayout, // VkImageLayout newLayout;
1372 subresourceRange // VkImageSubresourceRange subresourceRange;
1373 };
1374 vk.transitionImageLayoutEXT(device, 1, &transition);
1375
1376 const vk::VkImageCopy2KHR region =
1377 {
1378 vk::VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR, // VkStructureType sType;
1379 DE_NULL, // const void* pNext;
1380 subresourceLayers, // VkImageSubresourceLayers srcSubresource;
1381 offset, // VkOffset3D srcOffset;
1382 subresourceLayers, // VkImageSubresourceLayers dstSubresource;
1383 offset, // VkOffset3D dstOffset;
1384 m_size // VkExtent3D extent;
1385 };
1386
1387 const vk::VkHostImageCopyFlagsEXT hostImageCopyFlags = m_memcpy ? (vk::VkHostImageCopyFlagsEXT)vk::VK_HOST_IMAGE_COPY_MEMCPY_EXT : (vk::VkHostImageCopyFlagsEXT)0u;
1388
1389 const vk::VkCopyImageToImageInfoEXT copyImageToImageInfo =
1390 {
1391 vk::VK_STRUCTURE_TYPE_COPY_IMAGE_TO_IMAGE_INFO_EXT, // VkStructureType sType;
1392 DE_NULL, // const void* pNext;
1393 hostImageCopyFlags, // VkHostImageCopyFlagsEXT flags;
1394 **image, // VkImage srcImage;
1395 m_srcLayout, // VkImageLayout srcImageLayout;
1396 **copyImage, // VkImage dstImage;
1397 m_dstLayout, // VkImageLayout dstImageLayout;
1398 1u, // uint32_t regionCount;
1399 ®ion, // const VkImageCopy2* pRegions;
1400 };
1401
1402 vk.copyImageToImageEXT(device, ©ImageToImageInfo);
1403
1404 transition.oldLayout = m_dstLayout;
1405 transition.newLayout = m_srcLayout;
1406 vk.transitionImageLayoutEXT(device, 1, &transition);
1407 }
1408
1409 deUint8* data = new deUint8[bufferSize];
1410
1411 const vk::VkImageToMemoryCopyEXT region =
1412 {
1413 vk::VK_STRUCTURE_TYPE_IMAGE_TO_MEMORY_COPY_EXT, // VkStructureType sType;
1414 DE_NULL, // const void* pNext;
1415 data, // void* memoryHostPointer;
1416 0u, // uint32_t memoryRowLength;
1417 0u, // uint32_t memoryImageHeight;
1418 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
1419 offset, // VkOffset3D imageOffset;
1420 m_size, // VkExtent3D imageExtent;
1421 };
1422
1423 const vk::VkCopyImageToMemoryInfoEXT copyImageToMemoryInfo =
1424 {
1425 vk::VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO_EXT, // VkStructureType sType;
1426 DE_NULL, // const void* pNext;
1427 0u, // VkMemoryImageCopyFlagsEXT flags;
1428 endImage, // VkImage srcImage;
1429 m_srcLayout, // VkImageLayout srcImageLayout;
1430 1, // uint32_t regionCount;
1431 ®ion, // const VkImageToMemoryCopyEXT* pRegions;
1432 };
1433 vk.copyImageToMemoryEXT(device, ©ImageToMemoryInfo);
1434
1435 vk::beginCommandBuffer(vk, *cmdBuffer);
1436 {
1437 const vk::VkHostImageLayoutTransitionInfoEXT transition =
1438 {
1439 vk::VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO_EXT, // VkStructureType sType;
1440 DE_NULL, // const void* pNext;
1441 **image, // VkImage image;
1442 m_srcLayout, // VkImageLayout oldLayout;
1443 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1444 subresourceRange // VkImageSubresourceRange subresourceRange;
1445 };
1446 vk.transitionImageLayoutEXT(device, 1, &transition);
1447
1448 const vk::VkBufferImageCopy copyRegion =
1449 {
1450 0u, // VkDeviceSize bufferOffset;
1451 0u, // deUint32 bufferRowLength;
1452 0u, // deUint32 bufferImageHeight;
1453 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
1454 offset, // VkOffset3D imageOffset;
1455 m_size // VkExtent3D imageExtent;
1456 };
1457 vk.cmdCopyImageToBuffer(*cmdBuffer, **image, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **outputBuffer, 1u, ©Region);
1458 }
1459 vk::endCommandBuffer(vk, *cmdBuffer);
1460
1461 vk::submitCommandsAndWait(vk, device, queue, cmdBuffer.get());
1462 auto outputPtr = outputBuffer->getAllocation().getHostPtr();
1463 bool match = memcmp(data, outputPtr, bufferSize) == 0;
1464
1465 if (!match)
1466 {
1467 for (deUint32 i = 0; i < bufferSize; ++i) {
1468 if (data[i] != ((deUint8*)outputPtr)[i])
1469 {
1470 log << tcu::TestLog::Message << "At byte " << i << " data from vkCopyImageToMemoryEXT() is " << data[i] << ", but data from vkCmdCopyImageToBuffer() is " << ((deUint8*)outputPtr)[i] << tcu::TestLog::EndMessage;
1471 break;
1472 }
1473 }
1474 }
1475
1476 delete[] data;
1477
1478 if (!match)
1479 {
1480 return tcu::TestStatus::fail("Copies values do not match");
1481 }
1482
1483 return tcu::TestStatus::pass("Pass");
1484 }
1485
1486 class PreinitializedTestCase : public vkt::TestCase
1487 {
1488 public:
PreinitializedTestCase(tcu::TestContext & context,const char * name,const vk::VkFormat format,vk::VkImageLayout srcLayout,vk::VkImageLayout dstLayout,vk::VkExtent3D size,deUint32 arrayLayers,bool imageToImageCopy,bool memcpy,vk::VkImageTiling tiling)1489 PreinitializedTestCase (tcu::TestContext& context, const char* name, const vk::VkFormat format, vk::VkImageLayout srcLayout, vk::VkImageLayout dstLayout, vk::VkExtent3D size, deUint32 arrayLayers, bool imageToImageCopy, bool memcpy, vk::VkImageTiling tiling)
1490 : TestCase (context, name)
1491 , m_format (format)
1492 , m_srcLayout (srcLayout)
1493 , m_dstLayout (dstLayout)
1494 , m_size (size)
1495 , m_arrayLayers (arrayLayers)
1496 , m_imageToImageCopy (imageToImageCopy)
1497 , m_memcpy (memcpy)
1498 , m_tiling (tiling)
1499 {
1500 }
1501 private:
1502 void checkSupport (vkt::Context& context) const;
createInstance(vkt::Context & context) const1503 vkt::TestInstance* createInstance (vkt::Context& context) const { return new PreinitializedTestInstance(context, m_format, m_srcLayout, m_dstLayout, m_size, m_arrayLayers, m_imageToImageCopy, m_memcpy, m_tiling); }
1504
1505 const vk::VkFormat m_format;
1506 const vk::VkImageLayout m_srcLayout;
1507 const vk::VkImageLayout m_dstLayout;
1508 const vk::VkExtent3D m_size;
1509 const deUint32 m_arrayLayers;
1510 const bool m_imageToImageCopy;
1511 const bool m_memcpy;
1512 const vk::VkImageTiling m_tiling;
1513 };
1514
checkSupport(vkt::Context & context) const1515 void PreinitializedTestCase::checkSupport (vkt::Context& context) const
1516 {
1517 vk::VkInstance instance (context.getInstance());
1518 vk::InstanceDriver instanceDriver (context.getPlatformInterface(), instance);
1519 const InstanceInterface& vki = context.getInstanceInterface();
1520 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1521
1522 context.requireDeviceFunctionality("VK_EXT_host_image_copy");
1523
1524 if (m_tiling == vk::VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
1525 context.requireDeviceFunctionality("VK_EXT_image_drm_format_modifier");
1526
1527 if (m_srcLayout == vk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR || m_dstLayout == vk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR)
1528 context.requireDeviceFunctionality("VK_KHR_swapchain");
1529
1530 if (m_srcLayout == vk::VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL || m_dstLayout == vk::VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL ||
1531 m_srcLayout == vk::VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR || m_dstLayout == vk::VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR)
1532 context.requireDeviceFunctionality("VK_KHR_maintenance2");
1533
1534 if (m_srcLayout == vk::VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL || m_dstLayout == vk::VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL ||
1535 m_srcLayout == vk::VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL || m_dstLayout == vk::VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL ||
1536 m_srcLayout == vk::VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL || m_dstLayout == vk::VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL)
1537 context.requireDeviceFunctionality("VK_KHR_separate_depth_stencil_layouts");
1538
1539 if (m_srcLayout == vk::VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL || m_dstLayout == vk::VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL ||
1540 m_srcLayout == vk::VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL || m_dstLayout == vk::VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL)
1541 context.requireDeviceFunctionality("VK_KHR_synchronization2");
1542
1543 if (m_srcLayout == vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT || m_dstLayout == vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT)
1544 context.requireDeviceFunctionality("VK_EXT_attachment_feedback_loop_layout");
1545
1546 vk::VkPhysicalDeviceHostImageCopyFeaturesEXT hostImageCopyFeatures =
1547 {
1548 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT, // VkStructureType sType
1549 DE_NULL, // const void* pNext
1550 VK_FALSE, // VkBool32 hostImageCopy;
1551 };
1552
1553 vk::VkPhysicalDeviceFeatures features;
1554 deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
1555 vk::VkPhysicalDeviceFeatures2 features2 =
1556 {
1557 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // VkStructureType sType
1558 &hostImageCopyFeatures, // const void* pNext
1559 features // VkPhysicalDeviceFeatures features
1560 };
1561
1562 instanceDriver.getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
1563
1564 vk::VkPhysicalDeviceHostImageCopyPropertiesEXT hostImageCopyProperties =
1565 {
1566 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT, // VkStructureType sType;
1567 DE_NULL, // void* pNext;
1568 0u, // uint32_t copySrcLayoutCount;
1569 DE_NULL, // VkImageLayout* pCopySrcLayouts;
1570 0u, // uint32_t copyDstLayoutCount;
1571 DE_NULL, // VkImageLayout* pCopyDstLayouts;
1572 {}, // uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE];
1573 DE_FALSE // VkBool32 identicalMemoryTypeRequirements;
1574 };
1575
1576 getHostImageCopyProperties(instanceDriver, physicalDevice, &hostImageCopyProperties);
1577 std::vector<vk::VkImageLayout> srcLayouts(hostImageCopyProperties.copySrcLayoutCount);
1578 std::vector<vk::VkImageLayout> dstLayouts(hostImageCopyProperties.copyDstLayoutCount);
1579 hostImageCopyProperties.pCopySrcLayouts = srcLayouts.data();
1580 hostImageCopyProperties.pCopyDstLayouts = dstLayouts.data();
1581 getHostImageCopyProperties(instanceDriver, physicalDevice, &hostImageCopyProperties);
1582
1583 bool layoutSupported = false;
1584 for (deUint32 i = 0; i < hostImageCopyProperties.copySrcLayoutCount; ++i)
1585 {
1586 if (hostImageCopyProperties.pCopySrcLayouts[i] == m_srcLayout)
1587 layoutSupported = true;
1588 }
1589 if (layoutSupported == false)
1590 TCU_THROW(NotSupportedError, "Layout not supported for src host copy");
1591 layoutSupported = false;
1592 for (deUint32 i = 0; i < hostImageCopyProperties.copyDstLayoutCount; ++i)
1593 {
1594 if (hostImageCopyProperties.pCopyDstLayouts[i] == m_dstLayout)
1595 layoutSupported = true;
1596 }
1597 if (layoutSupported == false)
1598 TCU_THROW(NotSupportedError, "Layout not supported for dst host copy");
1599
1600 if (hostImageCopyFeatures.hostImageCopy != VK_TRUE)
1601 TCU_THROW(NotSupportedError, "hostImageCopy not supported");
1602
1603 deUint64 modifier = 0;
1604 checkSupportedFormatFeatures(instanceDriver, physicalDevice, m_format, m_tiling, &modifier);
1605
1606 vk::VkImageType const imageType = m_size.depth > 1 ? vk::VK_IMAGE_TYPE_3D : vk::VK_IMAGE_TYPE_2D;
1607 vk::VkImageFormatProperties2 imageFormatProperties =
1608 {
1609 vk::VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, // VkStructureType sType;
1610 DE_NULL, // void* pNext;
1611 {}, // VkImageFormatProperties imageFormatProperties;
1612 };
1613 vk::VkPhysicalDeviceImageDrmFormatModifierInfoEXT modifierInfo = {
1614 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, // VkStructureType sType;
1615 DE_NULL, // const void* pNext;
1616 modifier, // uint64_t drmFormatModifier;
1617 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1618 0u, // uint32_t queueFamilyIndexCount;
1619 DE_NULL // const uint32_t* pQueueFamilyIndices;
1620 };
1621 vk::VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
1622 {
1623 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // VkStructureType sType;
1624 m_tiling == vk::VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ? &modifierInfo : DE_NULL, // const void* pNext;
1625 m_format, // VkFormat format;
1626 imageType, // VkImageType type;
1627 m_tiling, // VkImageTiling tiling;
1628 vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
1629 (vk::VkImageCreateFlags)0u // VkImageCreateFlags flags;
1630 };
1631 if (vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageFormatProperties) == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1632 TCU_THROW(NotSupportedError, "Image format not supported.");
1633 if (imageFormatProperties.imageFormatProperties.maxArrayLayers < m_arrayLayers)
1634 TCU_THROW(NotSupportedError, "Required image array layers not supported.");
1635 }
1636
1637 class PropertiesTestInstance : public vkt::TestInstance
1638 {
1639 public:
PropertiesTestInstance(vkt::Context & context)1640 PropertiesTestInstance (vkt::Context& context)
1641 : vkt::TestInstance (context)
1642 {
1643 }
1644
1645 private:
1646 tcu::TestStatus iterate (void);
1647 };
1648
iterate(void)1649 tcu::TestStatus PropertiesTestInstance::iterate (void) {
1650 vk::VkInstance instance (m_context.getInstance());
1651 vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
1652 vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1653
1654 vk::VkPhysicalDeviceHostImageCopyPropertiesEXT hostImageCopyProperties =
1655 {
1656 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_PROPERTIES_EXT, // VkStructureType sType;
1657 DE_NULL, // void* pNext;
1658 0u, // uint32_t copySrcLayoutCount;
1659 DE_NULL, // VkImageLayout* pCopySrcLayouts;
1660 0u, // uint32_t copyDstLayoutCount;
1661 DE_NULL, // VkImageLayout* pCopyDstLayouts;
1662 {}, // uint8_t optimalTilingLayoutUUID[VK_UUID_SIZE];
1663 DE_FALSE // VkBool32 identicalMemoryTypeRequirements;
1664 };
1665 getHostImageCopyProperties(instanceDriver, physicalDevice, &hostImageCopyProperties);
1666 std::vector<vk::VkImageLayout> srcLayouts(hostImageCopyProperties.copySrcLayoutCount);
1667 std::vector<vk::VkImageLayout> dstLayouts(hostImageCopyProperties.copyDstLayoutCount);
1668 hostImageCopyProperties.pCopySrcLayouts = srcLayouts.data();
1669 hostImageCopyProperties.pCopyDstLayouts = dstLayouts.data();
1670 getHostImageCopyProperties(instanceDriver, physicalDevice, &hostImageCopyProperties);
1671
1672 if (hostImageCopyProperties.copySrcLayoutCount == 0)
1673 return tcu::TestStatus::fail("copySrcLayoutCount is 0");
1674 if (hostImageCopyProperties.copyDstLayoutCount == 0)
1675 return tcu::TestStatus::fail("copyDstLayoutCount is 0");
1676
1677 bool layoutSupported = false;
1678 for (deUint32 i = 0; i < hostImageCopyProperties.copySrcLayoutCount; ++i)
1679 {
1680 if (hostImageCopyProperties.pCopySrcLayouts[i] == vk::VK_IMAGE_LAYOUT_GENERAL)
1681 layoutSupported = true;
1682 }
1683 if (layoutSupported == false)
1684 return tcu::TestStatus::fail("VK_IMAGE_LAYOUT_GENERAL not supported for src host copy");
1685 layoutSupported = false;
1686 for (deUint32 i = 0; i < hostImageCopyProperties.copyDstLayoutCount; ++i)
1687 {
1688 if (hostImageCopyProperties.pCopyDstLayouts[i] == vk::VK_IMAGE_LAYOUT_GENERAL)
1689 layoutSupported = true;
1690 }
1691 if (layoutSupported == false)
1692 return tcu::TestStatus::fail("VK_IMAGE_LAYOUT_GENERAL not supported for dst host copy");
1693
1694 return tcu::TestStatus::pass("Pass");
1695 }
1696
1697 class PropertiesTestCase : public vkt::TestCase
1698 {
1699 public:
PropertiesTestCase(tcu::TestContext & context,const char * name)1700 PropertiesTestCase (tcu::TestContext& context, const char* name)
1701 : TestCase (context, name)
1702 {
1703 }
1704 private:
createInstance(vkt::Context & context) const1705 vkt::TestInstance* createInstance (vkt::Context& context) const { return new PropertiesTestInstance(context); }
1706 void checkSupport (vkt::Context& context) const;
1707 };
1708
checkSupport(vkt::Context & context) const1709 void PropertiesTestCase::checkSupport (vkt::Context& context) const {
1710 context.requireDeviceFunctionality("VK_EXT_host_image_copy");
1711 }
1712
1713 class QueryTestInstance : public vkt::TestInstance
1714 {
1715 public:
QueryTestInstance(vkt::Context & context,const vk::VkFormat format,const vk::VkImageTiling tiling)1716 QueryTestInstance (vkt::Context& context, const vk::VkFormat format, const vk::VkImageTiling tiling)
1717 : vkt::TestInstance (context)
1718 , m_format (format)
1719 , m_tiling (tiling)
1720 {
1721 }
1722
1723 private:
1724 tcu::TestStatus iterate (void);
1725
1726 const vk::VkFormat m_format;
1727 const vk::VkImageTiling m_tiling;
1728 };
1729
iterate(void)1730 tcu::TestStatus QueryTestInstance::iterate (void)
1731 {
1732 const InstanceInterface& vki = m_context.getInstanceInterface();
1733 const vk::VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
1734 tcu::TestLog& log = m_context.getTestContext().getLog();
1735
1736 const vk::VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
1737 {
1738 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // VkStructureType sType;
1739 DE_NULL, // const void* pNext;
1740 m_format, // VkFormat format;
1741 vk::VK_IMAGE_TYPE_2D, // VkImageType type;
1742 m_tiling, // VkImageTiling tiling;
1743 vk::VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT, // VkImageUsageFlags usage;
1744 (VkImageCreateFlags)0u // VkImageCreateFlags flags;
1745 };
1746
1747 vk::VkHostImageCopyDevicePerformanceQueryEXT hostImageCopyDevicePerformanceQuery = vk::initVulkanStructure();
1748 vk::VkImageFormatProperties2 imageFormatProperties = vk::initVulkanStructure(&hostImageCopyDevicePerformanceQuery);
1749 vk::VkResult res = vki.getPhysicalDeviceImageFormatProperties2(physicalDevice, &imageFormatInfo, &imageFormatProperties);
1750
1751 if (hostImageCopyDevicePerformanceQuery.identicalMemoryLayout == VK_FALSE) {
1752 if (hostImageCopyDevicePerformanceQuery.optimalDeviceAccess != VK_FALSE)
1753 {
1754 log << tcu::TestLog::Message << "VkHostImageCopyDevicePerformanceQueryEXT::identicalMemoryLayout is VK_FALSE, but VkHostImageCopyDevicePerformanceQueryEXT::optimalDeviceAccess is VK_TRUE" << tcu::TestLog::EndMessage;
1755 return tcu::TestStatus::fail("Fail");
1756 }
1757 }
1758 else
1759 {
1760 if (hostImageCopyDevicePerformanceQuery.optimalDeviceAccess != VK_TRUE)
1761 {
1762 log << tcu::TestLog::Message << "VkHostImageCopyDevicePerformanceQueryEXT::identicalMemoryLayout is VK_TRUE, but VkHostImageCopyDevicePerformanceQueryEXT::optimalDeviceAccess is VK_FALSE" << tcu::TestLog::EndMessage;
1763 return tcu::TestStatus::fail("Fail");
1764 }
1765 }
1766
1767 if (isBlockCompressedFormat(m_format) && res == vk::VK_SUCCESS)
1768 {
1769 if (hostImageCopyDevicePerformanceQuery.optimalDeviceAccess != VK_TRUE)
1770 {
1771 log << tcu::TestLog::Message << "Format is a block compressed format and vkGetPhysicalDeviceImageFormatProperties2 returned VK_SUCCESS, but VkHostImageCopyDevicePerformanceQueryEXT::optimalDeviceAccess is VK_FALSE" << tcu::TestLog::EndMessage;
1772 return tcu::TestStatus::fail("Fail");
1773 }
1774 }
1775
1776 if (!vk::isDepthStencilFormat(m_format))
1777 {
1778 vk::VkFormatProperties3 formatProperties3 = vk::initVulkanStructure();
1779 vk::VkFormatProperties2 formatProperties2 = vk::initVulkanStructure(&formatProperties3);
1780 vki.getPhysicalDeviceFormatProperties2(physicalDevice, m_format, &formatProperties2);
1781
1782 if (m_tiling == VK_IMAGE_TILING_OPTIMAL)
1783 {
1784 if ((formatProperties3.optimalTilingFeatures & VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0)
1785 {
1786 log << tcu::TestLog::Message << "VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT is supported in optimalTilingFeatures for format " << vk::getFormatStr(m_format).toString() << ", but VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT is not" << tcu::TestLog::EndMessage;
1787 return tcu::TestStatus::fail("VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT not supported");
1788 }
1789 }
1790 else if (m_tiling == VK_IMAGE_TILING_LINEAR)
1791 {
1792 if ((formatProperties3.linearTilingFeatures & VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT) == 0)
1793 {
1794 log << tcu::TestLog::Message << "VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT is supported in linearTilingFeatures for format " << vk::getFormatStr(m_format).toString() << ", but VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT is not" << tcu::TestLog::EndMessage;
1795 return tcu::TestStatus::fail("VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT not supported");
1796 }
1797 }
1798 }
1799
1800 return tcu::TestStatus::pass("Pass");
1801 }
1802
1803 class QueryTestCase : public vkt::TestCase
1804 {
1805 public:
QueryTestCase(tcu::TestContext & context,const char * name,const vk::VkFormat format,const vk::VkImageTiling tiling)1806 QueryTestCase(tcu::TestContext& context, const char* name, const vk::VkFormat format, const vk::VkImageTiling tiling)
1807 : TestCase (context, name)
1808 , m_format (format)
1809 , m_tiling (tiling)
1810 {
1811 }
1812 private:
createInstance(vkt::Context & context) const1813 vkt::TestInstance* createInstance (vkt::Context& context) const { return new QueryTestInstance(context, m_format, m_tiling); }
1814 void checkSupport (vkt::Context& context) const;
1815
1816 const vk::VkFormat m_format;
1817 const vk::VkImageTiling m_tiling;
1818 };
1819
checkSupport(vkt::Context & context) const1820 void QueryTestCase::checkSupport (vkt::Context& context) const {
1821 const InstanceInterface& vki = context.getInstanceInterface();
1822
1823 context.requireDeviceFunctionality("VK_EXT_host_image_copy");
1824
1825 vk::VkFormatProperties3 formatProperties3 = vk::initVulkanStructure();
1826 vk::VkFormatProperties2 formatProperties2 = vk::initVulkanStructure(&formatProperties3);
1827 vki.getPhysicalDeviceFormatProperties2(context.getPhysicalDevice(), m_format, &formatProperties2);
1828 if (m_tiling == VK_IMAGE_TILING_OPTIMAL && (formatProperties3.optimalTilingFeatures & vk::VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) == 0)
1829 TCU_THROW(NotSupportedError, "Format feature sampled image bit not supported for optimal tiling.");
1830 if (m_tiling == VK_IMAGE_TILING_LINEAR && (formatProperties3.linearTilingFeatures & vk::VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT) == 0)
1831 TCU_THROW(NotSupportedError, "Format feature sampled image bit not supported for linear tiling.");
1832 }
1833
testGenerator(tcu::TestCaseGroup * group)1834 void testGenerator(tcu::TestCaseGroup* group)
1835 {
1836 constexpr struct CopyTest
1837 {
1838 bool hostTransferLayout;
1839 bool copyMemoryToImage;
1840 const char* name;
1841 } copyTests[] =
1842 {
1843 // Host copy and transfer
1844 { true, true, "host_transfer_copy_general"},
1845 // Host transfer
1846 { true, false, "host_transfer"},
1847 // Host copy
1848 { false, true, "host_copy"},
1849 };
1850
1851 constexpr struct CopyImageToMemory
1852 {
1853 bool hostCopyImageToMemory;
1854 const char* name;
1855 } copyImageToMemoryTests[] = {
1856 // Copy from image to memory on host
1857 { true, "host_image_to_memory_copy"},
1858 // Copy from image to memory on gpu
1859 { false, "image_to_memory_copy"},
1860 };
1861
1862 constexpr struct TransitionTest
1863 {
1864 bool host;
1865 const char* name;
1866 } transitionTests[] =
1867 {
1868 // Transition using vkTransitionImageLayoutEXT
1869 { true, "host_transition"},
1870 // Transition using a pipeline barrier
1871 { false, "barrier_transition"},
1872 };
1873
1874 const struct FlagsTest
1875 {
1876 bool memcpy;
1877 const char* name;
1878 } flagsTests[] =
1879 {
1880 // Copy with no flags
1881 { false, "none"},
1882 // Copy with VK_HOST_IMAGE_COPY_MEMCPY_EXT flag
1883 { true, "memcpy"},
1884 };
1885
1886 const struct DynamicRendering {
1887 bool dynamicRendering;
1888 const char* name;
1889 } dynamicRendering[] = {
1890 // render pass
1891 { false, "render_pass"},
1892 // dynamic rendering
1893 { true, "dynamic_rendering"},
1894 };
1895
1896 const struct Tiling {
1897 vk::VkImageTiling tiling;
1898 const char* name;
1899 } tilingTests[] = {
1900 { vk::VK_IMAGE_TILING_LINEAR, "linear"},
1901 { vk::VK_IMAGE_TILING_OPTIMAL, "optimal"},
1902 };
1903
1904 const struct ImageFormatsAndCommand {
1905 Command command;
1906 vk::VkFormat sampled;
1907 vk::VkFormat output;
1908 } formatsAndCommands[] = {
1909 { DRAW, vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UNORM },
1910 { DRAW, vk::VK_FORMAT_R32G32B32A32_SFLOAT, vk::VK_FORMAT_R32G32B32A32_SFLOAT },
1911 { DRAW, vk::VK_FORMAT_R16_UNORM, vk::VK_FORMAT_R16_UNORM },
1912 { DRAW, vk::VK_FORMAT_D16_UNORM, vk::VK_FORMAT_R16_UNORM },
1913 { DRAW, vk::VK_FORMAT_D32_SFLOAT, vk::VK_FORMAT_R32_SFLOAT },
1914 { DRAW, vk::VK_FORMAT_BC7_UNORM_BLOCK, vk::VK_FORMAT_R8G8B8A8_UNORM },
1915 { DRAW, vk::VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, vk::VK_FORMAT_R8G8B8A8_UNORM },
1916 { DRAW, vk::VK_FORMAT_ASTC_4x4_UNORM_BLOCK, vk::VK_FORMAT_R8G8B8A8_UNORM },
1917 { DISPATCH, vk::VK_FORMAT_R10X6_UNORM_PACK16, vk::VK_FORMAT_R10X6_UNORM_PACK16 },
1918 { DISPATCH, vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UNORM },
1919 { DISPATCH, vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UINT },
1920 };
1921
1922 const struct ImageSizes
1923 {
1924 vk::VkExtent3D size;
1925 const char* name;
1926 } imageSizes[] =
1927 {
1928 { makeExtent3D(16u, 16u, 1u), "16x16"},
1929 { makeExtent3D(32u, 28u, 1u), "32x28"},
1930 { makeExtent3D(53u, 61u, 1u), "53x61"},
1931 };
1932
1933 constexpr struct ImageLayoutTest
1934 {
1935 vk::VkImageLayout srcLayout;
1936 vk::VkImageLayout dstLayout;
1937 const char* name;
1938 } imageLayoutTests[] =
1939 {
1940 { vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, "general_general"},
1941 { vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_src_transfer_dst"},
1942 };
1943
1944 constexpr struct IntermediateImageLayoutTest
1945 {
1946 vk::VkImageLayout layout;
1947 const char* name;
1948 } intermediateImageLayoutTests[] =
1949 {
1950 { vk::VK_IMAGE_LAYOUT_GENERAL, "general"},
1951 { vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "color_attachment_optimal"},
1952 { vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "depth_stencil_attachment_optimal"},
1953 { vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "depth_stencil_read_only_optimal"},
1954 { vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "shader_read_only_optimal"},
1955 { vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "transfer_src_optimal"},
1956 { vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_dst_optimal"},
1957 };
1958
1959 constexpr struct SparseTest
1960 {
1961 bool sparse;
1962 const char* name;
1963 } sparseTests[] =
1964 {
1965 // non-sparse image
1966 { false, "regular"},
1967 // sparse image
1968 { true, "sparse"},
1969 };
1970
1971 constexpr struct MipLevelRegionCountPaddingTest
1972 {
1973 deUint32 mipLevel;
1974 deUint32 regionsCount;
1975 deUint32 padding;
1976 const char* name;
1977 const char* desc;
1978 } mipLevelRegionCountPaddingTests[] =
1979 {
1980 { 0u, 1, 0u, "0_1_0", "" },
1981 { 1u, 1, 0u, "1_1_0", "" },
1982 { 4u, 1, 0u, "4_1_0", "" },
1983 { 0u, 4, 4u, "0_4_4", "" },
1984 { 0u, 16, 64u, "0_16_64", "" },
1985 };
1986
1987 tcu::TestContext& testCtx = group->getTestContext();
1988
1989 for (const auto& formatAndCommand : formatsAndCommands)
1990 {
1991 std::string formatName = formatAndCommand.command == DRAW ? "draw" : "dispatch";
1992 formatName += "_" + getFormatShortString(formatAndCommand.output) + "_" + getFormatShortString(formatAndCommand.sampled);
1993 tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(testCtx, formatName.c_str());
1994
1995 bool colorFormat = isCompressedFormat(formatAndCommand.sampled) ||
1996 !(tcu::hasDepthComponent(mapVkFormat(formatAndCommand.sampled).order) || tcu::hasDepthComponent(mapVkFormat(formatAndCommand.sampled).order));
1997
1998 for (const auto& copy : copyTests)
1999 {
2000 tcu::TestCaseGroup* const copyTestGroup = new tcu::TestCaseGroup(testCtx, copy.name);
2001 for (const auto& imageToMemory : copyImageToMemoryTests)
2002 {
2003 tcu::TestCaseGroup* const imageToMemoryGroup = new tcu::TestCaseGroup(testCtx, imageToMemory.name);
2004 for (const auto& transition : transitionTests)
2005 {
2006 tcu::TestCaseGroup* const transitionGroup = new tcu::TestCaseGroup(testCtx, transition.name);
2007 for (const auto& flags : flagsTests)
2008 {
2009 tcu::TestCaseGroup* const flagsGroup = new tcu::TestCaseGroup(testCtx, flags.name);
2010 for (const auto& layouts : imageLayoutTests)
2011 {
2012 tcu::TestCaseGroup* const layoutsGroup = new tcu::TestCaseGroup(testCtx, layouts.name);
2013 for (const auto& intermediateLayout : intermediateImageLayoutTests)
2014 {
2015 if (colorFormat && (intermediateLayout.layout == vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL || intermediateLayout.layout == vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL))
2016 continue;
2017 else if (!colorFormat && intermediateLayout.layout == vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
2018 continue;
2019
2020 tcu::TestCaseGroup* const intermediateLayoutGroup = new tcu::TestCaseGroup(testCtx, intermediateLayout.name);
2021 for (const auto& tiling : tilingTests)
2022 {
2023 tcu::TestCaseGroup* const tilingGroup = new tcu::TestCaseGroup(testCtx, tiling.name);
2024 for (const auto& mipLevelRegionCountPaddingTest : mipLevelRegionCountPaddingTests)
2025 {
2026 tcu::TestCaseGroup* const mipLevelRegionCountPaddingGroup = new tcu::TestCaseGroup(testCtx, mipLevelRegionCountPaddingTest.name);
2027 for (const auto& size : imageSizes)
2028 {
2029 tcu::TestCaseGroup* const sizeGroup = new tcu::TestCaseGroup(testCtx, size.name);
2030 for (const auto& sparse : sparseTests)
2031 {
2032 if (sparse.sparse && isCompressedFormat(formatAndCommand.sampled))
2033 continue;
2034
2035 tcu::TestCaseGroup* const sparseGroup = new tcu::TestCaseGroup(testCtx, sparse.name);
2036 for (const auto& renderingType : dynamicRendering)
2037 {
2038 if (renderingType.dynamicRendering && formatAndCommand.command == DISPATCH)
2039 continue;
2040
2041 const TestParameters parameters =
2042 {
2043 copy.copyMemoryToImage, // bool copyMemoryToImage
2044 imageToMemory.hostCopyImageToMemory, // bool hostCopyImageToMemory
2045 copy.hostTransferLayout, // bool hostTransferLayout
2046 transition.host, // bool outputImageHostTransition
2047 flags.memcpy, // bool memcpyFlag
2048 renderingType.dynamicRendering, // bool dynamicRendering
2049 formatAndCommand.command, // Command command
2050 formatAndCommand.sampled, // VkFormat imageSampledFormat
2051 layouts.srcLayout, // VkImageLayout srcLayout
2052 layouts.dstLayout, // VkImageLayout dstLayout
2053 intermediateLayout.layout, // VkImageLayout intermediateLayout
2054 tiling.tiling, // VkImageTiling sampledTiling;
2055 formatAndCommand.output, // VkFormat imageOutputFormat
2056 size.size, // VkExtent3D imageSize
2057 sparse.sparse, // bool sparse
2058 mipLevelRegionCountPaddingTest.mipLevel, // deUint32 mipLevel
2059 mipLevelRegionCountPaddingTest.regionsCount, // deUint32 regionsCount
2060 mipLevelRegionCountPaddingTest.padding // deUint32 padding
2061 };
2062
2063 sparseGroup->addChild(new HostImageCopyTestCase(testCtx, renderingType.name, parameters));
2064 }
2065 sizeGroup->addChild(sparseGroup);
2066 }
2067 mipLevelRegionCountPaddingGroup->addChild(sizeGroup);
2068 }
2069 tilingGroup->addChild(mipLevelRegionCountPaddingGroup);
2070 }
2071 intermediateLayoutGroup->addChild(tilingGroup);
2072 }
2073 layoutsGroup->addChild(intermediateLayoutGroup);
2074 }
2075 flagsGroup->addChild(layoutsGroup);
2076 }
2077 transitionGroup->addChild(flagsGroup);
2078 }
2079 imageToMemoryGroup->addChild(transitionGroup);
2080 }
2081 copyTestGroup->addChild(imageToMemoryGroup);
2082 }
2083 formatGroup->addChild(copyTestGroup);
2084 }
2085 group->addChild(formatGroup);
2086 }
2087
2088 const struct PreinitializedFormats {
2089 vk::VkFormat format;
2090 } preinitializedFormats[] = {
2091 { vk::VK_FORMAT_R8G8B8A8_UNORM },
2092 { vk::VK_FORMAT_R32G32B32A32_SFLOAT },
2093 { vk::VK_FORMAT_R16_UNORM },
2094 { vk::VK_FORMAT_R16G16_UINT },
2095 { vk::VK_FORMAT_B8G8R8A8_SINT },
2096 { vk::VK_FORMAT_R16_SFLOAT },
2097 };
2098
2099 const struct PreinitializedTiling {
2100 vk::VkImageTiling tiling;
2101 const char* name;
2102 } preinitializedTilingTests[] = {
2103 { vk::VK_IMAGE_TILING_LINEAR, "linear"},
2104 { vk::VK_IMAGE_TILING_OPTIMAL, "optimal"},
2105 { vk::VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, "drm_format_modifier"},
2106 };
2107
2108 constexpr struct PreinitializedImageLayoutTest
2109 {
2110 vk::VkImageLayout layout;
2111 const char* name;
2112 } preinitializedImageLayoutTests[] =
2113 {
2114 { vk::VK_IMAGE_LAYOUT_GENERAL, "general"},
2115 { vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "color_attachment_optimal"},
2116 { vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, "depth_stencil_attachment_optimal"},
2117 { vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, "depth_stencil_read_only_optimal"},
2118 { vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, "shader_read_only_optimal"},
2119 { vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "transfer_src_optimal"},
2120 { vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_dst_optimal"},
2121 { vk::VK_IMAGE_LAYOUT_PREINITIALIZED, "preinitialized"},
2122 { vk::VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, "present_src"},
2123 { vk::VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, "depth_read_only_stencil_attachment_optimal"},
2124 { vk::VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, "depth_attachment_stencil_read_only_optimal"},
2125 { vk::VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, "depth_read_only_optimal"},
2126 { vk::VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, "stencil_attachment_optimal"},
2127 { vk::VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, "stencil_read_only_optimal"},
2128 { vk::VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, "read_only_optimal"},
2129 { vk::VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, "attachment_optimal"},
2130 { vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT, "attachment_feedback_loop_optimal"},
2131 };
2132
2133 constexpr struct ImageToImageTest
2134 {
2135 bool imageToImageCopy;
2136 bool memcpy;
2137 const char* name;
2138 } imageToImageCopyTests[] =
2139 {
2140 { true, false, "image_to_image_copy"},
2141 { true, true, "image_to_image_memcpy"},
2142 { false, false, "preinitialized"},
2143 };
2144
2145 constexpr struct ImageSizeTest
2146 {
2147 vk::VkExtent3D size;
2148 deUint32 layerCount;
2149 const char* name;
2150 } imageSizeTests[] =
2151 {
2152 { {32, 32, 1}, 1, "32x32x1_1"},
2153 { {32, 32, 1}, 2, "32x32x1_2"},
2154 { {51, 63, 1}, 1, "51x63x1_1"},
2155 { {24, 24, 4}, 1, "24x24x4_4"},
2156 };
2157
2158 for (const auto& tiling : preinitializedTilingTests)
2159 {
2160 tcu::TestCaseGroup* const tilingGroup = new tcu::TestCaseGroup(testCtx, tiling.name);
2161 for (const auto& imageToImage : imageToImageCopyTests)
2162 {
2163 tcu::TestCaseGroup* const imageToImageCopyGroup = new tcu::TestCaseGroup(testCtx, imageToImage.name);
2164 for (const auto& srcLayout : preinitializedImageLayoutTests)
2165 {
2166 tcu::TestCaseGroup* const srcLayoutGroup = new tcu::TestCaseGroup(testCtx, srcLayout.name);
2167 for (const auto& dstLayout : preinitializedImageLayoutTests)
2168 {
2169 tcu::TestCaseGroup* const dstLayoutGroup = new tcu::TestCaseGroup(testCtx, dstLayout.name);
2170 for (const auto& size : imageSizeTests)
2171 {
2172 tcu::TestCaseGroup* const sizeGroup = new tcu::TestCaseGroup(testCtx, size.name);
2173 for (const auto& format : preinitializedFormats)
2174 {
2175 const auto formatName = getFormatShortString(format.format);
2176 sizeGroup->addChild(new PreinitializedTestCase(testCtx, formatName.c_str(), format.format, srcLayout.layout, dstLayout.layout, size.size, size.layerCount, imageToImage.imageToImageCopy, imageToImage.memcpy, tiling.tiling));
2177 }
2178 dstLayoutGroup->addChild(sizeGroup);
2179 }
2180 srcLayoutGroup->addChild(dstLayoutGroup);
2181 }
2182 imageToImageCopyGroup->addChild(srcLayoutGroup);
2183 }
2184 tilingGroup->addChild(imageToImageCopyGroup);
2185 }
2186 group->addChild(tilingGroup);
2187 }
2188
2189 tcu::TestCaseGroup* const propertiesGroup = new tcu::TestCaseGroup(testCtx, "properties");
2190 propertiesGroup->addChild(new PropertiesTestCase(testCtx, "properties"));
2191
2192 const struct QueryFormats {
2193 vk::VkFormat format;
2194 } queryFormats[] = {
2195 { vk::VK_FORMAT_R8G8B8A8_UNORM },
2196 { vk::VK_FORMAT_R32G32B32A32_SFLOAT },
2197 { vk::VK_FORMAT_R16_UNORM },
2198 { vk::VK_FORMAT_R16G16_UINT },
2199 { vk::VK_FORMAT_B8G8R8A8_SINT },
2200 { vk::VK_FORMAT_R16_SFLOAT },
2201 { vk::VK_FORMAT_D24_UNORM_S8_UINT },
2202 { vk::VK_FORMAT_BC7_UNORM_BLOCK },
2203 { vk::VK_FORMAT_BC5_SNORM_BLOCK },
2204 };
2205
2206 group->addChild(propertiesGroup);
2207
2208 tcu::TestCaseGroup* const queryGroup = new tcu::TestCaseGroup(testCtx, "query");
2209
2210 for (const auto& tiling : tilingTests)
2211 {
2212 tcu::TestCaseGroup* const tilingGroup = new tcu::TestCaseGroup(testCtx, tiling.name);
2213 for (const auto& format : queryFormats)
2214 {
2215 const auto formatName = getFormatShortString(format.format);
2216 tilingGroup->addChild(new QueryTestCase(testCtx, formatName.c_str(), format.format, tiling.tiling));
2217 }
2218 queryGroup->addChild(tilingGroup);
2219 }
2220
2221 group->addChild(queryGroup);
2222 }
2223
2224 } // anonymous
2225
createImageHostImageCopyTests(tcu::TestContext & testCtx)2226 tcu::TestCaseGroup* createImageHostImageCopyTests (tcu::TestContext& testCtx)
2227 {
2228 de::MovePtr<tcu::TestCaseGroup> testGroup (createTestGroup(testCtx, "host_image_copy", testGenerator));
2229 return testGroup.release();
2230 }
2231
2232 } // image
2233 } // vkt
2234