i965/miptree: Replace is_lossless_compressed with mt->aux_usage checks
[mesa.git] / src / mesa / drivers / dri / i965 / intel_screen.c
index 83b8a24509a440c9552b12712dac50e216f5454d..68026d991be26a122c02018fbd740e86d3b2d884 100644 (file)
@@ -37,6 +37,7 @@
 #include "swrast/s_renderbuffer.h"
 #include "util/ralloc.h"
 #include "brw_defines.h"
+#include "brw_state.h"
 #include "compiler/nir/nir.h"
 
 #include "utils.h"
@@ -278,31 +279,33 @@ static struct intel_image_format intel_image_formats[] = {
      { { 0, 0, 0, __DRI_IMAGE_FORMAT_R8, 1 },
        { 1, 1, 0, __DRI_IMAGE_FORMAT_GR88, 2 } } },
 
-   /* For YUYV buffers, we set up two overlapping DRI images and treat
-    * them as planar buffers in the compositors.  Plane 0 is GR88 and
-    * samples YU or YV pairs and places Y into the R component, while
-    * plane 1 is ARGB and samples YUYV clusters and places pairs and
-    * places U into the G component and V into A.  This lets the
-    * texture sampler interpolate the Y components correctly when
-    * sampling from plane 0, and interpolate U and V correctly when
-    * sampling from plane 1. */
+   /* For YUYV and UYVY buffers, we set up two overlapping DRI images
+    * and treat them as planar buffers in the compositors.
+    * Plane 0 is GR88 and samples YU or YV pairs and places Y into
+    * the R component, while plane 1 is ARGB/ABGR and samples YUYV/UYVY
+    * clusters and places pairs and places U into the G component and
+    * V into A.  This lets the texture sampler interpolate the Y
+    * components correctly when sampling from plane 0, and interpolate
+    * U and V correctly when sampling from plane 1. */
    { __DRI_IMAGE_FOURCC_YUYV, __DRI_IMAGE_COMPONENTS_Y_XUXV, 2,
      { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
-       { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } }
+       { 0, 1, 0, __DRI_IMAGE_FORMAT_ARGB8888, 4 } } },
+   { __DRI_IMAGE_FOURCC_UYVY, __DRI_IMAGE_COMPONENTS_Y_UXVX, 2,
+     { { 0, 0, 0, __DRI_IMAGE_FORMAT_GR88, 2 },
+       { 0, 1, 0, __DRI_IMAGE_FORMAT_ABGR8888, 4 } } }
 };
 
 static const struct {
    uint32_t tiling;
    uint64_t modifier;
    unsigned since_gen;
-   unsigned height_align;
 } tiling_modifier_map[] = {
    { .tiling = I915_TILING_NONE, .modifier = DRM_FORMAT_MOD_LINEAR,
-     .since_gen = 1, .height_align = 1 },
+     .since_gen = 1 },
    { .tiling = I915_TILING_X, .modifier = I915_FORMAT_MOD_X_TILED,
-     .since_gen = 1, .height_align = 8 },
+     .since_gen = 1 },
    { .tiling = I915_TILING_Y, .modifier = I915_FORMAT_MOD_Y_TILED,
-     .since_gen = 6, .height_align = 32 },
+     .since_gen = 6 },
 };
 
 static bool
@@ -318,19 +321,6 @@ modifier_is_supported(uint64_t modifier)
    return false;
 }
 
-static uint32_t
-modifier_to_tiling(uint64_t modifier)
-{
-   int i;
-
-   for (i = 0; i < ARRAY_SIZE(tiling_modifier_map); i++) {
-      if (tiling_modifier_map[i].modifier == modifier)
-         return tiling_modifier_map[i].tiling;
-   }
-
-   unreachable("modifier_to_tiling should only receive known modifiers");
-}
-
 static uint64_t
 tiling_to_modifier(uint32_t tiling)
 {
@@ -344,19 +334,6 @@ tiling_to_modifier(uint32_t tiling)
    unreachable("tiling_to_modifier received unknown tiling mode");
 }
 
