42,10 → 42,14 |
|
#include "brw/brw.h" |
#include "gen7_render.h" |
#include "gen4_common.h" |
#include "gen4_source.h" |
#include "gen4_vertex.h" |
#include "gen6_common.h" |
|
#define ALWAYS_INVALIDATE 0 |
#define ALWAYS_FLUSH 0 |
#define ALWAYS_STALL 0 |
|
#define NO_COMPOSITE 0 |
#define NO_COMPOSITE_SPANS 0 |
1022,28 → 1026,39 |
const struct sna_composite_op *op, |
uint16_t wm_binding_table) |
{ |
bool need_invalidate; |
bool need_flush; |
bool need_stall; |
|
assert(op->dst.bo->exec); |
|
gen7_emit_cc(sna, GEN7_BLEND(op->u.gen7.flags)); |
gen7_emit_sampler(sna, GEN7_SAMPLER(op->u.gen7.flags)); |
gen7_emit_sf(sna, GEN7_VERTEX(op->u.gen7.flags) >> 2); |
gen7_emit_wm(sna, GEN7_KERNEL(op->u.gen7.flags)); |
gen7_emit_vertex_elements(sna, op); |
need_invalidate = kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo); |
if (ALWAYS_INVALIDATE) |
need_invalidate = true; |
|
need_stall = gen7_emit_binding_table(sna, wm_binding_table); |
need_flush = |
sna->render_state.gen7.emit_flush && |
wm_binding_table & GEN7_READS_DST(op->u.gen7.flags); |
if (ALWAYS_FLUSH) |
need_flush = true; |
|
wm_binding_table &= ~1; |
|
need_stall = sna->render_state.gen7.surface_table != wm_binding_table; |
need_stall &= gen7_emit_drawing_rectangle(sna, op); |
if (ALWAYS_STALL) |
need_stall = true; |
|
if (ALWAYS_FLUSH || kgem_bo_is_dirty(op->src.bo) || kgem_bo_is_dirty(op->mask.bo)) { |
if (need_invalidate) { |
gen7_emit_pipe_invalidate(sna); |
kgem_clear_dirty(&sna->kgem); |
assert(op->dst.bo->exec); |
kgem_bo_mark_dirty(op->dst.bo); |
sna->render_state.gen7.emit_flush = false; |
|
need_flush = false; |
need_stall = false; |
} |
if (sna->render_state.gen7.emit_flush) { |
if (need_flush) { |
gen7_emit_pipe_flush(sna, need_stall); |
need_stall = false; |
} |
1050,6 → 1065,13 |
if (need_stall) |
gen7_emit_pipe_stall(sna); |
|
gen7_emit_cc(sna, GEN7_BLEND(op->u.gen7.flags)); |
gen7_emit_sampler(sna, GEN7_SAMPLER(op->u.gen7.flags)); |
gen7_emit_sf(sna, GEN7_VERTEX(op->u.gen7.flags) >> 2); |
gen7_emit_wm(sna, GEN7_KERNEL(op->u.gen7.flags)); |
gen7_emit_vertex_elements(sna, op); |
gen7_emit_binding_table(sna, wm_binding_table); |
|
sna->render_state.gen7.emit_flush = GEN7_READS_DST(op->u.gen7.flags); |
} |
|
1404,12 → 1426,14 |
const struct sna_composite_op *op) |
{ |
uint32_t *binding_table; |
uint16_t offset; |
uint16_t offset, dirty; |
|
gen7_get_batch(sna, op); |
|
binding_table = gen7_composite_get_binding_table(sna, &offset); |
|
dirty = kgem_bo_is_dirty(op->dst.bo); |
|
binding_table[0] = |
gen7_bind_bo(sna, |
op->dst.bo, op->dst.width, op->dst.height, |
1438,7 → 1462,7 |
offset = sna->render_state.gen7.surface_table; |
} |
|
gen7_emit_state(sna, op, offset); |
gen7_emit_state(sna, op, offset | dirty); |
} |
|
static void |
1445,16 → 1469,9 |
gen7_align_vertex(struct sna *sna, const struct sna_composite_op *op) |
{ |
if (op->floats_per_vertex != sna->render_state.gen7.floats_per_vertex) { |
if (sna->render.vertex_size - sna->render.vertex_used < 2*op->floats_per_rect) |
gen4_vertex_finish(sna); |
|
DBG(("aligning vertex: was %d, now %d floats per vertex, %d->%d\n", |
sna->render_state.gen7.floats_per_vertex, |
op->floats_per_vertex, |
sna->render.vertex_index, |
(sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex)); |
sna->render.vertex_index = (sna->render.vertex_used + op->floats_per_vertex - 1) / op->floats_per_vertex; |
sna->render.vertex_used = sna->render.vertex_index * op->floats_per_vertex; |
DBG(("aligning vertex: was %d, now %d floats per vertex\n", |
sna->render_state.gen7.floats_per_vertex, op->floats_per_vertex)); |
gen4_vertex_align(sna, op); |
sna->render_state.gen7.floats_per_vertex = op->floats_per_vertex; |
} |
} |
1548,7 → 1565,7 |
int src_height[6]; |
int src_pitch[6]; |
uint32_t *binding_table; |
uint16_t offset; |
uint16_t offset, dirty; |
int n_src, n; |
|
gen7_get_batch(sna, op); |
1586,6 → 1603,8 |
|
binding_table = gen7_composite_get_binding_table(sna, &offset); |
|
dirty = kgem_bo_is_dirty(op->dst.bo); |
|
binding_table[0] = |
gen7_bind_bo(sna, |
op->dst.bo, op->dst.width, op->dst.height, |
1602,7 → 1621,7 |
src_surf_format); |
} |
|
gen7_emit_state(sna, op, offset); |
gen7_emit_state(sna, op, offset | dirty); |
} |
|
static bool |
1669,12 → 1688,14 |
kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp.dst.bo); |
if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) { |
kgem_submit(&sna->kgem); |
assert(kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)); |
if (!kgem_check_bo(&sna->kgem, tmp.dst.bo, frame->bo, NULL)) |
return false; |
|
_kgem_set_mode(&sna->kgem, KGEM_RENDER); |
} |
|
gen7_align_vertex(sna, &tmp); |
gen7_emit_video_state(sna, &tmp); |
gen7_align_vertex(sna, &tmp); |
|
/* Set up the offset for translating from the given region (in screen |
* coordinates) to the backing pixmap. |
1874,7 → 1895,8 |
return false; |
} |
|
if (prefer_blt_fill(sna, dst_bo) || !gen7_check_dst_format(format)) { |
if (prefer_blt_fill(sna, dst_bo, FILL_BOXES) || |
!gen7_check_dst_format(format)) { |
uint8_t alu = GXinvalid; |
|
if (op <= PictOpSrc) { |
1949,11 → 1971,17 |
kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); |
if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { |
kgem_submit(&sna->kgem); |
assert(kgem_check_bo(&sna->kgem, dst_bo, NULL)); |
if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { |
kgem_bo_destroy(&sna->kgem, tmp.src.bo); |
if (tmp.redirect.real_bo) |
kgem_bo_destroy(&sna->kgem, tmp.dst.bo); |
return false; |
} |
_kgem_set_mode(&sna->kgem, KGEM_RENDER); |
} |
|
gen7_align_vertex(sna, &tmp); |
gen7_emit_fill_state(sna, &tmp); |
gen7_align_vertex(sna, &tmp); |
|
do { |
int n_this_time; |
1987,60 → 2015,6 |
} |
#endif |
|
static void gen7_render_flush(struct sna *sna) |
{ |
gen4_vertex_close(sna); |
|
assert(sna->render.vb_id == 0); |
assert(sna->render.vertex_offset == 0); |
} |
|
static void |
gen7_render_context_switch(struct kgem *kgem, |
int new_mode) |
{ |
if (kgem->nbatch) { |
DBG(("%s: switch rings %d -> %d\n", |
__FUNCTION__, kgem->mode, new_mode)); |
_kgem_submit(kgem); |
} |
|
kgem->ring = new_mode; |
} |
|
static void |
gen7_render_retire(struct kgem *kgem) |
{ |
struct sna *sna; |
|
if (kgem->ring && (kgem->has_semaphores || !kgem->need_retire)) |
kgem->ring = kgem->mode; |
|
sna = container_of(kgem, struct sna, kgem); |
if (kgem->nbatch == 0 && sna->render.vbo && !kgem_bo_is_busy(sna->render.vbo)) { |
DBG(("%s: resetting idle vbo\n", __FUNCTION__)); |
sna->render.vertex_used = 0; |
sna->render.vertex_index = 0; |
} |
} |
|
static void |
gen7_render_expire(struct kgem *kgem) |
{ |
struct sna *sna; |
|
sna = container_of(kgem, struct sna, kgem); |
if (sna->render.vbo && !sna->render.vertex_used) { |
DBG(("%s: discarding vbo\n", __FUNCTION__)); |
kgem_bo_destroy(kgem, sna->render.vbo); |
sna->render.vbo = NULL; |
sna->render.vertices = sna->render.vertex_data; |
sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); |
sna->render.vertex_used = 0; |
sna->render.vertex_index = 0; |
} |
} |
|
static void gen7_render_reset(struct sna *sna) |
{ |
sna->render_state.gen7.emit_flush = false; |
2056,6 → 2030,11 |
sna->render_state.gen7.drawrect_limit = -1; |
sna->render_state.gen7.surface_table = -1; |
|
if (sna->render.vbo && !kgem_bo_can_map(&sna->kgem, sna->render.vbo)) { |
DBG(("%s: discarding unmappable vbo\n", __FUNCTION__)); |
discard_vbo(sna); |
} |
|
sna->render.vertex_offset = 0; |
sna->render.nvertex_reloc = 0; |
sna->render.vb_id = 0; |
2066,23 → 2045,23 |
kgem_bo_destroy(&sna->kgem, sna->render_state.gen7.general_bo); |
} |
|
static bool is_gt3(struct sna *sna) |
static bool is_gt3(struct sna *sna, int devid) |
{ |
assert(sna->kgem.gen == 075); |
return sna->PciInfo->device_id & 0x20; |
return devid & 0x20; |
} |
|
static bool is_gt2(struct sna *sna) |
static bool is_gt2(struct sna *sna, int devid) |
{ |
return sna->PciInfo->device_id & (is_hsw(sna)? 0x30 : 0x20); |
return devid & (is_hsw(sna)? 0x30 : 0x20); |
} |
|
static bool is_mobile(struct sna *sna) |
static bool is_mobile(struct sna *sna, int devid) |
{ |
return (sna->PciInfo->device_id & 0xf) == 0x6; |
return (devid & 0xf) == 0x6; |
} |
|
static bool gen7_render_setup(struct sna *sna) |
static bool gen7_render_setup(struct sna *sna, int devid) |
{ |
struct gen7_render_state *state = &sna->render_state.gen7; |
struct sna_static_stream general; |
2091,9 → 2070,9 |
|
if (is_ivb(sna)) { |
state->info = &ivb_gt_info; |
if (sna->PciInfo->device_id & 0xf) { |
if (devid & 0xf) { |
state->info = &ivb_gt1_info; |
if (is_gt2(sna)) |
if (is_gt2(sna, devid)) |
state->info = &ivb_gt2_info; /* XXX requires GT_MODE WiZ disabled */ |
} |
} else if (is_byt(sna)) { |
2100,10 → 2079,10 |
state->info = &byt_gt_info; |
} else if (is_hsw(sna)) { |
state->info = &hsw_gt_info; |
if (sna->PciInfo->device_id & 0xf) { |
if (is_gt3(sna)) |
if (devid & 0xf) { |
if (is_gt3(sna, devid)) |
state->info = &hsw_gt3_info; |
else if (is_gt2(sna)) |
else if (is_gt2(sna, devid)) |
state->info = &hsw_gt2_info; |
else |
state->info = &hsw_gt1_info; |
2111,6 → 2090,8 |
} else |
return false; |
|
state->gt = state->info->gt; |
|
sna_static_stream_init(&general); |
|
/* Zero pad the start. If you see an offset of 0x0 in the batchbuffer |
2175,12 → 2156,14 |
|
const char *gen7_render_init(struct sna *sna, const char *backend) |
{ |
if (!gen7_render_setup(sna)) |
int devid = intel_get_device_id(sna); |
|
if (!gen7_render_setup(sna, devid)) |
return backend; |
|
sna->kgem.context_switch = gen7_render_context_switch; |
sna->kgem.retire = gen7_render_retire; |
sna->kgem.expire = gen7_render_expire; |
sna->kgem.context_switch = gen6_render_context_switch; |
sna->kgem.retire = gen6_render_retire; |
sna->kgem.expire = gen4_render_expire; |
|
#if 0 |
#if !NO_COMPOSITE |
2190,7 → 2173,7 |
#if !NO_COMPOSITE_SPANS |
sna->render.check_composite_spans = gen7_check_composite_spans; |
sna->render.composite_spans = gen7_render_composite_spans; |
if (is_mobile(sna) || is_gt2(sna) || is_byt(sna)) |
if (is_mobile(sna, devid) || is_gt2(sna, devid) || is_byt(sna)) |
sna->render.prefer_gpu |= PREFER_GPU_SPANS; |
#endif |
sna->render.video = gen7_render_video; |
2219,7 → 2202,7 |
sna->render.blit_tex = gen7_blit_tex; |
sna->render.caps = HW_BIT_BLIT | HW_TEX_BLIT; |
|
sna->render.flush = gen7_render_flush; |
sna->render.flush = gen4_render_flush; |
sna->render.reset = gen7_render_reset; |
sna->render.fini = gen7_render_fini; |
|
2312,7 → 2295,7 |
// tmp->box = gen7_render_composite_box; |
tmp->done = gen7_render_composite_done; |
|
kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo); |
kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); |
if (!kgem_check_bo(&sna->kgem, |
tmp->dst.bo, tmp->src.bo, tmp->mask.bo, |
NULL)) { |
2320,7 → 2303,7 |
_kgem_set_mode(&sna->kgem, KGEM_RENDER); |
} |
|
gen7_align_vertex(sna, tmp); |
gen7_emit_composite_state(sna, tmp); |
gen7_align_vertex(sna, tmp); |
return true; |
} |