Re: [Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.

2013-02-27 Thread Marek Olšák
What is this good for? Is it for UAVs? (unordered access views)

For UAVs, I think there is ARB_shader_storage_buffer_object and
pipe_context::set_shader_resources.

Marek

On Wed, Feb 27, 2013 at 3:18 AM,  srol...@vmware.com wrote:
 From: Roland Scheidegger srol...@vmware.com

 Unfortunately not usable from OpenGL, and no cap bit.
 Pretty similar to a 1d texture, though allows specifying a start element.
 The util code for handling clears also needs adjustments (and fix
 a bug causing crashes for handling pure integer formats there too).
 ---
  src/gallium/auxiliary/util/u_surface.c  |   55 
 +++
  src/gallium/drivers/llvmpipe/lp_rast.c  |   25 ++--
  src/gallium/drivers/llvmpipe/lp_rast_priv.h |4 +-
  src/gallium/drivers/llvmpipe/lp_scene.c |   35 +++--
  src/gallium/drivers/llvmpipe/lp_texture.c   |   44 +++--
  5 files changed, 108 insertions(+), 55 deletions(-)

 diff --git a/src/gallium/auxiliary/util/u_surface.c 
 b/src/gallium/auxiliary/util/u_surface.c
 index b948b46..fba0798 100644
 --- a/src/gallium/auxiliary/util/u_surface.c
 +++ b/src/gallium/auxiliary/util/u_surface.c
 @@ -323,20 +323,59 @@ util_clear_render_target(struct pipe_context *pipe,
 if (!dst-texture)
return;
 /* XXX: should handle multiple layers */
 -   dst_map = pipe_transfer_map(pipe,
 -   dst-texture,
 -   dst-u.tex.level,
 -   dst-u.tex.first_layer,
 -   PIPE_TRANSFER_WRITE,
 -   dstx, dsty, width, height, dst_trans);
 +
 +   if (dst-texture-target == PIPE_BUFFER) {
 +  /*
 +   * The fill naturally works on the surface format, however
 +   * the transfer uses resource format which is just bytes for buffers.
 +   */
 +  unsigned dx, w;
 +  unsigned pixstride = util_format_get_blocksize(dst-format);
 +  dx = dstx * pixstride;
 +  w = width * pixstride;
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  0, 0,
 +  PIPE_TRANSFER_WRITE,
 +  dx, 0, w, 1,
 +  dst_trans);
 +  dst_map = (uint8_t *)dst_map + dst-u.buf.first_element * pixstride;
 +   }
 +   else {
 +  /* XXX: should handle multiple layers */
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  dst-u.tex.level,
 +  dst-u.tex.first_layer,
 +  PIPE_TRANSFER_WRITE,
 +  dstx, dsty, width, height, dst_trans);
 +
 +   }

 assert(dst_map);

 if (dst_map) {
 +  enum pipe_format format = dst-format;
assert(dst_trans-stride  0);

 -  util_pack_color(color-f, dst-texture-format, uc);
 -  util_fill_rect(dst_map, dst-texture-format,
 +  if (util_format_is_pure_integer(format)) {
 + /*
 +  * We expect int/uint clear values here, though some APIs
 +  * might disagree (but in any case util_pack_color()
 +  * couldn't handle it)...
 +  */
 + if (util_format_is_pure_sint(format)) {
 +util_format_write_4i(format, color-i, 0, uc, 0, 0, 0, 1, 1);
 + }
 + else {
 +assert(util_format_is_pure_uint(format));
 +util_format_write_4ui(format, color-ui, 0, uc, 0, 0, 0, 1, 1);
 + }
 +  }
 +  else {
 + util_pack_color(color-f, dst-format, uc);
 +  }
 +  util_fill_rect(dst_map, dst-format,
   dst_trans-stride,
   0, 0, width, height, uc);

 diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c 
 b/src/gallium/drivers/llvmpipe/lp_rast.c
 index b5e5da6..6183f41 100644
 --- a/src/gallium/drivers/llvmpipe/lp_rast.c
 +++ b/src/gallium/drivers/llvmpipe/lp_rast.c
 @@ -165,32 +165,13 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,

   for (i = 0; i  scene-fb.nr_cbufs; i++) {
  enum pipe_format format = scene-fb.cbufs[i]-format;
 -/*
 - * XXX the format_write_4i/ui functions do clamping to max value
 - * and I'm not sure that's actually right - spec doesn't seem to
 - * say much about that topic. If it is should probably adjust the
 - * border color handling to do the same. If not and chopping off
 - * bits is the way to go, the write_4i and write_4ui functions
 - * would be identical.
 - */
 -if (util_format_is_pure_sint(format)) {
 -   int rgba[4];
 -   rgba[0] = arg.clear_color.i[0];
 -   rgba[1] = arg.clear_color.i[1];
 -   rgba[2] = arg.clear_color.i[2];
 -   rgba[3] = arg.clear_color.i[3];

 -   

Re: [Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.

2013-02-27 Thread Jose Fonseca
- Original Message -
 What is this good for? Is it for UAVs? (unordered access views)

No, it is just a standard D3D10 feature: 
http://msdn.microsoft.com/en-gb/library/windows/desktop/bb204897.aspx

Not sure if there's a particular use case for it (e.g, maybe DirectCompute uses 
this extensively), or just a matter of symmetry in the API (ie., if one can 
sample from buffer textures, then why not render into them?)

 For UAVs, I think there is ARB_shader_storage_buffer_object and
 pipe_context::set_shader_resources.

Yeah, D3D11 UAVs are also supposed to be bound separately in the pipeline.

Jose

 
 Marek
 
 On Wed, Feb 27, 2013 at 3:18 AM,  srol...@vmware.com wrote:
  From: Roland Scheidegger srol...@vmware.com
 
  Unfortunately not usable from OpenGL, and no cap bit.
  Pretty similar to a 1d texture, though allows specifying a start element.
  The util code for handling clears also needs adjustments (and fix
  a bug causing crashes for handling pure integer formats there too).
  ---
   src/gallium/auxiliary/util/u_surface.c  |   55
   +++
   src/gallium/drivers/llvmpipe/lp_rast.c  |   25 ++--
   src/gallium/drivers/llvmpipe/lp_rast_priv.h |4 +-
   src/gallium/drivers/llvmpipe/lp_scene.c |   35 +++--
   src/gallium/drivers/llvmpipe/lp_texture.c   |   44 +++--
   5 files changed, 108 insertions(+), 55 deletions(-)
 
  diff --git a/src/gallium/auxiliary/util/u_surface.c
  b/src/gallium/auxiliary/util/u_surface.c
  index b948b46..fba0798 100644
  --- a/src/gallium/auxiliary/util/u_surface.c
  +++ b/src/gallium/auxiliary/util/u_surface.c
  @@ -323,20 +323,59 @@ util_clear_render_target(struct pipe_context *pipe,
  if (!dst-texture)
 return;
  /* XXX: should handle multiple layers */
  -   dst_map = pipe_transfer_map(pipe,
  -   dst-texture,
  -   dst-u.tex.level,
  -   dst-u.tex.first_layer,
  -   PIPE_TRANSFER_WRITE,
  -   dstx, dsty, width, height, dst_trans);
  +
  +   if (dst-texture-target == PIPE_BUFFER) {
  +  /*
  +   * The fill naturally works on the surface format, however
  +   * the transfer uses resource format which is just bytes for
  buffers.
  +   */
  +  unsigned dx, w;
  +  unsigned pixstride = util_format_get_blocksize(dst-format);
  +  dx = dstx * pixstride;
  +  w = width * pixstride;
  +  dst_map = pipe_transfer_map(pipe,
  +  dst-texture,
  +  0, 0,
  +  PIPE_TRANSFER_WRITE,
  +  dx, 0, w, 1,
  +  dst_trans);
  +  dst_map = (uint8_t *)dst_map + dst-u.buf.first_element * pixstride;
  +   }
  +   else {
  +  /* XXX: should handle multiple layers */
  +  dst_map = pipe_transfer_map(pipe,
  +  dst-texture,
  +  dst-u.tex.level,
  +  dst-u.tex.first_layer,
  +  PIPE_TRANSFER_WRITE,
  +  dstx, dsty, width, height, dst_trans);
  +
  +   }
 
  assert(dst_map);
 
  if (dst_map) {
  +  enum pipe_format format = dst-format;
 assert(dst_trans-stride  0);
 
  -  util_pack_color(color-f, dst-texture-format, uc);
  -  util_fill_rect(dst_map, dst-texture-format,
  +  if (util_format_is_pure_integer(format)) {
  + /*
  +  * We expect int/uint clear values here, though some APIs
  +  * might disagree (but in any case util_pack_color()
  +  * couldn't handle it)...
  +  */
  + if (util_format_is_pure_sint(format)) {
  +util_format_write_4i(format, color-i, 0, uc, 0, 0, 0, 1, 1);
  + }
  + else {
  +assert(util_format_is_pure_uint(format));
  +util_format_write_4ui(format, color-ui, 0, uc, 0, 0, 0, 1,
  1);
  + }
  +  }
  +  else {
  + util_pack_color(color-f, dst-format, uc);
  +  }
  +  util_fill_rect(dst_map, dst-format,
dst_trans-stride,
0, 0, width, height, uc);
 
  diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c
  b/src/gallium/drivers/llvmpipe/lp_rast.c
  index b5e5da6..6183f41 100644
  --- a/src/gallium/drivers/llvmpipe/lp_rast.c
  +++ b/src/gallium/drivers/llvmpipe/lp_rast.c
  @@ -165,32 +165,13 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
 
for (i = 0; i  scene-fb.nr_cbufs; i++) {
   enum pipe_format format = scene-fb.cbufs[i]-format;
  -/*
  - * XXX the format_write_4i/ui functions do clamping to max
  value
  - * and I'm not sure that's actually right - spec doesn't seem
  to
  - * say much about that 

Re: [Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.

2013-02-27 Thread Christoph Bumiller
On 27.02.2013 10:44, Jose Fonseca wrote:
 - Original Message -
 What is this good for? Is it for UAVs? (unordered access views)
 No, it is just a standard D3D10 feature: 
 http://msdn.microsoft.com/en-gb/library/windows/desktop/bb204897.aspx

 Not sure if there's a particular use case for it (e.g, maybe DirectCompute 
 uses this extensively), or just a matter of symmetry in the API (ie., if one 
 can sample from buffer textures, then why not render into them?)
I can think of rendering to vertex buffers. It's just annoying that
there are no alignment restrictions on the range that is bound (worst
case you have to render to a temporary buffer and copy stuff around);
but at least it has to be = 8192 bytes (or elements, not sure) in D3D10.

 For UAVs, I think there is ARB_shader_storage_buffer_object and
 pipe_context::set_shader_resources.
 Yeah, D3D11 UAVs are also supposed to be bound separately in the pipeline.

 Jose

 Marek

 On Wed, Feb 27, 2013 at 3:18 AM,  srol...@vmware.com wrote:
 From: Roland Scheidegger srol...@vmware.com

 Unfortunately not usable from OpenGL, and no cap bit.
 Pretty similar to a 1d texture, though allows specifying a start element.
 The util code for handling clears also needs adjustments (and fix
 a bug causing crashes for handling pure integer formats there too).
 ---
  src/gallium/auxiliary/util/u_surface.c  |   55
  +++
  src/gallium/drivers/llvmpipe/lp_rast.c  |   25 ++--
  src/gallium/drivers/llvmpipe/lp_rast_priv.h |4 +-
  src/gallium/drivers/llvmpipe/lp_scene.c |   35 +++--
  src/gallium/drivers/llvmpipe/lp_texture.c   |   44 +++--
  5 files changed, 108 insertions(+), 55 deletions(-)

 diff --git a/src/gallium/auxiliary/util/u_surface.c
 b/src/gallium/auxiliary/util/u_surface.c
 index b948b46..fba0798 100644
 --- a/src/gallium/auxiliary/util/u_surface.c
 +++ b/src/gallium/auxiliary/util/u_surface.c
 @@ -323,20 +323,59 @@ util_clear_render_target(struct pipe_context *pipe,
 if (!dst-texture)
return;
 /* XXX: should handle multiple layers */
 -   dst_map = pipe_transfer_map(pipe,
 -   dst-texture,
 -   dst-u.tex.level,
 -   dst-u.tex.first_layer,
 -   PIPE_TRANSFER_WRITE,
 -   dstx, dsty, width, height, dst_trans);
 +
 +   if (dst-texture-target == PIPE_BUFFER) {
 +  /*
 +   * The fill naturally works on the surface format, however
 +   * the transfer uses resource format which is just bytes for
 buffers.
 +   */
 +  unsigned dx, w;
 +  unsigned pixstride = util_format_get_blocksize(dst-format);
 +  dx = dstx * pixstride;
 +  w = width * pixstride;
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  0, 0,
 +  PIPE_TRANSFER_WRITE,
 +  dx, 0, w, 1,
 +  dst_trans);
 +  dst_map = (uint8_t *)dst_map + dst-u.buf.first_element * pixstride;
 +   }
 +   else {
 +  /* XXX: should handle multiple layers */
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  dst-u.tex.level,
 +  dst-u.tex.first_layer,
 +  PIPE_TRANSFER_WRITE,
 +  dstx, dsty, width, height, dst_trans);
 +
 +   }

 assert(dst_map);

 if (dst_map) {
 +  enum pipe_format format = dst-format;
assert(dst_trans-stride  0);

 -  util_pack_color(color-f, dst-texture-format, uc);
 -  util_fill_rect(dst_map, dst-texture-format,
 +  if (util_format_is_pure_integer(format)) {
 + /*
 +  * We expect int/uint clear values here, though some APIs
 +  * might disagree (but in any case util_pack_color()
 +  * couldn't handle it)...
 +  */
 + if (util_format_is_pure_sint(format)) {
 +util_format_write_4i(format, color-i, 0, uc, 0, 0, 0, 1, 1);
 + }
 + else {
 +assert(util_format_is_pure_uint(format));
 +util_format_write_4ui(format, color-ui, 0, uc, 0, 0, 0, 1,
 1);
 + }
 +  }
 +  else {
 + util_pack_color(color-f, dst-format, uc);
 +  }
 +  util_fill_rect(dst_map, dst-format,
   dst_trans-stride,
   0, 0, width, height, uc);

 diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c
 b/src/gallium/drivers/llvmpipe/lp_rast.c
 index b5e5da6..6183f41 100644
 --- a/src/gallium/drivers/llvmpipe/lp_rast.c
 +++ b/src/gallium/drivers/llvmpipe/lp_rast.c
 @@ -165,32 +165,13 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,

   for (i = 0; i  scene-fb.nr_cbufs; i++) {
  enum pipe_format format = 

Re: [Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.

2013-02-27 Thread Roland Scheidegger
Am 27.02.2013 12:05, schrieb Christoph Bumiller:
 On 27.02.2013 10:44, Jose Fonseca wrote:
 - Original Message -
 What is this good for? Is it for UAVs? (unordered access views)
 No, it is just a standard D3D10 feature: 
 http://msdn.microsoft.com/en-gb/library/windows/desktop/bb204897.aspx

 Not sure if there's a particular use case for it (e.g, maybe DirectCompute 
 uses this extensively), or just a matter of symmetry in the API (ie., if one 
 can sample from buffer textures, then why not render into them?)
 I can think of rendering to vertex buffers. It's just annoying that
 there are no alignment restrictions on the range that is bound (worst
 case you have to render to a temporary buffer and copy stuff around);
 but at least it has to be = 8192 bytes (or elements, not sure) in D3D10.
It is 8192 elements (so same as 1d texture width really).
There is some minimal alignment restriction, the range needs to be
aligned to element width (this follows from specifying the start in
terms of elements directly). Well at least if I understand everything
correctly it doesn't work so well in testing yet :-).
I thought hw would be able to do this without hacks but can't tell for
sure. Note that d3d10 prevents you from having a depth buffer bound at
the same time if you use that feature so it's quite limited (though I
think this follows from the requirement that depth/stencil buffers need
same resource type as rendertargets, and you can't bind buffers as
depth/stencil).
All OpenGL extensions I've seen which allow you to write to some kind of
buffer require some special means to do that, and don't allow buffers to
be bound as ordinary render targets. Might be a mess to specify wrt
framebuffer (completeness requirements etc.) and due to
non-orthogonality (no depth buffer).

Roland



 
 For UAVs, I think there is ARB_shader_storage_buffer_object and
 pipe_context::set_shader_resources.
 Yeah, D3D11 UAVs are also supposed to be bound separately in the pipeline.

 Jose

 Marek

 On Wed, Feb 27, 2013 at 3:18 AM,  srol...@vmware.com wrote:
 From: Roland Scheidegger srol...@vmware.com

 Unfortunately not usable from OpenGL, and no cap bit.
 Pretty similar to a 1d texture, though allows specifying a start element.
 The util code for handling clears also needs adjustments (and fix
 a bug causing crashes for handling pure integer formats there too).
 ---
  src/gallium/auxiliary/util/u_surface.c  |   55
  +++
  src/gallium/drivers/llvmpipe/lp_rast.c  |   25 ++--
  src/gallium/drivers/llvmpipe/lp_rast_priv.h |4 +-
  src/gallium/drivers/llvmpipe/lp_scene.c |   35 +++--
  src/gallium/drivers/llvmpipe/lp_texture.c   |   44 +++--
  5 files changed, 108 insertions(+), 55 deletions(-)

 diff --git a/src/gallium/auxiliary/util/u_surface.c
 b/src/gallium/auxiliary/util/u_surface.c
 index b948b46..fba0798 100644
 --- a/src/gallium/auxiliary/util/u_surface.c
 +++ b/src/gallium/auxiliary/util/u_surface.c
 @@ -323,20 +323,59 @@ util_clear_render_target(struct pipe_context *pipe,
 if (!dst-texture)
return;
 /* XXX: should handle multiple layers */
 -   dst_map = pipe_transfer_map(pipe,
 -   dst-texture,
 -   dst-u.tex.level,
 -   dst-u.tex.first_layer,
 -   PIPE_TRANSFER_WRITE,
 -   dstx, dsty, width, height, dst_trans);
 +
 +   if (dst-texture-target == PIPE_BUFFER) {
 +  /*
 +   * The fill naturally works on the surface format, however
 +   * the transfer uses resource format which is just bytes for
 buffers.
 +   */
 +  unsigned dx, w;
 +  unsigned pixstride = util_format_get_blocksize(dst-format);
 +  dx = dstx * pixstride;
 +  w = width * pixstride;
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  0, 0,
 +  PIPE_TRANSFER_WRITE,
 +  dx, 0, w, 1,
 +  dst_trans);
 +  dst_map = (uint8_t *)dst_map + dst-u.buf.first_element * pixstride;
 +   }
 +   else {
 +  /* XXX: should handle multiple layers */
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  dst-u.tex.level,
 +  dst-u.tex.first_layer,
 +  PIPE_TRANSFER_WRITE,
 +  dstx, dsty, width, height, dst_trans);
 +
 +   }

 assert(dst_map);

 if (dst_map) {
 +  enum pipe_format format = dst-format;
assert(dst_trans-stride  0);

 -  util_pack_color(color-f, dst-texture-format, uc);
 -  util_fill_rect(dst_map, dst-texture-format,
 +  if (util_format_is_pure_integer(format)) {
 + /*
 +  * We expect int/uint clear values here, though 

Re: [Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.

2013-02-27 Thread Jose Fonseca
Looks good.

I think the u_surface change could go in separately though.

BTW, now that we can render/sampler from buffers, 
llvmpipe_is_resource_referenced needs to be updated: buffer may be referenced 
if they have BIND_SAMPLER/RENDERTARGET.

Weshould do something like if !BIND_SAMPLER/RENDERTARGET, return UNREFERENCED.

Jose

- Original Message -
 From: Roland Scheidegger srol...@vmware.com
 
 Unfortunately not usable from OpenGL, and no cap bit.
 Pretty similar to a 1d texture, though allows specifying a start element.
 The util code for handling clears also needs adjustments (and fix
 a bug causing crashes for handling pure integer formats there too).
 ---
  src/gallium/auxiliary/util/u_surface.c  |   55
  +++
  src/gallium/drivers/llvmpipe/lp_rast.c  |   25 ++--
  src/gallium/drivers/llvmpipe/lp_rast_priv.h |4 +-
  src/gallium/drivers/llvmpipe/lp_scene.c |   35 +++--
  src/gallium/drivers/llvmpipe/lp_texture.c   |   44 +++--
  5 files changed, 108 insertions(+), 55 deletions(-)
 
 diff --git a/src/gallium/auxiliary/util/u_surface.c
 b/src/gallium/auxiliary/util/u_surface.c
 index b948b46..fba0798 100644
 --- a/src/gallium/auxiliary/util/u_surface.c
 +++ b/src/gallium/auxiliary/util/u_surface.c
 @@ -323,20 +323,59 @@ util_clear_render_target(struct pipe_context *pipe,
 if (!dst-texture)
return;
 /* XXX: should handle multiple layers */
 -   dst_map = pipe_transfer_map(pipe,
 -   dst-texture,
 -   dst-u.tex.level,
 -   dst-u.tex.first_layer,
 -   PIPE_TRANSFER_WRITE,
 -   dstx, dsty, width, height, dst_trans);
 +
 +   if (dst-texture-target == PIPE_BUFFER) {
 +  /*
 +   * The fill naturally works on the surface format, however
 +   * the transfer uses resource format which is just bytes for buffers.
 +   */
 +  unsigned dx, w;
 +  unsigned pixstride = util_format_get_blocksize(dst-format);
 +  dx = dstx * pixstride;
 +  w = width * pixstride;
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  0, 0,
 +  PIPE_TRANSFER_WRITE,
 +  dx, 0, w, 1,
 +  dst_trans);
 +  dst_map = (uint8_t *)dst_map + dst-u.buf.first_element * pixstride;
 +   }
 +   else {
 +  /* XXX: should handle multiple layers */
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  dst-u.tex.level,
 +  dst-u.tex.first_layer,
 +  PIPE_TRANSFER_WRITE,
 +  dstx, dsty, width, height, dst_trans);
 +
 +   }
  
 assert(dst_map);
  
 if (dst_map) {
 +  enum pipe_format format = dst-format;
assert(dst_trans-stride  0);
  
 -  util_pack_color(color-f, dst-texture-format, uc);
 -  util_fill_rect(dst_map, dst-texture-format,
 +  if (util_format_is_pure_integer(format)) {
 + /*
 +  * We expect int/uint clear values here, though some APIs
 +  * might disagree (but in any case util_pack_color()
 +  * couldn't handle it)...
 +  */
 + if (util_format_is_pure_sint(format)) {
 +util_format_write_4i(format, color-i, 0, uc, 0, 0, 0, 1, 1);
 + }
 + else {
 +assert(util_format_is_pure_uint(format));
 +util_format_write_4ui(format, color-ui, 0, uc, 0, 0, 0, 1, 1);
 + }
 +  }
 +  else {
 + util_pack_color(color-f, dst-format, uc);
 +  }
 +  util_fill_rect(dst_map, dst-format,
   dst_trans-stride,
   0, 0, width, height, uc);
  
 diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c
 b/src/gallium/drivers/llvmpipe/lp_rast.c
 index b5e5da6..6183f41 100644
 --- a/src/gallium/drivers/llvmpipe/lp_rast.c
 +++ b/src/gallium/drivers/llvmpipe/lp_rast.c
 @@ -165,32 +165,13 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
  
   for (i = 0; i  scene-fb.nr_cbufs; i++) {
  enum pipe_format format = scene-fb.cbufs[i]-format;
 -/*
 - * XXX the format_write_4i/ui functions do clamping to max value
 - * and I'm not sure that's actually right - spec doesn't seem to
 - * say much about that topic. If it is should probably adjust
 the
 - * border color handling to do the same. If not and chopping off
 - * bits is the way to go, the write_4i and write_4ui functions
 - * would be identical.
 - */
 -if (util_format_is_pure_sint(format)) {
 -   int rgba[4];
 -   rgba[0] = arg.clear_color.i[0];
 -   rgba[1] = 

Re: [Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.

2013-02-27 Thread Roland Scheidegger
Am 27.02.2013 14:11, schrieb Jose Fonseca:
 Looks good.
 
 I think the u_surface change could go in separately though.
Ok.

 
 BTW, now that we can render/sampler from buffers, 
 llvmpipe_is_resource_referenced needs to be updated: buffer may be referenced 
 if they have BIND_SAMPLER/RENDERTARGET.
You are right. I actually looked at that llvmpipe_flush_resource
function and the rest seemed ok but didn't notice that
llvmpipe_is_resource_referenced wouldn't do anything for buffers.
I'll fix that.

 
 Weshould do something like if !BIND_SAMPLER/RENDERTARGET, return UNREFERENCED.
 
 Jose
 
 - Original Message -
 From: Roland Scheidegger srol...@vmware.com

 Unfortunately not usable from OpenGL, and no cap bit.
 Pretty similar to a 1d texture, though allows specifying a start element.
 The util code for handling clears also needs adjustments (and fix
 a bug causing crashes for handling pure integer formats there too).
 ---
  src/gallium/auxiliary/util/u_surface.c  |   55
  +++
  src/gallium/drivers/llvmpipe/lp_rast.c  |   25 ++--
  src/gallium/drivers/llvmpipe/lp_rast_priv.h |4 +-
  src/gallium/drivers/llvmpipe/lp_scene.c |   35 +++--
  src/gallium/drivers/llvmpipe/lp_texture.c   |   44 +++--
  5 files changed, 108 insertions(+), 55 deletions(-)

 diff --git a/src/gallium/auxiliary/util/u_surface.c
 b/src/gallium/auxiliary/util/u_surface.c
 index b948b46..fba0798 100644
 --- a/src/gallium/auxiliary/util/u_surface.c
 +++ b/src/gallium/auxiliary/util/u_surface.c
 @@ -323,20 +323,59 @@ util_clear_render_target(struct pipe_context *pipe,
 if (!dst-texture)
return;
 /* XXX: should handle multiple layers */
 -   dst_map = pipe_transfer_map(pipe,
 -   dst-texture,
 -   dst-u.tex.level,
 -   dst-u.tex.first_layer,
 -   PIPE_TRANSFER_WRITE,
 -   dstx, dsty, width, height, dst_trans);
 +
 +   if (dst-texture-target == PIPE_BUFFER) {
 +  /*
 +   * The fill naturally works on the surface format, however
 +   * the transfer uses resource format which is just bytes for buffers.
 +   */
 +  unsigned dx, w;
 +  unsigned pixstride = util_format_get_blocksize(dst-format);
 +  dx = dstx * pixstride;
 +  w = width * pixstride;
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  0, 0,
 +  PIPE_TRANSFER_WRITE,
 +  dx, 0, w, 1,
 +  dst_trans);
 +  dst_map = (uint8_t *)dst_map + dst-u.buf.first_element * pixstride;
 +   }
 +   else {
 +  /* XXX: should handle multiple layers */
 +  dst_map = pipe_transfer_map(pipe,
 +  dst-texture,
 +  dst-u.tex.level,
 +  dst-u.tex.first_layer,
 +  PIPE_TRANSFER_WRITE,
 +  dstx, dsty, width, height, dst_trans);
 +
 +   }
  
 assert(dst_map);
  
 if (dst_map) {
 +  enum pipe_format format = dst-format;
assert(dst_trans-stride  0);
  
 -  util_pack_color(color-f, dst-texture-format, uc);
 -  util_fill_rect(dst_map, dst-texture-format,
 +  if (util_format_is_pure_integer(format)) {
 + /*
 +  * We expect int/uint clear values here, though some APIs
 +  * might disagree (but in any case util_pack_color()
 +  * couldn't handle it)...
 +  */
 + if (util_format_is_pure_sint(format)) {
 +util_format_write_4i(format, color-i, 0, uc, 0, 0, 0, 1, 1);
 + }
 + else {
 +assert(util_format_is_pure_uint(format));
 +util_format_write_4ui(format, color-ui, 0, uc, 0, 0, 0, 1, 1);
 + }
 +  }
 +  else {
 + util_pack_color(color-f, dst-format, uc);
 +  }
 +  util_fill_rect(dst_map, dst-format,
   dst_trans-stride,
   0, 0, width, height, uc);
  
 diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c
 b/src/gallium/drivers/llvmpipe/lp_rast.c
 index b5e5da6..6183f41 100644
 --- a/src/gallium/drivers/llvmpipe/lp_rast.c
 +++ b/src/gallium/drivers/llvmpipe/lp_rast.c
 @@ -165,32 +165,13 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
  
   for (i = 0; i  scene-fb.nr_cbufs; i++) {
  enum pipe_format format = scene-fb.cbufs[i]-format;
 -/*
 - * XXX the format_write_4i/ui functions do clamping to max value
 - * and I'm not sure that's actually right - spec doesn't seem to
 - * say much about that topic. If it is should probably adjust
 the
 - * border color handling to do the same. If not and chopping off
 - * bits is the way to 

[Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.

2013-02-26 Thread sroland
From: Roland Scheidegger srol...@vmware.com

Unfortunately not usable from OpenGL, and no cap bit.
Pretty similar to a 1d texture, though allows specifying a start element.
The util code for handling clears also needs adjustments (and fix
a bug causing crashes for handling pure integer formats there too).
---
 src/gallium/auxiliary/util/u_surface.c  |   55 +++
 src/gallium/drivers/llvmpipe/lp_rast.c  |   25 ++--
 src/gallium/drivers/llvmpipe/lp_rast_priv.h |4 +-
 src/gallium/drivers/llvmpipe/lp_scene.c |   35 +++--
 src/gallium/drivers/llvmpipe/lp_texture.c   |   44 +++--
 5 files changed, 108 insertions(+), 55 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_surface.c 
b/src/gallium/auxiliary/util/u_surface.c
index b948b46..fba0798 100644
--- a/src/gallium/auxiliary/util/u_surface.c
+++ b/src/gallium/auxiliary/util/u_surface.c
@@ -323,20 +323,59 @@ util_clear_render_target(struct pipe_context *pipe,
if (!dst-texture)
   return;
/* XXX: should handle multiple layers */
-   dst_map = pipe_transfer_map(pipe,
-   dst-texture,
-   dst-u.tex.level,
-   dst-u.tex.first_layer,
-   PIPE_TRANSFER_WRITE,
-   dstx, dsty, width, height, dst_trans);
+
+   if (dst-texture-target == PIPE_BUFFER) {
+  /*
+   * The fill naturally works on the surface format, however
+   * the transfer uses resource format which is just bytes for buffers.
+   */
+  unsigned dx, w;
+  unsigned pixstride = util_format_get_blocksize(dst-format);
+  dx = dstx * pixstride;
+  w = width * pixstride;
+  dst_map = pipe_transfer_map(pipe,
+  dst-texture,
+  0, 0,
+  PIPE_TRANSFER_WRITE,
+  dx, 0, w, 1,
+  dst_trans);
+  dst_map = (uint8_t *)dst_map + dst-u.buf.first_element * pixstride;
+   }
+   else {
+  /* XXX: should handle multiple layers */
+  dst_map = pipe_transfer_map(pipe,
+  dst-texture,
+  dst-u.tex.level,
+  dst-u.tex.first_layer,
+  PIPE_TRANSFER_WRITE,
+  dstx, dsty, width, height, dst_trans);
+
+   }
 
assert(dst_map);
 
if (dst_map) {
+  enum pipe_format format = dst-format;
   assert(dst_trans-stride  0);
 
-  util_pack_color(color-f, dst-texture-format, uc);
-  util_fill_rect(dst_map, dst-texture-format,
+  if (util_format_is_pure_integer(format)) {
+ /*
+  * We expect int/uint clear values here, though some APIs
+  * might disagree (but in any case util_pack_color()
+  * couldn't handle it)...
+  */
+ if (util_format_is_pure_sint(format)) {
+util_format_write_4i(format, color-i, 0, uc, 0, 0, 0, 1, 1);
+ }
+ else {
+assert(util_format_is_pure_uint(format));
+util_format_write_4ui(format, color-ui, 0, uc, 0, 0, 0, 1, 1);
+ }
+  }
+  else {
+ util_pack_color(color-f, dst-format, uc);
+  }
+  util_fill_rect(dst_map, dst-format,
  dst_trans-stride,
  0, 0, width, height, uc);
 
diff --git a/src/gallium/drivers/llvmpipe/lp_rast.c 
b/src/gallium/drivers/llvmpipe/lp_rast.c
index b5e5da6..6183f41 100644
--- a/src/gallium/drivers/llvmpipe/lp_rast.c
+++ b/src/gallium/drivers/llvmpipe/lp_rast.c
@@ -165,32 +165,13 @@ lp_rast_clear_color(struct lp_rasterizer_task *task,
 
  for (i = 0; i  scene-fb.nr_cbufs; i++) {
 enum pipe_format format = scene-fb.cbufs[i]-format;
-/*
- * XXX the format_write_4i/ui functions do clamping to max value
- * and I'm not sure that's actually right - spec doesn't seem to
- * say much about that topic. If it is should probably adjust the
- * border color handling to do the same. If not and chopping off
- * bits is the way to go, the write_4i and write_4ui functions
- * would be identical.
- */
-if (util_format_is_pure_sint(format)) {
-   int rgba[4];
-   rgba[0] = arg.clear_color.i[0];
-   rgba[1] = arg.clear_color.i[1];
-   rgba[2] = arg.clear_color.i[2];
-   rgba[3] = arg.clear_color.i[3];
 
-   util_format_write_4i(format, rgba, 0, uc, 0, 0, 0, 1, 1);
+if (util_format_is_pure_sint(format)) {
+   util_format_write_4i(format, arg.clear_color.i, 0, uc, 0, 0, 
0, 1, 1);
 }
 else {
-   unsigned rgba[4];
-   rgba[0] = arg.clear_color.ui[0];
-   rgba[1]