Merge remote-tracking branch 'mesa-public/master' into vulkan
[mesa.git] / src / mesa / drivers / dri / i965 / intel_screen.c
index c0f5c927ed8ff306a3613dc2d0851b1653466e0a..5911b44445492ed234649dc82208a19ba5257fc4 100644 (file)
@@ -122,7 +122,7 @@ aub_dump_bmp(struct gl_context *ctx)
 {
    struct gl_framebuffer *fb = ctx->DrawBuffer;
 
-   for (int i = 0; i < fb->_NumColorDrawBuffers; i++) {
+   for (unsigned i = 0; i < fb->_NumColorDrawBuffers; i++) {
       struct intel_renderbuffer *irb =
         intel_renderbuffer(fb->_ColorDrawBuffers[i]);
 
@@ -229,6 +229,12 @@ static struct intel_image_format intel_image_formats[] = {
    { __DRI_IMAGE_FOURCC_RGB565, __DRI_IMAGE_COMPONENTS_RGB, 1,
      { { 0, 0, 0, __DRI_IMAGE_FORMAT_RGB565, 2 } } },
 
+   { __DRI_IMAGE_FOURCC_R8, __DRI_IMAGE_COMPONENTS_R, 1,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 }, } },
+
+   { __DRI_IMAGE_FOURCC_GR88, __DRI_IMAGE_COMPONENTS_RG, 1,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 }, } },
+
    { __DRI_IMAGE_FOURCC_YUV410, __DRI_IMAGE_COMPONENTS_Y_U_V, 3,
      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
        { 1, 2, 2, __DRI_IMAGE_FORMAT_R8, 1 },
@@ -1123,25 +1129,48 @@ intel_detect_swizzling(struct intel_screen *screen)
       return true;
 }
 
-static bool
+static int
 intel_detect_timestamp(struct intel_screen *screen)
 {
-   uint64_t dummy = 0;
-   int loop = 10;
+   uint64_t dummy = 0, last = 0;
+   int upper, lower, loops;
 
-   /*
-    * On 32bit systems, some old kernels trigger a hw bug resulting in the
-    * TIMESTAMP register being shifted and the low 32bits always zero. Detect
-    * this by repeating the read a few times and check the register is
-    * incrementing every 80ns as expected and not stuck on zero (as would be
-    * the case with the buggy kernel/hw.).
+   /* On 64bit systems, some old kernels trigger a hw bug resulting in the
+    * TIMESTAMP register being shifted and the low 32bits always zero.
+    *
+    * More recent kernels offer an interface to read the full 36bits
+    * everywhere.
     */
-   do {
+   if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP | 1, &dummy) == 0)
+      return 3;
+
+   /* Determine if we have a 32bit or 64bit kernel by inspecting the
+    * upper 32bits for a rapidly changing timestamp.
+    */
+   if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP, &last))
+      return 0;
+
+   upper = lower = 0;
+   for (loops = 0; loops < 10; loops++) {
+      /* The TIMESTAMP should change every 80ns, so several round trips
+       * through the kernel should be enough to advance it.
+       */
       if (drm_intel_reg_read(screen->bufmgr, TIMESTAMP, &dummy))
-        return false;
-   } while ((dummy & 0xffffffff) == 0 && --loop);
+         return 0;
+
+      upper += (dummy >> 32) != (last >> 32);
+      if (upper > 1) /* beware 32bit counter overflow */
+         return 2; /* upper dword holds the low 32bits of the timestamp */
+
+      lower += (dummy & 0xffffffff) != (last & 0xffffffff);
+      if (lower > 1)
+         return 1; /* timestamp is unshifted */
 
-   return loop > 0;
+      last = dummy;
+   }
+
+   /* No advancement? No timestamp! */
+   return 0;
 }
 
 /**
@@ -1190,7 +1219,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
    __DRIconfig **configs = NULL;
 
    /* Generate singlesample configs without accumulation buffer. */
-   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+   for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
       __DRIconfig **new_configs;
       int num_depth_stencil_bits = 2;
 
