Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
e6f5258
Started on batch API query methods
Waqar-ukaea Oct 30, 2025
4334524
Added a batch_ray_fire miniapp for extra testing
Waqar-ukaea Oct 30, 2025
1dbc734
Added test_cases for batch_ray_fire
Waqar-ukaea Nov 4, 2025
b388e66
Implemented batch_point_in_volume()
Waqar-ukaea Nov 5, 2025
c9af01e
Added a batch_point in volume miniapp for extra testing
Waqar-ukaea Nov 5, 2025
1025013
Added stress test for batch_ray_fire which calls over a batch of 10M …
Waqar-ukaea Nov 5, 2025
0daa265
Added a catch2 microbenchmark to the large number of rays stress test
Waqar-ukaea Nov 6, 2025
f7a49ba
Rebased changes from #170
Waqar-ukaea Nov 7, 2025
742b1f0
Overloading ray_fire/point_in_volume for batch calls
Waqar-ukaea Nov 10, 2025
8cdab31
Added method descriptions for the two overloads
Waqar-ukaea Nov 10, 2025
081abc1
Refactor batch based point_in_volume tests
Waqar-ukaea Nov 11, 2025
e9af504
Dropped dir mask in batch PIV calls + made dirs optional
Waqar-ukaea Nov 12, 2025
0f0811c
Added a new ray-benchmark tool to compare embree vs gprt ray throughput
Waqar-ukaea Nov 12, 2025
50d0e07
Removed performance benchmarking in unit tests
Waqar-ukaea Nov 12, 2025
a2092ec
Removed the leftover extra call to rebuild SBT
Waqar-ukaea Nov 18, 2025
eb5d3e9
Update AABB population program to properly distribute threads
Waqar-ukaea Nov 19, 2025
00bc00e
Move timer to exclude memory transfer around raygen launch
Waqar-ukaea Nov 19, 2025
59f59d3
Ensured timer still setup for Embree ray benchamrking
Waqar-ukaea Nov 19, 2025
8ac2744
Add default stubs for GPU specific ray tracing methods. Cleanup embre…
Waqar-ukaea Nov 25, 2025
7bc2ec7
Refactor raygen launching functions to make use of PushConstants for …
Waqar-ukaea Nov 25, 2025
605e573
Added methods for pre-packing rays and performing ray_fire on those rays
Waqar-ukaea Nov 25, 2025
5e140f9
Update ray_benchmark tool to make use of ray pre-packing and ray_fire…
Waqar-ukaea Nov 25, 2025
e7bdeaa
Added include guard to header with shared types between slang and C++
Waqar-ukaea Nov 27, 2025
71e4d4f
Fixed ambiguity with mixing GPRT math types (double3) and linalg
Waqar-ukaea Nov 27, 2025
d412746
Refactored internal and public facing rayhit buffers to shared POD
Waqar-ukaea Nov 27, 2025
be5ea23
Refactored ray-benchmark miniapp to write into XDG's rayhit buffers d…
Waqar-ukaea Nov 27, 2025
59c97c2
Refactored ray_benchmark miniapp to make use of new xdg::Timer objects
Waqar-ukaea Nov 28, 2025
3c84151
Switch constant DILATION_FACTOR to be inline const so it compiles wit…
Waqar-ukaea Dec 3, 2025
bbc9562
Ensure embree path is making use of all CPU threads available
Waqar-ukaea Dec 3, 2025
2364b04
Extended random ray generation to get random origins too
Waqar-ukaea Dec 3, 2025
498a10d
Added in source-radius for GPRT but fails to compile
Waqar-ukaea Dec 3, 2025
67002b1
No idea why but apparently I need the xdg->prepare_volume_for_raytrac…
Waqar-ukaea Dec 4, 2025
5cf0169
Moved some header definitions around to make it possible to compile w…
Waqar-ukaea Dec 5, 2025
dc9b55a
Added a python script to drive multiple ray-benchmarks
Waqar-ukaea Dec 5, 2025
cb38689
Updated GPRT render tool to make use of upstream API changes for GUI …
Waqar-ukaea Jan 13, 2026
6494af3
Updated batch query tests to make use of TEMPLATE_TEST_CASE pattern
Waqar-ukaea Jan 13, 2026
69742fa
Set default RayHit buffer size to be 1m rays
Waqar-ukaea Jan 14, 2026
553e0b9
Attempting to implement a callback based method for populating intern…
Waqar-ukaea Jan 19, 2026
f0f7389
Removed the now redundant pack_external_rays() code path
Waqar-ukaea Jan 19, 2026
ce80cdd
Made DeviceRayHitBuffers more opaque to abstract away from GPRT speci…
Waqar-ukaea Jan 19, 2026
201d069
Updated some comments
Waqar-ukaea Jan 19, 2026
7c25fda
Renamed ray_fire_packed() to ray_fire_prepared()
Waqar-ukaea Jan 19, 2026
2d78b02
Added the required CMake linking to GPRT for ray_benchmark miniapp
Waqar-ukaea Jan 19, 2026
5704d88
Adding the ability to trace against multiple volumes for prepared rays
Waqar-ukaea Jan 21, 2026
b920f9c
Added the ability to trace against multiple volumes within same rayge…
Waqar-ukaea Jan 23, 2026
055eca8
Abstracted some methods from ray_benchmark into functions for use in …
Waqar-ukaea Jan 26, 2026
c6c71fa
Added test for filling ray buffers directly + ray_fire_prepared code …
Waqar-ukaea Jan 28, 2026
e758e69
Merge pull request #13 from Waqar-ukaea/ray-population-callback
Waqar-ukaea Jan 28, 2026
5f21bd2
Merging ray population from remote
Waqar-ukaea Jan 28, 2026
6aabf14
Removed header causing compilation error + gated test for direct buff…
Waqar-ukaea Jan 29, 2026
9192c19
Fixed redundant include causing libmesh only build to fail
Waqar-ukaea Jan 30, 2026
5f930ad
Core API changes to allow batch queries with XDG
Waqar-ukaea Jan 30, 2026
53d9632
Added tests for batch query API with GPRT
Waqar-ukaea Jan 30, 2026
663dad5
Added wiring for point_in_volume_prepared()
Waqar-ukaea Jan 30, 2026
3e41d89
Added test for point_in_volume_prepared() codepath
Waqar-ukaea Jan 30, 2026
cb2976e
Added point_in_volume_prepared()
Waqar-ukaea Jan 30, 2026
abd0ce2
Added tests for point_in_volume_prepared()
Waqar-ukaea Jan 30, 2026
d229e4f
Fixed wrong function signature call and redefinition of helper functi…
Waqar-ukaea Jan 30, 2026
d88e7fc
Remove stale GPRT specific code from xdg.cpp
Waqar-ukaea Jan 30, 2026
bf001ab
Updated direct_buffer_access test to also test multi-volume
Waqar-ukaea Feb 3, 2026
dd3bda0
Cleaned up some function names and added some warnings for no rays pa…
Waqar-ukaea Feb 3, 2026
c0d180f
Fixed multi-volume tests
Waqar-ukaea Feb 3, 2026
8218938
Added Device side MeshID to sense mapping to handle reverse sense for…
Waqar-ukaea Feb 3, 2026
422a386
Cleanup unused variables in shared host/device side structs
Waqar-ukaea Feb 3, 2026
ea3d53c
Implemented methods for directly populating ray buffers on device
Waqar-ukaea Feb 3, 2026
7290e64
Some extra pre-review cleanups
Waqar-ukaea Feb 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions include/xdg/gprt/ray.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef _XDG_GPRT_RAY_H
#define _XDG_GPRT_RAY_H

