Skip to content

Commit 69944a2

Browse files
committed
Fixing the constant buffers containing the scene data being GPU uploaded while the wrong context was enabled
1 parent e5d7d92 commit 69944a2

File tree

3 files changed

+55
-18
lines changed

3 files changed

+55
-18
lines changed

genesis/ext/pyrender/offscreen.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def __init__(self, point_size=1.0, pyopengl_platform="pyglet", seg_node_map=None
3434
self.point_size = point_size
3535
self._platform = None
3636
self._is_software = False
37+
self._has_valid_context = False
3738
self._create(pyopengl_platform)
3839
self._seg_node_map = seg_node_map
3940

@@ -66,6 +67,38 @@ def point_size(self):
6667
def point_size(self, value):
6768
self._point_size = float(value)
6869

70+
def make_current(self):
71+
"""This function sets the current context and must be called before all rendering and GPU upload operations.
72+
"""
73+
if self._has_valid_context:
74+
gs.raise_exception("The method was called while having an other context current. Please call 'make_uncurrent' first.")
75+
76+
self._platform.make_current()
77+
78+
# If platform does not support dynamically-resizing framebuffers,
79+
# destroy it and restart it
80+
if (
81+
self._platform.viewport_height != self.viewport_height
82+
or self._platform.viewport_width != self.viewport_width
83+
):
84+
if not self._platform.supports_framebuffers():
85+
self.delete()
86+
self._create()
87+
88+
# Only needs to happen if the context was deleted and created
89+
self._platform.make_current()
90+
91+
self._has_valid_context = True
92+
93+
def make_uncurrent(self):
94+
"""This function unsets the current context and must be called after all rendering and GPU upload operations
95+
are done.
96+
"""
97+
if not self._has_valid_context:
98+
gs.raise_exception("The method was called before making a context current.")
99+
self._platform.make_uncurrent()
100+
self._has_valid_context = False
101+
69102
def render(
70103
self,
71104
scene,
@@ -97,24 +130,13 @@ def render(
97130
depth_im : (h, w) float32
98131
The depth buffer in linear units.
99132
"""
133+
if not self._has_valid_context:
134+
gs.raise_exception("Ensure that the right context is set before rendering. Please call the method 'make_current'.")
100135

101136
if camera_node is not None:
102137
saved_camera_node = scene.main_camera_node
103138
scene.main_camera_node = camera_node
104139

105-
self._platform.make_current()
106-
# If platform does not support dynamically-resizing framebuffers,
107-
# destroy it and restart it
108-
if (
109-
self._platform.viewport_height != self.viewport_height
110-
or self._platform.viewport_width != self.viewport_width
111-
):
112-
if not self._platform.supports_framebuffers():
113-
self.delete()
114-
self._create()
115-
116-
self._platform.make_current()
117-
118140
# Forcibly disable shadow for software rendering as it may hang indefinitely
119141
if shadow and not self._is_software:
120142
flags |= RenderFlags.SHADOWS_ALL
@@ -172,9 +194,6 @@ def get_program(self, vertex_shader, fragment_shader, geometry_shader=None, defi
172194

173195
renderer._program_cache = old_cache
174196

175-
# Make the platform not current
176-
self._platform.make_uncurrent()
177-
178197
if camera_node is not None:
179198
scene.main_camera_node = saved_camera_node
180199

genesis/vis/rasterizer.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def __init__(self, viewer, context):
1818
self._camera_targets = dict()
1919
self._offscreen = self._viewer is None
2020
self._renderer = None
21+
self._buffer_updates = None
2122

2223
def build(self):
2324
if self._context is None:
@@ -57,6 +58,16 @@ def remove_camera(self, camera):
5758
def render_camera(self, camera, rgb=True, depth=False, segmentation=False, normal=False):
5859
rgb_arr, depth_arr, seg_idxc_arr, normal_arr = None, None, None, None
5960
if self._offscreen:
61+
# Set the context
62+
self._renderer.make_current()
63+
64+
# Update the buffers
65+
if self._buffer_updates is None:
66+
gs.raise_exception("Buffers were not set before rendering. Please call 'update_scene' method.")
67+
68+
self._context.jit.update_buffer(self._buffer_updates)
69+
70+
# Render
6071
if rgb or depth or normal:
6172
retval = self._renderer.render(
6273
self._context._scene,
@@ -82,7 +93,14 @@ def render_camera(self, camera, rgb=True, depth=False, segmentation=False, norma
8293
normal=False,
8394
seg=True,
8495
)
96+
97+
# Unset the context
98+
self._renderer.make_uncurrent()
8599
else:
100+
# Update the buffers
101+
self._context.jit.update_buffer(self._buffer_updates)
102+
103+
# Render
86104
if rgb or depth or normal:
87105
retval = self._viewer._pyrender_viewer.render_offscreen(
88106
self._camera_nodes[camera.uid],
@@ -111,8 +129,7 @@ def render_camera(self, camera, rgb=True, depth=False, segmentation=False, norma
111129
return rgb_arr, depth_arr, seg_idxc_arr, normal_arr
112130

113131
def update_scene(self):
114-
buffer_updates = self._context.update()
115-
self._context.jit.update_buffer(buffer_updates)
132+
self._buffer_updates = self._context.update()
116133

117134
def destroy(self):
118135
for node in self._camera_nodes.values():

genesis/vis/visualizer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ def build(self):
156156
self._viewer.update(auto_refresh=True)
157157
else:
158158
# viewer creation will compile rendering kernels if viewer is not created, render here once to compile
159+
self._rasterizer.update_scene()
159160
self._rasterizer.render_camera(self._cameras[0])
160161

161162
def update(self, force=True, auto=None):

0 commit comments

Comments
 (0)