Subversion Repositories Kolibri OS

Rev

Rev 2360 | Rev 3033 | 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. //    printf("bitmap %x\n", bitmap);
  94.     if( bitmap == NULL)
  95.         goto err1;
  96.  
  97.     bitmap->handle = handle;
  98.     bitmap->header.destroy = destroy_bitmap;
  99.     bitmap->obj    = NULL;
  100.  
  101.  
  102.     hman_set_data(&bm_man, handle, bitmap);
  103.  
  104.     pitch = ALIGN(width*4,64);
  105.  
  106.     size =  roundup(pitch*height, PAGE_SIZE);
  107.  
  108. //    printf("pitch %d size %d\n", pitch, size);
  109.  
  110.     obj = i915_gem_alloc_object(main_device, size);
  111.     if (obj == NULL)
  112.         goto err2;
  113.  
  114.     ret = i915_gem_object_pin(obj, 4096, true);
  115.     if (ret)
  116.         goto err3;
  117.  
  118.     max_pitch = ALIGN(max_width*4,64);
  119.     max_size =  roundup(max_pitch*max_height, PAGE_SIZE);
  120.  
  121.     uaddr = UserAlloc(max_size);
  122.     if( uaddr == NULL)
  123.         goto err4;
  124.     else
  125.     {
  126.         u32_t *src, *dst;
  127.         u32 count, max_count;
  128.  
  129. #define page_tabs  0xFDC00000      /* really dirty hack */
  130.  
  131.         src =  (u32_t*)obj->pages;
  132.         dst =  &((u32_t*)page_tabs)[(u32_t)uaddr >> 12];
  133.         count = size/4096;
  134.         max_count = max_size/4096 - count;
  135.  
  136.         while(count--)
  137.         {
  138.             *dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page
  139.         };
  140.         while(max_count--)
  141.             *dst++ = 0;                              // cleanup unused space
  142.     }
  143.  
  144.     obj->mapped = uaddr ;
  145.  
  146.     bitmap->handle = handle;
  147.     bitmap->uaddr  = uaddr;
  148.     bitmap->pitch  = pitch;
  149.     bitmap->gaddr  = obj->gtt_offset;
  150.  
  151.     bitmap->width  = width;
  152.     bitmap->height = height;
  153.     bitmap->max_width  = max_width;
  154.     bitmap->max_height = max_height;
  155.  
  156.     bitmap->obj    = obj;
  157.     bitmap->header.destroy = destroy_bitmap;
  158.  
  159.     pbitmap->handle = handle;
  160.     pbitmap->data   = uaddr;
  161.     pbitmap->pitch  = pitch;
  162.  
  163.  
  164.     printf("%s handle: %d pitch: %d gpu_addr: %x user_addr: %x\n",
  165.             __FUNCTION__, handle, pitch, obj->gtt_offset, uaddr);
  166.  
  167.     return 0;
  168.  
  169. err4:
  170.     i915_gem_object_unpin(obj);
  171. err3:
  172.     drm_gem_object_unreference(&obj->base);
  173. err2:
  174.     free_handle(&bm_man, handle);
  175.     __DestroyObject(bitmap);
  176. err1:
  177.     return -1;
  178.  
  179. };
  180.  
  181.  
  182. int lock_surface(struct io_call_12 *pbitmap)
  183. {
  184.     int ret;
  185.  
  186.     drm_i915_private_t *dev_priv = main_device->dev_private;
  187.  
  188.     bitmap_t  *bitmap;
  189.  
  190.     if(unlikely(pbitmap->handle == 0))
  191.         return -1;
  192.  
  193.     bitmap = (bitmap_t*)hman_get_data(&bm_man, pbitmap->handle);
  194.  
  195.     if(unlikely(bitmap==NULL))
  196.         return -1;
  197.  
  198.     ret = gem_object_lock(bitmap->obj);
  199.     if(ret !=0 )
  200.     {
  201.         pbitmap->data  = NULL;
  202.         pbitmap->pitch = 0;
  203.  
  204.         dbgprintf("%s fail\n", __FUNCTION__);
  205.         return ret;
  206.     };
  207.  
  208.     pbitmap->data  = bitmap->uaddr;
  209.     pbitmap->pitch = bitmap->pitch;
  210.  
  211.     return 0;
  212. };
  213.  
  214.  
  215. int init_hman(struct hman *man, u32 count)
  216. {
  217.     u32* data;
  218.  
  219.     data = malloc(count*sizeof(u32*));
  220.     if(data)
  221.     {
  222.         int i;
  223.  
  224.         for(i=0;i < count-1;)
  225.             data[i] = ++i;
  226.         data[i] = 0;
  227.  
  228.         man->table = data;
  229.         man->next  = 0;
  230.         man->avail = count;
  231.         man->count = count;
  232.  
  233.         return 0;
  234.     };
  235.     return -ENOMEM;
  236. };
  237.  
  238. u32  alloc_handle(struct hman *man)
  239. {
  240.     u32 handle = 0;
  241.  
  242.     if(man->avail)
  243.     {
  244.         handle = man->next;
  245.         man->next = man->table[handle];
  246.         man->avail--;
  247.         handle++;
  248.     }
  249.     return handle;
  250. };
  251.  
  252. int free_handle(struct hman *man, u32 handle)
  253. {
  254.     int ret = -1;
  255.  
  256.     handle--;
  257.  
  258.     if(handle < man->count)
  259.     {
  260.         man->table[handle] = man->next;
  261.         man->next = handle;
  262.         man->avail++;
  263.         ret = 0;
  264.     };
  265.  
  266.     return ret;
  267. };
  268.  
  269.  
  270. void *drm_intel_bo_map(struct drm_i915_gem_object *obj, int write_enable)
  271. {
  272.     u8 *kaddr;
  273.  
  274.     kaddr = AllocKernelSpace(obj->base.size);
  275.     if( kaddr != NULL)
  276.     {
  277.         u32_t *src = (u32_t*)obj->pages;
  278.         u32_t *dst = &((u32_t*)page_tabs)[(u32_t)kaddr >> 12];
  279.  
  280.         u32 count  = obj->base.size/4096;
  281.  
  282.         while(count--)
  283.         {
  284.             *dst++ = (0xFFFFF000 & *src++) | 0x003 ;
  285.         };
  286.         return kaddr;
  287.     };
  288.     return NULL;
  289. }
  290.  
  291. void destroy_gem_object(uint32_t handle)
  292. {
  293.     struct drm_i915_gem_object *obj = (void*)handle;
  294.     drm_gem_object_unreference(&obj->base);
  295.  
  296. };
  297.  
  298.  
  299. void write_gem_object(uint32_t handle, u32 offset, u32 size, u8* src)
  300. {
  301.     struct drm_i915_gem_object *obj = (void*)handle;
  302.     u8    *dst;
  303.     int    ret;
  304.  
  305.     ret = i915_gem_object_pin(obj, 4096, true);
  306.     if (ret)
  307.         return;
  308.  
  309.     dst = drm_intel_bo_map(obj, true);
  310.     if( dst != NULL )
  311.     {
  312.         memmove(dst+offset, src, size);
  313.         FreeKernelSpace(dst);
  314.     };
  315. };
  316.  
  317. u32 get_buffer_offset(uint32_t handle)
  318. {
  319.     struct drm_i915_gem_object *obj = (void*)handle;
  320.  
  321.     return obj->gtt_offset;
  322. };
  323.  
  324.  
  325. int get_driver_caps(hwcaps_t *caps)
  326. {
  327.     int ret = 0;
  328.     ENTER();
  329.  
  330.     switch(caps->idx)
  331.     {
  332.         case 0:
  333.             caps->opt[0] = DRIVER_CAPS_0;
  334.             caps->opt[1] = DRIVER_CAPS_1;
  335.             break;
  336.  
  337.         case 1:
  338.             caps->cap1.max_tex_width  = 4096;
  339.             caps->cap1.max_tex_height = 4096;
  340.             break;
  341.         default:
  342.             ret = 1;
  343.     };
  344.     caps->idx = 1;
  345.     return ret;
  346. }
  347.  
  348.