#include "gprt.h"
#include "../shared_enums.h"

/*
* Double-precision ray and hit structures used by the GPRT backend.
*
* These types are not inherently GPRT-specific, but we keep them here for now
* since GPRT is the only GPU backend. If another GPU backend is added, these
* can be reused. Unifying them with the CPU/Embree types is possible, but may
* not be worth the added complexity at this stage.
*/

namespace xdg {

struct dblRay
{
double3 origin;
double3 direction;
int volume_mesh_id; // MeshID of the volume this ray will be traced against
uint enabled; // Flag to indicate if the ray is active
// TODO - Implement exclude primtives functionality. Right now these are essentially just stubs.
int32_t* exclude_primitives; // Optional for excluding primitives
int32_t exclude_count; // Number of excluded primitives
};


// TODO - Should we define separate hit structs for PIV and ray-fire or do we think its better to keep them together?
struct dblHit
{
double distance;
int surf_id;
int primitive_id;
PointInVolume piv; // Point in volume check result (0 for outside, 1 for inside)
};

}


#endif
86 changes: 67 additions & 19 deletions include/xdg/gprt/ray_tracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@

#include "xdg/constants.h"
#include "xdg/mesh_manager_interface.h"
#include "xdg/primitive_ref.h"
#include "xdg/geometry_data.h"
#include "xdg/ray_tracing_interface.h"
#include "xdg/ray.h"
#include "xdg/error.h"
#include "gprt/gprt.h"

