Commit graph

3947 commits

Author SHA1 Message Date
Samuel Iglesias Gonsalvez
5b080e3ddf mesa: enable ARB_shader_storage_buffer_object extension for GLES 3.1
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Samuel Iglesias Gonsalvez
9b477ad49d main: Add SHADER_STORAGE_BLOCK and BUFFER_VARIABLE support for ARB_program_interface_query
Including TOP_LEVEL_ARRAY_SIZE and TOP_LEVEL_ARRAY_STRIDE queries.

v2:
- Use std430_array_stride() to get top level array stride following std430's rules.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Iago Toral Quiroga
0f18945cb6 glsl: Do not allow reads from write-only buffer variables
The error location won't be right, but fixing that would require to check
for this as we process each type of AST node that can involve a variable
read.

v2:
  - Limit the check to buffer variables, image variables have different
    semantics involved.

Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Iago Toral Quiroga
995a719499 glsl: Do not allow assignments to read-only buffer variables
v2:
  - Merge the error check for the readonly qualifier with the already
    existing check for variables flagged as readonly (Timothy).
  - Limit the check to buffer variables, image variables have different
    semantics involved (Curro).

Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Samuel Iglesias Gonsalvez
6ef82f039c glsl: Allow memory qualifiers on shader storage buffer blocks
v2:
  - Memory qualifiers on shader storage buffer objects do not come in the form
    of layout qualifiers, they are block-level qualifiers.

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Iago Toral Quiroga
f1b647fdd1 glsl: Apply memory qualifiers to buffer variables
v2:
  - Save memory qualifier info in the top level members of a shader
    storage block.
  - Add a checks to record_compare() which is used when comparing
    shader storage buffer declarations in different shaders.
  - Always report an error for incompatible readonly/writeonly
    definitions, whether they are present at block or field level.

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Iago Toral Quiroga
f4c8c01a3d glsl: Allow use of memory qualifiers with ARB_shader_storage_buffer_object.
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Iago Toral Quiroga
a07d0c2657 glsl: First argument to atomic functions must be a buffer variable
v2:
  - Add ssbo_in the names of the static functions so it is clear that this
    is specific to SSBO atomics.

v3:
  - Move the check after the loop (Kristian Høgsberg)

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Iago Toral Quiroga
9d5c0be5d5 nir: Implement lowered SSBO atomic intrinsics
The original GLSL IR intrinsics have been lowered to an internal
version that accepts a block index and an offset instead of a
SSBO reference.

v2 (Connor):
  - Document the sources used by the atomic intrinsics.

Reviewed-by: Connor Abbott <connor.w.abbott@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:23 +02:00
Iago Toral Quiroga
d2719b6e4f glsl: lower SSBO atomic intrinsics
The first argument to SSBO atomics is a reference to a SSBO buffer variable
so we want to compute its block index and offset and provide these values
to an internal version of the intrinsic that takes them instead of the
buffer variable reference.

v2:
- Support single components of integer vectors to be passed in as arguments.
- Get interface packing information from interface's type.

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
da659087b9 glsl: use ir_rvalue instead of ir_dereference in auxiliary functions
In a later commit we will need to handle ir_swizzle nodes too, which are
not an ir_dereference. That can happen, for example, when we pass a
component of an integer vector as argument to any of the SSBO atomic
functions.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Iago Toral Quiroga
ea0a1f5beb glsl: Add atomic functions from ARB_shader_storage_buffer_object
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Iago Toral Quiroga
2cacebaad3 glsl: Rename atomic counter functions
Shader Storage Buffer Object will add new atomic functions that are not
associated with counters, so better have atomic counter-specific functions
explicitly include the word "counter" in their names.

Reviewed-by: Timothy Arceri <t_arceri@yahoo.com.au>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
586142658e glsl: atomic counters can be declared as buffer-qualified variables
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Iago Toral Quiroga
475d9c32d1 nir/glsl_to_nir: ignore an instruction's dest if it hasn't any
Reviewed-by: Connor Abbott <connor.w.abbott@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Iago Toral Quiroga
e59ae238b6 nir: Implement __intrinsic_load_ssbo
v2:
- Fix ssbo loads with boolean variables.

v3:
- Simplify the changes (Kristian)

