mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 08:40:11 +01:00
glsl/linker: Count and check image resources.
v2: Add comment about the reason why image variables take up space
from the default uniform block.
Reviewed-by: Paul Berry <stereotype441@gmail.com>
This commit is contained in:
parent
e8dbe430aa
commit
e51158f2e7
2 changed files with 59 additions and 1 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -276,6 +278,11 @@ public:
|
|||
*/
|
||||
unsigned num_shader_samplers;
|
||||
|
||||
/**
|
||||
* Number of images used
|
||||
*/
|
||||
unsigned num_shader_images;
|
||||
|
||||
/**
|
||||
* Number of uniforms used in the current shader
|
||||
*/
|
||||
|
|
@ -303,6 +310,15 @@ 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;
|
||||
|
||||
/* As drivers are likely to represent image uniforms as
|
||||
* scalar indices, count them against the limit of uniform
|
||||
* components in the default block. The spec allows image
|
||||
* uniforms to use up no more than one scalar slot.
|
||||
*/
|
||||
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 +798,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;
|
||||
|
|
|
|||
|
|
@ -2031,6 +2031,46 @@ 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)
|
||||
{
|
||||
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_STAGES; i++) {
|
||||
struct gl_shader *sh = prog->_LinkedShaders[i];
|
||||
|
||||
if (sh) {
|
||||
if (sh->NumImages > ctx->Const.Program[i].MaxImageUniforms)
|
||||
linker_error(prog, "Too many %s shader image uniforms",
|
||||
_mesa_shader_stage_to_string(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->data.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)
|
||||
{
|
||||
|
|
@ -2394,6 +2434,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)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue