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(-)
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 || -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev