virtualx-engine/thirdparty/embree/kernels/geometry/curveNv_intersector.h
jfons a69cc9f13d
Upgrade Embree to the latest official release.
Since Embree v3.13.0 supports AARCH64, switch back to the
official repo instead of using Embree-aarch64.

`thirdparty/embree/patches/godot-changes.patch` should now contain
an accurate diff of the changes done to the library.

(cherry picked from commit 767e374dce)
2021-05-22 15:14:07 +02:00

181 lines
6.7 KiB
C++

// Copyright 2009-2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include "curveNv.h"
#include "curveNi_intersector.h"
namespace embree
{
namespace isa
{
template<int M>
struct CurveNvIntersector1 : public CurveNiIntersector1<M>
{
typedef CurveNv<M> Primitive;
typedef CurvePrecalculations1 Precalculations;
template<typename Intersector, typename Epilog>
static __forceinline void intersect_t(const Precalculations& pre, RayHit& ray, IntersectContext* context, const Primitive& prim)
{
vfloat<M> tNear;
vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear);
const size_t N = prim.N;
size_t mask = movemask(valid);
while (mask)
{
const size_t i = bscf(mask);
STAT3(normal.trav_prims,1,1,1);
const unsigned int geomID = prim.geomID(N);
const unsigned int primID = prim.primID(N)[i];
const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
size_t mask1 = mask;
const size_t i1 = bscf(mask1);
if (mask) {
prefetchL1(&prim.vertices(i1,N)[0]);
prefetchL1(&prim.vertices(i1,N)[4]);
if (mask1) {
const size_t i2 = bsf(mask1);
prefetchL2(&prim.vertices(i2,N)[0]);
prefetchL2(&prim.vertices(i2,N)[4]);
}
}
Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID));
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
}
}
template<typename Intersector, typename Epilog>
static __forceinline bool occluded_t(const Precalculations& pre, Ray& ray, IntersectContext* context, const Primitive& prim)
{
vfloat<M> tNear;
vbool<M> valid = CurveNiIntersector1<M>::intersect(ray,prim,tNear);
const size_t N = prim.N;
size_t mask = movemask(valid);
while (mask)
{
const size_t i = bscf(mask);
STAT3(shadow.trav_prims,1,1,1);
const unsigned int geomID = prim.geomID(N);
const unsigned int primID = prim.primID(N)[i];
const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
size_t mask1 = mask;
const size_t i1 = bscf(mask1);
if (mask) {
prefetchL1(&prim.vertices(i1,N)[0]);
prefetchL1(&prim.vertices(i1,N)[4]);
if (mask1) {
const size_t i2 = bsf(mask1);
prefetchL2(&prim.vertices(i2,N)[0]);
prefetchL2(&prim.vertices(i2,N)[4]);
}
}
if (Intersector().intersect(pre,ray,context,geom,primID,a0,a1,a2,a3,Epilog(ray,context,geomID,primID)))
return true;
mask &= movemask(tNear <= vfloat<M>(ray.tfar));
}
return false;
}
};
template<int M, int K>
struct CurveNvIntersectorK : public CurveNiIntersectorK<M,K>
{
typedef CurveNv<M> Primitive;
typedef CurvePrecalculationsK<K> Precalculations;
template<typename Intersector, typename Epilog>
static __forceinline void intersect_t(Precalculations& pre, RayHitK<K>& ray, const size_t k, IntersectContext* context, const Primitive& prim)
{
vfloat<M> tNear;
vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear);
const size_t N = prim.N;
size_t mask = movemask(valid);
while (mask)
{
const size_t i = bscf(mask);
STAT3(normal.trav_prims,1,1,1);
const unsigned int geomID = prim.geomID(N);
const unsigned int primID = prim.primID(N)[i];
const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
size_t mask1 = mask;
const size_t i1 = bscf(mask1);
if (mask) {
prefetchL1(&prim.vertices(i1,N)[0]);
prefetchL1(&prim.vertices(i1,N)[4]);
if (mask1) {
const size_t i2 = bsf(mask1);
prefetchL2(&prim.vertices(i2,N)[0]);
prefetchL2(&prim.vertices(i2,N)[4]);
}
}
Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID));
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
}
}
template<typename Intersector, typename Epilog>
static __forceinline bool occluded_t(Precalculations& pre, RayK<K>& ray, const size_t k, IntersectContext* context, const Primitive& prim)
{
vfloat<M> tNear;
vbool<M> valid = CurveNiIntersectorK<M,K>::intersect(ray,k,prim,tNear);
const size_t N = prim.N;
size_t mask = movemask(valid);
while (mask)
{
const size_t i = bscf(mask);
STAT3(shadow.trav_prims,1,1,1);
const unsigned int geomID = prim.geomID(N);
const unsigned int primID = prim.primID(N)[i];
const CurveGeometry* geom = (CurveGeometry*) context->scene->get(geomID);
const Vec3ff a0 = Vec3ff::loadu(&prim.vertices(i,N)[0]);
const Vec3ff a1 = Vec3ff::loadu(&prim.vertices(i,N)[1]);
const Vec3ff a2 = Vec3ff::loadu(&prim.vertices(i,N)[2]);
const Vec3ff a3 = Vec3ff::loadu(&prim.vertices(i,N)[3]);
size_t mask1 = mask;
const size_t i1 = bscf(mask1);
if (mask) {
prefetchL1(&prim.vertices(i1,N)[0]);
prefetchL1(&prim.vertices(i1,N)[4]);
if (mask1) {
const size_t i2 = bsf(mask1);
prefetchL2(&prim.vertices(i2,N)[0]);
prefetchL2(&prim.vertices(i2,N)[4]);
}
}
if (Intersector().intersect(pre,ray,k,context,geom,primID,a0,a1,a2,a3,Epilog(ray,k,context,geomID,primID)))
return true;
mask &= movemask(tNear <= vfloat<M>(ray.tfar[k]));
}
return false;
}
};
}
}