Reviewed-by: Connor Abbott <connor.w.abbott@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
3e70c968de nir: modify the instruction insertion in nir_visitor::visit(ir_call *ir)
This patch moves nir_instr_insert_after_cf_list call into each case
in the intrinsics switch at nir_visitor::visit(ir_call *ir) and
define a nir_dest variable which will be used when handling
ir->return_deref after the switch.

This patch simplifies the code for nir_intrinsic_load_ssbo
implementation changes we are going to do next.

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Iago Toral Quiroga
9bb7d9ecf8 nir: Implement __intrinsic_store_ssbo
v2 (Connor):
 - Make the STORE() macro take arguments for the extra sources (and their
   size) and any extra indices required.

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
203cd1bf28 glsl: shader storage blocks use different max block size values than uniforms
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
eb9a9b62b1 glsl: ignore buffer variables when counting uniform components
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
138e4ae8ae glsl: number of active shader storage blocks must be within allowed limits
Notice that we should differentiate between shader storage blocks and
uniform blocks, since they have different limits.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
a7b4ab45d0 glsl: a shader storage buffer must be smaller than the maximum size allowed
Otherwise, generate a link time error as per the
ARB_shader_storage_buffer_object spec.

v2:
- Fix error message (Jordan)

v3:
- Move std140_size() changes to its own patch (Kristian)

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
e854a98001 glsl: add std430 interface packing support to ssbo related operations
v2:
- Get interface packing information from interface's type, not the
  variable type.
- Simplify is_std430 condition in emit_access() for readability (Jordan)
- Add a commment explaing why array of three-component vector case is
  different in std430 than the rest of cases.
- Add calls to std430_array_stride().

v3:
- Simplify size_mul change for std430's case (Jordan)
- Fix commit log lines length (Jordan)
- Pass 'packing' instead of 'is_std430' to emit_access() (Kristian)

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
1be180b941 glsl: Add std430 support to program_resource_visitor's member functions
They are used to calculate the offset, array stride of uniform/shader
storage buffer variables. Take into account this info to get the right
value for std430.

v2:
- Fix commit log line length and indention. (Jordan)

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
8f0167c65b glsl: Add parser/compiler support for std430 interface packing qualifier
v2:
- Fix a missing check in has_layout()

v3:
- Mention shader storage block in error message for layout qualifiers
  (Kristian).

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:22 +02:00
Samuel Iglesias Gonsalvez
35476c2bae glsl: Add std430 related member functions to glsl_type class
They are used to calculate size, base alignment and array stride values
for a glsl_type following std430 rules.

v2:
- Paste OpenGL 4.3 spec wording as it mentions stride of array. (Jordan)

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
a40f917c4b glsl: allow default qualifiers for shader storage block definitions
This kind of definitions:

    layout(xxx) buffer;

was not supported by commit 84fc5fece0.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
3763a0e0a7 glsl: Move interface block processing to glsl_parser_extras.cpp
No functional changes.

Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
9c1f10b1bc glsl: ignore default qualifier declarations when checking for duplicate layout qualifiers
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
130031168d glsl: layout qualifier can appear more than once since OpenGL 4.20
Also if GL_ARB_shading_language_420pack extension is enabled.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
003ce30e36 nir: Implement ir_unop_get_buffer_size
This is how backends provide the buffer size required to compute
the size of unsized arrays in the previous patch

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
750c694474 glsl: implement unsized array length
v2:
- Reduce the number of lines over 80 character line width
  limit. (Thomas Hellan)

v3:
- Inject the formula to compute the array length in the IR, backends
  only need to provide the buffer size (Curro)
- Create an auxiliary function to simplify code (Jordan Justen)
- Rename variables (Jordan Justen)

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
273f61a005 glsl: Add parser/compiler support for unsized array's length()
The unsized array length is computed with the following formula:

array.length() =
   max((buffer_object_size - offset_of_array) / stride_of_array, 0)

Of these, only the buffer size needs to be provided by the backends, the
frontend already knows the values of the two other variables.

This patch identifies the cases where we need to get the length of an
unsized array, injecting ir_unop_ssbo_unsized_array_length expressions
that will be lowered (in a later patch) to inject the formula mentioned
above.

It also adds the ir_unop_get_buffer_size expression that drivers will
implement to provide the buffer length.

