Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 2339 → Rev 2340

/drivers/video/drm/i915/bitmap.c
0,0 → 1,224
 
#include <drmP.h>
#include <drm.h>
#include "i915_drm.h"
#include "i915_drv.h"
#include "intel_drv.h"
#include "bitmap.h"
 
extern struct drm_device *main_device;
 
struct hman bm_man;
 
int init_bitmaps()
{
int ret;
 
ret = init_hman(&bm_man, 1024);
 
return ret;
};
 
 
int create_bitmap(struct ubitmap *pbitmap, int width, int height)
{
struct drm_i915_gem_object *obj;
 
bitmap_t *bitmap;
u32 handle;
u32 size;
u32 pitch;
void *uaddr;
 
int ret;
 
pbitmap->handle = 0;
pbitmap->data = NULL;
 
if((width==0)||(height==0)||(width>4096)||(height>4096))
goto err1;
 
handle = alloc_handle(&bm_man);
 
if(handle == 0)
goto err1;
 
bitmap = CreateObject(GetPid(), sizeof(*bitmap));
if( bitmap == NULL)
goto err1;
 
hman_set_data(&bm_man, handle, bitmap);
 
pitch = ALIGN(width*4,64);
 
size = roundup(pitch*height, PAGE_SIZE);
 
obj = i915_gem_alloc_object(main_device, size);
if (obj == NULL)
goto err2;
 
ret = i915_gem_object_pin(obj, 4096, true);
if (ret)
goto err3;
 
uaddr = UserAlloc(size);
if( uaddr == NULL)
goto err4;
else
{
u32_t *src, *dst;
int count;
 
#define page_tabs 0xFDC00000 /* really dirty hack */
 
src = (u32_t*)obj->pages;
dst = &((u32_t*)page_tabs)[(u32_t)uaddr >> 12];
count = size/4096;
 
while(count--)
{
*dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page
};
}
 
bitmap->handle = handle;
bitmap->width = width;
bitmap->height = height;
bitmap->pitch = pitch;
bitmap->gaddr = obj->gtt_offset;
bitmap->uaddr = uaddr;
bitmap->obj = obj;
 
pbitmap->handle = handle;
pbitmap->data = uaddr;
return 0;
 
err4:
// drm_gem_object_unpin;
err3:
// drm_gem_object_unreference(&obj->base);
err2:
free_handle(&bm_man, handle);
DestroyObject(bitmap);
err1:
return -1;
 
};
 
 
int create_video(int width, int height, u32_t *outp)
{
struct drm_i915_gem_object *obj;
 
size_t size;
size_t pitch;
void *uaddr;
 
int ret;
 
if((width==0)||(height==0)||(width>4096)||(height>4096))
goto err1;
 
pitch = ALIGN(width*4,64);
 
size = roundup(pitch*height, PAGE_SIZE);
 
obj = i915_gem_alloc_object(main_device, size);
if (obj == NULL)
goto err2;
 
ret = i915_gem_object_pin(obj, 4096, true);
if (ret)
goto err3;
 
uaddr = UserAlloc(size);
if( uaddr == NULL)
goto err4;
else
{
u32_t *src, *dst;
int count;
 
#define page_tabs 0xFDC00000 /* really dirty hack */
 
src = (u32_t*)obj->pages;
dst = &((u32_t*)page_tabs)[(u32_t)uaddr >> 12];
count = size/4096;
 
while(count--)
{
*dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page
};
}
 
outp[0] = obj->gtt_offset;
outp[2] = (u32)uaddr;
outp[3] = pitch;
 
return 0;
 
err4:
// drm_gem_object_unpin;
err3:
// drm_gem_object_unreference(&obj->base);
err2:
err1:
return -1;
};
 
 
int init_hman(struct hman *man, u32 count)
{
u32* data;
 
data = malloc(count*sizeof(u32*));
if(data)
{
int i;
 
for(i=0;i < count-1;)
data[i] = ++i;
data[i] = 0;
 
man->table = data;
man->next = 0;
man->avail = count;
man->count = count;
 
return 0;
};
return -ENOMEM;
};
 
u32 alloc_handle(struct hman *man)
{
u32 handle = 0;
 
if(man->avail)
{
handle = man->next;
man->next = man->table[handle];
man->avail--;
handle++;
}
return handle;
};
 
int free_handle(struct hman *man, u32 handle)
{
int ret = -1;
 
handle--;
 
if(handle < man->count)
{
man->table[handle] = man->next;
man->next = handle;
man->avail++;
ret = 0;
};
 
return ret;
};