Subversion Repositories Kolibri OS

Rev

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