v2:
- Do not define a triop that will force backends to implement the
  entire formula, they should only need to provide the buffer size
  since the other values are known by the frontend (Curro).

v3:
- Call state->has_shader_storage_buffer_objects() in ast_function.cpp instead
  of using state->ARB_shader_storage_buffer_object_enable (Tapani).

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
1440d2a683 glsl: Add unsized array support to glsl_type::std140_size()
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
68f5a4e6d2 glsl: fix indention in glsl_types.cpp
No functional changes.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
f3f64cd0c4 glsl: add support for unsized arrays in shader storage blocks
They only can be defined in the last position of the shader
storage blocks.

When an unsized array is used in different shaders, it might be
converted in different sized arrays, avoid get a linker error
in that case.

v2:
- Rework error condition and error messages (Timothy Arceri)

v3:
- Move OpenGL ES check to its own patch.

Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:21 +02:00
Samuel Iglesias Gonsalvez
f45d39f6af glsl: return error if unsized arrays are found in OpenGL ES
Signed-off-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
2015-09-25 08:39:20 +02:00
Tapani Pälli
4639cea292 glsl: add packed varyings to program resource list
This makes sure that user is still able to query properties about
variables that have gotten packed by lower_packed_varyings pass.

Fixes following OpenGL ES 3.1 test:
   ES31-CTS.program_interface_query.separate-programs-vertex

v2: fix 'name included in packed list' check (Ilia Mirkin)
v3: iterate over instances of name using strtok_r (Ilia Mirkin)

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Marta Lofstedt <marta.lofstedt@intel.com>
2015-09-25 08:14:41 +03:00
Tapani Pälli
a6b55beb78 mesa: add packed_varyings list to gl_shader
This is required to store information about packed varyings, currently
these variables get lost and cannot be retrieved later in sensible way
for program interface queries. List will be utilized by next patch.

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Marta Lofstedt <marta.lofstedt@intel.com>
2015-09-25 08:05:59 +03:00
Matt Turner
d6bb46bbe8 glsl: Expose gl_MaxTess{Control,Evaluation}AtomicCounters.
... with only ARB_shader_atomic_counters.

I expected to see interactions with ARB_tessellation_shader in the
ARB_shader_atomic_counters spec, but they do not exist. It seems that we
should unconditionally expose these variables in the presence of
ARB_shader_atomic_counters:

   gl_MaxTessControlAtomicCounters
   gl_MaxTessEvaluationAtomicCounters

This partially reverts commit da7adb99e8. The commit also affected
gl_MaxTessControlImageUniforms and gl_MaxTessEvaluationImageUniforms
similarly but the ARB_shader_image_load_store spec does list an
interaction with ARB_tessellation_shader.

Cc: "11.0" <mesa-stable@lists.freedesktop.org>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=92095
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
2015-09-24 12:15:47 -07:00
Timothy Arceri
827d794834 glsl: correctly detect inactive UBO arrays
Previously the code was trying to get the packing type from the array not the
interface.

Cc: Ian Romanick <ian.d.romanick@intel.com>
Cc: Antia Puentes <apuentes@igalia.com>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
2015-09-24 10:07:42 +10:00
Kenneth Graunke
542d40d698 nir: Add new GS intrinsics that maintain a count of emitted vertices.
This patch also introduces a lowering pass to convert the simple GS
intrinsics to the new ones.  See the comments above that for the
rationale behind the new intrinsics.

This should be useful for i965; it's a generic enough mechanism that I
could see other drivers potentially using it as well, so I don't feel
too bad about putting it in the generic code.

v2:
- Use nir_after_block_before_jump for the cursor (caught by Jason
  Ekstrand - I'd mistakenly used nir_after_block when rebasing this
  code onto the new NIR control flow API).
- Remove the old emit_vertex intrinsic at the end, rather than in
  the middle (requested by Jason).
- Use state->... directly rather than locals (requested by Jason).
- Report progress from nir_lower_gs_intrinsics() (requested by me).
- Remove "Authors:" section from file comment (requested by
  Michael Schellenberger Costa).

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 11:00:00 -07:00
Kenneth Graunke
0a040975ec nir: Add unit tests for control flow graphs.
Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Acked-by: Jason Ekstrand <jason.ekstrand@intel.com>
Acked-by: Connor Abbott <cwabbott0@gmail.com>
2015-09-23 11:00:00 -07:00
Kenneth Graunke
fbaa1b19d7 nir/cf: Fix dominance metadata in the dead control flow pass.
The NIR control flow modification API churns the block structure,
splitting blocks, stitching them back together, and so on.  Preserving
information about block dominance is hard (and probably not worthwhile).

