or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

algorithm-kernels.mddriver-api.mdgpu-arrays.mdindex.mdkernel-compilation.mdmath-functions.mdopengl-integration.mdrandom-numbers.md

opengl-integration.mddocs/

0

# OpenGL Integration

1

2

Integration with OpenGL for graphics programming, allowing sharing of buffer objects and textures between CUDA and OpenGL contexts. This enables seamless interoperability for graphics and compute applications.

3

4

## Capabilities

5

6

### Initialization and Context Management

7

8

Initialize OpenGL integration and manage shared contexts between CUDA and OpenGL.

9

10

```python { .api }

11

def init() -> None:

12

"""

13

Initialize OpenGL integration.

14

15

Must be called before any OpenGL interoperability functions.

16

Requires an active OpenGL context.

17

"""

18

19

def make_context(device: Device, flags: int = 0) -> Context:

20

"""

21

Create CUDA context with OpenGL interoperability.

22

23

Parameters:

24

- device: Device, CUDA device

25

- flags: int, context creation flags

26

27

Returns:

28

Context: CUDA context with OpenGL support

29

"""

30

```

31

32

### Buffer Object Interoperability

33

34

Share OpenGL buffer objects with CUDA for compute operations on graphics data.

35

36

```python { .api }

37

class BufferObject:

38

"""OpenGL buffer object wrapper for CUDA interoperability."""

39

40

def __init__(self, buffer_id: int):

41

"""

42

Create buffer object from OpenGL buffer ID.

43

44

Parameters:

45

- buffer_id: int, OpenGL buffer object ID

46

"""

47

48

def register(self, flags: int = 0) -> RegisteredBuffer:

49

"""

50

Register buffer for CUDA access.

51

52

Parameters:

53

- flags: int, registration flags

54

55

Returns:

56

RegisteredBuffer: registered buffer for mapping

57

"""

58

59

class RegisteredBuffer:

60

"""Registered OpenGL buffer for CUDA access."""

61

62

def map(self, flags: int = 0) -> BufferObjectMapping:

63

"""

64

Map buffer for CUDA access.

65

66

Parameters:

67

- flags: int, mapping flags

68

69

Returns:

70

BufferObjectMapping: mapped buffer for CUDA operations

71

"""

72

73

def unregister(self) -> None:

74

"""Unregister buffer from CUDA."""

75

76

class BufferObjectMapping:

77

"""Mapped OpenGL buffer accessible from CUDA."""

78

79

def device_ptr(self) -> DeviceAllocation:

80

"""

81

Get CUDA device pointer to buffer data.

82

83

Returns:

84

DeviceAllocation: device pointer to buffer memory

85

"""

86

87

def size(self) -> int:

88

"""

89

Get buffer size in bytes.

90

91

Returns:

92

int: buffer size in bytes

93

"""

94

95

def unmap(self) -> None:

96

"""Unmap buffer from CUDA access."""

97

98

def __enter__(self) -> BufferObjectMapping:

99

"""Context manager entry."""

100

return self

101

102

def __exit__(self, exc_type, exc_val, exc_tb) -> None:

103

"""Context manager exit (automatically unmaps)."""

104

self.unmap()

105

```

106

107

### Image and Texture Interoperability

108

109

Share OpenGL textures and images with CUDA for image processing operations.

110

111

```python { .api }

112

class RegisteredImage:

113

"""Registered OpenGL image/texture for CUDA access."""

114

115

def __init__(self, image_id: int, target: int, flags: int = 0):

116

"""

117

Register OpenGL image/texture for CUDA access.

118

119

Parameters:

120

- image_id: int, OpenGL texture/image ID

121

- target: int, OpenGL texture target (GL_TEXTURE_2D, etc.)

122

- flags: int, registration flags

123

"""

124

125

def map(self, flags: int = 0) -> RegisteredMapping:

126

"""

127

Map image for CUDA access.

128

129

Parameters:

130

- flags: int, mapping flags

131

132

Returns:

133

RegisteredMapping: mapped image for CUDA operations

134

"""

135

136

def unregister(self) -> None:

137

"""Unregister image from CUDA."""

138

139

class RegisteredMapping:

140

"""Mapped OpenGL image accessible from CUDA."""

141

142

def array(self) -> Array:

143

"""

144

Get CUDA array from mapped image.

145

146

Returns:

147

Array: CUDA array representing image data

148

"""

149

150

def device_ptr_and_size(self) -> tuple[DeviceAllocation, int]:

151

"""

152

Get device pointer and size.

153

154

Returns:

155

tuple: (device_pointer, size_in_bytes)

156

"""

157

158

def unmap(self) -> None:

159

"""Unmap image from CUDA access."""

160

161

def __enter__(self) -> RegisteredMapping:

162

"""Context manager entry."""

163

return self

164

165

def __exit__(self, exc_type, exc_val, exc_tb) -> None:

166

"""Context manager exit (automatically unmaps)."""

167

self.unmap()

168

```

169

170

### Graphics Resource Management

171

172

Manage graphics resources and their CUDA interoperability state.

173

174

```python { .api }

175

def graphics_map_flags() -> object:

176

"""

177

Get graphics mapping flags namespace.

178

179

Returns:

180

object: namespace with mapping flag constants

181

"""

182

183

def register_buffer_object(buffer_id: int, flags: int = 0) -> RegisteredBuffer:

184

"""

185

Register OpenGL buffer object for CUDA access.

186

187

Parameters:

188

- buffer_id: int, OpenGL buffer object ID

189

- flags: int, registration flags

190

191

Returns:

192

RegisteredBuffer: registered buffer object

193

"""

194

195

def register_image(image_id: int, target: int, flags: int = 0) -> RegisteredImage:

196

"""

197

Register OpenGL image/texture for CUDA access.

198

199

Parameters:

200

- image_id: int, OpenGL texture/image ID

201

- target: int, OpenGL texture target

202

- flags: int, registration flags

203

204

Returns:

205

RegisteredImage: registered image object

206

"""

207

208

def unregister_buffer_object(registered_buffer: RegisteredBuffer) -> None:

209

"""

210

Unregister buffer object from CUDA.

211

212

Parameters:

213

- registered_buffer: RegisteredBuffer, buffer to unregister

214

"""

215

216

def unregister_image(registered_image: RegisteredImage) -> None:

217

"""

218

Unregister image from CUDA.

219

220

Parameters:

221

- registered_image: RegisteredImage, image to unregister

222

"""

223

```

224

225

### Synchronization

226

227

Synchronize operations between CUDA and OpenGL contexts.

228

229

```python { .api }

230

def gl_sync() -> None:

231

"""

232

Synchronize OpenGL operations.

233

234

Ensures all pending OpenGL operations complete before CUDA operations.

235

"""

236

237

def cuda_gl_sync() -> None:

238

"""

239

Synchronize CUDA-OpenGL operations.

240

241

Ensures proper ordering between CUDA and OpenGL operations.

242

"""

243

```

244

245

## Usage Examples

246

247

### Basic Buffer Sharing

248

249

```python

250

import pycuda.gl as cuda_gl

251

import pycuda.driver as cuda

252

import pycuda.gpuarray as gpuarray

253

import OpenGL.GL as gl

254

import numpy as np

255

256

# Initialize OpenGL integration

257

cuda_gl.init()

258

259

# Create OpenGL vertex buffer

260

vertex_data = np.array([[0.0, 0.0], [1.0, 0.0], [0.5, 1.0]], dtype=np.float32)

261

vbo = gl.glGenBuffers(1)

262

gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo)

263

gl.glBufferData(gl.GL_ARRAY_BUFFER, vertex_data.nbytes, vertex_data, gl.GL_DYNAMIC_DRAW)

264

265

# Register buffer with CUDA

266

cuda_buffer = cuda_gl.BufferObject(vbo)

267

registered_buffer = cuda_buffer.register()

268

269

# Map buffer for CUDA access

270

with registered_buffer.map() as mapping:

271

# Get device pointer

272

dev_ptr = mapping.device_ptr()

273

size = mapping.size()

274

275

# Create GPU array from buffer

276

gpu_array = gpuarray.GPUArray(vertex_data.shape, vertex_data.dtype, gpudata=dev_ptr)

277

278

# Perform CUDA operations on vertex data

279

gpu_array *= 2.0 # Scale vertices

280

281

# Buffer is automatically unmapped when exiting context

282

# Vertex data is now modified and available to OpenGL

283

```

284

285

### Texture Processing

286

287

