#define BACK_UNFILLED_BIT 0x2
-static void compile_clip_prog( struct brw_context *brw,
- struct brw_clip_prog_key *key )
+static enum pipe_error
+compile_clip_prog( struct brw_context *brw,
+ struct brw_clip_prog_key *key,
+ struct brw_winsys_buffer **bo_out )
{
+ enum pipe_error ret;
struct brw_clip_compile c;
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;
- }
+ c.offset_hpos = delta + c.key.output_hpos * ATTR_SIZE;
- /* XXX: c.nr_attrs is very redundant:
- */
- c.nr_attrs = c.key.nr_attrs;
+ if (c.key.output_color0 != BRW_OUTPUT_NOT_PRESENT)
+ c.offset_color0 = delta + c.key.output_color0 * ATTR_SIZE;
+
+ if (c.key.output_color1 != BRW_OUTPUT_NOT_PRESENT)
+ c.offset_color1 = delta + c.key.output_color1 * ATTR_SIZE;
+
+ if (c.key.output_bfc0 != BRW_OUTPUT_NOT_PRESENT)
+ c.offset_bfc0 = delta + c.key.output_bfc0 * ATTR_SIZE;
+
+ if (c.key.output_bfc1 != BRW_OUTPUT_NOT_PRESENT)
+ c.offset_bfc1 = delta + c.key.output_bfc1 * ATTR_SIZE;
+
+ if (c.key.output_edgeflag != BRW_OUTPUT_NOT_PRESENT)
+ 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? */
+ c.nr_regs = (c.key.nr_attrs + 1) / 2 + 3; /* are vertices packed, or reg-aligned? */
else
- c.nr_regs = (c.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
+ c.nr_regs = (c.key.nr_attrs + 1) / 2 + 1; /* are vertices packed, or reg-aligned? */
c.nr_bytes = c.nr_regs * REG_SIZE;
break;
default:
assert(0);
- return;
+ return PIPE_ERROR_BAD_INPUT;
}
/* get the program
*/
- program = brw_get_program(&c.func, &program_size);
+ ret = brw_get_program(&c.func, &program, &program_size);
+ if (ret)
+ return ret;
/* Upload
*/
- brw->sws->bo_unreference(brw->clip.prog_bo);
- brw->clip.prog_bo = brw_upload_cache( &brw->cache,
- BRW_CLIP_PROG,
- &c.key, sizeof(c.key),
- NULL, 0,
- program, program_size,
- &c.prog_data,
- &brw->clip.prog_data );
+ ret = brw_upload_cache( &brw->cache,
+ BRW_CLIP_PROG,
+ &c.key, sizeof(c.key),
+ NULL, 0,
+ program, program_size,
+ &c.prog_data,
+ &brw->clip.prog_data,
+ bo_out );
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}
/* Calculate interpolants for triangle and line rasterization.
*/
-static void upload_clip_prog(struct brw_context *brw)
+static enum pipe_error
+upload_clip_prog(struct brw_context *brw)
{
+ 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;
+
/* 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;
+ key.output_edgeflag = vs->output_edgeflag;
/* PIPE_NEW_CLIP */
key.nr_userclip = brw->curr.ucp.nr;
- brw->sws->bo_unreference(brw->clip.prog_bo);
- brw->clip.prog_bo = brw_search_cache(&brw->cache, BRW_CLIP_PROG,
- &key, sizeof(key),
- NULL, 0,
- &brw->clip.prog_data);
- if (brw->clip.prog_bo == NULL)
- compile_clip_prog( brw, &key );
+ /* Already cached?
+ */
+ if (brw_search_cache(&brw->cache, BRW_CLIP_PROG,
+ &key, sizeof(key),
+ NULL, 0,
+ &brw->clip.prog_data,
+ &brw->clip.prog_bo))
+ return PIPE_OK;
+
+ /* Compile new program:
+ */
+ ret = compile_clip_prog( brw, &key, &brw->clip.prog_bo );
+ if (ret)
+ return ret;
+
+ return PIPE_OK;
}