ilo: support PIPE_CAP_USER_CONSTANT_BUFFERS
authorChia-I Wu <olvaffe@gmail.com>
Wed, 26 Jun 2013 04:26:02 +0000 (12:26 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Wed, 26 Jun 2013 08:42:45 +0000 (16:42 +0800)
We need it for HUD support, and will need it for push constants in the future.

src/gallium/drivers/ilo/ilo_context.c
src/gallium/drivers/ilo/ilo_context.h
src/gallium/drivers/ilo/ilo_gpe.h
src/gallium/drivers/ilo/ilo_screen.c
src/gallium/drivers/ilo/ilo_state.c

index d3e900661ee92f2628629d8364ea2832a49c2c8f..e355a9c3089fb6f7630237f86f27ced8130e83c4 100644 (file)
@@ -25,6 +25,7 @@
  *    Chia-I Wu <olv@lunarg.com>
  */
 
+#include "util/u_upload_mgr.h"
 #include "intel_chipset.h"
 
 #include "ilo_3d.h"
@@ -96,7 +97,8 @@ ilo_context_destroy(struct pipe_context *pipe)
    if (ilo->last_cp_bo)
       intel_bo_unreference(ilo->last_cp_bo);
 
-   util_slab_destroy(&ilo->transfer_mempool);
+   if (ilo->uploader)
+      u_upload_destroy(ilo->uploader);
 
    if (ilo->blitter)
       ilo_blitter_destroy(ilo->blitter);
@@ -107,6 +109,8 @@ ilo_context_destroy(struct pipe_context *pipe)
    if (ilo->cp)
       ilo_cp_destroy(ilo->cp);
 
+   util_slab_destroy(&ilo->transfer_mempool);
+
    FREE(ilo);
 }
 
@@ -123,6 +127,13 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
    ilo->winsys = is->winsys;
    ilo->dev = &is->dev;
 
+   /*
+    * initialize first, otherwise it may not be safe to call
+    * ilo_context_destroy() on errors
+    */
+   util_slab_create(&ilo->transfer_mempool,
+         sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED);
+
    ilo->cp = ilo_cp_create(ilo->winsys, is->dev.has_llc);
    ilo->shader_cache = ilo_shader_cache_create();
    if (ilo->cp)
@@ -133,12 +144,16 @@ ilo_context_create(struct pipe_screen *screen, void *priv)
       return NULL;
    }
 
+   ilo->uploader = u_upload_create(&ilo->base, 1024 * 1024, 16,
+         PIPE_BIND_CONSTANT_BUFFER);
+   if (!ilo->uploader) {
+      ilo_context_destroy(&ilo->base);
+      return NULL;
+   }
+
    ilo_cp_set_flush_callback(ilo->cp,
          ilo_context_cp_flushed, (void *) ilo);
 
-   util_slab_create(&ilo->transfer_mempool,
-         sizeof(struct ilo_transfer), 64, UTIL_SLAB_SINGLETHREADED);
-
    ilo->base.screen = screen;
    ilo->base.priv = priv;
 
index a37ed001b4c64f03f376d2c61882692709ffa663..ed9bba39ab5402c54c22013ee02ac663800d5461 100644 (file)
@@ -34,6 +34,7 @@
 #include "ilo_gpe.h"
 #include "ilo_common.h"
 
+struct u_upload_mgr;
 struct intel_winsys;
 struct intel_bo;
 struct ilo_3d;
