summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/link_uniform_blocks.cpp
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-05-25 13:31:41 +1000
committerDave Airlie <airlied@redhat.com>2016-05-26 12:42:10 +1000
commit5b2675093e863a52b610f112884ae12d42513770 (patch)
tree065396a166ddf061a56396cca08059d33195fe7b /src/compiler/glsl/link_uniform_blocks.cpp
parent4d70fd1bc79a5923505f99494a68bb506f3cde66 (diff)
downloadexternal_mesa3d-5b2675093e863a52b610f112884ae12d42513770.zip
external_mesa3d-5b2675093e863a52b610f112884ae12d42513770.tar.gz
external_mesa3d-5b2675093e863a52b610f112884ae12d42513770.tar.bz2
glsl: handle implicit sized arrays in ssbo
The current code disallows unsized arrays except at the end of an SSBO but it is a bit overzealous in doing so. struct a { int b[]; int f[4]; }; is valid as long as b is implicitly sized within the shader, i.e. it is accessed only by integer indices. I've submitted some piglit tests to test for this. This also has no regressions on piglit on my Haswell. This fixes: GL45-CTS.shader_storage_buffer_object.basic-syntax GL45-CTS.shader_storage_buffer_object.basic-syntaxSSO This patch moves a chunk of the linker code down, so that we don't link the uniform blocks until after we've merged all the variables. The logic went something like: Removing the checks for last ssbo member unsized from the compiler and into the linker, meant doing the check in the link_uniform_blocks code. However to do that the array sizing had to happen first, so we knew that the only unsized arrays were in the last block. But array sizing required the variable to be merged, otherwise you'd get two different array sizes in different version of two variables, and one would get lost when merged. So the solution was to move array sizing up, after variable merging, but before uniform block visiting. Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/compiler/glsl/link_uniform_blocks.cpp')
-rw-r--r--src/compiler/glsl/link_uniform_blocks.cpp16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/compiler/glsl/link_uniform_blocks.cpp b/src/compiler/glsl/link_uniform_blocks.cpp
index ac415b5..3c2d13c 100644
--- a/src/compiler/glsl/link_uniform_blocks.cpp
+++ b/src/compiler/glsl/link_uniform_blocks.cpp
@@ -34,9 +34,10 @@ namespace {
class ubo_visitor : public program_resource_visitor {
public:
ubo_visitor(void *mem_ctx, gl_uniform_buffer_variable *variables,
- unsigned num_variables)
+ unsigned num_variables, struct gl_shader_program *prog)
: index(0), offset(0), buffer_size(0), variables(variables),
- num_variables(num_variables), mem_ctx(mem_ctx), is_array_instance(false)
+ num_variables(num_variables), mem_ctx(mem_ctx), is_array_instance(false),
+ prog(prog)
{
/* empty */
}
@@ -56,6 +57,7 @@ public:
unsigned num_variables;
void *mem_ctx;
bool is_array_instance;
+ struct gl_shader_program *prog;
private:
virtual void visit_field(const glsl_type *type, const char *name,
@@ -148,7 +150,13 @@ private:
*/
const glsl_type *type_for_size = type;
if (type->is_unsized_array()) {
- assert(last_field);
+ if (!last_field) {
+ linker_error(prog, "unsized array `%s' definition: "
+ "only last member of a shader storage block "
+ "can be defined as unsized array",
+ name);
+ }
+
type_for_size = type->without_array();
}
@@ -314,7 +322,7 @@ create_buffer_blocks(void *mem_ctx, struct gl_context *ctx,
/* Add each variable from each uniform block to the API tracking
* structures.
*/
- ubo_visitor parcel(blocks, variables, num_variables);
+ ubo_visitor parcel(blocks, variables, num_variables, prog);
STATIC_ASSERT(unsigned(GLSL_INTERFACE_PACKING_STD140)
== unsigned(ubo_packing_std140));