panfrost: Use the pan_shader_prepare_rsd() helper

This implies late preparation of the fragment shader RSD, but given the
simplicity of pan_shader_prepare_rsd() (it's basically a 1:1 translation
between shader info and the RSD fields), it's unlikely to make a
difference. If we really want to optimize the time spent preparing the
RSD, we should consider caching a packed version at the batch level and
re-using it when nothing changed.

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8963>
This commit is contained in:
Boris Brezillon 2021-02-13 09:01:15 +01:00 committed by Marge Bot
parent ec51b841a7
commit c21c6d134b
3 changed files with 16 additions and 143 deletions

View File

@ -39,93 +39,6 @@
#include "tgsi/tgsi_dump.h"
static void
pan_prepare_midgard_props(struct panfrost_shader_state *state)
{
pan_prepare(&state->properties, RENDERER_PROPERTIES);
state->properties.uniform_buffer_count = state->info.ubo_count;
state->properties.midgard.uniform_count = state->info.midgard.uniform_cutoff;
state->properties.midgard.shader_has_side_effects = state->info.writes_global;
state->properties.midgard.fp_mode = MALI_FP_MODE_GL_INF_NAN_ALLOWED;
/* For fragment shaders, work register count, early-z, reads at draw-time */
if (state->info.stage != MESA_SHADER_FRAGMENT)
state->properties.midgard.work_register_count = state->info.work_reg_count;
}
static void
pan_prepare_bifrost_props(struct panfrost_shader_state *state)
{
unsigned fau_count = DIV_ROUND_UP(state->info.push.count, 2);
switch (state->info.stage) {
case MESA_SHADER_VERTEX:
pan_prepare(&state->properties, RENDERER_PROPERTIES);
state->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
state->properties.uniform_buffer_count = state->info.ubo_count;
pan_prepare(&state->preload, PRELOAD);
state->preload.uniform_count = fau_count;
state->preload.vertex.vertex_id = true;
state->preload.vertex.instance_id = true;
break;
case MESA_SHADER_FRAGMENT:
pan_prepare(&state->properties, RENDERER_PROPERTIES);
/* Early-Z set at draw-time */
if (state->info.fs.writes_depth || state->info.fs.writes_stencil) {
state->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_FORCE_LATE;
state->properties.bifrost.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_LATE;
} else if (state->info.fs.can_discard) {
state->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_FORCE_LATE;
state->properties.bifrost.pixel_kill_operation = MALI_PIXEL_KILL_WEAK_EARLY;
} else {
state->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
state->properties.bifrost.pixel_kill_operation = MALI_PIXEL_KILL_FORCE_EARLY;
}
state->properties.uniform_buffer_count = state->info.ubo_count;
state->properties.bifrost.shader_modifies_coverage = state->info.fs.can_discard;
state->properties.bifrost.shader_wait_dependency_6 = state->info.bifrost.wait_6;
state->properties.bifrost.shader_wait_dependency_7 = state->info.bifrost.wait_7;
pan_prepare(&state->preload, PRELOAD);
state->preload.uniform_count = fau_count;
state->preload.fragment.fragment_position = state->info.fs.reads_frag_coord;
state->preload.fragment.coverage = true;
state->preload.fragment.primitive_flags = state->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 */
state->preload.fragment.sample_mask_id =
state->info.fs.reads_sample_id |
state->info.fs.reads_sample_pos |
state->info.fs.reads_sample_mask_in |
state->info.fs.reads_helper_invocation;
break;
case MESA_SHADER_COMPUTE:
pan_prepare(&state->properties, RENDERER_PROPERTIES);
state->properties.uniform_buffer_count = state->info.ubo_count;
pan_prepare(&state->preload, PRELOAD);
state->preload.uniform_count = fau_count;
state->preload.compute.local_invocation_xy = true;
state->preload.compute.local_invocation_z = true;
state->preload.compute.work_group_x = true;
state->preload.compute.work_group_y = true;
state->preload.compute.work_group_z = true;
state->preload.compute.global_invocation_x = true;
state->preload.compute.global_invocation_y = true;
state->preload.compute.global_invocation_z = true;
break;
default:
unreachable("TODO");
}
}
static void
pan_upload_shader_descriptor(struct panfrost_context *ctx,
struct panfrost_shader_state *state)
@ -137,11 +50,9 @@ pan_upload_shader_descriptor(struct panfrost_context *ctx,
&state->upload.offset, &state->upload.rsrc, (void **) &out);
pan_pack(out, RENDERER_STATE, cfg) {
cfg.shader = state->shader;
cfg.properties = state->properties;
if (pan_is_bifrost(dev))
cfg.preload = state->preload;
pan_shader_prepare_rsd(dev, &state->info,
state->bo ? state->bo->ptr.gpu : 0,
&cfg);
}
u_upload_unmap(ctx->state_uploader);
@ -181,52 +92,13 @@ panfrost_shader_compile(struct panfrost_context *ctx,
pan_shader_compile(dev, s, &inputs, &binary, &state->info);
/* Prepare the compiled binary for upload */
mali_ptr shader = 0;
int size = binary.size;
if (size) {
state->bo = panfrost_bo_create(dev, size, PAN_BO_EXECUTE);
memcpy(state->bo->ptr.cpu, binary.data, size);
shader = state->bo->ptr.gpu;
if (binary.size) {
state->bo = panfrost_bo_create(dev, binary.size, PAN_BO_EXECUTE);
memcpy(state->bo->ptr.cpu, binary.data, binary.size);
}
/* Midgard needs the first tag on the bottom nibble */
if (!pan_is_bifrost(dev))
shader |= state->info.midgard.first_tag;
/* Prepare the descriptors at compile-time */
state->shader.shader = shader;
state->shader.attribute_count = state->info.attribute_count;
state->shader.varying_count = state->info.varyings.input_count +
state->info.varyings.output_count;
state->shader.texture_count = state->info.texture_count;
state->shader.sampler_count = state->info.texture_count;
if (pan_is_bifrost(dev))
pan_prepare_bifrost_props(state);
else
pan_prepare_midgard_props(state);
state->properties.shader_contains_barrier =
state->info.contains_barrier;
/* Ordering gaurantees are the same */
if (stage == MESA_SHADER_FRAGMENT) {
state->properties.shader_contains_barrier |=
state->info.fs.helper_invocations;
state->properties.stencil_from_shader =
state->info.fs.writes_stencil;
state->properties.depth_source =
state->info.fs.writes_depth ?
MALI_DEPTH_SOURCE_SHADER :
MALI_DEPTH_SOURCE_FIXED_FUNCTION;
} else {
state->properties.depth_source =
MALI_DEPTH_SOURCE_FIXED_FUNCTION;
}
if (stage != MESA_SHADER_FRAGMENT)
pan_upload_shader_descriptor(ctx, state);

View File

@ -34,6 +34,7 @@
#include "pan_cmdstream.h"
#include "pan_context.h"
#include "pan_job.h"
#include "pan_shader.h"
#include "pan_texture.h"
/* If a BO is accessed for a particular shader stage, will it be in the primary
@ -423,6 +424,7 @@ panfrost_prepare_bifrost_fs_state(struct panfrost_context *ctx,
struct panfrost_blend_final *blend,
struct MALI_RENDERER_STATE *state)
{
const struct panfrost_device *dev = pan_device(ctx->base.screen);
struct panfrost_shader_state *fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
unsigned rt_count = ctx->pipe_framebuffer.nr_cbufs;
@ -433,18 +435,19 @@ panfrost_prepare_bifrost_fs_state(struct panfrost_context *ctx,
state->properties.bifrost.allow_forward_pixel_to_be_killed = true;
state->properties.bifrost.zs_update_operation = MALI_PIXEL_KILL_STRONG_EARLY;
} else {
pan_shader_prepare_rsd(dev, &fs->info,
fs->bo ? fs->bo->ptr.gpu : 0,
state);
bool no_blend = true;
for (unsigned i = 0; i < rt_count; ++i)
no_blend &= (!blend[i].load_dest | blend[i].no_colour);
state->properties = fs->properties;
state->properties.bifrost.allow_forward_pixel_to_kill =
!fs->info.fs.can_discard &&
!fs->info.fs.writes_depth &&
no_blend;
state->shader = fs->shader;
state->preload = fs->preload;
}
}
@ -465,6 +468,10 @@ panfrost_prepare_midgard_fs_state(struct panfrost_context *ctx,
state->properties.depth_source = MALI_DEPTH_SOURCE_FIXED_FUNCTION;
state->properties.midgard.force_early_z = true;
} else {
pan_shader_prepare_rsd(dev, &fs->info,
fs->bo ? fs->bo->ptr.gpu : 0,
state);
/* Reasons to disable early-Z from a shader perspective */
bool late_z = fs->info.fs.can_discard || fs->info.writes_global ||
fs->info.fs.writes_depth || fs->info.fs.writes_stencil;
@ -480,7 +487,6 @@ panfrost_prepare_midgard_fs_state(struct panfrost_context *ctx,
has_blend_shader |= blend[c].is_shader;
/* TODO: Reduce this limit? */
state->properties = fs->properties;
if (has_blend_shader)
state->properties.midgard.work_register_count = MAX2(fs->info.work_reg_count, 8);
else
@ -497,7 +503,6 @@ panfrost_prepare_midgard_fs_state(struct panfrost_context *ctx,
(!zs_enabled && fs->info.fs.can_discard);
state->properties.midgard.shader_contains_discard =
zs_enabled && fs->info.fs.can_discard;
state->shader = fs->shader;
}
if (dev->quirks & MIDGARD_SFBD && ctx->pipe_framebuffer.nr_cbufs > 0) {

View File

@ -210,10 +210,6 @@ struct panfrost_shader_state {
uint32_t offset;
} upload;
struct MALI_SHADER shader;
struct MALI_RENDERER_PROPERTIES properties;
struct MALI_PRELOAD preload;
struct pan_shader_info info;
struct pipe_stream_output_info stream_output;