glsl: Fix uniform buffer object counting.

We were counting uniforms located in UBOs against the default uniform
block limit, while not doing any counting against the specific combined
limit.

Note that I couldn't quite find justification for the way I did this, but
I think it's the only sensible thing: The spec talks about components, so
each "float" in a std140 block would count as 1 component and a "vec4"
would count as 4, though they occupy the same amount of space.  Since GPU
limits on uniform buffer loads are surely going to be about the size of
the blocks, I just counted them that way.

Fixes link failures in piglit
arb_uniform_buffer_object/maxuniformblocksize when ported to geometry
shaders on Paul's GS branch, since in that case the max block size is
bigger than the default uniform block component limit.

Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Eric Anholt 2013-05-23 11:10:15 -07:00
parent 93c8692ce9
commit 38e77e545d
3 changed files with 43 additions and 4 deletions

View file

@ -170,6 +170,7 @@ public:
void process(ir_variable *var)
{
this->is_ubo_var = var->is_in_uniform_block();
if (var->is_interface_instance())
program_resource_visitor::process(var->interface_type,
var->interface_type->name);
@ -197,6 +198,8 @@ public:
*/
unsigned num_shader_uniform_components;
bool is_ubo_var;
private:
virtual void visit_field(const glsl_type *type, const char *name,
bool row_major)
@ -222,7 +225,8 @@ private:
* Note that samplers do not count against this limit because they
* don't use any storage on current hardware.
*/
this->num_shader_uniform_components += values;
if (!is_ubo_var)
this->num_shader_uniform_components += values;
}
/* If the uniform is already in the map, there's nothing more to do.
@ -681,6 +685,12 @@ link_assign_uniform_locations(struct gl_shader_program *prog)
sh->num_samplers = uniform_size.num_shader_samplers;
sh->num_uniform_components = uniform_size.num_shader_uniform_components;
sh->num_combined_uniform_components = sh->num_uniform_components;
for (unsigned i = 0; i < sh->NumUniformBlocks; i++) {
sh->num_combined_uniform_components +=
sh->UniformBlocks[i].UniformBufferSize / 4;
}
}
const unsigned num_user_uniforms = uniform_size.num_active_uniforms;

View file

@ -1523,12 +1523,18 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
ctx->Const.GeometryProgram.MaxTextureImageUnits
};
const unsigned max_uniform_components[MESA_SHADER_TYPES] = {
const unsigned max_default_uniform_components[MESA_SHADER_TYPES] = {
ctx->Const.VertexProgram.MaxUniformComponents,
ctx->Const.FragmentProgram.MaxUniformComponents,
ctx->Const.GeometryProgram.MaxUniformComponents
};
const unsigned max_combined_uniform_components[MESA_SHADER_TYPES] = {
ctx->Const.VertexProgram.MaxCombinedUniformComponents,
ctx->Const.FragmentProgram.MaxCombinedUniformComponents,
ctx->Const.GeometryProgram.MaxCombinedUniformComponents
};
const unsigned max_uniform_blocks[MESA_SHADER_TYPES] = {
ctx->Const.VertexProgram.MaxUniformBlocks,
ctx->Const.FragmentProgram.MaxUniformBlocks,
@ -1546,7 +1552,22 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
shader_names[i]);
}
if (sh->num_uniform_components > max_uniform_components[i]) {
if (sh->num_uniform_components > max_default_uniform_components[i]) {
if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
linker_warning(prog, "Too many %s shader default uniform block "
"components, but the driver will try to optimize "
"them out; this is non-portable out-of-spec "
"behavior\n",
shader_names[i]);
} else {
linker_error(prog, "Too many %s shader default uniform block "
"components",
shader_names[i]);
}
}
if (sh->num_combined_uniform_components >
max_combined_uniform_components[i]) {
if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
linker_warning(prog, "Too many %s shader uniform components, "
"but the driver will try to optimize them out; "

View file

@ -2140,12 +2140,20 @@ struct gl_shader
gl_texture_index SamplerTargets[MAX_SAMPLERS];
/**
* Number of uniform components used by this shader.
* Number of default uniform block components used by this shader.
*
* This field is only set post-linking.
*/
unsigned num_uniform_components;
/**
* Number of combined uniform components used by this shader.
*
* This field is only set post-linking. It is the sum of the uniform block
* sizes divided by sizeof(float), and num_uniform_compoennts.
*/
unsigned num_combined_uniform_components;
/**
* This shader's uniform block information.
*