Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. #include <drm/drmP.h>
  3. #include <drm/i915_drm.h>
  4. #include "i915_drv.h"
  5. #include "intel_drv.h"
  6. #include "hmm.h"
  7. #include "bitmap.h"
  8.  
  9. #define DRIVER_CAPS_0   HW_BIT_BLIT;
  10. #define DRIVER_CAPS_1   0
  11.  
  12. struct context *context_map[256];
  13.  
  14. struct hmm bm_mm;
  15.  
  16. extern struct drm_device *main_device;
  17.  
  18.  
  19.  
  20. void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
  21. {
  22.     dma_addr_t *pages = bitmap->obj->allocated_pages;;
  23.     int i;
  24.  
  25.     printf("destroy bitmap %d\n", bitmap->handle);
  26.     free_handle(&bm_mm, bitmap->handle);
  27.     bitmap->handle = 0;
  28.     bitmap->obj->base.read_domains = I915_GEM_DOMAIN_GTT;
  29.     bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  30.  
  31.     mutex_lock(&main_device->struct_mutex);
  32.     drm_gem_object_unreference(&bitmap->obj->base);
  33.     mutex_unlock(&main_device->struct_mutex);
  34.  
  35.     if(pages != NULL)
  36.     {
  37.         for (i = 0; i < bitmap->page_count; i++)
  38.             FreePage(pages[i]);
  39.  
  40.         free(pages);
  41.     };
  42.     UserFree(bitmap->uaddr);
  43.     __DestroyObject(bitmap);
  44. };
  45.  
  46.  
  47. static int bitmap_get_pages_gtt(struct drm_i915_gem_object *obj)
  48. {
  49.     int page_count;
  50.  
  51.     /* Get the list of pages out of our struct file.  They'll be pinned
  52.      * at this point until we release them.
  53.      */
  54.     page_count = obj->base.size / PAGE_SIZE;
  55.     BUG_ON(obj->allocated_pages == NULL);
  56.     BUG_ON(obj->pages.page != NULL);
  57.  
  58.     obj->pages.page = obj->allocated_pages;
  59.     obj->pages.nents = page_count;
  60.  
  61.  
  62. //   if (obj->tiling_mode != I915_TILING_NONE)
  63. //       i915_gem_object_do_bit_17_swizzle(obj);
  64.  
  65.     return 0;
  66. }
  67.  
  68. static void bitmap_put_pages_gtt(struct drm_i915_gem_object *obj)
  69. {
  70.     int ret, i;
  71.  
  72.     BUG_ON(obj->madv == __I915_MADV_PURGED);
  73.  
  74.     ret = i915_gem_object_set_to_cpu_domain(obj, true);
  75.     if (ret) {
  76.         /* In the event of a disaster, abandon all caches and
  77.          * hope for the best.
  78.          */
  79.         WARN_ON(ret != -EIO);
  80.         i915_gem_clflush_object(obj);
  81.         obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  82.     }
  83.  
  84.     if (obj->madv == I915_MADV_DONTNEED)
  85.         obj->dirty = 0;
  86.  
  87.     obj->dirty = 0;
  88. }
  89.  
  90. static const struct drm_i915_gem_object_ops bitmap_object_ops = {
  91.     .get_pages = bitmap_get_pages_gtt,
  92.     .put_pages = bitmap_put_pages_gtt,
  93. };
  94.  
  95.  
  96.  
  97. #if 0
  98. struct  io_call_10         /*     SRV_CREATE_SURFACE    */
  99. {
  100.     u32     handle;       // ignored
  101.     void   *data;         // ignored
  102.  
  103.     u32     width;
  104.     u32     height;
  105.     u32     pitch;        // ignored
  106.  
  107.     u32     max_width;
  108.     u32     max_height;
  109.     u32     format;       // reserved mbz
  110. };
  111.  
  112. #endif
  113.  
  114. int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap)
  115. {
  116.     struct drm_i915_gem_object *obj;
  117.  
  118.     bitmap_t   *bitmap;
  119.     u32         handle;
  120.     u32         width, max_width;
  121.     u32         height, max_height;
  122.     u32         size,  max_size;
  123.     u32         pitch, max_pitch;
  124.     void       *uaddr;
  125.     dma_addr_t *pages;
  126.     u32         page_count;
  127.  
  128.     int         i;
  129.  
  130.     int   ret;
  131.  
  132.     pbitmap->handle = 0;
  133.     pbitmap->data   = (void*)-1;
  134.  
  135.     width  = pbitmap->width;
  136.     height = pbitmap->height;
  137.  
  138.     if((width == 0)||(height == 0)||(width > 4096)||(height > 4096))
  139.         goto err1;
  140.  
  141. /*
  142.     if( ((pbitmap->max_width !=0 ) &&
  143.          (pbitmap->max_width < width)) ||
  144.          (pbitmap->max_width > 4096) )
  145.         goto err1;
  146.  
  147.     if( ((pbitmap->max_height !=0 ) &&
  148.          (pbitmap->max_height < width)) ||
  149.          (pbitmap->max_height > 4096) )
  150.         goto err1;
  151.  
  152.     if( pbitmap->format != 0)
  153.         goto err1;
  154. */
  155.  
  156.     max_width  = (pbitmap->max_width ==0) ? width  : pbitmap->max_width;
  157.     max_height = (pbitmap->max_height==0) ? height : pbitmap->max_height;
  158.  
  159.     handle = alloc_handle(&bm_mm);
  160. //    printf("%s %d\n",__FUNCTION__, handle);
  161.  
  162.     if(handle == 0)
  163.         goto err1;
  164.  
  165.     bitmap = CreateObject(GetPid(), sizeof(*bitmap));
  166. //    printf("bitmap %x\n", bitmap);
  167.     if( bitmap == NULL)
  168.         goto err2;
  169.  
  170.     bitmap->handle = handle;
  171.     bitmap->header.destroy = destroy_bitmap;
  172.     bitmap->obj    = NULL;
  173.  
  174.     hmm_set_data(&bm_mm, handle, bitmap);
  175.  
  176.     pitch = ALIGN(width*4,64);
  177.     size =  roundup(pitch*height, PAGE_SIZE);
  178.  
  179. //    printf("pitch %d size %d\n", pitch, size);
  180.  
  181.     max_pitch = ALIGN(max_width*4,64);
  182.     max_size =  roundup(max_pitch*max_height, PAGE_SIZE);
  183.  
  184. //    printf("max_pitch %d max_size %d\n", max_pitch, max_size);
  185.  
  186.     uaddr = UserAlloc(max_size);
  187.     if( uaddr == NULL)
  188.         goto err3;
  189.     else
  190.     {
  191.         u32           max_count;
  192.         dma_addr_t    page;
  193.         char *vaddr = uaddr;
  194.  
  195.         page_count = size/PAGE_SIZE;
  196.         max_count = max_size/PAGE_SIZE;
  197.  
  198.         pages = kzalloc(max_count*sizeof(dma_addr_t), 0);
  199.         if( pages == NULL)
  200.             goto err4;
  201.  
  202.         for(i = 0; i < page_count; i++, vaddr+= PAGE_SIZE)
  203.         {
  204.             page = AllocPage();
  205.             if ( page == 0 )
  206.                 goto err4;
  207.             pages[i] = page;
  208.  
  209.             MapPage(vaddr, page, 0x207);        //map as shared page
  210.         };
  211.         bitmap->page_count = page_count;
  212.         bitmap->max_count  = max_count;
  213.     };
  214.  
  215.     obj = i915_gem_alloc_object(dev, size);
  216.     if (obj == NULL)
  217.         goto err4;
  218.  
  219.     obj->ops = &bitmap_object_ops;
  220.     obj->allocated_pages = pages;
  221.  
  222.     ret = i915_gem_object_pin(obj, PAGE_SIZE, true,true);
  223.     if (ret)
  224.         goto err5;
  225.  
  226.     obj->mapped = uaddr ;
  227.  
  228.     bitmap->handle = handle;
  229.     bitmap->uaddr  = uaddr;
  230.     bitmap->pitch  = pitch;
  231.     bitmap->gaddr  = obj->gtt_offset;
  232.  
  233.     bitmap->width  = width;
  234.     bitmap->height = height;
  235.     bitmap->max_width  = max_width;
  236.     bitmap->max_height = max_height;
  237.  
  238.     bitmap->obj    = obj;
  239.     bitmap->header.destroy = destroy_bitmap;
  240.  
  241.     pbitmap->handle = handle;
  242.     pbitmap->data   = uaddr;
  243.     pbitmap->pitch  = pitch;
  244.  
  245.  
  246.     printf("%s handle: %d pitch: %d gpu_addr: %x user_addr: %x\n",
  247.             __FUNCTION__, handle, pitch, obj->gtt_offset, uaddr);
  248.  
  249.     return 0;
  250.  
  251. err5:
  252.     mutex_lock(&dev->struct_mutex);
  253.     drm_gem_object_unreference(&obj->base);
  254.     mutex_unlock(&dev->struct_mutex);
  255.  
  256. err4:
  257.     while (i--)
  258.         FreePage(pages[i]);
  259.     free(pages);
  260.     UserFree(uaddr);
  261.  
  262. err3:
  263.     __DestroyObject(bitmap);
  264. err2:
  265.     free_handle(&bm_mm, handle);
  266. err1:
  267.     return -1;
  268. };
  269.  
  270.  
  271. int lock_surface(struct io_call_12 *pbitmap)
  272. {
  273.     int ret;
  274.  
  275.     bitmap_t  *bitmap;
  276.  
  277.     if(unlikely(pbitmap->handle == 0))
  278.         return -1;
  279.  
  280.     bitmap = (bitmap_t*)hmm_get_data(&bm_mm, pbitmap->handle);
  281.  
  282.     if(unlikely(bitmap==NULL))
  283.         return -1;
  284.  
  285.     ret = i915_gem_object_set_to_cpu_domain(bitmap->obj, true);
  286.  
  287.     if(ret != 0 )
  288.     {
  289.         pbitmap->data  = NULL;
  290.         pbitmap->pitch = 0;
  291.  
  292.         dbgprintf("%s fail\n", __FUNCTION__);
  293.         return ret;
  294.     };
  295.  
  296.     pbitmap->data  = bitmap->uaddr;
  297.     pbitmap->pitch = bitmap->pitch;
  298.  
  299.     return 0;
  300. };
  301.  
  302.  
  303.  
  304.  
  305. int init_bitmaps()
  306. {
  307.     int ret;
  308.  
  309.     ret = init_hmm(&bm_mm, 1024);
  310.  
  311.     return ret;
  312. };
  313.  
  314.  
  315.  
  316. int get_driver_caps(hwcaps_t *caps)
  317. {
  318.     int ret = 0;
  319.  
  320.     switch(caps->idx)
  321.     {
  322.         case 0:
  323.             caps->opt[0] = DRIVER_CAPS_0;
  324.             caps->opt[1] = DRIVER_CAPS_1;
  325.             break;
  326.  
  327.         case 1:
  328.             caps->cap1.max_tex_width  = 4096;
  329.             caps->cap1.max_tex_height = 4096;
  330.             break;
  331.         default:
  332.             ret = 1;
  333.     };
  334.     caps->idx = 1;
  335.     return ret;
  336. }
  337.  
  338.  
  339. void __attribute__((regparm(1))) destroy_context(struct context *context)
  340. {
  341.     printf("destroy context %x\n", context);
  342.  
  343.     context_map[context->slot] = NULL;
  344.  
  345.     mutex_lock(&main_device->struct_mutex);
  346.     drm_gem_object_unreference(&context->obj->base);
  347.     mutex_unlock(&main_device->struct_mutex);
  348.  
  349.     __DestroyObject(context);
  350. };
  351.  
  352.  
  353. #define CURRENT_TASK             (0x80003000)
  354.  
  355. struct context *get_context(struct drm_device *dev)
  356. {
  357.     struct context *context;
  358.     struct io_call_10 io_10;
  359.     int    slot = *((u8*)CURRENT_TASK);
  360.     int    ret;
  361.  
  362.     context = context_map[slot];
  363.  
  364.     if( context != NULL)
  365.         return context;
  366.  
  367.     context = CreateObject(GetPid(), sizeof(*context));
  368.     printf("context %x\n", context);
  369.     if( context != NULL)
  370.     {
  371.         drm_i915_private_t *dev_priv = dev->dev_private;
  372.         struct drm_i915_gem_object *obj;
  373.  
  374.         obj = i915_gem_alloc_object(dev, 4096);
  375.         i915_gem_object_pin(obj, 4096, true, true);
  376.  
  377.         context->obj = obj;
  378.         context->cmd_buffer = MapIoMem((addr_t)obj->pages.page[0], 4096, PG_SW|PG_NOCACHE);
  379.         context->cmd_offset = obj->gtt_offset;
  380.  
  381.         context->header.destroy = destroy_context;
  382.         context->mask  = NULL;
  383.         context->seqno = 0;
  384.         context->slot  = slot;
  385.  
  386.         context_map[slot] = context;
  387.     };
  388.     return context;
  389. };
  390.  
  391.