@@ -233,45 +233,58 @@ class SwiftShaderTest : public testing::Test
233233 GLuint fragmentShader;
234234 };
235235
236- ProgramHandles createProgram (const std::string& vs, const std::string& fs )
236+ GLuint MakeShader (const std::string &source, GLenum shaderType )
237237 {
238+ GLuint shader = glCreateShader (shaderType);
239+ const char *c_source[1 ] = { source.c_str () };
240+ glShaderSource (shader, 1 , c_source, nullptr );
241+ glCompileShader (shader);
242+ EXPECT_GLENUM_EQ (GL_NONE, glGetError ());
243+
238244 GLchar buf[1024 ];
245+ GLint compileStatus = 0 ;
246+ glGetShaderiv (shader, GL_COMPILE_STATUS, &compileStatus);
247+ glGetShaderInfoLog (shader, sizeof (buf), nullptr , buf);
248+ EXPECT_EQ (compileStatus, GL_TRUE) << " Compile status: " << std::endl << buf;
239249
240- ProgramHandles ph;
241- ph.program = glCreateProgram ();
242- EXPECT_GLENUM_EQ (GL_NONE, glGetError ());
250+ return shader;
251+ }
243252
244- ph.vertexShader = glCreateShader (GL_VERTEX_SHADER);
245- const char * vsSource[1 ] = { vs.c_str () };
246- glShaderSource (ph.vertexShader , 1 , vsSource, nullptr );
247- glCompileShader (ph.vertexShader );
248- EXPECT_GLENUM_EQ (GL_NONE, glGetError ());
249- GLint vsCompileStatus = 0 ;
250- glGetShaderiv (ph.vertexShader , GL_COMPILE_STATUS, &vsCompileStatus);
251- glGetShaderInfoLog (ph.vertexShader , sizeof (buf), nullptr , buf);
252- EXPECT_EQ (vsCompileStatus, GL_TRUE) << " Compile status: " << std::endl << buf;
253+ GLuint MakeProgram (GLuint vs, GLuint fs)
254+ {
255+ GLuint program;
253256
254- ph.fragmentShader = glCreateShader (GL_FRAGMENT_SHADER);
255- const char * fsSource[1 ] = { fs.c_str () };
256- glShaderSource (ph.fragmentShader , 1 , fsSource, nullptr );
257- glCompileShader (ph.fragmentShader );
257+ program = glCreateProgram ();
258258 EXPECT_GLENUM_EQ (GL_NONE, glGetError ());
259- GLint fsCompileStatus = 0 ;
260- glGetShaderiv (ph.fragmentShader , GL_COMPILE_STATUS, &fsCompileStatus);
261- glGetShaderInfoLog (ph.fragmentShader , sizeof (buf), nullptr , buf);
262- EXPECT_EQ (fsCompileStatus, GL_TRUE) << " Compile status: " << std::endl << buf;
263259
264- glAttachShader (ph.program , ph.vertexShader );
265- glAttachShader (ph.program , ph.fragmentShader );
266- glLinkProgram (ph.program );
260+ glAttachShader (program, vs);
261+ glAttachShader (program, fs);
267262 EXPECT_GLENUM_EQ (GL_NONE, glGetError ());
268263
264+ return program;
265+ }
266+
267+ void LinkProgram (GLuint program)
268+ {
269+ GLchar buf[1024 ];
270+ glLinkProgram (program);
271+
269272 GLint linkStatus = 0 ;
270- glGetProgramiv (ph. program , GL_LINK_STATUS, &linkStatus);
271- glGetProgramInfoLog (ph. program , sizeof (buf), nullptr , buf);
273+ glGetProgramiv (program, GL_LINK_STATUS, &linkStatus);
274+ glGetProgramInfoLog (program, sizeof (buf), nullptr , buf);
272275 EXPECT_NE (linkStatus, 0 ) << " Link status: " << std::endl << buf;
273276
274277 EXPECT_GLENUM_EQ (GL_NONE, glGetError ());
278+ }
279+
280+
281+ ProgramHandles createProgram (const std::string& vs, const std::string& fs)
282+ {
283+ ProgramHandles ph;
284+ ph.vertexShader = MakeShader (vs, GL_VERTEX_SHADER);
285+ ph.fragmentShader = MakeShader (fs, GL_FRAGMENT_SHADER);
286+ ph.program = MakeProgram (ph.vertexShader , ph.fragmentShader );
287+ LinkProgram (ph.program );
275288
276289 return ph;
277290 }
@@ -1206,6 +1219,81 @@ TEST_F(SwiftShaderTest, TransformFeedback_DrawArraysInstanced)
12061219 Uninitialize ();
12071220}
12081221
1222+ TEST_F (SwiftShaderTest, TransformFeedback_BadViewport)
1223+ {
1224+ Initialize (3 , false );
1225+
1226+ GLuint tfBuffer;
1227+ glGenBuffers (1 , &tfBuffer);
1228+ glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, tfBuffer);
1229+ glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 1 << 12 , nullptr , GL_STATIC_DRAW);
1230+
1231+ std::string vsSource =
1232+ R"( #version 300 es
1233+ in vec4 a_position;
1234+ void main()
1235+ {
1236+ gl_Position = a_position;
1237+ })" ;
1238+ std::string fsSource =
1239+ R"( #version 300 es
1240+ precision highp float;
1241+ out vec4 my_FragColor;
1242+ void main()
1243+ {
1244+ my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
1245+ })" ;
1246+
1247+ const char *varyings[] = { " gl_Position" };
1248+
1249+ GLuint vs = MakeShader (vsSource, GL_VERTEX_SHADER);
1250+ GLuint fs = MakeShader (fsSource, GL_FRAGMENT_SHADER);
1251+ GLuint program = MakeProgram (vs, fs);
1252+
1253+ glTransformFeedbackVaryings (program, 1 ,
1254+ &varyings[0 ], GL_INTERLEAVED_ATTRIBS);
1255+ LinkProgram (program);
1256+ glUseProgram (program);
1257+
1258+ glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0 , tfBuffer);
1259+ glBeginTransformFeedback (GL_TRIANGLES);
1260+
1261+ GLuint primitivesWrittenQuery = 0 ;
1262+ glGenQueries (1 , &primitivesWrittenQuery);
1263+ glBeginQuery (GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, primitivesWrittenQuery);
1264+
1265+ glViewport (0 , 10000000 , 300 , 300 );
1266+
1267+ GLint positionLocation = glGetAttribLocation (program, " a_position" );
1268+ GLfloat quadVertices[] = {
1269+ -1 .0f , 1 .0f , 0 .5f ,
1270+ -1 .0f , -1 .0f , 0 .5f ,
1271+ 1 .0f , -1 .0f , 0 .5f ,
1272+ -1 .0f , 1 .0f , 0 .5f ,
1273+ 1 .0f , -1 .0f , 0 .5f ,
1274+ 1 .0f , 1 .0f , 0 .5f ,
1275+ };
1276+
1277+ glBindBuffer (GL_ARRAY_BUFFER, 0 );
1278+
1279+ glVertexAttribPointer (positionLocation, 3 , GL_FLOAT, GL_FALSE, 0 , &quadVertices[0 ]);
1280+
1281+ glDrawArrays (GL_TRIANGLES, 0 , 6 );
1282+ glDisableVertexAttribArray (positionLocation);
1283+ glVertexAttribPointer (positionLocation, 4 , GL_FLOAT, GL_FALSE, 0 , nullptr );
1284+
1285+ glEndQuery (GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
1286+ glEndTransformFeedback ();
1287+
1288+ GLuint primitivesWritten = 0 ;
1289+ glGetQueryObjectuiv (primitivesWrittenQuery, GL_QUERY_RESULT_EXT, &primitivesWritten);
1290+ EXPECT_GLENUM_EQ (GL_NONE, glGetError ());
1291+
1292+ EXPECT_EQ (2u , primitivesWritten);
1293+
1294+ Uninitialize ();
1295+ }
1296+
12091297// Test conditions that should result in a GL_OUT_OF_MEMORY and not crash
12101298TEST_F (SwiftShaderTest, OutOfMemory)
12111299{
0 commit comments