From ec51b841a7420e1fece911e1fdc3d783a08a93f2 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sat, 13 Feb 2021 08:41:47 +0100 Subject: [PATCH] panfrost: Provide a helper to prepare the shader related parts of an RSD Signed-off-by: Boris Brezillon Acked-by: Alyssa Rosenzweig Part-of: --- src/panfrost/lib/pan_shader.h | 122 ++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) diff --git a/src/panfrost/lib/pan_shader.h b/src/panfrost/lib/pan_shader.h index b67d5a2e596..43f6733eafc 100644 --- a/src/panfrost/lib/pan_shader.h +++ b/src/panfrost/lib/pan_shader.h @@ -28,6 +28,9 @@ #include "compiler/nir/nir.h" #include "panfrost/util/pan_ir.h" +#include "pan_device.h" +#include "midgard_pack.h" + struct panfrost_device; const nir_shader_compiler_options * @@ -40,4 +43,123 @@ pan_shader_compile(const struct panfrost_device *dev, struct util_dynarray *binary, struct pan_shader_info *info); +static inline void +pan_shader_prepare_midgard_rsd(const struct pan_shader_info *info, + struct MALI_RENDERER_STATE *rsd) +{ + rsd->properties.uniform_buffer_count = info->ubo_count; + rsd->properties.midgard.uniform_count = info->midgard.uniform_cutoff; + rsd->properties.midgard.shader_has_side_effects = info->writes_global; + rsd->properties.midgard.fp_mode = MALI_FP_MODE_GL_INF_NAN_ALLOWED; + + /* For fragment shaders, work register count, early-z, reads at draw-time */ + + if (info->stage != MESA_SHADER_FRAGMENT) + rsd->properties.midgard.work_register_count = info->work_reg_count; +} + +static inline void +pan_shader_prepare_bifrost_rsd(const struct pan_shader_info *info, + struct MALI_RENDERER_STATE *rsd) +{ + unsigned fau_count = DIV_ROUND_UP(info->push.count, 2); + + switch (info->stage) { + case MESA_SHADER_VERTEX: + rsd->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY; + rsd->properties.uniform_buffer_count = info->ubo_count; + + rsd->preload.uniform_count = fau_count; + rsd->preload.vertex.vertex_id = true; + rsd->preload.vertex.instance_id = true; + break; + + case MESA_SHADER_FRAGMENT: + /* Early-Z set at draw-time */ + if (info->fs.writes_depth || info->fs.writes_stencil) { + rsd->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_FORCE_LATE; + rsd->properties.bifrost.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_LATE; + } else if (info->fs.can_discard) { + rsd->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_FORCE_LATE; + rsd->properties.bifrost.pixel_kill_operation = MALI_PIXEL_KILL_WEAK_EARLY; + } else { + rsd->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY; + rsd->properties.bifrost.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_EARLY; + } + rsd->properties.uniform_buffer_count = info->ubo_count; + rsd->properties.bifrost.shader_modifies_coverage = info->fs.can_discard; + rsd->properties.bifrost.shader_wait_dependency_6 = info->bifrost.wait_6; + rsd->properties.bifrost.shader_wait_dependency_7 = info->bifrost.wait_7; + + rsd->preload.uniform_count = fau_count; + rsd->preload.fragment.fragment_position = info->fs.reads_frag_coord; + rsd->preload.fragment.coverage = true; + rsd->preload.fragment.primitive_flags = info->fs.reads_face; + + /* Contains sample ID and sample mask. Sample position and + * helper invocation are expressed in terms of the above, so + * preload for those too */ + rsd->preload.fragment.sample_mask_id = + info->fs.reads_sample_id | + info->fs.reads_sample_pos | + info->fs.reads_sample_mask_in | + info->fs.reads_helper_invocation; + break; + + case MESA_SHADER_COMPUTE: + rsd->properties.uniform_buffer_count = info->ubo_count; + + rsd->preload.uniform_count = fau_count; + rsd->preload.compute.local_invocation_xy = true; + rsd->preload.compute.local_invocation_z = true; + rsd->preload.compute.work_group_x = true; + rsd->preload.compute.work_group_y = true; + rsd->preload.compute.work_group_z = true; + rsd->preload.compute.global_invocation_x = true; + rsd->preload.compute.global_invocation_y = true; + rsd->preload.compute.global_invocation_z = true; + break; + + default: + unreachable("TODO"); + } +} + +static inline void +pan_shader_prepare_rsd(const struct panfrost_device *dev, + const struct pan_shader_info *shader_info, + mali_ptr shader_ptr, + struct MALI_RENDERER_STATE *rsd) +{ + if (!pan_is_bifrost(dev)) + shader_ptr |= shader_info->midgard.first_tag; + + rsd->shader.shader = shader_ptr; + rsd->shader.attribute_count = shader_info->attribute_count; + rsd->shader.varying_count = shader_info->varyings.input_count + + shader_info->varyings.output_count; + rsd->shader.texture_count = shader_info->texture_count; + rsd->shader.sampler_count = shader_info->texture_count; + rsd->properties.shader_contains_barrier = shader_info->contains_barrier; + + if (shader_info->stage == MESA_SHADER_FRAGMENT) { + rsd->properties.shader_contains_barrier |= + shader_info->fs.helper_invocations; + 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; + } else { + rsd->properties.depth_source = + MALI_DEPTH_SOURCE_FIXED_FUNCTION; + } + + if (pan_is_bifrost(dev)) + pan_shader_prepare_bifrost_rsd(shader_info, rsd); + else + pan_shader_prepare_midgard_rsd(shader_info, rsd); +} + #endif