llvmpipe: support rendering to buffer render targets.
Unfortunately not usable from OpenGL, and no cap bit. Pretty similar to a 1d texture, though allows specifying a start element. v2: also fix up renderbuffer width (which will get promoted to fb width) to be the number of elements Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
2fcd3638be
commit
686f6c69bd
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
/* setting width as number of elements should get us correct renderbuffer width */
|
||||
ps->width = surf_tmpl->u.buf.last_element - surf_tmpl->u.buf.first_element + 1;
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue