[49/63] shader_runner/spirv: Load a replacement .shader_test

Submitted by apinheiro on Feb. 23, 2019, 11:45 p.m.

Details

Message ID 20190223234551.21111-50-apinheiro@igalia.com
State New
Headers show
Series "ARB_gl_spirv full series" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

apinheiro Feb. 23, 2019, 11:45 p.m.
From: Neil Roberts <nroberts@igalia.com>

This adds a new new command line option "-spirv". If no SPIRV line is
found in the require section and "-spirv" is passed to the command
line, then it will try to load a replacement script by appending .spv
to the name of the file.

In that way, now "SPIRV YES" meaning changes slightly, from "Use by
default the SPIR-V on this shader test" to "We have a SPIR-V on this
shader, by default use it without looking for a external replacement
file".

We also added a "SPIRV NO" line that points that the shader is not
compatible with SPIR-V, so would be skipped even using -spirv.

"-spirv" is the counter-part command line option to "-glsl". The new
"-spirv" option is used to try to run tests on SPIR-V mode even if
they doesn't have a SPIR-V included, while "-glsl" is for tests that
even having SPIR-V included, we want them to run on GLSL mode.

Obviously it is a mistake to use "-spirv" and "-glsl" at the same
time.

v2: update on the code and commit message due the addition of the
    "-glsl" command line option, plus command line options

Signed-off-by: Neil Roberts <nroberts@igalia.com>
Signed-off-by: Alejandro PiƱeiro <apinheiro@igalia.com>
---
 tests/shaders/shader_runner.c | 79 +++++++++++++++++++++++++++++------
 1 file changed, 66 insertions(+), 13 deletions(-)

Patch hide | download patch | download mbox

diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c
index c53980b20..927926a35 100644
--- a/tests/shaders/shader_runner.c
+++ b/tests/shaders/shader_runner.c
@@ -57,12 +57,17 @@  PIGLIT_GL_TEST_CONFIG_BEGIN
 	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
 
-	/* By default SPIR-V mode is false. It will not be enabled
-	 * unless the script includes SPIRV YES or SPIRV ONLY lines at
-	 * [require] section, so it will be handled later.
-	 */
 	if (argc > 1) {
-		get_required_config(argv[1], spirv_replaces_glsl, &config);
+		bool spirv = spirv_replaces_glsl;
+
+		for (int i = 1; i < argc; ++i) {
+			if (!strcmp(argv[i], "-spirv")) {
+				spirv = true;
+				break;
+			}
+		}
+
+		get_required_config(argv[1], spirv, &config);
 	} else {
 		config.supports_gl_compat_version = 10;
 	}
@@ -180,6 +185,7 @@  static bool glsl_in_use = false;
 static bool force_glsl = false;
 static bool spirv_in_use = false;
 static bool force_no_names = false;
+static bool test_contains_spirv = false;
 static GLchar *prog_err_info = NULL;
 static GLuint vao = 0;
 static GLuint draw_fbo, read_fbo;
@@ -1220,15 +1226,21 @@  process_requirement(const char *line)
 		spirv_replaces_glsl = !force_glsl;
 
 		if (parse_str(line, "ONLY", NULL)) {
+			spirv_replaces_glsl = true;
+			test_contains_spirv = true;
+
 			if (force_glsl) {
 				printf("This shader is not compatible with GLSL\n");
 				return PIGLIT_SKIP;
 			}
 		} else if (parse_str(line, "YES", NULL)) {
-			/* Empty. Everything already set. Just parsing
-			 * correct options
-			 */
-		} else {
+			test_contains_spirv = true;
+		} else if (parse_str(line, "NO", &line)) {
+			if (spirv_replaces_glsl) {
+				printf("This shader is not compatible with SPIR-V\n");
+				return PIGLIT_SKIP;
+			}
+                } else {
 			printf("Unknown SPIRV line in [require]\n");
 			return PIGLIT_FAIL;
 		}
@@ -1651,6 +1663,26 @@  process_specialization(enum states state, const char *line)
 	return PIGLIT_FAIL;
 }
 
