Subversion Repositories Kolibri OS

Rev

Rev 2352 | Rev 2361 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1.  
  2. #include <drmP.h>
  3. #include <drm.h>
  4. #include "i915_drm.h"
  5. #include "i915_drv.h"
  6. #include "intel_drv.h"
  7. #include "bitmap.h"
  8.  
  9. #define memmove __builtin_memmove
  10.  
  11. int gem_object_lock(struct drm_i915_gem_object *obj);
  12.  
  13. #define DRIVER_CAPS_0   HW_BIT_BLIT | HW_TEX_BLIT;
  14. #define DRIVER_CAPS_1   0
  15.  
  16. extern struct drm_device *main_device;
  17.  
  18. struct hman bm_man;
  19.  
  20. void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
  21. {
  22.     printf("destroy bitmap %d\n", bitmap->handle);
  23.     free_handle(&bm_man, bitmap->handle);
  24.     bitmap->handle = 0;
  25.     bitmap->obj->base.read_domains = I915_GEM_DOMAIN_GTT;
  26.     bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  27.  
  28.     mutex_lock(&main_device->struct_mutex);
  29.     drm_gem_object_unreference(&bitmap->obj->base);
  30.     mutex_unlock(&main_device->struct_mutex);
  31.  
  32.     __DestroyObject(bitmap);
  33. };
  34.  
  35. int init_bitmaps()
  36. {
  37.     int ret;
  38.  
  39.     ret = init_hman(&bm_man, 1024);
  40.  
  41.     return ret;
  42. };
  43.  
  44.  
  45. int create_surface(struct io_call_10 *pbitmap)
  46. {
  47.     struct drm_i915_gem_object *obj;
  48.  
  49.     bitmap_t   *bitmap;
  50.     u32         handle;
  51.     u32         width, max_width;
  52.     u32         height, max_height;
  53.     u32         size,  max_size;
  54.     u32         pitch, max_pitch;
  55.     void       *uaddr;
  56.  
  57.     int   ret;
  58.  
  59.     pbitmap->handle = 0;
  60.     pbitmap->data   = (void*)-1;
  61.  
  62.     width  = pbitmap->width;
  63.     height = pbitmap->height;
  64.  
  65. /*
  66.     if((width==0)||(height==0)||(width>4096)||(height>4096))
  67.         goto err1;
  68.  
  69.     if( ((pbitmap->max_width !=0 ) &&
  70.          (pbitmap->max_width < width)) ||
  71.          (pbitmap->max_width > 4096) )
  72.         goto err1;
  73.  
  74.     if( ((pbitmap->max_height !=0 ) &&
  75.          (pbitmap->max_height < width)) ||
  76.          (pbitmap->max_height > 4096) )
  77.         goto err1;
  78.  
  79.     if( pbitmap->format != 0)
  80.         goto err1;
  81. */
  82.  
  83.     max_width  = (pbitmap->max_width ==0) ? width  : pbitmap->max_width;
  84.     max_height = (pbitmap->max_height==0) ? height : pbitmap->max_height;
  85.  
  86.     handle = alloc_handle(&bm_man);
  87. //    printf("%s %d\n",__FUNCTION__, handle);
  88.  
  89.     if(handle == 0)
  90.         goto err1;
  91.  
  92.     bitmap = CreateObject(GetPid(), sizeof(*bitmap));
  93.     bitmap->handle = handle;
  94.     bitmap->header.destroy = destroy_bitmap;
  95.     bitmap->obj    = NULL;
  96.  
  97. //    printf("bitmap %x\n", bitmap);
  98.     if( bitmap == NULL)
  99.         goto err1;
  100.  
  101.     hman_set_data(&bm_man, handle, bitmap);
  102.  
  103.     pitch = ALIGN(width*4,64);
  104.  
  105.     size =  roundup(pitch*height, PAGE_SIZE);
  106.  
  107. //    printf("pitch %d size %d\n", pitch, size);
  108.  
  109.     obj = i915_gem_alloc_object(main_device, size);
  110.     if (obj == NULL)
  111.         goto err2;
  112.  
  113.     ret = i915_gem_object_pin(obj, 4096, true);
  114.     if (ret)
  115.         goto err3;
  116.  
  117.     max_pitch = ALIGN(max_width*4,64);
  118.     max_size =  roundup(max_pitch*max_height, PAGE_SIZE);
  119.  
  120.     uaddr = UserAlloc(max_size);
  121.     if( uaddr == NULL)
  122.         goto err4;
  123.     else
  124.     {
  125.         u32_t *src, *dst;
  126.         u32 count, max_count;
  127.  
  128. #define page_tabs  0xFDC00000      /* really dirty hack */
  129.  
  130.         src =  (u32_t*)obj->pages;
  131.         dst =  &((u32_t*)page_tabs)[(u32_t)uaddr >> 12];
  132.         count = size/4096;
  133.         max_count = max_size/4096 - count;
  134.  
  135.         while(count--)
  136.         {
  137.             *dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page
  138.         };
  139.         while(max_count--)
  140.             *dst++ = 0;                              // cleanup unused space
  141.     }
  142.  
  143.     obj->mapped = uaddr ;
  144.  
  145.     bitmap->handle = handle;
  146.     bitmap->uaddr  = uaddr;
  147.     bitmap->pitch  = pitch;
  148.     bitmap->gaddr  = obj->gtt_offset;
  149.  
  150.     bitmap->width  = width;
  151.     bitmap->height = height;
  152.     bitmap->max_width  = max_width;
  153.     bitmap->max_height = max_height;
  154.  
  155.     bitmap->obj    = obj;
  156.     bitmap->header.destroy = destroy_bitmap;
  157.  
  158.     pbitmap->handle = handle;
  159.     pbitmap->data   = uaddr;
  160.     pbitmap->pitch  = pitch;
  161.  
  162.  
  163.     printf("%s handle: %d pitch: %d gpu_addr: %x user_addr: %x\n",
  164.             __FUNCTION__, handle, pitch, obj->gtt_offset, uaddr);
  165.  
  166.     return 0;
  167.  
  168. err4:
  169.     i915_gem_object_unpin(obj);
  170. err3:
  171.     drm_gem_object_unreference(&obj->base);
  172. err2:
  173.     free_handle(&bm_man, handle);
  174.     __DestroyObject(bitmap);
  175. err1:
  176.     return -1;
  177.  
  178. };
  179.  
  180.  
  181. int lock_surface(struct io_call_12 *pbitmap)
  182. {
  183.     int ret;
  184.  
  185.     drm_i915_private_t *dev_priv = main_device->dev_private;
  186.  
  187.     bitmap_t  *bitmap;
  188.  
  189.     if(unlikely(pbitmap->handle == 0))
  190.         return -1;
  191.  
  192.     bitmap = (bitmap_t*)hman_get_data(&bm_man, pbitmap->handle);
  193.  
  194.     if(unlikely(bitmap==NULL))
  195.         return -1;
  196.  
  197.     ret = gem_object_lock(bitmap->obj);
  198.     if(ret !=0 )
  199.     {
  200.         pbitmap->data  = NULL;
  201.         pbitmap->pitch = 0;
  202.  
  203.         dbgprintf("%s fail\n", __FUNCTION__);
  204.         return ret;
  205.     };
  206.  
  207.     pbitmap->data  = bitmap->uaddr;
  208.     pbitmap->pitch = bitmap->pitch;
  209.  
  210.     return 0;
  211. };
  212.  
  213. int init_hman(struct hman *man, u32 count)
  214. {
  215.     u32* data;
  216.  
  217.     data = malloc(count*sizeof(u32*));
  218.     if(data)
  219.     {
  220.         int i;
  221.  
  222.         for(i=0;i < count-1;)
  223.             data[i] = ++i;
  224.         data[i] = 0;
  225.  
  226.         man->table = data;
  227.         man->next  = 0;
  228.         man->avail = count;
  229.         man->count = count;
  230.  
  231.         return 0;
  232.     };
  233.     return -ENOMEM;
  234. };
  235.  
  236. u32  alloc_handle(struct hman *man)
  237. {
  238.     u32 handle = 0;
  239.  
  240.     if(man->avail)
  241.     {
  242.         handle = man->next;
  243.         man->next = man->table[handle];
  244.         man->avail--;
  245.         handle++;
  246.     }
  247.     return handle;
  248. };
  249.  
  250. int free_handle(struct hman *man, u32 handle)
  251. {
  252.     int ret = -1;
  253.  
  254.     handle--;
  255.  
  256.     if(handle < man->count)
  257.     {
  258.         man->table[handle] = man->next;
  259.         man->next = handle;
  260.         man->avail++;
  261.         ret = 0;
  262.     };
  263.  
  264.     return ret;
  265. };
  266.  
  267.  
  268. void *drm_intel_bo_map(struct drm_i915_gem_object *obj, int write_enable)
  269. {
  270.     u8 *kaddr;
  271.  
  272.     kaddr = AllocKernelSpace(obj->base.size);
  273.     if( kaddr != NULL)
  274.     {
  275.         u32_t *src = (u32_t*)obj->pages;
  276.         u32_t *dst = &((u32_t*)page_tabs)[(u32_t)kaddr >> 12];
  277.  
  278.         u32 count  = obj->base.size/4096;
  279.  
  280.         while(count--)
  281.         {
  282.             *dst++ = (0xFFFFF000 & *src++) | 0x003 ;
  283.         };
  284.         return kaddr;
  285.     };
  286.     return NULL;
  287. }
  288.  
  289. void destroy_gem_object(uint32_t handle)
  290. {
  291.     struct drm_i915_gem_object *obj = (void*)handle;
  292.     drm_gem_object_unreference(&obj->base);
  293.  
  294. };
  295.  
  296.  
  297. void write_gem_object(uint32_t handle, u32 offset, u32 size, u8* src)
  298. {
  299.     struct drm_i915_gem_object *obj = (void*)handle;
  300.     u8    *dst;
  301.     int    ret;
  302.  
  303.     ret = i915_gem_object_pin(obj, 4096, true);
  304.     if (ret)
  305.         return;
  306.  
  307.     dst = drm_intel_bo_map(obj, true);
  308.     if( dst != NULL )
  309.     {
  310.         memmove(dst+offset, src, size);
  311.         FreeKernelSpace(dst);
  312.     };
  313. };
  314.  
  315. u32 get_buffer_offset(uint32_t handle)
  316. {
  317.     struct drm_i915_gem_object *obj = (void*)handle;
  318.  
  319.     return obj->gtt_offset;
  320. };
  321.  
  322.  
  323. int get_driver_caps(hwcaps_t *caps)
  324. {
  325.     int ret = 0;
  326.     ENTER();
  327.  
  328.     switch(caps->idx)
  329.     {
  330.         case 0:
  331.             caps->opt[0] = DRIVER_CAPS_0;
  332.             caps->opt[1] = DRIVER_CAPS_1;
  333.             break;
  334.  
  335.         case 1:
  336.             caps->cap1.max_tex_width  = 4096;
  337.             caps->cap1.max_tex_height = 4096;
  338.             break;
  339.         default:
  340.             ret = 1;
  341.     };
  342.     caps->idx = 1;
  343.     return ret;
  344. }
  345.  
  346.