ac/nir: Move varying cost functions from radeonsi to common code.
This code will be shared between RADV and RadeonSI. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Georg Lehmann <dadschoorse@gmail.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28676>
This commit is contained in:
@@ -1580,3 +1580,129 @@ ac_get_global_ids(nir_builder *b, unsigned num_components, unsigned bit_size)
|
||||
|
||||
return nir_iadd(b, nir_imul(b, block_ids, block_size), local_ids);
|
||||
}
|
||||
|
||||
unsigned
|
||||
ac_nir_varying_expression_max_cost(nir_shader *producer, nir_shader *consumer)
|
||||
{
|
||||
switch (consumer->info.stage) {
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
/* VS->TCS
|
||||
* Non-amplifying shaders can always have their varying expressions
|
||||
* moved into later shaders.
|
||||
*/
|
||||
return UINT_MAX;
|
||||
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
/* VS->GS, TES->GS */
|
||||
return consumer->info.gs.vertices_in == 1 ? UINT_MAX :
|
||||
consumer->info.gs.vertices_in == 2 ? 20 : 14;
|
||||
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
/* TCS->TES and VS->TES (OpenGL only) */
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
/* Up to 3 uniforms and 5 ALUs. */
|
||||
return 14;
|
||||
|
||||
default:
|
||||
unreachable("unexpected shader stage");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
ac_nir_varying_estimate_instr_cost(nir_instr *instr)
|
||||
{
|
||||
unsigned dst_bit_size, src_bit_size, num_dst_dwords;
|
||||
nir_op alu_op;
|
||||
|
||||
/* This is a very loose approximation based on gfx10. */
|
||||
switch (instr->type) {
|
||||
case nir_instr_type_alu:
|
||||
dst_bit_size = nir_instr_as_alu(instr)->def.bit_size;
|
||||
src_bit_size = nir_instr_as_alu(instr)->src[0].src.ssa->bit_size;
|
||||
alu_op = nir_instr_as_alu(instr)->op;
|
||||
num_dst_dwords = DIV_ROUND_UP(dst_bit_size, 32);
|
||||
|
||||
switch (alu_op) {
|
||||
case nir_op_mov:
|
||||
case nir_op_vec2:
|
||||
case nir_op_vec3:
|
||||
case nir_op_vec4:
|
||||
case nir_op_vec5:
|
||||
case nir_op_vec8:
|
||||
case nir_op_vec16:
|
||||
case nir_op_fabs:
|
||||
case nir_op_fneg:
|
||||
case nir_op_fsat:
|
||||
return 0;
|
||||
|
||||
case nir_op_imul:
|
||||
case nir_op_umul_low:
|
||||
return dst_bit_size <= 16 ? 1 : 4 * num_dst_dwords;
|
||||
|
||||
case nir_op_imul_high:
|
||||
case nir_op_umul_high:
|
||||
case nir_op_imul_2x32_64:
|
||||
case nir_op_umul_2x32_64:
|
||||
return 4;
|
||||
|
||||
case nir_op_fexp2:
|
||||
case nir_op_flog2:
|
||||
case nir_op_frcp:
|
||||
case nir_op_frsq:
|
||||
case nir_op_fsqrt:
|
||||
case nir_op_fsin:
|
||||
case nir_op_fcos:
|
||||
case nir_op_fsin_amd:
|
||||
case nir_op_fcos_amd:
|
||||
return 4; /* FP16 & FP32. */
|
||||
|
||||
case nir_op_fpow:
|
||||
return 4 + 1 + 4; /* log2 + mul + exp2 */
|
||||
|
||||
case nir_op_fsign:
|
||||
return dst_bit_size == 64 ? 4 : 3; /* See ac_build_fsign. */
|
||||
|
||||
case nir_op_idiv:
|
||||
case nir_op_udiv:
|
||||
case nir_op_imod:
|
||||
case nir_op_umod:
|
||||
case nir_op_irem:
|
||||
return dst_bit_size == 64 ? 80 : 40;
|
||||
|
||||
case nir_op_fdiv:
|
||||
return dst_bit_size == 64 ? 80 : 5; /* FP16 & FP32: rcp + mul */
|
||||
|
||||
case nir_op_fmod:
|
||||
case nir_op_frem:
|
||||
return dst_bit_size == 64 ? 80 : 8;
|
||||
|
||||
default:
|
||||
/* Double opcodes. Comparisons have always full performance. */
|
||||
if ((dst_bit_size == 64 &&
|
||||
nir_op_infos[alu_op].output_type & nir_type_float) ||
|
||||
(dst_bit_size >= 8 && src_bit_size == 64 &&
|
||||
nir_op_infos[alu_op].input_types[0] & nir_type_float))
|
||||
return 16;
|
||||
|
||||
return DIV_ROUND_UP(MAX2(dst_bit_size, src_bit_size), 32);
|
||||
}
|
||||
|
||||
case nir_instr_type_intrinsic:
|
||||
dst_bit_size = nir_instr_as_intrinsic(instr)->def.bit_size;
|
||||
num_dst_dwords = DIV_ROUND_UP(dst_bit_size, 32);
|
||||
|
||||
switch (nir_instr_as_intrinsic(instr)->intrinsic) {
|
||||
case nir_intrinsic_load_deref:
|
||||
/* Uniform or UBO load.
|
||||
* Set a low cost to balance the number of scalar loads and ALUs.
|
||||
*/
|
||||
return 3 * num_dst_dwords;
|
||||
|
||||
default:
|
||||
unreachable("unexpected intrinsic");
|
||||
}
|
||||
|
||||
default:
|
||||
unreachable("unexpected instr type");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,6 +314,12 @@ ac_nir_store_debug_log_amd(nir_builder *b, nir_def *uvec4);
|
||||
bool
|
||||
ac_nir_opt_pack_half(nir_shader *shader, enum amd_gfx_level gfx_level);
|
||||
|
||||
unsigned
|
||||
ac_nir_varying_expression_max_cost(nir_shader *producer, nir_shader *consumer);
|
||||
|
||||
unsigned
|
||||
ac_nir_varying_estimate_instr_cost(nir_instr *instr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "compiler/nir/nir.h"
|
||||
#include "ac_nir.h"
|
||||
#include "ac_shader_util.h"
|
||||
#include "radeon_uvd_enc.h"
|
||||
#include "radeon_vce.h"
|
||||
@@ -1460,123 +1461,7 @@ static unsigned si_varying_expression_max_cost(nir_shader *producer, nir_shader
|
||||
}
|
||||
}
|
||||
|
||||
switch (consumer->info.stage) {
|
||||
case MESA_SHADER_TESS_CTRL: /* VS->TCS */
|
||||
/* Non-amplifying shaders can always have their variyng expressions
|
||||
* moved into later shaders.
|
||||
*/
|
||||
return UINT_MAX;
|
||||
|
||||
case MESA_SHADER_GEOMETRY: /* VS->GS, TES->GS */
|
||||
return consumer->info.gs.vertices_in == 1 ? UINT_MAX :
|
||||
consumer->info.gs.vertices_in == 2 ? 20 : 14;
|
||||
|
||||
case MESA_SHADER_TESS_EVAL: /* VS->TES, TCS->TES */
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
/* Up to 3 uniforms and 5 ALUs. */
|
||||
return 14;
|
||||
|
||||
default:
|
||||
unreachable("unexpected shader stage");
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned si_varying_estimate_instr_cost(nir_instr *instr)
|
||||
{
|
||||
unsigned dst_bit_size, src_bit_size, num_dst_dwords;
|
||||
nir_op alu_op;
|
||||
|
||||
/* This is a very loose approximation based on gfx10. */
|
||||
switch (instr->type) {
|
||||
case nir_instr_type_alu:
|
||||
dst_bit_size = nir_instr_as_alu(instr)->def.bit_size;
|
||||
src_bit_size = nir_instr_as_alu(instr)->src[0].src.ssa->bit_size;
|
||||
alu_op = nir_instr_as_alu(instr)->op;
|
||||
num_dst_dwords = DIV_ROUND_UP(dst_bit_size, 32);
|
||||
|
||||
switch (alu_op) {
|
||||
case nir_op_mov:
|
||||
case nir_op_vec2:
|
||||
case nir_op_vec3:
|
||||
case nir_op_vec4:
|
||||
case nir_op_vec5:
|
||||
case nir_op_vec8:
|
||||
case nir_op_vec16:
|
||||
case nir_op_fabs:
|
||||
case nir_op_fneg:
|
||||
case nir_op_fsat:
|
||||
return 0;
|
||||
|
||||
case nir_op_imul:
|
||||
case nir_op_umul_low:
|
||||
return dst_bit_size <= 16 ? 1 : 4 * num_dst_dwords;
|
||||
|
||||
case nir_op_imul_high:
|
||||
case nir_op_umul_high:
|
||||
case nir_op_imul_2x32_64:
|
||||
case nir_op_umul_2x32_64:
|
||||
return 4;
|
||||
|
||||
case nir_op_fexp2:
|
||||
case nir_op_flog2:
|
||||
case nir_op_frcp:
|
||||
case nir_op_frsq:
|
||||
case nir_op_fsqrt:
|
||||
case nir_op_fsin:
|
||||
case nir_op_fcos:
|
||||
case nir_op_fsin_amd:
|
||||
case nir_op_fcos_amd:
|
||||
return 4; /* FP16 & FP32. */
|
||||
|
||||
case nir_op_fpow:
|
||||
return 4 + 1 + 4; /* log2 + mul + exp2 */
|
||||
|
||||
case nir_op_fsign:
|
||||
return dst_bit_size == 64 ? 4 : 3; /* See ac_build_fsign. */
|
||||
|
||||
case nir_op_idiv:
|
||||
case nir_op_udiv:
|
||||
case nir_op_imod:
|
||||
case nir_op_umod:
|
||||
case nir_op_irem:
|
||||
return dst_bit_size == 64 ? 80 : 40;
|
||||
|
||||
case nir_op_fdiv:
|
||||
return dst_bit_size == 64 ? 80 : 5; /* FP16 & FP32: rcp + mul */
|
||||
|
||||
case nir_op_fmod:
|
||||
case nir_op_frem:
|
||||
return dst_bit_size == 64 ? 80 : 8;
|
||||
|
||||
default:
|
||||
/* Double opcodes. Comparisons have always full performance. */
|
||||
if ((dst_bit_size == 64 &&
|
||||
nir_op_infos[alu_op].output_type & nir_type_float) ||
|
||||
(dst_bit_size >= 8 && src_bit_size == 64 &&
|
||||
nir_op_infos[alu_op].input_types[0] & nir_type_float))
|
||||
return 16;
|
||||
|
||||
return DIV_ROUND_UP(MAX2(dst_bit_size, src_bit_size), 32);
|
||||
}
|
||||
|
||||
case nir_instr_type_intrinsic:
|
||||
dst_bit_size = nir_instr_as_intrinsic(instr)->def.bit_size;
|
||||
num_dst_dwords = DIV_ROUND_UP(dst_bit_size, 32);
|
||||
|
||||
switch (nir_instr_as_intrinsic(instr)->intrinsic) {
|
||||
case nir_intrinsic_load_deref:
|
||||
/* Uniform or UBO load.
|
||||
* Set a low cost to balance the number of scalar loads and ALUs.
|
||||
*/
|
||||
return 3 * num_dst_dwords;
|
||||
|
||||
default:
|
||||
unreachable("unexpected intrinsic");
|
||||
}
|
||||
|
||||
default:
|
||||
unreachable("unexpected instr type");
|
||||
}
|
||||
return ac_nir_varying_expression_max_cost(producer, consumer);
|
||||
}
|
||||
|
||||
|
||||
@@ -1696,5 +1581,5 @@ void si_init_screen_get_functions(struct si_screen *sscreen)
|
||||
BITFIELD_BIT(MESA_SHADER_TESS_EVAL);
|
||||
options->support_indirect_outputs = BITFIELD_BIT(MESA_SHADER_TESS_CTRL);
|
||||
options->varying_expression_max_cost = si_varying_expression_max_cost;
|
||||
options->varying_estimate_instr_cost = si_varying_estimate_instr_cost;
|
||||
options->varying_estimate_instr_cost = ac_nir_varying_estimate_instr_cost;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user