#include "shared_structs.h"

extern GPRTProgram dbl_deviceCode;
Expand All @@ -26,17 +23,16 @@ enum class RayGenType {
};

struct gprtRayHit {
size_t capacity = 1; // Max number of rays allocated
size_t size = 0; // Current number of active rays
DeviceRayHitBuffers view; // external facing POD for rayhit buffers
size_t size = 0; // Current number of active rays

GPRTBufferOf<dblRay> ray = nullptr;
GPRTBufferOf<dblHit> hit = nullptr;
dblRay* devRayAddr = nullptr;
dblHit* devHitAddr = nullptr;

bool is_valid() const { return capacity > 0 && ray && hit && devRayAddr && devHitAddr; }
bool is_valid() const {
return view.capacity > 0 && ray && hit && view.rayDevPtr && view.hitDevPtr;
}
};

class GPRTRayTracer : public RayTracer {
public:
GPRTRayTracer();
Expand Down Expand Up @@ -90,8 +86,17 @@ class GPRTRayTracer : public RayTracer {
HitOrientation orientation = HitOrientation::EXITING,
std::vector<MeshID>* const exclude_primitives = nullptr) override;

void ray_fire_prepared(const size_t num_rays,
const double dist_limit = INFTY,
HitOrientation orientation = HitOrientation::EXITING) override;

void point_in_volume_prepared(const size_t num_rays) override;

std::pair<double, MeshID> closest(TreeID scene,
const Position& origin) override {};
const Position& origin) override {
fatal_error("Closest queries are not currently supported with GPRT ray tracer");
return {INFTY, ID_NONE};
};

