[Mesa-dev] [PATCH 20/23] glsl/linker: Count and check image resources.
Francisco Jerez
currojerez at riseup.net
Tue Nov 26 00:02:36 PST 2013
---
src/glsl/link_uniforms.cpp | 13 +++++++++++-
src/glsl/linker.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp
index 0a15739..c75a38c 100644
--- a/src/glsl/link_uniforms.cpp
+++ b/src/glsl/link_uniforms.cpp
@@ -240,7 +240,8 @@ class count_uniform_size : public program_resource_visitor {
public:
count_uniform_size(struct string_to_uint_map *map)
: num_active_uniforms(0), num_values(0), num_shader_samplers(0),
- num_shader_uniform_components(0), is_ubo_var(false), map(map)
+ num_shader_images(0), num_shader_uniform_components(0),
+ is_ubo_var(false), map(map)
{
/* empty */
}
@@ -248,6 +249,7 @@ public:
void start_shader()
{
this->num_shader_samplers = 0;
+ this->num_shader_images = 0;
this->num_shader_uniform_components = 0;
}
@@ -277,6 +279,11 @@ public:
unsigned num_shader_samplers;
/**
+ * Number of images used
+ */
+ unsigned num_shader_images;
+
+ /**
* Number of uniforms used in the current shader
*/
unsigned num_shader_uniform_components;
@@ -303,6 +310,9 @@ private:
if (type->contains_sampler()) {
this->num_shader_samplers +=
type->is_array() ? type->array_size() : 1;
+ } else if (type->contains_image()) {
+ this->num_shader_images += values;
+ this->num_shader_uniform_components += values;
} else {
/* Accumulate the total number of uniform slots used by this shader.
* Note that samplers do not count against this limit because they
@@ -782,6 +792,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
}
sh->num_samplers = uniform_size.num_shader_samplers;
+ sh->NumImages = uniform_size.num_shader_images;
sh->num_uniform_components = uniform_size.num_shader_uniform_components;
sh->num_combined_uniform_components = sh->num_uniform_components;
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index fac186a..86a0cae 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1980,6 +1980,55 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
+/**
+ * Validate shader image resources.
+ */
+static void
+check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+ STATIC_ASSERT(MESA_SHADER_TYPES == 3);
+ static const char *const shader_names[MESA_SHADER_TYPES] = {
+ "vertex", "geometry", "fragment"
+ };
+ const unsigned max_images[MESA_SHADER_TYPES] = {
+ ctx->Const.VertexProgram.MaxImageUniforms,
+ ctx->Const.GeometryProgram.MaxImageUniforms,
+ ctx->Const.FragmentProgram.MaxImageUniforms
+ };
+ unsigned total_image_units = 0;
+ unsigned fragment_outputs = 0;
+
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ return;
+
+ for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
+ struct gl_shader *sh = prog->_LinkedShaders[i];
+
+ if (sh) {
+ if (sh->NumImages > max_images[i])
+ linker_error(prog, "Too many %s shader image uniforms",
+ shader_names[i]);
+
+ total_image_units += sh->NumImages;
+
+ if (i == MESA_SHADER_FRAGMENT) {
+ foreach_list(node, sh->ir) {
+ ir_variable *var = ((ir_instruction *)node)->as_variable();
+ if (var && var->mode == ir_var_shader_out)
+ fragment_outputs += var->type->count_attribute_slots();
+ }
+ }
+ }
+ }
+
+ if (total_image_units > ctx->Const.MaxCombinedImageUniforms)
+ linker_error(prog, "Too many combined image uniforms");
+
+ if (total_image_units + fragment_outputs >
+ ctx->Const.MaxCombinedImageUnitsAndFragmentOutputs)
+ linker_error(prog, "Too many combined image uniforms and fragment outputs");
+}
+
void
link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
{
@@ -2367,6 +2416,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
store_fragdepth_layout(prog);
check_resources(ctx, prog);
+ check_image_resources(ctx, prog);
link_check_atomic_counter_resources(ctx, prog);
if (!prog->LinkStatus)
--
1.8.3.4
More information about the mesa-dev
mailing list