Skip to content

Commit ecb3f2d

Browse files
committed
integrate GPU version into Trace
1 parent 2e06678 commit ecb3f2d

File tree

12 files changed

+353
-115
lines changed

12 files changed

+353
-115
lines changed

docs/code/TraceMakie.jl

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using Makie, Trace, ImageShow, Colors, FileIO, LinearAlgebra, GeometryBasics
2+
using AMDGPU
3+
ArrayType = ROCArray
24

35
function to_spectrum(data::Colorant)
46
rgb = RGBf(data)
@@ -136,10 +138,10 @@ function render_scene(scene::Makie.Scene)
136138
return render_scene(c -> Trace.WhittedIntegrator(c, Trace.UniformSampler(8), 5), scene)
137139
end
138140

139-
function render_scene(integrator_f, mscene::Makie.Scene)
140-
# Only set background image if it isn't set by env light, since
141+
function convert_scene(scene::Makie.Scene)
142+
# Only set background image if it isn't set by env light, since
141143
# background image takes precedence
142-
resolution = Point2f(size(mscene))
144+
resolution = Point2f(size(scene))
143145
f = Trace.LanczosSincFilter(Point2f(1.0f0), 3.0f0)
144146
film = Trace.Film(
145147
resolution,
@@ -148,25 +150,43 @@ function render_scene(integrator_f, mscene::Makie.Scene)
148150
"trace-test.png",
149151
)
150152
primitives = []
151-
for plot in mscene.plots
153+
for plot in scene.plots
152154
prim = to_trace_primitive(plot)
153155
!isnothing(prim) && push!(primitives, prim)
154156
end
155-
camera = to_trace_camera(mscene, film)
157+
camera = to_trace_camera(scene, film)
156158
lights = []
157-
for light in mscene.lights
159+
for light in scene.lights
158160
l = to_trace_light(light)
159161
isnothing(l) || push!(lights, l)
160162
end
161163
if isempty(lights)
162164
error("Must have at least one light")
163165
end
164166
bvh = Trace.BVHAccel(primitives, 1)
165-
integrator = integrator_f(camera)
166167
scene = Trace.Scene([lights...], bvh)
168+
return scene, camera, film
169+
end
170+
171+
function render_whitted(mscene::Makie.Scene; samples_per_pixel=8, max_depth=5)
172+
scene, camera, film = convert_scene(mscene)
173+
integrator = Trace.WhittedIntegrator(camera, Trace.UniformSampler(samples_per_pixel), max_depth)
167174
integrator(scene, film)
168175
return reverse(film.framebuffer, dims=1)
169176
end
177+
178+
function render_gpu(mscene::Makie.Scene, ArrayType; samples_per_pixel=8, max_depth=5)
179+
scene, camera, film = convert_scene(mscene)
180+
preserve = []
181+
gpu_scene = Trace.to_gpu(ArrayType, scene; preserve=preserve)
182+
res = Int.((film.resolution...,))
183+
gpu_img = ArrayType(zeros(RGBf, res))
184+
GC.@preserve preserve begin
185+
Trace.launch_trace_image!(gpu_img, camera, gpu_scene, Int32(samples_per_pixel), Int32(max_depth))
186+
end
187+
return Array(gpu_img)
188+
end
189+
170190
glass = Trace.GlassMaterial(
171191
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
172192
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
@@ -191,9 +211,12 @@ begin
191211
cam3d!(scene)
192212
mesh!(scene, catmesh, color=load(Makie.assetpath("diffusemap.png")))
193213
center!(scene)
214+
@time render_whitted(scene)
194215
# 1.024328 seconds (16.94 M allocations: 5.108 GiB, 46.19% gc time, 81 lock conflicts)
195216
# 0.913530 seconds (16.93 M allocations: 5.108 GiB, 42.52% gc time, 57 lock conflicts)
196-
@time render_scene(scene)
217+
# 0.416158 seconds (75.58 k allocations: 88.646 MiB, 2.44% gc time, 16 lock conflicts)
218+
@time render_gpu(scene, ArrayType)
219+
# 0.135438 seconds (76.03 k allocations: 82.406 MiB, 8.57% gc time)
197220
end
198221

199222
begin
@@ -206,7 +229,48 @@ begin
206229
zs = [cos(x) * sin(y) for x in xs, y in ys]
207230
surface!(scene, xs, ys, zs)
208231
center!(scene)
209-
# 1.598740s
232+
233+
@time render_whitted(scene)
234+
# 1.598740s
210235
# 1.179450 seconds (17.30 M allocations: 5.126 GiB, 36.48% gc time, 94 lock conflicts)
211-
@time render_scene(scene)
236+
# 0.976180 seconds (443.12 k allocations: 107.841 MiB, 6.60% gc time, 12 lock conflicts)
237+
@time render_gpu(scene, ArrayType)
238+
# 0.236231 seconds (443.48 k allocations: 101.598 MiB, 3.92% gc time)
239+
end
240+
241+
model = load(joinpath(@__DIR__, "..", "src", "assets", "models", "caustic-glass.ply"))
242+
begin
243+
glass = Trace.GlassMaterial(
244+
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
245+
Trace.ConstantTexture(Trace.RGBSpectrum(1.0f0)),
246+
Trace.ConstantTexture(0.0f0),
247+
Trace.ConstantTexture(0.0f0),
248+
Trace.ConstantTexture(1.25f0),
249+
true,
250+
)
251+
plastic = Trace.PlasticMaterial(
252+
Trace.ConstantTexture(Trace.RGBSpectrum(0.6399999857f0, 0.6399999857f0, 0.6399999857f0)),
253+
Trace.ConstantTexture(Trace.RGBSpectrum(0.1000000015f0, 0.1000000015f0, 0.1000000015f0)),
254+
Trace.ConstantTexture(0.010408001f0),
255+
true,
256+
)
257+
scene = Scene(size=(1024, 1024); lights=[
258+
AmbientLight(RGBf(1, 1, 1)),
259+
PointLight(Vec3f(4, 4, 10), RGBf(150, 150, 150)),
260+
PointLight(Vec3f(-3, 10, 2.5), RGBf(60, 60, 60)),
261+
PointLight(Vec3f(0, 3, 0.5), RGBf(40, 40, 40))
262+
])
263+
cam3d!(scene)
264+
cm = scene.camera_controls
265+
mesh!(scene, model, material=glass)
266+
mini, maxi = extrema(Rect3f(decompose(Point, model)))
267+
floorrect = Rect3f(Vec3f(-10, mini[2], -10), Vec3f(20, -1, 20))
268+
mesh!(scene, floorrect, material=plastic)
269+
center!(scene)
270+
update_cam!(scene, Vec3f(-1.6, 6.2, 0.2), Vec3f(-3.6, 2.5, 2.4), Vec3f(0, 1, 0))
271+
272+
@time render_whitted(scene)
273+
# 9.820304 seconds (1.69 M allocations: 235.165 MiB, 0.51% gc time, 3 lock conflicts)
274+
@time render_gpu(scene, ArrayType)
275+
# 6.128600 seconds (1.70 M allocations: 228.875 MiB, 1.09% gc time)
212276
end

docs/code/basic-scene.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ end
7272

7373
begin
7474
integrator = Trace.WhittedIntegrator(cam, Trace.UniformSampler(8), 5)
75-
@btime integrator(scene, film)
75+
@time integrator(scene, film)
7676
img = reverse(film.framebuffer, dims=1)
7777
end
7878

docs/code/caustic_glass.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ using GeometryBasics, ImageShow
22
using LinearAlgebra, Makie
33
using Trace, FileIO, MeshIO
44

5+
model = load(joinpath(@__DIR__, "..", "src", "assets", "models", "caustic-glass.ply"))
56
begin
67
glass = Trace.GlassMaterial(
78
Trace.ConstantTexture(Trace.RGBSpectrum(1f0)),

src/Trace.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ include("filter.jl")
224224
include("film.jl")
225225

226226

227-
228227
include("camera/camera.jl")
229228
include("sampler/sampling.jl")
230229
include("sampler/sampler.jl")
@@ -246,6 +245,7 @@ include("lights/environment.jl")
246245

247246
include("integrators/sampler.jl")
248247
include("integrators/sppm.jl")
248+
include("kernel-abstractions.jl")
249249

250250
# include("model_loader.jl")
251251

src/film.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ end
154154

155155
@inline function filter_offset(x, discrete_point, inv_filter_radius, filter_table_width)
156156
fx = abs((x - discrete_point[1]) * inv_filter_radius * filter_table_width)
157-
return clamp(ceil(Int32, fx), Int32(1), Int32(filter_table_width)) # TODO is clipping ok?
157+
return clamp(u_int32(ceil(fx)), Int32(1), Int32(filter_table_width)) # TODO is clipping ok?
158158
end
159159

160160
function filter_offsets(start, stop, discrete_point, inv_filter_radius, filter_table_width)::NTuple{8, Int32}
@@ -208,15 +208,15 @@ end
208208
Point in (x, y) format.
209209
"""
210210
@inline function get_pixel_index(t::FilmTile, p::Point2)
211-
i1, i2 = Int32.((p .- t.bounds.p_min .+ 1))
211+
i1, i2 = u_int32.((p .- t.bounds.p_min .+ 1f0))
212212
return CartesianIndex(i2, i1)
213213
end
214214

215215
"""
216216
Point in (x, y) format.
217217
"""
218218
@inline function get_pixel_index(f::Film, p::Point2)
219-
i1, i2 = Int32.((p .- f.crop_bounds.p_min .+ 1.0))
219+
i1, i2 = u_int32.((p .- f.crop_bounds.p_min .+ 1f0))
220220
return CartesianIndex(i2, i1)
221221
end
222222

@@ -227,6 +227,7 @@ function merge_film_tile!(f::Film, ft::FilmTile)
227227
ft_filter_weight_sum = ft.pixels.filter_weight_sum
228228
f_xyz = f.pixels.xyz
229229
f_filter_weight_sum = f.pixels.filter_weight_sum
230+
230231
@inbounds for y in y_range, x in x_range
231232
pixel = Point2{Int32}(x, y)
232233
ft_idx = get_pixel_index(ft, pixel)
@@ -236,6 +237,7 @@ function merge_film_tile!(f::Film, ft::FilmTile)
236237
end
237238
end
238239

240+
239241
function set_image!(f::Film, spectrum::Matrix{S}) where {S<:Spectrum}
240242
@real_assert size(f.pixels) == size(spectrum)
241243
f.pixels.xyz .= to_XYZ.(spectrum)

0 commit comments

Comments
 (0)