ir3: Plumb through ray_intersection intrinsic

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28447>
This commit is contained in:
Connor Abbott 2024-03-15 10:41:49 -04:00 committed by Marge Bot
parent 91f19bcbe0
commit 2d45836c95
5 changed files with 47 additions and 1 deletions

View file

@ -699,7 +699,8 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
case nir_intrinsic_load_const_ir3:
case nir_intrinsic_load_frag_size_ir3:
case nir_intrinsic_load_frag_offset_ir3:
case nir_intrinsic_bindless_resource_ir3: {
case nir_intrinsic_bindless_resource_ir3:
case nir_intrinsic_ray_intersection_ir3: {
unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs;
for (unsigned i = 0; i < num_srcs; i++) {
if (src_divergent(instr->src[i], state)) {

View file

@ -1363,6 +1363,12 @@ intrinsic("ssbo_atomic_swap_ir3", src_comp=[1, 1, 1, 1, 1], dest_comp=1,
load("uav_ir3", [1, 2],
indices=[ACCESS, ALIGN_MUL, ALIGN_OFFSET], flags=[CAN_ELIMINATE])
# IR3 intrinsic for "ray_intersection" instruction.
# The input and output arguments are the same as the instruction.
# See https://gitlab.freedesktop.org/freedreno/freedreno/-/wikis/a7xx-ray-tracing
intrinsic("ray_intersection_ir3", src_comp=[2, 1, 8, 1], dest_comp=5,
flags=[CAN_REORDER, CAN_ELIMINATE])
# System values for freedreno geometry shaders.
system_value("vs_primitive_stride_ir3", 1)
system_value("vs_vertex_stride_ir3", 1)

View file

@ -1192,6 +1192,7 @@ is_load(struct ir3_instruction *instr)
case OPC_L2G:
case OPC_LDLW:
case OPC_LDLV:
case OPC_RAY_INTERSECTION:
/* probably some others too.. */
return true;
case OPC_LDC:
@ -3031,6 +3032,7 @@ INSTR4(ATOMIC_S_OR)
INSTR4(ATOMIC_S_XOR)
#endif
INSTR4NODST(LDG_K)
INSTR5(RAY_INTERSECTION)
/* cat7 instructions: */
INSTR0(BAR)

View file

@ -2609,6 +2609,32 @@ emit_shfl(struct ir3_context *ctx, nir_intrinsic_instr *intr)
return shfl;
}
static void
emit_ray_intersection(struct ir3_context *ctx, nir_intrinsic_instr *intr,
struct ir3_instruction **dst)
{
struct ir3_builder *b = &ctx->build;
struct ir3_instruction *bvh_base =
ir3_create_collect(b, ir3_get_src(ctx, &intr->src[0]), 2);
struct ir3_instruction *idx = ir3_get_src(ctx, &intr->src[1])[0];
struct ir3_instruction *ray_info =
ir3_create_collect(b, ir3_get_src(ctx, &intr->src[2]), 8);
struct ir3_instruction *flags = ir3_get_src(ctx, &intr->src[3])[0];
struct ir3_instruction *dst_init =
ir3_collect(b, NULL, NULL, NULL, create_immed(b, 0), NULL);
struct ir3_instruction *ray_intersection =
ir3_RAY_INTERSECTION(b, bvh_base, 0, idx, 0, ray_info, 0, flags, 0,
dst_init, 0);
ray_intersection->dsts[0]->wrmask = MASK(5);
ir3_reg_tie(ray_intersection->dsts[0], ray_intersection->srcs[4]);
ir3_split_dest(b, dst, ray_intersection, 0, 5);
}
static void setup_input(struct ir3_context *ctx, nir_intrinsic_instr *intr);
static void setup_output(struct ir3_context *ctx, nir_intrinsic_instr *intr);
@ -3417,6 +3443,9 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
case nir_intrinsic_shuffle_xor_uniform_ir3:
dst[0] = emit_shfl(ctx, intr);
break;
case nir_intrinsic_ray_intersection_ir3:
emit_ray_intersection(ctx, intr, dst);
break;
default:
ir3_context_error(ctx, "Unhandled intrinsic type: %s\n",
nir_intrinsic_infos[intr->intrinsic].name);

View file

@ -483,6 +483,14 @@ validate_instr(struct ir3_validate_ctx *ctx, struct ir3_instruction *instr)
validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
break;
case OPC_RAY_INTERSECTION:
validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));
validate_assert(ctx, !(instr->srcs[1]->flags & IR3_REG_HALF));
validate_assert(ctx, !(instr->srcs[2]->flags & IR3_REG_HALF));
validate_assert(ctx, !(instr->srcs[3]->flags & IR3_REG_HALF));
validate_assert(ctx, !(instr->srcs[4]->flags & IR3_REG_HALF));
validate_assert(ctx, !(instr->dsts[0]->flags & IR3_REG_HALF));
break;
default:
validate_reg_size(ctx, instr->dsts[0], instr->cat6.type);
validate_assert(ctx, !(instr->srcs[0]->flags & IR3_REG_HALF));