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 Input Geometry Shader Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktGeometryInputGeometryShaderTests.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::Vec4; 52 using tcu::TestStatus; 53 using tcu::TestContext; 54 using tcu::TestCaseGroup; 55 using de::MovePtr; 56 using std::string; 57 using std::vector; 58 59 class GeometryInputTestInstance : public GeometryExpanderRenderTestInstance 60 { 61 public: 62 GeometryInputTestInstance (Context& context, 63 const VkPrimitiveTopology primitiveType, 64 const char* name); 65 66 GeometryInputTestInstance (Context& context, 67 const VkPrimitiveTopology primitiveType, 68 const char* name, 69 const int numDrawVertices); 70 71 void genVertexAttribData (void); 72 }; 73 74 GeometryInputTestInstance::GeometryInputTestInstance (Context& context, 75 const VkPrimitiveTopology primitiveType, 76 const char* name) 77 : GeometryExpanderRenderTestInstance (context, primitiveType, name) 78 { 79 genVertexAttribData(); 80 } 81 82 GeometryInputTestInstance::GeometryInputTestInstance (Context& context, 83 const VkPrimitiveTopology primitiveType, 84 const char* name, 85 const int numDrawVertices) 86 : GeometryExpanderRenderTestInstance (context, primitiveType, name) 87 { 88 genVertexAttribData(); 89 m_numDrawVertices = numDrawVertices; 90 } 91 92 void GeometryInputTestInstance::genVertexAttribData (void) 93 { 94 // Create 1 X 2 grid in triangle strip adjacent - order 95 const float scale = 0.3f; 96 const Vec4 offset (-0.5f, -0.2f, 0.0f, 1.0f); 97 m_numDrawVertices = 12; 98 99 m_vertexPosData.resize(m_numDrawVertices); 100 m_vertexPosData[ 0] = Vec4( 0, 0, 0.0f, 0.0f) * scale + offset; 101 m_vertexPosData[ 1] = Vec4(-1, -1, 0.0f, 0.0f) * scale + offset; 102 m_vertexPosData[ 2] = Vec4( 0, -1, 0.0f, 0.0f) * scale + offset; 103 m_vertexPosData[ 3] = Vec4( 1, 1, 0.0f, 0.0f) * scale + offset; 104 m_vertexPosData[ 4] = Vec4( 1, 0, 0.0f, 0.0f) * scale + offset; 105 m_vertexPosData[ 5] = Vec4( 0, -2, 0.0f, 0.0f) * scale + offset; 106 m_vertexPosData[ 6] = Vec4( 1, -1, 0.0f, 0.0f) * scale + offset; 107 m_vertexPosData[ 7] = Vec4( 2, 1, 0.0f, 0.0f) * scale + offset; 108 m_vertexPosData[ 8] = Vec4( 2, 0, 0.0f, 0.0f) * scale + offset; 109 m_vertexPosData[ 9] = Vec4( 1, -2, 0.0f, 0.0f) * scale + offset; 110 m_vertexPosData[10] = Vec4( 2, -1, 0.0f, 0.0f) * scale + offset; 111 m_vertexPosData[11] = Vec4( 3, 0, 0.0f, 0.0f) * scale + offset; 112 113 // Red and white 114 m_vertexAttrData.resize(m_numDrawVertices); 115 for (int i = 0; i < m_numDrawVertices; ++i) 116 m_vertexAttrData[i] = (i % 2 == 0) ? Vec4(1, 1, 1, 1) : Vec4(1, 0, 0, 1); 117 } 118 119 class GeometryExpanderRenderTest : public TestCase 120 { 121 public: 122 GeometryExpanderRenderTest (TestContext& testCtx, 123 const PrimitiveTestSpec& inputPrimitives); 124 125 void initPrograms (SourceCollections& sourceCollections) const; 126 virtual TestInstance* createInstance (Context& context) const; 127 128 protected: 129 string shaderGeometry (bool pointSize) const; 130 const VkPrimitiveTopology m_primitiveType; 131 const VkPrimitiveTopology m_outputType; 132 }; 133 134 GeometryExpanderRenderTest::GeometryExpanderRenderTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives) 135 : TestCase (testCtx, inputPrimitives.name, inputPrimitives.name) 136 , m_primitiveType (inputPrimitives.primitiveType) 137 , m_outputType (inputPrimitives.outputType) 138 { 139 140 } 141 142 void GeometryExpanderRenderTest::initPrograms (SourceCollections& sourceCollections) const 143 { 144 { 145 std::ostringstream src; 146 src << "#version 310 es\n" 147 <<"layout(location = 0) in highp vec4 a_position;\n" 148 <<"layout(location = 1) in highp vec4 a_color;\n" 149 <<"layout(location = 0) out highp vec4 v_geom_FragColor;\n" 150 <<"void main (void)\n" 151 <<"{\n" 152 <<" gl_Position = a_position;\n" 153 <<" v_geom_FragColor = a_color;\n" 154 <<"}\n"; 155 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str()); 156 } 157 158 { 159 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(shaderGeometry(false)); 160 if (m_outputType == VK_PRIMITIVE_TOPOLOGY_POINT_LIST) 161 sourceCollections.glslSources.add("geometry_pointsize") << glu::GeometrySource(shaderGeometry(true)); 162 } 163 164 { 165 std::ostringstream src; 166 src << "#version 310 es\n" 167 <<"layout(location = 0) out highp vec4 fragColor;\n" 168 <<"layout(location = 0) in highp vec4 v_frag_FragColor;\n" 169 <<"void main (void)\n" 170 <<"{\n" 171 <<" fragColor = v_frag_FragColor;\n" 172 <<"}\n"; 173 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str()); 174 } 175 } 176 177 TestInstance* GeometryExpanderRenderTest::createInstance (Context& context) const 178 { 179 return new GeometryInputTestInstance(context, m_primitiveType, getName()); 180 } 181 182 string GeometryExpanderRenderTest::shaderGeometry (bool pointSize) const 183 { 184 std::ostringstream src; 185 src << "#version 310 es\n" 186 << "#extension GL_EXT_geometry_shader : require\n"; 187 if (pointSize) 188 src <<"#extension GL_EXT_geometry_point_size : require\n"; 189 src << "layout(" << inputTypeToGLString(m_primitiveType) << ") in;\n" 190 << "layout(" << outputTypeToGLString(m_outputType) << ", max_vertices = " << calcOutputVertices(m_primitiveType) << ") out;\n" 191 << "layout(location = 0) in highp vec4 v_geom_FragColor[];\n" 192 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n" 193 << "\n" 194 << "void main (void)\n" 195 << "{\n" 196 << " const highp vec4 offset0 = vec4(-0.07, -0.01, 0.0, 0.0);\n" 197 << " const highp vec4 offset1 = vec4( 0.03, -0.03, 0.0, 0.0);\n" 198 << " const highp vec4 offset2 = vec4(-0.01, 0.08, 0.0, 0.0);\n" 199 << " highp vec4 yoffset = float(gl_PrimitiveIDIn) * vec4(0.02, 0.1, 0.0, 0.0);\n" 200 << "\n" 201 << " for (highp int ndx = 0; ndx < gl_in.length(); ndx++)\n" 202 << " {\n"; 203 if (pointSize) 204 src << " gl_PointSize = 1.0;\n"; 205 src << " gl_Position = gl_in[ndx].gl_Position + offset0 + yoffset;\n" 206 << " v_frag_FragColor = v_geom_FragColor[ndx];\n" 207 << " EmitVertex();\n" 208 << "\n"; 209 if (pointSize) 210 src << " gl_PointSize = 1.0;\n"; 211 src << " gl_Position = gl_in[ndx].gl_Position + offset1 + yoffset;\n" 212 << " v_frag_FragColor = v_geom_FragColor[ndx];\n" 213 << " EmitVertex();\n" 214 << "\n"; 215 if (pointSize) 216 src << " gl_PointSize = 1.0;\n"; 217 src << " gl_Position = gl_in[ndx].gl_Position + offset2 + yoffset;\n" 218 << " v_frag_FragColor = v_geom_FragColor[ndx];\n" 219 << " EmitVertex();\n" 220 << " EndPrimitive();\n" 221 << " }\n" 222 << "}\n"; 223 return src.str(); 224 } 225 226 class TriangleStripAdjacencyVertexCountTest : public GeometryExpanderRenderTest 227 { 228 public: 229 TriangleStripAdjacencyVertexCountTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices); 230 virtual TestInstance* createInstance (Context& context) const; 231 private: 232 const int m_numInputVertices; 233 }; 234 235 TriangleStripAdjacencyVertexCountTest::TriangleStripAdjacencyVertexCountTest (TestContext& testCtx, const PrimitiveTestSpec& inputPrimitives, const int numInputVertices) 236 : GeometryExpanderRenderTest (testCtx, inputPrimitives) 237 , m_numInputVertices (numInputVertices) 238 { 239 } 240 241 TestInstance* TriangleStripAdjacencyVertexCountTest::createInstance (Context& context) const 242 { 243 return new GeometryInputTestInstance(context, m_primitiveType, getName(), m_numInputVertices); 244 } 245 246 } // anonymous 247 248 TestCaseGroup* createInputGeometryShaderTests (TestContext& testCtx) 249 { 250 MovePtr<TestCaseGroup> inputPrimitiveGroup (new TestCaseGroup(testCtx, "input", "Different input primitives.")); 251 MovePtr<TestCaseGroup> basicPrimitiveGroup (new TestCaseGroup(testCtx, "basic_primitive", "Basic Primitive geometry tests")); 252 MovePtr<TestCaseGroup> triStripAdjacencyGroup (new TestCaseGroup(testCtx, "triangle_strip_adjacency", "Different triangle_strip_adjacency vertex counts.")); 253 MovePtr<TestCaseGroup> conversionPrimitiveGroup (new TestCaseGroup(testCtx, "conversion", "Different input and output primitives.")); 254 255 const PrimitiveTestSpec inputPrimitives[] = 256 { 257 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points", VK_PRIMITIVE_TOPOLOGY_POINT_LIST }, 258 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP }, 259 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, "line_strip", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP }, 260 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }, 261 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, "triangle_strip", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }, 262 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, "triangle_fan", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }, 263 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, "lines_adjacency", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP }, 264 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, "line_strip_adjacency", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP }, 265 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, "triangles_adjacency", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP } 266 }; 267 268 // more basic types 269 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(inputPrimitives); ++ndx) 270 basicPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, inputPrimitives[ndx])); 271 272 // triangle strip adjacency with different vertex counts 273 for (int vertexCount = 0; vertexCount <= 12; ++vertexCount) 274 { 275 const string name = "vertex_count_" + de::toString(vertexCount); 276 const PrimitiveTestSpec primitives = { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, name.c_str(), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP }; 277 278 triStripAdjacencyGroup->addChild(new TriangleStripAdjacencyVertexCountTest(testCtx, primitives, vertexCount)); 279 } 280 281 // different type conversions 282 { 283 static const PrimitiveTestSpec conversionPrimitives[] = 284 { 285 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles_to_points", VK_PRIMITIVE_TOPOLOGY_POINT_LIST }, 286 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines_to_points", VK_PRIMITIVE_TOPOLOGY_POINT_LIST }, 287 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points_to_lines", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP }, 288 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, "triangles_to_lines", VK_PRIMITIVE_TOPOLOGY_LINE_STRIP }, 289 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, "points_to_triangles", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP}, 290 { VK_PRIMITIVE_TOPOLOGY_LINE_LIST, "lines_to_triangles", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP} 291 }; 292 293 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(conversionPrimitives); ++ndx) 294 conversionPrimitiveGroup->addChild(new GeometryExpanderRenderTest(testCtx, conversionPrimitives[ndx])); 295 } 296 297 inputPrimitiveGroup->addChild(basicPrimitiveGroup.release()); 298 inputPrimitiveGroup->addChild(triStripAdjacencyGroup.release()); 299 inputPrimitiveGroup->addChild(conversionPrimitiveGroup.release()); 300 return inputPrimitiveGroup.release(); 301 } 302 303 } // geometry 304 } // vkt 305