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