This allows a minor optimization for texture upload.
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
trans = virgl_resource_create_transfer(ctx, resource, &vbuf->metadata, level,
usage, box);
- readback = virgl_res_needs_readback(vctx, vbuf, usage);
+ readback = virgl_res_needs_readback(vctx, vbuf, usage, 0);
if (readback)
vs->vws->transfer_get(vs->vws, vbuf->hw_res, box, trans->base.stride,
trans->l_stride, trans->offset, level);
surf = vctx->framebuffer.zsbuf;
if (surf) {
res = virgl_resource(surf->texture);
- if (res)
+ if (res) {
vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
+ virgl_resource_dirty(res, surf->u.tex.level);
+ }
}
for (i = 0; i < vctx->framebuffer.nr_cbufs; i++) {
surf = vctx->framebuffer.cbufs[i];
if (surf) {
res = virgl_resource(surf->texture);
- if (res)
+ if (res) {
vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
+ virgl_resource_dirty(res, surf->u.tex.level);
+ }
}
}
}
struct virgl_resource *dres = virgl_resource(dst);
struct virgl_resource *sres = virgl_resource(src);
- virgl_resource_dirty(dres, 0);
+ virgl_resource_dirty(dres, dst_level);
virgl_encode_resource_copy_region(vctx, dres,
dst_level, dstx, dsty, dstz,
sres, src_level,
(util_format_is_srgb(blit->dst.resource->format) ==
util_format_is_srgb(blit->dst.format)));
- virgl_resource_dirty(dres, 0);
+ virgl_resource_dirty(dres, blit->dst.level);
virgl_encode_blit(vctx, dres, sres,
blit);
}
if (res->u.b.target == PIPE_BUFFER) {
virgl_encoder_write_dword(ctx->cbuf, state->u.buf.offset / elem_size);
virgl_encoder_write_dword(ctx->cbuf, (state->u.buf.offset + state->u.buf.size) / elem_size - 1);
- virgl_resource_dirty(res, 0);
} else {
virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_layer | state->u.tex.last_layer << 16);
virgl_encoder_write_dword(ctx->cbuf, state->u.tex.first_level | state->u.tex.last_level << 8);
virgl_encoder_write_dword(ctx->cbuf, images[i].u.buf.offset);
virgl_encoder_write_dword(ctx->cbuf, images[i].u.buf.size);
virgl_encoder_write_res(ctx, res);
- virgl_resource_dirty(res, 0);
+ virgl_resource_dirty(res, images[i].u.tex.level);
} else {
virgl_encoder_write_dword(ctx->cbuf, 0);
virgl_encoder_write_dword(ctx->cbuf, 0);
bool virgl_res_needs_readback(struct virgl_context *vctx,
struct virgl_resource *res,
- unsigned usage)
+ unsigned usage, unsigned level)
{
bool readback = true;
- if (res->clean[0])
+ if (res->clean[level])
readback = false;
else if (usage & PIPE_TRANSFER_DISCARD_RANGE)
readback = false;
void virgl_resource_dirty(struct virgl_resource *res, uint32_t level)
{
- if (res)
- res->clean[0] = FALSE;
+ if (res) {
+ if (res->u.b.target == PIPE_BUFFER)
+ res->clean[0] = FALSE;
+ else
+ res->clean[level] = FALSE;
+ }
}
unsigned usage);
bool virgl_res_needs_readback(struct virgl_context *vctx,
struct virgl_resource *res,
- unsigned usage);
+ unsigned usage, unsigned level);
void virgl_resource_layout(struct pipe_resource *pt,
struct virgl_resource_metadata *metadata);
trans->resolve_tmp = NULL;
}
- readback = virgl_res_needs_readback(vctx, vtex, usage);
+ readback = virgl_res_needs_readback(vctx, vtex, usage, level);
if (readback)
vs->vws->transfer_get(vs->vws, hw_res, box, trans->base.stride,
trans->l_stride, trans->offset, level);
if (trans->base.usage & PIPE_TRANSFER_WRITE) {
if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
struct virgl_screen *vs = virgl_screen(ctx->screen);
- vtex->clean[0] = FALSE;
vctx->num_transfers++;
vs->vws->transfer_put(vs->vws, vtex->hw_res,
&transfer->box, trans->base.stride,