#include "main/mtypes.h"
#include "main/imports.h"
-#include "program.h"
-#include "prog_parameter.h"
-#include "prog_parameter_layout.h"
-#include "prog_statevars.h"
-#include "prog_instruction.h"
+#include "shader/program.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_parameter_layout.h"
+#include "shader/prog_statevars.h"
+#include "shader/prog_instruction.h"
-#include "symbol_table.h"
-#include "program_parser.h"
+#include "shader/symbol_table.h"
+#include "shader/program_parser.h"
extern void *yy_scan_string(char *);
extern void yy_delete_buffer(void *);
struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
static int initialize_symbol_from_const(struct gl_program *prog,
- struct asm_symbol *param_var, const struct asm_vector *vec);
+ struct asm_symbol *param_var, const struct asm_vector *vec,
+ GLboolean allowSwizzle);
static int yyparse(struct asm_parser_state *state);
static void init_dst_reg(struct prog_dst_register *r);
+static void set_dst_reg(struct prog_dst_register *r,
+ gl_register_file file, GLint index);
+
static void init_src_reg(struct asm_src_register *r);
+static void set_src_reg(struct asm_src_register *r,
+ gl_register_file file, GLint index);
+
+static void set_src_reg_swz(struct asm_src_register *r,
+ gl_register_file file, GLint index, GLuint swizzle);
+
static void asm_instruction_set_operands(struct asm_instruction *inst,
const struct prog_dst_register *dst, const struct asm_src_register *src0,
const struct asm_src_register *src1, const struct asm_src_register *src2);
}
+ free($2);
+
if (!valid) {
const char *const err_str = (state->mode == ARB_vertex)
? "invalid ARB vertex program option"
memset(& temp_sym, 0, sizeof(temp_sym));
temp_sym.param_binding_begin = ~0;
- initialize_symbol_from_const(state->prog, & temp_sym, & $1);
+ initialize_symbol_from_const(state->prog, & temp_sym, & $1, GL_TRUE);
- init_src_reg(& $$);
- $$.Base.File = PROGRAM_CONSTANT;
- $$.Base.Index = temp_sym.param_binding_begin;
+ set_src_reg_swz(& $$, PROGRAM_CONSTANT,
+ temp_sym.param_binding_begin,
+ temp_sym.param_binding_swizzle);
}
;
YYERROR;
}
- state->prog->OutputsWritten |= (1U << $$.Index);
+ state->prog->OutputsWritten |= BITFIELD64_BIT($$.Index);
}
}
;
maskedAddrReg: addrReg addrWriteMask
{
- init_dst_reg(& $$);
- $$.File = PROGRAM_ADDRESS;
- $$.Index = 0;
+ set_dst_reg(& $$, PROGRAM_ADDRESS, 0);
$$.WriteMask = $2.mask;
}
;
}
| string
{
+ char s;
+
if (strlen($1) > 1) {
yyerror(& @1, state, "invalid extended swizzle selector");
YYERROR;
}
- switch ($1[0]) {
+ s = $1[0];
+ free($1);
+
+ switch (s) {
case 'x':
$$.swz = SWIZZLE_X;
$$.xyzw_valid = 1;
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid operand variable");
YYERROR;
init_src_reg(& $$);
switch (s->type) {
case at_temp:
- $$.Base.File = PROGRAM_TEMPORARY;
- $$.Base.Index = s->temp_binding;
+ set_src_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
break;
case at_param:
- $$.Base.File = s->param_binding_type;
- $$.Base.Index = s->param_binding_begin;
+ set_src_reg_swz(& $$, s->param_binding_type,
+ s->param_binding_begin,
+ s->param_binding_swizzle);
break;
case at_attrib:
- $$.Base.File = PROGRAM_INPUT;
- $$.Base.Index = s->attrib_binding;
+ set_src_reg(& $$, PROGRAM_INPUT, s->attrib_binding);
state->prog->InputsRead |= (1U << $$.Base.Index);
if (!validate_inputs(& @1, state)) {
}
| attribBinding
{
- init_src_reg(& $$);
- $$.Base.File = PROGRAM_INPUT;
- $$.Base.Index = $1;
+ set_src_reg(& $$, PROGRAM_INPUT, $1);
state->prog->InputsRead |= (1U << $$.Base.Index);
if (!validate_inputs(& @1, state)) {
}
| paramSingleItemUse
{
- init_src_reg(& $$);
- $$.Base.File = ($1.name != NULL)
+ gl_register_file file = ($1.name != NULL)
? $1.param_binding_type
: PROGRAM_CONSTANT;
- $$.Base.Index = $1.param_binding_begin;
+ set_src_reg_swz(& $$, file, $1.param_binding_begin,
+ $1.param_binding_swizzle);
}
;
dstReg: resultBinding
{
- init_dst_reg(& $$);
- $$.File = PROGRAM_OUTPUT;
- $$.Index = $1;
+ set_dst_reg(& $$, PROGRAM_OUTPUT, $1);
}
| USED_IDENTIFIER /* temporaryReg | vertexResultReg */
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid operand variable");
YYERROR;
YYERROR;
}
- init_dst_reg(& $$);
switch (s->type) {
case at_temp:
- $$.File = PROGRAM_TEMPORARY;
- $$.Index = s->temp_binding;
+ set_dst_reg(& $$, PROGRAM_TEMPORARY, s->temp_binding);
break;
case at_output:
- $$.File = PROGRAM_OUTPUT;
- $$.Index = s->output_binding;
+ set_dst_reg(& $$, PROGRAM_OUTPUT, s->output_binding);
break;
default:
- $$.File = s->param_binding_type;
- $$.Index = s->param_binding_begin;
+ set_dst_reg(& $$, s->param_binding_type, s->param_binding_begin);
break;
}
}
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid operand variable");
YYERROR;
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $1);
+ free($1);
+
if (s == NULL) {
yyerror(& @1, state, "invalid array member");
YYERROR;
? err_str : "invalid condition code");
if (err_str != NULL) {
- _mesa_free(err_str);
+ free(err_str);
}
YYERROR;
? err_str : "invalid condition code");
if (err_str != NULL) {
- _mesa_free(err_str);
+ free(err_str);
}
YYERROR;
declare_variable(state, $2, at_attrib, & @2);
if (s == NULL) {
+ free($2);
YYERROR;
} else {
s->attrib_binding = $4;
declare_variable(state, $2, at_param, & @2);
if (s == NULL) {
+ free($2);
YYERROR;
} else {
s->param_binding_type = $3.param_binding_type;
s->param_binding_begin = $3.param_binding_begin;
s->param_binding_length = $3.param_binding_length;
+ s->param_binding_swizzle = SWIZZLE_XYZW;
s->param_is_array = 0;
}
}
PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
{
if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
+ free($2);
yyerror(& @4, state,
"parameter array size and number of bindings must match");
YYERROR;
declare_variable(state, $2, $6.type, & @2);
if (s == NULL) {
+ free($2);
YYERROR;
} else {
s->param_binding_type = $6.param_binding_type;
s->param_binding_begin = $6.param_binding_begin;
s->param_binding_length = $6.param_binding_length;
+ s->param_binding_swizzle = SWIZZLE_XYZW;
s->param_is_array = 1;
}
}
{
memset(& $$, 0, sizeof($$));
$$.param_binding_begin = ~0;
- initialize_symbol_from_const(state->prog, & $$, & $1);
+ initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
}
;
{
memset(& $$, 0, sizeof($$));
$$.param_binding_begin = ~0;
- initialize_symbol_from_const(state->prog, & $$, & $1);
+ initialize_symbol_from_const(state->prog, & $$, & $1, GL_TRUE);
}
;
{
memset(& $$, 0, sizeof($$));
$$.param_binding_begin = ~0;
- initialize_symbol_from_const(state->prog, & $$, & $1);
+ initialize_symbol_from_const(state->prog, & $$, & $1, GL_FALSE);
}
;
? err_str : "invalid storage size specifier");
if (err_str != NULL) {
- _mesa_free(err_str);
+ free(err_str);
}
YYERROR;
varNameList: varNameList ',' IDENTIFIER
{
if (!declare_variable(state, $3, $<integer>0, & @3)) {
+ free($3);
YYERROR;
}
}
| IDENTIFIER
{
if (!declare_variable(state, $1, $<integer>0, & @1)) {
+ free($1);
YYERROR;
}
}
declare_variable(state, $3, at_output, & @3);
if (s == NULL) {
+ free($3);
YYERROR;
} else {
s->output_binding = $5;
struct asm_symbol *target = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, $4);
+ free($4);
if (exist != NULL) {
- yyerror(& @2, state, "redeclared identifier");
+ char m[1000];
+ _mesa_snprintf(m, sizeof(m), "redeclared identifier: %s", $2);
+ free($2);
+ yyerror(& @2, state, m);
YYERROR;
} else if (target == NULL) {
+ free($2);
yyerror(& @4, state,
"undefined variable binding in ALIAS statement");
YYERROR;
} else {
- _mesa_symbol_table_add_symbol(state->st, 0, strdup($2), target);
+ _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
}
}
;
}
+/** Like init_dst_reg() but set the File and Index fields. */
+void
+set_dst_reg(struct prog_dst_register *r, gl_register_file file, GLint index)
+{
+ const GLint maxIndex = 1 << INST_INDEX_BITS;
+ const GLint minIndex = 0;
+ ASSERT(index >= minIndex);
+ (void) minIndex;
+ ASSERT(index <= maxIndex);
+ (void) maxIndex;
+ ASSERT(file == PROGRAM_TEMPORARY ||
+ file == PROGRAM_ADDRESS ||
+ file == PROGRAM_OUTPUT);
+ memset(r, 0, sizeof(*r));
+ r->File = file;
+ r->Index = index;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
void
init_src_reg(struct asm_src_register *r)
{
}
+/** Like init_src_reg() but set the File and Index fields.
+ * \return GL_TRUE if a valid src register, GL_FALSE otherwise
+ */
+void
+set_src_reg(struct asm_src_register *r, gl_register_file file, GLint index)
+{
+ set_src_reg_swz(r, file, index, SWIZZLE_XYZW);
+}
+
+
+void
+set_src_reg_swz(struct asm_src_register *r, gl_register_file file, GLint index,
+ GLuint swizzle)
+{
+ const GLint maxIndex = (1 << INST_INDEX_BITS) - 1;
+ const GLint minIndex = -(1 << INST_INDEX_BITS);
+ ASSERT(file < PROGRAM_FILE_MAX);
+ ASSERT(index >= minIndex);
+ (void) minIndex;
+ ASSERT(index <= maxIndex);
+ (void) maxIndex;
+ memset(r, 0, sizeof(*r));
+ r->Base.File = file;
+ r->Base.Index = index;
+ r->Base.Swizzle = swizzle;
+ r->Symbol = NULL;
+}
+
+
/**
* Validate the set of inputs used by a program
*
if (exist != NULL) {
yyerror(locp, state, "redeclared identifier");
} else {
- const size_t name_len = strlen(name);
-
- s = calloc(1, sizeof(struct asm_symbol) + name_len + 1);
- s->name = (char *)(s + 1);
+ s = calloc(1, sizeof(struct asm_symbol));
+ s->name = name;
s->type = t;
- memcpy((char *) s->name, name, name_len + 1);
-
switch (t) {
case at_temp:
if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
param_list->StateFlags |= _mesa_program_state_flags(tokens);
/* free name string here since we duplicated it in add_parameter() */
- _mesa_free(name);
+ free(name);
return index;
}
state_tokens[2] = state_tokens[3] = row;
idx = add_state_reference(prog->Parameters, state_tokens);
- if (param_var->param_binding_begin == ~0U)
+ if (param_var->param_binding_begin == ~0U) {
param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
+
param_var->param_binding_length++;
}
}
else {
idx = add_state_reference(prog->Parameters, state_tokens);
- if (param_var->param_binding_begin == ~0U)
+ if (param_var->param_binding_begin == ~0U) {
param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
param_var->param_binding_length++;
}
assert((state_tokens[1] == STATE_ENV)
|| (state_tokens[1] == STATE_LOCAL));
+ /*
+ * The param type is STATE_VAR. The program parameter entry will
+ * effectively be a pointer into the LOCAL or ENV parameter array.
+ */
param_var->type = at_param;
- param_var->param_binding_type = (state_tokens[1] == STATE_ENV)
- ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
/* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
* we need to unroll it and call add_state_reference() for each row
state_tokens[2] = state_tokens[3] = row;
idx = add_state_reference(prog->Parameters, state_tokens);
- if (param_var->param_binding_begin == ~0U)
+ if (param_var->param_binding_begin == ~0U) {
param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
param_var->param_binding_length++;
}
}
else {
idx = add_state_reference(prog->Parameters, state_tokens);
- if (param_var->param_binding_begin == ~0U)
+ if (param_var->param_binding_begin == ~0U) {
param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = SWIZZLE_XYZW;
+ }
param_var->param_binding_length++;
}
}
+/**
+ * Put a float/vector constant/literal into the parameter list.
+ * \param param_var returns info about the parameter/constant's location,
+ * binding, type, etc.
+ * \param vec the vector/constant to add
+ * \param allowSwizzle if true, try to consolidate constants which only differ
+ * by a swizzle. We don't want to do this when building
+ * arrays of constants that may be indexed indirectly.
+ * \return index of the constant in the parameter list.
+ */
int
initialize_symbol_from_const(struct gl_program *prog,
struct asm_symbol *param_var,
- const struct asm_vector *vec)
+ const struct asm_vector *vec,
+ GLboolean allowSwizzle)
{
- const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT,
- NULL, vec->count, GL_NONE, vec->data,
- NULL, 0x0);
+ unsigned swizzle;
+ const int idx = _mesa_add_unnamed_constant(prog->Parameters,
+ vec->data, vec->count,
+ allowSwizzle ? &swizzle : NULL);
param_var->type = at_param;
param_var->param_binding_type = PROGRAM_CONSTANT;
- if (param_var->param_binding_begin == ~0U)
+ if (param_var->param_binding_begin == ~0U) {
param_var->param_binding_begin = idx;
+ param_var->param_binding_swizzle = allowSwizzle ? swizzle : SWIZZLE_XYZW;
+ }
param_var->param_binding_length++;
return idx;
va_start(args, fmt);
/* Call vsnprintf once to determine how large the final string is. Call it
- * again to do the actual formatting. from the vsnprintf manual page:
+ * again to do the actual formatting. from the v_mesa_snprintf manual page:
*
* Upon successful return, these functions return the number of
* characters printed (not including the trailing '\0' used to end
*/
length = 1 + vsnprintf(NULL, 0, fmt, args);
- str = _mesa_malloc(length);
+ str = malloc(length);
if (str) {
vsnprintf(str, length, fmt, args);
}
err_str = make_error_string("glProgramStringARB(%s)\n", s);
if (err_str) {
_mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
- _mesa_free(err_str);
+ free(err_str);
}
err_str = make_error_string("line %u, char %u: error: %s\n",
_mesa_set_program_error(state->ctx, locp->position, err_str);
if (err_str) {
- _mesa_free(err_str);
+ free(err_str);
}
}
/* Make a copy of the program string and force it to be NUL-terminated.
*/
- strz = (GLubyte *) _mesa_malloc(len + 1);
+ strz = (GLubyte *) malloc(len + 1);
if (strz == NULL) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
return GL_FALSE;
}
- _mesa_memcpy (strz, str, len);
+ memcpy (strz, str, len);
strz[len] = '\0';
- if (state->prog->String != NULL) {
- _mesa_free(state->prog->String);
- state->prog->String = NULL;
- }
-
state->prog->String = strz;
state->st = _mesa_symbol_table_ctor();
error:
for (inst = state->inst_head; inst != NULL; inst = temp) {
temp = inst->next;
- _mesa_free(inst);
+ free(inst);
}
state->inst_head = NULL;
for (sym = state->sym; sym != NULL; sym = temp) {
temp = sym->next;
- _mesa_free(sym);
+ free((void *) sym->name);
+ free(sym);
}
state->sym = NULL;
_mesa_symbol_table_dtor(state->st);
state->st = NULL;
- if (state->string_dumpster != NULL) {
- _mesa_free(state->string_dumpster);
- state->dumpster_size = 0;
- }
-
return result;
}