Module: Mesa
Branch: main
Commit: 75f7910850df52d2c47b9f49d8df34cda3c28d1b
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=75f7910850df52d2c47b9f49d8df34cda3c28d1b

Author: Max R <max8...@gmail.com>
Date:   Mon Oct 30 18:27:35 2023 +0300

virgl: Implement clear_render_target and clear_depth_stencil

This functions are required by d3d10umd frontend.
To implement both clear_render_target and clear_depth_stencil
common virgl command VIRGL_CCMD_CLEAR_SURFACE is introduced.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25947>

---

 src/gallium/drivers/virgl/virgl_context.c | 55 +++++++++++++++++++++++++++++--
 src/gallium/drivers/virgl/virgl_encode.c  | 29 ++++++++++++++++
 src/gallium/drivers/virgl/virgl_encode.h  |  8 +++++
 src/virtio/virtio-gpu/virgl_protocol.h    | 17 ++++++++++
 4 files changed, 107 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/virgl/virgl_context.c 
b/src/gallium/drivers/virgl/virgl_context.c
index 6a4473d2eb7..2c2a741ada4 100644
--- a/src/gallium/drivers/virgl/virgl_context.c
+++ b/src/gallium/drivers/virgl/virgl_context.c
@@ -916,9 +916,54 @@ static void virgl_clear_render_target(struct pipe_context 
*ctx,
                                       unsigned dstx, unsigned dsty,
                                       unsigned width, unsigned height,
                                       bool render_condition_enabled)
