summaryrefslogtreecommitdiffstats
path: root/src/glsl
Commit message (Collapse)AuthorAgeFilesLines
* glsl: validate IR after linking (debug builds only)Paul Berry2011-08-081-0/+8
| | | | | | | | | | | | | | | | | | | | At least one of the invariants verified by IR validation concerns the relative ordering of toplevel constructs in the IR: references to global variables must come after the declarations of those global variables. Since linking affects the ordering of toplevel constructs in the IR, it's possible that a bug in the linker will cause invalid IR to be generated, even if all the pre-linked shaders are valid. (In fact, such a bug was fixed by the previous commit.) Bugs like this are easily masked by further optimization passes, particularly inlining. So to make them easier to track down, this patch addes an IR validation step right after linking, and before final optimization occurs. The validation only occurs on debug builds. Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: When linking, emit functions at the tail of the final linked program.Paul Berry2011-08-081-2/+4
| | | | | | | | | | | | | | | | | | | | | When link_functions.cpp adds a new function to the final linked program, it needs to add it after any global variable declarations that the function refers to, otherwise the IR will be invalid (because variable declarations must occur before variable accesses). The easiest way to do that is to have the linker emit functions to the tail of the final linked program. The linker used to emit functions to the head of the final linked program, in an effort to keep callees sorted before their callers. However, this was not reliable: it didn't work for functions declared or defined in the same compilation unit as main, for diamond-shaped patterns in the call graph, or for some obscure cases involving overloaded functions. And no code currently relies on this sort order. No Piglit regressions with i965 Ironlake. Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Check array size is const before asserting that no IR was generated.Paul Berry2011-08-081-5/+8
| | | | | | | | | | | | | process_array_type() contains an assertion to verify that no IR instructions are generated while processing the expression that specifies the size of the array. This assertion needs to happen _after_ checking whether the expression is constant. Otherwise we may crash on an illegal shader rather than reporting an error. Fixes piglit tests array-size-non-builtin-function.vert and array-size-with-side-effect.vert. Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Constant-fold built-in functions before outputting IRPaul Berry2011-08-081-2/+14
| | | | | | | | | | | | | | Rearranged the logic for converting the ast for a function call to hir, so that we constant fold before emitting any IR. Previously we would emit some IR, and then only later detect whether we could constant fold. The unnecessary IR would usually get cleaned up by a later optimization step, however in the case of a builtin function being used to compute an array size, it was causing an assertion. Fixes Piglit test array-size-constant-relational.vert. Reviewed-by: Kenneth Graunke <[email protected]> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38625
* glsl: Emit function signatures at toplevel, even for built-ins.Paul Berry2011-08-084-20/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ast-to-hir conversion needs to emit function signatures in two circumstances: when a function declaration (or definition) is encountered, and when a built-in function is encountered. To avoid emitting a function signature in an illegal place (such as inside a function), emit_function() checked whether we were inside a function definition, and if so, emitted the signature before the function definition. However, this didn't cover the case of emitting function signatures for built-in functions when those built-in functions are called from inside the constant integer expression that specifies the length of a global array. This failed because when processing an array length, we are emitting IR into a dummy exec_list (see process_array_type() in ast_to_hir.cpp). process_array_type() later checks (via an assertion) that no instructions were emitted to the dummy exec_list, based on the reasonable assumption that we shouldn't need to emit instructions to calculate the value of a constant. This patch changes emit_function() so that it emits function signatures at toplevel in all cases. This partially fixes bug 38625 (https://bugs.freedesktop.org/show_bug.cgi?id=38625). The remainder of the fix is in the patch that follows. Reviewed-by: Kenneth Graunke <[email protected]>
* Revert "glsl: Skip processing the first function's body in do_dead_functions()."Paul Berry2011-08-081-10/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | opt_dead_functions contained a shortcut to skip processing the first function's body, based on the assumption that IR functions are topologically sorted, with callees always coming before their callers (therefore the first function cannot contain any calls). This assumption turns out not to be true in general. For example, the following code snippet gets translated to IR that violates this assumption: void f(); void g(); void f() { g(); } void g() { ... } In practice, the shortcut didn't cause bugs because of a coincidence of the circumstances in which opt_dead_functions is called: (a) we do inlining right before dead function elimination, and inlining (when successful) eliminates all calls. (b) for user-defined functions, inlining is always successful, because previous optimization passes (during compilation) have reduced them to a form that is eligible for inlining. (c) the function that appears first in the IR can't possibly call a built-in function, because built-in functions are always emitted before the function that calls them. It seems unnecessarily fragile to have opt_dead_functions depend on these coincidences. And the next patch in this series will break (c). So I'm reverting the shortcut. The consequence will be a slight increase in link time for complex shaders. This reverts commit c75427f4c8767e131e5fb3de44fbc9d904cb992d. Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: silence warning about trailing comma in enum listBrian Paul2011-08-081-1/+1
|
* glsl: empty declarations should be validChia-I Wu2011-08-052-12/+8
| | | | | | | | | | | | | | | Unlike C++, empty declarations such as float; should be valid. The spec is not explicit about this actually. Some apps that generate their shader sources may rely on this. This was noted when porting one of them to Linux from Windows. Reviewed-by: Chad Versace <[email protected]> Note: this is a candidate for the 7.11 branch.
* mesa: Ensure that gl_shader_program::InfoLog is never NULLIan Romanick2011-08-021-0/+1
| | | | | | | | | | | | | | | | This prevents assertion failures in ralloc_strcat. The ralloc_free in _mesa_free_shader_program_data can be omitted because freeing the gl_shader_program in _mesa_delete_shader_program will take care of this automatically. A bunch of this code could use a refactor to use ralloc a bit more effectively. A bunch of the things that are allocated with malloc and owned by the gl_shader_program should be allocated with ralloc (using the gl_shader_program as the context). Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
* linker: Make linker_{error,warning} generally availableIan Romanick2011-08-024-3/+22
| | | | | | | | | | linker_warning is a new function. It's identical to linker_error except that it doesn't set LinkStatus=false and it prepends "warning: " on messages instead of "error: ". Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
* linker: Make linker_error set LinkStatus to falseIan Romanick2011-08-024-100/+90
| | | | | | | | | | | | Remove the other places that set LinkStatus to false since they all immediately follow a call to linker_error. The function linker_error was previously known as linker_error_printf. The name was changed because it may seem surprising that a printf function will set an error flag. Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
* glsl: improve the accuracy of the atan(x,y) builtin function.Paul Berry2011-08-011-1/+3
| | | | | | | | | | The previous formula for atan(x,y) returned a value of +/- pi whenever |x|<0.0001, and used a formula based on atan(y/x) otherwise. This broke in cases where both x and y were small (e.g. atan(1e-5, 1e-5)). This patch modifies the formula so that it returns a value of +/- pi whenever |x|<1e-8*|y|, and uses the formula based on atan(y/x) otherwise.
* glsl: improve the accuracy of the asin() builtin function.Paul Berry2011-08-011-28/+40
| | | | | | | | | | | | | | | | | | | | | | | | The previous formula for asin(x) was algebraically equivalent to: sign(x)*(pi/2 - sqrt(1-|x|)*(A + B|x| + C|x|^2)) where A, B, and C were arbitrary constants determined by a curve fit. This formula had a worst case absolute error of 0.00448, an unbounded worst case relative error, and a discontinuity near x=0. Changed the formula to: sign(x)*(pi/2 - sqrt(1-|x|)*(pi/2 + (pi/4-1)|x| + A|x|^2 + B|x|^3)) where A and B are arbitrary constants determined by a curve fit. This has a worst case absolute error of 0.00039, a worst case relative error of 0.000405, and no discontinuities. I don't expect a significant performance degradation, since the extra multiply-accumulate should be fast compared to the sqrt() computation. Fixes piglit tests {vs,fs}-asin-float and {vs,fs}-atan-*
* glsl: Remove duplicate commentChad Versace2011-08-011-8/+0
| | | | | | | Remove duplicate doxgen comment for ir_function.cpp:parameter_lists_match(). Signed-off-by: Chad Versace <[email protected]>
* glsl: Clarify ir_function::matching_sigature()Chad Versace2011-07-301-20/+33
| | | | | | | | | | | The function used a variable named 'score', which was an outright lie. A signature matches or it doesn't; there is no fuzzy scoring. Change the return type of parameter_lists_match() to an enum, and let ir_function::matching_sigature() switch on that enum. Reviewed-by: Kenneth Graunke <[email protected]> Signed-off-by: Chad Versace <[email protected]>
* glsl: Fix conversions in array constructorsChad Versace2011-07-301-2/+10
| | | | | | | | | | | | | | | | | | | | | | Array constructors obey narrower conversion rules than other constructors [1] --- they use the implicit conversion rules [2] instead of the scalar constructor conversions [3]. But process_array_constructor() was incorrectly applying the broader rules. [1] GLSL 1.50 spec, Section 5.4.4 Array Constructors, page 52 (58 of pdf) [2] GLSL 1.50 spec, Section 4.1.10 Implicit Conversions, page 25 (31 of pdf) [3] GLSL 1.50 spec, Section 5.4.1 Conversion, page 48 (54 of pdf) To fix this, first check (with glsl_type::can_be_implicitly_converted_to) if an implicit conversion is legal before performing the conversion. Fixes: piglit:spec/glsl-1.20/compiler/structure-and-array-operations/array-ctor-implicit-conversion-bool-float.vert piglit:spec/glsl-1.20/compiler/structure-and-array-operations/array-ctor-implicit-conversion-bvec*-vec*.vert Note: This is a candidate for the 7.10 and 7.11 branches. Reviewed-by: Kenneth Graunke <[email protected]> Signed-off-by: Chad Versace <[email protected]>
* glsl: Remove ir_function.cpp:type_compare()Chad Versace2011-07-301-61/+0
| | | | | | | | | The function is no longer used and has been replaced by glsl_type::can_implicitly_convert_to(). Note: This is a candidate for the 7.10 and 7.11 branches. Reviewed-by: Kenneth Graunke <[email protected]> Signed-off-by: Chad Versace <[email protected]>
* glsl: Fix implicit conversions in non-constructor function callsChad Versace2011-07-301-17/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Context ------- In ast_function_expression::hir(), parameter_lists_match() checks if the function call's actual parameter list matches the signature's parameter list, where the match may require implicit conversion of some arguments. To check if an implicit conversion exists between individual arguments, type_compare() is used. Problems -------- type_compare() allowed the following illegal implicit conversions: bool -> float bvecN -> vecN int -> uint ivecN -> uvecN uint -> int uvecN -> ivecN Change ------ type_compare() is buggy, so replace it with glsl_type::can_be_implicitly_converted_to(). This comprises a rewrite of parameter_lists_match(). Fixes piglit:spec/glsl-1.20/compiler/built-in-functions/outerProduct-bvec*.vert Note: This is a candidate for the 7.10 and 7.11 branches. Reviewed-by: Kenneth Graunke <[email protected]> Signed-off-by: Chad Versace <[email protected]>
* glsl: Add method glsl_type::can_implicitly_convert_to()Chad Versace2011-07-302-0/+51
| | | | | | | | | | | | | | This method checks if a source type is identical to or can be implicitly converted to a target type according to the GLSL 1.20 spec, Section 4.1.10 Implicit Conversions. The following commits use the method for a bugfix: glsl: Fix implicit conversions in non-constructor function calls glsl: Fix implicit conversions in array constructors Note: This is a candidate for the 7.10 and 7.11 branches. Reviewed-by: Kenneth Graunke <[email protected]> Signed-off-by: Chad Versace <[email protected]>
* Add dependency generation for Mesa and GLSL dricore objects.Eric Anholt2011-07-281-0/+1
| | | | | Reviewed-By: Christopher James Halse Rogers <[email protected]>
* glsl: improve the accuracy of the radians() builtin functionPaul Berry2011-07-281-4/+4
| | | | | | | | | | | The constant used in the radians() function didn't have enough precision, causing a relative error of 1.676e-5, which is far worse than the precision of 32-bit floats. This patch reduces the relative error to 1.14e-9, which is the best we can do in 32 bits. Fixes piglit tests {fs,vs}-radians-{float,vec2,vec3,vec4}. Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Add source location tracking to TODO listIan Romanick2011-07-271-0/+5
|
* glsl: Remove completed items from the TODO listIan Romanick2011-07-271-16/+0
|
* glsl: Correctly return progress from lower_variable_index_to_cond_assignIan Romanick2011-07-251-1/+3
| | | | | | | | | | | | | | | | | | | | lower_variable_index_to_cond_assign runs until it can't make any more progress. It then returns the result of the last pass which will always be false. This caused the lowering loop in _mesa_ir_link_shader to end before doing one last round of lower_if_to_cond_assign. This caused several if-statements (resulting from lower_variable_index_to_cond_assign) to be left in the IR. In addition to this change, lower_variable_index_to_cond_assign should take a flag indicating whether or not it should even generate if-statements. This is easily controlled by switch_generator::linear_sequence_max_length. This would generate much better code on architectures without any flow contol. Fixes i915 piglit regressions glsl-texcoord-array and glsl-fs-vec4-indexing-temp-src. Reviewed-by: Eric Anholt <[email protected]>
* glsl: Compare vector indices in blocksIan Romanick2011-07-231-23/+39
| | | | | | | | Just like the non-constant array index lowering pass, compare all N indices at once. For accesses to a vec4, this saves 3 comparison instructions on a vector architecture. Reviewed-by: Eric Anholt <[email protected]>
* glsl: Factor out code that generates block of index comparisonsIan Romanick2011-07-232-42/+73
| | | | Reviewed-by: Eric Anholt <[email protected]>
* glsl: Treat ir_dereference_array of non-var as a constant for loweringIan Romanick2011-07-231-2/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | Previously the code would just look at deref->array->type to see if it was a constant. This isn't good enough because deref->array might be another ir_dereference_array... of a constant. As a result, deref->array->type wouldn't be a constant, but deref->variable_referenced() would return NULL. The unchecked NULL pointer would shortly lead to a segfault. Instead just look at the return of deref->variable_referenced(). If it's NULL, assume that either a constant or some other form of anonymous temporary storage is being dereferenced. This is a bit hinkey because most drivers treat constant arrays as uniforms, but the lowering pass treats them as temporaries. This keeps the behavior of the old code, so this change isn't making things worse. Fixes i965 piglit: vs-temp-array-mat[234]-index-col-rd vs-temp-array-mat[234]-index-col-row-rd vs-uniform-array-mat[234]-index-col-rd vs-uniform-array-mat[234]-index-col-row-rd Reviewed-by: Eric Anholt <[email protected]>
* glsl: When lowering non-constant vector indexing, respect existing conditionsIan Romanick2011-07-231-5/+24
| | | | | | | If the non-constant index was in the LHS of an assignment, any existing condititon on that assignment would be lost. Reviewed-by: Eric Anholt <[email protected]>
* glsl: When lowering non-constant array indexing, respect existing conditionsIan Romanick2011-07-231-3/+18
| | | | | | | | | | | | | | | If the non-constant index was in the LHS of an assignment, any existing condititon on that assignment would be lost. Fixes i965 piglit: fs-temp-array-mat[234]-col-row-wr fs-temp-array-mat[234]-index-col-row-wr fs-temp-array-mat[234]-index-col-wr fs-temp-array-mat[234]-index-row-wr vs-varying-array-mat[234]-index-col-wr Reviewed-by: Eric Anholt <[email protected]>
* glsl: Rework lowering of non-constant array indexingIan Romanick2011-07-231-19/+116
| | | | | | | | | | | | | | | | | | | | | | | | | The previous implementation could easily get tricked if the LHS of an assignment included a non-constant index that was "inside" another dereference. For example: mat4 m[2]; m[0][i] = vec4(0.0); Due to the way it tracked whether the array was being assigned, it would think that the non-constant index was in an r-value. The new code fixes that by tracking l-values and r-values differently. The index is also replaced by cloning the IR and replacing the index variable instead of the odd way it was done before. v2: Apply some simplifications suggested by Eric Anholt. Making assignment_generator::rvalue be ir_dereference instead of ir_rvalue simplified the code a bit. Fixes i965 piglit fs-temp-array-mat[234]-index-wr and vs-varying-array-mat[234]-index-wr. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=34691 Reviewed-by: Eric Anholt <[email protected]>
* glsl: Split out part of variable_index_to_cond_assign_visitor::needs_loweringIan Romanick2011-07-231-5/+10
| | | | | | | Other code will soon need to know if an array needs lowering based exclusively on the storage mode. Reviewed-by: Eric Anholt <[email protected]>
* glsl: Move is_array_or_matrix outside visitor classIan Romanick2011-07-231-5/+6
| | | | | | | There's no reason for it to be there, and another class that may not have access to the visitor will need it soon. Reviewed-by: Eric Anholt <[email protected]>
* glsl: Add standalone_scaffolding.cpp to SConscript.Vinson Lee2011-07-221-0/+1
|
* glsl: Add unit tests for lower_jumps.cppPaul Berry2011-07-2253-0/+1538
| | | | | | | | | | | | | | These tests invoke do_lower_jumps() in isolation (using the glsl_test executable) and verify that it transforms the IR in the expected way. The unit tests may be run from the top level directory using "make check". For reference, I've also checked in the Python script create_test_cases.py, which was used to generate these tests. It is not necessary to run this script in order to run the tests. Acked-by: Chad Versace <[email protected]>
* glsl: Create a standalone executable for testing optimization passes.Paul Berry2011-07-225-3/+403
| | | | | | | | | | | | | This patch adds a new build artifact, glsl_test, which can be used for testing optimization passes in isolation. I'm hoping that we will be able to add other useful standalone tests to this executable in the future. Accordingly, it is built in a modular fashion: the main() function uses its first argument to determine which test function to invoke, removes that argument from argv[], and then calls that function to interpret the rest of the command line arguments and perform the test. Currently the only test function is "optpass", which tests optimization passes.
* glsl: Move functions into standalone_scaffolding.cpp for later reuse.Paul Berry2011-07-224-58/+150
| | | | | | | | | | | | | | | | This patch moves the following functions from main.cpp (the main cpp file for the standalone executable that is used to create the built-in functions) to standalone_scaffolding.cpp, so that they can be re-used in other standalone executables: - initialize_context()* - _mesa_new_shader() - _mesa_reference_shader() *initialize_context contained some code that was specific to main.cpp, so it was split into two functions: initialize_context() (which remains in main.cpp), and initialize_context_from_defaults() (which is in standalone_scaffolding.cpp).
* glsl: Add ir_function_detect_recursion.cpp to SConscript.Vinson Lee2011-07-201-0/+1
|
* glsl: Reject shaders that contain static recursionIan Romanick2011-07-205-0/+404
| | | | | | | | | | | | | | | | | | | The GLSL 1.20 and later specs say: "Recursion is not allowed, not even statically. Static recursion is present if the static function call graph of the program contains cycles." Recursion is detected and rejected both a compile-time and at link-time. The complie-time check happens to detect some cases that may be removed by various optimization passes. The spec doesn't seem to allow this, but other vendors (e.g., NVIDIA) appear to only check at link-time after all optimizations. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=33885 Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Eric Anholt <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Make prototype_string publicly availableIan Romanick2011-07-202-2/+8
| | | | | | | | Also clarify the documentation for one of the parameters. Reviewed-by: Paul Berry <[email protected]> Reviewed-by: Eric Anholt <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: Avoid massive ralloc_strndup overhead in S-Expression parsing.Kenneth Graunke2011-07-202-19/+47
| | | | | | | | | | | | | | | | | | | | | When parsing S-Expressions, we need to store nul-terminated strings for Symbol nodes. Prior to this patch, we called ralloc_strndup each time we constructed a new s_symbol. It turns out that this is obscenely expensive. Instead, copy the whole buffer before parsing and overwrite it to contain \0 bytes at the appropriate locations. Since atoms are separated by whitespace, (), or ;, we can safely overwrite the character after a Symbol. While much of the buffer may be unused, copying the whole buffer is simple and guaranteed to provide enough space. Prior to this, running piglit-run.py -t glsl tests/quick.tests with GLSL 1.30 enabled took just over 10 minutes on my machine. Now it takes 5. NOTE: This is a candidate for stable release branches (because it will make running comparison tests so much less irritating.) Signed-off-by: Kenneth Graunke <[email protected]>
* glsl: silence warning in linker.cppBrian Paul2011-07-191-1/+1
|
* glsl: Ensure that sampler declarations are always uniform or "in" parameters.Paul Berry2011-07-181-0/+35
| | | | | | | | | | | | | | | | | | | | | | This brings us into compliance with page 17 (page 22 of the PDF) of the GLSL 1.20 spec: "[Sampler types] can only be declared as function parameters or uniform variables (see Section 4.3.5 "Uniform"). ... [Samplers] cannot be used as out or inout function parameters." The spec isn't explicit about whether this rule applies to structs/arrays containing shaders, but the intent seems to be to ensure that it can always be determined at compile time which sampler is being used in each texture lookup. So to avoid creating a loophole, the rule needs to apply to structs/arrays containing shaders as well. Fixes piglit tests spec/glsl-1.10/compiler/samplers/*.frag, and fixes bug 38987. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38987 Reviewed-by: Ian Romanick <[email protected]>
* glsl: Move type_contains_sampler() into glsl_type for later reuse.Paul Berry2011-07-183-16/+23
| | | | | | | The new location, as a member function of glsl_type, is more consistent with queries like is_sampler(), is_boolean(), is_float(), etc. Placing the function inside glsl_type also makes it available to any code that uses glsl_types.
* linker: Only over-ride built-ins when a prototype has been seenIan Romanick2011-07-172-5/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | The GLSL spec says: "If a built-in function is redeclared in a shader (i.e., a prototype is visible) before a call to it, then the linker will only attempt to resolve that call within the set of shaders that are linked with it." This patch enforces this behavior. When a function call is processed a flag is set in the ir_call to indicate whether the previously seen prototype is the built-in or not. At link time a call will only bind to an instance of a function that matches the "want built-in" setting in the ir_call. This has the odd side effect that first call to abs() in the shader below will call the built-in and the second will not: float foo(float x) { return abs(x); } float abs(float x) { return -x; } float bar(float x) { return abs(x); } This seems insane, but it matches what the spec says. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31744
* glsl: Reject ambiguous function calls (multiple inexact matches).Kenneth Graunke2011-07-111-6/+27
| | | | | | | | | | | | | | | | | | | According to the GLSL 1.20 specification, "it is a semantic error if there are multiple ways to apply [implicit] conversions [...] such that the call can be made to match multiple signatures." Fixes a regression caused by 60eb63a855cb89962f2d5bb91e238ff2d1ab8702, which implemented the wrong policy of finding a "closest" match. However, this is not a revert, since the original code failed to continue looking for an exact match once it found two inexact matches. It's OK to have multiple inexact matches if there's also an exact match. NOTE: This is a candidate for the 7.10 and 7.11 branches. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38971 Reviewed-by: Eric Anholt <[email protected]> Signed-off-by: Kenneth Graunke <[email protected]>
* glsl: Lower break instructions when necessary at the end of a loop.Paul Berry2011-07-081-1/+54
| | | | | | | | | | | | | | | | | | Normally lower_jumps.cpp doesn't need to lower a break instruction that occurs at the end of a loop, because all back-ends can produce proper GPU instructions for a break instruction in this "canonical" location. However, if other break instructions within the loop are already being lowered, then a break instruction at the end of the loop needs to be lowered too, since after the optimization is complete a new conditional break will be inserted at the end of the loop. Without this patch, lower_jumps.cpp may require multiple passes in order to lower all jumps. This results in sub-optimal output because lower_jumps.cpp produces a brand new set of temporary variables each time it is run, and the redundant temporary variables are not guaranteed to be eliminated by later optimization passes. Fixes unit test test_lower_breaks_6.
* glsl: In lower_jumps.cpp, lower both branches of a conditional.Paul Berry2011-07-081-1/+4
| | | | | | | | | | | | | | | Previously, lower_jumps.cpp would break out of its loop after lowering a jump instruction in just the then- or else-branch of a conditional, and it would fail to lower a jump instruction occurring in the other branch. Without this patch, lower_jumps.cpp may require multiple passes in order to lower all jumps. This results in sub-optimal output because lower_jumps.cpp produces a brand new set of temporary variables each time it is run, and the redundant temporary variables are not guaranteed to be eliminated by later optimization passes. Fixes unit test test_lower_returns_4.
* glsl: Use foreach_list in lower_jumps.cppPaul Berry2011-07-081-1/+12
| | | | | | | | | | | | | | | | | | | | | | | The visitor class in lower_jumps.cpp never removes or replaces the instruction being visited, but it frequently alters or removes the instructions that follow it. Therefore, to make sure the altered IR is visited, it needs to iterate through exec_lists using foreach_list rather than visit_exec_list(). Without this patch, lower_jumps.cpp may require multiple passes in order to lower all jumps. This results in sub-optimal output because lower_jumps.cpp produces a brand new set of temporary variables each time it is run, and the redundant temporary variables are not guaranteed to be eliminated by later optimization passes. Also, certain invariants assumed by lower_jumps.cpp may fail to hold, causing assertion failures. Fixes unit tests test_lower_pulled_out_jump, test_lower_unified_returns, test_lower_guarded_conditional_break, test_lower_return_non_void_at_end_of_loop, and test_lower_returns_3. Reviewed-by: Kenneth Graunke <[email protected]>
* glsl: lower unconditional returns and continues in loops.Paul Berry2011-07-081-8/+54
| | | | | | | | | | | | | | | | | Previously, lower_jumps.cpp would only lower return and continue statements that appeared inside conditionals. This patch makes it lower unconditional returns and continue statements that occur inside a loop. Such unconditional flow control statements would be unlikely to be explicitly coded by a reasonable user, however they might arise as a result of other optimizations. Without this patch, lower_jumps.cpp might not lower certain return and continue statements, causing some backends to fail. Fixes unit tests test_lower_return_void_at_end_of_loop and test_remove_continue_at_end_of_loop.
* glsl: Lower unconditional return statements.Paul Berry2011-07-081-0/+14
| | | | | | | | | | Previously, lower_jumps.cpp only lowered return statements that appeared inside of an if statement. Without this patch, lower_jumps.cpp might not lower certain return statements, causing some back-ends to fail (as in bug #36669). Fixes unit test test_lower_returns_1.