X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_program.c;h=bfc6d90922a4fec629ec70e20e8238fd4fd36ea1;hb=d3faac7a155969722cd5c1e7806c141762c39757;hp=a060880092eac2f2c2723b095be7e5b0614245b1;hpb=a398a9d7e7f8fe19eaa0c33b36ab6816472b698c;p=mesa.git diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index a060880092e..bfc6d90922a 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -1,8 +1,8 @@ /************************************************************************** - * + * * Copyright 2007 VMware, Inc. * All Rights Reserved. - * + * * 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 @@ -10,11 +10,11 @@ * distribute, sub license, 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 NON-INFRINGEMENT. @@ -22,7 +22,7 @@ * 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. - * + * **************************************************************************/ /* * Authors: @@ -32,7 +32,7 @@ #include "main/errors.h" -#include "main/imports.h" + #include "main/hash.h" #include "main/mtypes.h" #include "program/prog_parameter.h" @@ -53,6 +53,8 @@ #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_ureg.h" +#include "util/u_memory.h" + #include "st_debug.h" #include "st_cb_bitmap.h" #include "st_cb_drawpixels.h" @@ -68,6 +70,8 @@ #include "cso_cache/cso_context.h" +static void +destroy_program_variants(struct st_context *st, struct gl_program *target); static void set_affected_state_flags(uint64_t *states, @@ -334,6 +338,19 @@ st_release_variants(struct st_context *st, struct st_program *p) */ } +/** + * Free all basic program variants and unref program. + */ +void +st_release_program(struct st_context *st, struct st_program **p) +{ + if (!*p) + return; + + destroy_program_variants(st, &((*p)->Base)); + st_reference_prog(st, p, NULL); +} + void st_finalize_nir_before_variants(struct nir_shader *nir) { @@ -371,6 +388,7 @@ st_translate_prog_to_nir(struct st_context *st, struct gl_program *prog, NIR_PASS_V(nir, st_nir_lower_wpos_ytransform, prog, screen); NIR_PASS_V(nir, nir_lower_system_values); + NIR_PASS_V(nir, nir_lower_compute_system_values, NULL); /* Optimise NIR */ NIR_PASS_V(nir, nir_opt_constant_folding); @@ -478,8 +496,6 @@ st_translate_vertex_program(struct st_context *st, if (stp->Base.arb.IsPositionInvariant) _mesa_insert_mvp_code(st->ctx, &stp->Base); - st_prepare_vertex_program(stp); - /* ARB_vp: */ if (!stp->glsl_to_tgsi) { _mesa_remove_output_reads(&stp->Base, PROGRAM_OUTPUT); @@ -511,14 +527,34 @@ st_translate_vertex_program(struct st_context *st, stp->state.type = PIPE_SHADER_IR_NIR; stp->Base.nir = st_translate_prog_to_nir(st, &stp->Base, MESA_SHADER_VERTEX); + + /* We must update stp->Base.info after translation and before + * st_prepare_vertex_program is called, because inputs_read + * may become outdated after NIR optimization passes. + * + * For ffvp/ARB_vp inputs_read is populated based + * on declared attributes without taking their usage into + * consideration. When creating shader variants we expect + * that their inputs_read would match the base ones for + * input mapping to work properly. + */ + nir_shader_gather_info(stp->Base.nir, + nir_shader_get_entrypoint(stp->Base.nir)); + st_nir_assign_vs_in_locations(stp->Base.nir); + stp->Base.info = stp->Base.nir->info; + /* For st_draw_feedback, we need to generate TGSI too if draw doesn't * use LLVM. */ - if (draw_has_llvm()) + if (draw_has_llvm()) { + st_prepare_vertex_program(stp); return true; + } } } + st_prepare_vertex_program(stp); + /* Get semantic names and indices. */ for (attr = 0; attr < VARYING_SLOT_MAX; attr++) { if (stp->Base.info.outputs_written & BITFIELD64_BIT(attr)) { @@ -633,6 +669,47 @@ get_nir_shader(struct st_context *st, struct st_program *stp) return nir_deserialize(NULL, options, &blob_reader); } +static void +lower_ucp(struct st_context *st, + struct nir_shader *nir, + unsigned ucp_enables, + struct gl_program_parameter_list *params) +{ + if (nir->info.outputs_written & VARYING_BIT_CLIP_DIST0) + NIR_PASS_V(nir, nir_lower_clip_disable, ucp_enables); + else { + struct pipe_screen *screen = st->pipe->screen; + bool can_compact = screen->get_param(screen, + PIPE_CAP_NIR_COMPACT_ARRAYS); + bool use_eye = st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] != NULL; + + gl_state_index16 clipplane_state[MAX_CLIP_PLANES][STATE_LENGTH]; + for (int i = 0; i < MAX_CLIP_PLANES; ++i) { + if (use_eye) { + clipplane_state[i][0] = STATE_CLIPPLANE; + clipplane_state[i][1] = i; + } else { + clipplane_state[i][0] = STATE_INTERNAL; + clipplane_state[i][1] = STATE_CLIP_INTERNAL; + clipplane_state[i][2] = i; + } + _mesa_add_state_reference(params, clipplane_state[i]); + } + + if (nir->info.stage == MESA_SHADER_VERTEX) { + NIR_PASS_V(nir, nir_lower_clip_vs, ucp_enables, + true, can_compact, clipplane_state); + } else if (nir->info.stage == MESA_SHADER_GEOMETRY) { + NIR_PASS_V(nir, nir_lower_clip_gs, ucp_enables, + can_compact, clipplane_state); + } + + NIR_PASS_V(nir, nir_lower_io_to_temporaries, + nir_shader_get_entrypoint(nir), true, false); + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + } +} + static const gl_state_index16 depth_range_state[STATE_LENGTH] = { STATE_DEPTH_RANGE }; @@ -643,7 +720,6 @@ st_create_vp_variant(struct st_context *st, { struct st_common_variant *vpv = CALLOC_STRUCT(st_common_variant); struct pipe_context *pipe = st->pipe; - struct pipe_screen *screen = pipe->screen; struct pipe_shader_state state = {0}; static const gl_state_index16 point_size_state[STATE_LENGTH] = @@ -677,28 +753,7 @@ st_create_vp_variant(struct st_context *st, } if (key->lower_ucp) { - bool can_compact = screen->get_param(screen, - PIPE_CAP_NIR_COMPACT_ARRAYS); - - bool use_eye = st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] != NULL; - gl_state_index16 clipplane_state[MAX_CLIP_PLANES][STATE_LENGTH]; - for (int i = 0; i < MAX_CLIP_PLANES; ++i) { - if (use_eye) { - clipplane_state[i][0] = STATE_CLIPPLANE; - clipplane_state[i][1] = i; - } else { - clipplane_state[i][0] = STATE_INTERNAL; - clipplane_state[i][1] = STATE_CLIP_INTERNAL; - clipplane_state[i][2] = i; - } - _mesa_add_state_reference(params, clipplane_state[i]); - } - - NIR_PASS_V(state.ir.nir, nir_lower_clip_vs, key->lower_ucp, - true, can_compact, clipplane_state); - NIR_PASS_V(state.ir.nir, nir_lower_io_to_temporaries, - nir_shader_get_entrypoint(state.ir.nir), true, false); - NIR_PASS_V(state.ir.nir, nir_lower_global_vars_to_local); + lower_ucp(st, state.ir.nir, key->lower_ucp, params); finalize = true; } @@ -1237,13 +1292,14 @@ st_create_fp_variant(struct st_context *st, } if (key->lower_two_sided_color) { - NIR_PASS_V(state.ir.nir, nir_lower_two_sided_color); + bool face_sysval = st->ctx->Const.GLSLFrontFacingIsSysVal; + NIR_PASS_V(state.ir.nir, nir_lower_two_sided_color, face_sysval); finalize = true; } if (key->persample_shading) { nir_shader *shader = state.ir.nir; - nir_foreach_variable(var, &shader->inputs) + nir_foreach_shader_in_variable(var, shader) var->data.sample = true; finalize = true; } @@ -1733,6 +1789,7 @@ st_get_common_variant(struct st_context *st, struct pipe_context *pipe = st->pipe; struct st_variant *v; struct pipe_shader_state state = {0}; + struct gl_program_parameter_list *params = prog->Base.Parameters; /* Search for existing variant */ for (v = prog->variants; v; v = v->next) { @@ -1755,6 +1812,11 @@ st_get_common_variant(struct st_context *st, finalize = true; } + if (key->lower_ucp) { + lower_ucp(st, state.ir.nir, key->lower_ucp, params); + finalize = true; + } + state.stream_output = prog->state.stream_output; if (finalize || !st->allow_st_finalize_nir_twice) {