intel-2D: move hw-depended code in to separate drivers

git-svn-id: svn://kolibrios.org@4372 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2013-12-17 12:47:01 +00:00
parent ca070c3e7f
commit 32fc93ddb1
4 changed files with 635 additions and 476 deletions

View File

@ -0,0 +1,101 @@
LIBRARY= pixlib
CC=gcc
CFLAGS = -U_Win32 -U_WIN32 -U__MINGW32__ -c -O2 -fomit-frame-pointer
LD = ld
AR= ar
STRIP = $(PREFIX)strip
LDFLAGS:= -shared -s -nostdlib -T ../newlib/dll.lds --entry _DllStartup --image-base=0
PXFLAGS:= --version-script pixlib.ver --output-def $(LIBRARY).orig.def --out-implib $(LIBRARY).dll.a
SNAFLAGS:= --version-script sna.ver --output-def sna.def
INCLUDES= -I. -I../libdrm/intel -I../libdrm/include/drm -I./render_program -I../pixman -I../newlib/include
LIBPATH:= -L../../lib
LIBS:= -ldll -lc.dll
DEFINES:= -DHAS_DEBUG_FULL=0 -DSHOW_BATCH=0 -DDEBUG_DUMP=0
SRC_PIXLIB = pixlib.c
SRC_SNA = sna/gen3_render.c \
sna/gen4_render.c \
sna/gen4_vertex.c \
sna/gen5_render.c \
sna/gen6_render.c \
sna/gen7_render.c \
sna/kgem.c \
sna/sna.c \
sna/sna_cpu.c \
sna/sna_stream.c \
sna/sna_transform.c \
sna/utils.c \
sna/brw/brw_eu.c \
sna/brw/brw_eu_emit.c \
sna/brw/brw_sf.c \
sna/brw/brw_wm.c
SRC_UXA = pixlib_uxa.c \
uxa/uxa.c \
uxa/i965_3d.c \
uxa/i965_render.c \
uxa/intel_batchbuffer.c
OBJ_PIXLIB = $(patsubst %.c, %.o, $(SRC_PIXLIB))
OBJ_UXA = $(patsubst %.c, %.o, $(SRC_UXA))
OBJ_SNA = $(patsubst %.c, %.o, $(SRC_SNA))
ifeq ($(findstring ebox,$(MAKECMDGOALS)),ebox)
CFLAGS+=-march=pentium-mmx
DEFINES+= -DBUILD_EBOX
else
LIBS+= -ldrm.dll
ifeq ($(findstring uxa,$(MAKECMDGOALS)),uxa)
OBJECTS= $(OBJ_UXA)
DEFINES+= -DBUILD_UXA
else
OBJECTS= $(OBJ_SNA)
DEFINES+= -DBUILD_SNA
LIBS+= -lgcc
endif
endif
# targets
all:$(LIBRARY).dll intel-sna.drv intel-uxa.drv
uxa:$(LIBRARY).dll
ebox:$(LIBRARY).dll
$(LIBRARY).dll: $(OBJ_PIXLIB) Makefile
$(LD) $(LDFLAGS) $(PXFLAGS) $(LIBPATH) -o $@ $(OBJ_PIXLIB) $(LIBS)
$(STRIP) $@
mv -f $@ ../../bin
mv -f $(LIBRARY).dll.a ../../lib
intel-sna.drv: $(OBJ_SNA) Makefile
$(LD) $(LDFLAGS) $(SNAFLAGS) $(LIBPATH) -o $@ $(OBJ_SNA) $(LIBS)
$(STRIP) $@
mv -f $@ ../../bin
intel-uxa.drv: $(OBJ_UXA) Makefile
$(LD) $(LDFLAGS) $(LIBPATH) -o $@ $(OBJ_UXA) $(LIBS)
$(STRIP) $@
mv -f $@ ../../bin
%.o : %.c Makefile
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDES) -o $@ $<
clean:
-rm -f *.o

View File

