Fix missing dependency on sparse binds
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / api / vktApiBufferViewAccessTests.cpp
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
80         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
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
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
179 BufferViewTestInstance::~BufferViewTestInstance                                                 (void)
180 {
181 }
182
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
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
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:
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
522         virtual                                                 ~BufferViewTestCase                                     (void)
523         {}
524         virtual void                                    initPrograms                                            (SourceCollections&                     programCollection) const;
525
526         virtual TestInstance*                   createInstance                                          (Context&                                       context) const
527         {
528                 return new BufferViewTestInstance(context, m_bufferViewTestInfo);
529         }
530 private:
531         BufferViewCaseParams                    m_bufferViewTestInfo;
532 };
533
534 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
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
619 BufferViewAllFormatsTestInstance::~BufferViewAllFormatsTestInstance             (void)
620 {
621 }
622
623 /* Taken from BindingShaderAccessTests.cpp */
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
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
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
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
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
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:
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
978         virtual                                                 ~BufferViewAllFormatsTestCase           (void)
979         {}
980         virtual void                                    initPrograms                                            (SourceCollections&                     programCollection) const;
981
982         virtual TestInstance*                   createInstance                                          (Context&                                       context) const
983         {
984                 return new BufferViewAllFormatsTestInstance(context, m_bufferViewTestInfo);
985         }
986
987 private:
988         BufferViewCaseParams                    m_bufferViewTestInfo;
989 };
990
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
1000 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
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
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