From: Neil Roberts <nrobe...@igalia.com> There can now be extra sections such as the following in the shader_test file:
[vertex shader specializations] uint 0 3 These will get passed to glSpecializeShader when compiling the corresponding shader. --- tests/shaders/shader_runner.c | 181 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 1 deletion(-) diff --git a/tests/shaders/shader_runner.c b/tests/shaders/shader_runner.c index abe0df0b0..bffc444d7 100644 --- a/tests/shaders/shader_runner.c +++ b/tests/shaders/shader_runner.c @@ -165,6 +165,16 @@ static bool use_get_program_binary = false; static bool report_subtests = false; +struct specialization_list { + size_t buffer_size; + size_t n_entries; + GLuint *indices; + union { GLuint u; GLfloat f; } *values; +}; + +static struct specialization_list +specializations[SHADER_TYPES]; + static struct texture_binding { GLuint obj; unsigned width; @@ -258,19 +268,25 @@ enum states { vertex_shader, vertex_shader_passthrough, vertex_shader_spirv, + vertex_shader_specializations, vertex_program, tess_ctrl_shader, tess_ctrl_shader_spirv, + tess_ctrl_shader_specializations, tess_eval_shader, tess_eval_shader_spirv, + tess_eval_shader_specializations, geometry_shader, geometry_shader_spirv, + geometry_shader_specializations, geometry_layout, fragment_shader, fragment_shader_spirv, + fragment_shader_specializations, fragment_program, compute_shader, compute_shader_spirv, + compute_shader_specializations, vertex_data, test, }; @@ -719,7 +735,36 @@ load_and_specialize_spirv(GLenum target, glShaderBinary(1, &shader, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, binary, size); - glSpecializeShaderARB(shader, "main", 0, NULL, NULL); + const struct specialization_list *specs; + + switch (target) { + case GL_VERTEX_SHADER: + specs = specializations + 0; + break; + case GL_TESS_CONTROL_SHADER: + specs = specializations + 1; + break; + case GL_TESS_EVALUATION_SHADER: + specs = specializations + 2; + break; + case GL_GEOMETRY_SHADER: + specs = specializations + 3; + break; + case GL_FRAGMENT_SHADER: + specs = specializations + 4; + break; + case GL_COMPUTE_SHADER: + specs = specializations + 5; + break; + default: + assert(!"Should not get here."); + } + + glSpecializeShaderARB(shader, + "main", + specs->n_entries, + specs->indices, + &specs->values[0].u); GLint ok; glGetShaderiv(shader, GL_COMPILE_STATUS, &ok); @@ -1256,6 +1301,9 @@ leave_state(enum states state, const char *line, const char *script_name) shader_string_size = line - shader_string; return assemble_spirv(GL_VERTEX_SHADER); + case vertex_shader_specializations: + break; + case tess_ctrl_shader: if (spirv_replaces_glsl) break; @@ -1268,6 +1316,9 @@ leave_state(enum states state, const char *line, const char *script_name) shader_string_size = line - shader_string; return assemble_spirv(GL_TESS_CONTROL_SHADER); + case tess_ctrl_shader_specializations: + break; + case tess_eval_shader: if (spirv_replaces_glsl) break; @@ -1280,6 +1331,9 @@ leave_state(enum states state, const char *line, const char *script_name) shader_string_size = line - shader_string; return assemble_spirv(GL_TESS_EVALUATION_SHADER); + case tess_eval_shader_specializations: + break; + case geometry_shader: if (spirv_replaces_glsl) break; @@ -1292,6 +1346,9 @@ leave_state(enum states state, const char *line, const char *script_name) shader_string_size = line - shader_string; return assemble_spirv(GL_GEOMETRY_SHADER); + case geometry_shader_specializations: + break; + case geometry_layout: break; @@ -1313,6 +1370,9 @@ leave_state(enum states state, const char *line, const char *script_name) shader_string_size = line - shader_string; return assemble_spirv(GL_FRAGMENT_SHADER); + case fragment_shader_specializations: + break; + case compute_shader: if (spirv_replaces_glsl) break; @@ -1325,6 +1385,9 @@ leave_state(enum states state, const char *line, const char *script_name) shader_string_size = line - shader_string; return assemble_spirv(GL_COMPUTE_SHADER); + case compute_shader_specializations: + break; + case vertex_data: vertex_data_end = line; break; @@ -1491,6 +1554,93 @@ cleanup: return result; } +static enum piglit_result +process_specialization(enum states state, const char *line) +{ + const char *end = strchrnul(line, '\n'); + const char *next; + enum { TYPE_FLOAT, TYPE_UINT } type; + + while (line < end && isspace(*line)) + line++; + + if (line >= end || *line == '#') + return PIGLIT_PASS; + + if (parse_str(line, "uint", &next)) + type = TYPE_UINT; + else if (parse_str(line, "float", &next)) + type = TYPE_FLOAT; + else + goto invalid; + + struct specialization_list *list; + + switch (state) { + case vertex_shader_specializations: + list = specializations + 0; + break; + case tess_ctrl_shader_specializations: + list = specializations + 1; + break; + case tess_eval_shader_specializations: + list = specializations + 2; + break; + case geometry_shader_specializations: + list = specializations + 3; + break; + case fragment_shader_specializations: + list = specializations + 4; + break; + case compute_shader_specializations: + list = specializations + 5; + break; + default: + assert(!"Should not get here."); + } + + if (list->n_entries >= list->buffer_size) { + if (list->buffer_size == 0) + list->buffer_size = 1; + else + list->buffer_size *= 2; + list->indices = realloc(list->indices, + (sizeof list->indices[0]) * + list->buffer_size); + list->values = realloc(list->values, + (sizeof list->values[0]) * + list->buffer_size); + } + + if (parse_uints(next, list->indices + list->n_entries, 1, &next) != 1) + goto invalid; + + switch (type) { + case TYPE_UINT: + if (parse_uints(next, + &list->values[list->n_entries].u, + 1, + &next) != 1) + goto invalid; + break; + case TYPE_FLOAT: + if (parse_floats(next, + &list->values[list->n_entries].f, + 1, + &next) != 1) + goto invalid; + break; + } + + list->n_entries++; + + return PIGLIT_PASS; + + invalid: + fprintf(stderr, "Invalid specialization line\n"); + return PIGLIT_FAIL; +} + static enum piglit_result process_test_script(const char *script_name) { @@ -1530,24 +1680,34 @@ process_test_script(const char *script_name) } else if (parse_str(line, "[vertex shader spirv]", NULL)) { state = vertex_shader_spirv; shader_string = NULL; + } else if (parse_str(line, "[vertex shader specializations]", NULL)) { + state = vertex_shader_specializations; } else if (parse_str(line, "[tessellation control shader]", NULL)) { state = tess_ctrl_shader; shader_string = NULL; } else if (parse_str(line, "[tessellation control shader spirv]", NULL)) { state = tess_ctrl_shader_spirv; shader_string = NULL; + } else if (parse_str(line, "[tessellation control shader specializations]", NULL)) { + state = tess_ctrl_shader_specializations; } else if (parse_str(line, "[tessellation evaluation shader]", NULL)) { state = tess_eval_shader; shader_string = NULL; } else if (parse_str(line, "[tessellation evaluation shader spirv]", NULL)) { state = tess_eval_shader_spirv; shader_string = NULL; + } else if (parse_str(line, "[tessellation evaluation shader specializations]", NULL)) { + state = tess_eval_shader_specializations; } else if (parse_str(line, "[geometry shader]", NULL)) { state = geometry_shader; shader_string = NULL; + } else if (parse_str(line, "[geometry shader specializations]", NULL)) { + state = geometry_shader_specializations; } else if (parse_str(line, "[geometry shader spirv]", NULL)) { state = geometry_shader_spirv; shader_string = NULL; + } else if (parse_str(line, "[geometry shader specializations]", NULL)) { + state = geometry_shader_specializations; } else if (parse_str(line, "[geometry layout]", NULL)) { state = geometry_layout; shader_string = NULL; @@ -1557,15 +1717,21 @@ process_test_script(const char *script_name) } else if (parse_str(line, "[fragment program]", NULL)) { state = fragment_program; shader_string = NULL; + } else if (parse_str(line, "[fragment shader specializations]", NULL)) { + state = fragment_shader_specializations; } else if (parse_str(line, "[fragment shader spirv]", NULL)) { state = fragment_shader_spirv; shader_string = NULL; + } else if (parse_str(line, "[fragment shader specializations]", NULL)) { + state = fragment_shader_specializations; } else if (parse_str(line, "[compute shader]", NULL)) { state = compute_shader; shader_string = NULL; } else if (parse_str(line, "[compute shader spirv]", NULL)) { state = compute_shader_spirv; shader_string = NULL; + } else if (parse_str(line, "[compute shader specializations]", NULL)) { + state = compute_shader_specializations; } else if (parse_str(line, "[vertex data]", NULL)) { state = vertex_data; vertex_data_start = NULL; @@ -1615,6 +1781,19 @@ process_test_script(const char *script_name) shader_string = (char *) line; break; + case vertex_shader_specializations: + case tess_ctrl_shader_specializations: + case tess_eval_shader_specializations: + case geometry_shader_specializations: + case fragment_shader_specializations: + case compute_shader_specializations: { + enum piglit_result result = + process_specialization(state, line); + if (result != PIGLIT_PASS) + return result; + break; + } + case vertex_data: if (vertex_data_start == NULL) vertex_data_start = line; -- 2.14.1 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit