When lower_named_interface_blocks lowers a built-in interface block
member to an ir_variable, it needs to set explicit_location in the
ir_variable. Otherwise the linker gets confused and treats the
variable as a generic varying.
Fixes the following piglit tests, which were regressed by commit
63974c0 (glsl: Simplify the interface to
link_invalidate_variable_locations):
- clip-distance-bulk-copy
- clip-distance-in-bulk-read
- clip-distance-in-explicitly-sized
- clip-distance-in-param
- clip-distance-in-values
- core-inputs
- gs-redeclares-both-pervertex-blocks
- gs-redeclares-pervertex-in-only
- redeclare-pervertex-subset-vs-to-gs
- unsized-in-named-interface-block-gs
- unsized-in-named-interface-block-multiple
- unsized-in-unnamed-interface-block-gs
- unsized-in-unnamed-interface-block-multiple
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70820
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Since gl_ClipDistance is lowered from an array of floats to an array
of vec4's during compilation, transform feedback has special logic to
keep track of the pre-lowered array size so that attempting to perform
transform feedback on gl_ClipDistance produces a result with the
correct size.
Previously, this special logic always consulted the vertex shader's
size for gl_ClipDistance. This patch fixes it so that it uses the
geometry shader's size for gl_ClipDistance when a geometry shader is
in use.
Fixes piglit test spec/glsl-1.50/transform-feedback-type-and-size.
v2: Change the type of LastClipDistanceArraySize to "unsigned", and
clarify the comment above it.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
From the GLSL 1.50 spec, section 4.3.8.1 (Input Layout Qualifiers):
The layout qualifier identifiers for geometry shader inputs are
layout-qualifier-id
points
lines
lines_adjacency
triangles
triangles_adjacency
And from section 4.3.8.2 (Output Layout Qualifiers)
The layout qualifier identifiers for geometry shader outputs are
layout-qualifier-id
points
line_strip
triangle_strip
max_vertices = integer-constant
We were erroneously allowing line_strip and triangle_strip to be used
as input qualifiers, and we were allowing lines, lines_adjacency,
triangles, and triangles_adjacency to be used as output qualifiers.
Fixes piglit tests "glsl-1.50-gs-{input,output}-layout-qualifiers *".
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
The unit tests added in the previous commits prove some things about the
state of some internal data structures. The most important of these is
that all built-in input and output variables have explicit_location
set. This means that link_invalidate_variable_locations doesn't need to
know the range of non-generic shader inputs or outputs. It can simply
reset location state depending on whether explicit_location is set.
There are two additional assumptions that were already implicit in the
code that comments now document.
- ir_variable::is_unmatched_generic_inout is only used by the linker
when connecting outputs from one shader stage to inputs of another
shader stage.
- Any varying that has explicit_location set must be a built-in. This
will be true until GL_ARB_separate_shader_objects is supported.
As a result, the input_base and output_base parameters to
link_invalidate_variable_locations are no longer necessary, and the code
for resetting locations and setting is_unmatched_generic_inout can be
simplified.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Validates:
- ir_variable::explicit_location should not be modified.
- If ir_variable::explicit_location is not set, ir_variable::location,
ir_variable::location_frac, and
ir_variable::is_unmatched_generic_inout must be reset to 0.
- If ir_variable::explicit_location is set, ir_variable::location
should not be modified. ir_variable::location_frac, and
ir_variable::is_unmatched_generic_inout must be reset to 0.
Previous unit tests have shown that all non-generic inputs / outputs
have explicit_location set.
v2: Split the link_invalidate_variable_locations interface change out to
a separate patch. Remove the vertex_in_builtin_without_explicit and
vertex_out_builtin_without_explicit tests. There was a lot of good
discussion about this on the mailing list to which I refer the
interested reader. Both changes suggested by Paul.
http://lists.freedesktop.org/archives/mesa-dev/2013-October/046652.html
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
This will make it easier to unit test this function in successive
patches. Also, correct the prototype in linker.h. It was... wrong.
v2: Split the interface change from adding the unit tests. Suggested by
Paul.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Checks that the variables generated meet certain criteria.
- Geometry shader inputs have an explicit location.
- Geometry shader outputs have an explicit location.
- Fragment shader-only varying locations are not used.
- Geometry shader uniforms and system values don't have an explicit
location.
- Geometry shader constants don't have an explicit location and are
read-only.
- No other kinds of geometry variables exist.
It does not verify that an specific variables exist.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Checks that the variables generated meet certain criteria.
- Fragment shader inputs have an explicit location.
- Fragment shader outputs have an explicit location.
- Vertex / geometry shader-only varying locations are not used.
- Fragment shader uniforms and system values don't have an explicit
location.
- Fragment shader constants don't have an explicit location and are
read-only.
- No other kinds of fragment variables exist.
It does not verify that an specific variables exist.
v2: Use _mesa_varying_slot_in_fs in
fragment_builtin.inputs_have_explicit_location. Suggested by Paul.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Checks that the variables generated meet certain criteria.
- Vertex shader inputs have an explicit location.
- Vertex shader outputs have an explicit location.
- Fragment shader-only varying locations are not used.
- Vertex shader uniforms and system values don't have an explicit
location.
- Vertex shader constants don't have an explicit location and are
read-only.
- No other kinds of vertex variables exist.
It does not verify that an specific variables exist.
v2: Fix memory management mistakes in
common_builtin::string_starts_with_prefix. Clean up error message
reporting in common_builtin::no_invalid_variable_modes. Both suggested
by Paul.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Ever since the addition of interface blocks with instance names, we have
had an implicit invariant:
var->type->is_interface() ==
(var->type == var->interface_type)
The odd use of == here is intentional because !var->type->is_interface()
implies var->type != var->interface_type.
Further, if var->type->is_array() is true, we have a related implicit
invariant:
var->type->fields.array->is_interface() ==
(var->type->fields.array == var->interface_type)
However, the ir_variable constructor doesn't maintain either invariant.
That seems kind of silly... and I tripped over it while writing some
other code. This patch makes the constructor do the right thing, and it
introduces some tests to verify that behavior.
v2: Add general-ir-test to .gitignore. Update the description of the
ir_variable invariant for arrays in the commit message. Both suggested
by Paul.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Paul Berry <stereotype441@gmail.com>
Previously, Mesa followed the linkage rules outlined in the GLSL
1.20-1.40 specs, which (collectively) said that GLSL versions 1.10 and
1.20 could be linked together, but no other versions could be linked.
In GLSL 4.30, the linkage rules were relaxed so that any two desktop
GLSL versions can be linked together. This change was made because it
reflected the behaviour of nearly all existing implementations (see
Khronos bug 8463). Mesa was one of the few (perhaps the only)
exceptions to prohibit cross-linking of some GLSL versions.
Since the GLSL linkage rules were deliberately relaxed in order to
match the behaviour of existing implementations, it seems appropriate
to relax the rules in Mesa too (even though Mesa doesn't support GLSL
4.30 yet).
Note that linking ES and desktop shaders is still prohibited, as is
linking ES shaders having different GLSL versions.
Fixes piglit tests "shaders/version-mixing {interstage,intrastage}".
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
In commit f878d20 (glsl: Update ir_variable::max_ifc_array_access
properly), I accidentally used the wrong kind of check to determine
whether the variable being accessed was an interface instance (I used
var->get_interface_type() != NULL when I should have used
var->is_interface_instance()). As a result, if an unnamed interface
block contained a struct which contained an array,
update_max_array_access() would mistakenly interpret the struct as a
named interface block and try to dereference a null
var->max_ifc_array_access.
This patch corrects the check, fixing the null dereference.
Fixes piglit test interface-block-struct-nesting.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70368
Reviewed-by: Matt Turner <mattst88@gmail.com>
In desktop GLSL, location qualifiers are case-insensitive. In GLSL
ES, they are case-sensitive. This patch handles the difference by
using a new function to match layout qualifiers,
match_layout_qualifier(), which calls either strcmp() or strcasecmp()
as appropriate.
Fixes piglit tests:
- layout-not-case-sensitive-in.geom
- layout-not-case-sensitive-max-vert.geom
- layout-not-case-sensitive-out.geom
- layout-not-case-sensitive.frag
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Two extra instructions in some heroesofnewerth shaders, but a win for
everything else.
total instructions in shared programs: 1531352 -> 1530815 (-0.04%)
instructions in affected programs: 121898 -> 121361 (-0.44%)
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This patch populates the following built-in GLSL 1.50 variables based
on constants stored in ctx->Const:
- gl_MaxVertexOutputComponents
- gl_MaxGeometryInputComponents
- gl_MaxGeometryOutputComponents
- gl_MaxFragmentInputComponents
- gl_MaxGeometryTextureImageUnits
- gl_MaxGeometryOutputVertices
- gl_MaxGeometryTotalOutputComponents
- gl_MaxGeometryUniformComponents
- gl_MaxGeometryVaryingComponents
On i965/gen7, fixes all Piglit tests in "spec/glsl-1.50/built-in
constants/*" except for gl_MaxCombinedTextureImageUnits and
gl_MaxGeometryUniformComponents.
Reviewed-by: Matt Turner <mattst88@gmail.com>
This was overriding the top-level .dir-locals.el causing some settings
(like forcing spaces instead of tabs!) to be lost.
Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
From section 4.1.9 (Arrays) of the GLSL 4.40 spec (as of revision 7):
However, unless noted otherwise, blocks cannot be redeclared;
an unsized array in a user-declared block cannot be sized
through redeclaration.
The only place where the spec notes that interface blocks can be
redeclared is to allow for redeclaration of built-in interface blocks
such as gl_PerVertex. Therefore, user-defined interface blocks can
never be redeclared. This is a clarification of previous intent (see
Khronos bug 10659).
We were already preventing interface block redeclaration using the
same block name at compile time, but we weren't preventing interface
block redeclaration using the same instance name (and different block
names) at compile time. And we weren't preventing an instance name
from conflicting with a previously-declared ordinary variable.
In practice the problem would be caught at link time, but only because
of a coincidence: since ast_interface_block::hir() wasn't doing any
checking to see if the instance name already existed in the shader, it
was creating a second ir_variable in the shader having the same name
but a different type. Coincidentally, when the linker checked for
intrastage consistency of global variable declarations, it treated the
two declarations from the same shader as a conflict, so it reported a
link error.
But it seems dangerous to rely on that linker behaviour to catch
illegal redeclarations that really ought to be detected at compile
time.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This patch verifies that:
- The gl_PerVertex input interface block may only be redeclared in a
geometry shader, and that it may only be redeclared as gl_in[].
- The gl_PerVertex output interface block may only be redeclared in a
vertex or geometry shader, and that it may only be redeclared as a
non-array without an interface name.
- gl_PerVertex may not be redeclared as any other type of interface
block (i.e. as a uniform interface block).
As a side-effect, the code now keeps track of what the previous
declaration of gl_PerVertex was--this will be needed in future
patches.
Fixes piglit tests:
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-in-with-incorrect-name.geom
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-as-array.geom
- spec/glsl-1.50/compiler/gs-redeclares-pervertex-out-with-instance-name.geom
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
In later patches, we'll use this in order to implement the required
behaviour that after the gl_PerVertex interface block has been
redeclared, only members of the redeclared interface block may be
used.
v2: Update the function name and comment to clarify that we aren't
actually removing the variable from the symbol table, just disabling
it.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This will be used by future patches to change an ir_variable's
interface type when the gl_PerVertex built-in interface block is
redeclared.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This patch modifies the get_variable_being_redeclared() function so
that it no longer relies on the ast_declaration for the variable being
redeclared. In future patches, this will allow
get_variable_being_redeclared() to be used for processing
redeclarations of the built-in gl_PerVertex interface block.
v2: Also make get_variable_being_redeclared() static.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Note: we need to make an exception for the gl_PerVertex interface
block, since in geometry shaders it is allowed to be redeclared with
the instance name gl_in. Future patches will make redeclaration of
gl_PerVertex work properly.
Fixes piglit test
spec/glsl-1.50/compiler/interface-block-instance-name-uses-gl-prefix.vert.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Note: we need to make an exception for the gl_PerVertex interface
block, since built-in variables are allowed to be redeclared inside
it. Future patches will make redeclaration of gl_PerVertex work
properly.
Fixes piglit tests:
- spec/glsl-1.50/compiler/interface-block-array-elem-uses-gl-prefix.vert
- spec/glsl-1.50/compiler/named-interface-block-elem-uses-gl-prefix.vert
- spec/glsl-1.50/compiler/unnamed-interface-block-elem-uses-gl-prefix.vert
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Note: we need to make an exception for the gl_PerVertex interface
block, since this is allowed to be redeclared. Future patches will
make redeclaration of gl_PerVertex work properly.
Fixes piglit test
spec/glsl-1.50/compiler/interface-block-name-uses-gl-prefix.vert.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Note: some limited amount of redeclaration is actually allowed,
provided the shader is redeclaring the built-in gl_PerVertex interface
block. Support for this will be added in future patches.
Fixes piglit tests
spec/glsl-1.50/compiler/unnamed-interface-block-elem-conflicts-with-prev-{block-elem,global}.vert.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
GLSL reserves identifiers beginning with "gl_" or containing "__", but
we haven't been consistent about enforcing this rule. This patch
makes a new function to check whether identifier names are valid. In
the process it closes a loophole where we would previously allow
function argument names to contain "__".
v2: Rename check_valid_identifier() -> validate_identifier(). Add
curly braces in validate_identifier().
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
In commit e2660770731b018411fbe1620cacddaf8dff5287 (glsl: Keep track
of location for interface block fields), I neglected to update
glsl_type::record_key_compare to account for the fact that interface
types now contain location information. As a result, interface types
that differ only by their location information would not be properly
distinguished.
At the moment this is not a problem, because the only interface block
in which location information != -1 is gl_PerVertex, and gl_PerVertex
is always created in the same way. However, in the patches that
follow, we'll be adding new ways to create gl_PerVertex (by
redeclaring it), so we'll need location information to be handled
properly.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Although these interfaces can't be accessed directly by GLSL (since
they don't have an instance name), they will be necessary in order to
allow redeclarations of gl_PerVertex.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Currently, we create just a single gl_PerVertex interface block for
geometry shader inputs. In later patches, we'll also need to create
an interface block for geometry and vertex shader outputs. Moving the
code into its own class will make reuse easier.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Previously, we erroneously used the name "gl_in" for both the block
name and the instance name.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
We use a location of -1 for variables which don't have their own
assigned locations--this includes ir_variables which represent named
interface blocks. Technically the location assigned to gl_in doesn't
matter, since gl_in is only accessed via its members (which have their
own locations). But it's nice to be consistent.
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
We were already setting the array size of unsized arrays that appeared
inside unnamed interface blocks, but we weren't updating
ir_variable::interface_type to reflect the new array size, causing
bogus link errors.
This patch causes array_sizing_visitor to keep track of all the
unnamed interface types it sees, and the ir_variables corresponding to
each one. After the visitor runs, a new function,
fixup_unnamed_interface_types(), adjusts each unnamed interface type
to correctly correspond with the array sizes in the ir_variables.
Fixes piglit tests:
- spec/glsl-1.50/execution/unsized-in-unnamed-interface-block-gs
- spec/glsl-1.50/execution/unsized-in-unnamed-interface-block-multiple
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
When multiple shaders of the same type access an interface block
containing an unsized array, we need to set the array size based on
the maximum array element accessed across all the shaders. This is
similar to what we already do with unsized arrays occurring outside of
interface blocks.
Note: one corner case is not yet addressed by these patches: the case
where one compilation unit defines an interface block containing
unsized arrays and another compilation unit defines the same interface
block containing sized arrays.
Fixes piglit test:
- spec/glsl-1.50/execution/unsized-in-named-interface-block-multiple
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Unsized arrays appearing inside named interface blocks now get a
proper size assigned by the array_sizing_visitor.
Fixes piglit tests:
- spec/glsl-1.50/execution/unsized-in-named-interface-block
- spec/glsl-1.50/execution/unsized-in-named-interface-block-gs
- spec/glsl-1.50/linker/unsized-in-named-interface-block
- spec/glsl-1.50/linker/unsized-in-named-interface-block-gs
- spec/glsl-1.50/linker/unsized-in-unnamed-interface-block-gs (*)
(*) is fixed by dumb luck--support for unsized arrays in unnamed
interface blocks will come in a later patch.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
This patch modifies update_max_array_access() so that it updates
ir_variable::max_ifc_array_access to reflect the shader's use of
arrays appearing within interface blocks.
v2: Use an ordinary function in ast_array_index.cpp rather than a
virtual function in ir_rvalue. Avoid dereferencing NULL when handling
accesses to ordinary structs.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
For interface blocks that contain arrays, this field will contain the
maximum element of each contained array that is accessed by the
shader. This is a first step toward supporting unsized arrays in
interface blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Currently, when converting an access to an array element from ast to
IR, we need to see if the array is an ir_dereference_variable, and if
so update the variable's max_array_access.
When we add support for unsized arrays in interface blocks, we'll also
need to account for cases where the array is an ir_dereference_record
and the record is an interface block.
To make this easier, move the update into its own function.
v2: Use an ordinary function in ast_array_index.cpp rather than a
virtual function in ir_rvalue.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>