From 32fc93ddb1561e4c4ea2aa249051105daad77d81 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Tue, 17 Dec 2013 12:47:01 +0000 Subject: [PATCH] intel-2D: move hw-depended code in to separate drivers git-svn-id: svn://kolibrios.org@4372 a494cfbc-eb01-0410-851d-a64ba20cac60 --- contrib/sdk/sources/Intel-2D/Makefile | 101 ++ .../Intel-2D/{pixlib_sna.c => pixlib.c} | 82 +- contrib/sdk/sources/Intel-2D/sna.ver | 15 + contrib/sdk/sources/Intel-2D/sna/sna.c | 913 +++++++++--------- 4 files changed, 635 insertions(+), 476 deletions(-) create mode 100644 contrib/sdk/sources/Intel-2D/Makefile rename contrib/sdk/sources/Intel-2D/{pixlib_sna.c => pixlib.c} (72%) create mode 100644 contrib/sdk/sources/Intel-2D/sna.ver diff --git a/contrib/sdk/sources/Intel-2D/Makefile b/contrib/sdk/sources/Intel-2D/Makefile new file mode 100644 index 0000000000..09424bf705 --- /dev/null +++ b/contrib/sdk/sources/Intel-2D/Makefile @@ -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 + + + + diff --git a/contrib/sdk/sources/Intel-2D/pixlib_sna.c b/contrib/sdk/sources/Intel-2D/pixlib.c similarity index 72% rename from contrib/sdk/sources/Intel-2D/pixlib_sna.c rename to contrib/sdk/sources/Intel-2D/pixlib.c index e967599b16..bd043ecfa6 100644 --- a/contrib/sdk/sources/Intel-2D/pixlib_sna.c +++ b/contrib/sdk/sources/Intel-2D/pixlib.c @@ -7,13 +7,26 @@ #include #include +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 SRV_GETVERSION 0 #define SRV_GET_CAPS 3 - #define BUFFER_SIZE(n) ((n)*sizeof(uint32_t)) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) @@ -31,26 +44,15 @@ typedef struct uint32_t flags; } 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 hw_caps; - +static struct pix_driver pix_driver; uint32_t init_pixlib(uint32_t caps) { + void *lib; + uint32_t (*drventry)(uint32_t service, struct pix_driver *driver); + uint32_t api_version; ioctl_t io; @@ -75,7 +77,18 @@ uint32_t init_pixlib(uint32_t caps) (DISPLAY_VERSION < (api_version >> 16))) 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) printf("2D caps %s%s%s\n", @@ -93,10 +106,9 @@ uint32_t init_pixlib(uint32_t caps) void done_pixlib() { if (hw_caps != 0) - sna_fini(); + pix_driver.fini(); }; - int create_bitmap(bitmap_t * bitmap) { uint32_t size, bo_size; @@ -108,8 +120,8 @@ int create_bitmap(bitmap_t * bitmap) bitmap->data = (void *) -1; bitmap->pitch = -1; - if (bitmap->flags &= hw_caps) - return sna_create_bitmap(bitmap); + if (bitmap->flags &= hw_caps) + return pix_driver.create_bitmap(bitmap); pitch = ALIGN(bitmap->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); - if (sf->flags & hw_caps) - return sna_destroy_bitmap(bitmap); + if (sf->flags & hw_caps) + return pix_driver.destroy_bitmap(bitmap); user_free(sf->data); free(sf); @@ -172,8 +184,8 @@ int lock_bitmap(bitmap_t * bitmap) if (bitmap->data != (void *) -1) return 0; - if (sf->flags & hw_caps) - return sna_lock_bitmap(bitmap); + if (sf->flags & hw_caps) + return pix_driver.lock_bitmap(bitmap); bitmap->data = sf->data; 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); - if (sf->flags & hw_caps & HW_BIT_BLIT) - return sna_blit_tex(bitmap, false, dst_x, dst_y, w, h, src_x, src_y); + if (sf->flags & hw_caps & HW_BIT_BLIT) + return pix_driver.blit(bitmap, false, dst_x, dst_y, w, h, src_x, src_y); bc.dstx = dst_x; 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); - if (sf->flags & hw_caps & HW_TEX_BLIT) - return sna_blit_tex(bitmap, true, dst_x, dst_y, w, h, 0, 0); + if (sf->flags & hw_caps & HW_TEX_BLIT) + return pix_driver.blit(bitmap, true, dst_x, dst_y, w, h, 0, 0); bc.dstx = dst_x; bc.dsty = dst_y; @@ -253,10 +265,8 @@ int resize_bitmap(bitmap_t * bitmap) surface_t *sf = to_surface(bitmap); - if (sf->flags & hw_caps) - { - return sna_resize_bitmap(bitmap); - }; + if (sf->flags & hw_caps) + return pix_driver.resize_bitmap(bitmap); pitch = ALIGN(bitmap->width * 4, 16); size = ALIGN(pitch * bitmap->height, 4096); @@ -280,3 +290,9 @@ int resize_bitmap(bitmap_t * bitmap) return 0; }; + +int sna_create_mask() +{ + return 0; +} + diff --git a/contrib/sdk/sources/Intel-2D/sna.ver b/contrib/sdk/sources/Intel-2D/sna.ver new file mode 100644 index 0000000000..3125725e55 --- /dev/null +++ b/contrib/sdk/sources/Intel-2D/sna.ver @@ -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; + *; +}; diff --git a/contrib/sdk/sources/Intel-2D/sna/sna.c b/contrib/sdk/sources/Intel-2D/sna/sna.c index 8dcfc2b3d5..2046d4820b 100644 --- a/contrib/sdk/sources/Intel-2D/sna/sna.c +++ b/contrib/sdk/sources/Intel-2D/sna/sna.c @@ -56,6 +56,20 @@ typedef struct { int b; } 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 int tls_mask; @@ -210,92 +224,6 @@ int sna_accel_init(struct sna *sna) 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 @@ -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_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; +} + + +