This was bothering me when redoing the binding tables.
#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 */
struct brw_vertex_program {
struct gl_vertex_program program;
GLuint id;
- drm_intel_bo *const_buffer; /** Program constant buffer/surface */
GLboolean use_const_buffer;
};
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;
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;
drm_intel_bo *prog_bo;
drm_intel_bo *state_bo;
+ drm_intel_bo *const_bo;
} wm;
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];
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.
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 );
}
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;
&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 */
* 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.
*
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;
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;
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,
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);
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);
* 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.
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;
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;
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;
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,