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 <libdrm/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 uint64_t
  47. nouveau_screen_get_timestamp(struct pipe_screen *pscreen)
  48. {
  49.         int64_t cpu_time = os_time_get() * 1000;
  50.  
  51.         /* getparam of PTIMER_TIME takes about x10 as long (several usecs) */
  52.  
  53.         return cpu_time + nouveau_screen(pscreen)->cpu_gpu_time_delta;
  54. }
  55.  
  56. static void
  57. nouveau_screen_fence_ref(struct pipe_screen *pscreen,
  58.                          struct pipe_fence_handle **ptr,
  59.                          struct pipe_fence_handle *pfence)
  60. {
  61.         nouveau_fence_ref(nouveau_fence(pfence), (struct nouveau_fence **)ptr);
  62. }
  63.  
  64. static boolean
  65. nouveau_screen_fence_signalled(struct pipe_screen *screen,
  66.                                struct pipe_fence_handle *pfence)
  67. {
  68.         return nouveau_fence_signalled(nouveau_fence(pfence));
  69. }
  70.  
  71. static boolean
  72. nouveau_screen_fence_finish(struct pipe_screen *screen,
  73.                             struct pipe_fence_handle *pfence,
  74.                             uint64_t timeout)
  75. {
  76.         return nouveau_fence_wait(nouveau_fence(pfence));
  77. }
  78.  
  79.  
  80. struct nouveau_bo *
  81. nouveau_screen_bo_from_handle(struct pipe_screen *pscreen,
  82.                               struct winsys_handle *whandle,
  83.                               unsigned *out_stride)
  84. {
  85.         struct nouveau_device *dev = nouveau_screen(pscreen)->device;
  86.         struct nouveau_bo *bo = 0;
  87.         int ret;
  88.  
  89.         ret = nouveau_bo_name_ref(dev, whandle->handle, &bo);
  90.         if (ret) {
  91.                 debug_printf("%s: ref name 0x%08x failed with %d\n",
  92.                              __FUNCTION__, whandle->handle, ret);
  93.                 return NULL;
  94.         }
  95.  
  96.         *out_stride = whandle->stride;
  97.         return bo;
  98. }
  99.  
  100.  
  101. boolean
  102. nouveau_screen_bo_get_handle(struct pipe_screen *pscreen,
  103.                              struct nouveau_bo *bo,
  104.                              unsigned stride,
  105.                              struct winsys_handle *whandle)
  106. {
  107.         whandle->stride = stride;
  108.  
  109.         if (whandle->type == DRM_API_HANDLE_TYPE_SHARED) {
  110.                 return nouveau_bo_name_get(bo, &whandle->handle) == 0;
  111.         } else if (whandle->type == DRM_API_HANDLE_TYPE_KMS) {
  112.                 whandle->handle = bo->handle;
  113.                 return TRUE;
  114.         } else {
  115.                 return FALSE;
  116.         }
  117. }
  118.  
  119. int
  120. nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev)
  121. {
  122.         struct pipe_screen *pscreen = &screen->base;
  123.         struct nv04_fifo nv04_data = { .vram = 0xbeef0201, .gart = 0xbeef0202 };
  124.         struct nvc0_fifo nvc0_data = { };
  125.         uint64_t time;
  126.         int size, ret;
  127.         void *data;
  128.         union nouveau_bo_config mm_config;
  129.  
  130.         char *nv_dbg = getenv("NOUVEAU_MESA_DEBUG");
  131.         if (nv_dbg)
  132.            nouveau_mesa_debug = atoi(nv_dbg);
  133.  
  134.         if (dev->chipset < 0xc0) {
  135.                 data = &nv04_data;
  136.                 size = sizeof(nv04_data);
  137.         } else {
  138.                 data = &nvc0_data;
  139.                 size = sizeof(nvc0_data);
  140.         }
  141.  
  142.         ret = nouveau_object_new(&dev->object, 0, NOUVEAU_FIFO_CHANNEL_CLASS,
  143.                                  data, size, &screen->channel);
  144.         if (ret)
  145.                 return ret;
  146.         screen->device = dev;
  147.  
  148.         ret = nouveau_client_new(screen->device, &screen->client);
  149.         if (ret)
  150.                 return ret;
  151.         ret = nouveau_pushbuf_new(screen->client, screen->channel,
  152.                                   4, 512 * 1024, 1,
  153.                                   &screen->pushbuf);
  154.         if (ret)
  155.                 return ret;
  156.  
  157.         /* getting CPU time first appears to be more accurate */
  158.         screen->cpu_gpu_time_delta = os_time_get();
  159.  
  160.         ret = nouveau_getparam(dev, NOUVEAU_GETPARAM_PTIMER_TIME, &time);
  161.         if (!ret)
  162.            screen->cpu_gpu_time_delta = time - screen->cpu_gpu_time_delta * 1000;
  163.  
  164.         pscreen->get_name = nouveau_screen_get_name;
  165.         pscreen->get_vendor = nouveau_screen_get_vendor;
  166.  
  167.         pscreen->get_timestamp = nouveau_screen_get_timestamp;
  168.  
  169.         pscreen->fence_reference = nouveau_screen_fence_ref;
  170.         pscreen->fence_signalled = nouveau_screen_fence_signalled;
  171.         pscreen->fence_finish = nouveau_screen_fence_finish;
  172.  
  173.         util_format_s3tc_init();
  174.  
  175.         screen->lowmem_bindings = PIPE_BIND_GLOBAL; /* gallium limit */
  176.         screen->vidmem_bindings =
  177.                 PIPE_BIND_RENDER_TARGET | PIPE_BIND_DEPTH_STENCIL |
  178.                 PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT | PIPE_BIND_CURSOR |
  179.                 PIPE_BIND_SAMPLER_VIEW |
  180.                 PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE |
  181.                 PIPE_BIND_GLOBAL;
  182.         screen->sysmem_bindings =
  183.                 PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_STREAM_OUTPUT;
  184.  
  185.         memset(&mm_config, 0, sizeof(mm_config));
  186.  
  187.         screen->mm_GART = nouveau_mm_create(dev,
  188.                                             NOUVEAU_BO_GART | NOUVEAU_BO_MAP,
  189.                                             &mm_config);
  190.         screen->mm_VRAM = nouveau_mm_create(dev, NOUVEAU_BO_VRAM, &mm_config);
  191.         return 0;
  192. }
  193.  
  194. void
  195. nouveau_screen_fini(struct nouveau_screen *screen)
  196. {
  197.         nouveau_mm_destroy(screen->mm_GART);
  198.         nouveau_mm_destroy(screen->mm_VRAM);
  199.  
  200.         nouveau_pushbuf_del(&screen->pushbuf);
  201.  
  202.         nouveau_client_del(&screen->client);
  203.         nouveau_object_del(&screen->channel);
  204.  
  205.         nouveau_device_del(&screen->device);
  206. }
  207.