From: Eric Anholt Date: Fri, 11 Jun 2010 00:09:21 +0000 (-0700) Subject: i965: Split constant buffer setup from its surface state/binding state. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=118a47623a11a374df371d52ed0294224e6a62dc;p=mesa.git i965: Split constant buffer setup from its surface state/binding state. This was bothering me when redoing the binding tables. --- diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index fa86f4d8127..a8290673838 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 c79b0a79e5c..e6d9ac8ebbc 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 b44742b7650..bd560acdadf 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 dce0c490068..364be941171 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 e0c121f3128..08535bb59cc 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 9bc585586cd..26164e907f4 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 a02e958c5e6..14227a51332 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 3998054eb44..2b216fddbb5 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,