Intel-2D: sna_blit_copy
i915: i915_gem_execbuffer2. It's full of bugs! git-svn-id: svn://kolibrios.org@3263 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
3dd2cc0db3
commit
75968b0534
|
@ -1149,6 +1149,9 @@ static bool gen6_rectangle_begin(struct sna *sna,
|
||||||
int id = 1 << GEN6_VERTEX(op->u.gen6.flags);
|
int id = 1 << GEN6_VERTEX(op->u.gen6.flags);
|
||||||
int ndwords;
|
int ndwords;
|
||||||
|
|
||||||
|
if (sna_vertex_wait__locked(&sna->render) && sna->render.vertex_offset)
|
||||||
|
return true;
|
||||||
|
|
||||||
ndwords = op->need_magic_ca_pass ? 60 : 6;
|
ndwords = op->need_magic_ca_pass ? 60 : 6;
|
||||||
if ((sna->render.vb_id & id) == 0)
|
if ((sna->render.vb_id & id) == 0)
|
||||||
ndwords += 5;
|
ndwords += 5;
|
||||||
|
@ -1165,6 +1168,12 @@ static bool gen6_rectangle_begin(struct sna *sna,
|
||||||
static int gen6_get_rectangles__flush(struct sna *sna,
|
static int gen6_get_rectangles__flush(struct sna *sna,
|
||||||
const struct sna_composite_op *op)
|
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))
|
if (!kgem_check_batch(&sna->kgem, op->need_magic_ca_pass ? 65 : 5))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1218,7 +1227,7 @@ flush:
|
||||||
gen4_vertex_flush(sna);
|
gen4_vertex_flush(sna);
|
||||||
gen6_magic_ca_pass(sna, op);
|
gen6_magic_ca_pass(sna, op);
|
||||||
}
|
}
|
||||||
// sna_vertex_wait__locked(&sna->render);
|
sna_vertex_wait__locked(&sna->render);
|
||||||
_kgem_submit(&sna->kgem);
|
_kgem_submit(&sna->kgem);
|
||||||
emit_state(sna, op);
|
emit_state(sna, op);
|
||||||
goto start;
|
goto start;
|
||||||
|
@ -2014,7 +2023,17 @@ gen6_render_composite(struct sna *sna,
|
||||||
}
|
}
|
||||||
tmp->done = gen6_render_composite_done;
|
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_emit_composite_state(sna, tmp);
|
||||||
gen6_align_vertex(sna, tmp);
|
gen6_align_vertex(sna, tmp);
|
||||||
|
@ -2654,6 +2673,13 @@ fallback:
|
||||||
assert(GEN6_SAMPLER(op->base.u.gen6.flags) == COPY_SAMPLER);
|
assert(GEN6_SAMPLER(op->base.u.gen6.flags) == COPY_SAMPLER);
|
||||||
assert(GEN6_VERTEX(op->base.u.gen6.flags) == COPY_VERTEX);
|
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_emit_copy_state(sna, &op->base);
|
||||||
gen6_align_vertex(sna, &op->base);
|
gen6_align_vertex(sna, &op->base);
|
||||||
|
@ -3149,7 +3175,13 @@ gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
|
||||||
assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
|
assert(GEN6_SAMPLER(tmp.u.gen6.flags) == FILL_SAMPLER);
|
||||||
assert(GEN6_VERTEX(tmp.u.gen6.flags) == FILL_VERTEX);
|
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_emit_fill_state(sna, &tmp);
|
||||||
gen6_align_vertex(sna, &tmp);
|
gen6_align_vertex(sna, &tmp);
|
||||||
|
@ -3173,6 +3205,7 @@ gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void gen6_render_flush(struct sna *sna)
|
static void gen6_render_flush(struct sna *sna)
|
||||||
{
|
{
|
||||||
|
@ -3182,7 +3215,17 @@ static void gen6_render_flush(struct sna *sna)
|
||||||
assert(sna->render.vertex_offset == 0);
|
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
|
static void
|
||||||
gen6_render_retire(struct kgem *kgem)
|
gen6_render_retire(struct kgem *kgem)
|
||||||
|
@ -3200,6 +3243,23 @@ gen6_render_retire(struct kgem *kgem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
static void gen6_render_reset(struct sna *sna)
|
||||||
{
|
{
|
||||||
|
@ -3319,8 +3379,9 @@ bool gen6_render_init(struct sna *sna)
|
||||||
if (!gen6_render_setup(sna))
|
if (!gen6_render_setup(sna))
|
||||||
return false;
|
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.retire = gen6_render_retire;
|
||||||
|
sna->kgem.expire = gen6_render_expire;
|
||||||
|
|
||||||
// sna->render.composite = gen6_render_composite;
|
// sna->render.composite = gen6_render_composite;
|
||||||
// sna->render.video = gen6_render_video;
|
// sna->render.video = gen6_render_video;
|
||||||
|
@ -3445,3 +3506,90 @@ int gen4_vertex_finish(struct sna *sna)
|
||||||
return sna->render.vertex_size - sna->render.vertex_used;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,13 +218,13 @@ typedef struct _drm_i915_sarea {
|
||||||
#define DRM_IOCTL_I915_HWS_ADDR
|
#define DRM_IOCTL_I915_HWS_ADDR
|
||||||
#define DRM_IOCTL_I915_GEM_INIT
|
#define DRM_IOCTL_I915_GEM_INIT
|
||||||
#define DRM_IOCTL_I915_GEM_EXECBUFFER
|
#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_PIN SRV_I915_GEM_PIN
|
||||||
#define DRM_IOCTL_I915_GEM_UNPIN
|
#define DRM_IOCTL_I915_GEM_UNPIN
|
||||||
#define DRM_IOCTL_I915_GEM_BUSY SRV_I915_GEM_BUSY
|
#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_SET_CACHEING SRV_I915_GEM_SET_CACHEING
|
||||||
#define DRM_IOCTL_I915_GEM_GET_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_ENTERVT
|
||||||
#define DRM_IOCTL_I915_GEM_LEAVEVT
|
#define DRM_IOCTL_I915_GEM_LEAVEVT
|
||||||
#define DRM_IOCTL_I915_GEM_CREATE SRV_I915_GEM_CREATE
|
#define DRM_IOCTL_I915_GEM_CREATE SRV_I915_GEM_CREATE
|
||||||
|
|
|
@ -108,6 +108,15 @@ search_snoop_cache(struct kgem *kgem, unsigned int num_pages, unsigned flags);
|
||||||
#define LOCAL_I915_EXEC_IS_PINNED (1<<10)
|
#define LOCAL_I915_EXEC_IS_PINNED (1<<10)
|
||||||
#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
|
#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
|
||||||
#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
|
#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 UNCACHED 0
|
||||||
#define SNOOPED 1
|
#define SNOOPED 1
|
||||||
|
|
||||||
|
@ -118,6 +127,13 @@ struct local_i915_gem_cacheing {
|
||||||
|
|
||||||
#define LOCAL_IOCTL_I915_GEM_SET_CACHEING SRV_I915_GEM_SET_CACHEING
|
#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_buffer {
|
||||||
struct kgem_bo base;
|
struct kgem_bo base;
|
||||||
void *mem;
|
void *mem;
|
||||||
|
@ -189,7 +205,7 @@ static bool gem_set_tiling(int fd, uint32_t handle, int tiling, int stride)
|
||||||
ret = ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling);
|
ret = ioctl(fd, DRM_IOCTL_I915_GEM_SET_TILING, &set_tiling);
|
||||||
} while (ret == -1 && (errno == EINTR || errno == EAGAIN));
|
} 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)
|
static bool gem_set_cacheing(int fd, uint32_t handle, int cacheing)
|
||||||
|
@ -260,19 +276,19 @@ retry_gtt:
|
||||||
retry_mmap:
|
retry_mmap:
|
||||||
// ptr = mmap(0, bytes(bo), PROT_READ | PROT_WRITE, MAP_SHARED,
|
// ptr = mmap(0, bytes(bo), PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||||
// kgem->fd, mmap_arg.offset);
|
// kgem->fd, mmap_arg.offset);
|
||||||
if (ptr == 0) {
|
// if (ptr == 0) {
|
||||||
printf("%s: failed to mmap %d, %d bytes, into GTT domain: %d\n",
|
printf("%s: failed to mmap %d, %d bytes, into GTT domain: %d\n",
|
||||||
__FUNCTION__, bo->handle, bytes(bo), 0);
|
__FUNCTION__, bo->handle, bytes(bo), 0);
|
||||||
if (__kgem_throttle_retire(kgem, 0))
|
// if (__kgem_throttle_retire(kgem, 0))
|
||||||
goto retry_mmap;
|
// goto retry_mmap;
|
||||||
|
|
||||||
if (kgem->need_expire) {
|
// if (kgem->need_expire) {
|
||||||
kgem_cleanup_cache(kgem);
|
// kgem_cleanup_cache(kgem);
|
||||||
goto retry_mmap;
|
// goto retry_mmap;
|
||||||
}
|
// }
|
||||||
|
|
||||||
ptr = NULL;
|
ptr = NULL;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
@ -639,10 +655,10 @@ static bool test_has_semaphores_enabled(struct kgem *kgem)
|
||||||
|
|
||||||
static bool __kgem_throttle(struct kgem *kgem)
|
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 false;
|
||||||
|
|
||||||
// return errno == EIO;
|
return errno == EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_hw_supported(struct kgem *kgem,
|
static bool is_hw_supported(struct kgem *kgem,
|
||||||
|
@ -1073,7 +1089,138 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
|
||||||
kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT;
|
kgem->batch_flags_base |= LOCAL_I915_EXEC_HANDLE_LUT;
|
||||||
if (kgem->has_pinned_batches)
|
if (kgem->has_pinned_batches)
|
||||||
kgem->batch_flags_base |= LOCAL_I915_EXEC_IS_PINNED;
|
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 *
|
static struct drm_i915_gem_exec_object2 *
|
||||||
|
@ -1763,11 +1910,27 @@ bool kgem_retire(struct kgem *kgem)
|
||||||
return retired;
|
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)
|
static void kgem_commit(struct kgem *kgem)
|
||||||
{
|
{
|
||||||
|
@ -2328,15 +2491,15 @@ void _kgem_submit(struct kgem *kgem)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ret = drmIoctl(kgem->fd,
|
ret = drmIoctl(kgem->fd,
|
||||||
// DRM_IOCTL_I915_GEM_EXECBUFFER2,
|
DRM_IOCTL_I915_GEM_EXECBUFFER2,
|
||||||
// &execbuf);
|
&execbuf);
|
||||||
// while (ret == -1 && errno == EBUSY && retry--) {
|
while (ret == -1 && errno == EBUSY && retry--) {
|
||||||
// __kgem_throttle(kgem);
|
__kgem_throttle(kgem);
|
||||||
// ret = drmIoctl(kgem->fd,
|
ret = drmIoctl(kgem->fd,
|
||||||
// DRM_IOCTL_I915_GEM_EXECBUFFER2,
|
DRM_IOCTL_I915_GEM_EXECBUFFER2,
|
||||||
// &execbuf);
|
&execbuf);
|
||||||
// }
|
}
|
||||||
if (DEBUG_SYNC && ret == 0) {
|
if (DEBUG_SYNC && ret == 0) {
|
||||||
struct drm_i915_gem_set_domain set_domain;
|
struct drm_i915_gem_set_domain set_domain;
|
||||||
|
|
||||||
|
@ -2898,8 +3061,6 @@ inline int kgem_bo_fenced_size(struct kgem *kgem, struct kgem_bo *bo)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
struct kgem_bo *kgem_create_2d(struct kgem *kgem,
|
struct kgem_bo *kgem_create_2d(struct kgem *kgem,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
|
@ -3379,6 +3540,7 @@ create:
|
||||||
return bo;
|
return bo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
|
struct kgem_bo *kgem_create_cpu_2d(struct kgem *kgem,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
|
@ -3497,11 +3659,80 @@ void _kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo)
|
||||||
__kgem_bo_destroy(kgem, bo);
|
__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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -3545,6 +3776,9 @@ uint32_t kgem_add_reloc(struct kgem *kgem,
|
||||||
|
|
||||||
assert((read_write_domain & 0x7fff) == 0 || bo != NULL);
|
assert((read_write_domain & 0x7fff) == 0 || bo != NULL);
|
||||||
|
|
||||||
|
// if( bo != NULL && bo->handle == -1)
|
||||||
|
// return 0;
|
||||||
|
|
||||||
index = kgem->nreloc++;
|
index = kgem->nreloc++;
|
||||||
assert(index < ARRAY_SIZE(kgem->reloc));
|
assert(index < ARRAY_SIZE(kgem->reloc));
|
||||||
kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
|
kgem->reloc[index].offset = pos * sizeof(kgem->batch[0]);
|
||||||
|
@ -3851,6 +4085,42 @@ void kgem_clear_dirty(struct kgem *kgem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
uint32_t kgem_bo_get_binding(struct kgem_bo *bo, uint32_t format)
|
||||||
{
|
{
|
||||||
struct kgem_bo_binding *b;
|
struct kgem_bo_binding *b;
|
||||||
|
@ -3889,5 +4159,37 @@ void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#ifndef KGEM_H
|
#ifndef KGEM_H
|
||||||
#define KGEM_H
|
#define KGEM_H
|
||||||
|
|
||||||
#define HAS_DEBUG_FULL 1
|
#define HAS_DEBUG_FULL 0
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
#include "sna.h"
|
#include "sna.h"
|
||||||
|
|
||||||
|
#include <pixlib2.h>
|
||||||
|
|
||||||
|
static struct sna_fb sna_fb;
|
||||||
|
|
||||||
typedef struct __attribute__((packed))
|
typedef struct __attribute__((packed))
|
||||||
{
|
{
|
||||||
unsigned handle;
|
unsigned handle;
|
||||||
|
@ -64,7 +68,7 @@ void no_render_init(struct sna *sna)
|
||||||
// render->clear = no_render_clear;
|
// render->clear = no_render_clear;
|
||||||
|
|
||||||
render->reset = no_render_reset;
|
render->reset = no_render_reset;
|
||||||
render->flush = no_render_flush;
|
// render->flush = no_render_flush;
|
||||||
// render->fini = no_render_fini;
|
// render->fini = no_render_fini;
|
||||||
|
|
||||||
// sna->kgem.context_switch = no_render_context_switch;
|
// sna->kgem.context_switch = no_render_context_switch;
|
||||||
|
@ -129,24 +133,9 @@ bool sna_accel_init(struct sna *sna)
|
||||||
// return false;
|
// return false;
|
||||||
|
|
||||||
sna_device = sna;
|
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);
|
return kgem_init_fb(&sna->kgem, &sna_fb);
|
||||||
|
|
||||||
sna->render.clear(sna, &screen, screen_bo);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sna_init(uint32_t service)
|
int sna_init(uint32_t service)
|
||||||
|
@ -339,37 +328,69 @@ done:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int sna_blit_copy(uint32_t dst_bitmap, int dst_x, int dst_y,
|
int sna_blit_copy(bitmap_t *src_bitmap, int dst_x, int dst_y,
|
||||||
int w, int h, uint32_t src_bitmap, int src_x, int src_y)
|
int w, int h, int src_x, int src_y)
|
||||||
|
|
||||||
{
|
{
|
||||||
struct sna_copy_op copy;
|
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(&src, 0, sizeof(src));
|
||||||
memset(&dst_bo, 0, sizeof(dst_bo));
|
memset(&dst, 0, sizeof(dst));
|
||||||
|
|
||||||
// src_bo.gaddr = src_bitmap->gaddr;
|
src.drawable.bitsPerPixel = 32;
|
||||||
// src_bo.pitch = src_bitmap->pitch;
|
src.drawable.width = src_bitmap->width;
|
||||||
// src_bo.tiling = 0;
|
src.drawable.height = src_bitmap->height;
|
||||||
|
|
||||||
// dst_bo.gaddr = dst_bitmap->gaddr;
|
dst.drawable.bitsPerPixel = 32;
|
||||||
// dst_bo.pitch = dst_bitmap->pitch;
|
dst.drawable.width = sna_fb.width;
|
||||||
// dst_bo.tiling = 0;
|
dst.drawable.height = sna_fb.height;
|
||||||
|
|
||||||
memset(©, 0, sizeof(copy));
|
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.blt(sna_device, ©, src_x, src_y, w, h, dst_x, dst_y);
|
||||||
copy.done(sna_device, ©);
|
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,
|
int sna_blit_tex(bitmap_t *dst_bitmap, int dst_x, int dst_y,
|
||||||
|
|
|
@ -44,7 +44,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "intel_driver.h"
|
#include "intel_driver.h"
|
||||||
#include "pciaccess.h"
|
#include "pciaccess.h"
|
||||||
|
@ -69,11 +69,13 @@ int drmIoctl(int fd, unsigned long request, void *arg);
|
||||||
#define SRV_I915_GEM_GET_APERTURE 26
|
#define SRV_I915_GEM_GET_APERTURE 26
|
||||||
#define SRV_I915_GEM_PWRITE 27
|
#define SRV_I915_GEM_PWRITE 27
|
||||||
#define SRV_I915_GEM_BUSY 28
|
#define SRV_I915_GEM_BUSY 28
|
||||||
|
|
||||||
#define SRV_I915_GEM_SET_DOMAIN 29
|
#define SRV_I915_GEM_SET_DOMAIN 29
|
||||||
#define SRV_I915_GEM_MMAP 30
|
#define SRV_I915_GEM_MMAP 30
|
||||||
#define SRV_I915_GEM_MMAP_GTT 31
|
#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 DRM_IOCTL_GEM_CLOSE SRV_DRM_GEM_CLOSE
|
||||||
|
@ -153,6 +155,15 @@ typedef struct _Pixmap {
|
||||||
} PixmapRec;
|
} PixmapRec;
|
||||||
|
|
||||||
|
|
||||||
|
struct sna_fb
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t tiling;
|
||||||
|
|
||||||
|
struct kgem_bo *fb_bo;
|
||||||
|
};
|
||||||
|
|
||||||
struct pixman_box16
|
struct pixman_box16
|
||||||
{
|
{
|
||||||
|
|
|
@ -471,7 +471,6 @@ unsigned sna_static_stream_compile_wm(struct sna *sna,
|
||||||
struct kgem_bo *sna_static_stream_fini(struct sna *sna,
|
struct kgem_bo *sna_static_stream_fini(struct sna *sna,
|
||||||
struct sna_static_stream *stream);
|
struct sna_static_stream *stream);
|
||||||
|
|
||||||
/*
|
|
||||||
struct kgem_bo *
|
struct kgem_bo *
|
||||||
sna_render_get_solid(struct sna *sna,
|
sna_render_get_solid(struct sna *sna,
|
||||||
uint32_t color);
|
uint32_t color);
|
||||||
|
@ -479,9 +478,6 @@ sna_render_get_solid(struct sna *sna,
|
||||||
void
|
void
|
||||||
sna_render_flush_solid(struct sna *sna);
|
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_for_color(uint32_t color, int depth);
|
||||||
uint32_t sna_rgba_to_color(uint32_t rgba, uint32_t format);
|
uint32_t sna_rgba_to_color(uint32_t rgba, uint32_t format);
|
||||||
|
@ -493,8 +489,6 @@ bool sna_get_rgba_from_pixel(uint32_t pixel,
|
||||||
uint32_t format);
|
uint32_t format);
|
||||||
bool sna_picture_is_solid(PicturePtr picture, uint32_t *color);
|
bool sna_picture_is_solid(PicturePtr picture, uint32_t *color);
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
void no_render_init(struct sna *sna);
|
void no_render_init(struct sna *sna);
|
||||||
|
|
||||||
bool gen2_render_init(struct sna *sna);
|
bool gen2_render_init(struct sna *sna);
|
||||||
|
@ -683,8 +677,37 @@ bool
|
||||||
sna_composite_mask_is_opaque(PicturePtr mask);
|
sna_composite_mask_is_opaque(PicturePtr mask);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void sna_vertex_init(struct sna *sna);
|
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 */
|
#endif /* SNA_RENDER_H */
|
||||||
|
|
|
@ -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;
|
||||||
|
};
|
|
@ -1547,12 +1547,15 @@ int i915_driver_unload(struct drm_device *dev)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int i915_driver_open(struct drm_device *dev, struct drm_file *file)
|
int i915_driver_open(struct drm_device *dev, struct drm_file *file)
|
||||||
{
|
{
|
||||||
struct drm_i915_file_private *file_priv;
|
struct drm_i915_file_private *file_priv;
|
||||||
|
|
||||||
DRM_DEBUG_DRIVER("\n");
|
DRM_DEBUG_DRIVER("\n");
|
||||||
|
ENTER();
|
||||||
|
|
||||||
file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL);
|
file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL);
|
||||||
if (!file_priv)
|
if (!file_priv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1564,9 +1567,11 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file)
|
||||||
|
|
||||||
idr_init(&file_priv->context_idr);
|
idr_init(&file_priv->context_idr);
|
||||||
|
|
||||||
|
LEAVE();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
/**
|
/**
|
||||||
* i915_driver_lastclose - clean up after all DRM clients have exited
|
* i915_driver_lastclose - clean up after all DRM clients have exited
|
||||||
* @dev: DRM device
|
* @dev: DRM device
|
||||||
|
|
|
@ -492,7 +492,7 @@ static struct drm_driver driver = {
|
||||||
// DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME,
|
// DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | DRIVER_PRIME,
|
||||||
// .load = i915_driver_load,
|
// .load = i915_driver_load,
|
||||||
// .unload = i915_driver_unload,
|
// .unload = i915_driver_unload,
|
||||||
// .open = i915_driver_open,
|
.open = i915_driver_open,
|
||||||
// .lastclose = i915_driver_lastclose,
|
// .lastclose = i915_driver_lastclose,
|
||||||
// .preclose = i915_driver_preclose,
|
// .preclose = i915_driver_preclose,
|
||||||
// .postclose = i915_driver_postclose,
|
// .postclose = i915_driver_postclose,
|
||||||
|
@ -577,6 +577,12 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
|
|
||||||
dev->driver = &driver;
|
dev->driver = &driver;
|
||||||
|
|
||||||
|
if (dev->driver->open) {
|
||||||
|
ret = dev->driver->open(dev, priv);
|
||||||
|
if (ret < 0)
|
||||||
|
goto err_g4;
|
||||||
|
}
|
||||||
|
|
||||||
ret = i915_driver_load(dev, ent->driver_data );
|
ret = i915_driver_load(dev, ent->driver_data );
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -37,6 +37,10 @@
|
||||||
|
|
||||||
extern int x86_clflush_size;
|
extern int x86_clflush_size;
|
||||||
|
|
||||||
|
#define PROT_READ 0x1 /* page can be read */
|
||||||
|
#define PROT_WRITE 0x2 /* page can be written */
|
||||||
|
#define MAP_SHARED 0x01 /* Share changes */
|
||||||
|
|
||||||
#undef mb
|
#undef mb
|
||||||
#undef rmb
|
#undef rmb
|
||||||
#undef wmb
|
#undef wmb
|
||||||
|
@ -44,6 +48,10 @@ extern int x86_clflush_size;
|
||||||
#define rmb() asm volatile ("lfence")
|
#define rmb() asm volatile ("lfence")
|
||||||
#define wmb() asm volatile ("sfence")
|
#define wmb() asm volatile ("sfence")
|
||||||
|
|
||||||
|
unsigned long vm_mmap(struct file *file, unsigned long addr,
|
||||||
|
unsigned long len, unsigned long prot,
|
||||||
|
unsigned long flag, unsigned long offset);
|
||||||
|
|
||||||
static inline void clflush(volatile void *__p)
|
static inline void clflush(volatile void *__p)
|
||||||
{
|
{
|
||||||
asm volatile("clflush %0" : "+m" (*(volatile char*)__p));
|
asm volatile("clflush %0" : "+m" (*(volatile char*)__p));
|
||||||
|
@ -1296,8 +1304,8 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
||||||
if (obj == NULL)
|
if (obj == NULL)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
dbgprintf("%s offset %lld size %lld not supported\n",
|
dbgprintf("%s offset %lld size %lld\n",
|
||||||
args->offset, args->size);
|
__FUNCTION__, args->offset, args->size);
|
||||||
/* prime objects have no backing filp to GEM mmap
|
/* prime objects have no backing filp to GEM mmap
|
||||||
* pages from.
|
* pages from.
|
||||||
*/
|
*/
|
||||||
|
@ -1306,17 +1314,16 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// addr = vm_mmap(obj->filp, 0, args->size,
|
addr = vm_mmap(obj->filp, 0, args->size,
|
||||||
// PROT_READ | PROT_WRITE, MAP_SHARED,
|
PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||||
// args->offset);
|
args->offset);
|
||||||
drm_gem_object_unreference_unlocked(obj);
|
drm_gem_object_unreference_unlocked(obj);
|
||||||
// if (IS_ERR((void *)addr))
|
if (IS_ERR((void *)addr))
|
||||||
// return addr;
|
return addr;
|
||||||
|
|
||||||
args->addr_ptr = (uint64_t) addr;
|
args->addr_ptr = (uint64_t) addr;
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
// return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1444,8 +1451,8 @@ i915_gem_object_truncate(struct drm_i915_gem_object *obj)
|
||||||
|
|
||||||
// i915_gem_object_free_mmap_offset(obj);
|
// i915_gem_object_free_mmap_offset(obj);
|
||||||
|
|
||||||
// if (obj->base.filp == NULL)
|
if (obj->base.filp == NULL)
|
||||||
// return;
|
return;
|
||||||
|
|
||||||
/* Our goal here is to return as much of the memory as
|
/* Our goal here is to return as much of the memory as
|
||||||
* is possible back to the system as we are called from OOM.
|
* is possible back to the system as we are called from OOM.
|
||||||
|
@ -1491,7 +1498,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
page_cache_release(page);
|
// page_cache_release(page);
|
||||||
}
|
}
|
||||||
//DRM_DEBUG_KMS("%s release %d pages\n", __FUNCTION__, page_count);
|
//DRM_DEBUG_KMS("%s release %d pages\n", __FUNCTION__, page_count);
|
||||||
obj->dirty = 0;
|
obj->dirty = 0;
|
||||||
|
@ -1784,7 +1791,17 @@ i915_add_request(struct intel_ring_buffer *ring,
|
||||||
list_add_tail(&request->list, &ring->request_list);
|
list_add_tail(&request->list, &ring->request_list);
|
||||||
request->file_priv = NULL;
|
request->file_priv = NULL;
|
||||||
|
|
||||||
|
if (file) {
|
||||||
|
struct drm_i915_file_private *file_priv = file->driver_priv;
|
||||||
|
|
||||||
|
spin_lock(&file_priv->mm.lock);
|
||||||
|
request->file_priv = file_priv;
|
||||||
|
list_add_tail(&request->client_list,
|
||||||
|
&file_priv->mm.request_list);
|
||||||
|
spin_unlock(&file_priv->mm.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
trace_i915_gem_request_add(ring, request->seqno);
|
||||||
ring->outstanding_lazy_request = 0;
|
ring->outstanding_lazy_request = 0;
|
||||||
|
|
||||||
if (!dev_priv->mm.suspended) {
|
if (!dev_priv->mm.suspended) {
|
||||||
|
@ -1805,8 +1822,21 @@ i915_add_request(struct intel_ring_buffer *ring,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
i915_gem_request_remove_from_client(struct drm_i915_gem_request *request)
|
||||||
|
{
|
||||||
|
struct drm_i915_file_private *file_priv = request->file_priv;
|
||||||
|
|
||||||
|
if (!file_priv)
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock(&file_priv->mm.lock);
|
||||||
|
if (request->file_priv) {
|
||||||
|
list_del(&request->client_list);
|
||||||
|
request->file_priv = NULL;
|
||||||
|
}
|
||||||
|
spin_unlock(&file_priv->mm.lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
|
static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
|
||||||
struct intel_ring_buffer *ring)
|
struct intel_ring_buffer *ring)
|
||||||
|
@ -1819,7 +1849,7 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv,
|
||||||
list);
|
list);
|
||||||
|
|
||||||
list_del(&request->list);
|
list_del(&request->list);
|
||||||
// i915_gem_request_remove_from_client(request);
|
i915_gem_request_remove_from_client(request);
|
||||||
kfree(request);
|
kfree(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1887,6 +1917,8 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
|
||||||
{
|
{
|
||||||
uint32_t seqno;
|
uint32_t seqno;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
if (list_empty(&ring->request_list))
|
if (list_empty(&ring->request_list))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1913,6 +1945,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
|
||||||
ring->last_retired_head = request->tail;
|
ring->last_retired_head = request->tail;
|
||||||
|
|
||||||
list_del(&request->list);
|
list_del(&request->list);
|
||||||
|
i915_gem_request_remove_from_client(request);
|
||||||
kfree(request);
|
kfree(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1939,6 +1972,7 @@ i915_gem_retire_requests_ring(struct intel_ring_buffer *ring)
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_ON(i915_verify_lists(ring->dev));
|
WARN_ON(i915_verify_lists(ring->dev));
|
||||||
|
LEAVE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1961,6 +1995,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
|
||||||
bool idle;
|
bool idle;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
dev_priv = container_of(work, drm_i915_private_t,
|
dev_priv = container_of(work, drm_i915_private_t,
|
||||||
mm.retire_work.work);
|
mm.retire_work.work);
|
||||||
dev = dev_priv->dev;
|
dev = dev_priv->dev;
|
||||||
|
@ -1990,6 +2026,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
|
||||||
intel_mark_idle(dev);
|
intel_mark_idle(dev);
|
||||||
|
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
|
LEAVE();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2127,6 +2165,9 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
|
||||||
drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
|
drm_i915_private_t *dev_priv = obj->base.dev->dev_private;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if(obj == get_fb_obj())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (obj->gtt_space == NULL)
|
if (obj->gtt_space == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -3105,7 +3146,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* Throttle our rendering by waiting until the ring has completed our requests
|
/* Throttle our rendering by waiting until the ring has completed our requests
|
||||||
* emitted over 20 msec ago.
|
* emitted over 20 msec ago.
|
||||||
*
|
*
|
||||||
|
@ -3121,7 +3161,7 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
|
||||||
{
|
{
|
||||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||||
struct drm_i915_file_private *file_priv = file->driver_priv;
|
struct drm_i915_file_private *file_priv = file->driver_priv;
|
||||||
unsigned long recent_enough = GetTimerTics() - msecs_to_jiffies(20);
|
unsigned long recent_enough = GetTimerTicks() - msecs_to_jiffies(20);
|
||||||
struct drm_i915_gem_request *request;
|
struct drm_i915_gem_request *request;
|
||||||
struct intel_ring_buffer *ring = NULL;
|
struct intel_ring_buffer *ring = NULL;
|
||||||
u32 seqno = 0;
|
u32 seqno = 0;
|
||||||
|
@ -3149,7 +3189,6 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
int
|
int
|
||||||
i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||||
|
@ -3162,7 +3201,6 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||||
if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
if (WARN_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (obj->gtt_space != NULL) {
|
if (obj->gtt_space != NULL) {
|
||||||
if ((alignment && obj->gtt_offset & (alignment - 1)) ||
|
if ((alignment && obj->gtt_offset & (alignment - 1)) ||
|
||||||
(map_and_fenceable && !obj->map_and_fenceable)) {
|
(map_and_fenceable && !obj->map_and_fenceable)) {
|
||||||
|
@ -3178,7 +3216,6 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (obj->gtt_space == NULL) {
|
if (obj->gtt_space == NULL) {
|
||||||
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
|
struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
|
||||||
|
@ -3342,7 +3379,6 @@ unlock:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
int
|
int
|
||||||
i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
|
i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
|
||||||
struct drm_file *file_priv)
|
struct drm_file *file_priv)
|
||||||
|
@ -3350,6 +3386,8 @@ i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
|
||||||
return i915_gem_ring_throttle(dev, file_priv);
|
return i915_gem_ring_throttle(dev, file_priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
int
|
int
|
||||||
i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
|
i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
|
||||||
struct drm_file *file_priv)
|
struct drm_file *file_priv)
|
||||||
|
@ -3545,7 +3583,7 @@ i915_gem_idle(struct drm_device *dev)
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
/* Cancel the retire work handler, which should be idle now. */
|
/* Cancel the retire work handler, which should be idle now. */
|
||||||
// cancel_delayed_work_sync(&dev_priv->mm.retire_work);
|
cancel_delayed_work_sync(&dev_priv->mm.retire_work);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,5 +23,7 @@
|
||||||
#define trace_i915_reg_rw(a, b, c, d)
|
#define trace_i915_reg_rw(a, b, c, d)
|
||||||
#define trace_i915_ring_wait_begin(a)
|
#define trace_i915_ring_wait_begin(a)
|
||||||
#define trace_i915_gem_object_pwrite(a, b, c)
|
#define trace_i915_gem_object_pwrite(a, b, c)
|
||||||
|
#define trace_i915_gem_request_add(a, b)
|
||||||
|
#define trace_i915_gem_ring_dispatch(a, b, c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6985,6 +6985,8 @@ void intel_mark_fb_busy(struct drm_i915_gem_object *obj)
|
||||||
struct drm_device *dev = obj->base.dev;
|
struct drm_device *dev = obj->base.dev;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
if (!i915_powersave)
|
if (!i915_powersave)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -7002,6 +7004,8 @@ void intel_mark_fb_idle(struct drm_i915_gem_object *obj)
|
||||||
struct drm_device *dev = obj->base.dev;
|
struct drm_device *dev = obj->base.dev;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
|
ENTER();
|
||||||
|
|
||||||
if (!i915_powersave)
|
if (!i915_powersave)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,12 @@
|
||||||
#include <drm/i915_drm.h>
|
#include <drm/i915_drm.h>
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
|
|
||||||
|
static struct drm_i915_gem_object *fb_obj;
|
||||||
|
|
||||||
|
struct drm_i915_gem_object *get_fb_obj()
|
||||||
|
{
|
||||||
|
return fb_obj;
|
||||||
|
};
|
||||||
|
|
||||||
struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
|
struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
|
||||||
{
|
{
|
||||||
|
@ -144,6 +150,10 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||||
obj->gtt_space = &lfb_vm_node;
|
obj->gtt_space = &lfb_vm_node;
|
||||||
obj->gtt_offset = 0;
|
obj->gtt_offset = 0;
|
||||||
obj->pin_count = 2;
|
obj->pin_count = 2;
|
||||||
|
obj->cache_level = I915_CACHE_NONE;
|
||||||
|
obj->base.write_domain = 0;
|
||||||
|
obj->base.read_domains = I915_GEM_DOMAIN_GTT;
|
||||||
|
|
||||||
}
|
}
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
|
@ -182,7 +192,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||||
info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;
|
info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset;
|
||||||
info->fix.smem_len = size;
|
info->fix.smem_len = size;
|
||||||
|
|
||||||
info->screen_base = 0xFE000000;
|
info->screen_base = (void*) 0xFE000000;
|
||||||
info->screen_size = size;
|
info->screen_size = size;
|
||||||
|
|
||||||
// memset(info->screen_base, 0, size);
|
// memset(info->screen_base, 0, size);
|
||||||
|
@ -200,6 +210,8 @@ static int intelfb_create(struct intel_fbdev *ifbdev,
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
// vga_switcheroo_client_fb_set(dev->pdev, info);
|
// vga_switcheroo_client_fb_set(dev->pdev, info);
|
||||||
|
|
||||||
|
fb_obj = obj;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_unpin:
|
out_unpin:
|
||||||
|
|
|
@ -624,6 +624,23 @@ cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
|
||||||
return old;
|
return old;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sna_fb
|
||||||
|
{
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t tiling;
|
||||||
|
};
|
||||||
|
|
||||||
|
int i915_fbinfo(struct sna_fb *fb)
|
||||||
|
{
|
||||||
|
fb->width = os_display->width;
|
||||||
|
fb->height = os_display->height;
|
||||||
|
fb->pitch = os_display->pitch;
|
||||||
|
fb->tiling = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef __HWA__
|
#ifdef __HWA__
|
||||||
|
|
|
@ -70,8 +70,8 @@ u32_t drvEntry(int action, char *cmdline)
|
||||||
|
|
||||||
if(!dbg_open(log))
|
if(!dbg_open(log))
|
||||||
{
|
{
|
||||||
// strcpy(log, "/tmp1/1/i915.log");
|
strcpy(log, "/tmp1/1/i915.log");
|
||||||
strcpy(log, "/RD/1/DRIVERS/i915.log");
|
// strcpy(log, "/RD/1/DRIVERS/i915.log");
|
||||||
|
|
||||||
if(!dbg_open(log))
|
if(!dbg_open(log))
|
||||||
{
|
{
|
||||||
|
@ -132,6 +132,12 @@ u32_t drvEntry(int action, char *cmdline)
|
||||||
#define SRV_I915_GEM_PWRITE 27
|
#define SRV_I915_GEM_PWRITE 27
|
||||||
#define SRV_I915_GEM_BUSY 28
|
#define SRV_I915_GEM_BUSY 28
|
||||||
#define SRV_I915_GEM_SET_DOMAIN 29
|
#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 check_input(size) \
|
#define check_input(size) \
|
||||||
|
@ -247,6 +253,22 @@ int _stdcall display_handler(ioctl_t *io)
|
||||||
retval = i915_gem_set_domain_ioctl(main_device, inp, file);
|
retval = i915_gem_set_domain_ioctl(main_device, inp, file);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SRV_I915_GEM_THROTTLE:
|
||||||
|
retval = i915_gem_throttle_ioctl(main_device, inp, file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SRV_I915_GEM_MMAP:
|
||||||
|
retval = i915_gem_mmap_ioctl(main_device, inp, file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SRV_FBINFO:
|
||||||
|
retval = i915_fbinfo(inp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SRV_I915_GEM_EXECBUFFER2:
|
||||||
|
retval = i915_gem_execbuffer2(main_device, inp, file);
|
||||||
|
break;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#include <ddk.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
#include <drm/drmP.h>
|
#include <drm/drmP.h>
|
||||||
#include <drm/i915_drm.h>
|
#include <drm/i915_drm.h>
|
||||||
#include "i915_drv.h"
|
#include "i915_drv.h"
|
||||||
|
@ -57,3 +59,39 @@ struct page *shmem_read_mapping_page_gfp(struct file *filep,
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
unsigned long vm_mmap(struct file *file, unsigned long addr,
|
||||||
|
unsigned long len, unsigned long prot,
|
||||||
|
unsigned long flag, unsigned long offset)
|
||||||
|
{
|
||||||
|
char *mem, *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (unlikely(offset + PAGE_ALIGN(len) < offset))
|
||||||
|
return -EINVAL;
|
||||||
|
if (unlikely(offset & ~PAGE_MASK))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
mem = UserAlloc(len);
|
||||||
|
if(unlikely(mem == NULL))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
for(i = offset, ptr = mem; i < offset+len; i+= 4096, ptr+= 4096)
|
||||||
|
{
|
||||||
|
struct page *page;
|
||||||
|
|
||||||
|
page = shmem_read_mapping_page_gfp(file, i/PAGE_SIZE,0);
|
||||||
|
|
||||||
|
if (unlikely(IS_ERR(page)))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
MapPage(ptr, (addr_t)page, PG_SHARED|PG_UW);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (unsigned long)mem;
|
||||||
|
err:
|
||||||
|
UserFree(mem);
|
||||||
|
return -ENOMEM;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue