[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