i965: Bind UBOs as surfaces like we do for pull constants.
authorEric Anholt <eric@anholt.net>
Wed, 20 Jun 2012 19:29:29 +0000 (12:29 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 7 Aug 2012 20:54:51 +0000 (13:54 -0700)
v2: Comment fix, drop extraneous parens (review by Kenneth)

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs_surface_state.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c

index 8a082abce7a445cc08573d9f4d940918b596f311..1548f81ec4fd41c89fefc025ceb07975db0b6eb7 100644 (file)
@@ -493,6 +493,9 @@ struct brw_vs_ouput_sizes {
 /** Maximum number of actual buffers used for stream output */
 #define BRW_MAX_SOL_BUFFERS 4
 
+#define BRW_MAX_WM_UBOS              12
+#define BRW_MAX_VS_UBOS              12
+
 /**
  * Helpers to create Surface Binding Table indexes for draw buffers,
  * textures, and constant buffers.
@@ -518,6 +521,11 @@ struct brw_vs_ouput_sizes {
  *    |   . |     .                   |
  *    |   : |     :                   |
  *    |  24 | Texture 15              |
+ *    |-----|-------------------------|
+ *    |  25 | UBO 0                   |
+ *    |   . |     .                   |
+ *    |   : |     :                   |
+ *    |  36 | UBO 11                  |
  *    +-------------------------------+
  *
  * Our VS binding tables are programmed as follows:
@@ -529,6 +537,11 @@ struct brw_vs_ouput_sizes {
  *    |   . |     .                   |
  *    |   : |     :                   |
  *    |  16 | Texture 15              |
+ *    +-----+-------------------------+
+ *    |  17 | UBO 0                   |
+ *    |   . |     .                   |
+ *    |   : |     :                   |
+ *    |  28 | UBO 11                  |
  *    +-------------------------------+
  *
  * Our (gen6) GS binding tables are programmed as follows:
@@ -547,13 +560,15 @@ struct brw_vs_ouput_sizes {
 #define SURF_INDEX_DRAW(d)           (d)
 #define SURF_INDEX_FRAG_CONST_BUFFER (BRW_MAX_DRAW_BUFFERS + 1)
 #define SURF_INDEX_TEXTURE(t)        (BRW_MAX_DRAW_BUFFERS + 2 + (t))
+#define SURF_INDEX_WM_UBO(u)         (SURF_INDEX_TEXTURE(BRW_MAX_TEX_UNIT) + u)
 
 /** Maximum size of the binding table. */
-#define BRW_MAX_WM_SURFACES          SURF_INDEX_TEXTURE(BRW_MAX_TEX_UNIT)
+#define BRW_MAX_WM_SURFACES          SURF_INDEX_WM_UBO(BRW_MAX_WM_UBOS)
 
 #define SURF_INDEX_VERT_CONST_BUFFER (0)
 #define SURF_INDEX_VS_TEXTURE(t)     (SURF_INDEX_VERT_CONST_BUFFER + 1 + (t))
-#define BRW_MAX_VS_SURFACES          SURF_INDEX_VS_TEXTURE(BRW_MAX_TEX_UNIT)
+#define SURF_INDEX_VS_UBO(u)         (SURF_INDEX_VS_TEXTURE(BRW_MAX_TEX_UNIT) + u)
+#define BRW_MAX_VS_SURFACES          SURF_INDEX_VS_UBO(BRW_MAX_VS_UBOS)
 
 #define SURF_INDEX_SOL_BINDING(t)    ((t))
 #define BRW_MAX_GS_SURFACES          SURF_INDEX_SOL_BINDING(BRW_MAX_SOL_BINDINGS)
@@ -1135,6 +1150,9 @@ brw_update_sol_surface(struct brw_context *brw,
                        struct gl_buffer_object *buffer_obj,
                        uint32_t *out_offset, unsigned num_vector_components,
                        unsigned stride_dwords, unsigned offset_dwords);
+void brw_upload_ubo_surfaces(struct brw_context *brw,
+                            struct gl_shader *shader,
+                            uint32_t *surf_offsets);
 
 /* gen6_sol.c */
 void
index 8b99c521b7846e44b61231c72a049381b022d7c2..2540cd574b2d55407bdab57f7b97cea54e1fc4f3 100644 (file)
@@ -71,6 +71,7 @@ extern const struct brw_tracked_state brw_state_base_address;
 extern const struct brw_tracked_state brw_urb_fence;
 extern const struct brw_tracked_state brw_vertex_state;
 extern const struct brw_tracked_state brw_vs_prog;
+extern const struct brw_tracked_state brw_vs_ubo_surfaces;
 extern const struct brw_tracked_state brw_vs_unit;
 extern const struct brw_tracked_state brw_wm_input_sizes;
 extern const struct brw_tracked_state brw_wm_prog;
@@ -78,6 +79,7 @@ extern const struct brw_tracked_state brw_renderbuffer_surfaces;
 extern const struct brw_tracked_state brw_texture_surfaces;
 extern const struct brw_tracked_state brw_wm_binding_table;
 extern const struct brw_tracked_state brw_vs_binding_table;
+extern const struct brw_tracked_state brw_wm_ubo_surfaces;
 extern const struct brw_tracked_state brw_wm_unit;
 
 extern const struct brw_tracked_state brw_psp_urb_cbs;
index 12535ed01cdcdd9d0f0036e8a5fea284867128cf..c3e6de49779f761dd70c810e805152ed9de8e2f7 100644 (file)
@@ -143,7 +143,9 @@ static const struct brw_tracked_state *gen6_atoms[] =
     * table upload must be last.
     */
    &brw_vs_pull_constants,
+   &brw_vs_ubo_surfaces,
    &brw_wm_pull_constants,
+   &brw_wm_ubo_surfaces,
    &gen6_renderbuffer_surfaces,
    &brw_texture_surfaces,
    &gen6_sol_surface,
@@ -215,7 +217,9 @@ const struct brw_tracked_state *gen7_atoms[] =
     * table upload must be last.
     */
    &brw_vs_pull_constants,
+   &brw_vs_ubo_surfaces,
    &brw_wm_pull_constants,
+   &brw_wm_ubo_surfaces,
    &gen6_renderbuffer_surfaces,
    &brw_texture_surfaces,
    &brw_vs_binding_table,
index b1b073e9bdebc65ddb3d0427b6f3ae939ad12d29..feec455876251f35a099ccfc03a5dc9d76a7be7c 100644 (file)
@@ -250,7 +250,7 @@ do_vs_prog(struct brw_context *brw,
    if (c.prog_data.nr_pull_params)
       c.prog_data.num_surfaces = 1;
    if (c.vp->program.Base.SamplersUsed)
-      c.prog_data.num_surfaces = BRW_MAX_VS_SURFACES;
+      c.prog_data.num_surfaces = SURF_INDEX_VS_TEXTURE(BRW_MAX_TEX_UNIT);
 
    /* Scratch space is used for register spilling */
    if (c.last_scratch) {
index 202614551a504f8b3d5a4325d49a424fcdb8f50e..e29797e92fa70b202a1eb8da51d4d274241bacc2 100644 (file)
@@ -111,6 +111,30 @@ const struct brw_tracked_state brw_vs_pull_constants = {
    .emit = brw_upload_vs_pull_constants,
 };
 
+static void
+brw_upload_vs_ubo_surfaces(struct brw_context *brw)
+{
+   struct gl_context *ctx = &brw->intel.ctx;
+   /* _NEW_PROGRAM */
+   struct gl_shader_program *prog = ctx->Shader.CurrentVertexProgram;
+
+   if (!prog)
+      return;
+
+   brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_VERTEX],
+                          &brw->vs.surf_offset[SURF_INDEX_VS_UBO(0)]);
+}
+
+const struct brw_tracked_state brw_vs_ubo_surfaces = {
+   .dirty = {
+      .mesa = (_NEW_PROGRAM |
+              _NEW_BUFFER_OBJECT),
+      .brw = BRW_NEW_BATCH,
+      .cache = 0,
+   },
+   .emit = brw_upload_vs_ubo_surfaces,
+};
+
 /**
  * Constructs the binding table for the WM surface state, which maps unit
  * numbers to surface state objects.
index 33c21982a476e4fe8e8d383e9413c2137021016a..4d3d265d40c83b631b5203c6f42c3abfa6d0671d 100644 (file)
@@ -1263,6 +1263,65 @@ const struct brw_tracked_state brw_texture_surfaces = {
    .emit = brw_update_texture_surfaces,
 };
 
+void
+brw_upload_ubo_surfaces(struct brw_context *brw,
+                       struct gl_shader *shader,
+                       uint32_t *surf_offsets)
+{
+   struct gl_context *ctx = &brw->intel.ctx;
+   struct intel_context *intel = &brw->intel;
+
+   if (!shader)
+      return;
+
+   for (int i = 0; i < shader->NumUniformBlocks; i++) {
+      struct gl_uniform_buffer_binding *binding;
+      struct intel_buffer_object *intel_bo;
+
+      binding = &ctx->UniformBufferBindings[shader->UniformBlocks[i].Binding];
+      intel_bo = intel_buffer_object(binding->BufferObject);
+      drm_intel_bo *bo = intel_bufferobj_buffer(intel, intel_bo, INTEL_READ);
+
+      /* Because behavior for referencing outside of the binding's size in the
+       * glBindBufferRange case is undefined, we can just bind the whole buffer
+       * glBindBufferBase wants and be a correct implementation.
+       */
+      int size = bo->size - binding->Offset;
+      size = ALIGN(size, 16) / 16; /* The interface takes a number of vec4s */
+
+      intel->vtbl.create_constant_surface(brw, bo, binding->Offset,
+                                         size,
+                                         &surf_offsets[i]);
+   }
+
+   if (shader->NumUniformBlocks)
+      brw->state.dirty.brw |= BRW_NEW_SURFACES;
+}
+
+static void
+brw_upload_wm_ubo_surfaces(struct brw_context *brw)
+{
+   struct gl_context *ctx = &brw->intel.ctx;
+   /* _NEW_PROGRAM */
+   struct gl_shader_program *prog = ctx->Shader._CurrentFragmentProgram;
+
+   if (!prog)
+      return;
+
+   brw_upload_ubo_surfaces(brw, prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
+                          &brw->wm.surf_offset[SURF_INDEX_WM_UBO(0)]);
+}
+
+const struct brw_tracked_state brw_wm_ubo_surfaces = {
+   .dirty = {
+      .mesa = (_NEW_PROGRAM |
+              _NEW_BUFFER_OBJECT),
+      .brw = BRW_NEW_BATCH,
+      .cache = 0,
+   },
+   .emit = brw_upload_wm_ubo_surfaces,
+};
+
 /**
  * Constructs the binding table for the WM surface state, which maps unit
  * numbers to surface state objects.