Timothy Arceri
2015-May-24 22:34 UTC
[Nouveau] [Mesa-dev] [PATCH 07/11] glsl: Add arb_cull_distance support
On Sun, 2015-05-24 at 19:58 +0200, Tobias Klausmann wrote:> Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> > --- > src/glsl/ast_to_hir.cpp | 14 +++++ > src/glsl/builtin_variables.cpp | 13 +++- > src/glsl/glcpp/glcpp-parse.y | 3 + > src/glsl/glsl_parser_extras.cpp | 1 + > src/glsl/glsl_parser_extras.h | 3 + > src/glsl/link_varyings.cpp | 2 +- > src/glsl/linker.cpp | 121 +++++++++++++++++++++++++----------- > src/glsl/standalone_scaffolding.cpp | 1 + > src/glsl/tests/varyings_test.cpp | 27 ++++++++ > 9 files changed, 145 insertions(+), 40 deletions(-) > > diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp > index 8aebb13..4db2b2e 100644 > --- a/src/glsl/ast_to_hir.cpp > +++ b/src/glsl/ast_to_hir.cpp > @@ -1045,6 +1045,20 @@ check_builtin_array_max_size(const char *name, unsigned size, > _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot " > "be larger than gl_MaxClipDistances (%u)", > state->Const.MaxClipPlanes); > + } else if (strcmp("gl_CullDistance", name) == 0 > + && size > state->Const.MaxClipPlanes) { > + /* From the ARB_cull_distance spec: > + * > + * "The gl_CullDistance array is predeclared as unsized and > + * must be sized by the shader either redeclaring it with > + * a size or indexing it only with integral constant > + * expressions. The size determines the number and set of > + * enabled cull distances and can be at most > + * gl_MaxCullDistances." > + */ > + _mesa_glsl_error(&loc, state, "`gl_CullDistance' array size cannot " > + "be larger than gl_MaxCullDistances (%u)", > + state->Const.MaxClipPlanes); > } > } > > diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp > index 6806aa1..78c8db2 100644 > --- a/src/glsl/builtin_variables.cpp > +++ b/src/glsl/builtin_variables.cpp > @@ -298,7 +298,7 @@ public: > const glsl_type *construct_interface_instance() const; > > private: > - glsl_struct_field fields[10]; > + glsl_struct_field fields[11]; > unsigned num_fields; > }; > > @@ -600,6 +600,12 @@ builtin_variable_generator::generate_constants() > add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4); > } > > + if (state->is_version(450, 0) || state->ARB_cull_distance_enable) { > + add_const("gl_MaxCullDistances", state->Const.MaxClipPlanes); > + add_const("gl_MaxCombinedClipAndCullDistances", > + state->Const.MaxClipPlanes); > + } > + > if (state->is_version(150, 0)) { > add_const("gl_MaxVertexOutputComponents", > state->Const.MaxVertexOutputComponents); > @@ -1029,6 +1035,11 @@ builtin_variable_generator::generate_varyings() > "gl_ClipDistance"); > } > > + if (state->is_version(450, 0) || state->ARB_cull_distance_enable) { > + ADD_VARYING(VARYING_SLOT_CULL_DIST0, array(float_t, 0), > + "gl_CullDistance"); > + } > + > if (compatibility) { > ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord"); > ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord"); > diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y > index a11b6b2..536c17f 100644 > --- a/src/glsl/glcpp/glcpp-parse.y > +++ b/src/glsl/glcpp/glcpp-parse.y > @@ -2483,6 +2483,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio > > if (extensions->ARB_shader_precision) > add_builtin_define(parser, "GL_ARB_shader_precision", 1); > + > + if (extensions->ARB_cull_distance) > + add_builtin_define(parser, "GL_ARB_cull_distance", 1); > } > } > > diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp > index 046d5d7..d1cd8ff 100644 > --- a/src/glsl/glsl_parser_extras.cpp > +++ b/src/glsl/glsl_parser_extras.cpp > @@ -554,6 +554,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { > EXT(ARB_arrays_of_arrays, true, false, ARB_arrays_of_arrays), > EXT(ARB_compute_shader, true, false, ARB_compute_shader), > EXT(ARB_conservative_depth, true, false, ARB_conservative_depth), > + EXT(ARB_cull_distance, true, false, ARB_cull_distance), > EXT(ARB_derivative_control, true, false, ARB_derivative_control), > EXT(ARB_draw_buffers, true, false, dummy_true), > EXT(ARB_draw_instanced, true, false, ARB_draw_instanced), > diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h > index 9a0c24e..8572905 100644 > --- a/src/glsl/glsl_parser_extras.h > +++ b/src/glsl/glsl_parser_extras.h > @@ -378,6 +378,7 @@ struct _mesa_glsl_parse_state { > > /* ARB_viewport_array */ > unsigned MaxViewports; > + > } Const; > > /** > @@ -430,6 +431,8 @@ struct _mesa_glsl_parse_state { > bool ARB_compute_shader_warn; > bool ARB_conservative_depth_enable; > bool ARB_conservative_depth_warn; > + bool ARB_cull_distance_enable; > + bool ARB_cull_distance_warn; > bool ARB_derivative_control_enable; > bool ARB_derivative_control_warn; > bool ARB_draw_buffers_enable; > diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp > index 46f84c6..81c0dac 100644 > --- a/src/glsl/link_varyings.cpp > +++ b/src/glsl/link_varyings.cpp > @@ -404,7 +404,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx, > this->matched_candidate->type->fields.array->vector_elements; > unsigned actual_array_size > (this->is_clip_distance_mesa || this->is_cull_distance_mesa) ? > - prog->LastClipDistanceArraySize : > + prog->LastClipCullDistanceArraySize : > this->matched_candidate->type->array_size(); > > if (this->is_subscripted) { > diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp > index e616520..8bb1a5c 100644 > --- a/src/glsl/linker.cpp > +++ b/src/glsl/linker.cpp > @@ -474,49 +474,94 @@ link_invalidate_variable_locations(exec_list *ir) > } > > > + > /** > - * Set UsesClipDistance and ClipDistanceArraySize based on the given shader. > + * Set UsesClipCullDistance and ClipCullDistanceArraySize based on the given > + * shader. > * > - * Also check for errors based on incorrect usage of gl_ClipVertex and > - * gl_ClipDistance. > + * Also check for errors based on incorrect usage of gl_ClipVertex, > + * gl_ClipDistance and gl_CullDistance. > + * > + * Additionally test whether the arrays gl_ClipDistance and gl_CullDistance > + * exceed the maximum size defined by gl_MaxCombinedClipAndCullDistances. > * > * Return false if an error was reported. > */ > static void > -analyze_clip_usage(struct gl_shader_program *prog, > - struct gl_shader *shader, GLboolean *UsesClipDistance, > - GLuint *ClipDistanceArraySize) > +analyze_clip_cull_usage(struct gl_shader_program *prog, > + struct gl_shader *shader, > + struct gl_context *ctx, > + GLboolean *UsesClipCullDistance, > + GLuint *ClipCullDistanceArraySize) > { > - *ClipDistanceArraySize = 0; > + *ClipCullDistanceArraySize = 0; > > - if (!prog->IsES && prog->Version >= 130) { > - /* From section 7.1 (Vertex Shader Special Variables) of the > - * GLSL 1.30 spec: > - * > - * "It is an error for a shader to statically write both > - * gl_ClipVertex and gl_ClipDistance." > - * > - * This does not apply to GLSL ES shaders, since GLSL ES defines neither > - * gl_ClipVertex nor gl_ClipDistance. > - */ > + if (prog->IsES && prog->Version < 130) { > + *UsesClipCullDistance = false; > + } else { > find_assignment_visitor clip_vertex("gl_ClipVertex"); > find_assignment_visitor clip_distance("gl_ClipDistance"); > + find_assignment_visitor cull_distance("gl_CullDistance"); > > clip_vertex.run(shader->ir); > clip_distance.run(shader->ir); > + cull_distance.run(shader->ir); > + > + /* From the ARB_cull_distance spec: > + * > + * It is a compile-time or link-time error for the set of shaders forming > + * a program to statically read or write both gl_ClipVertex and either > + * gl_ClipDistance or gl_CullDistance. > + * > + * This does not apply to GLSL ES shaders, since GLSL ES defines neither > + * gl_ClipVertex, gl_ClipDistance or gl_CullDistance. > + */ > if (clip_vertex.variable_found() && clip_distance.variable_found()) { > linker_error(prog, "%s shader writes to both `gl_ClipVertex' " > "and `gl_ClipDistance'\n", > _mesa_shader_stage_to_string(shader->Stage)); > return; > } > - *UsesClipDistance = clip_distance.variable_found(); > + if (clip_vertex.variable_found() && cull_distance.variable_found()) { > + linker_error(prog, "%s shader writes to both `gl_ClipVertex' " > + "and `gl_CullDistance'\n", > + _mesa_shader_stage_to_string(shader->Stage)); > + return; > + } > + > + *UsesClipCullDistance = clip_distance.variable_found() | > + cull_distance.variable_found(); > + > ir_variable *clip_distance_var > shader->symbols->get_variable("gl_ClipDistance"); > + ir_variable *cull_distance_var > + shader->symbols->get_variable("gl_CullDistance"); > + > if (clip_distance_var) > - *ClipDistanceArraySize = clip_distance_var->type->length; > - } else { > - *UsesClipDistance = false; > + *ClipCullDistanceArraySize = clip_distance_var->type->was_unsized ? > + clip_distance_var->type->length -1 : > + clip_distance_var->type->length; > + > + if (cull_distance_var) > + *ClipCullDistanceArraySize+= cull_distance_var->type->was_unsized ? > + cull_distance_var->type->length -1 : > + cull_distance_var->type->length;How come this needs to be done for former unsized arrays?> + > + /* From the ARB_cull_distance spec: > + * > + * It is a compile-time or link-time error for the set of shaders forming > + * a program to have the sum of the sizes of the gl_ClipDistance and > + * gl_CullDistance arrays to be larger than > + * gl_MaxCombinedClipAndCullDistances. > + */ > + if (*ClipCullDistanceArraySize > ctx->Const.MaxClipPlanes) { > + linker_error(prog, "%s shader: the combined size of " > + "'gl_ClipDistance' and 'gl_CullDistance' size cannot " > + "be larger than " > + "gl_MaxCombinedClipAndCullDistances (%u)", > + _mesa_shader_stage_to_string(shader->Stage), > + ctx->Const.MaxClipPlanes); > + } > } > } > > @@ -524,14 +569,14 @@ analyze_clip_usage(struct gl_shader_program *prog, > /** > * Verify that a vertex shader executable meets all semantic requirements. > * > - * Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize > - * as a side effect. > + * Also sets prog->Vert.UsesClipCullDistance and > + * prog->Vert.ClipCullDistanceArraySize as a side effect. > * > * \param shader Vertex shader executable to be verified > */ > void > validate_vertex_shader_executable(struct gl_shader_program *prog, > - struct gl_shader *shader) > + struct gl_shader *shader, struct gl_context *ctx) > { > if (shader == NULL) > return; > @@ -578,8 +623,8 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, > } > } > > - analyze_clip_usage(prog, shader, &prog->Vert.UsesClipDistance, > - &prog->Vert.ClipDistanceArraySize); > + analyze_clip_cull_usage(prog, shader, ctx, &prog->Vert.UsesClipCullDistance, > + &prog->Vert.ClipCullDistanceArraySize); > } > > > @@ -590,7 +635,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, > */ > void > validate_fragment_shader_executable(struct gl_shader_program *prog, > - struct gl_shader *shader) > + struct gl_shader *shader, struct gl_context *ctx) > { > if (shader == NULL) > return; > @@ -610,14 +655,14 @@ validate_fragment_shader_executable(struct gl_shader_program *prog, > /** > * Verify that a geometry shader executable meets all semantic requirements > * > - * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipDistance, and > - * prog->Geom.ClipDistanceArraySize as a side effect. > + * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipCullDistance, and > + * prog->Geom.ClipCullDistanceArraySize as a side effect. > * > * \param shader Geometry shader executable to be verified > */ > void > validate_geometry_shader_executable(struct gl_shader_program *prog, > - struct gl_shader *shader) > + struct gl_shader *shader, struct gl_context *ctx) > { > if (shader == NULL) > return; > @@ -625,8 +670,8 @@ validate_geometry_shader_executable(struct gl_shader_program *prog, > unsigned num_vertices = vertices_per_prim(prog->Geom.InputType); > prog->Geom.VerticesIn = num_vertices; > > - analyze_clip_usage(prog, shader, &prog->Geom.UsesClipDistance, > - &prog->Geom.ClipDistanceArraySize); > + analyze_clip_cull_usage(prog, shader, ctx, &prog->Geom.UsesClipCullDistance, > + &prog->Geom.ClipCullDistanceArraySize); > } > > /** > @@ -2834,13 +2879,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) > > switch (stage) { > case MESA_SHADER_VERTEX: > - validate_vertex_shader_executable(prog, sh); > + validate_vertex_shader_executable(prog, sh, ctx); > break; > case MESA_SHADER_GEOMETRY: > - validate_geometry_shader_executable(prog, sh); > + validate_geometry_shader_executable(prog, sh, ctx); > break; > case MESA_SHADER_FRAGMENT: > - validate_fragment_shader_executable(prog, sh); > + validate_fragment_shader_executable(prog, sh, ctx); > break; > } > if (!prog->LinkStatus) > @@ -2851,11 +2896,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) > } > > if (num_shaders[MESA_SHADER_GEOMETRY] > 0) > - prog->LastClipDistanceArraySize = prog->Geom.ClipDistanceArraySize; > + prog->LastClipCullDistanceArraySize = prog->Geom.ClipCullDistanceArraySize; > else if (num_shaders[MESA_SHADER_VERTEX] > 0) > - prog->LastClipDistanceArraySize = prog->Vert.ClipDistanceArraySize; > + prog->LastClipCullDistanceArraySize = prog->Vert.ClipCullDistanceArraySize; > else > - prog->LastClipDistanceArraySize = 0; /* Not used */ > + prog->LastClipCullDistanceArraySize = 0; /* Not used */ > > /* Here begins the inter-stage linking phase. Some initial validation is > * performed, then locations are assigned for uniforms, attributes, and > diff --git a/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp > index a109c4e..0ac16bb 100644 > --- a/src/glsl/standalone_scaffolding.cpp > +++ b/src/glsl/standalone_scaffolding.cpp > @@ -142,6 +142,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) > ctx->Extensions.ARB_texture_query_lod = true; > ctx->Extensions.ARB_uniform_buffer_object = true; > ctx->Extensions.ARB_viewport_array = true; > + ctx->Extensions.ARB_cull_distance = true; > > ctx->Extensions.OES_EGL_image_external = true; > ctx->Extensions.OES_standard_derivatives = true; > diff --git a/src/glsl/tests/varyings_test.cpp b/src/glsl/tests/varyings_test.cpp > index 4573529..7a962c5 100644 > --- a/src/glsl/tests/varyings_test.cpp > +++ b/src/glsl/tests/varyings_test.cpp > @@ -202,6 +202,33 @@ TEST_F(link_varyings, gl_ClipDistance) > EXPECT_TRUE(is_empty(consumer_interface_inputs)); > } > > +TEST_F(link_varyings, gl_CullDistance) > +{ > + const glsl_type *const array_8_of_float > + glsl_type::get_array_instance(glsl_type::vec(1), 8); > + > + ir_variable *const culldistance > + new(mem_ctx) ir_variable(array_8_of_float, > + "gl_CullDistance", > + ir_var_shader_in); > + > + culldistance->data.explicit_location = true; > + culldistance->data.location = VARYING_SLOT_CULL_DIST0; > + culldistance->data.explicit_index = 0; > + > + ir.push_tail(culldistance); > + > + ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, > + &ir, > + consumer_inputs, > + consumer_interface_inputs, > + junk)); > + > + EXPECT_EQ(culldistance, junk[VARYING_SLOT_CULL_DIST0]); > + EXPECT_TRUE(is_empty(consumer_inputs)); > + EXPECT_TRUE(is_empty(consumer_interface_inputs)); > +} > + > TEST_F(link_varyings, single_interface_input) > { > ir_variable *const v =
Tobias Klausmann
2015-May-24 22:46 UTC
[Nouveau] [Mesa-dev] [PATCH 07/11] glsl: Add arb_cull_distance support
hi, replay inline. On 25.05.2015 00:34, Timothy Arceri wrote:> On Sun, 2015-05-24 at 19:58 +0200, Tobias Klausmann wrote: >> Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> >> --- >> src/glsl/ast_to_hir.cpp | 14 +++++ >> src/glsl/builtin_variables.cpp | 13 +++- >> src/glsl/glcpp/glcpp-parse.y | 3 + >> src/glsl/glsl_parser_extras.cpp | 1 + >> src/glsl/glsl_parser_extras.h | 3 + >> src/glsl/link_varyings.cpp | 2 +- >> src/glsl/linker.cpp | 121 +++++++++++++++++++++++++----------- >> src/glsl/standalone_scaffolding.cpp | 1 + >> src/glsl/tests/varyings_test.cpp | 27 ++++++++ >> 9 files changed, 145 insertions(+), 40 deletions(-) >> >> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp >> index 8aebb13..4db2b2e 100644 >> --- a/src/glsl/ast_to_hir.cpp >> +++ b/src/glsl/ast_to_hir.cpp >> @@ -1045,6 +1045,20 @@ check_builtin_array_max_size(const char *name, unsigned size, >> _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot " >> "be larger than gl_MaxClipDistances (%u)", >> state->Const.MaxClipPlanes); >> + } else if (strcmp("gl_CullDistance", name) == 0 >> + && size > state->Const.MaxClipPlanes) { >> + /* From the ARB_cull_distance spec: >> + * >> + * "The gl_CullDistance array is predeclared as unsized and >> + * must be sized by the shader either redeclaring it with >> + * a size or indexing it only with integral constant >> + * expressions. The size determines the number and set of >> + * enabled cull distances and can be at most >> + * gl_MaxCullDistances." >> + */ >> + _mesa_glsl_error(&loc, state, "`gl_CullDistance' array size cannot " >> + "be larger than gl_MaxCullDistances (%u)", >> + state->Const.MaxClipPlanes); >> } >> } >> >> diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp >> index 6806aa1..78c8db2 100644 >> --- a/src/glsl/builtin_variables.cpp >> +++ b/src/glsl/builtin_variables.cpp >> @@ -298,7 +298,7 @@ public: >> const glsl_type *construct_interface_instance() const; >> >> private: >> - glsl_struct_field fields[10]; >> + glsl_struct_field fields[11]; >> unsigned num_fields; >> }; >> >> @@ -600,6 +600,12 @@ builtin_variable_generator::generate_constants() >> add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4); >> } >> >> + if (state->is_version(450, 0) || state->ARB_cull_distance_enable) { >> + add_const("gl_MaxCullDistances", state->Const.MaxClipPlanes); >> + add_const("gl_MaxCombinedClipAndCullDistances", >> + state->Const.MaxClipPlanes); >> + } >> + >> if (state->is_version(150, 0)) { >> add_const("gl_MaxVertexOutputComponents", >> state->Const.MaxVertexOutputComponents); >> @@ -1029,6 +1035,11 @@ builtin_variable_generator::generate_varyings() >> "gl_ClipDistance"); >> } >> >> + if (state->is_version(450, 0) || state->ARB_cull_distance_enable) { >> + ADD_VARYING(VARYING_SLOT_CULL_DIST0, array(float_t, 0), >> + "gl_CullDistance"); >> + } >> + >> if (compatibility) { >> ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord"); >> ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord"); >> diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y >> index a11b6b2..536c17f 100644 >> --- a/src/glsl/glcpp/glcpp-parse.y >> +++ b/src/glsl/glcpp/glcpp-parse.y >> @@ -2483,6 +2483,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio >> >> if (extensions->ARB_shader_precision) >> add_builtin_define(parser, "GL_ARB_shader_precision", 1); >> + >> + if (extensions->ARB_cull_distance) >> + add_builtin_define(parser, "GL_ARB_cull_distance", 1); >> } >> } >> >> diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp >> index 046d5d7..d1cd8ff 100644 >> --- a/src/glsl/glsl_parser_extras.cpp >> +++ b/src/glsl/glsl_parser_extras.cpp >> @@ -554,6 +554,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { >> EXT(ARB_arrays_of_arrays, true, false, ARB_arrays_of_arrays), >> EXT(ARB_compute_shader, true, false, ARB_compute_shader), >> EXT(ARB_conservative_depth, true, false, ARB_conservative_depth), >> + EXT(ARB_cull_distance, true, false, ARB_cull_distance), >> EXT(ARB_derivative_control, true, false, ARB_derivative_control), >> EXT(ARB_draw_buffers, true, false, dummy_true), >> EXT(ARB_draw_instanced, true, false, ARB_draw_instanced), >> diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h >> index 9a0c24e..8572905 100644 >> --- a/src/glsl/glsl_parser_extras.h >> +++ b/src/glsl/glsl_parser_extras.h >> @@ -378,6 +378,7 @@ struct _mesa_glsl_parse_state { >> >> /* ARB_viewport_array */ >> unsigned MaxViewports; >> + >> } Const; >> >> /** >> @@ -430,6 +431,8 @@ struct _mesa_glsl_parse_state { >> bool ARB_compute_shader_warn; >> bool ARB_conservative_depth_enable; >> bool ARB_conservative_depth_warn; >> + bool ARB_cull_distance_enable; >> + bool ARB_cull_distance_warn; >> bool ARB_derivative_control_enable; >> bool ARB_derivative_control_warn; >> bool ARB_draw_buffers_enable; >> diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp >> index 46f84c6..81c0dac 100644 >> --- a/src/glsl/link_varyings.cpp >> +++ b/src/glsl/link_varyings.cpp >> @@ -404,7 +404,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx, >> this->matched_candidate->type->fields.array->vector_elements; >> unsigned actual_array_size >> (this->is_clip_distance_mesa || this->is_cull_distance_mesa) ? >> - prog->LastClipDistanceArraySize : >> + prog->LastClipCullDistanceArraySize : >> this->matched_candidate->type->array_size(); >> >> if (this->is_subscripted) { >> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp >> index e616520..8bb1a5c 100644 >> --- a/src/glsl/linker.cpp >> +++ b/src/glsl/linker.cpp >> @@ -474,49 +474,94 @@ link_invalidate_variable_locations(exec_list *ir) >> } >> >> >> + >> /** >> - * Set UsesClipDistance and ClipDistanceArraySize based on the given shader. >> + * Set UsesClipCullDistance and ClipCullDistanceArraySize based on the given >> + * shader. >> * >> - * Also check for errors based on incorrect usage of gl_ClipVertex and >> - * gl_ClipDistance. >> + * Also check for errors based on incorrect usage of gl_ClipVertex, >> + * gl_ClipDistance and gl_CullDistance. >> + * >> + * Additionally test whether the arrays gl_ClipDistance and gl_CullDistance >> + * exceed the maximum size defined by gl_MaxCombinedClipAndCullDistances. >> * >> * Return false if an error was reported. >> */ >> static void >> -analyze_clip_usage(struct gl_shader_program *prog, >> - struct gl_shader *shader, GLboolean *UsesClipDistance, >> - GLuint *ClipDistanceArraySize) >> +analyze_clip_cull_usage(struct gl_shader_program *prog, >> + struct gl_shader *shader, >> + struct gl_context *ctx, >> + GLboolean *UsesClipCullDistance, >> + GLuint *ClipCullDistanceArraySize) >> { >> - *ClipDistanceArraySize = 0; >> + *ClipCullDistanceArraySize = 0; >> >> - if (!prog->IsES && prog->Version >= 130) { >> - /* From section 7.1 (Vertex Shader Special Variables) of the >> - * GLSL 1.30 spec: >> - * >> - * "It is an error for a shader to statically write both >> - * gl_ClipVertex and gl_ClipDistance." >> - * >> - * This does not apply to GLSL ES shaders, since GLSL ES defines neither >> - * gl_ClipVertex nor gl_ClipDistance. >> - */ >> + if (prog->IsES && prog->Version < 130) { >> + *UsesClipCullDistance = false; >> + } else { >> find_assignment_visitor clip_vertex("gl_ClipVertex"); >> find_assignment_visitor clip_distance("gl_ClipDistance"); >> + find_assignment_visitor cull_distance("gl_CullDistance"); >> >> clip_vertex.run(shader->ir); >> clip_distance.run(shader->ir); >> + cull_distance.run(shader->ir); >> + >> + /* From the ARB_cull_distance spec: >> + * >> + * It is a compile-time or link-time error for the set of shaders forming >> + * a program to statically read or write both gl_ClipVertex and either >> + * gl_ClipDistance or gl_CullDistance. >> + * >> + * This does not apply to GLSL ES shaders, since GLSL ES defines neither >> + * gl_ClipVertex, gl_ClipDistance or gl_CullDistance. >> + */ >> if (clip_vertex.variable_found() && clip_distance.variable_found()) { >> linker_error(prog, "%s shader writes to both `gl_ClipVertex' " >> "and `gl_ClipDistance'\n", >> _mesa_shader_stage_to_string(shader->Stage)); >> return; >> } >> - *UsesClipDistance = clip_distance.variable_found(); >> + if (clip_vertex.variable_found() && cull_distance.variable_found()) { >> + linker_error(prog, "%s shader writes to both `gl_ClipVertex' " >> + "and `gl_CullDistance'\n", >> + _mesa_shader_stage_to_string(shader->Stage)); >> + return; >> + } >> + >> + *UsesClipCullDistance = clip_distance.variable_found() | >> + cull_distance.variable_found(); >> + >> ir_variable *clip_distance_var >> shader->symbols->get_variable("gl_ClipDistance"); >> + ir_variable *cull_distance_var >> + shader->symbols->get_variable("gl_CullDistance"); >> + >> if (clip_distance_var) >> - *ClipDistanceArraySize = clip_distance_var->type->length; >> - } else { >> - *UsesClipDistance = false; >> + *ClipCullDistanceArraySize = clip_distance_var->type->was_unsized ? >> + clip_distance_var->type->length -1 : >> + clip_distance_var->type->length; >> + >> + if (cull_distance_var) >> + *ClipCullDistanceArraySize+= cull_distance_var->type->was_unsized ? >> + cull_distance_var->type->length -1 : >> + cull_distance_var->type->length; > > How come this needs to be done for former unsized arrays? >We replace an unsized array with a default size of 1 ( fixup_type() ) , so with either cull or clip set to max (8) and the other array left unsized we would end up with a total of 9 reported, that would trigger the error below.> >> + >> + /* From the ARB_cull_distance spec: >> + * >> + * It is a compile-time or link-time error for the set of shaders forming >> + * a program to have the sum of the sizes of the gl_ClipDistance and >> + * gl_CullDistance arrays to be larger than >> + * gl_MaxCombinedClipAndCullDistances. >> + */ >> + if (*ClipCullDistanceArraySize > ctx->Const.MaxClipPlanes) { >> + linker_error(prog, "%s shader: the combined size of " >> + "'gl_ClipDistance' and 'gl_CullDistance' size cannot " >> + "be larger than " >> + "gl_MaxCombinedClipAndCullDistances (%u)", >> + _mesa_shader_stage_to_string(shader->Stage), >> + ctx->Const.MaxClipPlanes); >> + } >> } >> } >> >> @@ -524,14 +569,14 @@ analyze_clip_usage(struct gl_shader_program *prog, >> /** >> * Verify that a vertex shader executable meets all semantic requirements. >> * >> - * Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize >> - * as a side effect. >> + * Also sets prog->Vert.UsesClipCullDistance and >> + * prog->Vert.ClipCullDistanceArraySize as a side effect. >> * >> * \param shader Vertex shader executable to be verified >> */ >> void >> validate_vertex_shader_executable(struct gl_shader_program *prog, >> - struct gl_shader *shader) >> + struct gl_shader *shader, struct gl_context *ctx) >> { >> if (shader == NULL) >> return; >> @@ -578,8 +623,8 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, >> } >> } >> >> - analyze_clip_usage(prog, shader, &prog->Vert.UsesClipDistance, >> - &prog->Vert.ClipDistanceArraySize); >> + analyze_clip_cull_usage(prog, shader, ctx, &prog->Vert.UsesClipCullDistance, >> + &prog->Vert.ClipCullDistanceArraySize); >> } >> >> >> @@ -590,7 +635,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, >> */ >> void >> validate_fragment_shader_executable(struct gl_shader_program *prog, >> - struct gl_shader *shader) >> + struct gl_shader *shader, struct gl_context *ctx) >> { >> if (shader == NULL) >> return; >> @@ -610,14 +655,14 @@ validate_fragment_shader_executable(struct gl_shader_program *prog, >> /** >> * Verify that a geometry shader executable meets all semantic requirements >> * >> - * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipDistance, and >> - * prog->Geom.ClipDistanceArraySize as a side effect. >> + * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipCullDistance, and >> + * prog->Geom.ClipCullDistanceArraySize as a side effect. >> * >> * \param shader Geometry shader executable to be verified >> */ >> void >> validate_geometry_shader_executable(struct gl_shader_program *prog, >> - struct gl_shader *shader) >> + struct gl_shader *shader, struct gl_context *ctx) >> { >> if (shader == NULL) >> return; >> @@ -625,8 +670,8 @@ validate_geometry_shader_executable(struct gl_shader_program *prog, >> unsigned num_vertices = vertices_per_prim(prog->Geom.InputType); >> prog->Geom.VerticesIn = num_vertices; >> >> - analyze_clip_usage(prog, shader, &prog->Geom.UsesClipDistance, >> - &prog->Geom.ClipDistanceArraySize); >> + analyze_clip_cull_usage(prog, shader, ctx, &prog->Geom.UsesClipCullDistance, >> + &prog->Geom.ClipCullDistanceArraySize); >> } >> >> /** >> @@ -2834,13 +2879,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) >> >> switch (stage) { >> case MESA_SHADER_VERTEX: >> - validate_vertex_shader_executable(prog, sh); >> + validate_vertex_shader_executable(prog, sh, ctx); >> break; >> case MESA_SHADER_GEOMETRY: >> - validate_geometry_shader_executable(prog, sh); >> + validate_geometry_shader_executable(prog, sh, ctx); >> break; >> case MESA_SHADER_FRAGMENT: >> - validate_fragment_shader_executable(prog, sh); >> + validate_fragment_shader_executable(prog, sh, ctx); >> break; >> } >> if (!prog->LinkStatus) >> @@ -2851,11 +2896,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) >> } >> >> if (num_shaders[MESA_SHADER_GEOMETRY] > 0) >> - prog->LastClipDistanceArraySize = prog->Geom.ClipDistanceArraySize; >> + prog->LastClipCullDistanceArraySize = prog->Geom.ClipCullDistanceArraySize; >> else if (num_shaders[MESA_SHADER_VERTEX] > 0) >> - prog->LastClipDistanceArraySize = prog->Vert.ClipDistanceArraySize; >> + prog->LastClipCullDistanceArraySize = prog->Vert.ClipCullDistanceArraySize; >> else >> - prog->LastClipDistanceArraySize = 0; /* Not used */ >> + prog->LastClipCullDistanceArraySize = 0; /* Not used */ >> >> /* Here begins the inter-stage linking phase. Some initial validation is >> * performed, then locations are assigned for uniforms, attributes, and >> diff --git a/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp >> index a109c4e..0ac16bb 100644 >> --- a/src/glsl/standalone_scaffolding.cpp >> +++ b/src/glsl/standalone_scaffolding.cpp >> @@ -142,6 +142,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) >> ctx->Extensions.ARB_texture_query_lod = true; >> ctx->Extensions.ARB_uniform_buffer_object = true; >> ctx->Extensions.ARB_viewport_array = true; >> + ctx->Extensions.ARB_cull_distance = true; >> >> ctx->Extensions.OES_EGL_image_external = true; >> ctx->Extensions.OES_standard_derivatives = true; >> diff --git a/src/glsl/tests/varyings_test.cpp b/src/glsl/tests/varyings_test.cpp >> index 4573529..7a962c5 100644 >> --- a/src/glsl/tests/varyings_test.cpp >> +++ b/src/glsl/tests/varyings_test.cpp >> @@ -202,6 +202,33 @@ TEST_F(link_varyings, gl_ClipDistance) >> EXPECT_TRUE(is_empty(consumer_interface_inputs)); >> } >> >> +TEST_F(link_varyings, gl_CullDistance) >> +{ >> + const glsl_type *const array_8_of_float >> + glsl_type::get_array_instance(glsl_type::vec(1), 8); >> + >> + ir_variable *const culldistance >> + new(mem_ctx) ir_variable(array_8_of_float, >> + "gl_CullDistance", >> + ir_var_shader_in); >> + >> + culldistance->data.explicit_location = true; >> + culldistance->data.location = VARYING_SLOT_CULL_DIST0; >> + culldistance->data.explicit_index = 0; >> + >> + ir.push_tail(culldistance); >> + >> + ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, >> + &ir, >> + consumer_inputs, >> + consumer_interface_inputs, >> + junk)); >> + >> + EXPECT_EQ(culldistance, junk[VARYING_SLOT_CULL_DIST0]); >> + EXPECT_TRUE(is_empty(consumer_inputs)); >> + EXPECT_TRUE(is_empty(consumer_interface_inputs)); >> +} >> + >> TEST_F(link_varyings, single_interface_input) >> { >> ir_variable *const v >
Timothy Arceri
2015-May-24 23:19 UTC
[Nouveau] [Mesa-dev] [PATCH 07/11] glsl: Add arb_cull_distance support
On Mon, 2015-05-25 at 00:46 +0200, Tobias Klausmann wrote:> hi, > replay inline. > > On 25.05.2015 00:34, Timothy Arceri wrote: > > On Sun, 2015-05-24 at 19:58 +0200, Tobias Klausmann wrote: > >> Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann at mni.thm.de> > >> --- > >> src/glsl/ast_to_hir.cpp | 14 +++++ > >> src/glsl/builtin_variables.cpp | 13 +++- > >> src/glsl/glcpp/glcpp-parse.y | 3 + > >> src/glsl/glsl_parser_extras.cpp | 1 + > >> src/glsl/glsl_parser_extras.h | 3 + > >> src/glsl/link_varyings.cpp | 2 +- > >> src/glsl/linker.cpp | 121 +++++++++++++++++++++++++----------- > >> src/glsl/standalone_scaffolding.cpp | 1 + > >> src/glsl/tests/varyings_test.cpp | 27 ++++++++ > >> 9 files changed, 145 insertions(+), 40 deletions(-) > >> > >> diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp > >> index 8aebb13..4db2b2e 100644 > >> --- a/src/glsl/ast_to_hir.cpp > >> +++ b/src/glsl/ast_to_hir.cpp > >> @@ -1045,6 +1045,20 @@ check_builtin_array_max_size(const char *name, unsigned size, > >> _mesa_glsl_error(&loc, state, "`gl_ClipDistance' array size cannot " > >> "be larger than gl_MaxClipDistances (%u)", > >> state->Const.MaxClipPlanes); > >> + } else if (strcmp("gl_CullDistance", name) == 0 > >> + && size > state->Const.MaxClipPlanes) { > >> + /* From the ARB_cull_distance spec: > >> + * > >> + * "The gl_CullDistance array is predeclared as unsized and > >> + * must be sized by the shader either redeclaring it with > >> + * a size or indexing it only with integral constant > >> + * expressions. The size determines the number and set of > >> + * enabled cull distances and can be at most > >> + * gl_MaxCullDistances." > >> + */ > >> + _mesa_glsl_error(&loc, state, "`gl_CullDistance' array size cannot " > >> + "be larger than gl_MaxCullDistances (%u)", > >> + state->Const.MaxClipPlanes); > >> } > >> } > >> > >> diff --git a/src/glsl/builtin_variables.cpp b/src/glsl/builtin_variables.cpp > >> index 6806aa1..78c8db2 100644 > >> --- a/src/glsl/builtin_variables.cpp > >> +++ b/src/glsl/builtin_variables.cpp > >> @@ -298,7 +298,7 @@ public: > >> const glsl_type *construct_interface_instance() const; > >> > >> private: > >> - glsl_struct_field fields[10]; > >> + glsl_struct_field fields[11]; > >> unsigned num_fields; > >> }; > >> > >> @@ -600,6 +600,12 @@ builtin_variable_generator::generate_constants() > >> add_const("gl_MaxVaryingComponents", state->ctx->Const.MaxVarying * 4); > >> } > >> > >> + if (state->is_version(450, 0) || state->ARB_cull_distance_enable) { > >> + add_const("gl_MaxCullDistances", state->Const.MaxClipPlanes); > >> + add_const("gl_MaxCombinedClipAndCullDistances", > >> + state->Const.MaxClipPlanes); > >> + } > >> + > >> if (state->is_version(150, 0)) { > >> add_const("gl_MaxVertexOutputComponents", > >> state->Const.MaxVertexOutputComponents); > >> @@ -1029,6 +1035,11 @@ builtin_variable_generator::generate_varyings() > >> "gl_ClipDistance"); > >> } > >> > >> + if (state->is_version(450, 0) || state->ARB_cull_distance_enable) { > >> + ADD_VARYING(VARYING_SLOT_CULL_DIST0, array(float_t, 0), > >> + "gl_CullDistance"); > >> + } > >> + > >> if (compatibility) { > >> ADD_VARYING(VARYING_SLOT_TEX0, array(vec4_t, 0), "gl_TexCoord"); > >> ADD_VARYING(VARYING_SLOT_FOGC, float_t, "gl_FogFragCoord"); > >> diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y > >> index a11b6b2..536c17f 100644 > >> --- a/src/glsl/glcpp/glcpp-parse.y > >> +++ b/src/glsl/glcpp/glcpp-parse.y > >> @@ -2483,6 +2483,9 @@ _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t versio > >> > >> if (extensions->ARB_shader_precision) > >> add_builtin_define(parser, "GL_ARB_shader_precision", 1); > >> + > >> + if (extensions->ARB_cull_distance) > >> + add_builtin_define(parser, "GL_ARB_cull_distance", 1); > >> } > >> } > >> > >> diff --git a/src/glsl/glsl_parser_extras.cpp b/src/glsl/glsl_parser_extras.cpp > >> index 046d5d7..d1cd8ff 100644 > >> --- a/src/glsl/glsl_parser_extras.cpp > >> +++ b/src/glsl/glsl_parser_extras.cpp > >> @@ -554,6 +554,7 @@ static const _mesa_glsl_extension _mesa_glsl_supported_extensions[] = { > >> EXT(ARB_arrays_of_arrays, true, false, ARB_arrays_of_arrays), > >> EXT(ARB_compute_shader, true, false, ARB_compute_shader), > >> EXT(ARB_conservative_depth, true, false, ARB_conservative_depth), > >> + EXT(ARB_cull_distance, true, false, ARB_cull_distance), > >> EXT(ARB_derivative_control, true, false, ARB_derivative_control), > >> EXT(ARB_draw_buffers, true, false, dummy_true), > >> EXT(ARB_draw_instanced, true, false, ARB_draw_instanced), > >> diff --git a/src/glsl/glsl_parser_extras.h b/src/glsl/glsl_parser_extras.h > >> index 9a0c24e..8572905 100644 > >> --- a/src/glsl/glsl_parser_extras.h > >> +++ b/src/glsl/glsl_parser_extras.h > >> @@ -378,6 +378,7 @@ struct _mesa_glsl_parse_state { > >> > >> /* ARB_viewport_array */ > >> unsigned MaxViewports; > >> + > >> } Const; > >> > >> /** > >> @@ -430,6 +431,8 @@ struct _mesa_glsl_parse_state { > >> bool ARB_compute_shader_warn; > >> bool ARB_conservative_depth_enable; > >> bool ARB_conservative_depth_warn; > >> + bool ARB_cull_distance_enable; > >> + bool ARB_cull_distance_warn; > >> bool ARB_derivative_control_enable; > >> bool ARB_derivative_control_warn; > >> bool ARB_draw_buffers_enable; > >> diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp > >> index 46f84c6..81c0dac 100644 > >> --- a/src/glsl/link_varyings.cpp > >> +++ b/src/glsl/link_varyings.cpp > >> @@ -404,7 +404,7 @@ tfeedback_decl::assign_location(struct gl_context *ctx, > >> this->matched_candidate->type->fields.array->vector_elements; > >> unsigned actual_array_size > >> (this->is_clip_distance_mesa || this->is_cull_distance_mesa) ? > >> - prog->LastClipDistanceArraySize : > >> + prog->LastClipCullDistanceArraySize : > >> this->matched_candidate->type->array_size(); > >> > >> if (this->is_subscripted) { > >> diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp > >> index e616520..8bb1a5c 100644 > >> --- a/src/glsl/linker.cpp > >> +++ b/src/glsl/linker.cpp > >> @@ -474,49 +474,94 @@ link_invalidate_variable_locations(exec_list *ir) > >> } > >> > >> > >> + > >> /** > >> - * Set UsesClipDistance and ClipDistanceArraySize based on the given shader. > >> + * Set UsesClipCullDistance and ClipCullDistanceArraySize based on the given > >> + * shader. > >> * > >> - * Also check for errors based on incorrect usage of gl_ClipVertex and > >> - * gl_ClipDistance. > >> + * Also check for errors based on incorrect usage of gl_ClipVertex, > >> + * gl_ClipDistance and gl_CullDistance. > >> + * > >> + * Additionally test whether the arrays gl_ClipDistance and gl_CullDistance > >> + * exceed the maximum size defined by gl_MaxCombinedClipAndCullDistances. > >> * > >> * Return false if an error was reported. > >> */ > >> static void > >> -analyze_clip_usage(struct gl_shader_program *prog, > >> - struct gl_shader *shader, GLboolean *UsesClipDistance, > >> - GLuint *ClipDistanceArraySize) > >> +analyze_clip_cull_usage(struct gl_shader_program *prog, > >> + struct gl_shader *shader, > >> + struct gl_context *ctx, > >> + GLboolean *UsesClipCullDistance, > >> + GLuint *ClipCullDistanceArraySize) > >> { > >> - *ClipDistanceArraySize = 0; > >> + *ClipCullDistanceArraySize = 0; > >> > >> - if (!prog->IsES && prog->Version >= 130) { > >> - /* From section 7.1 (Vertex Shader Special Variables) of the > >> - * GLSL 1.30 spec: > >> - * > >> - * "It is an error for a shader to statically write both > >> - * gl_ClipVertex and gl_ClipDistance." > >> - * > >> - * This does not apply to GLSL ES shaders, since GLSL ES defines neither > >> - * gl_ClipVertex nor gl_ClipDistance. > >> - */ > >> + if (prog->IsES && prog->Version < 130) { > >> + *UsesClipCullDistance = false; > >> + } else { > >> find_assignment_visitor clip_vertex("gl_ClipVertex"); > >> find_assignment_visitor clip_distance("gl_ClipDistance"); > >> + find_assignment_visitor cull_distance("gl_CullDistance"); > >> > >> clip_vertex.run(shader->ir); > >> clip_distance.run(shader->ir); > >> + cull_distance.run(shader->ir); > >> + > >> + /* From the ARB_cull_distance spec: > >> + * > >> + * It is a compile-time or link-time error for the set of shaders forming > >> + * a program to statically read or write both gl_ClipVertex and either > >> + * gl_ClipDistance or gl_CullDistance. > >> + * > >> + * This does not apply to GLSL ES shaders, since GLSL ES defines neither > >> + * gl_ClipVertex, gl_ClipDistance or gl_CullDistance. > >> + */ > >> if (clip_vertex.variable_found() && clip_distance.variable_found()) { > >> linker_error(prog, "%s shader writes to both `gl_ClipVertex' " > >> "and `gl_ClipDistance'\n", > >> _mesa_shader_stage_to_string(shader->Stage)); > >> return; > >> } > >> - *UsesClipDistance = clip_distance.variable_found(); > >> + if (clip_vertex.variable_found() && cull_distance.variable_found()) { > >> + linker_error(prog, "%s shader writes to both `gl_ClipVertex' " > >> + "and `gl_CullDistance'\n", > >> + _mesa_shader_stage_to_string(shader->Stage)); > >> + return; > >> + } > >> + > >> + *UsesClipCullDistance = clip_distance.variable_found() | > >> + cull_distance.variable_found(); > >> + > >> ir_variable *clip_distance_var > >> shader->symbols->get_variable("gl_ClipDistance"); > >> + ir_variable *cull_distance_var > >> + shader->symbols->get_variable("gl_CullDistance"); > >> + > >> if (clip_distance_var) > >> - *ClipDistanceArraySize = clip_distance_var->type->length; > >> - } else { > >> - *UsesClipDistance = false; > >> + *ClipCullDistanceArraySize = clip_distance_var->type->was_unsized ? > >> + clip_distance_var->type->length -1 : > >> + clip_distance_var->type->length; > >> + > >> + if (cull_distance_var) > >> + *ClipCullDistanceArraySize+= cull_distance_var->type->was_unsized ? > >> + cull_distance_var->type->length -1 : > >> + cull_distance_var->type->length; > > > > How come this needs to be done for former unsized arrays? > > > > We replace an unsized array with a default size of 1 ( fixup_type() ) , > so with either cull or clip set to max (8) and the other array left > unsized we would end up with a total of 9 reported, that would trigger > the error below.I see. Is there a piglit test for this? I couldn't find it but I may be blind. I take it the Nvidia driver passes in this case? Wouldn't you only want the test below to pass if the unsized cull or clip is unused? If it defaults to 1 (or is resized to 1) and its used then isn't it valid for this to fail?> > > > >> + > >> + /* From the ARB_cull_distance spec: > >> + * > >> + * It is a compile-time or link-time error for the set of shaders forming > >> + * a program to have the sum of the sizes of the gl_ClipDistance and > >> + * gl_CullDistance arrays to be larger than > >> + * gl_MaxCombinedClipAndCullDistances. > >> + */ > >> + if (*ClipCullDistanceArraySize > ctx->Const.MaxClipPlanes) { > >> + linker_error(prog, "%s shader: the combined size of " > >> + "'gl_ClipDistance' and 'gl_CullDistance' size cannot " > >> + "be larger than " > >> + "gl_MaxCombinedClipAndCullDistances (%u)", > >> + _mesa_shader_stage_to_string(shader->Stage), > >> + ctx->Const.MaxClipPlanes); > >> + } > >> } > >> } > >> > >> @@ -524,14 +569,14 @@ analyze_clip_usage(struct gl_shader_program *prog, > >> /** > >> * Verify that a vertex shader executable meets all semantic requirements. > >> * > >> - * Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize > >> - * as a side effect. > >> + * Also sets prog->Vert.UsesClipCullDistance and > >> + * prog->Vert.ClipCullDistanceArraySize as a side effect. > >> * > >> * \param shader Vertex shader executable to be verified > >> */ > >> void > >> validate_vertex_shader_executable(struct gl_shader_program *prog, > >> - struct gl_shader *shader) > >> + struct gl_shader *shader, struct gl_context *ctx) > >> { > >> if (shader == NULL) > >> return; > >> @@ -578,8 +623,8 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, > >> } > >> } > >> > >> - analyze_clip_usage(prog, shader, &prog->Vert.UsesClipDistance, > >> - &prog->Vert.ClipDistanceArraySize); > >> + analyze_clip_cull_usage(prog, shader, ctx, &prog->Vert.UsesClipCullDistance, > >> + &prog->Vert.ClipCullDistanceArraySize); > >> } > >> > >> > >> @@ -590,7 +635,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, > >> */ > >> void > >> validate_fragment_shader_executable(struct gl_shader_program *prog, > >> - struct gl_shader *shader) > >> + struct gl_shader *shader, struct gl_context *ctx) > >> { > >> if (shader == NULL) > >> return; > >> @@ -610,14 +655,14 @@ validate_fragment_shader_executable(struct gl_shader_program *prog, > >> /** > >> * Verify that a geometry shader executable meets all semantic requirements > >> * > >> - * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipDistance, and > >> - * prog->Geom.ClipDistanceArraySize as a side effect. > >> + * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipCullDistance, and > >> + * prog->Geom.ClipCullDistanceArraySize as a side effect. > >> * > >> * \param shader Geometry shader executable to be verified > >> */ > >> void > >> validate_geometry_shader_executable(struct gl_shader_program *prog, > >> - struct gl_shader *shader) > >> + struct gl_shader *shader, struct gl_context *ctx) > >> { > >> if (shader == NULL) > >> return; > >> @@ -625,8 +670,8 @@ validate_geometry_shader_executable(struct gl_shader_program *prog, > >> unsigned num_vertices = vertices_per_prim(prog->Geom.InputType); > >> prog->Geom.VerticesIn = num_vertices; > >> > >> - analyze_clip_usage(prog, shader, &prog->Geom.UsesClipDistance, > >> - &prog->Geom.ClipDistanceArraySize); > >> + analyze_clip_cull_usage(prog, shader, ctx, &prog->Geom.UsesClipCullDistance, > >> + &prog->Geom.ClipCullDistanceArraySize); > >> } > >> > >> /** > >> @@ -2834,13 +2879,13 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) > >> > >> switch (stage) { > >> case MESA_SHADER_VERTEX: > >> - validate_vertex_shader_executable(prog, sh); > >> + validate_vertex_shader_executable(prog, sh, ctx); > >> break; > >> case MESA_SHADER_GEOMETRY: > >> - validate_geometry_shader_executable(prog, sh); > >> + validate_geometry_shader_executable(prog, sh, ctx); > >> break; > >> case MESA_SHADER_FRAGMENT: > >> - validate_fragment_shader_executable(prog, sh); > >> + validate_fragment_shader_executable(prog, sh, ctx); > >> break; > >> } > >> if (!prog->LinkStatus) > >> @@ -2851,11 +2896,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) > >> } > >> > >> if (num_shaders[MESA_SHADER_GEOMETRY] > 0) > >> - prog->LastClipDistanceArraySize = prog->Geom.ClipDistanceArraySize; > >> + prog->LastClipCullDistanceArraySize = prog->Geom.ClipCullDistanceArraySize; > >> else if (num_shaders[MESA_SHADER_VERTEX] > 0) > >> - prog->LastClipDistanceArraySize = prog->Vert.ClipDistanceArraySize; > >> + prog->LastClipCullDistanceArraySize = prog->Vert.ClipCullDistanceArraySize; > >> else > >> - prog->LastClipDistanceArraySize = 0; /* Not used */ > >> + prog->LastClipCullDistanceArraySize = 0; /* Not used */ > >> > >> /* Here begins the inter-stage linking phase. Some initial validation is > >> * performed, then locations are assigned for uniforms, attributes, and > >> diff --git a/src/glsl/standalone_scaffolding.cpp b/src/glsl/standalone_scaffolding.cpp > >> index a109c4e..0ac16bb 100644 > >> --- a/src/glsl/standalone_scaffolding.cpp > >> +++ b/src/glsl/standalone_scaffolding.cpp > >> @@ -142,6 +142,7 @@ void initialize_context_to_defaults(struct gl_context *ctx, gl_api api) > >> ctx->Extensions.ARB_texture_query_lod = true; > >> ctx->Extensions.ARB_uniform_buffer_object = true; > >> ctx->Extensions.ARB_viewport_array = true; > >> + ctx->Extensions.ARB_cull_distance = true; > >> > >> ctx->Extensions.OES_EGL_image_external = true; > >> ctx->Extensions.OES_standard_derivatives = true; > >> diff --git a/src/glsl/tests/varyings_test.cpp b/src/glsl/tests/varyings_test.cpp > >> index 4573529..7a962c5 100644 > >> --- a/src/glsl/tests/varyings_test.cpp > >> +++ b/src/glsl/tests/varyings_test.cpp > >> @@ -202,6 +202,33 @@ TEST_F(link_varyings, gl_ClipDistance) > >> EXPECT_TRUE(is_empty(consumer_interface_inputs)); > >> } > >> > >> +TEST_F(link_varyings, gl_CullDistance) > >> +{ > >> + const glsl_type *const array_8_of_float > >> + glsl_type::get_array_instance(glsl_type::vec(1), 8); > >> + > >> + ir_variable *const culldistance > >> + new(mem_ctx) ir_variable(array_8_of_float, > >> + "gl_CullDistance", > >> + ir_var_shader_in); > >> + > >> + culldistance->data.explicit_location = true; > >> + culldistance->data.location = VARYING_SLOT_CULL_DIST0; > >> + culldistance->data.explicit_index = 0; > >> + > >> + ir.push_tail(culldistance); > >> + > >> + ASSERT_TRUE(linker::populate_consumer_input_sets(mem_ctx, > >> + &ir, > >> + consumer_inputs, > >> + consumer_interface_inputs, > >> + junk)); > >> + > >> + EXPECT_EQ(culldistance, junk[VARYING_SLOT_CULL_DIST0]); > >> + EXPECT_TRUE(is_empty(consumer_inputs)); > >> + EXPECT_TRUE(is_empty(consumer_interface_inputs)); > >> +} > >> + > >> TEST_F(link_varyings, single_interface_input) > >> { > >> ir_variable *const v > > >