diff --git a/src/panfrost/lib/pan_shader.h b/src/panfrost/lib/pan_shader.h index bd10b00cfb0..96a52cad2d1 100644 --- a/src/panfrost/lib/pan_shader.h +++ b/src/panfrost/lib/pan_shader.h @@ -58,6 +58,72 @@ pan_shader_stage(const struct pan_shader_info *info) } #endif +#if PAN_ARCH >= 7 +static inline enum mali_shader_register_allocation +pan_register_allocation(unsigned work_reg_count) +{ + return (work_reg_count <= 32) ? + MALI_SHADER_REGISTER_ALLOCATION_32_PER_THREAD : + MALI_SHADER_REGISTER_ALLOCATION_64_PER_THREAD; +} +#endif + +#if PAN_ARCH >= 6 +/* Classify a shader into the following pixel kill categories: + * + * (force early, strong early): no side effects/depth/stencil/coverage writes (force) + * (weak early, weak early): no side effects/depth/stencil/coverage writes + * (weak early, force late): no side effects/depth/stencil writes + * (force late, weak early): side effects but no depth/stencil/coverage writes + * (force late, force early): only run for side effects + * (force late, force late): depth/stencil writes + * + * Note that discard is considered a coverage write. TODO: what about + * alpha-to-coverage? + * */ + +struct pan_pixel_kill { + enum mali_pixel_kill pixel_kill; + enum mali_pixel_kill zs_update; +}; + +#define RETURN_PIXEL_KILL(kill, update) return (struct pan_pixel_kill) { \ + MALI_PIXEL_KILL_## kill, MALI_PIXEL_KILL_## update \ +} + +static inline struct pan_pixel_kill +pan_shader_classify_pixel_kill_coverage(const struct pan_shader_info *info) +{ + bool force_early = info->fs.early_fragment_tests; + bool sidefx = info->writes_global; + bool coverage = info->fs.writes_coverage || info->fs.can_discard; + bool depth = info->fs.writes_depth; + bool stencil = info->fs.writes_stencil; + + if (force_early) + RETURN_PIXEL_KILL(FORCE_EARLY, STRONG_EARLY); + else if (depth || stencil || (sidefx && coverage)) + RETURN_PIXEL_KILL(FORCE_LATE, FORCE_LATE); + else if (sidefx) + RETURN_PIXEL_KILL(FORCE_LATE, WEAK_EARLY); + else if (coverage) + RETURN_PIXEL_KILL(WEAK_EARLY, FORCE_LATE); + else + RETURN_PIXEL_KILL(WEAK_EARLY, WEAK_EARLY); +} + +#undef RETURN_PIXEL_KILL + +#endif + +static inline enum mali_depth_source +pan_depth_source(const struct pan_shader_info *info) +{ + return info->fs.writes_depth ? MALI_DEPTH_SOURCE_SHADER : + MALI_DEPTH_SOURCE_FIXED_FUNCTION; +} + +#if PAN_ARCH <= 7 #if PAN_ARCH <= 5 static inline void pan_shader_prepare_midgard_rsd(const struct pan_shader_info *info, @@ -85,60 +151,6 @@ pan_shader_prepare_midgard_rsd(const struct pan_shader_info *info, #else -/* Classify a shader into the following pixel kill categories: - * - * (force early, strong early): no side effects/depth/stencil/coverage writes (force) - * (weak early, weak early): no side effects/depth/stencil/coverage writes - * (weak early, force late): no side effects/depth/stencil writes - * (force late, weak early): side effects but no depth/stencil/coverage writes - * (force late, force early): only run for side effects - * (force late, force late): depth/stencil writes - * - * Note that discard is considered a coverage write. TODO: what about - * alpha-to-coverage? - * */ - -#define SET_PIXEL_KILL(kill, update) do { \ - rsd->properties.pixel_kill_operation = MALI_PIXEL_KILL_## kill; \ - rsd->properties.zs_update_operation = MALI_PIXEL_KILL_## update; \ -} while(0) - -static inline void -pan_shader_classify_pixel_kill_coverage(const struct pan_shader_info *info, - struct MALI_RENDERER_STATE *rsd) -{ - bool force_early = info->fs.early_fragment_tests; - bool sidefx = info->writes_global; - bool coverage = info->fs.writes_coverage || info->fs.can_discard; - bool depth = info->fs.writes_depth; - bool stencil = info->fs.writes_stencil; - - rsd->properties.shader_modifies_coverage = coverage; - - if (force_early) - SET_PIXEL_KILL(FORCE_EARLY, STRONG_EARLY); - else if (depth || stencil || (sidefx && coverage)) - SET_PIXEL_KILL(FORCE_LATE, FORCE_LATE); - else if (sidefx) - SET_PIXEL_KILL(FORCE_LATE, WEAK_EARLY); - else if (coverage) - SET_PIXEL_KILL(WEAK_EARLY, FORCE_LATE); - else - SET_PIXEL_KILL(WEAK_EARLY, WEAK_EARLY); -} - -#undef SET_PIXEL_KILL - -#if PAN_ARCH >= 7 -static enum mali_shader_register_allocation -pan_register_allocation(unsigned work_reg_count) -{ - return (work_reg_count <= 32) ? - MALI_SHADER_REGISTER_ALLOCATION_32_PER_THREAD : - MALI_SHADER_REGISTER_ALLOCATION_64_PER_THREAD; -} -#endif - #define pan_preloads(reg) (preload & BITFIELD64_BIT(reg)) static void @@ -217,7 +229,13 @@ pan_shader_prepare_bifrost_rsd(const struct pan_shader_info *info, pan_make_preload(info->stage, info->preload, &rsd->preload); if (info->stage == MESA_SHADER_FRAGMENT) { - pan_shader_classify_pixel_kill_coverage(info, rsd); + struct pan_pixel_kill kill = pan_shader_classify_pixel_kill_coverage(info); + + rsd->properties.pixel_kill_operation = kill.pixel_kill; + rsd->properties.zs_update_operation = kill.zs_update; + + rsd->properties.shader_modifies_coverage = + info->fs.writes_coverage || info->fs.can_discard; /* Match the mesa/st convention. If this needs to be flipped, * nir_lower_pntc_ytransform will do so. */ @@ -272,10 +290,7 @@ pan_shader_prepare_rsd(const struct pan_shader_info *shader_info, if (shader_info->stage == MESA_SHADER_FRAGMENT) { rsd->properties.stencil_from_shader = shader_info->fs.writes_stencil; - rsd->properties.depth_source = - shader_info->fs.writes_depth ? - MALI_DEPTH_SOURCE_SHADER : - MALI_DEPTH_SOURCE_FIXED_FUNCTION; + rsd->properties.depth_source = pan_depth_source(shader_info); /* This also needs to be set if the API forces per-sample * shading, but that'll just got ORed in */ @@ -290,5 +305,6 @@ pan_shader_prepare_rsd(const struct pan_shader_info *shader_info, #endif } #endif /* PAN_ARCH */ +#endif #endif