OpenGL
Created at 2017-06-04T19:34:27+09:00

Mesa

  • [x] build system and debug development setup
    • libglapi, (libGL,) libEGL, swrast_dri
  • [ ] Follow swrast dri and llvmpipe
  • [ ] Shader program compilation/execution
  • [ ] pipeline: vertex -> primitive -> fragment -> pixels
    • from OpenGL 4.5 spec
    • Fixed parts
    • Chapter 13. Fixed-Function Vertex Post-Processing
      • viewport ?
    • Chapter 14. Fixed-Function Primitive Assembly and Rasterization (lp_rast.c)
      • create gl_PointCoord, gl_FragCoord for each fragment
    • Programmable parts
    • Chapter 11. vertex shader
    • Chapter 15. fragment shader

Build from source

Relation between source and build artifacts:

  • mapi/glapi/gen, mapi => libglapi.so, libGLESv1_CM.so, libGLESv2.so.2.0.0
  • glx/ => libGL.so
  • egl/ => libEGL.so
  • egl/wayland/wayland-drm/ => wayland-drm.c (wl server), wayland-drm-protocol.c, wayland-drm-{server,client}-protocol.h
  • egl/wayland/wayland-egl/ => libwayland-egl.so, wayland-egl.h
  • compiler/ => libglsl.la , ..
  • libglsl.la + mesa/ => libmesa.la or libmesagallium.la
  • gallium/drivers/softpipe/,llvmpipe/ => libllvmpipe.la,libsoftpipe.la
  • gallium/targets/dri/ + libmesagallium.la + libglapi.la + libllvmpipe.la + ... => gallium_dri.la, gallium/swrast_dri.so

Link against debug build

[ Mesa main repo ]
$ mkdir out/Debug
$ cd out/Debug
$ ../../configure CFLAGS='-g -O0' CXXFLAGS='-g -O0' \
                  --enable-gles1 --enable-gles2 \
                  --with-gallium-drivers=swrast --with-dri-drivers='' \
                  --with-platforms=wayland \
                  --disable-osmesa \
                  --disable-gbm --disable-dri3 --disable-glx
$ make
$ ls lib/libglapi.so lib/libEGL.so lib/gallium/swrast_dri.so
lib/gallium/swrast_dri.so  lib/libEGL.so  lib/libglapi.so

