diff -ruN mesa-26.1.4/include/GL/osmesa.h mesa-26.1.4-banan_os/include/GL/osmesa.h --- mesa-26.1.4/include/GL/osmesa.h 1970-01-01 02:00:00.000000000 +0200 +++ mesa-26.1.4-banan_os/include/GL/osmesa.h 2026-07-05 04:20:13.927530490 +0300 @@ -0,0 +1,332 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * Mesa Off-Screen rendering interface. + * + * This is an operating system and window system independent interface to + * Mesa which allows one to render images into a client-supplied buffer in + * main memory. Such images may manipulated or saved in whatever way the + * client wants. + * + * These are the API functions: + * OSMesaCreateContext - create a new Off-Screen Mesa rendering context + * OSMesaMakeCurrent - bind an OSMesaContext to a client's image buffer + * and make the specified context the current one. + * OSMesaDestroyContext - destroy an OSMesaContext + * OSMesaGetCurrentContext - return thread's current context ID + * OSMesaPixelStore - controls how pixels are stored in image buffer + * OSMesaGetIntegerv - return OSMesa state parameters + * + * + * The limits on the width and height of an image buffer can be retrieved + * via OSMesaGetIntegerv(OSMESA_MAX_WIDTH/OSMESA_MAX_HEIGHT). + */ + + +#ifndef OSMESA_H +#define OSMESA_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + + +#define OSMESA_MAJOR_VERSION 11 +#define OSMESA_MINOR_VERSION 2 +#define OSMESA_PATCH_VERSION 0 + + + +/* + * Values for the format parameter of OSMesaCreateContext() + * New in version 2.0. + */ +#define OSMESA_COLOR_INDEX GL_COLOR_INDEX +#define OSMESA_RGBA GL_RGBA +#define OSMESA_BGRA 0x1 +#define OSMESA_ARGB 0x2 +#define OSMESA_RGB GL_RGB +#define OSMESA_BGR 0x4 +#define OSMESA_RGB_565 0x5 + + +/* + * OSMesaPixelStore() parameters: + * New in version 2.0. + */ +#define OSMESA_ROW_LENGTH 0x10 +#define OSMESA_Y_UP 0x11 + + +/* + * Accepted by OSMesaGetIntegerv: + */ +#define OSMESA_WIDTH 0x20 +#define OSMESA_HEIGHT 0x21 +#define OSMESA_FORMAT 0x22 +#define OSMESA_TYPE 0x23 +#define OSMESA_MAX_WIDTH 0x24 /* new in 4.0 */ +#define OSMESA_MAX_HEIGHT 0x25 /* new in 4.0 */ + +/* + * Accepted in OSMesaCreateContextAttrib's attribute list. + */ +#define OSMESA_DEPTH_BITS 0x30 +#define OSMESA_STENCIL_BITS 0x31 +#define OSMESA_ACCUM_BITS 0x32 +#define OSMESA_PROFILE 0x33 +#define OSMESA_CORE_PROFILE 0x34 +#define OSMESA_COMPAT_PROFILE 0x35 +#define OSMESA_CONTEXT_MAJOR_VERSION 0x36 +#define OSMESA_CONTEXT_MINOR_VERSION 0x37 + + +typedef struct osmesa_context *OSMesaContext; + + +/* + * Create an Off-Screen Mesa rendering context. The only attribute needed is + * an RGBA vs Color-Index mode flag. + * + * Input: format - one of OSMESA_COLOR_INDEX, OSMESA_RGBA, OSMESA_BGRA, + * OSMESA_ARGB, OSMESA_RGB, or OSMESA_BGR. + * sharelist - specifies another OSMesaContext with which to share + * display lists. NULL indicates no sharing. + * Return: an OSMesaContext or 0 if error + */ +GLAPI OSMesaContext APIENTRY +OSMesaCreateContext( GLenum format, OSMesaContext sharelist ); + + + +/* + * Create an Off-Screen Mesa rendering context and specify desired + * size of depth buffer, stencil buffer and accumulation buffer. + * If you specify zero for depthBits, stencilBits, accumBits you + * can save some memory. + * + * New in Mesa 3.5 + */ +GLAPI OSMesaContext APIENTRY +OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits, + GLint accumBits, OSMesaContext sharelist); + + +/* + * Create an Off-Screen Mesa rendering context with attribute list. + * The list is composed of (attribute, value) pairs and terminated with + * attribute==0. Supported Attributes: + * + * Attributes Values + * -------------------------------------------------------------------------- + * OSMESA_FORMAT OSMESA_RGBA*, OSMESA_BGRA, OSMESA_ARGB, etc. + * OSMESA_DEPTH_BITS 0*, 16, 24, 32 + * OSMESA_STENCIL_BITS 0*, 8 + * OSMESA_ACCUM_BITS 0*, 16 + * OSMESA_PROFILE OSMESA_COMPAT_PROFILE*, OSMESA_CORE_PROFILE + * OSMESA_CONTEXT_MAJOR_VERSION 1*, 2, 3 + * OSMESA_CONTEXT_MINOR_VERSION 0+ + * + * Note: * = default value + * + * We return a context version >= what's specified by OSMESA_CONTEXT_MAJOR/ + * MINOR_VERSION for the given profile. For example, if you request a GL 1.4 + * compat profile, you might get a GL 3.0 compat profile. + * Otherwise, null is returned if the version/profile is not supported. + * + * New in Mesa 11.2 + */ +GLAPI OSMesaContext APIENTRY +OSMesaCreateContextAttribs( const int *attribList, OSMesaContext sharelist ); + + + +/* + * Destroy an Off-Screen Mesa rendering context. + * + * Input: ctx - the context to destroy + */ +GLAPI void APIENTRY +OSMesaDestroyContext( OSMesaContext ctx ); + + + +/* + * Bind an OSMesaContext to an image buffer. The image buffer is just a + * block of memory which the client provides. Its size must be at least + * as large as width*height*sizeof(type). Its address should be a multiple + * of 4 if using RGBA mode. + * + * Image data is stored in the order of glDrawPixels: row-major order + * with the lower-left image pixel stored in the first array position + * (ie. bottom-to-top). + * + * Since the only type initially supported is GL_UNSIGNED_BYTE, if the + * context is in RGBA mode, each pixel will be stored as a 4-byte RGBA + * value. If the context is in color indexed mode, each pixel will be + * stored as a 1-byte value. + * + * If the context's viewport hasn't been initialized yet, it will now be + * initialized to (0,0,width,height). + * + * Input: ctx - the rendering context + * buffer - the image buffer memory + * type - data type for pixel components, only GL_UNSIGNED_BYTE + * supported now + * width, height - size of image buffer in pixels, at least 1 + * Return: GL_TRUE if success, GL_FALSE if error because of invalid ctx, + * invalid buffer address, type!=GL_UNSIGNED_BYTE, width<1, height<1, + * width>internal limit or height>internal limit. + */ +GLAPI GLboolean APIENTRY +OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type, + GLsizei width, GLsizei height ); + + + + +/* + * Return the current Off-Screen Mesa rendering context handle. + */ +GLAPI OSMesaContext APIENTRY +OSMesaGetCurrentContext( void ); + + + +/* + * Set pixel store/packing parameters for the current context. + * This is similar to glPixelStore. + * Input: pname - OSMESA_ROW_LENGTH + * specify actual pixels per row in image buffer + * 0 = same as image width (default) + * OSMESA_Y_UP + * zero = Y coordinates increase downward + * non-zero = Y coordinates increase upward (default) + * value - the value for the parameter pname + * + * New in version 2.0. + */ +GLAPI void APIENTRY +OSMesaPixelStore( GLint pname, GLint value ); + + + +/* + * Return an integer value like glGetIntegerv. + * Input: pname - + * OSMESA_WIDTH return current image width + * OSMESA_HEIGHT return current image height + * OSMESA_FORMAT return image format + * OSMESA_TYPE return color component data type + * OSMESA_ROW_LENGTH return row length in pixels + * OSMESA_Y_UP returns 1 or 0 to indicate Y axis direction + * value - pointer to integer in which to return result. + */ +GLAPI void APIENTRY +OSMesaGetIntegerv( GLint pname, GLint *value ); + + + +/* + * Return the depth buffer associated with an OSMesa context. + * Input: c - the OSMesa context + * Output: width, height - size of buffer in pixels + * bytesPerValue - bytes per depth value (2 or 4) + * buffer - pointer to depth buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + * + * New in Mesa 2.4. + */ +GLAPI GLboolean APIENTRY +OSMesaGetDepthBuffer( OSMesaContext c, GLint *width, GLint *height, + GLint *bytesPerValue, void **buffer ); + + + +/* + * Return the color buffer associated with an OSMesa context. + * Input: c - the OSMesa context + * Output: width, height - size of buffer in pixels + * format - buffer format (OSMESA_FORMAT) + * buffer - pointer to depth buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + * + * New in Mesa 3.3. + */ +GLAPI GLboolean APIENTRY +OSMesaGetColorBuffer( OSMesaContext c, GLint *width, GLint *height, + GLint *format, void **buffer ); + + + +/** + * This typedef is new in Mesa 6.3. + */ +typedef void (*OSMESAproc)(); + + +/* + * Return pointer to the named function. + * New in Mesa 4.1 + * Return OSMESAproc in 6.3. + */ +GLAPI OSMESAproc APIENTRY +OSMesaGetProcAddress( const char *funcName ); + + + +/** + * Enable/disable color clamping, off by default. + * New in Mesa 6.4.2 + */ +GLAPI void APIENTRY +OSMesaColorClamp(GLboolean enable); + + +/** + * Enable/disable Gallium post-process filters. + * This should be called after a context is created, but before it is + * made current for the first time. After a context has been made + * current, this function has no effect. + * If the enable_value param is zero, the filter is disabled. Otherwise + * the filter is enabled, and the value may control the filter's quality. + * New in Mesa 10.0 + */ +GLAPI void APIENTRY +OSMesaPostprocess(OSMesaContext osmesa, const char *filter, + unsigned enable_value); + + +#ifdef __cplusplus +} +#endif + + +#endif diff -ruN mesa-26.1.4/include/meson.build mesa-26.1.4-banan_os/include/meson.build --- mesa-26.1.4/include/meson.build 2026-07-01 17:16:13.000000000 +0300 +++ mesa-26.1.4-banan_os/include/meson.build 2026-07-05 04:20:13.934374363 +0300 @@ -78,6 +78,10 @@ ) endif +if with_osmesa + install_headers('GL/osmesa.h', subdir : 'GL') +endif + if with_dri install_headers('GL/internal/dri_interface.h', subdir : 'GL/internal') endif diff -ruN mesa-26.1.4/meson.build mesa-26.1.4-banan_os/meson.build --- mesa-26.1.4/meson.build 2026-07-01 17:16:13.000000000 +0300 +++ mesa-26.1.4-banan_os/meson.build 2026-07-05 04:20:13.894859382 +0300 @@ -107,6 +107,7 @@ with_aco_tests = get_option('build-aco-tests') with_glx_read_only_text = get_option('glx-read-only-text') with_glx_direct = get_option('glx-direct') +with_osmesa = get_option('osmesa') with_vulkan_overlay_layer = get_option('vulkan-layers').contains('overlay') with_vulkan_device_select_layer = get_option('vulkan-layers').contains('device-select') with_vulkan_screenshot_layer = get_option('vulkan-layers').contains('screenshot') @@ -2152,6 +2153,17 @@ pre_args += '-DHAVE_LIBUNWIND' endif +if with_osmesa + if not with_gallium_swrast + error('OSMesa gallium requires gallium softpipe or llvmpipe.') + endif + if host_machine.system() == 'windows' + osmesa_lib_name = 'osmesa' + else + osmesa_lib_name = 'OSMesa' + endif +endif + # TODO: symbol mangling with_wayland_bind_display = with_platform_wayland and get_option('legacy-wayland').contains('bind-wayland-display') @@ -2567,6 +2579,7 @@ gallium_frontends += 'rusticl' endif gallium_summary += {'Frontends': gallium_frontends} + gallium_summary += {'Off-screen rendering (OSMesa)': with_osmesa ? 'lib' + osmesa_lib_name : false} gallium_summary += {'HUD lm-sensors': dep_lmsensors.found()} endif summary(gallium_summary, section: 'Gallium', bool_yn: true, list_sep: ' ') diff -ruN mesa-26.1.4/meson.options mesa-26.1.4-banan_os/meson.options --- mesa-26.1.4/meson.options 2026-07-01 17:16:13.000000000 +0300 +++ mesa-26.1.4-banan_os/meson.options 2026-07-05 04:20:13.784091541 +0300 @@ -547,6 +547,13 @@ ) option( + 'osmesa', + type : 'boolean', + value : false, + description : 'Build OSmesa.' +) + +option( 'tools', type : 'array', value : [], diff -ruN mesa-26.1.4/src/gallium/frontends/osmesa/meson.build mesa-26.1.4-banan_os/src/gallium/frontends/osmesa/meson.build --- mesa-26.1.4/src/gallium/frontends/osmesa/meson.build 1970-01-01 02:00:00.000000000 +0200 +++ mesa-26.1.4-banan_os/src/gallium/frontends/osmesa/meson.build 2026-07-05 04:20:14.131684982 +0300 @@ -0,0 +1,19 @@ +# Copyright © 2017-2018 Intel Corporation +# SPDX-License-Identifier: MIT + +osmesa_st_c_args = [] +if with_platform_windows + if not with_shared_glapi + osmesa_st_c_args += ['-D_GLAPI_NO_EXPORTS'] + endif +endif + +libosmesa_st = static_library( + 'osmesa_st', + 'osmesa.c', + c_args : osmesa_st_c_args, + include_directories : [ + inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_mesa, + ], + dependencies : [idep_mesautil], +) diff -ruN mesa-26.1.4/src/gallium/frontends/osmesa/osmesa.c mesa-26.1.4-banan_os/src/gallium/frontends/osmesa/osmesa.c --- mesa-26.1.4/src/gallium/frontends/osmesa/osmesa.c 1970-01-01 02:00:00.000000000 +0200 +++ mesa-26.1.4-banan_os/src/gallium/frontends/osmesa/osmesa.c 2026-07-05 04:20:14.131719693 +0300 @@ -0,0 +1,1029 @@ +/* + * Copyright (c) 2013 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* + * Off-Screen rendering into client memory. + * OpenGL gallium frontend for softpipe and llvmpipe. + * + * Notes: + * + * If Gallium is built with LLVM support we use the llvmpipe driver. + * Otherwise we use softpipe. The GALLIUM_DRIVER environment variable + * may be set to "softpipe" or "llvmpipe" to override. + * + * With softpipe we could render directly into the user's buffer by using a + * display target resource. However, softpipe doesn't support "upside-down" + * rendering which would be needed for the OSMESA_Y_UP=TRUE case. + * + * With llvmpipe we could only render directly into the user's buffer when its + * width and height is a multiple of the tile size (64 pixels). + * + * Because of these constraints we always render into ordinary resources then + * copy the results to the user's buffer in the flush_front() function which + * is called when the app calls glFlush/Finish. + * + * In general, the OSMesa interface is pretty ugly and not a good match + * for Gallium. But we're interested in doing the best we can to preserve + * application portability. With a little work we could come up with a + * much nicer, new off-screen Gallium interface... + */ + +/** + * The following block is for avoid windows.h to be included + * and osmesa require APIENTRY to be defined + */ +#include "util/glheader.h" +#ifndef APIENTRY +#define APIENTRY GLAPIENTRY +#endif +#include "GL/osmesa.h" + +#include +#include + +#include "state_tracker/st_context.h" + +#include "glapi/glapi/glapi.h" /* for OSMesaGetProcAddress below */ + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_state.h" + +#include "util/u_atomic.h" +#include "util/box.h" +#include "util/u_debug.h" +#include "util/format/u_format.h" +#include "util/u_inlines.h" +#include "util/u_memory.h" + +#include "postprocess/filters.h" +#include "postprocess/postprocess.h" + +#include "frontend/api.h" + + + +extern struct pipe_screen * +osmesa_create_screen(void); + + + +struct osmesa_buffer +{ + struct pipe_frontend_drawable base; + struct st_visual visual; + unsigned width, height; + + struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; + + void *map; + + struct osmesa_buffer *next; /**< next in linked list */ +}; + + +struct osmesa_context +{ + struct st_context *st; + + bool ever_used; /*< Has this context ever been current? */ + + struct osmesa_buffer *current_buffer; + + /* Storage for depth/stencil, if the user has requested access. The backing + * driver always has its own storage for the actual depth/stencil, which we + * have to transfer in and out. + */ + void *zs; + unsigned zs_stride; + + enum pipe_format depth_stencil_format, accum_format; + + GLenum format; /*< User-specified context format */ + GLenum type; /*< Buffer's data type */ + GLint user_row_length; /*< user-specified number of pixels per row */ + GLboolean y_up; /*< TRUE -> Y increases upward */ + /*< FALSE -> Y increases downward */ + + /** Which postprocessing filters are enabled. */ + unsigned pp_enabled[PP_FILTERS]; + struct pp_queue_t *pp; +}; + +/** + * Called from the ST manager. + */ +static int +osmesa_st_get_param(struct pipe_frontend_screen *fscreen, enum st_manager_param param) +{ + /* no-op */ + return 0; +} + +static struct pipe_frontend_screen *global_fscreen = NULL; + +static void +destroy_st_manager(void) +{ + if (global_fscreen) { + if (global_fscreen->screen) + global_fscreen->screen->destroy(global_fscreen->screen); + FREE(global_fscreen); + } +} + +static void +create_st_manager(void) +{ + if (atexit(destroy_st_manager) != 0) + return; + + global_fscreen = CALLOC_STRUCT(pipe_frontend_screen); + if (global_fscreen) { + global_fscreen->screen = osmesa_create_screen(); + global_fscreen->get_param = osmesa_st_get_param; + global_fscreen->get_egl_image = NULL; + } +} + +/** + * Create/return a singleton st_manager object. + */ +static struct pipe_frontend_screen * +get_st_manager(void) +{ + static once_flag create_once_flag = ONCE_FLAG_INIT; + + call_once(&create_once_flag, create_st_manager); + + return global_fscreen; +} + +/* Reads the color or depth buffer from the backing context to either the user storage + * (color buffer) or our temporary (z/s) + */ +static void +osmesa_read_buffer(OSMesaContext osmesa, struct pipe_resource *res, void *dst, + int dst_stride, bool y_up) +{ + struct pipe_context *pipe = osmesa->st->pipe; + + struct pipe_box box; + u_box_2d(0, 0, res->width0, res->height0, &box); + + struct pipe_transfer *transfer = NULL; + uint8_t *src = pipe->texture_map(pipe, res, 0, PIPE_MAP_READ, &box, + &transfer); + + /* + * Copy the color buffer from the resource to the user's buffer. + */ + + if (y_up) { + /* need to flip image upside down */ + dst = (uint8_t *)dst + (res->height0 - 1) * dst_stride; + dst_stride = -dst_stride; + } + + unsigned bpp = util_format_get_blocksize(res->format); + for (unsigned y = 0; y < res->height0; y++) + { + memcpy(dst, src, bpp * res->width0); + dst = (uint8_t *)dst + dst_stride; + src += transfer->stride; + } + + pipe->texture_unmap(pipe, transfer); +} + + +/** + * Given an OSMESA_x format and a GL_y type, return the best + * matching PIPE_FORMAT_z. + * Note that we can't exactly match all user format/type combinations + * with gallium formats. If we find this to be a problem, we can + * implement more elaborate format/type conversion in the flush_front() + * function. + */ +static enum pipe_format +osmesa_choose_format(GLenum format, GLenum type) +{ + switch (format) { + case OSMESA_RGBA: + if (type == GL_UNSIGNED_BYTE) { +#if UTIL_ARCH_LITTLE_ENDIAN + return PIPE_FORMAT_R8G8B8A8_UNORM; +#else + return PIPE_FORMAT_A8B8G8R8_UNORM; +#endif + } + else if (type == GL_UNSIGNED_SHORT) { + return PIPE_FORMAT_R16G16B16A16_UNORM; + } + else if (type == GL_FLOAT) { + return PIPE_FORMAT_R32G32B32A32_FLOAT; + } + else { + return PIPE_FORMAT_NONE; + } + break; + case OSMESA_BGRA: + if (type == GL_UNSIGNED_BYTE) { +#if UTIL_ARCH_LITTLE_ENDIAN + return PIPE_FORMAT_B8G8R8A8_UNORM; +#else + return PIPE_FORMAT_A8R8G8B8_UNORM; +#endif + } + else if (type == GL_UNSIGNED_SHORT) { + return PIPE_FORMAT_R16G16B16A16_UNORM; + } + else if (type == GL_FLOAT) { + return PIPE_FORMAT_R32G32B32A32_FLOAT; + } + else { + return PIPE_FORMAT_NONE; + } + break; + case OSMESA_ARGB: + if (type == GL_UNSIGNED_BYTE) { +#if UTIL_ARCH_LITTLE_ENDIAN + return PIPE_FORMAT_A8R8G8B8_UNORM; +#else + return PIPE_FORMAT_B8G8R8A8_UNORM; +#endif + } + else if (type == GL_UNSIGNED_SHORT) { + return PIPE_FORMAT_R16G16B16A16_UNORM; + } + else if (type == GL_FLOAT) { + return PIPE_FORMAT_R32G32B32A32_FLOAT; + } + else { + return PIPE_FORMAT_NONE; + } + break; + case OSMESA_RGB: + if (type == GL_UNSIGNED_BYTE) { + return PIPE_FORMAT_R8G8B8_UNORM; + } + else if (type == GL_UNSIGNED_SHORT) { + return PIPE_FORMAT_R16G16B16_UNORM; + } + else if (type == GL_FLOAT) { + return PIPE_FORMAT_R32G32B32_FLOAT; + } + else { + return PIPE_FORMAT_NONE; + } + break; + case OSMESA_BGR: + /* No gallium format for this one */ + return PIPE_FORMAT_NONE; + case OSMESA_RGB_565: + if (type != GL_UNSIGNED_SHORT_5_6_5) + return PIPE_FORMAT_NONE; + return PIPE_FORMAT_B5G6R5_UNORM; + default: + return PIPE_FORMAT_NONE; + } +} + + +/** + * Initialize an st_visual object. + */ +static void +osmesa_init_st_visual(struct st_visual *vis, + enum pipe_format color_format, + enum pipe_format ds_format, + enum pipe_format accum_format) +{ + vis->buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK; + + if (ds_format != PIPE_FORMAT_NONE) + vis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; + if (accum_format != PIPE_FORMAT_NONE) + vis->buffer_mask |= ST_ATTACHMENT_ACCUM; + + vis->color_format = color_format; + vis->depth_stencil_format = ds_format; + vis->accum_format = accum_format; + vis->samples = 1; +} + + +/** + * Return the osmesa_buffer that corresponds to an pipe_frontend_drawable. + */ +static inline struct osmesa_buffer * +drawable_to_osbuffer(struct pipe_frontend_drawable *drawable) +{ + return (struct osmesa_buffer *)drawable; +} + + +/** + * Called via glFlush/glFinish. This is where we copy the contents + * of the driver's color buffer into the user-specified buffer. + */ +static bool +osmesa_st_framebuffer_flush_front(struct st_context *st, + struct pipe_frontend_drawable *drawable, + enum st_attachment_type statt) +{ + OSMesaContext osmesa = OSMesaGetCurrentContext(); + struct osmesa_buffer *osbuffer = drawable_to_osbuffer(drawable); + struct pipe_resource *res = osbuffer->textures[statt]; + unsigned bpp; + int dst_stride; + + if (statt != ST_ATTACHMENT_FRONT_LEFT) + return false; + + if (osmesa->pp) { + struct pipe_resource *zsbuf = NULL; + unsigned i; + + /* Find the z/stencil buffer if there is one */ + for (i = 0; i < ARRAY_SIZE(osbuffer->textures); i++) { + struct pipe_resource *res = osbuffer->textures[i]; + if (res) { + const struct util_format_description *desc = + util_format_description(res->format); + + if (util_format_has_depth(desc)) { + zsbuf = res; + break; + } + } + } + + /* run the postprocess stage(s) */ + pp_run(osmesa->pp, res, res, zsbuf); + } + + /* Snapshot the color buffer to the user's buffer. */ + bpp = util_format_get_blocksize(osbuffer->visual.color_format); + if (osmesa->user_row_length) + dst_stride = bpp * osmesa->user_row_length; + else + dst_stride = bpp * osbuffer->width; + + osmesa_read_buffer(osmesa, res, osbuffer->map, dst_stride, osmesa->y_up); + + /* If the user has requested the Z/S buffer, then snapshot that one too. */ + if (osmesa->zs) { + osmesa_read_buffer(osmesa, osbuffer->textures[ST_ATTACHMENT_DEPTH_STENCIL], + osmesa->zs, osmesa->zs_stride, true); + } + + return true; +} + + +/** + * Called by the st manager to validate the framebuffer (allocate + * its resources). + */ +static bool +osmesa_st_framebuffer_validate(struct st_context *st, + struct pipe_frontend_drawable *drawable, + const enum st_attachment_type *statts, + unsigned count, + struct pipe_resource **out, + struct pipe_resource **resolve) +{ + struct pipe_screen *screen = get_st_manager()->screen; + enum st_attachment_type i; + struct osmesa_buffer *osbuffer = drawable_to_osbuffer(drawable); + struct pipe_resource templat; + + memset(&templat, 0, sizeof(templat)); + templat.target = PIPE_TEXTURE_RECT; + templat.format = 0; /* setup below */ + templat.last_level = 0; + templat.width0 = osbuffer->width; + templat.height0 = osbuffer->height; + templat.depth0 = 1; + templat.array_size = 1; + templat.usage = PIPE_USAGE_DEFAULT; + templat.bind = 0; /* setup below */ + templat.flags = 0; + + for (i = 0; i < count; i++) { + enum pipe_format format = PIPE_FORMAT_NONE; + unsigned bind = 0; + + /* + * At this time, we really only need to handle the front-left color + * attachment, since that's all we specified for the visual in + * osmesa_init_st_visual(). + */ + if (statts[i] == ST_ATTACHMENT_FRONT_LEFT) { + format = osbuffer->visual.color_format; + bind = PIPE_BIND_RENDER_TARGET; + } + else if (statts[i] == ST_ATTACHMENT_DEPTH_STENCIL) { + format = osbuffer->visual.depth_stencil_format; + bind = PIPE_BIND_DEPTH_STENCIL; + } + else if (statts[i] == ST_ATTACHMENT_ACCUM) { + format = osbuffer->visual.accum_format; + bind = PIPE_BIND_RENDER_TARGET; + } + else { + debug_warning("Unexpected attachment type in " + "osmesa_st_framebuffer_validate()"); + } + + templat.format = format; + templat.bind = bind; + pipe_resource_reference(&out[i], NULL); + out[i] = osbuffer->textures[statts[i]] = + screen->resource_create(screen, &templat); + } + + return true; +} + +static uint32_t osmesa_fb_ID = 0; + + +/** + * Create new buffer and add to linked list. + */ +static struct osmesa_buffer * +osmesa_create_buffer(enum pipe_format color_format, + enum pipe_format ds_format, + enum pipe_format accum_format) +{ + struct osmesa_buffer *osbuffer = CALLOC_STRUCT(osmesa_buffer); + if (osbuffer) { + osbuffer->base.flush_front = osmesa_st_framebuffer_flush_front; + osbuffer->base.validate = osmesa_st_framebuffer_validate; + p_atomic_set(&osbuffer->base.stamp, 1); + osbuffer->base.ID = p_atomic_inc_return(&osmesa_fb_ID); + osbuffer->base.fscreen = get_st_manager(); + osbuffer->base.visual = &osbuffer->visual; + + osmesa_init_st_visual(&osbuffer->visual, color_format, + ds_format, accum_format); + } + + return osbuffer; +} + + +static void +osmesa_destroy_buffer(struct osmesa_buffer *osbuffer) +{ + /* + * Notify the state manager that the associated framebuffer interface + * is no longer valid. + */ + st_api_destroy_drawable(&osbuffer->base); + + FREE(osbuffer); +} + + + +/**********************************************************************/ +/***** Public Functions *****/ +/**********************************************************************/ + + +/** + * Create an Off-Screen Mesa rendering context. The only attribute needed is + * an RGBA vs Color-Index mode flag. + * + * Input: format - Must be GL_RGBA + * sharelist - specifies another OSMesaContext with which to share + * display lists. NULL indicates no sharing. + * Return: an OSMesaContext or 0 if error + */ +GLAPI OSMesaContext GLAPIENTRY +OSMesaCreateContext(GLenum format, OSMesaContext sharelist) +{ + return OSMesaCreateContextExt(format, 24, 8, 0, sharelist); +} + + +/** + * New in Mesa 3.5 + * + * Create context and specify size of ancillary buffers. + */ +GLAPI OSMesaContext GLAPIENTRY +OSMesaCreateContextExt(GLenum format, GLint depthBits, GLint stencilBits, + GLint accumBits, OSMesaContext sharelist) +{ + int attribs[100], n = 0; + + attribs[n++] = OSMESA_FORMAT; + attribs[n++] = format; + attribs[n++] = OSMESA_DEPTH_BITS; + attribs[n++] = depthBits; + attribs[n++] = OSMESA_STENCIL_BITS; + attribs[n++] = stencilBits; + attribs[n++] = OSMESA_ACCUM_BITS; + attribs[n++] = accumBits; + attribs[n++] = 0; + + return OSMesaCreateContextAttribs(attribs, sharelist); +} + + +/** + * New in Mesa 11.2 + * + * Create context with attribute list. + */ +GLAPI OSMesaContext GLAPIENTRY +OSMesaCreateContextAttribs(const int *attribList, OSMesaContext sharelist) +{ + OSMesaContext osmesa; + struct st_context *st_shared; + enum st_context_error st_error = 0; + struct st_context_attribs attribs; + GLenum format = GL_RGBA; + int depthBits = 0, stencilBits = 0, accumBits = 0; + int profile = OSMESA_COMPAT_PROFILE, version_major = 1, version_minor = 0; + int i; + + if (sharelist) { + st_shared = sharelist->st; + } + else { + st_shared = NULL; + } + + for (i = 0; attribList[i]; i += 2) { + switch (attribList[i]) { + case OSMESA_FORMAT: + format = attribList[i+1]; + switch (format) { + case OSMESA_COLOR_INDEX: + case OSMESA_RGBA: + case OSMESA_BGRA: + case OSMESA_ARGB: + case OSMESA_RGB: + case OSMESA_BGR: + case OSMESA_RGB_565: + /* legal */ + break; + default: + return NULL; + } + break; + case OSMESA_DEPTH_BITS: + depthBits = attribList[i+1]; + if (depthBits < 0) + return NULL; + break; + case OSMESA_STENCIL_BITS: + stencilBits = attribList[i+1]; + if (stencilBits < 0) + return NULL; + break; + case OSMESA_ACCUM_BITS: + accumBits = attribList[i+1]; + if (accumBits < 0) + return NULL; + break; + case OSMESA_PROFILE: + profile = attribList[i+1]; + if (profile != OSMESA_CORE_PROFILE && + profile != OSMESA_COMPAT_PROFILE) + return NULL; + break; + case OSMESA_CONTEXT_MAJOR_VERSION: + version_major = attribList[i+1]; + if (version_major < 1) + return NULL; + break; + case OSMESA_CONTEXT_MINOR_VERSION: + version_minor = attribList[i+1]; + if (version_minor < 0) + return NULL; + break; + case 0: + /* end of list */ + break; + default: + fprintf(stderr, "Bad attribute in OSMesaCreateContextAttribs()\n"); + return NULL; + } + } + + osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context); + if (!osmesa) + return NULL; + + /* Choose depth/stencil/accum buffer formats */ + if (accumBits > 0) { + osmesa->accum_format = PIPE_FORMAT_R16G16B16A16_SNORM; + } + if (depthBits > 0 && stencilBits > 0) { + osmesa->depth_stencil_format = PIPE_FORMAT_Z24_UNORM_S8_UINT; + } + else if (stencilBits > 0) { + osmesa->depth_stencil_format = PIPE_FORMAT_S8_UINT; + } + else if (depthBits >= 24) { + osmesa->depth_stencil_format = PIPE_FORMAT_Z24X8_UNORM; + } + else if (depthBits >= 16) { + osmesa->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; + } + + /* + * Create the rendering context + */ + memset(&attribs, 0, sizeof(attribs)); + attribs.profile = (profile == OSMESA_CORE_PROFILE) + ? API_OPENGL_CORE : API_OPENGL_COMPAT; + attribs.major = version_major; + attribs.minor = version_minor; + attribs.flags = 0; /* ST_CONTEXT_FLAG_x */ + attribs.options.force_glsl_extensions_warn = false; + attribs.options.disable_blend_func_extended = false; + attribs.options.disable_glsl_line_continuations = false; + attribs.options.force_glsl_version = 0; + + osmesa_init_st_visual(&attribs.visual, + PIPE_FORMAT_NONE, + osmesa->depth_stencil_format, + osmesa->accum_format); + + osmesa->st = st_api_create_context(get_st_manager(), + &attribs, &st_error, st_shared); + if (!osmesa->st) { + FREE(osmesa); + return NULL; + } + + osmesa->st->frontend_context = osmesa; + + osmesa->format = format; + osmesa->user_row_length = 0; + osmesa->y_up = GL_TRUE; + + return osmesa; +} + + + +/** + * Destroy an Off-Screen Mesa rendering context. + * + * \param osmesa the context to destroy + */ +GLAPI void GLAPIENTRY +OSMesaDestroyContext(OSMesaContext osmesa) +{ + if (osmesa) { + pp_free(osmesa->pp); + st_destroy_context(osmesa->st); + free(osmesa->zs); + FREE(osmesa); + } +} + + +/** + * Bind an OSMesaContext to an image buffer. The image buffer is just a + * block of memory which the client provides. Its size must be at least + * as large as width*height*pixelSize. Its address should be a multiple + * of 4 if using RGBA mode. + * + * By default, image data is stored in the order of glDrawPixels: row-major + * order with the lower-left image pixel stored in the first array position + * (ie. bottom-to-top). + * + * If the context's viewport hasn't been initialized yet, it will now be + * initialized to (0,0,width,height). + * + * Input: osmesa - the rendering context + * buffer - the image buffer memory + * type - data type for pixel components + * GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT + * or GL_FLOAT. + * width, height - size of image buffer in pixels, at least 1 + * Return: GL_TRUE if success, GL_FALSE if error because of invalid osmesa, + * invalid type, invalid size, etc. + */ +GLAPI GLboolean GLAPIENTRY +OSMesaMakeCurrent(OSMesaContext osmesa, void *buffer, GLenum type, + GLsizei width, GLsizei height) +{ + enum pipe_format color_format; + + if (!osmesa && !buffer) { + st_api_make_current(NULL, NULL, NULL); + return GL_TRUE; + } + + if (!osmesa || !buffer || width < 1 || height < 1) { + return GL_FALSE; + } + + color_format = osmesa_choose_format(osmesa->format, type); + if (color_format == PIPE_FORMAT_NONE) { + fprintf(stderr, "OSMesaMakeCurrent(unsupported format/type)\n"); + return GL_FALSE; + } + + /* See if we already have a buffer that uses these pixel formats */ + if (osmesa->current_buffer && + (osmesa->current_buffer->visual.color_format != color_format || + osmesa->current_buffer->visual.depth_stencil_format != osmesa->depth_stencil_format || + osmesa->current_buffer->visual.accum_format != osmesa->accum_format || + osmesa->current_buffer->width != width || + osmesa->current_buffer->height != height)) { + osmesa_destroy_buffer(osmesa->current_buffer); + osmesa->current_buffer = NULL; + } + + if (!osmesa->current_buffer) { + osmesa->current_buffer = osmesa_create_buffer(color_format, + osmesa->depth_stencil_format, + osmesa->accum_format); + } + + struct osmesa_buffer *osbuffer = osmesa->current_buffer; + + osbuffer->width = width; + osbuffer->height = height; + osbuffer->map = buffer; + + osmesa->type = type; + + st_api_make_current(osmesa->st, &osbuffer->base, &osbuffer->base); + + /* XXX: We should probably load the current color value into the buffer here + * to match classic swrast behavior (context's fb starts with the contents of + * your pixel buffer). + */ + + if (!osmesa->ever_used) { + /* one-time init, just postprocessing for now */ + bool any_pp_enabled = false; + unsigned i; + + for (i = 0; i < ARRAY_SIZE(osmesa->pp_enabled); i++) { + if (osmesa->pp_enabled[i]) { + any_pp_enabled = true; + break; + } + } + + if (any_pp_enabled) { + osmesa->pp = pp_init(osmesa->st->pipe, + osmesa->pp_enabled, + osmesa->st->cso_context, + osmesa->st, + st_context_invalidate_state); + + pp_init_fbos(osmesa->pp, width, height); + } + + osmesa->ever_used = true; + } + + return GL_TRUE; +} + + + +GLAPI OSMesaContext GLAPIENTRY +OSMesaGetCurrentContext(void) +{ + struct st_context *st = st_api_get_current(); + return st ? (OSMesaContext) st->frontend_context : NULL; +} + + + +GLAPI void GLAPIENTRY +OSMesaPixelStore(GLint pname, GLint value) +{ + OSMesaContext osmesa = OSMesaGetCurrentContext(); + + switch (pname) { + case OSMESA_ROW_LENGTH: + osmesa->user_row_length = value; + break; + case OSMESA_Y_UP: + osmesa->y_up = value ? GL_TRUE : GL_FALSE; + break; + default: + fprintf(stderr, "Invalid pname in OSMesaPixelStore()\n"); + return; + } +} + + +GLAPI void GLAPIENTRY +OSMesaGetIntegerv(GLint pname, GLint *value) +{ + OSMesaContext osmesa = OSMesaGetCurrentContext(); + struct osmesa_buffer *osbuffer = osmesa ? osmesa->current_buffer : NULL; + + switch (pname) { + case OSMESA_WIDTH: + *value = osbuffer ? osbuffer->width : 0; + return; + case OSMESA_HEIGHT: + *value = osbuffer ? osbuffer->height : 0; + return; + case OSMESA_FORMAT: + *value = osmesa->format; + return; + case OSMESA_TYPE: + /* current color buffer's data type */ + *value = osmesa->type; + return; + case OSMESA_ROW_LENGTH: + *value = osmesa->user_row_length; + return; + case OSMESA_Y_UP: + *value = osmesa->y_up; + return; + case OSMESA_MAX_WIDTH: + FALLTHROUGH; + case OSMESA_MAX_HEIGHT: + { + struct pipe_screen *screen = get_st_manager()->screen; + *value = screen->caps.max_texture_2d_size; + } + return; + default: + fprintf(stderr, "Invalid pname in OSMesaGetIntegerv()\n"); + return; + } +} + + +/** + * Return information about the depth buffer associated with an OSMesa context. + * Input: c - the OSMesa context + * Output: width, height - size of buffer in pixels + * bytesPerValue - bytes per depth value (2 or 4) + * buffer - pointer to depth buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + */ +GLAPI GLboolean GLAPIENTRY +OSMesaGetDepthBuffer(OSMesaContext c, GLint *width, GLint *height, + GLint *bytesPerValue, void **buffer) +{ + struct osmesa_buffer *osbuffer = c->current_buffer; + struct pipe_resource *res = osbuffer->textures[ST_ATTACHMENT_DEPTH_STENCIL]; + + if (!res) { + *width = 0; + *height = 0; + *bytesPerValue = 0; + *buffer = NULL; + return GL_FALSE; + } + + *width = res->width0; + *height = res->height0; + *bytesPerValue = util_format_get_blocksize(res->format); + + if (!c->zs) { + c->zs_stride = *width * *bytesPerValue; + c->zs = calloc(c->zs_stride, *height); + if (!c->zs) + return GL_FALSE; + + osmesa_read_buffer(c, res, c->zs, c->zs_stride, true); + } + + *buffer = c->zs; + + return GL_TRUE; +} + + +/** + * Return the color buffer associated with an OSMesa context. + * Input: c - the OSMesa context + * Output: width, height - size of buffer in pixels + * format - the pixel format (OSMESA_FORMAT) + * buffer - pointer to color buffer values + * Return: GL_TRUE or GL_FALSE to indicate success or failure. + */ +GLAPI GLboolean GLAPIENTRY +OSMesaGetColorBuffer(OSMesaContext osmesa, GLint *width, + GLint *height, GLint *format, void **buffer) +{ + struct osmesa_buffer *osbuffer = osmesa->current_buffer; + + if (osbuffer) { + *width = osbuffer->width; + *height = osbuffer->height; + *format = osmesa->format; + *buffer = osbuffer->map; + return GL_TRUE; + } + else { + *width = 0; + *height = 0; + *format = 0; + *buffer = 0; + return GL_FALSE; + } +} + + +struct name_function +{ + const char *Name; + OSMESAproc Function; +}; + +static struct name_function functions[] = { + { "OSMesaCreateContext", (OSMESAproc) OSMesaCreateContext }, + { "OSMesaCreateContextExt", (OSMESAproc) OSMesaCreateContextExt }, + { "OSMesaCreateContextAttribs", (OSMESAproc) OSMesaCreateContextAttribs }, + { "OSMesaDestroyContext", (OSMESAproc) OSMesaDestroyContext }, + { "OSMesaMakeCurrent", (OSMESAproc) OSMesaMakeCurrent }, + { "OSMesaGetCurrentContext", (OSMESAproc) OSMesaGetCurrentContext }, + { "OSMesaPixelStore", (OSMESAproc) OSMesaPixelStore }, + { "OSMesaGetIntegerv", (OSMESAproc) OSMesaGetIntegerv }, + { "OSMesaGetDepthBuffer", (OSMESAproc) OSMesaGetDepthBuffer }, + { "OSMesaGetColorBuffer", (OSMESAproc) OSMesaGetColorBuffer }, + { "OSMesaGetProcAddress", (OSMESAproc) OSMesaGetProcAddress }, + { "OSMesaColorClamp", (OSMESAproc) OSMesaColorClamp }, + { "OSMesaPostprocess", (OSMESAproc) OSMesaPostprocess }, + { NULL, NULL } +}; + + +GLAPI OSMESAproc GLAPIENTRY +OSMesaGetProcAddress(const char *funcName) +{ + int i; + for (i = 0; functions[i].Name; i++) { + if (strcmp(functions[i].Name, funcName) == 0) + return functions[i].Function; + } + return _mesa_glapi_get_proc_address(funcName); +} + + +GLAPI void GLAPIENTRY +OSMesaColorClamp(GLboolean enable) +{ + extern void GLAPIENTRY _mesa_ClampColor(GLenum target, GLenum clamp); + + _mesa_ClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, + enable ? GL_TRUE : GL_FIXED_ONLY_ARB); +} + + +GLAPI void GLAPIENTRY +OSMesaPostprocess(OSMesaContext osmesa, const char *filter, + unsigned enable_value) +{ + if (!osmesa->ever_used) { + /* We can only enable/disable postprocess filters before a context + * is made current for the first time. + */ + unsigned i; + + for (i = 0; i < PP_FILTERS; i++) { + if (strcmp(pp_filters[i].name, filter) == 0) { + osmesa->pp_enabled[i] = enable_value; + return; + } + } + debug_warning("OSMesaPostprocess(unknown filter)\n"); + } + else { + debug_warning("Calling OSMesaPostprocess() after OSMesaMakeCurrent()\n"); + } +} diff -ruN mesa-26.1.4/src/gallium/meson.build mesa-26.1.4-banan_os/src/gallium/meson.build --- mesa-26.1.4/src/gallium/meson.build 2026-07-01 17:16:13.000000000 +0300 +++ mesa-26.1.4-banan_os/src/gallium/meson.build 2026-07-05 04:20:14.035181849 +0300 @@ -232,6 +232,10 @@ subdir('frontends/dri') subdir('targets/dri') endif +if with_osmesa + subdir('frontends/osmesa') + subdir('targets/osmesa') +endif if with_platform_haiku subdir('frontends/hgl') endif diff -ruN mesa-26.1.4/src/gallium/targets/osmesa/meson.build mesa-26.1.4-banan_os/src/gallium/targets/osmesa/meson.build --- mesa-26.1.4/src/gallium/targets/osmesa/meson.build 1970-01-01 02:00:00.000000000 +0200 +++ mesa-26.1.4-banan_os/src/gallium/targets/osmesa/meson.build 2026-07-05 04:20:14.212936332 +0300 @@ -0,0 +1,36 @@ +# Copyright © 2017 Intel Corporation +# SPDX-License-Identifier: MIT + +osmesa_link_args = [] +osmesa_link_deps = [] + +if with_ld_version_script + osmesa_link_args += ['-Wl,--version-script', join_paths(meson.current_source_dir(), 'osmesa.sym')] + osmesa_link_deps += files('osmesa.sym') +endif + +libosmesa = shared_library( + osmesa_lib_name, + files('osmesa_target.c'), + include_directories : [ + inc_include, inc_src, inc_gallium, inc_gallium_aux, inc_gallium_winsys, + inc_gallium_drivers, + ], + gnu_symbol_visibility : 'hidden', + link_args : [ld_args_gc_sections, osmesa_link_args], + link_depends : osmesa_link_deps, + link_whole : [libosmesa_st, libglapi_bridge], + link_with : [libmesa, libgallium, libglapi, libws_null], + dependencies : [dep_ws2_32, dep_thread, dep_clock, dep_unwind, driver_swrast, idep_mesautil], + install : true, + version : '8.0.0', + darwin_versions : '9.0.0', +) + +pkg.generate( + name : 'osmesa', + description : 'Mesa Off-screen Rendering Library', + version : '8.0.0', + libraries : libosmesa, + libraries_private : gl_priv_libs, +) diff -ruN mesa-26.1.4/src/gallium/targets/osmesa/osmesa.sym mesa-26.1.4-banan_os/src/gallium/targets/osmesa/osmesa.sym --- mesa-26.1.4/src/gallium/targets/osmesa/osmesa.sym 1970-01-01 02:00:00.000000000 +0200 +++ mesa-26.1.4-banan_os/src/gallium/targets/osmesa/osmesa.sym 2026-07-05 04:20:14.212992485 +0300 @@ -0,0 +1,19 @@ +{ + global: + OSMesaColorClamp; + OSMesaCreateContext; + OSMesaCreateContextAttribs; + OSMesaCreateContextExt; + OSMesaDestroyContext; + OSMesaGetColorBuffer; + OSMesaGetCurrentContext; + OSMesaGetDepthBuffer; + OSMesaGetIntegerv; + OSMesaGetProcAddress; + OSMesaMakeCurrent; + OSMesaPixelStore; + OSMesaPostprocess; + gl*; + local: + *; +}; diff -ruN mesa-26.1.4/src/gallium/targets/osmesa/osmesa_target.c mesa-26.1.4-banan_os/src/gallium/targets/osmesa/osmesa_target.c --- mesa-26.1.4/src/gallium/targets/osmesa/osmesa_target.c 1970-01-01 02:00:00.000000000 +0200 +++ mesa-26.1.4-banan_os/src/gallium/targets/osmesa/osmesa_target.c 2026-07-05 04:20:14.213049196 +0300 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + + +#include "target-helpers/inline_sw_helper.h" +#include "target-helpers/inline_debug_helper.h" + +#include "sw/null/null_sw_winsys.h" + + +struct pipe_screen * +osmesa_create_screen(void); + + +struct pipe_screen * +osmesa_create_screen(void) +{ + struct sw_winsys *winsys; + struct pipe_screen *screen; + + /* We use a null software winsys since we always just render to ordinary + * driver resources. + */ + winsys = null_sw_create(); + if (!winsys) + return NULL; + + /* Create llvmpipe or softpipe screen */ + screen = sw_screen_create(winsys); + if (!screen) { + winsys->destroy(winsys); + return NULL; + } + + /* Inject optional trace, debug, etc. wrappers */ + return debug_screen_wrap(screen); +}