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>
This commit is contained in:
Max R 2023-10-30 18:27:35 +03:00 committed by Marge Bot
parent 796cba9bda
commit 75f7910850
4 changed files with 107 additions and 2 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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