1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 The Android Open Source Project
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Image size Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktImageSizeTests.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktImageTestsUtil.hpp"
28 #include "vktImageTexture.hpp"
29
30 #include "vkDefs.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkBarrierUtil.hpp"
37 #include "vkBuilderUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "vkBufferWithMemory.hpp"
42
43 #include "deUniquePtr.hpp"
44 #include "deStringUtil.hpp"
45
46 #include <string>
47
48 using namespace vk;
49
50 namespace vkt
51 {
52 namespace image
53 {
54 namespace
55 {
56
57 //! Get a texture based on image type and suggested size.
getTexture(const ImageType imageType, const tcu::IVec3& size)58 Texture getTexture (const ImageType imageType, const tcu::IVec3& size)
59 {
60 switch (imageType)
61 {
62 case IMAGE_TYPE_1D:
63 case IMAGE_TYPE_BUFFER:
64 return Texture(imageType, tcu::IVec3(size.x(), 1, 1), 1);
65
66 case IMAGE_TYPE_1D_ARRAY:
67 return Texture(imageType, tcu::IVec3(size.x(), 1, 1), size.y());
68
69 case IMAGE_TYPE_2D:
70 return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), 1);
71
72 case IMAGE_TYPE_2D_ARRAY:
73 return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), size.z());
74
75 case IMAGE_TYPE_CUBE:
76 return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 6);
77
78 case IMAGE_TYPE_CUBE_ARRAY:
79 return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 2*6);
80
81 case IMAGE_TYPE_3D:
82 return Texture(imageType, size, 1);
83
84 default:
85 DE_FATAL("Internal error");
86 return Texture(IMAGE_TYPE_LAST, tcu::IVec3(), 0);
87 }
88 }
89
makeImageCreateInfo(const Texture& texture, const VkFormat format, const bool is2DViewOf3D)90 inline VkImageCreateInfo makeImageCreateInfo (const Texture& texture, const VkFormat format, const bool is2DViewOf3D)
91 {
92 VkImageViewCreateFlags createFlags = 0u;
93
94 if (isCube(texture))
95 createFlags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
96 #ifndef CTS_USES_VULKANSC
97 else if (is2DViewOf3D)
98 createFlags |= VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT;
99 #else
100 DE_UNREF(is2DViewOf3D);
101 #endif // CTS_USES_VULKANSC
102
103 const VkImageCreateInfo imageParams =
104 {
105 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
106 DE_NULL, // const void* pNext;
107 createFlags, // VkImageCreateFlags flags;
108 mapImageType(texture.type()), // VkImageType imageType;
109 format, // VkFormat format;
110 makeExtent3D(texture.layerSize()), // VkExtent3D extent;
111 1u, // deUint32 mipLevels;
112 (deUint32)texture.numLayers(), // deUint32 arrayLayers;
113 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
114 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
115 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
116 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
117 0u, // deUint32 queueFamilyIndexCount;
118 DE_NULL, // const deUint32* pQueueFamilyIndices;
119 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
120 };
121 return imageParams;
122 }
123
124 //! Interpret the memory as IVec3
readIVec3(const void* const data)125 inline tcu::IVec3 readIVec3 (const void* const data)
126 {
127 const int* const p = reinterpret_cast<const int*>(data);
128 return tcu::IVec3(p[0], p[1], p[2]);
129 }
130
getExpectedImageSizeResult(const Texture& texture, const bool is2DViewOf3D)131 tcu::IVec3 getExpectedImageSizeResult (const Texture& texture, const bool is2DViewOf3D)
132 {
133 // GLSL imageSize() function returns:
134 // z = 0 for cubes
135 // z = N for cube arrays, where N is the number of cubes
136 // y or z = L where L is the number of layers for other array types (e.g. 1D array, 2D array)
137 // z = D where D is the depth of 3d image
138
139 const tcu::IVec3 size = texture.size();
140 const int numCubeFaces = 6;
141
142 switch (texture.type())
143 {
144 case IMAGE_TYPE_1D:
145 case IMAGE_TYPE_BUFFER:
146 return tcu::IVec3(size.x(), 0, 0);
147
148 case IMAGE_TYPE_1D_ARRAY:
149 case IMAGE_TYPE_2D:
150 case IMAGE_TYPE_CUBE:
151 return tcu::IVec3(size.x(), size.y(), 0);
152
153 case IMAGE_TYPE_2D_ARRAY:
154 case IMAGE_TYPE_3D:
155 {
156 if (is2DViewOf3D)
157 return tcu::IVec3(size.x(), size.y(), 0);
158 return size;
159 }
160
161 case IMAGE_TYPE_CUBE_ARRAY:
162 return tcu::IVec3(size.x(), size.y(), size.z() / numCubeFaces);
163
164 default:
165 DE_FATAL("Internal error");
166 return tcu::IVec3();
167 }
168 }
169
170 class SizeTest : public TestCase
171 {
172 public:
173 enum TestFlags
174 {
175 FLAG_READONLY_IMAGE = 1u << 0,
176 FLAG_WRITEONLY_IMAGE = 1u << 1,
177 };
178
179 SizeTest (tcu::TestContext& testCtx,
180 const std::string& name,
181 const Texture& texture,
182 const VkFormat format,
183 const deUint32 flags,
184 const bool is2DViewOf3D);
185
186 void initPrograms (SourceCollections& programCollection) const;
187 TestInstance* createInstance (Context& context) const;
188 virtual void checkSupport (Context& context) const;
189
190 private:
191 const Texture m_texture;
192 const VkFormat m_format;
193 const bool m_useReadonly;
194 const bool m_useWriteonly;
195 const bool m_2DViewOf3D;
196 };
197
SizeTest(tcu::TestContext& testCtx, const std::string& name, const Texture& texture, const VkFormat format, const deUint32 flags, const bool is2DViewOf3D)198 SizeTest::SizeTest (tcu::TestContext& testCtx,
199 const std::string& name,
200 const Texture& texture,
201 const VkFormat format,
202 const deUint32 flags,
203 const bool is2DViewOf3D)
204 : TestCase (testCtx, name)
205 , m_texture (texture)
206 , m_format (format)
207 , m_useReadonly ((flags & FLAG_READONLY_IMAGE) != 0)
208 , m_useWriteonly ((flags & FLAG_WRITEONLY_IMAGE) != 0)
209 , m_2DViewOf3D (is2DViewOf3D)
210 {
211 // We expect at least one flag to be set.
212 DE_ASSERT(m_useReadonly || m_useWriteonly);
213
214 // For 2D views of 3D we need 3D images.
215 DE_ASSERT(!m_2DViewOf3D || m_texture.type() == IMAGE_TYPE_3D);
216 }
217
checkSupport(Context& context) const218 void SizeTest::checkSupport (Context& context) const
219 {
220 const auto imgType = m_texture.type();
221
222 if (imgType == IMAGE_TYPE_CUBE_ARRAY)
223 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);
224
225 if (imgType != IMAGE_TYPE_BUFFER)
226 {
227 const auto& vki = context.getInstanceInterface();
228 const auto physicalDevice = context.getPhysicalDevice();
229 const auto createInfo = makeImageCreateInfo(m_texture, m_format, m_2DViewOf3D);
230 VkImageFormatProperties formatProperties;
231
232 const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, createInfo.format, createInfo.imageType, createInfo.tiling, createInfo.usage, createInfo.flags, &formatProperties);
233
234 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
235 TCU_THROW(NotSupportedError, "Format not supported for the specified usage");
236 }
237
238 if (m_2DViewOf3D)
239 context.requireDeviceFunctionality("VK_EXT_image_2d_view_of_3d");
240 }
241
initPrograms(SourceCollections& programCollection) const242 void SizeTest::initPrograms (SourceCollections& programCollection) const
243 {
244 const std::string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_format));
245 const std::string imageTypeStr = getShaderImageType(mapVkFormat(m_format), (m_2DViewOf3D ? IMAGE_TYPE_2D : m_texture.type()));
246 const int dimension = m_texture.dimension();
247
248 std::ostringstream accessQualifier;
249 if (m_useReadonly)
250 accessQualifier << " readonly";
251 if (m_useWriteonly)
252 accessQualifier << " writeonly";
253
254 std::ostringstream src;
255 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
256 << "\n"
257 << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
258 << "layout (binding = 0, " << formatQualifierStr << ")" << accessQualifier.str() << " uniform highp " << imageTypeStr << " u_image;\n"
259 << "layout (binding = 1) writeonly buffer Output {\n"
260 << " ivec3 size;\n"
261 << "} sb_out;\n"
262 << "\n"
263 << "void main (void)\n"
264 << "{\n"
265 << (dimension == 1 ?
266 " sb_out.size = ivec3(imageSize(u_image), 0, 0);\n"
267 : dimension == 2 || m_2DViewOf3D || m_texture.type() == IMAGE_TYPE_CUBE ? // cubes return ivec2
268 " sb_out.size = ivec3(imageSize(u_image), 0);\n"
269 : dimension == 3 ? // cube arrays return ivec3
270 " sb_out.size = imageSize(u_image);\n"
271 : "")
272 << "}\n";
273
274 programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
275 }
276
277 //! Build a case name, e.g. "readonly_writeonly_32x32"
getCaseName(const Texture& texture, const deUint32 flags, const bool is2DViewOf3D)278 std::string getCaseName (const Texture& texture, const deUint32 flags, const bool is2DViewOf3D)
279 {
280 std::ostringstream str;
281 str << ((flags & SizeTest::FLAG_READONLY_IMAGE) != 0 ? "readonly_" : "")
282 << ((flags & SizeTest::FLAG_WRITEONLY_IMAGE) != 0 ? "writeonly_" : "");
283
284 if (is2DViewOf3D)
285 str << "2d_view_";
286
287 const int numComponents = texture.dimension();
288 for (int i = 0; i < numComponents; ++i)
289 str << (i == 0 ? "" : "x") << texture.size()[i];
290
291 return str.str();
292 }
293
294 //! Base test instance for image and buffer tests
295 class SizeTestInstance : public TestInstance
296 {
297 public:
298 SizeTestInstance (Context& context,
299 const Texture& texture,
300 const VkFormat format,
301 const bool is2DViewOf3D = false);
302
303 tcu::TestStatus iterate (void);
~SizeTestInstance(void)304 virtual ~SizeTestInstance (void) {}
305
306 protected:
307 virtual VkDescriptorSetLayout prepareDescriptors (void) = 0;
308 virtual VkDescriptorSet getDescriptorSet (void) const = 0;
309 virtual void commandBeforeCompute (const VkCommandBuffer cmdBuffer) = 0;
310
311 const Texture m_texture;
312 const VkFormat m_format;
313 const VkDeviceSize m_resultBufferSizeBytes;
314 const bool m_2DViewOf3D;
315 de::MovePtr<BufferWithMemory> m_resultBuffer; //!< Shader writes the output here.
316 };
317
SizeTestInstance(Context& context, const Texture& texture, const VkFormat format, const bool is2DViewOf3D)318 SizeTestInstance::SizeTestInstance (Context& context, const Texture& texture, const VkFormat format, const bool is2DViewOf3D)
319 : TestInstance (context)
320 , m_texture (texture)
321 , m_format (format)
322 , m_resultBufferSizeBytes (3 * sizeof(deUint32)) // ivec3 in shader
323 , m_2DViewOf3D (is2DViewOf3D)
324 {
325 const DeviceInterface& vk = m_context.getDeviceInterface();
326 const VkDevice device = m_context.getDevice();
327 Allocator& allocator = m_context.getDefaultAllocator();
328
329 // Create an SSBO for shader output.
330
331 m_resultBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(
332 vk, device, allocator,
333 makeBufferCreateInfo(m_resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
334 MemoryRequirement::HostVisible));
335 }
336
iterate(void)337 tcu::TestStatus SizeTestInstance::iterate (void)
338 {
339 const DeviceInterface& vk = m_context.getDeviceInterface();
340 const VkDevice device = m_context.getDevice();
341 const VkQueue queue = m_context.getUniversalQueue();
342 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
343
344 // Create memory barriers.
345
346 const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
347 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
348 m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
349
350 // Create the pipeline.
351
352 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
353
354 const VkDescriptorSetLayout descriptorSetLayout = prepareDescriptors();
355 const VkDescriptorSet descriptorSet = getDescriptorSet();
356
357 const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, descriptorSetLayout));
358 const Unique<VkPipeline> pipeline(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
359
360 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
361 const Unique<VkCommandBuffer> cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
362
363 beginCommandBuffer(vk, *cmdBuffer);
364
365 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
366 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
367
368 commandBeforeCompute(*cmdBuffer);
369 vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
370 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &shaderWriteBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
371
372 endCommandBuffer(vk, *cmdBuffer);
373
374 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
375
376 // Compare the result.
377
378 const Allocation& bufferAlloc = m_resultBuffer->getAllocation();
379 invalidateAlloc(vk, device, bufferAlloc);
380
381 const tcu::IVec3 resultSize = readIVec3(bufferAlloc.getHostPtr());
382 const tcu::IVec3 expectedSize = getExpectedImageSizeResult(m_texture, m_2DViewOf3D);
383
384 if (resultSize != expectedSize)
385 return tcu::TestStatus::fail("Incorrect imageSize(): expected " + de::toString(expectedSize) + " but got " + de::toString(resultSize));
386 else
387 return tcu::TestStatus::pass("Passed");
388 }
389
390 class ImageSizeTestInstance : public SizeTestInstance
391 {
392 public:
393 ImageSizeTestInstance (Context& context,
394 const Texture& texture,
395 const VkFormat format,
396 const bool is2DViewOf3D);
397
398 protected:
399 VkDescriptorSetLayout prepareDescriptors (void);
400 void commandBeforeCompute (const VkCommandBuffer cmdBuffer);
401
getDescriptorSet(void) const402 VkDescriptorSet getDescriptorSet (void) const { return *m_descriptorSet; }
403
404 de::MovePtr<Image> m_image;
405 Move<VkImageView> m_imageView;
406 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
407 Move<VkDescriptorPool> m_descriptorPool;
408 Move<VkDescriptorSet> m_descriptorSet;
409 };
410
ImageSizeTestInstance(Context& context, const Texture& texture, const VkFormat format, const bool is2DViewOf3D)411 ImageSizeTestInstance::ImageSizeTestInstance (Context& context, const Texture& texture, const VkFormat format, const bool is2DViewOf3D)
412 : SizeTestInstance (context, texture, format, is2DViewOf3D)
413 {
414 const DeviceInterface& vk = m_context.getDeviceInterface();
415 const VkDevice device = m_context.getDevice();
416 Allocator& allocator = m_context.getDefaultAllocator();
417
418 // Create an image. Its data will be uninitialized, as we're not reading from it.
419
420 m_image = de::MovePtr<Image>(new Image(vk, device, allocator, makeImageCreateInfo(m_texture, m_format, m_2DViewOf3D), MemoryRequirement::Any));
421
422 const auto baseLayer = (m_2DViewOf3D ? static_cast<uint32_t>(m_texture.size().z() / 2) : 0u);
423 const auto viewType = (m_2DViewOf3D ? VK_IMAGE_VIEW_TYPE_2D : mapImageViewType(m_texture.type()));
424 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseLayer, m_texture.numLayers());
425
426 m_imageView = makeImageView(vk, device, m_image->get(), viewType, m_format, subresourceRange);
427 }
428
prepareDescriptors(void)429 VkDescriptorSetLayout ImageSizeTestInstance::prepareDescriptors (void)
430 {
431 const DeviceInterface& vk = m_context.getDeviceInterface();
432 const VkDevice device = m_context.getDevice();
433
434 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
435 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
436 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
437 .build(vk, device);
438
439 m_descriptorPool = DescriptorPoolBuilder()
440 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
441 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
442 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
443
444 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
445
446 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
447 const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
448
449 DescriptorSetUpdateBuilder()
450 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
451 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
452 .update(vk, device);
453
454 return *m_descriptorSetLayout;
455 }
456
commandBeforeCompute(const VkCommandBuffer cmdBuffer)457 void ImageSizeTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer)
458 {
459 const DeviceInterface& vk = m_context.getDeviceInterface();
460
461 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers());
462 const VkImageMemoryBarrier barrierSetImageLayout = makeImageMemoryBarrier(
463 0u, VK_ACCESS_SHADER_READ_BIT,
464 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
465 m_image->get(), subresourceRange);
466
467 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &barrierSetImageLayout);
468 }
469
470 class BufferSizeTestInstance : public SizeTestInstance
471 {
472 public:
473 BufferSizeTestInstance (Context& context,
474 const Texture& texture,
475 const VkFormat format);
476
477 protected:
478 VkDescriptorSetLayout prepareDescriptors (void);
479
commandBeforeCompute(const VkCommandBuffer)480 void commandBeforeCompute (const VkCommandBuffer) {}
getDescriptorSet(void) const481 VkDescriptorSet getDescriptorSet (void) const { return *m_descriptorSet; }
482
483 de::MovePtr<BufferWithMemory> m_imageBuffer;
484 Move<VkBufferView> m_bufferView;
485 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
486 Move<VkDescriptorPool> m_descriptorPool;
487 Move<VkDescriptorSet> m_descriptorSet;
488 };
489
BufferSizeTestInstance(Context& context, const Texture& texture, const VkFormat format)490 BufferSizeTestInstance::BufferSizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
491 : SizeTestInstance (context, texture, format)
492 {
493 const DeviceInterface& vk = m_context.getDeviceInterface();
494 const VkDevice device = m_context.getDevice();
495 Allocator& allocator = m_context.getDefaultAllocator();
496
497 // Create a texel storage buffer. Its data be uninitialized, as we're not reading from it.
498
499 const VkDeviceSize imageSizeBytes = getImageSizeBytes(m_texture.size(), m_format);
500 m_imageBuffer = de::MovePtr<BufferWithMemory>(new BufferWithMemory(vk, device, allocator,
501 makeBufferCreateInfo(imageSizeBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), MemoryRequirement::Any));
502
503 m_bufferView = makeBufferView(vk, device, m_imageBuffer->get(), m_format, 0ull, imageSizeBytes);
504 }
505
prepareDescriptors(void)506 VkDescriptorSetLayout BufferSizeTestInstance::prepareDescriptors (void)
507 {
508 const DeviceInterface& vk = m_context.getDeviceInterface();
509 const VkDevice device = m_context.getDevice();
510
511 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
512 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
513 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
514 .build(vk, device);
515
516 m_descriptorPool = DescriptorPoolBuilder()
517 .addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
518 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
519 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
520
521 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
522
523 const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
524
525 DescriptorSetUpdateBuilder()
526 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, &m_bufferView.get())
527 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
528 .update(vk, device);
529
530 return *m_descriptorSetLayout;
531 }
532
createInstance(Context& context) const533 TestInstance* SizeTest::createInstance (Context& context) const
534 {
535 if (m_texture.type() == IMAGE_TYPE_BUFFER)
536 return new BufferSizeTestInstance(context, m_texture, m_format);
537 else
538 return new ImageSizeTestInstance(context, m_texture, m_format, m_2DViewOf3D);
539 }
540
541 } // anonymous ns
542
createImageSizeTests(tcu::TestContext& testCtx)543 tcu::TestCaseGroup* createImageSizeTests (tcu::TestContext& testCtx)
544 {
545 const ImageType s_imageTypes[] =
546 {
547 IMAGE_TYPE_1D,
548 IMAGE_TYPE_1D_ARRAY,
549 IMAGE_TYPE_2D,
550 IMAGE_TYPE_2D_ARRAY,
551 IMAGE_TYPE_3D,
552 IMAGE_TYPE_CUBE,
553 IMAGE_TYPE_CUBE_ARRAY,
554 IMAGE_TYPE_BUFFER,
555 };
556
557 //! Base sizes used to generate actual image/buffer sizes in the test.
558 const tcu::IVec3 s_baseImageSizes[] =
559 {
560 tcu::IVec3(32, 32, 32),
561 tcu::IVec3(12, 34, 56),
562 tcu::IVec3(1, 1, 1),
563 tcu::IVec3(7, 1, 1),
564 };
565
566 const deUint32 s_flags[] =
567 {
568 SizeTest::FLAG_READONLY_IMAGE,
569 SizeTest::FLAG_WRITEONLY_IMAGE,
570 SizeTest::FLAG_READONLY_IMAGE | SizeTest::FLAG_WRITEONLY_IMAGE,
571 };
572
573 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_size"));
574
575 const VkFormat format = VK_FORMAT_R32G32B32A32_SFLOAT;
576
577 for (const auto& imageType : s_imageTypes)
578 {
579 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str()));
580
581 for (const auto& flags : s_flags)
582 for (const auto& baseImageSize : s_baseImageSizes)
583 for (int boolIdx = 0; boolIdx < 2; ++boolIdx)
584 {
585 const bool is2DViewOf3D = (boolIdx > 0);
586
587 #ifdef CTS_USES_VULKANSC
588 // VulkanSC doesn't have VK_EXT_image_2d_view_of_3d
589 if (is2DViewOf3D)
590 continue;
591 #endif // CTS_USES_VULKANSC
592
593 if (is2DViewOf3D && imageType != IMAGE_TYPE_3D)
594 continue;
595
596 const Texture texture = getTexture(imageType, baseImageSize);
597 const auto caseName = getCaseName(texture, flags, is2DViewOf3D);
598
599 imageGroup->addChild(new SizeTest(testCtx, caseName, texture, format, flags, is2DViewOf3D));
600 }
601
602 testGroup->addChild(imageGroup.release());
603 }
604 return testGroup.release();
605 }
606
607 } // image
608 } // vkt
609