1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file vktImageTranscodingSupportTests.cpp
21 * \brief Transcoding support tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktImageTranscodingSupportTests.hpp"
25
26 #include "deUniquePtr.hpp"
27 #include "deStringUtil.hpp"
28 #include "deSharedPtr.hpp"
29 #include "deRandom.hpp"
30
31 #include "vktTestCaseUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vktImageTestsUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkRef.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"
44
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"
56
57 #include <vector>
58 #include <iomanip>
59
60 using namespace vk;
61 namespace vkt
62 {
63 namespace image
64 {
65 namespace
66 {
67 using std::string;
68 using std::vector;
69 using tcu::TestContext;
70 using tcu::TestStatus;
71 using tcu::UVec3;
72 using tcu::IVec3;
73 using tcu::CompressedTexFormat;
74 using tcu::CompressedTexture;
75 using tcu::Resource;
76 using tcu::Archive;
77 using tcu::ConstPixelBufferAccess;
78 using de::MovePtr;
79 using de::SharedPtr;
80 using de::Random;
81
82 enum Operation
83 {
84 OPERATION_ATTACHMENT_READ,
85 OPERATION_ATTACHMENT_WRITE,
86 OPERATION_TEXTURE_READ,
87 OPERATION_TEXTURE_WRITE,
88 OPERATION_LAST
89 };
90
91 struct TestParameters
92 {
93 Operation operation;
94 UVec3 size;
95 ImageType imageType;
96 VkImageUsageFlagBits testedImageUsageFeature;
97 VkFormat featuredFormat;
98 VkFormat featurelessFormat;
99 VkImageUsageFlags testedImageUsage;
100 VkImageUsageFlags pairedImageUsage;
101 const VkFormat* compatibleFormats;
102 };
103
104 const deUint32 SINGLE_LEVEL = 1u;
105 const deUint32 SINGLE_LAYER = 1u;
106
107 class BasicTranscodingTestInstance : public TestInstance
108 {
109 public:
110 BasicTranscodingTestInstance (Context& context,
111 const TestParameters& parameters);
112 virtual TestStatus iterate (void) = 0;
113 protected:
114 void generateData (deUint8* toFill,
115 size_t size,
116 const VkFormat format = VK_FORMAT_UNDEFINED);
117 const TestParameters m_parameters;
118 };
119
BasicTranscodingTestInstance(Context & context,const TestParameters & parameters)120 BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters)
121 : TestInstance (context)
122 , m_parameters (parameters)
123 {
124 }
125
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.
130 template <class T>
fixFloatIfNeeded(deUint8 * ptr_)131 void fixFloatIfNeeded(deUint8* ptr_)
132 {
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());
138 }
139
generateData(deUint8 * toFill,size_t size,const VkFormat format)140 void BasicTranscodingTestInstance::generateData (deUint8* toFill, size_t size, const VkFormat format)
141 {
142 const deUint8 pattern[] =
143 {
144 // 64-bit values
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)
165 // 32-bit values
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,
178 };
179
180 deUint8* start = toFill;
181 size_t sizeToRnd = size;
182
183 // Pattern part
184 if (size >= 2 * sizeof(pattern))
185 {
186 // Rotated pattern
187 for (size_t i = 0; i < sizeof(pattern); i++)
188 start[sizeof(pattern) - i - 1] = pattern[i];
189
190 start += sizeof(pattern);
191 sizeToRnd -= sizeof(pattern);
192
193 // Direct pattern
194 deMemcpy(start, pattern, sizeof(pattern));
195
196 start += sizeof(pattern);
197 sizeToRnd -= sizeof(pattern);
198 }
199
200 // Random part
201 {
202 DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0);
203
204 deUint32* start32 = reinterpret_cast<deUint32*>(start);
205 size_t sizeToRnd32 = sizeToRnd / sizeof(deUint32);
206 Random rnd (static_cast<deUint32>(format));
207
208 for (size_t i = 0; i < sizeToRnd32; i++)
209 start32[i] = rnd.getUint32();
210 }
211
212 {
213 // Remove certain values that may not be preserved based on the uncompressed view format
214 if (isSnormFormat(m_parameters.featuredFormat))
215 {
216 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
217
218 if (textureFormat.type == tcu::TextureFormat::SNORM_INT8)
219 {
220 for (size_t i = 0; i < size; i++)
221 {
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)
225 toFill[i] = 0x81;
226 }
227 }
228 else
229 {
230 for (size_t i = 0; i < size; i += 2)
231 {
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)
235 toFill[i+1] = 0x81;
236 }
237 }
238 }
239 else if (isFloatFormat(m_parameters.featuredFormat))
240 {
241 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
242
243 if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
244 {
245 for (size_t i = 0; i < size; i += 2)
246 fixFloatIfNeeded<tcu::Float16>(toFill + i);
247 }
248 else if (textureFormat.type == tcu::TextureFormat::FLOAT)
249 {
250 for (size_t i = 0; i < size; i += 4)
251 fixFloatIfNeeded<tcu::Float16>(toFill + i);
252
253 for (size_t i = 0; i < size; i += 4)
254 fixFloatIfNeeded<tcu::Float32>(toFill + i);
255 }
256 }
257 }
258 }
259
260 class GraphicsAttachmentsTestInstance : public BasicTranscodingTestInstance
261 {
262 public:
263 GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters);
264 virtual TestStatus iterate (void);
265
266 protected:
267 VkImageCreateInfo makeCreateImageInfo (const VkFormat format,
268 const ImageType type,
269 const UVec3& size,
270 const VkImageUsageFlags usageFlags,
271 const bool extendedImageCreateFlag);
272 VkImageViewUsageCreateInfo makeImageViewUsageCreateInfo (VkImageUsageFlags imageUsageFlags);
273 VkDeviceSize getUncompressedImageData (const VkFormat format,
274 const UVec3& size,
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);
278 };
279
GraphicsAttachmentsTestInstance(Context & context,const TestParameters & parameters)280 GraphicsAttachmentsTestInstance::GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters)
281 : BasicTranscodingTestInstance(context, parameters)
282 {
283 }
284
iterate(void)285 TestStatus GraphicsAttachmentsTestInstance::iterate (void)
286 {
287 std::vector<deUint8> srcData;
288 std::vector<deUint8> dstData;
289 de::MovePtr<Image> outputImage;
290
291 transcode(srcData, dstData, outputImage);
292
293 DE_ASSERT(srcData.size() > 0 && srcData.size() == dstData.size());
294
295 if (!compareAndLog(&srcData[0], &dstData[0], srcData.size()))
296 return TestStatus::fail("Output differs from input");
297
298 return TestStatus::pass("Pass");
299 }
300
transcode(std::vector<deUint8> & srcData,std::vector<deUint8> & dstData,de::MovePtr<Image> & outputImage)301 void GraphicsAttachmentsTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
302 {
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();
308
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);
312
313 const VkFormat srcFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.featurelessFormat :
314 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featuredFormat :
315 VK_FORMAT_UNDEFINED;
316 const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? true :
317 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? false :
318 false;
319 const VkImageUsageFlags srcImageUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.testedImageUsage :
320 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.pairedImageUsage :
321 0;
322 const VkImageViewUsageCreateInfo* srcImageViewUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? &imageViewUsage :
323 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? imageViewUsageNull :
324 imageViewUsageNull;
325 const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
326
327 const VkFormat dstFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.featuredFormat :
328 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featurelessFormat :
329 VK_FORMAT_UNDEFINED;
330 const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? false :
331 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? true :
332 false;
333 const VkImageUsageFlags dstImageUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.pairedImageUsage :
334 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.testedImageUsage :
335 0;
336 const VkImageViewUsageCreateInfo* dstImageViewUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? imageViewUsageNull :
337 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? &imageViewUsage :
338 imageViewUsageNull;
339 const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
340
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 };
347
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));
350
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));
354
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));
358
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));
361
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));
364
365 const Unique<VkRenderPass> renderPass (vkt::image::makeRenderPass(vk, device, m_parameters.featuredFormat, m_parameters.featuredFormat));
366
367 const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
368 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
369 .build(vk, device));
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));
375
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));
381 #else
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));
385
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]);
391
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));
394
395 DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
396
397 // Upload vertex data
398 deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
399 flushAlloc(vk, device, vertexBufferAlloc);
400
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);
405
406 beginCommandBuffer(vk, *cmdBuffer);
407 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
408
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);
413
414 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
415
416 DescriptorSetUpdateBuilder()
417 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo)
418 .update(vk, device);
419
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);
423
424 endRenderPass(vk, *cmdBuffer);
425
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);
430
431 const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
432 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
433 dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
434
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);
438
439 endCommandBuffer(vk, *cmdBuffer);
440
441 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
442
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);
447
448 outputImage = dstImage;
449 }
450
451
makeCreateImageInfo(const VkFormat format,const ImageType type,const UVec3 & size,const VkImageUsageFlags usageFlags,const bool extendedImageCreateFlag)452 VkImageCreateInfo GraphicsAttachmentsTestInstance::makeCreateImageInfo (const VkFormat format,
453 const ImageType type,
454 const UVec3& size,
455 const VkImageUsageFlags usageFlags,
456 const bool extendedImageCreateFlag)
457 {
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;
462
463 const VkImageCreateInfo createImageInfo =
464 {
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;
480 };
481
482 return createImageInfo;
483 }
484
makeImageViewUsageCreateInfo(VkImageUsageFlags imageUsageFlags)485 VkImageViewUsageCreateInfo GraphicsAttachmentsTestInstance::makeImageViewUsageCreateInfo (VkImageUsageFlags imageUsageFlags)
486 {
487 VkImageViewUsageCreateInfo imageViewUsageCreateInfo =
488 {
489 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO, //VkStructureType sType;
490 DE_NULL, //const void* pNext;
491 imageUsageFlags, //VkImageUsageFlags usage;
492 };
493
494 return imageViewUsageCreateInfo;
495 }
496
getUncompressedImageData(const VkFormat format,const UVec3 & size,std::vector<deUint8> & data)497 VkDeviceSize GraphicsAttachmentsTestInstance::getUncompressedImageData (const VkFormat format, const UVec3& size, std::vector<deUint8>& data)
498 {
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);
501
502 data.resize((size_t)sizeBytes);
503 generateData(&data[0], data.size(), format);
504
505 return sizeBytes;
506 }
507
compareAndLog(const void * reference,const void * result,size_t size)508 bool GraphicsAttachmentsTestInstance::compareAndLog (const void* reference, const void* result, size_t size)
509 {
510 tcu::TestLog& log = m_context.getTestContext().getLog();
511
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);
515 bool equal = true;
516
517 DE_ASSERT(size % sizeof(deUint64) == 0);
518
519 for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(sizew); ndx++)
520 {
521 if (ref64[ndx] != res64[ndx])
522 {
523 std::stringstream str;
524
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];
528
529 log.writeMessage(str.str().c_str());
530
531 equal = false;
532
533 break;
534 }
535 }
536
537 return equal;
538 }
539
540
541 class GraphicsTextureTestInstance : public GraphicsAttachmentsTestInstance
542 {
543 public:
544 GraphicsTextureTestInstance (Context& context, const TestParameters& parameters);
545
546 protected:
547 void transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage);
548 };
549
GraphicsTextureTestInstance(Context & context,const TestParameters & parameters)550 GraphicsTextureTestInstance::GraphicsTextureTestInstance (Context& context, const TestParameters& parameters)
551 : GraphicsAttachmentsTestInstance(context, parameters)
552 {
553 }
554
transcode(std::vector<deUint8> & srcData,std::vector<deUint8> & dstData,de::MovePtr<Image> & outputImage)555 void GraphicsTextureTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
556 {
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();
562
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);
566
567 const VkFormat srcFormat = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.featurelessFormat :
568 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featuredFormat :
569 VK_FORMAT_UNDEFINED;
570 const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ) ? true :
571 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? false :
572 false;
573 const VkImageUsageFlags srcImageUsageFlags = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.testedImageUsage :
574 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.pairedImageUsage :
575 0;
576 const VkImageViewUsageCreateInfo* srcImageViewUsage = (m_parameters.operation == OPERATION_TEXTURE_READ) ? &imageViewUsage :
577 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? imageViewUsageNull :
578 imageViewUsageNull;
579 const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
580
581 const VkFormat dstFormat = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.featuredFormat :
582 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featurelessFormat :
583 VK_FORMAT_UNDEFINED;
584 const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ) ? false :
585 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? true :
586 false;
587 const VkImageUsageFlags dstImageUsageFlags = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.pairedImageUsage :
588 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.testedImageUsage :
589 0;
590 const VkImageViewUsageCreateInfo* dstImageViewUsage = (m_parameters.operation == OPERATION_TEXTURE_READ) ? imageViewUsageNull :
591 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? &imageViewUsage :
592 imageViewUsageNull;
593 const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
594
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 };
601
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));
604
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));
608
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);
613
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));
616
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));
619
620 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device));
621
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)
625 .build(vk, device));
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));
635
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));
641 #else
642 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VkCommandPoolCreateFlags(0u), queueFamilyIndex));
643 #endif // CTS_USES_VULKANSC
644
645 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
646
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);
651
652 const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
653
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));
656
657 DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
658
659 // Upload vertex data
660 deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
661 flushAlloc(vk, device, vertexBufferAlloc);
662
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);
667
668 beginCommandBuffer(vk, *cmdBuffer);
669 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
670
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);
675
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);
678
679 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
680 {
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)
684 .update(vk, device);
685
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);
689 }
690 endRenderPass(vk, *cmdBuffer);
691
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);
696
697 const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
698 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
699 dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
700
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);
704
705 endCommandBuffer(vk, *cmdBuffer);
706
707 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
708
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);
713
714 outputImage = dstImage;
715 }
716
717 class ImageTranscodingCase : public TestCase
718 {
719 public:
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;
730
731 protected:
732 const TestParameters m_parameters;
733 };
734
ImageTranscodingCase(TestContext & testCtx,const std::string & name,const std::string & desc,const TestParameters & 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)
738 {
739 }
740
initPrograms(vk::SourceCollections & programCollection) const741 void ImageTranscodingCase::initPrograms (vk::SourceCollections& programCollection) const
742 {
743 DE_ASSERT(m_parameters.size.x() > 0);
744 DE_ASSERT(m_parameters.size.y() > 0);
745
746 ImageType imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
747
748 // Vertex shader
749 {
750 std::ostringstream src;
751 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
752 << "layout(location = 0) in vec4 v_in_position;\n"
753 << "\n"
754 << "void main (void)\n"
755 << "{\n"
756 << " gl_Position = v_in_position;\n"
757 << "}\n";
758
759 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
760 }
761
762 // Fragment shader
763 {
764 switch(m_parameters.operation)
765 {
766 case OPERATION_ATTACHMENT_READ:
767 case OPERATION_ATTACHMENT_WRITE:
768 {
769 std::ostringstream src;
770
771 const std::string dstTypeStr = getGlslAttachmentType(m_parameters.featuredFormat);
772 const std::string srcTypeStr = getGlslInputAttachmentType(m_parameters.featuredFormat);
773
774 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
775 << "precision highp int;\n"
776 << "precision highp float;\n"
777 << "\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"
780 << "\n"
781 << "void main (void)\n"
782 << "{\n"
783 << " o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
784 << "}\n";
785
786 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
787
788 break;
789 }
790
791 case OPERATION_TEXTURE_READ:
792 case OPERATION_TEXTURE_WRITE:
793 {
794 std::ostringstream src;
795
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));
799
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"
803 << "\n"
804 << "void main (void)\n"
805 << "{\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"
810 << "}\n";
811
812 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
813
814 break;
815 }
816
817 default:
818 DE_ASSERT(false);
819 }
820 }
821 }
822
isFormatUsageFlagSupported(Context & context,const VkFormat format,VkImageUsageFlags formatUsageFlags) const823 bool ImageTranscodingCase::isFormatUsageFlagSupported (Context& context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const
824 {
825 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
826 const InstanceInterface& vk = context.getInstanceInterface();
827 VkImageFormatProperties imageFormatProperties;
828 const VkResult queryResult = vk.getPhysicalDeviceImageFormatProperties(
829 physicalDevice,
830 format,
831 mapImageType(m_parameters.imageType),
832 VK_IMAGE_TILING_OPTIMAL,
833 formatUsageFlags,
834 VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
835 &imageFormatProperties);
836
837 return (queryResult == VK_SUCCESS);
838 }
839
checkSupport(Context & context) const840 void ImageTranscodingCase::checkSupport (Context& context) const
841 {
842 context.requireDeviceFunctionality("VK_KHR_maintenance2");
843
844 if ((m_parameters.operation == OPERATION_TEXTURE_READ || m_parameters.operation == OPERATION_TEXTURE_WRITE) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
845 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
846
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");
849
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");
852 }
853
createInstance(Context & context) const854 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
855 {
856 VkFormat featurelessFormat = VK_FORMAT_UNDEFINED;
857 bool differenceFound = false;
858
859 DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
860
861 for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
862 {
863 featurelessFormat = m_parameters.compatibleFormats[i];
864
865 if (isSupportedByFramework(featurelessFormat)
866 && !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
867 && isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
868 )
869 {
870 differenceFound = true;
871
872 break;
873 }
874 }
875
876 if (differenceFound)
877 {
878 #ifndef CTS_USES_VULKANSC
879 if ((context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
880 !context.getPortabilitySubsetFeatures().imageViewFormatReinterpretation))
881 {
882 tcu::TextureFormat textureImageFormat = vk::mapVkFormat(m_parameters.featuredFormat);
883 tcu::TextureFormat textureViewFormat = vk::mapVkFormat(featurelessFormat);
884
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");
887 }
888 #endif // CTS_USES_VULKANSC
889
890 TestParameters calculatedParameters =
891 {
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
901 };
902
903 switch (m_parameters.operation)
904 {
905 case OPERATION_ATTACHMENT_READ:
906 case OPERATION_ATTACHMENT_WRITE:
907 return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
908
909 case OPERATION_TEXTURE_READ:
910 case OPERATION_TEXTURE_WRITE:
911 return new GraphicsTextureTestInstance(context, calculatedParameters);
912
913 default:
914 TCU_THROW(InternalError, "Impossible");
915 }
916 }
917 else
918 TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
919 }
920
921 } // anonymous ns
922
923 static const VkFormat compatibleFormatList8Bit[] =
924 {
925 VK_FORMAT_R4G4_UNORM_PACK8,
926 VK_FORMAT_R8_UNORM,
927 VK_FORMAT_R8_SNORM,
928 VK_FORMAT_R8_USCALED,
929 VK_FORMAT_R8_SSCALED,
930 VK_FORMAT_R8_UINT,
931 VK_FORMAT_R8_SINT,
932 VK_FORMAT_R8_SRGB,
933
934 VK_FORMAT_UNDEFINED
935 };
936
937 static const VkFormat compatibleFormatList16Bit[] =
938 {
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,
950 VK_FORMAT_R8G8_UINT,
951 VK_FORMAT_R8G8_SINT,
952 VK_FORMAT_R8G8_SRGB,
953 VK_FORMAT_R16_UNORM,
954 VK_FORMAT_R16_SNORM,
955 VK_FORMAT_R16_USCALED,
956 VK_FORMAT_R16_SSCALED,
957 VK_FORMAT_R16_UINT,
958 VK_FORMAT_R16_SINT,
959 VK_FORMAT_R16_SFLOAT,
960 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
961 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
962
963 VK_FORMAT_UNDEFINED
964 };
965
966 static const VkFormat compatibleFormatList24Bit[] =
967 {
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,
982
983 VK_FORMAT_UNDEFINED
984 };
985
986 static const VkFormat compatibleFormatList32Bit[] =
987 {
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,
1028 VK_FORMAT_R32_UINT,
1029 VK_FORMAT_R32_SINT,
1030 VK_FORMAT_R32_SFLOAT,
1031
1032 VK_FORMAT_UNDEFINED
1033 };
1034
1035 static const VkFormat compatibleFormatList48Bit[] =
1036 {
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,
1044
1045 VK_FORMAT_UNDEFINED
1046 };
1047
1048 static const VkFormat compatibleFormatList64Bit[] =
1049 {
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,
1060 VK_FORMAT_R64_UINT,
1061 VK_FORMAT_R64_SINT,
1062 VK_FORMAT_R64_SFLOAT,
1063
1064 VK_FORMAT_UNDEFINED
1065 };
1066
1067 static const VkFormat compatibleFormatList96Bit[] =
1068 {
1069 VK_FORMAT_R32G32B32_UINT,
1070 VK_FORMAT_R32G32B32_SINT,
1071 VK_FORMAT_R32G32B32_SFLOAT,
1072
1073 VK_FORMAT_UNDEFINED
1074 };
1075
1076 static const VkFormat compatibleFormatList128Bit[] =
1077 {
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,
1084
1085 VK_FORMAT_UNDEFINED
1086 };
1087
1088 const VkFormat compatibleFormatList192Bit[] =
1089 {
1090 VK_FORMAT_R64G64B64_UINT,
1091 VK_FORMAT_R64G64B64_SINT,
1092 VK_FORMAT_R64G64B64_SFLOAT,
1093
1094 VK_FORMAT_UNDEFINED
1095 };
1096
1097 static const VkFormat compatibleFormatList256Bit[] =
1098 {
1099 VK_FORMAT_R64G64B64A64_UINT,
1100 VK_FORMAT_R64G64B64A64_SINT,
1101 VK_FORMAT_R64G64B64A64_SFLOAT,
1102
1103 VK_FORMAT_UNDEFINED
1104 };
1105
1106 static const VkFormat* compatibleFormatsList[] =
1107 {
1108 compatibleFormatList8Bit,
1109 compatibleFormatList16Bit,
1110 compatibleFormatList24Bit,
1111 compatibleFormatList32Bit,
1112 compatibleFormatList48Bit,
1113 compatibleFormatList64Bit,
1114 compatibleFormatList96Bit,
1115 compatibleFormatList128Bit,
1116 compatibleFormatList192Bit,
1117 compatibleFormatList256Bit,
1118 };
1119
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1120 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1121 {
1122 const std::string operationName[OPERATION_LAST] =
1123 {
1124 "attachment_read",
1125 "attachment_write",
1126 "texture_read",
1127 "texture_write",
1128 };
1129 const VkImageUsageFlagBits testedImageUsageFlags[OPERATION_LAST] =
1130 {
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,
1135 };
1136 const VkImageUsageFlagBits pairedImageUsageFlags[OPERATION_LAST] =
1137 {
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,
1142 };
1143 VkImageUsageFlags baseFlagsAddOn = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1144
1145 MovePtr<tcu::TestCaseGroup> imageTranscodingTests (new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1146
1147 for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1148 {
1149 MovePtr<tcu::TestCaseGroup> imageOperationGroup (new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1150
1151 for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1152 {
1153 for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1154 {
1155 const VkFormat featuredFormat = compatibleFormatsList[groupNdx][featuredFormatNdx];
1156 const VkFormat featurelessFormat = VK_FORMAT_UNDEFINED; // Lookup process is in createInstance()
1157
1158 if (!isSupportedByFramework(featuredFormat))
1159 continue;
1160
1161 // Cannot handle SRGB in shader layout classifier
1162 if (isSrgbFormat(featuredFormat))
1163 continue;
1164
1165 // Cannot handle packed in shader layout classifier
1166 if (isPackedType(featuredFormat))
1167 continue;
1168
1169 // Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1170 if (isComponentSwizzled(featuredFormat))
1171 continue;
1172
1173 // Cannot handle three-component images in shader layout classifier
1174 if (getNumUsedChannels(featuredFormat) == 3)
1175 continue;
1176
1177 const std::string testName = getFormatShortString(featuredFormat);
1178 const TestParameters parameters =
1179 {
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
1189 };
1190
1191 imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1192 }
1193 }
1194
1195 imageTranscodingTests->addChild(imageOperationGroup.release());
1196 }
1197
1198 return imageTranscodingTests.release();
1199 }
1200
1201 } // image
1202 } // vkt
1203