Mesa (master): i965: Split constant buffer setup from its surface state/ binding state.

Eric Anholt anholt at kemper.freedesktop.org
Fri Jun 11 00:21:46 PDT 2010


Module: Mesa
Branch: master
Commit: 118a47623a11a374df371d52ed0294224e6a62dc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=118a47623a11a374df371d52ed0294224e6a62dc

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jun 10 17:09:21 2010 -0700

i965: Split constant buffer setup from its surface state/binding state.

This was bothering me when redoing the binding tables.

---

 src/mesa/drivers/dri/i965/brw_context.h          |    6 ++-
 src/mesa/drivers/dri/i965/brw_curbe.c            |   10 ----
 src/mesa/drivers/dri/i965/brw_program.c          |   14 -----
 src/mesa/drivers/dri/i965/brw_state.h            |    2 +
 src/mesa/drivers/dri/i965/brw_state_upload.c     |    3 +
 src/mesa/drivers/dri/i965/brw_vs_surface_state.c |   63 +++++++++++++---------
 src/mesa/drivers/dri/i965/brw_vtbl.c             |    2 +
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |   57 +++++++++++---------
 8 files changed, 79 insertions(+), 78 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index fa86f4d..a829067 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -143,6 +143,8 @@ struct brw_context;
 #define BRW_NEW_NR_WM_SURFACES		0x40000
 #define BRW_NEW_NR_VS_SURFACES		0x80000
 #define BRW_NEW_INDEX_BUFFER		0x100000
