Harbor

Changelog 1cc7763354e2

pin opengl backend skeleton

@sky · 1 month ago · parent 7a40f9b3a832
5 added 2 modified 0 deleted
gpu/backend/opengl/gl_backend.odin +162 -0 added
1 + package opengl_backend
2 +
3 + import "core:log"
4 + import gl "vendor:OpenGL"
5 +
6 + import bk ".."
7 +
8 + @(private)
9 + g_gl: ^OpenGL_State
10 +
11 + OpenGL_State :: struct {
12 + gl_ctx: GL_Context,
13 + width: u32,
14 + height: u32,
15 +
16 + default_render_pass: bk.Render_Pass_Handle,
17 + current_frame: u32,
18 + frame_active: bool,
19 + render_pass_active: bool,
20 + }
21 +
22 + init_opengl_backend :: proc(surface: bk.Surface_Desc, width, height: u32, title: cstring) -> (backend: bk.Backend, ok: bool) {
23 + state := new(OpenGL_State)
24 + if state == nil {
25 + log.error("gpu/opengl: failed to allocate OpenGL state")
26 + return {}, false
27 + }
28 + g_gl = state
29 +
30 + gl_ctx, context_ok := create_gl_context(surface, width, height, title)
31 + if !context_ok {
32 + log.error("gpu/opengl: failed to create OpenGL 4.5 core context")
33 + free(state)
34 + g_gl = nil
35 + return {}, false
36 + }
37 + state.gl_ctx = gl_ctx
38 + state.width = width
39 + state.height = height
40 + state.default_render_pass = bk.Render_Pass_Handle(1)
41 +
42 + gl.load_up_to(4, 5, gl_context_set_proc_address)
43 + gl.ClipControl(gl.UPPER_LEFT, gl.ZERO_TO_ONE)
44 + gl.Disable(gl.DEPTH_TEST)
45 + gl.Disable(gl.SCISSOR_TEST)
46 + gl.Disable(gl.BLEND)
47 +
48 + backend = bk.Backend{
49 + capabilities = bk.advertised_render_capabilities(),
50 +
51 + shutdown = shutdown_opengl,
52 + wait_idle = wait_idle_opengl,
53 +
54 + begin_frame = begin_frame_opengl,
55 + end_frame = end_frame_opengl,
56 + on_resize = on_resize_opengl,
57 + get_extent = get_extent_opengl,
58 + current_frame_index = current_frame_index_opengl,
59 +
60 + begin_render_pass = begin_render_pass_opengl,
61 + begin_default_pass = begin_default_pass_opengl,
62 + end_render_pass = end_render_pass_opengl,
63 + set_viewport = set_viewport_opengl,
64 + set_scissor = set_scissor_opengl,
65 + set_depth_bias = set_depth_bias_opengl,
66 +
67 + create_graphics_pipeline = create_graphics_pipeline_opengl,
68 + destroy_graphics_pipeline = destroy_graphics_pipeline_opengl,
69 + bind_graphics_pipeline = bind_graphics_pipeline_opengl,
70 + push_constants = push_constants_opengl,
71 +
72 + create_buffer = create_buffer_opengl,
73 + create_buffer_staged = create_buffer_staged_opengl,
74 + destroy_buffer = destroy_buffer_opengl,
75 + map_buffer = map_buffer_opengl,
76 + unmap_buffer = unmap_buffer_opengl,
77 + get_buffer_mapped = get_buffer_mapped_opengl,
78 + bind_vertex_buffer = bind_vertex_buffer_opengl,
79 + bind_index_buffer = bind_index_buffer_opengl,
80 +
81 + create_texture = create_texture_opengl,
82 + destroy_texture = destroy_texture_opengl,
83 +
84 + create_sampler = create_sampler_opengl,
85 + destroy_sampler = destroy_sampler_opengl,
86 +
87 + create_image = create_image_opengl,
88 + create_image_view = create_image_view_opengl,
89 + destroy_image = destroy_image_opengl,
90 +
91 + create_descriptor_set_layout = create_descriptor_set_layout_opengl,
92 + destroy_descriptor_set_layout = destroy_descriptor_set_layout_opengl,
93 + create_descriptor_pool = create_descriptor_pool_opengl,
94 + destroy_descriptor_pool = destroy_descriptor_pool_opengl,
95 + allocate_descriptor_set = allocate_descriptor_set_opengl,
96 + bind_descriptor_set = bind_descriptor_set_opengl,
97 + update_descriptor_image = update_descriptor_image_opengl,
98 + update_descriptor_buffer = update_descriptor_buffer_opengl,
99 +
100 + create_render_pass = create_render_pass_opengl,
101 + destroy_render_pass = destroy_render_pass_opengl,
102 + create_framebuffer = create_framebuffer_opengl,
103 + destroy_framebuffer = destroy_framebuffer_opengl,
104 +
105 + create_shader_module = create_shader_module_opengl,
106 + destroy_shader = destroy_shader_opengl,
107 +
108 + draw_indexed = draw_indexed_opengl,
109 +
110 + create_compute_pipeline = create_compute_pipeline_opengl,
111 + destroy_compute_pipeline = destroy_compute_pipeline_opengl,
112 + bind_compute_pipeline = bind_compute_pipeline_opengl,
113 + dispatch_compute = dispatch_compute_opengl,
114 + compute_barrier = compute_barrier_opengl,
115 +
116 + get_default_render_pass = get_default_render_pass_opengl,
117 + get_depth_format = get_depth_format_opengl,
118 + acquire_frame = acquire_frame_opengl,
119 + present_frame = present_frame_opengl,
120 + }
121 +
122 + bk.backend_initialized = true
123 + return backend, true
124 + }
125 +
126 + shutdown_opengl :: proc() {
127 + if g_gl == nil do return
128 + destroy_gl_context(&g_gl.gl_ctx)
129 + free(g_gl)
130 + g_gl = nil
131 + bk.backend_initialized = false
132 + }
133 +
134 + wait_idle_opengl :: proc() {
135 + gl.Finish()
136 + }
137 +
138 + current_frame_index_opengl :: proc() -> u32 {
139 + if g_gl == nil do return 0
140 + return g_gl.current_frame
141 + }
142 +
143 + get_extent_opengl :: proc() -> bk.Extent {
144 + if g_gl == nil do return {}
145 + return {g_gl.width, g_gl.height}
146 + }
147 +
148 + on_resize_opengl :: proc(width, height: u32) {
149 + if g_gl == nil do return
150 + g_gl.width = width
151 + g_gl.height = height
152 + resize_gl_context(&g_gl.gl_ctx, width, height)
153 + }
154 +
155 + get_default_render_pass_opengl :: proc() -> bk.Render_Pass_Handle {
156 + if g_gl == nil do return bk.NULL_RENDER_PASS
157 + return g_gl.default_render_pass
158 + }
159 +
160 + get_depth_format_opengl :: proc() -> bk.Format {
161 + return .D32_SFLOAT
162 + }
gpu/backend/opengl/gl_context_linux.odin +136 -0 added
1 + #+build linux
2 + package opengl_backend
3 +
4 + import "core:log"
5 + import egl "vendor:egl"
6 +
7 + import bk ".."
8 +
9 + GL_Context :: struct {
10 + display: egl.Display,
11 + surface: egl.Surface,
12 + gl_ctx: egl.Context,
13 + width: u32,
14 + height: u32,
15 + }
16 +
17 + create_gl_context :: proc(surface: bk.Surface_Desc, width, height: u32, title: cstring) -> (GL_Context, bool) {
18 + display: egl.Display
19 + native_window: egl.NativeWindowType
20 +
21 + switch surface.kind {
22 + case .X11:
23 + if surface.x11.display == nil || surface.x11.window == 0 {
24 + log.error("gpu/opengl: invalid X11 surface")
25 + return {}, false
26 + }
27 + display = egl.GetDisplay(egl.NativeDisplayType(surface.x11.display))
28 + native_window = egl.NativeWindowType(uintptr(surface.x11.window))
29 + case .Wayland:
30 + if surface.wayland.display == nil || surface.wayland.surface == nil {
31 + log.error("gpu/opengl: invalid Wayland surface")
32 + return {}, false
33 + }
34 + display = egl.GetDisplay(egl.NativeDisplayType(surface.wayland.display))
35 + native_window = egl.NativeWindowType(surface.wayland.surface)
36 + case .None, .Win32:
37 + log.error("gpu/opengl: Linux OpenGL backend requires X11 or Wayland surface")
38 + return {}, false
39 + }
40 +
41 + if display == egl.NO_DISPLAY {
42 + log.error("gpu/opengl: eglGetDisplay failed")
43 + return {}, false
44 + }
45 +
46 + major, minor: i32
47 + if !egl.Initialize(display, &major, &minor) {
48 + log.error("gpu/opengl: eglInitialize failed")
49 + return {}, false
50 + }
51 +
52 + if !egl.BindAPI(egl.OPENGL_API) {
53 + log.error("gpu/opengl: eglBindAPI(OpenGL) failed")
54 + egl.Terminate(display)
55 + return {}, false
56 + }
57 +
58 + config_attribs := [?]i32{
59 + egl.SURFACE_TYPE, egl.WINDOW_BIT,
60 + egl.RENDERABLE_TYPE, egl.OPENGL_BIT,
61 + egl.RED_SIZE, 8,
62 + egl.GREEN_SIZE, 8,
63 + egl.BLUE_SIZE, 8,
64 + egl.ALPHA_SIZE, 8,
65 + egl.DEPTH_SIZE, 24,
66 + egl.NONE,
67 + }
68 + config: egl.Config
69 + config_count: i32
70 + if !egl.ChooseConfig(display, &config_attribs[0], &config, 1, &config_count) || config_count == 0 {
71 + log.error("gpu/opengl: no compatible EGL config")
72 + egl.Terminate(display)
73 + return {}, false
74 + }
75 +
76 + egl_surface := egl.CreateWindowSurface(display, config, native_window, nil)
77 + if egl_surface == egl.NO_SURFACE {
78 + log.error("gpu/opengl: eglCreateWindowSurface failed")
79 + egl.Terminate(display)
80 + return {}, false
81 + }
82 +
83 + context_attribs := [?]i32{
84 + egl.CONTEXT_MAJOR_VERSION, 4,
85 + egl.CONTEXT_MINOR_VERSION, 5,
86 + egl.CONTEXT_OPENGL_PROFILE_MASK, egl.CONTEXT_OPENGL_CORE_PROFILE_BIT,
87 + egl.NONE,
88 + }
89 + gl_ctx := egl.CreateContext(display, config, egl.NO_CONTEXT, &context_attribs[0])
90 + if gl_ctx == egl.NO_CONTEXT {
91 + log.error("gpu/opengl: eglCreateContext(4.5 core) failed")
92 + egl.DestroySurface(display, egl_surface)
93 + egl.Terminate(display)
94 + return {}, false
95 + }
96 +
97 + if !egl.MakeCurrent(display, egl_surface, egl_surface, gl_ctx) {
98 + log.error("gpu/opengl: eglMakeCurrent failed")
99 + egl.DestroyContext(display, gl_ctx)
100 + egl.DestroySurface(display, egl_surface)
101 + egl.Terminate(display)
102 + return {}, false
103 + }
104 +
105 + egl.SwapInterval(display, 1)
106 + return {display = display, surface = egl_surface, gl_ctx = gl_ctx, width = width, height = height}, true
107 + }
108 +
109 + destroy_gl_context :: proc(ctx: ^GL_Context) {
110 + if ctx == nil || ctx.display == egl.NO_DISPLAY do return
111 + egl.MakeCurrent(ctx.display, egl.NO_SURFACE, egl.NO_SURFACE, egl.NO_CONTEXT)
112 + if ctx.gl_ctx != egl.NO_CONTEXT do egl.DestroyContext(ctx.display, ctx.gl_ctx)
113 + if ctx.surface != egl.NO_SURFACE do egl.DestroySurface(ctx.display, ctx.surface)
114 + egl.Terminate(ctx.display)
115 + ctx^ = {}
116 + }
117 +
118 + make_gl_context_current :: proc(ctx: ^GL_Context) -> bool {
119 + if ctx == nil || ctx.display == egl.NO_DISPLAY || ctx.gl_ctx == egl.NO_CONTEXT do return false
120 + return egl.MakeCurrent(ctx.display, ctx.surface, ctx.surface, ctx.gl_ctx) == egl.TRUE
121 + }
122 +
123 + swap_gl_context :: proc(ctx: ^GL_Context) -> bool {
124 + if ctx == nil || ctx.display == egl.NO_DISPLAY || ctx.surface == egl.NO_SURFACE do return false
125 + return egl.SwapBuffers(ctx.display, ctx.surface) == egl.TRUE
126 + }
127 +
128 + resize_gl_context :: proc(ctx: ^GL_Context, width, height: u32) {
129 + if ctx == nil do return
130 + ctx.width = width
131 + ctx.height = height
132 + }
133 +
134 + gl_context_set_proc_address :: proc(p: rawptr, name: cstring) {
135 + (^rawptr)(p)^ = egl.GetProcAddress(name)
136 + }
gpu/backend/opengl/gl_context_windows.odin +112 -0 added
1 + #+build windows
2 + package opengl_backend
3 +
4 + import "core:log"
5 + import win32 "core:sys/windows"
6 + import gl "vendor:OpenGL"
7 +
8 + import bk ".."
9 +
10 + GL_Context :: struct {
11 + hwnd: win32.HWND,
12 + hdc: win32.HDC,
13 + gl_ctx: win32.HGLRC,
14 + width: u32,
15 + height: u32,
16 + }
17 +
18 + create_gl_context :: proc(surface: bk.Surface_Desc, width, height: u32, title: cstring) -> (GL_Context, bool) {
19 + if surface.kind != .Win32 || surface.win32.hwnd == nil {
20 + log.error("gpu/opengl: Windows OpenGL backend requires Win32 surface")
21 + return {}, false
22 + }
23 +
24 + hwnd := win32.HWND(surface.win32.hwnd)
25 + hdc := win32.GetDC(hwnd)
26 + if hdc == nil {
27 + log.error("gpu/opengl: GetDC failed")
28 + return {}, false
29 + }
30 +
31 + pfd := win32.PIXELFORMATDESCRIPTOR{
32 + nSize = size_of(win32.PIXELFORMATDESCRIPTOR),
33 + nVersion = 1,
34 + dwFlags = win32.PFD_DRAW_TO_WINDOW | win32.PFD_SUPPORT_OPENGL | win32.PFD_DOUBLEBUFFER,
35 + iPixelType = win32.PFD_TYPE_RGBA,
36 + cColorBits = 32,
37 + cDepthBits = 24,
38 + cStencilBits = 8,
39 + iLayerType = win32.PFD_MAIN_PLANE,
40 + }
41 + pixel_format := win32.ChoosePixelFormat(hdc, &pfd)
42 + if pixel_format == 0 || !win32.SetPixelFormat(hdc, pixel_format, &pfd) {
43 + log.error("gpu/opengl: failed to set Win32 pixel format")
44 + win32.ReleaseDC(hwnd, hdc)
45 + return {}, false
46 + }
47 +
48 + dummy := win32.wglCreateContext(hdc)
49 + if dummy == nil || !win32.wglMakeCurrent(hdc, dummy) {
50 + log.error("gpu/opengl: failed to create WGL bootstrap context")
51 + if dummy != nil do win32.wglDeleteContext(dummy)
52 + win32.ReleaseDC(hwnd, hdc)
53 + return {}, false
54 + }
55 +
56 + gl.load_up_to(4, 5, win32.gl_set_proc_address)
57 + win32.wglCreateContextAttribsARB = auto_cast win32.wglGetProcAddress("wglCreateContextAttribsARB")
58 + if win32.wglCreateContextAttribsARB == nil {
59 + log.error("gpu/opengl: WGL_ARB_create_context unavailable")
60 + win32.wglMakeCurrent(nil, nil)
61 + win32.wglDeleteContext(dummy)
62 + win32.ReleaseDC(hwnd, hdc)
63 + return {}, false
64 + }
65 +
66 + attribs := [?]c_int{
67 + win32.CONTEXT_MAJOR_VERSION_ARB, 4,
68 + win32.CONTEXT_MINOR_VERSION_ARB, 5,
69 + win32.CONTEXT_PROFILE_MASK_ARB, win32.CONTEXT_CORE_PROFILE_BIT_ARB,
70 + 0,
71 + }
72 + gl_ctx := win32.wglCreateContextAttribsARB(hdc, nil, &attribs[0])
73 + win32.wglMakeCurrent(nil, nil)
74 + win32.wglDeleteContext(dummy)
75 + if gl_ctx == nil || !win32.wglMakeCurrent(hdc, gl_ctx) {
76 + log.error("gpu/opengl: failed to create WGL 4.5 core context")
77 + if gl_ctx != nil do win32.wglDeleteContext(gl_ctx)
78 + win32.ReleaseDC(hwnd, hdc)
79 + return {}, false
80 + }
81 +
82 + gl.load_up_to(4, 5, win32.gl_set_proc_address)
83 + return {hwnd = hwnd, hdc = hdc, gl_ctx = gl_ctx, width = width, height = height}, true
84 + }
85 +
86 + destroy_gl_context :: proc(ctx: ^GL_Context) {
87 + if ctx == nil || ctx.hdc == nil do return
88 + win32.wglMakeCurrent(nil, nil)
89 + if ctx.gl_ctx != nil do win32.wglDeleteContext(ctx.gl_ctx)
90 + if ctx.hwnd != nil do win32.ReleaseDC(ctx.hwnd, ctx.hdc)
91 + ctx^ = {}
92 + }
93 +
94 + make_gl_context_current :: proc(ctx: ^GL_Context) -> bool {
95 + if ctx == nil || ctx.hdc == nil || ctx.gl_ctx == nil do return false
96 + return win32.wglMakeCurrent(ctx.hdc, ctx.gl_ctx)
97 + }
98 +
99 + swap_gl_context :: proc(ctx: ^GL_Context) -> bool {
100 + if ctx == nil || ctx.hdc == nil do return false
101 + return win32.SwapBuffers(ctx.hdc)
102 + }
103 +
104 + resize_gl_context :: proc(ctx: ^GL_Context, width, height: u32) {
105 + if ctx == nil do return
106 + ctx.width = width
107 + ctx.height = height
108 + }
109 +
110 + gl_context_set_proc_address :: proc(p: rawptr, name: cstring) {
111 + win32.gl_set_proc_address(p, name)
112 + }
gpu/backend/opengl/gl_frame.odin +69 -0 added
1 + package opengl_backend
2 +
3 + import "core:log"
4 + import gl "vendor:OpenGL"
5 +
6 + import bk ".."
7 +
8 + begin_frame_opengl :: proc(clear_color: [4]f32) -> (bk.Frame_Context, bool) {
9 + if g_gl == nil {
10 + log.error("gpu/opengl: begin_frame before backend init")
11 + return {}, false
12 + }
13 + make_gl_context_current(&g_gl.gl_ctx)
14 + g_gl.frame_active = true
15 + return {frame_index = g_gl.current_frame}, true
16 + }
17 +
18 + end_frame_opengl :: proc(ctx: bk.Frame_Context) -> bool {
19 + if g_gl == nil do return false
20 + g_gl.frame_active = false
21 + g_gl.current_frame = (g_gl.current_frame + 1) % bk.MAX_FRAMES_IN_FLIGHT
22 + return false
23 + }
24 +
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 + begin_default_pass_opengl :: proc(ctx: bk.Frame_Context, clear_color: [4]f32) {
36 + if g_gl == nil do return
37 + gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
38 + gl.Viewport(0, 0, i32(g_gl.width), i32(g_gl.height))
39 + gl.ClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3])
40 + gl.ClearDepth(1.0)
41 + gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
42 + g_gl.render_pass_active = true
43 + }
44 +
45 + begin_render_pass_opengl :: proc(ctx: bk.Frame_Context, desc: bk.Render_Pass_Begin_Desc) {
46 + if desc.framebuffer == bk.NULL_FRAMEBUFFER {
47 + begin_default_pass_opengl(ctx, desc.clear_color)
48 + return
49 + }
50 + log.error("gpu/opengl: offscreen render passes not implemented yet")
51 + }
52 +
53 + end_render_pass_opengl :: proc(ctx: bk.Frame_Context) {
54 + if g_gl == nil do return
55 + g_gl.render_pass_active = false
56 + }
57 +
58 + set_viewport_opengl :: proc(ctx: bk.Frame_Context, x, y, w, h: f32) {
59 + gl.Viewport(i32(x), i32(y), i32(w), i32(h))
60 + }
61 +
62 + set_scissor_opengl :: proc(ctx: bk.Frame_Context, x, y: i32, w, h: u32) {
63 + gl.Enable(gl.SCISSOR_TEST)
64 + gl.Scissor(x, y, i32(w), i32(h))
65 + }
66 +
67 + set_depth_bias_opengl :: proc(ctx: bk.Frame_Context, constant, slope: f32) {
68 + log.error("gpu/opengl: depth bias not implemented yet")
69 + }
gpu/backend/opengl/gl_ops.odin +149 -0 added
1 + package opengl_backend
2 +
3 + import "core:log"
4 + import gl "vendor:OpenGL"
5 +
6 + import bk ".."
7 +
8 + create_graphics_pipeline_opengl :: proc(desc: bk.Pipeline_Desc) -> (bk.Pipeline_Handle, bool) {
9 + log.error("gpu/opengl: graphics pipelines not implemented yet")
10 + return bk.NULL_PIPELINE, false
11 + }
12 +
13 + destroy_graphics_pipeline_opengl :: proc(handle: bk.Pipeline_Handle) {}
14 +
15 + bind_graphics_pipeline_opengl :: proc(ctx: bk.Frame_Context, handle: bk.Pipeline_Handle) {}
16 +
17 + push_constants_opengl :: proc(ctx: bk.Frame_Context, pipeline: bk.Pipeline_Handle, stages: bk.Shader_Stage_Flags, offset, size: u32, data: rawptr) {
18 + log.error("gpu/opengl: push constants not implemented yet")
19 + }
20 +
21 + create_buffer_opengl :: proc(desc: bk.Buffer_Desc) -> (bk.Buffer_Handle, bool) {
22 + log.error("gpu/opengl: buffers not implemented yet")
23 + return bk.NULL_BUFFER, false
24 + }
25 +
26 + create_buffer_staged_opengl :: proc(data: rawptr, size: int, usage: bk.Buffer_Usage_Flags) -> (bk.Buffer_Handle, bool) {
27 + log.error("gpu/opengl: staged buffers not implemented yet")
28 + return bk.NULL_BUFFER, false
29 + }
30 +
31 + destroy_buffer_opengl :: proc(handle: bk.Buffer_Handle) {}
32 +
33 + map_buffer_opengl :: proc(handle: bk.Buffer_Handle) -> rawptr {
34 + log.error("gpu/opengl: buffer mapping not implemented yet")
35 + return nil
36 + }
37 +
38 + unmap_buffer_opengl :: proc(handle: bk.Buffer_Handle) {}
39 +
40 + get_buffer_mapped_opengl :: proc(handle: bk.Buffer_Handle) -> rawptr {
41 + return nil
42 + }
43 +
44 + bind_vertex_buffer_opengl :: proc(ctx: bk.Frame_Context, handle: bk.Buffer_Handle) {}
45 +
46 + bind_index_buffer_opengl :: proc(ctx: bk.Frame_Context, handle: bk.Buffer_Handle) {}
47 +
48 + create_texture_opengl :: proc(desc: bk.Texture_Desc, pixels: rawptr) -> (bk.Texture_Handle, bool) {
49 + log.error("gpu/opengl: textures not implemented yet")
50 + return bk.NULL_TEXTURE, false
51 + }
52 +
53 + destroy_texture_opengl :: proc(handle: bk.Texture_Handle) {}
54 +
55 + create_sampler_opengl :: proc(desc: bk.Sampler_Desc) -> (bk.Sampler_Handle, bool) {
56 + log.error("gpu/opengl: samplers not implemented yet")
57 + return bk.NULL_SAMPLER, false
58 + }
59 +
60 + destroy_sampler_opengl :: proc(handle: bk.Sampler_Handle) {}
61 +
62 + create_image_opengl :: proc(desc: bk.Texture_Desc) -> (bk.Texture_Handle, bool) {
63 + log.error("gpu/opengl: images not implemented yet")
64 + return bk.NULL_TEXTURE, false
65 + }
66 +
67 + create_image_view_opengl :: proc(texture: bk.Texture_Handle, format: bk.Format, aspect: bk.Image_Aspect_Flags) -> bool {
68 + log.error("gpu/opengl: image views not implemented yet")
69 + return false
70 + }
71 +
72 + destroy_image_opengl :: proc(handle: bk.Texture_Handle) {}
73 +
74 + create_descriptor_set_layout_opengl :: proc(bindings: []bk.Descriptor_Set_Layout_Binding) -> (bk.Descriptor_Handle, bool) {
75 + log.error("gpu/opengl: descriptor set layouts not implemented yet")
76 + return bk.NULL_DESCRIPTOR, false
77 + }
78 +
79 + destroy_descriptor_set_layout_opengl :: proc(handle: bk.Descriptor_Handle) {}
80 +
81 + create_descriptor_pool_opengl :: proc(max_sets: u32, types: []bk.Descriptor_Type, counts: []u32) -> (bk.Descriptor_Handle, bool) {
82 + log.error("gpu/opengl: descriptor pools not implemented yet")
83 + return bk.NULL_DESCRIPTOR, false
84 + }
85 +
86 + destroy_descriptor_pool_opengl :: proc(handle: bk.Descriptor_Handle) {}
87 +
88 + allocate_descriptor_set_opengl :: proc(pool: bk.Descriptor_Handle, layout: bk.Descriptor_Handle) -> (bk.Descriptor_Handle, bool) {
89 + log.error("gpu/opengl: descriptor sets not implemented yet")
90 + return bk.NULL_DESCRIPTOR, false
91 + }
92 +
93 + bind_descriptor_set_opengl :: proc(ctx: bk.Frame_Context, pipeline: bk.Pipeline_Handle, set: bk.Descriptor_Handle, index: u32) {
94 + log.error("gpu/opengl: descriptor binding not implemented yet")
95 + }
96 +
97 + update_descriptor_image_opengl :: proc(set: bk.Descriptor_Handle, binding: u32, texture: bk.Texture_Handle, sampler: bk.Sampler_Handle, layout: bk.Image_Layout) {
98 + log.error("gpu/opengl: image descriptor updates not implemented yet")
99 + }
100 +
101 + update_descriptor_buffer_opengl :: proc(set: bk.Descriptor_Handle, binding: u32, buffer: bk.Buffer_Handle, size: u64) {
102 + log.error("gpu/opengl: buffer descriptor updates not implemented yet")
103 + }
104 +
105 + create_render_pass_opengl :: proc(desc: bk.Render_Pass_Desc) -> (bk.Render_Pass_Handle, bool) {
106 + log.error("gpu/opengl: render pass objects not implemented yet")
107 + return bk.NULL_RENDER_PASS, false
108 + }
109 +
110 + destroy_render_pass_opengl :: proc(handle: bk.Render_Pass_Handle) {}
111 +
112 + create_framebuffer_opengl :: proc(desc: bk.Framebuffer_Desc) -> (bk.Framebuffer_Handle, bool) {
113 + log.error("gpu/opengl: framebuffers not implemented yet")
114 + return bk.NULL_FRAMEBUFFER, false
115 + }
116 +
117 + destroy_framebuffer_opengl :: proc(handle: bk.Framebuffer_Handle) {}
118 +
119 + create_shader_module_opengl :: proc(desc: bk.Shader_Module_Desc) -> (bk.Shader_Handle, bool) {
120 + if desc.format != .GLSL {
121 + log.error("gpu/opengl: shader module requires GLSL source")
122 + return bk.NULL_SHADER, false
123 + }
124 + log.error("gpu/opengl: shader modules not implemented yet")
125 + return bk.NULL_SHADER, false
126 + }
127 +
128 + destroy_shader_opengl :: proc(handle: bk.Shader_Handle) {}
129 +
130 + draw_indexed_opengl :: proc(ctx: bk.Frame_Context, index_count, instance_count: u32, first_index: u32, vertex_offset: i32, first_instance: u32) {
131 + log.error("gpu/opengl: draw_indexed not implemented yet")
132 + }
133 +
134 + create_compute_pipeline_opengl :: proc(shader: bk.Shader_Handle, num_buffers: u32, push_constant_size: u32) -> (bk.Pipeline_Handle, bool) {
135 + log.error("gpu/opengl: compute pipelines not implemented yet")
136 + return bk.NULL_PIPELINE, false
137 + }
138 +
139 + destroy_compute_pipeline_opengl :: proc(handle: bk.Pipeline_Handle) {}
140 +
141 + bind_compute_pipeline_opengl :: proc(ctx: bk.Frame_Context, handle: bk.Pipeline_Handle) {}
142 +
143 + dispatch_compute_opengl :: proc(ctx: bk.Frame_Context, groups_x, groups_y, groups_z: u32) {
144 + log.error("gpu/opengl: compute dispatch not implemented yet")
145 + }
146 +
147 + compute_barrier_opengl :: proc(ctx: bk.Frame_Context) {
148 + gl.MemoryBarrier(gl.SHADER_STORAGE_BARRIER_BIT | gl.TEXTURE_FETCH_BARRIER_BIT | gl.FRAMEBUFFER_BARRIER_BIT)
149 + }
gpu/gpu.odin modified

Diff hidden because this file has more than 800 lines.

gpu/renderer/draw2d.odin +1 -1 modified
635 unchanged lines hidden
636 636 // D3D NDC has Y+ up so we swap bottom/top to achieve the same Y-down result.
637 637 ortho_2d :: proc(left, right, bottom, top: f32) -> glsl.mat4x4 {
638 638 b, t: f32
639 - when bk.GPU_BACKEND == "vulkan" {
639 + when bk.GPU_BACKEND == "vulkan" || bk.GPU_BACKEND == "opengl" {
640 640 b = bottom
641 641 t = top
642 642 } else {
18 unchanged lines hidden