virgl: add UBOs to virgl_shader_binding_state
authorChia-I Wu <olvaffe@gmail.com>
Thu, 16 May 2019 21:00:54 +0000 (14:00 -0700)
committerChia-I Wu <olvaffe@gmail.com>
Fri, 7 Jun 2019 22:47:07 +0000 (22:47 +0000)
It replaces virgl_context::ubos.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
src/gallium/drivers/virgl/virgl_context.c
src/gallium/drivers/virgl/virgl_context.h

index f02ed2d211d7d5da6bc2209e44898fe275cdfa46..2479690e8d483ddf8da0e86fc6aa32745e63b214 100644 (file)
@@ -145,13 +145,16 @@ static void virgl_attach_res_uniform_buffers(struct virgl_context *vctx,
                                              enum pipe_shader_type shader_type)
 {
    struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
+   const struct virgl_shader_binding_state *binding =
+      &vctx->shader_bindings[shader_type];
+   uint32_t remaining_mask = binding->ubo_enabled_mask;
    struct virgl_resource *res;
-   unsigned i;
-   for (i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
-      res = virgl_resource(vctx->ubos[shader_type][i]);
-      if (res) {
-         vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
-      }
+
+   while (remaining_mask) {
+      int i = u_bit_scan(&remaining_mask);
+      res = virgl_resource(binding->ubos[i].buffer);
+      assert(res);
+      vws->emit_res(vws, vctx->cbuf, res->hw_res, FALSE);
    }
 }
 
@@ -505,20 +508,28 @@ static void virgl_set_constant_buffer(struct pipe_context *ctx,
                                      const struct pipe_constant_buffer *buf)
 {
    struct virgl_context *vctx = virgl_context(ctx);
+   struct virgl_shader_binding_state *binding =
+      &vctx->shader_bindings[shader];
 
-   if (buf) {
-      if (!buf->user_buffer){
-         struct virgl_resource *res = virgl_resource(buf->buffer);
-         virgl_encoder_set_uniform_buffer(vctx, shader, index, buf->buffer_offset,
-                                          buf->buffer_size, res);
-         pipe_resource_reference(&vctx->ubos[shader][index], buf->buffer);
-         return;
-      }
-      pipe_resource_reference(&vctx->ubos[shader][index], NULL);
-      virgl_encoder_write_constant_buffer(vctx, shader, index, buf->buffer_size / 4, buf->user_buffer);
+   if (buf && buf->buffer) {
+      struct virgl_resource *res = virgl_resource(buf->buffer);
+      virgl_encoder_set_uniform_buffer(vctx, shader, index,
+                                       buf->buffer_offset,
+                                       buf->buffer_size, res);
+
+      pipe_resource_reference(&binding->ubos[index].buffer, buf->buffer);
+      binding->ubos[index] = *buf;
+      binding->ubo_enabled_mask |= 1 << index;
    } else {
-      virgl_encoder_write_constant_buffer(vctx, shader, index, 0, NULL);
-      pipe_resource_reference(&vctx->ubos[shader][index], NULL);
+      static const struct pipe_constant_buffer dummy_ubo;
+      if (!buf)
+         buf = &dummy_ubo;
+      virgl_encoder_write_constant_buffer(vctx, shader, index,
+                                          buf->buffer_size / 4,
+                                          buf->user_buffer);
+
+      pipe_resource_reference(&binding->ubos[index].buffer, NULL);
+      binding->ubo_enabled_mask &= ~(1 << index);
    }
 }
 
@@ -1156,6 +1167,11 @@ virgl_release_shader_binding(struct virgl_context *vctx,
       pipe_sampler_view_reference(
             (struct pipe_sampler_view **)&binding->views[i], NULL);
    }
+
+   while (binding->ubo_enabled_mask) {
+      int i = u_bit_scan(&binding->ubo_enabled_mask);
+      pipe_resource_reference(&binding->ubos[i].buffer, NULL);
+   }
 }
 
 static void
index ad8ba5f98f03c4cebe7ec056e3987bdfb8a9227e..e8d65c6e97b1d2e11b44437536c046a870b21ea9 100644 (file)
@@ -54,6 +54,9 @@ struct virgl_rasterizer_state {
 struct virgl_shader_binding_state {
    struct pipe_sampler_view *views[16];
    uint32_t view_enabled_mask;
+
+   struct pipe_constant_buffer ubos[PIPE_MAX_CONSTANT_BUFFERS];
+   uint32_t ubo_enabled_mask;
 };
 
 struct virgl_context {
@@ -80,8 +83,6 @@ struct virgl_context {
    struct virgl_so_target so_targets[PIPE_MAX_SO_BUFFERS];
    unsigned num_so_targets;
 
-   struct pipe_resource *ubos[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS];
-
    struct pipe_resource *ssbos[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
    struct pipe_resource *images[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
    uint32_t num_draws, num_compute;