const GLuint *program;
GLuint program_size;
GLuint delta;
- GLuint i;
memset(&c, 0, sizeof(c));
else
delta = REG_SIZE;
- /* XXX: c.offset is now pretty redundant:
- */
- for (i = 0; i < c.key.nr_attrs; i++) {
- c.offset[i] = delta;
- delta += ATTR_SIZE;
- }
-
/* XXX: c.nr_attrs is very redundant:
*/
c.nr_attrs = c.key.nr_attrs;
+
+ c.offset_hpos = delta + c.key.output_hpos * ATTR_SIZE;
+
+ if (c.key.output_color0)
+ c.offset_color0 = delta + c.key.output_color0 * ATTR_SIZE;
+
+ if (c.key.output_color1)
+ c.offset_color1 = delta + c.key.output_color1 * ATTR_SIZE;
+
+ if (c.key.output_bfc0)
+ c.offset_bfc0 = delta + c.key.output_bfc0 * ATTR_SIZE;
+
+ if (c.key.output_bfc1)
+ c.offset_bfc1 = delta + c.key.output_bfc1 * ATTR_SIZE;
+
+ if (c.key.output_edgeflag)
+ c.offset_edgeflag = delta + c.key.output_edgeflag * ATTR_SIZE;
if (BRW_IS_IGDNG(brw))
c.nr_regs = (c.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
static enum pipe_error
upload_clip_prog(struct brw_context *brw)
{
- enum pipe_error ret;
+ const struct brw_vertex_shader *vs = brw->curr.vertex_shader;
struct brw_clip_prog_key key;
+ enum pipe_error ret;
/* Populate the key, starting from the almost-complete version from
* the rast state.
*/
/* PIPE_NEW_RAST */
- memcpy(&key, &brw->curr.rast->clip_key, sizeof key);
-
+ key = brw->curr.rast->clip_key;
+
/* BRW_NEW_REDUCED_PRIMITIVE */
key.primitive = brw->reduced_primitive;
+ /* XXX: if edgeflag is moved to a proper TGSI vs output, can remove
+ * dependency on CACHE_NEW_VS_PROG
+ */
+ /* CACHE_NEW_VS_PROG */
+ key.nr_attrs = brw->vs.prog_data->nr_outputs;
+ key.output_edgeflag = brw->vs.prog_data->output_edgeflag;
+
/* PIPE_NEW_VS */
- key.nr_attrs = brw->curr.vertex_shader->info.file_max[TGSI_FILE_OUTPUT] + 1;
+ key.output_hpos = vs->output_hpos;
+ key.output_color0 = vs->output_color0;
+ key.output_color1 = vs->output_color1;
+ key.output_bfc0 = vs->output_bfc0;
+ key.output_bfc1 = vs->output_bfc1;
/* PIPE_NEW_CLIP */
key.nr_userclip = brw->curr.ucp.nr;
* up polygon offset and flatshading at this point:
*/
struct brw_clip_prog_key {
- GLuint nr_attrs:5;
+ GLuint nr_attrs:6;
GLuint primitive:4;
GLuint nr_userclip:3;
GLuint do_flat_shading:1;
GLuint copy_bfc_cw:1;
GLuint copy_bfc_ccw:1;
GLuint clip_mode:3;
- GLuint pad1:7;
+ GLuint output_hpos:6; /* not always zero? */
+
+ GLuint output_color0:6;
+ GLuint output_color1:6;
+ GLuint output_bfc0:6;
+ GLuint output_bfc1:6;
+ GLuint output_edgeflag:6;
+ GLuint pad1:2;
GLfloat offset_factor;
GLfloat offset_units;
GLuint last_mrf;
GLuint header_position_offset;
- GLuint offset[PIPE_MAX_SHADER_OUTPUTS];
GLboolean need_ff_sync;
GLuint nr_color_attrs;
GLuint offset_color1;
GLuint offset_bfc0;
GLuint offset_bfc1;
-
+
+ GLuint offset_hpos;
GLuint offset_edgeflag;
};
struct brw_instruction *is_neg2 = NULL;
struct brw_instruction *not_culled;
struct brw_reg v1_null_ud = retype(vec1(brw_null_reg()), BRW_REGISTER_TYPE_UD);
- const int hpos = 0; /* XXX: position not always first element */
brw_MOV(p, get_addr_reg(vtx0), brw_address(c->reg.vertex[0]));
brw_MOV(p, get_addr_reg(vtx1), brw_address(c->reg.vertex[1]));
/* dp = DP4(vtx->position, plane)
*/
- brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset[hpos]), c->reg.plane_equation);
+ brw_DP4(p, vec4(c->reg.dp0), deref_4f(vtx0, c->offset_hpos), c->reg.plane_equation);
/* if (IS_NEGATIVE(dp1))
*/
brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
- brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset[hpos]), c->reg.plane_equation);
+ brw_DP4(p, vec4(c->reg.dp1), deref_4f(vtx1, c->offset_hpos), c->reg.plane_equation);
is_negative = brw_IF(p, BRW_EXECUTE_1);
{
/*
/* IS_NEGATIVE(prev) */
brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
- brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
+ brw_DP4(p, vec4(c->reg.dpPrev), deref_4f(vtxPrev, c->offset_hpos), c->reg.plane_equation);
prev_test = brw_IF(p, BRW_EXECUTE_1);
{
/* IS_POSITIVE(next)
*/
brw_set_conditionalmod(p, BRW_CONDITIONAL_GE);
- brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
+ brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset_hpos), c->reg.plane_equation);
next_test = brw_IF(p, BRW_EXECUTE_1);
{
/* IS_NEGATIVE(next)
*/
brw_set_conditionalmod(p, BRW_CONDITIONAL_L);
- brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset[VERT_RESULT_HPOS]), c->reg.plane_equation);
+ brw_DP4(p, vec4(c->reg.dp), deref_4f(vtx, c->offset_hpos), c->reg.plane_equation);
next_test = brw_IF(p, BRW_EXECUTE_1);
{
/* Going out of bounds. Avoid division by zero as we
brw_MOV(p, get_addr_reg(vt0), brw_address(c->reg.vertex[0]));
brw_MOV(p, get_addr_reg(vt1), brw_address(c->reg.vertex[1]));
brw_MOV(p, get_addr_reg(vt2), brw_address(c->reg.vertex[2]));
- brw_MOV(p, v0, deref_4f(vt0, c->offset[VERT_RESULT_HPOS]));
- brw_MOV(p, v1, deref_4f(vt1, c->offset[VERT_RESULT_HPOS]));
- brw_MOV(p, v2, deref_4f(vt2, c->offset[VERT_RESULT_HPOS]));
+ brw_MOV(p, v0, deref_4f(vt0, c->offset_hpos));
+ brw_MOV(p, v1, deref_4f(vt1, c->offset_hpos));
+ brw_MOV(p, v2, deref_4f(vt2, c->offset_hpos));
brw_AND(p, c->reg.planemask, c->reg.planemask, brw_imm_ud(~0x3f));
/* test nearz, xmin, ymin plane */
struct brw_compile *p = &c->func;
struct brw_reg e = c->reg.tmp0;
struct brw_reg f = c->reg.tmp1;
- struct brw_reg v0 = byte_offset(c->reg.vertex[0], c->offset[VERT_RESULT_HPOS]);
- struct brw_reg v1 = byte_offset(c->reg.vertex[1], c->offset[VERT_RESULT_HPOS]);
- struct brw_reg v2 = byte_offset(c->reg.vertex[2], c->offset[VERT_RESULT_HPOS]);
+ struct brw_reg v0 = byte_offset(c->reg.vertex[0], c->offset_hpos);
+ struct brw_reg v1 = byte_offset(c->reg.vertex[1], c->offset_hpos);
+ struct brw_reg v2 = byte_offset(c->reg.vertex[2], c->offset_hpos);
struct brw_reg v0n = get_tmp(c);
/* Do we have any colors to copy?
*/
- if (c->nr_color_attrs == 0)
+ if ((c->offset_color0 == 0 || c->offset_bfc0 == 0) &&
+ (c->offset_color1 == 0 || c->offset_bfc1 == 0))
return;
/* In some wierd degnerate cases we can end up testing the
/* Fixup position. Extract from the original vertex and re-project
* to screen space:
*/
- brw_MOV(p, tmp, deref_4f(vert_addr, c->offset[VERT_RESULT_HPOS]));
+ brw_MOV(p, tmp, deref_4f(vert_addr, c->offset_hpos));
brw_clip_project_position(c, tmp);
brw_MOV(p, deref_4f(vert_addr, c->header_position_offset), tmp);
struct brw_vertex_shader {
const struct tgsi_token *tokens;
+ struct brw_winsys_buffer *const_buffer; /** Program constant buffer/surface */
+
struct tgsi_shader_info info;
- unsigned has_flow_control:1;
+ GLuint has_flow_control:1;
+ GLuint use_const_buffer:1;
+
+ /* Offsets of special vertex shader outputs required for clipping.
+ */
+ GLuint output_hpos:6; /* not always zero? */
+ GLuint output_color0:6;
+ GLuint output_color1:6;
+ GLuint output_bfc0:6;
+ GLuint output_bfc1:6;
+ GLuint output_edgeflag:6;
unsigned id;
- struct brw_winsys_buffer *const_buffer; /** Program constant buffer/surface */
- GLboolean use_const_buffer;
};
struct brw_fs_signature {
GLuint nr_params; /**< number of TGSI_FILE_CONSTANT's */
- GLboolean copy_edgeflag;
+ GLuint output_edgeflag;
+
GLboolean writes_psiz;
/* Used for calculating urb partitions:
const struct pipe_shader_state *shader )
{
struct brw_context *brw = brw_context(pipe);
+ struct brw_vertex_shader *vs;
+ unsigned i;
- struct brw_vertex_shader *vs = CALLOC_STRUCT(brw_vertex_shader);
+ vs = CALLOC_STRUCT(brw_vertex_shader);
if (vs == NULL)
return NULL;
/* Duplicate tokens, scan shader
*/
- vs->id = brw->program_id++;
- vs->has_flow_control = has_flow_control(&vs->info);
-
vs->tokens = tgsi_dup_tokens(shader->tokens);
if (vs->tokens == NULL)
goto fail;
tgsi_scan_shader(vs->tokens, &vs->info);
+
+ vs->id = brw->program_id++;
+ vs->has_flow_control = has_flow_control(&vs->info);
+
+ for (i = 0; i < vs->info.num_outputs; i++) {
+ int index = vs->info.output_semantic_index[i];
+ switch (vs->info.output_semantic_name[i]) {
+ case TGSI_SEMANTIC_POSITION:
+ vs->output_hpos = i;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ if (index == 0)
+ vs->output_color0 = i;
+ else
+ vs->output_color1 = i;
+ break;
+ case TGSI_SEMANTIC_BCOLOR:
+ if (index == 0)
+ vs->output_bfc0 = i;
+ else
+ vs->output_bfc1 = i;
+ break;
+#if 0
+ case TGSI_SEMANTIC_EDGEFLAG:
+ vs->output_edgeflag = i;
+ break;
+#endif
+ }
+ }
+
+
/* Done:
*/
c.prog_data.nr_outputs = vp->info.num_outputs;
c.prog_data.nr_inputs = vp->info.num_inputs;
- c.prog_data.copy_edgeflag = c.key.copy_edgeflag;
+
+ /* XXX: we want edgeflag handling to be integrated to the vertex
+ * shader, but are currently faking the edgeflag output:
+ */
+ if (c.key.copy_edgeflag) {
+ c.prog_data.output_edgeflag = c.prog_data.nr_outputs;
+ c.prog_data.nr_outputs++;
+ }
+ else {
+ c.prog_data.output_edgeflag = ~0;
+ }
+
if (1)
tgsi_dump(c.vp->tokens, 0);
unsigned vs_output )
{
struct brw_vertex_shader *vs = c->vp;
- unsigned semantic = vs->info.output_semantic_name[vs_output];
- unsigned index = vs->info.output_semantic_index[vs_output];
- return (semantic == TGSI_SEMANTIC_POSITION &&
- index == 0);
+ if (vs_output == c->prog_data.output_edgeflag) {
+ return FALSE;
+ }
+ else {
+ unsigned semantic = vs->info.output_semantic_name[vs_output];
+ unsigned index = vs->info.output_semantic_index[vs_output];
+
+ return (semantic == TGSI_SEMANTIC_POSITION &&
+ index == 0);
+ }
}
unsigned *fs_input_slot )
{
struct brw_vertex_shader *vs = c->vp;
- unsigned semantic = vs->info.output_semantic_name[vs_output];
- unsigned index = vs->info.output_semantic_index[vs_output];
- unsigned i;
- for (i = 0; i < c->key.fs_signature.nr_inputs; i++) {
- if (c->key.fs_signature.input[i].semantic == semantic &&
+ if (vs_output == c->prog_data.output_edgeflag) {
+ *fs_input_slot = c->key.fs_signature.nr_inputs;
+ return TRUE;
+ }
+ else {
+ unsigned semantic = vs->info.output_semantic_name[vs_output];
+ unsigned index = vs->info.output_semantic_index[vs_output];
+ unsigned i;
+
+ for (i = 0; i < c->key.fs_signature.nr_inputs; i++) {
+ if (c->key.fs_signature.input[i].semantic == semantic &&
c->key.fs_signature.input[i].semantic_index == index) {
- *fs_input_slot = i;
- return TRUE;
+ *fs_input_slot = i;
+ return TRUE;
+ }
}
}
/* XXX: need to access vertex output semantics here:
*/
- for (i = 0; i < c->prog_data.nr_outputs; i++) {
+ for (i = 0; i < c->nr_outputs; i++) {
unsigned slot;
/* XXX: Put output position in slot zero always. Clipper, etc,
GLuint len_vertext_header = 2;
if (c->key.copy_edgeflag) {
- assert(0);
brw_MOV(p,
- get_reg(c, TGSI_FILE_OUTPUT, 0),
- get_reg(c, TGSI_FILE_INPUT, 0));
+ get_reg(c, TGSI_FILE_OUTPUT, c->prog_data.output_edgeflag),
+ brw_imm_f(1));
}
/* Build ndc coords */
assert(c->key.vp_nr_outputs >= 1);
c->prog_data.first_curbe_grf = c->key.nr_depth_regs * 2;
- c->prog_data.urb_read_length = c->key.vp_nr_outputs * 2;
+ c->prog_data.urb_read_length = (c->key.nr_inputs + 1) * 2;
c->prog_data.curb_read_length = c->nr_creg * 2;
/* Note this allocation: