diff options
-rw-r--r-- | src/intel/isl/isl.c | 53 | ||||
-rw-r--r-- | src/intel/isl/isl.h | 13 | ||||
-rw-r--r-- | src/intel/isl/isl_surface_state.c | 37 |
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; |