```python

288

import pycuda.gl as cuda_gl

289

import OpenGL.GL as gl

290

291

# Create OpenGL texture

292

texture_id = gl.glGenTextures(1)

293

gl.glBindTexture(gl.GL_TEXTURE_2D, texture_id)

294

gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, 512, 512, 0,

295

gl.GL_RGBA, gl.GL_FLOAT, None)

296

297

# Register texture with CUDA

298

registered_image = cuda_gl.RegisteredImage(texture_id, gl.GL_TEXTURE_2D)

299

300

# Map texture for CUDA access

301

with registered_image.map() as mapping:

302

# Get CUDA array from texture

303

cuda_array = mapping.array()

304

305

# Perform image processing operations

306

# (Would typically use custom kernels here)

307

308

# Process image with CUDA kernels...

309

pass

310

311

# Texture is automatically unmapped and available to OpenGL for rendering

312

```

313

314

### Ping-Pong Rendering with Compute

315

316

```python

317

class CudaGLInterop:

318

def __init__(self, width, height):

319

self.width = width

320

self.height = height

321

322

# Initialize OpenGL integration

323

cuda_gl.init()

324

325

# Create ping-pong textures

326

self.textures = gl.glGenTextures(2)

327

for i, tex_id in enumerate(self.textures):

328

gl.glBindTexture(gl.GL_TEXTURE_2D, tex_id)

329

gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGBA32F, width, height, 0,

330

gl.GL_RGBA, gl.GL_FLOAT, None)

331

gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST)

332

gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST)

333

334

# Register textures with CUDA

335

self.registered_images = [

336

cuda_gl.RegisteredImage(tex_id, gl.GL_TEXTURE_2D)

337

for tex_id in self.textures

338

]

339

340

self.current_texture = 0

341

342

def process_frame(self):

343

"""Process current texture with CUDA and swap buffers."""

344

# Map current texture for reading

345

with self.registered_images[self.current_texture].map() as input_mapping:

346

# Map next texture for writing

347

next_texture = (self.current_texture + 1) % 2

348

with self.registered_images[next_texture].map() as output_mapping:

349

350

# Get CUDA arrays

351

input_array = input_mapping.array()

352

output_array = output_mapping.array()

353

354

# Perform CUDA processing

355

self.cuda_process(input_array, output_array)

356

357

# Swap current texture

358

self.current_texture = (self.current_texture + 1) % 2

359

360

# Synchronize for OpenGL rendering

361

cuda_gl.cuda_gl_sync()

362

363

def cuda_process(self, input_array, output_array):

364

"""Perform CUDA processing on texture data."""

365

# Custom CUDA kernel processing would go here

366

pass

367

368

def get_current_texture(self):

369

"""Get current texture ID for OpenGL rendering."""

370

return self.textures[self.current_texture]

371

```

372

373

### Performance Considerations

374

375

```python

376

# Efficient buffer management

377

class GLBufferPool:

378

def __init__(self, buffer_size, pool_size=4):

379

self.buffer_size = buffer_size

380

self.available_buffers = []

381

self.mapped_buffers = {}

382

383

# Pre-allocate buffer pool

384

for _ in range(pool_size):

385

# Create OpenGL buffer

386

vbo = gl.glGenBuffers(1)

387

gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo)

388

gl.glBufferData(gl.GL_ARRAY_BUFFER, buffer_size, None, gl.GL_STREAM_DRAW)

389

390

# Register with CUDA

391

cuda_buffer = cuda_gl.BufferObject(vbo)

392

registered = cuda_buffer.register()

393

394

self.available_buffers.append((vbo, registered))

395

396

def get_buffer(self):

397

"""Get available buffer from pool."""

398

if not self.available_buffers:

399

raise RuntimeError("No available buffers in pool")

400

401

vbo, registered = self.available_buffers.pop()

402

mapping = registered.map()

403

self.mapped_buffers[vbo] = (registered, mapping)

404

405

return vbo, mapping

406

407

def return_buffer(self, vbo):

408

"""Return buffer to pool."""

409

if vbo in self.mapped_buffers:

410

registered, mapping = self.mapped_buffers.pop(vbo)

411

mapping.unmap()

412

self.available_buffers.append((vbo, registered))

413

```

414

415

## Constants and Flags

416

417

```python { .api }

418

# Graphics resource mapping flags

419

graphics_map_flags = SimpleNamespace(

420

NONE=0,

421

READ_ONLY=1,

422

WRITE_DISCARD=2

423

)

424

425

# Graphics resource registration flags

426

graphics_register_flags = SimpleNamespace(

427

NONE=0,

428

SURFACE_LDST=1,

429

TEXTURE_GATHER=2

430

)

431

```