287 lines
11 KiB
C++
287 lines
11 KiB
C++
// Copyright 2009-2021 Intel Corporation
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
#include "rttrace_validation.h"
|
|
|
|
#define sizeof_QBVH6_InternalNode6 64
|
|
#define QBVH6_rootNodeOffset 128
|
|
|
|
/*struct rayquery_impl_t {
|
|
rtfence_t fence;
|
|
rtglobals_t dispatchGlobalsPtr;
|
|
struct RTStack* rtStack;
|
|
TraceRayCtrl ctrl;
|
|
unsigned int bvh_level;
|
|
};*/
|
|
|
|
void use_rthwif_production()
|
|
{
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_raytracing_ext_flag_t intel_get_raytracing_ext_flag()
|
|
{
|
|
return intel_raytracing_ext_flag_ray_query;
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_ray_query_t intel_ray_query_init(intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel_i )
|
|
{
|
|
unsigned int bvh_level = 0;
|
|
|
|
//intel_raytracing_acceleration_structure_t* accel_i = sycl::global_ptr<intel_raytracing_acceleration_structure_t>(_accel_i).get();
|
|
HWAccel* accel = (HWAccel*)accel_i;
|
|
#if defined(EMBREE_SYCL_ALLOC_DISPATCH_GLOBALS)
|
|
rtglobals_t dispatchGlobalsPtr = (rtglobals_t) accel->dispatchGlobalsPtr;
|
|
#else
|
|
rtglobals_t dispatchGlobalsPtr = (rtglobals_t) intel_get_implicit_dispatch_globals();
|
|
#endif
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)intel_get_rt_stack( (rtglobals_t)dispatchGlobalsPtr )).get();
|
|
|
|
/* init ray */
|
|
rtStack->ray[bvh_level].init(ray,(uint64_t)accel + QBVH6_rootNodeOffset);
|
|
|
|
rtStack->committedHit.setT(INFINITY);
|
|
rtStack->committedHit.setU(0.0f);
|
|
rtStack->committedHit.setV(0.0f);
|
|
rtStack->committedHit.data = 0;
|
|
|
|
rtStack->potentialHit.setT(INFINITY);
|
|
rtStack->potentialHit.setU(0.0f);
|
|
rtStack->potentialHit.setV(0.0f);
|
|
rtStack->potentialHit.data = 0;
|
|
rtStack->potentialHit.done = 1;
|
|
rtStack->potentialHit.valid = 1;
|
|
|
|
return { nullptr, (void*) dispatchGlobalsPtr, rtStack, TRACE_RAY_INITIAL, bvh_level };
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_ray_query_forward_ray( intel_ray_query_t& query, intel_ray_desc_t ray, intel_raytracing_acceleration_structure_t accel_i)
|
|
{
|
|
HWAccel* accel = (HWAccel*)accel_i;
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
|
|
/* init ray */
|
|
unsigned int bvh_level = query.bvh_level+1;
|
|
rtStack->ray[bvh_level].init(ray,(uint64_t)accel + QBVH6_rootNodeOffset);
|
|
query = { nullptr, query.opaque1, query.opaque2, TRACE_RAY_INSTANCE, bvh_level };
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_ray_query_commit_potential_hit( intel_ray_query_t& query )
|
|
{
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
|
|
unsigned int bvh_level = query.bvh_level;
|
|
unsigned int rflags = rtStack->ray[bvh_level].rayFlags;
|
|
if (rflags & intel_ray_flags_accept_first_hit_and_end_search) {
|
|
rtStack->committedHit = rtStack->potentialHit;
|
|
rtStack->committedHit.valid = 1;
|
|
query = { nullptr, query.opaque1, query.opaque2, TRACE_RAY_DONE, bvh_level };
|
|
} else {
|
|
rtStack->potentialHit.valid = 1; // FIXME: is this required?
|
|
query = { nullptr, query.opaque1, query.opaque2, TRACE_RAY_COMMIT, bvh_level };
|
|
}
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_ray_query_commit_potential_hit_override( intel_ray_query_t& query, float override_hit_distance, intel_float2 override_uv )
|
|
{
|
|
//struct RTStack* rtStack = (struct RTStack*) query.opaque2;
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
|
|
rtStack->potentialHit.setT(override_hit_distance);
|
|
rtStack->potentialHit.setU(override_uv.x);
|
|
rtStack->potentialHit.setV(override_uv.y);
|
|
intel_ray_query_commit_potential_hit(query);
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_ray_query_start_traversal( intel_ray_query_t& query )
|
|
{
|
|
rtglobals_t dispatchGlobalsPtr = (rtglobals_t) query.opaque1;
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
|
|
rtStack->potentialHit.done = 1;
|
|
rtStack->potentialHit.valid = 1;
|
|
|
|
if (query.ctrl == TRACE_RAY_DONE) return;
|
|
rtfence_t fence = intel_dispatch_trace_ray_query(dispatchGlobalsPtr,query.bvh_level,query.ctrl);
|
|
query = { (void*) fence, query.opaque1, query.opaque2, TRACE_RAY_INITIAL, 0 };
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_ray_query_sync( intel_ray_query_t& query )
|
|
{
|
|
intel_rt_sync((rtfence_t)query.opaque0);
|
|
|
|
/* continue is default behaviour */
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
|
|
unsigned int bvh_level = rtStack->potentialHit.bvhLevel;
|
|
query = { query.opaque0, query.opaque1, query.opaque2, TRACE_RAY_CONTINUE, bvh_level };
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_sync_ray_query( intel_ray_query_t& query )
|
|
{
|
|
intel_rt_sync((rtfence_t)query.opaque0);
|
|
|
|
/* continue is default behaviour */
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
|
|
unsigned int bvh_level = rtStack->potentialHit.bvhLevel;
|
|
query = { query.opaque0, query.opaque1, query.opaque2, TRACE_RAY_CONTINUE, bvh_level };
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_ray_query_abandon( intel_ray_query_t& query )
|
|
{
|
|
intel_ray_query_sync(query);
|
|
query = { nullptr, nullptr, nullptr, TRACE_RAY_INITIAL, 0 };
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_hit_bvh_level( intel_ray_query_t& query, intel_hit_type_t hit_type ) {
|
|
return query.hit(hit_type).bvhLevel;
|
|
}
|
|
|
|
SYCL_EXTERNAL float intel_get_hit_distance( intel_ray_query_t& query, intel_hit_type_t hit_type ) {
|
|
return query.hit(hit_type).getT();
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_float2 intel_get_hit_barycentrics( intel_ray_query_t& query, intel_hit_type_t hit_type ) {
|
|
return { query.hit(hit_type).getU(), query.hit(hit_type).getV() };
|
|
}
|
|
|
|
SYCL_EXTERNAL bool intel_get_hit_front_face( intel_ray_query_t& query, intel_hit_type_t hit_type ) {
|
|
return query.hit(hit_type).frontFace;
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_hit_geometry_id(intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
struct PrimLeafDesc* __restrict leaf = (struct PrimLeafDesc*)query.hit(hit_type).getPrimLeafPtr();
|
|
return leaf->geomIndex;
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_hit_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
MemHit& hit = query.hit(hit_type);
|
|
void* __restrict leaf = hit.getPrimLeafPtr();
|
|
|
|
if (hit.leafType == NODE_TYPE_QUAD)
|
|
return ((QuadLeaf*)leaf)->primIndex0 + hit.primIndexDelta;
|
|
else
|
|
return ((ProceduralLeaf*)leaf)->_primIndex[hit.primLeafIndex];
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_hit_triangle_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
MemHit& hit = query.hit(hit_type);
|
|
QuadLeaf* __restrict leaf = (QuadLeaf*) hit.getPrimLeafPtr();
|
|
|
|
return leaf->primIndex0 + hit.primIndexDelta;
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_hit_procedural_primitive_id( intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
MemHit& hit = query.hit(hit_type);
|
|
ProceduralLeaf* __restrict leaf = (ProceduralLeaf*) hit.getPrimLeafPtr();
|
|
return leaf->_primIndex[hit.primLeafIndex];
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_hit_instance_id( intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
MemHit& hit = query.hit(hit_type);
|
|
InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr();
|
|
if (leaf == nullptr) return -1;
|
|
return leaf->part1.instanceIndex;
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_hit_instance_user_id( intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
MemHit& hit = query.hit(hit_type);
|
|
InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr();
|
|
if (leaf == nullptr) return -1;
|
|
return leaf->part1.instanceID;
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_float4x3 intel_get_hit_world_to_object( intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
MemHit& hit = query.hit(hit_type);
|
|
InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr();
|
|
if (leaf == nullptr) return { { 1,0,0 }, { 0,1,0 }, { 0,0,1 }, { 0,0,0 } };
|
|
return {
|
|
{ leaf->part0.world2obj_vx[0], leaf->part0.world2obj_vx[1], leaf->part0.world2obj_vx[2] },
|
|
{ leaf->part0.world2obj_vy[0], leaf->part0.world2obj_vy[1], leaf->part0.world2obj_vy[2] },
|
|
{ leaf->part0.world2obj_vz[0], leaf->part0.world2obj_vz[1], leaf->part0.world2obj_vz[2] },
|
|
{ leaf->part1.world2obj_p [0], leaf->part1.world2obj_p [1], leaf->part1.world2obj_p [2] }
|
|
};
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_float4x3 intel_get_hit_object_to_world( intel_ray_query_t& query, intel_hit_type_t hit_type )
|
|
{
|
|
MemHit& hit = query.hit(hit_type);
|
|
InstanceLeaf* __restrict leaf = (InstanceLeaf*) hit.getInstanceLeafPtr();
|
|
if (leaf == nullptr) return { { 1,0,0 }, { 0,1,0 }, { 0,0,1 }, { 0,0,0 } };
|
|
return {
|
|
{ leaf->part1.obj2world_vx[0], leaf->part1.obj2world_vx[1], leaf->part1.obj2world_vx[2] },
|
|
{ leaf->part1.obj2world_vy[0], leaf->part1.obj2world_vy[1], leaf->part1.obj2world_vy[2] },
|
|
{ leaf->part1.obj2world_vz[0], leaf->part1.obj2world_vz[1], leaf->part1.obj2world_vz[2] },
|
|
{ leaf->part0.obj2world_p [0], leaf->part0.obj2world_p [1], leaf->part0.obj2world_p [2] }
|
|
};
|
|
}
|
|
|
|
SYCL_EXTERNAL void intel_get_hit_triangle_vertices( intel_ray_query_t& query, intel_float3 verts_out[3], intel_hit_type_t hit_type )
|
|
{
|
|
const QuadLeaf* __restrict leaf = (const QuadLeaf*) query.hit(hit_type).getPrimLeafPtr();
|
|
|
|
unsigned int j0 = 0, j1 = 1, j2 = 2;
|
|
if (query.hit(hit_type).primLeafIndex != 0)
|
|
{
|
|
j0 = leaf->j0;
|
|
j1 = leaf->j1;
|
|
j2 = leaf->j2;
|
|
}
|
|
|
|
verts_out[0] = { leaf->v[j0][0], leaf->v[j0][1], leaf->v[j0][2] };
|
|
verts_out[1] = { leaf->v[j1][0], leaf->v[j1][1], leaf->v[j1][2] };
|
|
verts_out[2] = { leaf->v[j2][0], leaf->v[j2][1], leaf->v[j2][2] };
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_float3 intel_get_ray_origin( intel_ray_query_t& query, unsigned int bvh_level)
|
|
{
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
|
|
MemRay& ray = rtStack->ray[bvh_level];
|
|
return { ray.org[0], ray.org[1], ray.org[2] };
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_float3 intel_get_ray_direction( intel_ray_query_t& query, unsigned int bvh_level)
|
|
{
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
MemRay& ray = rtStack->ray[bvh_level];
|
|
return { ray.dir[0], ray.dir[1], ray.dir[2] };
|
|
}
|
|
|
|
SYCL_EXTERNAL float intel_get_ray_tmin( intel_ray_query_t& query, unsigned int bvh_level)
|
|
{
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
return rtStack->ray[bvh_level].tnear;
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_ray_flags_t intel_get_ray_flags( intel_ray_query_t& query, unsigned int bvh_level)
|
|
{
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
return (intel_ray_flags_t) rtStack->ray[bvh_level].rayFlags;
|
|
}
|
|
|
|
SYCL_EXTERNAL unsigned int intel_get_ray_mask( intel_ray_query_t& query, unsigned int bvh_level)
|
|
{
|
|
struct RTStack* __restrict rtStack = sycl::global_ptr<RTStack>((struct RTStack*)query.opaque2).get();
|
|
return rtStack->ray[bvh_level].rayMask;
|
|
}
|
|
|
|
SYCL_EXTERNAL bool intel_is_traversal_done( intel_ray_query_t& query ) {
|
|
return query.hit(intel_hit_type_potential_hit).done;
|
|
}
|
|
|
|
SYCL_EXTERNAL intel_candidate_type_t intel_get_hit_candidate( intel_ray_query_t& query, intel_hit_type_t hit_type) {
|
|
return query.hit(hit_type).leafType == NODE_TYPE_QUAD ? intel_candidate_type_triangle : intel_candidate_type_procedural;
|
|
}
|
|
|
|
SYCL_EXTERNAL bool intel_has_committed_hit( intel_ray_query_t& query ) {
|
|
return query.hit(intel_hit_type_committed_hit).valid;
|
|
}
|
|
|