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;
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);
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
_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;
/* 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;
*/
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;
bool need_direction;
struct brw_vue_map vue_map;
-
- bool has_flat_shading;
- bool has_noperspective_shading;
};
/**
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
* 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) ||
/* 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);
*/
/* 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);
/* 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);
* 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);
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);
}
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)));
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,
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);
};
+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;
~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;
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;
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);
* 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)
}
}
+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)) {
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));
}
}
}
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)
{
}
}
+ 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;
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);
}
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);
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?
*/
_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;
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) ||
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;
unsigned flag_value;
struct brw_vue_map vue_map;
- bool has_flat_shading;
};
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));
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;
*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;
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;
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);
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++)
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);
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);
}
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;
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;
&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);
}
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;
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);