aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2009-04-01 13:36:48 -0600
committerBrian Paul <[email protected]>2009-04-03 09:07:04 -0600
commit1e299ff828e808cbb1d92d9fedd528a3a8a3609e (patch)
treed11f0478fb668b89331bf51c432658d3bb6b11f9 /src/mesa/drivers
parent30adf0518168ded9c7f519a7c772cab728852b1f (diff)
i965: another checkpoint commit of new constant buffer support
Everything is in place now for using a true constant buffer for GLSL fragment shaders. Still some bugs to find though.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h8
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c172
2 files changed, 115 insertions, 65 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index 98c22121ec1..d0ab3bdc65f 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -253,6 +253,14 @@ struct brw_wm_compile {
GLuint tmp_index;
GLuint tmp_max;
GLuint subroutines[BRW_WM_MAX_SUBROUTINE];
+
+ /** using a real constant buffer? */
+ GLboolean use_const_buffer;
+ /** we may need up to 3 constants per instruction (if use_const_buffer) */
+ struct {
+ GLint index;
+ struct brw_reg reg;
+ } current_const[3];
};
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 41db3a805b7..01d1f7f0c2d 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -193,7 +193,19 @@ static void prealloc_reg(struct brw_wm_compile *c)
{
const int nr_params = c->fp->program.Base.Parameters->NumParameters;
- if (1 /* XXX threshold: nr_params <= 8 */) {
+ /* use a real constant buffer, or just use a section of the GRF? */
+ c->use_const_buffer = GL_FALSE; /* (nr_params > 8);*/
+ /*printf("USE CONST BUFFER? %d\n", c->use_const_buffer);*/
+
+ if (c->use_const_buffer) {
+ /* We'll use a real constant buffer and fetch constants from
+ * it with a dataport read message.
+ */
+
+ /* number of float constants in CURBE */
+ c->prog_data.nr_params = 0;
+ }
+ else {
const struct gl_program_parameter_list *plist =
c->fp->program.Base.Parameters;
int index = 0;
@@ -217,16 +229,6 @@ static void prealloc_reg(struct brw_wm_compile *c)
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 */
@@ -247,6 +249,49 @@ static void prealloc_reg(struct brw_wm_compile *c)
c->reg_index++;
c->stack = brw_uw16_reg(BRW_GENERAL_REGISTER_FILE, c->reg_index, 0);
c->reg_index += 2;
+
+ /* An instruction may reference up to three constants.
+ * They'll be found in these registers.
+ * XXX alloc these on demand!
+ */
+ if (c->use_const_buffer) {
+ c->current_const[0].reg = alloc_tmp(c);
+ c->current_const[1].reg = alloc_tmp(c);
+ c->current_const[2].reg = alloc_tmp(c);
+ }
+ /*printf("AFTER PRE_ALLOC, reg_index = %d\n", c->reg_index);*/
+}
+
+
+/**
+ * Check if any of the instruction's src registers are constants, uniforms,
+ * or statevars. If so, fetch any constants that we don't already have in
+ * the three GRF slots.
+ */
+static void fetch_constants(struct brw_wm_compile *c,
+ const struct prog_instruction *inst)
+{
+ struct brw_compile *p = &c->func;
+ GLuint i;
+
+ /* loop over instruction src regs */
+ for (i = 0; i < 3; i++) {
+ const struct prog_src_register *src = &inst->SrcReg[i];
+ if (src->File == PROGRAM_STATE_VAR ||
+ src->File == PROGRAM_UNIFORM) {
+ if (c->current_const[i].index != src->Index) {
+ /* need to fetch the constant now */
+ brw_dp_READ_4(p,
+ c->current_const[i].reg, /* writeback dest */
+ 1, /* msg_reg */
+ src->RelAddr, /* relative indexing? */
+ 16 * src->Index, /* byte offset */
+ BRW_WM_MAX_SURF - 1 /* binding table index */
+ );
+ c->current_const[i].index = src->Index;
+ }
+ }
+ }
}
@@ -263,6 +308,43 @@ static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
}
+static struct brw_reg
+get_src_reg_const(struct brw_wm_compile *c,
+ const struct prog_instruction *inst,
+ GLuint srcRegIndex, GLuint component)
+{
+ /* We should have already fetched the constant from the constant
+ * buffer in fetch_constants(). Now we just have to return a
+ * register description that extracts the needed component and
+ * smears it across all eight vector components.
+ */
+ const struct prog_src_register *src = &inst->SrcReg[srcRegIndex];
+ struct brw_reg const_reg;
+
+ assert(srcRegIndex < 3);
+ assert(c->current_const[srcRegIndex].index != -1);
+ const_reg = c->current_const[srcRegIndex].reg;
+
+ /*
+ printf("get const reg %d in slot %d, comp %d\n",
+ c->current_const[srcRegIndex].index,
+ srcRegIndex,
+ component);
+ */
+
+ /* extract desired float from the const_reg, and smear */
+ const_reg = stride(const_reg, 0, 1, 0);
+ const_reg.subnr = component * 4;
+
+ if (src->NegateBase)
+ const_reg = negate(const_reg);
+ if (src->Abs)
+ const_reg = brw_abs(const_reg);
+
+ return const_reg;
+}
+
+
/**
* Convert Mesa src register to brw register.
*/
@@ -274,8 +356,16 @@ static struct brw_reg get_src_reg(struct brw_wm_compile *c,
const GLuint nr = 1;
const GLuint component = GET_SWZ(src->Swizzle, channel);
- return get_reg(c, src->File, src->Index, component, nr,
- src->NegateBase, src->Abs);
+ if (c->use_const_buffer &&
+ (src->File == PROGRAM_STATE_VAR ||
+ src->File == PROGRAM_UNIFORM)) {
+ return get_src_reg_const(c, inst, srcRegIndex, component);
+ }
+ else {
+ /* other type of source register */
+ return get_reg(c, src->File, src->Index, component, nr,
+ src->NegateBase, src->Abs);
+ }
}
@@ -2473,48 +2563,6 @@ static void emit_tex(struct brw_wm_compile *c,
}
-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.
*/
@@ -2546,6 +2594,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
else
brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+ /* fetch any constants that this instruction needs */
+ if (c->use_const_buffer)
+ fetch_constants(c, inst);
+
switch (inst->Opcode) {
case WM_PIXELXY:
emit_pixel_xy(c, inst);
@@ -2599,17 +2651,7 @@ 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);