#include "util/u_math.h"
-#include "intel_batchbuffer.h"
-
+#include "brw_screen.h"
+#include "brw_batchbuffer.h"
#include "brw_defines.h"
#include "brw_context.h"
#include "brw_eu.h"
#include "brw_util.h"
#include "brw_state.h"
+#include "brw_pipe_rast.h"
#include "brw_clip.h"
#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));
c.func.single_program_flow = 1;
+ c.chipset = brw->chipset;
c.key = *key;
- c.need_ff_sync = BRW_IS_IGDNG(brw);
+ c.need_ff_sync = c.chipset.is_igdng;
/* Need to locate the two positions present in vertex + header.
* These are currently hardcoded:
*/
c.header_position_offset = ATTR_SIZE;
- if (BRW_IS_IGDNG(brw))
+ if (c.chipset.is_igdng)
delta = 3 * REG_SIZE;
else
delta = REG_SIZE;
- for (i = 0; i < VERT_RESULT_MAX; i++)
- if (c.key.attrs & (1<<i)) {
- c.offset[i] = delta;
- delta += ATTR_SIZE;
- }
+ c.offset_hpos = delta + c.key.output_hpos * ATTR_SIZE;
+
+ 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;
- c.nr_attrs = util_count_bits(c.key.attrs);
+ 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;
- memset(&key, 0, sizeof(key));
-
- /* Populate the key:
+ /* Populate the key, starting from the almost-complete version from
+ * the rast state.
*/
+
+ /* PIPE_NEW_RAST */
+ 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.attrs = brw->vs.prog_data->outputs_written;
- /* PIPE_NEW_RAST */
- key.do_flat_shading = brw->rast.base.flatshade;
- /* PIPE_NEW_UCP */
- key.nr_userclip = brw->nr_ucp;
+ key.nr_attrs = brw->vs.prog_data->nr_outputs;
- if (BRW_IS_IGDNG(brw))
- key.clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
- else
- key.clip_mode = BRW_CLIPMODE_NORMAL;
+ /* PIPE_NEW_VS */
+ 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_RAST */
- if (key.primitive == PIPE_PRIM_TRIANGLES) {
- if (brw->rast->cull_mode = PIPE_WINDING_BOTH)
- key.clip_mode = BRW_CLIPMODE_REJECT_ALL;
- else {
- key.fill_ccw = CLIP_CULL;
- key.fill_cw = CLIP_CULL;
-
- if (!(brw->rast->cull_mode & PIPE_WINDING_CCW)) {
- key.fill_ccw = translate_fill(brw->rast.fill_ccw);
- }
-
- if (!(brw->rast->cull_mode & PIPE_WINDING_CW)) {
- key.fill_cw = translate_fill(brw->rast.fill_cw);
- }
-
- if (key.fill_cw != CLIP_FILL ||
- key.fill_ccw != CLIP_FILL) {
- key.do_unfilled = 1;
- key.clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
- }
-
- key.offset_ccw = brw->rast.offset_ccw;
- key.offset_cw = brw->rast.offset_cw;
-
- if (brw->rast.light_twoside &&
- key.fill_cw != CLIP_CULL)
- key.copy_bfc_cw = 1;
-
- if (brw->rast.light_twoside &&
- key.fill_ccw != CLIP_CULL)
- key.copy_bfc_ccw = 1;
- }
- }
- }
+ /* PIPE_NEW_CLIP */
+ key.nr_userclip = brw->curr.ucp.nr;
+
+ /* 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;
- 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 );
+ return PIPE_OK;
}
const struct brw_tracked_state brw_clip_prog = {
.dirty = {
.mesa = (PIPE_NEW_RAST |
- PIPE_NEW_UCP),
+ PIPE_NEW_CLIP),
.brw = (BRW_NEW_REDUCED_PRIMITIVE),
.cache = CACHE_NEW_VS_PROG
},