/drivers/video/Intel-2D/gen6_render.c |
---|
1149,6 → 1149,9 |
int id = 1 << GEN6_VERTEX(op->u.gen6.flags); |
int ndwords; |
if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset) |
return true; |
ndwords = op->need_magic_ca_pass ? 60 : 6; |
if ((sna->render.vb_id & id) == 0) |
ndwords += 5; |
1165,6 → 1168,12 |
static int gen6_get_rectangles__flush(struct sna *sna, |
const struct sna_composite_op *op) |
{ |
/* Preventing discarding new vbo after lock contention */ |
if (sna_vertex_wait__locked(&sna->render)) { |
int rem = vertex_space(sna); |
if (rem > op->floats_per_rect) |
return rem; |
} |
if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5)) |
return 0; |
1218,7 → 1227,7 |
gen4_vertex_flush(sna); |
gen6_magic_ca_pass(sna, op); |
} |
// sna_vertex_wait__locked(&sna->render); |
sna_vertex_wait__locked(&sna->render); |
_kgem_submit(&sna->kgem); |
emit_state(sna, op); |
goto start; |
2014,8 → 2023,18 |
} |
tmp->done = gen6_render_composite_done; |
kgem_set_mode(&sna->kgem, KGEM_RENDER, tmp->dst.bo); |
if (!kgem_check_bo(&sna->kgem, |
tmp->dst.bo, tmp->src.bo, tmp->mask.bo, |
NULL)) { |
kgem_submit(&sna->kgem); |
if (!kgem_check_bo(&sna->kgem, |
tmp->dst.bo, tmp->src.bo, tmp->mask.bo, |
NULL)) |
goto cleanup_mask; |
_kgem_set_mode(&sna->kgem, KGEM_RENDER); |
} |
gen6_emit_composite_state(sna, tmp); |
gen6_align_vertex(sna, tmp); |
return true; |
2654,6 → 2673,13 |
assert(GEN6_SAMPLER(op->base.u.gen6.flags) == COPY_SAMPLER); |
assert(GEN6_VERTEX(op->base.u.gen6.flags) == COPY_VERTEX); |
kgem_set_mode(&sna->kgem, KGEM_RENDER, dst_bo); |
if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) { |
kgem_submit(&sna->kgem); |
if (!kgem_check_bo(&sna->kgem, dst_bo, src_bo, NULL)) |
goto fallback; |
_kgem_set_mode(&sna->kgem, KGEM_RENDER); |
} |
gen6_emit_copy_state(sna, &op->base); |
gen6_align_vertex(sna, &op->base); |
3149,8 → 3175,14 |
assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER); |
assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX); |
if (!kgem_check_bo(&sna->kgem, bo, NULL)) { |
kgem_submit(&sna->kgem); |
if (!kgem_check_bo(&sna->kgem, bo, NULL)) { |
kgem_bo_destroy(&sna->kgem, tmp.src.bo); |
return false; |
} |
} |
gen6_emit_fill_state(sna, &tmp); |
gen6_align_vertex(sna, &tmp); |
3173,6 → 3205,7 |
return true; |
} |
#endif |
static void gen6_render_flush(struct sna *sna) |
{ |
3182,8 → 3215,18 |
assert(sna->render.vertex_offset == 0); |
} |
#endif |
static void |
gen6_render_context_switch(struct kgem *kgem, |
int new_mode) |
{ |
if (kgem->nbatch) { |
DBG(("%s: from %d to %d\n", __FUNCTION__, kgem->mode, new_mode)); |
_kgem_submit(kgem); |
} |
kgem->ring = new_mode; |
} |
static void |
gen6_render_retire(struct kgem *kgem) |
{ |
3200,7 → 3243,24 |
} |
} |
static void |
gen6_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 handle=%d\n", __FUNCTION__, sna->render.vbo->handle)); |
kgem_bo_destroy(kgem, sna->render.vbo); |
assert(!sna->render.active); |
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 gen6_render_reset(struct sna *sna) |
{ |
sna->render_state.gen6.needs_invariant = true; |
3319,8 → 3379,9 |
if (!gen6_render_setup(sna)) |
return false; |
// sna->kgem.context_switch = gen6_render_context_switch; |
sna->kgem.context_switch = gen6_render_context_switch; |
sna->kgem.retire = gen6_render_retire; |
sna->kgem.expire = gen6_render_expire; |
// sna->render.composite = gen6_render_composite; |
// sna->render.video = gen6_render_video; |
3445,3 → 3506,90 |
return sna->render.vertex_size - sna->render.vertex_used; |
} |
void gen4_vertex_close(struct sna *sna) |
{ |
struct kgem_bo *bo, *free_bo = NULL; |
unsigned int i, delta = 0; |
assert(sna->render.vertex_offset == 0); |
if (!sna->render.vb_id) |
return; |
DBG(("%s: used=%d, vbo active? %d, vb=%x, nreloc=%d\n", |
__FUNCTION__, sna->render.vertex_used, sna->render.vbo ? sna->render.vbo->handle : 0, |
sna->render.vb_id, sna->render.nvertex_reloc)); |
assert(!sna->render.active); |
bo = sna->render.vbo; |
if (bo) { |
if (sna->render.vertex_size - sna->render.vertex_used < 64) { |
DBG(("%s: discarding vbo (full), handle=%d\n", __FUNCTION__, sna->render.vbo->handle)); |
sna->render.vbo = NULL; |
sna->render.vertices = sna->render.vertex_data; |
sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); |
free_bo = bo; |
} else if (IS_CPU_MAP(bo->map) && !sna->kgem.has_llc) { |
DBG(("%s: converting CPU map to GTT\n", __FUNCTION__)); |
sna->render.vertices = |
kgem_bo_map__gtt(&sna->kgem, sna->render.vbo); |
if (sna->render.vertices == NULL) { |
sna->render.vbo = NULL; |
sna->render.vertices = sna->render.vertex_data; |
sna->render.vertex_size = ARRAY_SIZE(sna->render.vertex_data); |
free_bo = bo; |
} |
} |
} else { |
if (sna->kgem.nbatch + sna->render.vertex_used <= sna->kgem.surface) { |
DBG(("%s: copy to batch: %d @ %d\n", __FUNCTION__, |
sna->render.vertex_used, sna->kgem.nbatch)); |
memcpy(sna->kgem.batch + sna->kgem.nbatch, |
sna->render.vertex_data, |
sna->render.vertex_used * 4); |
delta = sna->kgem.nbatch * 4; |
bo = NULL; |
sna->kgem.nbatch += sna->render.vertex_used; |
} else { |
bo = kgem_create_linear(&sna->kgem, |
4*sna->render.vertex_used, |
CREATE_NO_THROTTLE); |
if (bo && !kgem_bo_write(&sna->kgem, bo, |
sna->render.vertex_data, |
4*sna->render.vertex_used)) { |
kgem_bo_destroy(&sna->kgem, bo); |
bo = NULL; |
} |
DBG(("%s: new vbo: %d\n", __FUNCTION__, |
sna->render.vertex_used)); |
free_bo = bo; |
} |
} |
assert(sna->render.nvertex_reloc); |
for (i = 0; i < sna->render.nvertex_reloc; i++) { |
DBG(("%s: reloc[%d] = %d\n", __FUNCTION__, |
i, sna->render.vertex_reloc[i])); |
sna->kgem.batch[sna->render.vertex_reloc[i]] = |
kgem_add_reloc(&sna->kgem, |
sna->render.vertex_reloc[i], bo, |
I915_GEM_DOMAIN_VERTEX << 16, |
delta); |
} |
sna->render.nvertex_reloc = 0; |
sna->render.vb_id = 0; |
if (sna->render.vbo == NULL) { |
assert(!sna->render.active); |
sna->render.vertex_used = 0; |
sna->render.vertex_index = 0; |
assert(sna->render.vertices == sna->render.vertex_data); |
assert(sna->render.vertex_size == ARRAY_SIZE(sna->render.vertex_data)); |
} |
if (free_bo) |
kgem_bo_destroy(&sna->kgem, free_bo); |
} |
/drivers/video/Intel-2D/i915_drm.h |
---|
218,13 → 218,13 |
#define DRM_IOCTL_I915_HWS_ADDR |
#define DRM_IOCTL_I915_GEM_INIT |
#define DRM_IOCTL_I915_GEM_EXECBUFFER |
#define DRM_IOCTL_I915_GEM_EXECBUFFER2 |
#define DRM_IOCTL_I915_GEM_EXECBUFFER2 SRV_I915_GEM_EXECBUFFER2 |
#define DRM_IOCTL_I915_GEM_PIN SRV_I915_GEM_PIN |
#define DRM_IOCTL_I915_GEM_UNPIN |
#define DRM_IOCTL_I915_GEM_BUSY SRV_I915_GEM_BUSY |
#define DRM_IOCTL_I915_GEM_SET_CACHEING SRV_I915_GEM_SET_CACHEING |
#define DRM_IOCTL_I915_GEM_GET_CACHEING |
#define DRM_IOCTL_I915_GEM_THROTTLE |
#define DRM_IOCTL_I915_GEM_THROTTLE SRV_I915_GEM_THROTTLE |
#define DRM_IOCTL_I915_GEM_ENTERVT |
#define DRM_IOCTL_I915_GEM_LEAVEVT |
#define DRM_IOCTL_I915_GEM_CREATE SRV_I915_GEM_CREATE |
/drivers/video/Intel-2D/kgem-sna.c |
---|
108,6 → 108,15 |
#define LOCAL_I915_EXEC_IS_PINNED (1<<10) |
#define LOCAL_I915_EXEC_NO_RELOC (1<<11) |
#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12) |
struct local_i915_gem_userptr { |
uint64_t user_ptr; |
uint32_t user_size; |
uint32_t flags; |
#define I915_USERPTR_READ_ONLY (1<<0) |
#define I915_USERPTR_UNSYNCHRONIZED (1<<31) |
uint32_t handle; |
}; |
#define UNCACHED 0 |
#define SNOOPED 1 |
118,6 → 127,13 |
#define LOCAL_IOCTL_I915_GEM_SET_CACHEING SRV_I915_GEM_SET_CACHEING |
struct local_fbinfo { |
int width; |
int height; |
int pitch; |
int tiling; |
}; |
struct kgem_buffer { |
struct kgem_bo base; |
void *mem; |
189,7 → 205,7 |
ret = ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling); |
} while (ret == -1 && (errno == EINTR || errno == EAGAIN)); |
*/ |
return ret == 0; |
return false;//ret == 0; |
} |
static bool gem_set_cacheing(int fd, uint32_t handle, int cacheing) |
260,19 → 276,19 |
retry_mmap: |
// ptr = mmap(0, bytes(bo), PROT_READ | PROT_WRITE, MAP_SHARED, |
// kgem->fd, mmap_arg.offset); |
if (ptr == 0) { |
// if (ptr == 0) { |
printf("%s: failed to mmap %d, %d bytes, into GTT domain: %d\n", |
__FUNCTION__, bo->handle, bytes(bo), 0); |
if (__kgem_throttle_retire(kgem, 0)) |
goto retry_mmap; |
// if (__kgem_throttle_retire(kgem, 0)) |
// goto retry_mmap; |
if (kgem->need_expire) { |
kgem_cleanup_cache(kgem); |
goto retry_mmap; |
} |
// if (kgem->need_expire) { |
// kgem_cleanup_cache(kgem); |
// goto retry_mmap; |
// } |
ptr = NULL; |
} |
// } |
return ptr; |
} |
639,10 → 655,10 |
static bool __kgem_throttle(struct kgem *kgem) |
{ |
// if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL) == 0) |
if (drmIoctl(kgem->fd, DRM_IOCTL_I915_GEM_THROTTLE, NULL) == 0) |
return false; |
// return errno == EIO; |
return errno == EIO; |
} |
static bool is_hw_supported(struct kgem *kgem, |
1073,9 → 1089,140 |
kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT; |
if (kgem->has_pinned_batches) |
kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED; |
} |
/* XXX hopefully a good approximation */ |
static uint32_t kgem_get_unique_id(struct kgem *kgem) |
{ |
uint32_t id; |
id = ++kgem->unique_id; |
if (id == 0) |
id = ++kgem->unique_id; |
return id; |
} |
inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags) |
{ |
if (flags & CREATE_PRIME) |
return 256; |
if (flags & CREATE_SCANOUT) |
return 64; |
return kgem->min_alignment; |
} |
static uint32_t kgem_untiled_pitch(struct kgem *kgem, |
uint32_t width, uint32_t bpp, |
unsigned flags) |
{ |
width = ALIGN(width, 2) * bpp >> 3; |
return ALIGN(width, kgem_pitch_alignment(kgem, flags)); |
} |
static uint32_t kgem_surface_size(struct kgem *kgem, |
bool relaxed_fencing, |
unsigned flags, |
uint32_t width, |
uint32_t height, |
uint32_t bpp, |
uint32_t tiling, |
uint32_t *pitch) |
{ |
uint32_t tile_width, tile_height; |
uint32_t size; |
assert(width <= MAXSHORT); |
assert(height <= MAXSHORT); |
if (kgem->gen <= 030) { |
if (tiling) { |
if (kgem->gen < 030) { |
tile_width = 128; |
tile_height = 32; |
} else { |
tile_width = 512; |
tile_height = 16; |
} |
} else { |
tile_width = 2 * bpp >> 3; |
tile_width = ALIGN(tile_width, |
kgem_pitch_alignment(kgem, flags)); |
tile_height = 2; |
} |
} else switch (tiling) { |
default: |
case I915_TILING_NONE: |
tile_width = 2 * bpp >> 3; |
tile_width = ALIGN(tile_width, |
kgem_pitch_alignment(kgem, flags)); |
tile_height = 2; |
break; |
/* XXX align to an even tile row */ |
case I915_TILING_X: |
tile_width = 512; |
tile_height = 16; |
break; |
case I915_TILING_Y: |
tile_width = 128; |
tile_height = 64; |
break; |
} |
*pitch = ALIGN(width * bpp / 8, tile_width); |
height = ALIGN(height, tile_height); |
if (kgem->gen >= 040) |
return PAGE_ALIGN(*pitch * height); |
/* If it is too wide for the blitter, don't even bother. */ |
if (tiling != I915_TILING_NONE) { |
if (*pitch > 8192) |
return 0; |
for (size = tile_width; size < *pitch; size <<= 1) |
; |
*pitch = size; |
} else { |
if (*pitch >= 32768) |
return 0; |
} |
size = *pitch * height; |
if (relaxed_fencing || tiling == I915_TILING_NONE) |
return PAGE_ALIGN(size); |
/* We need to allocate a pot fence region for a tiled buffer. */ |
if (kgem->gen < 030) |
tile_width = 512 * 1024; |
else |
tile_width = 1024 * 1024; |
while (tile_width < size) |
tile_width *= 2; |
return tile_width; |
} |
static uint32_t kgem_aligned_height(struct kgem *kgem, |
uint32_t height, uint32_t tiling) |
{ |
uint32_t tile_height; |
if (kgem->gen <= 030) { |
tile_height = tiling ? kgem->gen < 030 ? 32 : 16 : 1; |
} else switch (tiling) { |
/* XXX align to an even tile row */ |
default: |
case I915_TILING_NONE: |
tile_height = 1; |
break; |
case I915_TILING_X: |
tile_height = 16; |
break; |
case I915_TILING_Y: |
tile_height = 64; |
break; |
} |
return ALIGN(height, tile_height); |
} |
static struct drm_i915_gem_exec_object2 * |
kgem_add_handle(struct kgem *kgem, struct kgem_bo *bo) |
{ |
1763,12 → 1910,28 |
return retired; |
} |
bool __kgem_ring_is_idle(struct kgem *kgem, int ring) |
{ |
struct kgem_request *rq; |
assert(!list_is_empty(&kgem->requests[ring])); |
rq = list_last_entry(&kgem->requests[ring], |
struct kgem_request, list); |
if (__kgem_busy(kgem, rq->bo->handle)) { |
DBG(("%s: last requests handle=%d still busy\n", |
__FUNCTION__, rq->bo->handle)); |
return false; |
} |
DBG(("%s: ring=%d idle (handle=%d)\n", |
__FUNCTION__, ring, rq->bo->handle)); |
kgem_retire__requests_ring(kgem, ring); |
assert(list_is_empty(&kgem->requests[ring])); |
return true; |
} |
static void kgem_commit(struct kgem *kgem) |
{ |
struct kgem_request *rq = kgem->next_request; |
2328,15 → 2491,15 |
// ret = drmIoctl(kgem->fd, |
// DRM_IOCTL_I915_GEM_EXECBUFFER2, |
// &execbuf); |
// while (ret == -1 && errno == EBUSY && retry--) { |
// __kgem_throttle(kgem); |
// ret = drmIoctl(kgem->fd, |
// DRM_IOCTL_I915_GEM_EXECBUFFER2, |
// &execbuf); |
// } |
ret = drmIoctl(kgem->fd, |
DRM_IOCTL_I915_GEM_EXECBUFFER2, |
&execbuf); |
while (ret == -1 && errno == EBUSY && retry--) { |
__kgem_throttle(kgem); |
ret = drmIoctl(kgem->fd, |
DRM_IOCTL_I915_GEM_EXECBUFFER2, |
&execbuf); |
} |
if (DEBUG_SYNC && ret == 0) { |
struct drm_i915_gem_set_domain set_domain; |
2898,8 → 3061,6 |
return size; |
} |
#if 0 |
struct kgem_bo *kgem_create_2d(struct kgem *kgem, |
int width, |
int height, |
3379,6 → 3540,7 |
return bo; |
} |
#if 0 |
struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem, |
int width, |
int height, |
3497,21 → 3659,80 |
__kgem_bo_destroy(kgem, bo); |
} |
void __kgem_flush(struct kgem *kgem, struct kgem_bo *bo) |
{ |
assert(bo->rq); |
assert(bo->exec == NULL); |
assert(bo->needs_flush); |
/* The kernel will emit a flush *and* update its own flushing lists. */ |
if (!__kgem_busy(kgem, bo->handle)) |
__kgem_bo_clear_busy(bo); |
DBG(("%s: handle=%d, busy?=%d\n", |
__FUNCTION__, bo->handle, bo->rq != NULL)); |
} |
inline static bool needs_semaphore(struct kgem *kgem, struct kgem_bo *bo) |
{ |
return kgem->nreloc && bo->rq && RQ_RING(bo->rq) != kgem->ring; |
} |
bool kgem_check_bo(struct kgem *kgem, ...) |
{ |
va_list ap; |
struct kgem_bo *bo; |
int num_exec = 0; |
int num_pages = 0; |
bool flush = false; |
va_start(ap, kgem); |
while ((bo = va_arg(ap, struct kgem_bo *))) { |
while (bo->proxy) |
bo = bo->proxy; |
if (bo->exec) |
continue; |
if (needs_semaphore(kgem, bo)) |
return false; |
num_pages += num_pages(bo); |
num_exec++; |
flush |= bo->flush; |
} |
va_end(ap); |
DBG(("%s: num_pages=+%d, num_exec=+%d\n", |
__FUNCTION__, num_pages, num_exec)); |
if (!num_pages) |
return true; |
if (kgem_flush(kgem, flush)) |
return false; |
if (kgem->aperture > kgem->aperture_low && |
kgem_ring_is_idle(kgem, kgem->ring)) { |
DBG(("%s: current aperture usage (%d) is greater than low water mark (%d)\n", |
__FUNCTION__, kgem->aperture, kgem->aperture_low)); |
return false; |
} |
if (num_pages + kgem->aperture > kgem->aperture_high) { |
DBG(("%s: final aperture usage (%d) is greater than high water mark (%d)\n", |
__FUNCTION__, num_pages + kgem->aperture, kgem->aperture_high)); |
return false; |
} |
if (kgem->nexec + num_exec >= KGEM_EXEC_SIZE(kgem)) { |
DBG(("%s: out of exec slots (%d + %d / %d)\n", __FUNCTION__, |
kgem->nexec, num_exec, KGEM_EXEC_SIZE(kgem))); |
return false; |
} |
return true; |
} |
3532,6 → 3753,16 |
uint32_t kgem_add_reloc(struct kgem *kgem, |
uint32_t pos, |
struct kgem_bo *bo, |
3545,6 → 3776,9 |
assert((read_write_domain & 0x7fff) == 0 || bo != NULL); |
// if( bo != NULL && bo->handle == -1) |
// return 0; |
index = kgem->nreloc++; |
assert(index < ARRAY_SIZE(kgem->reloc)); |
kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]); |
3851,6 → 4085,42 |
} |
} |
struct kgem_bo *kgem_create_proxy(struct kgem *kgem, |
struct kgem_bo *target, |
int offset, int length) |
{ |
struct kgem_bo *bo; |
DBG(("%s: target handle=%d [proxy? %d], offset=%d, length=%d, io=%d\n", |
__FUNCTION__, target->handle, target->proxy ? target->proxy->delta : -1, |
offset, length, target->io)); |
bo = __kgem_bo_alloc(target->handle, length); |
if (bo == NULL) |
return NULL; |
bo->unique_id = kgem_get_unique_id(kgem); |
bo->reusable = false; |
bo->size.bytes = length; |
bo->io = target->io && target->proxy == NULL; |
bo->dirty = target->dirty; |
bo->tiling = target->tiling; |
bo->pitch = target->pitch; |
assert(!bo->scanout); |
bo->proxy = kgem_bo_reference(target); |
bo->delta = offset; |
if (target->exec) { |
list_move_tail(&bo->request, &kgem->next_request->buffers); |
bo->exec = &_kgem_dummy_exec; |
} |
bo->rq = target->rq; |
return bo; |
} |
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format) |
{ |
struct kgem_bo_binding *b; |
3889,5 → 4159,37 |
} |
int kgem_init_fb(struct kgem *kgem, struct sna_fb *fb) |
{ |
struct kgem_bo *bo; |
size_t size; |
int ret; |
ret = drmIoctl(kgem->fd, SRV_FBINFO, fb); |
if( ret != 0 ) |
return 0; |
size = fb->pitch * fb->height / PAGE_SIZE; |
bo = __kgem_bo_alloc(-2, size); |
if (!bo) { |
return 0; |
} |
bo->domain = DOMAIN_GTT; |
bo->unique_id = kgem_get_unique_id(kgem); |
bo->pitch = fb->pitch; |
bo->tiling = I915_TILING_NONE; |
bo->scanout = 1; |
fb->fb_bo = bo; |
printf("fb width %d height %d pitch %d bo %p\n", |
fb->width, fb->height, fb->pitch, fb->fb_bo); |
return 1; |
}; |
/drivers/video/Intel-2D/kgem.h |
---|
28,7 → 28,7 |
#ifndef KGEM_H |
#define KGEM_H |
#define HAS_DEBUG_FULL 1 |
#define HAS_DEBUG_FULL 0 |
#include <stdint.h> |
#include <stdbool.h> |
/drivers/video/Intel-2D/sna.c |
---|
5,6 → 5,10 |
#include "sna.h" |
#include <pixlib2.h> |
static struct sna_fb sna_fb; |
typedef struct __attribute__((packed)) |
{ |
unsigned handle; |
64,7 → 68,7 |
// render->clear = no_render_clear; |
render->reset = no_render_reset; |
render->flush = no_render_flush; |
// render->flush = no_render_flush; |
// render->fini = no_render_fini; |
// sna->kgem.context_switch = no_render_context_switch; |
129,26 → 133,11 |
// return false; |
sna_device = sna; |
#if 0 |
{ |
struct kgem_bo *screen_bo; |
bitmap_t screen; |
screen.pitch = 1024*4; |
screen.gaddr = 0; |
screen.width = 1024; |
screen.height = 768; |
screen.obj = (void*)-1; |
screen_bo = create_bo(&screen); |
sna->render.clear(sna, &screen, screen_bo); |
return kgem_init_fb(&sna->kgem, &sna_fb); |
} |
#endif |
return true; |
} |
int sna_init(uint32_t service) |
{ |
ioctl_t io; |
339,37 → 328,69 |
#endif |
int sna_blit_copy(uint32_t dst_bitmap, int dst_x, int dst_y, |
int w, int h, uint32_t src_bitmap, int src_x, int src_y) |
int sna_blit_copy(bitmap_t *src_bitmap, int dst_x, int dst_y, |
int w, int h, int src_x, int src_y) |
{ |
struct sna_copy_op copy; |
struct kgem_bo src_bo, dst_bo; |
struct _Pixmap src, dst; |
struct kgem_bo *src_bo; |
memset(&src_bo, 0, sizeof(src_bo)); |
memset(&dst_bo, 0, sizeof(dst_bo)); |
memset(&src, 0, sizeof(src)); |
memset(&dst, 0, sizeof(dst)); |
// src_bo.gaddr = src_bitmap->gaddr; |
// src_bo.pitch = src_bitmap->pitch; |
// src_bo.tiling = 0; |
src.drawable.bitsPerPixel = 32; |
src.drawable.width = src_bitmap->width; |
src.drawable.height = src_bitmap->height; |
// dst_bo.gaddr = dst_bitmap->gaddr; |
// dst_bo.pitch = dst_bitmap->pitch; |
// dst_bo.tiling = 0; |
dst.drawable.bitsPerPixel = 32; |
dst.drawable.width = sna_fb.width; |
dst.drawable.height = sna_fb.height; |
memset(©, 0, sizeof(copy)); |
sna_device->render.copy(sna_device, GXcopy, NULL, &src_bo, NULL, &dst_bo, ©); |
src_bo = (struct kgem_bo*)src_bitmap->handle; |
if( sna_device->render.copy(sna_device, GXcopy, |
&src, src_bo, |
&dst, sna_fb.fb_bo, ©) ) |
{ |
copy.blt(sna_device, ©, src_x, src_y, w, h, dst_x, dst_y); |
copy.done(sna_device, ©); |
} |
kgem_submit(&sna_device->kgem); |
// __asm__ __volatile__("int3"); |
// _kgem_submit(&sna_device->kgem, &execbuffer); |
}; |
int sna_create_bitmap(bitmap_t *bitmap) |
{ |
struct kgem_bo *bo; |
bo = kgem_create_2d(&sna_device->kgem, bitmap->width, bitmap->height, |
32,I915_TILING_NONE, CREATE_CPU_MAP); |
if(bo == NULL) |
goto err_1; |
void *map = kgem_bo_map(&sna_device->kgem, bo); |
if(map == NULL) |
goto err_2; |
bitmap->handle = (uint32_t)bo; |
bitmap->pitch = bo->pitch; |
bitmap->data = map; |
return 0; |
err_2: |
kgem_bo_destroy(&sna_device->kgem, bo); |
err_1: |
return -1; |
}; |
/* |
int sna_blit_tex(bitmap_t *dst_bitmap, int dst_x, int dst_y, |
/drivers/video/Intel-2D/sna.h |
---|
44,8 → 44,8 |
#include <stdint.h> |
#include <memory.h> |
#include <malloc.h> |
#include <errno.h> |
#include "intel_driver.h" |
#include "pciaccess.h" |
69,13 → 69,15 |
#define SRV_I915_GEM_GET_APERTURE 26 |
#define SRV_I915_GEM_PWRITE 27 |
#define SRV_I915_GEM_BUSY 28 |
#define SRV_I915_GEM_SET_DOMAIN 29 |
#define SRV_I915_GEM_MMAP 30 |
#define SRV_I915_GEM_THROTTLE 32 |
#define SRV_FBINFO 33 |
#define SRV_I915_GEM_EXECBUFFER2 34 |
#define SRV_I915_GEM_MMAP_GTT 31 |
#define DRM_IOCTL_GEM_CLOSE SRV_DRM_GEM_CLOSE |
#define PIXMAN_FORMAT(bpp,type,a,r,g,b) (((bpp) << 24) | \ |
153,7 → 155,16 |
} PixmapRec; |
struct sna_fb |
{ |
uint32_t width; |
uint32_t height; |
uint32_t pitch; |
uint32_t tiling; |
struct kgem_bo *fb_bo; |
}; |
struct pixman_box16 |
{ |
int16_t x1, y1, x2, y2; |
/drivers/video/Intel-2D/sna_render.h |
---|
471,7 → 471,6 |
struct kgem_bo *sna_static_stream_fini(struct sna *sna, |
struct sna_static_stream *stream); |
/* |
struct kgem_bo * |
sna_render_get_solid(struct sna *sna, |
uint32_t color); |
479,9 → 478,6 |
void |
sna_render_flush_solid(struct sna *sna); |
struct kgem_bo * |
sna_render_get_gradient(struct sna *sna, |
PictGradient *pattern); |
uint32_t sna_rgba_for_color(uint32_t color, int depth); |
uint32_t sna_rgba_to_color(uint32_t rgba, uint32_t format); |
493,8 → 489,6 |
uint32_t format); |
bool sna_picture_is_solid(PicturePtr picture, uint32_t *color); |
*/ |
void no_render_init(struct sna *sna); |
bool gen2_render_init(struct sna *sna); |
683,8 → 677,37 |
sna_composite_mask_is_opaque(PicturePtr mask); |
#endif |
void sna_vertex_init(struct sna *sna); |
static inline void sna_vertex_lock(struct sna_render *r) |
{ |
// pthread_mutex_lock(&r->lock); |
} |
static inline void sna_vertex_acquire__locked(struct sna_render *r) |
{ |
r->active++; |
} |
static inline void sna_vertex_unlock(struct sna_render *r) |
{ |
// pthread_mutex_unlock(&r->lock); |
} |
static inline void sna_vertex_release__locked(struct sna_render *r) |
{ |
assert(r->active > 0); |
--r->active; |
// if (--r->active == 0) |
// pthread_cond_signal(&r->wait); |
} |
static inline bool sna_vertex_wait__locked(struct sna_render *r) |
{ |
bool was_active = r->active; |
// while (r->active) |
// pthread_cond_wait(&r->wait, &r->lock); |
return was_active; |
} |
#endif /* SNA_RENDER_H */ |
/drivers/video/Intel-2D/utils.c |
---|
0,0 → 1,150 |
#include <stdint.h> |
#include <stdio.h> |
static inline void native_cpuid(unsigned int *eax, unsigned int *ebx, |
unsigned int *ecx, unsigned int *edx) |
{ |
/* ecx is often an input as well as an output. */ |
asm volatile("cpuid" |
: "=a" (*eax), |
"=b" (*ebx), |
"=c" (*ecx), |
"=d" (*edx) |
: "0" (*eax), "2" (*ecx) |
: "memory"); |
} |
/* Some CPUID calls want 'count' to be placed in ecx */ |
static inline void cpuid_count(unsigned int op, int count, |
unsigned int *eax, unsigned int *ebx, |
unsigned int *ecx, unsigned int *edx) |
{ |
*eax = op; |
*ecx = count; |
native_cpuid(eax, ebx, ecx, edx); |
} |
enum _cache_type { |
CACHE_TYPE_NULL = 0, |
CACHE_TYPE_DATA = 1, |
CACHE_TYPE_INST = 2, |
CACHE_TYPE_UNIFIED = 3 |
}; |
union _cpuid4_leaf_eax { |
struct { |
enum _cache_type type:5; |
unsigned int level:3; |
unsigned int is_self_initializing:1; |
unsigned int is_fully_associative:1; |
unsigned int reserved:4; |
unsigned int num_threads_sharing:12; |
unsigned int num_cores_on_die:6; |
} split; |
uint32_t full; |
}; |
union _cpuid4_leaf_ebx { |
struct { |
unsigned int coherency_line_size:12; |
unsigned int physical_line_partition:10; |
unsigned int ways_of_associativity:10; |
} split; |
uint32_t full; |
}; |
union _cpuid4_leaf_ecx { |
struct { |
unsigned int number_of_sets:32; |
} split; |
uint32_t full; |
}; |
struct _cpuid4_info_regs { |
union _cpuid4_leaf_eax eax; |
union _cpuid4_leaf_ebx ebx; |
union _cpuid4_leaf_ecx ecx; |
unsigned long size; |
}; |
static int |
cpuid4_cache_lookup_regs(int index, |
struct _cpuid4_info_regs *this_leaf) |
{ |
union _cpuid4_leaf_eax eax; |
union _cpuid4_leaf_ebx ebx; |
union _cpuid4_leaf_ecx ecx; |
unsigned edx; |
cpuid_count(4, index, &eax.full, &ebx.full, &ecx.full, &edx); |
if (eax.split.type == CACHE_TYPE_NULL) |
return -1; /* better error ? */ |
this_leaf->eax = eax; |
this_leaf->ebx = ebx; |
this_leaf->ecx = ecx; |
this_leaf->size = (ecx.split.number_of_sets + 1) * |
(ebx.split.coherency_line_size + 1) * |
(ebx.split.physical_line_partition + 1) * |
(ebx.split.ways_of_associativity + 1); |
return 0; |
} |
static int find_num_cache_leaves() |
{ |
unsigned int eax, ebx, ecx, edx, op; |
union _cpuid4_leaf_eax cache_eax; |
int i = -1; |
do { |
++i; |
/* Do cpuid(op) loop to find out num_cache_leaves */ |
cpuid_count(4, i, &eax, &ebx, &ecx, &edx); |
cache_eax.full = eax; |
} while (cache_eax.split.type != CACHE_TYPE_NULL); |
return i; |
}; |
unsigned int cpu_cache_size() |
{ |
unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ |
unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ |
unsigned int num_cache_leaves; |
num_cache_leaves = find_num_cache_leaves(); |
for (i = 0; i < num_cache_leaves; i++) |
{ |
struct _cpuid4_info_regs this_leaf; |
int retval; |
retval = cpuid4_cache_lookup_regs(i, &this_leaf); |
if (retval >= 0) { |
switch (this_leaf.eax.split.level) |
{ |
case 1: |
if (this_leaf.eax.split.type == CACHE_TYPE_DATA) |
new_l1d = this_leaf.size; |
else if (this_leaf.eax.split.type == CACHE_TYPE_INST) |
new_l1i = this_leaf.size; |
break; |
case 2: |
new_l2 = this_leaf.size; |
break; |
case 3: |
new_l3 = this_leaf.size; |
break; |
default: |
break; |
} |
} |
} |
printf("l2 cache %d l3 cache %d\n", new_l2, new_l3); |
return new_l3 != 0 ? new_l3 : new_l2; |
}; |