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