Re: [Mesa-dev] [PATCH 21/28] i965/blorp: Add initial support for NIR-based blit shaders
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
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
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) +{ +