radv: Add radv_nir_lower_hit_attrib_derefs_tests

Tests hit attrib lowering for various variable/type configurations.

Reviewed-by: Friedrich Vock <friedrich.vock@gmx.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24271>
This commit is contained in:
Konstantin Seurer 2023-07-21 11:56:43 +02:00 committed by Marge Bot
parent f51227d253
commit 11282598e6
2 changed files with 267 additions and 0 deletions

View file

@ -277,3 +277,34 @@ _dev_icd = custom_target(
)
devenv.append('VK_ICD_FILENAMES', _dev_icd.full_path())
if with_tests
test(
'radv_tests',
executable(
'radv_tests',
files(
'nir/radv_nir_lower_hit_attrib_derefs.c',
'tests/radv_nir_lower_hit_attrib_derefs_tests.cpp',
),
cpp_args : [cpp_msvc_compat_args],
gnu_symbol_visibility : 'hidden',
include_directories : [
inc_include,
inc_src,
inc_mapi,
inc_mesa,
inc_gallium,
inc_gallium_aux,
inc_amd,
inc_amd_common,
inc_compiler,
inc_util,
include_directories('.'),
],
dependencies : [dep_thread, idep_gtest, idep_nir, idep_mesautil],
),
suite : ['compiler', 'nir'],
protocol : 'gtest',
)
endif

View file

