Plus, begin the new code for vertex shader const buffers.
struct brw_vertex_program {
struct gl_vertex_program program;
GLuint id;
+ dri_bo *const_buffer; /** Program constant buffer/surface */
};
GLuint id; /**< serial no. to identify frag progs, never re-used */
GLboolean isGLSL; /**< really, any IF/LOOP/CONT/BREAK instructions */
- /** Program constant buffer/surface */
- dri_bo *const_buffer;
+ dri_bo *const_buffer; /** Program constant buffer/surface */
};
/**
- * Vertex/fragment shader constants are stored in a pseudo 1D texture.
- * This function updates the constants in that buffer.
+ * Copy Mesa program parameters into given constant buffer.
*/
static void
-update_texture_constant_buffer(struct brw_context *brw)
+update_constant_buffer(struct brw_context *brw,
+ const struct gl_program_parameter_list *params,
+ dri_bo *const_buffer)
{
- 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);
- assert(fp->const_buffer);
- assert(fp->const_buffer->size >= size);
-
- /* copy constants into the buffer */
+ /* copy Mesa program constants into the buffer */
if (size > 0) {
GLubyte *map;
- dri_bo_map(fp->const_buffer, GL_TRUE);
- map = fp->const_buffer->virtual;
+
+ assert(const_buffer);
+ assert(const_buffer->size >= size);
+
+ dri_bo_map(const_buffer, GL_TRUE);
+ map = const_buffer->virtual;
memcpy(map, params->ParameterValues, size);
- dri_bo_unmap(fp->const_buffer);
+ dri_bo_unmap(const_buffer);
}
}
+static void
+update_vertex_constant_buffer(struct brw_context *brw)
+{
+ struct brw_vertex_program *vp =
+ (struct brw_vertex_program *) brw->vertex_program;
+ update_constant_buffer(brw, vp->program.Base.Parameters, vp->const_buffer);
+}
+
+
+static void
+update_fragment_constant_buffer(struct brw_context *brw)
+{
+ struct brw_fragment_program *fp =
+ (struct brw_fragment_program *) brw->fragment_program;
+ update_constant_buffer(brw, fp->program.Base.Parameters, fp->const_buffer);
+}
+
+
static void emit_constant_buffer(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
GLuint sz = brw->curbe.total_size;
- update_texture_constant_buffer(brw);
+ update_vertex_constant_buffer(brw);
+ update_fragment_constant_buffer(brw);
BEGIN_BATCH(2, IGNORE_CLIPRECTS);
if (sz == 0) {
brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
newFP->id = brw->program_id++;
newFP->isGLSL = brw_wm_is_glsl(fprog);
-
- /* alloc constant buffer/surface */
- {
- const struct gl_program_parameter_list *params = prog->Parameters;
- const int size = params->NumParameters * 4 * sizeof(GLfloat);
-
- /* free old const buffer if too small */
- if (newFP->const_buffer && newFP->const_buffer->size < size) {
- dri_bo_unreference(newFP->const_buffer);
- newFP->const_buffer = NULL;
- }
-
- if (!newFP->const_buffer) {
- newFP->const_buffer = drm_intel_bo_alloc(intel->bufmgr,
- "fp_const_buffer",
- size, 64);
- }
- }
}
else if (target == GL_VERTEX_PROGRAM_ARB) {
struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
/**
- * Update the constant buffer surface.
+ * Update the surface state for a constant buffer.
+ * The constant buffer will be (re)allocated here if needed.
*/
-static void
+static dri_bo *
brw_update_constant_surface( GLcontext *ctx,
- const struct brw_fragment_program *fp )
+ GLuint surf,
+ dri_bo *const_buffer,
+ const struct gl_program_parameter_list *params)
{
struct brw_context *brw = brw_context(ctx);
struct brw_wm_surface_key key;
- const GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER;
- const GLuint numParams = fp->program.Base.Parameters->NumParameters;
+ struct intel_context *intel = &brw->intel;
+ const int size = params->NumParameters * 4 * sizeof(GLfloat);
+
+ /* free old const buffer if too small */
+ if (const_buffer && const_buffer->size < size) {
+ dri_bo_unreference(const_buffer);
+ const_buffer = NULL;
+ }
+
+ /* alloc new buffer if needed */
+ if (!const_buffer) {
+ const_buffer =
+ drm_intel_bo_alloc(intel->bufmgr, "vp/fp_const_buffer", size, 64);
+ }
memset(&key, 0, sizeof(key));
key.format = MESA_FORMAT_RGBA_FLOAT32;
key.internal_format = GL_RGBA;
- key.bo = fp->const_buffer;
-
+ key.bo = const_buffer;
key.depthmode = GL_NONE;
- key.pitch = numParams;
- key.width = numParams;
+ key.pitch = params->NumParameters;
+ key.width = params->NumParameters;
key.height = 1;
key.depth = 1;
key.cpp = 16;
if (brw->wm.surf_bo[surf] == NULL) {
brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key);
}
+
+ return const_buffer;
}
old_nr_surfaces = brw->wm.nr_surfaces;
brw->wm.nr_surfaces = MAX_DRAW_BUFFERS;
- /* Update surface for fragment shader constant buffer */
+ /* Update surface / buffer for vertex shader constant buffer */
{
- const GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER + 1;
- const struct brw_fragment_program *fp =
- brw_fragment_program_const(brw->fragment_program);
+ const GLuint surf = SURF_INDEX_VERT_CONST_BUFFER + 1;
+ struct brw_vertex_program *vp =
+ (struct brw_vertex_program *) brw->vertex_program;
+ vp->const_buffer =
+ brw_update_constant_surface(ctx,
+ SURF_INDEX_VERT_CONST_BUFFER,
+ vp->const_buffer,
+ vp->program.Base.Parameters);
- brw_update_constant_surface(ctx, fp);
brw->wm.nr_surfaces = surf + 1;
}
+ /* Update surface / buffer for fragment shader constant buffer */
+ {
+ const GLuint surf = SURF_INDEX_FRAG_CONST_BUFFER + 1;
+ struct brw_fragment_program *fp =
+ (struct brw_fragment_program *) brw->fragment_program;
+ fp->const_buffer =
+ brw_update_constant_surface(ctx,
+ SURF_INDEX_FRAG_CONST_BUFFER,
+ fp->const_buffer,
+ fp->program.Base.Parameters);
+
+ brw->wm.nr_surfaces = surf + 1;
+ }
/* Update surfaces for textures */
for (i = 0; i < BRW_MAX_TEX_UNIT; i++) {