-static unsigned
-get_tiled_height(uint64_t modifier, unsigned height)
-{
-   int i;
-
-   for (i = 0; i < ARRAY_SIZE(tiling_modifier_map); i++) {
-      if (tiling_modifier_map[i].modifier == modifier)
-         return ALIGN(height, tiling_modifier_map[i].height_align);
-   }
-
-   unreachable("get_tiled_height received unknown tiling mode");
-}
-
 static void
 intel_image_warn_if_unaligned(__DRIimage *image, const char *func)
 {
@@ -638,10 +615,8 @@ intel_create_image_common(__DRIscreen *dri_screen,
 {
    __DRIimage *image;
    struct intel_screen *screen = dri_screen->driverPrivate;
-   uint32_t tiling;
    uint64_t modifier = DRM_FORMAT_MOD_INVALID;
-   unsigned tiled_height;
-   int cpp;
+   bool ok;
 
    /* Callers of this may specify a modifier, or a dri usage, but not both. The
     * newer modifier interface deprecates the older usage flags newer modifier
@@ -671,23 +646,44 @@ intel_create_image_common(__DRIscreen *dri_screen,
          modifier = I915_FORMAT_MOD_X_TILED;
       }
    }
-   tiling = modifier_to_tiling(modifier);
-   tiled_height = get_tiled_height(modifier, height);
 
    image = intel_allocate_image(screen, format, loaderPrivate);
    if (image == NULL)
       return NULL;
 
-   cpp = _mesa_get_format_bytes(image->format);
-   image->bo = brw_bo_alloc_tiled_2d(screen->bufmgr, "image",
-                                     width, tiled_height, cpp, tiling,
-                                     &image->pitch, 0);
+   const struct isl_drm_modifier_info *mod_info =
+      isl_drm_modifier_get_info(modifier);
+
+   struct isl_surf surf;
+   ok = isl_surf_init(&screen->isl_dev, &surf,
+                      .dim = ISL_SURF_DIM_2D,
+                      .format = brw_isl_format_for_mesa_format(image->format),
+                      .width = width,
+                      .height = height,
+                      .depth = 1,
+                      .levels = 1,
+                      .array_len = 1,
+                      .samples = 1,
+                      .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT |
+                               ISL_SURF_USAGE_TEXTURE_BIT |
+                               ISL_SURF_USAGE_STORAGE_BIT,
+                      .tiling_flags = (1 << mod_info->tiling));
+   assert(ok);
+   if (!ok) {
+      free(image);
+      return NULL;
+   }
+
+   image->bo = brw_bo_alloc_tiled(screen->bufmgr, "image", surf.size,
+                                  isl_tiling_to_i915_tiling(mod_info->tiling),
+                                  surf.row_pitch, 0);
    if (image->bo == NULL) {
       free(image);
       return NULL;
    }
    image->width = width;
    image->height = height;
+   image->pitch = surf.row_pitch;
    image->modifier = modifier;
 
    return image;
@@ -850,8 +846,8 @@ intel_create_image_from_fds_common(__DRIscreen *dri_screen,
    struct intel_screen *screen = dri_screen->driverPrivate;
    struct intel_image_format *f;
    __DRIimage *image;
-   unsigned tiled_height;
    int i, index;
+   bool ok;
 
    if (fds == NULL || num_fds < 1)
       return NULL;
@@ -902,7 +898,6 @@ intel_create_image_from_fds_common(__DRIscreen *dri_screen,
       image->modifier = modifier;
    else
       image->modifier = tiling_to_modifier(image->bo->tiling_mode);
-   tiled_height = get_tiled_height(image->modifier, height);
 
    int size = 0;
    for (i = 0; i < f->nplanes; i++) {
@@ -910,8 +905,33 @@ intel_create_image_from_fds_common(__DRIscreen *dri_screen,
       image->offsets[index] = offsets[index];
       image->strides[index] = strides[index];
 
-      const int plane_height = tiled_height >> f->planes[i].height_shift;
-      const int end = offsets[index] + plane_height * strides[index];
+      const struct isl_drm_modifier_info *mod_info =
+         isl_drm_modifier_get_info(image->modifier);
+
+      mesa_format format = driImageFormatToGLFormat(f->planes[i].dri_format);
+
+      struct isl_surf surf;
+      ok = isl_surf_init(&screen->isl_dev, &surf,
+                         .dim = ISL_SURF_DIM_2D,
+                         .format = brw_isl_format_for_mesa_format(format),
+                         .width = image->width >> f->planes[i].width_shift,
+                         .height = image->height >> f->planes[i].height_shift,
+                         .depth = 1,
+                         .levels = 1,
+                         .array_len = 1,
+                         .samples = 1,
+                         .row_pitch = strides[index],
+                         .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT |
+                                  ISL_SURF_USAGE_TEXTURE_BIT |
+                                  ISL_SURF_USAGE_STORAGE_BIT,
+                         .tiling_flags = (1 << mod_info->tiling));
+      if (!ok) {
+         brw_bo_unreference(image->bo);
+         free(image);
+         return NULL;
+      }
+
+      const int end = offsets[index] + surf.size;
       if (size < end)
          size = end;
    }
@@ -1254,6 +1274,7 @@ static const __DRIextension *screenExtensions[] = {
     &intelImageExtension.base,
     &intelRendererQueryExtension.base,
     &dri2ConfigQueryExtension.base,
+    &dri2NoErrorExtension.base,
     NULL
 };
 
@@ -1265,6 +1286,7 @@ static const __DRIextension *intelRobustScreenExtensions[] = {
     &intelRendererQueryExtension.base,
     &dri2ConfigQueryExtension.base,
     &dri2Robustness.base,
+    &dri2NoErrorExtension.base,
     NULL
 };
 
@@ -1367,11 +1389,11 @@ intelCreateBuffer(__DRIscreen *dri_screen,
    }
 
    /* setup the hardware-based renderbuffers */
-   rb = intel_create_winsys_renderbuffer(rgbFormat, num_samples);
+   rb = intel_create_winsys_renderbuffer(screen, rgbFormat, num_samples);
    _mesa_attach_and_own_rb(fb, BUFFER_FRONT_LEFT, &rb->Base.Base);
 
    if (mesaVis->doubleBufferMode) {
-      rb = intel_create_winsys_renderbuffer(rgbFormat, num_samples);
+      rb = intel_create_winsys_renderbuffer(screen, rgbFormat, num_samples);
       _mesa_attach_and_own_rb(fb, BUFFER_BACK_LEFT, &rb->Base.Base);
    }
 
@@ -1384,10 +1406,11 @@ intelCreateBuffer(__DRIscreen *dri_screen,
       assert(mesaVis->stencilBits == 8);
 
       if (screen->devinfo.has_hiz_and_separate_stencil) {
-         rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_X8_UINT,
+         rb = intel_create_private_renderbuffer(screen,
+                                                MESA_FORMAT_Z24_UNORM_X8_UINT,
                                                 num_samples);
          _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, &rb->Base.Base);
-         rb = intel_create_private_renderbuffer(MESA_FORMAT_S_UINT8,
+         rb = intel_create_private_renderbuffer(screen, MESA_FORMAT_S_UINT8,
                                                 num_samples);
          _mesa_attach_and_own_rb(fb, BUFFER_STENCIL, &rb->Base.Base);
       } else {
@@ -1395,7 +1418,8 @@ intelCreateBuffer(__DRIscreen *dri_screen,
           * Use combined depth/stencil. Note that the renderbuffer is
           * attached to two attachment points.
           */
-         rb = intel_create_private_renderbuffer(MESA_FORMAT_Z24_UNORM_S8_UINT,
+         rb = intel_create_private_renderbuffer(screen,
+                                                MESA_FORMAT_Z24_UNORM_S8_UINT,
                                                 num_samples);
          _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, &rb->Base.Base);
          _mesa_attach_and_reference_rb(fb, BUFFER_STENCIL, &rb->Base.Base);
@@ -1403,7 +1427,7 @@ intelCreateBuffer(__DRIscreen *dri_screen,
    }
    else if (mesaVis->depthBits == 16) {
       assert(mesaVis->stencilBits == 0);
-      rb = intel_create_private_renderbuffer(MESA_FORMAT_Z_UNORM16,
+      rb = intel_create_private_renderbuffer(screen, MESA_FORMAT_Z_UNORM16,
                                              num_samples);
       _mesa_attach_and_own_rb(fb, BUFFER_DEPTH, &rb->Base.Base);
    }
@@ -1715,7 +1739,28 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
    static const mesa_format formats[] = {
       MESA_FORMAT_B5G6R5_UNORM,
       MESA_FORMAT_B8G8R8A8_UNORM,
-      MESA_FORMAT_B8G8R8X8_UNORM
+      MESA_FORMAT_B8G8R8X8_UNORM,
+
+      /* The 32-bit RGBA format must not precede the 32-bit BGRA format.
+       * Likewise for RGBX and BGRX.  Otherwise, the GLX client and the GLX
+       * server may disagree on which format the GLXFBConfig represents,
+       * resulting in swapped color channels.
+       *
+       * The problem, as of 2017-05-30:
+       * When matching a GLXFBConfig to a __DRIconfig, GLX ignores the channel
+       * order and chooses the first __DRIconfig with the expected channel
+       * sizes. Specifically, GLX compares the GLXFBConfig's and __DRIconfig's
+       * __DRI_ATTRIB_{CHANNEL}_SIZE but ignores __DRI_ATTRIB_{CHANNEL}_MASK.
+       *
+       * EGL does not suffer from this problem. It correctly compares the
+       * channel masks when matching EGLConfig to __DRIconfig.
+       */
+
+      /* Required by Android, for HAL_PIXEL_FORMAT_RGBA_8888. */
+      MESA_FORMAT_R8G8B8A8_UNORM,
+
+      /* Required by Android, for HAL_PIXEL_FORMAT_RGBX_8888. */
+      MESA_FORMAT_R8G8B8X8_UNORM,
    };
 
    /* GLX_SWAP_COPY_OML is not supported due to page flipping. */
@@ -1983,7 +2028,7 @@ parse_devid_override(const char *devid_override)
          return name_map[i].pci_id;
    }
 
-   return strtod(devid_override, NULL);
+   return strtol(devid_override, NULL, 0);
 }
 
 /**
@@ -2095,6 +2140,9 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
    screen->hw_has_swizzling = intel_detect_swizzling(screen);
    screen->hw_has_timestamp = intel_detect_timestamp(screen);
 
+   isl_device_init(&screen->isl_dev, &screen->devinfo,
+                   screen->hw_has_swizzling);
+
    /* GENs prior to 8 do not support EU/Subslice info */
    if (devinfo->gen >= 8) {
       intel_detect_sseu(screen);
@@ -2281,11 +2329,14 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
    screen->compiler = brw_compiler_create(screen, devinfo);
    screen->compiler->shader_debug_log = shader_debug_log_mesa;
    screen->compiler->shader_perf_log = shader_perf_log_mesa;
+   screen->compiler->constant_buffer_0_is_relative = devinfo->gen < 8;
    screen->program_id = 1;
 
    screen->has_exec_fence =
      intel_get_boolean(screen, I915_PARAM_HAS_EXEC_FENCE);
 
+   intel_screen_init_surface_formats(screen);
+
    return (const __DRIconfig**) intel_screen_make_configs(dri_screen);
 }