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"
34 #include "deRandom.hpp"
50 class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance
53 BuiltinGlFrontFacingCaseInstance (Context& context);
55 TestStatus iterate (void);
56 virtual void setupDefaultInputs (void);
59 BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context)
60 : ShaderRenderCaseInstance (context)
64 TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void)
66 const UVec2 viewportSize = getViewportSize();
67 const int width = viewportSize.x();
68 const int height = viewportSize.y();
69 const RGBA threshold (2, 2, 2, 2);
70 Surface resImage (width, height);
71 Surface refImage (width, height);
72 bool compareOk = false;
73 const deUint16 indices[12] =
82 render(6, 4, indices);
83 copy(resImage.getAccess(), getResultImage().getAccess());
85 for (int y = 0; y < refImage.getHeight(); y++)
87 for (int x = 0; x < refImage.getWidth()/2; x++)
88 refImage.setPixel(x, y, RGBA::green());
90 for (int x = refImage.getWidth()/2; x < refImage.getWidth(); x++)
91 refImage.setPixel(x, y, RGBA::blue());
94 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
97 return TestStatus::pass("Result image matches reference");
99 return TestStatus::fail("Image mismatch");
102 void BuiltinGlFrontFacingCaseInstance::setupDefaultInputs (void)
104 const float vertices[] =
106 -1.0f, -1.0f, 0.0f, 1.0f,
107 0.0f, -1.0f, 0.0f, 1.0f,
108 1.0f, -1.0f, 0.0f, 1.0f,
109 1.0f, 1.0f, 0.0f, 1.0f,
110 0.0f, 1.0f, 0.0f, 1.0f,
111 -1.0f, 1.0f, 0.0f, 1.0f
114 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
117 class BuiltinGlFrontFacingCase : public TestCase
120 BuiltinGlFrontFacingCase (TestContext& testCtx, const string& name, const string& description);
121 virtual ~BuiltinGlFrontFacingCase (void);
123 void initPrograms (SourceCollections& dst) const;
124 TestInstance* createInstance (Context& context) const;
127 BuiltinGlFrontFacingCase (const BuiltinGlFrontFacingCase&); // not allowed!
128 BuiltinGlFrontFacingCase& operator= (const BuiltinGlFrontFacingCase&); // not allowed!
131 BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, const string& name, const string& description)
132 : TestCase(testCtx, name, description)
136 BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void)
140 void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& dst) const
142 dst.glslSources.add("vert") << glu::VertexSource(
144 "layout(location = 0) in highp vec4 a_position;\n"
147 " gl_Position = a_position;\n"
150 dst.glslSources.add("frag") << glu::FragmentSource(
152 "layout(location = 0) out lowp vec4 o_color;\n"
155 " if (gl_FrontFacing)\n"
156 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
158 " o_color = vec4(0.0, 0.0, 1.0, 1.0);\n"
162 TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
164 return new BuiltinGlFrontFacingCaseInstance(context);
167 class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
170 BuiltinGlFragCoordXYZCaseInstance (Context& context);
172 TestStatus iterate (void);
173 virtual void setupDefaultInputs (void);
176 BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
177 : ShaderRenderCaseInstance (context)
181 TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
183 const UVec2 viewportSize = getViewportSize();
184 const int width = viewportSize.x();
185 const int height = viewportSize.y();
186 const tcu::Vec3 scale (1.f / float(width), 1.f / float(height), 1.0f);
187 const tcu::RGBA threshold (2, 2, 2, 2);
188 Surface resImage (width, height);
189 Surface refImage (width, height);
190 bool compareOk = false;
191 const deUint16 indices[6] =
198 addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
200 render(4, 2, indices);
201 copy(resImage.getAccess(), getResultImage().getAccess());
204 for (int y = 0; y < refImage.getHeight(); y++)
206 for (int x = 0; x < refImage.getWidth(); x++)
208 const float xf = (float(x)+.5f) / float(refImage.getWidth());
209 const float yf = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
210 const float z = (xf + yf) / 2.0f;
211 const Vec3 fragCoord (float(x)+.5f, float(y)+.5f, z);
212 const Vec3 scaledFC = fragCoord*scale;
213 const Vec4 color (scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
215 refImage.setPixel(x, y, RGBA(color));
219 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
222 return TestStatus::pass("Result image matches reference");
224 return TestStatus::fail("Image mismatch");
227 void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
229 const float vertices[] =
231 -1.0f, 1.0f, 0.0f, 1.0f,
232 -1.0f, -1.0f, 0.5f, 1.0f,
233 1.0f, 1.0f, 0.5f, 1.0f,
234 1.0f, -1.0f, 1.0f, 1.0f,
237 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
240 class BuiltinGlFragCoordXYZCase : public TestCase
243 BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description);
244 virtual ~BuiltinGlFragCoordXYZCase (void);
246 void initPrograms (SourceCollections& dst) const;
247 TestInstance* createInstance (Context& context) const;
250 BuiltinGlFragCoordXYZCase (const BuiltinGlFragCoordXYZCase&); // not allowed!
251 BuiltinGlFragCoordXYZCase& operator= (const BuiltinGlFragCoordXYZCase&); // not allowed!
254 BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
255 : TestCase(testCtx, name, description)
259 BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
263 void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
265 dst.glslSources.add("vert") << glu::VertexSource(
267 "layout(location = 0) in highp vec4 a_position;\n"
270 " gl_Position = a_position;\n"
273 dst.glslSources.add("frag") << glu::FragmentSource(
275 "layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
276 "layout(location = 0) out highp vec4 o_color;\n"
279 " o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
283 TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
285 return new BuiltinGlFragCoordXYZCaseInstance(context);
288 inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
290 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]);
293 class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
296 BuiltinGlFragCoordWCaseInstance (Context& context);
298 TestStatus iterate (void);
299 virtual void setupDefaultInputs (void);
307 BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
308 : ShaderRenderCaseInstance (context)
309 , m_w (1.7f, 2.0f, 1.2f, 1.0f)
313 TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
315 const UVec2 viewportSize = getViewportSize();
316 const int width = viewportSize.x();
317 const int height = viewportSize.y();
318 const tcu::RGBA threshold (2, 2, 2, 2);
319 Surface resImage (width, height);
320 Surface refImage (width, height);
321 bool compareOk = false;
322 const deUint16 indices[6] =
329 render(4, 2, indices);
330 copy(resImage.getAccess(), getResultImage().getAccess());
333 for (int y = 0; y < refImage.getHeight(); y++)
335 for (int x = 0; x < refImage.getWidth(); x++)
337 const float xf = (float(x)+.5f) / float(refImage.getWidth());
338 const float yf = (float(refImage.getHeight()-y-1)+.5f) / float(refImage.getHeight());
339 const float oow = ((xf + yf) < 1.0f)
340 ? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
341 : 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);
342 const Vec4 color (0.0f, oow - 1.0f, 0.0f, 1.0f);
344 refImage.setPixel(x, y, RGBA(color));
348 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
351 return TestStatus::pass("Result image matches reference");
353 return TestStatus::fail("Image mismatch");
356 void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
358 const float vertices[] =
360 -m_w[0], m_w[0], 0.0f, m_w[0],
361 -m_w[1], -m_w[1], 0.0f, m_w[1],
362 m_w[2], m_w[2], 0.0f, m_w[2],
363 m_w[3], -m_w[3], 0.0f, m_w[3]
366 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
369 class BuiltinGlFragCoordWCase : public TestCase
372 BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description);
373 virtual ~BuiltinGlFragCoordWCase (void);
375 void initPrograms (SourceCollections& dst) const;
376 TestInstance* createInstance (Context& context) const;
379 BuiltinGlFragCoordWCase (const BuiltinGlFragCoordWCase&); // not allowed!
380 BuiltinGlFragCoordWCase& operator= (const BuiltinGlFragCoordWCase&); // not allowed!
383 BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
384 : TestCase(testCtx, name, description)
388 BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
392 void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
394 dst.glslSources.add("vert") << glu::VertexSource(
396 "layout(location = 0) in highp vec4 a_position;\n"
399 " gl_Position = a_position;\n"
402 dst.glslSources.add("frag") << glu::FragmentSource(
404 "layout(location = 0) out highp vec4 o_color;\n"
407 " o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
411 TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
413 return new BuiltinGlFragCoordWCaseInstance(context);
416 class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
419 BuiltinGlPointCoordCaseInstance (Context& context);
421 TestStatus iterate (void);
422 virtual void setupDefaultInputs (void);
425 BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context)
426 : ShaderRenderCaseInstance (context)
430 TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
432 const UVec2 viewportSize = getViewportSize();
433 const int width = viewportSize.x();
434 const int height = viewportSize.y();
435 const float threshold = 0.02f;
436 const int numPoints = 16;
437 vector<Vec3> coords (numPoints);
438 de::Random rnd (0x145fa);
439 Surface resImage (width, height);
440 Surface refImage (width, height);
441 bool compareOk = false;
443 // Compute coordinates.
445 const VkPhysicalDeviceLimits& limits = m_context.getDeviceProperties().limits;
446 const float minPointSize = limits.pointSizeRange[0];
447 const float maxPointSize = limits.pointSizeRange[1];
448 const int pointSizeDeltaMultiples = de::max(1, deCeilFloatToInt32((maxPointSize - minPointSize) / limits.pointSizeGranularity));
450 TCU_CHECK(minPointSize <= maxPointSize);
452 for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
454 coord->x() = rnd.getFloat(-0.9f, 0.9f);
455 coord->y() = rnd.getFloat(-0.9f, 0.9f);
456 coord->z() = de::min(maxPointSize, minPointSize + float(rnd.getInt(0, pointSizeDeltaMultiples)) * limits.pointSizeGranularity);
461 addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
462 render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
463 copy(resImage.getAccess(), getResultImage().getAccess());
466 clear(refImage.getAccess(), m_clearColor);
468 for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
470 const float centerX = float(width) *(pointIter->x()*0.5f + 0.5f);
471 const float centerY = float(height)*(pointIter->y()*0.5f + 0.5f);
472 const float size = pointIter->z();
473 const int x0 = deRoundFloatToInt32(centerX - size*0.5f);
474 const int y0 = deRoundFloatToInt32(centerY - size*0.5f);
475 const int x1 = deRoundFloatToInt32(centerX + size*0.5f);
476 const int y1 = deRoundFloatToInt32(centerY + size*0.5f);
480 for (int yo = 0; yo < h; yo++)
482 for (int xo = 0; xo < w; xo++)
484 const int dx = x0+xo;
485 const int dy = y0+yo;
486 const float fragX = float(dx) + 0.5f;
487 const float fragY = float(dy) + 0.5f;
488 const float s = 0.5f + (fragX - centerX) / size;
489 const float t = 0.5f + (fragY - centerY) / size;
490 const Vec4 color (s, t, 0.0f, 1.0f);
492 if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
493 refImage.setPixel(dx, dy, RGBA(color));
498 compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
501 return TestStatus::pass("Result image matches reference");
503 return TestStatus::fail("Image mismatch");
506 void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
510 class BuiltinGlPointCoordCase : public TestCase
513 BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description);
514 virtual ~BuiltinGlPointCoordCase (void);
516 void initPrograms (SourceCollections& dst) const;
517 TestInstance* createInstance (Context& context) const;
520 BuiltinGlPointCoordCase (const BuiltinGlPointCoordCase&); // not allowed!
521 BuiltinGlPointCoordCase& operator= (const BuiltinGlPointCoordCase&); // not allowed!
524 BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description)
525 : TestCase(testCtx, name, description)
529 BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
533 void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
535 dst.glslSources.add("vert") << glu::VertexSource(
537 "layout(location = 0) in highp vec3 a_position;\n"
540 " gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
541 " gl_PointSize = a_position.z;\n"
544 dst.glslSources.add("frag") << glu::FragmentSource(
546 "layout(location = 0) out lowp vec4 o_color;\n"
549 " o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
553 TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
555 return new BuiltinGlPointCoordCaseInstance(context);
558 enum ShaderInputTypeBits
560 SHADER_INPUT_BUILTIN_BIT = 0x01,
561 SHADER_INPUT_VARYING_BIT = 0x02,
562 SHADER_INPUT_CONSTANT_BIT = 0x04
565 typedef deUint16 ShaderInputTypes;
567 string shaderInputTypeToString (ShaderInputTypes type)
569 string typeString = "input";
574 if (type & SHADER_INPUT_BUILTIN_BIT)
575 typeString += "_builtin";
577 if (type & SHADER_INPUT_VARYING_BIT)
578 typeString += "_varying";
580 if (type & SHADER_INPUT_CONSTANT_BIT)
581 typeString += "_constant";
586 class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
589 BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes);
591 TestStatus iterate (void);
592 virtual void setupDefaultInputs (void);
593 virtual void updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
596 const ShaderInputTypes m_shaderInputTypes;
597 const Vec4 m_constantColor;
600 BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
601 : ShaderRenderCaseInstance (context)
602 , m_shaderInputTypes (shaderInputTypes)
603 , m_constantColor (0.1f, 0.05f, 0.2f, 0.0f)
607 TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
609 const UVec2 viewportSize = getViewportSize();
610 const int width = viewportSize.x();
611 const int height = viewportSize.y();
612 const tcu::RGBA threshold (2, 2, 2, 2);
613 Surface resImage (width, height);
614 Surface refImage (width, height);
615 bool compareOk = false;
616 const VkPushConstantRange pcRanges =
618 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
619 0u, // deUint32 offset;
620 sizeof(Vec4) // deUint32 size;
622 const deUint16 indices[12] =
632 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
633 setPushConstantRanges(1, &pcRanges);
635 render(6, 4, indices);
636 copy(resImage.getAccess(), getResultImage().getAccess());
639 for (int y = 0; y < refImage.getHeight(); y++)
641 for (int x = 0; x < refImage.getWidth(); x++)
643 Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
645 if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
646 !(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
648 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
650 const float xf = (float(x)+.5f) / float(refImage.getWidth());
651 color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
654 color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
657 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
658 color += m_constantColor;
660 refImage.setPixel(x, y, RGBA(color));
664 compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
667 return TestStatus::pass("Result image matches reference");
669 return TestStatus::fail("Image mismatch");
672 void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
674 const float vertices[] =
676 -1.0f, -1.0f, 0.0f, 1.0f,
677 0.0f, -1.0f, 0.0f, 1.0f,
678 1.0f, -1.0f, 0.0f, 1.0f,
679 1.0f, 1.0f, 0.0f, 1.0f,
680 0.0f, 1.0f, 0.0f, 1.0f,
681 -1.0f, 1.0f, 0.0f, 1.0f
684 addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
686 if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
688 const float colors[] =
690 0.6f, 0.0f, 0.0f, 1.0f,
691 0.3f, 0.3f, 0.0f, 1.0f,
692 0.0f, 0.6f, 0.0f, 1.0f,
693 0.0f, 0.6f, 0.0f, 1.0f,
694 0.3f, 0.3f, 0.0f, 1.0f,
695 0.6f, 0.0f, 0.0f, 1.0f
697 addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
701 void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
703 if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
705 const DeviceInterface& vk = m_context.getDeviceInterface();
706 vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
710 class BuiltinInputVariationsCase : public TestCase
713 BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
714 virtual ~BuiltinInputVariationsCase (void);
716 void initPrograms (SourceCollections& dst) const;
717 TestInstance* createInstance (Context& context) const;
720 BuiltinInputVariationsCase (const BuiltinInputVariationsCase&); // not allowed!
721 BuiltinInputVariationsCase& operator= (const BuiltinInputVariationsCase&); // not allowed!
722 const ShaderInputTypes m_shaderInputTypes;
725 BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
726 : TestCase (testCtx, name, description)
727 , m_shaderInputTypes (shaderInputTypes)
731 BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
735 void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
737 map<string, string> vertexParams;
738 map<string, string> fragmentParams;
739 const tcu::StringTemplate vertexCodeTemplate (
741 "layout(location = 0) in highp vec4 a_position;\n"
742 "out gl_PerVertex {\n"
743 " vec4 gl_Position;\n"
748 " gl_Position = a_position;\n"
752 const tcu::StringTemplate fragmentCodeTemplate (
756 "layout(location = 0) out highp vec4 o_color;\n"
759 " o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
765 vertexParams["VARYING_DECL"] =
766 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 1) in highp vec4 a_color;\n"
767 "layout(location = 0) out highp vec4 v_color;\n"
770 vertexParams["VARYING_USAGE"] =
771 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "v_color = a_color;\n"
774 fragmentParams["VARYING_DECL"] =
775 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "layout(location = 0) in highp vec4 a_color;\n"
778 fragmentParams["CONSTANT_DECL"] =
779 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "layout(push_constant) uniform PCBlock {\n"
784 fragmentParams["BUILTIN_USAGE"] =
785 m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT ? "if (gl_FrontFacing)\n"
788 fragmentParams["VARYING_USAGE"] =
789 m_shaderInputTypes & SHADER_INPUT_VARYING_BIT ? "o_color += vec4(a_color.xyz, 0.0);\n"
790 : "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
793 fragmentParams["CONSTANT_USAGE"] =
794 m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT ? "o_color += pc.color;\n"
797 dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
798 dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
801 TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
803 return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
808 TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
810 de::MovePtr<TestCaseGroup> builtinGroup (new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
811 de::MovePtr<TestCaseGroup> simpleGroup (new TestCaseGroup(testCtx, "simple", "Simple cases."));
812 de::MovePtr<TestCaseGroup> inputVariationsGroup (new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
814 simpleGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, "frontfacing", "FrontFacing test"));
815 simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
816 simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
817 simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test"));
819 builtinGroup->addChild(simpleGroup.release());
821 for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
823 inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
826 builtinGroup->addChild(inputVariationsGroup.release());
827 return builtinGroup.release();