static struct prog_src_register search_or_add_const4f( struct brw_wm_compile *c, GLfloat s0, GLfloat s1, GLfloat s2, GLfloat s3) { struct gl_program_parameter_list *paramList = c->fp->program.Base.Parameters; GLfloat values[4]; GLuint idx; GLuint swizzle; values[0] = s0; values[1] = s1; values[2] = s2; values[3] = s3; /* Have to search, otherwise multiple compilations will each grow * the parameter list. */ for (idx = 0; idx < paramList->NumParameters; idx++) { if (paramList->Parameters[idx].Type == PROGRAM_CONSTANT && memcmp(paramList->ParameterValues[idx], values, sizeof(values)) == 0) /* XXX: this mimics the mesa bug which puts all constants and * parameters into the "PROGRAM_STATE_VAR" category: */ return src_reg(PROGRAM_STATE_VAR, idx); } idx = _mesa_add_unnamed_constant( paramList, values, 4, &swizzle ); assert(swizzle == SWIZZLE_NOOP); /* Need to handle swizzle in reg setup */ return src_reg(PROGRAM_STATE_VAR, idx); }
/** * "Post-process" a GPU program. This is intended to be used for debugging. * Example actions include no-op'ing instructions or changing instruction * behaviour. */ void _mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog) { static const GLfloat white[4] = { 0.5, 0.5, 0.5, 0.5 }; GLuint i; GLuint whiteSwizzle; GLint whiteIndex = _mesa_add_unnamed_constant(prog->Parameters, (gl_constant_value *) white, 4, &whiteSwizzle); (void) whiteIndex; for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; const GLuint n = _mesa_num_inst_src_regs(inst->Opcode); (void) n; if (_mesa_is_tex_instruction(inst->Opcode)) { #if 0 /* replace TEX/TXP/TXB with MOV */ inst->Opcode = OPCODE_MOV; inst->DstReg.WriteMask = WRITEMASK_XYZW; inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; inst->SrcReg[0].Negate = NEGATE_NONE; #endif #if 0 /* disable shadow texture mode */ inst->TexShadow = 0; #endif } if (inst->Opcode == OPCODE_TXP) { #if 0 inst->Opcode = OPCODE_MOV; inst->DstReg.WriteMask = WRITEMASK_XYZW; inst->SrcReg[0].File = PROGRAM_CONSTANT; inst->SrcReg[0].Index = whiteIndex; inst->SrcReg[0].Swizzle = SWIZZLE_XYZW; inst->SrcReg[0].Negate = NEGATE_NONE; #endif #if 0 inst->TexShadow = 0; #endif #if 0 inst->Opcode = OPCODE_TEX; inst->TexShadow = 0; #endif } } }
static struct prog_src_register src_reg_for_vec4(struct gl_program *prog, const float *val) { struct prog_src_register src; unsigned swiz; memset(&src, 0, sizeof(src)); src.File = PROGRAM_CONSTANT; src.Index = _mesa_add_unnamed_constant(prog->Parameters, (gl_constant_value *) val, 4, &swiz); src.Swizzle = swiz; return src; }
static struct ureg register_const4f( struct tnl_program *p, GLfloat s0, GLfloat s1, GLfloat s2, GLfloat s3) { GLfloat values[4]; GLint idx; GLuint swizzle; values[0] = s0; values[1] = s1; values[2] = s2; values[3] = s3; idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, &swizzle ); ASSERT(swizzle == SWIZZLE_NOOP); return make_ureg(PROGRAM_CONSTANT, idx); }
static struct ureg register_const4f( struct tnl_program *p, GLfloat s0, GLfloat s1, GLfloat s2, GLfloat s3) { GLfloat values[4]; GLint idx; GLuint swizzle; values[0] = s0; values[1] = s1; values[2] = s2; values[3] = s3; idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4, &swizzle); /* XXX what about swizzle? */ return make_ureg(PROGRAM_STATE_VAR, idx); }
/** * Parse a vector source (register, constant, etc): * <vectorSrc> ::= <absVectorSrc> * | <baseVectorSrc> * <absVectorSrc> ::= <negate> "|" <baseVectorSrc> "|" */ static GLboolean Parse_VectorSrc(struct parse_state *parseState, struct prog_src_register *srcReg) { GLfloat sign = 1.0F; GLubyte token[100]; GLint idx; GLuint negateBase, negateAbs; /* * First, take care of +/- and absolute value stuff. */ if (Parse_String(parseState, "-")) sign = -1.0F; else if (Parse_String(parseState, "+")) sign = +1.0F; if (Parse_String(parseState, "|")) { srcReg->Abs = GL_TRUE; negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; if (Parse_String(parseState, "-")) negateBase = NEGATE_XYZW; else if (Parse_String(parseState, "+")) negateBase = NEGATE_NONE; else negateBase = NEGATE_NONE; } else { srcReg->Abs = GL_FALSE; negateAbs = NEGATE_NONE; negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; } srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; /* This should be the real src vector/register name */ if (!Peek_Token(parseState, token)) RETURN_ERROR; /* Src reg can be Rn, Hn, f[n], p[n], a named parameter, a scalar * literal or vector literal. */ if (token[0] == 'R' || token[0] == 'H') { srcReg->File = PROGRAM_TEMPORARY; if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; srcReg->Index = idx; } else if (token[0] == 'f') { /* XXX this might be an identifier! */ srcReg->File = PROGRAM_INPUT; if (!Parse_FragReg(parseState, &idx)) RETURN_ERROR; srcReg->Index = idx; } else if (token[0] == 'p') { /* XXX this might be an identifier! */ srcReg->File = PROGRAM_LOCAL_PARAM; if (!Parse_ProgramParamReg(parseState, &idx)) RETURN_ERROR; srcReg->Index = idx; } else if (IsLetter(token[0])){ GLubyte ident[100]; GLint paramIndex; if (!Parse_Identifier(parseState, ident)) RETURN_ERROR; paramIndex = _mesa_lookup_parameter_index(parseState->parameters, -1, (const char *) ident); if (paramIndex < 0) { RETURN_ERROR2("Undefined constant or parameter: ", ident); } srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } else if (IsDigit(token[0]) || token[0] == '-' || token[0] == '+' || token[0] == '.'){ /* literal scalar constant */ GLfloat values[4]; GLuint paramIndex; if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4, NULL); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } else if (token[0] == '{'){ /* literal vector constant */ GLfloat values[4]; GLuint paramIndex; (void) Parse_String(parseState, "{"); if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4, NULL); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } else { RETURN_ERROR2("Invalid source register name", token); } /* init swizzle fields */ srcReg->Swizzle = SWIZZLE_NOOP; /* Look for optional swizzle suffix */ if (Parse_String(parseState, ".")) { GLuint swz[4]; if (!Parse_Token(parseState, token)) RETURN_ERROR; if (!Parse_SwizzleSuffix(token, swz)) RETURN_ERROR1("Invalid swizzle suffix"); srcReg->Swizzle = MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); } /* Finish absolute value */ if (srcReg->Abs && !Parse_String(parseState, "|")) { RETURN_ERROR1("Expected |"); } return GL_TRUE; }
static GLboolean Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg) { GLubyte token[100]; GLfloat sign = 1.0F; GLboolean needSuffix = GL_TRUE; GLint idx; GLuint negateBase, negateAbs; /* * First, take care of +/- and absolute value stuff. */ if (Parse_String(parseState, "-")) sign = -1.0F; else if (Parse_String(parseState, "+")) sign = +1.0F; if (Parse_String(parseState, "|")) { srcReg->Abs = GL_TRUE; negateAbs = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; if (Parse_String(parseState, "-")) negateBase = NEGATE_XYZW; else if (Parse_String(parseState, "+")) negateBase = NEGATE_NONE; else negateBase = NEGATE_NONE; } else { srcReg->Abs = GL_FALSE; negateAbs = NEGATE_NONE; negateBase = (sign < 0.0F) ? NEGATE_XYZW : NEGATE_NONE; } srcReg->Negate = srcReg->Abs ? negateAbs : negateBase; if (!Peek_Token(parseState, token)) RETURN_ERROR; /* Src reg can be R<n>, H<n> or a named fragment attrib */ if (token[0] == 'R' || token[0] == 'H') { srcReg->File = PROGRAM_TEMPORARY; if (!Parse_TempReg(parseState, &idx)) RETURN_ERROR; srcReg->Index = idx; } else if (token[0] == 'f') { srcReg->File = PROGRAM_INPUT; if (!Parse_FragReg(parseState, &idx)) RETURN_ERROR; srcReg->Index = idx; } else if (token[0] == '{') { /* vector literal */ GLfloat values[4]; GLuint paramIndex; (void) Parse_String(parseState, "{"); if (!Parse_VectorConstant(parseState, values)) RETURN_ERROR; paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4, NULL); srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } else if (IsLetter(token[0])){ /* named param/constant */ GLubyte ident[100]; GLint paramIndex; if (!Parse_Identifier(parseState, ident)) RETURN_ERROR; paramIndex = _mesa_lookup_parameter_index(parseState->parameters, -1, (const char *) ident); if (paramIndex < 0) { RETURN_ERROR2("Undefined constant or parameter: ", ident); } srcReg->File = PROGRAM_NAMED_PARAM; srcReg->Index = paramIndex; } else if (IsDigit(token[0])) { /* scalar literal */ GLfloat values[4]; GLuint paramIndex; if (!Parse_ScalarConstant(parseState, values)) RETURN_ERROR; paramIndex = _mesa_add_unnamed_constant(parseState->parameters, values, 4, NULL); srcReg->Index = paramIndex; srcReg->File = PROGRAM_NAMED_PARAM; needSuffix = GL_FALSE; } else { RETURN_ERROR2("Invalid scalar source argument", token); } srcReg->Swizzle = 0; if (needSuffix) { /* parse .[xyzw] suffix */ if (!Parse_String(parseState, ".")) RETURN_ERROR1("Expected ."); if (!Parse_Token(parseState, token)) RETURN_ERROR; if (token[0] == 'x' && token[1] == 0) { srcReg->Swizzle = 0; } else if (token[0] == 'y' && token[1] == 0) { srcReg->Swizzle = 1; } else if (token[0] == 'z' && token[1] == 0) { srcReg->Swizzle = 2; } else if (token[0] == 'w' && token[1] == 0) { srcReg->Swizzle = 3; } else { RETURN_ERROR1("Invalid scalar source suffix"); } } /* Finish absolute value */ if (srcReg->Abs && !Parse_String(parseState, "|")) { RETURN_ERROR1("Expected |"); } return GL_TRUE; }
/** * XXX description??? * \return GL_TRUE for success, GL_FALSE for failure */ GLboolean _mesa_layout_parameters(struct asm_parser_state *state) { struct gl_program_parameter_list *layout; struct asm_instruction *inst; unsigned i; layout = _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters); /* PASS 1: Move any parameters that are accessed indirectly from the * original parameter list to the new parameter list. */ for (inst = state->inst_head; inst != NULL; inst = inst->next) { for (i = 0; i < 3; i++) { if (inst->SrcReg[i].Base.RelAddr) { /* Only attempt to add the to the new parameter list once. */ if (!inst->SrcReg[i].Symbol->pass1_done) { const int new_begin = copy_indirect_accessed_array(state->prog->Parameters, layout, inst->SrcReg[i].Symbol->param_binding_begin, inst->SrcReg[i].Symbol->param_binding_length); if (new_begin < 0) { return GL_FALSE; } inst->SrcReg[i].Symbol->param_binding_begin = new_begin; inst->SrcReg[i].Symbol->pass1_done = 1; } /* Previously the Index was just the offset from the parameter * array. Now that the base of the parameter array is known, the * index can be updated to its actual value. */ inst->Base.SrcReg[i] = inst->SrcReg[i].Base; inst->Base.SrcReg[i].Index += inst->SrcReg[i].Symbol->param_binding_begin; } } } /* PASS 2: Move any parameters that are not accessed indirectly from the * original parameter list to the new parameter list. */ for (inst = state->inst_head; inst != NULL; inst = inst->next) { for (i = 0; i < 3; i++) { const struct gl_program_parameter *p; const int idx = inst->SrcReg[i].Base.Index; unsigned swizzle = SWIZZLE_NOOP; /* All relative addressed operands were processed on the first * pass. Just skip them here. */ if (inst->SrcReg[i].Base.RelAddr) { continue; } if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING ) || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) { continue; } inst->Base.SrcReg[i] = inst->SrcReg[i].Base; p = & state->prog->Parameters->Parameters[idx]; switch (p->Type) { case PROGRAM_CONSTANT: { const float *const v = state->prog->Parameters->ParameterValues[idx]; inst->Base.SrcReg[i].Index = _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle); inst->Base.SrcReg[i].Swizzle = _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle); break; } case PROGRAM_STATE_VAR: inst->Base.SrcReg[i].Index = _mesa_add_state_reference(layout, p->StateIndexes); break; default: break; } inst->SrcReg[i].Base.File = p->Type; inst->Base.SrcReg[i].File = p->Type; } } layout->StateFlags = state->prog->Parameters->StateFlags; _mesa_free_parameter_list(state->prog->Parameters); state->prog->Parameters = layout; return GL_TRUE; }