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