1 #ifndef _VKTPIPELINESAMPLELOCATIONSUTIL_HPP
2 #define _VKTPIPELINESAMPLELOCATIONSUTIL_HPP
3 /*------------------------------------------------------------------------
4  * Vulkan Conformance Tests
5  * ------------------------
6  *
7  * Copyright (c) 2019 Advanced Micro Devices, Inc.
8  * Copyright (c) 2019 The Khronos Group Inc.
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Utilities for VK_EXT_sample_locations
25  *//*--------------------------------------------------------------------*/
26 
27 #include "vkDefs.hpp"
28 #include "vkTypeUtil.hpp"
29 #include "vktPipelineMakeUtil.hpp"
30 #include "vktTestCase.hpp"
31 #include "tcuVector.hpp"
32 #include <vector>
33 
34 namespace vkt
35 {
36 namespace pipeline
37 {
38 
39 //! Specify sample locations in a pixel grid
40 class MultisamplePixelGrid
41 {
42 public:
MultisamplePixelGrid(const tcu::UVec2 & gridSize,const vk::VkSampleCountFlagBits numSamples)43     MultisamplePixelGrid(const tcu::UVec2 &gridSize, const vk::VkSampleCountFlagBits numSamples)
44         : m_gridSize(gridSize)
45         , m_numSamples(numSamples)
46         , m_sampleLocations(gridSize.x() * gridSize.y() * numSamples)
47     {
48         DE_ASSERT(gridSize.x() > 0 && gridSize.y() > 0);
49         DE_ASSERT(numSamples > 1);
50     }
51 
52     //! If grid x,y is larger than gridSize, then each coordinate is wrapped, x' = x % size_x
getSample(uint32_t gridX,uint32_t gridY,const uint32_t sampleNdx) const53     const vk::VkSampleLocationEXT &getSample(uint32_t gridX, uint32_t gridY, const uint32_t sampleNdx) const
54     {
55         return m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)];
56     }
57 
setSample(const uint32_t gridX,const uint32_t gridY,const uint32_t sampleNdx,const vk::VkSampleLocationEXT & location)58     void setSample(const uint32_t gridX, const uint32_t gridY, const uint32_t sampleNdx,
59                    const vk::VkSampleLocationEXT &location)
60     {
61         DE_ASSERT(gridX < m_gridSize.x());
62         DE_ASSERT(gridY < m_gridSize.y());
63 
64         m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)] = location;
65     }
66 
size(void) const67     const tcu::UVec2 &size(void) const
68     {
69         return m_gridSize;
70     }
samplesPerPixel(void) const71     vk::VkSampleCountFlagBits samplesPerPixel(void) const
72     {
73         return m_numSamples;
74     }
sampleLocations(void) const75     const vk::VkSampleLocationEXT *sampleLocations(void) const
76     {
77         return dataOrNullPtr(m_sampleLocations);
78     }
sampleLocations(void)79     vk::VkSampleLocationEXT *sampleLocations(void)
80     {
81         return dataOrNullPtr(m_sampleLocations);
82     }
sampleLocationCount(void) const83     uint32_t sampleLocationCount(void) const
84     {
85         return static_cast<uint32_t>(m_sampleLocations.size());
86     }
87 
88 private:
getSampleIndex(uint32_t gridX,uint32_t gridY,const uint32_t sampleNdx) const89     uint32_t getSampleIndex(uint32_t gridX, uint32_t gridY, const uint32_t sampleNdx) const
90     {
91         gridX %= m_gridSize.x();
92         gridY %= m_gridSize.y();
93         return (gridY * m_gridSize.x() + gridX) * static_cast<uint32_t>(m_numSamples) + sampleNdx;
94     }
95 
96     tcu::UVec2 m_gridSize;
97     vk::VkSampleCountFlagBits m_numSamples;
98     std::vector<vk::VkSampleLocationEXT> m_sampleLocations;
99 };
100 
101 //! References the data inside MultisamplePixelGrid
makeSampleLocationsInfo(const MultisamplePixelGrid & pixelGrid)102 inline vk::VkSampleLocationsInfoEXT makeSampleLocationsInfo(const MultisamplePixelGrid &pixelGrid)
103 {
104     const vk::VkSampleLocationsInfoEXT info = {
105         vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType               sType;
106         DE_NULL,                                         // const void*                   pNext;
107         pixelGrid.samplesPerPixel(),                     // VkSampleCountFlagBits         sampleLocationsPerPixel;
108         vk::makeExtent2D(pixelGrid.size().x(),
109                          pixelGrid.size().y()), // VkExtent2D                    sampleLocationGridSize;
110         pixelGrid.sampleLocationCount(),        // uint32_t                      sampleLocationsCount;
111         pixelGrid.sampleLocations(),            // const VkSampleLocationEXT*    pSampleLocations;
112     };
113     return info;
114 }
115 
116 //! Fill each grid pixel with a distinct samples pattern, rounding locations based on subPixelBits
117 void fillSampleLocationsRandom(MultisamplePixelGrid &grid, const uint32_t subPixelBits, const uint32_t seed = 142u);
118 
119 } // namespace pipeline
120 } // namespace vkt
121 
122 #endif // _VKTPIPELINESAMPLELOCATIONSUTIL_HPP
123