Add negative tests for per-patch output aggregate types.

Bug: 19894936
Change-Id: I2d5b78c98a380a10831145c937d88a154eb131f1
diff --git a/data/gles31/shaders/tessellation_negative_user_defined_io.test b/data/gles31/shaders/tessellation_negative_user_defined_io.test
new file mode 100644
index 0000000..36bd5e7
--- /dev/null
+++ b/data/gles31/shaders/tessellation_negative_user_defined_io.test
@@ -0,0 +1,116 @@
+case per_patch_array_of_structs
+	version 310 es
+	desc "per-patch variable type is array of structs"
+	expect compile_or_link_fail
+	require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+	vertex ""
+		#version 310 es
+		${VERTEX_DECLARATIONS}
+		void main()
+		{
+			${VERTEX_OUTPUT}
+		}
+	""
+	tessellation_control ""
+		#version 310 es
+		${TESSELLATION_CONTROL_DECLARATIONS}
+		struct S
+		{
+			highp float a;
+			highp vec2 b;
+		};
+		patch out S patchVariable[2]; // array of structures is illegal
+		void main()
+		{
+			patchVariable[0].a = gl_in[0].gl_Position.x;
+			patchVariable[0].b = gl_in[0].gl_Position.yz;
+			patchVariable[1].a = gl_in[0].gl_Position.z;
+			patchVariable[1].b = gl_in[0].gl_Position.wx;
+			${TESSELLATION_CONTROL_OUTPUT}
+		}
+	""
+	tessellation_evaluation ""
+		#version 310 es
+		${TESSELLATION_EVALUATION_DECLARATIONS}
+		struct S
+		{
+			highp float a;
+			highp vec2 b;
+		};
+		patch in S patchVariable[2]; // array of structures is illegal
+		out mediump float te_out;
+		void main()
+		{
+			te_out = patchVariable[0].a + patchVariable[1].b.y;
+			${TESSELLATION_EVALUATION_OUTPUT}
+		}
+	""
+	fragment ""
+		#version 310 es
+		precision mediump float;
+		${FRAGMENT_DECLARATIONS}
+		in mediump float te_out;
+		void main()
+		{
+			${FRAG_COLOR} = vec4(te_out);
+		}
+	""
+end
+
+case per_patch_structs_containing_arrays
+	version 310 es
+	desc "per-patch variable type is struct containing array"
+	expect compile_or_link_fail
+	require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+	vertex ""
+		#version 310 es
+		${VERTEX_DECLARATIONS}
+		void main()
+		{
+			${VERTEX_OUTPUT}
+		}
+	""
+	tessellation_control ""
+		#version 310 es
+		${TESSELLATION_CONTROL_DECLARATIONS}
+		struct S
+		{
+			highp float a;
+			highp float b[2];
+		};
+		patch out S patchVariable; // output structure containing array is illegal
+		void main()
+		{
+			patchVariable.a = gl_in[0].gl_Position.x;
+			patchVariable.b[0] = gl_in[0].gl_Position.y;
+			patchVariable.b[1] = gl_in[0].gl_Position.w;
+			${TESSELLATION_CONTROL_OUTPUT}
+		}
+	""
+	tessellation_evaluation ""
+		#version 310 es
+		${TESSELLATION_EVALUATION_DECLARATIONS}
+		struct S
+		{
+			highp float a;
+			highp float b[2];
+		};
+		patch in S patchVariable; // output structure containing array is illegal
+		out mediump float te_out;
+		void main()
+		{
+			te_out = patchVariable.a + patchVariable.b[1];
+			${TESSELLATION_EVALUATION_OUTPUT}
+		}
+	""
+	fragment ""
+		#version 310 es
+		precision mediump float;
+		${FRAGMENT_DECLARATIONS}
+		in mediump float te_out;
+		void main()
+		{
+			${FRAG_COLOR} = vec4(te_out);
+		}
+	""
+end
diff --git a/modules/gles31/functional/es31fTessellationTests.cpp b/modules/gles31/functional/es31fTessellationTests.cpp
index 45b8295..4b7ceac 100644
--- a/modules/gles31/functional/es31fTessellationTests.cpp
+++ b/modules/gles31/functional/es31fTessellationTests.cpp
@@ -23,6 +23,7 @@
 
 #include "es31fTessellationTests.hpp"
 #include "glsTextureTestUtil.hpp"
+#include "glsShaderLibrary.hpp"
 #include "glsStateQueryUtil.hpp"
 #include "gluShaderProgram.hpp"
 #include "gluRenderContext.hpp"
@@ -7568,6 +7569,17 @@
 				}
 			}
 		}
+
+		{
+			TestCaseGroup* const				negativeGroup	= new TestCaseGroup(m_context, "negative", "Negative cases");
+			gls::ShaderLibrary					shaderLibrary	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo());
+			const std::vector<tcu::TestNode*>	children		= shaderLibrary.loadShaderFile("shaders/tessellation_negative_user_defined_io.test");
+
+			userDefinedIOGroup->addChild(negativeGroup);
+
+			for (int i = 0; i < (int)children.size(); i++)
+				negativeGroup->addChild(children[i]);
+		}
 	}
 }