Subversion Repositories Kolibri OS

Rev

Rev 3051 | 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.  
  11. #define DRIVER_CAPS_0   0
  12. #define DRIVER_CAPS_1   0
  13.  
  14. struct context *context_map[256];
  15.  
  16. struct hmm bm_mm;
  17.  
  18. extern struct drm_device *main_device;
  19.  
  20.  
  21. void __attribute__((regparm(1))) destroy_bitmap(bitmap_t *bitmap)
  22. {
  23.     dma_addr_t *pages = bitmap->obj->allocated_pages;
  24.     int i;
  25.  
  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.         DRM_DEBUG("%s release %d pages\n", __FUNCTION__, bitmap->page_count);
  41.  
  42.         free(pages);
  43.     };
  44.     UserFree(bitmap->uaddr);
  45.     __DestroyObject(bitmap);
  46. };
  47.  
  48.  
  49. static int bitmap_get_pages_gtt(struct drm_i915_gem_object *obj)
  50. {
  51.     int page_count;
  52.  
  53.     /* Get the list of pages out of our struct file.  They'll be pinned
  54.      * at this point until we release them.
  55.      */
  56.  
  57.     page_count = obj->base.size / PAGE_SIZE;
  58.     BUG_ON(obj->allocated_pages == NULL);
  59.     BUG_ON(obj->pages.page != NULL);
  60.  
  61.     obj->pages.page = obj->allocated_pages;
  62.     obj->pages.nents = page_count;
  63.  
  64.  
  65. //   if (obj->tiling_mode != I915_TILING_NONE)
  66. //       i915_gem_object_do_bit_17_swizzle(obj);
  67.  
  68.     return 0;
  69. }
  70.  
  71. static void bitmap_put_pages_gtt(struct drm_i915_gem_object *obj)
  72. {
  73.     int ret, i;
  74.  
  75.     BUG_ON(obj->madv == __I915_MADV_PURGED);
  76.  
  77.     ret = i915_gem_object_set_to_cpu_domain(obj, true);
  78.     if (ret) {
  79.         /* In the event of a disaster, abandon all caches and
  80.          * hope for the best.
  81.          */
  82.         WARN_ON(ret != -EIO);
  83.         i915_gem_clflush_object(obj);
  84.         obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU;
  85.     }
  86.  
  87.     if (obj->madv == I915_MADV_DONTNEED)
  88.         obj->dirty = 0;
  89.  
  90.     obj->dirty = 0;
  91. }
  92.  
  93. static const struct drm_i915_gem_object_ops bitmap_object_ops = {
  94.     .get_pages = bitmap_get_pages_gtt,
  95.     .put_pages = bitmap_put_pages_gtt,
  96. };
  97.  
  98.  
  99.  
  100. #if 0
  101. struct  io_call_10         /*     SRV_CREATE_SURFACE    */
  102. {
  103.     u32     handle;       // ignored
  104.     void   *data;         // ignored
  105.  
  106.     u32     width;
  107.     u32     height;
  108.     u32     pitch;        // ignored
  109.  
  110.     u32     max_width;
  111.     u32     max_height;
  112.     u32     format;       // reserved mbz
  113. };
  114.  
  115. #endif
  116.  
  117. int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap)
  118. {
  119.     struct drm_i915_gem_object *obj;
  120.  
  121.     bitmap_t   *bitmap;
  122.     u32         handle;
  123.     u32         width, max_width;
  124.     u32         height, max_height;
  125.     u32         size,  max_size;
  126.     u32         pitch, max_pitch;
  127.     void       *uaddr;
  128.     dma_addr_t *pages;
  129.     u32         page_count;
  130.  
  131.     int         i;
  132.  
  133.     int   ret;
  134.  
  135.     pbitmap->handle = 0;
  136.     pbitmap->data   = (void*)-1;
  137.  
  138.     width  = pbitmap->width;
  139.     height = pbitmap->height;
  140.  
  141.     if((width == 0)||(height == 0)||(width > 4096)||(height > 4096))
  142.         goto err1;
  143.  
  144. /*
  145.     if( ((pbitmap->max_width !=0 ) &&
  146.          (pbitmap->max_width < width)) ||
  147.          (pbitmap->max_width > 4096) )
  148.         goto err1;
  149.  
  150.     if( ((pbitmap->max_height !=0 ) &&
  151.          (pbitmap->max_height < width)) ||
  152.          (pbitmap->max_height > 4096) )
  153.         goto err1;
  154.  
  155.     if( pbitmap->format != 0)
  156.         goto err1;
  157. */
  158.  
  159.     max_width  = (pbitmap->max_width ==0) ? width  : pbitmap->max_width;
  160.     max_height = (pbitmap->max_height==0) ? height : pbitmap->max_height;
  161.  
  162.     handle = alloc_handle(&bm_mm);
  163. //    printf("%s %d\n",__FUNCTION__, handle);
  164.  
  165.     if(handle == 0)
  166.         goto err1;
  167.  
  168.     bitmap = CreateObject(GetPid(), sizeof(*bitmap));
  169. //    printf("bitmap %x\n", bitmap);
  170.     if( bitmap == NULL)
  171.         goto err2;
  172.  
  173.     bitmap->handle = handle;
  174.     bitmap->header.destroy = destroy_bitmap;
  175.     bitmap->obj    = NULL;
  176.  
  177.     hmm_set_data(&bm_mm, handle, bitmap);
  178.  
  179.     pitch = ALIGN(width*4,64);
  180.     size =  roundup(pitch*height, PAGE_SIZE);
  181.  
  182. //    printf("pitch %d size %d\n", pitch, size);
  183.  
  184.     max_pitch = ALIGN(max_width*4,64);
  185.     max_size =  roundup(max_pitch*max_height, PAGE_SIZE);
  186.  
  187. //    printf("max_pitch %d max_size %d\n", max_pitch, max_size);
  188.  
  189.     uaddr = UserAlloc(max_size);
  190.     if( uaddr == NULL)
  191.         goto err3;
  192.     else
  193.     {
  194.         u32           max_count;
  195.         dma_addr_t    page;
  196.         char *vaddr = uaddr;
  197.  
  198.         page_count = size/PAGE_SIZE;
  199.         max_count = max_size/PAGE_SIZE;
  200.  
  201.         pages = kzalloc(max_count*sizeof(dma_addr_t), 0);
  202.         if( pages == NULL)
  203.             goto err4;
  204.  
  205.         for(i = 0; i < page_count; i++, vaddr+= PAGE_SIZE)
  206.         {
  207.             page = AllocPage();
  208.             if ( page == 0 )
  209.                 goto err4;
  210.             pages[i] = page;
  211.  
  212.             MapPage(vaddr, page, 0x207);        //map as shared page
  213.         };
  214.         for(;i < max_count; i++, vaddr+= PAGE_SIZE)
  215.         {
  216.             MapPage(vaddr, 0, 0);        //map as shared page
  217.         };
  218.  
  219.         bitmap->page_count = page_count;
  220.         bitmap->max_count  = max_count;
  221.     };
  222.  
  223.     DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__, page_count);
  224.  
  225.     obj = i915_gem_alloc_object(dev, size);
  226.     if (obj == NULL)
  227.         goto err4;
  228.  
  229.     obj->ops = &bitmap_object_ops;
  230.     obj->allocated_pages = pages;
  231.  
  232.     ret = i915_gem_object_pin(obj, PAGE_SIZE, true,true);
  233.     if (ret)
  234.         goto err5;
  235.  
  236.     obj->mapped    = uaddr ;
  237.  
  238.     bitmap->handle = handle;
  239.     bitmap->uaddr  = uaddr;
  240.     bitmap->pitch  = pitch;
  241.     bitmap->gaddr  = obj->gtt_offset;
  242.  
  243.     bitmap->width  = width;
  244.     bitmap->height = height;
  245.     bitmap->max_width  = max_width;
  246.     bitmap->max_height = max_height;
  247.  
  248.     bitmap->obj    = obj;
  249.     bitmap->header.destroy = destroy_bitmap;
  250.  
  251.     pbitmap->handle = handle;
  252.     pbitmap->data   = uaddr;
  253.     pbitmap->pitch  = pitch;
  254.  
  255.  
  256.     DRM_DEBUG("%s handle: %d pitch: %d gpu_addr: %x user_addr: %x\n",
  257.             __FUNCTION__, handle, pitch, obj->gtt_offset, uaddr);
  258.  
  259.     return 0;
  260.  
  261. err5:
  262.     mutex_lock(&dev->struct_mutex);
  263.     drm_gem_object_unreference(&obj->base);
  264.     mutex_unlock(&dev->struct_mutex);
  265.  
  266. err4:
  267.     while (i--)
  268.         FreePage(pages[i]);
  269.     free(pages);
  270.     UserFree(uaddr);
  271.  
  272. err3:
  273.     __DestroyObject(bitmap);
  274. err2:
  275.     free_handle(&bm_mm, handle);
  276. err1:
  277.     return -1;
  278. };
  279.  
  280.  
  281. int lock_surface(struct io_call_12 *pbitmap)
  282. {
  283.     int ret;
  284.  
  285.     bitmap_t  *bitmap;
  286.  
  287.     if(unlikely(pbitmap->handle == 0))
  288.         return -1;
  289.  
  290.     bitmap = (bitmap_t*)hmm_get_data(&bm_mm, pbitmap->handle);
  291.  
  292.     if(unlikely(bitmap==NULL))
  293.         return -1;
  294.  
  295.     mutex_lock(&main_device->struct_mutex);
  296.     ret = i915_gem_object_set_to_cpu_domain(bitmap->obj, true);
  297.     mutex_unlock(&main_device->struct_mutex);
  298.  
  299.     if(ret != 0 )
  300.     {
  301.         pbitmap->data  = NULL;
  302.         pbitmap->pitch = 0;
  303.  
  304.         dbgprintf("%s fail\n", __FUNCTION__);
  305.         return ret;
  306.     };
  307.  
  308.     pbitmap->data  = bitmap->uaddr;
  309.     pbitmap->pitch = bitmap->pitch;
  310.  
  311.     return 0;
  312. };
  313.  
  314.  
  315. int resize_surface(struct io_call_14 *pbitmap)
  316. {
  317.     bitmap_t  *bitmap;
  318.     dma_addr_t page, *pages;
  319.     u32        size, page_count;
  320.     u32        width, height;
  321.     u32        pitch;
  322.     int        i;
  323.     int        ret = 0;
  324.  
  325.  
  326.     if(unlikely(pbitmap->handle == 0))
  327.         return -1;
  328.  
  329.     bitmap = (bitmap_t*)hmm_get_data(&bm_mm, pbitmap->handle);
  330.  
  331.     if(unlikely(bitmap==NULL))
  332.         return -1;
  333.  
  334.     if( pbitmap->new_width > bitmap->max_width ||
  335.         pbitmap->new_height > bitmap->max_height)
  336.         return -1;
  337.  
  338.     width  = pbitmap->new_width;
  339.     height = pbitmap->new_height;
  340.  
  341.     pitch = ALIGN(width*4,64);
  342.     size =  roundup(pitch * height, PAGE_SIZE);
  343.     page_count = size/PAGE_SIZE;
  344.  
  345.     DRM_DEBUG("new width %d height %d pitch %d size %d\n",
  346.             width, height, pitch, size);
  347.  
  348.     if(page_count > bitmap->page_count)
  349.     {
  350.         char *vaddr = bitmap->uaddr + PAGE_SIZE * bitmap->page_count;
  351.  
  352.         pages = bitmap->obj->allocated_pages;
  353.  
  354.         DRM_DEBUG("old pages %d new_pages %d vaddr %x\n",
  355.                 bitmap->page_count, page_count, vaddr);
  356.  
  357.         for(i = bitmap->page_count; i < page_count; i++, vaddr+= PAGE_SIZE)
  358.         {
  359.             page = AllocPage();
  360.             if ( page == 0 )
  361.                 goto err4;
  362.             pages[i] = page;
  363.             MapPage(vaddr, page, 0x207);        //map as shared page
  364.         };
  365.  
  366.         DRM_DEBUG("%s alloc %d pages\n", __FUNCTION__,
  367.                   page_count - bitmap->page_count);
  368.  
  369.         i915_gem_object_unpin(bitmap->obj);
  370.         i915_gem_object_unbind(bitmap->obj);
  371.         bitmap->obj->base.size = size;
  372.         bitmap->obj->pages.nents = page_count;
  373.  
  374.         ret = i915_gem_object_pin(bitmap->obj, PAGE_SIZE, true,true);
  375.         if (ret)
  376.             goto err4;
  377.  
  378.         bitmap->page_count = page_count;
  379.         bitmap->gaddr  = bitmap->obj->gtt_offset;
  380.     }
  381.     else if(page_count < bitmap->page_count)
  382.     {
  383.         char *vaddr = bitmap->uaddr + PAGE_SIZE * page_count;
  384.  
  385.         i915_gem_object_unpin(bitmap->obj);
  386.         i915_gem_object_unbind(bitmap->obj);
  387.  
  388.         pages = bitmap->obj->allocated_pages;
  389.  
  390.         DRM_DEBUG("old pages %d new_pages %d vaddr %x\n",
  391.                 bitmap->page_count, page_count, vaddr);
  392.  
  393.         for(i = page_count; i < bitmap->page_count; i++, vaddr+= PAGE_SIZE)
  394.         {
  395.             MapPage(vaddr, 0, 0);        //unmap
  396.  
  397.             FreePage(pages[i]);
  398.             pages[i] = 0;
  399.         };
  400.  
  401.         DRM_DEBUG("%s release %d pages\n", __FUNCTION__,
  402.                   bitmap->page_count - page_count);
  403.  
  404.         bitmap->obj->base.size = size;
  405.         bitmap->obj->pages.nents = page_count;
  406.  
  407.         ret = i915_gem_object_pin(bitmap->obj, PAGE_SIZE, true,true);
  408.         if (ret)
  409.             goto err3;
  410.  
  411.         bitmap->page_count = page_count;
  412.         bitmap->gaddr  = bitmap->obj->gtt_offset;
  413.     };
  414.  
  415.     bitmap->width  = width;
  416.     bitmap->height = height;
  417.     bitmap->pitch  = pitch;
  418.  
  419.  
  420.     pbitmap->data  = bitmap->uaddr;
  421.     pbitmap->pitch = bitmap->pitch;
  422.  
  423.     return 0;
  424.  
  425. err4:
  426.     while (i-- > bitmap->page_count)
  427.         FreePage(pages[i]);
  428.  
  429. err3:
  430.     return -1;
  431. };
  432.  
  433.  
  434. int init_bitmaps()
  435. {
  436.     int ret;
  437.  
  438.     ret = init_hmm(&bm_mm, 1024);
  439.  
  440.     return ret;
  441. };
  442.  
  443.  
  444.  
  445. int get_driver_caps(hwcaps_t *caps)
  446. {
  447.     int ret = 0;
  448.  
  449.     switch(caps->idx)
  450.     {
  451.         case 0:
  452.             caps->opt[0] = DRIVER_CAPS_0;
  453.             caps->opt[1] = DRIVER_CAPS_1;
  454.             break;
  455.  
  456.         case 1:
  457.             caps->cap1.max_tex_width  = 4096;
  458.             caps->cap1.max_tex_height = 4096;
  459.             break;
  460.         default:
  461.             ret = 1;
  462.     };
  463.     caps->idx = 1;
  464.     return ret;
  465. }
  466.  
  467.  
  468. void __attribute__((regparm(1))) destroy_context(struct context *context)
  469. {
  470.     DRM_DEBUG("destroy context %x\n", context);
  471.  
  472.     context_map[context->slot] = NULL;
  473.  
  474.     FreeKernelSpace(context->cmd_buffer);
  475.  
  476.     mutex_lock(&main_device->struct_mutex);
  477.     drm_gem_object_unreference(&context->obj->base);
  478.     mutex_unlock(&main_device->struct_mutex);
  479.  
  480.     __DestroyObject(context);
  481. };
  482.  
  483.  
  484. #define CURRENT_TASK             (0x80003000)
  485.  
  486. struct context *get_context(struct drm_device *dev)
  487. {
  488.     struct context *context;
  489.     struct io_call_10 io_10;
  490.     int    slot = *((u8*)CURRENT_TASK);
  491.     int    ret;
  492.  
  493.     context = context_map[slot];
  494.  
  495.     if( context != NULL)
  496.         return context;
  497.  
  498.     context = CreateObject(GetPid(), sizeof(*context));
  499.  
  500.     if( context != NULL)
  501.     {
  502.         drm_i915_private_t *dev_priv = dev->dev_private;
  503.         struct drm_i915_gem_object *obj;
  504.  
  505.         obj = i915_gem_alloc_object(dev, 4096);
  506.         i915_gem_object_pin(obj, 4096, true, true);
  507.  
  508.         context->obj = obj;
  509.         context->cmd_buffer = MapIoMem((addr_t)obj->pages.page[0], 4096, PG_SW|PG_NOCACHE);
  510.         context->cmd_offset = obj->gtt_offset;
  511.  
  512.         context->header.destroy = destroy_context;
  513.         context->mask  = NULL;
  514.         context->seqno = 0;
  515.         context->slot  = slot;
  516.  
  517.         context_map[slot] = context;
  518.     };
  519.     return context;
  520. };
  521.  
  522.