[Mesa-dev] [PATCH 5/9] st/mesa: implement PBO upload for multiple layers

Marek Olšák maraeo at gmail.com
Thu Jan 21 02:12:17 PST 2016


On Mon, Jan 18, 2016 at 11:22 PM, Nicolai Hähnle <nhaehnle at gmail.com> wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
>
> Use instancing to generate two triangles for each destination layer and use
> a geometry shader to route the layer index.

A better way is to disable the geometry shader and write the layer
index in the vertex shader. Some drivers (such as svga) might not
support it though.

> ---
>  src/mesa/state_tracker/st_cb_texture.c | 145 +++++++++++++++++++++++++++------
>  src/mesa/state_tracker/st_context.h    |   2 +
>  2 files changed, 122 insertions(+), 25 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index c3aadb5..7804786 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -698,17 +698,9 @@ st_init_pbo_upload(struct st_context *st)
>
>     st->pbo_upload.rgba_only =
>        screen->get_param(screen, PIPE_CAP_BUFFER_SAMPLER_VIEW_RGBA_ONLY);
> -
> -   /* Create the vertex shader */
> -   {
> -      unsigned semantic_names[] = { TGSI_SEMANTIC_POSITION };
> -      unsigned semantic_indexes[] = { 0 };
> -
> -      st->pbo_upload.vs = util_make_vertex_passthrough_shader(pipe, 1,
> -                                                              semantic_names,
> -                                                              semantic_indexes,
> -                                                              FALSE);
> -   }
> +   st->pbo_upload.upload_layers =
> +      screen->get_param(screen, PIPE_CAP_TGSI_INSTANCEID) &&
> +      screen->get_param(screen, PIPE_CAP_MAX_GEOMETRY_OUTPUT_VERTICES) >= 3;
>
>     /* Blend state */
>     memset(&st->pbo_upload.blend, 0, sizeof(struct pipe_blend_state));
> @@ -1113,7 +1105,82 @@ reinterpret_formats(enum pipe_format *src_format, enum pipe_format *dst_format)
>  }
>
>  static void *
> -create_pbo_upload_shader(struct pipe_context *pipe)
> +create_pbo_upload_vs(struct st_context *st)
> +{
> +   struct ureg_program *ureg;
> +   struct ureg_src in_pos;
> +   struct ureg_src in_instanceid;
> +   struct ureg_dst out_pos;
> +
> +   ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
> +
> +   in_pos = ureg_DECL_vs_input(ureg, TGSI_SEMANTIC_POSITION);
> +
> +   if (st->pbo_upload.upload_layers)
> +      in_instanceid = ureg_DECL_system_value(ureg, TGSI_SEMANTIC_INSTANCEID, 0);
> +
> +   out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
> +
> +   /* out_pos = in_pos */
> +   ureg_MOV(ureg, out_pos, in_pos);
> +
> +   if (st->pbo_upload.upload_layers) {
> +      /* out_pos.z = i2f(gl_InstanceID) */
> +      ureg_I2F(ureg, ureg_writemask(out_pos, TGSI_WRITEMASK_Z),
> +                     ureg_scalar(in_instanceid, TGSI_SWIZZLE_X));
> +   }
> +
> +   ureg_END(ureg);
> +
> +   return ureg_create_shader_and_destroy(ureg, st->pipe);
> +}
> +
> +static void *
> +create_pbo_upload_gs(struct st_context *st)
> +{
> +   static const int zero = 0;
> +   struct ureg_program *ureg;
> +   struct ureg_dst out_pos;
> +   struct ureg_dst out_layer;
> +   struct ureg_src in_pos;
> +   struct ureg_src imm;
> +   unsigned i;
> +
> +   ureg = ureg_create(TGSI_PROCESSOR_GEOMETRY);
> +   if (!ureg)
> +      return NULL;
> +
> +   ureg_property(ureg, TGSI_PROPERTY_GS_INPUT_PRIM, PIPE_PRIM_TRIANGLES);
> +   ureg_property(ureg, TGSI_PROPERTY_GS_OUTPUT_PRIM, PIPE_PRIM_TRIANGLE_STRIP);
> +   ureg_property(ureg, TGSI_PROPERTY_GS_MAX_OUTPUT_VERTICES, 3);
> +
> +   out_pos = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
> +   out_layer = ureg_DECL_output(ureg, TGSI_SEMANTIC_LAYER, 0);
> +
> +   in_pos = ureg_DECL_input(ureg, TGSI_SEMANTIC_POSITION, 0, 0, 1);
> +
> +   imm = ureg_DECL_immediate_int(ureg, &zero, 1);
> +
> +   for (i = 0; i < 3; ++i) {
> +      struct ureg_src in_pos_vertex = ureg_src_dimension(in_pos, i);
> +
> +      /* out_pos = in_pos[i] */
> +      ureg_MOV(ureg, out_pos, in_pos_vertex);
> +
> +      /* out_layer.x = f2i(in_pos[i].z) */
> +      ureg_F2I(ureg, ureg_writemask(out_layer, TGSI_WRITEMASK_X),
> +                     ureg_scalar(in_pos_vertex, TGSI_SWIZZLE_Z));
> +
> +      ureg_EMIT(ureg, ureg_scalar(imm, TGSI_SWIZZLE_X));
> +   }
> +
> +   ureg_END(ureg);
> +
> +   return ureg_create_shader_and_destroy(ureg, st->pipe);
> +}
> +
> +static void *
> +create_pbo_upload_fs(struct st_context *st)
>  {
>     struct ureg_program *ureg;
>     struct ureg_dst out;
> @@ -1122,7 +1189,10 @@ create_pbo_upload_shader(struct pipe_context *pipe)
>     struct ureg_src const0;
>     struct ureg_dst temp0;
>
> -   ureg    = ureg_create(TGSI_PROCESSOR_FRAGMENT);
> +   ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
> +   if (!ureg)
> +      return NULL;
> +
>     out     = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
>     sampler = ureg_DECL_sampler(ureg, 0);
>     pos     = ureg_DECL_fs_input(ureg, TGSI_SEMANTIC_POSITION, 0,
> @@ -1130,15 +1200,15 @@ create_pbo_upload_shader(struct pipe_context *pipe)
>     const0  = ureg_DECL_constant(ureg, 0);
>     temp0   = ureg_DECL_temporary(ureg);
>
> -   /* Note: const0 = [ -xoffset, -yoffset, stride, 0 ] */
> +   /* Note: const0 = [ -xoffset, -yoffset, stride, stride * image_height ] */
>
>     ureg_MOV(ureg, temp0, pos);
>
> -   /* temp0.xy = f2i(temp0.xy) */
> -   ureg_F2I(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XY),
> +   /* temp0.xyz = f2i(temp0.xyz) */
> +   ureg_F2I(ureg, ureg_writemask(temp0, TGSI_WRITEMASK_XYZ),
>                    ureg_swizzle(ureg_src(temp0),
>                                 TGSI_SWIZZLE_X, TGSI_SWIZZLE_Y,
> -                               TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y));
> +                               TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z));

I think this relies on unclamped POSITION.z, right? I wonder if
POSITION.z is always unclamped if depth clipping is disabled.

Marek


More information about the mesa-dev mailing list