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