[ Use weston's simple-egl ]
$ mkdir out/Debug
$ cd out/Debug
$ ../../configure CFLAGS='-g -O0' \
                  SIMPLE_EGL_CLIENT_CFLAGS="-I/home/hiogawa/code/others/mesa/mesa/include" \
                  SIMPLE_EGL_CLIENT_LIBS="-L/home/hiogawa/code/others/mesa/mesa/out/Debug/lib \
                    $(pkg-config --cflags --libs egl glesv2 wayland-client wayland-egl wayland-cursor)"
$ make
$ LD_LIBRARY_PATH=<path-to-mesa>/out/Debug/lib ldd weston-simple-egl # check linking
    linux-vdso.so.1 (0x00007ffd16cfc000)
    libEGL.so.1 => /home/hiogawa/code/others/mesa/mesa/out/Debug/lib/libEGL.so.1 (0x00007f0367206000)
    libGLESv2.so.2 => /home/hiogawa/code/others/mesa/mesa/out/Debug/lib/libGLESv2.so.2 (0x00007f0366ffc000)
    libwayland-egl.so.1 => /home/hiogawa/code/others/mesa/mesa/out/Debug/lib/libwayland-egl.so.1 (0x00007f0366dfa000)
    libwayland-client.so.0 => /usr/lib/libwayland-client.so.0 (0x00007f0366bc7000)
    libwayland-cursor.so.0 => /usr/lib/libwayland-cursor.so.0 (0x00007f03669bf000)
  ...
    libglapi.so.0 => /home/hiogawa/code/others/mesa/mesa/out/Debug/src/mapi/shared-glapi/.libs/libglapi.so.0 (0x00007f0365664000)
  ...
$ LD_LIBRARY_PATH=/home/hiogawa/code/others/mesa/mesa/out/Debug/lib \
  LIBGL_ALWAYS_SOFTWARE=yes \
  LIBGL_DRIVERS_PATH=/home/hiogawa/code/others/mesa/mesa/out/Debug/lib/gallium \
  GALLIUM_DRIVER=llvmpipe \
  lldb weston-simple-egl
(lldb) breakpoint set --name main
(lldb) breakpoint set --name glDrawArrays # this will break into assembly code dispatching to vbo_exec_DrawArrays

# Tips:
# - When debugger is on the line of glXXX, you can use 'thread step-inst' (or 'S' in gui)
#   to look through assembly dispatching routing.

EGL DRI routine (as Wayland client)

[ Data structure ]
__DRIscreen
'-' dri_screen (as driverPrivate)
  '-' st_manager (as base)
    '-' pipe_screen
  '-' st_api (e.g. st_gl_api)
    '-' (as vtable) create_context, make_current
  '-' pipe_loader_device (> pipe_loader_sw_device)
    '-' pipe_loader_ops

llvmpipe_screen (< pipe_screen)
'-' base
  '-' (as vtable) destroy, context_create, resource_create, ...
'-' sw_winsys (> dri_sw_winsys)
  '-' (as vtable) destroy, displaytarget_create, ...
'-' lp_rasterizer
  '-' threads

__DRIContext
'-' __DRIscreen
'-' dri_context (as driverPrivate)
  '-' st_api (copied from dri_screen)
  '-' st_context_iface
    '-' pipe_context
    '-' cso_context
  '-' pp_queue_t
  '-' hud_context

gl_context
'-' st_context (< st_context_iface)
  '-' cso_create
  '-' pipe_context
'-' vbo_context
  '-' draw_prims
  '-' gl_vertex_array
  '-' vbo_exec_context
    '-' vtx
      '-' gl_buffer_object
      '-* gl_vertex_array
      '-* _mesa_prim

llvmpipe_context (< pipe_context)
'-' pipe
  '-' (as vtable) draw_vbo, flush, ...
'-' draw_context
  '-' draw_llvm
    '-' LLVMContextRef
    '-' draw_jit_context
  '-' pipeline
    '-' rasterize
    '-' ...
  '-' pt (pass through)
    '-' draw_pt_front_end (> vsplit_frontend)
    '-' middle
      '-' llvm_middle_end (< draw_pt_middle_end)
        '-' draw_llvm
          '-* draw_llvm_variant
            '-' gallivm_state
              '-' LLVMXXX (e.g. LLVMModuleRef, LLVMMCJITMemoryManagerRef, ..)
              '-' lp_generated_code
            '-' llvm_vertex_shader
            '-' draw_jit_vert_func
            '-* LLVMTypeRef (e.g. function, )
        '-' pt_emit
          '-' translate_sse (< translate)
            '-' translate
              '-' run
  '-' vs (vertex shader stage)
    '-' draw_vertex_shader
  '-' lp_setup_context (< vbuf_render)
    '-' vbuf_render
      '-' (as vtable) draw_arrays, set_primitive, allocate_vertices
      '-' vbuf_stage
        '-' (as vtable) point, line, tri
    '-' vertex_buffer (as *void)
    '-' vertex_info
    '-' lp_scene
  '-' fs (fragment shader stage)
    '-' draw_fragment_shader
'-' blitter_context

__DRIdrawable
'-' dri_drawable (as driverPrivate)
  '-' st_framebuffer_iface (as base)
  '-' st_visual

st_framebuffer
'-' gl_framebuffer (as Base)
  '-* gl_renderbuffer_attachment
    '-' gl_renderbuffer (> st_renderbuffer)
'-' st_framebuffer_iface


[ Setup ]

- eglGetDisplay =>
  - _EGL_PLATFORM_WAYLAND

- eglInitialize =>
  - .. _eglBuiltInDriverDRI2
  - dri2_initialize => dri2_initialize_wayland =>
    - dri2_initialize_wayland_swrast (when LIBGL_ALWAYS_SOFTWARE) =>
      - struct dri2_egl_display *dri2_dpy = calloc
      - roundtrip (discover server's wl_shm interface)
        - registry_handle_global_swrast => dri2_dpy->wl_shm = wl_registry_bind
      - dri2_dpy->driver_name = strdup("swrast")
      - .. dlopen('gallium/swarst_dri.so') and call __driDriverGetExtensions_swrast =>
        - globalDriverAPI = &galliumsw_driver_api
        - returns galliumsw_driver_extensions
      - dri2_dpy->vtbl = &dri2_wl_swrast_display_vtbl
      - __DRIswrastExtension.createNewScreen (i.e. driSWRastCreateNewScreen) =>
        - driCreateNewScreen2 =>
          - psp->driver = globalDriverAPI
          - drisw_init_screen =>
            - struct dri_screen *screen = CALLOC_STRUCT
            - pipe_loader_sw_probe_dri =>
              - struct pipe_loader_sw_device *sdev = CALLOC_STRUCT
              - pipe_loader_sw_probe_init_common =>
                - sdev->base.driver_name = "swrast"
                - sdev->base.ops = &pipe_loader_sw_ops
                - sdev->dd = &driver_descriptors
              - sdev->ws = sdev->dd->winsys[i].create_winsys (dri_create_sw_winsys) =>
                - struct dri_sw_winsys *ws = CALLOC_STRUCT
                - ws->base.displaytarget_create = dri_sw_displaytarget_create, dri_sw_displaytarget_from_handle, ..
            - struct pipe_screen *pscreen = pipe_loader_create_screen =>
              - pipe_loader_sw_create_screen (as pipe_loader_sw_ops.create_screen) =>
                - struct pipe_screen *screen => sw_screen_create(<sw_winsys>) (as driver_descriptors.create_screen) =>
                  - debug_get_option("GALLIUM_DRIVER", ...) =>
                  - sw_screen_create_named =>
                    - struct pipe_screen *screen = llvmpipe_create_screen =>
                      - struct llvmpipe_screen *screen = CALLOC_STRUCT
                      - screen->base.context_create = llvmpipe_create_context, llvmpipe_flush_frontbuffer, ..
                      - llvmpipe_init_screen_resource_funcs =>
                        - screen->resource_create = llvmpipe_resource_create, llvmpipe_resource_from_handle, ..
                      - screen->rast = lp_rast_create =>
                        - struct lp_rasterizer *rast = CALLOC_STRUCT
                        - rast->full_scenes = lp_scene_queue_create =>
                          - struct lp_scene_queue *queue = CALLOC_STRUCT
                          - queue->ring = util_ringbuffer_create
                        - create_rast_threads =>
                          - pipe_semaphore_init
                          - rast->threads[i] = u_thread_create(thread_function, ...) => ... pthread_create
                            (SEE BELOW for what thread_function does)
                        - pipe_barrier_init =>
            - dri_init_screen_helper =>
              - screen->base.screen = pscreen (as <st_manager.screen> = <pipe_screen>)
              - screen->st_api = st_gl_api_create => return st_gl_api

- eglCreateContext =>
  - dri2_create_context (as _EGLDriver.API.CreateContext) =>
    - driCreateContextAttribs (as driSWRastExtension.createContextAttribs) =>
      - dri_create_context (as galliumsw_driver_api.CreateContext) =>
        - struct dri_context *ctx = CALLOC_STRUCT
        - ctx->st = stapi->create_context (st_api_create_context) =>
          - struct pipe_context *pipe = smapi->screen->context_create (llvmpipe_create_context) =>
            - struct llvmpipe_context = align_malloc
            - llvmpipe_init_xxx_funcs (e.g. draw, fs, vs, etc ...)
            - llvmpipe_init_draw_funcs => llvmpipe->pipe.draw_vbo = llvmpipe_draw_vbo
            - llvmpipe_init_fs_funcs => llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state ...
            - llvmpipe_init_vs_funcs => llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state ...
            - llvmpipe->draw = draw_create_with_llvm_context => draw_create_context =>
              - struct draw_context *draw = CALLOC_STRUCT
              - draw->llvm = draw_llvm_create =>
                - struct draw_llvm *llvm = CALLOC_STRUCT
                - llvm->context = LLVMContextCreate
              - draw_init =>
                - draw_pipeline_init =>
                  - draw->pipeline.xxx = draw_xxx_stage (e.g. draw->pipeline.wide_line = draw_wide_line_stage)
                - draw_pt_init =>
                  - draw->pt.front.vsplit = draw_pt_vsplit =>
                    - struct vsplit_frontend *vsplit = CALLOC_STRUCT
                    - vsplit->base.run = NULL
                    - ...
                  - draw->pt.middle.llvm = draw_pt_fetch_pipeline_or_emit_llvm =>
                    - struct llvm_middle_end *fpme = CALLOC_STRUCT
                    - fpme->base.bind_parameters = llvm_middle_end_bind_parameters
                    - fpme->base.run_linear      = llvm_middle_end_linear_run
                    - fpme->emit = draw_pt_emit_create => struct pt_emit *emit = CALLOC_STRUCT
                    - ...
                - draw_vs_init => ...
              - draw->ia = draw_prim_assembler_create => struct draw_assembler *ia = CALLOC_STRUCT
            - llvmpipe->setup = lp_setup_create =>
              - struct lp_setup_context *setup = CALLOC_STRUCT
              - lp_setup_init_vbuf =>
                - setup->base.allocate_vertices = lp_setup_allocate_vertices
                - setup->base.draw_arrays = lp_setup_draw_arrays ...
              - draw_vbuf_stage =>
                - struct vbuf_stage *vbuf = CALLOC_STRUCT
                - vbuf->stage.draw = draw, vbuf->stage.tri = vbuf_first_tri, ...
              - draw_set_rasterize_stage
              - draw_set_render
              - setup->scenes[i] = lp_scene_create => struct lp_scene *scene = CALLOC_STRUCT
              - setup->triangle = first_triangle
            - ...
          - struct st_context *st = st_create_context =>
            - struct gl_context *ctx = calloc
            - st_init_driver_functions =>
              - _mesa_init_shader_object_functions => driver->LinkShader = _mesa_ir_link_shader
              - st_init_bufferobject_functions => functions->NewBufferObject = st_bufferobj_alloc, ...
              - st_init_drawpixels_functions => functions->DrawPixels = st_DrawPixels
              - ...
            - _mesa_initialize_context =>
              - ctx->Driver = *driverFunctions
              - init_attrib_groups =>
                - _mesa_init_varray => ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0)
                - ...
              - ctx->Exec = _mesa_alloc_dispatch_table =>
                - struct _glapi_table *table = _mesa_new_nop_table
            - st_create_context_priv =>
              - struct st_context *st = ST_CALLOC_STRUCT
              - _vbo_CreateContext =>
                - struct vbo_context *vbo = CALLOC_STRUCT
                - vbo_exec_init => vbo_exec_vtx_init =>
                  - _mesa_reference_buffer_object(... &exec->vtx.bufferobj )
                  - exec->vtx.buffer_map = _mesa_align_malloc
                  - vbo_exec_vtxfmt_init =>
                    - vfmt->XXX = vbo_exec_XXX (e.g vfmt->EvalCoord1f = vbo_exec_EvalCoord1f) ...
              - st->cso_context = cso_create_context =>
                - struct cso_context *ctx = CALLOC_STRUCT
              - st_init_draw => vbo->draw_prims = st_draw_vbo
              - _mesa_initialize_dispatch_tables => _mesa_initialize_exec_table =>
                - vbo_initialize_exec_dispatch =>
                  - SET_DrawArrays(exec, vbo_exec_DrawArrays) ...
                - SET_XXX(exec, _mesa_XXX) (e.g. SET_CopyBufferSubData(exec, _mesa_CopyBufferSubData)) ...
              - _mesa_initialize_vbo_vtxfmt => _mesa_install_exec_vtxfmt => install_vtxfmt =>
                - SET_Color4f(tab, vfmt->Color4f) ...
          - return st->iface
        - ctx->stapi = stapi
        - ctx->pp = pp_init => ...
        - ctx->hud = hud_create => ...
        - ctx->st->start_thread => ...

- eglCreateWindowSurface => _eglCreateWindowSurfaceCommon => dri2_create_window_surface =>
  - dri2_wl_create_window_surface (as dri2_wl_swrast_display_vtbl.create_window_surface) =>
    - struct dri2_egl_surface *dri2_surf = calloc
    - dri2_surf->dri_drawable = driCreateNewDrawable (as driSWRastExtension.createNewDrawable) =>
      - __DRIdrawable *pdraw = malloc
      - drisw_create_buffer (as galliumsw_driver_api.CreateBuffer) =>
        - dri_create_buffer =>
          - struct dri_drawable *drawable = CALLOC_STRUCT

- eglMakeCurrent => dri2_make_current =>
  - _eglBindContext
  - driBindContext (as driCoreExtension.bindContext) =>
    - dri_make_current (as galliumsw_driver_api.CreateContext.MakeCurrent) =>
      - st_api_make_current (as st_gl_api.make_current) =>
        - struct st_framebuffer *stdraw = st_framebuffer_reuse_or_create => st_framebuffer_create =>
          - struct st_framebuffer *stfb = CALLOC_STRUCT
          - stfb->iface = stfbi
          - st_framebuffer_add_renderbuffer =>
            - struct gl_renderbuffer *rb = st_new_renderbuffer_fb =>
              - struct st_renderbuffer *strb = ST_CALLOC_STRUCT
              - _mesa_init_renderbuffer
            - _mesa_attach_and_own_rb =>
              - fb->Attachment[bufferName].Renderbuffer = rb
        - _mesa_make_current =>
          - _glapi_set_context => ...
          - _glapi_set_dispatch(newCtx->CurrentClientDispatch) => ... (SEE BELOW about GL dispatching)
        - st_framebuffer_reference

- eglSwapBuffers =>
  - wl_shm ??

GL

[ Vertex handling ]
TODO
- glVertexAttribPointer, glEnableVertexAttribArray


[ Drawing ]
- glDrawArrays =>
  - vbo_exec_DrawArrays => vbo_draw_arrays =>
    - struct _mesa_prim (on stack)
    - st_draw_vbo (as vbo_context.draw_prims) =>
      - struct pipe_draw_info (on stack)
      - cso_draw_vbo => llvmpipe_draw_vbo (as pipe_context.draw_vbo) =>
        - llvmpipe_update_derived => llvmpipe_update_fs => generate_variant =>
          - struct lp_fragment_shader_variant *variant = CALLOC_STRUCT
          - variant->gallivm = gallivm_create => ...
          - generate_fragment(... RAST_EDGE_TEST)
          - generate_fragment(... RAST_WHOLE)
          - gallivm_compile_module
          - variant->jit_function[RAST_EDGE_TEST] = gallivm_jit_function(...)
          - variant->jit_function[RAST_WHOLE] = gallivm_jit_function(...)
        - draw_vbo =>
          - draw_pt_arrays =>
            - opt |= PT_CLIPTEST, opt |= PT_SHADE
            - struct draw_pt_front_end *frontend = draw->pt.front.vsplit
            - struct draw_pt_middle_end *middle = draw->pt.middle.llvm
            - vsplit_prepare (as frontend->prepare) =>
              - vsplit->base.run = vsplit_run_linear
              - llvm_middle_end_prepare (as middle->prepare) =>
                - draw_pt_post_vs_prepare, draw_pt_so_emit_prepare
                - draw_pt_emit_prepare =>
                  - emit->translate = translate_cache_find =>
                    - translate_create => translate_sse_create =>
                      - struct translate_sse *p = os_malloc_aligned
                      - (macro assembly code generation)
                      - build_vertex_emit(p, &p->linear_func, 0)
                      - p->translate.run = (run_func) x86_get_func(&p->linear_func)
                - draw_llvm_create_variant =>
                  - struct draw_llvm_variant *variant = MALLOC
                  - variant->gallivm = gallivm_create =>
                    - struct gallivm_state = CALLOC_STRUCT
                    - init_gallivm_state =>
                      - gallivm->module = LLVMModuleCreateWithNameInContext
                      - gallivm->builder = LLVMCreateBuilderInContext
                      - gallivm->target = LLVMCreateTargetData
                      - ... and pass manager, memory manager etc..
                  - create_jit_types, create_jit_vertex_header => ... LLVMStructTypeInContext
                  - draw_llvm_generate =>
                    - (generate llvm IR for vertex shader function)
                    - LLVMAddFunction
                    - generate_vs =>
                      - const struct tgsi_token *tokens = llvm->draw->vs.vertex_shader->state.tokens
                        (TODO: follow how tgsi_token is gotten)
                      - lp_build_tgsi_soa => lp_build_tgsi_llvm =>
                        - while !tgsi_parse_end_of_tokens
                          - lp_build_tgsi_context.emit_declaration, emit_immediate ...
                  - gallivm_compile_module =>
                    - LLVMRunFunctionPassManager
                    - init_gallivm_engine =>
                      - lp_build_create_jit_compiler_for_module =>
                        - EngineBuilder
                        - *OutCode = ShaderMemoryManager::getGeneratedCode
                        - ExecutionEngine *JIT = EngineBuilder::create
                  - variant->jit_func = gallivm_jit_function => LLVMGetPointerToGlobal
            - llvm_middle_end_bind_parameters (as middle->bind_parameters)
            - vsplit_run_linear (as frontend->run) (FUNC in draw_split_tmp.h) =>
              - vsplit_segment_simple_linear (as SEGMENT_SIMPLE) =>
                - llvm_middle_end_linear_run (as vsplit->middle->run_linear) =>
                  - struct draw_prim_info
                  - llvm_pipeline_generic =>
                    - struct draw_vertex_info llvm_vert_info
                    - llvm_vert_info.verts = MALLOC
                    - fpme->current_variant->jit_func => ...
                    - emit => draw_pt_emit_linear =>
                      - lp_setup_allocate_vertices (as render->allocate_vertices) =>
                        - setup->vertex_buffer = align_malloc
                      - translate->run (translate_sse.linear_func dynamically generated) => ...
                      - lp_setup_draw_arrays (as render->draw_arrays) =>
                        - lp_setup_update_state =>
                          - llvmpipe_update_setup =>
                          - set_scene_state =>
                            - begin_beginning =>
                              - lp_scene_bin_everywhere => lp_scene_bin_command => lp_scene_new_cmd_block =>
                                - struct data_block *block = MALLOC_STRUCT ...
                              - try_update_scene_state
                        - first_triangle(lp_setup_context, v0, v1, v2) (as setup->driangle) (for PIPE_PRIM_TRIANGLES) =>
                          - lp_setup_choose_triangle => setup->triangle = triangle_both
                          - triangle_both =>
                            - calc_fixed_position => ?
                            - retry_triangle_ccw =>
                              - do_triangle_ccw =>
                                - struct lp_rast_triangle *tri = lp_setup_alloc_triangle
                                - setup->setup.variant->jit_function (TODO where doest this code come from ?) => ...
                                - struct lp_rast_plane *plane = GET_PLANES(tri)
                                - lp_setup_bin_triangle =>
                                  - lp_scene_bin_cmd_with_state (e.g. with lp_rast_triangle_32_2 as cmd) =>
                                    - lp_scene_bin_command => lp_scene_new_cmd_block => tail->cmd[i] = cmd

(Flush a.k.a. start raster threads)
- drisw_swap_buffers => st_context_flush (as ctx->st->flush) =>
  - st_flush => do_flush (as st->pipe->flush) => llvmpipe_flush =>
    - draw_flush => ...
    - lp_setup_flush => set_scene_state(... SETUP_FLUSHED ...) =>
      - lp_setup_rasterize_scene =>
        - lp_rast_queue_scene =>
          - lp_scene_enqueue(rast->full_scenes, ..)
          - pipe_semaphore_signal(&task->work_ready)
        - lp_rast_finish => pipe_semaphore_wait

(Raster thread)
- thread_function => while(1)
  - pipe_semaphore_wait(&task->work_ready)
  - struct lp_scene *scene = lp_scene_dequeue
  - lp_rast_begin =>
    - lp_scene_begin_rasterization
    - lp_scene_bin_iter_begin
  - rasterize_scene =>
    - rasterize_bin => do_rasterize_bin =>
      - dispatch[block->cmd[k]]( task, block->arg[k] ) (e.g. lp_rast_triangle_32_2) =>
        - TAG(lp_rast_triangle)(task, args) =>
          - const struct lp_rast_triangle *tri = arg.triangle.tri
          - const int x = task->x, y = task->y
          - ...
          - TAG(do_block_16)(task, tri, plane, px, py, cx) =>
            - ...
            - block_full_4(task, tri, px, py) =>
              - lp_rast_shade_quads_all( struct lp_rasterizer_task *task ...) =>
                - struct lp_fragment_shader_variant *variant = (struct lp_rasterizer_task *task)->variant
                - ...
                - variant->jit_function
  - lp_rast_end => lp_scene_end_rasterization
  - pipe_semaphore_signal(&task->work_done)


[ Shader compilation ]
- TODO debug dump glsl, shader info, tgsi, llvm code ?
  - glsl -> tgsi -> llvm
- sources
  - tgsi_parse.{h,c}
  - p_shader_tokens.h (#define TGSI_OPCODE_XXX)

tgsi_parse_context
'-* tgsi_token
  '-' tgsi_token_type


[ Dispatching glXXX ]

(mapi/glapi/glapi.h)
extern __thread struct _glapi_table * _glapi_tls_Dispatch
extern __thread void * _glapi_tls_Context

(mapi/u_current.h)
#define u_current_table _glapi_tls_Dispatch
#define u_current_context _glapi_tls_Context

(mapi/glapi/glapi.c)
- _glapi_set_context => ..
- _glapi_set_dispatch =>
  - u_current_set_table =>
    - u_current_table = <_glapi_table>

(mapi/glapi/glapitemp.h (generated by gl_apitemp.py))
- glDrawArrays --> NAME(DrawArrays) =>
  - DISPATCH(DrawArrays, (mode, first, count), ..) -->
    GET_DISPATCH()->DrawArrays (mode, first, count) -->
    _glapi_tls_Dispatch->DrawArrays => ...


[ Shader ]
- glCreateShader, glShaderSource, glCompileShader
- glCreateProgram, glAttachShader, glLinkProgram, glUseProgram
- glBindAttribLocation

TODO

  • follow swrast pipeline first

  • [x] mesa development (building, debugging, logging)

  • follow spec (OpenGL, GLSL) https://khronos.org/registry/OpenGL/index_gl.php

  • follow intel video card spec ??

  • follow mesa implementation (intel, i965, brw, driver ? or swrast ?)

  • follow device driver

  • find real world example

    • chromium (compositor, skia)
    • window manager (kde, gnome, weston, sway)
    • free game and game engines (Urho3D, Unreal)
  • what's gallium layer

  • what's difference between softpipe, llvmpipe, swrt

  • dri: mesa/drivers/dri/{i965,radeon,swrast}

  • gallium: gallium/drivers/{radeon,llvmpipe,swr}

  • compiler: compiler/{glsl,nir,spirv}

  • mesa/swrast

Reference