Re: [Mesa-dev] [PATCH] llvmpipe: support rendering to buffer render targets.
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.
- 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.
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.
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.
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.
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.
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]