2012-02-16 11:48:38 +01:00
|
|
|
#include <drmP.h>
|
|
|
|
#include <drm.h>
|
|
|
|
#include "i915_drm.h"
|
|
|
|
#include "i915_drv.h"
|
|
|
|
#include "intel_drv.h"
|
|
|
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <errno-base.h>
|
|
|
|
#include <memory.h>
|
|
|
|
|
|
|
|
#include <syscall.h>
|
|
|
|
|
|
|
|
#include "../bitmap.h"
|
|
|
|
|
|
|
|
#include "sna.h"
|
|
|
|
|
|
|
|
struct kgem_bo *create_bo(bitmap_t *bitmap);
|
|
|
|
|
|
|
|
static Bool sna_solid_cache_init(struct sna *sna);
|
|
|
|
|
|
|
|
struct sna *sna_device;
|
|
|
|
|
|
|
|
void no_render_init(struct sna *sna)
|
|
|
|
{
|
|
|
|
struct sna_render *render = &sna->render;
|
|
|
|
|
|
|
|
memset (render,0, sizeof (*render));
|
|
|
|
|
|
|
|
render->vertices = render->vertex_data;
|
|
|
|
render->vertex_size = ARRAY_SIZE(render->vertex_data);
|
|
|
|
|
|
|
|
// render->composite = no_render_composite;
|
|
|
|
|
|
|
|
// render->copy_boxes = no_render_copy_boxes;
|
|
|
|
// render->copy = no_render_copy;
|
|
|
|
|
|
|
|
// render->fill_boxes = no_render_fill_boxes;
|
|
|
|
// render->fill = no_render_fill;
|
|
|
|
// render->fill_one = no_render_fill_one;
|
|
|
|
// render->clear = no_render_clear;
|
|
|
|
|
|
|
|
// render->reset = no_render_reset;
|
|
|
|
// render->flush = no_render_flush;
|
|
|
|
// render->fini = no_render_fini;
|
|
|
|
|
|
|
|
// sna->kgem.context_switch = no_render_context_switch;
|
|
|
|
// sna->kgem.retire = no_render_retire;
|
|
|
|
|
|
|
|
// if (sna->kgem.gen >= 60)
|
|
|
|
sna->kgem.ring = KGEM_RENDER;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Bool sna_accel_init(struct sna *sna)
|
|
|
|
{
|
|
|
|
const char *backend;
|
|
|
|
|
|
|
|
// list_init(&sna->deferred_free);
|
|
|
|
// list_init(&sna->dirty_pixmaps);
|
|
|
|
// list_init(&sna->active_pixmaps);
|
|
|
|
// list_init(&sna->inactive_clock[0]);
|
|
|
|
// list_init(&sna->inactive_clock[1]);
|
|
|
|
|
|
|
|
// sna_accel_install_timers(sna);
|
|
|
|
|
|
|
|
|
|
|
|
backend = "no";
|
|
|
|
sna->have_render = false;
|
|
|
|
sna->default_tiling = 0; //I915_TILING_X;
|
|
|
|
no_render_init(sna);
|
|
|
|
|
|
|
|
if ((sna->have_render = gen6_render_init(sna)))
|
|
|
|
backend = "SandyBridge";
|
|
|
|
|
|
|
|
/*
|
|
|
|
if (sna->chipset.info->gen >= 80) {
|
|
|
|
} else if (sna->chipset.info->gen >= 70) {
|
|
|
|
if ((sna->have_render = gen7_render_init(sna)))
|
|
|
|
backend = "IvyBridge";
|
|
|
|
} else if (sna->chipset.info->gen >= 60) {
|
|
|
|
if ((sna->have_render = gen6_render_init(sna)))
|
|
|
|
backend = "SandyBridge";
|
|
|
|
} else if (sna->chipset.info->gen >= 50) {
|
|
|
|
if ((sna->have_render = gen5_render_init(sna)))
|
|
|
|
backend = "Ironlake";
|
|
|
|
} else if (sna->chipset.info->gen >= 40) {
|
|
|
|
if ((sna->have_render = gen4_render_init(sna)))
|
|
|
|
backend = "Broadwater";
|
|
|
|
} else if (sna->chipset.info->gen >= 30) {
|
|
|
|
if ((sna->have_render = gen3_render_init(sna)))
|
|
|
|
backend = "gen3";
|
|
|
|
} else if (sna->chipset.info->gen >= 20) {
|
|
|
|
if ((sna->have_render = gen2_render_init(sna)))
|
|
|
|
backend = "gen2";
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
DBG(("%s(backend=%s, have_render=%d)\n",
|
|
|
|
__FUNCTION__, backend, sna->have_render));
|
|
|
|
|
|
|
|
kgem_reset(&sna->kgem);
|
|
|
|
|
|
|
|
if (!sna_solid_cache_init(sna))
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
int sna_init()
|
|
|
|
{
|
|
|
|
struct sna *sna;
|
|
|
|
|
|
|
|
DBG(("%s\n", __FUNCTION__));
|
|
|
|
|
|
|
|
sna = kzalloc(sizeof(struct sna), 0);
|
|
|
|
if (sna == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
// sna->mode.cpp = 4;
|
|
|
|
|
|
|
|
kgem_init(&sna->kgem, 60);
|
|
|
|
/*
|
|
|
|
if (!xf86ReturnOptValBool(sna->Options,
|
|
|
|
OPTION_RELAXED_FENCING,
|
|
|
|
sna->kgem.has_relaxed_fencing)) {
|
|
|
|
xf86DrvMsg(scrn->scrnIndex,
|
|
|
|
sna->kgem.has_relaxed_fencing ? X_CONFIG : X_PROBED,
|
|
|
|
"Disabling use of relaxed fencing\n");
|
|
|
|
sna->kgem.has_relaxed_fencing = 0;
|
|
|
|
}
|
|
|
|
if (!xf86ReturnOptValBool(sna->Options,
|
|
|
|
OPTION_VMAP,
|
|
|
|
sna->kgem.has_vmap)) {
|
|
|
|
xf86DrvMsg(scrn->scrnIndex,
|
|
|
|
sna->kgem.has_vmap ? X_CONFIG : X_PROBED,
|
|
|
|
"Disabling use of vmap\n");
|
|
|
|
sna->kgem.has_vmap = 0;
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Disable tiling by default */
|
|
|
|
sna->tiling = SNA_TILING_DISABLE;
|
|
|
|
|
|
|
|
/* Default fail-safe value of 75 Hz */
|
|
|
|
// sna->vblank_interval = 1000 * 1000 * 1000 / 75;
|
|
|
|
|
|
|
|
sna->flags = 0;
|
|
|
|
sna->flags |= SNA_NO_THROTTLE;
|
|
|
|
sna->flags |= SNA_NO_DELAYED_FLUSH;
|
|
|
|
|
|
|
|
return sna_accel_init(sna);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static Bool sna_solid_cache_init(struct sna *sna)
|
|
|
|
{
|
|
|
|
struct sna_solid_cache *cache = &sna->render.solid_cache;
|
|
|
|
|
|
|
|
DBG(("%s\n", __FUNCTION__));
|
|
|
|
|
|
|
|
cache->cache_bo =
|
|
|
|
kgem_create_linear(&sna->kgem, sizeof(cache->color));
|
|
|
|
if (!cache->cache_bo)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialise [0] with white since it is very common and filling the
|
|
|
|
* zeroth slot simplifies some of the checks.
|
|
|
|
*/
|
|
|
|
cache->color[0] = 0xffffffff;
|
|
|
|
cache->bo[0] = kgem_create_proxy(cache->cache_bo, 0, sizeof(uint32_t));
|
|
|
|
cache->bo[0]->pitch = 4;
|
|
|
|
cache->dirty = 1;
|
|
|
|
cache->size = 1;
|
|
|
|
cache->last = 0;
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sna_render_flush_solid(struct sna *sna)
|
|
|
|
{
|
|
|
|
struct sna_solid_cache *cache = &sna->render.solid_cache;
|
|
|
|
|
|
|
|
DBG(("sna_render_flush_solid(size=%d)\n", cache->size));
|
|
|
|
assert(cache->dirty);
|
|
|
|
assert(cache->size);
|
|
|
|
|
|
|
|
kgem_bo_write(&sna->kgem, cache->cache_bo,
|
|
|
|
cache->color, cache->size*sizeof(uint32_t));
|
|
|
|
cache->dirty = 0;
|
|
|
|
cache->last = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
sna_render_finish_solid(struct sna *sna, bool force)
|
|
|
|
{
|
|
|
|
struct sna_solid_cache *cache = &sna->render.solid_cache;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
DBG(("sna_render_finish_solid(force=%d, domain=%d, busy=%d, dirty=%d)\n",
|
|
|
|
force, cache->cache_bo->domain, cache->cache_bo->rq != NULL, cache->dirty));
|
|
|
|
|
|
|
|
if (!force && cache->cache_bo->domain != DOMAIN_GPU)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (cache->dirty)
|
|
|
|
sna_render_flush_solid(sna);
|
|
|
|
|
|
|
|
for (i = 0; i < cache->size; i++) {
|
|
|
|
if (cache->bo[i] == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
kgem_bo_destroy(&sna->kgem, cache->bo[i]);
|
|
|
|
cache->bo[i] = NULL;
|
|
|
|
}
|
|
|
|
kgem_bo_destroy(&sna->kgem, cache->cache_bo);
|
|
|
|
|
|
|
|
DBG(("sna_render_finish_solid reset\n"));
|
|
|
|
|
|
|
|
cache->cache_bo = kgem_create_linear(&sna->kgem, sizeof(cache->color));
|
|
|
|
cache->bo[0] = kgem_create_proxy(cache->cache_bo, 0, sizeof(uint32_t));
|
|
|
|
cache->bo[0]->pitch = 4;
|
|
|
|
if (force)
|
|
|
|
cache->size = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct kgem_bo *
|
|
|
|
sna_render_get_solid(struct sna *sna, uint32_t color)
|
|
|
|
{
|
|
|
|
struct sna_solid_cache *cache = &sna->render.solid_cache;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
DBG(("%s: %08x\n", __FUNCTION__, color));
|
|
|
|
|
|
|
|
// if ((color & 0xffffff) == 0) /* alpha only */
|
|
|
|
// return kgem_bo_reference(sna->render.alpha_cache.bo[color>>24]);
|
|
|
|
|
|
|
|
if (color == 0xffffffff) {
|
|
|
|
DBG(("%s(white)\n", __FUNCTION__));
|
|
|
|
return kgem_bo_reference(cache->bo[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cache->color[cache->last] == color) {
|
|
|
|
DBG(("sna_render_get_solid(%d) = %x (last)\n",
|
|
|
|
cache->last, color));
|
|
|
|
return kgem_bo_reference(cache->bo[cache->last]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 1; i < cache->size; i++) {
|
|
|
|
if (cache->color[i] == color) {
|
|
|
|
if (cache->bo[i] == NULL) {
|
|
|
|
DBG(("sna_render_get_solid(%d) = %x (recreate)\n",
|
|
|
|
i, color));
|
|
|
|
goto create;
|
|
|
|
} else {
|
|
|
|
DBG(("sna_render_get_solid(%d) = %x (old)\n",
|
|
|
|
i, color));
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sna_render_finish_solid(sna, i == ARRAY_SIZE(cache->color));
|
|
|
|
|
|
|
|
i = cache->size++;
|
|
|
|
cache->color[i] = color;
|
|
|
|
cache->dirty = 1;
|
|
|
|
DBG(("sna_render_get_solid(%d) = %x (new)\n", i, color));
|
|
|
|
|
|
|
|
create:
|
|
|
|
cache->bo[i] = kgem_create_proxy(cache->cache_bo,
|
|
|
|
i*sizeof(uint32_t), sizeof(uint32_t));
|
|
|
|
cache->bo[i]->pitch = 4;
|
|
|
|
|
|
|
|
done:
|
|
|
|
cache->last = i;
|
|
|
|
return kgem_bo_reference(cache->bo[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
int sna_blit_copy(bitmap_t *dst_bitmap, int dst_x, int dst_y,
|
|
|
|
int w, int h, bitmap_t *src_bitmap, int src_x, int src_y)
|
|
|
|
|
|
|
|
{
|
2012-02-18 15:32:16 +01:00
|
|
|
batchbuffer_t execbuffer;
|
|
|
|
|
2012-02-16 11:48:38 +01:00
|
|
|
struct kgem_bo src_bo, dst_bo;
|
|
|
|
|
2012-02-18 15:32:16 +01:00
|
|
|
memset(&execbuffer, 0, sizeof(execbuffer));
|
2012-02-16 11:48:38 +01:00
|
|
|
memset(&src_bo, 0, sizeof(src_bo));
|
|
|
|
memset(&dst_bo, 0, sizeof(dst_bo));
|
|
|
|
|
2012-02-18 15:32:16 +01:00
|
|
|
INIT_LIST_HEAD(&execbuffer.objects);
|
|
|
|
|
2012-02-16 11:48:38 +01:00
|
|
|
src_bo.gaddr = src_bitmap->gaddr;
|
|
|
|
src_bo.pitch = src_bitmap->pitch;
|
|
|
|
src_bo.tiling = 0;
|
|
|
|
|
|
|
|
dst_bo.gaddr = dst_bitmap->gaddr;
|
|
|
|
dst_bo.pitch = dst_bitmap->pitch;
|
|
|
|
dst_bo.tiling = 0;
|
|
|
|
|
|
|
|
sna_device->render.copy(sna_device, 0, src_bitmap, &src_bo,
|
|
|
|
dst_bitmap, &dst_bo, dst_x, dst_y,
|
|
|
|
src_x, src_y, w, h);
|
2012-02-18 15:32:16 +01:00
|
|
|
|
|
|
|
INIT_LIST_HEAD(&execbuffer.objects);
|
|
|
|
list_add_tail(&src_bitmap->obj->exec_list, &execbuffer.objects);
|
|
|
|
|
|
|
|
_kgem_submit(&sna_device->kgem, &execbuffer);
|
|
|
|
|
2012-02-16 11:48:38 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|