[Mesa-dev] [PATCH 2/2] mesa: fix GLSL program objects with more than 16 samplers combined
Eric Anholt
eric at anholt.net
Tue May 21 14:54:32 PDT 2013
Marek Olšák <maraeo at gmail.com> writes:
> The problem is the sampler units are allocated from the same pool for all
> shader stages, so if a vertex shader uses 12 samplers (0..11), the fragment
> shader samplers start at index 12, leaving only 4 sampler units
> for the fragment shader. The main cause is probably the fact that samplers
> (texture unit -> sampler unit mapping, etc.) are tracked globally
> for an entire program object.
>
> This commit adapts the GLSL linker and core Mesa such that the sampler units
> are assigned to sampler uniforms for each shader stage separately
> (if a sampler uniform is used in all shader stages, it may occupy a different
> sampler unit in each, and vice versa, an i-th sampler unit may refer to
> a different sampler uniform in each shader stage), and the sampler-specific
> variables are moved from gl_shader_program to gl_shader.
>
> This doesn't require any driver changes, and it fixes piglit/max-samplers
> for gallium and classic swrast. It also works with any number of shader
> stages.
I was initially uncomfortable with gl_uniform_storage getting bigger,
but it's *huge* already, and the increased overhead I thought I saw in
uniform updates isn't really there. So, just nitpicks:
> @@ -335,8 +339,38 @@ public:
> int ubo_block_index;
> int ubo_byte_offset;
> bool ubo_row_major;
> + gl_shader_type shader_type;
>
> private:
> + void handle_samplers(const glsl_type *base_type,
> + struct gl_uniform_storage *uniform)
> + {
> +
> + if (base_type->is_sampler()) {
> + uniform->sampler[shader_type].index = this->next_sampler;
> + uniform->sampler[shader_type].active = true;
> +
> + /* Increment the sampler by 1 for non-arrays and by the number of
> + * array elements for arrays.
> + */
bad tab indentation
> + this->next_sampler +=
> + MAX2(1, uniform->array_elements);
> +
> + const gl_texture_index target = base_type->sampler_index();
> + const unsigned shadow = base_type->sampler_shadow;
tabs
> + for (unsigned i = uniform->sampler[shader_type].index;
> + i < MIN2(this->next_sampler, MAX_SAMPLERS);
> + i++) {
> + this->targets[i] = target;
> + this->shader_samplers_used |= 1U << i;
> + this->shader_shadow_samplers |= shadow << i;
> + }
tabs
> @@ -388,26 +397,16 @@ private:
> base_type = type;
> }
>
> - if (base_type->is_sampler()) {
> - this->uniforms[id].sampler = this->next_sampler;
> + /* This assigns sampler uniforms to sampler units. */
> + handle_samplers(base_type, &this->uniforms[id]);
>
> - /* Increment the sampler by 1 for non-arrays and by the number of
> - * array elements for arrays.
> - */
> - this->next_sampler += MAX2(1, this->uniforms[id].array_elements);
> -
> - const gl_texture_index target = base_type->sampler_index();
> - const unsigned shadow = base_type->sampler_shadow;
> - for (unsigned i = this->uniforms[id].sampler
> - ; i < MIN2(this->next_sampler, MAX_SAMPLERS)
> - ; i++) {
> - this->targets[i] = target;
> - this->shader_samplers_used |= 1U << i;
> - this->shader_shadow_samplers |= shadow << i;
> - }
> -
> - } else {
> - this->uniforms[id].sampler = ~0;
> + /* If there is already storage associated with this uniform, it means
> + * that it was set while processing an earlier shader stage. For
> + * example, we may be processing the uniform in the fragment shader, but
> + * the uniform was already processed in the vertex shader.
> + */
> + if (this->uniforms[id].storage != NULL) {
> + return;
tabs
> @@ -119,6 +122,14 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler,
> return 0;
> }
>
> - return shader_program->UniformStorage[location].sampler + getname.offset;
> -}
> + if (!shader_program->UniformStorage[location].sampler[shader].active) {
> + linker_error(shader_program,
> + "cannot return a sampler named %s, because it is not "
> + "used in this shader stage. This is a driver bug.\n",
> + getname.name);
> + return 0;
> + }
Maybe _mesa_problem()? This isn't really called at link time, and you
want something really visible like an assert.
Other than the style bits,
Reviewed-by: Eric Anholt <eric at anholt.net>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130521/9554c33d/attachment.pgp>
More information about the mesa-dev
mailing list