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