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