panfrost: Pack draw-time RSD all-at-once

Manually inline the functions, delete the duplicates, and use GenXML the
way it's meant to be used. Template structs should **never** cross
function boundaries.

Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10869>
This commit is contained in:
Alyssa Rosenzweig
2021-05-14 19:41:33 -04:00
committed by Marge Bot
parent 8f2b2bcff4
commit bfd76ab501

View File

@@ -484,28 +484,6 @@ pan_merge_empty_fs(struct mali_renderer_state_packed *rsd, bool is_bifrost)
pan_merge((*rsd), empty_rsd, RENDERER_STATE);
}
static void
panfrost_prepare_bifrost_fs_state(struct panfrost_context *ctx,
struct MALI_RENDERER_STATE *state)
{
struct panfrost_shader_state *fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
struct panfrost_blend_state *so = ctx->blend;
bool alpha_to_coverage = so->base.alpha_to_coverage;
if (panfrost_fs_required(fs, so, &ctx->pipe_framebuffer)) {
/* Track if any colour buffer is reused across draws, either
* from reading it directly, or from failing to write it */
unsigned rt_mask = ctx->fb_rt_mask;
bool blend_reads_dest = (so->load_dest_mask & rt_mask);
state->properties.bifrost.allow_forward_pixel_to_kill =
fs->info.fs.can_fpk &&
!(rt_mask & ~fs->info.outputs_written) &&
!alpha_to_coverage &&
!blend_reads_dest;
}
}
/* Get the last blend shader, for an erratum workaround */
static mali_ptr
@@ -519,108 +497,108 @@ panfrost_last_nonnull(mali_ptr *ptrs, unsigned count)
return 0;
}
static void
panfrost_prepare_midgard_fs_state(struct panfrost_context *ctx,
mali_ptr *blend_shaders,
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);
const struct panfrost_zsa_state *zsa = ctx->depth_stencil;
unsigned rt_count = ctx->pipe_framebuffer.nr_cbufs;
bool alpha_to_coverage = ctx->blend->base.alpha_to_coverage;
if (panfrost_fs_required(fs, ctx->blend, &ctx->pipe_framebuffer)) {
state->properties.midgard.force_early_z =
fs->info.fs.can_early_z && !alpha_to_coverage &&
((enum mali_func) zsa->base.alpha_func == MALI_FUNC_ALWAYS);
bool has_blend_shader = false;
for (unsigned c = 0; c < rt_count; ++c)
has_blend_shader |= (blend_shaders[c] != 0);
/* TODO: Reduce this limit? */
if (has_blend_shader)
state->properties.midgard.work_register_count = MAX2(fs->info.work_reg_count, 8);
else
state->properties.midgard.work_register_count = fs->info.work_reg_count;
/* Workaround a hardware errata where early-z cannot be enabled
* when discarding even when the depth buffer is read-only, by
* lying to the hardware about the discard and setting the
* reads tilebuffer? flag to compensate */
state->properties.midgard.shader_reads_tilebuffer =
!zsa->enabled && fs->info.fs.can_discard;
state->properties.midgard.shader_contains_discard =
zsa->enabled && fs->info.fs.can_discard;
}
if (dev->quirks & MIDGARD_SFBD && ctx->pipe_framebuffer.nr_cbufs > 0) {
struct panfrost_blend_state *so = ctx->blend;
state->multisample_misc.sfbd_load_destination = so->info[0].load_dest;
state->multisample_misc.sfbd_blend_shader = (blend_shaders[0] != 0);
state->stencil_mask_misc.sfbd_write_enable = !so->info[0].no_colour;
state->stencil_mask_misc.sfbd_srgb = util_format_is_srgb(ctx->pipe_framebuffer.cbufs[0]->format);
state->stencil_mask_misc.sfbd_dither_disable = !so->base.dither;
state->stencil_mask_misc.sfbd_alpha_to_one = so->base.alpha_to_one;
if (blend_shaders[0]) {
state->sfbd_blend_shader = blend_shaders[0];
} else {
state->sfbd_blend_constant = pan_blend_get_constant(
so->info[0].constant_mask,
ctx->blend_color.color);
}
} else if (dev->quirks & MIDGARD_SFBD) {
/* If there is no colour buffer, leaving fields default is
* fine, except for blending which is nonnullable */
state->sfbd_blend_equation.color_mask = 0xf;
state->sfbd_blend_equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
state->sfbd_blend_equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
state->sfbd_blend_equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
state->sfbd_blend_equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
state->sfbd_blend_equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
state->sfbd_blend_equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
} else {
/* Workaround on v5 */
state->sfbd_blend_shader = panfrost_last_nonnull(blend_shaders, rt_count);
}
}
static void
panfrost_prepare_fs_state(struct panfrost_context *ctx,
mali_ptr *blend_shaders,
struct MALI_RENDERER_STATE *state)
struct mali_renderer_state_packed *rsd)
{
const struct panfrost_device *dev = pan_device(ctx->base.screen);
struct pipe_rasterizer_state *rast = &ctx->rasterizer->base;
const struct panfrost_zsa_state *zsa = ctx->depth_stencil;
struct panfrost_shader_state *fs = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
struct panfrost_blend_state *so = ctx->blend;
bool alpha_to_coverage = ctx->blend->base.alpha_to_coverage;
if (pan_is_bifrost(dev))
panfrost_prepare_bifrost_fs_state(ctx, state);
else
panfrost_prepare_midgard_fs_state(ctx, blend_shaders, state);
bool msaa = rast->multisample;
state->multisample_misc.sample_mask = msaa ? ctx->sample_mask : 0xFFFF;
state->multisample_misc.evaluate_per_sample =
msaa && (ctx->min_samples > 1);
pan_pack(rsd, RENDERER_STATE, cfg) {
if (pan_is_bifrost(dev) && panfrost_fs_required(fs, so, &ctx->pipe_framebuffer)) {
/* Track if any colour buffer is reused across draws, either
* from reading it directly, or from failing to write it */
unsigned rt_mask = ctx->fb_rt_mask;
bool blend_reads_dest = (so->load_dest_mask & rt_mask);
state->stencil_mask_misc.alpha_to_coverage = alpha_to_coverage;
state->depth_units = rast->offset_units * 2.0f;
state->depth_factor = rast->offset_scale;
cfg.properties.bifrost.allow_forward_pixel_to_kill =
fs->info.fs.can_fpk &&
!(rt_mask & ~fs->info.outputs_written) &&
!alpha_to_coverage &&
!blend_reads_dest;
} else if (!pan_is_bifrost(dev)) {
unsigned rt_count = ctx->pipe_framebuffer.nr_cbufs;
bool back_enab = zsa->base.stencil[1].enabled;
state->stencil_front.reference_value = ctx->stencil_ref.ref_value[0];
state->stencil_back.reference_value = ctx->stencil_ref.ref_value[back_enab ? 1 : 0];
if (panfrost_fs_required(fs, ctx->blend, &ctx->pipe_framebuffer)) {
cfg.properties.midgard.force_early_z =
fs->info.fs.can_early_z && !alpha_to_coverage &&
((enum mali_func) zsa->base.alpha_func == MALI_FUNC_ALWAYS);
/* v6+ fits register preload here, no alpha testing */
if (dev->arch <= 5)
state->alpha_reference = zsa->base.alpha_ref_value;
bool has_blend_shader = false;
for (unsigned c = 0; c < rt_count; ++c)
has_blend_shader |= (blend_shaders[c] != 0);
/* TODO: Reduce this limit? */
if (has_blend_shader)
cfg.properties.midgard.work_register_count = MAX2(fs->info.work_reg_count, 8);
else
cfg.properties.midgard.work_register_count = fs->info.work_reg_count;
/* Workaround a hardware errata where early-z cannot be enabled
* when discarding even when the depth buffer is read-only, by
* lying to the hardware about the discard and setting the
* reads tilebuffer? flag to compensate */
cfg.properties.midgard.shader_reads_tilebuffer =
!zsa->enabled && fs->info.fs.can_discard;
cfg.properties.midgard.shader_contains_discard =
zsa->enabled && fs->info.fs.can_discard;
}
if (dev->quirks & MIDGARD_SFBD && rt_count > 0) {
cfg.multisample_misc.sfbd_load_destination = so->info[0].load_dest;
cfg.multisample_misc.sfbd_blend_shader = (blend_shaders[0] != 0);
cfg.stencil_mask_misc.sfbd_write_enable = !so->info[0].no_colour;
cfg.stencil_mask_misc.sfbd_srgb = util_format_is_srgb(ctx->pipe_framebuffer.cbufs[0]->format);
cfg.stencil_mask_misc.sfbd_dither_disable = !so->base.dither;
cfg.stencil_mask_misc.sfbd_alpha_to_one = so->base.alpha_to_one;
if (blend_shaders[0]) {
cfg.sfbd_blend_shader = blend_shaders[0];
} else {
cfg.sfbd_blend_constant = pan_blend_get_constant(
so->info[0].constant_mask,
ctx->blend_color.color);
}
} else if (dev->quirks & MIDGARD_SFBD) {
/* If there is no colour buffer, leaving fields default is
* fine, except for blending which is nonnullable */
cfg.sfbd_blend_equation.color_mask = 0xf;
cfg.sfbd_blend_equation.rgb.a = MALI_BLEND_OPERAND_A_SRC;
cfg.sfbd_blend_equation.rgb.b = MALI_BLEND_OPERAND_B_SRC;
cfg.sfbd_blend_equation.rgb.c = MALI_BLEND_OPERAND_C_ZERO;
cfg.sfbd_blend_equation.alpha.a = MALI_BLEND_OPERAND_A_SRC;
cfg.sfbd_blend_equation.alpha.b = MALI_BLEND_OPERAND_B_SRC;
cfg.sfbd_blend_equation.alpha.c = MALI_BLEND_OPERAND_C_ZERO;
} else {
/* Workaround on v5 */
cfg.sfbd_blend_shader = panfrost_last_nonnull(blend_shaders, rt_count);
}
}
cfg.multisample_misc.sample_mask = msaa ? ctx->sample_mask : 0xFFFF;
cfg.multisample_misc.evaluate_per_sample =
msaa && (ctx->min_samples > 1);
cfg.stencil_mask_misc.alpha_to_coverage = alpha_to_coverage;
cfg.depth_units = rast->offset_units * 2.0f;
cfg.depth_factor = rast->offset_scale;
bool back_enab = zsa->base.stencil[1].enabled;
cfg.stencil_front.reference_value = ctx->stencil_ref.ref_value[0];
cfg.stencil_back.reference_value = ctx->stencil_ref.ref_value[back_enab ? 1 : 0];
/* v6+ fits register preload here, no alpha testing */
if (dev->arch <= 5)
cfg.alpha_reference = zsa->base.alpha_ref_value;
}
}
static void
@@ -638,10 +616,7 @@ panfrost_emit_frag_shader(struct panfrost_context *ctx,
* so stage to temporary storage rather than reading back write-combine
* memory, which will trash performance. */
struct mali_renderer_state_packed rsd;
pan_pack(&rsd, RENDERER_STATE, cfg) {
panfrost_prepare_fs_state(ctx, blend_shaders, &cfg);
}
panfrost_prepare_fs_state(ctx, blend_shaders, &rsd);
if ((dev->quirks & MIDGARD_SFBD)
&& ctx->pipe_framebuffer.nr_cbufs > 0