/*------------------------------------------------------------------------ * Vulkan Conformance Tests * ------------------------ * * Copyright (c) 2016 The Khronos Group Inc. * Copyright (c) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Varying Geometry Shader Tests *//*--------------------------------------------------------------------*/ #include "vktGeometryVaryingGeometryShaderTests.hpp" #include "vktGeometryBasicClass.hpp" #include "vktGeometryTestsUtil.hpp" #include "vkDefs.hpp" #include "vktTestCase.hpp" #include "vktTestCaseUtil.hpp" #include "vkImageUtil.hpp" #include "vkTypeUtil.hpp" #include "vkPrograms.hpp" #include "vkBuilderUtil.hpp" #include "vkRefUtil.hpp" #include "vkQueryUtil.hpp" #include "vkMemUtil.hpp" #include using namespace vk; namespace vkt { namespace geometry { namespace { using tcu::TestStatus; using tcu::TestContext; using tcu::TestCaseGroup; using std::string; using de::MovePtr; typedef enum VertexOutputs {VERTEXT_NO_OP = -1,VERTEXT_ZERO, VERTEXT_ONE} VertexOut; typedef enum GeometryOutputs {GEOMETRY_ZERO, GEOMETRY_ONE, GEOMETRY_TWO} GeometryOut; struct VaryingTestSpec { VertexOutputs vertexOutputs; GeometryOutputs geometryOutputs; const string name; }; class GeometryVaryingTestInstance : public GeometryExpanderRenderTestInstance { public: GeometryVaryingTestInstance (Context& context, const char* name); void genVertexAttribData (void); }; GeometryVaryingTestInstance::GeometryVaryingTestInstance (Context& context, const char* name) : GeometryExpanderRenderTestInstance (context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, name) { genVertexAttribData(); } void GeometryVaryingTestInstance::genVertexAttribData (void) { m_numDrawVertices = 3; m_vertexPosData.resize(m_numDrawVertices); m_vertexPosData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f); m_vertexPosData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f); m_vertexPosData[2] = tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f); m_vertexAttrData.resize(m_numDrawVertices); m_vertexAttrData[0] = tcu::Vec4(0.7f, 0.4f, 0.6f, 1.0f); m_vertexAttrData[1] = tcu::Vec4(0.9f, 0.2f, 0.5f, 1.0f); m_vertexAttrData[2] = tcu::Vec4(0.1f, 0.8f, 0.3f, 1.0f); } class VaryingTest : public TestCase { public: VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec); void checkSupport (Context& context) const; void initPrograms (SourceCollections& sourceCollections) const; virtual TestInstance* createInstance (Context& context) const; protected: const VaryingTestSpec m_varyingTestSpec; }; VaryingTest::VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec) : TestCase (testCtx, varyingTestSpec.name) , m_varyingTestSpec (varyingTestSpec) { } void VaryingTest::checkSupport (Context& context) const { context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER); } void VaryingTest::initPrograms (SourceCollections& sourceCollections) const { { std::ostringstream src; src << "#version 310 es\n" <<"layout(location = 0) in highp vec4 a_position;\n" <<"layout(location = 1) in highp vec4 a_color;\n"; switch(m_varyingTestSpec.vertexOutputs) { case VERTEXT_NO_OP: src << "void main (void)\n" << "{\n" << "}\n"; break; case VERTEXT_ZERO: src << "void main (void)\n" << "{\n" << " gl_Position = a_position;\n" << "}\n"; break; case VERTEXT_ONE: src <<"layout(location = 0) out highp vec4 v_geom_0;\n" << "void main (void)\n" << "{\n" << " gl_Position = a_position;\n" << " v_geom_0 = a_color;\n" << "}\n"; break; default: DE_ASSERT(0); } sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str()); } { std::ostringstream src; src << "#version 310 es\n" << "#extension GL_EXT_geometry_shader : require\n" << "layout(triangles) in;\n" << "layout(triangle_strip, max_vertices = 3) out;\n"; if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) src << "layout(location = 0) in highp vec4 v_geom_0[];\n"; if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE) src << "layout(location = 0) out highp vec4 v_frag_0;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) src << "layout(location = 1) out highp vec4 v_frag_1;\n"; src << "void main (void)\n" << "{\n" << " highp vec4 offset = vec4(-0.2, -0.2, 0.0, 0.0);\n" << " highp vec4 inputColor;\n" << "\n"; if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) src << " inputColor = v_geom_0[0];\n"; else src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP) src << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0) + offset;\n"; if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO) src << " gl_Position = gl_in[0].gl_Position + offset;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) src << " v_frag_0 = inputColor;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) src << " v_frag_0 = inputColor * 0.5;\n" << " v_frag_1 = inputColor.yxzw * 0.5;\n"; src << " EmitVertex();\n" << "\n"; if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) src << " inputColor = v_geom_0[1];\n"; else src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP) src << " gl_Position = vec4(1.0, 0.0, 0.0, 1.0) + offset;\n"; if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO) src << " gl_Position = gl_in[1].gl_Position + offset;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) src << " v_frag_0 = inputColor;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) src << " v_frag_0 = inputColor * 0.5;\n" << " v_frag_1 = inputColor.yxzw * 0.5;\n"; src << " EmitVertex();\n" << "\n"; if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) src << " inputColor = v_geom_0[2];\n"; else src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP) src << " gl_Position = vec4(1.0, 1.0, 0.0, 1.0) + offset;\n"; if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO) src << " gl_Position = gl_in[2].gl_Position + offset;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) src << " v_frag_0 = inputColor;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) src << " v_frag_0 = inputColor * 0.5;\n" << " v_frag_1 = inputColor.yxzw * 0.5;\n"; src << " EmitVertex();\n" << "\n" << " EndPrimitive();\n" << "}\n"; sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str()); } { std::ostringstream src; src << "#version 310 es\n" <<"layout(location = 0) out highp vec4 fragColor;\n"; if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE) src <<"layout(location = 0) in highp vec4 v_frag_0;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) src <<"layout(location = 1) in highp vec4 v_frag_1;\n"; src <<"void main (void)\n" <<"{\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ZERO) src <<"fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) src <<" fragColor = v_frag_0;\n"; if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) src <<" fragColor = v_frag_0 + v_frag_1.yxzw;\n"; src <<"}\n"; sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str()); } } TestInstance* VaryingTest::createInstance (Context& context) const { return new GeometryVaryingTestInstance(context, getName()); } } // anonymous TestCaseGroup* createVaryingGeometryShaderTests (TestContext& testCtx) { MovePtr varyingGroup (new TestCaseGroup(testCtx, "varying")); // varying { static const VaryingTestSpec varyingTests[] = { { VERTEXT_NO_OP, GEOMETRY_ONE, "vertex_no_op_geometry_out_1"}, { VERTEXT_ZERO, GEOMETRY_ONE, "vertex_out_0_geometry_out_1" }, { VERTEXT_ZERO, GEOMETRY_TWO, "vertex_out_0_geometry_out_2" }, { VERTEXT_ONE, GEOMETRY_ZERO, "vertex_out_1_geometry_out_0" }, { VERTEXT_ONE, GEOMETRY_TWO, "vertex_out_1_geometry_out_2" }, }; for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(varyingTests); ++ndx) varyingGroup->addChild(new VaryingTest(testCtx, varyingTests[ndx])); } return varyingGroup.release(); } } // geometry } // vkt