1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7 * Copyright (c) 2016 The Android Open Source Project
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
23 * \brief Shader builtin variable tests.
24 *//*--------------------------------------------------------------------*/
26 #include "vktShaderRenderBuiltinVarTests.hpp"
27 #include "vktShaderRender.hpp"
28 #include "gluShaderUtil.hpp"
29 #include "tcuImageCompare.hpp"
30 #include "tcuStringTemplate.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "tcuTestLog.hpp"
35 #include "deRandom.hpp"
51 class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance
54 BuiltinGlFrontFacingCaseInstance (Context& context);
56 TestStatus iterate (void);
57 virtual void setupDefaultInputs (void);
60 BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context)
61 : ShaderRenderCaseInstance (context)
65 TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void)
67 const UVec2 viewportSize = getViewportSize();
68 const int width = viewportSize.x();
69 const int height = viewportSize.y();
70 const RGBA threshold (2, 2, 2, 2);
71 Surface resImage (width, height);
72 Surface refImage (width, height);
73 bool compareOk = false;
74 const deUint16 indices[12] =
83 render(6, 4, indices);
84 copy(resImage.getAccess(), getResultImage().getAccess());
86 for (int y = 0; y < refImage.getHeight(); y++)
88 for (int x = 0; x < refImage.getWidth()/2; x++)
89 refImage.setPixel(x, y, RGBA::green());
91 for (int x = refImage.getWidth()/2; x < refImage.getWidth(); x++)
92 refImage.setPixel(x, y, RGBA::blue());
95 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
98 return TestStatus::pass("Result image matches reference");
100 return TestStatus::fail("Image mismatch");
103 void BuiltinGlFrontFacingCaseInstance::setupDefaultInputs (void)
105 const float vertices[] =
107 -1.0f, -1.0f, 0.0f, 1.0f,
108 0.0f, -1.0f, 0.0f, 1.0f,
109 1.0f, -1.0f, 0.0f, 1.0f,
110 1.0f, 1.0f, 0.0f, 1.0f,
111 0.0f, 1.0f, 0.0f, 1.0f,
112 -1.0f, 1.0f, 0.0f, 1.0f
115 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
118 class BuiltinGlFrontFacingCase : public TestCase
121 BuiltinGlFrontFacingCase (TestContext& testCtx, const string& name, const string& description);
122 virtual ~BuiltinGlFrontFacingCase (void);
124 void initPrograms (SourceCollections& dst) const;
125 TestInstance* createInstance (Context& context) const;
128 BuiltinGlFrontFacingCase (const BuiltinGlFrontFacingCase&); // not allowed!
129 BuiltinGlFrontFacingCase& operator= (const BuiltinGlFrontFacingCase&); // not allowed!
132 BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, const string& name, const string& description)
133 : TestCase(testCtx, name, description)
137 BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void)
141 void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& dst) const
143 dst.glslSources.add("vert") << glu::VertexSource(
145 "layout(location = 0) in highp vec4 a_position;\n"
148 " gl_Position = a_position;\n"
151 dst.glslSources.add("frag") << glu::FragmentSource(
153 "layout(location = 0) out lowp vec4 o_color;\n"
156 " if (gl_FrontFacing)\n"
157 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
159 " o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
163 TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
165 return new BuiltinGlFrontFacingCaseInstance(context);
168 class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
171 BuiltinGlFragCoordXYZCaseInstance (Context& context);
173 TestStatus iterate (void);
174 virtual void setupDefaultInputs (void);
177 BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
178 : ShaderRenderCaseInstance (context)
182 TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
184 const UVec2 viewportSize = getViewportSize();
185 const int width = viewportSize.x();
186 const int height = viewportSize.y();
187 const tcu::Vec3 scale (1.f / float(width), 1.f / float(height), 1.0f);
188 const tcu::RGBA threshold (2, 2, 2, 2);
189 Surface resImage (width, height);
190 Surface refImage (width, height);
191 bool compareOk = false;
192 const deUint16 indices[6] =
199 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
201 render(4, 2, indices);
202 copy(resImage.getAccess(), getResultImage().getAccess());
205 for (int y = 0; y < refImage.getHeight(); y++)
207 for (int x = 0; x < refImage.getWidth(); x++)
209 const float xf = (float(x)+.5f) / float(refImage.getWidth());
210 const float yf = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
211 const float z = (xf + yf) / 2.0f;
212 const Vec3 fragCoord (float(x)+.5f, float(y)+.5f, z);
213 const Vec3 scaledFC = fragCoord*scale;
214 const Vec4 color (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
216 refImage.setPixel(x, y, RGBA(color));
220 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
223 return TestStatus::pass("Result image matches reference");
225 return TestStatus::fail("Image mismatch");
228 void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
230 const float vertices[] =
232 -1.0f, 1.0f, 0.0f, 1.0f,
233 -1.0f, -1.0f, 0.5f, 1.0f,
234 1.0f, 1.0f, 0.5f, 1.0f,
235 1.0f, -1.0f, 1.0f, 1.0f,
238 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
241 class BuiltinGlFragCoordXYZCase : public TestCase
244 BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description);
245 virtual ~BuiltinGlFragCoordXYZCase (void);
247 void initPrograms (SourceCollections& dst) const;
248 TestInstance* createInstance (Context& context) const;
251 BuiltinGlFragCoordXYZCase (const BuiltinGlFragCoordXYZCase&); // not allowed!
252 BuiltinGlFragCoordXYZCase& operator= (const BuiltinGlFragCoordXYZCase&); // not allowed!
255 BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
256 : TestCase(testCtx, name, description)
260 BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
264 void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
266 dst.glslSources.add("vert") << glu::VertexSource(
268 "layout(location = 0) in highp vec4 a_position;\n"
271 " gl_Position = a_position;\n"
274 dst.glslSources.add("frag") << glu::FragmentSource(
276 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
277 "layout(location = 0) out highp vec4 o_color;\n"
280 " o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
284 TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
286 return new BuiltinGlFragCoordXYZCaseInstance(context);
289 inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
291 return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
294 class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
297 BuiltinGlFragCoordWCaseInstance (Context& context);
299 TestStatus iterate (void);
300 virtual void setupDefaultInputs (void);
308 BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
309 : ShaderRenderCaseInstance (context)
310 , m_w (1.7f, 2.0f, 1.2f, 1.0f)
314 TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
316 const UVec2 viewportSize = getViewportSize();
317 const int width = viewportSize.x();
318 const int height = viewportSize.y();
319 const tcu::RGBA threshold (2, 2, 2, 2);
320 Surface resImage (width, height);
321 Surface refImage (width, height);
322 bool compareOk = false;
323 const deUint16 indices[6] =
330 render(4, 2, indices);
331 copy(resImage.getAccess(), getResultImage().getAccess());
334 for (int y = 0; y < refImage.getHeight(); y++)
336 for (int x = 0; x < refImage.getWidth(); x++)
338 const float xf = (float(x)+.5f) / float(refImage.getWidth());
339 const float yf = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
340 const float oow = ((xf + yf) < 1.0f)
341 ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
342 : projectedTriInterpolate(Vec3(m_w[3], m_w[2], m_w[1]), Vec3(m_w[3], m_w[2], m_w[1]), 1.0f-xf, 1.0f-yf);
343 const Vec4 color (0.0f, oow - 1.0f, 0.0f, 1.0f);
345 refImage.setPixel(x, y, RGBA(color));
349 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
352 return TestStatus::pass("Result image matches reference");
354 return TestStatus::fail("Image mismatch");
357 void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
359 const float vertices[] =
361 -m_w[0], m_w[0], 0.0f, m_w[0],
362 -m_w[1], -m_w[1], 0.0f, m_w[1],
363 m_w[2], m_w[2], 0.0f, m_w[2],
364 m_w[3], -m_w[3], 0.0f, m_w[3]
367 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
370 class BuiltinGlFragCoordWCase : public TestCase
373 BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description);
374 virtual ~BuiltinGlFragCoordWCase (void);
376 void initPrograms (SourceCollections& dst) const;
377 TestInstance* createInstance (Context& context) const;
380 BuiltinGlFragCoordWCase (const BuiltinGlFragCoordWCase&); // not allowed!
381 BuiltinGlFragCoordWCase& operator= (const BuiltinGlFragCoordWCase&); // not allowed!
384 BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
385 : TestCase(testCtx, name, description)
389 BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
393 void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
395 dst.glslSources.add("vert") << glu::VertexSource(
397 "layout(location = 0) in highp vec4 a_position;\n"
400 " gl_Position = a_position;\n"
403 dst.glslSources.add("frag") << glu::FragmentSource(
405 "layout(location = 0) out highp vec4 o_color;\n"
408 " o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
412 TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
414 return new BuiltinGlFragCoordWCaseInstance(context);
417 class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
420 BuiltinGlPointCoordCaseInstance (Context& context);
422 TestStatus iterate (void);
423 virtual void setupDefaultInputs (void);
426 BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context)
427 : ShaderRenderCaseInstance (context)
431 TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
433 const UVec2 viewportSize = getViewportSize();
434 const int width = viewportSize.x();
435 const int height = viewportSize.y();
436 const float threshold = 0.02f;
437 const int numPoints = 16;
438 vector<Vec3> coords (numPoints);
439 de::Random rnd (0x145fa);
440 Surface resImage (width, height);
441 Surface refImage (width, height);
442 bool compareOk = false;
444 // Compute coordinates.
446 const VkPhysicalDeviceLimits& limits = m_context.getDeviceProperties().limits;
447 const float minPointSize = limits.pointSizeRange[0];
448 const float maxPointSize = limits.pointSizeRange[1];
449 const int pointSizeDeltaMultiples = de::max(1, deCeilFloatToInt32((maxPointSize - minPointSize) / limits.pointSizeGranularity));
451 TCU_CHECK(minPointSize <= maxPointSize);
453 for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
455 coord->x() = rnd.getFloat(-0.9f, 0.9f);
456 coord->y() = rnd.getFloat(-0.9f, 0.9f);
457 coord->z() = de::min(maxPointSize, minPointSize + float(rnd.getInt(0, pointSizeDeltaMultiples)) * limits.pointSizeGranularity);
462 addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
463 render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
464 copy(resImage.getAccess(), getResultImage().getAccess());
467 clear(refImage.getAccess(), m_clearColor);
469 for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
471 const float centerX = float(width) *(pointIter->x()*0.5f + 0.5f);
472 const float centerY = float(height)*(pointIter->y()*0.5f + 0.5f);
473 const float size = pointIter->z();
474 const int x0 = deRoundFloatToInt32(centerX - size*0.5f);
475 const int y0 = deRoundFloatToInt32(centerY - size*0.5f);
476 const int x1 = deRoundFloatToInt32(centerX + size*0.5f);
477 const int y1 = deRoundFloatToInt32(centerY + size*0.5f);
481 for (int yo = 0; yo < h; yo++)
483 for (int xo = 0; xo < w; xo++)
485 const int dx = x0+xo;
486 const int dy = y0+yo;
487 const float fragX = float(dx) + 0.5f;
488 const float fragY = float(dy) + 0.5f;
489 const float s = 0.5f + (fragX - centerX) / size;
490 const float t = 0.5f + (fragY - centerY) / size;
491 const Vec4 color (s, t, 0.0f, 1.0f);
493 if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
494 refImage.setPixel(dx, dy, RGBA(color));
499 compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
502 return TestStatus::pass("Result image matches reference");
504 return TestStatus::fail("Image mismatch");
507 void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
511 class BuiltinGlPointCoordCase : public TestCase
514 BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description);
515 virtual ~BuiltinGlPointCoordCase (void);
517 void initPrograms (SourceCollections& dst) const;
518 TestInstance* createInstance (Context& context) const;
521 BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&); // not allowed!
522 BuiltinGlPointCoordCase& operator= (const BuiltinGlPointCoordCase&); // not allowed!
525 BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description)
526 : TestCase(testCtx, name, description)
530 BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
534 void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
536 dst.glslSources.add("vert") << glu::VertexSource(
538 "layout(location = 0) in highp vec3 a_position;\n"
541 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
542 " gl_PointSize = a_position.z;\n"
545 dst.glslSources.add("frag") << glu::FragmentSource(
547 "layout(location = 0) out lowp vec4 o_color;\n"
550 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
554 TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
556 return new BuiltinGlPointCoordCaseInstance(context);
559 enum ShaderInputTypeBits
561 SHADER_INPUT_BUILTIN_BIT = 0x01,
562 SHADER_INPUT_VARYING_BIT = 0x02,
563 SHADER_INPUT_CONSTANT_BIT = 0x04
566 typedef deUint16 ShaderInputTypes;
568 string shaderInputTypeToString (ShaderInputTypes type)
570 string typeString = "input";
575 if (type & SHADER_INPUT_BUILTIN_BIT)
576 typeString += "_builtin";
578 if (type & SHADER_INPUT_VARYING_BIT)
579 typeString += "_varying";
581 if (type & SHADER_INPUT_CONSTANT_BIT)
582 typeString += "_constant";
587 class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
590 BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes);
592 TestStatus iterate (void);
593 virtual void setupDefaultInputs (void);
594 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
597 const ShaderInputTypes m_shaderInputTypes;
598 const Vec4 m_constantColor;
601 BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
602 : ShaderRenderCaseInstance (context)
603 , m_shaderInputTypes (shaderInputTypes)
604 , m_constantColor (0.1f, 0.05f, 0.2f, 0.0f)
608 TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
610 const UVec2 viewportSize = getViewportSize();
611 const int width = viewportSize.x();
612 const int height = viewportSize.y();
613 const tcu::RGBA threshold (2, 2, 2, 2);
614 Surface resImage (width, height);
615 Surface refImage (width, height);
616 bool compareOk = false;
617 const VkPushConstantRange pcRanges =
619 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
620 0u, // deUint32 offset;
621 sizeof(Vec4) // deUint32 size;
623 const deUint16 indices[12] =
633 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
634 setPushConstantRanges(1, &pcRanges);
636 render(6, 4, indices);
637 copy(resImage.getAccess(), getResultImage().getAccess());
640 for (int y = 0; y < refImage.getHeight(); y++)
642 for (int x = 0; x < refImage.getWidth(); x++)
644 Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
646 if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
647 !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
649 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
651 const float xf = (float(x)+.5f) / float(refImage.getWidth());
652 color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
655 color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
658 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
659 color += m_constantColor;
661 refImage.setPixel(x, y, RGBA(color));
665 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
668 return TestStatus::pass("Result image matches reference");
670 return TestStatus::fail("Image mismatch");
673 void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
675 const float vertices[] =
677 -1.0f, -1.0f, 0.0f, 1.0f,
678 0.0f, -1.0f, 0.0f, 1.0f,
679 1.0f, -1.0f, 0.0f, 1.0f,
680 1.0f, 1.0f, 0.0f, 1.0f,
681 0.0f, 1.0f, 0.0f, 1.0f,
682 -1.0f, 1.0f, 0.0f, 1.0f
685 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
687 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
689 const float colors[] =
691 0.6f, 0.0f, 0.0f, 1.0f,
692 0.3f, 0.3f, 0.0f, 1.0f,
693 0.0f, 0.6f, 0.0f, 1.0f,
694 0.0f, 0.6f, 0.0f, 1.0f,
695 0.3f, 0.3f, 0.0f, 1.0f,
696 0.6f, 0.0f, 0.0f, 1.0f
698 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
702 void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
704 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
706 const DeviceInterface& vk = m_context.getDeviceInterface();
707 vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
711 class BuiltinInputVariationsCase : public TestCase
714 BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
715 virtual ~BuiltinInputVariationsCase (void);
717 void initPrograms (SourceCollections& dst) const;
718 TestInstance* createInstance (Context& context) const;
721 BuiltinInputVariationsCase (const BuiltinInputVariationsCase&); // not allowed!
722 BuiltinInputVariationsCase& operator= (const BuiltinInputVariationsCase&); // not allowed!
723 const ShaderInputTypes m_shaderInputTypes;
726 BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
727 : TestCase (testCtx, name, description)
728 , m_shaderInputTypes (shaderInputTypes)
732 BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
736 void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
738 map<string, string> vertexParams;
739 map<string, string> fragmentParams;
740 const tcu::StringTemplate vertexCodeTemplate (
742 "layout(location = 0) in highp vec4 a_position;\n"
743 "out gl_PerVertex {\n"
744 " vec4 gl_Position;\n"
749 " gl_Position = a_position;\n"
753 const tcu::StringTemplate fragmentCodeTemplate (
757 "layout(location = 0) out highp vec4 o_color;\n"
760 " o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
766 vertexParams["VARYING_DECL"] =
767 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 1) in highp vec4 a_color;\n"
768 "layout(location = 0) out highp vec4 v_color;\n"
771 vertexParams["VARYING_USAGE"] =
772 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "v_color = a_color;\n"
775 fragmentParams["VARYING_DECL"] =
776 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 0) in highp vec4 a_color;\n"
779 fragmentParams["CONSTANT_DECL"] =
780 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "layout(push_constant) uniform PCBlock {\n"
785 fragmentParams["BUILTIN_USAGE"] =
786 m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT ? "if (gl_FrontFacing)\n"
789 fragmentParams["VARYING_USAGE"] =
790 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "o_color += vec4(a_color.xyz, 0.0);\n"
791 : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
794 fragmentParams["CONSTANT_USAGE"] =
795 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "o_color += pc.color;\n"
798 dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
799 dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
802 TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
804 return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
809 TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
811 de::MovePtr<TestCaseGroup> builtinGroup (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
812 de::MovePtr<TestCaseGroup> simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases."));
813 de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
815 simpleGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, "frontfacing", "FrontFacing test"));
816 simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
817 simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
818 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test"));
820 builtinGroup->addChild(simpleGroup.release());
822 for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
824 inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
827 builtinGroup->addChild(inputVariationsGroup.release());
828 return builtinGroup.release();