📄 utils.c
字号:
/* * (C) Copyright IBM Corporation 2002, 2004 * 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 * on the rights to use, copy, modify, merge, publish, distribute, sub * license, 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 (including the next * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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. *//** * \file utils.c * Utility functions for DRI drivers. * * \author Ian Romanick <idr@us.ibm.com> */#include <string.h>#include <stdlib.h>#include "mtypes.h"#include "extensions.h"#include "utils.h"#include "dispatch.h"int driDispatchRemapTable[ driDispatchRemapTable_size ];#if defined(USE_X86_ASM)#include "x86/common_x86_asm.h"#endif#if defined(USE_PPC_ASM)#include "ppc/common_ppc_features.h"#endifunsigneddriParseDebugString( const char * debug, const struct dri_debug_control * control ){ unsigned flag; flag = 0; if ( debug != NULL ) { while( control->string != NULL ) { if ( !strcmp( debug, "all" ) || strstr( debug, control->string ) != NULL ) { flag |= control->flag; } control++; } } return flag;}/** * Create the \c GL_RENDERER string for DRI drivers. * * Almost all DRI drivers use a \c GL_RENDERER string of the form: * * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>" * * Using the supplied chip name, driver data, and AGP speed, this function * creates the string. * * \param buffer Buffer to hold the \c GL_RENDERER string. * \param hardware_name Name of the hardware. * \param driver_date Driver date. * \param agp_mode AGP mode (speed). * * \returns * The length of the string stored in \c buffer. This does \b not include * the terminating \c NUL character. */unsigneddriGetRendererString( char * buffer, const char * hardware_name, const char * driver_date, GLuint agp_mode ){#define MAX_INFO 4 const char * cpu[MAX_INFO]; unsigned next = 0; unsigned i; unsigned offset; offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date ); /* Append any AGP-specific information. */ switch ( agp_mode ) { case 1: case 2: case 4: case 8: offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode ); break; default: break; } /* Append any CPU-specific information. */#ifdef USE_X86_ASM if ( _mesa_x86_cpu_features ) { cpu[next] = " x86"; next++; }# ifdef USE_MMX_ASM if ( cpu_has_mmx ) { cpu[next] = (cpu_has_mmxext) ? "/MMX+" : "/MMX"; next++; }# endif# ifdef USE_3DNOW_ASM if ( cpu_has_3dnow ) { cpu[next] = (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!"; next++; }# endif# ifdef USE_SSE_ASM if ( cpu_has_xmm ) { cpu[next] = (cpu_has_xmm2) ? "/SSE2" : "/SSE"; next++; }# endif#elif defined(USE_SPARC_ASM) cpu[0] = " SPARC"; next = 1;#elif defined(USE_PPC_ASM) if ( _mesa_ppc_cpu_features ) { cpu[next] = (cpu_has_64) ? " PowerPC 64" : " PowerPC"; next++; }# ifdef USE_VMX_ASM if ( cpu_has_vmx ) { cpu[next] = "/Altivec"; next++; }# endif if ( ! cpu_has_fpu ) { cpu[next] = "/No FPU"; next++; }#endif for ( i = 0 ; i < next ; i++ ) { const size_t len = strlen( cpu[i] ); strncpy( & buffer[ offset ], cpu[i], len ); offset += len; } return offset;}#define need_GL_ARB_multisample#define need_GL_ARB_transpose_matrix#define need_GL_ARB_window_pos#define need_GL_EXT_compiled_vertex_array#define need_GL_EXT_polygon_offset#define need_GL_EXT_texture_object#define need_GL_EXT_vertex_array#define need_GL_MESA_window_pos/* These are needed in *all* drivers because Mesa internally implements * certain functionality in terms of functions provided by these extensions. * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT. */#define need_GL_EXT_blend_func_separate#define need_GL_NV_vertex_program#include "extension_helper.h"static const struct dri_extension all_mesa_extensions[] = { { "GL_ARB_multisample", GL_ARB_multisample_functions }, { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions }, { "GL_ARB_window_pos", GL_ARB_window_pos_functions }, { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions }, { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions }, { "GL_EXT_polygon_offset", GL_EXT_polygon_offset_functions }, { "GL_EXT_texture_object", GL_EXT_texture_object_functions }, { "GL_EXT_vertex_array", GL_EXT_vertex_array_functions }, { "GL_MESA_window_pos", GL_MESA_window_pos_functions }, { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, { NULL, NULL }};/** * Enable extensions supported by the driver. * * \bug * ARB_imaging isn't handled properly. In Mesa, enabling ARB_imaging also * enables all the sub-extensions that are folded into it. This means that * we need to add entry-points (via \c driInitSingleExtension) for those * new functions here. */void driInitExtensions( GLcontext * ctx, const struct dri_extension * extensions_to_enable, GLboolean enable_imaging ){ static int first_time = 1; unsigned i; if ( first_time ) { for ( i = 0 ; i < driDispatchRemapTable_size ; i++ ) { driDispatchRemapTable[i] = -1; } first_time = 0; driInitExtensions( ctx, all_mesa_extensions, GL_FALSE ); } if ( (ctx != NULL) && enable_imaging ) { _mesa_enable_imaging_extensions( ctx ); } for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) { driInitSingleExtension( ctx, & extensions_to_enable[i] ); }}/** * Enable and add dispatch functions for a single extension * * \param ctx Context where extension is to be enabled. * \param ext Extension that is to be enabled. * * \sa driInitExtensions, _mesa_enable_extension, _glapi_add_entrypoint * * \todo * Determine if it would be better to use \c strlen instead of the hardcoded * for-loops. */void driInitSingleExtension( GLcontext * ctx, const struct dri_extension * ext ){ unsigned i; if ( ext->functions != NULL ) { for ( i = 0 ; ext->functions[i].strings != NULL ; i++ ) { const char * functions[16]; const char * parameter_signature; const char * str = ext->functions[i].strings; unsigned j; unsigned offset; /* Separate the parameter signature from the rest of the string. * If the parameter signature is empty (i.e., the string starts * with a NUL character), then the function has a void parameter * list. */ parameter_signature = str; while ( str[0] != '\0' ) { str++; } str++; /* Divide the string into the substrings that name each * entry-point for the function. */ for ( j = 0 ; j < 16 ; j++ ) { if ( str[0] == '\0' ) { functions[j] = NULL; break; } functions[j] = str; while ( str[0] != '\0' ) { str++; } str++; } /* Add each entry-point to the dispatch table. */ offset = _glapi_add_dispatch( functions, parameter_signature ); if (offset == -1) { fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed " "to add %s!\n", functions[0]); } else if (ext->functions[i].remap_index != -1) { driDispatchRemapTable[ ext->functions[i].remap_index ] = offset; } else if (ext->functions[i].offset != offset) { fprintf(stderr, "DISPATCH ERROR! %s -> %u != %u\n", functions[0], offset, ext->functions[i].offset); } } } if ( ctx != NULL ) { _mesa_enable_extension( ctx, ext->name ); }}/** * Utility function used by drivers to test the verions of other components. * * If one of the version requirements is not met, a message is logged using * \c __driUtilMessage. * * \param driver_name Name of the driver. Used in error messages. * \param driActual Actual DRI version supplied __driCreateNewScreen. * \param driExpected Minimum DRI version required by the driver. * \param ddxActual Actual DDX version supplied __driCreateNewScreen. * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver. * \param drmActual Actual DRM version supplied __driCreateNewScreen. * \param drmExpected Minimum DRM version required by the driver. * * \returns \c GL_TRUE if all version requirements are met. Otherwise, * \c GL_FALSE is returned. * * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2, __driUtilMessage * * \todo * Now that the old \c driCheckDriDdxDrmVersions function is gone, this * function and \c driCheckDriDdxDrmVersions2 should be renamed. */GLbooleandriCheckDriDdxDrmVersions3(const char * driver_name, const __DRIversion * driActual, const __DRIversion * driExpected, const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected, const __DRIversion * drmActual, const __DRIversion * drmExpected){ static const char format[] = "%s DRI driver expected %s version %d.%d.x " "but got version %d.%d.%d\n"; static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x " "but got version %d.%d.%d\n"; /* Check the DRI version */ if ( (driActual->major != driExpected->major) || (driActual->minor < driExpected->minor) ) { fprintf(stderr, format, driver_name, "DRI", driExpected->major, driExpected->minor, driActual->major, driActual->minor, driActual->patch); return GL_FALSE; } /* Check that the DDX driver version is compatible */ /* for miniglx we pass in -1 so we can ignore the DDX version */ if ( (ddxActual->major != -1) && ((ddxActual->major < ddxExpected->major_min) || (ddxActual->major > ddxExpected->major_max) || (ddxActual->minor < ddxExpected->minor)) ) { fprintf(stderr, format2, driver_name, "DDX", ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor, ddxActual->major, ddxActual->minor, ddxActual->patch); return GL_FALSE; } /* Check that the DRM driver version is compatible */ if ( (drmActual->major != drmExpected->major) || (drmActual->minor < drmExpected->minor) ) { fprintf(stderr, format, driver_name, "DRM", drmExpected->major, drmExpected->minor, drmActual->major, drmActual->minor, drmActual->patch); return GL_FALSE; } return GL_TRUE;}GLbooleandriCheckDriDdxDrmVersions2(const char * driver_name, const __DRIversion * driActual, const __DRIversion * driExpected, const __DRIversion * ddxActual, const __DRIversion * ddxExpected, const __DRIversion * drmActual, const __DRIversion * drmExpected){ __DRIutilversion2 ddx_expected; ddx_expected.major_min = ddxExpected->major; ddx_expected.major_max = ddxExpected->major; ddx_expected.minor = ddxExpected->minor; ddx_expected.patch = ddxExpected->patch; return driCheckDriDdxDrmVersions3(driver_name, driActual, driExpected, ddxActual, & ddx_expected, drmActual, drmExpected);}GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, GLint *x, GLint *y, GLsizei *width, GLsizei *height ){ /* left clipping */ if (*x < buffer->_Xmin) { *width -= (buffer->_Xmin - *x); *x = buffer->_Xmin; } /* right clipping */ if (*x + *width > buffer->_Xmax) *width -= (*x + *width - buffer->_Xmax - 1); if (*width <= 0) return GL_FALSE; /* bottom clipping */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -