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 (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsageFeature))
835 TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
836
837 if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
838 TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
839 }
840
createInstance(Context & context) const841 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
842 {
843 VkFormat featurelessFormat = VK_FORMAT_UNDEFINED;
844 bool differenceFound = false;
845
846 DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
847
848 for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
849 {
850 featurelessFormat = m_parameters.compatibleFormats[i];
851
852 if (isSupportedByFramework(featurelessFormat)
853 && !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
854 && isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
855 )
856 {
857 differenceFound = true;
858
859 break;
860 }
861 }
862
863 if (differenceFound)
864 {
865 TestParameters calculatedParameters =
866 {
867 m_parameters.operation, // Operation operation
868 m_parameters.size, // UVec3 size
869 m_parameters.imageType, // ImageType imageType
870 m_parameters.testedImageUsageFeature, // VkImageUsageFlagBits testedImageUsageFeature
871 m_parameters.featuredFormat, // VkFormat featuredFormat
872 featurelessFormat, // VkFormat featurelessFormat
873 m_parameters.testedImageUsage, // VkImageUsageFlags testedImageUsage
874 m_parameters.pairedImageUsage, // VkImageUsageFlags pairedImageUsage
875 DE_NULL, // const VkFormat* compatibleFormats
876 };
877
878 switch (m_parameters.operation)
879 {
880 case OPERATION_ATTACHMENT_READ:
881 case OPERATION_ATTACHMENT_WRITE:
882 return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
883
884 case OPERATION_TEXTURE_READ:
885 case OPERATION_TEXTURE_WRITE:
886 return new GraphicsTextureTestInstance(context, calculatedParameters);
887
888 default:
889 TCU_THROW(InternalError, "Impossible");
890 }
891 }
892 else
893 TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
894 }
895
896 } // anonymous ns
897
898 static const VkFormat compatibleFormatList8Bit[] =
899 {
900 VK_FORMAT_R4G4_UNORM_PACK8,
901 VK_FORMAT_R8_UNORM,
902 VK_FORMAT_R8_SNORM,
903 VK_FORMAT_R8_USCALED,
904 VK_FORMAT_R8_SSCALED,
905 VK_FORMAT_R8_UINT,
906 VK_FORMAT_R8_SINT,
907 VK_FORMAT_R8_SRGB,
908
909 VK_FORMAT_UNDEFINED
910 };
911
912 static const VkFormat compatibleFormatList16Bit[] =
913 {
914 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
915 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
916 VK_FORMAT_R5G6B5_UNORM_PACK16,
917 VK_FORMAT_B5G6R5_UNORM_PACK16,
918 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
919 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
920 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
921 VK_FORMAT_R8G8_UNORM,
922 VK_FORMAT_R8G8_SNORM,
923 VK_FORMAT_R8G8_USCALED,
924 VK_FORMAT_R8G8_SSCALED,
925 VK_FORMAT_R8G8_UINT,
926 VK_FORMAT_R8G8_SINT,
927 VK_FORMAT_R8G8_SRGB,
928 VK_FORMAT_R16_UNORM,
929 VK_FORMAT_R16_SNORM,
930 VK_FORMAT_R16_USCALED,
931 VK_FORMAT_R16_SSCALED,
932 VK_FORMAT_R16_UINT,
933 VK_FORMAT_R16_SINT,
934 VK_FORMAT_R16_SFLOAT,
935
936 VK_FORMAT_UNDEFINED
937 };
938
939 static const VkFormat compatibleFormatList24Bit[] =
940 {
941 VK_FORMAT_R8G8B8_UNORM,
942 VK_FORMAT_R8G8B8_SNORM,
943 VK_FORMAT_R8G8B8_USCALED,
944 VK_FORMAT_R8G8B8_SSCALED,
945 VK_FORMAT_R8G8B8_UINT,
946 VK_FORMAT_R8G8B8_SINT,
947 VK_FORMAT_R8G8B8_SRGB,
948 VK_FORMAT_B8G8R8_UNORM,
949 VK_FORMAT_B8G8R8_SNORM,
950 VK_FORMAT_B8G8R8_USCALED,
951 VK_FORMAT_B8G8R8_SSCALED,
952 VK_FORMAT_B8G8R8_UINT,
953 VK_FORMAT_B8G8R8_SINT,
954 VK_FORMAT_B8G8R8_SRGB,
955
956 VK_FORMAT_UNDEFINED
957 };
958
959 static const VkFormat compatibleFormatList32Bit[] =
960 {
961 VK_FORMAT_R8G8B8A8_UNORM,
962 VK_FORMAT_R8G8B8A8_SNORM,
963 VK_FORMAT_R8G8B8A8_USCALED,
964 VK_FORMAT_R8G8B8A8_SSCALED,
965 VK_FORMAT_R8G8B8A8_UINT,
966 VK_FORMAT_R8G8B8A8_SINT,
967 VK_FORMAT_R8G8B8A8_SRGB,
968 VK_FORMAT_B8G8R8A8_UNORM,
969 VK_FORMAT_B8G8R8A8_SNORM,
970 VK_FORMAT_B8G8R8A8_USCALED,
971 VK_FORMAT_B8G8R8A8_SSCALED,
972 VK_FORMAT_B8G8R8A8_UINT,
973 VK_FORMAT_B8G8R8A8_SINT,
974 VK_FORMAT_B8G8R8A8_SRGB,
975 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
976 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
977 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
978 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
979 VK_FORMAT_A8B8G8R8_UINT_PACK32,
980 VK_FORMAT_A8B8G8R8_SINT_PACK32,
981 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
982 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
983 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
984 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
985 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
986 VK_FORMAT_A2R10G10B10_UINT_PACK32,
987 VK_FORMAT_A2R10G10B10_SINT_PACK32,
988 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
989 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
990 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
991 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
992 VK_FORMAT_A2B10G10R10_UINT_PACK32,
993 VK_FORMAT_A2B10G10R10_SINT_PACK32,
994 VK_FORMAT_R16G16_UNORM,
995 VK_FORMAT_R16G16_SNORM,
996 VK_FORMAT_R16G16_USCALED,
997 VK_FORMAT_R16G16_SSCALED,
998 VK_FORMAT_R16G16_UINT,
999 VK_FORMAT_R16G16_SINT,
1000 VK_FORMAT_R16G16_SFLOAT,
1001 VK_FORMAT_R32_UINT,
1002 VK_FORMAT_R32_SINT,
1003 VK_FORMAT_R32_SFLOAT,
1004
1005 VK_FORMAT_UNDEFINED
1006 };
1007
1008 static const VkFormat compatibleFormatList48Bit[] =
1009 {
1010 VK_FORMAT_R16G16B16_UNORM,
1011 VK_FORMAT_R16G16B16_SNORM,
1012 VK_FORMAT_R16G16B16_USCALED,
1013 VK_FORMAT_R16G16B16_SSCALED,
1014 VK_FORMAT_R16G16B16_UINT,
1015 VK_FORMAT_R16G16B16_SINT,
1016 VK_FORMAT_R16G16B16_SFLOAT,
1017
1018 VK_FORMAT_UNDEFINED
1019 };
1020
1021 static const VkFormat compatibleFormatList64Bit[] =
1022 {
1023 VK_FORMAT_R16G16B16A16_UNORM,
1024 VK_FORMAT_R16G16B16A16_SNORM,
1025 VK_FORMAT_R16G16B16A16_USCALED,
1026 VK_FORMAT_R16G16B16A16_SSCALED,
1027 VK_FORMAT_R16G16B16A16_UINT,
1028 VK_FORMAT_R16G16B16A16_SINT,
1029 VK_FORMAT_R16G16B16A16_SFLOAT,
1030 VK_FORMAT_R32G32_UINT,
1031 VK_FORMAT_R32G32_SINT,
1032 VK_FORMAT_R32G32_SFLOAT,
1033 VK_FORMAT_R64_UINT,
1034 VK_FORMAT_R64_SINT,
1035 VK_FORMAT_R64_SFLOAT,
1036
1037 VK_FORMAT_UNDEFINED
1038 };
1039
1040 static const VkFormat compatibleFormatList96Bit[] =
1041 {
1042 VK_FORMAT_R32G32B32_UINT,
1043 VK_FORMAT_R32G32B32_SINT,
1044 VK_FORMAT_R32G32B32_SFLOAT,
1045
1046 VK_FORMAT_UNDEFINED
1047 };
1048
1049 static const VkFormat compatibleFormatList128Bit[] =
1050 {
1051 VK_FORMAT_R32G32B32A32_UINT,
1052 VK_FORMAT_R32G32B32A32_SINT,
1053 VK_FORMAT_R32G32B32A32_SFLOAT,
1054 VK_FORMAT_R64G64_UINT,
1055 VK_FORMAT_R64G64_SINT,
1056 VK_FORMAT_R64G64_SFLOAT,
1057
1058 VK_FORMAT_UNDEFINED
1059 };
1060
1061 const VkFormat compatibleFormatList192Bit[] =
1062 {
1063 VK_FORMAT_R64G64B64_UINT,
1064 VK_FORMAT_R64G64B64_SINT,
1065 VK_FORMAT_R64G64B64_SFLOAT,
1066
1067 VK_FORMAT_UNDEFINED
1068 };
1069
1070 static const VkFormat compatibleFormatList256Bit[] =
1071 {
1072 VK_FORMAT_R64G64B64A64_UINT,
1073 VK_FORMAT_R64G64B64A64_SINT,
1074 VK_FORMAT_R64G64B64A64_SFLOAT,
1075
1076 VK_FORMAT_UNDEFINED
1077 };
1078
1079 static const VkFormat* compatibleFormatsList[] =
1080 {
1081 compatibleFormatList8Bit,
1082 compatibleFormatList16Bit,
1083 compatibleFormatList24Bit,
1084 compatibleFormatList32Bit,
1085 compatibleFormatList48Bit,
1086 compatibleFormatList64Bit,
1087 compatibleFormatList96Bit,
1088 compatibleFormatList128Bit,
1089 compatibleFormatList192Bit,
1090 compatibleFormatList256Bit,
1091 };
1092
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1093 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1094 {
1095 const std::string operationName[OPERATION_LAST] =
1096 {
1097 "attachment_read",
1098 "attachment_write",
1099 "texture_read",
1100 "texture_write",
1101 };
1102 const VkImageUsageFlagBits testedImageUsageFlags[OPERATION_LAST] =
1103 {
1104 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1105 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1106 VK_IMAGE_USAGE_SAMPLED_BIT,
1107 VK_IMAGE_USAGE_STORAGE_BIT,
1108 };
1109 const VkImageUsageFlagBits pairedImageUsageFlags[OPERATION_LAST] =
1110 {
1111 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1112 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1113 VK_IMAGE_USAGE_STORAGE_BIT,
1114 VK_IMAGE_USAGE_SAMPLED_BIT,
1115 };
1116 VkImageUsageFlags baseFlagsAddOn = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1117
1118 MovePtr<tcu::TestCaseGroup> imageTranscodingTests (new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1119
1120 for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1121 {
1122 MovePtr<tcu::TestCaseGroup> imageOperationGroup (new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1123
1124 for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1125 {
1126 for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1127 {
1128 const VkFormat featuredFormat = compatibleFormatsList[groupNdx][featuredFormatNdx];
1129 const VkFormat featurelessFormat = VK_FORMAT_UNDEFINED; // Lookup process is in createInstance()
1130
1131 if (!isSupportedByFramework(featuredFormat))
1132 continue;
1133
1134 // Cannot handle SRGB in shader layout classifier
1135 if (isSrgbFormat(featuredFormat))
1136 continue;
1137
1138 // Cannot handle packed in shader layout classifier
1139 if (isPackedType(featuredFormat))
1140 continue;
1141
1142 // Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1143 if (isComponentSwizzled(featuredFormat))
1144 continue;
1145
1146 // Cannot handle three-component images in shader layout classifier
1147 if (getNumUsedChannels(featuredFormat) == 3)
1148 continue;
1149
1150 const std::string testName = getFormatShortString(featuredFormat);
1151 const TestParameters parameters =
1152 {
1153 static_cast<Operation>(operationNdx), // Operation operation
1154 UVec3(16u, 16u, 1u), // UVec3 size
1155 IMAGE_TYPE_2D, // ImageType imageType
1156 testedImageUsageFlags[operationNdx], // VkImageUsageFlagBits testedImageUsageFeature
1157 featuredFormat, // VkFormat featuredFormat
1158 featurelessFormat, // VkFormat featurelessFormat
1159 baseFlagsAddOn | testedImageUsageFlags[operationNdx], // VkImageUsageFlags testedImageUsage
1160 baseFlagsAddOn | pairedImageUsageFlags[operationNdx], // VkImageUsageFlags pairedImageUsage
1161 compatibleFormatsList[groupNdx] // const VkFormat* compatibleFormats
1162 };
1163
1164 imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1165 }
1166 }
1167
1168 imageTranscodingTests->addChild(imageOperationGroup.release());
1169 }
1170
1171 return imageTranscodingTests.release();
1172 }
1173
1174 } // image
1175 } // vkt
1176