From: Timothy Arceri Date: Wed, 19 Oct 2016 22:59:00 +0000 (+1100) Subject: i965: rewrite brw_setup_vue_interpolation() X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=91d61fbf7cb61a44a;p=mesa.git i965: rewrite brw_setup_vue_interpolation() Here brw_setup_vue_interpolation() is rewritten not to use the InterpQualifier array in gl_fragment_program which will allow us to remove it. This change also makes the code which is only used by gen4/5 more self contained as it now has its own gen5_fragment_program struct rather than storing the map in brw_context. This means the interpolation map will only get processed once and will get stored in the in memory cache rather than being processed everytime the fs changes. Also by calling this from the fs compile code rather than from the upload code and using the interpolation assigned there we can get rid of the BRW_NEW_INTERPOLATION_MAP flag. It might not seem ideal to add a gen5_fragment_program struct however by the end of this series we will have gotten rid of all the brw_{shader_stage}_program structs and replaced them with a generic brw_program struct so there will only be two program structs which is better than what we have now. V2: Don't remove BRW_NEW_INTERPOLATION_MAP from dirty_bit_map until the following patch to fix build error. V3 - Suggestions by Jason: - name struct gen4_fragment_program rather than gen5_fragment_program - don't use enum with memset() - create interp mode set helper and simplify logic to call it - add assert when calling function to show prog will never be NULL for gen4/5 i.e. no Vulkan Reviewed-by: Jason Ekstrand Reviewed-by: Kenneth Graunke --- diff --git a/src/intel/blorp/blorp.c b/src/intel/blorp/blorp.c index 5209ee23dea..8905cfa3873 100644 --- a/src/intel/blorp/blorp.c +++ b/src/intel/blorp/blorp.c @@ -211,9 +211,9 @@ brw_blorp_compile_nir_shader(struct blorp_context *blorp, struct nir_shader *nir nir_lower_io(nir, nir_var_uniform, nir_uniform_type_size, 0); const unsigned *program = - brw_compile_fs(compiler, blorp->driver_ctx, mem_ctx, - wm_key, &wm_prog_data, nir, - NULL, -1, -1, false, use_repclear, program_size, NULL); + brw_compile_fs(compiler, blorp->driver_ctx, mem_ctx, wm_key, + &wm_prog_data, nir, NULL, -1, -1, false, use_repclear, + NULL, program_size, NULL); /* Copy the relavent bits of wm_prog_data over into the blorp prog data */ prog_data->dispatch_8 = wm_prog_data.dispatch_8; diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c index 72f0643bd70..0aac7115343 100644 --- a/src/intel/vulkan/anv_pipeline.c +++ b/src/intel/vulkan/anv_pipeline.c @@ -678,7 +678,7 @@ anv_pipeline_compile_fs(struct anv_pipeline *pipeline, unsigned code_size; const unsigned *shader_code = brw_compile_fs(compiler, NULL, mem_ctx, &key, &prog_data, nir, - NULL, -1, -1, true, false, &code_size, NULL); + NULL, -1, -1, true, false, NULL, &code_size, NULL); if (shader_code == NULL) { ralloc_free(mem_ctx); return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c index 1134fa43878..8646b9e0154 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.c +++ b/src/mesa/drivers/dri/i965/brw_clip.c @@ -68,11 +68,6 @@ static void compile_clip_prog( struct brw_context *brw, c.key = *key; c.vue_map = brw->vue_map_geom_out; - c.has_flat_shading = - brw_any_flat_varyings(&key->interpolation_mode); - c.has_noperspective_shading = - brw_any_noperspective_varyings(&key->interpolation_mode); - /* nr_regs is the number of registers filled by reading data from the VUE. * This program accesses the entire VUE, so nr_regs needs to be the size of * the VUE (measured in pairs, since two slots are stored in each @@ -144,7 +139,7 @@ brw_upload_clip_prog(struct brw_context *brw) _NEW_POLYGON | _NEW_TRANSFORM, BRW_NEW_BLORP | - BRW_NEW_INTERPOLATION_MAP | + BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_REDUCED_PRIMITIVE | BRW_NEW_VUE_MAP_GEOM_OUT)) return; @@ -154,8 +149,16 @@ brw_upload_clip_prog(struct brw_context *brw) /* Populate the key: */ - /* BRW_NEW_INTERPOLATION_MAP */ - key.interpolation_mode = brw->interpolation_mode; + const struct gl_fragment_program *fprog = brw->fragment_program; + if (fprog) { + assert(brw->gen < 6); + struct gen4_fragment_program *p = (struct gen4_fragment_program *) fprog; + + /* BRW_NEW_FRAGMENT_PROGRAM */ + key.contains_flat_varying = p->contains_flat_varying; + key.contains_noperspective_varying = p->contains_noperspective_varying; + key.interp_mode = p->interp_mode; + } /* BRW_NEW_REDUCED_PRIMITIVE */ key.primitive = brw->reduced_primitive; diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h index 54c76822e22..355ae64eefe 100644 --- a/src/mesa/drivers/dri/i965/brw_clip.h +++ b/src/mesa/drivers/dri/i965/brw_clip.h @@ -47,7 +47,9 @@ */ struct brw_clip_prog_key { GLbitfield64 attrs; - struct interpolation_mode_map interpolation_mode; + bool contains_flat_varying; + bool contains_noperspective_varying; + unsigned char *interp_mode; GLuint primitive:4; GLuint nr_userclip:4; GLuint pv_first:1; @@ -128,9 +130,6 @@ struct brw_clip_compile { bool need_direction; struct brw_vue_map vue_map; - - bool has_flat_shading; - bool has_noperspective_shading; }; /** diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index 2c7f85a0e60..f9cabd2f98d 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -302,7 +302,7 @@ void brw_emit_line_clip( struct brw_clip_compile *c ) brw_clip_line_alloc_regs(c); brw_clip_init_ff_sync(c); - if (c->has_flat_shading) { + if (c->key.contains_flat_varying) { if (c->key.pv_first) brw_clip_copy_flatshaded_attributes(c, 1, 0); else diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index 4caa8f5aa07..52402e30bcf 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -650,7 +650,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c ) * flatshading, need to apply the flatshade here because we don't * respect the PV when converting to trifan for emit: */ - if (c->has_flat_shading) + if (c->key.contains_flat_varying) brw_clip_tri_flat_shade(c); if ((c->key.clip_mode == BRW_CLIPMODE_NORMAL) || diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c index d333d10d299..7c06857ff61 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c +++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c @@ -519,7 +519,7 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c ) /* Need to do this whether we clip or not: */ - if (c->has_flat_shading) + if (c->key.contains_flat_varying) brw_clip_tri_flat_shade(c); brw_clip_init_clipmask(c); diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c index f5d0a5ad946..4f1b0fd9fc9 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_util.c +++ b/src/mesa/drivers/dri/i965/brw_clip_util.c @@ -157,7 +157,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, */ /* Take a copy of the v0 NDC coordinates, in case dest == v0. */ - if (c->has_noperspective_shading) { + if (c->key.contains_noperspective_varying) { GLuint offset = brw_varying_to_offset(&c->vue_map, BRW_VARYING_SLOT_NDC); v0_ndc_copy = get_tmp(c); @@ -183,7 +183,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, /* If we have noperspective attributes, * we need to compute the screen-space t */ - if (c->has_noperspective_shading) { + if (c->key.contains_noperspective_varying) { GLuint delta = brw_varying_to_offset(&c->vue_map, BRW_VARYING_SLOT_NDC); struct brw_reg tmp = get_tmp(c); @@ -272,7 +272,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, * Unless the attribute is flat shaded -- in which case just copy * from one of the sources (doesn't matter which; already copied from pv) */ - GLuint interp = c->key.interpolation_mode.mode[slot]; + GLuint interp = c->key.interp_mode[slot]; if (interp != INTERP_MODE_FLAT) { struct brw_reg tmp = get_tmp(c); @@ -310,7 +310,7 @@ void brw_clip_interp_vertex( struct brw_clip_compile *c, brw_MOV(p, deref_4f(dest_ptr, delta), brw_imm_f(0)); } - if (c->has_noperspective_shading) + if (c->key.contains_noperspective_varying) release_tmp(c, t_nopersp); } @@ -406,7 +406,7 @@ void brw_clip_copy_flatshaded_attributes( struct brw_clip_compile *c, struct brw_codegen *p = &c->func; for (int i = 0; i < c->vue_map.num_slots; i++) { - if (c->key.interpolation_mode.mode[i] == INTERP_MODE_FLAT) { + if (c->key.interp_mode[i] == INTERP_MODE_FLAT) { brw_MOV(p, byte_offset(c->reg.vertex[to], brw_vue_slot_to_offset(i)), byte_offset(c->reg.vertex[from], brw_vue_slot_to_offset(i))); diff --git a/src/mesa/drivers/dri/i965/brw_compiler.h b/src/mesa/drivers/dri/i965/brw_compiler.h index 447d05b8198..772c11ee170 100644 --- a/src/mesa/drivers/dri/i965/brw_compiler.h +++ b/src/mesa/drivers/dri/i965/brw_compiler.h @@ -575,6 +575,12 @@ void brw_compute_tess_vue_map(struct brw_vue_map *const vue_map, const GLbitfield64 slots_valid, const GLbitfield is_patch); +/* brw_interpolation_map.c */ +void brw_setup_vue_interpolation(struct brw_vue_map *vue_map, + struct nir_shader *nir, + struct gl_program *prog, + const struct gen_device_info *devinfo); + enum shader_dispatch_mode { DISPATCH_MODE_4X1_SINGLE = 0, DISPATCH_MODE_4X2_DUAL_INSTANCE = 1, @@ -834,7 +840,7 @@ brw_compile_fs(const struct brw_compiler *compiler, void *log_data, int shader_time_index8, int shader_time_index16, bool allow_spilling, - bool use_rep_send, + bool use_rep_send, struct brw_vue_map *vue_map, unsigned *final_assembly_size, char **error_str); diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index e190d531c80..a40ba86d231 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -363,6 +363,20 @@ struct brw_fragment_program { }; +struct gen4_fragment_program { + struct brw_fragment_program base; + + bool contains_flat_varying; + bool contains_noperspective_varying; + + /* + * Mapping of varying slots to interpolation modes. + * Used Gen4/5 by the clip|sf|wm stages. + */ + unsigned char interp_mode[BRW_VARYING_SLOT_COUNT]; +}; + + /** Subclass of Mesa compute program */ struct brw_compute_program { struct gl_program program; @@ -385,32 +399,6 @@ struct brw_shader { ~VARYING_BIT_POS & ~VARYING_BIT_FACE) -/* - * Mapping of VUE map slots to interpolation modes. - */ -struct interpolation_mode_map { - unsigned char mode[BRW_VARYING_SLOT_COUNT]; -}; - -static inline bool brw_any_flat_varyings(struct interpolation_mode_map *map) -{ - for (int i = 0; i < BRW_VARYING_SLOT_COUNT; i++) - if (map->mode[i] == INTERP_MODE_FLAT) - return true; - - return false; -} - -static inline bool brw_any_noperspective_varyings(struct interpolation_mode_map *map) -{ - for (int i = 0; i < BRW_VARYING_SLOT_COUNT; i++) - if (map->mode[i] == INTERP_MODE_NOPERSPECTIVE) - return true; - - return false; -} - - struct brw_sf_prog_data { GLuint urb_read_length; GLuint total_grf; @@ -1273,11 +1261,6 @@ struct brw_context uint32_t render_target_format[MESA_FORMAT_COUNT]; bool format_supported_as_render_target[MESA_FORMAT_COUNT]; - /* Interpolation modes, one byte per vue slot. - * Used Gen4/5 by the clip|sf|wm stages. Ignored on Gen6+. - */ - struct interpolation_mode_map interpolation_mode; - /* PrimitiveRestart */ struct { bool in_progress; diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp index ea8c2e67d54..f839d368f3c 100644 --- a/src/mesa/drivers/dri/i965/brw_fs.cpp +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp @@ -6415,14 +6415,14 @@ brw_compile_fs(const struct brw_compiler *compiler, void *log_data, struct gl_program *prog, int shader_time_index8, int shader_time_index16, bool allow_spilling, - bool use_rep_send, + bool use_rep_send, struct brw_vue_map *vue_map, unsigned *final_assembly_size, char **error_str) { nir_shader *shader = nir_shader_clone(mem_ctx, src_shader); shader = brw_nir_apply_sampler_key(shader, compiler->devinfo, &key->tex, true); - brw_nir_lower_fs_inputs(shader, compiler->devinfo, key); + brw_nir_lower_fs_inputs(shader, vue_map, prog, compiler->devinfo, key); brw_nir_lower_fs_outputs(shader); if (!key->multisample_fbo) NIR_PASS_V(shader, demote_sample_qualifiers); diff --git a/src/mesa/drivers/dri/i965/brw_interpolation_map.c b/src/mesa/drivers/dri/i965/brw_interpolation_map.c index 097987b4684..fe14ea33f45 100644 --- a/src/mesa/drivers/dri/i965/brw_interpolation_map.c +++ b/src/mesa/drivers/dri/i965/brw_interpolation_map.c @@ -21,7 +21,8 @@ * IN THE SOFTWARE. */ -#include "brw_state.h" +#include "brw_compiler.h" +#include "brw_context.h" #include "compiler/nir/nir.h" static char const *get_qual_name(int mode) @@ -35,61 +36,61 @@ static char const *get_qual_name(int mode) } } +static void +gen4_frag_prog_set_interp_modes(struct gen4_fragment_program *prog, + struct brw_vue_map *vue_map, + unsigned location, unsigned slot_count, + enum glsl_interp_mode interp) +{ + for (unsigned k = 0; k < slot_count; k++) { + unsigned slot = vue_map->varying_to_slot[location + k]; + if (slot != -1 && prog->interp_mode[slot] == INTERP_MODE_NONE) { + prog->interp_mode[slot] = interp; + + if (prog->interp_mode[slot] == INTERP_MODE_FLAT) { + prog->contains_flat_varying = true; + } else if (prog->interp_mode[slot] == INTERP_MODE_NOPERSPECTIVE) { + prog->contains_noperspective_varying = true; + } + } + } +} /* Set up interpolation modes for every element in the VUE */ void -brw_setup_vue_interpolation(struct brw_context *brw) +brw_setup_vue_interpolation(struct brw_vue_map *vue_map, nir_shader *nir, + struct gl_program *prog, + const struct gen_device_info *devinfo) { - const struct gl_fragment_program *fprog = brw->fragment_program; - struct brw_vue_map *vue_map = &brw->vue_map_geom_out; - - if (!brw_state_dirty(brw, - _NEW_LIGHT, - BRW_NEW_BLORP | - BRW_NEW_FRAGMENT_PROGRAM | - BRW_NEW_VUE_MAP_GEOM_OUT)) - return; + struct gen4_fragment_program *fprog = (struct gen4_fragment_program *) prog; - memset(&brw->interpolation_mode, INTERP_MODE_NONE, sizeof(brw->interpolation_mode)); + /* Initialise interp_mode. INTERP_MODE_NONE == 0 */ + memset(fprog->interp_mode, 0, sizeof(fprog->interp_mode)); - brw->ctx.NewDriverState |= BRW_NEW_INTERPOLATION_MAP; - - if (!fprog) + if (!vue_map) return; - for (int i = 0; i < vue_map->num_slots; i++) { - int varying = vue_map->slot_to_varying[i]; - if (varying == -1) - continue; - - /* HPOS always wants noperspective. setting it up here allows - * us to not need special handling in the SF program. */ - if (varying == VARYING_SLOT_POS) { - brw->interpolation_mode.mode[i] = INTERP_MODE_NOPERSPECTIVE; - continue; - } - - int frag_attrib = varying; - if (varying == VARYING_SLOT_BFC0 || varying == VARYING_SLOT_BFC1) - frag_attrib = varying - VARYING_SLOT_BFC0 + VARYING_SLOT_COL0; + /* HPOS always wants noperspective. setting it up here allows + * us to not need special handling in the SF program. + */ + unsigned pos_slot = vue_map->varying_to_slot[VARYING_SLOT_POS]; + if (pos_slot != -1) {; + fprog->interp_mode[pos_slot] = INTERP_MODE_NOPERSPECTIVE; + fprog->contains_noperspective_varying = true; + } - if (!(fprog->Base.nir->info->inputs_read & BITFIELD64_BIT(frag_attrib))) - continue; + foreach_list_typed(nir_variable, var, node, &nir->inputs) { + unsigned location = var->data.location; + unsigned slot_count = glsl_count_attribute_slots(var->type, false); - enum glsl_interp_mode mode = fprog->InterpQualifier[frag_attrib]; + gen4_frag_prog_set_interp_modes(fprog, vue_map, location, slot_count, + var->data.interpolation); - /* If the mode is not specified, the default varies: Color values - * follow GL_SHADE_MODEL; everything else is smooth. - */ - if (mode == INTERP_MODE_NONE) { - if (frag_attrib == VARYING_SLOT_COL0 || frag_attrib == VARYING_SLOT_COL1) - mode = brw->ctx.Light.ShadeModel == GL_FLAT - ? INTERP_MODE_FLAT : INTERP_MODE_SMOOTH; - else - mode = INTERP_MODE_SMOOTH; + if (location == VARYING_SLOT_COL0 || location == VARYING_SLOT_COL1) { + location = location + VARYING_SLOT_BFC0 - VARYING_SLOT_COL0; + gen4_frag_prog_set_interp_modes(fprog, vue_map, location, + slot_count, var->data.interpolation); } - - brw->interpolation_mode.mode[i] = mode; } if (unlikely(INTEL_DEBUG & DEBUG_VUE)) { @@ -103,7 +104,7 @@ brw_setup_vue_interpolation(struct brw_context *brw) fprintf(stderr, "%d: %d %s ofs %d\n", i, varying, - get_qual_name(brw->interpolation_mode.mode[i]), + get_qual_name(fprog->interp_mode[i]), brw_vue_slot_to_offset(i)); } } diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c index 7334f68db3d..ec48da9f2f8 100644 --- a/src/mesa/drivers/dri/i965/brw_nir.c +++ b/src/mesa/drivers/dri/i965/brw_nir.c @@ -280,7 +280,8 @@ brw_nir_lower_tes_inputs(nir_shader *nir, const struct brw_vue_map *vue_map) } void -brw_nir_lower_fs_inputs(nir_shader *nir, +brw_nir_lower_fs_inputs(nir_shader *nir, struct brw_vue_map *vue_map, + struct gl_program *prog, const struct gen_device_info *devinfo, const struct brw_wm_prog_key *key) { @@ -311,6 +312,11 @@ brw_nir_lower_fs_inputs(nir_shader *nir, } } + if (devinfo->gen < 6) { + assert(prog); /* prog will be NULL when called from Vulkan */ + brw_setup_vue_interpolation(vue_map, nir, prog, devinfo); + } + nir_lower_io_options lower_io_options = 0; if (key->persample_interp) lower_io_options |= nir_lower_io_force_sample_interpolation; diff --git a/src/mesa/drivers/dri/i965/brw_nir.h b/src/mesa/drivers/dri/i965/brw_nir.h index 645a818c4e5..3c774d04033 100644 --- a/src/mesa/drivers/dri/i965/brw_nir.h +++ b/src/mesa/drivers/dri/i965/brw_nir.h @@ -104,7 +104,8 @@ void brw_nir_lower_vs_inputs(nir_shader *nir, void brw_nir_lower_vue_inputs(nir_shader *nir, bool is_scalar, const struct brw_vue_map *vue_map); void brw_nir_lower_tes_inputs(nir_shader *nir, const struct brw_vue_map *vue); -void brw_nir_lower_fs_inputs(nir_shader *nir, +void brw_nir_lower_fs_inputs(nir_shader *nir, struct brw_vue_map *vue_map, + struct gl_program *prog, const struct gen_device_info *devinfo, const struct brw_wm_prog_key *key); void brw_nir_lower_vue_outputs(nir_shader *nir, bool is_scalar); diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 7516baf1e1f..3176dc4ef28 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -142,7 +142,15 @@ static struct gl_program *brwNewProgram( struct gl_context *ctx, } case GL_FRAGMENT_PROGRAM_ARB: { - struct brw_fragment_program *prog = CALLOC_STRUCT(brw_fragment_program); + struct brw_fragment_program *prog; + if (brw->gen < 6) { + struct gen4_fragment_program *g4_prog = + CALLOC_STRUCT(gen4_fragment_program); + prog = &g4_prog->base; + } else { + prog = CALLOC_STRUCT(brw_fragment_program); + } + if (prog) { prog->id = get_new_program_id(brw->screen); diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c index 094260e2a1f..b0ed712f0a3 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.c +++ b/src/mesa/drivers/dri/i965/brw_sf.c @@ -79,7 +79,6 @@ static void compile_sf_prog( struct brw_context *brw, c.prog_data.urb_read_length = c.nr_attr_regs; c.prog_data.urb_entry_size = c.nr_setup_regs * 2; - c.has_flat_shading = brw_any_flat_varyings(&key->interpolation_mode); /* Which primitive? Or all three? */ @@ -148,7 +147,7 @@ brw_upload_sf_prog(struct brw_context *brw) _NEW_PROGRAM | _NEW_TRANSFORM, BRW_NEW_BLORP | - BRW_NEW_INTERPOLATION_MAP | + BRW_NEW_FRAGMENT_PROGRAM | BRW_NEW_REDUCED_PRIMITIVE | BRW_NEW_VUE_MAP_GEOM_OUT)) return; @@ -204,8 +203,15 @@ brw_upload_sf_prog(struct brw_context *brw) if ((ctx->Point.SpriteOrigin == GL_LOWER_LEFT) != render_to_fbo) key.sprite_origin_lower_left = true; - /* BRW_NEW_INTERPOLATION_MAP */ - key.interpolation_mode = brw->interpolation_mode; + const struct gl_fragment_program *fprog = brw->fragment_program; + if (fprog) { + assert(brw->gen < 6); + struct gen4_fragment_program *p = (struct gen4_fragment_program *) fprog; + + /* BRW_NEW_FRAGMENT_PROGRAM */ + key.contains_flat_varying = p->contains_flat_varying; + key.interp_mode = p->interp_mode; + } /* _NEW_LIGHT | _NEW_PROGRAM */ key.do_twoside_color = ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) || diff --git a/src/mesa/drivers/dri/i965/brw_sf.h b/src/mesa/drivers/dri/i965/brw_sf.h index 15102ac6119..ce4b2e36a8c 100644 --- a/src/mesa/drivers/dri/i965/brw_sf.h +++ b/src/mesa/drivers/dri/i965/brw_sf.h @@ -46,7 +46,8 @@ struct brw_sf_prog_key { GLbitfield64 attrs; - struct interpolation_mode_map interpolation_mode; + bool contains_flat_varying; + unsigned char *interp_mode; uint8_t point_sprite_coord_replace; GLuint primitive:2; GLuint do_twoside_color:1; @@ -98,7 +99,6 @@ struct brw_sf_compile { unsigned flag_value; struct brw_vue_map vue_map; - bool has_flat_shading; }; diff --git a/src/mesa/drivers/dri/i965/brw_sf_emit.c b/src/mesa/drivers/dri/i965/brw_sf_emit.c index fe05d547fbc..5f31fa51602 100644 --- a/src/mesa/drivers/dri/i965/brw_sf_emit.c +++ b/src/mesa/drivers/dri/i965/brw_sf_emit.c @@ -162,7 +162,7 @@ static void copy_flatshaded_attributes(struct brw_sf_compile *c, int i; for (i = 0; i < c->vue_map.num_slots; i++) { - if (c->key.interpolation_mode.mode[i] == INTERP_MODE_FLAT) { + if (c->key.interp_mode[i] == INTERP_MODE_FLAT) { brw_MOV(p, get_vue_slot(c, dst, i), get_vue_slot(c, src, i)); @@ -176,7 +176,7 @@ static int count_flatshaded_attributes(struct brw_sf_compile *c) int count = 0; for (i = 0; i < c->vue_map.num_slots; i++) - if (c->key.interpolation_mode.mode[i] == INTERP_MODE_FLAT) + if (c->key.interp_mode[i] == INTERP_MODE_FLAT) count++; return count; @@ -342,7 +342,7 @@ calculate_masks(struct brw_sf_compile *c, *pc_linear = 0; *pc = 0xf; - interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 0)]; + interp = c->key.interp_mode[vert_reg_to_vue_slot(c, reg, 0)]; if (interp == INTERP_MODE_SMOOTH) { *pc_linear = 0xf; *pc_persp = 0xf; @@ -354,7 +354,7 @@ calculate_masks(struct brw_sf_compile *c, if (vert_reg_to_varying(c, reg, 1) != BRW_VARYING_SLOT_COUNT) { *pc |= 0xf0; - interp = c->key.interpolation_mode.mode[vert_reg_to_vue_slot(c, reg, 1)]; + interp = c->key.interp_mode[vert_reg_to_vue_slot(c, reg, 1)]; if (interp == INTERP_MODE_SMOOTH) { *pc_linear |= 0xf0; *pc_persp |= 0xf0; @@ -428,7 +428,7 @@ void brw_emit_tri_setup(struct brw_sf_compile *c, bool allocate) if (c->key.do_twoside_color) do_twoside_color(c); - if (c->has_flat_shading) + if (c->key.contains_flat_varying) do_flatshade_triangle(c); @@ -514,7 +514,7 @@ void brw_emit_line_setup(struct brw_sf_compile *c, bool allocate) invert_det(c); copy_z_inv_w(c); - if (c->has_flat_shading) + if (c->key.contains_flat_varying) do_flatshade_line(c); for (i = 0; i < c->nr_setup_regs; i++) diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h index b42b9af4073..1420aaba59e 100644 --- a/src/mesa/drivers/dri/i965/brw_state.h +++ b/src/mesa/drivers/dri/i965/brw_state.h @@ -396,9 +396,6 @@ void gen7_enable_hw_binding_tables(struct brw_context *brw); void gen7_disable_hw_binding_tables(struct brw_context *brw); void gen7_reset_hw_bt_pool_offsets(struct brw_context *brw); -/* brw_interpolation_map.c */ -void brw_setup_vue_interpolation(struct brw_context *brw); - /* brw_clip.c */ void brw_upload_clip_prog(struct brw_context *brw); diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c index 17d1b2df599..17befe37def 100644 --- a/src/mesa/drivers/dri/i965/brw_state_upload.c +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c @@ -734,13 +734,12 @@ brw_upload_programs(struct brw_context *brw, ctx->Const.MaxViewports : 1; } + brw_upload_wm_prog(brw); + if (brw->gen < 6) { - brw_setup_vue_interpolation(brw); brw_upload_clip_prog(brw); brw_upload_sf_prog(brw); } - - brw_upload_wm_prog(brw); } else if (pipeline == BRW_COMPUTE_PIPELINE) { brw_upload_cs_prog(brw); } diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index e65f77a8c43..53b7d9bd91e 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -77,7 +77,8 @@ bool brw_codegen_wm_prog(struct brw_context *brw, struct gl_shader_program *prog, struct brw_fragment_program *fp, - struct brw_wm_prog_key *key) + struct brw_wm_prog_key *key, + struct brw_vue_map *vue_map) { const struct gen_device_info *devinfo = &brw->screen->devinfo; struct gl_context *ctx = &brw->ctx; @@ -146,8 +147,9 @@ brw_codegen_wm_prog(struct brw_context *brw, program = brw_compile_fs(brw->screen->compiler, brw, mem_ctx, key, &prog_data, fp->program.Base.nir, &fp->program.Base, st_index8, st_index16, - true, brw->use_rep_send, + true, brw->use_rep_send, vue_map, &program_size, &error_str); + if (program == NULL) { if (prog) { prog->LinkStatus = false; @@ -587,7 +589,8 @@ brw_upload_wm_prog(struct brw_context *brw) &key, sizeof(key), &brw->wm.base.prog_offset, &brw->wm.base.prog_data)) { - bool success = brw_codegen_wm_prog(brw, current, fp, &key); + bool success = brw_codegen_wm_prog(brw, current, fp, &key, + &brw->vue_map_geom_out); (void) success; assert(success); } @@ -641,7 +644,14 @@ brw_fs_precompile(struct gl_context *ctx, uint32_t old_prog_offset = brw->wm.base.prog_offset; struct brw_stage_prog_data *old_prog_data = brw->wm.base.prog_data; - bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key); + struct brw_vue_map vue_map; + if (brw->gen < 6) { + brw_compute_vue_map(&brw->screen->devinfo, &vue_map, + fp->Base.nir->info->inputs_read | VARYING_BIT_POS, + false); + } + + bool success = brw_codegen_wm_prog(brw, shader_prog, bfp, &key, &vue_map); brw->wm.base.prog_offset = old_prog_offset; brw->wm.base.prog_data = old_prog_data; diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h index 8fa24b1ae48..f4f513bef0a 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.h +++ b/src/mesa/drivers/dri/i965/brw_wm.h @@ -63,7 +63,8 @@ bool brw_color_buffer_write_enabled(struct brw_context *brw); bool brw_codegen_wm_prog(struct brw_context *brw, struct gl_shader_program *prog, struct brw_fragment_program *fp, - struct brw_wm_prog_key *key); + struct brw_wm_prog_key *key, + struct brw_vue_map *vue_map); void brw_wm_debug_recompile(struct brw_context *brw, struct gl_shader_program *prog, const struct brw_wm_prog_key *key);