diff options
author | Samuel Iglesias Gonsalvez <[email protected]> | 2015-04-13 16:17:07 +0200 |
---|---|---|
committer | Samuel Iglesias Gonsalvez <[email protected]> | 2015-09-25 08:39:21 +0200 |
commit | 273f61a0051a794d1a39d70fb1dbf46a3ca3c63f (patch) | |
tree | 85258cb644dccb440d29429d71dcbb7850f385d7 /src/glsl/ast_function.cpp | |
parent | 1440d2a6833902d9c966fe8ad7db46a7f787391c (diff) |
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 <[email protected]>
Reviewed-by: Kristian Høgsberg <[email protected]>
Diffstat (limited to 'src/glsl/ast_function.cpp')
-rw-r--r-- | src/glsl/ast_function.cpp | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index 803edf5a14d..ff5ecb954f0 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -1593,11 +1593,16 @@ ast_function_expression::handle_method(exec_list *instructions, if (op->type->is_array()) { if (op->type->is_unsized_array()) { - _mesa_glsl_error(&loc, state, "length called on unsized array"); - goto fail; + if (!state->has_shader_storage_buffer_objects()) { + _mesa_glsl_error(&loc, state, "length called on unsized array" + " only available with " + "ARB_shader_storage_buffer_object"); + } + /* Calculate length of an unsized array in run-time */ + result = new(ctx) ir_expression(ir_unop_ssbo_unsized_array_length, op); + } else { + result = new(ctx) ir_constant(op->type->array_size()); } - - result = new(ctx) ir_constant(op->type->array_size()); } else if (op->type->is_vector()) { if (state->ARB_shading_language_420pack_enable) { /* .length() returns int. */ |