[Piglit] [PATCH 2/9] shader_runner: Add -get-program-binary parameter

Jordan Justen jordan.l.justen at intel.com
Sat Jun 9 05:48:00 UTC 2018


This parameter will test ARB_get_program_binary and
OES_get_program_binary with any shader runner test.

If -get-program-binary, then shader_runner will check to see if the
extension is supported, and if 1 or more binary formats are supported.
If the extensions are not supported, or 0 formats are supported, then
the test will result in a skip.

If the program binary extension is supported and 1 or more binary
formats are supported, then following a successful link of the shader
runner program:

1. GetProgramBinary will be used to get the program
2. A new program will be generated
3. ProgramBinary will be used on the new program with the previously
   returned binary
4. The old program will be deleted
5. The shader runner will continue to run using the new program

Although this is not a focused test of the get_program_binary
extensions, it does allow any of the thousands of previously written
shader runner tests to be run while testing get_program_binary.

Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
---
 tests/shaders/shader_runner.c | 96 +++++++++++++++++++++++++++++++++++
 1 file changed, 96 insertions(+)

diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c
index c4e25a33d..b3f1b3deb 100644
--- a/tests/shaders/shader_runner.c
+++ b/tests/shaders/shader_runner.c
@@ -149,6 +149,8 @@ static GLuint draw_fbo, read_fbo;
 static GLint render_width, render_height;
 static GLint read_width, read_height;
 
+static bool use_get_program_binary = false;
+
 static bool report_subtests = false;
 
 static struct texture_binding {
@@ -580,6 +582,88 @@ compile_and_bind_program(GLenum target, const char *start, int len)
 	return PIGLIT_PASS;
 }
 
+static bool
+program_binary_save_restore()
+{
+	GLint binary_length;
+	void *binary;
+	GLenum binary_format;
+	GLint ok;
+	GLuint new_prog;
+
+	if (!use_get_program_binary)
+		return true;
+
+	glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+	if (!ok)
+		return true;
+
+#ifdef PIGLIT_USE_OPENGL
+	glGetProgramiv(prog, GL_PROGRAM_BINARY_LENGTH, &binary_length);
+#else
+	glGetProgramiv(prog, GL_PROGRAM_BINARY_LENGTH_OES, &binary_length);
+#endif
+	if (!piglit_check_gl_error(GL_NO_ERROR)) {
+		fprintf(stderr, "glGetProgramiv GL_PROGRAM_BINARY_LENGTH "
+		        "error\n");
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	binary = malloc(binary_length);
+	if (!binary)
+		return false;
+
+#ifdef PIGLIT_USE_OPENGL
+	glGetProgramBinary(prog, binary_length, &binary_length, &binary_format,
+	                   binary);
+#else
+	glGetProgramBinaryOES(prog, binary_length, &binary_length,
+	                      &binary_format, binary);
+#endif
+	if (!piglit_check_gl_error(GL_NO_ERROR)) {
+		fprintf(stderr, "glGetProgramBinary error\n");
+		free(binary);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	new_prog = glCreateProgram();
+	if (!piglit_check_gl_error(GL_NO_ERROR)) {
+		free(binary);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+#ifdef PIGLIT_USE_OPENGL
+	glProgramBinary(new_prog, binary_format, binary, binary_length);
+#else
+	glProgramBinaryOES(new_prog, binary_format, binary, binary_length);
+#endif
+	free(binary);
+	if (!piglit_check_gl_error(GL_NO_ERROR)) {
+		fprintf(stderr, "glProgramBinary error "
+			"(should not happend according to spec.)\n");
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	glGetProgramiv(prog, GL_LINK_STATUS, &ok);
+	if (!ok) {
+		fprintf(stderr, "link failure after glProgramBinary\n");
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	if (prog_in_use) {
+		glUseProgram(new_prog);
+		if (!piglit_check_gl_error(GL_NO_ERROR))
+			piglit_report_result(PIGLIT_FAIL);
+	}
+
+	glDeleteProgram(prog);
+	if (!piglit_check_gl_error(GL_NO_ERROR))
+		piglit_report_result(PIGLIT_FAIL);
+	prog = new_prog;
+
+	return true;
+}
+
 static enum piglit_result
 link_sso(GLenum target)
 {
@@ -606,6 +690,9 @@ link_sso(GLenum target)
 		return PIGLIT_FAIL;
 	}
 
+	if (!program_binary_save_restore())
+		return PIGLIT_FAIL;
+
 	switch (target) {
 	case GL_VERTEX_SHADER:
 		sso_vertex_prog = prog;
@@ -1097,6 +1184,8 @@ link_and_use_shaders(void)
 		glLinkProgram(prog);
 
 	if (!sso_in_use) {
+		if (!program_binary_save_restore())
+			return PIGLIT_FAIL;
 		glGetProgramiv(prog, GL_LINK_STATUS, &ok);
 		if (ok) {
 			link_ok = true;
@@ -4036,6 +4125,8 @@ piglit_init(int argc, char **argv)
 	enum piglit_result result;
 	float default_piglit_tolerance[4];
 
+	use_get_program_binary =
+		piglit_strip_arg(&argc, argv, "-get-program-binary");
 	report_subtests = piglit_strip_arg(&argc, argv, "-report-subtests");
 	if (argc < 2) {
 		printf("usage: shader_runner <test.shader_test>\n");
@@ -4106,6 +4197,11 @@ piglit_init(int argc, char **argv)
 		              &gl_num_program_binary_formats);
 #endif
 
+	if (use_get_program_binary) {
+		if (gl_num_program_binary_formats == 0)
+			piglit_report_result(PIGLIT_SKIP);
+	}
+
 	/* Automatic mode can run multiple tests per session. */
 	if (report_subtests) {
 		char testname[4096], *ext;
-- 
2.17.1



More information about the Piglit mailing list