@ -7,13 +7,26 @@
#include <pixlib2.h> #include <pixlib2.h>
#include <kos32sys.h> #include <kos32sys.h>
void* load_library(const char *name);
struct pix_driver
{
char *name;
int (*create_bitmap)(bitmap_t * bitmap);
int (*destroy_bitmap)(bitmap_t * bitmap);
int (*lock_bitmap)(bitmap_t * bitmap);
int (*blit)(bitmap_t * bitmap, bool scale, int dst_x, int dst_y,
int w, int h, int src_x, int src_y);
int (*resize_bitmap)(bitmap_t * bitmap);
void (*fini)(void);
};
#define DISPLAY_VERSION 0x0200 /* 2.00 */ #define DISPLAY_VERSION 0x0200 /* 2.00 */
#define SRV_GETVERSION 0 #define SRV_GETVERSION 0
#define SRV_GET_CAPS 3 #define SRV_GET_CAPS 3
#define BUFFER_SIZE(n) ((n)*sizeof(uint32_t)) #define BUFFER_SIZE(n) ((n)*sizeof(uint32_t))
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
@ -31,26 +44,15 @@ typedef struct
uint32_t flags; uint32_t flags;
} surface_t; } surface_t;
int sna_init(uint32_t service);
void sna_fini();
int sna_create_bitmap(bitmap_t * bitmap);
int sna_destroy_bitmap(bitmap_t * bitmap);
int sna_lock_bitmap(bitmap_t * bitmap);
int sna_resize_bitmap(bitmap_t *bitmap);
//int sna_blit_copy(bitmap_t * src_bitmap, int dst_x, int dst_y,
// int w, int h, int src_x, int src_y);
int sna_blit_tex(bitmap_t * src_bitmap, bool scale, int dst_x, int dst_y,
int w, int h, int src_x, int src_y);
static uint32_t service; static uint32_t service;
static uint32_t hw_caps; static uint32_t hw_caps;
static struct pix_driver pix_driver;
uint32_t init_pixlib(uint32_t caps) uint32_t init_pixlib(uint32_t caps)
{ {
void *lib;
uint32_t (*drventry)(uint32_t service, struct pix_driver *driver);
uint32_t api_version; uint32_t api_version;
ioctl_t io; ioctl_t io;
@ -75,7 +77,18 @@ uint32_t init_pixlib(uint32_t caps)
(DISPLAY_VERSION < (api_version >> 16))) (DISPLAY_VERSION < (api_version >> 16)))
goto fail; goto fail;
hw_caps = sna_init(service); lib = load_library("intel-sna.drv");
if(lib == 0)
lib = load_library("intel-uxa.drv");
if(lib == 0)
goto fail;
drventry = get_proc_address(lib, "DrvInit");
if( drventry == NULL)
goto fail;
hw_caps = drventry(service, &pix_driver);
if (hw_caps) if (hw_caps)
printf("2D caps %s%s%s\n", printf("2D caps %s%s%s\n",
@ -93,10 +106,9 @@ uint32_t init_pixlib(uint32_t caps)
void done_pixlib() void done_pixlib()
{ {
if (hw_caps != 0) if (hw_caps != 0)
sna_fini(); pix_driver.fini();
}; };
int create_bitmap(bitmap_t * bitmap) int create_bitmap(bitmap_t * bitmap)
{ {
uint32_t size, bo_size; uint32_t size, bo_size;
@ -108,8 +120,8 @@ int create_bitmap(bitmap_t * bitmap)
bitmap->data = (void *) -1; bitmap->data = (void *) -1;
bitmap->pitch = -1; bitmap->pitch = -1;
if (bitmap->flags &= hw_caps) if (bitmap->flags &= hw_caps)
return sna_create_bitmap(bitmap); return pix_driver.create_bitmap(bitmap);
pitch = ALIGN(bitmap->width * 4, 16); pitch = ALIGN(bitmap->width * 4, 16);
max_pitch = ALIGN(bitmap->max_width * 4, 16); max_pitch = ALIGN(bitmap->max_width * 4, 16);
@ -152,8 +164,8 @@ int destroy_bitmap(bitmap_t * bitmap)
{ {
surface_t *sf = to_surface(bitmap); surface_t *sf = to_surface(bitmap);
if (sf->flags & hw_caps) if (sf->flags & hw_caps)
return sna_destroy_bitmap(bitmap); return pix_driver.destroy_bitmap(bitmap);
user_free(sf->data); user_free(sf->data);
free(sf); free(sf);
@ -172,8 +184,8 @@ int lock_bitmap(bitmap_t * bitmap)
if (bitmap->data != (void *) -1) if (bitmap->data != (void *) -1)
return 0; return 0;
if (sf->flags & hw_caps) if (sf->flags & hw_caps)
return sna_lock_bitmap(bitmap); return pix_driver.lock_bitmap(bitmap);
bitmap->data = sf->data; bitmap->data = sf->data;
bitmap->pitch = sf->pitch; bitmap->pitch = sf->pitch;
@ -189,8 +201,8 @@ int blit_bitmap(bitmap_t * bitmap, int dst_x, int dst_y,
surface_t *sf = to_surface(bitmap); surface_t *sf = to_surface(bitmap);
if (sf->flags & hw_caps & HW_BIT_BLIT) if (sf->flags & hw_caps & HW_BIT_BLIT)
return sna_blit_tex(bitmap, false, dst_x, dst_y, w, h, src_x, src_y); return pix_driver.blit(bitmap, false, dst_x, dst_y, w, h, src_x, src_y);
bc.dstx = dst_x; bc.dstx = dst_x;
bc.dsty = dst_y; bc.dsty = dst_y;
@ -220,8 +232,8 @@ int fplay_blit_bitmap(bitmap_t * bitmap, int dst_x, int dst_y, int w, int h)
surface_t *sf = to_surface(bitmap); surface_t *sf = to_surface(bitmap);
if (sf->flags & hw_caps & HW_TEX_BLIT) if (sf->flags & hw_caps & HW_TEX_BLIT)
return sna_blit_tex(bitmap, true, dst_x, dst_y, w, h, 0, 0); return pix_driver.blit(bitmap, true, dst_x, dst_y, w, h, 0, 0);
bc.dstx = dst_x; bc.dstx = dst_x;
bc.dsty = dst_y; bc.dsty = dst_y;
@ -253,10 +265,8 @@ int resize_bitmap(bitmap_t * bitmap)
surface_t *sf = to_surface(bitmap); surface_t *sf = to_surface(bitmap);
if (sf->flags & hw_caps) if (sf->flags & hw_caps)
{ return pix_driver.resize_bitmap(bitmap);
return sna_resize_bitmap(bitmap);
};
pitch = ALIGN(bitmap->width * 4, 16); pitch = ALIGN(bitmap->width * 4, 16);
size = ALIGN(pitch * bitmap->height, 4096); size = ALIGN(pitch * bitmap->height, 4096);
@ -280,3 +290,9 @@ int resize_bitmap(bitmap_t * bitmap)
return 0; return 0;
}; };
int sna_create_mask()
{
return 0;
}

View File

@ -0,0 +1,15 @@
LIBDRM {
global: DllStartup;
DrvInit;
sna_bitmap_from_handle;
sna_blit_tex;
sna_create_mask;
sna_set_bo_handle;
local: __chkstk;
__chkstk_ms;
_alloca;
__uxa_lock;
_nm__tls_alloc;
*;
};

View File

@ -56,6 +56,20 @@ typedef struct {
int b; int b;
} rect_t; } rect_t;
struct pix_driver
{
char *name;
int (*create_bitmap)(bitmap_t * bitmap);
int (*destroy_bitmap)(bitmap_t * bitmap);
int (*lock_bitmap)(bitmap_t * bitmap);
int (*blit)(bitmap_t * bitmap, bool scale, int dst_x, int dst_y,
int w, int h, int src_x, int src_y);
int (*resize_bitmap)(bitmap_t * bitmap);
void (*fini)(void);
};
static struct sna_fb sna_fb; static struct sna_fb sna_fb;
static int tls_mask; static int tls_mask;
@ -210,92 +224,6 @@ int sna_accel_init(struct sna *sna)
return kgem_init_fb(&sna->kgem, &sna_fb); return kgem_init_fb(&sna->kgem, &sna_fb);
} }
int sna_init(uint32_t service)
{
ioctl_t io;
int caps = 0;
static struct pci_device device;
struct sna *sna;
DBG(("%s\n", __FUNCTION__));
__lock_acquire_recursive(__sna_lock);
if(sna_device)
goto done;
io.handle = service;
io.io_code = SRV_GET_PCI_INFO;
io.input = &device;
io.inp_size = sizeof(device);
io.output = NULL;
io.out_size = 0;
if (call_service(&io)!=0)
goto err1;
sna = malloc(sizeof(*sna));
if (sna == NULL)
goto err1;
memset(sna, 0, sizeof(*sna));
sna->cpu_features = sna_cpu_detect();
sna->PciInfo = &device;
sna->info = intel_detect_chipset(sna->PciInfo);
sna->scrn = service;
kgem_init(&sna->kgem, service, sna->PciInfo, sna->info->gen);
/* Disable tiling by default */
sna->tiling = 0;
/* Default fail-safe value of 75 Hz */
// sna->vblank_interval = 1000 * 1000 * 1000 / 75;
sna->flags = 0;
sna_accel_init(sna);
tls_mask = tls_alloc();
// printf("tls mask %x\n", tls_mask);
done:
caps = sna_device->render.caps;
err1:
__lock_release_recursive(__sna_lock);
return caps;
}
void sna_fini()
{
ENTER();
if( sna_device )
{
struct kgem_bo *mask;
__lock_acquire_recursive(__sna_lock);
mask = tls_get(tls_mask);
sna_device->render.fini(sna_device);
if(mask)
kgem_bo_destroy(&sna_device->kgem, mask);
// kgem_close_batches(&sna_device->kgem);
kgem_cleanup_cache(&sna_device->kgem);
sna_device = NULL;
__lock_release_recursive(__sna_lock);
};
LEAVE();
}
#if 0 #if 0
@ -489,223 +417,6 @@ typedef struct
int sna_create_bitmap(bitmap_t *bitmap)
{
surface_t *sf;
struct kgem_bo *bo;
sf = malloc(sizeof(*sf));
if(sf == NULL)
goto err_1;
__lock_acquire_recursive(__sna_lock);
bo = kgem_create_2d(&sna_device->kgem, bitmap->width, bitmap->height,
32,I915_TILING_NONE, CREATE_CPU_MAP);
if(bo == NULL)
goto err_2;
void *map = kgem_bo_map(&sna_device->kgem, bo);
if(map == NULL)
goto err_3;
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->data = map;
sf->pitch = bo->pitch;
sf->bo = bo;
sf->bo_size = PAGE_SIZE * bo->size.pages.count;
sf->flags = bitmap->flags;
bitmap->handle = (uint32_t)sf;
__lock_release_recursive(__sna_lock);
return 0;
err_3:
kgem_bo_destroy(&sna_device->kgem, bo);
err_2:
__lock_release_recursive(__sna_lock);
free(sf);
err_1:
return -1;
};
int sna_bitmap_from_handle(bitmap_t *bitmap, uint32_t handle)
{
surface_t *sf;
struct kgem_bo *bo;
sf = malloc(sizeof(*sf));
if(sf == NULL)
goto err_1;
__lock_acquire_recursive(__sna_lock);
bo = kgem_bo_from_handle(&sna_device->kgem, handle, bitmap->pitch, bitmap->height);
__lock_release_recursive(__sna_lock);
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->data = NULL;
sf->pitch = bo->pitch;
sf->bo = bo;
sf->bo_size = PAGE_SIZE * bo->size.pages.count;
sf->flags = bitmap->flags;
bitmap->handle = (uint32_t)sf;
return 0;
err_2:
__lock_release_recursive(__sna_lock);
free(sf);
err_1:
return -1;
};
void sna_set_bo_handle(bitmap_t *bitmap, int handle)
{
surface_t *sf = to_surface(bitmap);
struct kgem_bo *bo = sf->bo;
bo->handle = handle;
}
int sna_destroy_bitmap(bitmap_t *bitmap)
{
surface_t *sf = to_surface(bitmap);
__lock_acquire_recursive(__sna_lock);
kgem_bo_destroy(&sna_device->kgem, sf->bo);
__lock_release_recursive(__sna_lock);
free(sf);
bitmap->handle = -1;
bitmap->data = (void*)-1;
bitmap->pitch = -1;
return 0;
};
int sna_lock_bitmap(bitmap_t *bitmap)
{
surface_t *sf = to_surface(bitmap);
// printf("%s\n", __FUNCTION__);
__lock_acquire_recursive(__sna_lock);
kgem_bo_sync__cpu(&sna_device->kgem, sf->bo);
__lock_release_recursive(__sna_lock);
bitmap->data = sf->data;
bitmap->pitch = sf->pitch;
return 0;
};
int sna_resize_bitmap(bitmap_t *bitmap)
{
surface_t *sf = to_surface(bitmap);
struct kgem *kgem = &sna_device->kgem;
struct kgem_bo *bo = sf->bo;
uint32_t size;
uint32_t pitch;
bitmap->pitch = -1;
bitmap->data = (void *) -1;
size = kgem_surface_size(kgem,kgem->has_relaxed_fencing, CREATE_CPU_MAP,
bitmap->width, bitmap->height, 32, I915_TILING_NONE, &pitch);
assert(size && size <= kgem->max_object_size);
if(sf->bo_size >= size)
{
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->pitch = pitch;
bo->pitch = pitch;
return 0;
}
else
{
__lock_acquire_recursive(__sna_lock);
sna_bo_destroy(kgem, bo);
sf->bo = NULL;
bo = kgem_create_2d(kgem, bitmap->width, bitmap->height,
32, I915_TILING_NONE, CREATE_CPU_MAP);
if(bo == NULL)
{
__lock_release_recursive(__sna_lock);
return -1;
};
void *map = kgem_bo_map(kgem, bo);
if(map == NULL)
{
sna_bo_destroy(kgem, bo);
__lock_release_recursive(__sna_lock);
return -1;
};
__lock_release_recursive(__sna_lock);
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->data = map;
sf->pitch = bo->pitch;
sf->bo = bo;
sf->bo_size = PAGE_SIZE * bo->size.pages.count;
}
return 0;
};
int sna_create_mask()
{
struct kgem_bo *bo;
// printf("%s width %d height %d\n", __FUNCTION__, sna_fb.width, sna_fb.height);
__lock_acquire_recursive(__sna_lock);
bo = kgem_create_2d(&sna_device->kgem, sna_fb.width, sna_fb.height,
8,I915_TILING_NONE, CREATE_CPU_MAP);
if(unlikely(bo == NULL))
goto err_1;
int *map = kgem_bo_map(&sna_device->kgem, bo);
if(map == NULL)
goto err_2;
__lock_release_recursive(__sna_lock);
memset(map, 0, bo->pitch * sna_fb.height);
tls_set(tls_mask, bo);
return 0;
err_2:
kgem_bo_destroy(&sna_device->kgem, bo);
err_1:
__lock_release_recursive(__sna_lock);
return -1;
};
#define MI_LOAD_REGISTER_IMM (0x22<<23) #define MI_LOAD_REGISTER_IMM (0x22<<23)
#define MI_WAIT_FOR_EVENT (0x03<<23) #define MI_WAIT_FOR_EVENT (0x03<<23)
@ -806,146 +517,6 @@ sna_wait_for_scanline(struct sna *sna,
} }
bool
gen6_composite(struct sna *sna,
uint8_t op,
PixmapPtr src, struct kgem_bo *src_bo,
PixmapPtr mask,struct kgem_bo *mask_bo,
PixmapPtr dst, struct kgem_bo *dst_bo,
int32_t src_x, int32_t src_y,
int32_t msk_x, int32_t msk_y,
int32_t dst_x, int32_t dst_y,
int32_t width, int32_t height,
struct sna_composite_op *tmp);
#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3))
int sna_blit_tex(bitmap_t *bitmap, bool scale, int dst_x, int dst_y,
int w, int h, int src_x, int src_y)
{
surface_t *sf = to_surface(bitmap);
struct drm_i915_mask_update update;
struct sna_composite_op composite;
struct _Pixmap src, dst, mask;
struct kgem_bo *src_bo, *mask_bo;
int winx, winy;
char proc_info[1024];
get_proc_info(proc_info);
winx = *(uint32_t*)(proc_info+34);
winy = *(uint32_t*)(proc_info+38);
// winw = *(uint32_t*)(proc_info+42)+1;
// winh = *(uint32_t*)(proc_info+46)+1;
mask_bo = tls_get(tls_mask);
if(unlikely(mask_bo == NULL))
{
sna_create_mask();
mask_bo = tls_get(tls_mask);
if( mask_bo == NULL)
return -1;
};
if(kgem_update_fb(&sna_device->kgem, &sna_fb))
{
__lock_acquire_recursive(__sna_lock);
kgem_bo_destroy(&sna_device->kgem, mask_bo);
__lock_release_recursive(__sna_lock);
sna_create_mask();
mask_bo = tls_get(tls_mask);
if( mask_bo == NULL)
return -1;
}
VG_CLEAR(update);
update.handle = mask_bo->handle;
update.bo_map = (int)kgem_bo_map__cpu(&sna_device->kgem, mask_bo);
drmIoctl(sna_device->kgem.fd, SRV_MASK_UPDATE, &update);
mask_bo->pitch = update.bo_pitch;
memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst));
memset(&mask, 0, sizeof(dst));
src.drawable.bitsPerPixel = 32;
src.drawable.width = sf->width;
src.drawable.height = sf->height;
dst.drawable.bitsPerPixel = 32;
dst.drawable.width = sna_fb.width;
dst.drawable.height = sna_fb.height;
mask.drawable.bitsPerPixel = 8;
mask.drawable.width = update.width;
mask.drawable.height = update.height;
memset(&composite, 0, sizeof(composite));
src_bo = sf->bo;
__lock_acquire_recursive(__sna_lock);
{
rect_t crtc, clip;
crtc.l = 0;
crtc.t = 0;
crtc.r = sna_fb.width-1;
crtc.b = sna_fb.height-1;
clip.l = winx+dst_x;
clip.t = winy+dst_y;
clip.r = clip.l+w-1;
clip.b = clip.t+h-1;
kgem_set_mode(&sna_device->kgem, KGEM_RENDER, sna_fb.fb_bo);
sna_wait_for_scanline(sna_device, &crtc, &clip);
}
if( sna_device->render.blit_tex(sna_device, PictOpSrc,scale,
&src, src_bo,
&mask, mask_bo,
&dst, sna_fb.fb_bo,
src_x, src_y,
dst_x, dst_y,
winx+dst_x, winy+dst_y,
w, h,
&composite) )
{
struct sna_composite_rectangles r;
r.src.x = src_x;
r.src.y = src_y;
r.mask.x = dst_x;
r.mask.y = dst_y;
r.dst.x = winx+dst_x;
r.dst.y = winy+dst_y;
r.width = w;
r.height = h;
composite.blt(sna_device, &composite, &r);
composite.done(sna_device, &composite);
};
kgem_submit(&sna_device->kgem);
__lock_release_recursive(__sna_lock);
bitmap->data = (void*)-1;
bitmap->pitch = -1;
return 0;
}
@ -1091,3 +662,459 @@ int drmIoctl(int fd, unsigned long request, void *arg)
bool
gen6_composite(struct sna *sna,
uint8_t op,
PixmapPtr src, struct kgem_bo *src_bo,
PixmapPtr mask,struct kgem_bo *mask_bo,
PixmapPtr dst, struct kgem_bo *dst_bo,
int32_t src_x, int32_t src_y,
int32_t msk_x, int32_t msk_y,
int32_t dst_x, int32_t dst_y,
int32_t width, int32_t height,
struct sna_composite_op *tmp);
//#define MAP(ptr) ((void*)((uintptr_t)(ptr) & ~3))
int sna_bitmap_from_handle(bitmap_t *bitmap, uint32_t handle)
{
surface_t *sf;
struct kgem_bo *bo;
sf = malloc(sizeof(*sf));
if(sf == NULL)
goto err_1;
__lock_acquire_recursive(__sna_lock);
bo = kgem_bo_from_handle(&sna_device->kgem, handle, bitmap->pitch, bitmap->height);
__lock_release_recursive(__sna_lock);
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->data = NULL;
sf->pitch = bo->pitch;
sf->bo = bo;
sf->bo_size = PAGE_SIZE * bo->size.pages.count;
sf->flags = bitmap->flags;
bitmap->handle = (uint32_t)sf;
return 0;
err_2:
__lock_release_recursive(__sna_lock);
free(sf);
err_1:
return -1;
};
void sna_set_bo_handle(bitmap_t *bitmap, int handle)
{
surface_t *sf = to_surface(bitmap);
struct kgem_bo *bo = sf->bo;
bo->handle = handle;
}
static int sna_create_bitmap(bitmap_t *bitmap)
{
surface_t *sf;
struct kgem_bo *bo;
sf = malloc(sizeof(*sf));
if(sf == NULL)
goto err_1;
__lock_acquire_recursive(__sna_lock);
bo = kgem_create_2d(&sna_device->kgem, bitmap->width, bitmap->height,
32,I915_TILING_NONE, CREATE_CPU_MAP);
if(bo == NULL)
goto err_2;
void *map = kgem_bo_map(&sna_device->kgem, bo);
if(map == NULL)
goto err_3;
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->data = map;
sf->pitch = bo->pitch;
sf->bo = bo;
sf->bo_size = PAGE_SIZE * bo->size.pages.count;
sf->flags = bitmap->flags;
bitmap->handle = (uint32_t)sf;
__lock_release_recursive(__sna_lock);
return 0;
err_3:
kgem_bo_destroy(&sna_device->kgem, bo);
err_2:
__lock_release_recursive(__sna_lock);
free(sf);
err_1:
return -1;
};
static int sna_destroy_bitmap(bitmap_t *bitmap)
{
surface_t *sf = to_surface(bitmap);
__lock_acquire_recursive(__sna_lock);
kgem_bo_destroy(&sna_device->kgem, sf->bo);
__lock_release_recursive(__sna_lock);
free(sf);
bitmap->handle = -1;
bitmap->data = (void*)-1;
bitmap->pitch = -1;
return 0;
};
static int sna_lock_bitmap(bitmap_t *bitmap)
{
surface_t *sf = to_surface(bitmap);
// printf("%s\n", __FUNCTION__);
__lock_acquire_recursive(__sna_lock);
kgem_bo_sync__cpu(&sna_device->kgem, sf->bo);
__lock_release_recursive(__sna_lock);
bitmap->data = sf->data;
bitmap->pitch = sf->pitch;
return 0;
};
static int sna_resize_bitmap(bitmap_t *bitmap)
{
surface_t *sf = to_surface(bitmap);
struct kgem *kgem = &sna_device->kgem;
struct kgem_bo *bo = sf->bo;
uint32_t size;
uint32_t pitch;
bitmap->pitch = -1;
bitmap->data = (void *) -1;
size = kgem_surface_size(kgem,kgem->has_relaxed_fencing, CREATE_CPU_MAP,
bitmap->width, bitmap->height, 32, I915_TILING_NONE, &pitch);
assert(size && size <= kgem->max_object_size);
if(sf->bo_size >= size)
{
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->pitch = pitch;
bo->pitch = pitch;
return 0;
}
else
{
__lock_acquire_recursive(__sna_lock);
sna_bo_destroy(kgem, bo);
sf->bo = NULL;
bo = kgem_create_2d(kgem, bitmap->width, bitmap->height,
32, I915_TILING_NONE, CREATE_CPU_MAP);
if(bo == NULL)
{
__lock_release_recursive(__sna_lock);
return -1;
};
void *map = kgem_bo_map(kgem, bo);
if(map == NULL)
{
sna_bo_destroy(kgem, bo);
__lock_release_recursive(__sna_lock);
return -1;
};
__lock_release_recursive(__sna_lock);
sf->width = bitmap->width;
sf->height = bitmap->height;
sf->data = map;
sf->pitch = bo->pitch;
sf->bo = bo;
sf->bo_size = PAGE_SIZE * bo->size.pages.count;
}
return 0;
};
int sna_create_mask()
{
struct kgem_bo *bo;
// printf("%s width %d height %d\n", __FUNCTION__, sna_fb.width, sna_fb.height);
__lock_acquire_recursive(__sna_lock);
bo = kgem_create_2d(&sna_device->kgem, sna_fb.width, sna_fb.height,
8,I915_TILING_NONE, CREATE_CPU_MAP);
if(unlikely(bo == NULL))
goto err_1;
int *map = kgem_bo_map(&sna_device->kgem, bo);
if(map == NULL)
goto err_2;
__lock_release_recursive(__sna_lock);
memset(map, 0, bo->pitch * sna_fb.height);
tls_set(tls_mask, bo);
return 0;
err_2:
kgem_bo_destroy(&sna_device->kgem, bo);
err_1:
__lock_release_recursive(__sna_lock);
return -1;
};
int sna_blit_tex(bitmap_t *bitmap, bool scale, int dst_x, int dst_y,
int w, int h, int src_x, int src_y)
{
surface_t *sf = to_surface(bitmap);
struct drm_i915_mask_update update;
struct sna_composite_op composite;
struct _Pixmap src, dst, mask;
struct kgem_bo *src_bo, *mask_bo;
int winx, winy;
char proc_info[1024];
get_proc_info(proc_info);
winx = *(uint32_t*)(proc_info+34);
winy = *(uint32_t*)(proc_info+38);
// winw = *(uint32_t*)(proc_info+42)+1;
// winh = *(uint32_t*)(proc_info+46)+1;
mask_bo = tls_get(tls_mask);
if(unlikely(mask_bo == NULL))
{
sna_create_mask();
mask_bo = tls_get(tls_mask);
if( mask_bo == NULL)
return -1;
};
if(kgem_update_fb(&sna_device->kgem, &sna_fb))
{
__lock_acquire_recursive(__sna_lock);
kgem_bo_destroy(&sna_device->kgem, mask_bo);
__lock_release_recursive(__sna_lock);
sna_create_mask();
mask_bo = tls_get(tls_mask);
if( mask_bo == NULL)
return -1;
}
VG_CLEAR(update);
update.handle = mask_bo->handle;
update.bo_map = (int)kgem_bo_map__cpu(&sna_device->kgem, mask_bo);
drmIoctl(sna_device->kgem.fd, SRV_MASK_UPDATE, &update);
mask_bo->pitch = update.bo_pitch;
memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst));
memset(&mask, 0, sizeof(dst));
src.drawable.bitsPerPixel = 32;
src.drawable.width = sf->width;
src.drawable.height = sf->height;
dst.drawable.bitsPerPixel = 32;
dst.drawable.width = sna_fb.width;
dst.drawable.height = sna_fb.height;
mask.drawable.bitsPerPixel = 8;
mask.drawable.width = update.width;
mask.drawable.height = update.height;
memset(&composite, 0, sizeof(composite));
src_bo = sf->bo;
__lock_acquire_recursive(__sna_lock);
{
rect_t crtc, clip;
crtc.l = 0;
crtc.t = 0;
crtc.r = sna_fb.width-1;
crtc.b = sna_fb.height-1;
clip.l = winx+dst_x;
clip.t = winy+dst_y;
clip.r = clip.l+w-1;
clip.b = clip.t+h-1;
kgem_set_mode(&sna_device->kgem, KGEM_RENDER, sna_fb.fb_bo);
sna_wait_for_scanline(sna_device, &crtc, &clip);
}
if( sna_device->render.blit_tex(sna_device, PictOpSrc,scale,
&src, src_bo,
&mask, mask_bo,
&dst, sna_fb.fb_bo,
src_x, src_y,
dst_x, dst_y,
winx+dst_x, winy+dst_y,
w, h,
&composite) )
{
struct sna_composite_rectangles r;
r.src.x = src_x;
r.src.y = src_y;
r.mask.x = dst_x;
r.mask.y = dst_y;
r.dst.x = winx+dst_x;
r.dst.y = winy+dst_y;
r.width = w;
r.height = h;
composite.blt(sna_device, &composite, &r);
composite.done(sna_device, &composite);
};
kgem_submit(&sna_device->kgem);
__lock_release_recursive(__sna_lock);
bitmap->data = (void*)-1;
bitmap->pitch = -1;
return 0;
}
static void sna_fini()
{
ENTER();
if( sna_device )
{
struct kgem_bo *mask;
__lock_acquire_recursive(__sna_lock);
mask = tls_get(tls_mask);
sna_device->render.fini(sna_device);
if(mask)
kgem_bo_destroy(&sna_device->kgem, mask);
// kgem_close_batches(&sna_device->kgem);
kgem_cleanup_cache(&sna_device->kgem);
sna_device = NULL;
__lock_release_recursive(__sna_lock);
};
LEAVE();
}
uint32_t DrvInit(uint32_t service, struct pix_driver *driver)
{
ioctl_t io;
int caps = 0;
static struct pci_device device;
struct sna *sna;
DBG(("%s\n", __FUNCTION__));
__lock_acquire_recursive(__sna_lock);
if(sna_device)
goto done;
io.handle = service;
io.io_code = SRV_GET_PCI_INFO;
io.input = &device;
io.inp_size = sizeof(device);
io.output = NULL;
io.out_size = 0;
if (call_service(&io)!=0)
goto err1;
sna = malloc(sizeof(*sna));
if (sna == NULL)
goto err1;
memset(sna, 0, sizeof(*sna));
sna->cpu_features = sna_cpu_detect();
sna->PciInfo = &device;
sna->info = intel_detect_chipset(sna->PciInfo);
sna->scrn = service;
kgem_init(&sna->kgem, service, sna->PciInfo, sna->info->gen);
/* Disable tiling by default */
sna->tiling = 0;
/* Default fail-safe value of 75 Hz */
// sna->vblank_interval = 1000 * 1000 * 1000 / 75;
sna->flags = 0;
sna_accel_init(sna);
tls_mask = tls_alloc();
// printf("tls mask %x\n", tls_mask);
driver->create_bitmap = sna_create_bitmap;
driver->destroy_bitmap = sna_destroy_bitmap;
driver->lock_bitmap = sna_lock_bitmap;
driver->blit = sna_blit_tex;
driver->resize_bitmap = sna_resize_bitmap;
driver->fini = sna_fini;
done:
caps = sna_device->render.caps;
err1:
__lock_release_recursive(__sna_lock);
return caps;
}