Harbor

Changelog c56a8f0cd760

pin backend frame contract

@sky · 1 month ago · parent 88859d5c5166
0 added 5 modified 0 deleted
gpu/backend/backend.odin +57 -3 modified
464 unchanged lines hidden
465 465 // --- Sync ---
466 466 get_default_render_pass: proc() -> Render_Pass_Handle,
467 467 get_depth_format: proc() -> Format,
468 + }
468 469
469 - // --- Swapchain / presentation ---
470 - acquire_frame: proc() -> (image_index: u32, ok: bool),
471 - present_frame: proc(image_index: u32) -> bool,
470 + backend_vtable_is_complete :: proc(b: ^Backend) -> bool {
471 + if b == nil do return false
472 + return b.shutdown != nil &&
473 + b.wait_idle != nil &&
474 + b.begin_frame != nil &&
475 + b.end_frame != nil &&
476 + b.on_resize != nil &&
477 + b.get_extent != nil &&
478 + b.current_frame_index != nil &&
479 + b.begin_render_pass != nil &&
480 + b.begin_default_pass != nil &&
481 + b.end_render_pass != nil &&
482 + b.set_viewport != nil &&
483 + b.set_scissor != nil &&
484 + b.set_depth_bias != nil &&
485 + b.create_graphics_pipeline != nil &&
486 + b.destroy_graphics_pipeline != nil &&
487 + b.bind_graphics_pipeline != nil &&
488 + b.push_constants != nil &&
489 + b.create_buffer != nil &&
490 + b.create_buffer_staged != nil &&
491 + b.destroy_buffer != nil &&
492 + b.map_buffer != nil &&
493 + b.unmap_buffer != nil &&
494 + b.get_buffer_mapped != nil &&
495 + b.bind_vertex_buffer != nil &&
496 + b.bind_index_buffer != nil &&
497 + b.create_texture != nil &&
498 + b.destroy_texture != nil &&
499 + b.create_sampler != nil &&
500 + b.destroy_sampler != nil &&
501 + b.create_image != nil &&
502 + b.create_image_view != nil &&
503 + b.destroy_image != nil &&
504 + b.create_descriptor_set_layout != nil &&
505 + b.destroy_descriptor_set_layout != nil &&
506 + b.create_descriptor_pool != nil &&
507 + b.destroy_descriptor_pool != nil &&
508 + b.allocate_descriptor_set != nil &&
509 + b.bind_descriptor_set != nil &&
510 + b.update_descriptor_image != nil &&
511 + b.update_descriptor_buffer != nil &&
512 + b.create_render_pass != nil &&
513 + b.destroy_render_pass != nil &&
514 + b.create_framebuffer != nil &&
515 + b.destroy_framebuffer != nil &&
516 + b.create_shader_module != nil &&
517 + b.destroy_shader != nil &&
518 + b.draw_indexed != nil &&
519 + b.create_compute_pipeline != nil &&
520 + b.destroy_compute_pipeline != nil &&
521 + b.bind_compute_pipeline != nil &&
522 + b.dispatch_compute != nil &&
523 + b.compute_barrier != nil &&
524 + b.get_default_render_pass != nil &&
525 + b.get_depth_format != nil
472 526 }
473 527
474 528 // Initialized flag
1 unchanged lines hidden
gpu/backend/opengl/gl_backend.odin +0 -2 modified
225 unchanged lines hidden
226 226
227 227 get_default_render_pass = get_default_render_pass_opengl,
228 228 get_depth_format = get_depth_format_opengl,
229 - acquire_frame = acquire_frame_opengl,
230 - present_frame = present_frame_opengl,
231 229 }
232 230
233 231 bk.backend_initialized = true
74 unchanged lines hidden
gpu/backend/opengl/gl_frame.odin +3 -10 modified
16 unchanged lines hidden
17 17
18 18 end_frame_opengl :: proc(ctx: bk.Frame_Context) -> bool {
19 19 if g_gl == nil do return false
20 + if !swap_gl_context(&g_gl.gl_ctx) {
21 + log.error("gpu/opengl: swap buffers failed")
22 + }
20 23 g_gl.frame_active = false
21 24 g_gl.current_frame = (g_gl.current_frame + 1) % bk.MAX_FRAMES_IN_FLIGHT
22 25 return false
23 26 }
24 27
25 - acquire_frame_opengl :: proc() -> (image_index: u32, ok: bool) {
26 - if g_gl == nil do return 0, false
27 - return 0, true
28 - }
29 -
30 - present_frame_opengl :: proc(image_index: u32) -> bool {
31 - if g_gl == nil do return false
32 - return swap_gl_context(&g_gl.gl_ctx)
33 - }
34 -
35 28 begin_default_pass_opengl :: proc(ctx: bk.Frame_Context, clear_color: [4]f32) {
36 29 if g_gl == nil do return
37 30 gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
50 unchanged lines hidden
gpu/gpu.odin modified

Diff hidden because this file has more than 800 lines.

gpu/tests/capabilities_test.odin +7 -0 modified
30 unchanged lines hidden
31 31 testing.expect_value(t, caps.max_color_targets, u32(1))
32 32 testing.expect_value(t, caps.max_frames_in_flight, u32(bk.MAX_FRAMES_IN_FLIGHT))
33 33 }
34 +
35 + @(test)
36 + test_backend_vtable_rejects_missing_required_slots :: proc(t: ^testing.T) {
37 + testing.expect(t, !bk.backend_vtable_is_complete(nil))
38 + backend: bk.Backend
39 + testing.expect(t, !bk.backend_vtable_is_complete(&backend))
40 + }