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