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
43 #include "tcuTextureUtil.hpp"
44 #include "tcuTexture.hpp"
45 #include "tcuCompressedTexture.hpp"
46 #include "tcuVectorType.hpp"
47 #include "tcuResource.hpp"
48 #include "tcuImageIO.hpp"
49 #include "tcuImageCompare.hpp"
50 #include "tcuTestLog.hpp"
51 #include "tcuRGBA.hpp"
52 #include "tcuSurface.hpp"
53
54 #include <vector>
55 #include <iomanip>
56
57 using namespace vk;
58 namespace vkt
59 {
60 namespace image
61 {
62 namespace
63 {
64 using std::string;
65 using std::vector;
66 using tcu::TestContext;
67 using tcu::TestStatus;
68 using tcu::UVec3;
69 using tcu::IVec3;
70 using tcu::CompressedTexFormat;
71 using tcu::CompressedTexture;
72 using tcu::Resource;
73 using tcu::Archive;
74 using tcu::ConstPixelBufferAccess;
75 using de::MovePtr;
76 using de::SharedPtr;
77 using de::Random;
78
79 enum Operation
80 {
81 OPERATION_ATTACHMENT_READ,
82 OPERATION_ATTACHMENT_WRITE,
83 OPERATION_TEXTURE_READ,
84 OPERATION_TEXTURE_WRITE,
85 OPERATION_LAST
86 };
87
88 struct TestParameters
89 {
90 Operation operation;
91 UVec3 size;
92 ImageType imageType;
93 VkImageUsageFlagBits testedImageUsageFeature;
94 VkFormat featuredFormat;
95 VkFormat featurelessFormat;
96 VkImageUsageFlags testedImageUsage;
97 VkImageUsageFlags pairedImageUsage;
98 const VkFormat* compatibleFormats;
99 };
100
101 const deUint32 SINGLE_LEVEL = 1u;
102 const deUint32 SINGLE_LAYER = 1u;
103
104 class BasicTranscodingTestInstance : public TestInstance
105 {
106 public:
107 BasicTranscodingTestInstance (Context& context,
108 const TestParameters& parameters);
109 virtual TestStatus iterate (void) = 0;
110 protected:
111 void generateData (deUint8* toFill,
112 size_t size,
113 const VkFormat format = VK_FORMAT_UNDEFINED);
114 const TestParameters m_parameters;
115 };
116
BasicTranscodingTestInstance(Context & context,const TestParameters & parameters)117 BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters)
118 : TestInstance (context)
119 , m_parameters (parameters)
120 {
121 }
122
generateData(deUint8 * toFill,size_t size,const VkFormat format)123 void BasicTranscodingTestInstance::generateData (deUint8* toFill, size_t size, const VkFormat format)
124 {
125 const deUint8 pattern[] =
126 {
127 // 64-bit values
128 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
138 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Positive infinity
139 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Negative infinity
140 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS)
141 0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
142 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Start of a signalling NaN (NANS)
143 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
144 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ)
145 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ)
146 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Start of a quiet NaN (NANQ)
147 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ)
148 // 32-bit values
149 0x7F, 0x80, 0x00, 0x00, // Positive infinity
150 0xFF, 0x80, 0x00, 0x00, // Negative infinity
151 0x7F, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS)
152 0x7F, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
153 0xFF, 0x80, 0x00, 0x01, // Start of a signalling NaN (NANS)
154 0xFF, 0xBF, 0xFF, 0xFF, // End of a signalling NaN (NANS)
155 0x7F, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ)
156 0x7F, 0xFF, 0xFF, 0xFF, // End of of a quiet NaN (NANQ)
157 0xFF, 0xC0, 0x00, 0x00, // Start of a quiet NaN (NANQ)
158 0xFF, 0xFF, 0xFF, 0xFF, // End of a quiet NaN (NANQ)
159 0xAA, 0xAA, 0xAA, 0xAA,
160 0x55, 0x55, 0x55, 0x55,
161 };
162
163 deUint8* start = toFill;
164 size_t sizeToRnd = size;
165
166 // Pattern part
167 if (size >= 2 * sizeof(pattern))
168 {
169 // Rotated pattern
170 for (size_t i = 0; i < sizeof(pattern); i++)
171 start[sizeof(pattern) - i - 1] = pattern[i];
172
173 start += sizeof(pattern);
174 sizeToRnd -= sizeof(pattern);
175
176 // Direct pattern
177 deMemcpy(start, pattern, sizeof(pattern));
178
179 start += sizeof(pattern);
180 sizeToRnd -= sizeof(pattern);
181 }
182
183 // Random part
184 {
185 DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0);
186
187 deUint32* start32 = reinterpret_cast<deUint32*>(start);
188 size_t sizeToRnd32 = sizeToRnd / sizeof(deUint32);
189 Random rnd (static_cast<deUint32>(format));
190
191 for (size_t i = 0; i < sizeToRnd32; i++)
192 start32[i] = rnd.getUint32();
193 }
194
195 {
196 // Remove certain values that may not be preserved based on the uncompressed view format
197 if (isSnormFormat(m_parameters.featuredFormat))
198 {
199 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
200
201 if (textureFormat.type == tcu::TextureFormat::SNORM_INT8)
202 {
203 for (size_t i = 0; i < size; i++)
204 {
205 // SNORM fix: due to write operation in SNORM format
206 // replaces 0x80 to 0x81, remove these values from test
207 if (toFill[i] == 0x80)
208 toFill[i] = 0x81;
209 }
210 }
211 else
212 {
213 for (size_t i = 0; i < size; i += 2)
214 {
215 // SNORM fix: due to write operation in SNORM format
216 // replaces 0x00 0x80 to 0x01 0x80
217 if (toFill[i] == 0x00 && toFill[i+1] == 0x80)
218 toFill[i+1] = 0x81;
219 }
220 }
221 }
222 else if (isFloatFormat(m_parameters.featuredFormat))
223 {
224 tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
225
226 if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
227 {
228 for (size_t i = 0; i < size; i += 2)
229 {
230 // HALF_FLOAT fix: remove INF and NaN
231 if ((toFill[i+1] & 0x7C) == 0x7C)
232 toFill[i+1] = 0x00;
233 }
234 }
235 else if (textureFormat.type == tcu::TextureFormat::FLOAT)
236 {
237 for (size_t i = 0; i < size; i += 4)
238 {
239 // HALF_FLOAT fix: remove INF and NaN
240 if ((toFill[i+1] & 0x7C) == 0x7C)
241 toFill[i+1] = 0x00;
242 }
243
244 for (size_t i = 0; i < size; i += 4)
245 {
246 // FLOAT fix: remove INF, NaN, and denorm
247 // Little endian fix
248 if (((toFill[i+3] & 0x7F) == 0x7F && (toFill[i+2] & 0x80) == 0x80) || ((toFill[i+3] & 0x7F) == 0x00 && (toFill[i+2] & 0x80) == 0x00))
249 toFill[i+3] = 0x01;
250 // Big endian fix
251 if (((toFill[i+0] & 0x7F) == 0x7F && (toFill[i+1] & 0x80) == 0x80) || ((toFill[i+0] & 0x7F) == 0x00 && (toFill[i+1] & 0x80) == 0x00))
252 toFill[i+0] = 0x01;
253 }
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 (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, 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, 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 bool isFormatUsageFlagSupported (Context& context,
717 const VkFormat format,
718 VkImageUsageFlags formatUsageFlags) const;
719
720 protected:
721 const TestParameters m_parameters;
722 };
723
ImageTranscodingCase(TestContext & testCtx,const std::string & name,const std::string & desc,const TestParameters & parameters)724 ImageTranscodingCase::ImageTranscodingCase (TestContext& testCtx, const std::string& name, const std::string& desc, const TestParameters& parameters)
725 : TestCase (testCtx, name, desc)
726 , m_parameters (parameters)
727 {
728 }
729
initPrograms(vk::SourceCollections & programCollection) const730 void ImageTranscodingCase::initPrograms (vk::SourceCollections& programCollection) const
731 {
732 DE_ASSERT(m_parameters.size.x() > 0);
733 DE_ASSERT(m_parameters.size.y() > 0);
734
735 ImageType imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
736
737 // Vertex shader
738 {
739 std::ostringstream src;
740 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
741 << "layout(location = 0) in vec4 v_in_position;\n"
742 << "\n"
743 << "void main (void)\n"
744 << "{\n"
745 << " gl_Position = v_in_position;\n"
746 << "}\n";
747
748 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
749 }
750
751 // Fragment shader
752 {
753 switch(m_parameters.operation)
754 {
755 case OPERATION_ATTACHMENT_READ:
756 case OPERATION_ATTACHMENT_WRITE:
757 {
758 std::ostringstream src;
759
760 const std::string dstTypeStr = getGlslAttachmentType(m_parameters.featuredFormat);
761 const std::string srcTypeStr = getGlslInputAttachmentType(m_parameters.featuredFormat);
762
763 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
764 << "precision highp int;\n"
765 << "precision highp float;\n"
766 << "\n"
767 << "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
768 << "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr << " inputImage1;\n"
769 << "\n"
770 << "void main (void)\n"
771 << "{\n"
772 << " o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
773 << "}\n";
774
775 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
776
777 break;
778 }
779
780 case OPERATION_TEXTURE_READ:
781 case OPERATION_TEXTURE_WRITE:
782 {
783 std::ostringstream src;
784
785 const std::string srcSamplerTypeStr = getGlslSamplerType(mapVkFormat(m_parameters.featuredFormat), mapImageViewType(imageTypeForFS));
786 const std::string dstImageTypeStr = getShaderImageType(mapVkFormat(m_parameters.featuredFormat), imageTypeForFS);
787 const std::string dstFormatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_parameters.featuredFormat));
788
789 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
790 << "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
791 << "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr << " u_imageOut;\n"
792 << "\n"
793 << "void main (void)\n"
794 << "{\n"
795 << " const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
796 << " const ivec2 pixels_resolution = ivec2(textureSize(u_imageIn, 0)) - ivec2(1,1);\n"
797 << " const vec2 in_pos = vec2(out_pos) / vec2(pixels_resolution);\n"
798 << " imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
799 << "}\n";
800
801 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
802
803 break;
804 }
805
806 default:
807 DE_ASSERT(false);
808 }
809 }
810 }
811
isFormatUsageFlagSupported(Context & context,const VkFormat format,VkImageUsageFlags formatUsageFlags) const812 bool ImageTranscodingCase::isFormatUsageFlagSupported (Context& context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const
813 {
814 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
815 const InstanceInterface& vk = context.getInstanceInterface();
816 VkImageFormatProperties imageFormatProperties;
817 const VkResult queryResult = vk.getPhysicalDeviceImageFormatProperties(
818 physicalDevice,
819 format,
820 mapImageType(m_parameters.imageType),
821 VK_IMAGE_TILING_OPTIMAL,
822 formatUsageFlags,
823 VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR,
824 &imageFormatProperties);
825
826 return (queryResult == VK_SUCCESS);
827 }
828
createInstance(Context & context) const829 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
830 {
831 VkFormat featuredFormat = m_parameters.featuredFormat;
832 VkFormat featurelessFormat = VK_FORMAT_UNDEFINED;
833 bool differenceFound = false;
834
835 DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
836
837 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2"))
838 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported");
839
840 if (!isFormatUsageFlagSupported(context, featuredFormat, m_parameters.testedImageUsageFeature))
841 TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
842
843 if (!isFormatUsageFlagSupported(context, featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
844 TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
845
846 for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
847 {
848 featurelessFormat = m_parameters.compatibleFormats[i];
849
850 if (isSupportedByFramework(featurelessFormat)
851 && !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
852 && isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
853 )
854 {
855 differenceFound = true;
856
857 break;
858 }
859 }
860
861 if (differenceFound)
862 {
863 TestParameters calculatedParameters =
864 {
865 m_parameters.operation, // Operation operation
866 m_parameters.size, // UVec3 size
867 m_parameters.imageType, // ImageType imageType
868 m_parameters.testedImageUsageFeature, // VkImageUsageFlagBits testedImageUsageFeature
869 m_parameters.featuredFormat, // VkFormat featuredFormat
870 featurelessFormat, // VkFormat featurelessFormat
871 m_parameters.testedImageUsage, // VkImageUsageFlags testedImageUsage
872 m_parameters.pairedImageUsage, // VkImageUsageFlags pairedImageUsage
873 DE_NULL, // const VkFormat* compatibleFormats
874 };
875
876 switch (m_parameters.operation)
877 {
878 case OPERATION_ATTACHMENT_READ:
879 case OPERATION_ATTACHMENT_WRITE:
880 return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
881
882 case OPERATION_TEXTURE_READ:
883 case OPERATION_TEXTURE_WRITE:
884 return new GraphicsTextureTestInstance(context, calculatedParameters);
885
886 default:
887 TCU_THROW(InternalError, "Impossible");
888 }
889 }
890 else
891 TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
892 }
893
894 } // anonymous ns
895
896 static const VkFormat compatibleFormatList8Bit[] =
897 {
898 VK_FORMAT_R4G4_UNORM_PACK8,
899 VK_FORMAT_R8_UNORM,
900 VK_FORMAT_R8_SNORM,
901 VK_FORMAT_R8_USCALED,
902 VK_FORMAT_R8_SSCALED,
903 VK_FORMAT_R8_UINT,
904 VK_FORMAT_R8_SINT,
905 VK_FORMAT_R8_SRGB,
906
907 VK_FORMAT_UNDEFINED
908 };
909
910 static const VkFormat compatibleFormatList16Bit[] =
911 {
912 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
913 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
914 VK_FORMAT_R5G6B5_UNORM_PACK16,
915 VK_FORMAT_B5G6R5_UNORM_PACK16,
916 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
917 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
918 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
919 VK_FORMAT_R8G8_UNORM,
920 VK_FORMAT_R8G8_SNORM,
921 VK_FORMAT_R8G8_USCALED,
922 VK_FORMAT_R8G8_SSCALED,
923 VK_FORMAT_R8G8_UINT,
924 VK_FORMAT_R8G8_SINT,
925 VK_FORMAT_R8G8_SRGB,
926 VK_FORMAT_R16_UNORM,
927 VK_FORMAT_R16_SNORM,
928 VK_FORMAT_R16_USCALED,
929 VK_FORMAT_R16_SSCALED,
930 VK_FORMAT_R16_UINT,
931 VK_FORMAT_R16_SINT,
932 VK_FORMAT_R16_SFLOAT,
933
934 VK_FORMAT_UNDEFINED
935 };
936
937 static const VkFormat compatibleFormatList24Bit[] =
938 {
939 VK_FORMAT_R8G8B8_UNORM,
940 VK_FORMAT_R8G8B8_SNORM,
941 VK_FORMAT_R8G8B8_USCALED,
942 VK_FORMAT_R8G8B8_SSCALED,
943 VK_FORMAT_R8G8B8_UINT,
944 VK_FORMAT_R8G8B8_SINT,
945 VK_FORMAT_R8G8B8_SRGB,
946 VK_FORMAT_B8G8R8_UNORM,
947 VK_FORMAT_B8G8R8_SNORM,
948 VK_FORMAT_B8G8R8_USCALED,
949 VK_FORMAT_B8G8R8_SSCALED,
950 VK_FORMAT_B8G8R8_UINT,
951 VK_FORMAT_B8G8R8_SINT,
952 VK_FORMAT_B8G8R8_SRGB,
953
954 VK_FORMAT_UNDEFINED
955 };
956
957 static const VkFormat compatibleFormatList32Bit[] =
958 {
959 VK_FORMAT_R8G8B8A8_UNORM,
960 VK_FORMAT_R8G8B8A8_SNORM,
961 VK_FORMAT_R8G8B8A8_USCALED,
962 VK_FORMAT_R8G8B8A8_SSCALED,
963 VK_FORMAT_R8G8B8A8_UINT,
964 VK_FORMAT_R8G8B8A8_SINT,
965 VK_FORMAT_R8G8B8A8_SRGB,
966 VK_FORMAT_B8G8R8A8_UNORM,
967 VK_FORMAT_B8G8R8A8_SNORM,
968 VK_FORMAT_B8G8R8A8_USCALED,
969 VK_FORMAT_B8G8R8A8_SSCALED,
970 VK_FORMAT_B8G8R8A8_UINT,
971 VK_FORMAT_B8G8R8A8_SINT,
972 VK_FORMAT_B8G8R8A8_SRGB,
973 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
974 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
975 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
976 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
977 VK_FORMAT_A8B8G8R8_UINT_PACK32,
978 VK_FORMAT_A8B8G8R8_SINT_PACK32,
979 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
980 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
981 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
982 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
983 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
984 VK_FORMAT_A2R10G10B10_UINT_PACK32,
985 VK_FORMAT_A2R10G10B10_SINT_PACK32,
986 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
987 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
988 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
989 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
990 VK_FORMAT_A2B10G10R10_UINT_PACK32,
991 VK_FORMAT_A2B10G10R10_SINT_PACK32,
992 VK_FORMAT_R16G16_UNORM,
993 VK_FORMAT_R16G16_SNORM,
994 VK_FORMAT_R16G16_USCALED,
995 VK_FORMAT_R16G16_SSCALED,
996 VK_FORMAT_R16G16_UINT,
997 VK_FORMAT_R16G16_SINT,
998 VK_FORMAT_R16G16_SFLOAT,
999 VK_FORMAT_R32_UINT,
1000 VK_FORMAT_R32_SINT,
1001 VK_FORMAT_R32_SFLOAT,
1002
1003 VK_FORMAT_UNDEFINED
1004 };
1005
1006 static const VkFormat compatibleFormatList48Bit[] =
1007 {
1008 VK_FORMAT_R16G16B16_UNORM,
1009 VK_FORMAT_R16G16B16_SNORM,
1010 VK_FORMAT_R16G16B16_USCALED,
1011 VK_FORMAT_R16G16B16_SSCALED,
1012 VK_FORMAT_R16G16B16_UINT,
1013 VK_FORMAT_R16G16B16_SINT,
1014 VK_FORMAT_R16G16B16_SFLOAT,
1015
1016 VK_FORMAT_UNDEFINED
1017 };
1018
1019 static const VkFormat compatibleFormatList64Bit[] =
1020 {
1021 VK_FORMAT_R16G16B16A16_UNORM,
1022 VK_FORMAT_R16G16B16A16_SNORM,
1023 VK_FORMAT_R16G16B16A16_USCALED,
1024 VK_FORMAT_R16G16B16A16_SSCALED,
1025 VK_FORMAT_R16G16B16A16_UINT,
1026 VK_FORMAT_R16G16B16A16_SINT,
1027 VK_FORMAT_R16G16B16A16_SFLOAT,
1028 VK_FORMAT_R32G32_UINT,
1029 VK_FORMAT_R32G32_SINT,
1030 VK_FORMAT_R32G32_SFLOAT,
1031 VK_FORMAT_R64_UINT,
1032 VK_FORMAT_R64_SINT,
1033 VK_FORMAT_R64_SFLOAT,
1034
1035 VK_FORMAT_UNDEFINED
1036 };
1037
1038 static const VkFormat compatibleFormatList96Bit[] =
1039 {
1040 VK_FORMAT_R32G32B32_UINT,
1041 VK_FORMAT_R32G32B32_SINT,
1042 VK_FORMAT_R32G32B32_SFLOAT,
1043
1044 VK_FORMAT_UNDEFINED
1045 };
1046
1047 static const VkFormat compatibleFormatList128Bit[] =
1048 {
1049 VK_FORMAT_R32G32B32A32_UINT,
1050 VK_FORMAT_R32G32B32A32_SINT,
1051 VK_FORMAT_R32G32B32A32_SFLOAT,
1052 VK_FORMAT_R64G64_UINT,
1053 VK_FORMAT_R64G64_SINT,
1054 VK_FORMAT_R64G64_SFLOAT,
1055
1056 VK_FORMAT_UNDEFINED
1057 };
1058
1059 const VkFormat compatibleFormatList192Bit[] =
1060 {
1061 VK_FORMAT_R64G64B64_UINT,
1062 VK_FORMAT_R64G64B64_SINT,
1063 VK_FORMAT_R64G64B64_SFLOAT,
1064
1065 VK_FORMAT_UNDEFINED
1066 };
1067
1068 static const VkFormat compatibleFormatList256Bit[] =
1069 {
1070 VK_FORMAT_R64G64B64A64_UINT,
1071 VK_FORMAT_R64G64B64A64_SINT,
1072 VK_FORMAT_R64G64B64A64_SFLOAT,
1073
1074 VK_FORMAT_UNDEFINED
1075 };
1076
1077 static const VkFormat* compatibleFormatsList[] =
1078 {
1079 compatibleFormatList8Bit,
1080 compatibleFormatList16Bit,
1081 compatibleFormatList24Bit,
1082 compatibleFormatList32Bit,
1083 compatibleFormatList48Bit,
1084 compatibleFormatList64Bit,
1085 compatibleFormatList96Bit,
1086 compatibleFormatList128Bit,
1087 compatibleFormatList192Bit,
1088 compatibleFormatList256Bit,
1089 };
1090
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1091 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1092 {
1093 const std::string operationName[OPERATION_LAST] =
1094 {
1095 "attachment_read",
1096 "attachment_write",
1097 "texture_read",
1098 "texture_write",
1099 };
1100 const VkImageUsageFlagBits testedImageUsageFlags[OPERATION_LAST] =
1101 {
1102 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1103 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1104 VK_IMAGE_USAGE_SAMPLED_BIT,
1105 VK_IMAGE_USAGE_STORAGE_BIT,
1106 };
1107 const VkImageUsageFlagBits pairedImageUsageFlags[OPERATION_LAST] =
1108 {
1109 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1110 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1111 VK_IMAGE_USAGE_STORAGE_BIT,
1112 VK_IMAGE_USAGE_SAMPLED_BIT,
1113 };
1114 VkImageUsageFlags baseFlagsAddOn = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1115
1116 MovePtr<tcu::TestCaseGroup> imageTranscodingTests (new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1117
1118 for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1119 {
1120 MovePtr<tcu::TestCaseGroup> imageOperationGroup (new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1121
1122 for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1123 {
1124 for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1125 {
1126 const VkFormat featuredFormat = compatibleFormatsList[groupNdx][featuredFormatNdx];
1127 const VkFormat featurelessFormat = VK_FORMAT_UNDEFINED; // Lookup process is in createInstance()
1128
1129 if (!isSupportedByFramework(featuredFormat))
1130 continue;
1131
1132 // Cannot handle SRGB in shader layout classifier
1133 if (isSrgbFormat(featuredFormat))
1134 continue;
1135
1136 // Cannot handle packed in shader layout classifier
1137 if (isPackedType(featuredFormat))
1138 continue;
1139
1140 // Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1141 if (isComponentSwizzled(featuredFormat))
1142 continue;
1143
1144 // Cannot handle three-component images in shader layout classifier
1145 if (getNumUsedChannels(featuredFormat) == 3)
1146 continue;
1147
1148 const std::string testName = getFormatShortString(featuredFormat);
1149 const TestParameters parameters =
1150 {
1151 static_cast<Operation>(operationNdx), // Operation operation
1152 UVec3(16u, 16u, 1u), // UVec3 size
1153 IMAGE_TYPE_2D, // ImageType imageType
1154 testedImageUsageFlags[operationNdx], // VkImageUsageFlagBits testedImageUsageFeature
1155 featuredFormat, // VkFormat featuredFormat
1156 featurelessFormat, // VkFormat featurelessFormat
1157 baseFlagsAddOn | testedImageUsageFlags[operationNdx], // VkImageUsageFlags testedImageUsage
1158 baseFlagsAddOn | pairedImageUsageFlags[operationNdx], // VkImageUsageFlags pairedImageUsage
1159 compatibleFormatsList[groupNdx] // const VkFormat* compatibleFormats
1160 };
1161
1162 imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1163 }
1164 }
1165
1166 imageTranscodingTests->addChild(imageOperationGroup.release());
1167 }
1168
1169 return imageTranscodingTests.release();
1170 }
1171
1172 } // image
1173 } // vkt
1174