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