You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
5.4 KiB
212 lines
5.4 KiB
#include "ir3_nir.h"
|
|
|
|
#include "nir.h"
|
|
#include "nir_builder.h"
|
|
#include "nir_search.h"
|
|
#include "nir_search_helpers.h"
|
|
|
|
/* What follows is NIR algebraic transform code for the following 2
|
|
* transforms:
|
|
* ('fsin', 'x@32') => ('fsin', ('fsub', ('fmul', 6.2831853, ('ffract', ('fadd', ('fmul', 0.15915494, 'x'), 0.5))), 3.14159265))
|
|
* ('fcos', 'x@32') => ('fcos', ('fsub', ('fmul', 6.2831853, ('ffract', ('fadd', ('fmul', 0.15915494, 'x'), 0.5))), 3.14159265))
|
|
*/
|
|
|
|
|
|
static const nir_search_variable search0_0 = {
|
|
{ nir_search_value_variable, 32 },
|
|
0, /* x */
|
|
false,
|
|
nir_type_invalid,
|
|
NULL,
|
|
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
|
|
};
|
|
static const nir_search_expression search0 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
-1, 0,
|
|
nir_op_fsin,
|
|
{ &search0_0.value },
|
|
NULL,
|
|
};
|
|
|
|
static const nir_search_constant replace0_0_0_0 = {
|
|
{ nir_search_value_constant, 32 },
|
|
nir_type_float, { 0x401921fb53c8d4f1 /* 6.2831853 */ },
|
|
};
|
|
|
|
static const nir_search_constant replace0_0_0_1_0_0_0 = {
|
|
{ nir_search_value_constant, 32 },
|
|
nir_type_float, { 0x3fc45f306725feed /* 0.15915494 */ },
|
|
};
|
|
|
|
/* replace0_0_0_1_0_0_1 -> search0_0 in the cache */
|
|
static const nir_search_expression replace0_0_0_1_0_0 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
2, 1,
|
|
nir_op_fmul,
|
|
{ &replace0_0_0_1_0_0_0.value, &search0_0.value },
|
|
NULL,
|
|
};
|
|
|
|
static const nir_search_constant replace0_0_0_1_0_1 = {
|
|
{ nir_search_value_constant, 32 },
|
|
nir_type_float, { 0x3fe0000000000000 /* 0.5 */ },
|
|
};
|
|
static const nir_search_expression replace0_0_0_1_0 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
1, 2,
|
|
nir_op_fadd,
|
|
{ &replace0_0_0_1_0_0.value, &replace0_0_0_1_0_1.value },
|
|
NULL,
|
|
};
|
|
static const nir_search_expression replace0_0_0_1 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
-1, 2,
|
|
nir_op_ffract,
|
|
{ &replace0_0_0_1_0.value },
|
|
NULL,
|
|
};
|
|
static const nir_search_expression replace0_0_0 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
0, 3,
|
|
nir_op_fmul,
|
|
{ &replace0_0_0_0.value, &replace0_0_0_1.value },
|
|
NULL,
|
|
};
|
|
|
|
static const nir_search_constant replace0_0_1 = {
|
|
{ nir_search_value_constant, 32 },
|
|
nir_type_float, { 0x400921fb53c8d4f1 /* 3.14159265 */ },
|
|
};
|
|
static const nir_search_expression replace0_0 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
-1, 3,
|
|
nir_op_fsub,
|
|
{ &replace0_0_0.value, &replace0_0_1.value },
|
|
NULL,
|
|
};
|
|
static const nir_search_expression replace0 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
-1, 3,
|
|
nir_op_fsin,
|
|
{ &replace0_0.value },
|
|
NULL,
|
|
};
|
|
|
|
/* search1_0 -> search0_0 in the cache */
|
|
static const nir_search_expression search1 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
-1, 0,
|
|
nir_op_fcos,
|
|
{ &search0_0.value },
|
|
NULL,
|
|
};
|
|
|
|
/* replace1_0_0_0 -> replace0_0_0_0 in the cache */
|
|
|
|
/* replace1_0_0_1_0_0_0 -> replace0_0_0_1_0_0_0 in the cache */
|
|
|
|
/* replace1_0_0_1_0_0_1 -> search0_0 in the cache */
|
|
/* replace1_0_0_1_0_0 -> replace0_0_0_1_0_0 in the cache */
|
|
|
|
/* replace1_0_0_1_0_1 -> replace0_0_0_1_0_1 in the cache */
|
|
/* replace1_0_0_1_0 -> replace0_0_0_1_0 in the cache */
|
|
/* replace1_0_0_1 -> replace0_0_0_1 in the cache */
|
|
/* replace1_0_0 -> replace0_0_0 in the cache */
|
|
|
|
/* replace1_0_1 -> replace0_0_1 in the cache */
|
|
/* replace1_0 -> replace0_0 in the cache */
|
|
static const nir_search_expression replace1 = {
|
|
{ nir_search_value_expression, 32 },
|
|
false, false,
|
|
-1, 3,
|
|
nir_op_fcos,
|
|
{ &replace0_0.value },
|
|
NULL,
|
|
};
|
|
|
|
|
|
static const struct transform ir3_nir_apply_trig_workarounds_state2_xforms[] = {
|
|
{ &search0, &replace0.value, 0 },
|
|
};
|
|
static const struct transform ir3_nir_apply_trig_workarounds_state3_xforms[] = {
|
|
{ &search1, &replace1.value, 0 },
|
|
};
|
|
|
|
static const struct per_op_table ir3_nir_apply_trig_workarounds_table[nir_num_search_ops] = {
|
|
[nir_op_fsin] = {
|
|
.filter = (uint16_t []) {
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
},
|
|
|
|
.num_filtered_states = 1,
|
|
.table = (uint16_t []) {
|
|
|
|
2,
|
|
},
|
|
},
|
|
[nir_op_fcos] = {
|
|
.filter = (uint16_t []) {
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
},
|
|
|
|
.num_filtered_states = 1,
|
|
.table = (uint16_t []) {
|
|
|
|
3,
|
|
},
|
|
},
|
|
};
|
|
|
|
const struct transform *ir3_nir_apply_trig_workarounds_transforms[] = {
|
|
NULL,
|
|
NULL,
|
|
ir3_nir_apply_trig_workarounds_state2_xforms,
|
|
ir3_nir_apply_trig_workarounds_state3_xforms,
|
|
};
|
|
|
|
const uint16_t ir3_nir_apply_trig_workarounds_transform_counts[] = {
|
|
0,
|
|
0,
|
|
(uint16_t)ARRAY_SIZE(ir3_nir_apply_trig_workarounds_state2_xforms),
|
|
(uint16_t)ARRAY_SIZE(ir3_nir_apply_trig_workarounds_state3_xforms),
|
|
};
|
|
|
|
bool
|
|
ir3_nir_apply_trig_workarounds(nir_shader *shader)
|
|
{
|
|
bool progress = false;
|
|
bool condition_flags[1];
|
|
const nir_shader_compiler_options *options = shader->options;
|
|
const shader_info *info = &shader->info;
|
|
(void) options;
|
|
(void) info;
|
|
|
|
condition_flags[0] = true;
|
|
|
|
nir_foreach_function(function, shader) {
|
|
if (function->impl) {
|
|
progress |= nir_algebraic_impl(function->impl, condition_flags,
|
|
ir3_nir_apply_trig_workarounds_transforms,
|
|
ir3_nir_apply_trig_workarounds_transform_counts,
|
|
ir3_nir_apply_trig_workarounds_table);
|
|
}
|
|
}
|
|
|
|
return progress;
|
|
}
|
|
|