mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-02 20:58:04 +02:00
mesa: be smarter about allocating vert/frag program constants
Try to re-use constants/literals more often to make best use of the constant buffer space. See bug 21354.
This commit is contained in:
parent
71fb9d62ec
commit
9b678af796
1 changed files with 76 additions and 25 deletions
|
|
@ -563,6 +563,7 @@ struct var_cache
|
|||
* we take up with our state tokens or constants. Note that
|
||||
* this is _not_ the same as the number of param registers
|
||||
* we eventually use */
|
||||
GLuint swizzle; /**< swizzle to access this variable */
|
||||
struct var_cache *next;
|
||||
};
|
||||
|
||||
|
|
@ -581,6 +582,7 @@ var_cache_create (struct var_cache **va)
|
|||
(**va).param_binding_begin = ~0;
|
||||
(**va).param_binding_length = ~0;
|
||||
(**va).alias_binding = NULL;
|
||||
(**va).swizzle = SWIZZLE_XYZW;
|
||||
(**va).next = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -872,15 +874,16 @@ parse_signed_float (const GLubyte ** inst, struct arb_program *Program)
|
|||
* This picks out a constant value from the parsed array. The constant vector is r
|
||||
* returned in the *values array, which should be of length 4.
|
||||
*
|
||||
* \param values - The 4 component vector with the constant value in it
|
||||
* \param values - return the vector constant values.
|
||||
* \param size - returns the number elements in valuesOut [1..4]
|
||||
*/
|
||||
static GLvoid
|
||||
parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Program,
|
||||
GLboolean use)
|
||||
parse_constant(const GLubyte ** inst, GLfloat *values, GLint *size,
|
||||
struct arb_program *Program,
|
||||
GLboolean use)
|
||||
{
|
||||
GLuint components, i;
|
||||
|
||||
|
||||
switch (*(*inst)++) {
|
||||
case CONSTANT_SCALAR:
|
||||
if (use == GL_TRUE) {
|
||||
|
|
@ -893,7 +896,7 @@ parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Prog
|
|||
values[1] =
|
||||
values[2] = values[3] = parse_signed_float (inst, Program);
|
||||
}
|
||||
|
||||
*size = 1;
|
||||
break;
|
||||
case CONSTANT_VECTOR:
|
||||
values[0] = values[1] = values[2] = 0;
|
||||
|
|
@ -902,7 +905,12 @@ parse_constant (const GLubyte ** inst, GLfloat *values, struct arb_program *Prog
|
|||
for (i = 0; i < components; i++) {
|
||||
values[i] = parse_signed_float (inst, Program);
|
||||
}
|
||||
*size = 4;
|
||||
break;
|
||||
default:
|
||||
_mesa_problem(NULL, "unexpected case in parse_constant()");
|
||||
values[0] = 0.0F;
|
||||
*size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1816,7 +1824,6 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
|
|||
GLint idx;
|
||||
GLuint err = 0;
|
||||
gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
|
||||
GLfloat const_values[4];
|
||||
|
||||
GLubyte token = *(*inst)++;
|
||||
|
||||
|
|
@ -1908,18 +1915,31 @@ parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
|
|||
|
||||
case PARAM_CONSTANT:
|
||||
/* parsing something like {1.0, 2.0, 3.0, 4.0} */
|
||||
parse_constant (inst, const_values, Program, use);
|
||||
idx = _mesa_add_named_constant(Program->Base.Parameters,
|
||||
(char *) param_var->name,
|
||||
const_values, 4);
|
||||
if (param_var->param_binding_begin == ~0U)
|
||||
param_var->param_binding_begin = idx;
|
||||
param_var->param_binding_type = PROGRAM_STATE_VAR;
|
||||
/* Note: when we reference this parameter in an instruction later,
|
||||
* we'll check if it's really a constant/immediate and set the
|
||||
* instruction register type appropriately.
|
||||
*/
|
||||
param_var->param_binding_length++;
|
||||
{
|
||||
GLfloat const_values[4];
|
||||
GLint size;
|
||||
parse_constant(inst, const_values, &size, Program, use);
|
||||
if (param_var->name[0] == ' ') {
|
||||
/* this is an unnamed constant */
|
||||
idx = _mesa_add_unnamed_constant(Program->Base.Parameters,
|
||||
const_values, size,
|
||||
¶m_var->swizzle);
|
||||
}
|
||||
else {
|
||||
/* named parameter/constant */
|
||||
idx = _mesa_add_named_constant(Program->Base.Parameters,
|
||||
(char *) param_var->name,
|
||||
const_values, size);
|
||||
}
|
||||
if (param_var->param_binding_begin == ~0U)
|
||||
param_var->param_binding_begin = idx;
|
||||
param_var->param_binding_type = PROGRAM_STATE_VAR;
|
||||
/* Note: when we reference this parameter in an instruction later,
|
||||
* we'll check if it's really a constant/immediate and set the
|
||||
* instruction register type appropriately.
|
||||
*/
|
||||
param_var->param_binding_length++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -2428,6 +2448,9 @@ parse_swizzle_mask(const GLubyte ** inst, GLubyte *swizzle, GLint len)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 1)
|
||||
swizzle[1] = swizzle[2] = swizzle[3] = swizzle[0];
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2482,7 +2505,7 @@ static GLuint
|
|||
parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
|
||||
struct var_cache **vc_head,
|
||||
struct arb_program *Program,
|
||||
gl_register_file * File, GLint * Index,
|
||||
gl_register_file * File, GLint * Index, GLuint *swizzle,
|
||||
GLboolean *IsRelOffset )
|
||||
{
|
||||
struct var_cache *src;
|
||||
|
|
@ -2491,6 +2514,8 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
|
|||
|
||||
*IsRelOffset = 0;
|
||||
|
||||
*swizzle = SWIZZLE_XYZW; /* default */
|
||||
|
||||
/* And the binding for the src */
|
||||
switch (*(*inst)++) {
|
||||
case REGISTER_ATTRIB:
|
||||
|
|
@ -2546,6 +2571,7 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
|
|||
}
|
||||
|
||||
*Index = src->param_binding_begin + offset;
|
||||
*swizzle = src->swizzle;
|
||||
break;
|
||||
|
||||
case ARRAY_INDEX_RELATIVE:
|
||||
|
|
@ -2568,6 +2594,7 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
|
|||
/* And store it properly */
|
||||
*Index = src->param_binding_begin + rel_off;
|
||||
*IsRelOffset = 1;
|
||||
*swizzle = src->swizzle;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2579,6 +2606,7 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
|
|||
|
||||
*File = (gl_register_file) src->param_binding_type;
|
||||
*Index = src->param_binding_begin;
|
||||
*swizzle = src->swizzle;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
@ -2647,6 +2675,21 @@ parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
|
|||
}
|
||||
|
||||
|
||||
static GLuint
|
||||
swizzle_swizzle(GLuint baseSwizzle, const GLubyte swizzle[4])
|
||||
{
|
||||
GLuint i, swz, s[4];
|
||||
for (i = 0; i < 4; i++) {
|
||||
GLuint c = swizzle[i];
|
||||
if (c <= SWIZZLE_W)
|
||||
s[i] = GET_SWZ(baseSwizzle, c);
|
||||
else
|
||||
s[i] = c;
|
||||
}
|
||||
swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
|
||||
return swz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse vertex/fragment program vector source register.
|
||||
*/
|
||||
|
|
@ -2661,12 +2704,14 @@ parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst,
|
|||
GLubyte negateMask;
|
||||
GLubyte swizzle[4];
|
||||
GLboolean isRelOffset;
|
||||
GLuint baseSwizzle;
|
||||
|
||||
/* Grab the sign */
|
||||
negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
|
||||
|
||||
/* And the src reg */
|
||||
if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
|
||||
if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle,
|
||||
&isRelOffset))
|
||||
return 1;
|
||||
|
||||
/* finally, the swizzle */
|
||||
|
|
@ -2674,7 +2719,7 @@ parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst,
|
|||
|
||||
reg->File = file;
|
||||
reg->Index = index;
|
||||
reg->Swizzle = MAKE_SWIZZLE4(swizzle[0], swizzle[1], swizzle[2], swizzle[3]);
|
||||
reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle);
|
||||
reg->Negate = negateMask;
|
||||
reg->RelAddr = isRelOffset;
|
||||
return 0;
|
||||
|
|
@ -2695,12 +2740,14 @@ parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst,
|
|||
GLubyte negateMask;
|
||||
GLubyte swizzle[4];
|
||||
GLboolean isRelOffset;
|
||||
GLuint baseSwizzle;
|
||||
|
||||
/* Grab the sign */
|
||||
negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
|
||||
|
||||
/* And the src reg */
|
||||
if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &isRelOffset))
|
||||
if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle,
|
||||
&isRelOffset))
|
||||
return 1;
|
||||
|
||||
/* finally, the swizzle */
|
||||
|
|
@ -2708,7 +2755,7 @@ parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst,
|
|||
|
||||
reg->File = file;
|
||||
reg->Index = index;
|
||||
reg->Swizzle = (swizzle[0] << 0);
|
||||
reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle);
|
||||
reg->Negate = negateMask;
|
||||
reg->RelAddr = isRelOffset;
|
||||
return 0;
|
||||
|
|
@ -3019,8 +3066,10 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
|
|||
GLubyte negateMask;
|
||||
gl_register_file file;
|
||||
GLint index;
|
||||
GLuint baseSwizzle;
|
||||
|
||||
if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &rel))
|
||||
if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index,
|
||||
&baseSwizzle, &rel))
|
||||
return 1;
|
||||
parse_extended_swizzle_mask(inst, swizzle, &negateMask);
|
||||
fp->SrcReg[0].File = file;
|
||||
|
|
@ -3360,11 +3409,13 @@ parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
|
|||
GLboolean relAddr;
|
||||
gl_register_file file;
|
||||
GLint index;
|
||||
GLuint baseSwizzle;
|
||||
|
||||
if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
|
||||
return 1;
|
||||
|
||||
if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index, &relAddr))
|
||||
if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index,
|
||||
&baseSwizzle, &relAddr))
|
||||
return 1;
|
||||
parse_extended_swizzle_mask (inst, swizzle, &negateMask);
|
||||
vp->SrcReg[0].File = file;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue