virgl: implement ARB_clear_texture

Signed-off-by: Elie Tournier <elie.tournier@collabora.com>
Reviewed-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4345>
This commit is contained in:
Elie Tournier 2020-03-20 11:50:06 +00:00 committed by Marge Bot
parent a6321c4b5a
commit e705a2a9f4
4 changed files with 73 additions and 0 deletions

View File

@ -829,6 +829,24 @@ static void virgl_clear(struct pipe_context *ctx,
virgl_encode_clear(vctx, buffers, color, depth, stencil);
}
static void virgl_clear_texture(struct pipe_context *ctx,
struct pipe_resource *res,
unsigned int level,
const struct pipe_box *box,
const void *data)
{
struct virgl_context *vctx = virgl_context(ctx);
struct virgl_resource *vres = virgl_resource(res);
virgl_encode_clear_texture(vctx, vres, level, box, data);
/* Mark as dirty, since we are updating the host side resource
* without going through the corresponding guest side resource, and
* hence the two will diverge.
*/
virgl_resource_dirty(vres, level);
}
static void virgl_draw_vbo(struct pipe_context *ctx,
const struct pipe_draw_info *dinfo)
{
@ -1498,6 +1516,7 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
vctx->base.launch_grid = virgl_launch_grid;
vctx->base.clear = virgl_clear;
vctx->base.clear_texture = virgl_clear_texture;
vctx->base.draw_vbo = virgl_draw_vbo;
vctx->base.flush = virgl_flush_from_st;
vctx->base.screen = pscreen;

View File

@ -579,6 +579,38 @@ int virgl_encode_clear(struct virgl_context *ctx,
return 0;
}
int virgl_encode_clear_texture(struct virgl_context *ctx,
struct virgl_resource *res,
unsigned int level,
const struct pipe_box *box,
const void *data)
{
const struct util_format_description *desc = util_format_description(res->u.b.format);
unsigned block_bits = desc->block.bits;
uint32_t arr[4] = {0};
/* The spec describe <data> as a pointer to an array of between one
* and four components of texel data that will be used as the source
* for the constant fill value.
* Here, we are just copying the memory into <arr>. We do not try to
* re-create the data array. The host part will take care of interpreting
* the memory and applying the correct format to the clear call.
*/
memcpy(&arr, data, block_bits / 8);
virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CLEAR_TEXTURE, 0, VIRGL_CLEAR_TEXTURE_SIZE));
virgl_encoder_write_res(ctx, res);
virgl_encoder_write_dword(ctx->cbuf, level);
virgl_encoder_write_dword(ctx->cbuf, box->x);
virgl_encoder_write_dword(ctx->cbuf, box->y);
virgl_encoder_write_dword(ctx->cbuf, box->z);
virgl_encoder_write_dword(ctx->cbuf, box->width);
virgl_encoder_write_dword(ctx->cbuf, box->height);
virgl_encoder_write_dword(ctx->cbuf, box->depth);
for (unsigned i = 0; i < 4; i++)
virgl_encoder_write_dword(ctx->cbuf, arr[i]);
return 0;
}
int virgl_encoder_set_framebuffer_state(struct virgl_context *ctx,
const struct pipe_framebuffer_state *state)
{

View File

@ -116,6 +116,12 @@ int virgl_encode_clear(struct virgl_context *ctx,
const union pipe_color_union *color,
double depth, unsigned stencil);
int virgl_encode_clear_texture(struct virgl_context *ctx,
struct virgl_resource *res,
unsigned int level,
const struct pipe_box *box,
const void *data);
int virgl_encode_bind_object(struct virgl_context *ctx,
uint32_t handle, uint32_t object);
int virgl_encode_delete_object(struct virgl_context *ctx,

View File

@ -98,6 +98,7 @@ enum virgl_context_cmd {
VIRGL_CCMD_END_TRANSFERS,
VIRGL_CCMD_COPY_TRANSFER3D,
VIRGL_CCMD_SET_TWEAKS,
VIRGL_CCMD_CLEAR_TEXTURE,
};
/*
@ -598,4 +599,19 @@ enum vrend_tweak_type {
virgl_tweak_undefined
};
/* Clear texture */
#define VIRGL_CLEAR_TEXTURE_SIZE 12
#define VIRGL_TEXTURE_HANDLE 1
#define VIRGL_TEXTURE_LEVEL 2
#define VIRGL_TEXTURE_SRC_X 3
#define VIRGL_TEXTURE_SRC_Y 4
#define VIRGL_TEXTURE_SRC_Z 5
#define VIRGL_TEXTURE_SRC_W 6
#define VIRGL_TEXTURE_SRC_H 7
#define VIRGL_TEXTURE_SRC_D 8
#define VIRGL_TEXTURE_ARRAY_A 9
#define VIRGL_TEXTURE_ARRAY_B 10
#define VIRGL_TEXTURE_ARRAY_C 11
#define VIRGL_TEXTURE_ARRAY_D 12
#endif