1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------ 2e5c31af7Sopenharmony_ci* Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci* ------------------------ 4e5c31af7Sopenharmony_ci* 5e5c31af7Sopenharmony_ci* Copyright (c) 2016 The Khronos Group Inc. 6e5c31af7Sopenharmony_ci* Copyright (c) 2023 LunarG, Inc. 7e5c31af7Sopenharmony_ci* Copyright (c) 2023 Nintendo 8e5c31af7Sopenharmony_ci* 9e5c31af7Sopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License"); 10e5c31af7Sopenharmony_ci* you may not use this file except in compliance with the License. 11e5c31af7Sopenharmony_ci* You may obtain a copy of the License at 12e5c31af7Sopenharmony_ci* 13e5c31af7Sopenharmony_ci* http://www.apache.org/licenses/LICENSE-2.0 14e5c31af7Sopenharmony_ci* 15e5c31af7Sopenharmony_ci* Unless required by applicable law or agreed to in writing, software 16e5c31af7Sopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS, 17e5c31af7Sopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18e5c31af7Sopenharmony_ci* See the License for the specific language governing permissions and 19e5c31af7Sopenharmony_ci* limitations under the License. 20e5c31af7Sopenharmony_ci* 21e5c31af7Sopenharmony_ci*//* 22e5c31af7Sopenharmony_ci* \file vktPipelineMultisampleInterpolationTests.cpp 23e5c31af7Sopenharmony_ci* \brief Multisample Interpolation Tests 24e5c31af7Sopenharmony_ci*//*--------------------------------------------------------------------*/ 25e5c31af7Sopenharmony_ci 26e5c31af7Sopenharmony_ci#include "vktPipelineMultisampleInterpolationTests.hpp" 27e5c31af7Sopenharmony_ci#include "vktPipelineMultisampleBaseResolve.hpp" 28e5c31af7Sopenharmony_ci#include "vktPipelineMultisampleTestsUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vktPipelineMakeUtil.hpp" 30e5c31af7Sopenharmony_ci#include "vktAmberTestCase.hpp" 31e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 32e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp" 33e5c31af7Sopenharmony_ci#include <vector> 34e5c31af7Sopenharmony_ci 35e5c31af7Sopenharmony_cinamespace vkt 36e5c31af7Sopenharmony_ci{ 37e5c31af7Sopenharmony_cinamespace pipeline 38e5c31af7Sopenharmony_ci{ 39e5c31af7Sopenharmony_cinamespace multisample 40e5c31af7Sopenharmony_ci{ 41e5c31af7Sopenharmony_ci 42e5c31af7Sopenharmony_ciusing namespace vk; 43e5c31af7Sopenharmony_ci 44e5c31af7Sopenharmony_cistruct VertexDataNdc 45e5c31af7Sopenharmony_ci{ 46e5c31af7Sopenharmony_ci VertexDataNdc (const tcu::Vec4& posNdc) : positionNdc(posNdc) {} 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ci tcu::Vec4 positionNdc; 49e5c31af7Sopenharmony_ci}; 50e5c31af7Sopenharmony_ci 51e5c31af7Sopenharmony_cistruct VertexDataNdcScreen 52e5c31af7Sopenharmony_ci{ 53e5c31af7Sopenharmony_ci VertexDataNdcScreen (const tcu::Vec4& posNdc, const tcu::Vec2& posScreen) : positionNdc(posNdc), positionScreen(posScreen) {} 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_ci tcu::Vec4 positionNdc; 56e5c31af7Sopenharmony_ci tcu::Vec2 positionScreen; 57e5c31af7Sopenharmony_ci}; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_cistruct VertexDataNdcBarycentric 60e5c31af7Sopenharmony_ci{ 61e5c31af7Sopenharmony_ci VertexDataNdcBarycentric (const tcu::Vec4& posNdc, const tcu::Vec3& barCoord) : positionNdc(posNdc), barycentricCoord(barCoord) {} 62e5c31af7Sopenharmony_ci 63e5c31af7Sopenharmony_ci tcu::Vec4 positionNdc; 64e5c31af7Sopenharmony_ci tcu::Vec3 barycentricCoord; 65e5c31af7Sopenharmony_ci}; 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_cibool checkForError (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS, const deUint32 errorCompNdx) 68e5c31af7Sopenharmony_ci{ 69e5c31af7Sopenharmony_ci for (deUint32 z = 0u; z < imageRSInfo.extent.depth; ++z) 70e5c31af7Sopenharmony_ci for (deUint32 y = 0u; y < imageRSInfo.extent.height; ++y) 71e5c31af7Sopenharmony_ci for (deUint32 x = 0u; x < imageRSInfo.extent.width; ++x) 72e5c31af7Sopenharmony_ci { 73e5c31af7Sopenharmony_ci const deUint32 errorComponent = dataRS.getPixelUint(x, y, z)[errorCompNdx]; 74e5c31af7Sopenharmony_ci 75e5c31af7Sopenharmony_ci if (errorComponent > 0) 76e5c31af7Sopenharmony_ci return true; 77e5c31af7Sopenharmony_ci } 78e5c31af7Sopenharmony_ci 79e5c31af7Sopenharmony_ci return false; 80e5c31af7Sopenharmony_ci} 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_citemplate <typename CaseClassName> 83e5c31af7Sopenharmony_ciclass MSCase : public MultisampleCaseBase 84e5c31af7Sopenharmony_ci{ 85e5c31af7Sopenharmony_cipublic: 86e5c31af7Sopenharmony_ci MSCase (tcu::TestContext& testCtx, 87e5c31af7Sopenharmony_ci const std::string& name, 88e5c31af7Sopenharmony_ci const ImageMSParams& imageMSParams) 89e5c31af7Sopenharmony_ci : MultisampleCaseBase(testCtx, name, imageMSParams) {} 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci void init (void); 92e5c31af7Sopenharmony_ci void initPrograms (vk::SourceCollections& programCollection) const; 93e5c31af7Sopenharmony_ci void checkSupport (Context& context) const; 94e5c31af7Sopenharmony_ci TestInstance* createInstance (Context& context) const; 95e5c31af7Sopenharmony_ci static MultisampleCaseBase* createCase (tcu::TestContext& testCtx, 96e5c31af7Sopenharmony_ci const std::string& name, 97e5c31af7Sopenharmony_ci const ImageMSParams& imageMSParams); 98e5c31af7Sopenharmony_ci}; 99e5c31af7Sopenharmony_ci 100e5c31af7Sopenharmony_citemplate <typename CaseClassName> 101e5c31af7Sopenharmony_civoid MSCase<CaseClassName>::checkSupport (Context& context) const 102e5c31af7Sopenharmony_ci{ 103e5c31af7Sopenharmony_ci checkGraphicsPipelineLibrarySupport(context); 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 106e5c31af7Sopenharmony_ci if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") && 107e5c31af7Sopenharmony_ci !context.getPortabilitySubsetFeatures().shaderSampleRateInterpolationFunctions) 108e5c31af7Sopenharmony_ci { 109e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Shader sample rate interpolation functions are not supported by this implementation"); 110e5c31af7Sopenharmony_ci } 111e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 112e5c31af7Sopenharmony_ci 113e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING); 114e5c31af7Sopenharmony_ci} 115e5c31af7Sopenharmony_ci 116e5c31af7Sopenharmony_citemplate <typename CaseClassName> 117e5c31af7Sopenharmony_ciMultisampleCaseBase* MSCase<CaseClassName>::createCase (tcu::TestContext& testCtx, const std::string& name, const ImageMSParams& imageMSParams) 118e5c31af7Sopenharmony_ci{ 119e5c31af7Sopenharmony_ci return new MSCase<CaseClassName>(testCtx, name, imageMSParams); 120e5c31af7Sopenharmony_ci} 121e5c31af7Sopenharmony_ci 122e5c31af7Sopenharmony_citemplate <typename InstanceClassName> 123e5c31af7Sopenharmony_ciclass MSInstance : public MSInstanceBaseResolve 124e5c31af7Sopenharmony_ci{ 125e5c31af7Sopenharmony_cipublic: 126e5c31af7Sopenharmony_ci MSInstance (Context& context, 127e5c31af7Sopenharmony_ci const ImageMSParams& imageMSParams) 128e5c31af7Sopenharmony_ci : MSInstanceBaseResolve(context, imageMSParams) {} 129e5c31af7Sopenharmony_ci 130e5c31af7Sopenharmony_ci VertexDataDesc getVertexDataDescripton (void) const; 131e5c31af7Sopenharmony_ci void uploadVertexData (const Allocation& vertexBufferAllocation, 132e5c31af7Sopenharmony_ci const VertexDataDesc& vertexDataDescripton) const; 133e5c31af7Sopenharmony_ci tcu::TestStatus verifyImageData (const vk::VkImageCreateInfo& imageRSInfo, 134e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess& dataRS) const; 135e5c31af7Sopenharmony_ci}; 136e5c31af7Sopenharmony_ci 137e5c31af7Sopenharmony_ciclass MSInstanceDistinctValues; 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_citemplate<> MultisampleInstanceBase::VertexDataDesc MSInstance<MSInstanceDistinctValues>::getVertexDataDescripton (void) const 140e5c31af7Sopenharmony_ci{ 141e5c31af7Sopenharmony_ci VertexDataDesc vertexDataDesc; 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci vertexDataDesc.verticesCount = 3u; 144e5c31af7Sopenharmony_ci vertexDataDesc.dataStride = sizeof(VertexDataNdc); 145e5c31af7Sopenharmony_ci vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride; 146e5c31af7Sopenharmony_ci vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci const VkVertexInputAttributeDescription vertexAttribPositionNdc = 149e5c31af7Sopenharmony_ci { 150e5c31af7Sopenharmony_ci 0u, // deUint32 location; 151e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 152e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 153e5c31af7Sopenharmony_ci DE_OFFSET_OF(VertexDataNdc, positionNdc), // deUint32 offset; 154e5c31af7Sopenharmony_ci }; 155e5c31af7Sopenharmony_ci 156e5c31af7Sopenharmony_ci vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc); 157e5c31af7Sopenharmony_ci 158e5c31af7Sopenharmony_ci return vertexDataDesc; 159e5c31af7Sopenharmony_ci} 160e5c31af7Sopenharmony_ci 161e5c31af7Sopenharmony_citemplate<> void MSInstance<MSInstanceDistinctValues>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const 162e5c31af7Sopenharmony_ci{ 163e5c31af7Sopenharmony_ci std::vector<VertexDataNdc> vertices; 164e5c31af7Sopenharmony_ci 165e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdc(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f))); 166e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdc(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f))); 167e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdc(tcu::Vec4( 4.0f, -1.0f, 0.0f, 1.0f))); 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize)); 170e5c31af7Sopenharmony_ci} 171e5c31af7Sopenharmony_ci 172e5c31af7Sopenharmony_citemplate<> tcu::TestStatus MSInstance<MSInstanceDistinctValues>::verifyImageData (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS) const 173e5c31af7Sopenharmony_ci{ 174e5c31af7Sopenharmony_ci const deUint32 distinctValuesExpected = static_cast<deUint32>(m_imageMSParams.numSamples) + 1u; 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_ci std::vector<tcu::IVec4> distinctValues; 177e5c31af7Sopenharmony_ci 178e5c31af7Sopenharmony_ci for (deUint32 z = 0u; z < imageRSInfo.extent.depth; ++z) 179e5c31af7Sopenharmony_ci for (deUint32 y = 0u; y < imageRSInfo.extent.height; ++y) 180e5c31af7Sopenharmony_ci for (deUint32 x = 0u; x < imageRSInfo.extent.width; ++x) 181e5c31af7Sopenharmony_ci { 182e5c31af7Sopenharmony_ci const tcu::IVec4 pixel = dataRS.getPixelInt(x, y, z); 183e5c31af7Sopenharmony_ci 184e5c31af7Sopenharmony_ci if (std::find(distinctValues.begin(), distinctValues.end(), pixel) == distinctValues.end()) 185e5c31af7Sopenharmony_ci distinctValues.push_back(pixel); 186e5c31af7Sopenharmony_ci } 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci if (distinctValues.size() >= distinctValuesExpected) 189e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Passed"); 190e5c31af7Sopenharmony_ci else 191e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Expected numSamples+1 different colors in the output image"); 192e5c31af7Sopenharmony_ci} 193e5c31af7Sopenharmony_ci 194e5c31af7Sopenharmony_ciclass MSCaseSampleQualifierDistinctValues; 195e5c31af7Sopenharmony_ci 196e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseSampleQualifierDistinctValues>::init (void) 197e5c31af7Sopenharmony_ci{ 198e5c31af7Sopenharmony_ci m_testCtx.getLog() 199e5c31af7Sopenharmony_ci << tcu::TestLog::Message 200e5c31af7Sopenharmony_ci << "Verifying that a sample qualified varying is given different values for different samples.\n" 201e5c31af7Sopenharmony_ci << " Render full screen traingle with quadratic function defining red/green color pattern division.\n" 202e5c31af7Sopenharmony_ci << " => Resulting image should contain n+1 different colors, where n = sample count.\n" 203e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 204e5c31af7Sopenharmony_ci 205e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 206e5c31af7Sopenharmony_ci} 207e5c31af7Sopenharmony_ci 208e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseSampleQualifierDistinctValues>::initPrograms (vk::SourceCollections& programCollection) const 209e5c31af7Sopenharmony_ci{ 210e5c31af7Sopenharmony_ci // Create vertex shader 211e5c31af7Sopenharmony_ci std::ostringstream vs; 212e5c31af7Sopenharmony_ci 213e5c31af7Sopenharmony_ci vs << "#version 440\n" 214e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 215e5c31af7Sopenharmony_ci << "\n" 216e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 vs_out_position_ndc;\n" 217e5c31af7Sopenharmony_ci << "\n" 218e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 219e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 220e5c31af7Sopenharmony_ci << "};\n" 221e5c31af7Sopenharmony_ci << "void main (void)\n" 222e5c31af7Sopenharmony_ci << "{\n" 223e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 224e5c31af7Sopenharmony_ci << " vs_out_position_ndc = vs_in_position_ndc;\n" 225e5c31af7Sopenharmony_ci << "}\n"; 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 228e5c31af7Sopenharmony_ci 229e5c31af7Sopenharmony_ci // Create fragment shader 230e5c31af7Sopenharmony_ci std::ostringstream fs; 231e5c31af7Sopenharmony_ci 232e5c31af7Sopenharmony_ci fs << "#version 440\n" 233e5c31af7Sopenharmony_ci << "layout(location = 0) sample in vec4 fs_in_position_ndc;\n" 234e5c31af7Sopenharmony_ci << "\n" 235e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 236e5c31af7Sopenharmony_ci << "\n" 237e5c31af7Sopenharmony_ci << "void main (void)\n" 238e5c31af7Sopenharmony_ci << "{\n" 239e5c31af7Sopenharmony_ci << " if(fs_in_position_ndc.y < -2.0*pow(0.5*(fs_in_position_ndc.x + 1.0), 2.0) + 1.0)\n" 240e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 241e5c31af7Sopenharmony_ci << " else\n" 242e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 243e5c31af7Sopenharmony_ci << "}\n"; 244e5c31af7Sopenharmony_ci 245e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 246e5c31af7Sopenharmony_ci} 247e5c31af7Sopenharmony_ci 248e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseSampleQualifierDistinctValues>::checkSupport (Context& context) const 249e5c31af7Sopenharmony_ci{ 250e5c31af7Sopenharmony_ci checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_imageMSParams.pipelineConstructionType); 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ci context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING); 253e5c31af7Sopenharmony_ci} 254e5c31af7Sopenharmony_ci 255e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseSampleQualifierDistinctValues>::createInstance (Context& context) const 256e5c31af7Sopenharmony_ci{ 257e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceDistinctValues>(context, m_imageMSParams); 258e5c31af7Sopenharmony_ci} 259e5c31af7Sopenharmony_ci 260e5c31af7Sopenharmony_ciclass MSCaseInterpolateAtSampleDistinctValues; 261e5c31af7Sopenharmony_ci 262e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleDistinctValues>::init (void) 263e5c31af7Sopenharmony_ci{ 264e5c31af7Sopenharmony_ci m_testCtx.getLog() 265e5c31af7Sopenharmony_ci << tcu::TestLog::Message 266e5c31af7Sopenharmony_ci << "Verifying that a interpolateAtSample returns different values for different samples.\n" 267e5c31af7Sopenharmony_ci << " Render full screen traingle with quadratic function defining red/green color pattern division.\n" 268e5c31af7Sopenharmony_ci << " => Resulting image should contain n+1 different colors, where n = sample count.\n" 269e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 270e5c31af7Sopenharmony_ci 271e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 272e5c31af7Sopenharmony_ci} 273e5c31af7Sopenharmony_ci 274e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleDistinctValues>::initPrograms (vk::SourceCollections& programCollection) const 275e5c31af7Sopenharmony_ci{ 276e5c31af7Sopenharmony_ci // Create vertex shader 277e5c31af7Sopenharmony_ci std::ostringstream vs; 278e5c31af7Sopenharmony_ci 279e5c31af7Sopenharmony_ci vs << "#version 440\n" 280e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 281e5c31af7Sopenharmony_ci << "\n" 282e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 vs_out_position_ndc;\n" 283e5c31af7Sopenharmony_ci << "\n" 284e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 285e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 286e5c31af7Sopenharmony_ci << "};\n" 287e5c31af7Sopenharmony_ci << "void main (void)\n" 288e5c31af7Sopenharmony_ci << "{\n" 289e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 290e5c31af7Sopenharmony_ci << " vs_out_position_ndc = vs_in_position_ndc;\n" 291e5c31af7Sopenharmony_ci << "}\n"; 292e5c31af7Sopenharmony_ci 293e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_ci // Create fragment shader 296e5c31af7Sopenharmony_ci std::ostringstream fs; 297e5c31af7Sopenharmony_ci 298e5c31af7Sopenharmony_ci fs << "#version 440\n" 299e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 fs_in_position_ndc;\n" 300e5c31af7Sopenharmony_ci << "\n" 301e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 302e5c31af7Sopenharmony_ci << "\n" 303e5c31af7Sopenharmony_ci << "void main (void)\n" 304e5c31af7Sopenharmony_ci << "{\n" 305e5c31af7Sopenharmony_ci << " const vec4 position_ndc_at_sample = interpolateAtSample(fs_in_position_ndc, gl_SampleID);\n" 306e5c31af7Sopenharmony_ci << " if(position_ndc_at_sample.y < -2.0*pow(0.5*(position_ndc_at_sample.x + 1.0), 2.0) + 1.0)\n" 307e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 308e5c31af7Sopenharmony_ci << " else\n" 309e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 310e5c31af7Sopenharmony_ci << "}\n"; 311e5c31af7Sopenharmony_ci 312e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 313e5c31af7Sopenharmony_ci} 314e5c31af7Sopenharmony_ci 315e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseInterpolateAtSampleDistinctValues>::createInstance (Context& context) const 316e5c31af7Sopenharmony_ci{ 317e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceDistinctValues>(context, m_imageMSParams); 318e5c31af7Sopenharmony_ci} 319e5c31af7Sopenharmony_ci 320e5c31af7Sopenharmony_ciclass MSInstanceInterpolateScreenPosition; 321e5c31af7Sopenharmony_ci 322e5c31af7Sopenharmony_citemplate<> MSInstanceBaseResolve::VertexDataDesc MSInstance<MSInstanceInterpolateScreenPosition>::getVertexDataDescripton (void) const 323e5c31af7Sopenharmony_ci{ 324e5c31af7Sopenharmony_ci VertexDataDesc vertexDataDesc; 325e5c31af7Sopenharmony_ci 326e5c31af7Sopenharmony_ci vertexDataDesc.verticesCount = 4u; 327e5c31af7Sopenharmony_ci vertexDataDesc.dataStride = sizeof(VertexDataNdcScreen); 328e5c31af7Sopenharmony_ci vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride; 329e5c31af7Sopenharmony_ci vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci const VkVertexInputAttributeDescription vertexAttribPositionNdc = 332e5c31af7Sopenharmony_ci { 333e5c31af7Sopenharmony_ci 0u, // deUint32 location; 334e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 335e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 336e5c31af7Sopenharmony_ci DE_OFFSET_OF(VertexDataNdcScreen, positionNdc), // deUint32 offset; 337e5c31af7Sopenharmony_ci }; 338e5c31af7Sopenharmony_ci 339e5c31af7Sopenharmony_ci vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc); 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ci const VkVertexInputAttributeDescription vertexAttribPositionScreen = 342e5c31af7Sopenharmony_ci { 343e5c31af7Sopenharmony_ci 1u, // deUint32 location; 344e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 345e5c31af7Sopenharmony_ci VK_FORMAT_R32G32_SFLOAT, // VkFormat format; 346e5c31af7Sopenharmony_ci DE_OFFSET_OF(VertexDataNdcScreen, positionScreen), // deUint32 offset; 347e5c31af7Sopenharmony_ci }; 348e5c31af7Sopenharmony_ci 349e5c31af7Sopenharmony_ci vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionScreen); 350e5c31af7Sopenharmony_ci 351e5c31af7Sopenharmony_ci return vertexDataDesc; 352e5c31af7Sopenharmony_ci} 353e5c31af7Sopenharmony_ci 354e5c31af7Sopenharmony_citemplate<> void MSInstance<MSInstanceInterpolateScreenPosition>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const 355e5c31af7Sopenharmony_ci{ 356e5c31af7Sopenharmony_ci const tcu::UVec3 layerSize = getLayerSize(IMAGE_TYPE_2D, m_imageMSParams.imageSize); 357e5c31af7Sopenharmony_ci const float screenSizeX = static_cast<float>(layerSize.x()); 358e5c31af7Sopenharmony_ci const float screenSizeY = static_cast<float>(layerSize.y()); 359e5c31af7Sopenharmony_ci 360e5c31af7Sopenharmony_ci std::vector<VertexDataNdcScreen> vertices; 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdcScreen(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, 0.0f))); 363e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdcScreen(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, 0.0f))); 364e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdcScreen(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(0.0f, screenSizeY))); 365e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdcScreen(tcu::Vec4( 1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec2(screenSizeX, screenSizeY))); 366e5c31af7Sopenharmony_ci 367e5c31af7Sopenharmony_ci deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize)); 368e5c31af7Sopenharmony_ci} 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_citemplate<> tcu::TestStatus MSInstance<MSInstanceInterpolateScreenPosition>::verifyImageData (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS) const 371e5c31af7Sopenharmony_ci{ 372e5c31af7Sopenharmony_ci if (checkForError(imageRSInfo, dataRS, 0)) 373e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed"); 374e5c31af7Sopenharmony_ci 375e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Passed"); 376e5c31af7Sopenharmony_ci} 377e5c31af7Sopenharmony_ci 378e5c31af7Sopenharmony_ciclass MSCaseInterpolateAtSampleSingleSample; 379e5c31af7Sopenharmony_ci 380e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleSingleSample>::init (void) 381e5c31af7Sopenharmony_ci{ 382e5c31af7Sopenharmony_ci m_testCtx.getLog() 383e5c31af7Sopenharmony_ci << tcu::TestLog::Message 384e5c31af7Sopenharmony_ci << "Verifying that using interpolateAtSample with multisample buffers not available returns sample evaluated at the center of the pixel.\n" 385e5c31af7Sopenharmony_ci << " Interpolate varying containing screen space location.\n" 386e5c31af7Sopenharmony_ci << " => fract(screen space location) should be (about) (0.5, 0.5)\n" 387e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 388e5c31af7Sopenharmony_ci 389e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 390e5c31af7Sopenharmony_ci} 391e5c31af7Sopenharmony_ci 392e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleSingleSample>::initPrograms (vk::SourceCollections& programCollection) const 393e5c31af7Sopenharmony_ci{ 394e5c31af7Sopenharmony_ci // Create vertex shader 395e5c31af7Sopenharmony_ci std::ostringstream vs; 396e5c31af7Sopenharmony_ci 397e5c31af7Sopenharmony_ci vs << "#version 440\n" 398e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 399e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 vs_in_position_screen;\n" 400e5c31af7Sopenharmony_ci << "\n" 401e5c31af7Sopenharmony_ci << "layout(location = 0) out vec2 vs_out_position_screen;\n" 402e5c31af7Sopenharmony_ci << "\n" 403e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 404e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 405e5c31af7Sopenharmony_ci << "};\n" 406e5c31af7Sopenharmony_ci << "void main (void)\n" 407e5c31af7Sopenharmony_ci << "{\n" 408e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 409e5c31af7Sopenharmony_ci << " vs_out_position_screen = vs_in_position_screen;\n" 410e5c31af7Sopenharmony_ci << "}\n"; 411e5c31af7Sopenharmony_ci 412e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 413e5c31af7Sopenharmony_ci 414e5c31af7Sopenharmony_ci // Create fragment shader 415e5c31af7Sopenharmony_ci std::ostringstream fs; 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci fs << "#version 440\n" 418e5c31af7Sopenharmony_ci << "layout(location = 0) in vec2 fs_in_position_screen;\n" 419e5c31af7Sopenharmony_ci << "\n" 420e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 421e5c31af7Sopenharmony_ci << "\n" 422e5c31af7Sopenharmony_ci << "void main (void)\n" 423e5c31af7Sopenharmony_ci << "{\n" 424e5c31af7Sopenharmony_ci << " const float threshold = 0.15625;\n" 425e5c31af7Sopenharmony_ci << " const vec2 position_screen_at_sample = interpolateAtSample(fs_in_position_screen, 0);\n" 426e5c31af7Sopenharmony_ci << " const vec2 position_inside_pixel = fract(position_screen_at_sample);\n" 427e5c31af7Sopenharmony_ci << "\n" 428e5c31af7Sopenharmony_ci << " if (abs(position_inside_pixel.x - 0.5) <= threshold && abs(position_inside_pixel.y - 0.5) <= threshold)\n" 429e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 430e5c31af7Sopenharmony_ci << " else\n" 431e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 432e5c31af7Sopenharmony_ci << "}\n"; 433e5c31af7Sopenharmony_ci 434e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 435e5c31af7Sopenharmony_ci} 436e5c31af7Sopenharmony_ci 437e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseInterpolateAtSampleSingleSample>::createInstance (Context& context) const 438e5c31af7Sopenharmony_ci{ 439e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams); 440e5c31af7Sopenharmony_ci} 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ciclass MSCaseInterpolateAtSampleIgnoresCentroid; 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleIgnoresCentroid>::init (void) 445e5c31af7Sopenharmony_ci{ 446e5c31af7Sopenharmony_ci m_testCtx.getLog() 447e5c31af7Sopenharmony_ci << tcu::TestLog::Message 448e5c31af7Sopenharmony_ci << "Verifying that interpolateAtSample ignores centroid qualifier.\n" 449e5c31af7Sopenharmony_ci << " Interpolate varying containing screen space location with centroid and sample qualifiers.\n" 450e5c31af7Sopenharmony_ci << " => interpolateAtSample(screenSample, n) ~= interpolateAtSample(screenCentroid, n)\n" 451e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 452e5c31af7Sopenharmony_ci 453e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 454e5c31af7Sopenharmony_ci} 455e5c31af7Sopenharmony_ci 456e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleIgnoresCentroid>::initPrograms (vk::SourceCollections& programCollection) const 457e5c31af7Sopenharmony_ci{ 458e5c31af7Sopenharmony_ci // Create vertex shader 459e5c31af7Sopenharmony_ci std::ostringstream vs; 460e5c31af7Sopenharmony_ci 461e5c31af7Sopenharmony_ci vs << "#version 440\n" 462e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 463e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 vs_in_position_screen;\n" 464e5c31af7Sopenharmony_ci << "\n" 465e5c31af7Sopenharmony_ci << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n" 466e5c31af7Sopenharmony_ci << "layout(location = 1) out vec2 vs_out_pos_screen_fragment;\n" 467e5c31af7Sopenharmony_ci << "\n" 468e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 469e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 470e5c31af7Sopenharmony_ci << "};\n" 471e5c31af7Sopenharmony_ci << "void main (void)\n" 472e5c31af7Sopenharmony_ci << "{\n" 473e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 474e5c31af7Sopenharmony_ci << " vs_out_pos_screen_centroid = vs_in_position_screen;\n" 475e5c31af7Sopenharmony_ci << " vs_out_pos_screen_fragment = vs_in_position_screen;\n" 476e5c31af7Sopenharmony_ci << "}\n"; 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 479e5c31af7Sopenharmony_ci 480e5c31af7Sopenharmony_ci // Create fragment shader 481e5c31af7Sopenharmony_ci std::ostringstream fs; 482e5c31af7Sopenharmony_ci 483e5c31af7Sopenharmony_ci fs << "#version 440\n" 484e5c31af7Sopenharmony_ci << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n" 485e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 fs_in_pos_screen_fragment;\n" 486e5c31af7Sopenharmony_ci << "\n" 487e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 488e5c31af7Sopenharmony_ci << "\n" 489e5c31af7Sopenharmony_ci << "void main (void)\n" 490e5c31af7Sopenharmony_ci << "{\n" 491e5c31af7Sopenharmony_ci << " const float threshold = 0.0005;\n" 492e5c31af7Sopenharmony_ci << "\n" 493e5c31af7Sopenharmony_ci << " const vec2 position_a = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n" 494e5c31af7Sopenharmony_ci << " const vec2 position_b = interpolateAtSample(fs_in_pos_screen_fragment, gl_SampleID);\n" 495e5c31af7Sopenharmony_ci << " const bool valuesEqual = all(lessThan(abs(position_a - position_b), vec2(threshold)));\n" 496e5c31af7Sopenharmony_ci << "\n" 497e5c31af7Sopenharmony_ci << " if (valuesEqual)\n" 498e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 499e5c31af7Sopenharmony_ci << " else\n" 500e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 501e5c31af7Sopenharmony_ci << "}\n"; 502e5c31af7Sopenharmony_ci 503e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 504e5c31af7Sopenharmony_ci} 505e5c31af7Sopenharmony_ci 506e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseInterpolateAtSampleIgnoresCentroid>::createInstance (Context& context) const 507e5c31af7Sopenharmony_ci{ 508e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams); 509e5c31af7Sopenharmony_ci} 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ciclass MSCaseInterpolateAtSampleConsistency; 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleConsistency>::init (void) 514e5c31af7Sopenharmony_ci{ 515e5c31af7Sopenharmony_ci const std::string indexStr = de::toString(m_imageMSParams.componentData.index); 516e5c31af7Sopenharmony_ci std::string componentMsg; 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci switch (m_imageMSParams.componentData.source) 519e5c31af7Sopenharmony_ci { 520e5c31af7Sopenharmony_ci case multisample::ComponentSource::CONSTANT: componentMsg = "Using single constant component " + indexStr; break; 521e5c31af7Sopenharmony_ci case multisample::ComponentSource::PUSH_CONSTANT: componentMsg = "Using single component via push constant " + indexStr; break; 522e5c31af7Sopenharmony_ci default: break; 523e5c31af7Sopenharmony_ci } 524e5c31af7Sopenharmony_ci 525e5c31af7Sopenharmony_ci m_testCtx.getLog() 526e5c31af7Sopenharmony_ci << tcu::TestLog::Message 527e5c31af7Sopenharmony_ci << "Verifying that interpolateAtSample with the sample set to the current sampleID returns consistent values.\n" 528e5c31af7Sopenharmony_ci << (componentMsg.empty() ? std::string() : componentMsg + "\n") 529e5c31af7Sopenharmony_ci << " Interpolate varying containing screen space location with centroid and sample qualifiers.\n" 530e5c31af7Sopenharmony_ci << " => interpolateAtSample(screenCentroid, sampleID) = screenSample\n" 531e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 532e5c31af7Sopenharmony_ci 533e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 534e5c31af7Sopenharmony_ci} 535e5c31af7Sopenharmony_ci 536e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtSampleConsistency>::initPrograms (vk::SourceCollections& programCollection) const 537e5c31af7Sopenharmony_ci{ 538e5c31af7Sopenharmony_ci // Create vertex shader 539e5c31af7Sopenharmony_ci std::ostringstream vs; 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ci vs << "#version 440\n" 542e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 543e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 vs_in_position_screen;\n" 544e5c31af7Sopenharmony_ci << "\n" 545e5c31af7Sopenharmony_ci << "layout(location = 0) out vec2 vs_out_pos_screen_centroid;\n" 546e5c31af7Sopenharmony_ci << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n" 547e5c31af7Sopenharmony_ci << "\n" 548e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 549e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 550e5c31af7Sopenharmony_ci << "};\n" 551e5c31af7Sopenharmony_ci << "void main (void)\n" 552e5c31af7Sopenharmony_ci << "{\n" 553e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 554e5c31af7Sopenharmony_ci << " vs_out_pos_screen_centroid = vs_in_position_screen;\n" 555e5c31af7Sopenharmony_ci << " vs_out_pos_screen_sample = vs_in_position_screen;\n" 556e5c31af7Sopenharmony_ci << "}\n"; 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 559e5c31af7Sopenharmony_ci 560e5c31af7Sopenharmony_ci // Create fragment shader 561e5c31af7Sopenharmony_ci std::ostringstream fs; 562e5c31af7Sopenharmony_ci 563e5c31af7Sopenharmony_ci fs << "#version 440\n" 564e5c31af7Sopenharmony_ci << "layout(location = 0) centroid in vec2 fs_in_pos_screen_centroid;\n" 565e5c31af7Sopenharmony_ci << "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n" 566e5c31af7Sopenharmony_ci << "\n" 567e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 568e5c31af7Sopenharmony_ci << "\n"; 569e5c31af7Sopenharmony_ci 570e5c31af7Sopenharmony_ci if (m_imageMSParams.componentData.source == multisample::ComponentSource::PUSH_CONSTANT) 571e5c31af7Sopenharmony_ci { 572e5c31af7Sopenharmony_ci fs << "layout(push_constant) uniform PushConstants {\n" 573e5c31af7Sopenharmony_ci << " uint component;\n" 574e5c31af7Sopenharmony_ci << "};\n" 575e5c31af7Sopenharmony_ci << "\n"; 576e5c31af7Sopenharmony_ci } 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_ci fs << "void main (void)\n" 579e5c31af7Sopenharmony_ci << "{\n" 580e5c31af7Sopenharmony_ci << " const float threshold = 0.15625;\n" 581e5c31af7Sopenharmony_ci << "\n"; 582e5c31af7Sopenharmony_ci 583e5c31af7Sopenharmony_ci if (m_imageMSParams.componentData.source == multisample::ComponentSource::NONE) 584e5c31af7Sopenharmony_ci { 585e5c31af7Sopenharmony_ci fs << " const vec2 pos_interpolated_at_sample = interpolateAtSample(fs_in_pos_screen_centroid, gl_SampleID);\n" 586e5c31af7Sopenharmony_ci << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_sample - fs_in_pos_screen_sample), vec2(threshold)));\n"; 587e5c31af7Sopenharmony_ci } 588e5c31af7Sopenharmony_ci else if (m_imageMSParams.componentData.source == multisample::ComponentSource::CONSTANT) 589e5c31af7Sopenharmony_ci { 590e5c31af7Sopenharmony_ci const auto& index = m_imageMSParams.componentData.index; 591e5c31af7Sopenharmony_ci fs << " const float pos_interpolated_at_sample = interpolateAtSample(fs_in_pos_screen_centroid[" << index << "], gl_SampleID);\n" 592e5c31af7Sopenharmony_ci << " const bool valuesEqual = (abs(pos_interpolated_at_sample - fs_in_pos_screen_sample[" << index << "]) < threshold);\n"; 593e5c31af7Sopenharmony_ci } 594e5c31af7Sopenharmony_ci else // multisample::ComponentSource::PUSH_CONSTANT 595e5c31af7Sopenharmony_ci { 596e5c31af7Sopenharmony_ci fs << " const float pos_interpolated_at_sample = interpolateAtSample(fs_in_pos_screen_centroid[component], gl_SampleID);\n" 597e5c31af7Sopenharmony_ci << " const bool valuesEqual = (abs(pos_interpolated_at_sample - fs_in_pos_screen_sample[component]) < threshold);\n"; 598e5c31af7Sopenharmony_ci } 599e5c31af7Sopenharmony_ci 600e5c31af7Sopenharmony_ci fs << "\n" 601e5c31af7Sopenharmony_ci << " if (valuesEqual)\n" 602e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 603e5c31af7Sopenharmony_ci << " else\n" 604e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 605e5c31af7Sopenharmony_ci << "}\n"; 606e5c31af7Sopenharmony_ci 607e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 608e5c31af7Sopenharmony_ci} 609e5c31af7Sopenharmony_ci 610e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseInterpolateAtSampleConsistency>::createInstance (Context& context) const 611e5c31af7Sopenharmony_ci{ 612e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams); 613e5c31af7Sopenharmony_ci} 614e5c31af7Sopenharmony_ci 615e5c31af7Sopenharmony_ciclass MSCaseInterpolateAtCentroidConsistency; 616e5c31af7Sopenharmony_ci 617e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtCentroidConsistency>::init (void) 618e5c31af7Sopenharmony_ci{ 619e5c31af7Sopenharmony_ci const std::string indexStr = de::toString(m_imageMSParams.componentData.index); 620e5c31af7Sopenharmony_ci std::string componentMsg; 621e5c31af7Sopenharmony_ci 622e5c31af7Sopenharmony_ci switch (m_imageMSParams.componentData.source) 623e5c31af7Sopenharmony_ci { 624e5c31af7Sopenharmony_ci case multisample::ComponentSource::CONSTANT: componentMsg = "Using single constant component " + indexStr; break; 625e5c31af7Sopenharmony_ci case multisample::ComponentSource::PUSH_CONSTANT: componentMsg = "Using single component via push constant " + indexStr; break; 626e5c31af7Sopenharmony_ci default: break; 627e5c31af7Sopenharmony_ci } 628e5c31af7Sopenharmony_ci 629e5c31af7Sopenharmony_ci m_testCtx.getLog() 630e5c31af7Sopenharmony_ci << tcu::TestLog::Message 631e5c31af7Sopenharmony_ci << "Verifying that interpolateAtCentroid does not return different values than a corresponding centroid qualified varying.\n" 632e5c31af7Sopenharmony_ci << (componentMsg.empty() ? std::string() : componentMsg + "\n") 633e5c31af7Sopenharmony_ci << " Interpolate varying containing screen space location with sample and centroid qualifiers.\n" 634e5c31af7Sopenharmony_ci << " => interpolateAtCentroid(screenSample) = screenCentroid\n" 635e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 636e5c31af7Sopenharmony_ci 637e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 638e5c31af7Sopenharmony_ci} 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtCentroidConsistency>::initPrograms (vk::SourceCollections& programCollection) const 641e5c31af7Sopenharmony_ci{ 642e5c31af7Sopenharmony_ci // Create vertex shader 643e5c31af7Sopenharmony_ci std::ostringstream vs; 644e5c31af7Sopenharmony_ci 645e5c31af7Sopenharmony_ci vs << "#version 440\n" 646e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 647e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 vs_in_position_screen;\n" 648e5c31af7Sopenharmony_ci << "\n" 649e5c31af7Sopenharmony_ci << "layout(location = 0) out vec2 vs_out_pos_screen_sample[2];\n" 650e5c31af7Sopenharmony_ci << "layout(location = 2) out vec2 vs_out_pos_screen_centroid[2];\n" 651e5c31af7Sopenharmony_ci << "\n" 652e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 653e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 654e5c31af7Sopenharmony_ci << "};\n" 655e5c31af7Sopenharmony_ci << "void main (void)\n" 656e5c31af7Sopenharmony_ci << "{\n" 657e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 658e5c31af7Sopenharmony_ci // Index 0 is never read, so we'll populate them with bad values 659e5c31af7Sopenharmony_ci << " vs_out_pos_screen_sample[0] = vec2(-70.3, 42.1);\n" 660e5c31af7Sopenharmony_ci << " vs_out_pos_screen_centroid[0] = vec2(7.7, -3.2);\n" 661e5c31af7Sopenharmony_ci // Actual coordinates in index 1: 662e5c31af7Sopenharmony_ci << " vs_out_pos_screen_sample[1] = vs_in_position_screen;\n" 663e5c31af7Sopenharmony_ci << " vs_out_pos_screen_centroid[1] = vs_in_position_screen;\n" 664e5c31af7Sopenharmony_ci << "}\n"; 665e5c31af7Sopenharmony_ci 666e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 667e5c31af7Sopenharmony_ci 668e5c31af7Sopenharmony_ci // Create fragment shader 669e5c31af7Sopenharmony_ci std::ostringstream fs; 670e5c31af7Sopenharmony_ci 671e5c31af7Sopenharmony_ci fs << "#version 440\n" 672e5c31af7Sopenharmony_ci << "layout(location = 0) sample in vec2 fs_in_pos_screen_sample[2];\n" 673e5c31af7Sopenharmony_ci << "layout(location = 2) centroid in vec2 fs_in_pos_screen_centroid[2];\n" 674e5c31af7Sopenharmony_ci << "\n" 675e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 676e5c31af7Sopenharmony_ci << "\n"; 677e5c31af7Sopenharmony_ci 678e5c31af7Sopenharmony_ci if (m_imageMSParams.componentData.source == multisample::ComponentSource::PUSH_CONSTANT) 679e5c31af7Sopenharmony_ci { 680e5c31af7Sopenharmony_ci fs << "layout(push_constant) uniform PushConstants {\n" 681e5c31af7Sopenharmony_ci << " uint component;\n" 682e5c31af7Sopenharmony_ci << "};\n" 683e5c31af7Sopenharmony_ci << "\n"; 684e5c31af7Sopenharmony_ci } 685e5c31af7Sopenharmony_ci 686e5c31af7Sopenharmony_ci fs << "void main (void)\n" 687e5c31af7Sopenharmony_ci << "{\n" 688e5c31af7Sopenharmony_ci << " const float threshold = 0.0005;\n" 689e5c31af7Sopenharmony_ci << "\n"; 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci if (m_imageMSParams.componentData.source == multisample::ComponentSource::NONE) 692e5c31af7Sopenharmony_ci { 693e5c31af7Sopenharmony_ci fs << " const vec2 pos_interpolated_at_centroid = interpolateAtCentroid(fs_in_pos_screen_sample[1]);\n" 694e5c31af7Sopenharmony_ci << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_centroid - fs_in_pos_screen_centroid[1]), vec2(threshold)));\n"; 695e5c31af7Sopenharmony_ci } 696e5c31af7Sopenharmony_ci else if (m_imageMSParams.componentData.source == multisample::ComponentSource::CONSTANT) 697e5c31af7Sopenharmony_ci { 698e5c31af7Sopenharmony_ci const auto& index = m_imageMSParams.componentData.index; 699e5c31af7Sopenharmony_ci fs << " const float pos_interpolated_at_centroid = interpolateAtCentroid(fs_in_pos_screen_sample[1][" << index << "]);\n" 700e5c31af7Sopenharmony_ci << " const bool valuesEqual = (abs(pos_interpolated_at_centroid - fs_in_pos_screen_centroid[1][" << index << "]) < threshold);\n"; 701e5c31af7Sopenharmony_ci } 702e5c31af7Sopenharmony_ci else // multisample::ComponentSource::PUSH_CONSTANT 703e5c31af7Sopenharmony_ci { 704e5c31af7Sopenharmony_ci fs << " const float pos_interpolated_at_centroid = interpolateAtCentroid(fs_in_pos_screen_sample[1][component]);\n" 705e5c31af7Sopenharmony_ci << " const bool valuesEqual = (abs(pos_interpolated_at_centroid - fs_in_pos_screen_centroid[1][component]) < threshold);\n"; 706e5c31af7Sopenharmony_ci } 707e5c31af7Sopenharmony_ci 708e5c31af7Sopenharmony_ci fs << "\n" 709e5c31af7Sopenharmony_ci << " if (valuesEqual)\n" 710e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 711e5c31af7Sopenharmony_ci << " else\n" 712e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 713e5c31af7Sopenharmony_ci << "}\n"; 714e5c31af7Sopenharmony_ci 715e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 716e5c31af7Sopenharmony_ci} 717e5c31af7Sopenharmony_ci 718e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseInterpolateAtCentroidConsistency>::createInstance (Context& context) const 719e5c31af7Sopenharmony_ci{ 720e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams); 721e5c31af7Sopenharmony_ci} 722e5c31af7Sopenharmony_ci 723e5c31af7Sopenharmony_ciclass MSCaseInterpolateAtOffsetPixelCenter; 724e5c31af7Sopenharmony_ci 725e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtOffsetPixelCenter>::init (void) 726e5c31af7Sopenharmony_ci{ 727e5c31af7Sopenharmony_ci m_testCtx.getLog() 728e5c31af7Sopenharmony_ci << tcu::TestLog::Message 729e5c31af7Sopenharmony_ci << "Verifying that interpolateAtOffset returns value sampled at an offset from the center of the pixel.\n" 730e5c31af7Sopenharmony_ci << " Interpolate varying containing screen space location.\n" 731e5c31af7Sopenharmony_ci << " => interpolateAtOffset(screen, offset) should be \"varying value at the pixel center\" + offset" 732e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 733e5c31af7Sopenharmony_ci 734e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 735e5c31af7Sopenharmony_ci} 736e5c31af7Sopenharmony_ci 737e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtOffsetPixelCenter>::initPrograms (vk::SourceCollections& programCollection) const 738e5c31af7Sopenharmony_ci{ 739e5c31af7Sopenharmony_ci // Create vertex shader 740e5c31af7Sopenharmony_ci std::ostringstream vs; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci vs << "#version 440\n" 743e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 744e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 vs_in_position_screen;\n" 745e5c31af7Sopenharmony_ci << "\n" 746e5c31af7Sopenharmony_ci << "layout(location = 0) out vec2 vs_out_pos_screen;\n" 747e5c31af7Sopenharmony_ci << "layout(location = 1) out vec2 vs_out_offset;\n" 748e5c31af7Sopenharmony_ci << "\n" 749e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 750e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 751e5c31af7Sopenharmony_ci << "};\n" 752e5c31af7Sopenharmony_ci << "void main (void)\n" 753e5c31af7Sopenharmony_ci << "{\n" 754e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 755e5c31af7Sopenharmony_ci << " vs_out_pos_screen = vs_in_position_screen;\n" 756e5c31af7Sopenharmony_ci << " vs_out_offset = vs_in_position_ndc.xy * 0.5;\n" 757e5c31af7Sopenharmony_ci << "}\n"; 758e5c31af7Sopenharmony_ci 759e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 760e5c31af7Sopenharmony_ci 761e5c31af7Sopenharmony_ci // Create fragment shader 762e5c31af7Sopenharmony_ci std::ostringstream fs; 763e5c31af7Sopenharmony_ci 764e5c31af7Sopenharmony_ci fs << "#version 440\n" 765e5c31af7Sopenharmony_ci << "layout(location = 0) in vec2 fs_in_pos_screen;\n" 766e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 fs_in_offset;\n" 767e5c31af7Sopenharmony_ci << "\n" 768e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 769e5c31af7Sopenharmony_ci << "\n" 770e5c31af7Sopenharmony_ci << "void main (void)\n" 771e5c31af7Sopenharmony_ci << "{\n" 772e5c31af7Sopenharmony_ci << " const vec2 frag_center = interpolateAtOffset(fs_in_pos_screen, vec2(0.0));\n" 773e5c31af7Sopenharmony_ci << " const vec2 center_diff = abs(frag_center - fs_in_pos_screen);\n" 774e5c31af7Sopenharmony_ci << " const float threshold = 0.125;\n" 775e5c31af7Sopenharmony_ci << " bool valuesEqual = false;\n" 776e5c31af7Sopenharmony_ci << "\n" 777e5c31af7Sopenharmony_ci << " if (all(lessThan(center_diff, vec2(0.5 + threshold)))) {\n" 778e5c31af7Sopenharmony_ci << " const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen, fs_in_offset);\n" 779e5c31af7Sopenharmony_ci << " const vec2 reference_value = frag_center + fs_in_offset;\n" 780e5c31af7Sopenharmony_ci << "\n" 781e5c31af7Sopenharmony_ci << " valuesEqual = all(lessThan(abs(pos_interpolated_at_offset - reference_value), vec2(threshold)));\n" 782e5c31af7Sopenharmony_ci << " }\n" 783e5c31af7Sopenharmony_ci << "\n" 784e5c31af7Sopenharmony_ci << " if (valuesEqual)\n" 785e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 786e5c31af7Sopenharmony_ci << " else\n" 787e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 788e5c31af7Sopenharmony_ci << "}\n"; 789e5c31af7Sopenharmony_ci 790e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 791e5c31af7Sopenharmony_ci} 792e5c31af7Sopenharmony_ci 793e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseInterpolateAtOffsetPixelCenter>::createInstance (Context& context) const 794e5c31af7Sopenharmony_ci{ 795e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams); 796e5c31af7Sopenharmony_ci} 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ciclass MSCaseInterpolateAtOffsetSamplePosition; 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtOffsetSamplePosition>::init (void) 801e5c31af7Sopenharmony_ci{ 802e5c31af7Sopenharmony_ci const std::string indexStr = de::toString(m_imageMSParams.componentData.index); 803e5c31af7Sopenharmony_ci std::string componentMsg; 804e5c31af7Sopenharmony_ci 805e5c31af7Sopenharmony_ci switch (m_imageMSParams.componentData.source) 806e5c31af7Sopenharmony_ci { 807e5c31af7Sopenharmony_ci case multisample::ComponentSource::CONSTANT: componentMsg = "Using single constant component " + indexStr; break; 808e5c31af7Sopenharmony_ci case multisample::ComponentSource::PUSH_CONSTANT: componentMsg = "Using single component via push constant " + indexStr; break; 809e5c31af7Sopenharmony_ci default: break; 810e5c31af7Sopenharmony_ci } 811e5c31af7Sopenharmony_ci 812e5c31af7Sopenharmony_ci m_testCtx.getLog() 813e5c31af7Sopenharmony_ci << tcu::TestLog::Message 814e5c31af7Sopenharmony_ci << "Verifying that interpolateAtOffset of screen position with the offset of current sample position returns value " 815e5c31af7Sopenharmony_ci << "similar to screen position interpolated at sample.\n" 816e5c31af7Sopenharmony_ci << (componentMsg.empty() ? std::string() : componentMsg + "\n") 817e5c31af7Sopenharmony_ci << " Interpolate varying containing screen space location with and without sample qualifier.\n" 818e5c31af7Sopenharmony_ci << " => interpolateAtOffset(screenFragment, samplePosition - (0.5,0.5)) = screenSample" 819e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 822e5c31af7Sopenharmony_ci} 823e5c31af7Sopenharmony_ci 824e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseInterpolateAtOffsetSamplePosition>::initPrograms (vk::SourceCollections& programCollection) const 825e5c31af7Sopenharmony_ci{ 826e5c31af7Sopenharmony_ci // Create vertex shader 827e5c31af7Sopenharmony_ci std::ostringstream vs; 828e5c31af7Sopenharmony_ci 829e5c31af7Sopenharmony_ci vs << "#version 440\n" 830e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 831e5c31af7Sopenharmony_ci << "layout(location = 1) in vec2 vs_in_position_screen;\n" 832e5c31af7Sopenharmony_ci << "\n" 833e5c31af7Sopenharmony_ci << "layout(location = 0) out vec2 vs_out_pos_screen_fragment;\n" 834e5c31af7Sopenharmony_ci << "layout(location = 1) out vec2 vs_out_pos_screen_sample;\n" 835e5c31af7Sopenharmony_ci << "\n" 836e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 837e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 838e5c31af7Sopenharmony_ci << "};\n" 839e5c31af7Sopenharmony_ci << "void main (void)\n" 840e5c31af7Sopenharmony_ci << "{\n" 841e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 842e5c31af7Sopenharmony_ci << " vs_out_pos_screen_fragment = vs_in_position_screen;\n" 843e5c31af7Sopenharmony_ci << " vs_out_pos_screen_sample = vs_in_position_screen;\n" 844e5c31af7Sopenharmony_ci << "}\n"; 845e5c31af7Sopenharmony_ci 846e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 847e5c31af7Sopenharmony_ci 848e5c31af7Sopenharmony_ci // Create fragment shader 849e5c31af7Sopenharmony_ci std::ostringstream fs; 850e5c31af7Sopenharmony_ci 851e5c31af7Sopenharmony_ci fs << "#version 440\n" 852e5c31af7Sopenharmony_ci << "layout(location = 0) in vec2 fs_in_pos_screen_fragment;\n" 853e5c31af7Sopenharmony_ci << "layout(location = 1) sample in vec2 fs_in_pos_screen_sample;\n" 854e5c31af7Sopenharmony_ci << "\n" 855e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 856e5c31af7Sopenharmony_ci << "\n"; 857e5c31af7Sopenharmony_ci 858e5c31af7Sopenharmony_ci if (m_imageMSParams.componentData.source == multisample::ComponentSource::PUSH_CONSTANT) 859e5c31af7Sopenharmony_ci { 860e5c31af7Sopenharmony_ci fs << "layout(push_constant) uniform PushConstants {\n" 861e5c31af7Sopenharmony_ci << " uint component;\n" 862e5c31af7Sopenharmony_ci << "};\n" 863e5c31af7Sopenharmony_ci << "\n"; 864e5c31af7Sopenharmony_ci } 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci fs << "void main (void)\n" 867e5c31af7Sopenharmony_ci << "{\n" 868e5c31af7Sopenharmony_ci << " const float threshold = 0.15625;\n" 869e5c31af7Sopenharmony_ci << "\n" 870e5c31af7Sopenharmony_ci << " const vec2 offset = gl_SamplePosition - vec2(0.5, 0.5);\n"; 871e5c31af7Sopenharmony_ci 872e5c31af7Sopenharmony_ci if (m_imageMSParams.componentData.source == multisample::ComponentSource::NONE) 873e5c31af7Sopenharmony_ci { 874e5c31af7Sopenharmony_ci fs << " const vec2 pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen_fragment, offset);\n" 875e5c31af7Sopenharmony_ci << " const bool valuesEqual = all(lessThan(abs(pos_interpolated_at_offset - fs_in_pos_screen_sample), vec2(threshold)));\n"; 876e5c31af7Sopenharmony_ci } 877e5c31af7Sopenharmony_ci else if (m_imageMSParams.componentData.source == multisample::ComponentSource::CONSTANT) 878e5c31af7Sopenharmony_ci { 879e5c31af7Sopenharmony_ci const auto& index = m_imageMSParams.componentData.index; 880e5c31af7Sopenharmony_ci fs << " const float pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen_fragment[" << index << "], offset);\n" 881e5c31af7Sopenharmony_ci << " const bool valuesEqual = (abs(pos_interpolated_at_offset - fs_in_pos_screen_sample[" << index << "]) < threshold);\n"; 882e5c31af7Sopenharmony_ci } 883e5c31af7Sopenharmony_ci else // multisample::ComponentSource::PUSH_CONSTANT 884e5c31af7Sopenharmony_ci { 885e5c31af7Sopenharmony_ci fs << " const float pos_interpolated_at_offset = interpolateAtOffset(fs_in_pos_screen_fragment[component], offset);\n" 886e5c31af7Sopenharmony_ci << " const bool valuesEqual = (abs(pos_interpolated_at_offset - fs_in_pos_screen_sample[component]) < threshold);\n"; 887e5c31af7Sopenharmony_ci } 888e5c31af7Sopenharmony_ci 889e5c31af7Sopenharmony_ci fs << "\n" 890e5c31af7Sopenharmony_ci << " if (valuesEqual)\n" 891e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 892e5c31af7Sopenharmony_ci << " else\n" 893e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 894e5c31af7Sopenharmony_ci << "}\n"; 895e5c31af7Sopenharmony_ci 896e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 897e5c31af7Sopenharmony_ci} 898e5c31af7Sopenharmony_ci 899e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseInterpolateAtOffsetSamplePosition>::createInstance (Context& context) const 900e5c31af7Sopenharmony_ci{ 901e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceInterpolateScreenPosition>(context, m_imageMSParams); 902e5c31af7Sopenharmony_ci} 903e5c31af7Sopenharmony_ci 904e5c31af7Sopenharmony_ciclass MSInstanceInterpolateBarycentricCoordinates; 905e5c31af7Sopenharmony_ci 906e5c31af7Sopenharmony_citemplate<> MSInstanceBaseResolve::VertexDataDesc MSInstance<MSInstanceInterpolateBarycentricCoordinates>::getVertexDataDescripton (void) const 907e5c31af7Sopenharmony_ci{ 908e5c31af7Sopenharmony_ci VertexDataDesc vertexDataDesc; 909e5c31af7Sopenharmony_ci 910e5c31af7Sopenharmony_ci vertexDataDesc.verticesCount = 3u; 911e5c31af7Sopenharmony_ci vertexDataDesc.dataStride = sizeof(VertexDataNdcBarycentric); 912e5c31af7Sopenharmony_ci vertexDataDesc.dataSize = vertexDataDesc.verticesCount * vertexDataDesc.dataStride; 913e5c31af7Sopenharmony_ci vertexDataDesc.primitiveTopology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 914e5c31af7Sopenharmony_ci 915e5c31af7Sopenharmony_ci const VkVertexInputAttributeDescription vertexAttribPositionNdc = 916e5c31af7Sopenharmony_ci { 917e5c31af7Sopenharmony_ci 0u, // deUint32 location; 918e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 919e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 920e5c31af7Sopenharmony_ci DE_OFFSET_OF(VertexDataNdcBarycentric, positionNdc), // deUint32 offset; 921e5c31af7Sopenharmony_ci }; 922e5c31af7Sopenharmony_ci 923e5c31af7Sopenharmony_ci vertexDataDesc.vertexAttribDescVec.push_back(vertexAttribPositionNdc); 924e5c31af7Sopenharmony_ci 925e5c31af7Sopenharmony_ci const VkVertexInputAttributeDescription vertexAttrBarCoord = 926e5c31af7Sopenharmony_ci { 927e5c31af7Sopenharmony_ci 1u, // deUint32 location; 928e5c31af7Sopenharmony_ci 0u, // deUint32 binding; 929e5c31af7Sopenharmony_ci VK_FORMAT_R32G32B32_SFLOAT, // VkFormat format; 930e5c31af7Sopenharmony_ci DE_OFFSET_OF(VertexDataNdcBarycentric, barycentricCoord), // deUint32 offset; 931e5c31af7Sopenharmony_ci }; 932e5c31af7Sopenharmony_ci 933e5c31af7Sopenharmony_ci vertexDataDesc.vertexAttribDescVec.push_back(vertexAttrBarCoord); 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ci return vertexDataDesc; 936e5c31af7Sopenharmony_ci} 937e5c31af7Sopenharmony_ci 938e5c31af7Sopenharmony_citemplate<> void MSInstance<MSInstanceInterpolateBarycentricCoordinates>::uploadVertexData (const Allocation& vertexBufferAllocation, const VertexDataDesc& vertexDataDescripton) const 939e5c31af7Sopenharmony_ci{ 940e5c31af7Sopenharmony_ci // Create buffer storing vertex data 941e5c31af7Sopenharmony_ci std::vector<VertexDataNdcBarycentric> vertices; 942e5c31af7Sopenharmony_ci 943e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdcBarycentric(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 0.0f, 1.0f))); 944e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdcBarycentric(tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), tcu::Vec3(1.0f, 0.0f, 0.0f))); 945e5c31af7Sopenharmony_ci vertices.push_back(VertexDataNdcBarycentric(tcu::Vec4( 1.0f, -1.0f, 0.0f, 1.0f), tcu::Vec3(0.0f, 1.0f, 0.0f))); 946e5c31af7Sopenharmony_ci 947e5c31af7Sopenharmony_ci deMemcpy(vertexBufferAllocation.getHostPtr(), dataPointer(vertices), static_cast<std::size_t>(vertexDataDescripton.dataSize)); 948e5c31af7Sopenharmony_ci} 949e5c31af7Sopenharmony_ci 950e5c31af7Sopenharmony_citemplate<> tcu::TestStatus MSInstance<MSInstanceInterpolateBarycentricCoordinates>::verifyImageData (const vk::VkImageCreateInfo& imageRSInfo, const tcu::ConstPixelBufferAccess& dataRS) const 951e5c31af7Sopenharmony_ci{ 952e5c31af7Sopenharmony_ci if (checkForError(imageRSInfo, dataRS, 0)) 953e5c31af7Sopenharmony_ci return tcu::TestStatus::fail("Failed"); 954e5c31af7Sopenharmony_ci 955e5c31af7Sopenharmony_ci return tcu::TestStatus::pass("Passed"); 956e5c31af7Sopenharmony_ci} 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ciclass MSCaseCentroidQualifierInsidePrimitive; 959e5c31af7Sopenharmony_ci 960e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseCentroidQualifierInsidePrimitive>::init (void) 961e5c31af7Sopenharmony_ci{ 962e5c31af7Sopenharmony_ci m_testCtx.getLog() 963e5c31af7Sopenharmony_ci << tcu::TestLog::Message 964e5c31af7Sopenharmony_ci << "Verifying that varying qualified with centroid is interpolated at location inside both the pixel and the primitive being processed.\n" 965e5c31af7Sopenharmony_ci << " Interpolate triangle's barycentric coordinates with centroid qualifier.\n" 966e5c31af7Sopenharmony_ci << " => After interpolation we expect barycentric.xyz >= 0.0 && barycentric.xyz <= 1.0\n" 967e5c31af7Sopenharmony_ci << tcu::TestLog::EndMessage; 968e5c31af7Sopenharmony_ci 969e5c31af7Sopenharmony_ci MultisampleCaseBase::init(); 970e5c31af7Sopenharmony_ci} 971e5c31af7Sopenharmony_ci 972e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseCentroidQualifierInsidePrimitive>::initPrograms (vk::SourceCollections& programCollection) const 973e5c31af7Sopenharmony_ci{ 974e5c31af7Sopenharmony_ci // Create vertex shader 975e5c31af7Sopenharmony_ci std::ostringstream vs; 976e5c31af7Sopenharmony_ci 977e5c31af7Sopenharmony_ci vs << "#version 440\n" 978e5c31af7Sopenharmony_ci << "layout(location = 0) in vec4 vs_in_position_ndc;\n" 979e5c31af7Sopenharmony_ci << "layout(location = 1) in vec3 vs_in_barCoord;\n" 980e5c31af7Sopenharmony_ci << "\n" 981e5c31af7Sopenharmony_ci << "layout(location = 0) out vec3 vs_out_barCoord;\n" 982e5c31af7Sopenharmony_ci << "\n" 983e5c31af7Sopenharmony_ci << "out gl_PerVertex {\n" 984e5c31af7Sopenharmony_ci << " vec4 gl_Position;\n" 985e5c31af7Sopenharmony_ci << "};\n" 986e5c31af7Sopenharmony_ci << "void main (void)\n" 987e5c31af7Sopenharmony_ci << "{\n" 988e5c31af7Sopenharmony_ci << " gl_Position = vs_in_position_ndc;\n" 989e5c31af7Sopenharmony_ci << " vs_out_barCoord = vs_in_barCoord;\n" 990e5c31af7Sopenharmony_ci << "}\n"; 991e5c31af7Sopenharmony_ci 992e5c31af7Sopenharmony_ci programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str()); 993e5c31af7Sopenharmony_ci 994e5c31af7Sopenharmony_ci // Create fragment shader 995e5c31af7Sopenharmony_ci std::ostringstream fs; 996e5c31af7Sopenharmony_ci 997e5c31af7Sopenharmony_ci fs << "#version 440\n" 998e5c31af7Sopenharmony_ci << "layout(location = 0) centroid in vec3 fs_in_barCoord;\n" 999e5c31af7Sopenharmony_ci << "\n" 1000e5c31af7Sopenharmony_ci << "layout(location = 0) out vec4 fs_out_color;\n" 1001e5c31af7Sopenharmony_ci << "\n" 1002e5c31af7Sopenharmony_ci << "void main (void)\n" 1003e5c31af7Sopenharmony_ci << "{\n" 1004e5c31af7Sopenharmony_ci << " if( all(greaterThanEqual(fs_in_barCoord, vec3(0.0))) && all(lessThanEqual(fs_in_barCoord, vec3(1.0))) )\n" 1005e5c31af7Sopenharmony_ci << " fs_out_color = vec4(0.0, 1.0, 0.0, 1.0);\n" 1006e5c31af7Sopenharmony_ci << " else\n" 1007e5c31af7Sopenharmony_ci << " fs_out_color = vec4(1.0, 0.0, 0.0, 1.0);\n" 1008e5c31af7Sopenharmony_ci << "}\n"; 1009e5c31af7Sopenharmony_ci 1010e5c31af7Sopenharmony_ci programCollection.glslSources.add("fragment_shader") << glu::FragmentSource(fs.str()); 1011e5c31af7Sopenharmony_ci} 1012e5c31af7Sopenharmony_ci 1013e5c31af7Sopenharmony_citemplate<> void MSCase<MSCaseCentroidQualifierInsidePrimitive>::checkSupport (Context& context) const 1014e5c31af7Sopenharmony_ci{ 1015e5c31af7Sopenharmony_ci checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_imageMSParams.pipelineConstructionType); 1016e5c31af7Sopenharmony_ci} 1017e5c31af7Sopenharmony_ci 1018e5c31af7Sopenharmony_citemplate<> TestInstance* MSCase<MSCaseCentroidQualifierInsidePrimitive>::createInstance (Context& context) const 1019e5c31af7Sopenharmony_ci{ 1020e5c31af7Sopenharmony_ci return new MSInstance<MSInstanceInterpolateBarycentricCoordinates>(context, m_imageMSParams); 1021e5c31af7Sopenharmony_ci} 1022e5c31af7Sopenharmony_ci 1023e5c31af7Sopenharmony_ci} // multisample 1024e5c31af7Sopenharmony_ci 1025e5c31af7Sopenharmony_citcu::TestCaseGroup* createMultisampleInterpolationTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType) 1026e5c31af7Sopenharmony_ci{ 1027e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "multisample_interpolation")); 1028e5c31af7Sopenharmony_ci 1029e5c31af7Sopenharmony_ci const tcu::UVec3 imageSizes[] = 1030e5c31af7Sopenharmony_ci { 1031e5c31af7Sopenharmony_ci tcu::UVec3(128u, 128u, 1u), 1032e5c31af7Sopenharmony_ci tcu::UVec3(137u, 191u, 1u), 1033e5c31af7Sopenharmony_ci }; 1034e5c31af7Sopenharmony_ci 1035e5c31af7Sopenharmony_ci const deUint32 sizesElemCount = static_cast<deUint32>(sizeof(imageSizes) / sizeof(tcu::UVec3)); 1036e5c31af7Sopenharmony_ci 1037e5c31af7Sopenharmony_ci const vk::VkSampleCountFlagBits imageSamples[] = 1038e5c31af7Sopenharmony_ci { 1039e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_2_BIT, 1040e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_4_BIT, 1041e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_8_BIT, 1042e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_16_BIT, 1043e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_32_BIT, 1044e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_64_BIT, 1045e5c31af7Sopenharmony_ci }; 1046e5c31af7Sopenharmony_ci 1047e5c31af7Sopenharmony_ci const deUint32 samplesElemCount = static_cast<deUint32>(sizeof(imageSamples) / sizeof(vk::VkSampleCountFlagBits)); 1048e5c31af7Sopenharmony_ci 1049e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> caseGroup(new tcu::TestCaseGroup(testCtx, "sample_interpolate_at_single_sample")); 1050e5c31af7Sopenharmony_ci 1051e5c31af7Sopenharmony_ci for (deUint32 imageSizeNdx = 0u; imageSizeNdx < sizesElemCount; ++imageSizeNdx) 1052e5c31af7Sopenharmony_ci { 1053e5c31af7Sopenharmony_ci const tcu::UVec3 imageSize = imageSizes[imageSizeNdx]; 1054e5c31af7Sopenharmony_ci std::ostringstream imageSizeStream; 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_ci imageSizeStream << imageSize.x() << "_" << imageSize.y() << "_" << imageSize.z(); 1057e5c31af7Sopenharmony_ci 1058e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> sizeGroup(new tcu::TestCaseGroup(testCtx, imageSizeStream.str().c_str())); 1059e5c31af7Sopenharmony_ci 1060e5c31af7Sopenharmony_ci multisample::ImageMSParams imageParams 1061e5c31af7Sopenharmony_ci { 1062e5c31af7Sopenharmony_ci pipelineConstructionType, 1063e5c31af7Sopenharmony_ci vk::VK_SAMPLE_COUNT_1_BIT, 1064e5c31af7Sopenharmony_ci imageSize, 1065e5c31af7Sopenharmony_ci multisample::ComponentData{}, 1066e5c31af7Sopenharmony_ci 1.0f, 1067e5c31af7Sopenharmony_ci }; 1068e5c31af7Sopenharmony_ci sizeGroup->addChild(multisample::MSCase<multisample::MSCaseInterpolateAtSampleSingleSample>::createCase(testCtx, "samples_" + de::toString(1), imageParams)); 1069e5c31af7Sopenharmony_ci 1070e5c31af7Sopenharmony_ci caseGroup->addChild(sizeGroup.release()); 1071e5c31af7Sopenharmony_ci } 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ci testGroup->addChild(caseGroup.release()); 1074e5c31af7Sopenharmony_ci 1075e5c31af7Sopenharmony_ci testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleDistinctValues> > (testCtx, "sample_interpolate_at_distinct_values", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1076e5c31af7Sopenharmony_ci testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleIgnoresCentroid> >(testCtx, "sample_interpolate_at_ignores_centroid", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1077e5c31af7Sopenharmony_ci 1078e5c31af7Sopenharmony_ci // Test consistency in sample interpolation function 1079e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> sampleGroup(new tcu::TestCaseGroup(testCtx, "sample_interpolation_consistency")); 1080e5c31af7Sopenharmony_ci sampleGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleConsistency> > (testCtx, "all_components", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1081e5c31af7Sopenharmony_ci sampleGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleConsistency> > (testCtx, "component_0", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::CONSTANT, 0u})); 1082e5c31af7Sopenharmony_ci sampleGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleConsistency> > (testCtx, "component_1", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::CONSTANT, 1u})); 1083e5c31af7Sopenharmony_ci sampleGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleConsistency> > (testCtx, "pushc_component_0", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::PUSH_CONSTANT, 0u})); 1084e5c31af7Sopenharmony_ci sampleGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtSampleConsistency> > (testCtx, "pushc_component_1", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::PUSH_CONSTANT, 1u})); 1085e5c31af7Sopenharmony_ci testGroup->addChild(sampleGroup.release()); 1086e5c31af7Sopenharmony_ci 1087e5c31af7Sopenharmony_ci testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseSampleQualifierDistinctValues> > (testCtx, "sample_qualifier_distinct_values", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1088e5c31af7Sopenharmony_ci 1089e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> centroidGroup(new tcu::TestCaseGroup(testCtx, "centroid_interpolation_consistency", "Test consistency in centroid interpolation function")); 1090e5c31af7Sopenharmony_ci centroidGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtCentroidConsistency> > (testCtx, "all_components", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1091e5c31af7Sopenharmony_ci centroidGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtCentroidConsistency> > (testCtx, "component_0", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::CONSTANT, 0u})); 1092e5c31af7Sopenharmony_ci centroidGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtCentroidConsistency> > (testCtx, "component_1", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::CONSTANT, 1u})); 1093e5c31af7Sopenharmony_ci centroidGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtCentroidConsistency> > (testCtx, "pushc_component_0", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::PUSH_CONSTANT, 0u})); 1094e5c31af7Sopenharmony_ci centroidGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtCentroidConsistency> > (testCtx, "pushc_component_1", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::PUSH_CONSTANT, 1u})); 1095e5c31af7Sopenharmony_ci testGroup->addChild(centroidGroup.release()); 1096e5c31af7Sopenharmony_ci 1097e5c31af7Sopenharmony_ci#ifndef CTS_USES_VULKANSC 1098e5c31af7Sopenharmony_ci // there is no support for pipelineConstructionType in amber 1099e5c31af7Sopenharmony_ci if (pipelineConstructionType == vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) 1100e5c31af7Sopenharmony_ci { 1101e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> reInterpolationGroup(new tcu::TestCaseGroup(testCtx, "reinterpolation_consistency", "Test consistency in reinterpolation")); 1102e5c31af7Sopenharmony_ci std::vector<std::string> requirements; 1103e5c31af7Sopenharmony_ci requirements.push_back("Features.sampleRateShading"); 1104e5c31af7Sopenharmony_ci reInterpolationGroup->addChild(cts_amber::createAmberTestCase(testCtx, "interpolate_at_centroid", "", "pipeline", "reinterpolate_at_centroid.amber", requirements)); 1105e5c31af7Sopenharmony_ci reInterpolationGroup->addChild(cts_amber::createAmberTestCase(testCtx, "interpolate_at_sample", "", "pipeline", "reinterpolate_at_sample.amber", requirements)); 1106e5c31af7Sopenharmony_ci testGroup->addChild(reInterpolationGroup.release()); 1107e5c31af7Sopenharmony_ci 1108e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> nonuniformInterpolantIndexingGroup(new tcu::TestCaseGroup(testCtx, "nonuniform_interpolant_indexing", "Test nonuniform interpolant indexing")); 1109e5c31af7Sopenharmony_ci std::vector<std::string> requirementsNonuniformIntepolantIndexing; 1110e5c31af7Sopenharmony_ci requirementsNonuniformIntepolantIndexing.push_back("Features.sampleRateShading"); 1111e5c31af7Sopenharmony_ci nonuniformInterpolantIndexingGroup->addChild(cts_amber::createAmberTestCase(testCtx, "centroid", "pipeline/nonuniform_interpolant_indexing", "centroid.amber", requirementsNonuniformIntepolantIndexing)); 1112e5c31af7Sopenharmony_ci nonuniformInterpolantIndexingGroup->addChild(cts_amber::createAmberTestCase(testCtx, "sample", "pipeline/nonuniform_interpolant_indexing", "sample.amber", requirementsNonuniformIntepolantIndexing)); 1113e5c31af7Sopenharmony_ci nonuniformInterpolantIndexingGroup->addChild(cts_amber::createAmberTestCase(testCtx, "offset", "pipeline/nonuniform_interpolant_indexing", "offset.amber", requirementsNonuniformIntepolantIndexing)); 1114e5c31af7Sopenharmony_ci testGroup->addChild(nonuniformInterpolantIndexingGroup.release()); 1115e5c31af7Sopenharmony_ci } 1116e5c31af7Sopenharmony_ci 1117e5c31af7Sopenharmony_ci testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseCentroidQualifierInsidePrimitive> > (testCtx, "centroid_qualifier_inside_primitive", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1118e5c31af7Sopenharmony_ci#endif // CTS_USES_VULKANSC 1119e5c31af7Sopenharmony_ci testGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetPixelCenter> > (testCtx, "offset_interpolate_at_pixel_center", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1120e5c31af7Sopenharmony_ci 1121e5c31af7Sopenharmony_ci de::MovePtr<tcu::TestCaseGroup> offsetGroup(new tcu::TestCaseGroup(testCtx, "offset_interpolation_at_sample_position", "Test interpolation at offset function works for sample positions")); 1122e5c31af7Sopenharmony_ci offsetGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetSamplePosition> > (testCtx, "all_components", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount)); 1123e5c31af7Sopenharmony_ci offsetGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetSamplePosition> > (testCtx, "component_0", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::CONSTANT, 0u})); 1124e5c31af7Sopenharmony_ci offsetGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetSamplePosition> > (testCtx, "component_1", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::CONSTANT, 1u})); 1125e5c31af7Sopenharmony_ci offsetGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetSamplePosition> > (testCtx, "pushc_component_0", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::PUSH_CONSTANT, 0u})); 1126e5c31af7Sopenharmony_ci offsetGroup->addChild(makeMSGroup<multisample::MSCase<multisample::MSCaseInterpolateAtOffsetSamplePosition> > (testCtx, "pushc_component_1", pipelineConstructionType, imageSizes, sizesElemCount, imageSamples, samplesElemCount, multisample::ComponentData{multisample::ComponentSource::PUSH_CONSTANT, 1u})); 1127e5c31af7Sopenharmony_ci testGroup->addChild(offsetGroup.release()); 1128e5c31af7Sopenharmony_ci 1129e5c31af7Sopenharmony_ci return testGroup.release(); 1130e5c31af7Sopenharmony_ci} 1131e5c31af7Sopenharmony_ci 1132e5c31af7Sopenharmony_ci} // pipeline 1133e5c31af7Sopenharmony_ci} // vkt 1134