bool occluded(TreeID scene,
const Position& origin,
Expand All @@ -100,9 +105,31 @@ class GPRTRayTracer : public RayTracer {
fatal_error("Occlusion queries are not currently supported with GPRT ray tracer");
return false;
}


// Check to see if buffers large enough and resize if not
void check_rayhit_buffer_capacity(const size_t N) override;

// Method to expose device ray and hit buffers for external population
DeviceRayHitBuffers get_device_rayhit_buffers(const size_t N) override;

/**
* @brief Allocate device buffers and invoke a callback to populate them
*
* This method enables downstream applications to populate ray buffers using
* any compute API (GPRT, CUDA, HIP, etc.) without XDG needing to know the details.
*/
void populate_rays_external(size_t numRays,
const RayPopulationCallback& callback) override;

void transfer_hits_buffer_to_host(const size_t num_rays,
std::vector<dblHit>& hits);

GPRTContext context()
{
return context_;
}

private:
void check_ray_buffer_capacity(size_t N);

// GPRT objects
GPRTContext context_;
Expand All @@ -111,9 +138,8 @@ class GPRTRayTracer : public RayTracer {
GPRTAccel world_;
GPRTBuildParams buildParams_; //<! Build parameters for acceleration structures

// Shader programs
// Map of RayGen programs handled by this ray tracer
std::map<RayGenType, GPRTRayGenOf<dblRayGenData>> rayGenPrograms_;

GPRTMissOf<void> missProgram_;
GPRTComputeOf<DPTriangleGeomData> aabbPopulationProgram_; //<! AABB population program for double precision rays

Expand All @@ -133,14 +159,36 @@ class GPRTRayTracer : public RayTracer {

// Internal GPRT Mappings
std::unordered_map<SurfaceTreeID, GPRTAccel> surface_volume_tree_to_accel_map; // Map from XDG::TreeID to GPRTAccel for volume TLAS
std::vector<GPRTAccel> blas_handles_; // Store BLAS handles so that they can be explicitly referenced in destructor
std::unordered_map<SurfaceTreeID, MeshID> surface_tree_to_volume_map_;
std::vector<SurfaceAccelerationStructure> tlas_handles_; // Host side storage of TLAS device addresses
GPRTBufferOf<SurfaceAccelerationStructure> tlas_handle_buffer_; // Device buffer for TLAS addresses
std::vector<int> meshid_to_sense_; // Host-side MeshID -> sense map
GPRTBufferOf<int> meshid_to_sense_buffer_ {nullptr}; // Device buffer for MeshID -> sense map
bool initialized_ {false}; // flag to indicate if init() has been called

void update_tlas_table_();
void update_meshid_to_sense_();

// Internal GPRT helper method to upload data to device buffers, creating or resizing as needed
template <typename T>
void upload_device_buffer_(GPRTBufferOf<T>& buf, const std::vector<T>& host_data)
{
if (host_data.empty()) return;

if (!buf) {
buf = gprtDeviceBufferCreate<T>(context_, host_data.size(), host_data.data());
return;
}

gprtBufferResize<T>(context_, buf, host_data.size(), false);
gprtBufferMap(buf);
std::copy(host_data.begin(), host_data.end(), gprtBufferGetHostPointer(buf));
gprtBufferUnmap(buf);
}

// Global Tree IDs
GPRTAccel global_surface_accel_ {nullptr};
GPRTAccel global_element_accel_ {nullptr};

};

} // namespace xdg

#endif // include guard
46 changes: 14 additions & 32 deletions include/xdg/gprt/shared_structs.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,16 @@
#ifndef XDG_GPRT_SHARED_STRUCTS_H
#define XDG_GPRT_SHARED_STRUCTS_H

#include "gprt.h"
#include "../shared_enums.h"
#include "ray.h"

struct GPRTPrimitiveRef
{
int id; // ID of the primitive
int sense;
};

struct dblRay
{
double3 origin;
double3 direction;
double tMin; // Minimum distance for ray intersection
double tMax; // Maximum distance for ray intersection
int32_t* exclude_primitives; // Optional for excluding primitives
int32_t exclude_count; // Number of excluded primitives
xdg::HitOrientation hitOrientation;
int volume_tree; // TreeID of the volume being queried
SurfaceAccelerationStructure volume_accel; // The volume accel
// TODO - What else do we need here? Perhaps a flag for exclude prims?
};

struct dblHit
{
double distance;
int surf_id;
int primitive_id;
xdg::PointInVolume piv; // Point in volume check result (0 for outside, 1 for inside)
};

/* variables for double precision triangle mesh geometry */
struct DPTriangleGeomData {
Expand All @@ -35,26 +19,24 @@ struct DPTriangleGeomData {
uint3 *index; // index buffer
double3 *normals; // normals buffer
int surf_id;
int2 vols;
int forward_vol;
int reverse_vol;
dblRay *ray; // double precision rays
xdg::HitOrientation hitOrientation;
int forward_tree; // TreeID of the forward volume
int reverse_tree; // TreeID of the reverse volume
int* meshid_to_sense; // MeshID -> sense (+1 forward, -1 reverse)
xdg::dblRay *ray; // double precision rays
GPRTPrimitiveRef* primitive_refs;
int num_faces; // Number of faces in the geometry
};

struct dblRayGenData {
dblRay *ray;
dblHit *hit;
xdg::dblRay *ray;
xdg::dblHit *hit;
SurfaceAccelerationStructure* meshid_to_accel_address; // MeshID->TLAS address table to recover volume to trace against
};

/* A small structure of constants that can change every frame without rebuilding the
shader binding table. (must be 128 bytes or less) */

struct dblRayFirePushConstants {
struct dblPushConstants {
double tMax;
double tMin;
xdg::HitOrientation hitOrientation;
};

#endif
Loading
Loading