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