nouveau: rework shader param handling

Conflicts:

	src/mesa/drivers/dri/nouveau/nouveau_shader_0.c
This commit is contained in:
Ben Skeggs
2007-01-30 12:33:00 +11:00
parent de0cf18b09
commit ede8017d2c
3 changed files with 110 additions and 47 deletions
@@ -126,15 +126,16 @@ nvsUpdateShader(GLcontext *ctx, nouveauShader *nvs)
/* Update state parameters */
plist = nvs->mesa.vp.Base.Parameters;
_mesa_load_state_parameters(ctx, plist);
for (i=0; i<plist->NumParameters; i++) {
for (i=0; i<nvs->param_high; i++) {
if (!nvs->params[i].in_use)
continue;
if (!nvs->on_hardware) {
/* if we've been kicked off the hardware there's no guarantee our
* consts are still there.. reupload them all
*/
nvs->func->UpdateConst(ctx, nvs, i);
} else if (plist->Parameters[i].Type == PROGRAM_STATE_VAR) {
if (!nvs->params[i].source_val) /* this is a workaround when consts aren't alloc'd from id=0.. */
continue;
} else if (nvs->params[i].source_val) {
/* update any changed state parameters */
if (!TEST_EQ_4V(nvs->params[i].val, nvs->params[i].source_val))
nvs->func->UpdateConst(ctx, nvs, i);
@@ -58,6 +58,8 @@ typedef struct _nouveauShader {
int vp_attrib_map[NVS_MAX_ATTRIBS];
struct {
GLboolean in_use;
GLfloat *source_val; /* NULL if invariant */
float val[4];
/* Hardware-specific tracking, currently only nv30_fragprog
@@ -66,6 +68,7 @@ typedef struct _nouveauShader {
int *hw_index;
int hw_index_cnt;
} params[NVS_MAX_CONSTS];
int param_high;
/* Pass-private data */
void *pass_rec;
+102 -43
View File
@@ -113,6 +113,10 @@ static nvsCond _tx_mesa_condmask[] = {
struct pass0_rec {
int nvs_ipos;
int next_temp;
int mesa_const_base;
int mesa_const_last;
int swzconst_done;
int swzconst_id;
nvsRegister const_half;
@@ -308,8 +312,8 @@ pass0_make_dst_reg(nvsPtr nvs, nvsRegister *reg,
static void
pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src)
{
struct pass0_rec *rec = nvs->pass_rec;
struct gl_program *mesa = (struct gl_program *)&nvs->mesa.vp.Base;
struct gl_program_parameter_list *p = mesa->Parameters;
int i;
*reg = nvr_unused;
@@ -332,34 +336,16 @@ pass0_make_src_reg(nvsPtr nvs, nvsRegister *reg, struct prog_src_register *src)
NVS_FR_UNKNOWN;
}
break;
/* All const types seem to get shoved into here, not really sure why */
case PROGRAM_STATE_VAR:
switch (p->Parameters[src->Index].Type) {
case PROGRAM_NAMED_PARAM:
case PROGRAM_CONSTANT:
nvs->params[src->Index].source_val = NULL;
COPY_4V(nvs->params[src->Index].val,
p->ParameterValues[src->Index]);
break;
case PROGRAM_STATE_VAR:
nvs->params[src->Index].source_val =
p->ParameterValues[src->Index];
break;
default:
fprintf(stderr, "Unknown parameter type %d\n",
p->Parameters[src->Index].Type);
assert(0);
break;
case PROGRAM_NAMED_PARAM:
case PROGRAM_CONSTANT:
reg->file = NVS_FILE_CONST;
reg->index = src->Index + rec->mesa_const_base;
reg->indexed = src->RelAddr;
if (reg->indexed) {
reg->addr_reg = 0;
reg->addr_comp = NVS_SWZ_X;
}
if (src->RelAddr) {
reg->indexed = 1;
reg->addr_reg = 0;
reg->addr_comp = NVS_SWZ_X;
} else
reg->indexed = 0;
reg->file = NVS_FILE_CONST;
reg->index = src->Index;
break;
case PROGRAM_TEMPORARY:
reg->file = NVS_FILE_TEMP;
@@ -568,7 +554,6 @@ pass0_emulate_instruction(nouveauShader *nvs,
nvsFunc *shader = nvs->func;
nvsRegister src[3], dest, temp;
nvsInstruction *nvsinst;
struct pass0_rec *rec = nvs->pass_rec;
unsigned int mask = pass0_make_mask(inst->DstReg.WriteMask);
int i, sat;
@@ -825,6 +810,73 @@ pass0_build_attrib_map(nouveauShader *nvs, struct gl_vertex_program *vp)
}
}
static void
pass0_prealloc_mesa_consts(nouveauShader *nvs)
{
struct pass0_rec *rec = nvs->pass_rec;
struct gl_program *prog = &nvs->mesa.vp.Base;
struct prog_instruction *inst = prog->Instructions;
struct gl_program_parameter_list *plist = prog->Parameters;
int i;
/*XXX: not a good idea, params->hw_index is malloc'd */
memset(nvs->params, 0x00, sizeof(nvs->params));
/* When doing relative addressing on constants, the hardware needs us
* to fill the "const id" field with a positive value. Determine the
* most negative index that is used so that all accesses to a
* mesa-provided constant can be rebased to a positive index.
*/
while (inst->Opcode != OPCODE_END) {
for (i=0; i<_mesa_num_inst_src_regs(inst->Opcode); i++) {
struct prog_src_register *src = &inst->SrcReg[i];
switch (src->File) {
case PROGRAM_STATE_VAR:
case PROGRAM_CONSTANT:
case PROGRAM_NAMED_PARAM:
if (src->RelAddr && src->Index < 0) {
int base = src->Index * -1;
if (rec->mesa_const_base < base)
rec->mesa_const_base = base;
}
break;
default:
break;
}
}
inst++;
}
/* Init all const tracking/alloc info from the parameter list, rather
* than doing it as we translate the program. Otherwise we can't get
* at the correct constant info when relative addressing is being used.
*/
rec->mesa_const_last = plist->NumParameters + rec->mesa_const_base;
nvs->param_high = rec->mesa_const_last;
for (i=0; i<plist->NumParameters; i++) {
int hw = rec->mesa_const_base + i;
switch (plist->Parameters[i].Type) {
case PROGRAM_NAMED_PARAM:
case PROGRAM_STATE_VAR:
nvs->params[hw].in_use = GL_TRUE;
nvs->params[hw].source_val = plist->ParameterValues[i];
COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]);
break;
case PROGRAM_CONSTANT:
nvs->params[hw].in_use = GL_TRUE;
nvs->params[hw].source_val = NULL;
COPY_4V(nvs->params[hw].val, plist->ParameterValues[i]);
break;
default:
assert(0);
break;
}
}
}
GLboolean
nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
{
@@ -835,12 +887,28 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
struct pass0_rec *rec;
int ret = GL_FALSE;
rec = CALLOC_STRUCT(pass0_rec);
if (!rec)
return GL_FALSE;
rec->next_temp = prog->NumTemporaries;
nvs->pass_rec = rec;
nvs->program_tree = (nvsFragmentHeader*)
pass0_create_subroutine(nvs, "program body");
if (!nvs->program_tree) {
FREE(rec);
return GL_FALSE;
}
switch (prog->Target) {
case GL_VERTEX_PROGRAM_ARB:
nvs->func = &nmesa->VPfunc;
if (vp->IsPositionInvariant)
_mesa_insert_mvp_code(ctx, vp);
pass0_prealloc_mesa_consts(nvs);
#if 0
if (IS_FIXEDFUNCTION_PROG && CLIP_PLANES_USED)
pass0_insert_ff_clip_planes();
@@ -853,29 +921,20 @@ nouveau_shader_pass0(GLcontext *ctx, nouveauShader *nvs)
if (fp->FogOption != GL_NONE)
_mesa_append_fog_code(ctx, fp);
pass0_prealloc_mesa_consts(nvs);
break;
default:
fprintf(stderr, "Unknown program type %d", prog->Target);
FREE(rec);
/* DESTROY TREE!! */
return GL_FALSE;
}
nvs->func->card_priv = &nvs->card_priv;
rec = CALLOC_STRUCT(pass0_rec);
if (rec) {
rec->next_temp = prog->NumTemporaries;
nvs->pass_rec = rec;
nvs->program_tree = (nvsFragmentHeader*)
pass0_create_subroutine(nvs, "program body");
if (nvs->program_tree) {
ret = pass0_translate_instructions(nvs,
0, 0,
nvs->program_tree);
/*XXX: if (!ret) DESTROY TREE!!! */
}
FREE(rec);
}
ret = pass0_translate_instructions(nvs, 0, 0, nvs->program_tree);
/*XXX: if (!ret) DESTROY TREE!!! */
FREE(rec);
return ret;
}