+static char *
+spirv_replacement_script(const char *script_name)
+{
+	int len = strlen(script_name);
+	char *buf = malloc(len + 5);
+	memcpy(buf, script_name, len);
+	strcpy(buf + len, ".spv");
+
+	if (piglit_is_file_older_than(buf, script_name)) {
+		printf("SPIR-V shader_test %s is older than "
+		       "corresponding GLSL shader_test"
+		       "or does not exist.\n",
+		       buf);
+		free(buf);
+		return NULL;
+	}
+
+	return buf;
+}
+
 static enum piglit_result
 process_elements(enum states state, const char *line)
 {
@@ -1704,6 +1736,19 @@  process_test_script(const char *script_name)
 
 	while (line[0] != '\0') {
 		if (line[0] == '[') {
+			if (state == requirements &&
+				spirv_replaces_glsl &&
+				!test_contains_spirv) {
+					free(text);
+					char *replacement =
+                                                spirv_replacement_script(script_name);
+					if (replacement == NULL)
+						return PIGLIT_FAIL;
+					enum piglit_result res =
+						process_test_script(replacement);
+					free(replacement);
+					return res;
+				}
 			result = leave_state(state, line, script_name);
 			if (result != PIGLIT_PASS)
 				return result;
@@ -1873,6 +1918,7 @@  struct requirement_parse_results {
 	bool found_glsl;
 	bool found_size;
 	bool found_depthbuffer;
+	bool found_spirv;
 	struct component_version gl_version;
 	struct component_version glsl_version;
 	unsigned size[2];
@@ -1891,6 +1937,7 @@  parse_required_config(struct requirement_parse_results *results,
 	results->found_glsl = false;
 	results->found_size = false;
 	results->found_depthbuffer = false;
+	results->found_spirv = false;
 
 	if (line == NULL) {
 		printf("could not read file \"%s\"\n", script_name);
@@ -1940,9 +1987,14 @@  parse_required_config(struct requirement_parse_results *results,
 				parse_uints(line, results->size, 2, NULL);
 			} else if (parse_str(line, "depthbuffer", NULL)) {
 				results->found_depthbuffer = true;
+			} else if (parse_str(line, "SPIRV", &line)) {
+				if (parse_str(line, "ONLY", NULL) || parse_str(line, "YES", NULL)) {
+					results->found_spirv = true;
+				}
 			}
 		}
 
+
 		line = strchrnul(line, '\n');
 		if (line[0] != '\0')
 			line++;
@@ -2000,7 +2052,7 @@  choose_required_gl_version(struct requirement_parse_results *parse_results,
  * the GL and GLSL version requirements.  Use these to guide context creation.
  */
 static void
-get_required_config(const char *script_name, bool spirv,
+get_required_config(const char *script_name, bool force_spirv,
 		    struct piglit_gl_test_config *config)
 {
 	struct requirement_parse_results parse_results;
@@ -2009,7 +2061,7 @@  get_required_config(const char *script_name, bool spirv,
 	parse_required_config(&parse_results, script_name);
 	choose_required_gl_version(&parse_results, &required_gl_version);
 
-	if (spirv) {
+	if (force_spirv || parse_results.found_spirv) {
 		required_gl_version.es = false;
 		required_gl_version.core = true;
 		required_gl_version.num = MAX2(required_gl_version.num, 33);
@@ -5876,8 +5928,8 @@  piglit_init(int argc, char **argv)
 
 	report_subtests = piglit_strip_arg(&argc, argv, "-report-subtests");
 	force_glsl =  piglit_strip_arg(&argc, argv, "-glsl");
-
 	force_no_names = piglit_strip_arg(&argc, argv, "-force-no-names");
+	spirv_replaces_glsl = piglit_strip_arg(&argc, argv, "-spirv");
 
 	if (force_glsl && spirv_replaces_glsl) {
 		printf("Options -glsl and -spirv can't be used at the same time\n");
@@ -5888,7 +5940,8 @@  piglit_init(int argc, char **argv)
 		force_no_names = true;
 
 	if (argc < 2) {
-		printf("usage: shader_runner <test.shader_test> [-glsl] [-force-no-names]\n");
+		printf("usage: shader_runner <test.shader_test> [-glsl] "
+		       "[-force-no-names] [-spirv]\n");
 		exit(1);
 	}