Re: [Mesa-dev] [PATCH 21/28] i965/blorp: Add initial support for NIR-based blit shaders

2016-05-13 Thread Jason Ekstrand
On Thu, May 12, 2016 at 10:04 PM, Pohjolainen, Topi <
topi.pohjolai...@intel.com> wrote:

> On Tue, May 10, 2016 at 04:16:41PM -0700, Jason Ekstrand wrote:
> > Many of the more complex cases still fall back to the old shader builder.
> > ---
> >  src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 425
> +--
> >  1 file changed, 401 insertions(+), 24 deletions(-)
> >
> > diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> > index ea64b11..f94dd6f 100644
> > --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> > +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> > @@ -25,6 +25,8 @@
> >  #include "main/teximage.h"
> >  #include "main/fbobject.h"
> >
> > +#include "compiler/nir/nir_builder.h"
> > +
> >  #include "intel_fbo.h"
> >
> >  #include "brw_blorp.h"
> > @@ -332,6 +334,226 @@ enum sampler_message_arg
> > SAMPLER_MESSAGE_ARG_ZERO_INT,
> >  };
> >
> > +struct brw_blorp_blit_vars {
> > +   /* Uniforms values from brw_blorp_wm_push_constants */
> > +   nir_variable *u_dst_x0;
> > +   nir_variable *u_dst_x1;
> > +   nir_variable *u_dst_y0;
> > +   nir_variable *u_dst_y1;
> > +   nir_variable *u_rect_grid_x1;
> > +   nir_variable *u_rect_grid_y1;
> > +   struct {
> > +  nir_variable *multiplier;
> > +  nir_variable *offset;
> > +   } u_x_transform, u_y_transform;
> > +   nir_variable *u_src_z;
> > +
> > +   /* gl_FragCoord */
> > +   nir_variable *frag_coord;
> > +
> > +   /* gl_FragColor */
> > +   nir_variable *color_out;
> > +};
> > +
> > +static void
> > +brw_blorp_blit_vars_init(nir_builder *b, struct brw_blorp_blit_vars *v,
> > + const struct brw_blorp_blit_prog_key *key)
> > +{
> > +#define LOAD_UNIFORM(name, type)\
> > +   v->u_##name = nir_variable_create(b->shader, nir_var_uniform, type,
> #name); \
> > +   v->u_##name->data.location = \
> > +  offsetof(struct brw_blorp_wm_push_constants, name);
> > +
> > +   LOAD_UNIFORM(dst_x0, glsl_uint_type())
> > +   LOAD_UNIFORM(dst_x1, glsl_uint_type())
> > +   LOAD_UNIFORM(dst_y0, glsl_uint_type())
> > +   LOAD_UNIFORM(dst_y1, glsl_uint_type())
> > +   LOAD_UNIFORM(rect_grid_x1, glsl_float_type())
> > +   LOAD_UNIFORM(rect_grid_y1, glsl_float_type())
> > +   LOAD_UNIFORM(x_transform.multiplier, glsl_float_type())
> > +   LOAD_UNIFORM(x_transform.offset, glsl_float_type())
> > +   LOAD_UNIFORM(y_transform.multiplier, glsl_float_type())
> > +   LOAD_UNIFORM(y_transform.offset, glsl_float_type())
> > +   LOAD_UNIFORM(src_z, glsl_uint_type())
> > +
> > +#undef DECL_UNIFORM
> > +
> > +   v->frag_coord = nir_variable_create(b->shader, nir_var_shader_in,
> > +   glsl_vec4_type(),
> "gl_FragCoord");
> > +   v->frag_coord->data.location = VARYING_SLOT_POS;
> > +   v->frag_coord->data.origin_upper_left = true;
> > +
> > +   v->color_out = nir_variable_create(b->shader, nir_var_shader_out,
> > +  glsl_vec4_type(), "gl_FragColor");
> > +   v->color_out->data.location = FRAG_RESULT_COLOR;
> > +}
> > +
> > +nir_ssa_def *
> > +blorp_blit_get_frag_coords(nir_builder *b,
> > +   const struct brw_blorp_blit_prog_key *key,
> > +   struct brw_blorp_blit_vars *v)
> > +{
> > +   nir_ssa_def *coord = nir_f2i(b, nir_load_var(b, v->frag_coord));
> > +
> > +   if (key->persample_msaa_dispatch) {
> > +  return nir_vec3(b, nir_channel(b, coord, 0), nir_channel(b,
> coord, 1),
> > + nir_load_system_value(b, nir_intrinsic_load_sample_id, 0));
> > +   } else {
> > +  return nir_vec2(b, nir_channel(b, coord, 0), nir_channel(b,
> coord, 1));
> > +   }
> > +}
> > +
>
> We could keep the original comment here:
>
> /**
>  * Emit code to translate from destination (X, Y) coordinates to source
> (X, Y)
>  * coordinates.
>  */
>

