summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/intel/isl/isl.c53
-rw-r--r--src/intel/isl/isl.h13
-rw-r--r--src/intel/isl/isl_surface_state.c37
3 files changed, 71 insertions, 32 deletions
diff --git a/src/intel/isl/isl.c b/src/intel/isl/isl.c
index 875c691b43e..1b270c1d715 100644
--- a/src/intel/isl/isl.c
+++ b/src/intel/isl/isl.c
@@ -2322,3 +2322,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 c50b78d4701..fc1ff5f3f88 100644
--- a/src/intel/isl/isl.h
+++ b/src/intel/isl/isl.h
@@ -1731,6 +1731,19 @@ bool isl_color_value_is_zero(union isl_color_value value,
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 bff9693f02d..f181c3dfb2f 100644
--- a/src/intel/isl/isl_surface_state.c
+++ b/src/intel/isl/isl_surface_state.c
@@ -470,42 +470,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;