1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * Copyright (c) 2016 The Android Open Source Project 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief Varying Geometry Shader Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktGeometryVaryingGeometryShaderTests.hpp" 26 #include "vktGeometryBasicClass.hpp" 27 #include "vktGeometryTestsUtil.hpp" 28 29 #include "vkDefs.hpp" 30 #include "vktTestCase.hpp" 31 #include "vktTestCaseUtil.hpp" 32 #include "vkImageUtil.hpp" 33 #include "vkTypeUtil.hpp" 34 #include "vkPrograms.hpp" 35 #include "vkBuilderUtil.hpp" 36 37 #include "vkRefUtil.hpp" 38 #include "vkQueryUtil.hpp" 39 #include "vkMemUtil.hpp" 40 41 #include <string> 42 43 using namespace vk; 44 45 namespace vkt 46 { 47 namespace geometry 48 { 49 namespace 50 { 51 using tcu::TestStatus; 52 using tcu::TestContext; 53 using tcu::TestCaseGroup; 54 using std::string; 55 using de::MovePtr; 56 57 typedef enum VertexOutputs {VERTEXT_NO_OP = -1,VERTEXT_ZERO, VERTEXT_ONE} VertexOut; 58 typedef enum GeometryOutputs {GEOMETRY_ZERO, GEOMETRY_ONE, GEOMETRY_TWO} GeometryOut; 59 60 struct VaryingTestSpec 61 { 62 VertexOutputs vertexOutputs; 63 GeometryOutputs geometryOutputs; 64 const string name; 65 const string desc; 66 }; 67 68 class GeometryVaryingTestInstance : public GeometryExpanderRenderTestInstance 69 { 70 public: 71 GeometryVaryingTestInstance (Context& context, 72 const char* name); 73 74 void genVertexAttribData (void); 75 }; 76 77 GeometryVaryingTestInstance::GeometryVaryingTestInstance (Context& context, const char* name) 78 : GeometryExpanderRenderTestInstance (context, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, name) 79 { 80 genVertexAttribData(); 81 } 82 83 void GeometryVaryingTestInstance::genVertexAttribData (void) 84 { 85 m_numDrawVertices = 3; 86 m_vertexPosData.resize(m_numDrawVertices); 87 m_vertexPosData[0] = tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f); 88 m_vertexPosData[1] = tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f); 89 m_vertexPosData[2] = tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f); 90 91 m_vertexAttrData.resize(m_numDrawVertices); 92 m_vertexAttrData[0] = tcu::Vec4(0.7f, 0.4f, 0.6f, 1.0f); 93 m_vertexAttrData[1] = tcu::Vec4(0.9f, 0.2f, 0.5f, 1.0f); 94 m_vertexAttrData[2] = tcu::Vec4(0.1f, 0.8f, 0.3f, 1.0f); 95 } 96 97 class VaryingTest : public TestCase 98 { 99 public: 100 VaryingTest (TestContext& testCtx, 101 const VaryingTestSpec& varyingTestSpec); 102 103 void initPrograms (SourceCollections& sourceCollections) const; 104 virtual TestInstance* createInstance (Context& context) const; 105 106 protected: 107 const VaryingTestSpec m_varyingTestSpec; 108 }; 109 110 VaryingTest::VaryingTest (TestContext& testCtx, const VaryingTestSpec& varyingTestSpec) 111 : TestCase (testCtx, varyingTestSpec.name, varyingTestSpec.desc) 112 , m_varyingTestSpec (varyingTestSpec) 113 114 { 115 116 } 117 118 void VaryingTest::initPrograms (SourceCollections& sourceCollections) const 119 { 120 { 121 std::ostringstream src; 122 src << "#version 310 es\n" 123 <<"layout(location = 0) in highp vec4 a_position;\n" 124 <<"layout(location = 1) in highp vec4 a_color;\n"; 125 switch(m_varyingTestSpec.vertexOutputs) 126 { 127 case VERTEXT_NO_OP: 128 src << "void main (void)\n" 129 << "{\n" 130 << "}\n"; 131 break; 132 case VERTEXT_ZERO: 133 src << "void main (void)\n" 134 << "{\n" 135 << " gl_Position = a_position;\n" 136 << "}\n"; 137 break; 138 case VERTEXT_ONE: 139 src <<"layout(location = 0) out highp vec4 v_geom_0;\n" 140 << "void main (void)\n" 141 << "{\n" 142 << " gl_Position = a_position;\n" 143 << " v_geom_0 = a_color;\n" 144 << "}\n"; 145 break; 146 default: 147 DE_ASSERT(0); 148 } 149 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str()); 150 } 151 152 { 153 std::ostringstream src; 154 src << "#version 310 es\n" 155 << "#extension GL_EXT_geometry_shader : require\n" 156 << "layout(triangles) in;\n" 157 << "layout(triangle_strip, max_vertices = 3) out;\n"; 158 159 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) 160 src << "layout(location = 0) in highp vec4 v_geom_0[];\n"; 161 162 if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE) 163 src << "layout(location = 0) out highp vec4 v_frag_0;\n"; 164 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) 165 src << "layout(location = 1) out highp vec4 v_frag_1;\n"; 166 167 src << "void main (void)\n" 168 << "{\n" 169 << " highp vec4 offset = vec4(-0.2, -0.2, 0.0, 0.0);\n" 170 << " highp vec4 inputColor;\n" 171 << "\n"; 172 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) 173 src << " inputColor = v_geom_0[0];\n"; 174 else 175 src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; 176 177 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP) 178 src << " gl_Position = vec4(0.0, 0.0, 0.0, 1.0) + offset;\n"; 179 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO) 180 src << " gl_Position = gl_in[0].gl_Position + offset;\n"; 181 182 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) 183 src << " v_frag_0 = inputColor;\n"; 184 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) 185 src << " v_frag_0 = inputColor * 0.5;\n" 186 << " v_frag_1 = inputColor.yxzw * 0.5;\n"; 187 188 src << " EmitVertex();\n" 189 << "\n"; 190 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) 191 src << " inputColor = v_geom_0[1];\n"; 192 else 193 src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; 194 195 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP) 196 src << " gl_Position = vec4(1.0, 0.0, 0.0, 1.0) + offset;\n"; 197 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO) 198 src << " gl_Position = gl_in[1].gl_Position + offset;\n"; 199 200 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) 201 src << " v_frag_0 = inputColor;\n"; 202 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) 203 src << " v_frag_0 = inputColor * 0.5;\n" 204 << " v_frag_1 = inputColor.yxzw * 0.5;\n"; 205 206 src << " EmitVertex();\n" 207 << "\n"; 208 209 if (m_varyingTestSpec.vertexOutputs == VERTEXT_ONE) 210 src << " inputColor = v_geom_0[2];\n"; 211 else 212 src << " inputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; 213 214 if (m_varyingTestSpec.vertexOutputs == VERTEXT_NO_OP) 215 src << " gl_Position = vec4(1.0, 1.0, 0.0, 1.0) + offset;\n"; 216 if (m_varyingTestSpec.vertexOutputs >= VERTEXT_ZERO) 217 src << " gl_Position = gl_in[2].gl_Position + offset;\n"; 218 219 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) 220 src << " v_frag_0 = inputColor;\n"; 221 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) 222 src << " v_frag_0 = inputColor * 0.5;\n" 223 << " v_frag_1 = inputColor.yxzw * 0.5;\n"; 224 225 src << " EmitVertex();\n" 226 << "\n" 227 << " EndPrimitive();\n" 228 << "}\n"; 229 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(src.str()); 230 } 231 232 { 233 std::ostringstream src; 234 src << "#version 310 es\n" 235 <<"layout(location = 0) out highp vec4 fragColor;\n"; 236 if (m_varyingTestSpec.geometryOutputs >= GEOMETRY_ONE) 237 src <<"layout(location = 0) in highp vec4 v_frag_0;\n"; 238 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) 239 src <<"layout(location = 1) in highp vec4 v_frag_1;\n"; 240 241 src <<"void main (void)\n" 242 <<"{\n"; 243 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ZERO) 244 src <<"fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"; 245 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_ONE) 246 src <<" fragColor = v_frag_0;\n"; 247 if (m_varyingTestSpec.geometryOutputs == GEOMETRY_TWO) 248 src <<" fragColor = v_frag_0 + v_frag_1.yxzw;\n"; 249 src <<"}\n"; 250 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str()); 251 } 252 } 253 254 TestInstance* VaryingTest::createInstance (Context& context) const 255 { 256 return new GeometryVaryingTestInstance(context, getName()); 257 } 258 259 } // anonymous 260 261 TestCaseGroup* createVaryingGeometryShaderTests (TestContext& testCtx) 262 { 263 MovePtr<TestCaseGroup> varyingGroup (new TestCaseGroup(testCtx, "varying", "Test varyings.")); 264 265 // varying 266 { 267 static const VaryingTestSpec varyingTests[] = 268 { 269 { VERTEXT_NO_OP, GEOMETRY_ONE, "vertex_no_op_geometry_out_1", "vertex_no_op_geometry_out_1" }, 270 { VERTEXT_ZERO, GEOMETRY_ONE, "vertex_out_0_geometry_out_1", "vertex_out_0_geometry_out_1" }, 271 { VERTEXT_ZERO, GEOMETRY_TWO, "vertex_out_0_geometry_out_2", "vertex_out_0_geometry_out_2" }, 272 { VERTEXT_ONE, GEOMETRY_ZERO, "vertex_out_1_geometry_out_0", "vertex_out_1_geometry_out_0" }, 273 { VERTEXT_ONE, GEOMETRY_TWO, "vertex_out_1_geometry_out_2", "vertex_out_1_geometry_out_2" }, 274 }; 275 276 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(varyingTests); ++ndx) 277 varyingGroup->addChild(new VaryingTest(testCtx, varyingTests[ndx])); 278 } 279 280 return varyingGroup.release(); 281 } 282 283 } // geometry 284 } // vkt 285