@@ -1227,7 +1256,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
    /* Generate the minimum possible set of configs that include an
     * accumulation buffer.
     */
-   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+   for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
       __DRIconfig **new_configs;
 
       if (formats[i] == MESA_FORMAT_B5G6R5_UNORM) {
@@ -1259,7 +1288,7 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
     * supported.  Singlebuffer configs are not supported because no one wants
     * them.
     */
-   for (int i = 0; i < ARRAY_SIZE(formats); i++) {
+   for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
       if (devinfo->gen < 6)
          break;
 
@@ -1330,11 +1359,6 @@ set_max_gl_versions(struct intel_screen *screen)
    }
 }
 
-/* drop when libdrm 2.4.61 is released */
-#ifndef I915_PARAM_REVISION
-#define I915_PARAM_REVISION 32
-#endif
-
 static int
 brw_get_revision(int fd)
 {
@@ -1353,6 +1377,11 @@ brw_get_revision(int fd)
    return revision;
 }
 
+/* Drop when RS headers get pulled to libdrm */
+#ifndef I915_PARAM_HAS_RESOURCE_STREAMER
+#define I915_PARAM_HAS_RESOURCE_STREAMER 36
+#endif
+
 /**
  * This is the driver specific part of the createNewScreen entry point.
  * Called when using DRI2.
@@ -1445,9 +1474,90 @@ __DRIconfig **intelInitScreen2(__DRIscreen *psp)
    intelScreen->compiler = brw_compiler_create(intelScreen,
                                                intelScreen->devinfo);
 
+   if (intelScreen->devinfo->has_resource_streamer) {
+      int val = -1;
+      getparam.param = I915_PARAM_HAS_RESOURCE_STREAMER;
+      getparam.value = &val;
+
+      drmIoctl(psp->fd, DRM_IOCTL_I915_GETPARAM, &getparam);
+      intelScreen->has_resource_streamer = val > 0;
+   }
+
    return (const __DRIconfig**) intel_screen_make_configs(psp);
 }
 
+struct intel_screen *
+intel_screen_create(int fd)
+{
+   __DRIscreen *psp;
+   __DRIconfig **configs;
+   int i;
+
+   psp = malloc(sizeof(*psp));
+   if (psp == NULL)
+      return NULL;
+
+   psp->image.loader = (void *) 1; /* Don't complain about this being NULL */
+   psp->fd = fd;
+   psp->dri2.useInvalidate = (void *) 1;
+
+   configs = (__DRIconfig **) intelInitScreen2(psp);
+   for (i = 0; configs[i]; i++)
+      free(configs[i]);
+   free(configs);
+
+   return psp->driverPrivate;
+}
+
+void
+intel_screen_destroy(struct intel_screen *screen)
+{
+   __DRIscreen *psp;
+
+   psp = screen->driScrnPriv;
+   intelDestroyScreen(screen->driScrnPriv);
+   free(psp);
+}
+
+
+struct brw_context *
+intel_context_create(struct intel_screen *screen)
+{
+   __DRIcontext *driContextPriv;
+   struct brw_context *brw;
+   unsigned error;
+
+   driContextPriv = malloc(sizeof(*driContextPriv));
+   if (driContextPriv == NULL)
+      return NULL;
+
+   driContextPriv->driScreenPriv = screen->driScrnPriv;
+
+   brwCreateContext(API_OPENGL_CORE,
+                    NULL, /* visual */
+                    driContextPriv,
+                    3, 0,
+                    0, /* flags */
+                    false, /* notify_reset */
+                    &error,
+                    NULL);
+
+   brw = driContextPriv->driverPrivate;
+   brw->ctx.FirstTimeCurrent = false;
+
+   return driContextPriv->driverPrivate;
+}
+
+void
+intel_context_destroy(struct brw_context *brw)
+{
+   __DRIcontext *driContextPriv;
+
+   driContextPriv = brw->driContext;
+   intelDestroyContext(driContextPriv);
+   free(driContextPriv);
+}
+
 struct intel_buffer {
    __DRIbuffer base;
    drm_intel_bo *bo;