Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. #include "pipe/p_defines.h"
  2. #include "pipe/p_screen.h"
  3. #include "pipe/p_state.h"
  4.  
  5. #include "util/u_memory.h"
  6. #include "util/u_inlines.h"
  7. #include "util/u_format.h"
  8. #include "util/u_format_s3tc.h"
  9. #include "util/u_string.h"
  10.  
  11. #include "os/os_time.h"
  12.  
  13. #include <stdio.h>
  14. #include <errno.h>
  15. #include <stdlib.h>
  16.  
  17. #include <nouveau_drm.h>
  18.  
  19. #include "nouveau_winsys.h"
  20. #include "nouveau_screen.h"
  21. #include "nouveau_fence.h"
  22. #include "nouveau_mm.h"
  23. #include "nouveau_buffer.h"
  24.  
  25. /* XXX this should go away */
  26. #include "state_tracker/drm_driver.h"
  27.  
  28. int nouveau_mesa_debug = 0;
  29.  
  30. static const char *
  31. nouveau_screen_get_name(struct pipe_screen *pscreen)
  32. {
  33.         struct nouveau_device *dev = nouveau_screen(pscreen)->device;
  34.         static char buffer[128];
  35.  
  36.         util_snprintf(buffer, sizeof(buffer), "NV%02X", dev->chipset);
  37.         return buffer;
  38. }
  39.  
  40. static const char *
  41. nouveau_screen_get_vendor(struct pipe_screen *pscreen)
  42. {
  43.         return "nouveau";
  44. }
  45.  
  46. static const char *
  47. nouveau_screen_get_device_vendor(struct pipe_screen *pscreen)
  48. {
  49.         return "NVIDIA";
  50. }
  51.  
  52. static uint64_t
  53. nouveau_screen_get_timestamp(struct pipe_screen *pscreen)
  54. {
  55.         int64_t cpu_time = os_time_get() * 1000;
  56.  
  57.         /* getparam of PTIMER_TIME takes about x10 as long (several usecs) */
  58.  
  59.         return cpu_time + nouveau_screen(pscreen)->cpu_gpu_time_delta;
  60. }
  61.  
  62. static void
  63. nouveau_screen_fence_ref(struct pipe_screen *pscreen,
  64.                          struct pipe_fence_handle **ptr,
  65.                          struct pipe_fence_handle *pfence)
  66. {
  67.         nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr);
  68. }
  69.  
  70. static boolean
  71. nouveau_screen_fence_signalled(struct pipe_screen *screen,
  72.                                struct pipe_fence_handle *pfence)
  73. {
  74.         return nouveau_fence_signalled(nouveau_fence(pfence));
  75. }
  76.  
  77. static boolean
  78. nouveau_screen_fence_finish(struct pipe_screen *screen,
  79.                             struct pipe_fence_handle *pfence,
  80.                             uint64_t timeout)
  81. {
  82.         return nouveau_fence_wait(nouveau_fence(pfence));
  83. }
  84.  
  85.  
  86. struct nouveau_bo *
  87. nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
  88.                               struct winsys_handle *whandle,
  89.                               unsigned *out_stride)
  90. {
  91.         struct nouveau_device *dev = nouveau_screen(pscreen)->device;
  92.         struct nouveau_bo *bo = 0;
  93.         int ret;
  94.  
  95.         if (whandle->type != DRM_API_HANDLE_TYPE_SHARED &&
  96.             whandle->type != DRM_API_HANDLE_TYPE_FD) {
  97.                 debug_printf("%s: attempt to import unsupported handle type %d\n",
  98.                              __FUNCTION__, whandle->type);
  99.                 return NULL;
  100.         }
  101.  
  102.         if (whandle->type == DRM_API_HANDLE_TYPE_SHARED)
  103.                 ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
  104.         else
  105.                 ret = nouveau_bo_prime_handle_ref(dev, whandle->handle, &bo);
  106.  
  107.         if (ret) {
  108.                 debug_printf("%s: ref name 0x%08x failed with %d\n",
  109.                              __FUNCTION__, whandle->handle, ret);
  110.                 return NULL;
  111.         }
  112.  
  113.         *out_stride = whandle->stride;
  114.         return bo;
  115. }
  116.  
  117.  
  118. boolean
  119. nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
  120.                              struct nouveau_bo *bo,
  121.                              unsigned stride,
  122.                              struct winsys_handle *whandle)
  123. {
  124.         whandle->stride = stride;
  125.  
  126.         if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
  127.                 return nouveau_bo_name_get(bo, &whandle->handle) == 0;
  128.         } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
  129.                 whandle->handle = bo->handle;
  130.                 return TRUE;
  131.         } else if (whandle->type == DRM_API_HANDLE_TYPE_FD) {
  132.                 return nouveau_bo_set_prime(bo, (int *)&whandle->handle) == 0;
  133.         } else {
  134.                 return FALSE;
  135.         }
  136. }
  137.  
  138. int
  139. nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
  140. {
  141.         struct pipe_screen *pscreen = &screen->base;
  142.         struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
  143.         struct nvc0_fifo nvc0_data = { };
  144.         uint64_t time;
  145.         int size, ret;
  146.         void *data;
  147.         union nouveau_bo_config mm_config;
  148.  
  149.         char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG");
  150.         if (nv_dbg)
  151.            nouveau_mesa_debug = atoi(nv_dbg);
  152.  
  153.         /*
  154.          * this is initialized to 1 in nouveau_drm_screen_create after screen
  155.          * is fully constructed and added to the global screen list.
  156.          */
  157.         screen->refcount = -1;
  158.  
  159.         if (dev->chipset < 0xc0) {
  160.                 data = &nv04_data;
  161.                 size = sizeof(nv04_data);
  162.         } else {
  163.                 data = &nvc0_data;
  164.                 size = sizeof(nvc0_data);
  165.         }
  166.  
  167.         ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
  168.                                  data, size, &screen->channel);
  169.         if (ret)
  170.                 return ret;
  171.         screen->device = dev;
  172.  
  173.         ret = nouveau_client_new(screen->device, &screen->client);
  174.         if (ret)
  175.                 return ret;
  176.         ret = nouveau_pushbuf_new(screen->client, screen->channel,
  177.                                   4, 512 * 1024, 1,
  178.                                   &screen->pushbuf);
  179.         if (ret)
  180.                 return ret;
  181.  
  182.         /* getting CPU time first appears to be more accurate */
  183.         screen->cpu_gpu_time_delta = os_time_get();
  184.  
  185.         ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_PTIMER_TIME, &time);
  186.         if (!ret)
  187.            screen->cpu_gpu_time_delta = time - screen->cpu_gpu_time_delta * 1000;
  188.  
  189.         pscreen->get_name = nouveau_screen_get_name;
  190.         pscreen->get_vendor = nouveau_screen_get_vendor;
  191.         pscreen->get_device_vendor = nouveau_screen_get_device_vendor;
  192.  
  193.         pscreen->get_timestamp = nouveau_screen_get_timestamp;
  194.  
  195.         pscreen->fence_reference = nouveau_screen_fence_ref;
  196.         pscreen->fence_signalled = nouveau_screen_fence_signalled;
  197.         pscreen->fence_finish = nouveau_screen_fence_finish;
  198.  
  199.         util_format_s3tc_init();
  200.  
  201.         screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
  202.         screen->vidmem_bindings =
  203.                 PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
  204.                 PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT |
  205.                 PIPE_BIND_CURSOR |
  206.                 PIPE_BIND_SAMPLER_VIEW |
  207.                 PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE |
  208.                 PIPE_BIND_GLOBAL;
  209.         screen->sysmem_bindings =
  210.                 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT |
  211.                 PIPE_BIND_COMMAND_ARGS_BUFFER;
  212.  
  213.         memset(&mm_config, 0, sizeof(mm_config));
  214.  
  215.         screen->mm_GART = nouveau_mm_create(dev,
  216.                                             NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
  217.                                             &mm_config);
  218.         screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
  219.         return 0;
  220. }
  221.  
  222. void
  223. nouveau_screen_fini(struct nouveau_screen *screen)
  224. {
  225.         nouveau_mm_destroy(screen->mm_GART);
  226.         nouveau_mm_destroy(screen->mm_VRAM);
  227.  
  228.         nouveau_pushbuf_del(&screen->pushbuf);
  229.  
  230.         nouveau_client_del(&screen->client);
  231.         nouveau_object_del(&screen->channel);
  232.  
  233.         nouveau_device_del(&screen->device);
  234. }
  235.