Done.


> Otherwise this looks really nice, readability alone is improved a lot.
> There
> is no question that the original was written as clearly as it can be but
> now
> we are able to leave some many details into the generic compiler backend.
>
> > +nir_ssa_def *
> > +blorp_blit_apply_transform(nir_builder *b, nir_ssa_def *src_pos,
> > +   struct brw_blorp_blit_vars *v)
> > +{
> > +   nir_ssa_def *offset = nir_vec2(b, nir_load_var(b,
> v->u_x_transform.offset),
> > + nir_load_var(b,
> v->u_y_transform.offset));
> > +   nir_ssa_def *mul = nir_vec2(b, nir_load_var(b,
> v->u_x_transform.multiplier),
> > +  nir_load_var(b,
> v->u_y_transform.multiplier));
> > +
> > +   nir_ssa_def *pos = nir_ffma(b, src_pos, mul, offset);
> > +
> > +   if (src_pos->num_components == 3) {
> > +  /* Leave the sample id alone */
> > +  pos = nir_vec3(b, nir_channel(b, pos, 0), nir_channel(b, pos, 1),
> > +nir_channel(b, src_pos, 2));
> > +   }
> > +
> > +   return pos;
> > +}
> > +
> > +static nir_tex_instr *
> > +blorp_

Re: [Mesa-dev] [PATCH 21/28] i965/blorp: Add initial support for NIR-based blit shaders

2016-05-12 Thread Pohjolainen, Topi
On Tue, May 10, 2016 at 04:16:41PM -0700, Jason Ekstrand wrote:
> Many of the more complex cases still fall back to the old shader builder.
> ---
>  src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 425 
> +--
>  1 file changed, 401 insertions(+), 24 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp 
> b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> index ea64b11..f94dd6f 100644
> --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> @@ -25,6 +25,8 @@
>  #include "main/teximage.h"
>  #include "main/fbobject.h"
>  
> +#include "compiler/nir/nir_builder.h"
> +
>  #include "intel_fbo.h"
>  
>  #include "brw_blorp.h"
> @@ -332,6 +334,226 @@ enum sampler_message_arg
> SAMPLER_MESSAGE_ARG_ZERO_INT,
>  };
>  
> +struct brw_blorp_blit_vars {
> +   /* Uniforms values from brw_blorp_wm_push_constants */
> +   nir_variable *u_dst_x0;
> +   nir_variable *u_dst_x1;
> +   nir_variable *u_dst_y0;
> +   nir_variable *u_dst_y1;
> +   nir_variable *u_rect_grid_x1;
> +   nir_variable *u_rect_grid_y1;
> +   struct {
> +  nir_variable *multiplier;
> +  nir_variable *offset;
> +   } u_x_transform, u_y_transform;
> +   nir_variable *u_src_z;
> +
> +   /* gl_FragCoord */
> +   nir_variable *frag_coord;
> +
> +   /* gl_FragColor */
> +   nir_variable *color_out;
> +};
> +
> +static void
> +brw_blorp_blit_vars_init(nir_builder *b, struct brw_blorp_blit_vars *v,
> + const struct brw_blorp_blit_prog_key *key)
> +{
> +#define LOAD_UNIFORM(name, type)\
> +   v->u_##name = nir_variable_create(b->shader, nir_var_uniform, type, 
> #name); \
> +   v->u_##name->data.location = \
> +  offsetof(struct brw_blorp_wm_push_constants, name);
> +
> +   LOAD_UNIFORM(dst_x0, glsl_uint_type())
> +   LOAD_UNIFORM(dst_x1, glsl_uint_type())
> +   LOAD_UNIFORM(dst_y0, glsl_uint_type())
> +   LOAD_UNIFORM(dst_y1, glsl_uint_type())
> +   LOAD_UNIFORM(rect_grid_x1, glsl_float_type())
> +   LOAD_UNIFORM(rect_grid_y1, glsl_float_type())
> +   LOAD_UNIFORM(x_transform.multiplier, glsl_float_type())
> +   LOAD_UNIFORM(x_transform.offset, glsl_float_type())
> +   LOAD_UNIFORM(y_transform.multiplier, glsl_float_type())
> +   LOAD_UNIFORM(y_transform.offset, glsl_float_type())
> +   LOAD_UNIFORM(src_z, glsl_uint_type())
> +
> +#undef DECL_UNIFORM
> +
> +   v->frag_coord = nir_variable_create(b->shader, nir_var_shader_in,
> +   glsl_vec4_type(), "gl_FragCoord");
> +   v->frag_coord->data.location = VARYING_SLOT_POS;
> +   v->frag_coord->data.origin_upper_left = true;
> +
> +   v->color_out = nir_variable_create(b->shader, nir_var_shader_out,
> +  glsl_vec4_type(), "gl_FragColor");
> +   v->color_out->data.location = FRAG_RESULT_COLOR;
> +}
> +
> +nir_ssa_def *
> +blorp_blit_get_frag_coords(nir_builder *b,
> +   const struct brw_blorp_blit_prog_key *key,
> +   struct brw_blorp_blit_vars *v)
> +{
> +   nir_ssa_def *coord = nir_f2i(b, nir_load_var(b, v->frag_coord));
> +
> +   if (key->persample_msaa_dispatch) {
> +  return nir_vec3(b, nir_channel(b, coord, 0), nir_channel(b, coord, 1),
> + nir_load_system_value(b, nir_intrinsic_load_sample_id, 0));
> +   } else {
> +  return nir_vec2(b, nir_channel(b, coord, 0), nir_channel(b, coord, 1));
> +   }
> +}
> +

