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 Emit Geometry Shader Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktGeometryEmitGeometryShaderTests.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 std::string; 52 using de::MovePtr; 53 using tcu::Vec4; 54 using tcu::TestStatus; 55 using tcu::TestContext; 56 using tcu::TestCaseGroup; 57 58 typedef enum VertexOutputs {VERTEXT_NO_OP = -1,VERTEXT_ZERO, VERTEXT_ONE} VertexOut; 59 typedef enum GeometryOutputs {GEOMETRY_ZERO, GEOMETRY_ONE, GEOMETRY_TWO} GeometryOut; 60 61 struct EmitTestSpec 62 { 63 VkPrimitiveTopology primitiveTopology; 64 int emitCountA; //!< primitive A emit count 65 int endCountA; //!< primitive A end count 66 int emitCountB; //!< 67 int endCountB; //!< 68 string name; 69 string desc; 70 }; 71 72 class GeometryEmitTestInstance : public GeometryExpanderRenderTestInstance 73 { 74 public: 75 GeometryEmitTestInstance (Context& context, 76 const char* name); 77 void genVertexAttribData (void); 78 }; 79 80 GeometryEmitTestInstance::GeometryEmitTestInstance (Context& context, const char* name) 81 : GeometryExpanderRenderTestInstance (context, VK_PRIMITIVE_TOPOLOGY_POINT_LIST, name) 82 { 83 genVertexAttribData(); 84 } 85 86 void GeometryEmitTestInstance::genVertexAttribData (void) 87 { 88 m_numDrawVertices = 1; 89 m_vertexPosData.resize(m_numDrawVertices); 90 m_vertexPosData[0] = Vec4(0, 0, 0, 1); 91 92 m_vertexAttrData.resize(m_numDrawVertices); 93 m_vertexAttrData[0] = Vec4(1, 1, 1, 1); 94 } 95 96 class EmitTest : public TestCase 97 { 98 public: 99 EmitTest (TestContext& testCtx, 100 const EmitTestSpec& emitTestSpec); 101 102 void initPrograms (SourceCollections& sourceCollections) const; 103 virtual TestInstance* createInstance (Context& context) const; 104 105 protected: 106 string shaderGeometry (bool pointSize) const; 107 const EmitTestSpec m_emitTestSpec; 108 }; 109 110 EmitTest::EmitTest (TestContext& testCtx, const EmitTestSpec& emitTestSpec) 111 : TestCase (testCtx, emitTestSpec.name, emitTestSpec.desc) 112 , m_emitTestSpec (emitTestSpec) 113 114 { 115 116 } 117 118 void EmitTest::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 << "layout(location = 0) out highp vec4 v_geom_FragColor;\n" 126 << "void main (void)\n" 127 << "{\n" 128 << " gl_Position = a_position;\n" 129 << " v_geom_FragColor = a_color;\n" 130 << "}\n"; 131 sourceCollections.glslSources.add("vertex") << glu::VertexSource(src.str()); 132 } 133 134 { 135 sourceCollections.glslSources.add("geometry") << glu::GeometrySource(shaderGeometry(false)); 136 if(m_emitTestSpec.primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST) 137 sourceCollections.glslSources.add("geometry_pointsize") << glu::GeometrySource(shaderGeometry(true)); 138 } 139 140 { 141 std::ostringstream src; 142 src << "#version 310 es\n" 143 << "layout(location = 0) out mediump vec4 fragColor;\n" 144 << "layout(location = 0) in highp vec4 v_frag_FragColor;\n" 145 << "void main (void)\n" 146 << "{\n" 147 << " fragColor = v_frag_FragColor;\n" 148 <<"}\n"; 149 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(src.str()); 150 } 151 } 152 153 TestInstance* EmitTest::createInstance (Context& context) const 154 { 155 return new GeometryEmitTestInstance(context, getName()); 156 } 157 158 string EmitTest::shaderGeometry (bool pointSize) const 159 { 160 std::ostringstream src; 161 src << "#version 310 es\n" 162 << "#extension GL_EXT_geometry_shader : require\n"; 163 if (pointSize) 164 src <<"#extension GL_EXT_geometry_point_size : require\n"; 165 src << "layout(points) in;\n" 166 << "layout(" << outputTypeToGLString(m_emitTestSpec.primitiveTopology) << ", max_vertices = " << (m_emitTestSpec.emitCountA + m_emitTestSpec.emitCountB +1) << ") out;\n" 167 << "layout(location = 0) in highp vec4 v_geom_FragColor[];\n" 168 << "layout(location = 0) out highp vec4 v_frag_FragColor;\n" 169 << "void main (void)\n" 170 << "{\n" 171 << " const highp vec4 position0 = vec4(-0.5, 0.5, 0.0, 0.0);\n" 172 << " const highp vec4 position1 = vec4( 0.0, 0.1, 0.0, 0.0);\n" 173 << " const highp vec4 position2 = vec4( 0.5, 0.5, 0.0, 0.0);\n" 174 << " const highp vec4 position3 = vec4( 0.7, -0.2, 0.0, 0.0);\n" 175 << " const highp vec4 position4 = vec4( 0.2, 0.2, 0.0, 0.0);\n" 176 << " const highp vec4 position5 = vec4( 0.4, -0.3, 0.0, 0.0);\n"; 177 for (int i = 0; i < m_emitTestSpec.emitCountA; ++i) 178 { 179 if (pointSize) 180 src << " gl_PointSize = 1.0;\n"; 181 src << " gl_Position = gl_in[0].gl_Position + position" << i << ";\n" 182 " gl_PrimitiveID = gl_PrimitiveIDIn;\n" 183 " v_frag_FragColor = v_geom_FragColor[0];\n" 184 " EmitVertex();\n" 185 "\n"; 186 } 187 188 for (int i = 0; i < m_emitTestSpec.endCountA; ++i) 189 src << " EndPrimitive();\n"; 190 191 for (int i = 0; i < m_emitTestSpec.emitCountB; ++i) 192 { 193 if (pointSize) 194 src << " gl_PointSize = 1.0;\n"; 195 src << " gl_Position = gl_in[0].gl_Position + position" << (m_emitTestSpec.emitCountA + i) << ";\n" 196 " gl_PrimitiveID = gl_PrimitiveIDIn;\n" 197 " v_frag_FragColor = v_geom_FragColor[0];\n" 198 " EmitVertex();\n" 199 "\n"; 200 } 201 202 for (int i = 0; i < m_emitTestSpec.endCountB; ++i) 203 src << " EndPrimitive();\n"; 204 src << "}\n"; 205 return src.str(); 206 } 207 208 } // anonymous 209 210 TestCaseGroup* createEmitGeometryShaderTests (TestContext& testCtx) 211 { 212 MovePtr<TestCaseGroup> emitGroup (new TestCaseGroup(testCtx, "emit", "Different emit counts.")); 213 214 // emit different amounts 215 { 216 EmitTestSpec emitTests[] = 217 { 218 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, 0, 0, 0, "points" , ""}, 219 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, 1, 0, 0, "points" , ""}, 220 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 1, 1, 0, 0, "points" , ""}, 221 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 0, 2, 0, 0, "points" , ""}, 222 { VK_PRIMITIVE_TOPOLOGY_POINT_LIST, 1, 2, 0, 0, "points" , ""}, 223 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, 0, 0, 0, "line_strip" , ""}, 224 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, 1, 0, 0, "line_strip" , ""}, 225 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 1, 1, 0, 0, "line_strip" , ""}, 226 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 1, 0, 0, "line_strip" , ""}, 227 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 0, 2, 0, 0, "line_strip" , ""}, 228 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 1, 2, 0, 0, "line_strip" , ""}, 229 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 2, 0, 0, "line_strip" , ""}, 230 { VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, 2, 2, 2, 0, "line_strip" , ""}, 231 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0, 0, 0, 0, "triangle_strip", ""}, 232 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0, 1, 0, 0, "triangle_strip", ""}, 233 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 1, 1, 0, 0, "triangle_strip", ""}, 234 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 2, 1, 0, 0, "triangle_strip", ""}, 235 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 1, 0, 0, "triangle_strip", ""}, 236 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 0, 2, 0, 0, "triangle_strip", ""}, 237 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 1, 2, 0, 0, "triangle_strip", ""}, 238 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 2, 2, 0, 0, "triangle_strip", ""}, 239 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 2, 0, 0, "triangle_strip", ""}, 240 { VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, 3, 2, 3, 0, "triangle_strip", ""}, 241 }; 242 243 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(emitTests); ++ndx) 244 { 245 emitTests[ndx].name = std::string(emitTests[ndx].name) + "_emit_" + de::toString(emitTests[ndx].emitCountA) + "_end_" + de::toString(emitTests[ndx].endCountA); 246 emitTests[ndx].desc = std::string(emitTests[ndx].name) + " output, emit " + de::toString(emitTests[ndx].emitCountA) + " vertices, call EndPrimitive " + de::toString(emitTests[ndx].endCountA) + " times"; 247 248 if (emitTests[ndx].emitCountB) 249 { 250 emitTests[ndx].name += "_emit_" + de::toString(emitTests[ndx].emitCountB) + "_end_" + de::toString(emitTests[ndx].endCountB); 251 emitTests[ndx].desc += ", emit " + de::toString(emitTests[ndx].emitCountB) + " vertices, call EndPrimitive " + de::toString(emitTests[ndx].endCountB) + " times"; 252 } 253 254 emitGroup->addChild(new EmitTest(testCtx, emitTests[ndx])); 255 } 256 } 257 258 return emitGroup.release(); 259 } 260 261 } // geometry 262 } // vkt 263