mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-22 06:38:09 +02:00
The first commit just optimizes operation where the result of the subgroup operation is the same as each of the individual channel results. This is a subset of the things optimized by ACO. See also https://gitlab.freedesktop.org/mesa/mesa/-/issues/3731#note_682802. Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27044>
81 lines
2 KiB
C
81 lines
2 KiB
C
/*
|
|
* Copyright 2023 Intel Corporation
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
* Optimize subgroup operations with uniform sources.
|
|
*/
|
|
|
|
#include "nir/nir.h"
|
|
#include "nir/nir_builder.h"
|
|
|
|
static bool
|
|
opt_uniform_subgroup_filter(const nir_instr *instr, const void *_state)
|
|
{
|
|
if (instr->type != nir_instr_type_intrinsic)
|
|
return false;
|
|
|
|
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
|
|
|
switch (intrin->intrinsic) {
|
|
case nir_intrinsic_shuffle:
|
|
case nir_intrinsic_read_invocation:
|
|
case nir_intrinsic_read_first_invocation:
|
|
case nir_intrinsic_quad_broadcast:
|
|
case nir_intrinsic_quad_swap_horizontal:
|
|
case nir_intrinsic_quad_swap_vertical:
|
|
case nir_intrinsic_quad_swap_diagonal:
|
|
case nir_intrinsic_quad_swizzle_amd:
|
|
case nir_intrinsic_masked_swizzle_amd:
|
|
return !nir_src_is_divergent(intrin->src[0]);
|
|
|
|
case nir_intrinsic_reduce:
|
|
case nir_intrinsic_inclusive_scan: {
|
|
if (nir_src_is_divergent(intrin->src[0]))
|
|
return false;
|
|
|
|
const nir_op reduction_op = (nir_op) nir_intrinsic_reduction_op(intrin);
|
|
|
|
switch (reduction_op) {
|
|
case nir_op_imin:
|
|
case nir_op_umin:
|
|
case nir_op_fmin:
|
|
case nir_op_imax:
|
|
case nir_op_umax:
|
|
case nir_op_fmax:
|
|
case nir_op_iand:
|
|
case nir_op_ior:
|
|
return true;
|
|
|
|
/* FINISHME: iadd, ixor, and fadd are also possible. */
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static nir_def *
|
|
opt_uniform_subgroup_instr(nir_builder *b, nir_instr *instr, void *_state)
|
|
{
|
|
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
|
|
|
return intrin->src[0].ssa;
|
|
}
|
|
|
|
bool
|
|
nir_opt_uniform_subgroup(nir_shader *shader)
|
|
{
|
|
bool progress = nir_shader_lower_instructions(shader,
|
|
opt_uniform_subgroup_filter,
|
|
opt_uniform_subgroup_instr,
|
|
NULL);
|
|
|
|
return progress;
|
|
}
|
|
|