[03/29] intel/isl: Add an isl_swizzle_supports_rendering helper

Submitted by Jason Ekstrand on Jan. 27, 2018, 1:59 a.m.

Details

Message ID 1517018398-30701-4-git-send-email-jason.ekstrand@intel.com
State New
Headers show
Series "blorp: Add support for more formats" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Jason Ekstrand Jan. 27, 2018, 1:59 a.m.
This helper encodes more details, specifically about Haswell, than the
previous asserts in isl_surface_state.c.
---
 src/intel/isl/isl.c                              | 53 ++++++++++++++++++++++++
 src/intel/isl/isl.h                              | 13 ++++++
 src/intel/isl/isl_surface_state.c                | 37 +++--------------
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |  2 +-
 4 files changed, 72 insertions(+), 33 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
index 59f512f..4133b53 100644
--- a/src/intel/isl/isl.c
+++ b/src/intel/isl/isl.c
@@ -2291,3 +2291,56 @@  isl_surf_get_depth_format(const struct isl_device *dev,
       return 5; /* D16_UNORM */
    }
 }
+
+bool
+isl_swizzle_supports_rendering(const struct gen_device_info *devinfo,
+                               struct isl_swizzle swizzle)
+{
+   if (devinfo->is_haswell) {
+      /* From the Haswell PRM,
+       * RENDER_SURFACE_STATE::Shader Channel Select Red
+       *
+       *    "The Shader channel selects also define which shader channels are
+       *    written to which surface channel. If the Shader channel select is
+       *    SCS_ZERO or SCS_ONE then it is not written to the surface. If the
+       *    shader channel select is SCS_RED it is written to the surface red
+       *    channel and so on. If more than one shader channel select is set
+       *    to the same surface channel only the first shader channel in RGBA
+       *    order will be written."
+       */
+      return true;
+   } else if (devinfo->gen <= 7) {
+      /* Ivy Bridge and early doesn't have any swizzling */
+      return isl_swizzle_is_identity(swizzle);
+   } else {
+      /* From the Sky Lake PRM Vol. 2d,
+       * RENDER_SURFACE_STATE::Shader Channel Select Red
+       *
+       *    "For Render Target, Red, Green and Blue Shader Channel Selects
+       *    MUST be such that only valid components can be swapped i.e. only
+       *    change the order of components in the pixel. Any other values for
+       *    these Shader Channel Select fields are not valid for Render
+       *    Targets. This also means that there MUST not be multiple shader
+       *    channels mapped to the same RT channel."
+       *
+       * From the Sky Lake PRM Vol. 2d,
+       * RENDER_SURFACE_STATE::Shader Channel Select Alpha
+       *
+       *    "For Render Target, this field MUST be programmed to
+       *    value = SCS_ALPHA."
+       */
+      return (swizzle.r == ISL_CHANNEL_SELECT_RED ||
+              swizzle.r == ISL_CHANNEL_SELECT_GREEN ||
+              swizzle.r == ISL_CHANNEL_SELECT_BLUE) &&
+             (swizzle.g == ISL_CHANNEL_SELECT_RED ||
+              swizzle.g == ISL_CHANNEL_SELECT_GREEN ||
+              swizzle.g == ISL_CHANNEL_SELECT_BLUE) &&
+             (swizzle.b == ISL_CHANNEL_SELECT_RED ||
+              swizzle.b == ISL_CHANNEL_SELECT_GREEN ||
+              swizzle.b == ISL_CHANNEL_SELECT_BLUE) &&
+             swizzle.r != swizzle.g &&
+             swizzle.r != swizzle.b &&
+             swizzle.g != swizzle.b &&
+             swizzle.a == ISL_CHANNEL_SELECT_ALPHA;
+   }
+}
diff --git a/src/intel/isl/isl.h b/src/intel/isl/isl.h
index e3acb0e..a15ba8a 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -1671,6 +1671,19 @@  isl_extent4d(uint32_t width, uint32_t height, uint32_t depth,
 bool isl_color_value_is_zero_one(union isl_color_value value,
                                  enum isl_format format);
 
+static inline bool
+isl_swizzle_is_identity(struct isl_swizzle swizzle)
+{
+   return swizzle.r == ISL_CHANNEL_SELECT_RED &&
+          swizzle.g == ISL_CHANNEL_SELECT_GREEN &&
+          swizzle.b == ISL_CHANNEL_SELECT_BLUE &&
+          swizzle.a == ISL_CHANNEL_SELECT_ALPHA;
+}
+
+bool
+isl_swizzle_supports_rendering(const struct gen_device_info *devinfo,
+                               struct isl_swizzle swizzle);
+
 #define isl_surf_init(dev, surf, ...) \
    isl_surf_init_s((dev), (surf), \
                    &(struct isl_surf_init_info) {  __VA_ARGS__ });
diff --git a/src/intel/isl/isl_surface_state.c b/src/intel/isl/isl_surface_state.c
index bfb27fa..3e8be8c 100644
--- a/src/intel/isl/isl_surface_state.c
+++ b/src/intel/isl/isl_surface_state.c
@@ -468,42 +468,15 @@  isl_genX(surf_fill_state_s)(const struct isl_device *dev, void *state,
 #endif
 
 #if (GEN_GEN >= 8 || GEN_IS_HASWELL)
-   if (info->view->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) {
-      /* From the Sky Lake PRM Vol. 2d,
-       * RENDER_SURFACE_STATE::Shader Channel Select Red
-       *
-       *    "For Render Target, Red, Green and Blue Shader Channel Selects
-       *    MUST be such that only valid components can be swapped i.e. only
-       *    change the order of components in the pixel. Any other values for
-       *    these Shader Channel Select fields are not valid for Render
-       *    Targets. This also means that there MUST not be multiple shader
-       *    channels mapped to the same RT channel."
-       */
-      assert(info->view->swizzle.r == ISL_CHANNEL_SELECT_RED ||
-             info->view->swizzle.r == ISL_CHANNEL_SELECT_GREEN ||
-             info->view->swizzle.r == ISL_CHANNEL_SELECT_BLUE);
-      assert(info->view->swizzle.g == ISL_CHANNEL_SELECT_RED ||
-             info->view->swizzle.g == ISL_CHANNEL_SELECT_GREEN ||
-             info->view->swizzle.g == ISL_CHANNEL_SELECT_BLUE);
-      assert(info->view->swizzle.b == ISL_CHANNEL_SELECT_RED ||
-             info->view->swizzle.b == ISL_CHANNEL_SELECT_GREEN ||
-             info->view->swizzle.b == ISL_CHANNEL_SELECT_BLUE);
-      assert(info->view->swizzle.r != info->view->swizzle.g);
-      assert(info->view->swizzle.r != info->view->swizzle.b);
-      assert(info->view->swizzle.g != info->view->swizzle.b);
-
-      /* From the Sky Lake PRM Vol. 2d,
-       * RENDER_SURFACE_STATE::Shader Channel Select Alpha
-       *
-       *    "For Render Target, this field MUST be programmed to
-       *    value = SCS_ALPHA."
-       */
-      assert(info->view->swizzle.a == ISL_CHANNEL_SELECT_ALPHA);
-   }
+   if (info->view->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT)
+      assert(isl_swizzle_supports_rendering(dev->info, info->view->swizzle));
+
    s.ShaderChannelSelectRed = (enum GENX(ShaderChannelSelect)) info->view->swizzle.r;
    s.ShaderChannelSelectGreen = (enum GENX(ShaderChannelSelect)) info->view->swizzle.g;
    s.ShaderChannelSelectBlue = (enum GENX(ShaderChannelSelect)) info->view->swizzle.b;
    s.ShaderChannelSelectAlpha = (enum GENX(ShaderChannelSelect)) info->view->swizzle.a;
+#else
+   assert(isl_swizzle_is_identity(info->view->swizzle));
 #endif
 
    s.SurfaceBaseAddress = info->address;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 39985f0..3c28920 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -562,7 +562,7 @@  static void brw_update_texture_surface(struct gl_context *ctx,
       /* On Ivy Bridge and earlier, we handle texture swizzle with shader
        * code.  The actual surface swizzle should be identity.
        */
-      if (brw->gen <= 7 && !brw->is_haswell)
+      if (devinfo->gen <= 7 && !devinfo->is_haswell)
          view.swizzle = ISL_SWIZZLE_IDENTITY;
 
       if (obj->Target == GL_TEXTURE_CUBE_MAP ||