+
+int virgl_encode_host_debug_flagstring(struct virgl_context *ctx,
+ const char *flagstring)
+{
+ unsigned long slen = strlen(flagstring) + 1;
+ uint32_t sslen;
+ uint32_t string_length;
+
+ if (!slen)
+ return 0;
+
+ if (slen > 4 * 0xffff) {
+ debug_printf("VIRGL: host debug flag string too long, will be truncated\n");
+ slen = 4 * 0xffff;
+ }
+
+ sslen = (uint32_t )(slen + 3) / 4;
+ string_length = (uint32_t)MIN2(sslen * 4, slen);
+
+ virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_DEBUG_FLAGS, 0, sslen));
+ virgl_encoder_write_block(ctx->cbuf, (const uint8_t *)flagstring, string_length);
+ return 0;
+}
+
+int virgl_encode_tweak(struct virgl_context *ctx, enum vrend_tweak_type tweak, uint32_t value)
+{
+ virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_SET_TWEAKS, 0, VIRGL_SET_TWEAKS_SIZE));
+ virgl_encoder_write_dword(ctx->cbuf, tweak);
+ virgl_encoder_write_dword(ctx->cbuf, value);
+ return 0;
+}
+
+
+int virgl_encode_get_query_result_qbo(struct virgl_context *ctx,
+ uint32_t handle,
+ struct virgl_resource *res, boolean wait,
+ uint32_t result_type,
+ uint32_t offset,
+ uint32_t index)
+{
+ virgl_encoder_write_cmd_dword(ctx, VIRGL_CMD0(VIRGL_CCMD_GET_QUERY_RESULT_QBO, 0, VIRGL_QUERY_RESULT_QBO_SIZE));
+ virgl_encoder_write_dword(ctx->cbuf, handle);
+ virgl_encoder_write_res(ctx, res);
+ virgl_encoder_write_dword(ctx->cbuf, wait ? 1 : 0);
+ virgl_encoder_write_dword(ctx->cbuf, result_type);
+ virgl_encoder_write_dword(ctx->cbuf, offset);
+ virgl_encoder_write_dword(ctx->cbuf, index);
+ return 0;
+}
+
+void virgl_encode_transfer(struct virgl_screen *vs, struct virgl_cmd_buf *buf,
+ struct virgl_transfer *trans, uint32_t direction)
+{
+ uint32_t command;
+ command = VIRGL_CMD0(VIRGL_CCMD_TRANSFER3D, 0, VIRGL_TRANSFER3D_SIZE);
+ virgl_encoder_write_dword(buf, command);
+ virgl_encoder_transfer3d_common(vs, buf, trans,
+ virgl_transfer3d_host_inferred_stride);
+ virgl_encoder_write_dword(buf, trans->offset);
+ virgl_encoder_write_dword(buf, direction);
+}
+
+void virgl_encode_copy_transfer(struct virgl_context *ctx,
+ struct virgl_transfer *trans)
+{
+ uint32_t command;
+ struct virgl_resource *copy_src_res = virgl_resource(trans->copy_src_res);
+ struct virgl_screen *vs = virgl_screen(ctx->base.screen);
+
+ command = VIRGL_CMD0(VIRGL_CCMD_COPY_TRANSFER3D, 0, VIRGL_COPY_TRANSFER3D_SIZE);
+ virgl_encoder_write_cmd_dword(ctx, command);
+ /* Copy transfers need to explicitly specify the stride, since it may differ
+ * from the image stride.
+ */
+ virgl_encoder_transfer3d_common(vs, ctx->cbuf, trans, virgl_transfer3d_explicit_stride);
+ virgl_encoder_emit_resource(vs, ctx->cbuf, copy_src_res);
+ virgl_encoder_write_dword(ctx->cbuf, trans->copy_src_offset);
+ /* At the moment all copy transfers are synchronized. */
+ virgl_encoder_write_dword(ctx->cbuf, 1);
+}
+
+void virgl_encode_end_transfers(struct virgl_cmd_buf *buf)
+{
+ uint32_t command, diff;
+ diff = VIRGL_MAX_TBUF_DWORDS - buf->cdw;
+ if (diff) {
+ command = VIRGL_CMD0(VIRGL_CCMD_END_TRANSFERS, 0, diff - 1);
+ virgl_encoder_write_dword(buf, command);
+ }
+}