* up polygon offset and flatshading at this point:
*/
struct brw_clip_prog_key {
- GLuint attrs:16;
+ GLuint attrs:32;
GLuint primitive:4;
GLuint nr_userclip:3;
GLuint do_flat_shading:1;
GLuint fill_ccw:2; /* includes cull information */
GLuint offset_cw:1;
GLuint offset_ccw:1;
- GLuint pad0:1;
+ GLuint pad0:17;
GLuint copy_bfc_cw:1;
GLuint copy_bfc_ccw:1;
#include "api_noop.h"
#include "vtxfmt.h"
+#include "shader/shader_api.h"
+
/***************************************
* Mesa's Driver Functions
***************************************/
{ NULL, NULL }
};
+static void brwLinkProgram(GLcontext *ctx, GLuint program)
+{
+ struct brw_context *brw = brw_context(ctx);
+ struct brw_vertex_program *vert_prog;
+ struct brw_fragment_program *frag_prog;
+ struct gl_shader_program *sh_prog;
+ _mesa_link_program(ctx, program);
+
+ sh_prog = _mesa_lookup_shader_program(ctx, program);
+ if (sh_prog) {
+ sh_prog->FragmentProgram =
+ _mesa_realloc(sh_prog->FragmentProgram,
+ sizeof(struct gl_fragment_program),
+ sizeof(struct brw_fragment_program));
+ frag_prog = (struct brw_fragment_program *)sh_prog->FragmentProgram;
+ frag_prog->id = brw->program_id++;
+ sh_prog->VertexProgram = _mesa_realloc(sh_prog->VertexProgram,
+ sizeof(struct gl_vertex_program),
+ sizeof(struct brw_vertex_program));
+ vert_prog = (struct brw_vertex_program *)sh_prog->VertexProgram;
+ vert_prog->id = brw->program_id++;
+ }
+}
+
+static void brwUseProgram(GLcontext *ctx, GLuint program)
+{
+ struct brw_context *brw = brw_context(ctx);
+ struct gl_shader_program *sh_prog;
+ _mesa_use_program(ctx, program);
+ sh_prog = ctx->Shader.CurrentProgram;
+ if (sh_prog) {
+ ctx->VertexProgram.Enabled = GL_TRUE;
+ ctx->FragmentProgram.Enabled = GL_TRUE;
+ brw->attribs.VertexProgram->Current = sh_prog->VertexProgram;
+ brw->attribs.FragmentProgram->Current = sh_prog->FragmentProgram;
+ brw->state.dirty.brw |= BRW_NEW_VERTEX_PROGRAM;
+ brw->state.dirty.brw |= BRW_NEW_FRAGMENT_PROGRAM;
+ }
+}
+static void brwInitProgFuncs( struct dd_function_table *functions )
+{
+ functions->UseProgram = brwUseProgram;
+ functions->LinkProgram = brwLinkProgram;
+}
static void brwInitDriverFunctions( struct dd_function_table *functions )
{
intelInitDriverFunctions( functions );
brwInitTextureFuncs( functions );
brwInitFragProgFuncs( functions );
+ brwInitProgFuncs( functions );
}
struct brw_reg dst,
struct brw_reg src);
-
+void brw_set_src1( struct brw_instruction *insn,
+ struct brw_reg reg );
#endif
}
-static void brw_set_src1( struct brw_instruction *insn,
+void brw_set_src1( struct brw_instruction *insn,
struct brw_reg reg )
{
assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
#define MAX_GS_VERTS (4)
struct brw_gs_prog_key {
+ GLuint attrs:32;
GLuint primitive:4;
- GLuint attrs:16;
GLuint hint_gs_always:1;
GLuint need_gs_prog:1;
- GLuint pad:10;
+ GLuint pad:26;
};
struct brw_gs_compile {
#define SF_UNFILLED_TRIS 3
struct brw_sf_prog_key {
+ GLuint attrs:32;
GLuint primitive:2;
GLuint do_twoside_color:1;
GLuint do_flat_shading:1;
- GLuint attrs:16;
GLuint frontface_ccw:1;
- GLuint pad:11;
+ GLuint pad:27;
};
struct brw_reg r1;
struct brw_reg regs[PROGRAM_ADDRESS+1][128];
struct brw_reg tmp;
+ struct brw_reg ret;
struct brw_reg userplane[6];
WRITEMASK_X);
reg++;
}
+
+ c->ret = brw_reg(BRW_GENERAL_REGISTER_FILE,
+ reg,
+ 0,
+ BRW_REGISTER_TYPE_D,
+ BRW_VERTICAL_STRIDE_8,
+ BRW_WIDTH_8,
+ BRW_HORIZONTAL_STRIDE_1,
+ BRW_SWIZZLE_XXXX,
+ WRITEMASK_X);
+ reg++;
/* Some opcodes need an internal temporary:
}
}
+static void emit_sop( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1,
+ GLuint cond)
+{
+ brw_push_insn_state(p);
+ brw_CMP(p, brw_null_reg(), cond, arg0, arg1);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_MOV(p, dst, brw_imm_f(1.0f));
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_MOV(p, dst, brw_imm_f(0.0f));
+ brw_pop_insn_state(p);
+}
+static void emit_seq( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_EQ);
+}
-
+static void emit_sne( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_NEQ);
+}
static void emit_slt( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- /* Could be done with an if/else/endif, but this method uses half
- * the instructions. Note that we are careful to reference the
- * arguments before writing the dest. That means we emit the
- * instructions in an odd order and have to play with the flag
- * values.
- */
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(1.0));
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
+}
- /* Where the test succeeded, overwite with zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(0.0));
- brw_pop_insn_state(p);
+static void emit_sle( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_LE);
}
+static void emit_sgt( struct brw_compile *p,
+ struct brw_reg dst,
+ struct brw_reg arg0,
+ struct brw_reg arg1 )
+{
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_G);
+}
static void emit_sge( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
struct brw_reg arg1 )
{
- brw_push_insn_state(p);
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0, arg1);
-
- /* Write all values to zero:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
- brw_MOV(p, dst, brw_imm_f(0));
-
- /* Where the test succeeded, overwite with 1:
- */
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
- brw_MOV(p, dst, brw_imm_f(1.0));
- brw_pop_insn_state(p);
+ emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_GE);
}
-
static void emit_max( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg arg0,
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
case PROGRAM_OUTPUT:
- case PROGRAM_STATE_VAR:
assert(c->regs[file][index].nr != 0);
return c->regs[file][index];
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_UNIFORM:
+ assert(c->regs[PROGRAM_STATE_VAR][index].nr != 0);
+ return c->regs[PROGRAM_STATE_VAR][index];
case PROGRAM_ADDRESS:
assert(index == 0);
return c->regs[file][index];
}
-
-
+static void
+post_vs_emit( struct brw_vs_compile *c, struct brw_instruction *end_inst )
+{
+ GLuint nr_insns = c->vp->program.Base.NumInstructions;
+ GLuint insn, target_insn;
+ struct prog_instruction *inst1, *inst2;
+ struct brw_instruction *brw_inst1, *brw_inst2;
+ int offset;
+ for (insn = 0; insn < nr_insns; insn++) {
+ inst1 = &c->vp->program.Base.Instructions[insn];
+ brw_inst1 = inst1->Data;
+ switch (inst1->Opcode) {
+ case OPCODE_CAL:
+ case OPCODE_BRA:
+ target_insn = inst1->BranchTarget;
+ inst2 = &c->vp->program.Base.Instructions[target_insn];
+ brw_inst2 = inst2->Data;
+ offset = brw_inst2 - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ case OPCODE_END:
+ offset = end_inst - brw_inst1;
+ brw_set_src1(brw_inst1, brw_imm_d(offset*16));
+ break;
+ default:
+ break;
+ }
+ }
+}
/* Emit the fragment program instructions here.
*/
-void brw_vs_emit( struct brw_vs_compile *c )
+void brw_vs_emit(struct brw_vs_compile *c )
{
+#define MAX_IFSN 32
struct brw_compile *p = &c->func;
GLuint nr_insns = c->vp->program.Base.NumInstructions;
- GLuint insn;
-
+ GLuint insn, if_insn = 0;
+ struct brw_instruction *end_inst;
+ struct brw_instruction *if_inst[32];
if (INTEL_DEBUG & DEBUG_VS) {
_mesa_printf("\n\n\nvs-emit:\n");
/* Get argument regs. SWZ is special and does this itself.
*/
+ inst->Data = &p->store[p->nr_insn];
if (inst->Opcode != OPCODE_SWZ)
for (i = 0; i < 3; i++)
args[i] = get_arg(c, inst->SrcReg[i]);
*/
dst = get_dst(c, inst->DstReg);
-
switch (inst->Opcode) {
case OPCODE_ABS:
brw_MOV(p, dst, brw_abs(args[0]));
case OPCODE_RSQ:
emit_math1(c, BRW_MATH_FUNCTION_RSQ, dst, args[0], BRW_MATH_PRECISION_FULL);
break;
+
+ case OPCODE_SEQ:
+ emit_seq(p, dst, args[0], args[1]);
+ break;
+ case OPCODE_SNE:
+ emit_sne(p, dst, args[0], args[1]);
+ break;
case OPCODE_SGE:
emit_sge(p, dst, args[0], args[1]);
break;
+ case OPCODE_SGT:
+ emit_sgt(p, dst, args[0], args[1]);
+ break;
case OPCODE_SLT:
emit_slt(p, dst, args[0], args[1]);
break;
+ case OPCODE_SLE:
+ emit_sle(p, dst, args[0], args[1]);
+ break;
case OPCODE_SUB:
brw_ADD(p, dst, args[0], negate(args[1]));
break;
case OPCODE_XPD:
emit_xpd(p, dst, args[0], args[1]);
break;
+ case OPCODE_IF:
+ assert(if_insn < MAX_IFSN);
+ if_inst[if_insn++] = brw_IF(p, BRW_EXECUTE_8);
+ break;
+ case OPCODE_ELSE:
+ brw_ELSE(p, if_inst[if_insn]);
+ break;
+ case OPCODE_ENDIF:
+ assert(if_insn > 0);
+ brw_ENDIF(p, if_inst[--if_insn]);
+ break;
+ case OPCODE_BRA:
+ brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ brw_set_predicate_control_flag_value(p, 0xFF);
+ break;
+ case OPCODE_CAL:
+ brw_ADD(p, c->ret, brw_ip_reg(), brw_imm_d(2*16));
+ inst->Data = &p->store[p->nr_insn];
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
+ case OPCODE_RET:
+ brw_MOV(p, brw_ip_reg(), c->ret);
case OPCODE_END:
+ brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
+ break;
case OPCODE_PRINT:
+ case OPCODE_BGNSUB:
+ case OPCODE_ENDSUB:
break;
default:
+ _mesa_printf("Unsupport opcode %d in vertex shader\n", inst->Opcode);
break;
}
release_tmps(c);
}
+ end_inst = &p->store[p->nr_insn];
emit_vertex_write(c);
-
+ post_vs_emit(c, end_inst);
}
-
-
-
-
-
struct ureg slt = get_temp(p);
emit_op2(p, OPCODE_DP3, spot, 0, ureg_negate(VPpli), spot_dir_norm);
- emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot);
+ emit_op2(p, OPCODE_SLT, slt, 0, spot, swizzle1(spot_dir_norm,W));
emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W));
emit_op2(p, OPCODE_MUL, att, 0, slt, spot);
case OPCODE_POW:
case OPCODE_SUB:
case OPCODE_SGE:
+ case OPCODE_SGT:
+ case OPCODE_SLE:
case OPCODE_SLT:
+ case OPCODE_SEQ:
+ case OPCODE_SNE:
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
}
}
}
-
-
-static void emit_slt( struct brw_compile *p,
+static void emit_sop( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
+ GLuint cond,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
for (i = 0; i < 4; i++) {
if (mask & (1<<i)) {
brw_MOV(p, dst[i], brw_imm_f(0));
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_L, arg0[i], arg1[i]);
+ brw_CMP(p, brw_null_reg(), cond, arg0[i], arg1[i]);
brw_MOV(p, dst[i], brw_imm_f(1.0));
brw_set_predicate_control_flag_value(p, 0xff);
}
}
}
-/* Isn't this just the same as the above with the args swapped?
- */
-static void emit_sge( struct brw_compile *p,
+static void emit_slt( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
- GLuint i;
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1);
+}
- for (i = 0; i < 4; i++) {
- if (mask & (1<<i)) {
- brw_MOV(p, dst[i], brw_imm_f(0));
- brw_CMP(p, brw_null_reg(), BRW_CONDITIONAL_GE, arg0[i], arg1[i]);
- brw_MOV(p, dst[i], brw_imm_f(1.0));
- brw_set_predicate_control_flag_value(p, 0xff);
- }
- }
+static void emit_sle( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_LE, arg0, arg1);
+}
+
+static void emit_sgt( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_G, arg0, arg1);
+}
+
+static void emit_sge( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_GE, arg0, arg1);
}
+static void emit_seq( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_EQ, arg0, arg1);
+}
+static void emit_sne( struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ const struct brw_reg *arg0,
+ const struct brw_reg *arg1 )
+{
+ emit_sop(p, dst, mask, BRW_CONDITIONAL_NEQ, arg0, arg1);
+}
static void emit_cmp( struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
const struct brw_reg *arg0 )
{
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
- function == BRW_MATH_FUNCTION_SINCOS);
+ //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
+ // function == BRW_MATH_FUNCTION_SINCOS);
brw_MOV(p, brw_message_reg(2), arg0[0]);
emit_slt(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_SLE:
+ emit_sle(p, dst, dst_flags, args[0], args[1]);
+ break;
+ case OPCODE_SGT:
+ emit_sgt(p, dst, dst_flags, args[0], args[1]);
+ break;
case OPCODE_SGE:
emit_sge(p, dst, dst_flags, args[0], args[1]);
break;
+ case OPCODE_SEQ:
+ emit_seq(p, dst, dst_flags, args[0], args[1]);
+ break;
+ case OPCODE_SNE:
+ emit_sne(p, dst, dst_flags, args[0], args[1]);
+ break;
case OPCODE_LIT:
emit_lit(p, dst, dst_flags, args[0]);
break;
default:
- assert(0);
+ _mesa_printf("unsupport opcode %d in fragment program\n",
+ inst->opcode);
}
for (i = 0; i < 4; i++)
case PROGRAM_PAYLOAD:
case PROGRAM_TEMPORARY:
case PROGRAM_OUTPUT:
+ case PROGRAM_VARYING:
break;
case PROGRAM_LOCAL_PARAM:
break;
case PROGRAM_STATE_VAR:
+ case PROGRAM_UNIFORM:
+ case PROGRAM_CONSTANT:
case PROGRAM_NAMED_PARAM: {
struct gl_program_parameter_list *plist = c->fp->program.Base.Parameters;
break;
case PROGRAM_STATE_VAR:
+ case PROGRAM_UNIFORM:
/* These may change from run to run:
*/
ref = get_param_ref(c, &plist->ParameterValues[idx][component] );
case OPCODE_SUB:
case OPCODE_SLT:
+ case OPCODE_SLE:
case OPCODE_SGE:
+ case OPCODE_SGT:
+ case OPCODE_SEQ:
+ case OPCODE_SNE:
case OPCODE_ADD:
case OPCODE_MAX:
case OPCODE_MIN:
case OPCODE_DST:
case OPCODE_TXP:
default:
- assert(0);
break;
}
#define need_GL_EXT_fog_coord
#define need_GL_EXT_multi_draw_arrays
#define need_GL_EXT_secondary_color
+#define need_GL_VERSION_2_0
#include "extension_helper.h"
#ifndef VERBOSE
{ "GL_MESA_ycbcr_texture", NULL },
{ "GL_NV_blend_square", NULL },
{ "GL_SGIS_generate_mipmap", NULL },
+ { "GL_ARB_shading_language_100", GL_VERSION_2_0_functions},
+ /* XXX not implement yet, to compile builtin glsl lib */
+ { "GL_ARB_draw_buffers", NULL },
{ NULL, NULL }
};
n->Store->File = PROGRAM_TEMPORARY;
n->Store->Size = _slang_sizeof_type_specifier(&n->Var->type.specifier);
+ A->program->NumTemporaries++;
assert(n->Store->Size > 0);
}
return n;