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
44 #include "tcuTextureUtil.hpp"
45 #include "tcuTexture.hpp"
46 #include "tcuCompressedTexture.hpp"
47 #include "tcuVectorType.hpp"
48 #include "tcuResource.hpp"
49 #include "tcuImageIO.hpp"
50 #include "tcuImageCompare.hpp"
51 #include "tcuTestLog.hpp"
52 #include "tcuRGBA.hpp"
53 #include "tcuSurface.hpp"
54 #include "tcuFloat.hpp"
55
56 #include <vector>
57 #include <iomanip>
58
59 using namespace vk;
60 namespace vkt
61 {
62 namespace image
63 {
64 namespace
65 {
66 using std::string;
67 using std::vector;
68 using tcu::TestContext;
69 using tcu::TestStatus;
70 using tcu::UVec3;
71 using tcu::IVec3;
72 using tcu::CompressedTexFormat;
73 using tcu::CompressedTexture;
74 using tcu::Resource;
75 using tcu::Archive;
76 using tcu::ConstPixelBufferAccess;
77 using de::MovePtr;
78 using de::SharedPtr;
79 using de::Random;
80
81 enum Operation
82 {
83 OPERATION_ATTACHMENT_READ,
84 OPERATION_ATTACHMENT_WRITE,
85 OPERATION_TEXTURE_READ,
86 OPERATION_TEXTURE_WRITE,
87 OPERATION_LAST
88 };
89
90 struct TestParameters
91 {
92 Operation operation;
93 UVec3 size;
94 ImageType imageType;
95 VkImageUsageFlagBits testedImageUsageFeature;
96 VkFormat featuredFormat;
97 VkFormat featurelessFormat;
98 VkImageUsageFlags testedImageUsage;
99 VkImageUsageFlags pairedImageUsage;
100 const VkFormat* compatibleFormats;
101 };
102
103 const deUint32 SINGLE_LEVEL = 1u;
104 const deUint32 SINGLE_LAYER = 1u;
105
106 class BasicTranscodingTestInstance : public TestInstance
107 {
108 public:
109 BasicTranscodingTestInstance (Context& context,
110 const TestParameters& parameters);
111 virtual TestStatus iterate (void) = 0;
112 protected:
113 void generateData (deUint8* toFill,
114 size_t size,
115 const VkFormat format = VK_FORMAT_UNDEFINED);
116 const TestParameters m_parameters;
117 };
118
BasicTranscodingTestInstance(Context & context,const TestParameters & parameters)119 BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters)
120 : TestInstance (context)
121 , m_parameters (parameters)
122 {
123 }
124
125 // Replace Infs and NaNs with the largest normal value.
126 // Replace denormal numbers with the smallest normal value.
127 // Leave the rest untouched.
128 // T is a tcu::Float specialization.
129 template <class T>
fixFloatIfNeeded(deUint8 * ptr_)130 void fixFloatIfNeeded(deUint8* ptr_)
131 {
132 T* ptr = reinterpret_cast<T*>(ptr_);
133 if (ptr->isInf() || ptr->isNaN())
134 *ptr = T::largestNormal(ptr->sign());
135 else if (ptr->isDenorm())
136 *ptr = T::smallestNormal(ptr->sign());
137 }
138
generateData(deUint8 * toFill,size_t size,const VkFormat format)139 void BasicTranscodingTestInstance::generateData (deUint8* toFill, size_t size, const VkFormat format)
140 {
141 const deUint8 pattern[] =
142 {
143 // 64-bit values
144 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
149 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
154 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Positive infinity
155 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Negative infinity
156 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS)
157 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
158 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS)
159 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
160 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ)
161 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ)
162 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ)
163 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ)
164 // 32-bit values
165 0x7F, 0x80, 0x00, 0x00, // Positive infinity
166 0xFF, 0x80, 0x00, 0x00, // Negative infinity
167 0x7F, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS)
168 0x7F, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
169 0xFF, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS)
170 0xFF, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
171 0x7F, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ)
172 0x7F, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ)
173 0xFF, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ)
174 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ)
175 0xAA, 0xAA, 0xAA, 0xAA,
176 0x55, 0x55, 0x55, 0x55,
177 };
178
179 deUint8* start = toFill;
180 size_t sizeToRnd = size;
181
182 // Pattern part
183 if (size >= 2 * sizeof(pattern))
184 {
185 // Rotated pattern
186 for (size_t i = 0; i < sizeof(pattern); i++)
187 start[sizeof(pattern) - i - 1] = pattern[i];
188
189 start += sizeof(pattern);
190 sizeToRnd -= sizeof(pattern);
191
192 // Direct pattern
193 deMemcpy(start, pattern, sizeof(pattern));
194
195 start += sizeof(pattern);
196 sizeToRnd -= sizeof(pattern);
197 }
198
199 // Random part
200 {
201 DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0);
202
203 deUint32* start32 = reinterpret_cast<deUint32*>(start);
204 size_t sizeToRnd32 = sizeToRnd / sizeof(deUint32);
205 Random rnd (static_cast<deUint32>(format));
206
207 for (size_t i = 0; i < sizeToRnd32; i++)
208 start32[i] = rnd.getUint32();
209 }
210
211 {
212 // Remove certain values that may not be preserved based on the uncompressed view format
213 if (isSnormFormat(m_parameters.featuredFormat))
214 {
215 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
216
217 if (textureFormat.type == tcu::TextureFormat::SNORM_INT8)
218 {
219 for (size_t i = 0; i < size; i++)
220 {
221 // SNORM fix: due to write operation in SNORM format
222 // replaces 0x80 to 0x81, remove these values from test
223 if (toFill[i] == 0x80)
224 toFill[i] = 0x81;
225 }
226 }
227 else
228 {
229 for (size_t i = 0; i < size; i += 2)
230 {
231 // SNORM fix: due to write operation in SNORM format
232 // replaces 0x00 0x80 to 0x01 0x80
233 if (toFill[i] == 0x00 && toFill[i+1] == 0x80)
234 toFill[i+1] = 0x81;
235 }
236 }
237 }
238 else if (isFloatFormat(m_parameters.featuredFormat))
239 {
240 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
241
242 if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
243 {
244 for (size_t i = 0; i < size; i += 2)
245 fixFloatIfNeeded<tcu::Float16>(toFill + i);
246 }
247 else if (textureFormat.type == tcu::TextureFormat::FLOAT)
248 {
249 for (size_t i = 0; i < size; i += 4)
250 fixFloatIfNeeded<tcu::Float16>(toFill + i);
251
252 for (size_t i = 0; i < size; i += 4)
253 fixFloatIfNeeded<tcu::Float32>(toFill + i);
254 }
255 }
256 }
257 }
258
259 class GraphicsAttachmentsTestInstance : public BasicTranscodingTestInstance
260 {
261 public:
262 GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters);
263 virtual TestStatus iterate (void);
264
265 protected:
266 VkImageCreateInfo makeCreateImageInfo (const VkFormat format,
267 const ImageType type,
268 const UVec3& size,
269 const VkImageUsageFlags usageFlags,
270 const bool extendedImageCreateFlag);
271 VkImageViewUsageCreateInfo makeImageViewUsageCreateInfo (VkImageUsageFlags imageUsageFlags);
272 VkDeviceSize getUncompressedImageData (const VkFormat format,
273 const UVec3& size,
274 std::vector<deUint8>& data);
275 virtual void transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage);
276 bool compareAndLog (const void* reference, const void* result, size_t size);
277 };
278
GraphicsAttachmentsTestInstance(Context & context,const TestParameters & parameters)279 GraphicsAttachmentsTestInstance::GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters)
280 : BasicTranscodingTestInstance(context, parameters)
281 {
282 }
283
iterate(void)284 TestStatus GraphicsAttachmentsTestInstance::iterate (void)
285 {
286 std::vector<deUint8> srcData;
287 std::vector<deUint8> dstData;
288 de::MovePtr<Image> outputImage;
289
290 transcode(srcData, dstData, outputImage);
291
292 DE_ASSERT(srcData.size() > 0 && srcData.size() == dstData.size());
293
294 if (!compareAndLog(&srcData[0], &dstData[0], srcData.size()))
295 return TestStatus::fail("Output differs from input");
296
297 return TestStatus::pass("Pass");
298 }
299
transcode(std::vector<deUint8> & srcData,std::vector<deUint8> & dstData,de::MovePtr<Image> & outputImage)300 void GraphicsAttachmentsTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
301 {
302 const DeviceInterface& vk = m_context.getDeviceInterface();
303 const VkDevice device = m_context.getDevice();
304 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
305 const VkQueue queue = m_context.getUniversalQueue();
306 Allocator& allocator = m_context.getDefaultAllocator();
307
308 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
309 const VkImageViewUsageCreateInfo* imageViewUsageNull = (VkImageViewUsageCreateInfo*)DE_NULL;
310 const VkImageViewUsageCreateInfo imageViewUsage = makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
311
312 const VkFormat srcFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.featurelessFormat :
313 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featuredFormat :
314 VK_FORMAT_UNDEFINED;
315 const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? true :
316 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? false :
317 false;
318 const VkImageUsageFlags srcImageUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.testedImageUsage :
319 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.pairedImageUsage :
320 0;
321 const VkImageViewUsageCreateInfo* srcImageViewUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? &imageViewUsage :
322 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? imageViewUsageNull :
323 imageViewUsageNull;
324 const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
325
326 const VkFormat dstFormat = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.featuredFormat :
327 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featurelessFormat :
328 VK_FORMAT_UNDEFINED;
329 const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? false :
330 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? true :
331 false;
332 const VkImageUsageFlags dstImageUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? m_parameters.pairedImageUsage :
333 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.testedImageUsage :
334 0;
335 const VkImageViewUsageCreateInfo* dstImageViewUsageFlags = (m_parameters.operation == OPERATION_ATTACHMENT_READ) ? imageViewUsageNull :
336 (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? &imageViewUsage :
337 imageViewUsageNull;
338 const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
339
340 const std::vector<tcu::Vec4> vertexArray = createFullscreenQuad();
341 const deUint32 vertexCount = static_cast<deUint32>(vertexArray.size());
342 const size_t vertexBufferSizeInBytes = vertexCount * sizeof(vertexArray[0]);
343 const MovePtr<Buffer> vertexBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
344 const Allocation& vertexBufferAlloc = vertexBuffer->getAllocation();
345 const VkDeviceSize vertexBufferOffset[] = { 0 };
346
347 const VkBufferCreateInfo srcImageBufferInfo (makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
348 const MovePtr<Buffer> srcImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
349
350 const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
351 const MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
352 Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, srcImageViewUsageFlags));
353
354 const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
355 de::MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
356 Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, dstImageViewUsageFlags));
357
358 const VkBufferCreateInfo dstImageBufferInfo (makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
359 MovePtr<Buffer> dstImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
360
361 const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
362 const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
363
364 const Unique<VkRenderPass> renderPass (vkt::image::makeRenderPass(vk, device, m_parameters.featuredFormat, m_parameters.featuredFormat));
365
366 const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
367 .addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
368 .build(vk, device));
369 const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
370 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, SINGLE_LAYER)
371 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, SINGLE_LAYER));
372 const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
373 const VkDescriptorImageInfo descriptorSrcImageInfo (makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
374
375 const VkExtent2D renderSize (makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
376 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
377 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 1u));
378 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
379 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
380
381 const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
382 const VkBufferMemoryBarrier srcCopyBufferBarrierPre = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
383 const VkImageMemoryBarrier srcCopyImageBarrierPre = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), subresourceRange);
384 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);
385 const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
386
387 const VkImageView attachmentBindInfos[] = { *srcImageView, *dstImageView };
388 const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos, renderSize.width, renderSize.height, SINGLE_LAYER));
389
390 DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
391
392 // Upload vertex data
393 deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
394 flushAlloc(vk, device, vertexBufferAlloc);
395
396 // Upload source image data
397 const Allocation& alloc = srcImageBuffer->getAllocation();
398 deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
399 flushAlloc(vk, device, alloc);
400
401 beginCommandBuffer(vk, *cmdBuffer);
402 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
403
404 //Copy buffer to image
405 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre);
406 vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion);
407 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);
408
409 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
410
411 DescriptorSetUpdateBuilder()
412 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo)
413 .update(vk, device);
414
415 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
416 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
417 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
418
419 endRenderPass(vk, *cmdBuffer);
420
421 const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
422 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
423 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
424 dstImage->get(), subresourceRange);
425
426 const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
427 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
428 dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
429
430 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);
431 vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
432 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);
433
434 endCommandBuffer(vk, *cmdBuffer);
435
436 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
437
438 const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
439 invalidateAlloc(vk, device, dstImageBufferAlloc);
440 dstData.resize((size_t)dstImageSizeInBytes);
441 deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
442
443 outputImage = dstImage;
444 }
445
446
makeCreateImageInfo(const VkFormat format,const ImageType type,const UVec3 & size,const VkImageUsageFlags usageFlags,const bool extendedImageCreateFlag)447 VkImageCreateInfo GraphicsAttachmentsTestInstance::makeCreateImageInfo (const VkFormat format,
448 const ImageType type,
449 const UVec3& size,
450 const VkImageUsageFlags usageFlags,
451 const bool extendedImageCreateFlag)
452 {
453 const VkImageType imageType = mapImageType(type);
454 const VkImageCreateFlags imageCreateFlagsBase = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
455 const VkImageCreateFlags imageCreateFlagsAddOn = extendedImageCreateFlag ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0;
456 const VkImageCreateFlags imageCreateFlags = imageCreateFlagsBase | imageCreateFlagsAddOn;
457
458 const VkImageCreateInfo createImageInfo =
459 {
460 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
461 DE_NULL, // const void* pNext;
462 imageCreateFlags, // VkImageCreateFlags flags;
463 imageType, // VkImageType imageType;
464 format, // VkFormat format;
465 makeExtent3D(getLayerSize(type, size)), // VkExtent3D extent;
466 1u, // deUint32 mipLevels;
467 1u, // deUint32 arrayLayers;
468 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
469 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
470 usageFlags, // VkImageUsageFlags usage;
471 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
472 0u, // deUint32 queueFamilyIndexCount;
473 DE_NULL, // const deUint32* pQueueFamilyIndices;
474 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
475 };
476
477 return createImageInfo;
478 }
479
makeImageViewUsageCreateInfo(VkImageUsageFlags imageUsageFlags)480 VkImageViewUsageCreateInfo GraphicsAttachmentsTestInstance::makeImageViewUsageCreateInfo (VkImageUsageFlags imageUsageFlags)
481 {
482 VkImageViewUsageCreateInfo imageViewUsageCreateInfo =
483 {
484 VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR, //VkStructureType sType;
485 DE_NULL, //const void* pNext;
486 imageUsageFlags, //VkImageUsageFlags usage;
487 };
488
489 return imageViewUsageCreateInfo;
490 }
491
getUncompressedImageData(const VkFormat format,const UVec3 & size,std::vector<deUint8> & data)492 VkDeviceSize GraphicsAttachmentsTestInstance::getUncompressedImageData (const VkFormat format, const UVec3& size, std::vector<deUint8>& data)
493 {
494 tcu::IVec3 sizeAsIVec3 = tcu::IVec3(static_cast<int>(size[0]), static_cast<int>(size[1]), static_cast<int>(size[2]));
495 VkDeviceSize sizeBytes = getImageSizeBytes(sizeAsIVec3, format);
496
497 data.resize((size_t)sizeBytes);
498 generateData(&data[0], data.size(), format);
499
500 return sizeBytes;
501 }
502
compareAndLog(const void * reference,const void * result,size_t size)503 bool GraphicsAttachmentsTestInstance::compareAndLog (const void* reference, const void* result, size_t size)
504 {
505 tcu::TestLog& log = m_context.getTestContext().getLog();
506
507 const deUint64* ref64 = reinterpret_cast<const deUint64*>(reference);
508 const deUint64* res64 = reinterpret_cast<const deUint64*>(result);
509 const size_t sizew = size / sizeof(deUint64);
510 bool equal = true;
511
512 DE_ASSERT(size % sizeof(deUint64) == 0);
513
514 for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(sizew); ndx++)
515 {
516 if (ref64[ndx] != res64[ndx])
517 {
518 std::stringstream str;
519
520 str << "Difference begins near byte " << ndx * sizeof(deUint64) << "."
521 << " reference value: 0x" << std::hex << std::setw(2ull * sizeof(deUint64)) << std::setfill('0') << ref64[ndx]
522 << " result value: 0x" << std::hex << std::setw(2ull * sizeof(deUint64)) << std::setfill('0') << res64[ndx];
523
524 log.writeMessage(str.str().c_str());
525
526 equal = false;
527
528 break;
529 }
530 }
531
532 return equal;
533 }
534
535
536 class GraphicsTextureTestInstance : public GraphicsAttachmentsTestInstance
537 {
538 public:
539 GraphicsTextureTestInstance (Context& context, const TestParameters& parameters);
540
541 protected:
542 void transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage);
543 };
544
GraphicsTextureTestInstance(Context & context,const TestParameters & parameters)545 GraphicsTextureTestInstance::GraphicsTextureTestInstance (Context& context, const TestParameters& parameters)
546 : GraphicsAttachmentsTestInstance(context, parameters)
547 {
548 }
549
transcode(std::vector<deUint8> & srcData,std::vector<deUint8> & dstData,de::MovePtr<Image> & outputImage)550 void GraphicsTextureTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
551 {
552 const DeviceInterface& vk = m_context.getDeviceInterface();
553 const VkDevice device = m_context.getDevice();
554 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
555 const VkQueue queue = m_context.getUniversalQueue();
556 Allocator& allocator = m_context.getDefaultAllocator();
557
558 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
559 const VkImageViewUsageCreateInfo* imageViewUsageNull = (VkImageViewUsageCreateInfo*)DE_NULL;
560 const VkImageViewUsageCreateInfo imageViewUsage = makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
561
562 const VkFormat srcFormat = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.featurelessFormat :
563 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featuredFormat :
564 VK_FORMAT_UNDEFINED;
565 const bool srcExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ) ? true :
566 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? false :
567 false;
568 const VkImageUsageFlags srcImageUsageFlags = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.testedImageUsage :
569 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.pairedImageUsage :
570 0;
571 const VkImageViewUsageCreateInfo* srcImageViewUsage = (m_parameters.operation == OPERATION_TEXTURE_READ) ? &imageViewUsage :
572 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? imageViewUsageNull :
573 imageViewUsageNull;
574 const VkDeviceSize srcImageSizeInBytes = getUncompressedImageData(srcFormat, m_parameters.size, srcData);
575
576 const VkFormat dstFormat = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.featuredFormat :
577 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featurelessFormat :
578 VK_FORMAT_UNDEFINED;
579 const bool dstExtendedImageCreate = (m_parameters.operation == OPERATION_TEXTURE_READ) ? false :
580 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? true :
581 false;
582 const VkImageUsageFlags dstImageUsageFlags = (m_parameters.operation == OPERATION_TEXTURE_READ) ? m_parameters.pairedImageUsage :
583 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.testedImageUsage :
584 0;
585 const VkImageViewUsageCreateInfo* dstImageViewUsage = (m_parameters.operation == OPERATION_TEXTURE_READ) ? imageViewUsageNull :
586 (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? &imageViewUsage :
587 imageViewUsageNull;
588 const VkDeviceSize dstImageSizeInBytes = getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
589
590 const std::vector<tcu::Vec4> vertexArray = createFullscreenQuad();
591 const deUint32 vertexCount = static_cast<deUint32>(vertexArray.size());
592 const size_t vertexBufferSizeInBytes = vertexCount * sizeof(vertexArray[0]);
593 const MovePtr<Buffer> vertexBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
594 const Allocation& vertexBufferAlloc = vertexBuffer->getAllocation();
595 const VkDeviceSize vertexBufferOffset[] = { 0 };
596
597 const VkBufferCreateInfo srcImageBufferInfo (makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
598 const MovePtr<Buffer> srcImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
599
600 const VkImageCreateInfo srcImageCreateInfo = makeCreateImageInfo(srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
601 const MovePtr<Image> srcImage (new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
602 Move<VkImageView> srcImageView (makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, srcImageViewUsage));
603
604 const VkImageCreateInfo dstImageCreateInfo = makeCreateImageInfo(dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
605 de::MovePtr<Image> dstImage (new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
606 Move<VkImageView> dstImageView (makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, dstImageViewUsage));
607 const VkImageMemoryBarrier dstCopyImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), subresourceRange);
608
609 const VkBufferCreateInfo dstImageBufferInfo (makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
610 MovePtr<Buffer> dstImageBuffer = MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
611
612 const Unique<VkShaderModule> vertShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
613 const Unique<VkShaderModule> fragShaderModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
614
615 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device));
616
617 const Move<VkDescriptorSetLayout> descriptorSetLayout (DescriptorSetLayoutBuilder()
618 .addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
619 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
620 .build(vk, device));
621 const Move<VkDescriptorPool> descriptorPool (DescriptorPoolBuilder()
622 .addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
623 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
624 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
625 const Move<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
626 const VkSamplerCreateInfo srcSamplerInfo (makeSamplerCreateInfo());
627 const Move<VkSampler> srcSampler = vk::createSampler(vk, device, &srcSamplerInfo);
628 const VkDescriptorImageInfo descriptorSrcImage (makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
629 const VkDescriptorImageInfo descriptorDstImage (makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL));
630
631 const VkExtent2D renderSize (makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
632 const Unique<VkPipelineLayout> pipelineLayout (makePipelineLayout(vk, device, *descriptorSetLayout));
633 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 0u));
634 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
635 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
636
637 const VkBufferImageCopy srcCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
638 const VkBufferMemoryBarrier srcCopyBufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
639 const VkImageMemoryBarrier srcCopyImageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
640 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);
641
642 const VkBufferImageCopy dstCopyRegion = makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
643
644 const VkExtent2D framebufferSize (makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
645 const Move<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize.width, framebufferSize.height, SINGLE_LAYER));
646
647 DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
648
649 // Upload vertex data
650 deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
651 flushAlloc(vk, device, vertexBufferAlloc);
652
653 // Upload source image data
654 const Allocation& alloc = srcImageBuffer->getAllocation();
655 deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
656 flushAlloc(vk, device, alloc);
657
658 beginCommandBuffer(vk, *cmdBuffer);
659 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
660
661 //Copy buffer to image
662 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrier, 1u, &srcCopyImageBarrier);
663 vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1u, &srcCopyRegion);
664 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);
665
666 // Make source image readable
667 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);
668
669 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
670 {
671 DescriptorSetUpdateBuilder()
672 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage)
673 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImage)
674 .update(vk, device);
675
676 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
677 vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
678 vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
679 }
680 endRenderPass(vk, *cmdBuffer);
681
682 const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
683 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
684 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
685 dstImage->get(), subresourceRange);
686
687 const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
688 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
689 dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
690
691 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);
692 vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
693 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);
694
695 endCommandBuffer(vk, *cmdBuffer);
696
697 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
698
699 const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
700 invalidateAlloc(vk, device, dstImageBufferAlloc);
701 dstData.resize((size_t)dstImageSizeInBytes);
702 deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
703
704 outputImage = dstImage;
705 }
706
707 class ImageTranscodingCase : public TestCase
708 {
709 public:
710 ImageTranscodingCase (TestContext& testCtx,
711 const std::string& name,
712 const std::string& desc,
713 const TestParameters& parameters);
714 void initPrograms (SourceCollections& programCollection) const;
715 TestInstance* createInstance (Context& context) const;
716 virtual void checkSupport (Context& context) const;
717 bool isFormatUsageFlagSupported (Context& context,
718 const VkFormat format,
719 VkImageUsageFlags formatUsageFlags) const;
720
721 protected:
722 const TestParameters m_parameters;
723 };
724
ImageTranscodingCase(TestContext & testCtx,const std::string & name,const std::string & desc,const TestParameters & parameters)725 ImageTranscodingCase::ImageTranscodingCase (TestContext& testCtx, const std::string& name, const std::string& desc, const TestParameters& parameters)
726 : TestCase (testCtx, name, desc)
727 , m_parameters (parameters)
728 {
729 }
730
initPrograms(vk::SourceCollections & programCollection) const731 void ImageTranscodingCase::initPrograms (vk::SourceCollections& programCollection) const
732 {
733 DE_ASSERT(m_parameters.size.x() > 0);
734 DE_ASSERT(m_parameters.size.y() > 0);
735
736 ImageType imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
737
738 // Vertex shader
739 {
740 std::ostringstream src;
741 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
742 << "layout(location = 0) in vec4 v_in_position;\n"
743 << "\n"
744 << "void main (void)\n"
745 << "{\n"
746 << " gl_Position = v_in_position;\n"
747 << "}\n";
748
749 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
750 }
751
752 // Fragment shader
753 {
754 switch(m_parameters.operation)
755 {
756 case OPERATION_ATTACHMENT_READ:
757 case OPERATION_ATTACHMENT_WRITE:
758 {
759 std::ostringstream src;
760
761 const std::string dstTypeStr = getGlslAttachmentType(m_parameters.featuredFormat);
762 const std::string srcTypeStr = getGlslInputAttachmentType(m_parameters.featuredFormat);
763
764 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
765 << "precision highp int;\n"
766 << "precision highp float;\n"
767 << "\n"
768 << "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
769 << "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr << " inputImage1;\n"
770 << "\n"
771 << "void main (void)\n"
772 << "{\n"
773 << " o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
774 << "}\n";
775
776 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
777
778 break;
779 }
780
781 case OPERATION_TEXTURE_READ:
782 case OPERATION_TEXTURE_WRITE:
783 {
784 std::ostringstream src;
785
786 const std::string srcSamplerTypeStr = getGlslSamplerType(mapVkFormat(m_parameters.featuredFormat), mapImageViewType(imageTypeForFS));
787 const std::string dstImageTypeStr = getShaderImageType(mapVkFormat(m_parameters.featuredFormat), imageTypeForFS);
788 const std::string dstFormatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_parameters.featuredFormat));
789
790 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
791 << "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
792 << "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr << " u_imageOut;\n"
793 << "\n"
794 << "void main (void)\n"
795 << "{\n"
796 << " const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
797 << " const vec2 pixels_resolution = vec2(textureSize(u_imageIn, 0));\n"
798 << " const vec2 in_pos = vec2(gl_FragCoord.xy) / vec2(pixels_resolution);\n"
799 << " imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
800 << "}\n";
801
802 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
803
804 break;
805 }
806
807 default:
808 DE_ASSERT(false);
809 }
810 }
811 }
812
isFormatUsageFlagSupported(Context & context,const VkFormat format,VkImageUsageFlags formatUsageFlags) const813 bool ImageTranscodingCase::isFormatUsageFlagSupported (Context& context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const
814 {
815 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
816 const InstanceInterface& vk = context.getInstanceInterface();
817 VkImageFormatProperties imageFormatProperties;
818 const VkResult queryResult = vk.getPhysicalDeviceImageFormatProperties(
819 physicalDevice,
820 format,
821 mapImageType(m_parameters.imageType),
822 VK_IMAGE_TILING_OPTIMAL,
823 formatUsageFlags,
824 VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR,
825 &imageFormatProperties);
826
827 return (queryResult == VK_SUCCESS);
828 }
829
checkSupport(Context & context) const830 void ImageTranscodingCase::checkSupport (Context& context) const
831 {
832 context.requireDeviceFunctionality("VK_KHR_maintenance2");
833
834 if ((m_parameters.operation == OPERATION_TEXTURE_READ || m_parameters.operation == OPERATION_TEXTURE_WRITE) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
835 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
836
837 if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsageFeature))
838 TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
839
840 if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
841 TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
842 }
843
createInstance(Context & context) const844 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
845 {
846 VkFormat featurelessFormat = VK_FORMAT_UNDEFINED;
847 bool differenceFound = false;
848
849 DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
850
851 for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
852 {
853 featurelessFormat = m_parameters.compatibleFormats[i];
854
855 if (isSupportedByFramework(featurelessFormat)
856 && !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
857 && isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
858 )
859 {
860 differenceFound = true;
861
862 break;
863 }
864 }
865
866 if (differenceFound)
867 {
868 if ((context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
869 !context.getPortabilitySubsetFeatures().imageViewFormatReinterpretation))
870 {
871 tcu::TextureFormat textureImageFormat = vk::mapVkFormat(m_parameters.featuredFormat);
872 tcu::TextureFormat textureViewFormat = vk::mapVkFormat(featurelessFormat);
873
874 if (tcu::getTextureFormatBitDepth(textureImageFormat) != tcu::getTextureFormatBitDepth(textureViewFormat))
875 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");
876 }
877
878 TestParameters calculatedParameters =
879 {
880 m_parameters.operation, // Operation operation
881 m_parameters.size, // UVec3 size
882 m_parameters.imageType, // ImageType imageType
883 m_parameters.testedImageUsageFeature, // VkImageUsageFlagBits testedImageUsageFeature
884 m_parameters.featuredFormat, // VkFormat featuredFormat
885 featurelessFormat, // VkFormat featurelessFormat
886 m_parameters.testedImageUsage, // VkImageUsageFlags testedImageUsage
887 m_parameters.pairedImageUsage, // VkImageUsageFlags pairedImageUsage
888 DE_NULL, // const VkFormat* compatibleFormats
889 };
890
891 switch (m_parameters.operation)
892 {
893 case OPERATION_ATTACHMENT_READ:
894 case OPERATION_ATTACHMENT_WRITE:
895 return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
896
897 case OPERATION_TEXTURE_READ:
898 case OPERATION_TEXTURE_WRITE:
899 return new GraphicsTextureTestInstance(context, calculatedParameters);
900
901 default:
902 TCU_THROW(InternalError, "Impossible");
903 }
904 }
905 else
906 TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
907 }
908
909 } // anonymous ns
910
911 static const VkFormat compatibleFormatList8Bit[] =
912 {
913 VK_FORMAT_R4G4_UNORM_PACK8,
914 VK_FORMAT_R8_UNORM,
915 VK_FORMAT_R8_SNORM,
916 VK_FORMAT_R8_USCALED,
917 VK_FORMAT_R8_SSCALED,
918 VK_FORMAT_R8_UINT,
919 VK_FORMAT_R8_SINT,
920 VK_FORMAT_R8_SRGB,
921
922 VK_FORMAT_UNDEFINED
923 };
924
925 static const VkFormat compatibleFormatList16Bit[] =
926 {
927 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
928 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
929 VK_FORMAT_R5G6B5_UNORM_PACK16,
930 VK_FORMAT_B5G6R5_UNORM_PACK16,
931 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
932 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
933 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
934 VK_FORMAT_R8G8_UNORM,
935 VK_FORMAT_R8G8_SNORM,
936 VK_FORMAT_R8G8_USCALED,
937 VK_FORMAT_R8G8_SSCALED,
938 VK_FORMAT_R8G8_UINT,
939 VK_FORMAT_R8G8_SINT,
940 VK_FORMAT_R8G8_SRGB,
941 VK_FORMAT_R16_UNORM,
942 VK_FORMAT_R16_SNORM,
943 VK_FORMAT_R16_USCALED,
944 VK_FORMAT_R16_SSCALED,
945 VK_FORMAT_R16_UINT,
946 VK_FORMAT_R16_SINT,
947 VK_FORMAT_R16_SFLOAT,
948 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
949 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
950
951 VK_FORMAT_UNDEFINED
952 };
953
954 static const VkFormat compatibleFormatList24Bit[] =
955 {
956 VK_FORMAT_R8G8B8_UNORM,
957 VK_FORMAT_R8G8B8_SNORM,
958 VK_FORMAT_R8G8B8_USCALED,
959 VK_FORMAT_R8G8B8_SSCALED,
960 VK_FORMAT_R8G8B8_UINT,
961 VK_FORMAT_R8G8B8_SINT,
962 VK_FORMAT_R8G8B8_SRGB,
963 VK_FORMAT_B8G8R8_UNORM,
964 VK_FORMAT_B8G8R8_SNORM,
965 VK_FORMAT_B8G8R8_USCALED,
966 VK_FORMAT_B8G8R8_SSCALED,
967 VK_FORMAT_B8G8R8_UINT,
968 VK_FORMAT_B8G8R8_SINT,
969 VK_FORMAT_B8G8R8_SRGB,
970
971 VK_FORMAT_UNDEFINED
972 };
973
974 static const VkFormat compatibleFormatList32Bit[] =
975 {
976 VK_FORMAT_R8G8B8A8_UNORM,
977 VK_FORMAT_R8G8B8A8_SNORM,
978 VK_FORMAT_R8G8B8A8_USCALED,
979 VK_FORMAT_R8G8B8A8_SSCALED,
980 VK_FORMAT_R8G8B8A8_UINT,
981 VK_FORMAT_R8G8B8A8_SINT,
982 VK_FORMAT_R8G8B8A8_SRGB,
983 VK_FORMAT_B8G8R8A8_UNORM,
984 VK_FORMAT_B8G8R8A8_SNORM,
985 VK_FORMAT_B8G8R8A8_USCALED,
986 VK_FORMAT_B8G8R8A8_SSCALED,
987 VK_FORMAT_B8G8R8A8_UINT,
988 VK_FORMAT_B8G8R8A8_SINT,
989 VK_FORMAT_B8G8R8A8_SRGB,
990 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
991 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
992 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
993 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
994 VK_FORMAT_A8B8G8R8_UINT_PACK32,
995 VK_FORMAT_A8B8G8R8_SINT_PACK32,
996 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
997 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
998 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
999 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1000 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1001 VK_FORMAT_A2R10G10B10_UINT_PACK32,
1002 VK_FORMAT_A2R10G10B10_SINT_PACK32,
1003 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1004 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1005 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1006 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1007 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1008 VK_FORMAT_A2B10G10R10_SINT_PACK32,
1009 VK_FORMAT_R16G16_UNORM,
1010 VK_FORMAT_R16G16_SNORM,
1011 VK_FORMAT_R16G16_USCALED,
1012 VK_FORMAT_R16G16_SSCALED,
1013 VK_FORMAT_R16G16_UINT,
1014 VK_FORMAT_R16G16_SINT,
1015 VK_FORMAT_R16G16_SFLOAT,
1016 VK_FORMAT_R32_UINT,
1017 VK_FORMAT_R32_SINT,
1018 VK_FORMAT_R32_SFLOAT,
1019
1020 VK_FORMAT_UNDEFINED
1021 };
1022
1023 static const VkFormat compatibleFormatList48Bit[] =
1024 {
1025 VK_FORMAT_R16G16B16_UNORM,
1026 VK_FORMAT_R16G16B16_SNORM,
1027 VK_FORMAT_R16G16B16_USCALED,
1028 VK_FORMAT_R16G16B16_SSCALED,
1029 VK_FORMAT_R16G16B16_UINT,
1030 VK_FORMAT_R16G16B16_SINT,
1031 VK_FORMAT_R16G16B16_SFLOAT,
1032
1033 VK_FORMAT_UNDEFINED
1034 };
1035
1036 static const VkFormat compatibleFormatList64Bit[] =
1037 {
1038 VK_FORMAT_R16G16B16A16_UNORM,
1039 VK_FORMAT_R16G16B16A16_SNORM,
1040 VK_FORMAT_R16G16B16A16_USCALED,
1041 VK_FORMAT_R16G16B16A16_SSCALED,
1042 VK_FORMAT_R16G16B16A16_UINT,
1043 VK_FORMAT_R16G16B16A16_SINT,
1044 VK_FORMAT_R16G16B16A16_SFLOAT,
1045 VK_FORMAT_R32G32_UINT,
1046 VK_FORMAT_R32G32_SINT,
1047 VK_FORMAT_R32G32_SFLOAT,
1048 VK_FORMAT_R64_UINT,
1049 VK_FORMAT_R64_SINT,
1050 VK_FORMAT_R64_SFLOAT,
1051
1052 VK_FORMAT_UNDEFINED
1053 };
1054
1055 static const VkFormat compatibleFormatList96Bit[] =
1056 {
1057 VK_FORMAT_R32G32B32_UINT,
1058 VK_FORMAT_R32G32B32_SINT,
1059 VK_FORMAT_R32G32B32_SFLOAT,
1060
1061 VK_FORMAT_UNDEFINED
1062 };
1063
1064 static const VkFormat compatibleFormatList128Bit[] =
1065 {
1066 VK_FORMAT_R32G32B32A32_UINT,
1067 VK_FORMAT_R32G32B32A32_SINT,
1068 VK_FORMAT_R32G32B32A32_SFLOAT,
1069 VK_FORMAT_R64G64_UINT,
1070 VK_FORMAT_R64G64_SINT,
1071 VK_FORMAT_R64G64_SFLOAT,
1072
1073 VK_FORMAT_UNDEFINED
1074 };
1075
1076 const VkFormat compatibleFormatList192Bit[] =
1077 {
1078 VK_FORMAT_R64G64B64_UINT,
1079 VK_FORMAT_R64G64B64_SINT,
1080 VK_FORMAT_R64G64B64_SFLOAT,
1081
1082 VK_FORMAT_UNDEFINED
1083 };
1084
1085 static const VkFormat compatibleFormatList256Bit[] =
1086 {
1087 VK_FORMAT_R64G64B64A64_UINT,
1088 VK_FORMAT_R64G64B64A64_SINT,
1089 VK_FORMAT_R64G64B64A64_SFLOAT,
1090
1091 VK_FORMAT_UNDEFINED
1092 };
1093
1094 static const VkFormat* compatibleFormatsList[] =
1095 {
1096 compatibleFormatList8Bit,
1097 compatibleFormatList16Bit,
1098 compatibleFormatList24Bit,
1099 compatibleFormatList32Bit,
1100 compatibleFormatList48Bit,
1101 compatibleFormatList64Bit,
1102 compatibleFormatList96Bit,
1103 compatibleFormatList128Bit,
1104 compatibleFormatList192Bit,
1105 compatibleFormatList256Bit,
1106 };
1107
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1108 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1109 {
1110 const std::string operationName[OPERATION_LAST] =
1111 {
1112 "attachment_read",
1113 "attachment_write",
1114 "texture_read",
1115 "texture_write",
1116 };
1117 const VkImageUsageFlagBits testedImageUsageFlags[OPERATION_LAST] =
1118 {
1119 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1120 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1121 VK_IMAGE_USAGE_SAMPLED_BIT,
1122 VK_IMAGE_USAGE_STORAGE_BIT,
1123 };
1124 const VkImageUsageFlagBits pairedImageUsageFlags[OPERATION_LAST] =
1125 {
1126 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1127 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1128 VK_IMAGE_USAGE_STORAGE_BIT,
1129 VK_IMAGE_USAGE_SAMPLED_BIT,
1130 };
1131 VkImageUsageFlags baseFlagsAddOn = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1132
1133 MovePtr<tcu::TestCaseGroup> imageTranscodingTests (new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1134
1135 for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1136 {
1137 MovePtr<tcu::TestCaseGroup> imageOperationGroup (new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1138
1139 for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1140 {
1141 for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1142 {
1143 const VkFormat featuredFormat = compatibleFormatsList[groupNdx][featuredFormatNdx];
1144 const VkFormat featurelessFormat = VK_FORMAT_UNDEFINED; // Lookup process is in createInstance()
1145
1146 if (!isSupportedByFramework(featuredFormat))
1147 continue;
1148
1149 // Cannot handle SRGB in shader layout classifier
1150 if (isSrgbFormat(featuredFormat))
1151 continue;
1152
1153 // Cannot handle packed in shader layout classifier
1154 if (isPackedType(featuredFormat))
1155 continue;
1156
1157 // Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1158 if (isComponentSwizzled(featuredFormat))
1159 continue;
1160
1161 // Cannot handle three-component images in shader layout classifier
1162 if (getNumUsedChannels(featuredFormat) == 3)
1163 continue;
1164
1165 const std::string testName = getFormatShortString(featuredFormat);
1166 const TestParameters parameters =
1167 {
1168 static_cast<Operation>(operationNdx), // Operation operation
1169 UVec3(16u, 16u, 1u), // UVec3 size
1170 IMAGE_TYPE_2D, // ImageType imageType
1171 testedImageUsageFlags[operationNdx], // VkImageUsageFlagBits testedImageUsageFeature
1172 featuredFormat, // VkFormat featuredFormat
1173 featurelessFormat, // VkFormat featurelessFormat
1174 baseFlagsAddOn | testedImageUsageFlags[operationNdx], // VkImageUsageFlags testedImageUsage
1175 baseFlagsAddOn | pairedImageUsageFlags[operationNdx], // VkImageUsageFlags pairedImageUsage
1176 compatibleFormatsList[groupNdx] // const VkFormat* compatibleFormats
1177 };
1178
1179 imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1180 }
1181 }
1182
1183 imageTranscodingTests->addChild(imageOperationGroup.release());
1184 }
1185
1186 return imageTranscodingTests.release();
1187 }
1188
1189 } // image
1190 } // vkt
1191