We could keep the original comment here:

/**
 * Emit code to translate from destination (X, Y) coordinates to source (X, Y)
 * coordinates.
 */

Otherwise this looks really nice, readability alone is improved a lot. There
is no question that the original was written as clearly as it can be but now
we are able to leave some many details into the generic compiler backend.

> +nir_ssa_def *
> +blorp_blit_apply_transform(nir_builder *b, nir_ssa_def *src_pos,
> +   struct brw_blorp_blit_vars *v)
> +{
> +   nir_ssa_def *offset = nir_vec2(b, nir_load_var(b, 
> v->u_x_transform.offset),
> + nir_load_var(b, 
> v->u_y_transform.offset));
> +   nir_ssa_def *mul = nir_vec2(b, nir_load_var(b, 
> v->u_x_transform.multiplier),
> +  nir_load_var(b, 
> v->u_y_transform.multiplier));
> +
> +   nir_ssa_def *pos = nir_ffma(b, src_pos, mul, offset);
> +
> +   if (src_pos->num_components == 3) {
> +  /* Leave the sample id alone */
> +  pos = nir_vec3(b, nir_channel(b, pos, 0), nir_channel(b, pos, 1),
> +nir_channel(b, src_pos, 2));
> +   }
> +
> +   return pos;
> +}
> +
> +static nir_tex_instr *
> +blorp_create_nir_tex_instr(nir_shader *shader, nir_texop op,
> +   nir_ssa_def *pos, unsigned num_srcs,
> +   enum brw_reg_type dst_type)
> +{
> +   nir_tex_instr *tex = nir_tex_instr_create(shader, num_srcs);
> +
> +   tex->op = op;
> +
> +   switch (dst_type) {
> +   case BRW_REGISTER_TYPE_F:
> +

[Mesa-dev] [PATCH 21/28] i965/blorp: Add initial support for NIR-based blit shaders

2016-05-10 Thread Jason Ekstrand
Many of the more complex cases still fall back to the old shader builder.
---
 src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 425 +--
 1 file changed, 401 insertions(+), 24 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp 
b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index ea64b11..f94dd6f 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -25,6 +25,8 @@
 #include "main/teximage.h"
 #include "main/fbobject.h"
 
+#include "compiler/nir/nir_builder.h"
+
 #include "intel_fbo.h"
 
 #include "brw_blorp.h"
@@ -332,6 +334,226 @@ enum sampler_message_arg
SAMPLER_MESSAGE_ARG_ZERO_INT,
 };
 
+struct brw_blorp_blit_vars {
+   /* Uniforms values from brw_blorp_wm_push_constants */
+   nir_variable *u_dst_x0;
+   nir_variable *u_dst_x1;
+   nir_variable *u_dst_y0;
+   nir_variable *u_dst_y1;
+   nir_variable *u_rect_grid_x1;
+   nir_variable *u_rect_grid_y1;
+   struct {
+  nir_variable *multiplier;
+  nir_variable *offset;
+   } u_x_transform, u_y_transform;
+   nir_variable *u_src_z;
+
+   /* gl_FragCoord */
+   nir_variable *frag_coord;
+
+   /* gl_FragColor */
+   nir_variable *color_out;
+};
+
+static void
+brw_blorp_blit_vars_init(nir_builder *b, struct brw_blorp_blit_vars *v,
+ const struct brw_blorp_blit_prog_key *key)
+{
+#define LOAD_UNIFORM(name, type)\
+   v->u_##name = nir_variable_create(b->shader, nir_var_uniform, type, #name); 
\
+   v->u_##name->data.location = \
+  offsetof(struct brw_blorp_wm_push_constants, name);
+
+   LOAD_UNIFORM(dst_x0, glsl_uint_type())
+   LOAD_UNIFORM(dst_x1, glsl_uint_type())
+   LOAD_UNIFORM(dst_y0, glsl_uint_type())
+   LOAD_UNIFORM(dst_y1, glsl_uint_type())
+   LOAD_UNIFORM(rect_grid_x1, glsl_float_type())
+   LOAD_UNIFORM(rect_grid_y1, glsl_float_type())
+   LOAD_UNIFORM(x_transform.multiplier, glsl_float_type())
+   LOAD_UNIFORM(x_transform.offset, glsl_float_type())
+   LOAD_UNIFORM(y_transform.multiplier, glsl_float_type())
+   LOAD_UNIFORM(y_transform.offset, glsl_float_type())
+   LOAD_UNIFORM(src_z, glsl_uint_type())
+
+#undef DECL_UNIFORM
+
+   v->frag_coord = nir_variable_create(b->shader, nir_var_shader_in,
+   glsl_vec4_type(), "gl_FragCoord");
+   v->frag_coord->data.location = VARYING_SLOT_POS;
+   v->frag_coord->data.origin_upper_left = true;
+
+   v->color_out = nir_variable_create(b->shader, nir_var_shader_out,
+  glsl_vec4_type(), "gl_FragColor");
+   v->color_out->data.location = FRAG_RESULT_COLOR;
+}
+
+nir_ssa_def *
+blorp_blit_get_frag_coords(nir_builder *b,
+   const struct brw_blorp_blit_prog_key *key,
+   struct brw_blorp_blit_vars *v)
+{
+   nir_ssa_def *coord = nir_f2i(b, nir_load_var(b, v->frag_coord));
+
+   if (key->persample_msaa_dispatch) {
+  return nir_vec3(b, nir_channel(b, coord, 0), nir_channel(b, coord, 1),
+ nir_load_system_value(b, nir_intrinsic_load_sample_id, 0));
+   } else {
+  return nir_vec2(b, nir_channel(b, coord, 0), nir_channel(b, coord, 1));
+   }
+}
+
+nir_ssa_def *
+blorp_blit_apply_transform(nir_builder *b, nir_ssa_def *src_pos,
+   struct brw_blorp_blit_vars *v)
+{
+   nir_ssa_def *offset = nir_vec2(b, nir_load_var(b, v->u_x_transform.offset),
+ nir_load_var(b, v->u_y_transform.offset));
+   nir_ssa_def *mul = nir_vec2(b, nir_load_var(b, v->u_x_transform.multiplier),
+  nir_load_var(b, 
v->u_y_transform.multiplier));
+
+   nir_ssa_def *pos = nir_ffma(b, src_pos, mul, offset);
+
+   if (src_pos->num_components == 3) {
+  /* Leave the sample id alone */
+  pos = nir_vec3(b, nir_channel(b, pos, 0), nir_channel(b, pos, 1),
+nir_channel(b, src_pos, 2));
+   }
+
+   return pos;
+}
+
+static nir_tex_instr *
+blorp_create_nir_tex_instr(nir_shader *shader, nir_texop op,
+   nir_ssa_def *pos, unsigned num_srcs,
+   enum brw_reg_type dst_type)
+{
+   nir_tex_instr *tex = nir_tex_instr_create(shader, num_srcs);
+
+   tex->op = op;
+
+   switch (dst_type) {
+   case BRW_REGISTER_TYPE_F:
+  tex->dest_type = nir_type_float;
+  break;
+   case BRW_REGISTER_TYPE_D:
+  tex->dest_type = nir_type_int;
+  break;
+   case BRW_REGISTER_TYPE_UD:
+  tex->dest_type = nir_type_uint;
+  break;
+   default:
+  unreachable("Invalid texture return type");
+   }
+
+   tex->is_array = false;
+   tex->is_shadow = false;
+
+   /* Blorp only has one texture and it's bound at unit 0 */
+   tex->texture = NULL;
+   tex->sampler = NULL;
+   tex->texture_index = 0;
+   tex->sampler_index = 0;
+
+   nir_ssa_dest_init(&tex->instr, &tex->dest, 4, 32, NULL);
+
+   return tex;
+}
+
+static nir_ssa_def *
+blorp_nir_tex(nir_builder *b, nir_ssa_def *pos, enum brw_reg_type dst_type)
+{
+