Path: blob/master/thirdparty/embree/kernels/geometry/curveNv_intersector.h
9905 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "curveNv.h"6#include "curveNi_intersector.h"78namespace embree9{10namespace isa11{12template<int M>13struct CurveNvIntersector1 : public CurveNiIntersector1<M>14{15typedef CurveNv<M> Primitive;16typedef CurvePrecalculations1 Precalculations;1718template<typename Intersector, typename Epilog>19static __forceinline void intersect_t(const Precalculations& pre, RayHit& ray, RayQueryContext* context, const Primitive& prim)20{21vfloat<M> tNear;22vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear);2324const size_t N = prim.N;25size_t mask = movemask(valid);26while (mask)27{28const size_t i = bscf(mask);29STAT3(normal.trav_prims,1,1,1);30const unsigned int geomID = prim.geomID(N);31const unsigned int primID = prim.primID(N)[i];32const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);33const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);34const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);35const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);36const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);3738size_t mask1 = mask;39const size_t i1 = bscf(mask1);40if (mask) {41prefetchL1(&prim.vertices(i1,N)[0]);42prefetchL1(&prim.vertices(i1,N)[4]);43if (mask1) {44const size_t i2 = bsf(mask1);45prefetchL2(&prim.vertices(i2,N)[0]);46prefetchL2(&prim.vertices(i2,N)[4]);47}48}4950Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID));51mask &= movemask(tNear <= vfloat<M>(ray.tfar));52}53}5455template<typename Intersector, typename Epilog>56static __forceinline bool occluded_t(const Precalculations& pre, Ray& ray, RayQueryContext* context, const Primitive& prim)57{58vfloat<M> tNear;59vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear);6061const size_t N = prim.N;62size_t mask = movemask(valid);63while (mask)64{65const size_t i = bscf(mask);66STAT3(shadow.trav_prims,1,1,1);67const unsigned int geomID = prim.geomID(N);68const unsigned int primID = prim.primID(N)[i];69const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);70const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);71const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);72const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);73const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);7475size_t mask1 = mask;76const size_t i1 = bscf(mask1);77if (mask) {78prefetchL1(&prim.vertices(i1,N)[0]);79prefetchL1(&prim.vertices(i1,N)[4]);80if (mask1) {81const size_t i2 = bsf(mask1);82prefetchL2(&prim.vertices(i2,N)[0]);83prefetchL2(&prim.vertices(i2,N)[4]);84}85}8687if (Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID)))88return true;8990mask &= movemask(tNear <= vfloat<M>(ray.tfar));91}92return false;93}94};9596template<int M, int K>97struct CurveNvIntersectorK : public CurveNiIntersectorK<M,K>98{99typedef CurveNv<M> Primitive;100typedef CurvePrecalculationsK<K> Precalculations;101102template<typename Intersector, typename Epilog>103static __forceinline void intersect_t(Precalculations& pre, RayHitK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)104{105vfloat<M> tNear;106vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear);107108const size_t N = prim.N;109size_t mask = movemask(valid);110while (mask)111{112const size_t i = bscf(mask);113STAT3(normal.trav_prims,1,1,1);114const unsigned int geomID = prim.geomID(N);115const unsigned int primID = prim.primID(N)[i];116const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);117const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);118const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);119const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);120const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);121122size_t mask1 = mask;123const size_t i1 = bscf(mask1);124if (mask) {125prefetchL1(&prim.vertices(i1,N)[0]);126prefetchL1(&prim.vertices(i1,N)[4]);127if (mask1) {128const size_t i2 = bsf(mask1);129prefetchL2(&prim.vertices(i2,N)[0]);130prefetchL2(&prim.vertices(i2,N)[4]);131}132}133134Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID));135mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));136}137}138139template<typename Intersector, typename Epilog>140static __forceinline bool occluded_t(Precalculations& pre, RayK<K>& ray, const size_t k, RayQueryContext* context, const Primitive& prim)141{142vfloat<M> tNear;143vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear);144145const size_t N = prim.N;146size_t mask = movemask(valid);147while (mask)148{149const size_t i = bscf(mask);150STAT3(shadow.trav_prims,1,1,1);151const unsigned int geomID = prim.geomID(N);152const unsigned int primID = prim.primID(N)[i];153const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);154const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);155const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);156const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);157const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);158159size_t mask1 = mask;160const size_t i1 = bscf(mask1);161if (mask) {162prefetchL1(&prim.vertices(i1,N)[0]);163prefetchL1(&prim.vertices(i1,N)[4]);164if (mask1) {165const size_t i2 = bsf(mask1);166prefetchL2(&prim.vertices(i2,N)[0]);167prefetchL2(&prim.vertices(i2,N)[4]);168}169}170171if (Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID)))172return true;173174mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));175}176return false;177}178};179}180}181182183