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
42 #include "deUniquePtr.hpp"
43 #include "deStringUtil.hpp"
44
45 #include <string>
46
47 using namespace vk;
48
49 namespace vkt
50 {
51 namespace image
52 {
53 namespace
54 {
55
56 //! Get a texture based on image type and suggested size.
getTexture(const ImageType imageType,const tcu::IVec3 & size)57 Texture getTexture (const ImageType imageType, const tcu::IVec3& size)
58 {
59 switch (imageType)
60 {
61 case IMAGE_TYPE_1D:
62 case IMAGE_TYPE_BUFFER:
63 return Texture(imageType, tcu::IVec3(size.x(), 1, 1), 1);
64
65 case IMAGE_TYPE_1D_ARRAY:
66 return Texture(imageType, tcu::IVec3(size.x(), 1, 1), size.y());
67
68 case IMAGE_TYPE_2D:
69 return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), 1);
70
71 case IMAGE_TYPE_2D_ARRAY:
72 return Texture(imageType, tcu::IVec3(size.x(), size.y(), 1), size.z());
73
74 case IMAGE_TYPE_CUBE:
75 return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 6);
76
77 case IMAGE_TYPE_CUBE_ARRAY:
78 return Texture(imageType, tcu::IVec3(size.x(), size.x(), 1), 2*6);
79
80 case IMAGE_TYPE_3D:
81 return Texture(imageType, size, 1);
82
83 default:
84 DE_FATAL("Internal error");
85 return Texture(IMAGE_TYPE_LAST, tcu::IVec3(), 0);
86 }
87 }
88
makeImageCreateInfo(const Texture & texture,const VkFormat format)89 inline VkImageCreateInfo makeImageCreateInfo (const Texture& texture, const VkFormat format)
90 {
91 const VkImageCreateInfo imageParams =
92 {
93 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
94 DE_NULL, // const void* pNext;
95 (isCube(texture) ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0u), // VkImageCreateFlags flags;
96 mapImageType(texture.type()), // VkImageType imageType;
97 format, // VkFormat format;
98 makeExtent3D(texture.layerSize()), // VkExtent3D extent;
99 1u, // deUint32 mipLevels;
100 (deUint32)texture.numLayers(), // deUint32 arrayLayers;
101 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
102 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
103 VK_IMAGE_USAGE_STORAGE_BIT, // VkImageUsageFlags usage;
104 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
105 0u, // deUint32 queueFamilyIndexCount;
106 DE_NULL, // const deUint32* pQueueFamilyIndices;
107 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
108 };
109 return imageParams;
110 }
111
112 //! Interpret the memory as IVec3
readIVec3(const void * const data)113 inline tcu::IVec3 readIVec3 (const void* const data)
114 {
115 const int* const p = reinterpret_cast<const int*>(data);
116 return tcu::IVec3(p[0], p[1], p[2]);
117 }
118
getExpectedImageSizeResult(const Texture & texture)119 tcu::IVec3 getExpectedImageSizeResult (const Texture& texture)
120 {
121 // GLSL imageSize() function returns:
122 // z = 0 for cubes
123 // z = N for cube arrays, where N is the number of cubes
124 // y or z = L where L is the number of layers for other array types (e.g. 1D array, 2D array)
125 // z = D where D is the depth of 3d image
126
127 const tcu::IVec3 size = texture.size();
128 const int numCubeFaces = 6;
129
130 switch (texture.type())
131 {
132 case IMAGE_TYPE_1D:
133 case IMAGE_TYPE_BUFFER:
134 return tcu::IVec3(size.x(), 0, 0);
135
136 case IMAGE_TYPE_1D_ARRAY:
137 case IMAGE_TYPE_2D:
138 case IMAGE_TYPE_CUBE:
139 return tcu::IVec3(size.x(), size.y(), 0);
140
141 case IMAGE_TYPE_2D_ARRAY:
142 case IMAGE_TYPE_3D:
143 return size;
144
145 case IMAGE_TYPE_CUBE_ARRAY:
146 return tcu::IVec3(size.x(), size.y(), size.z() / numCubeFaces);
147
148 default:
149 DE_FATAL("Internal error");
150 return tcu::IVec3();
151 }
152 }
153
154 class SizeTest : public TestCase
155 {
156 public:
157 enum TestFlags
158 {
159 FLAG_READONLY_IMAGE = 1u << 0,
160 FLAG_WRITEONLY_IMAGE = 1u << 1,
161 };
162
163 SizeTest (tcu::TestContext& testCtx,
164 const std::string& name,
165 const std::string& description,
166 const Texture& texture,
167 const VkFormat format,
168 const deUint32 flags = 0);
169
170 void initPrograms (SourceCollections& programCollection) const;
171 TestInstance* createInstance (Context& context) const;
172 virtual void checkSupport (Context& context) const;
173
174 private:
175 const Texture m_texture;
176 const VkFormat m_format;
177 const bool m_useReadonly;
178 const bool m_useWriteonly;
179 };
180
SizeTest(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const Texture & texture,const VkFormat format,const deUint32 flags)181 SizeTest::SizeTest (tcu::TestContext& testCtx,
182 const std::string& name,
183 const std::string& description,
184 const Texture& texture,
185 const VkFormat format,
186 const deUint32 flags)
187 : TestCase (testCtx, name, description)
188 , m_texture (texture)
189 , m_format (format)
190 , m_useReadonly ((flags & FLAG_READONLY_IMAGE) != 0)
191 , m_useWriteonly ((flags & FLAG_WRITEONLY_IMAGE) != 0)
192 {
193 // We expect at least one flag to be set.
194 DE_ASSERT(m_useReadonly || m_useWriteonly);
195 }
196
checkSupport(Context & context) const197 void SizeTest::checkSupport (Context& context) const
198 {
199 if (m_texture.type() == IMAGE_TYPE_CUBE_ARRAY)
200 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);
201 }
202
initPrograms(SourceCollections & programCollection) const203 void SizeTest::initPrograms (SourceCollections& programCollection) const
204 {
205 const std::string formatQualifierStr = getShaderImageFormatQualifier(mapVkFormat(m_format));
206 const std::string imageTypeStr = getShaderImageType(mapVkFormat(m_format), m_texture.type());
207 const int dimension = m_texture.dimension();
208
209 std::ostringstream accessQualifier;
210 if (m_useReadonly)
211 accessQualifier << " readonly";
212 if (m_useWriteonly)
213 accessQualifier << " writeonly";
214
215 std::ostringstream src;
216 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
217 << "\n"
218 << "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
219 << "layout (binding = 0, " << formatQualifierStr << ")" << accessQualifier.str() << " uniform highp " << imageTypeStr << " u_image;\n"
220 << "layout (binding = 1) writeonly buffer Output {\n"
221 << " ivec3 size;\n"
222 << "} sb_out;\n"
223 << "\n"
224 << "void main (void)\n"
225 << "{\n"
226 << (dimension == 1 ?
227 " sb_out.size = ivec3(imageSize(u_image), 0, 0);\n"
228 : dimension == 2 || m_texture.type() == IMAGE_TYPE_CUBE ? // cubes return ivec2
229 " sb_out.size = ivec3(imageSize(u_image), 0);\n"
230 : dimension == 3 ? // cube arrays return ivec3
231 " sb_out.size = imageSize(u_image);\n"
232 : "")
233 << "}\n";
234
235 programCollection.glslSources.add("comp") << glu::ComputeSource(src.str());
236 }
237
238 //! Build a case name, e.g. "readonly_writeonly_32x32"
getCaseName(const Texture & texture,const deUint32 flags)239 std::string getCaseName (const Texture& texture, const deUint32 flags)
240 {
241 std::ostringstream str;
242 str << ((flags & SizeTest::FLAG_READONLY_IMAGE) != 0 ? "readonly_" : "")
243 << ((flags & SizeTest::FLAG_WRITEONLY_IMAGE) != 0 ? "writeonly_" : "");
244
245 const int numComponents = texture.dimension();
246 for (int i = 0; i < numComponents; ++i)
247 str << (i == 0 ? "" : "x") << texture.size()[i];
248
249 return str.str();
250 }
251
252 //! Base test instance for image and buffer tests
253 class SizeTestInstance : public TestInstance
254 {
255 public:
256 SizeTestInstance (Context& context,
257 const Texture& texture,
258 const VkFormat format);
259
260 tcu::TestStatus iterate (void);
~SizeTestInstance(void)261 virtual ~SizeTestInstance (void) {}
262
263 protected:
264 virtual VkDescriptorSetLayout prepareDescriptors (void) = 0;
265 virtual VkDescriptorSet getDescriptorSet (void) const = 0;
266 virtual void commandBeforeCompute (const VkCommandBuffer cmdBuffer) = 0;
267
268 const Texture m_texture;
269 const VkFormat m_format;
270 const VkDeviceSize m_resultBufferSizeBytes;
271 de::MovePtr<Buffer> m_resultBuffer; //!< Shader writes the output here.
272 };
273
SizeTestInstance(Context & context,const Texture & texture,const VkFormat format)274 SizeTestInstance::SizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
275 : TestInstance (context)
276 , m_texture (texture)
277 , m_format (format)
278 , m_resultBufferSizeBytes (3 * sizeof(deUint32)) // ivec3 in shader
279 {
280 const DeviceInterface& vk = m_context.getDeviceInterface();
281 const VkDevice device = m_context.getDevice();
282 Allocator& allocator = m_context.getDefaultAllocator();
283
284 // Create an SSBO for shader output.
285
286 m_resultBuffer = de::MovePtr<Buffer>(new Buffer(
287 vk, device, allocator,
288 makeBufferCreateInfo(m_resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
289 MemoryRequirement::HostVisible));
290 }
291
iterate(void)292 tcu::TestStatus SizeTestInstance::iterate (void)
293 {
294 const DeviceInterface& vk = m_context.getDeviceInterface();
295 const VkDevice device = m_context.getDevice();
296 const VkQueue queue = m_context.getUniversalQueue();
297 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
298
299 // Create memory barriers.
300
301 const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier(
302 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
303 m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
304
305 // Create the pipeline.
306
307 const Unique<VkShaderModule> shaderModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("comp"), 0));
308
309 const VkDescriptorSetLayout descriptorSetLayout = prepareDescriptors();
310 const VkDescriptorSet descriptorSet = getDescriptorSet();
311
312 const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, descriptorSetLayout));
313 const Unique<VkPipeline> pipeline(makeComputePipeline(vk, device, *pipelineLayout, *shaderModule));
314
315 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
316 const Unique<VkCommandBuffer> cmdBuffer(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
317
318 beginCommandBuffer(vk, *cmdBuffer);
319
320 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipeline);
321 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
322
323 commandBeforeCompute(*cmdBuffer);
324 vk.cmdDispatch(*cmdBuffer, 1, 1, 1);
325 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);
326
327 endCommandBuffer(vk, *cmdBuffer);
328
329 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
330
331 // Compare the result.
332
333 const Allocation& bufferAlloc = m_resultBuffer->getAllocation();
334 invalidateAlloc(vk, device, bufferAlloc);
335
336 const tcu::IVec3 resultSize = readIVec3(bufferAlloc.getHostPtr());
337 const tcu::IVec3 expectedSize = getExpectedImageSizeResult(m_texture);
338
339 if (resultSize != expectedSize)
340 return tcu::TestStatus::fail("Incorrect imageSize(): expected " + de::toString(expectedSize) + " but got " + de::toString(resultSize));
341 else
342 return tcu::TestStatus::pass("Passed");
343 }
344
345 class ImageSizeTestInstance : public SizeTestInstance
346 {
347 public:
348 ImageSizeTestInstance (Context& context,
349 const Texture& texture,
350 const VkFormat format);
351
352 protected:
353 VkDescriptorSetLayout prepareDescriptors (void);
354 void commandBeforeCompute (const VkCommandBuffer cmdBuffer);
355
getDescriptorSet(void) const356 VkDescriptorSet getDescriptorSet (void) const { return *m_descriptorSet; }
357
358 de::MovePtr<Image> m_image;
359 Move<VkImageView> m_imageView;
360 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
361 Move<VkDescriptorPool> m_descriptorPool;
362 Move<VkDescriptorSet> m_descriptorSet;
363 };
364
ImageSizeTestInstance(Context & context,const Texture & texture,const VkFormat format)365 ImageSizeTestInstance::ImageSizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
366 : SizeTestInstance (context, texture, format)
367 {
368 const DeviceInterface& vk = m_context.getDeviceInterface();
369 const VkDevice device = m_context.getDevice();
370 Allocator& allocator = m_context.getDefaultAllocator();
371
372 // Create an image. Its data be uninitialized, as we're not reading from it.
373
374 m_image = de::MovePtr<Image>(new Image(vk, device, allocator, makeImageCreateInfo(m_texture, m_format), MemoryRequirement::Any));
375
376 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers());
377 m_imageView = makeImageView(vk, device, m_image->get(), mapImageViewType(m_texture.type()), m_format, subresourceRange);
378 }
379
prepareDescriptors(void)380 VkDescriptorSetLayout ImageSizeTestInstance::prepareDescriptors (void)
381 {
382 const DeviceInterface& vk = m_context.getDeviceInterface();
383 const VkDevice device = m_context.getDevice();
384
385 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
386 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_COMPUTE_BIT)
387 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
388 .build(vk, device);
389
390 m_descriptorPool = DescriptorPoolBuilder()
391 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
392 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
393 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
394
395 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
396
397 const VkDescriptorImageInfo descriptorImageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageView, VK_IMAGE_LAYOUT_GENERAL);
398 const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
399
400 DescriptorSetUpdateBuilder()
401 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfo)
402 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
403 .update(vk, device);
404
405 return *m_descriptorSetLayout;
406 }
407
commandBeforeCompute(const VkCommandBuffer cmdBuffer)408 void ImageSizeTestInstance::commandBeforeCompute (const VkCommandBuffer cmdBuffer)
409 {
410 const DeviceInterface& vk = m_context.getDeviceInterface();
411
412 const VkImageSubresourceRange subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_texture.numLayers());
413 const VkImageMemoryBarrier barrierSetImageLayout = makeImageMemoryBarrier(
414 0u, VK_ACCESS_SHADER_READ_BIT,
415 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
416 m_image->get(), subresourceRange);
417
418 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);
419 }
420
421 class BufferSizeTestInstance : public SizeTestInstance
422 {
423 public:
424 BufferSizeTestInstance (Context& context,
425 const Texture& texture,
426 const VkFormat format);
427
428 protected:
429 VkDescriptorSetLayout prepareDescriptors (void);
430
commandBeforeCompute(const VkCommandBuffer)431 void commandBeforeCompute (const VkCommandBuffer) {}
getDescriptorSet(void) const432 VkDescriptorSet getDescriptorSet (void) const { return *m_descriptorSet; }
433
434 de::MovePtr<Buffer> m_imageBuffer;
435 Move<VkBufferView> m_bufferView;
436 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
437 Move<VkDescriptorPool> m_descriptorPool;
438 Move<VkDescriptorSet> m_descriptorSet;
439 };
440
BufferSizeTestInstance(Context & context,const Texture & texture,const VkFormat format)441 BufferSizeTestInstance::BufferSizeTestInstance (Context& context, const Texture& texture, const VkFormat format)
442 : SizeTestInstance (context, texture, format)
443 {
444 const DeviceInterface& vk = m_context.getDeviceInterface();
445 const VkDevice device = m_context.getDevice();
446 Allocator& allocator = m_context.getDefaultAllocator();
447
448 // Create a texel storage buffer. Its data be uninitialized, as we're not reading from it.
449
450 const VkDeviceSize imageSizeBytes = getImageSizeBytes(m_texture.size(), m_format);
451 m_imageBuffer = de::MovePtr<Buffer>(new Buffer(vk, device, allocator,
452 makeBufferCreateInfo(imageSizeBytes, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT), MemoryRequirement::Any));
453
454 m_bufferView = makeBufferView(vk, device, m_imageBuffer->get(), m_format, 0ull, imageSizeBytes);
455 }
456
prepareDescriptors(void)457 VkDescriptorSetLayout BufferSizeTestInstance::prepareDescriptors (void)
458 {
459 const DeviceInterface& vk = m_context.getDeviceInterface();
460 const VkDevice device = m_context.getDevice();
461
462 m_descriptorSetLayout = DescriptorSetLayoutBuilder()
463 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
464 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
465 .build(vk, device);
466
467 m_descriptorPool = DescriptorPoolBuilder()
468 .addType(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER)
469 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
470 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
471
472 m_descriptorSet = makeDescriptorSet(vk, device, *m_descriptorPool, *m_descriptorSetLayout);
473
474 const VkDescriptorBufferInfo descriptorBufferInfo = makeDescriptorBufferInfo(m_resultBuffer->get(), 0ull, m_resultBufferSizeBytes);
475
476 DescriptorSetUpdateBuilder()
477 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, &m_bufferView.get())
478 .writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo)
479 .update(vk, device);
480
481 return *m_descriptorSetLayout;
482 }
483
createInstance(Context & context) const484 TestInstance* SizeTest::createInstance (Context& context) const
485 {
486 if (m_texture.type() == IMAGE_TYPE_BUFFER)
487 return new BufferSizeTestInstance(context, m_texture, m_format);
488 else
489 return new ImageSizeTestInstance(context, m_texture, m_format);
490 }
491
492 static const ImageType s_imageTypes[] =
493 {
494 IMAGE_TYPE_1D,
495 IMAGE_TYPE_1D_ARRAY,
496 IMAGE_TYPE_2D,
497 IMAGE_TYPE_2D_ARRAY,
498 IMAGE_TYPE_3D,
499 IMAGE_TYPE_CUBE,
500 IMAGE_TYPE_CUBE_ARRAY,
501 IMAGE_TYPE_BUFFER,
502 };
503
504 //! Base sizes used to generate actual image/buffer sizes in the test.
505 static const tcu::IVec3 s_baseImageSizes[] =
506 {
507 tcu::IVec3(32, 32, 32),
508 tcu::IVec3(12, 34, 56),
509 tcu::IVec3(1, 1, 1),
510 tcu::IVec3(7, 1, 1),
511 };
512
513 static const deUint32 s_flags[] =
514 {
515 SizeTest::FLAG_READONLY_IMAGE,
516 SizeTest::FLAG_WRITEONLY_IMAGE,
517 SizeTest::FLAG_READONLY_IMAGE | SizeTest::FLAG_WRITEONLY_IMAGE,
518 };
519
520 } // anonymous ns
521
createImageSizeTests(tcu::TestContext & testCtx)522 tcu::TestCaseGroup* createImageSizeTests (tcu::TestContext& testCtx)
523 {
524 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_size", "imageSize() cases"));
525
526 const VkFormat format = VK_FORMAT_R32G32B32A32_SFLOAT;
527
528 for (int imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++imageTypeNdx)
529 {
530 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(s_imageTypes[imageTypeNdx]).c_str(), ""));
531
532 for (int flagNdx = 0; flagNdx < DE_LENGTH_OF_ARRAY(s_flags); ++flagNdx)
533 for (int imageSizeNdx = 0; imageSizeNdx < DE_LENGTH_OF_ARRAY(s_baseImageSizes); ++imageSizeNdx)
534 {
535 const Texture texture = getTexture(s_imageTypes[imageTypeNdx], s_baseImageSizes[imageSizeNdx]);
536 imageGroup->addChild(new SizeTest(testCtx, getCaseName(texture, s_flags[flagNdx]), "", texture, format, s_flags[flagNdx]));
537 }
538
539 testGroup->addChild(imageGroup.release());
540 }
541 return testGroup.release();
542 }
543
544 } // image
545 } // vkt
546