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(deUint32 gridX,deUint32 gridY,const deUint32 sampleNdx) const53 const vk::VkSampleLocationEXT& getSample (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
54 {
55 return m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)];
56 }
57
setSample(const deUint32 gridX,const deUint32 gridY,const deUint32 sampleNdx,const vk::VkSampleLocationEXT & location)58 void setSample (const deUint32 gridX, const deUint32 gridY, const deUint32 sampleNdx, const vk::VkSampleLocationEXT& location)
59 {
60 DE_ASSERT(gridX < m_gridSize.x());
61 DE_ASSERT(gridY < m_gridSize.y());
62
63 m_sampleLocations[getSampleIndex(gridX, gridY, sampleNdx)] = location;
64 }
65
size(void) const66 const tcu::UVec2& size (void) const { return m_gridSize; }
samplesPerPixel(void) const67 vk::VkSampleCountFlagBits samplesPerPixel (void) const { return m_numSamples; }
sampleLocations(void) const68 const vk::VkSampleLocationEXT* sampleLocations (void) const { return dataOrNullPtr(m_sampleLocations); }
sampleLocations(void)69 vk::VkSampleLocationEXT* sampleLocations (void) { return dataOrNullPtr(m_sampleLocations); }
sampleLocationCount(void) const70 deUint32 sampleLocationCount (void) const { return static_cast<deUint32>(m_sampleLocations.size()); }
71
72 private:
getSampleIndex(deUint32 gridX,deUint32 gridY,const deUint32 sampleNdx) const73 deUint32 getSampleIndex (deUint32 gridX, deUint32 gridY, const deUint32 sampleNdx) const
74 {
75 gridX %= m_gridSize.x();
76 gridY %= m_gridSize.y();
77 return (gridY * m_gridSize.x() + gridX) * static_cast<deUint32>(m_numSamples) + sampleNdx;
78 }
79
80 tcu::UVec2 m_gridSize;
81 vk::VkSampleCountFlagBits m_numSamples;
82 std::vector<vk::VkSampleLocationEXT> m_sampleLocations;
83 };
84
85 //! References the data inside MultisamplePixelGrid
makeSampleLocationsInfo(const MultisamplePixelGrid & pixelGrid)86 inline vk::VkSampleLocationsInfoEXT makeSampleLocationsInfo (const MultisamplePixelGrid& pixelGrid)
87 {
88 const vk::VkSampleLocationsInfoEXT info =
89 {
90 vk::VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, // VkStructureType sType;
91 DE_NULL, // const void* pNext;
92 pixelGrid.samplesPerPixel(), // VkSampleCountFlagBits sampleLocationsPerPixel;
93 vk::makeExtent2D(pixelGrid.size().x(), pixelGrid.size().y()), // VkExtent2D sampleLocationGridSize;
94 pixelGrid.sampleLocationCount(), // uint32_t sampleLocationsCount;
95 pixelGrid.sampleLocations(), // const VkSampleLocationEXT* pSampleLocations;
96 };
97 return info;
98 }
99
100 //! Fill each grid pixel with a distinct samples pattern, rounding locations based on subPixelBits
101 void fillSampleLocationsRandom (MultisamplePixelGrid& grid, const deUint32 subPixelBits, const deUint32 seed = 142u);
102
103 } // pipeline
104 } // vkt
105
106 #endif // _VKTPIPELINESAMPLELOCATIONSUTIL_HPP
107