+{
+   struct virgl_context *vctx = virgl_context(ctx);
+
+   virgl_encode_clear_surface(vctx, dst, PIPE_CLEAR_COLOR0, color,
+                             dstx, dsty, width, height, 
render_condition_enabled);
+
+   /* 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(virgl_resource(dst->texture), dst->u.tex.level);
+}
+
+static void virgl_clear_depth_stencil(struct pipe_context *ctx,
+                                      struct pipe_surface *dst,
+                                      unsigned clear_flags,
+                                      double depth,
+                                      unsigned stencil,
+                                      unsigned dstx, unsigned dsty,
+                                      unsigned width, unsigned height,
+                                      bool render_condition_enabled)
+{
+   struct virgl_context *vctx = virgl_context(ctx);
+
+   union pipe_color_union color;
+   memcpy(color.ui, &depth, sizeof(double));
+   color.ui[3] = stencil;
+
+   virgl_encode_clear_surface(vctx, dst, clear_flags, &color,
+                             dstx, dsty, width, height, 
render_condition_enabled);
+
+   /* 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(virgl_resource(dst->texture), dst->u.tex.level);
+}
+
+static void virgl_clear_render_target_stub(struct pipe_context *ctx,
+                                           struct pipe_surface *dst,
+                                           const union pipe_color_union *color,
+                                           unsigned dstx, unsigned dsty,
+                                           unsigned width, unsigned height,
+                                           bool render_condition_enabled)
 {
    if (virgl_debug & VIRGL_DEBUG_VERBOSE)
-      debug_printf("VIRGL: clear render target unsupported.\n");
+         debug_printf("VIRGL: clear depth stencil unsupported.\n");
+   return;
 }
 
 static void virgl_clear_texture(struct pipe_context *ctx,
@@ -1699,7 +1744,13 @@ 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_render_target = virgl_clear_render_target;
+   if (rs->caps.caps.v2.host_feature_check_version >= 21) {
+      vctx->base.clear_render_target = virgl_clear_render_target;
+      vctx->base.clear_depth_stencil = virgl_clear_depth_stencil;
+   } else {
+      // Stub is required by VL backend
+      vctx->base.clear_render_target = virgl_clear_render_target_stub;
+   }
    vctx->base.clear_texture = virgl_clear_texture;
    vctx->base.draw_vbo = virgl_draw_vbo;
    vctx->base.flush = virgl_flush_from_st;
diff --git a/src/gallium/drivers/virgl/virgl_encode.c 
b/src/gallium/drivers/virgl/virgl_encode.c
index a5b2a069446..c73d190d374 100644
--- a/src/gallium/drivers/virgl/virgl_encode.c
+++ b/src/gallium/drivers/virgl/virgl_encode.c
@@ -1825,3 +1825,32 @@ void virgl_encode_end_frame(struct virgl_context *ctx,
    virgl_encoder_write_dword(ctx->cbuf, cdc->handle);
    virgl_encoder_write_dword(ctx->cbuf, buf->handle);
 }
+
+int virgl_encode_clear_surface(struct virgl_context *ctx,
+                               struct pipe_surface *surf,
+                               unsigned buffers,
+                               const union pipe_color_union *color,
+                               unsigned dstx, unsigned dsty,
+                               unsigned width, unsigned height,
+                               bool render_condition_enabled)
+{
+   int i;
+   uint32_t tmp;
+   virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_CLEAR_SURFACE, 0, 
VIRGL_CLEAR_SURFACE_SIZE));
+   
+   tmp = VIRGL_CLEAR_SURFACE_S0_RENDER_CONDITION(render_condition_enabled) |
+         VIRGL_CLEAR_SURFACE_S0_BUFFERS(buffers);
+
+   virgl_encoder_write_dword(ctx->cbuf, tmp);
+   virgl_encoder_write_dword(ctx->cbuf, virgl_surface(surf)->handle);
+
+   for (i = 0; i < 4; i++)
+      virgl_encoder_write_dword(ctx->cbuf, color->ui[i]);
+
+   virgl_encoder_write_dword(ctx->cbuf, dstx);
+   virgl_encoder_write_dword(ctx->cbuf, dsty);
+   virgl_encoder_write_dword(ctx->cbuf, width);
+   virgl_encoder_write_dword(ctx->cbuf, height);
+
+   return 0;
+}
\ No newline at end of file
diff --git a/src/gallium/drivers/virgl/virgl_encode.h 
b/src/gallium/drivers/virgl/virgl_encode.h
index a27951a3b4b..1563c9fc76a 100644
--- a/src/gallium/drivers/virgl/virgl_encode.h
+++ b/src/gallium/drivers/virgl/virgl_encode.h
@@ -343,6 +343,14 @@ void virgl_encode_end_frame(struct virgl_context *ctx,
                             struct virgl_video_codec *cdc,
                             struct virgl_video_buffer *buf);
 
+int virgl_encode_clear_surface(struct virgl_context *ctx,
+                               struct pipe_surface *surf,
+                               unsigned buffers,
+                               const union pipe_color_union *color,
+                               unsigned dstx, unsigned dsty,
+                               unsigned width, unsigned height,
+                               bool render_condition_enabled);
+
 enum virgl_formats pipe_to_virgl_format(enum pipe_format format);
 enum pipe_format virgl_to_pipe_format(enum virgl_formats format);
 #endif
diff --git a/src/virtio/virtio-gpu/virgl_protocol.h 
b/src/virtio/virtio-gpu/virgl_protocol.h
index 05010777f19..34372b6b077 100644
--- a/src/virtio/virtio-gpu/virgl_protocol.h
+++ b/src/virtio/virtio-gpu/virgl_protocol.h
@@ -129,6 +129,8 @@ enum virgl_context_cmd {
    VIRGL_CCMD_ENCODE_BITSTREAM,
    VIRGL_CCMD_END_FRAME,
 
+   VIRGL_CCMD_CLEAR_SURFACE,
+
    VIRGL_MAX_COMMANDS
 };
 
@@ -763,4 +765,19 @@ enum vrend_tweak_type {
 #define VIRGL_END_FRAME_CDC_HANDLE          1
 #define VIRGL_END_FRAME_TGT_HANDLE          2
 
+/* VIRGL_CCMD_CLEAR_SURFACE */
+#define VIRGL_CLEAR_SURFACE_SIZE                   10
+#define VIRGL_CLEAR_SURFACE_S0                     1
+#define VIRGL_CLEAR_SURFACE_S0_RENDER_CONDITION(x) (((x)&0x1) << 0)
+#define VIRGL_CLEAR_SURFACE_S0_BUFFERS(x)          (((x)&0x7) << 1)
+#define VIRGL_CLEAR_SURFACE_HANDLE                 2
+#define VIRGL_CLEAR_SURFACE_COLOR_0                3 /* color is 4 * 
u32/f32/i32 or (depth/f64+stencil/u32) */
+#define VIRGL_CLEAR_SURFACE_COLOR_1                4
+#define VIRGL_CLEAR_SURFACE_COLOR_2                5
+#define VIRGL_CLEAR_SURFACE_COLOR_3                6
+#define VIRGL_CLEAR_SURFACE_DST_X                  7
+#define VIRGL_CLEAR_SURFACE_DST_Y                  8
+#define VIRGL_CLEAR_SURFACE_WIDTH                  9
+#define VIRGL_CLEAR_SURFACE_HEIGHT                 10
+
 #endif

Reply via email to