[Mesa-dev] [PATCH 5/5] i965: Implement ARB_fragment_layer_viewport.
Chris Forbes
chrisf at ijw.co.nz
Mon Oct 26 13:48:41 PDT 2015
For the series
Reviewed-by: Chris Forbes <chrisf at ijw.co.nz>
On Oct 27, 2015 7:03 AM, "Kenneth Graunke" <kenneth at whitecape.org> wrote:
> Normally, we could read gl_Layer from bits 26:16 of R0.0. However, the
> specification requires that bogus out-of-range 32-bit values written by
> previous stages need to appear in the fragment shader as-written.
>
> Instead, we pass in the full 32-bit value from the VUE header as an
> extra flat-shaded varying. We have the SF override the value to 0
> when the previous stage didn't actually write a value (it's actually
> defined to return 0).
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> Cc: Chris Forbes <chrisf at ijw.co.nz>
> ---
> src/mesa/drivers/dri/i965/brw_fs.cpp | 7 ++++++-
> src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 8 +++++++
> src/mesa/drivers/dri/i965/gen6_sf_state.c | 31
> ++++++++++++++++++++++++++++
> src/mesa/drivers/dri/i965/intel_extensions.c | 1 +
> 4 files changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp
> b/src/mesa/drivers/dri/i965/brw_fs.cpp
> index 2eef7af..5a82b04 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
> @@ -1442,6 +1442,9 @@ fs_visitor::calculate_urb_setup()
> }
> }
> } else {
> + bool include_vue_header =
> + nir->info.inputs_read & (VARYING_BIT_LAYER |
> VARYING_BIT_VIEWPORT);
> +
> /* We have enough input varyings that the SF/SBE pipeline stage
> can't
> * arbitrarily rearrange them to suit our whim; we have to put
> them
> * in an order that matches the output of the previous pipeline
> stage
> @@ -1451,7 +1454,9 @@ fs_visitor::calculate_urb_setup()
> brw_compute_vue_map(devinfo, &prev_stage_vue_map,
> key->input_slots_valid,
> nir->info.separate_shader);
> - int first_slot = 2 * BRW_SF_URB_ENTRY_READ_OFFSET;
> + int first_slot =
> + include_vue_header ? 0 : 2 * BRW_SF_URB_ENTRY_READ_OFFSET;
> +
> assert(prev_stage_vue_map.num_slots <= first_slot + 32);
> for (int slot = first_slot; slot < prev_stage_vue_map.num_slots;
> slot++) {
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> index 4950ba4..9c1f95c 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> @@ -71,6 +71,14 @@ fs_visitor::nir_setup_inputs()
> var->data.origin_upper_left);
> emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(),
> input, reg), 0xF);
> + } else if (var->data.location == VARYING_SLOT_LAYER) {
> + struct brw_reg reg = suboffset(interp_reg(VARYING_SLOT_LAYER,
> 1), 3);
> + reg.type = BRW_REGISTER_TYPE_D;
> + bld.emit(FS_OPCODE_CINTERP, retype(input, BRW_REGISTER_TYPE_D),
> reg);
> + } else if (var->data.location == VARYING_SLOT_VIEWPORT) {
> + struct brw_reg reg = suboffset(interp_reg(VARYING_SLOT_VIEWPORT,
> 2), 3);
> + reg.type = BRW_REGISTER_TYPE_D;
> + bld.emit(FS_OPCODE_CINTERP, retype(input, BRW_REGISTER_TYPE_D),
> reg);
> } else {
> emit_general_interpolation(input, var->name, var->type,
> (glsl_interp_qualifier)
> var->data.interpolation,
> diff --git a/src/mesa/drivers/dri/i965/gen6_sf_state.c
> b/src/mesa/drivers/dri/i965/gen6_sf_state.c
> index 0c8c053..2634e6b 100644
> --- a/src/mesa/drivers/dri/i965/gen6_sf_state.c
> +++ b/src/mesa/drivers/dri/i965/gen6_sf_state.c
> @@ -60,6 +60,23 @@ get_attr_override(const struct brw_vue_map *vue_map,
> int urb_entry_read_offset,
> /* Find the VUE slot for this attribute. */
> int slot = vue_map->varying_to_slot[fs_attr];
>
> + /* Viewport and Layer are stored in the VUE header. We need to
> override
> + * them to zero if earlier stages didn't write them, as GL requires
> that
> + * they read back as zero when not explicitly set.
> + */
> + if (fs_attr == VARYING_SLOT_VIEWPORT || fs_attr == VARYING_SLOT_LAYER)
> {
> + unsigned override =
> + ATTRIBUTE_0_OVERRIDE_X | ATTRIBUTE_0_OVERRIDE_W |
> + ATTRIBUTE_CONST_0000 << ATTRIBUTE_0_CONST_SOURCE_SHIFT;
> +
> + if (!(vue_map->slots_valid & VARYING_BIT_LAYER))
> + override |= ATTRIBUTE_0_OVERRIDE_Y;
> + if (!(vue_map->slots_valid & VARYING_BIT_VIEWPORT))
> + override |= ATTRIBUTE_0_OVERRIDE_Z;
> +
> + return override;
> + }
> +
> /* If there was only a back color written but not front, use back
> * as the color instead of undefined
> */
> @@ -169,6 +186,20 @@ calculate_attr_overrides(const struct brw_context
> *brw,
>
> *urb_entry_read_offset = BRW_SF_URB_ENTRY_READ_OFFSET;
>
> + /* BRW_NEW_FRAGMENT_PROGRAM
> + *
> + * If the fragment shader reads VARYING_SLOT_LAYER, then we need to
> pass in
> + * the full vertex header. Otherwise, we can program the SF to start
> + * reading at an offset of 1 (2 varying slots) to skip unnecessary
> data:
> + * - VARYING_SLOT_PSIZ and BRW_VARYING_SLOT_NDC on gen4-5
> + * - VARYING_SLOT_{PSIZ,LAYER} and VARYING_SLOT_POS on gen6+
> + */
> +
> + bool fs_needs_vue_header = brw->fragment_program->Base.InputsRead &
> + (VARYING_BIT_LAYER | VARYING_BIT_VIEWPORT);
> +
> + *urb_entry_read_offset = fs_needs_vue_header ? 0 : 1;
> +
> /* _NEW_LIGHT */
> bool shade_model_flat = brw->ctx.Light.ShadeModel == GL_FLAT;
>
> diff --git a/src/mesa/drivers/dri/i965/intel_extensions.c
> b/src/mesa/drivers/dri/i965/intel_extensions.c
> index c6826d6..4433410 100644
> --- a/src/mesa/drivers/dri/i965/intel_extensions.c
> +++ b/src/mesa/drivers/dri/i965/intel_extensions.c
> @@ -287,6 +287,7 @@ intelInitExtensions(struct gl_context *ctx)
> ctx->Extensions.ARB_conditional_render_inverted = true;
> ctx->Extensions.ARB_draw_buffers_blend = true;
> ctx->Extensions.ARB_ES3_compatibility = true;
> + ctx->Extensions.ARB_fragment_layer_viewport = true;
> ctx->Extensions.ARB_sample_shading = true;
> ctx->Extensions.ARB_shading_language_420pack = true;
> ctx->Extensions.ARB_shading_language_packing = true;
> --
> 2.6.2
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20151027/a5c83409/attachment-0001.html>
More information about the mesa-dev
mailing list