Initial 965 GLSL support

This commit is contained in:
Zou Nan hai 2007-04-12 09:43:00 +08:00
parent bce7043ebc
commit 35707dbe57
15 changed files with 283 additions and 82 deletions

View file

@ -42,7 +42,7 @@
* 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;
@ -51,7 +51,7 @@ struct brw_clip_prog_key {
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;

View file

@ -44,6 +44,8 @@
#include "api_noop.h"
#include "vtxfmt.h"
#include "shader/shader_api.h"
/***************************************
* Mesa's Driver Functions
***************************************/
@ -60,12 +62,57 @@ static const struct dri_extension brw_extensions[] =
{ 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 );
}

View file

@ -860,5 +860,6 @@ void brw_math_invert( struct brw_compile *p,
struct brw_reg dst,
struct brw_reg src);
void brw_set_src1( struct brw_instruction *insn,
struct brw_reg reg );
#endif

View file

@ -164,7 +164,7 @@ static void brw_set_src0( struct brw_instruction *insn,
}
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);

View file

@ -40,11 +40,11 @@
#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 {

View file

@ -45,12 +45,12 @@
#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;
};

View file

@ -67,6 +67,7 @@ struct brw_vs_compile {
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];

View file

@ -134,6 +134,17 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
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:
@ -213,57 +224,68 @@ static void unalias2( struct brw_vs_compile *c,
}
}
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));
/* 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);
emit_sop(p, dst, arg0, arg1, BRW_CONDITIONAL_L);
}
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,
@ -592,9 +614,13 @@ static struct brw_reg get_reg( struct brw_vs_compile *c,
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];
@ -891,17 +917,46 @@ static void emit_vertex_write( struct brw_vs_compile *c)
}
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");
@ -924,6 +979,7 @@ void brw_vs_emit( struct brw_vs_compile *c )
/* 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]);
@ -934,7 +990,6 @@ void brw_vs_emit( struct brw_vs_compile *c )
*/
dst = get_dst(c, inst->DstReg);
switch (inst->Opcode) {
case OPCODE_ABS:
brw_MOV(p, dst, brw_abs(args[0]));
@ -1003,12 +1058,25 @@ void brw_vs_emit( struct brw_vs_compile *c )
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;
@ -1021,21 +1089,45 @@ void brw_vs_emit( struct brw_vs_compile *c )
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);
}

View file

@ -855,7 +855,7 @@ static struct ureg calculate_light_attenuation( struct tnl_program *p,
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);

View file

@ -66,7 +66,11 @@ GLuint brw_wm_nr_args( GLuint opcode )
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:

View file

@ -343,7 +343,24 @@ static void emit_lrp( 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 )
{
GLuint i;
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(), cond, 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_slt( struct brw_compile *p,
const struct brw_reg *dst,
@ -351,39 +368,53 @@ static void emit_slt( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
GLuint i;
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_MOV(p, dst[i], brw_imm_f(1.0));
brw_set_predicate_control_flag_value(p, 0xff);
}
}
emit_sop(p, dst, mask, BRW_CONDITIONAL_L, arg0, arg1);
}
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);
}
/* Isn't this just the same as the above with the args swapped?
*/
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 )
{
GLuint i;
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);
}
}
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,
@ -543,8 +574,8 @@ static void emit_math1( struct brw_compile *p,
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]);
@ -1208,9 +1239,21 @@ void brw_wm_emit( struct brw_wm_compile *c )
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]);
@ -1231,7 +1274,8 @@ void brw_wm_emit( struct brw_wm_compile *c )
break;
default:
assert(0);
_mesa_printf("unsupport opcode %d in fragment program\n",
inst->opcode);
}
for (i = 0; i < 4; i++)

View file

@ -168,6 +168,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
case PROGRAM_PAYLOAD:
case PROGRAM_TEMPORARY:
case PROGRAM_OUTPUT:
case PROGRAM_VARYING:
break;
case PROGRAM_LOCAL_PARAM:
@ -179,6 +180,8 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
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;
@ -197,6 +200,7 @@ static const struct brw_wm_ref *pass0_get_reg( struct brw_wm_compile *c,
break;
case PROGRAM_STATE_VAR:
case PROGRAM_UNIFORM:
/* These may change from run to run:
*/
ref = get_param_ref(c, &plist->ParameterValues[idx][component] );

View file

@ -155,7 +155,11 @@ void brw_wm_pass1( struct brw_wm_compile *c )
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:
@ -257,7 +261,6 @@ void brw_wm_pass1( struct brw_wm_compile *c )
case OPCODE_DST:
case OPCODE_TXP:
default:
assert(0);
break;
}

View file

@ -81,6 +81,7 @@ int INTEL_DEBUG = (0);
#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
@ -180,6 +181,9 @@ const struct dri_extension card_extensions[] =
{ "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 }
};

View file

@ -1746,6 +1746,7 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var)
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;