# USE OR OTHER DEALINGS IN THE SOFTWARE.
AUTOMAKE_OPTIONS = foreign
+AM_CPPFLAGS = -I mesa
SUBDIRS = glcpp
ir_hierarchical_visitor.h \
ir_hierarchical_visitor.cpp \
ir_swizzle_swizzle.cpp \
+ ir_to_mesa.cpp \
+ ir_to_mesa.h \
ir_validate.cpp \
ir_vec_index_to_swizzle.cpp \
- linker.cpp
+ linker.cpp \
+ mesa_codegen.cpp \
+ msea_codegen.h
+
+DISTFILES = \
+ mesa_codegen.brg
BUILT_SOURCES = glsl_parser.h glsl_parser.cpp glsl_lexer.cpp
CLEANFILES = $(BUILT_SOURCES)
.lpp.cpp:
$(LEXCOMPILE) --outfile="$@" $<
+
+mesa_codegen.h: mesa_codegen.cpp
+
+mesa_codegen.cpp: mesa_codegen.brg
+ monoburg --no-glib -s $@ -d mesa_codegen.h $<
--- /dev/null
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file ir_to_mesa.cpp
+ *
+ * Translates the IR to ARB_fragment_program text if possible,
+ * printing the result
+ *
+ * The code generation is performed using monoburg. Because monoburg
+ * produces a single C file with the definitions of the node types in
+ * it, this file is included from the monoburg output.
+ */
+
+/* Quiet compiler warnings due to monoburg not marking functions defined
+ * in the header as inline.
+ */
+#define g_new
+#define g_error
+#include "mesa_codegen.h"
+
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_print_visitor.h"
+#include "ir_expression_flattening.h"
+#include "glsl_types.h"
+
+#include "shader/prog_instruction.h"
+
+ir_to_mesa_src_reg ir_to_mesa_undef = {
+ PROGRAM_UNDEFINED, 0, SWIZZLE_NOOP
+};
+
+ir_to_mesa_instruction *
+ir_to_mesa_emit_op3(struct mbtree *tree, enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1,
+ ir_to_mesa_src_reg src2)
+{
+ ir_to_mesa_instruction *inst = new ir_to_mesa_instruction();
+
+ inst->op = op;
+ inst->dst_reg = dst;
+ inst->src_reg[0] = src0;
+ inst->src_reg[1] = src1;
+ inst->src_reg[2] = src2;
+
+ tree->v->instructions.push_tail(inst);
+
+ return inst;
+}
+
+
+ir_to_mesa_instruction *
+ir_to_mesa_emit_op2(struct mbtree *tree, enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1)
+{
+ return ir_to_mesa_emit_op3(tree, op, dst, src0, src1, ir_to_mesa_undef);
+}
+
+ir_to_mesa_instruction *
+ir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0)
+{
+ return ir_to_mesa_emit_op3(tree, op,
+ dst, src0, ir_to_mesa_undef, ir_to_mesa_undef);
+}
+
+struct mbtree *
+ir_to_mesa_visitor::create_tree(int op, struct mbtree *left, struct mbtree *right)
+{
+ struct mbtree *tree = (struct mbtree *)calloc(sizeof(struct mbtree), 1);
+
+ tree->op = op;
+ tree->left = left;
+ tree->right = right;
+ tree->v = this;
+ tree->src_reg.swizzle = SWIZZLE_XYZW;
+
+ return tree;
+}
+
+const char *
+produce_swizzle(int8_t *swizzle, const char *reg_name,
+ const char **swizzle_reg_name)
+{
+ if (swizzle[0] == 0 &&
+ swizzle[1] == 1 &&
+ swizzle[2] == 2 &&
+ swizzle[3] == 3)
+ {
+ *swizzle_reg_name = reg_name;
+ } else {
+ char swizzle_letters[4] = { 'x', 'y', 'z', 'w' };
+ char *temp;
+ asprintf(&temp, "%s.%c%c%c%c",
+ reg_name,
+ swizzle_letters[swizzle[0]],
+ swizzle_letters[swizzle[1]],
+ swizzle_letters[swizzle[2]],
+ swizzle_letters[swizzle[3]]);
+ *swizzle_reg_name = temp;
+ }
+ return *swizzle_reg_name;
+}
+
+/**
+ * In the initial pass of codegen, we assign temporary numbers to
+ * intermediate results. (not SSA -- variable assignments will reuse
+ * storage). Actual register allocation for the Mesa VM occurs in a
+ * pass over the Mesa IR later.
+ */
+void
+ir_to_mesa_visitor::get_temp(struct mbtree *tree)
+{
+ tree->src_reg.file = PROGRAM_TEMPORARY;
+ tree->src_reg.index = this->next_temp++;
+}
+
+void
+ir_to_mesa_visitor::get_temp_for_var(ir_variable *var, struct mbtree *tree)
+{
+ temp_entry *entry;
+
+ foreach_iter(exec_list_iterator, iter, this->variable_storage) {
+ entry = (temp_entry *)iter.get();
+
+ if (entry->var == var) {
+ tree->src_reg.file = entry->file;
+ tree->src_reg.index = entry->index;
+ return;
+ }
+ }
+
+ entry = new temp_entry(var, PROGRAM_TEMPORARY, this->next_temp++);
+ this->variable_storage.push_tail(entry);
+
+ tree->src_reg.file = entry->file;
+ tree->src_reg.index = entry->index;
+}
+
+static void
+reduce(struct mbtree *t, int goal)
+{
+ struct mbtree *kids[10];
+ int rule = mono_burg_rule((MBState *)t->state, goal);
+ const uint16_t *nts = mono_burg_nts[rule];
+ int i;
+
+ mono_burg_kids (t, rule, kids);
+
+ for (i = 0; nts[i]; i++) {
+ reduce(kids[i], nts[i]);
+ }
+
+ if (t->left) {
+ if (mono_burg_func[rule]) {
+ mono_burg_func[rule](t, NULL);
+ } else {
+ printf("no code for rules %s\n", mono_burg_rule_string[rule]);
+ exit(1);
+ }
+ } else {
+ if (mono_burg_func[rule]) {
+ printf("unused code for rule %s\n", mono_burg_rule_string[rule]);
+ exit(1);
+ }
+ }
+}
+
+void
+ir_to_mesa_visitor::visit(ir_variable *ir)
+{
+ (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop *ir)
+{
+ (void)ir;
+
+ printf("Can't support loops, should be flattened before here\n");
+ exit(1);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_loop_jump *ir)
+{
+ (void) ir;
+ printf("Can't support loops, should be flattened before here\n");
+ exit(1);
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_function_signature *ir)
+{
+ assert(0);
+ (void)ir;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_function *ir)
+{
+ /* Ignore function bodies other than main() -- we shouldn't see calls to
+ * them since they should all be inlined before we get to ir_to_mesa.
+ */
+ if (strcmp(ir->name, "main") == 0) {
+ const ir_function_signature *sig;
+ exec_list empty;
+
+ sig = ir->matching_signature(&empty);
+
+ assert(sig);
+
+ foreach_iter(exec_list_iterator, iter, sig->body) {
+ ir_instruction *ir = (ir_instruction *)iter.get();
+
+ ir->accept(this);
+ }
+ }
+}
+
+void
+ir_to_mesa_visitor::visit(ir_expression *ir)
+{
+ unsigned int operand;
+ struct mbtree *op[2];
+ const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
+ const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
+ const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
+
+ for (operand = 0; operand < ir->get_num_operands(); operand++) {
+ this->result = NULL;
+ ir->operands[operand]->accept(this);
+ if (!this->result) {
+ ir_print_visitor v;
+ printf("Failed to get tree for expression operand:\n");
+ ir->operands[operand]->accept(&v);
+ exit(1);
+ }
+ op[operand] = this->result;
+ }
+
+ this->result = NULL;
+
+ switch (ir->operation) {
+ case ir_binop_add:
+ this->result = this->create_tree(MB_TERM_add_vec4_vec4, op[0], op[1]);
+ break;
+ case ir_binop_sub:
+ this->result = this->create_tree(MB_TERM_sub_vec4_vec4, op[0], op[1]);
+ break;
+ case ir_binop_mul:
+ this->result = this->create_tree(MB_TERM_mul_vec4_vec4, op[0], op[1]);
+ break;
+ case ir_binop_div:
+ this->result = this->create_tree(MB_TERM_div_vec4_vec4, op[0], op[1]);
+ break;
+ case ir_binop_dot:
+ if (ir->operands[0]->type == vec4_type) {
+ assert(ir->operands[1]->type == vec4_type);
+ this->result = this->create_tree(MB_TERM_dp4_vec4_vec4, op[0], op[1]);
+ } else if (ir->operands[0]->type == vec3_type) {
+ assert(ir->operands[1]->type == vec3_type);
+ this->result = this->create_tree(MB_TERM_dp3_vec4_vec4, op[0], op[1]);
+ } else if (ir->operands[0]->type == vec2_type) {
+ assert(ir->operands[1]->type == vec2_type);
+ this->result = this->create_tree(MB_TERM_dp2_vec4_vec4, op[0], op[1]);
+ }
+ break;
+ case ir_unop_sqrt:
+ this->result = this->create_tree(MB_TERM_sqrt_vec4, op[0], op[1]);
+ break;
+ default:
+ break;
+ }
+ if (!this->result) {
+ ir_print_visitor v;
+ printf("Failed to get tree for expression:\n");
+ ir->accept(&v);
+ exit(1);
+ }
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_swizzle *ir)
+{
+ struct mbtree *tree;
+ int i;
+ int swizzle[4];
+
+ /* FINISHME: Handle swizzles on the left side of an assignment. */
+
+ ir->val->accept(this);
+ assert(this->result);
+
+ tree = this->create_tree(MB_TERM_swizzle_vec4, this->result, NULL);
+
+ for (i = 0; i < 4; i++) {
+ if (i < ir->type->vector_elements) {
+ switch (i) {
+ case 0:
+ swizzle[i] = ir->mask.x;
+ break;
+ case 1:
+ swizzle[i] = ir->mask.y;
+ break;
+ case 2:
+ swizzle[i] = ir->mask.z;
+ break;
+ case 3:
+ swizzle[i] = ir->mask.w;
+ break;
+ }
+ } else {
+ /* If the type is smaller than a vec4, replicate the last
+ * channel out.
+ */
+ swizzle[i] = ir->type->vector_elements - 1;
+ }
+ }
+
+ tree->src_reg.swizzle = MAKE_SWIZZLE4(swizzle[0],
+ swizzle[1],
+ swizzle[2],
+ swizzle[3]);
+
+ this->result = tree;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
+{
+ struct mbtree *tree;
+ int size_swizzles[4] = {
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ };
+
+ ir_variable *var = ir->var->as_variable();
+
+ /* By the time we make it to this stage, matric`es should be broken down
+ * to vectors.
+ */
+ assert(!var->type->is_matrix());
+
+ tree = this->create_tree(MB_TERM_reference_vec4, NULL, NULL);
+
+ if (strncmp(var->name, "gl_", 3) == 0) {
+ if (strcmp(var->name, "gl_FragColor") == 0) {
+ tree->src_reg.file = PROGRAM_INPUT;
+ tree->src_reg.index = FRAG_ATTRIB_COL0;
+ } else {
+ assert(0);
+ }
+ } else {
+ this->get_temp_for_var(var, tree);
+ }
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1];
+
+ this->result = tree;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_array *ir)
+{
+ struct mbtree *tree;
+ int size_swizzles[4] = {
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
+ MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ };
+
+ ir_variable *var = ir->array->as_variable();
+ ir_constant *index = ir->array_index->constant_expression_value();
+ char *name;
+
+ assert(var);
+ assert(index);
+ assert(strcmp(var->name, "gl_TexCoord") == 0);
+
+ asprintf(&name, "fragment.texcoord[%d]", index->value.i[0]);
+ tree = this->create_tree(MB_TERM_reference_vec4, NULL, NULL);
+ tree->reg_name = name;
+
+ /* If the type is smaller than a vec4, replicate the last channel out. */
+ tree->src_reg.swizzle = size_swizzles[ir->type->vector_elements - 1];
+
+ this->result = tree;
+}
+
+void
+ir_to_mesa_visitor::visit(ir_dereference_record *ir)
+{
+ (void)ir;
+ assert(0);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_assignment *ir)
+{
+ struct mbtree *l, *r, *t;
+
+ ir->lhs->accept(this);
+ l = this->result;
+ ir->rhs->accept(this);
+ r = this->result;
+ assert(l);
+ assert(r);
+
+ assert(!ir->condition);
+
+ t = this->create_tree(MB_TERM_assign, l, r);
+ mono_burg_label(t, NULL);
+ reduce(t, MB_NTERM_stmt);
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_constant *ir)
+{
+ struct mbtree *tree;
+
+ assert(!ir->type->is_matrix());
+
+ tree = this->create_tree(MB_TERM_reference_vec4, NULL, NULL);
+
+ assert(ir->type->base_type == GLSL_TYPE_FLOAT);
+
+ /* FINISHME: This will end up being _mesa_add_unnamed_constant,
+ * which handles sharing values and sharing channels of vec4
+ * constants for small values.
+ */
+ /* FINISHME: Do something with the constant values for now.
+ */
+ tree->src_reg.file = PROGRAM_CONSTANT;
+ tree->src_reg.index = this->next_constant++;
+ tree->src_reg.swizzle = SWIZZLE_NOOP;
+
+ this->result = tree;
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_call *ir)
+{
+ printf("Can't support call to %s\n", ir->callee_name());
+ exit(1);
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_texture *ir)
+{
+ assert(0);
+
+ ir->coordinate->accept(this);
+}
+
+void
+ir_to_mesa_visitor::visit(ir_return *ir)
+{
+ assert(0);
+
+ ir->get_value()->accept(this);
+}
+
+
+void
+ir_to_mesa_visitor::visit(ir_if *ir)
+{
+ (void)ir;
+ printf("Can't support conditionals, should be flattened before here.\n");
+ exit(1);
+}
+
+static struct prog_src_register
+mesa_src_reg_from_ir_src_reg(ir_to_mesa_src_reg reg)
+{
+ struct prog_src_register mesa_reg;
+
+ mesa_reg.File = reg.file;
+ mesa_reg.Index = reg.index;
+
+ return mesa_reg;
+}
+
+void
+do_ir_to_mesa(exec_list *instructions)
+{
+ ir_to_mesa_visitor v;
+ struct prog_instruction *mesa_instructions, *mesa_inst;
+
+ visit_exec_list(instructions, &v);
+
+ int num_instructions = 0;
+ foreach_iter(exec_list_iterator, iter, v.instructions) {
+ num_instructions++;
+ }
+
+ mesa_instructions =
+ (struct prog_instruction *)calloc(num_instructions,
+ sizeof(*mesa_instructions));
+
+ mesa_inst = mesa_instructions;
+ foreach_iter(exec_list_iterator, iter, v.instructions) {
+ ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
+ mesa_inst->Opcode = inst->op;
+ mesa_inst->DstReg.File = inst->dst_reg.file;
+ mesa_inst->DstReg.Index = inst->dst_reg.index;
+ mesa_inst->SrcReg[0] = mesa_src_reg_from_ir_src_reg(inst->src_reg[0]);
+ mesa_inst->SrcReg[1] = mesa_src_reg_from_ir_src_reg(inst->src_reg[1]);
+ mesa_inst->SrcReg[2] = mesa_src_reg_from_ir_src_reg(inst->src_reg[2]);
+ mesa_inst++;
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ir.h"
+#include "shader/prog_instruction.h"
+
+/**
+ * \file ir_to_mesa.h
+ *
+ * Translates the IR to Mesa IR if possible.
+ */
+
+/**
+ * This struct is a corresponding struct to Mesa prog_src_register, with
+ * wider fields.
+ */
+typedef struct ir_to_mesa_src_reg {
+ int file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+ int swizzle; /**< SWIZZLE_XYZWONEZERO swizzles from Mesa. */
+} ir_to_mesa_src_reg;
+
+typedef struct ir_to_mesa_dst_reg {
+ int file; /**< PROGRAM_* from Mesa */
+ int index; /**< temporary index, VERT_ATTRIB_*, FRAG_ATTRIB_*, etc. */
+} ir_to_mesa_dst_reg;
+
+extern ir_to_mesa_src_reg ir_to_mesa_undef;
+
+class ir_to_mesa_instruction : public exec_node {
+public:
+ enum prog_opcode op;
+ ir_to_mesa_dst_reg dst_reg;
+ ir_to_mesa_src_reg src_reg[3];
+};
+
+struct mbtree {
+ struct mbtree *left;
+ struct mbtree *right;
+ void *state;
+ uint16_t op;
+ const char *reg_name;
+ const char *swizzle_reg_name;
+ class ir_to_mesa_visitor *v;
+
+ /**
+ * This is the representation of this tree node's results as a
+ * source register for its consumer.
+ */
+ ir_to_mesa_src_reg src_reg;
+};
+
+void do_ir_to_mesa(exec_list *instructions);
+
+class temp_entry : public exec_node {
+public:
+ temp_entry(ir_variable *var, int file, int index)
+ : file(file), index(index), var(var)
+ {
+ /* empty */
+ }
+
+ int file;
+ int index;
+ ir_variable *var; /* variable that maps to this, if any */
+};
+
+class ir_to_mesa_visitor : public ir_visitor {
+public:
+ ir_to_mesa_visitor()
+ {
+ result = NULL;
+ next_temp = 0;
+ next_constant = 0;
+ }
+
+ int next_temp;
+ int next_constant;
+
+ void get_temp(struct mbtree *tree);
+
+ void get_temp_for_var(ir_variable *var, struct mbtree *tree);
+
+ struct mbtree *create_tree(int op,
+ struct mbtree *left,
+ struct mbtree *right);
+
+ /**
+ * \name Visit methods
+ *
+ * As typical for the visitor pattern, there must be one \c visit method for
+ * each concrete subclass of \c ir_instruction. Virtual base classes within
+ * the hierarchy should not have \c visit methods.
+ */
+ /*@{*/
+ virtual void visit(ir_variable *);
+ virtual void visit(ir_loop *);
+ virtual void visit(ir_loop_jump *);
+ virtual void visit(ir_function_signature *);
+ virtual void visit(ir_function *);
+ virtual void visit(ir_expression *);
+ virtual void visit(ir_swizzle *);
+ virtual void visit(ir_dereference_variable *);
+ virtual void visit(ir_dereference_array *);
+ virtual void visit(ir_dereference_record *);
+ virtual void visit(ir_assignment *);
+ virtual void visit(ir_constant *);
+ virtual void visit(ir_call *);
+ virtual void visit(ir_return *);
+ virtual void visit(ir_texture *);
+ virtual void visit(ir_if *);
+ /*@}*/
+
+ struct mbtree *result;
+
+ /** List of temp_entry */
+ exec_list variable_storage;
+
+ /** List of ir_to_mesa_instruction */
+ exec_list instructions;
+};
+
+ir_to_mesa_instruction *
+ir_to_mesa_emit_op1(struct mbtree *tree, enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0);
+
+ir_to_mesa_instruction *
+ir_to_mesa_emit_op2(struct mbtree *tree, enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1);
+
+ir_to_mesa_instruction *
+ir_to_mesa_emit_op3(struct mbtree *tree, enum prog_opcode op,
+ ir_to_mesa_dst_reg dst,
+ ir_to_mesa_src_reg src0,
+ ir_to_mesa_src_reg src1,
+ ir_to_mesa_src_reg src2);
+
+inline ir_to_mesa_dst_reg
+ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg reg)
+{
+ ir_to_mesa_dst_reg dst_reg;
+
+ dst_reg.file = reg.file;
+ dst_reg.index = reg.index;
+
+ return dst_reg;
+}
#define MAX_DRAW_BUFFERS 8
#define MAX_VARYING 16
+#include <GL/gl.h>
+
/**
* Indexes for vertex program attributes.
* GL_NV_vertex_program aliases generic attributes over the conventional
FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS)
} gl_frag_result;
+/**
+ * Names of the various vertex/fragment program register files, etc.
+ *
+ * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
+ * All values should fit in a 4-bit field.
+ *
+ * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
+ * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
+ * be "uniform" variables since they can only be set outside glBegin/End.
+ * They're also all stored in the same Parameters array.
+ */
+typedef enum
+{
+ PROGRAM_TEMPORARY, /**< machine->Temporary[] */
+ PROGRAM_INPUT, /**< machine->Inputs[] */
+ PROGRAM_OUTPUT, /**< machine->Outputs[] */
+ PROGRAM_VARYING, /**< machine->Inputs[]/Outputs[] */
+ PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */
+ PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */
+ PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */
+ PROGRAM_NAMED_PARAM, /**< gl_program->Parameters[] */
+ PROGRAM_CONSTANT, /**< gl_program->Parameters[] */
+ PROGRAM_UNIFORM, /**< gl_program->Parameters[] */
+ PROGRAM_WRITE_ONLY, /**< A dummy, write-only register */
+ PROGRAM_ADDRESS, /**< machine->AddressReg */
+ PROGRAM_SAMPLER, /**< for shader samplers, compile-time only */
+ PROGRAM_UNDEFINED, /**< Invalid/TBD value */
+ PROGRAM_FILE_MAX
+} gl_register_file;
+
#endif
--- /dev/null
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.3
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * \file prog_instruction.h
+ *
+ * Vertex/fragment program instruction datatypes and constants.
+ *
+ * \author Brian Paul
+ * \author Keith Whitwell
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+
+#ifndef PROG_INSTRUCTION_H
+#define PROG_INSTRUCTION_H
+
+
+#include "main/mtypes.h"
+
+
+/**
+ * Swizzle indexes.
+ * Do not change!
+ */
+/*@{*/
+#define SWIZZLE_X 0
+#define SWIZZLE_Y 1
+#define SWIZZLE_Z 2
+#define SWIZZLE_W 3
+#define SWIZZLE_ZERO 4 /**< For SWZ instruction only */
+#define SWIZZLE_ONE 5 /**< For SWZ instruction only */
+#define SWIZZLE_NIL 7 /**< used during shader code gen (undefined value) */
+/*@}*/
+
+#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9))
+#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3)
+#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7)
+#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1)
+
+#define SWIZZLE_XYZW MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W)
+#define SWIZZLE_XXXX MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)
+#define SWIZZLE_YYYY MAKE_SWIZZLE4(SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y)
+#define SWIZZLE_ZZZZ MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)
+#define SWIZZLE_WWWW MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/**
+ * Writemask values, 1 bit per component.
+ */
+/*@{*/
+#define WRITEMASK_X 0x1
+#define WRITEMASK_Y 0x2
+#define WRITEMASK_XY 0x3
+#define WRITEMASK_Z 0x4
+#define WRITEMASK_XZ 0x5
+#define WRITEMASK_YZ 0x6
+#define WRITEMASK_XYZ 0x7
+#define WRITEMASK_W 0x8
+#define WRITEMASK_XW 0x9
+#define WRITEMASK_YW 0xa
+#define WRITEMASK_XYW 0xb
+#define WRITEMASK_ZW 0xc
+#define WRITEMASK_XZW 0xd
+#define WRITEMASK_YZW 0xe
+#define WRITEMASK_XYZW 0xf
+/*@}*/
+
+
+/**
+ * Condition codes
+ */
+/*@{*/
+#define COND_GT 1 /**< greater than zero */
+#define COND_EQ 2 /**< equal to zero */
+#define COND_LT 3 /**< less than zero */
+#define COND_UN 4 /**< unordered (NaN) */
+#define COND_GE 5 /**< greater than or equal to zero */
+#define COND_LE 6 /**< less than or equal to zero */
+#define COND_NE 7 /**< not equal to zero */
+#define COND_TR 8 /**< always true */
+#define COND_FL 9 /**< always false */
+/*@}*/
+
+
+/**
+ * Instruction precision for GL_NV_fragment_program
+ */
+/*@{*/
+#define FLOAT32 0x1
+#define FLOAT16 0x2
+#define FIXED12 0x4
+/*@}*/
+
+
+/**
+ * Saturation modes when storing values.
+ */
+/*@{*/
+#define SATURATE_OFF 0
+#define SATURATE_ZERO_ONE 1
+/*@}*/
+
+
+/**
+ * Per-component negation masks
+ */
+/*@{*/
+#define NEGATE_X 0x1
+#define NEGATE_Y 0x2
+#define NEGATE_Z 0x4
+#define NEGATE_W 0x8
+#define NEGATE_XYZ 0x7
+#define NEGATE_XYZW 0xf
+#define NEGATE_NONE 0x0
+/*@}*/
+
+
+/**
+ * Program instruction opcodes, for both vertex and fragment programs.
+ * \note changes to this opcode list must be reflected in t_vb_arbprogram.c
+ */
+typedef enum prog_opcode {
+ /* ARB_vp ARB_fp NV_vp NV_fp GLSL */
+ /*------------------------------------------*/
+ OPCODE_NOP = 0, /* X */
+ OPCODE_ABS, /* X X 1.1 X */
+ OPCODE_ADD, /* X X X X X */
+ OPCODE_AND, /* */
+ OPCODE_ARA, /* 2 */
+ OPCODE_ARL, /* X X */
+ OPCODE_ARL_NV, /* 2 */
+ OPCODE_ARR, /* 2 */
+ OPCODE_BGNLOOP, /* opt */
+ OPCODE_BGNSUB, /* opt */
+ OPCODE_BRA, /* 2 X */
+ OPCODE_BRK, /* 2 opt */
+ OPCODE_CAL, /* 2 2 */
+ OPCODE_CMP, /* X */
+ OPCODE_CONT, /* opt */
+ OPCODE_COS, /* X 2 X X */
+ OPCODE_DDX, /* X X */
+ OPCODE_DDY, /* X X */
+ OPCODE_DP2, /* 2 */
+ OPCODE_DP2A, /* 2 */
+ OPCODE_DP3, /* X X X X X */
+ OPCODE_DP4, /* X X X X X */
+ OPCODE_DPH, /* X X 1.1 */
+ OPCODE_DST, /* X X X X */
+ OPCODE_ELSE, /* X */
+ OPCODE_END, /* X X X X opt */
+ OPCODE_ENDIF, /* opt */
+ OPCODE_ENDLOOP, /* opt */
+ OPCODE_ENDSUB, /* opt */
+ OPCODE_EX2, /* X X 2 X X */
+ OPCODE_EXP, /* X X X */
+ OPCODE_FLR, /* X X 2 X X */
+ OPCODE_FRC, /* X X 2 X X */
+ OPCODE_IF, /* opt */
+ OPCODE_KIL, /* X */
+ OPCODE_KIL_NV, /* X X */
+ OPCODE_LG2, /* X X 2 X X */
+ OPCODE_LIT, /* X X X X */
+ OPCODE_LOG, /* X X X */
+ OPCODE_LRP, /* X X */
+ OPCODE_MAD, /* X X X X X */
+ OPCODE_MAX, /* X X X X X */
+ OPCODE_MIN, /* X X X X X */
+ OPCODE_MOV, /* X X X X X */
+ OPCODE_MUL, /* X X X X X */
+ OPCODE_NOISE1, /* X */
+ OPCODE_NOISE2, /* X */
+ OPCODE_NOISE3, /* X */
+ OPCODE_NOISE4, /* X */
+ OPCODE_NOT, /* */
+ OPCODE_NRM3, /* */
+ OPCODE_NRM4, /* */
+ OPCODE_OR, /* */
+ OPCODE_PK2H, /* X */
+ OPCODE_PK2US, /* X */
+ OPCODE_PK4B, /* X */
+ OPCODE_PK4UB, /* X */
+ OPCODE_POW, /* X X X X */
+ OPCODE_POPA, /* 3 */
+ OPCODE_PRINT, /* X X */
+ OPCODE_PUSHA, /* 3 */
+ OPCODE_RCC, /* 1.1 */
+ OPCODE_RCP, /* X X X X X */
+ OPCODE_RET, /* 2 2 */
+ OPCODE_RFL, /* X X */
+ OPCODE_RSQ, /* X X X X X */
+ OPCODE_SCS, /* X */
+ OPCODE_SEQ, /* 2 X X */
+ OPCODE_SFL, /* 2 X */
+ OPCODE_SGE, /* X X X X X */
+ OPCODE_SGT, /* 2 X X */
+ OPCODE_SIN, /* X 2 X X */
+ OPCODE_SLE, /* 2 X X */
+ OPCODE_SLT, /* X X X X X */
+ OPCODE_SNE, /* 2 X X */
+ OPCODE_SSG, /* 2 */
+ OPCODE_STR, /* 2 X */
+ OPCODE_SUB, /* X X 1.1 X X */
+ OPCODE_SWZ, /* X X */
+ OPCODE_TEX, /* X 3 X X */
+ OPCODE_TXB, /* X 3 X */
+ OPCODE_TXD, /* X X */
+ OPCODE_TXL, /* 3 2 X */
+ OPCODE_TXP, /* X X */
+ OPCODE_TXP_NV, /* 3 X */
+ OPCODE_TRUNC, /* X */
+ OPCODE_UP2H, /* X */
+ OPCODE_UP2US, /* X */
+ OPCODE_UP4B, /* X */
+ OPCODE_UP4UB, /* X */
+ OPCODE_X2D, /* X */
+ OPCODE_XOR, /* */
+ OPCODE_XPD, /* X X X */
+ MAX_OPCODE
+} gl_inst_opcode;
+
+
+/**
+ * Number of bits for the src/dst register Index field.
+ * This limits the size of temp/uniform register files.
+ */
+#define INST_INDEX_BITS 10
+
+
+/**
+ * Instruction source register.
+ */
+struct prog_src_register
+{
+ GLuint File:4; /**< One of the PROGRAM_* register file values. */
+ GLint Index:(INST_INDEX_BITS+1); /**< Extra bit here for sign bit.
+ * May be negative for relative addressing.
+ */
+ GLuint Swizzle:12;
+ GLuint RelAddr:1;
+
+ /** Take the component-wise absolute value */
+ GLuint Abs:1;
+
+ /**
+ * Post-Abs negation.
+ * This will either be NEGATE_NONE or NEGATE_XYZW, except for the SWZ
+ * instruction which allows per-component negation.
+ */
+ GLuint Negate:4;
+};
+
+
+/**
+ * Instruction destination register.
+ */
+struct prog_dst_register
+{
+ GLuint File:4; /**< One of the PROGRAM_* register file values */
+ GLuint Index:INST_INDEX_BITS; /**< Unsigned, never negative */
+ GLuint WriteMask:4;
+ GLuint RelAddr:1;
+
+ /**
+ * \name Conditional destination update control.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ /*@{*/
+ /**
+ * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT,
+ * NE, TR, or UN). Dest reg is only written to if the matching
+ * (swizzled) condition code value passes. When a conditional update mask
+ * is not specified, this will be \c COND_TR.
+ */
+ GLuint CondMask:4;
+
+ /**
+ * Condition code swizzle value.
+ */
+ GLuint CondSwizzle:12;
+
+ /**
+ * Selects the condition code register to use for conditional destination
+ * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only
+ * condition code register 0 is available. In NV_vertex_program3 mode,
+ * condition code registers 0 and 1 are available.
+ */
+ GLuint CondSrc:1;
+ /*@}*/
+};
+
+
+/**
+ * Vertex/fragment program instruction.
+ */
+struct prog_instruction
+{
+ gl_inst_opcode Opcode;
+ struct prog_src_register SrcReg[3];
+ struct prog_dst_register DstReg;
+
+ /**
+ * Indicates that the instruction should update the condition code
+ * register.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ GLuint CondUpdate:1;
+
+ /**
+ * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the
+ * condition code register that is to be updated.
+ *
+ * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition
+ * code register 0 is available. In GL_NV_vertex_program3 mode, condition
+ * code registers 0 and 1 are available.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2,
+ * NV_vertex_program2_option.
+ */
+ GLuint CondDst:1;
+
+ /**
+ * Saturate each value of the vectored result to the range [0,1] or the
+ * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is
+ * only available in NV_fragment_program2 mode.
+ * Value is one of the SATURATE_* tokens.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
+ */
+ GLuint SaturateMode:2;
+
+ /**
+ * Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
+ *
+ * \since
+ * NV_fragment_program, NV_fragment_program_option.
+ */
+ GLuint Precision:3;
+
+ /**
+ * \name Extra fields for TEX, TXB, TXD, TXL, TXP instructions.
+ */
+ /*@{*/
+ /** Source texture unit. */
+ GLuint TexSrcUnit:5;
+
+ /** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
+ GLuint TexSrcTarget:3;
+
+ /** True if tex instruction should do shadow comparison */
+ GLuint TexShadow:1;
+ /*@}*/
+
+ /**
+ * For BRA and CAL instructions, the location to jump to.
+ * For BGNLOOP, points to ENDLOOP (and vice-versa).
+ * For BRK, points to BGNLOOP (which points to ENDLOOP).
+ * For IF, points to ELSE or ENDIF.
+ * For ELSE, points to ENDIF.
+ */
+ GLint BranchTarget;
+
+ /** for debugging purposes */
+ const char *Comment;
+
+ /** Arbitrary data. Used for OPCODE_PRINT and some drivers */
+ void *Data;
+
+ /** for driver use (try to remove someday) */
+ GLint Aux;
+};
+
+
+extern void
+_mesa_init_instructions(struct prog_instruction *inst, GLuint count);
+
+extern struct prog_instruction *
+_mesa_alloc_instructions(GLuint numInst);
+
+extern struct prog_instruction *
+_mesa_realloc_instructions(struct prog_instruction *oldInst,
+ GLuint numOldInst, GLuint numNewInst);
+
+extern struct prog_instruction *
+_mesa_copy_instructions(struct prog_instruction *dest,
+ const struct prog_instruction *src, GLuint n);
+
+extern void
+_mesa_free_instructions(struct prog_instruction *inst, GLuint count);
+
+extern GLuint
+_mesa_num_inst_src_regs(gl_inst_opcode opcode);
+
+extern GLuint
+_mesa_num_inst_dst_regs(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_is_tex_instruction(gl_inst_opcode opcode);
+
+extern GLboolean
+_mesa_check_soa_dependencies(const struct prog_instruction *inst);
+
+extern const char *
+_mesa_opcode_string(gl_inst_opcode opcode);
+
+
+#endif /* PROG_INSTRUCTION_H */
--- /dev/null
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/* DO NOT EDIT mesa_codegen.h. It is a generated file produced
+ * from mesa_codegen.brg and will be overwritten.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdio.h>
+
+/* Everything before the first %% is pasted at the start of the
+ * mesa_codegen.h header file.
+ */
+
+#include "ir_to_mesa.h"
+
+#define MBTREE_TYPE struct mbtree
+
+%%
+%term assign
+%term reference_vec4
+%term add_vec4_vec4
+%term sub_vec4_vec4
+%term mul_vec4_vec4
+%term div_vec4_vec4
+%term dp4_vec4_vec4
+%term dp3_vec4_vec4
+%term dp2_vec4_vec4
+%term sqrt_vec4
+%term swizzle_vec4
+
+%start stmt
+
+alloced_vec4: reference_vec4 0
+
+vec4: alloced_vec4 0
+alloced_vec4: vec4 1
+{
+ /* FINISHME */
+ tree->v->get_temp(tree);
+}
+
+stmt: assign(alloced_vec4, alloced_vec4) 1
+{
+ ir_to_mesa_emit_op1(tree, OPCODE_MOV,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg);
+}
+
+vec4: swizzle_vec4(alloced_vec4) 1
+{
+ ir_to_mesa_src_reg reg = tree->left->src_reg;
+ int swiz[4];
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ swiz[i] = GET_SWZ(tree->src_reg.swizzle, i);
+ if (swiz[i] >= SWIZZLE_X && swiz[i] <= SWIZZLE_Y) {
+ swiz[i] = GET_SWZ(tree->left->src_reg.swizzle, swiz[i]);
+ }
+ }
+ reg.swizzle = MAKE_SWIZZLE4(swiz[0], swiz[1], swiz[2], swiz[3]);
+
+ ir_to_mesa_emit_op1(tree, OPCODE_MOV,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ reg);
+}
+
+vec4: add_vec4_vec4(alloced_vec4, alloced_vec4) 1
+{
+ ir_to_mesa_emit_op2(tree, OPCODE_ADD,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg,
+ tree->right->src_reg);
+}
+
+vec4: sub_vec4_vec4(alloced_vec4, alloced_vec4) 1
+{
+ ir_to_mesa_emit_op2(tree, OPCODE_SUB,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg,
+ tree->right->src_reg);
+}
+
+vec4: mul_vec4_vec4(alloced_vec4, alloced_vec4) 1
+{
+ ir_to_mesa_emit_op2(tree, OPCODE_MUL,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg,
+ tree->right->src_reg);
+}
+
+vec4: dp4_vec4_vec4(alloced_vec4, alloced_vec4) 1
+{
+ ir_to_mesa_emit_op2(tree, OPCODE_DP4,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg,
+ tree->right->src_reg);
+ tree->src_reg.swizzle = SWIZZLE_XXXX;
+}
+
+vec4: dp3_vec4_vec4(alloced_vec4, alloced_vec4) 1
+{
+ ir_to_mesa_emit_op2(tree, OPCODE_DP3,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg,
+ tree->right->src_reg);
+ tree->src_reg.swizzle = SWIZZLE_XXXX;
+}
+
+
+vec4: dp2_vec4_vec4(alloced_vec4, alloced_vec4) 1
+{
+ ir_to_mesa_emit_op2(tree, OPCODE_DP2,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg,
+ tree->right->src_reg);
+ tree->src_reg.swizzle = SWIZZLE_XXXX;
+}
+
+vec4: div_vec4_vec4(alloced_vec4, alloced_vec4) 1
+{
+ /* FINISHME: Mesa RCP only uses the X channel, this node is for vec4. */
+ ir_to_mesa_emit_op1(tree, OPCODE_RCP,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->right->src_reg);
+
+ ir_to_mesa_emit_op2(tree, OPCODE_MUL,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->src_reg,
+ tree->left->src_reg);
+}
+
+vec4: sqrt_vec4(alloced_vec4) 1
+{
+ /* FINISHME: Mesa RSQ only uses the X channel, this node is for vec4. */
+ ir_to_mesa_emit_op1(tree, OPCODE_RSQ,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->left->src_reg);
+
+ ir_to_mesa_emit_op1(tree, OPCODE_RCP,
+ ir_to_mesa_dst_reg_from_src(tree->src_reg),
+ tree->src_reg);
+}
+
+%%
*/
#include <GL/gl.h>
+#include "main/mtypes.h"
/**
* Based on gl_shader in Mesa's mtypes.h.
};
-typedef int gl_register_file;
typedef int gl_state_index;
#define STATE_LENGTH 5