[Mesa-dev] [PATCH 119/133] nir: Rework the way samplers are lowered
Chris Forbes
chrisf at ijw.co.nz
Tue Jan 6 15:05:56 PST 2015
Looks reasonable to me.
Reviewed-by: Chris Forbes <chrisf at ijw.co.nz>
On Tue, Dec 16, 2014 at 7:13 PM, Jason Ekstrand <jason at jlekstrand.net> wrote:
> ---
> src/glsl/nir/nir_lower_samplers.cpp | 149 ++++++++++++++++++------------------
> 1 file changed, 74 insertions(+), 75 deletions(-)
>
> diff --git a/src/glsl/nir/nir_lower_samplers.cpp b/src/glsl/nir/nir_lower_samplers.cpp
> index d94183c..ece4dc3 100644
> --- a/src/glsl/nir/nir_lower_samplers.cpp
> +++ b/src/glsl/nir/nir_lower_samplers.cpp
> @@ -36,67 +36,9 @@ extern "C" {
> }
>
> static unsigned
> -get_deref_name_offset(nir_deref_var *deref_var,
> - gl_shader_program *shader_program, char **name,
> - void *mem_ctx)
> -{
> - nir_deref *deref = &deref_var->deref;
> - nir_deref_array *deref_array;
> - nir_deref_struct *deref_struct;
> -
> - *name = ralloc_strdup(mem_ctx, deref_var->var->name);
> -
> - while (deref->child != NULL) {
> - switch (deref->child->deref_type) {
> - case nir_deref_type_array:
> - deref_array = nir_deref_as_array(deref->child);
> - if (deref_array->deref_array_type == nir_deref_array_type_indirect) {
> - /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
> - * while GLSL 1.30 requires that the array indices be
> - * constant integer expressions. We don't expect any driver
> - * to actually work with a really variable array index, so
> - * all that would work would be an unrolled loop counter that
> - * ends up being constant.
> - */
> - ralloc_strcat(&shader_program->InfoLog,
> - "warning: Variable sampler array index unsupported.\n"
> - "This feature of the language was removed in GLSL 1.20 "
> - "and is unlikely to be supported for 1.10 in Mesa.\n");
> - }
> - if (deref_array->deref.child == NULL) {
> - return deref_array->base_offset;
> - }
> - ralloc_asprintf_append(name, "[%u]", deref_array->base_offset);
> - break;
> -
> - case nir_deref_type_struct: {
> - deref_struct = nir_deref_as_struct(deref->child);
> - const char *field = glsl_get_struct_elem_name(deref->type,
> - deref_struct->index);
> - ralloc_asprintf_append(name, ".%s", field);
> - break;
> - }
> -
> - default:
> - assert(0);
> - break;
> - }
> - deref = deref->child;
> - }
> -
> - return 0;
> -}
> -
> -static unsigned
> -get_sampler_index(nir_deref_var *sampler,
> - struct gl_shader_program *shader_program,
> +get_sampler_index(struct gl_shader_program *shader_program, const char *name,
> const struct gl_program *prog)
> {
> - void *mem_ctx = ralloc_context(NULL);
> - char *name;
> - unsigned offset = get_deref_name_offset(sampler, shader_program, &name,
> - mem_ctx);
> -
> GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target);
>
> unsigned location;
> @@ -115,33 +57,86 @@ get_sampler_index(nir_deref_var *sampler,
> return 0;
> }
>
> - ralloc_free(mem_ctx);
> -
> - return shader_program->UniformStorage[location].sampler[shader].index +
> - offset;
> + return shader_program->UniformStorage[location].sampler[shader].index;
> }
>
> static void
> lower_sampler(nir_tex_instr *instr, struct gl_shader_program *shader_program,
> - const struct gl_program *prog)
> + const struct gl_program *prog, void *mem_ctx)
> {
> - if (instr->sampler) {
> - instr->sampler_index = get_sampler_index(instr->sampler, shader_program,
> - prog);
> - nir_src empty_src;
> - memset(&empty_src, 0, sizeof empty_src);
> - for (nir_deref *deref = &instr->sampler->deref; deref; deref = deref->child) {
> - if (deref->deref_type == nir_deref_type_array) {
> - nir_deref_array *arr = nir_deref_as_array(deref);
> - nir_instr_rewrite_src(&instr->instr, &arr->indirect, empty_src);
> + if (instr->sampler == NULL)
> + return;
> +
> + /* Get the name and the offset */
> + instr->sampler_index = 0;
> + instr->has_sampler_indirect = false;
> + char *name = ralloc_strdup(mem_ctx, instr->sampler->var->name);
> +
> + for (nir_deref *deref = &instr->sampler->deref;
> + deref->child; deref = deref->child) {
> + switch (deref->child->deref_type) {
> + case nir_deref_type_array: {
> + nir_deref_array *deref_array = nir_deref_as_array(deref->child);
> +
> + /* XXX: We're assuming here that the indirect is the last array
> + * thing we have. This should be ok for now as we don't support
> + * arrays_of_arrays yet.
> + */
> + assert(!instr->has_sampler_indirect);
> +
> + instr->sampler_index *= glsl_get_length(deref->type);
> + switch (deref_array->deref_array_type) {
> + case nir_deref_array_type_direct:
> + instr->sampler_index += deref_array->base_offset;
> + if (deref_array->deref.child)
> + ralloc_asprintf_append(&name, "[%u]", deref_array->base_offset);
> + break;
> + case nir_deref_array_type_indirect: {
> + assert(!instr->has_sampler_indirect);
> +
> + nir_instr_rewrite_src(&instr->instr, &instr->sampler_indirect,
> + nir_src_copy(deref_array->indirect, mem_ctx));
> + instr->has_sampler_indirect = true;
> + instr->sampler_indirect_max = glsl_get_length(deref->type) - 1;
> +
> + nir_src empty;
> + memset(&empty, 0, sizeof empty);
> + nir_instr_rewrite_src(&instr->instr, &deref_array->indirect, empty);
> +
> + if (deref_array->deref.child)
> + ralloc_strcat(&name, "[0]");
> + break;
> }
> +
> + case nir_deref_array_type_wildcard:
> + unreachable("Cannot copy samplers");
> + default:
> + unreachable("Invalid deref array type");
> + }
> + break;
> }
>
> - instr->sampler = NULL;
> + case nir_deref_type_struct: {
> + nir_deref_struct *deref_struct = nir_deref_as_struct(deref->child);
> + const char *field = glsl_get_struct_elem_name(deref->type,
> + deref_struct->index);
> + ralloc_asprintf_append(&name, ".%s", field);
> + break;
> + }
> +
> + default:
> + unreachable("Invalid deref type");
> + break;
> + }
> }
> +
> + instr->sampler_index += get_sampler_index(shader_program, name, prog);
> +
> + instr->sampler = NULL;
> }
>
> typedef struct {
> + void *mem_ctx;
> struct gl_shader_program *shader_program;
> struct gl_program *prog;
> } lower_state;
> @@ -154,7 +149,8 @@ lower_block_cb(nir_block *block, void *_state)
> nir_foreach_instr(block, instr) {
> if (instr->type == nir_instr_type_tex) {
> nir_tex_instr *tex_instr = nir_instr_as_tex(instr);
> - lower_sampler(tex_instr, state->shader_program, state->prog);
> + lower_sampler(tex_instr, state->shader_program, state->prog,
> + state->mem_ctx);
> }
> }
>
> @@ -166,8 +162,11 @@ lower_impl(nir_function_impl *impl, struct gl_shader_program *shader_program,
> struct gl_program *prog)
> {
> lower_state state;
> +
> + state.mem_ctx = ralloc_parent(impl);
> state.shader_program = shader_program;
> state.prog = prog;
> +
> nir_foreach_block(impl, lower_block_cb, &state);
> }
>
> --
> 2.2.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list