+#define BRW_NEW_VS_CONSTBUF		0x200000
+#define BRW_NEW_WM_CONSTBUF		0x200000
 
 struct brw_state_flags {
    /** State update flags signalled by mesa internals */
@@ -160,7 +162,6 @@ struct brw_state_flags {
 struct brw_vertex_program {
    struct gl_vertex_program program;
    GLuint id;
-   drm_intel_bo *const_buffer;    /** Program constant buffer/surface */
    GLboolean use_const_buffer;
 };
 
@@ -172,7 +173,6 @@ struct brw_fragment_program {
    GLboolean isGLSL;  /**< really, any IF/LOOP/CONT/BREAK instructions */
 
    GLboolean use_const_buffer;
-   drm_intel_bo *const_buffer;    /** Program constant buffer/surface */
 
    /** for debugging, which texture units are referenced */
    GLbitfield tex_units_used;
@@ -594,6 +594,7 @@ struct brw_context
 
       drm_intel_bo *prog_bo;
       drm_intel_bo *state_bo;
+      drm_intel_bo *const_bo;
 
       /** Binding table of pointers to surf_bo entries */
       drm_intel_bo *bind_bo;
@@ -653,6 +654,7 @@ struct brw_context
 
       drm_intel_bo *prog_bo;
       drm_intel_bo *state_bo;
+      drm_intel_bo *const_bo;
    } wm;
 
 
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index c79b0a7..e6d9ac8 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -200,8 +200,6 @@ static void prepare_constant_buffer(struct brw_context *brw)
    if (brw->curbe.wm_size) {
       GLuint offset = brw->curbe.wm_start * 16;
 
-      _mesa_load_state_parameters(ctx, fp->program.Base.Parameters); 
-
       /* copy float constants */
       for (i = 0; i < brw->wm.prog_data->nr_params; i++) 
 	 buf[offset + i] = *brw->wm.prog_data->param[i];
@@ -244,14 +242,6 @@ static void prepare_constant_buffer(struct brw_context *brw)
       GLuint offset = brw->curbe.vs_start * 16;
       GLuint nr = brw->vs.prog_data->nr_params / 4;
 
-      if (brw->vertex_program->IsNVProgram)
-	 _mesa_load_tracked_matrices(ctx);
-
-      /* Updates the ParamaterValues[i] pointers for all parameters of the
-       * basic type of PROGRAM_STATE_VAR.
-       */
-      _mesa_load_state_parameters(ctx, vp->program.Base.Parameters); 
-
       if (vp->use_const_buffer) {
 	 /* Load the subset of push constants that will get used when
 	  * we also have a pull constant buffer.
diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c
index b44742b..bd560ac 100644
--- a/src/mesa/drivers/dri/i965/brw_program.c
+++ b/src/mesa/drivers/dri/i965/brw_program.c
@@ -95,20 +95,6 @@ static struct gl_program *brwNewProgram( GLcontext *ctx,
 static void brwDeleteProgram( GLcontext *ctx,
 			      struct gl_program *prog )
 {
-   if (prog->Target == GL_FRAGMENT_PROGRAM_ARB) {
-      struct gl_fragment_program *fp = (struct gl_fragment_program *) prog;
-      struct brw_fragment_program *brw_fp = brw_fragment_program(fp);
-
-      drm_intel_bo_unreference(brw_fp->const_buffer);
-   }
-
-   if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
-      struct gl_vertex_program *vp = (struct gl_vertex_program *) prog;
-      struct brw_vertex_program *brw_vp = brw_vertex_program(vp);
-
-      drm_intel_bo_unreference(brw_vp->const_buffer);
-   }
-
    _mesa_delete_program( ctx, prog );
 }
 
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index dce0c49..364be94 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -51,6 +51,8 @@ const struct brw_tracked_state brw_cc_unit;
 const struct brw_tracked_state brw_check_fallback;
 const struct brw_tracked_state brw_clip_prog;
 const struct brw_tracked_state brw_clip_unit;
+const struct brw_tracked_state brw_vs_constants;
+const struct brw_tracked_state brw_wm_constants;
 const struct brw_tracked_state brw_constant_buffer;
 const struct brw_tracked_state brw_curbe_offsets;
 const struct brw_tracked_state brw_invarient_state;
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index e0c121f..08535bb 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -63,6 +63,9 @@ static const struct brw_tracked_state *gen4_atoms[] =
 
    &brw_cc_unit,
 
+   &brw_vs_constants, /* Before vs_surfaces and constant_buffer */
+   &brw_wm_constants, /* Before wm_surfaces and constant_buffer */
+
    &brw_vs_surfaces,		/* must do before unit */
    &brw_wm_constant_surface,	/* must do before wm surfaces/bind bo */
    &brw_wm_surfaces,		/* must do before samplers and unit */
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 9bc5855..26164e9 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_surface_state.c
@@ -42,42 +42,59 @@
  * Otherwise, constants go through the CURBEs using the brw_constant_buffer
  * state atom.
  */
-static drm_intel_bo *
-brw_vs_update_constant_buffer(struct brw_context *brw)
+static void
+prepare_vs_constants(struct brw_context *brw)
 {
+   GLcontext *ctx = &brw->intel.ctx;
    struct intel_context *intel = &brw->intel;
    struct brw_vertex_program *vp =
       (struct brw_vertex_program *) brw->vertex_program;
    const struct gl_program_parameter_list *params = vp->program.Base.Parameters;
    const int size = params->NumParameters * 4 * sizeof(GLfloat);
-   drm_intel_bo *const_buffer;
    int i;
 
-   /* BRW_NEW_VERTEX_PROGRAM */
-   if (!vp->use_const_buffer)
-      return NULL;
-
-   const_buffer = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer",
-				     size, 64);
-
-   /* _NEW_PROGRAM_CONSTANTS */
+   if (vp->program.IsNVProgram)
+      _mesa_load_tracked_matrices(ctx);
 
    /* Updates the ParamaterValues[i] pointers for all parameters of the
     * basic type of PROGRAM_STATE_VAR.
     */
    _mesa_load_state_parameters(&brw->intel.ctx, vp->program.Base.Parameters);
 
-   drm_intel_gem_bo_map_gtt(const_buffer);
+   /* BRW_NEW_VERTEX_PROGRAM */
+   if (!vp->use_const_buffer) {
+      if (brw->vs.const_bo) {
+	 drm_intel_bo_unreference(brw->vs.const_bo);
+	 brw->vs.const_bo = NULL;
+	 brw->state.dirty.brw |= BRW_NEW_VS_CONSTBUF;
+      }
+      return;
+   }
+
+   /* _NEW_PROGRAM_CONSTANTS */
+   drm_intel_bo_unreference(brw->vs.const_bo);
+   brw->vs.const_bo = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer",
+					 size, 64);
+
+   drm_intel_gem_bo_map_gtt(brw->vs.const_bo);
    for (i = 0; i < params->NumParameters; i++) {
-      memcpy(const_buffer->virtual + i * 4 * sizeof(float),
+      memcpy(brw->vs.const_bo->virtual + i * 4 * sizeof(float),
 	     params->ParameterValues[i],
 	     4 * sizeof(float));
    }
-   drm_intel_gem_bo_unmap_gtt(const_buffer);
-
-   return const_buffer;
+   drm_intel_gem_bo_unmap_gtt(brw->vs.const_bo);
+   brw->state.dirty.brw |= BRW_NEW_VS_CONSTBUF;
 }
 
+const struct brw_tracked_state brw_vs_constants = {
+   .dirty = {
+      .mesa = (_NEW_PROGRAM_CONSTANTS),
+      .brw = (BRW_NEW_VERTEX_PROGRAM),
+      .cache = 0
+   },
+   .prepare = prepare_vs_constants,
+};
+
 /**
  * Update the surface state for a VS constant buffer.
  *
@@ -95,16 +112,10 @@ brw_update_vs_constant_surface( GLcontext *ctx,
 
    assert(surf == 0);
 
-   /* If we're in this state update atom, we need to update VS constants, so
-    * free the old buffer and create a new one for the new contents.
-    */
-   drm_intel_bo_unreference(vp->const_buffer);
-   vp->const_buffer = brw_vs_update_constant_buffer(brw);
-
    /* If there's no constant buffer, then no surface BO is needed to point at
     * it.
     */
-   if (vp->const_buffer == NULL) {
+   if (brw->vs.const_bo == NULL) {
       drm_intel_bo_unreference(brw->vs.surf_bo[surf]);
       brw->vs.surf_bo[surf] = NULL;
       return;
@@ -114,7 +125,7 @@ brw_update_vs_constant_surface( GLcontext *ctx,
 
    key.format = MESA_FORMAT_RGBA_FLOAT32;
    key.internal_format = GL_RGBA;
-   key.bo = vp->const_buffer;
+   key.bo = brw->vs.const_bo;
    key.depthmode = GL_NONE;
    key.pitch = params->NumParameters;
    key.width = params->NumParameters;
@@ -223,8 +234,8 @@ static void prepare_vs_surfaces(struct brw_context *brw )
 
 const struct brw_tracked_state brw_vs_surfaces = {
    .dirty = {
-      .mesa = (_NEW_PROGRAM_CONSTANTS),
-      .brw = (BRW_NEW_VERTEX_PROGRAM),
+      .mesa = 0,
+      .brw = (BRW_NEW_VS_CONSTBUF),
       .cache = 0
    },
    .prepare = prepare_vs_surfaces,
diff --git a/src/mesa/drivers/dri/i965/brw_vtbl.c b/src/mesa/drivers/dri/i965/brw_vtbl.c
index a02e958..14227a5 100644
--- a/src/mesa/drivers/dri/i965/brw_vtbl.c
+++ b/src/mesa/drivers/dri/i965/brw_vtbl.c
@@ -83,6 +83,7 @@ static void brw_destroy_context( struct intel_context *intel )
    dri_bo_release(&brw->vs.prog_bo);
    dri_bo_release(&brw->vs.state_bo);
    dri_bo_release(&brw->vs.bind_bo);
+   dri_bo_release(&brw->vs.const_bo);
    dri_bo_release(&brw->gs.prog_bo);
    dri_bo_release(&brw->gs.state_bo);
    dri_bo_release(&brw->clip.prog_bo);
@@ -99,6 +100,7 @@ static void brw_destroy_context( struct intel_context *intel )
    dri_bo_release(&brw->wm.sampler_bo);
    dri_bo_release(&brw->wm.prog_bo);
    dri_bo_release(&brw->wm.state_bo);
+   dri_bo_release(&brw->wm.const_bo);
    dri_bo_release(&brw->cc.prog_bo);
    dri_bo_release(&brw->cc.state_bo);
    dri_bo_release(&brw->cc.vp_bo);
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 3998054..2b216fd 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -337,29 +337,45 @@ brw_create_constant_surface( struct brw_context *brw,
  * Otherwise, constants go through the CURBEs using the brw_constant_buffer
  * state atom.
  */
-static drm_intel_bo *
-brw_wm_update_constant_buffer(struct brw_context *brw)
+static void
+prepare_wm_constants(struct brw_context *brw)
 {
+   GLcontext *ctx = &brw->intel.ctx;
    struct intel_context *intel = &brw->intel;
    struct brw_fragment_program *fp =
       (struct brw_fragment_program *) brw->fragment_program;
    const struct gl_program_parameter_list *params = fp->program.Base.Parameters;
    const int size = params->NumParameters * 4 * sizeof(GLfloat);
-   drm_intel_bo *const_buffer;
+
+   _mesa_load_state_parameters(ctx, fp->program.Base.Parameters);
 
    /* BRW_NEW_FRAGMENT_PROGRAM */
-   if (!fp->use_const_buffer)
-      return NULL;
+   if (!fp->use_const_buffer) {
+      if (brw->wm.const_bo) {
+	 drm_intel_bo_unreference(brw->wm.const_bo);
+	 brw->wm.const_bo = NULL;
+	 brw->state.dirty.brw |= BRW_NEW_WM_CONSTBUF;
+      }
+      return;
+   }
 
-   const_buffer = drm_intel_bo_alloc(intel->bufmgr, "fp_const_buffer",
-				     size, 64);
+   drm_intel_bo_unreference(brw->wm.const_bo);
+   brw->wm.const_bo = drm_intel_bo_alloc(intel->bufmgr, "vp_const_buffer",
+					 size, 64);
 
    /* _NEW_PROGRAM_CONSTANTS */
-   drm_intel_bo_subdata(const_buffer, 0, size, params->ParameterValues);
-
-   return const_buffer;
+   drm_intel_bo_subdata(brw->wm.const_bo, 0, size, params->ParameterValues);
 }
 
+const struct brw_tracked_state brw_wm_constants = {
+   .dirty = {
+      .mesa = (_NEW_PROGRAM_CONSTANTS),
+      .brw = (BRW_NEW_FRAGMENT_PROGRAM),
+      .cache = 0
+   },
+   .prepare = prepare_wm_constants,
+};
+
 /**
  * Update the surface state for a WM constant buffer.
  * The constant buffer will be (re)allocated here if needed.
@@ -375,16 +391,10 @@ brw_update_wm_constant_surface( GLcontext *ctx,
    const struct gl_program_parameter_list *params =
       fp->program.Base.Parameters;
 
-   /* If we're in this state update atom, we need to update WM constants, so
-    * free the old buffer and create a new one for the new contents.
-    */
-   drm_intel_bo_unreference(fp->const_buffer);
-   fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
    /* If there's no constant buffer, then no surface BO is needed to point at
     * it.
     */
-   if (fp->const_buffer == NULL) {
+   if (brw->wm.const_bo == NULL) {
       drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
       brw->wm.surf_bo[surf] = NULL;
       return;
@@ -394,7 +404,7 @@ brw_update_wm_constant_surface( GLcontext *ctx,
 
    key.format = MESA_FORMAT_RGBA_FLOAT32;
    key.internal_format = GL_RGBA;
-   key.bo = fp->const_buffer;
+   key.bo = brw->wm.const_bo;
    key.depthmode = GL_NONE;
    key.pitch = params->NumParameters;
    key.width = params->NumParameters;
@@ -431,17 +441,12 @@ brw_update_wm_constant_surface( GLcontext *ctx,
 static void prepare_wm_constant_surface(struct brw_context *brw )
 {
    GLcontext *ctx = &brw->intel.ctx;
-   struct brw_fragment_program *fp =
-      (struct brw_fragment_program *) brw->fragment_program;
    GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
 
-   drm_intel_bo_unreference(fp->const_buffer);
-   fp->const_buffer = brw_wm_update_constant_buffer(brw);
-
    /* If there's no constant buffer, then no surface BO is needed to point at
     * it.
     */
-   if (fp->const_buffer == 0) {
+   if (brw->wm.const_bo == 0) {
       if (brw->wm.surf_bo[surf] != NULL) {
 	 drm_intel_bo_unreference(brw->wm.surf_bo[surf]);
 	 brw->wm.surf_bo[surf] = NULL;
@@ -455,8 +460,8 @@ static void prepare_wm_constant_surface(struct brw_context *brw )
 
 const struct brw_tracked_state brw_wm_constant_surface = {
    .dirty = {
-      .mesa = (_NEW_PROGRAM_CONSTANTS),
-      .brw = (BRW_NEW_FRAGMENT_PROGRAM),
+      .mesa = 0,
+      .brw = (BRW_NEW_WM_CONSTBUF),
       .cache = 0
    },
    .prepare = prepare_wm_constant_surface,



More information about the mesa-commit mailing list