virgl: fixup_readback_format --> fixup_formats
[mesa.git] / src / gallium / drivers / virgl / virgl_context.c
index 2324878672e194a35f9bcdc06ceac24903b320b9..bbb5247c86f1b4585a02b8e3dcc1248785052af4 100644 (file)
@@ -47,6 +47,7 @@
 #include "virgl_protocol.h"
 #include "virgl_resource.h"
 #include "virgl_screen.h"
+#include "virgl_staging_mgr.h"
 
 struct virgl_vertex_elements_state {
    uint32_t handle;
@@ -87,7 +88,7 @@ virgl_rebind_resource(struct virgl_context *vctx,
    /* Queries use internally created buffers and do not go through transfers.
     * Index buffers are not bindable.  They are not tracked.
     */
-   MAYBE_UNUSED const unsigned tracked_bind = (PIPE_BIND_VERTEX_BUFFER |
+   ASSERTED const unsigned tracked_bind = (PIPE_BIND_VERTEX_BUFFER |
                                                PIPE_BIND_CONSTANT_BUFFER |
                                                PIPE_BIND_SHADER_BUFFER |
                                                PIPE_BIND_SHADER_IMAGE);
@@ -463,6 +464,9 @@ static void *virgl_create_rasterizer_state(struct pipe_context *ctx,
    vrs->rs = *rs_state;
    vrs->handle = virgl_object_assign_handle();
 
+   assert(rs_state->depth_clip_near ||
+          virgl_screen(ctx->screen)->caps.caps.v1.bset.depth_clip_disable);
+
    virgl_encode_rasterizer_state(vctx, vrs->handle, rs_state);
    return (void *)vrs;
 }
@@ -869,6 +873,22 @@ static void virgl_draw_vbo(struct pipe_context *ctx,
 
 }
 
+static void virgl_submit_cmd(struct virgl_winsys *vws,
+                             struct virgl_cmd_buf *cbuf,
+                            struct pipe_fence_handle **fence)
+{
+   if (unlikely(virgl_debug & VIRGL_DEBUG_SYNC)) {
+      struct pipe_fence_handle *sync_fence = NULL;
+
+      vws->submit_cmd(vws, cbuf, &sync_fence);
+
+      vws->fence_wait(vws, sync_fence, PIPE_TIMEOUT_INFINITE);
+      vws->fence_reference(vws, &sync_fence, NULL);
+   } else {
+      vws->submit_cmd(vws, cbuf, fence);
+   }
+}
+
 static void virgl_flush_eq(struct virgl_context *ctx, void *closure,
                           struct pipe_fence_handle **fence)
 {
@@ -887,7 +907,8 @@ static void virgl_flush_eq(struct virgl_context *ctx, void *closure,
    ctx->num_draws = ctx->num_compute = 0;
 
    virgl_transfer_queue_clear(&ctx->queue, ctx->cbuf);
-   rs->vws->submit_cmd(rs->vws, ctx->cbuf, fence);
+
+   virgl_submit_cmd(rs->vws, ctx->cbuf, fence);
 
    /* Reserve some space for transfers. */
    if (ctx->encoded_transfers)
@@ -1355,8 +1376,8 @@ virgl_context_destroy( struct pipe_context *ctx )
    rs->vws->cmd_buf_destroy(vctx->cbuf);
    if (vctx->uploader)
       u_upload_destroy(vctx->uploader);
-   if (vctx->transfer_uploader)
-      u_upload_destroy(vctx->transfer_uploader);
+   if (vctx->supports_staging)
+      virgl_staging_destroy(&vctx->staging);
    util_primconvert_destroy(vctx->primconvert);
    virgl_transfer_queue_fini(&vctx->queue);
 
@@ -1402,6 +1423,19 @@ static void virgl_get_sample_position(struct pipe_context *ctx,
                    index, sample_count, out_value[0], out_value[1]);
 }
 
+static void virgl_send_tweaks(struct virgl_context *vctx, struct virgl_screen *rs)
+{
+   if (rs->tweak_gles_emulate_bgra)
+      virgl_encode_tweak(vctx, virgl_tweak_gles_brga_emulate, 1);
+
+   if (rs->tweak_gles_apply_bgra_dest_swizzle)
+      virgl_encode_tweak(vctx, virgl_tweak_gles_brga_apply_dest_swizzle, 1);
+
+   if (rs->tweak_gles_tf3_value > 0)
+      virgl_encode_tweak(vctx, virgl_tweak_gles_tf3_samples_passes_multiplier,
+                         rs->tweak_gles_tf3_value);
+}
+
 struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
                                           void *priv,
                                           unsigned flags)
@@ -1517,17 +1551,12 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
            goto fail;
    vctx->base.stream_uploader = vctx->uploader;
    vctx->base.const_uploader = vctx->uploader;
-   /* Use a custom/staging buffer for the transfer uploader, since we are
-    * using it only for copies to other resources.
-    */
+
+   /* We use a special staging buffer as the source of copy transfers. */
    if ((rs->caps.caps.v2.capability_bits & VIRGL_CAP_COPY_TRANSFER) &&
        vctx->encoded_transfers) {
-      vctx->transfer_uploader = u_upload_create(&vctx->base, 1024 * 1024,
-                                                PIPE_BIND_CUSTOM,
-                                                PIPE_USAGE_STAGING,
-                                                VIRGL_RESOURCE_FLAG_STAGING);
-      if (!vctx->transfer_uploader)
-              goto fail;
+      virgl_staging_init(&vctx->staging, &vctx->base, 1024 * 1024);
+      vctx->supports_staging = true;
    }
 
    vctx->hw_sub_ctx_id = rs->sub_ctx_id++;
@@ -1541,6 +1570,9 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
          virgl_encode_host_debug_flagstring(vctx, host_debug_flagstring);
    }
 
+   if (rs->caps.caps.v2.capability_bits & VIRGL_CAP_APP_TWEAK_SUPPORT)
+      virgl_send_tweaks(vctx, rs);
+
    return &vctx->base;
 fail:
    virgl_context_destroy(&vctx->base);