@ -0,0 +1,236 @@
/*
* Copyright © 2023 Valve Corporation
* SPDX-License-Identifier: MIT
*/
#include "nir/radv_nir.h"
#include "tests/nir_test.h"
#include "radv_constants.h"
class radv_nir_lower_hit_attrib_derefs_test : public nir_test {
protected:
radv_nir_lower_hit_attrib_derefs_test(): nir_test("radv_nir_lower_hit_attrib_derefs_test")
{
b->shader->info.stage = MESA_SHADER_INTERSECTION;
}
void validate(uint32_t used_bits[RADV_MAX_HIT_ATTRIB_DWORDS], uint32_t used_dwords, bool constant_fold);
};
void
radv_nir_lower_hit_attrib_derefs_test::validate(uint32_t used_bits[RADV_MAX_HIT_ATTRIB_DWORDS], uint32_t used_dwords,
bool constant_fold)
{
EXPECT_TRUE(radv_nir_lower_hit_attrib_derefs(b->shader));
nir_validate_shader(b->shader, "After radv_nir_lower_hit_attrib_derefs");
srand(918763498);
uint32_t values[RADV_MAX_HIT_ATTRIB_DWORDS];
for (uint32_t i = 0; i < ARRAY_SIZE(values); i++)
values[i] = ((uint32_t)rand() ^ ((uint32_t)rand() << 1)) & used_bits[i];
nir_function_impl *impl = nir_shader_get_entrypoint(b->shader);
if (constant_fold) {
nir_foreach_block (block, impl) {
nir_foreach_instr_safe (instr, block) {
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic != nir_intrinsic_load_hit_attrib_amd)
continue;
b->cursor = nir_after_instr(instr);
nir_def *value = nir_imm_int(b, values[nir_intrinsic_base(intr)]);
nir_def_rewrite_uses(&intr->def, value);
}
}
NIR_PASS(_, b->shader, nir_opt_constant_folding);
}
NIR_PASS(_, b->shader, nir_opt_dce);
uint32_t stored_dwords = 0;
nir_foreach_block (block, impl) {
nir_foreach_instr_safe (instr, block) {
/* Make sure that all ray_hit_attrib variables have been lowered. */
if (instr->type == nir_instr_type_deref) {
EXPECT_FALSE(nir_deref_mode_is(nir_instr_as_deref(instr), nir_var_ray_hit_attrib));
}
if (instr->type != nir_instr_type_intrinsic)
continue;
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
if (intr->intrinsic != nir_intrinsic_store_hit_attrib_amd)
continue;
uint32_t base = nir_intrinsic_base(intr);
EXPECT_LT(base, RADV_MAX_HIT_ATTRIB_DWORDS);
stored_dwords |= BITFIELD_BIT(base);
bool is_const = nir_src_is_const(intr->src[0]);
EXPECT_TRUE(is_const || !constant_fold);
if (!is_const)
continue;
uint32_t src = nir_src_as_uint(intr->src[0]);
EXPECT_EQ(src, values[base] & used_bits[base]);
}
}
EXPECT_EQ(stored_dwords, used_dwords);
}
TEST_F(radv_nir_lower_hit_attrib_derefs_test, types)
{
nir_variable *vec3_var = nir_variable_create(b->shader, nir_var_ray_hit_attrib, glsl_vec_type(3), "vec3");
nir_variable *uint64_var = nir_variable_create(b->shader, nir_var_ray_hit_attrib, glsl_uint64_t_type(), "uint64_t");
nir_variable *uint16_var = nir_variable_create(b->shader, nir_var_ray_hit_attrib, glsl_uint16_t_type(), "uint16_t");
nir_variable *uint8_var = nir_variable_create(b->shader, nir_var_ray_hit_attrib, glsl_uint8_t_type(), "uint8_t");
nir_variable *bool_var = nir_variable_create(b->shader, nir_var_ray_hit_attrib, glsl_bool_type(), "bool");
nir_variable *vars[5] = {
vec3_var, uint64_var, uint16_var, uint8_var, bool_var,
};
for (uint32_t i = 0; i < ARRAY_SIZE(vars); i++) {
nir_def *load = nir_load_var(b, vars[i]);
nir_store_var(b, vars[i], load, (1 << load->num_components) - 1);
}
uint32_t masks[RADV_MAX_HIT_ATTRIB_DWORDS] = {
/* vec3 */
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
/* padding */
0,
/* uint64_t */
0xFFFFFFFF,
0xFFFFFFFF,
/* uint16_t uint8_t */
0xFFFFFFFF,
/* bool */
1,
};
validate(masks, 0b11110111, true);
}
TEST_F(radv_nir_lower_hit_attrib_derefs_test, array)
{
nir_variable *array_var =
nir_variable_create(b->shader, nir_var_ray_hit_attrib,
glsl_array_type(glsl_uint_type(), RADV_MAX_HIT_ATTRIB_DWORDS, 0), "uint32_t[]");
for (uint32_t i = 0; i < RADV_MAX_HIT_ATTRIB_DWORDS; i++) {
nir_def *load = nir_load_array_var_imm(b, array_var, i);
nir_store_array_var_imm(b, array_var, i, load, 0x1);
}
uint32_t masks[RADV_MAX_HIT_ATTRIB_DWORDS] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
};
validate(masks, 0xFF, true);
}
TEST_F(radv_nir_lower_hit_attrib_derefs_test, dynamic_array)
{
nir_variable *array_var =
nir_variable_create(b->shader, nir_var_ray_hit_attrib,
glsl_array_type(glsl_uint_type(), RADV_MAX_HIT_ATTRIB_DWORDS, 0), "uint32_t[]");
nir_def *index = nir_load_local_invocation_index(b);
nir_def *load = nir_load_array_var(b, array_var, index);
nir_store_array_var(b, array_var, index, load, 0x1);
uint32_t masks[RADV_MAX_HIT_ATTRIB_DWORDS] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
};
validate(masks, 0xFF, false);
}
TEST_F(radv_nir_lower_hit_attrib_derefs_test, struct)
{
glsl_struct_field fields[5] = {
glsl_struct_field(glsl_vec_type(3), "vec3"), glsl_struct_field(glsl_uint64_t_type(), "uint64_t"),
glsl_struct_field(glsl_uint16_t_type(), "uint16_t"), glsl_struct_field(glsl_uint8_t_type(), "uint8_t"),
glsl_struct_field(glsl_bool_type(), "bool"),
};
const glsl_type *var_type = glsl_struct_type(fields, ARRAY_SIZE(fields), "hit_attrib_struct", false);
nir_variable *struct_var = nir_variable_create(b->shader, nir_var_ray_hit_attrib, var_type, "hit_attrib_struct");
nir_deref_instr *var_deref = nir_build_deref_var(b, struct_var);
for (uint32_t i = 0; i < ARRAY_SIZE(fields); i++) {
nir_deref_instr *member_deref = nir_build_deref_struct(b, var_deref, i);
nir_def *load = nir_load_deref(b, member_deref);
nir_store_deref(b, member_deref, load, (1 << load->num_components) - 1);
}
uint32_t masks[RADV_MAX_HIT_ATTRIB_DWORDS] = {
/* vec3 */
0xFFFFFFFF,
0xFFFFFFFF,
0xFFFFFFFF,
/* padding */
0,
/* uint64_t */
0xFFFFFFFF,
0xFFFFFFFF,
/* uint16_t uint8_t */
0xFFFFFFFF,
/* bool */
1,
};
validate(masks, 0b11110111, true);
}
TEST_F(radv_nir_lower_hit_attrib_derefs_test, array_inside_struct)
{
glsl_struct_field field =
glsl_struct_field(glsl_array_type(glsl_uint_type(), RADV_MAX_HIT_ATTRIB_DWORDS, 0), "array");
const glsl_type *var_type = glsl_struct_type(&field, 1, "hit_attrib_struct", false);
nir_variable *struct_var = nir_variable_create(b->shader, nir_var_ray_hit_attrib, var_type, "hit_attrib_struct");
nir_deref_instr *var_deref = nir_build_deref_var(b, struct_var);
nir_deref_instr *member_deref = nir_build_deref_struct(b, var_deref, 0);
for (uint32_t i = 0; i < RADV_MAX_HIT_ATTRIB_DWORDS; i++) {
nir_deref_instr *element_deref = nir_build_deref_array_imm(b, member_deref, i);
nir_def *load = nir_load_deref(b, element_deref);
nir_store_deref(b, element_deref, load, (1 << load->num_components) - 1);
}
uint32_t masks[RADV_MAX_HIT_ATTRIB_DWORDS] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
};
validate(masks, 0xFF, true);
}
TEST_F(radv_nir_lower_hit_attrib_derefs_test, struct_inside_array)
{
glsl_struct_field field = glsl_struct_field(glsl_uint_type(), "array");
const glsl_type *struct_type = glsl_struct_type(&field, 1, "hit_attrib_struct", false);
nir_variable *array_var =
nir_variable_create(b->shader, nir_var_ray_hit_attrib,
glsl_array_type(struct_type, RADV_MAX_HIT_ATTRIB_DWORDS, 0), "hit_attrib_struct[]");
nir_deref_instr *var_deref = nir_build_deref_var(b, array_var);
for (uint32_t i = 0; i < RADV_MAX_HIT_ATTRIB_DWORDS; i++) {
nir_deref_instr *element_deref = nir_build_deref_array_imm(b, var_deref, i);
nir_deref_instr *member_deref = nir_build_deref_struct(b, element_deref, 0);
nir_def *load = nir_load_deref(b, member_deref);
nir_store_deref(b, member_deref, load, (1 << load->num_components) - 1);
}
uint32_t masks[RADV_MAX_HIT_ATTRIB_DWORDS] = {
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
};
validate(masks, 0xFF, true);
}