[Mesa-dev] [PATCH 17/22] i965: Bind UBOs as surfaces like we do for pull constants.

Kenneth Graunke kenneth at whitecape.org
Tue Jul 31 23:34:53 PDT 2012


On 07/31/2012 03:01 PM, Eric Anholt wrote:
> ---
>  src/mesa/drivers/dri/i965/brw_context.h          |   22 +++++++-
>  src/mesa/drivers/dri/i965/brw_state.h            |    2 +
>  src/mesa/drivers/dri/i965/brw_state_upload.c     |    4 ++
>  src/mesa/drivers/dri/i965/brw_vs.c               |    2 +-
>  src/mesa/drivers/dri/i965/brw_vs_surface_state.c |   24 +++++++++
>  src/mesa/drivers/dri/i965/brw_wm_surface_state.c |   59 ++++++++++++++++++++++
>  6 files changed, 110 insertions(+), 3 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
> index 8a082ab..7414732 100644
> --- a/src/mesa/drivers/dri/i965/brw_context.h
> +++ b/src/mesa/drivers/dri/i965/brw_context.h
> @@ -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 15                  |

You mean "UBO 11" here (cut & paste error from "Texture 15" above).

>   *    +-------------------------------+
>   *
>   * 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
> diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
> index 8b99c52..2540cd5 100644
> --- a/src/mesa/drivers/dri/i965/brw_state.h
> +++ b/src/mesa/drivers/dri/i965/brw_state.h
> @@ -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;
> diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
> index 12535ed..c3e6de4 100644
> --- a/src/mesa/drivers/dri/i965/brw_state_upload.c
> +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
> @@ -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,
> diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
> index 7e69032..81c586a 100644
> --- a/src/mesa/drivers/dri/i965/brw_vs.c
> +++ b/src/mesa/drivers/dri/i965/brw_vs.c
> @@ -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) {
> diff --git a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
> index 2026145..5509cff 100644
> --- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
> +++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
> @@ -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),

You don't actually need the extra parenthesis...IMHO,

  .foo = bits | morebits | yetmorebits,
  .bar = ...

is already quite readable, and definitely unambiguous (the = and , are
clear delimiters).  Not a big deal either way though.

> +      .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.
> diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> index 02800f8..c645340 100644
> --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> @@ -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),

Ditto on the parenthesis.

> +      .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.
> 

Otherwise, looks good to me.
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>


More information about the mesa-dev mailing list