-
Notifications
You must be signed in to change notification settings - Fork 14
Adding a ray batch query API #178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e6f5258
4334524
1dbc734
b388e66
c9af01e
1025013
0daa265
f7a49ba
742b1f0
8cdab31
081abc1
e9af504
0f0811c
50d0e07
a2092ec
eb5d3e9
00bc00e
59f59d3
8ac2744
7bc2ec7
605e573
5e140f9
e7bdeaa
71e4d4f
d412746
be5ea23
59c97c2
3c84151
bbc9562
2364b04
498a10d
67002b1
5cf0169
dc9b55a
cb38689
6494af3
69742fa
553e0b9
f0f7389
ce80cdd
201d069
7c25fda
2d78b02
5704d88
b920f9c
055eca8
c6c71fa
e758e69
5f21bd2
6aabf14
9192c19
5f930ad
53d9632
663dad5
3e41d89
cb2976e
abd0ce2
d229e4f
d88e7fc
bf001ab
dd3bda0
c0d180f
8218938
422a386
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| #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 | ||
| int32_t* exclude_primitives; // Optional for excluding primitives | ||
| int32_t exclude_count; // Number of excluded primitives | ||
| }; | ||
|
|
||
|
|
||
| struct dblHit | ||
| { | ||
| double distance; | ||
| int surf_id; | ||
| int primitive_id; | ||
| PointInVolume piv; // Point in volume check result (0 for outside, 1 for inside) | ||
| }; | ||
|
|
||
| } | ||
|
|
||
|
|
||
| #endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
|
|
@@ -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(); | ||
|
|
@@ -83,15 +79,40 @@ class GPRTRayTracer : public RayTracer { | |
| const Direction* direction = nullptr, | ||
| const std::vector<MeshID>* exclude_primitives = nullptr) const override; | ||
|
|
||
| void point_in_volume(TreeID tree, | ||
| const Position* points, | ||
| const size_t num_points, | ||
| uint8_t* results, | ||
| const Direction* directions = nullptr, | ||
| std::vector<MeshID>* exclude_primitives = nullptr) override; | ||
|
|
||
| std::pair<double, MeshID> ray_fire(TreeID scene, | ||
| const Position& origin, | ||
| const Direction& direction, | ||
| const double dist_limit = INFTY, | ||
| HitOrientation orientation = HitOrientation::EXITING, | ||
| std::vector<MeshID>* const exclude_primitives = nullptr) override; | ||
| void ray_fire(TreeID tree, | ||
| const Position* origins, | ||
| const Direction* directions, | ||
| const size_t num_rays, | ||
| double* hitDistances, | ||
| MeshID* surfaceIDs, | ||
| const double dist_limit = INFTY, | ||
| 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, | ||
|
|
@@ -100,9 +121,41 @@ 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) override; | ||
|
|
||
| GPRTContext context() | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally any methods working with or returning GPRT-specific information will be private in this class.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. The reason I had this was so I could "test" my method for taking an externally filled set of device buffers in my But or a real world application working with XDG they wouldn't be using GPRT anyway so there is no need to have a function that returns the same And tbh thinking about it i dont actually know if i need to attach the compute shader in the |
||
| { | ||
| return context_; | ||
| } | ||
|
|
||
| SurfaceAccelerationStructure* tlas_handle_device_ptr() const | ||
| { | ||
| return gprtBufferGetDevicePointer(tlas_handle_buffer_); | ||
| } | ||
|
|
||
| size_t tlas_handle_count() const | ||
| { | ||
| return tlas_handles_.size(); | ||
| } | ||
|
|
||
| private: | ||
| void check_ray_buffer_capacity(size_t N); | ||
|
|
||
| // GPRT objects | ||
| GPRTContext context_; | ||
|
|
@@ -133,7 +186,31 @@ 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_(); | ||
|
|
||
| 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}; | ||
|
|
@@ -142,5 +219,4 @@ class GPRTRayTracer : public RayTracer { | |
| }; | ||
|
|
||
| } // namespace xdg | ||
|
|
||
| #endif // include guard | ||
| #endif // include guard | ||
Uh oh!
There was an error while loading. Please reload this page.