diff options
-rw-r--r-- | src/mesa/state_tracker/st_glsl_to_nir.cpp.orig | 479 |
1 files changed, 0 insertions, 479 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_nir.cpp.orig b/src/mesa/state_tracker/st_glsl_to_nir.cpp.orig deleted file mode 100644 index 38d6c7068c2..00000000000 --- a/src/mesa/state_tracker/st_glsl_to_nir.cpp.orig +++ /dev/null @@ -1,479 +0,0 @@ -/* - * Copyright © 2015 Red Hat - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "st_nir.h" - -#include "pipe/p_defines.h" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -#include "program/program.h" -#include "program/prog_statevars.h" -#include "program/prog_parameter.h" -#include "program/ir_to_mesa.h" -#include "main/mtypes.h" -#include "main/errors.h" -#include "main/shaderapi.h" -#include "main/uniforms.h" -#include "util/string_to_uint_map.h" - -#include "st_context.h" -#include "st_program.h" - -#include "compiler/nir/nir.h" -#include "compiler/glsl_types.h" -#include "compiler/glsl/glsl_to_nir.h" -#include "compiler/glsl/ir.h" - - -static int -type_size(const struct glsl_type *type) -{ - return type->count_attribute_slots(false); -} - -/* Depending on PIPE_CAP_TGSI_TEXCOORD (st->needs_texcoord_semantic) we - * may need to fix up varying slots so the glsl->nir path is aligned - * with the anything->tgsi->nir path. - */ -static void -st_nir_fixup_varying_slots(struct st_context *st, struct exec_list *var_list) -{ - if (st->needs_texcoord_semantic) - return; - - nir_foreach_variable(var, var_list) { - if (var->data.location >= VARYING_SLOT_VAR0) { - var->data.location += 9; - } else if ((var->data.location >= VARYING_SLOT_TEX0) && - (var->data.location <= VARYING_SLOT_TEX7)) { - var->data.location += VARYING_SLOT_VAR0 - VARYING_SLOT_TEX0; - } - } -} - -/* input location assignment for VS inputs must be handled specially, so - * that it is aligned w/ st's vbo state. - * (This isn't the case with, for ex, FS inputs, which only need to agree - * on varying-slot w/ the VS outputs) - */ -static void -st_nir_assign_vs_in_locations(struct gl_program *prog, nir_shader *nir) -{ - unsigned attr, num_inputs = 0; - unsigned input_to_index[VERT_ATTRIB_MAX] = {0}; - - /* TODO de-duplicate w/ similar code in st_translate_vertex_program()? */ - for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) { - if ((prog->info.inputs_read & BITFIELD64_BIT(attr)) != 0) { - input_to_index[attr] = num_inputs; - num_inputs++; - if ((prog->info.double_inputs_read & BITFIELD64_BIT(attr)) != 0) { - /* add placeholder for second part of a double attribute */ - num_inputs++; - } - } else { - input_to_index[attr] = ~0; - } - } - - /* bit of a hack, mirroring st_translate_vertex_program */ - input_to_index[VERT_ATTRIB_EDGEFLAG] = num_inputs; - - nir->num_inputs = 0; - nir_foreach_variable_safe(var, &nir->inputs) { - attr = var->data.location; - assert(attr < ARRAY_SIZE(input_to_index)); - - if (input_to_index[attr] != ~0u) { - var->data.driver_location = input_to_index[attr]; - nir->num_inputs++; - } else { - /* Move unused input variables to the globals list (with no - * initialization), to avoid confusing drivers looking through the - * inputs array and expecting to find inputs with a driver_location - * set. - */ - exec_node_remove(&var->node); - var->data.mode = nir_var_global; - exec_list_push_tail(&nir->globals, &var->node); - } - } -} - -static int -st_nir_lookup_parameter_index(const struct gl_program_parameter_list *params, - const char *name) -{ - int loc = _mesa_lookup_parameter_index(params, name); - - /* is there a better way to do this? If we have something like: - * - * struct S { - * float f; - * vec4 v; - * }; - * uniform S color; - * - * Then what we get in prog->Parameters looks like: - * - * 0: Name=color.f, Type=6, DataType=1406, Size=1 - * 1: Name=color.v, Type=6, DataType=8b52, Size=4 - * - * So the name doesn't match up and _mesa_lookup_parameter_index() - * fails. In this case just find the first matching "color.*".. - * - * Note for arrays you could end up w/ color[n].f, for example. - * - * glsl_to_tgsi works slightly differently in this regard. It is - * emitting something more low level, so it just translates the - * params list 1:1 to CONST[] regs. Going from GLSL IR to TGSI, - * it just calculates the additional offset of struct field members - * in glsl_to_tgsi_visitor::visit(ir_dereference_record *ir) or - * glsl_to_tgsi_visitor::visit(ir_dereference_array *ir). It never - * needs to work backwards to get base var loc from the param-list - * which already has them separated out. - */ - if (loc < 0) { - int namelen = strlen(name); - for (unsigned i = 0; i < params->NumParameters; i++) { - struct gl_program_parameter *p = ¶ms->Parameters[i]; - if ((strncmp(p->Name, name, namelen) == 0) && - ((p->Name[namelen] == '.') || (p->Name[namelen] == '['))) { - loc = i; - break; - } - } - } - - return loc; -} - -static void -st_nir_assign_uniform_locations(struct gl_program *prog, - struct gl_shader_program *shader_program, - struct exec_list *uniform_list, unsigned *size) -{ - int max = 0; - int shaderidx = 0; - - nir_foreach_variable(uniform, uniform_list) { - int loc; - - /* - * UBO's have their own address spaces, so don't count them towards the - * number of global uniforms - */ - if ((uniform->data.mode == nir_var_uniform || uniform->data.mode == nir_var_shader_storage) && - uniform->interface_type != NULL) - continue; - - if (uniform->type->is_sampler()) { - unsigned val = 0; - bool found = shader_program->UniformHash->get(val, uniform->name); - loc = shaderidx++; - assert(found); - (void) found; /* silence unused var warning */ - /* this ensure that nir_lower_samplers looks at the correct - * shader_program->UniformStorage[location]: - */ - uniform->data.location = val; - } else if (strncmp(uniform->name, "gl_", 3) == 0) { - const gl_state_index *const stateTokens = (gl_state_index *)uniform->state_slots[0].tokens; - /* This state reference has already been setup by ir_to_mesa, but we'll - * get the same index back here. - */ - loc = _mesa_add_state_reference(prog->Parameters, stateTokens); - } else { - loc = st_nir_lookup_parameter_index(prog->Parameters, uniform->name); - } - - uniform->data.driver_location = loc; - - max = MAX2(max, loc + type_size(uniform->type)); - } - *size = max; -} - -extern "C" { - -/* First half of converting glsl_to_nir.. this leaves things in a pre- - * nir_lower_io state, so that shader variants can more easily insert/ - * replace variables, etc. - */ -nir_shader * -st_glsl_to_nir(struct st_context *st, struct gl_program *prog, - struct gl_shader_program *shader_program, - gl_shader_stage stage) -{ - struct pipe_screen *pscreen = st->pipe->screen; - enum pipe_shader_type ptarget = pipe_shader_type_from_mesa(stage); - const nir_shader_compiler_options *options; - nir_shader *nir; - - assert(pscreen->get_compiler_options); /* drivers using NIR must implement this */ - - options = (const nir_shader_compiler_options *) - pscreen->get_compiler_options(pscreen, PIPE_SHADER_IR_NIR, ptarget); - assert(options); - - if (prog->nir) - return prog->nir; - - nir = glsl_to_nir(shader_program, stage, options); - - NIR_PASS_V(nir, nir_lower_io_to_temporaries, - nir_shader_get_entrypoint(nir), - true, true); - NIR_PASS_V(nir, nir_lower_global_vars_to_local); - NIR_PASS_V(nir, nir_split_var_copies); - NIR_PASS_V(nir, nir_lower_var_copies); - NIR_PASS_V(nir, st_nir_lower_builtin); - NIR_PASS_V(nir, nir_lower_atomics, shader_program); - - /* fragment shaders may need : */ - if (stage == MESA_SHADER_FRAGMENT) { - static const gl_state_index wposTransformState[STATE_LENGTH] = { - STATE_INTERNAL, STATE_FB_WPOS_Y_TRANSFORM - }; - nir_lower_wpos_ytransform_options wpos_options = { { 0 } }; - struct pipe_screen *pscreen = st->pipe->screen; - - memcpy(wpos_options.state_tokens, wposTransformState, - sizeof(wpos_options.state_tokens)); - wpos_options.fs_coord_origin_upper_left = - pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT); - wpos_options.fs_coord_origin_lower_left = - pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT); - wpos_options.fs_coord_pixel_center_integer = - pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER); - wpos_options.fs_coord_pixel_center_half_integer = - pscreen->get_param(pscreen, PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER); - - if (nir_lower_wpos_ytransform(nir, &wpos_options)) { - nir_validate_shader(nir); - _mesa_add_state_reference(prog->Parameters, wposTransformState); - } - } - - if (st->ctx->_Shader->Flags & GLSL_DUMP) { - _mesa_log("\n"); - _mesa_log("NIR IR for linked %s program %d:\n", - _mesa_shader_stage_to_string(stage), - shader_program->Name); - nir_print_shader(nir, _mesa_get_log_file()); - _mesa_log("\n\n"); - } - - prog->nir = nir; - - return nir; -} - -/* TODO any better helper somewhere to sort a list? */ - -static void -insert_sorted(struct exec_list *var_list, nir_variable *new_var) -{ - nir_foreach_variable(var, var_list) { - if (var->data.location > new_var->data.location) { - exec_node_insert_node_before(&var->node, &new_var->node); - return; - } - } - exec_list_push_tail(var_list, &new_var->node); -} - -static void -sort_varyings(struct exec_list *var_list) -{ - struct exec_list new_list; - exec_list_make_empty(&new_list); - nir_foreach_variable_safe(var, var_list) { - exec_node_remove(&var->node); - insert_sorted(&new_list, var); - } - exec_list_move_nodes_to(&new_list, var_list); -} - -/* Second half of preparing nir from glsl, which happens after shader - * variant lowering. - */ -void -st_finalize_nir(struct st_context *st, struct gl_program *prog, nir_shader *nir) -{ - struct pipe_screen *screen = st->pipe->screen; - - NIR_PASS_V(nir, nir_split_var_copies); - NIR_PASS_V(nir, nir_lower_var_copies); - NIR_PASS_V(nir, nir_lower_io_types); - - if (nir->stage == MESA_SHADER_VERTEX) { - /* Needs special handling so drvloc matches the vbo state: */ - st_nir_assign_vs_in_locations(prog, nir); - /* Re-lower global vars, to deal with any dead VS inputs. */ - NIR_PASS_V(nir, nir_lower_global_vars_to_local); - - sort_varyings(&nir->outputs); - nir_assign_var_locations(&nir->outputs, - &nir->num_outputs, - type_size); - st_nir_fixup_varying_slots(st, &nir->outputs); - } else if (nir->stage == MESA_SHADER_FRAGMENT) { - sort_varyings(&nir->inputs); - nir_assign_var_locations(&nir->inputs, - &nir->num_inputs, - type_size); - st_nir_fixup_varying_slots(st, &nir->inputs); - nir_assign_var_locations(&nir->outputs, - &nir->num_outputs, - type_size); - } else if (nir->stage == MESA_SHADER_COMPUTE) { - /* TODO? */ - } else { - unreachable("invalid shader type for tgsi bypass\n"); - } - - struct gl_shader_program *shader_program; - switch (nir->stage) { - case MESA_SHADER_VERTEX: - shader_program = ((struct st_vertex_program *)prog)->shader_program; - break; - case MESA_SHADER_FRAGMENT: - shader_program = ((struct st_fragment_program *)prog)->shader_program; - break; - case MESA_SHADER_COMPUTE: - shader_program = ((struct st_compute_program *)prog)->shader_program; - break; - default: - assert(!"should not be reached"); - return; - } - - NIR_PASS_V(nir, nir_lower_atomics_to_ssbo, - st->ctx->Const.Program[nir->stage].MaxAtomicBuffers); - - st_nir_assign_uniform_locations(prog, shader_program, - &nir->uniforms, &nir->num_uniforms); - - NIR_PASS_V(nir, nir_lower_system_values); - - if (screen->get_param(screen, PIPE_CAP_NIR_SAMPLERS_AS_DEREF)) - NIR_PASS_V(nir, nir_lower_samplers_as_deref, shader_program); - else - NIR_PASS_V(nir, nir_lower_samplers, shader_program); -} - -struct gl_program * -st_nir_get_mesa_program(struct gl_context *ctx, - struct gl_shader_program *shader_program, - struct gl_linked_shader *shader) -{ - struct gl_program *prog; - - validate_ir_tree(shader->ir); - - prog = shader->Program; - - prog->Parameters = _mesa_new_parameter_list(); - - do_set_program_inouts(shader->ir, prog, shader->Stage); - - _mesa_copy_linked_program_data(shader_program, shader); - _mesa_generate_parameters_list_for_uniforms(ctx, shader_program, shader, - prog->Parameters); - - /* Make a pass over the IR to add state references for any built-in - * uniforms that are used. This has to be done now (during linking). - * Code generation doesn't happen until the first time this shader is - * used for rendering. Waiting until then to generate the parameters is - * too late. At that point, the values for the built-in uniforms won't - * get sent to the shader. - */ - foreach_in_list(ir_instruction, node, shader->ir) { - ir_variable *var = node->as_variable(); - - if ((var == NULL) || (var->data.mode != ir_var_uniform) || - (strncmp(var->name, "gl_", 3) != 0)) - continue; - - const ir_state_slot *const slots = var->get_state_slots(); - assert(slots != NULL); - - for (unsigned int i = 0; i < var->get_num_state_slots(); i++) { - _mesa_add_state_reference(prog->Parameters, - (gl_state_index *) slots[i].tokens); - } - } - - if (ctx->_Shader->Flags & GLSL_DUMP) { - _mesa_log("\n"); - _mesa_log("GLSL IR for linked %s program %d:\n", - _mesa_shader_stage_to_string(shader->Stage), - shader_program->Name); - _mesa_print_ir(_mesa_get_log_file(), shader->ir, NULL); - _mesa_log("\n\n"); - } - - prog->ShadowSamplers = shader->shadow_samplers; - prog->ExternalSamplersUsed = gl_external_samplers(prog); - _mesa_update_shader_textures_used(shader_program, prog); - - /* Avoid reallocation of the program parameter list, because the uniform - * storage is only associated with the original parameter list. - * This should be enough for Bitmap and DrawPixels constants. - */ - _mesa_reserve_parameter_storage(prog->Parameters, 8); - - /* This has to be done last. Any operation the can cause - * prog->ParameterValues to get reallocated (e.g., anything that adds a - * program constant) has to happen before creating this linkage. - */ - _mesa_associate_uniform_storage(ctx, shader_program, prog, true); - - struct st_vertex_program *stvp; - struct st_fragment_program *stfp; - struct st_compute_program *stcp; - - switch (shader->Stage) { - case MESA_SHADER_VERTEX: - stvp = (struct st_vertex_program *)prog; - stvp->shader_program = shader_program; - break; - case MESA_SHADER_FRAGMENT: - stfp = (struct st_fragment_program *)prog; - stfp->shader_program = shader_program; - break; - case MESA_SHADER_COMPUTE: - stcp = (struct st_compute_program *)prog; - stcp->shader_program = shader_program; - break; - default: - assert(!"should not be reached"); - return NULL; - } - - return prog; -} - -} /* extern "C" */ |