----- 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 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