From f5674b566e0da9406484cff4249297bd8c6cf445 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 20 Feb 2009 10:48:52 -0700 Subject: i965: var renaming, clean-up --- src/mesa/drivers/dri/i965/brw_program.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'src/mesa/drivers/dri/i965/brw_program.c') diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 0c86911044..774180c28c 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -94,7 +94,6 @@ static struct gl_program *brwNewProgram( GLcontext *ctx, static void brwDeleteProgram( GLcontext *ctx, struct gl_program *prog ) { - _mesa_delete_program( ctx, prog ); } @@ -110,30 +109,29 @@ static void brwProgramStringNotify( GLcontext *ctx, GLenum target, struct gl_program *prog ) { + struct brw_context *brw = brw_context(ctx); if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; - struct brw_context *brw = brw_context(ctx); - struct brw_fragment_program *p = (struct brw_fragment_program *)prog; - struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program; + struct brw_fragment_program *newFP = (struct brw_fragment_program *) prog; + struct brw_fragment_program *curFP = (struct brw_fragment_program *) brw->fragment_program; if (fprog->FogOption) { _mesa_append_fog_code(ctx, fprog); fprog->FogOption = GL_NONE; } - if (p == fp) + if (newFP == curFP) brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; - p->id = brw->program_id++; + newFP->id = brw->program_id++; } else if (target == GL_VERTEX_PROGRAM_ARB) { - struct brw_context *brw = brw_context(ctx); - struct brw_vertex_program *p = (struct brw_vertex_program *)prog; - struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program; - if (p == vp) + struct brw_vertex_program *newVP = (struct brw_vertex_program *) prog; + struct brw_vertex_program *curVP = (struct brw_vertex_program *) brw->vertex_program; + if (newVP == curVP) brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; - if (p->program.IsPositionInvariant) { - _mesa_insert_mvp_code(ctx, &p->program); + if (newVP->program.IsPositionInvariant) { + _mesa_insert_mvp_code(ctx, &newVP->program); } - p->id = brw->program_id++; + newVP->id = brw->program_id++; /* Also tell tnl about it: */ -- cgit v1.2.3 From 5cbd1170da0a902fdc9c460584bc503b0c4085a6 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Mar 2009 16:04:53 -0700 Subject: i965: avoid unnecessary calls to brw_wm_is_glsl() This function scans the shader to see if it has any GLSL features like conditionals and loops. Calling this during state validation is expensive. Just call it when the shader is given to the driver and save the result. There's some new/temporary assertions to be sure we don't get out of sync on this. --- src/mesa/drivers/dri/i965/brw_context.h | 1 + src/mesa/drivers/dri/i965/brw_program.c | 2 ++ src/mesa/drivers/dri/i965/brw_wm.c | 5 ++++- src/mesa/drivers/dri/i965/brw_wm_state.c | 6 +++++- 4 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/i965/brw_program.c') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 2e2eaf5721..af904ee6d6 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -164,6 +164,7 @@ struct brw_vertex_program { struct brw_fragment_program { struct gl_fragment_program program; GLuint id; /**< serial no. to identify frag progs, never re-used */ + GLboolean isGLSL; /**< really, any IF/LOOP/CONT/BREAK instructions */ }; diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 774180c28c..2894cce3d6 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -38,6 +38,7 @@ #include "brw_context.h" #include "brw_util.h" +#include "brw_wm.h" static void brwBindProgram( GLcontext *ctx, GLenum target, @@ -122,6 +123,7 @@ static void brwProgramStringNotify( GLcontext *ctx, if (newFP == curFP) brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM; newFP->id = brw->program_id++; + newFP->isGLSL = brw_wm_is_glsl(fprog); } else if (target == GL_VERTEX_PROGRAM_ARB) { struct brw_vertex_program *newVP = (struct brw_vertex_program *) prog; diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 879000644b..1645ca0b70 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -149,11 +149,14 @@ static void do_wm_prog( struct brw_context *brw, brw_init_compile(brw, &c->func); + /* temporary sanity check assertion */ + ASSERT(fp->isGLSL == brw_wm_is_glsl(&c->fp->program)); + /* * Shader which use GLSL features such as flow control are handled * differently from "simple" shaders. */ - if (brw_wm_is_glsl(&c->fp->program)) { + if (fp->isGLSL) { brw_wm_glsl_emit(brw, c); } else { diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c index f7ea756fb0..63fc8a004f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_state.c @@ -62,6 +62,7 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) { GLcontext *ctx = &brw->intel.ctx; const struct gl_fragment_program *fp = brw->fragment_program; + const struct brw_fragment_program *bfp = (struct brw_fragment_program *) fp; struct intel_context *intel = &brw->intel; memset(key, 0, sizeof(*key)); @@ -107,7 +108,10 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key) /* _NEW_COLOR */ key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled; - key->is_glsl = brw_wm_is_glsl(fp); + key->is_glsl = bfp->isGLSL; + + /* temporary sanity check assertion */ + ASSERT(bfp->isGLSL == brw_wm_is_glsl(fp)); /* XXX: This needs a flag to indicate when it changes. */ key->stats_wm = intel->stats_wm; -- cgit v1.2.3 From 9c781de015f32b2caadd5a6d999cc6885188a4a4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 10 Mar 2009 15:53:33 -0600 Subject: i965: use new cast wrappers --- src/mesa/drivers/dri/i965/brw_curbe.c | 8 +++++--- src/mesa/drivers/dri/i965/brw_program.c | 13 +++++++++---- src/mesa/drivers/dri/i965/brw_vs_constval.c | 4 ++-- 3 files changed, 16 insertions(+), 9 deletions(-) (limited to 'src/mesa/drivers/dri/i965/brw_program.c') diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 4bee54fba7..f90f72c7db 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -53,7 +53,7 @@ static void calculate_curbe_offsets( struct brw_context *brw ) GLuint nr_fp_regs = (brw->wm.prog_data->nr_params + 15) / 16; /* BRW_NEW_VERTEX_PROGRAM */ - struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program; + struct brw_vertex_program *vp = brw_vertex_program(brw->vertex_program); GLuint nr_vp_regs = (vp->program.Base.Parameters->NumParameters * 4 + 15) / 16; GLuint nr_clip_regs = 0; GLuint total_regs; @@ -174,8 +174,10 @@ static GLfloat fixed_plane[6][4] = { static void prepare_constant_buffer(struct brw_context *brw) { GLcontext *ctx = &brw->intel.ctx; - const struct brw_vertex_program *vp = (struct brw_vertex_program *)brw->vertex_program; - const struct brw_fragment_program *fp = (struct brw_fragment_program *)brw->fragment_program; + const struct brw_vertex_program *vp = + brw_vertex_program_const(brw->vertex_program); + const struct brw_fragment_program *fp = + brw_fragment_program_const(brw->fragment_program); const GLuint sz = brw->curbe.total_size; const GLuint bufsz = sz * 16 * sizeof(GLfloat); GLfloat *buf; diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 2894cce3d6..d90bd82038 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -113,8 +113,10 @@ static void brwProgramStringNotify( GLcontext *ctx, struct brw_context *brw = brw_context(ctx); if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; - struct brw_fragment_program *newFP = (struct brw_fragment_program *) prog; - struct brw_fragment_program *curFP = (struct brw_fragment_program *) brw->fragment_program; + struct brw_fragment_program *newFP = brw_fragment_program(fprog); + const struct brw_fragment_program *curFP = + brw_fragment_program_const(brw->fragment_program); + if (fprog->FogOption) { _mesa_append_fog_code(ctx, fprog); fprog->FogOption = GL_NONE; @@ -126,8 +128,11 @@ static void brwProgramStringNotify( GLcontext *ctx, newFP->isGLSL = brw_wm_is_glsl(fprog); } else if (target == GL_VERTEX_PROGRAM_ARB) { - struct brw_vertex_program *newVP = (struct brw_vertex_program *) prog; - struct brw_vertex_program *curVP = (struct brw_vertex_program *) brw->vertex_program; + struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog; + struct brw_vertex_program *newVP = brw_vertex_program(vprog); + const struct brw_vertex_program *curVP = + brw_vertex_program_const(brw->vertex_program); + if (newVP == curVP) brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM; if (newVP->program.IsPositionInvariant) { diff --git a/src/mesa/drivers/dri/i965/brw_vs_constval.c b/src/mesa/drivers/dri/i965/brw_vs_constval.c index 9977677fd7..d29eb17f8c 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_constval.c +++ b/src/mesa/drivers/dri/i965/brw_vs_constval.c @@ -170,8 +170,8 @@ static void calc_wm_input_sizes( struct brw_context *brw ) { GLcontext *ctx = &brw->intel.ctx; /* BRW_NEW_VERTEX_PROGRAM */ - struct brw_vertex_program *vp = - (struct brw_vertex_program *)brw->vertex_program; + const struct brw_vertex_program *vp = + brw_vertex_program_const(brw->vertex_program); /* BRW_NEW_INPUT_DIMENSIONS */ struct tracker t; GLuint insn; -- cgit v1.2.3 From 597cd5b94e4818679af1134d053541f3d2cfb80e Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 31 Mar 2009 17:06:22 -0600 Subject: i965: check-point commit of new constant buffer support Currently, shader constants are stored in the GRF (loaded from the CURBE prior to shader execution). This severly limits the number of constants and temps that we can support. This new code will support (practically) unlimited size constant buffers and free up registers in the GRF. We allocate a new buffer object for the constants and read them with "Read" messages/instructions. When only a small number of constants are used, we can still use the old method. The code works for fragment shaders only (and is actually disabled) for now. Need to do the same thing for vertex shaders and need to add the necessary code-gen to fetch the constants which are referenced by the shader instructions. --- src/mesa/drivers/dri/i965/brw_context.h | 17 ++- src/mesa/drivers/dri/i965/brw_curbe.c | 31 ++++++ src/mesa/drivers/dri/i965/brw_program.c | 20 ++++ src/mesa/drivers/dri/i965/brw_wm_glsl.c | 133 ++++++++++++++++++----- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 122 +++++++++++++++++++-- 5 files changed, 288 insertions(+), 35 deletions(-) (limited to 'src/mesa/drivers/dri/i965/brw_program.c') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index a020b621d6..01e07c967f 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -167,6 +167,9 @@ struct brw_fragment_program { struct gl_fragment_program program; 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; }; @@ -238,8 +241,16 @@ struct brw_vs_ouput_sizes { }; +/** Number of texture sampler units */ #define BRW_MAX_TEX_UNIT 16 -#define BRW_WM_MAX_SURF BRW_MAX_TEX_UNIT + MAX_DRAW_BUFFERS + +/** + * Size of our surface binding table. + * This contains pointers to the drawing surfaces and current texture + * objects and shader constant buffer (+1). + */ +#define BRW_WM_MAX_SURF (MAX_DRAW_BUFFERS + BRW_MAX_TEX_UNIT + 1) + enum brw_cache_id { BRW_CC_VP, @@ -513,8 +524,8 @@ struct brw_context /* BRW_NEW_CURBE_OFFSETS: */ struct { - GLuint wm_start; - GLuint wm_size; + GLuint wm_start; /**< pos of first wm const in CURBE buffer */ + GLuint wm_size; /**< number of float[4] consts, multiple of 16 */ GLuint clip_start; GLuint clip_size; GLuint vs_start; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index 545dedd34b..39a8610952 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -38,6 +38,7 @@ #include "shader/prog_parameter.h" #include "shader/prog_statevars.h" #include "intel_batchbuffer.h" +#include "intel_regions.h" #include "brw_context.h" #include "brw_defines.h" #include "brw_state.h" @@ -251,6 +252,7 @@ static void prepare_constant_buffer(struct brw_context *brw) _mesa_load_state_parameters(ctx, vp->program.Base.Parameters); + /* XXX just use a memcpy here */ for (i = 0; i < nr; i++) { const GLfloat *value = vp->program.Base.Parameters->ParameterValues[i]; buf[offset + i * 4 + 0] = value[0]; @@ -330,11 +332,40 @@ static void prepare_constant_buffer(struct brw_context *brw) } +/** + * Vertex/fragment shader constants are stored in a pseudo 1D texture. + * This function updates the constants in that buffer. + */ +static void +update_texture_constant_buffer(struct brw_context *brw) +{ + 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); + + assert(fp->const_buffer); + assert(fp->const_buffer->size >= size); + + /* copy constants into the buffer */ + if (size > 0) { + GLubyte *map; + dri_bo_map(fp->const_buffer, GL_TRUE); + map = fp->const_buffer->virtual; + memcpy(map, params->ParameterValues, size); + dri_bo_unmap(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); + BEGIN_BATCH(2, IGNORE_CLIPRECTS); if (sz == 0) { OUT_BATCH((CMD_CONST_BUFFER << 16) | (2 - 2)); diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index d90bd82038..457bc2fc7f 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -111,6 +111,8 @@ static void brwProgramStringNotify( GLcontext *ctx, struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); + struct intel_context *intel = &brw->intel; + if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; struct brw_fragment_program *newFP = brw_fragment_program(fprog); @@ -126,6 +128,24 @@ static void brwProgramStringNotify( GLcontext *ctx, 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; diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c index 67ba59c325..28ef84e4aa 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c +++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c @@ -192,28 +192,41 @@ static void prealloc_reg(struct brw_wm_compile *c) /* constants */ { const int nr_params = c->fp->program.Base.Parameters->NumParameters; - const struct gl_program_parameter_list *plist = - c->fp->program.Base.Parameters; - int index = 0; - - /* number of float constants */ - c->prog_data.nr_params = 4 * nr_params; - - /* loop over program constants (float[4]) */ - for (i = 0; i < nr_params; i++) { - /* loop over XYZW channels */ - for (j = 0; j < 4; j++, index++) { - reg = brw_vec1_grf(c->reg_index + index / 8, index % 8); - /* Save pointer to parameter/constant value. - * Constants will be copied in prepare_constant_buffer() - */ - c->prog_data.param[index] = &plist->ParameterValues[i][j]; - set_reg(c, PROGRAM_STATE_VAR, i, j, reg); - } - } - /* number of constant regs used (each reg is float[8]) */ - c->nr_creg = 2 * ((4 * nr_params + 15) / 16); - c->reg_index += c->nr_creg; + + if (1 /* XXX threshold: nr_params <= 8 */) { + const struct gl_program_parameter_list *plist = + c->fp->program.Base.Parameters; + int index = 0; + + /* number of float constants in CURBE */ + c->prog_data.nr_params = 4 * nr_params; + + /* loop over program constants (float[4]) */ + for (i = 0; i < nr_params; i++) { + /* loop over XYZW channels */ + for (j = 0; j < 4; j++, index++) { + reg = brw_vec1_grf(c->reg_index + index / 8, index % 8); + /* Save pointer to parameter/constant value. + * Constants will be copied in prepare_constant_buffer() + */ + c->prog_data.param[index] = &plist->ParameterValues[i][j]; + set_reg(c, PROGRAM_STATE_VAR, i, j, reg); + } + } + /* number of constant regs used (each reg is float[8]) */ + c->nr_creg = 2 * ((4 * nr_params + 15) / 16); + c->reg_index += c->nr_creg; + } + else { + /* number of float constants in CURBE */ + c->prog_data.nr_params = 0; + + /* When there's a lot of FP constanst we'll store them in a + * texture-like buffer instead of using the CURBE buffer. + * This means we won't use GRF registers for constants and we'll + * have to fetch constants with a dataport read. + */ + } } /* fragment shader inputs */ @@ -892,6 +905,19 @@ static void emit_add(struct brw_wm_compile *c, brw_set_saturate(p, 0); } +static void emit_arl(struct brw_wm_compile *c, + struct prog_instruction *inst) +{ + struct brw_compile *p = &c->func; + struct brw_reg src0, addr_reg; + brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0); + addr_reg = brw_uw8_reg(BRW_ARCHITECTURE_REGISTER_FILE, + BRW_ARF_ADDRESS, 0); + src0 = get_src_reg(c, &inst->SrcReg[0], 0); /* channel 0 */ + brw_MOV(p, addr_reg, src0); + brw_set_saturate(p, 0); +} + static void emit_sub(struct brw_wm_compile *c, struct prog_instruction *inst) { @@ -2331,9 +2357,10 @@ static void emit_txb(struct brw_wm_compile *c, struct brw_compile *p = &c->func; struct brw_reg dst[4], src[4], payload_reg; GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]; - GLuint i; + payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0); + for (i = 0; i < 4; i++) dst[i] = get_dst_reg(c, inst, i); for (i = 0; i < 4; i++) @@ -2372,13 +2399,13 @@ static void emit_txb(struct brw_wm_compile *c, 0); /* eot */ } + static void emit_tex(struct brw_wm_compile *c, struct prog_instruction *inst) { struct brw_compile *p = &c->func; struct brw_reg dst[4], src[4], payload_reg; GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit]; - GLuint msg_len; GLuint i, nr; GLuint emit; @@ -2419,7 +2446,7 @@ static void emit_tex(struct brw_wm_compile *c, } if (shadow) { - brw_MOV(p, brw_message_reg(5), brw_imm_f(0)); /* lod / bais */ + brw_MOV(p, brw_message_reg(5), brw_imm_f(0)); /* lod / bias */ brw_MOV(p, brw_message_reg(6), src[2]); /* ref value / R coord */ } @@ -2439,6 +2466,49 @@ static void emit_tex(struct brw_wm_compile *c, brw_MOV(p, dst[3], brw_imm_f(1.0)); } + +static void emit_get_constant(struct brw_context *brw, + struct brw_wm_compile *c, + struct prog_instruction *inst, + GLuint constIndex) +{ + struct brw_compile *p = &c->func; + struct brw_reg dst[4]; + GLuint i; + const int mark = mark_tmps( c ); + struct brw_reg writeback_reg[4]; + + /* XXX only need 1 temp reg??? */ + for (i = 0; i < 4; i++) { + writeback_reg[i] = alloc_tmp(c); + } + + for (i = 0; i < 4; i++) { + dst[i] = get_dst_reg(c, inst, i); + } + + /* Get float[4] vector from constant buffer */ + brw_dp_READ_4(p, + writeback_reg[0], /* first writeback dest */ + 1, /* msg_reg */ + GL_FALSE, /* rel addr? */ + 16 * constIndex, /* byte offset */ + BRW_WM_MAX_SURF - 1 /* surface, binding table index */ + ); + + /* Extract the four channel values, smear across dest registers */ + for (i = 0; i < 4; i++) { + /* extract 1 float from the writeback reg */ + struct brw_reg new_src = stride(writeback_reg[0], 0, 1, 0); + new_src.subnr = i * 4; + /* and smear it into the dest register */ + brw_MOV(p, dst[i], new_src); + } + + release_tmps( c, mark ); +} + + /** * Resolve subroutine calls after code emit is done. */ @@ -2504,6 +2574,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) case OPCODE_ADD: emit_add(c, inst); break; + case OPCODE_ARL: + emit_arl(c, inst); + break; case OPCODE_SUB: emit_sub(c, inst); break; @@ -2520,7 +2593,17 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c) emit_trunc(c, inst); break; case OPCODE_MOV: +#if 0 + /* test hook for new constant buffer code */ + if (inst->SrcReg[0].File == PROGRAM_UNIFORM) { + emit_get_constant(brw, c, inst, inst->SrcReg[0].Index); + } + else { + emit_mov(c, inst); + } +#else emit_mov(c, inst); +#endif break; case OPCODE_DP3: emit_dp3(c, inst); 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 1fc537ca20..e7d55d5dbd 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -33,6 +33,7 @@ #include "main/mtypes.h" #include "main/texformat.h" #include "main/texstore.h" +#include "shader/prog_parameter.h" #include "intel_mipmap_tree.h" #include "intel_batchbuffer.h" @@ -287,6 +288,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) struct intel_texture_object *intelObj = intel_texture_object(tObj); struct gl_texture_image *firstImage = tObj->Image[0][intelObj->firstLevel]; struct brw_wm_surface_key key; + const GLuint j = MAX_DRAW_BUFFERS + unit; memset(&key, 0, sizeof(key)); @@ -313,16 +315,111 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit ) key.cpp = intelObj->mt->cpp; key.tiling = intelObj->mt->region->tiling; - dri_bo_unreference(brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS]); - brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, - &key, sizeof(key), - &key.bo, key.bo ? 1 : 0, - NULL); - if (brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] == NULL) { - brw->wm.surf_bo[unit + MAX_DRAW_BUFFERS] = brw_create_texture_surface(brw, &key); + dri_bo_unreference(brw->wm.surf_bo[j]); + brw->wm.surf_bo[j] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, key.bo ? 1 : 0, + NULL); + if (brw->wm.surf_bo[j] == NULL) { + brw->wm.surf_bo[j] = brw_create_texture_surface(brw, &key); } } + + +/** + * Create the constant buffer surface. Fragment shader constanst will be + * read from this buffer with Data Port Read instructions/messages. + */ +static dri_bo * +brw_create_constant_surface( struct brw_context *brw, + struct brw_wm_surface_key *key ) +{ + const GLint w = key->width - 1; + struct brw_surface_state surf; + dri_bo *bo; + + memset(&surf, 0, sizeof(surf)); + + surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW; + surf.ss0.surface_type = BRW_SURFACE_BUFFER; + surf.ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT; + + /* This is ok for all textures with channel width 8bit or less: + */ + assert(key->bo); + if (key->bo) + surf.ss1.base_addr = key->bo->offset; /* reloc */ + else + surf.ss1.base_addr = key->offset; + + surf.ss2.width = w & 0x7f; /* bits 6:0 of size or width */ + surf.ss2.height = (w >> 7) & 0x1fff; /* bits 19:7 of size or width */ + surf.ss3.depth = (w >> 20) & 0x7f; /* bits 26:20 of size or width */ + surf.ss3.pitch = (key->pitch * key->cpp) - 1; + brw_set_surface_tiling(&surf, key->tiling); + + bo = brw_upload_cache(&brw->cache, BRW_SS_SURFACE, + key, sizeof(*key), + &key->bo, key->bo ? 1 : 0, + &surf, sizeof(surf), + NULL, NULL); + + if (key->bo) { + /* Emit relocation to surface contents */ + dri_bo_emit_reloc(bo, + I915_GEM_DOMAIN_SAMPLER, 0, + 0, + offsetof(struct brw_surface_state, ss1), + key->bo); + } + + return bo; +} + + +/** + * Update the constant buffer surface. + */ +static void +brw_update_constant_surface( GLcontext *ctx, + const struct brw_fragment_program *fp ) +{ + struct brw_context *brw = brw_context(ctx); + struct brw_wm_surface_key key; + const GLuint j = BRW_WM_MAX_SURF - 1; + const GLuint numParams = fp->program.Base.Parameters->NumParameters; + + memset(&key, 0, sizeof(key)); + + key.format = MESA_FORMAT_RGBA_FLOAT32; + key.internal_format = GL_RGBA; + key.bo = fp->const_buffer; + + key.depthmode = GL_NONE; + key.pitch = numParams; + key.width = numParams; + key.height = 1; + key.depth = 1; + key.cpp = 16; + + /* + printf("%s:\n", __FUNCTION__); + printf(" width %d height %d depth %d cpp %d pitch %d\n", + key.width, key.height, key.depth, key.cpp, key.pitch); + */ + + dri_bo_unreference(brw->wm.surf_bo[j]); + brw->wm.surf_bo[j] = brw_search_cache(&brw->cache, BRW_SS_SURFACE, + &key, sizeof(key), + &key.bo, key.bo ? 1 : 0, + NULL); + if (brw->wm.surf_bo[j] == NULL) { + brw->wm.surf_bo[j] = brw_create_constant_surface(brw, &key); + } +} + + /** * Sets up a surface state structure to point at the given region. * While it is only used for the front/back buffer currently, it should be @@ -514,6 +611,17 @@ static void prepare_wm_surfaces(struct brw_context *brw ) } } + /* Update surface for fragment shader constant buffer */ + { + const GLuint j = BRW_WM_MAX_SURF - 1; + const struct brw_fragment_program *fp = + brw_fragment_program_const(brw->fragment_program); + + brw_update_constant_surface(ctx, fp); + brw->wm.nr_surfaces = j + 1; + } + + dri_bo_unreference(brw->wm.bind_bo); brw->wm.bind_bo = brw_wm_get_binding_table(brw); -- cgit v1.2.3 From 3163ea145309f1f8e103cc880ea40c61af5fb5cd Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 10:33:08 -0600 Subject: i965: free shader's constant buffer in brwDeleteProgram() Fixes mem leak observed with texcombine test. --- src/mesa/drivers/dri/i965/brw_program.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/mesa/drivers/dri/i965/brw_program.c') diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index 457bc2fc7f..fbf1ddd1e3 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -95,6 +95,12 @@ 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 *fprog = (struct gl_fragment_program *) prog; + struct brw_fragment_program *brw_fprog = brw_fragment_program(fprog); + dri_bo_unreference(brw_fprog->const_buffer); + } + _mesa_delete_program( ctx, prog ); } -- cgit v1.2.3 From 20f3497e4b6756e330f7b3f54e8acaa1d6c92052 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 9 Apr 2009 18:37:03 -0600 Subject: i965: re-org of some of the new constant buffer code Plus, begin the new code for vertex shader const buffers. --- src/mesa/drivers/dri/i965/brw_context.h | 4 +- src/mesa/drivers/dri/i965/brw_curbe.c | 46 ++++++++++++------ src/mesa/drivers/dri/i965/brw_program.c | 18 ------- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 61 ++++++++++++++++++------ 4 files changed, 81 insertions(+), 48 deletions(-) (limited to 'src/mesa/drivers/dri/i965/brw_program.c') diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index c6e15c8914..6a9252d037 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -159,6 +159,7 @@ struct brw_state_flags { struct brw_vertex_program { struct gl_vertex_program program; GLuint id; + dri_bo *const_buffer; /** Program constant buffer/surface */ }; @@ -168,8 +169,7 @@ struct brw_fragment_program { 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 */ }; diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c index a6bfb7507e..08b602a5ab 100644 --- a/src/mesa/drivers/dri/i965/brw_curbe.c +++ b/src/mesa/drivers/dri/i965/brw_curbe.c @@ -333,37 +333,55 @@ static void prepare_constant_buffer(struct brw_context *brw) /** - * 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) { diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index fbf1ddd1e3..cc65157259 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -134,24 +134,6 @@ static void brwProgramStringNotify( GLcontext *ctx, 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; 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 0fb2bdacef..40d6c38f4f 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -379,26 +379,40 @@ brw_create_constant_surface( struct brw_context *brw, /** - * 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; @@ -417,6 +431,8 @@ brw_update_constant_surface( GLcontext *ctx, if (brw->wm.surf_bo[surf] == NULL) { brw->wm.surf_bo[surf] = brw_create_constant_surface(brw, &key); } + + return const_buffer; } @@ -587,16 +603,33 @@ static void prepare_wm_surfaces(struct brw_context *brw ) 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++) { -- cgit v1.2.3 From 4e96c8196934be4fe09f82e2fcd7e776a7553479 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 10 Apr 2009 13:32:04 -0600 Subject: i965: remove unused var --- src/mesa/drivers/dri/i965/brw_program.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/drivers/dri/i965/brw_program.c') diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index cc65157259..bac69187c1 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -117,7 +117,6 @@ static void brwProgramStringNotify( GLcontext *ctx, struct gl_program *prog ) { struct brw_context *brw = brw_context(ctx); - struct intel_context *intel = &brw->intel; if (target == GL_FRAGMENT_PROGRAM_ARB) { struct gl_fragment_program *fprog = (struct gl_fragment_program *) prog; -- cgit v1.2.3