X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fstate_tracker%2Fst_program.c;h=f052655efcee8d76ef5734eac9d8972dd634915d;hb=500b0735c0caa293d22fb3728cb76d267a016834;hp=c0e63b8a98c8cae18625c7fe25977c7085885ad9;hpb=84e845c9696ab673f1d95fda47843028ed0c71a7;p=mesa.git diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index c0e63b8a98c..f052655efce 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 "util/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, @@ -343,7 +347,7 @@ st_release_program(struct st_context *st, struct st_program **p) if (!*p) return; - st_release_variants(st, *p); + destroy_program_variants(st, &((*p)->Base)); st_reference_prog(st, p, NULL); } @@ -384,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); @@ -491,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); @@ -508,7 +511,8 @@ st_translate_vertex_program(struct st_context *st, stp->affected_states |= ST_NEW_VS_CONSTANTS; /* Translate to NIR if preferred. */ - if (st->pipe->screen->get_shader_param(st->pipe->screen, + if (PIPE_SHADER_IR_NIR == + st->pipe->screen->get_shader_param(st->pipe->screen, PIPE_SHADER_VERTEX, PIPE_SHADER_CAP_PREFERRED_IR)) { assert(!stp->glsl_to_tgsi); @@ -524,14 +528,35 @@ 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()) + /* TODO: Draw can't handle lowered IO. */ + if (draw_has_llvm() && !stp->Base.info.io_lowered) { + 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)) { @@ -551,12 +576,7 @@ st_translate_vertex_program(struct st_context *st, if (ureg == NULL) return false; - if (stp->Base.info.clip_distance_array_size) - ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED, - stp->Base.info.clip_distance_array_size); - if (stp->Base.info.cull_distance_array_size) - ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED, - stp->Base.info.cull_distance_array_size); + ureg_setup_shader_info(ureg, &stp->Base.info); if (ST_DEBUG & DEBUG_MESA) { _mesa_print_program(&stp->Base); @@ -646,6 +666,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 }; @@ -656,7 +717,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] = @@ -668,7 +728,9 @@ st_create_vp_variant(struct st_context *st, state.stream_output = stvp->state.stream_output; if (stvp->state.type == PIPE_SHADER_IR_NIR && - (!key->is_draw_shader || draw_has_llvm())) { + (!key->is_draw_shader || + /* TODO: Draw can't handle lowered IO. */ + (draw_has_llvm() && !stvp->Base.info.io_lowered))) { bool finalize = false; state.type = PIPE_SHADER_IR_NIR; @@ -690,28 +752,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; } @@ -861,6 +902,7 @@ st_translate_fragment_program(struct st_context *st, /* Translate to NIR. */ if (!stfp->ati_fs && + PIPE_SHADER_IR_NIR == st->pipe->screen->get_shader_param(st->pipe->screen, PIPE_SHADER_FRAGMENT, PIPE_SHADER_CAP_PREFERRED_IR)) { @@ -1111,6 +1153,8 @@ st_translate_fragment_program(struct st_context *st, if (ureg == NULL) return false; + ureg_setup_shader_info(ureg, &stfp->Base.info); + if (ST_DEBUG & DEBUG_MESA) { _mesa_print_program(&stfp->Base); _mesa_print_program_parameters(st->ctx, &stfp->Base); @@ -1119,29 +1163,6 @@ st_translate_fragment_program(struct st_context *st, if (write_all == GL_TRUE) ureg_property(ureg, TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS, 1); - if (stfp->Base.info.fs.depth_layout != FRAG_DEPTH_LAYOUT_NONE) { - switch (stfp->Base.info.fs.depth_layout) { - case FRAG_DEPTH_LAYOUT_ANY: - ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, - TGSI_FS_DEPTH_LAYOUT_ANY); - break; - case FRAG_DEPTH_LAYOUT_GREATER: - ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, - TGSI_FS_DEPTH_LAYOUT_GREATER); - break; - case FRAG_DEPTH_LAYOUT_LESS: - ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, - TGSI_FS_DEPTH_LAYOUT_LESS); - break; - case FRAG_DEPTH_LAYOUT_UNCHANGED: - ureg_property(ureg, TGSI_PROPERTY_FS_DEPTH_LAYOUT, - TGSI_FS_DEPTH_LAYOUT_UNCHANGED); - break; - default: - assert(0); - } - } - if (stfp->glsl_to_tgsi) { st_translate_program(st->ctx, PIPE_SHADER_FRAGMENT, @@ -1250,13 +1271,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; } @@ -1562,48 +1584,7 @@ st_translate_common_program(struct st_context *st, if (ureg == NULL) return false; - switch (stage) { - case PIPE_SHADER_TESS_CTRL: - ureg_property(ureg, TGSI_PROPERTY_TCS_VERTICES_OUT, - stp->Base.info.tess.tcs_vertices_out); - break; - - case PIPE_SHADER_TESS_EVAL: - if (stp->Base.info.tess.primitive_mode == GL_ISOLINES) - ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, GL_LINES); - else - ureg_property(ureg, TGSI_PROPERTY_TES_PRIM_MODE, - stp->Base.info.tess.primitive_mode); - - STATIC_ASSERT((TESS_SPACING_EQUAL + 1) % 3 == PIPE_TESS_SPACING_EQUAL); - STATIC_ASSERT((TESS_SPACING_FRACTIONAL_ODD + 1) % 3 == - PIPE_TESS_SPACING_FRACTIONAL_ODD); - STATIC_ASSERT((TESS_SPACING_FRACTIONAL_EVEN + 1) % 3 == - PIPE_TESS_SPACING_FRACTIONAL_EVEN); - - ureg_property(ureg, TGSI_PROPERTY_TES_SPACING, - (stp->Base.info.tess.spacing + 1) % 3); - - ureg_property(ureg, TGSI_PROPERTY_TES_VERTEX_ORDER_CW, - !stp->Base.info.tess.ccw); - ureg_property(ureg, TGSI_PROPERTY_TES_POINT_MODE, - stp->Base.info.tess.point_mode); - break; - - case PIPE_SHADER_GEOMETRY: - ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, - stp->Base.info.gs.input_primitive); - ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, - stp->Base.info.gs.output_primitive); - ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, - stp->Base.info.gs.vertices_out); - ureg_property(ureg, TGSI_PROPERTY_GS_INVOCATIONS, - stp->Base.info.gs.invocations); - break; - - default: - break; - } + ureg_setup_shader_info(ureg, &stp->Base.info); ubyte inputSlotToAttr[VARYING_SLOT_TESS_MAX]; ubyte inputMapping[VARYING_SLOT_TESS_MAX]; @@ -1625,13 +1606,6 @@ st_translate_common_program(struct st_context *st, memset(outputMapping, 0, sizeof(outputMapping)); memset(&stp->state, 0, sizeof(stp->state)); - if (prog->info.clip_distance_array_size) - ureg_property(ureg, TGSI_PROPERTY_NUM_CLIPDIST_ENABLED, - prog->info.clip_distance_array_size); - if (prog->info.cull_distance_array_size) - ureg_property(ureg, TGSI_PROPERTY_NUM_CULLDIST_ENABLED, - prog->info.cull_distance_array_size); - /* * Convert Mesa program inputs to TGSI input register semantics. */ @@ -1746,6 +1720,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) { @@ -1768,6 +1743,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) {