@@ -48,15 +49,17 @@ struct ilo_context {
    struct intel_winsys *winsys;
    struct ilo_dev_info *dev;
 
+   struct util_slab_mempool transfer_mempool;
+
    struct ilo_cp *cp;
    struct intel_bo *last_cp_bo;
 
-   struct util_slab_mempool transfer_mempool;
-
    struct ilo_shader_cache *shader_cache;
    struct ilo_3d *hw3d;
    struct ilo_blitter *blitter;
 
+   struct u_upload_mgr *uploader;
+
    uint32_t dirty;
 
    struct ilo_vb_state vb;
index 5e313abd3869a2e8654bd4607608fee9f3fada50..7825e58a40fe5c997fc8445ebd70ea57a714ebee 100644 (file)
@@ -207,6 +207,13 @@ struct ilo_view_state {
 struct ilo_cbuf_cso {
    struct pipe_resource *resource;
    struct ilo_view_surface surface;
+
+   /*
+    * this CSO is not so constant because user buffer needs to be uploaded in
+    * finalize_constant_buffers()
+    */
+   const void *user_buffer;
+   unsigned user_buffer_size;
 };
 
 struct ilo_cbuf_state {
index d2b211366b10e09b1038ccbf16b3a5c5d30c5cdd..aaceb7a6494162fc3d425229c877b5f2e7d327c6 100644 (file)
@@ -393,7 +393,7 @@ ilo_get_param(struct pipe_screen *screen, enum pipe_cap param)
    case PIPE_CAP_USER_INDEX_BUFFERS:
       return false;
    case PIPE_CAP_USER_CONSTANT_BUFFERS:
-      return false; /* TODO push constants */
+      return true;
    case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
       /* imposed by OWord (Dual) Block Read */
       return 16;
index 7046a69890c1f0f35941390f99ee64009dd2415c..71783dfaca8d7332aa275d60ce084a7d10f55cdc 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "util/u_framebuffer.h"
 #include "util/u_helpers.h"
+#include "util/u_upload_mgr.h"
 
 #include "ilo_context.h"
 #include "ilo_resource.h"
@@ -86,18 +87,40 @@ finalize_shader_states(struct ilo_context *ilo)
 static void
 finalize_constant_buffers(struct ilo_context *ilo)
 {
-   int sh;
+   int sh, i;
 
    if (!(ilo->dirty & ILO_DIRTY_CONSTANT_BUFFER))
       return;
 
+   /* TODO push constants? */
    for (sh = 0; sh < PIPE_SHADER_TYPES; sh++) {
-      int last_cbuf = Elements(ilo->cbuf[sh].cso) - 1;
+      int last_cbuf = -1;
 
-      /* find the last cbuf */
-      while (last_cbuf >= 0 &&
-             !ilo->cbuf[sh].cso[last_cbuf].resource)
-         last_cbuf--;
+      for (i = 0; i < Elements(ilo->cbuf[sh].cso); i++) {
+         struct ilo_cbuf_cso *cbuf = &ilo->cbuf[sh].cso[i];
+
+         /* upload user buffer */
+         if (cbuf->user_buffer) {
+            const enum pipe_format elem_format =
+               PIPE_FORMAT_R32G32B32A32_FLOAT;
+            unsigned offset;
+
+            u_upload_data(ilo->uploader, 0, cbuf->user_buffer_size,
+                  cbuf->user_buffer, &offset, &cbuf->resource);
+
+            ilo_gpe_init_view_surface_for_buffer(ilo->dev,
+                  ilo_buffer(cbuf->resource),
+                  offset, cbuf->user_buffer_size,
+                  util_format_get_blocksize(elem_format), elem_format,
+                  false, false, &cbuf->surface);
+
+            cbuf->user_buffer = NULL;
+            cbuf->user_buffer_size = 0;
+         }
+
+         if (cbuf->resource)
+            last_cbuf = i;
+      }
 
       ilo->cbuf[sh].count = last_cbuf + 1;
    }
@@ -112,6 +135,8 @@ ilo_finalize_states(struct ilo_context *ilo)
 {
    finalize_shader_states(ilo);
    finalize_constant_buffers(ilo);
+
+   u_upload_unmap(ilo->uploader);
 }
 
 static void *
@@ -509,7 +534,7 @@ ilo_set_clip_state(struct pipe_context *pipe,
 static void
 ilo_set_constant_buffer(struct pipe_context *pipe,
                         uint shader, uint index,
-                        struct pipe_constant_buffer *buf)
+                        struct pipe_constant_buffer *state)
 {
    struct ilo_context *ilo = ilo_context(pipe);
    struct ilo_cbuf_cso *cbuf;
@@ -519,22 +544,37 @@ ilo_set_constant_buffer(struct pipe_context *pipe,
 
    cbuf = &ilo->cbuf[shader].cso[index];
 
-   if (buf) {
-      const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   if (state) {
+      pipe_resource_reference(&cbuf->resource, state->buffer);
+
+      if (state->buffer) {
+         const enum pipe_format elem_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
 
-      /* no PIPE_CAP_USER_CONSTANT_BUFFERS */
-      assert(!buf->user_buffer);
+         ilo_gpe_init_view_surface_for_buffer(ilo->dev,
+               ilo_buffer(cbuf->resource),
+               state->buffer_offset, state->buffer_size,
+               util_format_get_blocksize(elem_format), elem_format,
+               false, false, &cbuf->surface);
 
-      pipe_resource_reference(&cbuf->resource, buf->buffer);
+         cbuf->user_buffer = NULL;
+         cbuf->user_buffer_size = 0;
+      }
+      else {
+         assert(state->user_buffer);
+
+         cbuf->surface.bo = NULL;
 
-      ilo_gpe_init_view_surface_for_buffer(ilo->dev, ilo_buffer(buf->buffer),
-            buf->buffer_offset, buf->buffer_size,
-            util_format_get_blocksize(elem_format), elem_format,
-            false, false, &cbuf->surface);
+         /* state->buffer_offset does not apply for user buffer */
+         cbuf->user_buffer = state->user_buffer;
+         cbuf->user_buffer_size = state->buffer_size;
+      }
    }
    else {
       pipe_resource_reference(&cbuf->resource, NULL);
       cbuf->surface.bo = NULL;
+
+      cbuf->user_buffer = NULL;
+      cbuf->user_buffer_size = 0;
    }
 
    /* the correct value will be set in ilo_finalize_states() */