1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2019 Advanced Micro Devices, Inc. 6 * Copyright (c) 2019 The Khronos Group Inc. 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 Utilities for VK_EXT_sample_locations 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktPipelineSampleLocationsUtil.hpp" 26#include "deRandom.hpp" 27#include <set> 28 29namespace vkt 30{ 31namespace pipeline 32{ 33using namespace vk; 34using tcu::UVec2; 35using tcu::Vec2; 36 37//! Order a Vector by X, Y, Z, and W 38template<typename VectorT> 39struct LessThan 40{ 41 bool operator()(const VectorT& v1, const VectorT& v2) const 42 { 43 for (int i = 0; i < VectorT::SIZE; ++i) 44 { 45 if (v1[i] == v2[i]) 46 continue; 47 else 48 return v1[i] < v2[i]; 49 } 50 51 return false; 52 } 53}; 54 55static inline deUint32 numSamplesPerPixel (const MultisamplePixelGrid& pixelGrid) 56{ 57 return static_cast<deUint32>(pixelGrid.samplesPerPixel()); 58} 59 60//! Fill each grid pixel with a distinct samples pattern, rounding locations based on subPixelBits 61void fillSampleLocationsRandom (MultisamplePixelGrid& grid, const deUint32 subPixelBits, const deUint32 seed) 62{ 63 const deUint32 guardOffset = 1u; // don't put samples on the right or the bottom edge of the pixel 64 const deUint32 maxLocationIndex = 1u << subPixelBits; 65 de::Random rng (seed); 66 67 for (deUint32 gridY = 0; gridY < grid.size().y(); ++gridY) 68 for (deUint32 gridX = 0; gridX < grid.size().x(); ++gridX) 69 { 70 std::set<UVec2, LessThan<UVec2> > takenLocationIndices; 71 for (deUint32 sampleNdx = 0; sampleNdx < numSamplesPerPixel(grid); /* no increment */) 72 { 73 const UVec2 locationNdx (rng.getUint32() % (maxLocationIndex + 1 - guardOffset), 74 rng.getUint32() % (maxLocationIndex + 1 - guardOffset)); 75 76 if (takenLocationIndices.find(locationNdx) == takenLocationIndices.end()) 77 { 78 const VkSampleLocationEXT location = 79 { 80 static_cast<float>(locationNdx.x()) / static_cast<float>(maxLocationIndex), // float x; 81 static_cast<float>(locationNdx.y()) / static_cast<float>(maxLocationIndex), // float y; 82 }; 83 84 grid.setSample(gridX, gridY, sampleNdx, location); 85 takenLocationIndices.insert(locationNdx); 86 87 ++sampleNdx; // next sample 88 } 89 } 90 } 91} 92 93} // pipeline 94} // vkt 95