i965: Split constant buffer setup from its surface state/binding state.
authorEric Anholt <eric@anholt.net>
Fri, 11 Jun 2010 00:09:21 +0000 (17:09 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 11 Jun 2010 07:15:56 +0000 (00:15 -0700)
This was bothering me when redoing the binding tables.

src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_curbe.c
src/mesa/drivers/dri/i965/brw_program.c
src/mesa/drivers/dri/i965/brw_state.h
src/mesa/drivers/dri/i965/brw_state_upload.c
src/mesa/drivers/dri/i965/brw_vs_surface_state.c
src/mesa/drivers/dri/i965/brw_vtbl.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c

index fa86f4d812748e2cdc4a5500b4b630a10d05774c..a8290673838b8e62f40f595f292fd8b94b8e5303 100644 (file)
@@ -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;
 
 
index c79b0a79e5ca5b5b89f0e972a5365dfd7cb4e964..e6d9ac8ebbc6875401b8a64a28852931c985aedd 100644 (file)
@@ -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.
index b44742b76504dcb3246c493a988bd25efc3a0ab6..bd560acdadf69192d97b78ea30f7f63a5bbeb3e1 100644 (file)
@@ -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 );
 }
 
index dce0c4900687adf29fdb0e26c1cbf9e306479509..364be9411712361bca8a76729a18a6a79dd00265 100644 (file)
@@ -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;
index e0c121f3128b753770cc2fb390f30b21f5d5a9cd..08535bb59cc5b857b28052c9d9b034692e22b3c0 100644 (file)
@@ -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 */
index 9bc585586cd47917a5ec5b904bb94bd730847749..26164e907f4fbf351e17a62386007ebaa1a36b21 100644 (file)
  * 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,
index a02e958c5e6637af306d7adc1ee164a2a50a6551..14227a51332f1988370e8461f1168b1af6689cc9 100644 (file)
@@ -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);
index 3998054eb448ba7f289b8f11ecb67943ef4d040e..2b216fddbb5369885116af1f24f1b35addff4012 100644 (file)
@@ -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,