From 8afe7310a73a5c998589141f1c217732371fc707 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Thu, 15 Nov 2012 08:04:26 +0000 Subject: [PATCH] i915: resize surface git-svn-id: svn://kolibrios.org@3039 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/ddk/core.S | 4 ++ drivers/ddk/malloc/malloc.c | 9 ++- drivers/include/linux/kernel.h | 8 ++- drivers/video/drm/i915/bitmap.c | 102 ++++++++++++++++++++++++++- drivers/video/drm/i915/bitmap.h | 20 ++++-- drivers/video/drm/i915/i915_gem.c | 5 +- drivers/video/drm/i915/kms_display.c | 6 +- drivers/video/drm/i915/main.c | 6 ++ 8 files changed, 144 insertions(+), 16 deletions(-) diff --git a/drivers/ddk/core.S b/drivers/ddk/core.S index d61b1ab83e..0b0f8a3c1a 100644 --- a/drivers/ddk/core.S +++ b/drivers/ddk/core.S @@ -62,6 +62,7 @@ .global _TimerHs .global _UserAlloc + .global _UserFree .global _WaitEvent @@ -123,6 +124,7 @@ .def _TimerHs; .scl 2; .type 32; .endef .def _UserAlloc; .scl 2; .type 32; .endef + .def _UserFree; .scl 2; .type 32; .endef .def _WaitEvent; .scl 2; .type 32; .endef @@ -185,6 +187,7 @@ _SysMsgBoardStr: _TimerHs: _UserAlloc: +_UserFree: _WaitEvent: ret @@ -252,6 +255,7 @@ _WaitEvent: .ascii " -export:TimerHs" # stdcall .ascii " -export:UserAlloc" # stdcall + .ascii " -export:UserFree" # stdcall .ascii " -export:WaitEvent" # stdcall diff --git a/drivers/ddk/malloc/malloc.c b/drivers/ddk/malloc/malloc.c index 2427fcd3ae..3ef406a2e3 100644 --- a/drivers/ddk/malloc/malloc.c +++ b/drivers/ddk/malloc/malloc.c @@ -89,9 +89,9 @@ typedef unsigned int flag_t; /* The type of various bit flag sets */ #define NO_SEGMENT_TRAVERSAL 1 #define MALLOC_ALIGNMENT ((size_t)8U) #define CHUNK_OVERHEAD (SIZE_T_SIZE) -#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#define DEFAULT_TRIM_THRESHOLD ((size_t)512U * (size_t)1024U) +#define DEFAULT_GRANULARITY ((size_t)128U * (size_t)1024U) +#define DEFAULT_MMAP_THRESHOLD ((size_t)512U * (size_t)1024U) +#define DEFAULT_TRIM_THRESHOLD ((size_t)1024U * (size_t)1024U) /* The bit mask value corresponding to MALLOC_ALIGNMENT */ #define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) @@ -835,6 +835,7 @@ static int has_segment_link(mstate m, msegmentptr ss) static inline void* os_mmap(size_t size) { void* ptr = KernelAlloc(size); + printf("%s %x %d bytes\n",__FUNCTION__, ptr, size); return (ptr != 0)? ptr: MFAIL; } @@ -1110,6 +1111,8 @@ static void* sys_alloc(mstate m, size_t nb) ensure_initialization(); + printf("%s %d bytes\n", __FUNCTION__, nb); + /* Directly map large chunks, but only if already initialized */ if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { diff --git a/drivers/include/linux/kernel.h b/drivers/include/linux/kernel.h index c4dc5a8c31..521e22f272 100644 --- a/drivers/include/linux/kernel.h +++ b/drivers/include/linux/kernel.h @@ -36,7 +36,13 @@ #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) -#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) +/* The `const' in roundup() prevents gcc-3.3 from calling __divdi3 */ +#define roundup(x, y) ( \ +{ \ + const typeof(y) __y = y; \ + (((x) + (__y - 1)) / __y) * __y; \ +} \ +) #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) #define DIV_ROUND_CLOSEST(x, divisor)( \ diff --git a/drivers/video/drm/i915/bitmap.c b/drivers/video/drm/i915/bitmap.c index df96886fd4..308751d1c0 100644 --- a/drivers/video/drm/i915/bitmap.c +++ b/drivers/video/drm/i915/bitmap.c @@ -36,7 +36,7 @@ void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap) for (i = 0; i < bitmap->page_count; i++) FreePage(pages[i]); - DRM_DEBUG("%s freec %d pages\n", __FUNCTION__, bitmap->page_count); + DRM_DEBUG("%s release %d pages\n", __FUNCTION__, bitmap->page_count); free(pages); }; @@ -52,6 +52,7 @@ static int bitmap_get_pages_gtt(struct drm_i915_gem_object *obj) /* Get the list of pages out of our struct file. They'll be pinned * at this point until we release them. */ + page_count = obj->base.size / PAGE_SIZE; BUG_ON(obj->allocated_pages == NULL); BUG_ON(obj->pages.page != NULL); @@ -305,6 +306,105 @@ int lock_surface(struct io_call_12 *pbitmap) }; +int resize_surface(struct io_call_14 *pbitmap) +{ + bitmap_t *bitmap; + dma_addr_t page, *pages; + u32 size, page_count; + u32 width, height; + u32 pitch; + int i; + int ret = 0; + + + if(unlikely(pbitmap->handle == 0)) + return -1; + + bitmap = (bitmap_t*)hmm_get_data(&bm_mm, pbitmap->handle); + + if(unlikely(bitmap==NULL)) + return -1; + + if( pbitmap->new_width > bitmap->max_width || + pbitmap->new_height > bitmap->max_height) + return -1; + + width = pbitmap->new_width; + height = pbitmap->new_height; + + pitch = ALIGN(width*4,64); + size = roundup(pitch * height, PAGE_SIZE); + page_count = size/PAGE_SIZE; + + DRM_DEBUG("new width %d height %d pitch %d size %d\n", + width, height, pitch, size); + + if( page_count == bitmap->page_count ) + { + bitmap->width = width; + bitmap->height = height; + bitmap->pitch = pitch; + } + else if(page_count > bitmap->page_count) + { + char *vaddr = bitmap->uaddr + PAGE_SIZE * bitmap->page_count; + + pages = bitmap->obj->allocated_pages; + + DRM_DEBUG("old pages %d new_pages %d vaddr %x\n", + bitmap->page_count, page_count, vaddr); + + for(i = bitmap->page_count; i < page_count; i++, vaddr+= PAGE_SIZE) + { + page = AllocPage(); + if ( page == 0 ) + goto err4; + pages[i] = page; + MapPage(vaddr, page, 0x207); //map as shared page + }; + + DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__, + page_count - bitmap->page_count); + +// mutex_lock(&main_device->struct_mutex); + + i915_gem_object_unpin(bitmap->obj); + i915_gem_object_unbind(bitmap->obj); + bitmap->obj->base.size = size; + bitmap->obj->pages.nents = page_count; + + ret = i915_gem_object_pin(bitmap->obj, PAGE_SIZE, true,true); + if (ret) + goto err4; +// mutex_unlock(&main_device->struct_mutex); + + bitmap->page_count = page_count; + bitmap->width = width; + bitmap->height = height; + bitmap->pitch = pitch; + bitmap->gaddr = bitmap->obj->gtt_offset; + }; + + if(ret != 0 ) + { + pbitmap->data = NULL; + pbitmap->pitch = 0; + + dbgprintf("%s fail\n", __FUNCTION__); + return ret; + }; + + pbitmap->data = bitmap->uaddr; + pbitmap->pitch = bitmap->pitch; + + return 0; + +err4: + while (i-- > bitmap->page_count) + FreePage(pages[i]); + + return -1; +}; int init_bitmaps() diff --git a/drivers/video/drm/i915/bitmap.h b/drivers/video/drm/i915/bitmap.h index 90b062efb1..eb5d9d0adf 100644 --- a/drivers/video/drm/i915/bitmap.h +++ b/drivers/video/drm/i915/bitmap.h @@ -17,7 +17,7 @@ typedef struct kobj_t header; u32 handle; - void *uaddr; + char *uaddr; u32 pitch; u32 gaddr; @@ -50,14 +50,19 @@ struct io_call_10 /* SRV_CREATE_SURFACE */ struct io_call_12 /* SRV_LOCK_SURFACE */ { - u32 handle; // ignored - void *data; // ignored - - u32 width; - u32 height; - u32 pitch; // ignored + u32 handle; + void *data; + u32 pitch; }; +struct io_call_14 /* SRV_RESIZE_SURFACE */ +{ + u32 handle; + void *data; + u32 new_width; + u32 new_height; + u32 pitch; +}; typedef struct { @@ -93,6 +98,7 @@ struct context int get_driver_caps(hwcaps_t *caps); int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap); int lock_surface(struct io_call_12 *pbitmap); +int resize_surface(struct io_call_14 *pbitmap); struct context *get_context(struct drm_device *dev); diff --git a/drivers/video/drm/i915/i915_gem.c b/drivers/video/drm/i915/i915_gem.c index c339619735..412ef10c6d 100644 --- a/drivers/video/drm/i915/i915_gem.c +++ b/drivers/video/drm/i915/i915_gem.c @@ -1409,7 +1409,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) for (i = 0; i < obj->pages.nents; i++) FreePage(obj->pages.page[i]); - DRM_DEBUG_KMS("%s free %d pages\n", __FUNCTION__, obj->pages.nents); + DRM_DEBUG_KMS("%s release %d pages\n", __FUNCTION__, obj->pages.nents); obj->dirty = 0; kfree(obj->pages.page); } @@ -1419,6 +1419,9 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj) { const struct drm_i915_gem_object_ops *ops = obj->ops; +// printf("page %x pin count %d\n", +// obj->pages.page, obj->pages_pin_count ); + if (obj->pages.page == NULL) return 0; diff --git a/drivers/video/drm/i915/kms_display.c b/drivers/video/drm/i915/kms_display.c index 31347b4a49..a2697c287a 100644 --- a/drivers/video/drm/i915/kms_display.c +++ b/drivers/video/drm/i915/kms_display.c @@ -716,8 +716,8 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y, dst_clip.xmin = 0; dst_clip.ymin = 0; - dst_clip.xmax = winrc.right-winrc.left-1; - dst_clip.ymax = winrc.bottom -winrc.top-1; + dst_clip.xmax = winrc.right-winrc.left; + dst_clip.ymax = winrc.bottom -winrc.top; src_clip.xmin = 0; src_clip.ymin = 0; @@ -869,7 +869,7 @@ int blit_video(u32 hbitmap, int dst_x, int dst_y, b[n++] = cmd; b[n++] = br13; b[n++] = (dst_y << 16) | dst_x; // left, top - b[n++] = ((dst_y+height-1)<< 16)|(dst_x+width-1); // bottom, right + b[n++] = ((dst_y+height)<< 16)|(dst_x+width); // bottom, right b[n++] = 0; // destination b[n++] = (src_y << 16) | src_x; // source left & top b[n++] = bitmap->pitch; // source pitch diff --git a/drivers/video/drm/i915/main.c b/drivers/video/drm/i915/main.c index 29e46df2dc..fb3fa12f1a 100644 --- a/drivers/video/drm/i915/main.c +++ b/drivers/video/drm/i915/main.c @@ -100,6 +100,8 @@ u32_t drvEntry(int action, char *cmdline) #define SRV_DESTROY_SURFACE 11 #define SRV_LOCK_SURFACE 12 #define SRV_UNLOCK_SURFACE 13 +#define SRV_RESIZE_SURFACE 14 + #define SRV_BLIT_VIDEO 20 @@ -158,6 +160,10 @@ int _stdcall display_handler(ioctl_t *io) retval = lock_surface((struct io_call_12*)inp); break; + case SRV_RESIZE_SURFACE: + retval = resize_surface((struct io_call_14*)inp); + break; + case SRV_BLIT_VIDEO: blit_video( inp[0], inp[1], inp[2], inp[3], inp[4], inp[5], inp[6]);