[Mesa-dev] [PATCH 1/3] gallium: split transfer_inline_write into buffer and texture callbacks

Nicolai Hähnle nhaehnle at gmail.com
Tue Jul 19 14:00:06 UTC 2016


On 18.07.2016 14:25, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> to reduce the call indirections with u_resource_vtbl.
>
> The worst call tree you could get was:
>    - u_transfer_inline_write_vtbl
>      - u_default_transfer_inline_write
>        - u_transfer_map_vtbl
>          - driver_transfer_map
>        - u_transfer_unmap_vtbl
>          - driver_transfer_unmap
>
> That's 6 indirect calls. Some drivers only had 5. The goal is to have
> 1 indirect call for drivers that care. The resource type can be determined
> statically at most call sites.
>
> The new interface is:
>    pipe_context::buffer_subdata(ctx, resource, usage, offset, size, data)
>    pipe_context::texture_subdata(ctx, resource, level, usage, box, data,
>                                  stride, layer_stride)
> ---
[snip]
> diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c
> index 5abd3be..53029b6 100644
> --- a/src/gallium/drivers/ilo/ilo_transfer.c
> +++ b/src/gallium/drivers/ilo/ilo_transfer.c
> @@ -1236,34 +1236,6 @@ ilo_transfer_map(struct pipe_context *pipe,
>      return ptr;
>   }
>
> -static void
> -ilo_transfer_inline_write(struct pipe_context *pipe,
> -                          struct pipe_resource *res,
> -                          unsigned level,
> -                          unsigned usage,
> -                          const struct pipe_box *box,
> -                          const void *data,
> -                          unsigned stride,
> -                          unsigned layer_stride)
> -{
> -   if (likely(res->target == PIPE_BUFFER) &&
> -       !(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
> -      /* they should specify just an offset and a size */
> -      assert(level == 0);
> -      assert(box->y == 0);
> -      assert(box->z == 0);
> -      assert(box->height == 1);
> -      assert(box->depth == 1);
> -
> -      buf_pwrite(ilo_context(pipe), res,
> -            usage, box->x, box->width, data);
> -   }
> -   else {
> -      u_default_transfer_inline_write(pipe, res,
> -            level, usage, box, data, stride, layer_stride);
> -   }
> -}
> -
>   /**
>    * Initialize transfer-related functions.
>    */
> @@ -1273,5 +1245,6 @@ ilo_init_transfer_functions(struct ilo_context *ilo)
>      ilo->base.transfer_map = ilo_transfer_map;
>      ilo->base.transfer_flush_region = ilo_transfer_flush_region;
>      ilo->base.transfer_unmap = ilo_transfer_unmap;
> -   ilo->base.transfer_inline_write = ilo_transfer_inline_write;
> +   ilo->base.buffer_subdata = u_default_buffer_subdata;
> +   ilo->base.texture_subdata = u_default_texture_subdata;

This is a change of behavior - buffer_subdata should end up calling 
buf_pwrite in the !PIPE_TRANSFER_UNSYNCHRONIZED case. Or, if nobody 
cares, buf_pwrite should be deleted.


> diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
> index 36f1c6b..0d4c4ef 100644
> --- a/src/gallium/drivers/llvmpipe/lp_texture.c
> +++ b/src/gallium/drivers/llvmpipe/lp_texture.c
> @@ -816,5 +816,6 @@ llvmpipe_init_context_resource_funcs(struct pipe_context *pipe)
>      pipe->transfer_unmap = llvmpipe_transfer_unmap;
>
>      pipe->transfer_flush_region = u_default_transfer_flush_region;
> -   pipe->transfer_inline_write = u_default_transfer_inline_write;
> +   pipe->buffer_subdata = u_default_buffer_subdata;
> +   pipe->texture_subdata = u_default_texture_subdata;
>   }
> diff --git a/src/gallium/drivers/noop/noop_pipe.c b/src/gallium/drivers/noop/noop_pipe.c
> index 99e5f1a..523e798 100644
> --- a/src/gallium/drivers/noop/noop_pipe.c
> +++ b/src/gallium/drivers/noop/noop_pipe.c
> @@ -192,14 +192,21 @@ static void noop_transfer_unmap(struct pipe_context *pipe,
>      FREE(transfer);
>   }
>
> -static void noop_transfer_inline_write(struct pipe_context *pipe,
> -					struct pipe_resource *resource,
> -					unsigned level,
> -					unsigned usage,
> -					const struct pipe_box *box,
> -					const void *data,
> -					unsigned stride,
> -					unsigned layer_stride)
> +static void noop_buffer_subdata(struct pipe_context *pipe,
> +                                struct pipe_resource *resource,
> +                                unsigned usage, unsigned offset,
> +                                unsigned size, const void *data)
> +{
> +}
> +
> +static void noop_texture_subdata(struct pipe_context *pipe,
> +                                 struct pipe_resource *resource,
> +                                 unsigned level,
> +                                 unsigned usage,
> +                                 const struct pipe_box *box,
> +                                 const void *data,
> +                                 unsigned stride,
> +                                 unsigned layer_stride)
>   {
>   }
>
> @@ -294,7 +301,8 @@ static struct pipe_context *noop_create_context(struct pipe_screen *screen,
>   	ctx->transfer_map = noop_transfer_map;
>   	ctx->transfer_flush_region = noop_transfer_flush_region;
>   	ctx->transfer_unmap = noop_transfer_unmap;
> -	ctx->transfer_inline_write = noop_transfer_inline_write;
> +        ctx->buffer_subdata = noop_buffer_subdata;
> +	ctx->texture_subdata = noop_texture_subdata;

Whitespace (tabs vs. spaces?).

>   	noop_init_state_functions(ctx);
>
>   	return ctx;
[snip]
> diff --git a/src/gallium/drivers/radeon/r600_pipe_common.c b/src/gallium/drivers/radeon/r600_pipe_common.c
> index 647832b..230bf68 100644
> --- a/src/gallium/drivers/radeon/r600_pipe_common.c
> +++ b/src/gallium/drivers/radeon/r600_pipe_common.c
> @@ -422,7 +422,8 @@ bool r600_common_context_init(struct r600_common_context *rctx,
>   	rctx->b.transfer_map = u_transfer_map_vtbl;
>   	rctx->b.transfer_flush_region = u_transfer_flush_region_vtbl;
>   	rctx->b.transfer_unmap = u_transfer_unmap_vtbl;
> -	rctx->b.transfer_inline_write = u_default_transfer_inline_write;
> +	rctx->b.buffer_subdata = u_default_buffer_subdata;
> +        rctx->b.texture_subdata = u_default_texture_subdata;

Inconsistent whitespace.

Apart from the comments above, this patch is

Reviewed-by: Nicolai Hähnle <nicolai.haehnle at amd.com>

>           rctx->b.memory_barrier = r600_memory_barrier;
>   	rctx->b.flush = r600_flush_from_st;
>   	rctx->b.set_debug_callback = r600_set_debug_callback;
> diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
> index 7763f81..f7c2f80 100644
> --- a/src/gallium/drivers/radeon/r600_texture.c
> +++ b/src/gallium/drivers/radeon/r600_texture.c
> @@ -1628,7 +1628,6 @@ static const struct u_resource_vtbl r600_texture_vtbl =
>   	r600_texture_transfer_map,	/* transfer_map */
>   	u_default_transfer_flush_region, /* transfer_flush_region */
>   	r600_texture_transfer_unmap,	/* transfer_unmap */
> -	NULL				/* transfer_inline_write */
>   };
>
>   struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
> diff --git a/src/gallium/drivers/rbug/rbug_context.c b/src/gallium/drivers/rbug/rbug_context.c
> index 77f09b0..83914d3 100644
> --- a/src/gallium/drivers/rbug/rbug_context.c
> +++ b/src/gallium/drivers/rbug/rbug_context.c
> @@ -1141,14 +1141,31 @@ rbug_context_transfer_unmap(struct pipe_context *_context,
>
>
>   static void
> -rbug_context_transfer_inline_write(struct pipe_context *_context,
> -                                   struct pipe_resource *_resource,
> -                                   unsigned level,
> -                                   unsigned usage,
> -                                   const struct pipe_box *box,
> -                                   const void *data,
> -                                   unsigned stride,
> -                                   unsigned layer_stride)
> +rbug_context_buffer_subdata(struct pipe_context *_context,
> +                            struct pipe_resource *_resource,
> +                            unsigned usage, unsigned offset,
> +                            unsigned size, const void *data)
> +{
> +   struct rbug_context *rb_pipe = rbug_context(_context);
> +   struct rbug_resource *rb_resource = rbug_resource(_resource);
> +   struct pipe_context *context = rb_pipe->pipe;
> +   struct pipe_resource *resource = rb_resource->resource;
> +
> +   pipe_mutex_lock(rb_pipe->call_mutex);
> +   context->buffer_subdata(context, resource, usage, offset, size, data);
> +   pipe_mutex_unlock(rb_pipe->call_mutex);
> +}
> +
> +
> +static void
> +rbug_context_texture_subdata(struct pipe_context *_context,
> +                             struct pipe_resource *_resource,
> +                             unsigned level,
> +                             unsigned usage,
> +                             const struct pipe_box *box,
> +                             const void *data,
> +                             unsigned stride,
> +                             unsigned layer_stride)
>   {
>      struct rbug_context *rb_pipe = rbug_context(_context);
>      struct rbug_resource *rb_resource = rbug_resource(_resource);
> @@ -1156,14 +1173,14 @@ rbug_context_transfer_inline_write(struct pipe_context *_context,
>      struct pipe_resource *resource = rb_resource->resource;
>
>      pipe_mutex_lock(rb_pipe->call_mutex);
> -   context->transfer_inline_write(context,
> -                                  resource,
> -                                  level,
> -                                  usage,
> -                                  box,
> -                                  data,
> -                                  stride,
> -                                  layer_stride);
> +   context->texture_subdata(context,
> +                            resource,
> +                            level,
> +                            usage,
> +                            box,
> +                            data,
> +                            stride,
> +                            layer_stride);
>      pipe_mutex_unlock(rb_pipe->call_mutex);
>   }
>
> @@ -1252,7 +1269,8 @@ rbug_context_create(struct pipe_screen *_screen, struct pipe_context *pipe)
>      rb_pipe->base.transfer_map = rbug_context_transfer_map;
>      rb_pipe->base.transfer_unmap = rbug_context_transfer_unmap;
>      rb_pipe->base.transfer_flush_region = rbug_context_transfer_flush_region;
> -   rb_pipe->base.transfer_inline_write = rbug_context_transfer_inline_write;
> +   rb_pipe->base.buffer_subdata = rbug_context_buffer_subdata;
> +   rb_pipe->base.texture_subdata = rbug_context_texture_subdata;
>
>      rb_pipe->pipe = pipe;
>
> diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
> index 64666fe..9c64397 100644
> --- a/src/gallium/drivers/softpipe/sp_texture.c
> +++ b/src/gallium/drivers/softpipe/sp_texture.c
> @@ -514,7 +514,8 @@ softpipe_init_texture_funcs(struct pipe_context *pipe)
>      pipe->transfer_unmap = softpipe_transfer_unmap;
>
>      pipe->transfer_flush_region = u_default_transfer_flush_region;
> -   pipe->transfer_inline_write = u_default_transfer_inline_write;
> +   pipe->buffer_subdata = u_default_buffer_subdata;
> +   pipe->texture_subdata = u_default_texture_subdata;
>
>      pipe->create_surface = softpipe_create_surface;
>      pipe->surface_destroy = softpipe_surface_destroy;
> diff --git a/src/gallium/drivers/svga/svga_resource.c b/src/gallium/drivers/svga/svga_resource.c
> index 264ac33..6a297a2 100644
> --- a/src/gallium/drivers/svga/svga_resource.c
> +++ b/src/gallium/drivers/svga/svga_resource.c
> @@ -107,7 +107,8 @@ svga_init_resource_functions(struct svga_context *svga)
>      svga->pipe.transfer_map = u_transfer_map_vtbl;
>      svga->pipe.transfer_flush_region = u_transfer_flush_region_vtbl;
>      svga->pipe.transfer_unmap = u_transfer_unmap_vtbl;
> -   svga->pipe.transfer_inline_write = u_transfer_inline_write_vtbl;
> +   svga->pipe.buffer_subdata = u_default_buffer_subdata;
> +   svga->pipe.texture_subdata = u_default_texture_subdata;
>
>      if (svga_have_vgpu10(svga)) {
>         svga->pipe.generate_mipmap = svga_texture_generate_mipmap;
> diff --git a/src/gallium/drivers/svga/svga_resource_buffer.c b/src/gallium/drivers/svga/svga_resource_buffer.c
> index a92a5c1..68ce103 100644
> --- a/src/gallium/drivers/svga/svga_resource_buffer.c
> +++ b/src/gallium/drivers/svga/svga_resource_buffer.c
> @@ -369,7 +369,6 @@ struct u_resource_vtbl svga_buffer_vtbl =
>      svga_buffer_transfer_map,	     /* transfer_map */
>      svga_buffer_transfer_flush_region,  /* transfer_flush_region */
>      svga_buffer_transfer_unmap,	     /* transfer_unmap */
> -   u_default_transfer_inline_write   /* transfer_inline_write */
>   };
>
>
> diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c
> index 9e1aaab..230221a 100644
> --- a/src/gallium/drivers/svga/svga_resource_texture.c
> +++ b/src/gallium/drivers/svga/svga_resource_texture.c
> @@ -779,7 +779,6 @@ struct u_resource_vtbl svga_texture_vtbl =
>      svga_texture_transfer_map,	      /* transfer_map */
>      u_default_transfer_flush_region,   /* transfer_flush_region */
>      svga_texture_transfer_unmap,	      /* transfer_unmap */
> -   u_default_transfer_inline_write    /* transfer_inline_write */
>   };
>
>
> diff --git a/src/gallium/drivers/swr/swr_context.cpp b/src/gallium/drivers/swr/swr_context.cpp
> index 1f3a14c..1083c9d 100644
> --- a/src/gallium/drivers/swr/swr_context.cpp
> +++ b/src/gallium/drivers/swr/swr_context.cpp
> @@ -376,7 +376,8 @@ swr_create_context(struct pipe_screen *p_screen, void *priv, unsigned flags)
>      ctx->pipe.transfer_unmap = swr_transfer_unmap;
>
>      ctx->pipe.transfer_flush_region = u_default_transfer_flush_region;
> -   ctx->pipe.transfer_inline_write = u_default_transfer_inline_write;
> +   ctx->pipe.buffer_subdata = u_default_buffer_subdata;
> +   ctx->pipe.texture_subdata = u_default_texture_subdata;
>
>      ctx->pipe.resource_copy_region = swr_resource_copy;
>      ctx->pipe.render_condition = swr_render_condition;
> diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
> index c1ad991..65d7f4e 100644
> --- a/src/gallium/drivers/trace/tr_context.c
> +++ b/src/gallium/drivers/trace/tr_context.c
> @@ -1470,7 +1470,7 @@ trace_context_transfer_map(struct pipe_context *_context,
>
>      /*
>       * Map and transfers can't be serialized so we convert all write transfers
> -    * to transfer_inline_write and ignore read transfers.
> +    * to texture/buffer_subdata and ignore read transfers.
>       */
>
>      map = context->transfer_map(context, texture, level, usage, box, &result);
> @@ -1512,7 +1512,7 @@ trace_context_transfer_unmap(struct pipe_context *_context,
>
>      if (tr_trans->map) {
>         /*
> -       * Fake a transfer_inline_write
> +       * Fake a texture/buffer_subdata
>          */
>
>         struct pipe_resource *resource = transfer->resource;
> @@ -1522,7 +1522,10 @@ trace_context_transfer_unmap(struct pipe_context *_context,
>         unsigned stride = transfer->stride;
>         unsigned layer_stride = transfer->layer_stride;
>
> -      trace_dump_call_begin("pipe_context", "transfer_inline_write");
> +      if (resource->target == PIPE_BUFFER)
> +         trace_dump_call_begin("pipe_context", "buffer_subdata");
> +      else
> +         trace_dump_call_begin("pipe_context", "texture_subdata");
>
>         trace_dump_arg(ptr, context);
>         trace_dump_arg(ptr, resource);
> @@ -1552,14 +1555,47 @@ trace_context_transfer_unmap(struct pipe_context *_context,
>
>
>   static void
> -trace_context_transfer_inline_write(struct pipe_context *_context,
> -                                    struct pipe_resource *_resource,
> -                                    unsigned level,
> -                                    unsigned usage,
> -                                    const struct pipe_box *box,
> -                                    const void *data,
> -                                    unsigned stride,
> -                                    unsigned layer_stride)
> +trace_context_buffer_subdata(struct pipe_context *_context,
> +                             struct pipe_resource *_resource,
> +                             unsigned usage, unsigned offset,
> +                             unsigned size, const void *data)
> +{
> +   struct trace_context *tr_context = trace_context(_context);
> +   struct trace_resource *tr_res = trace_resource(_resource);
> +   struct pipe_context *context = tr_context->pipe;
> +   struct pipe_resource *resource = tr_res->resource;
> +   struct pipe_box box;
> +
> +   assert(resource->screen == context->screen);
> +
> +   trace_dump_call_begin("pipe_context", "buffer_subdata");
> +
> +   trace_dump_arg(ptr, context);
> +   trace_dump_arg(ptr, resource);
> +   trace_dump_arg(uint, usage);
> +   trace_dump_arg(uint, offset);
> +   trace_dump_arg(uint, size);
> +
> +   trace_dump_arg_begin("data");
> +   u_box_1d(offset, size, &box);
> +   trace_dump_box_bytes(data, resource, &box, 0, 0);
> +   trace_dump_arg_end();
> +
> +   trace_dump_call_end();
> +
> +   context->buffer_subdata(context, resource, usage, offset, size, data);
> +}
> +
> +
> +static void
> +trace_context_texture_subdata(struct pipe_context *_context,
> +                              struct pipe_resource *_resource,
> +                              unsigned level,
> +                              unsigned usage,
> +                              const struct pipe_box *box,
> +                              const void *data,
> +                              unsigned stride,
> +                              unsigned layer_stride)
>   {
>      struct trace_context *tr_context = trace_context(_context);
>      struct trace_resource *tr_res = trace_resource(_resource);
> @@ -1568,7 +1604,7 @@ trace_context_transfer_inline_write(struct pipe_context *_context,
>
>      assert(resource->screen == context->screen);
>
> -   trace_dump_call_begin("pipe_context", "transfer_inline_write");
> +   trace_dump_call_begin("pipe_context", "texture_subdata");
>
>      trace_dump_arg(ptr, context);
>      trace_dump_arg(ptr, resource);
> @@ -1589,8 +1625,8 @@ trace_context_transfer_inline_write(struct pipe_context *_context,
>
>      trace_dump_call_end();
>
> -   context->transfer_inline_write(context, resource, level, usage, box,
> -                                  data, stride, layer_stride);
> +   context->texture_subdata(context, resource, level, usage, box,
> +                            data, stride, layer_stride);
>   }
>
>
> @@ -1873,7 +1909,8 @@ trace_context_create(struct trace_screen *tr_scr,
>      TR_CTX_INIT(transfer_map);
>      TR_CTX_INIT(transfer_unmap);
>      TR_CTX_INIT(transfer_flush_region);
> -   TR_CTX_INIT(transfer_inline_write);
> +   TR_CTX_INIT(buffer_subdata);
> +   TR_CTX_INIT(texture_subdata);
>
>   #undef TR_CTX_INIT
>
> diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c
> index 08d7d20..398aa81 100644
> --- a/src/gallium/drivers/vc4/vc4_resource.c
> +++ b/src/gallium/drivers/vc4/vc4_resource.c
> @@ -353,7 +353,6 @@ static const struct u_resource_vtbl vc4_resource_vtbl = {
>           .transfer_map             = vc4_resource_transfer_map,
>           .transfer_flush_region    = u_default_transfer_flush_region,
>           .transfer_unmap           = vc4_resource_transfer_unmap,
> -        .transfer_inline_write    = u_default_transfer_inline_write,
>   };
>
>   static void
> @@ -985,7 +984,8 @@ vc4_resource_context_init(struct pipe_context *pctx)
>           pctx->transfer_map = u_transfer_map_vtbl;
>           pctx->transfer_flush_region = u_transfer_flush_region_vtbl;
>           pctx->transfer_unmap = u_transfer_unmap_vtbl;
> -        pctx->transfer_inline_write = u_transfer_inline_write_vtbl;
> +        pctx->buffer_subdata = u_default_buffer_subdata;
> +        pctx->texture_subdata = u_default_texture_subdata;
>           pctx->create_surface = vc4_create_surface;
>           pctx->surface_destroy = vc4_surface_destroy;
>           pctx->resource_copy_region = util_resource_copy_region;
> diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c
> index 9403407..153df8d 100644
> --- a/src/gallium/drivers/virgl/virgl_buffer.c
> +++ b/src/gallium/drivers/virgl/virgl_buffer.c
> @@ -145,7 +145,6 @@ static const struct u_resource_vtbl virgl_buffer_vtbl =
>      virgl_buffer_transfer_map,                /* transfer_map */
>      virgl_buffer_transfer_flush_region,       /* transfer_flush_region */
>      virgl_buffer_transfer_unmap,              /* transfer_unmap */
> -   virgl_transfer_inline_write               /* transfer_inline_write */
>   };
>
>   struct pipe_resource *virgl_buffer_create(struct virgl_screen *vs,
> diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c
> index 2b37947..441b0c1 100644
> --- a/src/gallium/drivers/virgl/virgl_resource.c
> +++ b/src/gallium/drivers/virgl/virgl_resource.c
> @@ -82,10 +82,22 @@ void virgl_init_screen_resource_functions(struct pipe_screen *screen)
>       screen->resource_destroy = u_resource_destroy_vtbl;
>   }
>
> +static void virgl_buffer_subdata(struct pipe_context *pipe,
> +                                 struct pipe_resource *resource,
> +                                 unsigned usage, unsigned offset,
> +                                 unsigned size, const void *data)
> +{
> +   struct pipe_box box;
> +
> +   u_box_1d(offset, size, &box);
> +   virgl_transfer_inline_write(pipe, resource, 0, usage, &box, data, 0, 0);
> +}
> +
>   void virgl_init_context_resource_functions(struct pipe_context *ctx)
>   {
>       ctx->transfer_map = u_transfer_map_vtbl;
>       ctx->transfer_flush_region = u_transfer_flush_region_vtbl;
>       ctx->transfer_unmap = u_transfer_unmap_vtbl;
> -    ctx->transfer_inline_write = u_transfer_inline_write_vtbl;
> +    ctx->buffer_subdata = virgl_buffer_subdata;
> +    ctx->texture_subdata = u_default_texture_subdata;
>   }
> diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c
> index 34db056..64b6744 100644
> --- a/src/gallium/drivers/virgl/virgl_texture.c
> +++ b/src/gallium/drivers/virgl/virgl_texture.c
> @@ -304,7 +304,6 @@ static const struct u_resource_vtbl virgl_texture_vtbl =
>      virgl_texture_transfer_map,          /* transfer_map */
>      NULL,                                /* transfer_flush_region */
>      virgl_texture_transfer_unmap,        /* transfer_unmap */
> -   u_default_transfer_inline_write      /* transfer_inline_write */
>   };
>
>   struct pipe_resource *
> diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
> index 0c88e00..fe567b6 100644
> --- a/src/gallium/include/pipe/p_context.h
> +++ b/src/gallium/include/pipe/p_context.h
> @@ -519,16 +519,23 @@ struct pipe_context {
>                             struct pipe_transfer *transfer);
>
>      /* One-shot transfer operation with data supplied in a user
> -    * pointer.  XXX: strides??
> -    */
> -   void (*transfer_inline_write)( struct pipe_context *,
> -                                  struct pipe_resource *,
> -                                  unsigned level,
> -                                  unsigned usage, /* a combination of PIPE_TRANSFER_x */
> -                                  const struct pipe_box *,
> -                                  const void *data,
> -                                  unsigned stride,
> -                                  unsigned layer_stride);
> +    * pointer.
> +    */
> +   void (*buffer_subdata)(struct pipe_context *,
> +                          struct pipe_resource *,
> +                          unsigned usage, /* a combination of PIPE_TRANSFER_x */
> +                          unsigned offset,
> +                          unsigned size,
> +                          const void *data);
> +
> +   void (*texture_subdata)(struct pipe_context *,
> +                           struct pipe_resource *,
> +                           unsigned level,
> +                           unsigned usage, /* a combination of PIPE_TRANSFER_x */
> +                           const struct pipe_box *,
> +                           const void *data,
> +                           unsigned stride,
> +                           unsigned layer_stride);
>
>      /**
>       * Flush any pending framebuffer writes and invalidate texture caches.
> diff --git a/src/gallium/state_trackers/clover/core/resource.cpp b/src/gallium/state_trackers/clover/core/resource.cpp
> index 10a29a9..83781d3 100644
> --- a/src/gallium/state_trackers/clover/core/resource.cpp
> +++ b/src/gallium/state_trackers/clover/core/resource.cpp
> @@ -161,9 +161,13 @@ root_resource::root_resource(clover::device &dev, memory_obj &obj,
>         box rect { {{ 0, 0, 0 }}, {{ info.width0, info.height0, info.depth0 }} };
>         unsigned cpp = util_format_get_blocksize(info.format);
>
> -      q.pipe->transfer_inline_write(q.pipe, pipe, 0, PIPE_TRANSFER_WRITE,
> -                                    rect, data_ptr, cpp * info.width0,
> -                                    cpp * info.width0 * info.height0);
> +      if (pipe->target == PIPE_BUFFER)
> +         q.pipe->buffer_subdata(q.pipe, pipe, PIPE_TRANSFER_WRITE,
> +                                0, info.width0, data_ptr);
> +      else
> +         q.pipe->texture_subdata(q.pipe, pipe, 0, PIPE_TRANSFER_WRITE,
> +                                 rect, data_ptr, cpp * info.width0,
> +                                 cpp * info.width0 * info.height0);
>      }
>   }
>
> diff --git a/src/gallium/state_trackers/nine/buffer9.h b/src/gallium/state_trackers/nine/buffer9.h
> index 8bdb432..c109cf6 100644
> --- a/src/gallium/state_trackers/nine/buffer9.h
> +++ b/src/gallium/state_trackers/nine/buffer9.h
> @@ -88,10 +88,10 @@ NineBuffer9_Upload( struct NineBuffer9 *This )
>       struct pipe_context *pipe = This->pipe;
>
>       assert(This->base.pool == D3DPOOL_MANAGED && This->managed.dirty);
> -    pipe->transfer_inline_write(pipe, This->base.resource, 0, 0,
> -                                &This->managed.dirty_box,
> -                                (char *)This->managed.data + This->managed.dirty_box.x,
> -                                This->size, This->size);
> +    pipe->buffer_subdata(pipe, This->base.resource, 0,
> +                         This->managed.dirty_box.x,
> +                         This->managed.dirty_box.width,
> +                         (char *)This->managed.data + This->managed.dirty_box.x);
>       This->managed.dirty = FALSE;
>   }
>
> diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
> index 6aa6325..fd098ca 100644
> --- a/src/gallium/state_trackers/nine/nine_state.c
> +++ b/src/gallium/state_trackers/nine/nine_state.c
> @@ -86,8 +86,7 @@ prepare_ps_constants_userbuf(struct NineDevice9 *device);
>           DBG("upload ConstantF [%u .. %u]\n", x, (x) + (c) - 1); \
>           box.x = (p) * 4 * sizeof(float); \
>           box.width = (c) * 4 * sizeof(float); \
> -        pipe->transfer_inline_write(pipe, buf, 0, usage, &box, &((d)[p * 4]), \
> -                                    0, 0); \
> +        pipe->buffer_subdata(pipe, buf, usage, box.x, box.width, &((d)[p * 4])); \
>       } while(0)
>
>   /* OK, this is a bit ugly ... */
> @@ -186,7 +185,7 @@ upload_constants(struct NineDevice9 *device, unsigned shader_type)
>          box.x = x;
>          box.width = c * 4;
>          DBG("upload ConstantB [%u .. %u]\n", x, x + c - 1);
> -       pipe->transfer_inline_write(pipe, buf, 0, usage, &box, data_b, 0, 0);
> +       pipe->buffer_subdata(pipe, buf, usage, box.x, box.width, data_b);
>       }
>
>       /* int4 */
> @@ -203,7 +202,7 @@ upload_constants(struct NineDevice9 *device, unsigned shader_type)
>               box.x += x * 4 * sizeof(int);
>               box.width = c * 4 * sizeof(int);
>               c = 0;
> -            pipe->transfer_inline_write(pipe, buf, 0, usage, &box, data, 0, 0);
> +            pipe->buffer_subdata(pipe, buf, usage, box.x, box.width, data);
>           }
>       }
>       if (c) {
> @@ -212,7 +211,7 @@ upload_constants(struct NineDevice9 *device, unsigned shader_type)
>           box.x  = buf->width0 - (NINE_MAX_CONST_I * 4 + NINE_MAX_CONST_B) * 4;
>           box.x += x * 4 * sizeof(int);
>           box.width = c * 4 * sizeof(int);
> -        pipe->transfer_inline_write(pipe, buf, 0, usage, &box, data, 0, 0);
> +        pipe->buffer_subdata(pipe, buf, usage, box.x, box.width, data);
>       }
>
>       /* TODO: only upload these when shader itself changes */
> @@ -224,7 +223,7 @@ upload_constants(struct NineDevice9 *device, unsigned shader_type)
>               n += r->end - r->bgn;
>               box.width = (r->end - r->bgn) * 4 * sizeof(float);
>               data = &lconstf_data[4 * n];
> -            pipe->transfer_inline_write(pipe, buf, 0, usage, &box, data, 0, 0);
> +            pipe->buffer_subdata(pipe, buf, usage, box.x, box.width, data);
>               r = r->next;
>           }
>       }
> diff --git a/src/gallium/state_trackers/nine/surface9.c b/src/gallium/state_trackers/nine/surface9.c
> index 2606dbf..6a4a0d9 100644
> --- a/src/gallium/state_trackers/nine/surface9.c
> +++ b/src/gallium/state_trackers/nine/surface9.c
> @@ -673,8 +673,8 @@ NineSurface9_UploadSelf( struct NineSurface9 *This,
>
>       ptr = NineSurface9_GetSystemMemPointer(This, box.x, box.y);
>
> -    pipe->transfer_inline_write(pipe, res, This->level, 0,
> -                                &box, ptr, This->stride, 0);
> +    pipe->texture_subdata(pipe, res, This->level, 0,
> +                          &box, ptr, This->stride, 0);
>
>       return D3D_OK;
>   }
> diff --git a/src/gallium/state_trackers/nine/volume9.c b/src/gallium/state_trackers/nine/volume9.c
> index 1fdc638..0302b09 100644
> --- a/src/gallium/state_trackers/nine/volume9.c
> +++ b/src/gallium/state_trackers/nine/volume9.c
> @@ -496,8 +496,8 @@ NineVolume9_UploadSelf( struct NineVolume9 *This,
>
>       ptr = NineVolume9_GetSystemMemPointer(This, box.x, box.y, box.z);
>
> -    pipe->transfer_inline_write(pipe, res, This->level, 0, &box,
> -                                ptr, This->stride, This->layer_stride);
> +    pipe->texture_subdata(pipe, res, This->level, 0, &box,
> +                          ptr, This->stride, This->layer_stride);
>
>       return D3D_OK;
>   }
> diff --git a/src/gallium/state_trackers/omx/vid_enc.c b/src/gallium/state_trackers/omx/vid_enc.c
> index 642238e..0d7ab28 100644
> --- a/src/gallium/state_trackers/omx/vid_enc.c
> +++ b/src/gallium/state_trackers/omx/vid_enc.c
> @@ -905,16 +905,16 @@ static OMX_ERRORTYPE enc_LoadImage(omx_base_PortType *port, OMX_BUFFERHEADERTYPE
>         box.width = def->nFrameWidth;
>         box.height = def->nFrameHeight;
>         box.depth = 1;
> -      priv->s_pipe->transfer_inline_write(priv->s_pipe, views[0]->texture, 0,
> -                                          PIPE_TRANSFER_WRITE, &box,
> -                                          ptr, def->nStride, 0);
> +      priv->s_pipe->texture_subdata(priv->s_pipe, views[0]->texture, 0,
> +                                    PIPE_TRANSFER_WRITE, &box,
> +                                    ptr, def->nStride, 0);
>         ptr = ((uint8_t*)buf->pBuffer) + (def->nStride * box.height);
>         box.width = def->nFrameWidth / 2;
>         box.height = def->nFrameHeight / 2;
>         box.depth = 1;
> -      priv->s_pipe->transfer_inline_write(priv->s_pipe, views[1]->texture, 0,
> -                                          PIPE_TRANSFER_WRITE, &box,
> -                                          ptr, def->nStride, 0);
> +      priv->s_pipe->texture_subdata(priv->s_pipe, views[1]->texture, 0,
> +                                    PIPE_TRANSFER_WRITE, &box,
> +                                    ptr, def->nStride, 0);
>      } else {
>         struct pipe_blit_info blit;
>         struct vl_video_buffer *dst_buf = (struct vl_video_buffer *)vbuf;
> diff --git a/src/gallium/state_trackers/va/image.c b/src/gallium/state_trackers/va/image.c
> index 1b956e3..36b2469 100644
> --- a/src/gallium/state_trackers/va/image.c
> +++ b/src/gallium/state_trackers/va/image.c
> @@ -515,10 +515,10 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
>         vlVaVideoSurfaceSize(surf, i, &width, &height);
>         for (j = 0; j < views[i]->texture->array_size; ++j) {
>            struct pipe_box dst_box = {0, 0, j, width, height, 1};
> -         drv->pipe->transfer_inline_write(drv->pipe, views[i]->texture, 0,
> -            PIPE_TRANSFER_WRITE, &dst_box,
> -            data[i] + pitches[i] * j,
> -            pitches[i] * views[i]->texture->array_size, 0);
> +         drv->pipe->texture_subdata(drv->pipe, views[i]->texture, 0,
> +                                    PIPE_TRANSFER_WRITE, &dst_box,
> +                                    data[i] + pitches[i] * j,
> +                                    pitches[i] * views[i]->texture->array_size, 0);
>         }
>      }
>      pipe_mutex_unlock(drv->mutex);
> diff --git a/src/gallium/state_trackers/vdpau/bitmap.c b/src/gallium/state_trackers/vdpau/bitmap.c
> index 35c8820..fd67a98 100644
> --- a/src/gallium/state_trackers/vdpau/bitmap.c
> +++ b/src/gallium/state_trackers/vdpau/bitmap.c
> @@ -201,9 +201,9 @@ vlVdpBitmapSurfacePutBitsNative(VdpBitmapSurface surface,
>      vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
>
>      dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture);
> -   pipe->transfer_inline_write(pipe, vlsurface->sampler_view->texture, 0,
> -                               PIPE_TRANSFER_WRITE, &dst_box, *source_data,
> -                               *source_pitches, 0);
> +   pipe->texture_subdata(pipe, vlsurface->sampler_view->texture, 0,
> +                         PIPE_TRANSFER_WRITE, &dst_box, *source_data,
> +                         *source_pitches, 0);
>
>      pipe_mutex_unlock(vlsurface->device->mutex);
>
> diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c
> index 8a064e8..0b4f081 100644
> --- a/src/gallium/state_trackers/vdpau/output.c
> +++ b/src/gallium/state_trackers/vdpau/output.c
> @@ -257,9 +257,9 @@ vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface,
>      vlVdpResolveDelayedRendering(vlsurface->device, NULL, NULL);
>
>      dst_box = RectToPipeBox(destination_rect, vlsurface->sampler_view->texture);
> -   pipe->transfer_inline_write(pipe, vlsurface->sampler_view->texture, 0,
> -                               PIPE_TRANSFER_WRITE, &dst_box, *source_data,
> -                               *source_pitches, 0);
> +   pipe->texture_subdata(pipe, vlsurface->sampler_view->texture, 0,
> +                         PIPE_TRANSFER_WRITE, &dst_box, *source_data,
> +                         *source_pitches, 0);
>      pipe_mutex_unlock(vlsurface->device->mutex);
>
>      return VDP_STATUS_OK;
> @@ -346,9 +346,9 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
>      box.height = res->height0;
>      box.depth = res->depth0;
>
> -   context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box,
> -                                  source_data[0], source_pitch[0],
> -                                  source_pitch[0] * res->height0);
> +   context->texture_subdata(context, res, 0, PIPE_TRANSFER_WRITE, &box,
> +                            source_data[0], source_pitch[0],
> +                            source_pitch[0] * res->height0);
>
>      memset(&sv_tmpl, 0, sizeof(sv_tmpl));
>      u_sampler_view_default_template(&sv_tmpl, res, res->format);
> @@ -379,8 +379,8 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
>      box.height = res->height0;
>      box.depth = res->depth0;
>
> -   context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table,
> -                                  util_format_get_stride(colortbl_format, res->width0), 0);
> +   context->texture_subdata(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table,
> +                            util_format_get_stride(colortbl_format, res->width0), 0);
>
>      memset(&sv_tmpl, 0, sizeof(sv_tmpl));
>      u_sampler_view_default_template(&sv_tmpl, res, res->format);
> @@ -485,8 +485,8 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
>            sv->texture->width0, sv->texture->height0, 1
>         };
>
> -      pipe->transfer_inline_write(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE, &dst_box,
> -                                  source_data[i], source_pitches[i], 0);
> +      pipe->texture_subdata(pipe, sv->texture, 0, PIPE_TRANSFER_WRITE, &dst_box,
> +                            source_data[i], source_pitches[i], 0);
>      }
>
>      if (!csc_matrix) {
> diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
> index 7998527..6dc479a 100644
> --- a/src/gallium/state_trackers/vdpau/surface.c
> +++ b/src/gallium/state_trackers/vdpau/surface.c
> @@ -359,11 +359,11 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
>               width, height, 1
>            };
>
> -         pipe->transfer_inline_write(pipe, sv->texture, 0,
> -                                     PIPE_TRANSFER_WRITE, &dst_box,
> -                                     source_data[i] + source_pitches[i] * j,
> -                                     source_pitches[i] * sv->texture->array_size,
> -                                     0);
> +         pipe->texture_subdata(pipe, sv->texture, 0,
> +                               PIPE_TRANSFER_WRITE, &dst_box,
> +                               source_data[i] + source_pitches[i] * j,
> +                               source_pitches[i] * sv->texture->array_size,
> +                               0);
>         }
>      }
>      pipe_mutex_unlock(p_surf->device->mutex);
> diff --git a/src/gallium/tests/graw/fs-test.c b/src/gallium/tests/graw/fs-test.c
> index bd5259a..b237692 100644
> --- a/src/gallium/tests/graw/fs-test.c
> +++ b/src/gallium/tests/graw/fs-test.c
> @@ -311,14 +311,14 @@ static void init_tex( void )
>
>      u_box_2d(0,0,SIZE,SIZE, &box);
>
> -   ctx->transfer_inline_write(ctx,
> -                              samptex,
> -                              0,
> -                              PIPE_TRANSFER_WRITE,
> -                              &box,
> -                              tex2d,
> -                              sizeof tex2d[0],
> -                              sizeof tex2d);
> +   ctx->texture_subdata(ctx,
> +                        samptex,
> +                        0,
> +                        PIPE_TRANSFER_WRITE,
> +                        &box,
> +                        tex2d,
> +                        sizeof tex2d[0],
> +                        sizeof tex2d);
>
>      /* Possibly read back & compare against original data:
>       */
> diff --git a/src/gallium/tests/graw/graw_util.h b/src/gallium/tests/graw/graw_util.h
> index 5d72bb9..f603385 100644
> --- a/src/gallium/tests/graw/graw_util.h
> +++ b/src/gallium/tests/graw/graw_util.h
> @@ -242,14 +242,14 @@ graw_util_create_tex2d(const struct graw_info *info,
>
>      u_box_2d(0, 0, width, height, &box);
>
> -   info->ctx->transfer_inline_write(info->ctx,
> -                                    tex,
> -                                    0,
> -                                    PIPE_TRANSFER_WRITE,
> -                                    &box,
> -                                    data,
> -                                    row_stride,
> -                                    image_bytes);
> +   info->ctx->texture_subdata(info->ctx,
> +                              tex,
> +                              0,
> +                              PIPE_TRANSFER_WRITE,
> +                              &box,
> +                              data,
> +                              row_stride,
> +                              image_bytes);
>
>      /* Possibly read back & compare against original data:
>       */
> diff --git a/src/gallium/tests/graw/gs-test.c b/src/gallium/tests/graw/gs-test.c
> index c680b62..00fb591 100644
> --- a/src/gallium/tests/graw/gs-test.c
> +++ b/src/gallium/tests/graw/gs-test.c
> @@ -149,7 +149,6 @@ static float constants2[] =
>   static void init_fs_constbuf( void )
>   {
>      struct pipe_resource templat;
> -   struct pipe_box box;
>
>      templat.target = PIPE_BUFFER;
>      templat.format = PIPE_FORMAT_R8_UNORM;
> @@ -169,34 +168,18 @@ static void init_fs_constbuf( void )
>         exit(4);
>
>      {
> -      u_box_2d(0,0,sizeof(constants1),1, &box);
> -
> -      ctx->transfer_inline_write(ctx,
> -                                 constbuf1,
> -                                 0,
> -                                 PIPE_TRANSFER_WRITE,
> -                                 &box,
> -                                 constants1,
> -                                 sizeof constants1,
> -                                 sizeof constants1);
> -
> +      ctx->buffer_subdata(ctx, constbuf1,
> +                          PIPE_TRANSFER_WRITE,
> +                          0, sizeof(constants1), constants1);
>
>         pipe_set_constant_buffer(ctx,
>                                  PIPE_SHADER_GEOMETRY, 0,
>                                  constbuf1);
>      }
>      {
> -      u_box_2d(0,0,sizeof(constants2),1, &box);
> -
> -      ctx->transfer_inline_write(ctx,
> -                                 constbuf2,
> -                                 0,
> -                                 PIPE_TRANSFER_WRITE,
> -                                 &box,
> -                                 constants2,
> -                                 sizeof constants2,
> -                                 sizeof constants2);
> -
> +      ctx->buffer_subdata(ctx, constbuf2,
> +                          PIPE_TRANSFER_WRITE,
> +                          0, sizeof(constants2), constants2);
>
>         pipe_set_constant_buffer(ctx,
>                                  PIPE_SHADER_GEOMETRY, 1,
> @@ -418,14 +401,14 @@ static void init_tex( void )
>
>      u_box_2d(0,0,SIZE,SIZE, &box);
>
> -   ctx->transfer_inline_write(ctx,
> -                              samptex,
> -                              0,
> -                              PIPE_TRANSFER_WRITE,
> -                              &box,
> -                              tex2d,
> -                              sizeof tex2d[0],
> -                              sizeof tex2d);
> +   ctx->texture_subdata(ctx,
> +                        samptex,
> +                        0,
> +                        PIPE_TRANSFER_WRITE,
> +                        &box,
> +                        tex2d,
> +                        sizeof tex2d[0],
> +         sizeof tex2d);
>
>      /* Possibly read back & compare against original data:
>       */
> diff --git a/src/gallium/tests/graw/quad-sample.c b/src/gallium/tests/graw/quad-sample.c
> index 97f241f..d1bee35 100644
> --- a/src/gallium/tests/graw/quad-sample.c
> +++ b/src/gallium/tests/graw/quad-sample.c
> @@ -226,14 +226,14 @@ static void init_tex( void )
>
>      u_box_2d(0,0,SIZE,SIZE, &box);
>
> -   ctx->transfer_inline_write(ctx,
> -                              samptex,
> -                              0,
> -                              PIPE_TRANSFER_WRITE,
> -                              &box,
> -                              tex2d,
> -                              sizeof tex2d[0],
> -                              sizeof tex2d);
> +   ctx->texture_subdata(ctx,
> +                        samptex,
> +                        0,
> +                        PIPE_TRANSFER_WRITE,
> +                        &box,
> +                        tex2d,
> +                        sizeof tex2d[0],
> +                        sizeof tex2d);
>
>      /* Possibly read back & compare against original data:
>       */
> diff --git a/src/gallium/tests/graw/vs-test.c b/src/gallium/tests/graw/vs-test.c
> index 3a55131..48f06f4 100644
> --- a/src/gallium/tests/graw/vs-test.c
> +++ b/src/gallium/tests/graw/vs-test.c
> @@ -100,15 +100,9 @@ static void init_fs_constbuf( void )
>
>      u_box_2d(0,0,sizeof(constants),1, &box);
>
> -   ctx->transfer_inline_write(ctx,
> -                              constbuf,
> -                              0,
> -                              PIPE_TRANSFER_WRITE,
> -                              &box,
> -                              constants,
> -                              sizeof constants,
> -                              sizeof constants);
> -
> +   ctx->buffer_subdata(ctx, constbuf,
> +                       PIPE_TRANSFER_WRITE,
> +                       0, sizeof(constants), constants);
>
>      pipe_set_constant_buffer(ctx,
>                               PIPE_SHADER_VERTEX, 0,
> @@ -305,14 +299,14 @@ static void init_tex( void )
>
>      u_box_2d(0,0,SIZE,SIZE, &box);
>
> -   ctx->transfer_inline_write(ctx,
> -                              samptex,
> -                              0,
> -                              PIPE_TRANSFER_WRITE,
> -                              &box,
> -                              tex2d,
> -                              sizeof tex2d[0],
> -                              sizeof tex2d);
> +   ctx->texture_subdata(ctx,
> +                        samptex,
> +                        0,
> +                        PIPE_TRANSFER_WRITE,
> +                        &box,
> +                        tex2d,
> +                        sizeof tex2d[0],
> +                        sizeof tex2d);
>
>      /* Possibly read back & compare against original data:
>       */
> diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
> index 1a8aea3..2d4c821 100644
> --- a/src/mesa/state_tracker/st_cb_bufferobjects.c
> +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
> @@ -196,12 +196,9 @@ st_bufferobj_data(struct gl_context *ctx,
>             * This should be the same as creating a new buffer, but we avoid
>             * a lot of validation in Mesa.
>             */
> -         struct pipe_box box;
> -
> -         u_box_1d(0, size, &box);
> -         pipe->transfer_inline_write(pipe, st_obj->buffer, 0,
> -                                    PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE,
> -                                    &box, data, 0, 0);
> +         pipe->buffer_subdata(pipe, st_obj->buffer,
> +                              PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE,
> +                              0, size, data);
>            return GL_TRUE;
>         } else if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER)) {
>            pipe->invalidate_resource(pipe, st_obj->buffer);
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index a76775f..d2acc71 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -1339,7 +1339,7 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
>      if (!dst)
>         goto fallback;
>
> -   /* Try transfer_inline_write, which should be the fastest memcpy path. */
> +   /* Try texture_subdata, which should be the fastest memcpy path. */
>      if (pixels &&
>          !_mesa_is_bufferobj(unpack->BufferObj) &&
>          _mesa_texstore_can_use_memcpy(ctx, texImage->_BaseFormat,
> @@ -1365,8 +1365,8 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
>         }
>
>         u_box_3d(xoffset, yoffset, zoffset + dstz, width, height, depth, &box);
> -      pipe->transfer_inline_write(pipe, dst, dst_level, 0,
> -                                  &box, data, stride, layer_stride);
> +      pipe->texture_subdata(pipe, dst, dst_level, 0,
> +                            &box, data, stride, layer_stride);
>         return;
>      }
>
>


More information about the mesa-dev mailing list