1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 * \file vktImageTranscodingSupportTests.cpp
21 * \brief Transcoding support tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktImageTranscodingSupportTests.hpp"
26 #include "deUniquePtr.hpp"
27 #include "deStringUtil.hpp"
28 #include "deSharedPtr.hpp"
29 #include "deRandom.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vktImageTestsUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBuilderUtil.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 #include "vkObjUtil.hpp"
43 #include "vkBufferWithMemory.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuTexture.hpp"
47 #include "tcuCompressedTexture.hpp"
48 #include "tcuVectorType.hpp"
49 #include "tcuResource.hpp"
50 #include "tcuImageIO.hpp"
51 #include "tcuImageCompare.hpp"
52 #include "tcuTestLog.hpp"
53 #include "tcuRGBA.hpp"
54 #include "tcuSurface.hpp"
55 #include "tcuFloat.hpp"
69 using tcu::TestContext;
70 using tcu::TestStatus;
73 using tcu::CompressedTexFormat;
74 using tcu::CompressedTexture;
77 using tcu::ConstPixelBufferAccess;
84 OPERATION_ATTACHMENT_READ,
85 OPERATION_ATTACHMENT_WRITE,
86 OPERATION_TEXTURE_READ,
87 OPERATION_TEXTURE_WRITE,
96 VkImageUsageFlagBits testedImageUsageFeature;
97 VkFormat featuredFormat;
98 VkFormat featurelessFormat;
99 VkImageUsageFlags testedImageUsage;
100 VkImageUsageFlags pairedImageUsage;
101 const VkFormat* compatibleFormats;
104 const deUint32 SINGLE_LEVEL = 1u;
105 const deUint32 SINGLE_LAYER = 1u;
107 class BasicTranscodingTestInstance : public TestInstance
110 BasicTranscodingTestInstance (Context& context,
111 const TestParameters& parameters);
112 virtual TestStatus iterate (void) = 0;
114 void generateData (deUint8* toFill,
116 const VkFormat format = VK_FORMAT_UNDEFINED);
117 const TestParameters m_parameters;
120 BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters)
121 : TestInstance (context)
122 , m_parameters (parameters)
126 // Replace Infs and NaNs with the largest normal value.
127 // Replace denormal numbers with the smallest normal value.
128 // Leave the rest untouched.
129 // T is a tcu::Float specialization.
131 void fixFloatIfNeeded(deUint8* ptr_)
133 T* ptr = reinterpret_cast<T*>(ptr_);
134 if (ptr->isInf() || ptr->isNaN())
135 *ptr = T::largestNormal(ptr->sign());
136 else if (ptr->isDenorm())
137 *ptr = T::smallestNormal(ptr->sign());
140 void BasicTranscodingTestInstance::generateData (deUint8* toFill, size_t size, const VkFormat format)
142 const deUint8 pattern[] =
145 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
155 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Positive infinity
156 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Negative infinity
157 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS)
158 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
159 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS)
160 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
161 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ)
162 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ)
163 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ)
164 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ)
166 0x7F, 0x80, 0x00, 0x00, // Positive infinity
167 0xFF, 0x80, 0x00, 0x00, // Negative infinity
168 0x7F, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS)
169 0x7F, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
170 0xFF, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS)
171 0xFF, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
172 0x7F, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ)
173 0x7F, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ)
174 0xFF, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ)
175 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ)
176 0xAA, 0xAA, 0xAA, 0xAA,
177 0x55, 0x55, 0x55, 0x55,
180 deUint8* start = toFill;
181 size_t sizeToRnd = size;
184 if (size >= 2 * sizeof(pattern))
187 for (size_t i = 0; i < sizeof(pattern); i++)
188 start[sizeof(pattern) - i - 1] = pattern[i];
190 start += sizeof(pattern);
191 sizeToRnd -= sizeof(pattern);
194 deMemcpy(start, pattern, sizeof(pattern));
196 start += sizeof(pattern);
197 sizeToRnd -= sizeof(pattern);
202 DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0);
204 deUint32* start32 = reinterpret_cast<deUint32*>(start);
205 size_t sizeToRnd32 = sizeToRnd / sizeof(deUint32);
206 Random rnd (static_cast<deUint32>(format));
208 for (size_t i = 0; i < sizeToRnd32; i++)
209 start32[i] = rnd.getUint32();
213 // Remove certain values that may not be preserved based on the uncompressed view format
214 if (isSnormFormat(m_parameters.featuredFormat))
216 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
218 if (textureFormat.type == tcu::TextureFormat::SNORM_INT8)
220 for (size_t i = 0; i < size; i++)
222 // SNORM fix: due to write operation in SNORM format
223 // replaces 0x80 to 0x81, remove these values from test
224 if (toFill[i] == 0x80)
230 for (size_t i = 0; i < size; i += 2)
232 // SNORM fix: due to write operation in SNORM format
233 // replaces 0x00 0x80 to 0x01 0x80
234 if (toFill[i] == 0x00 && toFill[i+1] == 0x80)
239 else if (isFloatFormat(m_parameters.featuredFormat))
241 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
243 if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
245 for (size_t i = 0; i < size; i += 2)
246 fixFloatIfNeeded<tcu::Float16>(toFill + i);
248 else if (textureFormat.type == tcu::TextureFormat::FLOAT)
250 for (size_t i = 0; i < size; i += 4)
251 fixFloatIfNeeded<tcu::Float16>(toFill + i);
253 for (size_t i = 0; i < size; i += 4)
254 fixFloatIfNeeded<tcu::Float32>(toFill + i);
260 class GraphicsAttachmentsTestInstance : public BasicTranscodingTestInstance
263 GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters);
264 virtual TestStatus iterate (void);
267 VkImageCreateInfo makeCreateImageInfo (const VkFormat format,
268 const ImageType type,
270 const VkImageUsageFlags usageFlags,
271 const bool extendedImageCreateFlag);
272 VkImageViewUsageCreateInfo makeImageViewUsageCreateInfo (VkImageUsageFlags imageUsageFlags);
273 VkDeviceSize getUncompressedImageData (const VkFormat format,
275 std::vector<deUint8>& data);
276 virtual void transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage);
277 bool compareAndLog (const void* reference, const void* result, size_t size);
280 GraphicsAttachmentsTestInstance::GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters)
281 : BasicTranscodingTestInstance(context, parameters)
285 TestStatus GraphicsAttachmentsTestInstance::iterate (void)
287 std::vector<deUint8> srcData;
288 std::vector<deUint8> dstData;
289 de::MovePtr<Image> outputImage;
291 transcode(srcData, dstData, outputImage);
293 DE_ASSERT(srcData.size() > 0 && srcData.size() == dstData.size());
295 if (!compareAndLog(&srcData[0], &dstData[0], srcData.size()))
296 return TestStatus::fail("Output differs from input");
298 return TestStatus::pass("Pass");
301 void GraphicsAttachmentsTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
303 const DeviceInterface& vk = m_context.getDeviceInterface();
304 const VkDevice device = m_context.getDevice();
305 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
306 const VkQueue queue = m_context.getUniversalQueue();
307 Allocator& allocator = m_context.getDefaultAllocator();
309 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
310 const VkImageViewUsageCreateInfo* imageViewUsageNull = (VkImageViewUsageCreateInfo*)DE_NULL;
311 const VkImageViewUsageCreateInfo imageViewUsage = makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
313 const VkFormat srcFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.featurelessFormat :
314 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featuredFormat :
316 const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? true :
317 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? false :
319 const VkImageUsageFlags srcImageUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.testedImageUsage :
320 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.pairedImageUsage :
322 const VkImageViewUsageCreateInfo* srcImageViewUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? &imageViewUsage :
323 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? imageViewUsageNull :
325 const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
327 const VkFormat dstFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.featuredFormat :
328 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featurelessFormat :
330 const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? false :
331 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? true :
333 const VkImageUsageFlags dstImageUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.pairedImageUsage :
334 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.testedImageUsage :
336 const VkImageViewUsageCreateInfo* dstImageViewUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? imageViewUsageNull :
337 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? &imageViewUsage :
339 const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
341 const std::vector<tcu::Vec4> vertexArray = createFullscreenQuad();
342 const deUint32 vertexCount = static_cast<deUint32>(vertexArray.size());
343 const size_t vertexBufferSizeInBytes = vertexCount * sizeof(vertexArray[0]);
344 const MovePtr<BufferWithMemory> vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
345 const Allocation& vertexBufferAlloc = vertexBuffer->getAllocation();
346 const VkDeviceSize vertexBufferOffset[] = { 0 };
348 const VkBufferCreateInfo srcImageBufferInfo (makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
349 const MovePtr<BufferWithMemory> srcImageBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
351 const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
352 const MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
353 Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, srcImageViewUsageFlags));
355 const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
356 de::MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
357 Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, dstImageViewUsageFlags));
359 const VkBufferCreateInfo dstImageBufferInfo (makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
360 MovePtr<BufferWithMemory> dstImageBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
362 const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
363 const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
365 const Unique<VkRenderPass> renderPass (vkt::image::makeRenderPass(vk, device, m_parameters.featuredFormat, m_parameters.featuredFormat));
367 const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
368 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
370 const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
371 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, SINGLE_LAYER)
372 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, SINGLE_LAYER));
373 const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
374 const VkDescriptorImageInfo descriptorSrcImageInfo (makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
376 const VkExtent2D renderSize (makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
377 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
378 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 1u));
379 #ifndef CTS_USES_VULKANSC
380 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
382 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VkCommandPoolCreateFlags(0u), queueFamilyIndex));
383 #endif // CTS_USES_VULKANSC
384 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
386 const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
387 const VkBufferMemoryBarrier srcCopyBufferBarrierPre = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
388 const VkImageMemoryBarrier srcCopyImageBarrierPre = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), subresourceRange);
389 const VkImageMemoryBarrier srcCopyImageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
390 const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
392 const VkImageView attachmentBindInfos[] = { *srcImageView, *dstImageView };
393 const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos, renderSize.width, renderSize.height, SINGLE_LAYER));
395 DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
397 // Upload vertex data
398 deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
399 flushAlloc(vk, device, vertexBufferAlloc);
401 // Upload source image data
402 const Allocation& alloc = srcImageBuffer->getAllocation();
403 deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
404 flushAlloc(vk, device, alloc);
406 beginCommandBuffer(vk, *cmdBuffer);
407 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
409 //Copy buffer to image
410 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre);
411 vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion);
412 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &srcCopyImageBarrierPost);
414 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
416 DescriptorSetUpdateBuilder()
417 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo)
420 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
421 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
422 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
424 endRenderPass(vk, *cmdBuffer);
426 const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
427 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
428 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
429 dstImage->get(), subresourceRange);
431 const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
432 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
433 dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
435 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier);
436 vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
437 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
439 endCommandBuffer(vk, *cmdBuffer);
441 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
443 const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
444 invalidateAlloc(vk, device, dstImageBufferAlloc);
445 dstData.resize((size_t)dstImageSizeInBytes);
446 deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
448 outputImage = dstImage;
452 VkImageCreateInfo GraphicsAttachmentsTestInstance::makeCreateImageInfo (const VkFormat format,
453 const ImageType type,
455 const VkImageUsageFlags usageFlags,
456 const bool extendedImageCreateFlag)
458 const VkImageType imageType = mapImageType(type);
459 const VkImageCreateFlags imageCreateFlagsBase = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
460 const VkImageCreateFlags imageCreateFlagsAddOn = extendedImageCreateFlag ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT : 0;
461 const VkImageCreateFlags imageCreateFlags = imageCreateFlagsBase | imageCreateFlagsAddOn;
463 const VkImageCreateInfo createImageInfo =
465 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
466 DE_NULL, // const void* pNext;
467 imageCreateFlags, // VkImageCreateFlags flags;
468 imageType, // VkImageType imageType;
469 format, // VkFormat format;
470 makeExtent3D(getLayerSize(type, size)), // VkExtent3D extent;
471 1u, // deUint32 mipLevels;
472 1u, // deUint32 arrayLayers;
473 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
474 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
475 usageFlags, // VkImageUsageFlags usage;
476 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
477 0u, // deUint32 queueFamilyIndexCount;
478 DE_NULL, // const deUint32* pQueueFamilyIndices;
479 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
482 return createImageInfo;
485 VkImageViewUsageCreateInfo GraphicsAttachmentsTestInstance::makeImageViewUsageCreateInfo (VkImageUsageFlags imageUsageFlags)
487 VkImageViewUsageCreateInfo imageViewUsageCreateInfo =
489 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, //VkStructureType sType;
490 DE_NULL, //const void* pNext;
491 imageUsageFlags, //VkImageUsageFlags usage;
494 return imageViewUsageCreateInfo;
497 VkDeviceSize GraphicsAttachmentsTestInstance::getUncompressedImageData (const VkFormat format, const UVec3& size, std::vector<deUint8>& data)
499 tcu::IVec3 sizeAsIVec3 = tcu::IVec3(static_cast<int>(size[0]), static_cast<int>(size[1]), static_cast<int>(size[2]));
500 VkDeviceSize sizeBytes = getImageSizeBytes(sizeAsIVec3, format);
502 data.resize((size_t)sizeBytes);
503 generateData(&data[0], data.size(), format);
508 bool GraphicsAttachmentsTestInstance::compareAndLog (const void* reference, const void* result, size_t size)
510 tcu::TestLog& log = m_context.getTestContext().getLog();
512 const deUint64* ref64 = reinterpret_cast<const deUint64*>(reference);
513 const deUint64* res64 = reinterpret_cast<const deUint64*>(result);
514 const size_t sizew = size / sizeof(deUint64);
517 DE_ASSERT(size % sizeof(deUint64) == 0);
519 for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(sizew); ndx++)
521 if (ref64[ndx] != res64[ndx])
523 std::stringstream str;
525 str << "Difference begins near byte " << ndx * sizeof(deUint64) << "."
526 << " reference value: 0x" << std::hex << std::setw(2ull * sizeof(deUint64)) << std::setfill('0') << ref64[ndx]
527 << " result value: 0x" << std::hex << std::setw(2ull * sizeof(deUint64)) << std::setfill('0') << res64[ndx];
529 log.writeMessage(str.str().c_str());
541 class GraphicsTextureTestInstance : public GraphicsAttachmentsTestInstance
544 GraphicsTextureTestInstance (Context& context, const TestParameters& parameters);
547 void transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage);
550 GraphicsTextureTestInstance::GraphicsTextureTestInstance (Context& context, const TestParameters& parameters)
551 : GraphicsAttachmentsTestInstance(context, parameters)
555 void GraphicsTextureTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
557 const DeviceInterface& vk = m_context.getDeviceInterface();
558 const VkDevice device = m_context.getDevice();
559 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
560 const VkQueue queue = m_context.getUniversalQueue();
561 Allocator& allocator = m_context.getDefaultAllocator();
563 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
564 const VkImageViewUsageCreateInfo* imageViewUsageNull = (VkImageViewUsageCreateInfo*)DE_NULL;
565 const VkImageViewUsageCreateInfo imageViewUsage = makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
567 const VkFormat srcFormat = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.featurelessFormat :
568 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featuredFormat :
570 const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ) ? true :
571 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? false :
573 const VkImageUsageFlags srcImageUsageFlags = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.testedImageUsage :
574 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.pairedImageUsage :
576 const VkImageViewUsageCreateInfo* srcImageViewUsage = (m_parameters.operation == OPERATION_TEXTURE_READ) ? &imageViewUsage :
577 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? imageViewUsageNull :
579 const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
581 const VkFormat dstFormat = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.featuredFormat :
582 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featurelessFormat :
584 const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ) ? false :
585 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? true :
587 const VkImageUsageFlags dstImageUsageFlags = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.pairedImageUsage :
588 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.testedImageUsage :
590 const VkImageViewUsageCreateInfo* dstImageViewUsage = (m_parameters.operation == OPERATION_TEXTURE_READ) ? imageViewUsageNull :
591 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? &imageViewUsage :
593 const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
595 const std::vector<tcu::Vec4> vertexArray = createFullscreenQuad();
596 const deUint32 vertexCount = static_cast<deUint32>(vertexArray.size());
597 const size_t vertexBufferSizeInBytes = vertexCount * sizeof(vertexArray[0]);
598 const MovePtr<BufferWithMemory> vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
599 const Allocation& vertexBufferAlloc = vertexBuffer->getAllocation();
600 const VkDeviceSize vertexBufferOffset[] = { 0 };
602 const VkBufferCreateInfo srcImageBufferInfo (makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
603 const MovePtr<BufferWithMemory> srcImageBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
605 const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
606 const MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
607 Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, srcImageViewUsage));
609 const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
610 de::MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
611 Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, dstImageViewUsage));
612 const VkImageMemoryBarrier dstCopyImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), subresourceRange);
614 const VkBufferCreateInfo dstImageBufferInfo (makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
615 MovePtr<BufferWithMemory> dstImageBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
617 const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
618 const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
620 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device));
622 const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
623 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
624 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
626 const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
627 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
628 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
629 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
630 const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
631 const VkSamplerCreateInfo srcSamplerInfo (makeSamplerCreateInfo());
632 const Move<VkSampler> srcSampler = vk::createSampler(vk, device, &srcSamplerInfo);
633 const VkDescriptorImageInfo descriptorSrcImage (makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
634 const VkDescriptorImageInfo descriptorDstImage (makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL));
636 const VkExtent2D renderSize (makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
637 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
638 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 0u));
639 #ifndef CTS_USES_VULKANSC
640 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
642 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VkCommandPoolCreateFlags(0u), queueFamilyIndex));
643 #endif // CTS_USES_VULKANSC
645 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
647 const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
648 const VkBufferMemoryBarrier srcCopyBufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
649 const VkImageMemoryBarrier srcCopyImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
650 const VkImageMemoryBarrier srcCopyImageBarrierPost = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
652 const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
654 const VkExtent2D framebufferSize (makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
655 const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize.width, framebufferSize.height, SINGLE_LAYER));
657 DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
659 // Upload vertex data
660 deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
661 flushAlloc(vk, device, vertexBufferAlloc);
663 // Upload source image data
664 const Allocation& alloc = srcImageBuffer->getAllocation();
665 deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
666 flushAlloc(vk, device, alloc);
668 beginCommandBuffer(vk, *cmdBuffer);
669 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
671 //Copy buffer to image
672 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrier, 1u, &srcCopyImageBarrier);
673 vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1u, &srcCopyRegion);
674 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &srcCopyImageBarrierPost);
676 // Make source image readable
677 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstCopyImageBarrier);
679 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
681 DescriptorSetUpdateBuilder()
682 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage)
683 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImage)
686 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
687 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
688 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
690 endRenderPass(vk, *cmdBuffer);
692 const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
693 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
694 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
695 dstImage->get(), subresourceRange);
697 const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
698 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
699 dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
701 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier);
702 vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
703 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, ©Barrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
705 endCommandBuffer(vk, *cmdBuffer);
707 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
709 const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
710 invalidateAlloc(vk, device, dstImageBufferAlloc);
711 dstData.resize((size_t)dstImageSizeInBytes);
712 deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
714 outputImage = dstImage;
717 class ImageTranscodingCase : public TestCase
720 ImageTranscodingCase (TestContext& testCtx,
721 const std::string& name,
722 const std::string& desc,
723 const TestParameters& parameters);
724 void initPrograms (SourceCollections& programCollection) const;
725 TestInstance* createInstance (Context& context) const;
726 virtual void checkSupport (Context& context) const;
727 bool isFormatUsageFlagSupported (Context& context,
728 const VkFormat format,
729 VkImageUsageFlags formatUsageFlags) const;
732 const TestParameters m_parameters;
735 ImageTranscodingCase::ImageTranscodingCase (TestContext& testCtx, const std::string& name, const std::string& desc, const TestParameters& parameters)
736 : TestCase (testCtx, name, desc)
737 , m_parameters (parameters)
741 void ImageTranscodingCase::initPrograms (vk::SourceCollections& programCollection) const
743 DE_ASSERT(m_parameters.size.x() > 0);
744 DE_ASSERT(m_parameters.size.y() > 0);
746 ImageType imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
750 std::ostringstream src;
751 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
752 << "layout(location = 0) in vec4 v_in_position;\n"
754 << "void main (void)\n"
756 << " gl_Position = v_in_position;\n"
759 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
764 switch(m_parameters.operation)
766 case OPERATION_ATTACHMENT_READ:
767 case OPERATION_ATTACHMENT_WRITE:
769 std::ostringstream src;
771 const std::string dstTypeStr = getGlslAttachmentType(m_parameters.featuredFormat);
772 const std::string srcTypeStr = getGlslInputAttachmentType(m_parameters.featuredFormat);
774 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
775 << "precision highp int;\n"
776 << "precision highp float;\n"
778 << "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
779 << "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr << " inputImage1;\n"
781 << "void main (void)\n"
783 << " o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
786 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
791 case OPERATION_TEXTURE_READ:
792 case OPERATION_TEXTURE_WRITE:
794 std::ostringstream src;
796 const std::string srcSamplerTypeStr = getGlslSamplerType(mapVkFormat(m_parameters.featuredFormat), mapImageViewType(imageTypeForFS));
797 const std::string dstImageTypeStr = getShaderImageType(mapVkFormat(m_parameters.featuredFormat), imageTypeForFS);
798 const std::string dstFormatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_parameters.featuredFormat));
800 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
801 << "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
802 << "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr << " u_imageOut;\n"
804 << "void main (void)\n"
806 << " const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
807 << " const vec2 pixels_resolution = vec2(textureSize(u_imageIn, 0));\n"
808 << " const vec2 in_pos = vec2(gl_FragCoord.xy) / vec2(pixels_resolution);\n"
809 << " imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
812 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
823 bool ImageTranscodingCase::isFormatUsageFlagSupported (Context& context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const
825 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
826 const InstanceInterface& vk = context.getInstanceInterface();
827 VkImageFormatProperties imageFormatProperties;
828 const VkResult queryResult = vk.getPhysicalDeviceImageFormatProperties(
831 mapImageType(m_parameters.imageType),
832 VK_IMAGE_TILING_OPTIMAL,
834 VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
835 &imageFormatProperties);
837 return (queryResult == VK_SUCCESS);
840 void ImageTranscodingCase::checkSupport (Context& context) const
842 context.requireDeviceFunctionality("VK_KHR_maintenance2");
844 if ((m_parameters.operation == OPERATION_TEXTURE_READ || m_parameters.operation == OPERATION_TEXTURE_WRITE) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
845 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
847 if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsageFeature))
848 TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
850 if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
851 TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
854 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
856 VkFormat featurelessFormat = VK_FORMAT_UNDEFINED;
857 bool differenceFound = false;
859 DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
861 for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
863 featurelessFormat = m_parameters.compatibleFormats[i];
865 if (isSupportedByFramework(featurelessFormat)
866 && !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
867 && isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
870 differenceFound = true;
878 #ifndef CTS_USES_VULKANSC
879 if ((context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
880 !context.getPortabilitySubsetFeatures().imageViewFormatReinterpretation))
882 tcu::TextureFormat textureImageFormat = vk::mapVkFormat(m_parameters.featuredFormat);
883 tcu::TextureFormat textureViewFormat = vk::mapVkFormat(featurelessFormat);
885 if (tcu::getTextureFormatBitDepth(textureImageFormat) != tcu::getTextureFormatBitDepth(textureViewFormat))
886 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Format must not contain a different number of bits in each component, than the format of the VkImage");
888 #endif // CTS_USES_VULKANSC
890 TestParameters calculatedParameters =
892 m_parameters.operation, // Operation operation
893 m_parameters.size, // UVec3 size
894 m_parameters.imageType, // ImageType imageType
895 m_parameters.testedImageUsageFeature, // VkImageUsageFlagBits testedImageUsageFeature
896 m_parameters.featuredFormat, // VkFormat featuredFormat
897 featurelessFormat, // VkFormat featurelessFormat
898 m_parameters.testedImageUsage, // VkImageUsageFlags testedImageUsage
899 m_parameters.pairedImageUsage, // VkImageUsageFlags pairedImageUsage
900 DE_NULL, // const VkFormat* compatibleFormats
903 switch (m_parameters.operation)
905 case OPERATION_ATTACHMENT_READ:
906 case OPERATION_ATTACHMENT_WRITE:
907 return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
909 case OPERATION_TEXTURE_READ:
910 case OPERATION_TEXTURE_WRITE:
911 return new GraphicsTextureTestInstance(context, calculatedParameters);
914 TCU_THROW(InternalError, "Impossible");
918 TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
923 static const VkFormat compatibleFormatList8Bit[] =
925 VK_FORMAT_R4G4_UNORM_PACK8,
928 VK_FORMAT_R8_USCALED,
929 VK_FORMAT_R8_SSCALED,
937 static const VkFormat compatibleFormatList16Bit[] =
939 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
940 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
941 VK_FORMAT_R5G6B5_UNORM_PACK16,
942 VK_FORMAT_B5G6R5_UNORM_PACK16,
943 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
944 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
945 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
946 VK_FORMAT_R8G8_UNORM,
947 VK_FORMAT_R8G8_SNORM,
948 VK_FORMAT_R8G8_USCALED,
949 VK_FORMAT_R8G8_SSCALED,
955 VK_FORMAT_R16_USCALED,
956 VK_FORMAT_R16_SSCALED,
959 VK_FORMAT_R16_SFLOAT,
960 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
961 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
966 static const VkFormat compatibleFormatList24Bit[] =
968 VK_FORMAT_R8G8B8_UNORM,
969 VK_FORMAT_R8G8B8_SNORM,
970 VK_FORMAT_R8G8B8_USCALED,
971 VK_FORMAT_R8G8B8_SSCALED,
972 VK_FORMAT_R8G8B8_UINT,
973 VK_FORMAT_R8G8B8_SINT,
974 VK_FORMAT_R8G8B8_SRGB,
975 VK_FORMAT_B8G8R8_UNORM,
976 VK_FORMAT_B8G8R8_SNORM,
977 VK_FORMAT_B8G8R8_USCALED,
978 VK_FORMAT_B8G8R8_SSCALED,
979 VK_FORMAT_B8G8R8_UINT,
980 VK_FORMAT_B8G8R8_SINT,
981 VK_FORMAT_B8G8R8_SRGB,
986 static const VkFormat compatibleFormatList32Bit[] =
988 VK_FORMAT_R8G8B8A8_UNORM,
989 VK_FORMAT_R8G8B8A8_SNORM,
990 VK_FORMAT_R8G8B8A8_USCALED,
991 VK_FORMAT_R8G8B8A8_SSCALED,
992 VK_FORMAT_R8G8B8A8_UINT,
993 VK_FORMAT_R8G8B8A8_SINT,
994 VK_FORMAT_R8G8B8A8_SRGB,
995 VK_FORMAT_B8G8R8A8_UNORM,
996 VK_FORMAT_B8G8R8A8_SNORM,
997 VK_FORMAT_B8G8R8A8_USCALED,
998 VK_FORMAT_B8G8R8A8_SSCALED,
999 VK_FORMAT_B8G8R8A8_UINT,
1000 VK_FORMAT_B8G8R8A8_SINT,
1001 VK_FORMAT_B8G8R8A8_SRGB,
1002 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1003 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1004 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1005 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1006 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1007 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1008 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1009 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1010 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1011 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1012 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1013 VK_FORMAT_A2R10G10B10_UINT_PACK32,
1014 VK_FORMAT_A2R10G10B10_SINT_PACK32,
1015 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1016 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1017 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1018 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1019 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1020 VK_FORMAT_A2B10G10R10_SINT_PACK32,
1021 VK_FORMAT_R16G16_UNORM,
1022 VK_FORMAT_R16G16_SNORM,
1023 VK_FORMAT_R16G16_USCALED,
1024 VK_FORMAT_R16G16_SSCALED,
1025 VK_FORMAT_R16G16_UINT,
1026 VK_FORMAT_R16G16_SINT,
1027 VK_FORMAT_R16G16_SFLOAT,
1030 VK_FORMAT_R32_SFLOAT,
1035 static const VkFormat compatibleFormatList48Bit[] =
1037 VK_FORMAT_R16G16B16_UNORM,
1038 VK_FORMAT_R16G16B16_SNORM,
1039 VK_FORMAT_R16G16B16_USCALED,
1040 VK_FORMAT_R16G16B16_SSCALED,
1041 VK_FORMAT_R16G16B16_UINT,
1042 VK_FORMAT_R16G16B16_SINT,
1043 VK_FORMAT_R16G16B16_SFLOAT,
1048 static const VkFormat compatibleFormatList64Bit[] =
1050 VK_FORMAT_R16G16B16A16_UNORM,
1051 VK_FORMAT_R16G16B16A16_SNORM,
1052 VK_FORMAT_R16G16B16A16_USCALED,
1053 VK_FORMAT_R16G16B16A16_SSCALED,
1054 VK_FORMAT_R16G16B16A16_UINT,
1055 VK_FORMAT_R16G16B16A16_SINT,
1056 VK_FORMAT_R16G16B16A16_SFLOAT,
1057 VK_FORMAT_R32G32_UINT,
1058 VK_FORMAT_R32G32_SINT,
1059 VK_FORMAT_R32G32_SFLOAT,
1062 VK_FORMAT_R64_SFLOAT,
1067 static const VkFormat compatibleFormatList96Bit[] =
1069 VK_FORMAT_R32G32B32_UINT,
1070 VK_FORMAT_R32G32B32_SINT,
1071 VK_FORMAT_R32G32B32_SFLOAT,
1076 static const VkFormat compatibleFormatList128Bit[] =
1078 VK_FORMAT_R32G32B32A32_UINT,
1079 VK_FORMAT_R32G32B32A32_SINT,
1080 VK_FORMAT_R32G32B32A32_SFLOAT,
1081 VK_FORMAT_R64G64_UINT,
1082 VK_FORMAT_R64G64_SINT,
1083 VK_FORMAT_R64G64_SFLOAT,
1088 const VkFormat compatibleFormatList192Bit[] =
1090 VK_FORMAT_R64G64B64_UINT,
1091 VK_FORMAT_R64G64B64_SINT,
1092 VK_FORMAT_R64G64B64_SFLOAT,
1097 static const VkFormat compatibleFormatList256Bit[] =
1099 VK_FORMAT_R64G64B64A64_UINT,
1100 VK_FORMAT_R64G64B64A64_SINT,
1101 VK_FORMAT_R64G64B64A64_SFLOAT,
1106 static const VkFormat* compatibleFormatsList[] =
1108 compatibleFormatList8Bit,
1109 compatibleFormatList16Bit,
1110 compatibleFormatList24Bit,
1111 compatibleFormatList32Bit,
1112 compatibleFormatList48Bit,
1113 compatibleFormatList64Bit,
1114 compatibleFormatList96Bit,
1115 compatibleFormatList128Bit,
1116 compatibleFormatList192Bit,
1117 compatibleFormatList256Bit,
1120 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1122 const std::string operationName[OPERATION_LAST] =
1129 const VkImageUsageFlagBits testedImageUsageFlags[OPERATION_LAST] =
1131 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1132 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1133 VK_IMAGE_USAGE_SAMPLED_BIT,
1134 VK_IMAGE_USAGE_STORAGE_BIT,
1136 const VkImageUsageFlagBits pairedImageUsageFlags[OPERATION_LAST] =
1138 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1139 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1140 VK_IMAGE_USAGE_STORAGE_BIT,
1141 VK_IMAGE_USAGE_SAMPLED_BIT,
1143 VkImageUsageFlags baseFlagsAddOn = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1145 MovePtr<tcu::TestCaseGroup> imageTranscodingTests (new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1147 for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1149 MovePtr<tcu::TestCaseGroup> imageOperationGroup (new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1151 for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1153 for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1155 const VkFormat featuredFormat = compatibleFormatsList[groupNdx][featuredFormatNdx];
1156 const VkFormat featurelessFormat = VK_FORMAT_UNDEFINED; // Lookup process is in createInstance()
1158 if (!isSupportedByFramework(featuredFormat))
1161 // Cannot handle SRGB in shader layout classifier
1162 if (isSrgbFormat(featuredFormat))
1165 // Cannot handle packed in shader layout classifier
1166 if (isPackedType(featuredFormat))
1169 // Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1170 if (isComponentSwizzled(featuredFormat))
1173 // Cannot handle three-component images in shader layout classifier
1174 if (getNumUsedChannels(featuredFormat) == 3)
1177 const std::string testName = getFormatShortString(featuredFormat);
1178 const TestParameters parameters =
1180 static_cast<Operation>(operationNdx), // Operation operation
1181 UVec3(16u, 16u, 1u), // UVec3 size
1182 IMAGE_TYPE_2D, // ImageType imageType
1183 testedImageUsageFlags[operationNdx], // VkImageUsageFlagBits testedImageUsageFeature
1184 featuredFormat, // VkFormat featuredFormat
1185 featurelessFormat, // VkFormat featurelessFormat
1186 baseFlagsAddOn | testedImageUsageFlags[operationNdx], // VkImageUsageFlags testedImageUsage
1187 baseFlagsAddOn | pairedImageUsageFlags[operationNdx], // VkImageUsageFlags pairedImageUsage
1188 compatibleFormatsList[groupNdx] // const VkFormat* compatibleFormats
1191 imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1195 imageTranscodingTests->addChild(imageOperationGroup.release());
1198 return imageTranscodingTests.release();