1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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 Vulkan Buffer View Memory Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktApiBufferViewAccessTests.hpp"
26 #include "vktApiBufferAndImageAllocationUtil.hpp"
27
28 #include "deStringUtil.hpp"
29 #include "deUniquePtr.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktTestCaseUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRef.hpp"
37 #include "vkRefUtil.hpp"
38 #include "vkTypeUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuTexture.hpp"
43 #include "tcuTextureUtil.hpp"
44 #include "deSharedPtr.hpp"
45 #include "deArrayUtil.hpp"
46 #include "tcuVectorUtil.hpp"
47 #include "../image/vktImageTestsUtil.hpp"
48
49 namespace vkt
50 {
51
52 namespace api
53 {
54
55 using namespace vk;
56
57 namespace
58 {
59
60 enum AllocationKind
61 {
62 ALLOCATION_KIND_SUBALLOCATION = 0,
63 ALLOCATION_KIND_DEDICATED = 1,
64 ALLOCATION_KIND_LAST
65 };
66
67 struct BufferViewCaseParams
68 {
69 deUint32 bufferSize;
70 deUint32 bufferViewSize;
71 deUint32 elementOffset;
72 AllocationKind bufferAllocationKind;
73 AllocationKind imageAllocationKind;
74
75 VkFormat format;
76 VkBufferUsageFlags createUsage;
77 VkBufferUsageFlags bindUsage;
78 VkFormatFeatureFlags feature;
79 VkDescriptorType descType;
80
BufferViewCaseParamsvkt::api::__anon27760::BufferViewCaseParams81 BufferViewCaseParams (deUint32 bufferSize_,
82 deUint32 bufferViewSize_,
83 deUint32 elementOffset_,
84 AllocationKind bufferAllocKind_,
85 AllocationKind imageAllocKind_,
86 VkFormat format_ = VK_FORMAT_R32_UINT,
87 VkBufferUsageFlags createUsage_ = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
88 VkBufferUsageFlags bindUsage_ = VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM,
89 VkFormatFeatureFlags featureFlags_ = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT,
90 VkDescriptorType descType_ = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER)
91 : bufferSize(bufferSize_)
92 , bufferViewSize(bufferViewSize_)
93 , elementOffset(elementOffset_)
94 , bufferAllocationKind(bufferAllocKind_)
95 , imageAllocationKind(imageAllocKind_)
96 , format(format_)
97 , createUsage(createUsage_)
98 , bindUsage(bindUsage_)
99 , feature(featureFlags_)
100 , descType(descType_)
101 {
102 }
103 };
104
105 class BufferViewTestInstance : public vkt::TestInstance
106 {
107 public:
108 BufferViewTestInstance (Context& context,
109 BufferViewCaseParams testCase);
110 virtual ~BufferViewTestInstance (void);
111 virtual tcu::TestStatus iterate (void);
112
113 private:
114 void createQuad (void);
115 tcu::TestStatus checkResult (deInt8 factor);
116
117 private:
118 BufferViewCaseParams m_testCase;
119
120 const tcu::IVec2 m_renderSize;
121 const VkFormat m_colorFormat;
122
123 const VkDeviceSize m_pixelDataSize;
124
125 Move<VkImage> m_colorImage;
126 de::MovePtr<Allocation> m_colorImageAlloc;
127 Move<VkImageView> m_colorAttachmentView;
128 Move<VkRenderPass> m_renderPass;
129 Move<VkFramebuffer> m_framebuffer;
130
131 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
132 Move<VkDescriptorPool> m_descriptorPool;
133 Move<VkDescriptorSet> m_descriptorSet;
134
135 Move<VkBuffer> m_uniformBuffer;
136 de::MovePtr<vk::Allocation> m_uniformBufferAlloc;
137 Move<VkBufferView> m_uniformBufferView;
138
139 Move<VkShaderModule> m_vertexShaderModule;
140 Move<VkShaderModule> m_fragmentShaderModule;
141
142 Move<VkBuffer> m_vertexBuffer;
143 std::vector<tcu::Vec4> m_vertices;
144 de::MovePtr<Allocation> m_vertexBufferAlloc;
145
146 Move<VkPipelineLayout> m_pipelineLayout;
147 Move<VkPipeline> m_graphicsPipelines;
148
149 Move<VkCommandPool> m_cmdPool;
150 Move<VkCommandBuffer> m_cmdBuffer;
151
152 Move<VkBuffer> m_resultBuffer;
153 de::MovePtr<Allocation> m_resultBufferAlloc;
154 };
155
generateBuffer(std::vector<deUint32>& uniformData, deUint32 bufferSize, deInt8 factor)156 static void generateBuffer (std::vector<deUint32>& uniformData,
157 deUint32 bufferSize,
158 deInt8 factor)
159 {
160 for (deUint32 i = 0; i < bufferSize; ++i)
161 uniformData.push_back(factor * i);
162 }
163
createQuad(void)164 void BufferViewTestInstance::createQuad (void)
165 {
166 tcu::Vec4 a(-1.0, -1.0, 0.0, 1.0);
167 tcu::Vec4 b(1.0, -1.0, 0.0, 1.0);
168 tcu::Vec4 c(1.0, 1.0, 0.0, 1.0);
169 tcu::Vec4 d(-1.0, 1.0, 0.0, 1.0);
170
171 // Triangle 1
172 m_vertices.push_back(a);
173 m_vertices.push_back(c);
174 m_vertices.push_back(b);
175
176 // Triangle 2
177 m_vertices.push_back(c);
178 m_vertices.push_back(a);
179 m_vertices.push_back(d);
180 }
181
~BufferViewTestInstance(void)182 BufferViewTestInstance::~BufferViewTestInstance (void)
183 {
184 }
185
BufferViewTestInstance(Context& context, BufferViewCaseParams testCase)186 BufferViewTestInstance::BufferViewTestInstance (Context& context,
187 BufferViewCaseParams testCase)
188 : vkt::TestInstance (context)
189 , m_testCase (testCase)
190 , m_renderSize (testCase.bufferViewSize, testCase.bufferViewSize)
191 , m_colorFormat (VK_FORMAT_R32_UINT)
192 , m_pixelDataSize (m_renderSize.x() * m_renderSize.y() * mapVkFormat(m_colorFormat).getPixelSize())
193 {
194 const DeviceInterface& vk = context.getDeviceInterface();
195 const VkDevice vkDevice = context.getDevice();
196 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
197 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
198 const VkComponentMapping channelMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
199
200 // Create color image
201 if (m_testCase.imageAllocationKind == ALLOCATION_KIND_DEDICATED)
202 {
203 ImageDedicatedAllocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc);
204 }
205 else
206 {
207 ImageSuballocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc);
208 }
209
210 // Create destination buffer
211 if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED)
212 {
213 BufferDedicatedAllocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
214 }
215 else
216 {
217 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
218 }
219
220 // Create color attachment view
221 {
222 const VkImageViewCreateInfo colorAttachmentViewParams =
223 {
224 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
225 DE_NULL, // const void* pNext;
226 0u, // VkImageViewCreateFlags flags;
227 *m_colorImage, // VkImage image;
228 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
229 m_colorFormat, // VkFormat format;
230 channelMappingRGBA, // VkChannelMapping channels;
231 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
232 };
233
234 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
235 }
236
237 // Create render pass
238 m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat);
239
240 // Create framebuffer
241 {
242 const VkImageView attachmentBindInfos[1] =
243 {
244 *m_colorAttachmentView,
245 };
246
247 const VkFramebufferCreateInfo framebufferParams =
248 {
249 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
250 DE_NULL, // const void* pNext;
251 (VkFramebufferCreateFlags)0,
252 *m_renderPass, // VkRenderPass renderPass;
253 1u, // deUint32 attachmentCount;
254 attachmentBindInfos, // const VkImageView* pAttachments;
255 (deUint32)m_renderSize.x(), // deUint32 width;
256 (deUint32)m_renderSize.y(), // deUint32 height;
257 1u // deUint32 layers;
258 };
259
260 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
261 }
262
263 // Create descriptors
264 {
265 const VkDescriptorSetLayoutBinding
266 layoutBindings[1] =
267 {
268 {
269 0u, // deUint32 binding;
270 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType descriptorType;
271 1u, // deUint32 arraySize;
272 VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags;
273 DE_NULL // const VkSampler* pImmutableSamplers;
274 },
275 };
276
277 const VkDescriptorSetLayoutCreateInfo
278 descriptorLayoutParams =
279 {
280 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
281 DE_NULL, // const void* pNext;
282 (VkDescriptorSetLayoutCreateFlags)0,
283 DE_LENGTH_OF_ARRAY(layoutBindings), // deUint32 count;
284 layoutBindings // const VkDescriptorSetLayoutBinding pBinding;
285 };
286
287 m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams);
288
289 // Generate buffer
290 std::vector<deUint32> uniformData;
291 generateBuffer(uniformData, testCase.bufferSize, 1);
292
293 const VkDeviceSize uniformSize = testCase.bufferSize * sizeof(deUint32);
294
295 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, uniformSize, testCase.createUsage, m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible, m_uniformBufferAlloc);
296 deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
297 flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
298
299 const VkBufferViewCreateInfo viewInfo =
300 {
301 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
302 DE_NULL, // void* pNext;
303 (VkBufferViewCreateFlags)0,
304 *m_uniformBuffer, // VkBuffer buffer;
305 m_colorFormat, // VkFormat format;
306 m_testCase.elementOffset * sizeof(deUint32), // VkDeviceSize offset;
307 m_testCase.bufferViewSize * sizeof(deUint32) // VkDeviceSize range;
308 };
309
310 m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo);
311
312 const VkDescriptorPoolSize descriptorTypes[1] =
313 {
314 {
315 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType type;
316 1 // deUint32 count;
317 }
318 };
319
320 const VkDescriptorPoolCreateInfo
321 descriptorPoolParams =
322 {
323 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType;
324 DE_NULL, // void* pNext;
325 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags;
326 1u, // uint32_t maxSets;
327 DE_LENGTH_OF_ARRAY(descriptorTypes), // deUint32 count;
328 descriptorTypes // const VkDescriptorTypeCount* pTypeCount
329 };
330
331 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams);
332
333 const VkDescriptorSetAllocateInfo
334 descriptorSetParams =
335 {
336 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
337 DE_NULL,
338 *m_descriptorPool,
339 1u,
340 &m_descriptorSetLayout.get(),
341 };
342 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams);
343
344 const VkWriteDescriptorSet writeDescritporSets[] =
345 {
346 {
347 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
348 DE_NULL, // const void* pNext;
349 *m_descriptorSet, // VkDescriptorSet destSet;
350 0, // deUint32 destBinding;
351 0, // deUint32 destArrayElement;
352 1u, // deUint32 count;
353 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType descriptorType;
354 (const VkDescriptorImageInfo*)DE_NULL,
355 (const VkDescriptorBufferInfo*)DE_NULL,
356 &m_uniformBufferView.get(),
357 }
358 };
359
360 vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL);
361 }
362
363 // Create pipeline layout
364 {
365 const VkPipelineLayoutCreateInfo
366 pipelineLayoutParams =
367 {
368 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
369 DE_NULL, // const void* pNext;
370 (VkPipelineLayoutCreateFlags)0,
371 1u, // deUint32 descriptorSetCount;
372 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
373 0u, // deUint32 pushConstantRangeCount;
374 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
375 };
376
377 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
378 }
379
380 // Create shaders
381 {
382 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
383 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
384 }
385
386 // Create pipeline
387 {
388 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize));
389 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
390
391 m_graphicsPipelines = makeGraphicsPipeline(vk, // const DeviceInterface& vk
392 vkDevice, // const VkDevice device
393 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
394 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
395 DE_NULL, // const VkShaderModule tessellationControlModule
396 DE_NULL, // const VkShaderModule tessellationEvalModule
397 DE_NULL, // const VkShaderModule geometryShaderModule
398 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
399 *m_renderPass, // const VkRenderPass renderPass
400 viewports, // const std::vector<VkViewport>& viewports
401 scissors); // const std::vector<VkRect2D>& scissors
402 }
403
404 // Create vertex buffer
405 {
406 createQuad();
407 const VkDeviceSize vertexDataSize = m_vertices.size() * sizeof(tcu::Vec4);
408
409 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, m_context, memAlloc, m_vertexBuffer, MemoryRequirement::HostVisible, m_vertexBufferAlloc);
410
411 // Load vertices into vertex buffer
412 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), (size_t)vertexDataSize);
413 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
414 }
415
416 // Create command pool
417 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
418
419 // Create command buffer
420 {
421 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
422
423 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
424
425 const VkImageMemoryBarrier initialImageBarrier =
426 {
427 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
428 DE_NULL, // const void* pNext;
429 0, // VkAccessFlags srcAccessMask;
430 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
431 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
432 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
433 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
434 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
435 *m_colorImage, // VkImage image;
436 { // VkImageSubresourceRange subresourceRange;
437 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
438 0u, // deUint32 baseMipLevel;
439 1u, // deUint32 mipLevels;
440 0u, // deUint32 baseArraySlice;
441 1u // deUint32 arraySize;
442 }
443 };
444
445 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &initialImageBarrier);
446
447 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f));
448
449 const VkDeviceSize vertexBufferOffset[1] = { 0 };
450
451 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines);
452 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL);
453 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), vertexBufferOffset);
454 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
455 endRenderPass(vk, *m_cmdBuffer);
456 copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, *m_resultBuffer, m_renderSize);
457 endCommandBuffer(vk, *m_cmdBuffer);
458 }
459 }
460
checkResult(deInt8 factor)461 tcu::TestStatus BufferViewTestInstance::checkResult (deInt8 factor)
462 {
463 const DeviceInterface& vk = m_context.getDeviceInterface();
464 const VkDevice vkDevice = m_context.getDevice();
465 const tcu::TextureFormat tcuFormat = mapVkFormat(m_colorFormat);
466 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, m_renderSize.x(), m_renderSize.y()));
467
468 invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
469 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_resultBufferAlloc->getHostPtr()));
470
471 tcu::ConstPixelBufferAccess pixelBuffer = resultLevel->getAccess();
472 for (deInt32 i = 0; i < (deInt32) m_renderSize.x(); ++i)
473 {
474 tcu::IVec4 pixel = pixelBuffer.getPixelInt(i, i);
475 deInt32 expected = factor * (m_testCase.elementOffset + i);
476 deInt32 actual = pixel[0];
477 if (expected != actual)
478 {
479 std::ostringstream errorMessage;
480 errorMessage << "BufferView test failed. expected: " << expected << " actual: " << actual;
481 return tcu::TestStatus::fail(errorMessage.str());
482 }
483 }
484
485 return tcu::TestStatus::pass("BufferView test");
486 }
487
iterate(void)488 tcu::TestStatus BufferViewTestInstance::iterate (void)
489 {
490 const DeviceInterface& vk = m_context.getDeviceInterface();
491 const VkDevice vkDevice = m_context.getDevice();
492 const VkQueue queue = m_context.getUniversalQueue();
493
494 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
495
496 tcu::TestStatus testStatus = checkResult(1);
497 if (testStatus.getCode() != QP_TEST_RESULT_PASS)
498 return testStatus;
499
500 // Generate and bind another buffer
501 std::vector<deUint32> uniformData;
502 const VkDeviceSize uniformSize = m_testCase.bufferSize * sizeof(deUint32);
503 const deInt8 factor = 2;
504
505 generateBuffer(uniformData, m_testCase.bufferSize, factor);
506 deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize);
507 flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
508
509 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
510
511 return checkResult(factor);
512 }
513
514 class BufferViewTestCase : public vkt::TestCase
515 {
516 public:
BufferViewTestCase(tcu::TestContext& testCtx, const std::string& name, BufferViewCaseParams bufferViewTestInfo)517 BufferViewTestCase (tcu::TestContext& testCtx,
518 const std::string& name,
519 BufferViewCaseParams bufferViewTestInfo)
520 : vkt::TestCase (testCtx, name)
521 , m_bufferViewTestInfo (bufferViewTestInfo)
522 {}
523
~BufferViewTestCase(void)524 virtual ~BufferViewTestCase (void)
525 {}
526 virtual void initPrograms (SourceCollections& programCollection) const;
527
createInstance(Context& context) const528 virtual TestInstance* createInstance (Context& context) const
529 {
530 return new BufferViewTestInstance(context, m_bufferViewTestInfo);
531 }
532 private:
533 BufferViewCaseParams m_bufferViewTestInfo;
534 };
535
initPrograms(SourceCollections& programCollection) const536 void BufferViewTestCase::initPrograms (SourceCollections& programCollection) const
537 {
538 programCollection.glslSources.add("vert") << glu::VertexSource(
539 "#version 310 es\n"
540 "layout (location = 0) in highp vec4 a_position;\n"
541 "void main()\n"
542 "{\n"
543 " gl_Position = a_position;\n"
544 "}\n");
545
546
547 programCollection.glslSources.add("frag") << glu::FragmentSource(
548 "#version 310 es\n"
549 "#extension GL_EXT_texture_buffer : enable\n"
550 "layout (set=0, binding=0) uniform highp utextureBuffer u_buffer;\n"
551 "layout (location = 0) out highp uint o_color;\n"
552 "void main()\n"
553 "{\n"
554 " o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n"
555 "}\n");
556 }
557
558 class BufferViewAllFormatsTestInstance : public vkt::TestInstance
559 {
560 public:
561 BufferViewAllFormatsTestInstance (Context& context,
562 BufferViewCaseParams testCase);
563 virtual ~BufferViewAllFormatsTestInstance (void);
564 virtual tcu::TestStatus iterate (void);
565
566 private:
567 void checkTexelBufferSupport (Context& context,
568 VkFormat format,
569 BufferViewCaseParams testCase);
570 int getFetchPos (int fetchPosNdx);
571 tcu::TestStatus checkResult ();
572 tcu::TestStatus checkResultFloat ();
573 void populateSourceBuffer (const tcu::PixelBufferAccess& access, deUint32 bufferNdx);
574
575 private:
576 enum
577 {
578 // some arbitrary points
579 SAMPLE_POINT_0 = 6,
580 SAMPLE_POINT_1 = 51,
581 SAMPLE_POINT_2 = 42,
582 SAMPLE_POINT_3 = 25,
583 };
584
585 BufferViewCaseParams m_testCase;
586 const VkFormat m_bufferFormat;
587
588 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
589 Move<VkDescriptorPool> m_descriptorPool;
590 Move<VkDescriptorSet> m_descriptorSet;
591
592 Move<VkBuffer> m_uniformBuffer;
593 de::MovePtr<vk::Allocation> m_uniformBufferAlloc;
594 Move<VkBufferView> m_uniformBufferView;
595 Move<VkShaderModule> m_computeShaderModule;
596 Move<VkPipelineLayout> m_pipelineLayout;
597 Move<VkPipeline> m_computePipeline;
598
599 Move<VkCommandPool> m_cmdPool;
600 Move<VkCommandBuffer> m_cmdBuffer;
601
602 Move<VkBuffer> m_resultBuffer;
603 de::MovePtr<Allocation> m_resultBufferAlloc;
604
605 de::ArrayBuffer<deUint8> m_sourceBuffer;
606 tcu::ConstPixelBufferAccess m_sourceView;
607 };
608
checkTexelBufferSupport(Context& context, VkFormat format, BufferViewCaseParams testCase)609 void BufferViewAllFormatsTestInstance::checkTexelBufferSupport (Context& context, VkFormat format, BufferViewCaseParams testCase)
610 {
611 const InstanceInterface& vki = context.getInstanceInterface();
612 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
613
614 VkFormatProperties properties;
615 properties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format);
616
617 if (!(properties.bufferFeatures & testCase.feature))
618 TCU_THROW(NotSupportedError, "Format not supported");
619
620 #ifndef CTS_USES_VULKANSC
621 if(testCase.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM)
622 {
623 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance5"))
624 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance5 not supported");
625 }
626 #endif
627 }
628
~BufferViewAllFormatsTestInstance(void)629 BufferViewAllFormatsTestInstance::~BufferViewAllFormatsTestInstance (void)
630 {
631 }
632
633 /* Taken from BindingShaderAccessTests.cpp */
populateSourceBuffer(const tcu::PixelBufferAccess& access, deUint32 bufferNdx)634 void BufferViewAllFormatsTestInstance::populateSourceBuffer (const tcu::PixelBufferAccess& access, deUint32 bufferNdx)
635 {
636 DE_ASSERT(access.getHeight() == 1);
637 DE_ASSERT(access.getDepth() == 1);
638
639 const deInt32 width = access.getWidth();
640
641 for (int x = 0; x < width; ++x)
642 {
643 int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
644 int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
645 int blue = 16 * (x % 16); //!< 16-long triangle wave
646
647 DE_ASSERT(de::inRange(red, 0, 255));
648 DE_ASSERT(de::inRange(green, 0, 255));
649 DE_ASSERT(de::inRange(blue, 0, 255));
650
651 if (bufferNdx % 2 == 0) red = 255 - red;
652 if (bufferNdx % 3 == 0) green = 255 - green;
653 if (bufferNdx % 4 == 0) blue = 255 - blue;
654
655 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
656 }
657 }
658
BufferViewAllFormatsTestInstance(Context& context, BufferViewCaseParams testCase)659 BufferViewAllFormatsTestInstance::BufferViewAllFormatsTestInstance (Context& context,
660 BufferViewCaseParams testCase)
661 : vkt::TestInstance (context)
662 , m_testCase (testCase)
663 , m_bufferFormat (testCase.format)
664 {
665 const DeviceInterface& vk = context.getDeviceInterface();
666 const VkDevice vkDevice = context.getDevice();
667 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
668 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
669
670 checkTexelBufferSupport(context, m_bufferFormat, testCase);
671
672 // Create a result buffer
673 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, sizeof(tcu::Vec4[4]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc);
674
675 // Create descriptors
676 {
677 const VkDescriptorSetLayoutBinding layoutBindings[2] =
678 {
679 {
680 0u, // deUint32 binding;
681 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
682 1u, // deUint32 arraySize;
683 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
684 DE_NULL // const VkSampler* pImmutableSamplers;
685 },
686 {
687 1u, // deUint32 binding;
688 testCase.descType, // VkDescriptorType descriptorType;
689 1u, // deUint32 arraySize;
690 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags;
691 DE_NULL // const VkSampler* pImmutableSamplers;
692 },
693 };
694
695 const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams =
696 {
697 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
698 DE_NULL, // const void* pNext;
699 (VkDescriptorSetLayoutCreateFlags)0,
700 DE_LENGTH_OF_ARRAY(layoutBindings), // deUint32 count;
701 layoutBindings // const VkDescriptorSetLayoutBinding pBinding;
702 };
703
704 m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams);
705
706
707 // Generate buffer
708 const tcu::TextureFormat tcuFormat = mapVkFormat(m_bufferFormat);
709
710 de::ArrayBuffer<deUint8> sourceBuffer(testCase.bufferSize);
711 populateSourceBuffer(tcu::PixelBufferAccess(tcuFormat, tcu::IVec3(testCase.bufferSize / tcuFormat.getPixelSize(), 1, 1), sourceBuffer.getPtr()), 0);
712
713 m_sourceBuffer = sourceBuffer;
714 m_sourceView = tcu::ConstPixelBufferAccess(tcuFormat, tcu::IVec3(64, 1, 1), m_sourceBuffer.getPtr());
715
716 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, sourceBuffer.size(), testCase.createUsage, m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible, m_uniformBufferAlloc);
717 deMemcpy(m_uniformBufferAlloc->getHostPtr(), sourceBuffer.getPtr(), sourceBuffer.size());
718 flushAlloc(vk, vkDevice, *m_uniformBufferAlloc);
719
720 VkBufferViewCreateInfo viewInfo =
721 {
722 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
723 DE_NULL, // void* pNext;
724 (VkBufferViewCreateFlags)0,
725 *m_uniformBuffer, // VkBuffer buffer;
726 m_bufferFormat, // VkFormat format;
727 m_testCase.elementOffset, // VkDeviceSize offset;
728 VK_WHOLE_SIZE // VkDeviceSize range;
729 };
730
731 #ifndef CTS_USES_VULKANSC
732 VkBufferUsageFlags2CreateInfoKHR bindUsageInfo;
733 if (testCase.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM)
734 {
735 bindUsageInfo.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR; // VkStructureType sType;
736 bindUsageInfo.pNext = DE_NULL; // const void* pNext;
737 bindUsageInfo.usage = testCase.bindUsage; // VkBufferUsageFlags2KHR usage;
738
739 viewInfo.pNext = &bindUsageInfo;
740 }
741 #endif
742
743 m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo);
744
745 const VkDescriptorPoolSize descriptorTypes[2] =
746 {
747 {
748 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType type;
749 1 // deUint32 count;
750 },
751 {
752 testCase.descType, // VkDescriptorType type;
753 1 // deUint32 count;
754 }
755 };
756
757 const VkDescriptorPoolCreateInfo
758 descriptorPoolParams =
759 {
760 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType;
761 DE_NULL, // void* pNext;
762 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags;
763 1u, // uint32_t maxSets;
764 DE_LENGTH_OF_ARRAY(descriptorTypes), // deUint32 count;
765 descriptorTypes // const VkDescriptorTypeCount* pTypeCount
766 };
767
768 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams);
769
770 const VkDescriptorSetAllocateInfo
771 descriptorSetParams =
772 {
773 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
774 DE_NULL,
775 *m_descriptorPool,
776 1u,
777 &m_descriptorSetLayout.get(),
778 };
779 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams);
780
781 const VkDescriptorBufferInfo outBufferInfo =
782 {
783 m_resultBuffer.get(),
784 0,
785 sizeof(tcu::Vec4[4])
786 };
787
788 const VkWriteDescriptorSet writeDescritporSets[] =
789 {
790 {
791 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
792 DE_NULL, // const void* pNext;
793 *m_descriptorSet, // VkDescriptorSet destSet;
794 0, // deUint32 destBinding;
795 0, // deUint32 destArrayElement;
796 1u, // deUint32 count;
797 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType;
798 (const VkDescriptorImageInfo*)DE_NULL,
799 &outBufferInfo,
800 (const VkBufferView*)DE_NULL,
801 },
802 {
803 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
804 DE_NULL, // const void* pNext;
805 *m_descriptorSet, // VkDescriptorSet destSet;
806 1, // deUint32 destBinding;
807 0, // deUint32 destArrayElement;
808 1u, // deUint32 count;
809 testCase.descType, // VkDescriptorType descriptorType;
810 (const VkDescriptorImageInfo*)DE_NULL,
811 (const VkDescriptorBufferInfo*)DE_NULL,
812 &m_uniformBufferView.get(),
813 }
814 };
815
816 vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL);
817 }
818
819 // Create pipeline layout
820 {
821 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
822 {
823 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
824 DE_NULL, // const void* pNext;
825 (VkPipelineLayoutCreateFlags)0,
826 1u, // deUint32 descriptorSetCount;
827 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
828 0u, // deUint32 pushConstantRangeCount;
829 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
830 };
831
832 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
833 }
834
835 // Create shaders
836 {
837 m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("comp"), 0);
838 }
839
840 // Create pipeline
841 {
842 m_computePipeline = makeComputePipeline(vk, vkDevice, m_pipelineLayout.get(), m_computeShaderModule.get());
843 }
844
845 // Create command pool
846 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
847
848 // Create and record a command buffer
849 {
850 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
851
852 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
853
854 vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
855 vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, nullptr);
856
857 const vk::VkBufferMemoryBarrier barrier =
858 {
859 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
860 DE_NULL,
861 vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
862 vk::VK_ACCESS_UNIFORM_READ_BIT, // dstAccessMask
863 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
864 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
865 *m_resultBuffer, // buffer
866 0u, // offset
867 sizeof(tcu::Vec4[4]), // size
868 };
869 const vk::VkBufferMemoryBarrier bufferBarrier =
870 {
871 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
872 DE_NULL,
873 vk::VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
874 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
875 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
876 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
877 *m_resultBuffer, // buffer
878 (vk::VkDeviceSize)0u, // offset
879 sizeof(tcu::Vec4[4]), // size
880 };
881
882 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, &barrier, 0u, nullptr);
883 //vk.cmdDispatch(*m_cmdBuffer, 1u, 1u, 1u);
884 vk.cmdDispatch(*m_cmdBuffer, 4u, 1u, 1u);
885 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 0u, &bufferBarrier, 0u, nullptr);
886 endCommandBuffer(vk, *m_cmdBuffer);
887 }
888 }
889
getFetchPos(int fetchPosNdx)890 int BufferViewAllFormatsTestInstance::getFetchPos (int fetchPosNdx)
891 {
892 static const int fetchPositions[4] =
893 {
894 SAMPLE_POINT_0,
895 SAMPLE_POINT_1,
896 SAMPLE_POINT_2,
897 SAMPLE_POINT_3,
898 };
899
900 return fetchPositions[fetchPosNdx];
901 }
902
checkResult()903 tcu::TestStatus BufferViewAllFormatsTestInstance::checkResult ()
904 {
905 const DeviceInterface& vk = m_context.getDeviceInterface();
906 const VkDevice vkDevice = m_context.getDevice();
907 bool allResultsOk = true;
908
909 tcu::UVec4 results[4];
910 invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
911 deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::UVec4[4]));
912
913 // verify
914 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
915 {
916 const tcu::UVec4 result = results[resultNdx];
917 const tcu::UVec4 conversionThreshold = tcu::UVec4(0);
918 tcu::UVec4 reference = tcu::UVec4(0);
919
920 reference += m_sourceView.getPixelUint(getFetchPos(resultNdx), 0, 0);
921
922 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
923 {
924 allResultsOk = false;
925
926 m_context.getTestContext().getLog()
927 << tcu::TestLog::Message
928 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
929 << tcu::TestLog::EndMessage;
930 }
931 }
932
933 if (allResultsOk)
934 return tcu::TestStatus::pass("Pass");
935 else
936 return tcu::TestStatus::fail("Invalid result values");
937 }
938
checkResultFloat()939 tcu::TestStatus BufferViewAllFormatsTestInstance::checkResultFloat ()
940 {
941 const DeviceInterface& vk = m_context.getDeviceInterface();
942 const VkDevice vkDevice = m_context.getDevice();
943 bool allResultsOk = true;
944
945 tcu::Vec4 results[4];
946 invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc);
947 deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::Vec4[4]));
948
949 // verify
950 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
951 {
952 const tcu::Vec4 result = results[resultNdx];
953 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
954 tcu::Vec4 reference = tcu::Vec4(0.0f);
955
956 reference += m_sourceView.getPixel(getFetchPos(resultNdx), 0, 0);
957
958 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
959 {
960 allResultsOk = false;
961
962 m_context.getTestContext().getLog()
963 << tcu::TestLog::Message
964 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
965 << tcu::TestLog::EndMessage;
966 }
967 }
968
969 if (allResultsOk)
970 return tcu::TestStatus::pass("Pass");
971 else
972 return tcu::TestStatus::fail("Invalid result values");
973 }
974
iterate(void)975 tcu::TestStatus BufferViewAllFormatsTestInstance::iterate (void)
976 {
977 const DeviceInterface& vk = m_context.getDeviceInterface();
978 const VkDevice vkDevice = m_context.getDevice();
979 const VkQueue queue = m_context.getUniversalQueue();
980
981 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
982
983 if (isIntFormat(m_bufferFormat) || isUintFormat(m_bufferFormat))
984 return checkResult();
985 else
986 return checkResultFloat();
987 }
988
989
990 class BufferViewAllFormatsTestCase : public vkt::TestCase
991 {
992 public:
BufferViewAllFormatsTestCase(tcu::TestContext& testCtx, const std::string& name, BufferViewCaseParams bufferViewTestInfo)993 BufferViewAllFormatsTestCase (tcu::TestContext& testCtx,
994 const std::string& name,
995 BufferViewCaseParams bufferViewTestInfo)
996 : vkt::TestCase (testCtx, name)
997 , m_bufferViewTestInfo (bufferViewTestInfo)
998 {}
999
~BufferViewAllFormatsTestCase(void)1000 virtual ~BufferViewAllFormatsTestCase (void)
1001 {}
1002 virtual void initPrograms (SourceCollections& programCollection) const;
checkSupport(Context& context) const1003 virtual void checkSupport (Context& context) const
1004 {
1005 const InstanceInterface& vki = context.getInstanceInterface();
1006 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1007
1008 #ifndef CTS_USES_VULKANSC
1009 if ((m_bufferViewTestInfo.format == VK_FORMAT_A8_UNORM_KHR) ||
1010 (m_bufferViewTestInfo.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR))
1011 context.requireDeviceFunctionality("VK_KHR_maintenance5");
1012 #endif // CTS_USES_VULKANSC
1013
1014 if ((m_bufferViewTestInfo.createUsage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) != 0)
1015 {
1016 VkFormatProperties properties;
1017 properties = getPhysicalDeviceFormatProperties(vki, physicalDevice, m_bufferViewTestInfo.format);
1018 if ((properties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) == 0)
1019 {
1020 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT not supported for format");
1021 }
1022 }
1023 }
1024
createInstance(Context& context) const1025 virtual TestInstance* createInstance (Context& context) const
1026 {
1027 return new BufferViewAllFormatsTestInstance(context, m_bufferViewTestInfo);
1028 }
1029
1030 private:
1031 BufferViewCaseParams m_bufferViewTestInfo;
1032 };
1033
strLayoutFormat(VkFormat format)1034 const std::string strLayoutFormat (VkFormat format)
1035 {
1036 std::ostringstream buf;
1037
1038 buf << ", " << image::getShaderImageFormatQualifier(mapVkFormat(format)).c_str();
1039
1040 return buf.str();
1041 }
1042
initPrograms(SourceCollections& programCollection) const1043 void BufferViewAllFormatsTestCase::initPrograms (SourceCollections& programCollection) const
1044 {
1045 std::ostringstream buf;
1046
1047 const bool isIntFmt = isIntFormat(m_bufferViewTestInfo.format);
1048 const bool isUintFmt = isUintFormat(m_bufferViewTestInfo.format);
1049
1050 bool isUniform;
1051 if (m_bufferViewTestInfo.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM)
1052 {
1053 isUniform = m_bufferViewTestInfo.bindUsage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ? true : false;
1054 }
1055 else
1056 {
1057 isUniform = m_bufferViewTestInfo.createUsage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ? true : false;
1058 }
1059 const char* const storageType = isUniform ? "textureBuffer " : "imageBuffer ";
1060 const char* const extraOption = isUniform ? "" : "readonly ";
1061 const std::string stringFmtLayout = isUniform ? "" : strLayoutFormat(m_bufferViewTestInfo.format);
1062 const char* const fmtLayout = isUniform ? "" : stringFmtLayout.c_str();
1063 const char* const opName = isUniform ? "texelFetch" : "imageLoad";
1064 const char* const outFormat = isIntFmt ? "i" : isUintFmt ? "u" : "";
1065 const char* const inFormat = vk::isScaledFormat(m_bufferViewTestInfo.format)? "" : outFormat;
1066
1067 buf << "#version 440\n"
1068 << "#extension GL_EXT_texture_buffer : require\n"
1069 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1070 << "layout(set = 0, binding = 1" << fmtLayout << ") uniform highp " << extraOption << inFormat << storageType << " texelBuffer;\n"
1071 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
1072 << "{\n"
1073 << " highp " << outFormat << "vec4 read_colors[4];\n"
1074 << "} b_out;\n"
1075 << "void main (void)\n"
1076 << "{\n"
1077 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
1078 << " highp " << outFormat << "vec4 result_color;\n"
1079 << " result_color = " << outFormat << "vec4(0);\n"
1080 << " if (quadrant_id == 0)\n"
1081 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 6));\n"
1082 << " else if (quadrant_id == 1)\n"
1083 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 51));\n"
1084 << " else if (quadrant_id == 2)\n"
1085 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 42));\n"
1086 << " else\n"
1087 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 25));\n"
1088 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
1089 << "}\n";
1090
1091 programCollection.glslSources.add("comp") << glu::ComputeSource(buf.str());
1092 }
1093
1094 } // anonymous
1095
isSupportedImageLoadStore(const tcu::TextureFormat& format)1096 bool isSupportedImageLoadStore (const tcu::TextureFormat& format)
1097 {
1098 if (!image::isPackedType(mapTextureFormat(format)))
1099 {
1100 switch (format.order)
1101 {
1102 case tcu::TextureFormat::RGBA:
1103 break;
1104 default:
1105 return false;
1106 }
1107
1108 switch (format.type)
1109 {
1110 case tcu::TextureFormat::FLOAT:
1111 case tcu::TextureFormat::HALF_FLOAT:
1112
1113 case tcu::TextureFormat::UNSIGNED_INT32:
1114 case tcu::TextureFormat::UNSIGNED_INT16:
1115 case tcu::TextureFormat::UNSIGNED_INT8:
1116
1117 case tcu::TextureFormat::SIGNED_INT32:
1118 case tcu::TextureFormat::SIGNED_INT16:
1119 case tcu::TextureFormat::SIGNED_INT8:
1120
1121 case tcu::TextureFormat::UNORM_INT16:
1122 case tcu::TextureFormat::UNORM_INT8:
1123
1124 case tcu::TextureFormat::SNORM_INT16:
1125 case tcu::TextureFormat::SNORM_INT8:
1126 break;
1127
1128 default:
1129 return false;
1130 }
1131 }
1132 else
1133 {
1134 switch (mapTextureFormat(format))
1135 {
1136 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
1137 case VK_FORMAT_A2B10G10R10_UINT_PACK32:
1138 break;
1139
1140 default:
1141 return false;
1142 }
1143 }
1144
1145 return true;
1146 }
1147
createBufferViewAccessTests(tcu::TestContext& testCtx)1148 tcu::TestCaseGroup* createBufferViewAccessTests (tcu::TestContext& testCtx)
1149 {
1150 const char* const bufferTexts[ALLOCATION_KIND_LAST] =
1151 {
1152 "buffer_suballocated",
1153 "buffer_dedicated_alloc"
1154 };
1155
1156 const char* const imageTexts[ALLOCATION_KIND_LAST] =
1157 {
1158 "image_suballocated",
1159 "image_dedicated_alloc"
1160 };
1161
1162 de::MovePtr<tcu::TestCaseGroup> bufferViewTests (new tcu::TestCaseGroup(testCtx, "access"));
1163 de::MovePtr<tcu::TestCaseGroup> bufferViewAllocationGroupTests[] =
1164 {
1165 // BufferView Access Tests for Suballocated Objects
1166 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "suballocation")),
1167 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "dedicated_alloc", "BufferView Access Tests for Dedicatedly Allocated Objects"))
1168 };
1169
1170 for (deUint32 buffersAllocationNdx = 0u; buffersAllocationNdx < ALLOCATION_KIND_LAST; ++buffersAllocationNdx)
1171 for (deUint32 imageAllocationNdx = 0u; imageAllocationNdx < ALLOCATION_KIND_LAST; ++imageAllocationNdx)
1172 {
1173 const deUint32 testCaseGroupNdx = (buffersAllocationNdx == 0u && imageAllocationNdx == 0u) ? 0u : 1u;
1174 de::MovePtr<tcu::TestCaseGroup>&
1175 currentTestsGroup = bufferViewAllocationGroupTests[testCaseGroupNdx];
1176 {
1177 const BufferViewCaseParams info =
1178 {
1179 512, // deUint32 bufferSize
1180 512, // deUint32 bufferViewSize
1181 0, // deUint32 elementOffset
1182 static_cast<AllocationKind>(buffersAllocationNdx),
1183 static_cast<AllocationKind>(imageAllocationNdx)
1184 };
1185 std::ostringstream name;
1186 name << "buffer_view_memory_test_complete";
1187 if (testCaseGroupNdx != 0)
1188 name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1189 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info));
1190 }
1191
1192 {
1193 const BufferViewCaseParams info =
1194 {
1195 4096, // deUint32 bufferSize
1196 512, // deUint32 bufferViewSize
1197 0, // deUint32 elementOffset
1198 static_cast<AllocationKind>(buffersAllocationNdx),
1199 static_cast<AllocationKind>(imageAllocationNdx)
1200 };
1201 std::ostringstream name;
1202 name << "buffer_view_memory_test_partial_offset0";
1203 if (testCaseGroupNdx != 0)
1204 name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1205 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info));
1206 }
1207
1208 {
1209 const BufferViewCaseParams info =
1210 {
1211 4096, // deUint32 bufferSize
1212 512, // deUint32 bufferViewSize
1213 128, // deUint32 elementOffset
1214 static_cast<AllocationKind>(buffersAllocationNdx),
1215 static_cast<AllocationKind>(imageAllocationNdx)
1216 };
1217 std::ostringstream name;
1218 name << "buffer_view_memory_test_partial_offset1";
1219 if (testCaseGroupNdx != 0)
1220 name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx];
1221 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info));
1222 }
1223 }
1224
1225 for (deUint32 subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx)
1226 {
1227 bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release());
1228 }
1229
1230 VkFormat testFormats[] =
1231 {
1232 VK_FORMAT_R4G4_UNORM_PACK8,
1233 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1234 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1235 VK_FORMAT_R5G6B5_UNORM_PACK16,
1236 VK_FORMAT_B5G6R5_UNORM_PACK16,
1237 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1238 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1239 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
1240 #ifndef CTS_USES_VULKANSC
1241 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
1242 #endif // CTS_USES_VULKANSC
1243 VK_FORMAT_R8_UNORM,
1244 VK_FORMAT_R8_SNORM,
1245 VK_FORMAT_R8_USCALED,
1246 VK_FORMAT_R8_SSCALED,
1247 VK_FORMAT_R8_UINT,
1248 VK_FORMAT_R8_SINT,
1249 #ifndef CTS_USES_VULKANSC
1250 VK_FORMAT_A8_UNORM_KHR,
1251 #endif // CTS_USES_VULKANSC
1252 VK_FORMAT_R8G8_UNORM,
1253 VK_FORMAT_R8G8_SNORM,
1254 VK_FORMAT_R8G8_USCALED,
1255 VK_FORMAT_R8G8_SSCALED,
1256 VK_FORMAT_R8G8_UINT,
1257 VK_FORMAT_R8G8_SINT,
1258 VK_FORMAT_R8G8B8_UNORM,
1259 VK_FORMAT_R8G8B8_SNORM,
1260 VK_FORMAT_R8G8B8_USCALED,
1261 VK_FORMAT_R8G8B8_SSCALED,
1262 VK_FORMAT_R8G8B8_UINT,
1263 VK_FORMAT_R8G8B8_SINT,
1264 VK_FORMAT_B8G8R8_UNORM,
1265 VK_FORMAT_B8G8R8_SNORM,
1266 VK_FORMAT_B8G8R8_USCALED,
1267 VK_FORMAT_B8G8R8_SSCALED,
1268 VK_FORMAT_B8G8R8_UINT,
1269 VK_FORMAT_B8G8R8_SINT,
1270 VK_FORMAT_R8G8B8A8_UNORM,
1271 VK_FORMAT_R8G8B8A8_SNORM,
1272 VK_FORMAT_R8G8B8A8_USCALED,
1273 VK_FORMAT_R8G8B8A8_SSCALED,
1274 VK_FORMAT_R8G8B8A8_UINT,
1275 VK_FORMAT_R8G8B8A8_SINT,
1276 VK_FORMAT_B8G8R8A8_UNORM,
1277 VK_FORMAT_B8G8R8A8_SNORM,
1278 VK_FORMAT_B8G8R8A8_USCALED,
1279 VK_FORMAT_B8G8R8A8_SSCALED,
1280 VK_FORMAT_B8G8R8A8_UINT,
1281 VK_FORMAT_B8G8R8A8_SINT,
1282 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1283 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1284 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1285 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1286 VK_FORMAT_A8B8G8R8_UINT_PACK32,
1287 VK_FORMAT_A8B8G8R8_SINT_PACK32,
1288 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1289 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1290 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1291 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1292 VK_FORMAT_A2R10G10B10_UINT_PACK32,
1293 VK_FORMAT_A2R10G10B10_SINT_PACK32,
1294 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1295 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1296 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1297 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1298 VK_FORMAT_A2B10G10R10_UINT_PACK32,
1299 VK_FORMAT_A2B10G10R10_SINT_PACK32,
1300 VK_FORMAT_R16_UNORM,
1301 VK_FORMAT_R16_SNORM,
1302 VK_FORMAT_R16_USCALED,
1303 VK_FORMAT_R16_SSCALED,
1304 VK_FORMAT_R16_UINT,
1305 VK_FORMAT_R16_SINT,
1306 VK_FORMAT_R16_SFLOAT,
1307 VK_FORMAT_R16G16_UNORM,
1308 VK_FORMAT_R16G16_SNORM,
1309 VK_FORMAT_R16G16_USCALED,
1310 VK_FORMAT_R16G16_SSCALED,
1311 VK_FORMAT_R16G16_UINT,
1312 VK_FORMAT_R16G16_SINT,
1313 VK_FORMAT_R16G16_SFLOAT,
1314 VK_FORMAT_R16G16B16_UNORM,
1315 VK_FORMAT_R16G16B16_SNORM,
1316 VK_FORMAT_R16G16B16_USCALED,
1317 VK_FORMAT_R16G16B16_SSCALED,
1318 VK_FORMAT_R16G16B16_UINT,
1319 VK_FORMAT_R16G16B16_SINT,
1320 VK_FORMAT_R16G16B16_SFLOAT,
1321 VK_FORMAT_R16G16B16A16_UNORM,
1322 VK_FORMAT_R16G16B16A16_SNORM,
1323 VK_FORMAT_R16G16B16A16_USCALED,
1324 VK_FORMAT_R16G16B16A16_SSCALED,
1325 VK_FORMAT_R16G16B16A16_UINT,
1326 VK_FORMAT_R16G16B16A16_SINT,
1327 VK_FORMAT_R16G16B16A16_SFLOAT,
1328 VK_FORMAT_R32_UINT,
1329 VK_FORMAT_R32_SINT,
1330 VK_FORMAT_R32_SFLOAT,
1331 VK_FORMAT_R32G32_UINT,
1332 VK_FORMAT_R32G32_SINT,
1333 VK_FORMAT_R32G32_SFLOAT,
1334 };
1335
1336 {
1337 const char* const usageName[] = { "uniform_texel_buffer", "storage_texel_buffer"};
1338 const vk::VkBufferUsageFlags createUsage[] = { vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT };
1339 const vk::VkBufferUsageFlags bindUsage[] = { vk::VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM, vk::VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM };
1340 const vk::VkFormatFeatureFlags feature[] = { vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT };
1341 const vk::VkDescriptorType descType[] = { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER };
1342
1343 for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(createUsage); ++usageNdx)
1344 {
1345 de::MovePtr<tcu::TestCaseGroup> usageGroup (new tcu::TestCaseGroup(testCtx, usageName[usageNdx], ""));
1346
1347 for (deUint32 formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); formatIdx++)
1348 {
1349 const auto skip = strlen("VK_FORMAT_");
1350 const std::string fmtName = de::toLower(std::string(getFormatName(testFormats[formatIdx])).substr(skip));
1351
1352 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, fmtName.c_str(), ""));
1353
1354 if (createUsage[usageNdx] == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT && !isSupportedImageLoadStore(mapVkFormat(testFormats[formatIdx])))
1355 continue;
1356
1357 const BufferViewCaseParams info =
1358 {
1359 512, // deUint32 bufferSize
1360 128, // deUint32 bufferViewSize
1361 0, // deUint32 elementOffset
1362 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind bufferAllocationKind
1363 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind imageAllocationKind
1364
1365 testFormats[formatIdx], // VkFormat format
1366 createUsage[usageNdx], // VkBufferUsageFlags createUsage
1367 bindUsage[usageNdx], // VkBufferUsageFlags bindUsage
1368 feature[usageNdx], // VkFormatFeatureFlags2KHR feature
1369 descType[usageNdx], // VkDescriptorType descType
1370 };
1371
1372 usageGroup->addChild(new BufferViewAllFormatsTestCase(testCtx, fmtName.c_str(), info));
1373 }
1374
1375 bufferViewTests->addChild(usageGroup.release());
1376 }
1377 }
1378
1379 #ifndef CTS_USES_VULKANSC
1380 de::MovePtr<tcu::TestCaseGroup> uniformStorageGroup (new tcu::TestCaseGroup(testCtx, "uniform_storage_texel_buffer", ""));
1381 {
1382
1383 const char* const usageName[] = { "bind_as_uniform", "bind_as_storage" };
1384 const vk::VkBufferUsageFlags createUsage = vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT;
1385 const vk::VkBufferUsageFlags bindUsage[] = { vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT };
1386 const vk::VkFormatFeatureFlags feature[] = { vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT };
1387 const vk::VkDescriptorType descType[] = { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER };
1388
1389 for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageName); ++usageNdx)
1390 {
1391 de::MovePtr<tcu::TestCaseGroup> usageGroup (new tcu::TestCaseGroup(testCtx, usageName[usageNdx], ""));
1392
1393 for (deUint32 formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); formatIdx++)
1394 {
1395 const auto skip = strlen("VK_FORMAT_");
1396 const std::string fmtName = de::toLower(std::string(getFormatName(testFormats[formatIdx])).substr(skip));
1397
1398 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, fmtName.c_str(), ""));
1399
1400 if (bindUsage[usageNdx] == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT && !isSupportedImageLoadStore(mapVkFormat(testFormats[formatIdx])))
1401 continue;
1402
1403 const BufferViewCaseParams info =
1404 {
1405 512, // deUint32 bufferSize
1406 128, // deUint32 bufferViewSize
1407 0, // deUint32 elementOffset
1408 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind bufferAllocationKind
1409 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind imageAllocationKind
1410
1411 testFormats[formatIdx], // VkFormat format
1412 createUsage, // VkBufferUsageFlags createUsage
1413 bindUsage[usageNdx], // VkBufferUsageFlags bindUsage
1414 feature[usageNdx], // VkFormatFeatureFlags2KHR feature
1415 descType[usageNdx], // VkDescriptorType descType
1416 };
1417
1418 usageGroup->addChild(new BufferViewAllFormatsTestCase(testCtx, fmtName.c_str(), info));
1419 }
1420
1421 uniformStorageGroup->addChild(usageGroup.release());
1422 }
1423 }
1424
1425 bufferViewTests->addChild(uniformStorageGroup.release());
1426 #endif
1427
1428 return bufferViewTests.release();
1429 }
1430
1431 } // api
1432 } // vkt
1433