From e705a2a9f48d3247557d468216c797dfb1758826 Mon Sep 17 00:00:00 2001 From: Elie Tournier Date: Fri, 20 Mar 2020 11:50:06 +0000 Subject: [PATCH] virgl: implement ARB_clear_texture Signed-off-by: Elie Tournier Reviewed-by: Gert Wollny Part-of: --- src/gallium/drivers/virgl/virgl_context.c | 19 +++++++++++++ src/gallium/drivers/virgl/virgl_encode.c | 32 ++++++++++++++++++++++ src/gallium/drivers/virgl/virgl_encode.h | 6 ++++ src/gallium/drivers/virgl/virgl_protocol.h | 16 +++++++++++ 4 files changed, 73 insertions(+) diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 381a9c023a8..150eed8b68c 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -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; diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c index c255a1c12e4..292cc2bb0d6 100644 --- a/src/gallium/drivers/virgl/virgl_encode.c +++ b/src/gallium/drivers/virgl/virgl_encode.c @@ -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 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 . 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) { diff --git a/src/gallium/drivers/virgl/virgl_encode.h b/src/gallium/drivers/virgl/virgl_encode.h index 3a12f9e935c..385b8ed262e 100644 --- a/src/gallium/drivers/virgl/virgl_encode.h +++ b/src/gallium/drivers/virgl/virgl_encode.h @@ -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, diff --git a/src/gallium/drivers/virgl/virgl_protocol.h b/src/gallium/drivers/virgl/virgl_protocol.h index d14caa292b3..0139abd825b 100644 --- a/src/gallium/drivers/virgl/virgl_protocol.h +++ b/src/gallium/drivers/virgl/virgl_protocol.h @@ -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