This patch makes nir_cf_extract() throw away all metadata, like we do
when adding/removing jumps.

We then make the dead control flow pass compute dominance information
right before it uses it.  This is necessary because earlier work by the
pass may have invalidated it.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 11:00:00 -07:00
Kenneth Graunke
6560838703 nir/cf: Fix unlink_block_successors to actually unlink the second one.
Calling unlink_blocks(block, block->successors[0]) will successfully
unlink the first successor, but then will shift block->successors[1]
down to block->successor[0].  So the successors[1] != NULL check will
always fail.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 11:00:00 -07:00
Kenneth Graunke
024e5ec977 nir/cf: Alter block successors before adding a fake link.
Consider the case of "while (...) { break }".  Or in NIR:

        block block_0 (0x7ab640):
        ...
        /* succs: block_1 */
        loop {
                block block_1:
                /* preds: block_0 */
                break
                /* succs: block_2 */
        }
        block block_2:

Calling nir_handle_remove_jump(block_1, nir_jump_break) will remove the break.
Unfortunately, it would mangle the predecessors and successors.

Here, block_2->predecessors->entries == 1, so we would create a fake
link, setting block_1->successors[1] = block_2, and adding block_1 to
block_2's predecessor set.  This is illegal: a block cannot specify the
same successor twice.  In particular, adding the predecessor would have
no effect, as it was already present in the set.

We'd then call unlink_block_successors(), which would delete the fake
link and remove block_1 from block_2's predecessor set.  It would then
delete successors[0], and attempt to remove block_1 from block_2's
predecessor set a second time...except that it wouldn't be present,
triggering an assertion failure.

The fix appears to be simple: simply unlink the block's successors and
recreate them to point at the correct blocks first.  Then, add the fake
link.  In the above example, removing the break would cause block_1 to
have itself as a successor (as it becomes an infinite loop), so adding
the fake link won't cause a duplicate successor.

v2: Add comments (requested by Connor Abbott) and fix commit message.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 10:59:59 -07:00
Kenneth Graunke
0991b2eb35 nir/cf: Conditionally do block_add_normal_succs() in unlink_jump();
There is a bug where we mess up predecessors/successors due to the
ordering of unlinking/recreating edges/adding fake edges.  In order to
fix that, I need everything in one routine.

However, calling block_add_normal_succs() isn't safe from
cleanup_cf_node() - it would crash trying to insert phi undefs.
So unfortunately I need to add a parameter.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 10:59:59 -07:00
Kenneth Graunke
9674c76c0e nir/cf: Don't break outer-block successors in split_block_beginning().
Consider the following NIR:

   block block_0;
   /* succs: block_1 block_2 */
   if (...) {
      block block_1;
      ...
   } else {
      block block_2;
   }

Calling split_block_beginning() on block_1 would break block_0's
successors:  link_block() sets both successors of a block, so calling
link_block(block_0, new_block, NULL) would throw away the second
successor, leaving only /* succ: new_block */.  This is invalid: the
block before an if statement must have two successors.

Changing the call to link_block(pred, new_block, pred->successors[0])
would correctly leave both successors in place, but because unlink_block
may shift successor[1] to successor[0], it may not preserve the original
order.  NIR maintains a convention that successor[0] must point to the
"then" block, while successor[1] points to the "else" block, so we need
to take care to preserve this ordering.

This patch creates a new function that swaps out one successor for
another, preserving the ordering.  It then uses this to fix the issue.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 10:59:59 -07:00
Kenneth Graunke
e2637db618 nir/cf: Make a helper function for removing a predecessor.
I need to do this in a second place, and I'd rather make a helper
function than cut and paste the code.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 10:59:59 -07:00
Kenneth Graunke
6a67ede6b3 nir: Validate that a block doesn't have two identical successors.
This is invalid, and causes disasters if we try to unlink successors:
removing the first will work, but removing the second copy will fail
because the block isn't in the successor's predecessor set any longer.

Signed-off-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
2015-09-23 10:59:59 -07:00