mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
r300: Cleanup fragment program constant allocation, share constants
The constant/parameter allocation was significantly simplified, removing one unnecessary copy operation of parameters. The dirty state tracking is unchanged and far from optimal, since all state is always re-fetched. Constants and parameters are now emitted only once, which significantly reduces the resource pressure on larger programs.
This commit is contained in:
parent
5a65478783
commit
61821a41c0
2 changed files with 62 additions and 74 deletions
|
|
@ -767,23 +767,21 @@ struct r300_fragment_program {
|
|||
int tex_offset;
|
||||
int tex_end;
|
||||
|
||||
/* Hardware constants */
|
||||
GLfloat constant[PFS_NUM_CONST_REGS][4];
|
||||
/* Hardware constants.
|
||||
* Contains a pointer to the value. The destination of the pointer
|
||||
* is supposed to be updated when GL state changes.
|
||||
* Typically, this is either a pointer into
|
||||
* gl_program_parameter_list::ParameterValues, or a pointer to a
|
||||
* global constant (e.g. for sin/cos-approximation)
|
||||
*/
|
||||
const GLfloat* constant[PFS_NUM_CONST_REGS];
|
||||
int const_nr;
|
||||
|
||||
/* Tracked parameters */
|
||||
struct {
|
||||
int idx; /* hardware index */
|
||||
GLfloat *values; /* pointer to values */
|
||||
} param[PFS_NUM_CONST_REGS];
|
||||
int param_nr;
|
||||
GLboolean params_uptodate;
|
||||
|
||||
int max_temp_idx;
|
||||
|
||||
/* the index of the sin constant is stored here */
|
||||
GLint const_sin[2];
|
||||
|
||||
|
||||
GLuint optimization;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -468,47 +468,39 @@ static void free_temp(struct r300_fragment_program *rp, GLuint r)
|
|||
}
|
||||
}
|
||||
|
||||
static GLuint emit_param4fv(struct r300_fragment_program *rp,
|
||||
GLfloat *values)
|
||||
{
|
||||
GLuint r = undef;
|
||||
GLuint index;
|
||||
int pidx;
|
||||
|
||||
pidx = rp->param_nr++;
|
||||
index = rp->const_nr++;
|
||||
if (pidx >= PFS_NUM_CONST_REGS || index >= PFS_NUM_CONST_REGS) {
|
||||
ERROR("Out of const/param slots!\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
rp->param[pidx].idx = index;
|
||||
rp->param[pidx].values = values;
|
||||
rp->params_uptodate = GL_FALSE;
|
||||
|
||||
REG_SET_TYPE(r, REG_TYPE_CONST);
|
||||
REG_SET_INDEX(r, index);
|
||||
REG_SET_VALID(r, GL_TRUE);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit a hardware constant/parameter.
|
||||
*
|
||||
* \p cp Stable pointer to an array of 4 floats.
|
||||
* The pointer must be stable in the sense that it remains to be valid
|
||||
* and hold the contents of the constant/parameter throughout the lifetime
|
||||
* of the fragment program (actually, up until the next time the fragment
|
||||
* program is translated).
|
||||
*/
|
||||
static GLuint emit_const4fv(struct r300_fragment_program *rp, const GLfloat* cp)
|
||||
{
|
||||
GLuint r = undef;
|
||||
GLuint index;
|
||||
GLuint reg = undef;
|
||||
int index;
|
||||
|
||||
index = rp->const_nr++;
|
||||
if (index >= PFS_NUM_CONST_REGS) {
|
||||
ERROR("Out of hw constants!\n");
|
||||
return r;
|
||||
for(index = 0; index < rp->const_nr; ++index) {
|
||||
if (rp->constant[index] == cp)
|
||||
break;
|
||||
}
|
||||
|
||||
COPY_4V(rp->constant[index], cp);
|
||||
if (index >= rp->const_nr) {
|
||||
if (index >= PFS_NUM_CONST_REGS) {
|
||||
ERROR("Out of hw constants!\n");
|
||||
return reg;
|
||||
}
|
||||
|
||||
REG_SET_TYPE(r, REG_TYPE_CONST);
|
||||
REG_SET_INDEX(r, index);
|
||||
REG_SET_VALID(r, GL_TRUE);
|
||||
return r;
|
||||
rp->const_nr++;
|
||||
rp->constant[index] = cp;
|
||||
}
|
||||
|
||||
REG_SET_TYPE(reg, REG_TYPE_CONST);
|
||||
REG_SET_INDEX(reg, index);
|
||||
REG_SET_VALID(reg, GL_TRUE);
|
||||
return reg;
|
||||
}
|
||||
|
||||
static inline GLuint negate(GLuint r)
|
||||
|
|
@ -762,16 +754,16 @@ static GLuint t_src(struct r300_fragment_program *rp,
|
|||
REG_SET_TYPE(r, REG_TYPE_INPUT);
|
||||
break;
|
||||
case PROGRAM_LOCAL_PARAM:
|
||||
r = emit_param4fv(rp,
|
||||
r = emit_const4fv(rp,
|
||||
rp->mesa_program.Base.LocalParams[fpsrc.Index]);
|
||||
break;
|
||||
case PROGRAM_ENV_PARAM:
|
||||
r = emit_param4fv(rp,
|
||||
r = emit_const4fv(rp,
|
||||
rp->ctx->FragmentProgram.Parameters[fpsrc.Index]);
|
||||
break;
|
||||
case PROGRAM_STATE_VAR:
|
||||
case PROGRAM_NAMED_PARAM:
|
||||
r = emit_param4fv(rp,
|
||||
r = emit_const4fv(rp,
|
||||
rp->mesa_program.Base.Parameters->ParameterValues[fpsrc.Index]);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -1393,22 +1385,27 @@ static GLuint get_attrib(struct r300_fragment_program *rp, GLuint attr)
|
|||
}
|
||||
#endif
|
||||
|
||||
static GLfloat SinCosConsts[2][4] = {
|
||||
{
|
||||
1.273239545, // 4/PI
|
||||
-0.405284735, // -4/(PI*PI)
|
||||
3.141592654, // PI
|
||||
0.2225 // weight
|
||||
},
|
||||
{
|
||||
0.75,
|
||||
0.0,
|
||||
0.159154943, // 1/(2*PI)
|
||||
6.283185307 // 2*PI
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static void make_sin_const(struct r300_fragment_program *rp)
|
||||
{
|
||||
if(rp->const_sin[0] == -1){
|
||||
GLfloat cnstv[4];
|
||||
|
||||
cnstv[0] = 1.273239545; // 4/PI
|
||||
cnstv[1] =-0.405284735; // -4/(PI*PI)
|
||||
cnstv[2] = 3.141592654; // PI
|
||||
cnstv[3] = 0.2225; // weight
|
||||
rp->const_sin[0] = emit_const4fv(rp, cnstv);
|
||||
|
||||
cnstv[0] = 0.75;
|
||||
cnstv[1] = 0.0;
|
||||
cnstv[2] = 0.159154943; // 1/(2*PI)
|
||||
cnstv[3] = 6.283185307; // 2*PI
|
||||
rp->const_sin[1] = emit_const4fv(rp, cnstv);
|
||||
if(rp->const_sin[0] == -1) {
|
||||
rp->const_sin[0] = emit_const4fv(rp, SinCosConsts[0]);
|
||||
rp->const_sin[1] = emit_const4fv(rp, SinCosConsts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1434,6 +1431,8 @@ static void make_sin_const(struct r300_fragment_program *rp)
|
|||
* emit_arith is a bit too conservative because it doesn't understand
|
||||
* partial writes to the vector component.
|
||||
*/
|
||||
static const GLfloat LitConst[4] = { 127.999999, 127.999999, 127.999999, -127.999999 };
|
||||
|
||||
static void emit_lit(struct r300_fragment_program *rp,
|
||||
GLuint dest,
|
||||
int mask,
|
||||
|
|
@ -1441,12 +1440,11 @@ static void emit_lit(struct r300_fragment_program *rp,
|
|||
int flags)
|
||||
{
|
||||
COMPILE_STATE;
|
||||
static const GLfloat cnstv[4] = { 127.999999, 127.999999, 127.999999, -127.999999 };
|
||||
GLuint cnst;
|
||||
int needTemporary;
|
||||
GLuint temp;
|
||||
|
||||
cnst = emit_const4fv(rp, cnstv);
|
||||
cnst = emit_const4fv(rp, LitConst);
|
||||
|
||||
needTemporary = 0;
|
||||
if ((mask & WRITEMASK_XYZW) != WRITEMASK_XYZW) {
|
||||
|
|
@ -2123,8 +2121,6 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp)
|
|||
rp->cur_node = 0;
|
||||
rp->first_node_has_tex = 0;
|
||||
rp->const_nr = 0;
|
||||
rp->param_nr = 0;
|
||||
rp->params_uptodate = GL_FALSE;
|
||||
rp->max_temp_idx = 0;
|
||||
rp->node[0].alu_end = -1;
|
||||
rp->node[0].tex_end = -1;
|
||||
|
|
@ -2231,16 +2227,10 @@ static void init_program(r300ContextPtr r300, struct r300_fragment_program *rp)
|
|||
static void update_params(struct r300_fragment_program *rp)
|
||||
{
|
||||
struct gl_fragment_program *mp = &rp->mesa_program;
|
||||
int i;
|
||||
|
||||
/* Ask Mesa nicely to fill in ParameterValues for us */
|
||||
if (rp->param_nr)
|
||||
if (mp->Base.Parameters)
|
||||
_mesa_load_state_parameters(rp->ctx, mp->Base.Parameters);
|
||||
|
||||
for (i=0;i<rp->param_nr;i++)
|
||||
COPY_4V(rp->constant[rp->param[i].idx], rp->param[i].values);
|
||||
|
||||
rp->params_uptodate = GL_TRUE;
|
||||
}
|
||||
|
||||
void r300_translate_fragment_shader(r300ContextPtr r300, struct r300_fragment_program *rp)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue