virgl: implement ARB_clear_texture
authorElie Tournier <tournier.elie@gmail.com>
Fri, 20 Mar 2020 11:50:06 +0000 (11:50 +0000)
committerMarge Bot <eric+marge@anholt.net>
Thu, 7 May 2020 10:21:50 +0000 (10:21 +0000)
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>

src/gallium/drivers/virgl/virgl_context.c
src/gallium/drivers/virgl/virgl_encode.c
src/gallium/drivers/virgl/virgl_encode.h
src/gallium/drivers/virgl/virgl_protocol.h

index 381a9c023a824609b8cbee66e0e72598dbebd397..150eed8b68ca711309a0f9ea0f4d0c60ec1a2229 100644 (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;
index c255a1c12e46ac731d75c1566fa5fe7bed83e8be..292cc2bb0d6e8b4fdfbc11eb8f3e34c0b69a6b96 100644 (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)
 {
index 3a12f9e935c73645d2d1a8f33a669657bcebc910..385b8ed262e1b15d7f752a97f0eb11d80387da35 100644 (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,
index d14caa292b31d3b5f13b624ae44db64ef9e74f6f..0139abd825ba0141ac7a8adb91b8f79c1fcef92e 100644 (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