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 = 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] = arg.clear_color.ui[1]; >>> - rgba[2] = arg.clear_color.ui[2]; >>> - rgba[3] = arg.clear_color.ui[3]; >>> - >>> assert(util_format_is_pure_uint(format)); >>> - util_format_write_4ui(format, rgba, 0, &uc, 0, 0, 0, 1, 1); >>> + util_format_write_4ui(format, arg.clear_color.ui, 0, &uc, >>> 0, 0, 0, 1, 1); >>> } >>> >>> util_fill_rect(scene->cbufs[i].map, >>> diff --git a/src/gallium/drivers/llvmpipe/lp_rast_priv.h >>> b/src/gallium/drivers/llvmpipe/lp_rast_priv.h >>> index 5db8fcd..c0f41f6 100644 >>> --- a/src/gallium/drivers/llvmpipe/lp_rast_priv.h >>> +++ b/src/gallium/drivers/llvmpipe/lp_rast_priv.h >>> @@ -196,7 +196,7 @@ lp_rast_get_unswizzled_color_tile_pointer(struct >>> lp_rasterizer_task *task, >>> struct pipe_surface *cbuf = scene->fb.cbufs[buf]; >>> assert(cbuf); >>> >>> - format_bytes = util_format_description(cbuf->format)->block.bits / >>> 8; >>> + format_bytes = util_format_get_blocksize(cbuf->format); >>> task->color_tiles[buf] = scene->cbufs[buf].map + >>> scene->cbufs[buf].stride * task->y + format_bytes * task->x; >>> } >>> >>> @@ -221,7 +221,7 @@ lp_rast_get_unswizzled_color_block_pointer(struct >>> lp_rasterizer_task *task, >>> assert((y % TILE_VECTOR_HEIGHT) == 0); >>> assert(buf < task->scene->fb.nr_cbufs); >>> >>> - format_bytes = >>> util_format_description(task->scene->fb.cbufs[buf]->format)->block.bits / >>> 8; >>> + format_bytes = >>> util_format_get_blocksize(task->scene->fb.cbufs[buf]->format); >>> >>> color = lp_rast_get_unswizzled_color_tile_pointer(task, buf, >>> LP_TEX_USAGE_READ_WRITE); >>> assert(color); >>> diff --git a/src/gallium/drivers/llvmpipe/lp_scene.c >>> b/src/gallium/drivers/llvmpipe/lp_scene.c >>> index 328c0f7..fec2f74 100644 >>> --- a/src/gallium/drivers/llvmpipe/lp_scene.c >>> +++ b/src/gallium/drivers/llvmpipe/lp_scene.c >>> @@ -141,15 +141,24 @@ lp_scene_begin_rasterization(struct lp_scene *scene) >>> >>> for (i = 0; i < scene->fb.nr_cbufs; i++) { >>> struct pipe_surface *cbuf = scene->fb.cbufs[i]; >>> - assert(cbuf->u.tex.first_layer == cbuf->u.tex.last_layer); >>> - scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture, >>> - >>> cbuf->u.tex.level); >>> - >>> - scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture, >>> - cbuf->u.tex.level, >>> - cbuf->u.tex.first_layer, >>> - LP_TEX_USAGE_READ_WRITE, >>> - LP_TEX_LAYOUT_LINEAR); >>> + if (llvmpipe_resource_is_texture(cbuf->texture)) { >>> + assert(cbuf->u.tex.first_layer == cbuf->u.tex.last_layer); >>> + scene->cbufs[i].stride = llvmpipe_resource_stride(cbuf->texture, >>> + >>> cbuf->u.tex.level); >>> + >>> + scene->cbufs[i].map = llvmpipe_resource_map(cbuf->texture, >>> + cbuf->u.tex.level, >>> + >>> cbuf->u.tex.first_layer, >>> + >>> LP_TEX_USAGE_READ_WRITE, >>> + >>> LP_TEX_LAYOUT_LINEAR); >>> + } >>> + else { >>> + struct llvmpipe_resource *lpr = llvmpipe_resource(cbuf->texture); >>> + unsigned pixstride = util_format_get_blocksize(cbuf->format); >>> + scene->cbufs[i].stride = cbuf->texture->width0; >>> + scene->cbufs[i].map = lpr->data; >>> + scene->cbufs[i].map += cbuf->u.buf.first_element * pixstride; >>> + } >>> } >>> >>> if (fb->zsbuf) { >>> @@ -182,9 +191,11 @@ lp_scene_end_rasterization(struct lp_scene *scene ) >>> for (i = 0; i < scene->fb.nr_cbufs; i++) { >>> if (scene->cbufs[i].map) { >>> struct pipe_surface *cbuf = scene->fb.cbufs[i]; >>> - llvmpipe_resource_unmap(cbuf->texture, >>> - cbuf->u.tex.level, >>> - cbuf->u.tex.first_layer); >>> + if (llvmpipe_resource_is_texture(cbuf->texture)) { >>> + llvmpipe_resource_unmap(cbuf->texture, >>> + cbuf->u.tex.level, >>> + cbuf->u.tex.first_layer); >>> + } >>> scene->cbufs[i].map = NULL; >>> } >>> } >>> diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c >>> b/src/gallium/drivers/llvmpipe/lp_texture.c >>> index f923292..7387166 100644 >>> --- a/src/gallium/drivers/llvmpipe/lp_texture.c >>> +++ b/src/gallium/drivers/llvmpipe/lp_texture.c >>> @@ -297,6 +297,12 @@ llvmpipe_resource_create(struct pipe_screen *_screen, >>> assert(templat->depth0 == 1); >>> assert(templat->last_level == 0); >>> lpr->data = align_malloc(bytes, 16); >>> + /* >>> + * buffers don't really have stride but it's probably safer >>> + * (for code doing same calculations for buffers and textures) >>> + * to put something sane in there. >>> + */ >>> + lpr->row_stride[0] = bytes; >>> if (!lpr->data) >>> goto fail; >>> memset(lpr->data, 0, bytes); >>> @@ -578,12 +584,23 @@ llvmpipe_create_surface(struct pipe_context *pipe, >>> pipe_resource_reference(&ps->texture, pt); >>> ps->context = pipe; >>> ps->format = surf_tmpl->format; >>> - ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); >>> - ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); >>> - >>> - ps->u.tex.level = surf_tmpl->u.tex.level; >>> - ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; >>> - ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; >>> + if (llvmpipe_resource_is_texture(pt)) { >>> + assert(surf_tmpl->u.tex.level <= pt->last_level); >>> + ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level); >>> + ps->height = u_minify(pt->height0, surf_tmpl->u.tex.level); >>> + ps->u.tex.level = surf_tmpl->u.tex.level; >>> + ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer; >>> + ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer; >>> + } >>> + else { >>> + const enum pipe_format format = surf_tmpl->format; >>> + ps->width = pt->width0 / util_format_get_blocksize(format); >>> + ps->height = pt->height0; >>> + ps->u.buf.first_element = surf_tmpl->u.buf.first_element; >>> + ps->u.buf.last_element = surf_tmpl->u.buf.last_element; >>> + assert(ps->u.buf.first_element <= ps->u.buf.last_element); >>> + assert(ps->u.buf.last_element < ps->width); >>> + } >>> } >>> return ps; >>> } >>> @@ -1342,12 +1359,17 @@ llvmpipe_resource_size(const struct pipe_resource >>> *resource) >>> const struct llvmpipe_resource *lpr = >>> llvmpipe_resource_const(resource); >>> unsigned lvl, size = 0; >>> >>> - for (lvl = 0; lvl <= lpr->base.last_level; lvl++) { >>> - if (lpr->linear_img.data) >>> - size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR); >>> + if (llvmpipe_resource_is_texture(resource)) { >>> + for (lvl = 0; lvl <= lpr->base.last_level; lvl++) { >>> + if (lpr->linear_img.data) >>> + size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_LINEAR); >>> >>> - if (lpr->tiled_img.data) >>> - size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED); >>> + if (lpr->tiled_img.data) >>> + size += tex_image_size(lpr, lvl, LP_TEX_LAYOUT_TILED); >>> + } >>> + } >>> + else { >>> + size = resource->width0; >>> } >>> >>> return size; >>> -- >>> 1.7.9.5 >>> >>> _______________________________________________ >>> mesa-dev mailing list >>> mesa-dev@lists.freedesktop.org >>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev