diff options
Diffstat (limited to 'mesalib/src/mesa/drivers')
78 files changed, 37279 insertions, 0 deletions
diff --git a/mesalib/src/mesa/drivers/Makefile b/mesalib/src/mesa/drivers/Makefile new file mode 100644 index 000000000..c5998413e --- /dev/null +++ b/mesalib/src/mesa/drivers/Makefile @@ -0,0 +1,29 @@ +# src/mesa/drivers/Makefile + +TOP = ../../.. +include $(TOP)/configs/current + + +default: + @for dir in $(DRIVER_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1; \ + fi \ + done + + +clean: + @for dir in $(DRIVER_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) || exit 1; \ + fi \ + done + + +install: + @for dir in $(DRIVER_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1; \ + fi \ + done + diff --git a/mesalib/src/mesa/drivers/common/descrip.mms b/mesalib/src/mesa/drivers/common/descrip.mms new file mode 100644 index 000000000..d5bbc69df --- /dev/null +++ b/mesalib/src/mesa/drivers/common/descrip.mms @@ -0,0 +1,42 @@ +# Makefile for core library for VMS +# contributed by Jouk Jansen joukj@hrem.nano.tudelft.nl +# Last revision : 29 September 2008 + +.first + define gl [----.include.gl] + define math [--.math] + define tnl [--.tnl] + define swrast [--.swrast] + define glapi [--.glapi] + define shader [--.shader] + define main [--.main] + +.include [----]mms-config. + +##### MACROS ##### + +VPATH = RCS + +INCDIR = [----.include],[--.main],[--.glapi],[--.shader] +LIBDIR = [----.lib] +CFLAGS = /include=($(INCDIR),[])/define=(PTHREADS=1)/name=(as_is,short)\ + /float=ieee/ieee=denorm/warn=disable=(PTRMISMATCH) + +SOURCES = driverfuncs.c + +OBJECTS =driverfuncs.obj + +##### RULES ##### + +VERSION=Mesa V3.4 + +##### TARGETS ##### +# Make the library +$(LIBDIR)$(GL_LIB) : $(OBJECTS) + @ library $(LIBDIR)$(GL_LIB) $(OBJECTS) + +clean : + purge + delete *.obj;* + +driverfuncs.obj : driverfuncs.c diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c new file mode 100644 index 000000000..a9f3c8e72 --- /dev/null +++ b/mesalib/src/mesa/drivers/common/driverfuncs.c @@ -0,0 +1,353 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 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 + * BRIAN PAUL 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 "main/glheader.h" +#include "main/imports.h" +#include "main/arrayobj.h" +#include "main/buffers.h" +#include "main/context.h" +#include "main/framebuffer.h" +#include "main/mipmap.h" +#include "main/queryobj.h" +#include "main/renderbuffer.h" +#include "main/texcompress.h" +#include "main/texformat.h" +#include "main/texgetimage.h" +#include "main/teximage.h" +#include "main/texobj.h" +#include "main/texstore.h" +#if FEATURE_ARB_vertex_buffer_object +#include "main/bufferobj.h" +#endif +#if FEATURE_EXT_framebuffer_object +#include "main/fbobject.h" +#include "main/texrender.h" +#endif +#if FEATURE_ARB_sync +#include "main/syncobj.h" +#endif + +#include "shader/program.h" +#include "shader/prog_execute.h" +#include "shader/shader_api.h" +#include "tnl/tnl.h" +#include "swrast/swrast.h" + +#include "driverfuncs.h" + + + +/** + * Plug in default functions for all pointers in the dd_function_table + * structure. + * Device drivers should call this function and then plug in any + * functions which it wants to override. + * Some functions (pointers) MUST be implemented by all drivers (REQUIRED). + * + * \param table the dd_function_table to initialize + */ +void +_mesa_init_driver_functions(struct dd_function_table *driver) +{ + _mesa_bzero(driver, sizeof(*driver)); + + driver->GetString = NULL; /* REQUIRED! */ + driver->UpdateState = NULL; /* REQUIRED! */ + driver->GetBufferSize = NULL; /* REQUIRED! */ + driver->ResizeBuffers = _mesa_resize_framebuffer; + driver->Error = NULL; + + driver->Finish = NULL; + driver->Flush = NULL; + + /* framebuffer/image functions */ + driver->Clear = _swrast_Clear; + driver->Accum = _swrast_Accum; + driver->RasterPos = _tnl_RasterPos; + driver->DrawPixels = _swrast_DrawPixels; + driver->ReadPixels = _swrast_ReadPixels; + driver->CopyPixels = _swrast_CopyPixels; + driver->Bitmap = _swrast_Bitmap; + + /* Texture functions */ + driver->ChooseTextureFormat = _mesa_choose_tex_format; + driver->TexImage1D = _mesa_store_teximage1d; + driver->TexImage2D = _mesa_store_teximage2d; + driver->TexImage3D = _mesa_store_teximage3d; + driver->TexSubImage1D = _mesa_store_texsubimage1d; + driver->TexSubImage2D = _mesa_store_texsubimage2d; + driver->TexSubImage3D = _mesa_store_texsubimage3d; + driver->GetTexImage = _mesa_get_teximage; + driver->CopyTexImage1D = _swrast_copy_teximage1d; + driver->CopyTexImage2D = _swrast_copy_teximage2d; + driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d; + driver->CopyTexSubImage2D = _swrast_copy_texsubimage2d; + driver->CopyTexSubImage3D = _swrast_copy_texsubimage3d; + driver->GenerateMipmap = _mesa_generate_mipmap; + driver->TestProxyTexImage = _mesa_test_proxy_teximage; + driver->CompressedTexImage1D = _mesa_store_compressed_teximage1d; + driver->CompressedTexImage2D = _mesa_store_compressed_teximage2d; + driver->CompressedTexImage3D = _mesa_store_compressed_teximage3d; + driver->CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; + driver->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; + driver->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + driver->GetCompressedTexImage = _mesa_get_compressed_teximage; + driver->CompressedTextureSize = _mesa_compressed_texture_size; + driver->BindTexture = NULL; + driver->NewTextureObject = _mesa_new_texture_object; + driver->DeleteTexture = _mesa_delete_texture_object; + driver->NewTextureImage = _mesa_new_texture_image; + driver->FreeTexImageData = _mesa_free_texture_image_data; + driver->MapTexture = NULL; + driver->UnmapTexture = NULL; + driver->TextureMemCpy = _mesa_memcpy; + driver->IsTextureResident = NULL; + driver->PrioritizeTexture = NULL; + driver->ActiveTexture = NULL; + driver->UpdateTexturePalette = NULL; + + /* imaging */ + driver->CopyColorTable = _swrast_CopyColorTable; + driver->CopyColorSubTable = _swrast_CopyColorSubTable; + driver->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + driver->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; + + /* Vertex/fragment programs */ + driver->BindProgram = NULL; + driver->NewProgram = _mesa_new_program; + driver->DeleteProgram = _mesa_delete_program; + + /* simple state commands */ + driver->AlphaFunc = NULL; + driver->BlendColor = NULL; + driver->BlendEquationSeparate = NULL; + driver->BlendFuncSeparate = NULL; + driver->ClearColor = NULL; + driver->ClearDepth = NULL; + driver->ClearIndex = NULL; + driver->ClearStencil = NULL; + driver->ClipPlane = NULL; + driver->ColorMask = NULL; + driver->ColorMaterial = NULL; + driver->CullFace = NULL; + driver->DrawBuffer = NULL; + driver->DrawBuffers = NULL; + driver->FrontFace = NULL; + driver->DepthFunc = NULL; + driver->DepthMask = NULL; + driver->DepthRange = NULL; + driver->Enable = NULL; + driver->Fogfv = NULL; + driver->Hint = NULL; + driver->IndexMask = NULL; + driver->Lightfv = NULL; + driver->LightModelfv = NULL; + driver->LineStipple = NULL; + driver->LineWidth = NULL; + driver->LogicOpcode = NULL; + driver->PointParameterfv = NULL; + driver->PointSize = NULL; + driver->PolygonMode = NULL; + driver->PolygonOffset = NULL; + driver->PolygonStipple = NULL; + driver->ReadBuffer = NULL; + driver->RenderMode = NULL; + driver->Scissor = NULL; + driver->ShadeModel = NULL; + driver->StencilFuncSeparate = NULL; + driver->StencilOpSeparate = NULL; + driver->StencilMaskSeparate = NULL; + driver->TexGen = NULL; + driver->TexEnv = NULL; + driver->TexParameter = NULL; + driver->TextureMatrix = NULL; + driver->Viewport = NULL; + + /* vertex arrays */ + driver->VertexPointer = NULL; + driver->NormalPointer = NULL; + driver->ColorPointer = NULL; + driver->FogCoordPointer = NULL; + driver->IndexPointer = NULL; + driver->SecondaryColorPointer = NULL; + driver->TexCoordPointer = NULL; + driver->EdgeFlagPointer = NULL; + driver->VertexAttribPointer = NULL; + driver->LockArraysEXT = NULL; + driver->UnlockArraysEXT = NULL; + + /* state queries */ + driver->GetBooleanv = NULL; + driver->GetDoublev = NULL; + driver->GetFloatv = NULL; + driver->GetIntegerv = NULL; + driver->GetInteger64v = NULL; + driver->GetPointerv = NULL; + + /* buffer objects */ + _mesa_init_buffer_object_functions(driver); + + /* query objects */ + _mesa_init_query_object_functions(driver); + +#if FEATURE_ARB_sync + _mesa_init_sync_object_functions(driver); +#endif + +#if FEATURE_EXT_framebuffer_object + driver->NewFramebuffer = _mesa_new_framebuffer; + driver->NewRenderbuffer = _mesa_new_soft_renderbuffer; + driver->RenderTexture = _mesa_render_texture; + driver->FinishRenderTexture = _mesa_finish_render_texture; + driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer; +#endif + +#if FEATURE_EXT_framebuffer_blit + driver->BlitFramebuffer = _swrast_BlitFramebuffer; +#endif + + /* APPLE_vertex_array_object */ + driver->NewArrayObject = _mesa_new_array_object; + driver->DeleteArrayObject = _mesa_delete_array_object; + driver->BindArrayObject = NULL; + + /* T&L stuff */ + driver->NeedValidate = GL_FALSE; + driver->ValidateTnlModule = NULL; + driver->CurrentExecPrimitive = 0; + driver->CurrentSavePrimitive = 0; + driver->NeedFlush = 0; + driver->SaveNeedFlush = 0; + + driver->ProgramStringNotify = _tnl_program_string; + driver->FlushVertices = NULL; + driver->SaveFlushVertices = NULL; + driver->NotifySaveBegin = NULL; + driver->LightingSpaceChange = NULL; + + /* display list */ + driver->NewList = NULL; + driver->EndList = NULL; + driver->BeginCallList = NULL; + driver->EndCallList = NULL; + + + /* XXX temporary here */ + _mesa_init_glsl_driver_functions(driver); +} + + +/** + * Call the ctx->Driver.* state functions with current values to initialize + * driver state. + * Only the Intel drivers use this so far. + */ +void +_mesa_init_driver_state(GLcontext *ctx) +{ + ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); + + ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); + + ctx->Driver.BlendEquationSeparate(ctx, + ctx->Color.BlendEquationRGB, + ctx->Color.BlendEquationA); + + ctx->Driver.BlendFuncSeparate(ctx, + ctx->Color.BlendSrcRGB, + ctx->Color.BlendDstRGB, + ctx->Color.BlendSrcA, ctx->Color.BlendDstA); + + ctx->Driver.ColorMask(ctx, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode); + ctx->Driver.DepthFunc(ctx, ctx->Depth.Func); + ctx->Driver.DepthMask(ctx, ctx->Depth.Mask); + + ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); + ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled); + ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag); + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); + ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag); + ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled); + ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled); + ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag); + ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); + ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled); + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled); + ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); + + ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); + ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0); + ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); + ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); + ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); + + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + + { + GLfloat f = (GLfloat) ctx->Light.Model.ColorControl; + ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f); + } + + ctx->Driver.LineWidth(ctx, ctx->Line.Width); + ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp); + ctx->Driver.PointSize(ctx, ctx->Point.Size); + ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); + ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, + ctx->Stencil.Function[0], + ctx->Stencil.Ref[0], + ctx->Stencil.ValueMask[0]); + ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, + ctx->Stencil.Function[1], + ctx->Stencil.Ref[1], + ctx->Stencil.ValueMask[1]); + ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]); + ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]); + ctx->Driver.StencilOpSeparate(ctx, GL_FRONT, + ctx->Stencil.FailFunc[0], + ctx->Stencil.ZFailFunc[0], + ctx->Stencil.ZPassFunc[0]); + ctx->Driver.StencilOpSeparate(ctx, GL_BACK, + ctx->Stencil.FailFunc[1], + ctx->Stencil.ZFailFunc[1], + ctx->Stencil.ZPassFunc[1]); + + + ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]); +} diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.h b/mesalib/src/mesa/drivers/common/driverfuncs.h new file mode 100644 index 000000000..4c90ed12f --- /dev/null +++ b/mesalib/src/mesa/drivers/common/driverfuncs.h @@ -0,0 +1,37 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 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 + * BRIAN PAUL 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. + */ + + +#ifndef DRIVERFUNCS_H +#define DRIVERFUNCS_H + +extern void +_mesa_init_driver_functions(struct dd_function_table *driver); + + +extern void +_mesa_init_driver_state(GLcontext *ctx); + + +#endif diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c new file mode 100644 index 000000000..2741a41bf --- /dev/null +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -0,0 +1,1638 @@ +/* + * Mesa 3-D graphics library + * Version: 7.6 + * + * Copyright (C) 2009 VMware, Inc. 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 + * BRIAN PAUL 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. + */ + +/** + * Meta operations. Some GL operations can be expressed in terms of + * other GL operations. For example, glBlitFramebuffer() can be done + * with texture mapping and glClear() can be done with polygon rendering. + * + * \author Brian Paul + */ + + +#include "main/glheader.h" +#include "main/mtypes.h" +#include "main/imports.h" +#include "main/arrayobj.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/depth.h" +#include "main/enable.h" +#include "main/image.h" +#include "main/macros.h" +#include "main/matrix.h" +#include "main/polygon.h" +#include "main/readpix.h" +#include "main/scissor.h" +#include "main/shaders.h" +#include "main/stencil.h" +#include "main/texobj.h" +#include "main/texenv.h" +#include "main/teximage.h" +#include "main/texparam.h" +#include "main/texstate.h" +#include "main/varray.h" +#include "main/viewport.h" +#include "shader/program.h" +#include "shader/arbprogram.h" +#include "swrast/swrast.h" +#include "drivers/common/meta.h" + + +/** + * State which we may save/restore across meta ops. + * XXX this may be incomplete... + */ +struct save_state +{ + GLbitfield SavedState; /**< bitmask of META_* flags */ + + /** META_ALPHA_TEST */ + GLboolean AlphaEnabled; + + /** META_BLEND */ + GLboolean BlendEnabled; + GLboolean ColorLogicOpEnabled; + + /** META_COLOR_MASK */ + GLubyte ColorMask[4]; + + /** META_DEPTH_TEST */ + struct gl_depthbuffer_attrib Depth; + + /** META_FOG */ + GLboolean Fog; + + /** META_PIXEL_STORE */ + struct gl_pixelstore_attrib Pack, Unpack; + + /** META_RASTERIZATION */ + GLenum FrontPolygonMode, BackPolygonMode; + GLboolean PolygonOffset; + GLboolean PolygonSmooth; + GLboolean PolygonStipple; + GLboolean PolygonCull; + + /** META_SCISSOR */ + struct gl_scissor_attrib Scissor; + + /** META_SHADER */ + GLboolean VertexProgramEnabled; + struct gl_vertex_program *VertexProgram; + GLboolean FragmentProgramEnabled; + struct gl_fragment_program *FragmentProgram; + GLuint Shader; + + /** META_STENCIL_TEST */ + struct gl_stencil_attrib Stencil; + + /** META_TRANSFORM */ + GLenum MatrixMode; + GLfloat ModelviewMatrix[16]; + GLfloat ProjectionMatrix[16]; + GLfloat TextureMatrix[16]; + GLbitfield ClipPlanesEnabled; + + /** META_TEXTURE */ + GLuint ActiveUnit; + GLuint ClientActiveUnit; + /** for unit[0] only */ + struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS]; + /** mask of TEXTURE_2D_BIT, etc */ + GLbitfield TexEnabled[MAX_TEXTURE_UNITS]; + GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS]; + GLuint EnvMode; /* unit[0] only */ + + /** META_VERTEX */ + struct gl_array_object *ArrayObj; + struct gl_buffer_object *ArrayBufferObj; + + /** META_VIEWPORT */ + GLint ViewportX, ViewportY, ViewportW, ViewportH; + GLclampd DepthNear, DepthFar; + + /** Miscellaneous (always disabled) */ + GLboolean Lighting; +}; + + +/** + * State for glBlitFramebufer() + */ +struct blit_state +{ + GLuint ArrayObj; + GLuint VBO; + GLuint DepthFP; +}; + + +/** + * State for glClear() + */ +struct clear_state +{ + GLuint ArrayObj; + GLuint VBO; +}; + + +/** + * State for glCopyPixels() + */ +struct copypix_state +{ + GLuint ArrayObj; + GLuint VBO; +}; + + +/** + * State for glDrawPixels() + */ +struct drawpix_state +{ + GLuint ArrayObj; + + GLuint StencilFP; /**< Fragment program for drawing stencil images */ + GLuint DepthFP; /**< Fragment program for drawing depth images */ +}; + + +/** + * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc. + * This is currently shared by all the meta ops. But we could create a + * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc. + */ +struct temp_texture +{ + GLuint TexObj; + GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */ + GLsizei MaxSize; /**< Max possible texture size */ + GLboolean NPOT; /**< Non-power of two size OK? */ + GLsizei Width, Height; /**< Current texture size */ + GLenum IntFormat; + GLfloat Sright, Ttop; /**< right, top texcoords */ +}; + + +/** + * All per-context meta state. + */ +struct gl_meta_state +{ + struct save_state Save; /**< state saved during meta-ops */ + + struct temp_texture TempTex; + + struct blit_state Blit; /**< For _mesa_meta_blit_framebuffer() */ + struct clear_state Clear; /**< For _mesa_meta_clear() */ + struct copypix_state CopyPix; /**< For _mesa_meta_copy_pixels() */ + struct drawpix_state DrawPix; /**< For _mesa_meta_draw_pixels() */ + + /* other possible meta-ops: + * glBitmap() + * glGenerateMipmap() + */ +}; + + +/** + * Initialize meta-ops for a context. + * To be called once during context creation. + */ +void +_mesa_meta_init(GLcontext *ctx) +{ + ASSERT(!ctx->Meta); + + ctx->Meta = CALLOC_STRUCT(gl_meta_state); +} + + +/** + * Free context meta-op state. + * To be called once during context destruction. + */ +void +_mesa_meta_free(GLcontext *ctx) +{ + struct gl_meta_state *meta = ctx->Meta; + + if (_mesa_get_current_context()) { + /* if there's no current context, these textures, buffers, etc should + * still get freed by _mesa_free_context_data(). + */ + + _mesa_DeleteTextures(1, &meta->TempTex.TexObj); + + /* glBlitFramebuffer */ + _mesa_DeleteBuffersARB(1, & meta->Blit.VBO); + _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj); + _mesa_DeletePrograms(1, &meta->Blit.DepthFP); + + /* glClear */ + _mesa_DeleteBuffersARB(1, & meta->Clear.VBO); + _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj); + + /* glCopyPixels */ + _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO); + _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj); + + /* glDrawPixels */ + _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj); + _mesa_DeletePrograms(1, &meta->DrawPix.DepthFP); + _mesa_DeletePrograms(1, &meta->DrawPix.StencilFP); + } + + _mesa_free(ctx->Meta); + ctx->Meta = NULL; +} + + +/** + * Enter meta state. This is like a light-weight version of glPushAttrib + * but it also resets most GL state back to default values. + * + * \param state bitmask of META_* flags indicating which attribute groups + * to save and reset to their defaults + */ +static void +_mesa_meta_begin(GLcontext *ctx, GLbitfield state) +{ + struct save_state *save = &ctx->Meta->Save; + + save->SavedState = state; + + if (state & META_ALPHA_TEST) { + save->AlphaEnabled = ctx->Color.AlphaEnabled; + if (ctx->Color.AlphaEnabled) + _mesa_Disable(GL_ALPHA_TEST); + } + + if (state & META_BLEND) { + save->BlendEnabled = ctx->Color.BlendEnabled; + if (ctx->Color.BlendEnabled) + _mesa_Disable(GL_BLEND); + save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled; + if (ctx->Color.ColorLogicOpEnabled) + _mesa_Disable(GL_COLOR_LOGIC_OP); + } + + if (state & META_COLOR_MASK) { + COPY_4V(save->ColorMask, ctx->Color.ColorMask); + if (!ctx->Color.ColorMask[0] || + !ctx->Color.ColorMask[1] || + !ctx->Color.ColorMask[2] || + !ctx->Color.ColorMask[3]) + _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + } + + if (state & META_DEPTH_TEST) { + save->Depth = ctx->Depth; /* struct copy */ + if (ctx->Depth.Test) + _mesa_Disable(GL_DEPTH_TEST); + } + + if (state & META_FOG) { + save->Fog = ctx->Fog.Enabled; + if (ctx->Fog.Enabled) + _mesa_set_enable(ctx, GL_FOG, GL_FALSE); + } + + if (state & META_PIXEL_STORE) { + save->Pack = ctx->Pack; + save->Unpack = ctx->Unpack; + ctx->Pack = ctx->DefaultPacking; + ctx->Unpack = ctx->DefaultPacking; + } + + if (state & META_RASTERIZATION) { + save->FrontPolygonMode = ctx->Polygon.FrontMode; + save->BackPolygonMode = ctx->Polygon.BackMode; + save->PolygonOffset = ctx->Polygon.OffsetFill; + save->PolygonSmooth = ctx->Polygon.SmoothFlag; + save->PolygonStipple = ctx->Polygon.StippleFlag; + save->PolygonCull = ctx->Polygon.CullFlag; + _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL); + _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE); + _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE); + _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE); + _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE); + } + + if (state & META_SCISSOR) { + save->Scissor = ctx->Scissor; /* struct copy */ + } + + if (state & META_SHADER) { + if (ctx->Extensions.ARB_vertex_program) { + save->VertexProgramEnabled = ctx->VertexProgram.Enabled; + save->VertexProgram = ctx->VertexProgram.Current; + _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE); + } + + if (ctx->Extensions.ARB_fragment_program) { + save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled; + save->FragmentProgram = ctx->FragmentProgram.Current; + _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE); + } + + if (ctx->Extensions.ARB_shader_objects) { + save->Shader = ctx->Shader.CurrentProgram ? + ctx->Shader.CurrentProgram->Name : 0; + _mesa_UseProgramObjectARB(0); + } + } + + if (state & META_STENCIL_TEST) { + save->Stencil = ctx->Stencil; /* struct copy */ + if (ctx->Stencil.Enabled) + _mesa_Disable(GL_STENCIL_TEST); + /* NOTE: other stencil state not reset */ + } + + if (state & META_TEXTURE) { + GLuint u, tgt; + + save->ActiveUnit = ctx->Texture.CurrentUnit; + save->ClientActiveUnit = ctx->Array.ActiveTexture; + save->EnvMode = ctx->Texture.Unit[0].EnvMode; + + /* Disable all texture units */ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled; + save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled; + if (ctx->Texture.Unit[u].Enabled || + ctx->Texture.Unit[u].TexGenEnabled) { + _mesa_ActiveTextureARB(GL_TEXTURE0 + u); + _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE); + _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE); + } + } + + /* save current texture objects for unit[0] only */ + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { + _mesa_reference_texobj(&save->CurrentTexture[tgt], + ctx->Texture.Unit[0].CurrentTex[tgt]); + } + + /* set defaults for unit[0] */ + _mesa_ActiveTextureARB(GL_TEXTURE0); + _mesa_ClientActiveTextureARB(GL_TEXTURE0); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + } + + if (state & META_TRANSFORM) { + GLuint activeTexture = ctx->Texture.CurrentUnit; + _mesa_memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m, + 16 * sizeof(GLfloat)); + _mesa_memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m, + 16 * sizeof(GLfloat)); + _mesa_memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m, + 16 * sizeof(GLfloat)); + save->MatrixMode = ctx->Transform.MatrixMode; + /* set 1:1 vertex:pixel coordinate transform */ + _mesa_ActiveTextureARB(GL_TEXTURE0); + _mesa_MatrixMode(GL_TEXTURE); + _mesa_LoadIdentity(); + _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture); + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_LoadIdentity(); + _mesa_MatrixMode(GL_PROJECTION); + _mesa_LoadIdentity(); + _mesa_Ortho(0.0F, ctx->DrawBuffer->Width, + 0.0F, ctx->DrawBuffer->Height, + -1.0F, 1.0F); + save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled; + if (ctx->Transform.ClipPlanesEnabled) { + GLuint i; + for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { + _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE); + } + } + } + + if (state & META_VERTEX) { + /* save vertex array object state */ + _mesa_reference_array_object(ctx, &save->ArrayObj, + ctx->Array.ArrayObj); + _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, + ctx->Array.ArrayBufferObj); + /* set some default state? */ + } + + if (state & META_VIEWPORT) { + /* save viewport state */ + save->ViewportX = ctx->Viewport.X; + save->ViewportY = ctx->Viewport.Y; + save->ViewportW = ctx->Viewport.Width; + save->ViewportH = ctx->Viewport.Height; + /* set viewport to match window size */ + if (ctx->Viewport.X != 0 || + ctx->Viewport.Y != 0 || + ctx->Viewport.Width != ctx->DrawBuffer->Width || + ctx->Viewport.Height != ctx->DrawBuffer->Height) { + _mesa_set_viewport(ctx, 0, 0, + ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); + } + /* save depth range state */ + save->DepthNear = ctx->Viewport.Near; + save->DepthFar = ctx->Viewport.Far; + /* set depth range to default */ + _mesa_DepthRange(0.0, 1.0); + } + + /* misc */ + { + save->Lighting = ctx->Light.Enabled; + if (ctx->Light.Enabled) + _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE); + } +} + + +/** + * Leave meta state. This is like a light-weight version of glPopAttrib(). + */ +static void +_mesa_meta_end(GLcontext *ctx) +{ + struct save_state *save = &ctx->Meta->Save; + const GLbitfield state = save->SavedState; + + if (state & META_ALPHA_TEST) { + if (ctx->Color.AlphaEnabled != save->AlphaEnabled) + _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled); + } + + if (state & META_BLEND) { + if (ctx->Color.BlendEnabled != save->BlendEnabled) + _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled); + if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled) + _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled); + } + + if (state & META_COLOR_MASK) { + if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask)) + _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1], + save->ColorMask[2], save->ColorMask[3]); + } + + if (state & META_DEPTH_TEST) { + if (ctx->Depth.Test != save->Depth.Test) + _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test); + _mesa_DepthFunc(save->Depth.Func); + _mesa_DepthMask(save->Depth.Mask); + } + + if (state & META_FOG) { + _mesa_set_enable(ctx, GL_FOG, save->Fog); + } + + if (state & META_PIXEL_STORE) { + ctx->Pack = save->Pack; + ctx->Unpack = save->Unpack; + } + + if (state & META_RASTERIZATION) { + _mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode); + _mesa_PolygonMode(GL_BACK, save->BackPolygonMode); + _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple); + _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset); + _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth); + _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull); + } + + if (state & META_SCISSOR) { + _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled); + _mesa_Scissor(save->Scissor.X, save->Scissor.Y, + save->Scissor.Width, save->Scissor.Height); + } + + if (state & META_SHADER) { + if (ctx->Extensions.ARB_vertex_program) { + _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, + save->VertexProgramEnabled); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + save->VertexProgram); + } + + if (ctx->Extensions.ARB_fragment_program) { + _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, + save->FragmentProgramEnabled); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + save->FragmentProgram); + } + + if (ctx->Extensions.ARB_shader_objects) { + _mesa_UseProgramObjectARB(save->Shader); + } + } + + if (state & META_STENCIL_TEST) { + const struct gl_stencil_attrib *stencil = &save->Stencil; + + _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); + _mesa_ClearStencil(stencil->Clear); + if (ctx->Extensions.EXT_stencil_two_side) { + _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT, + stencil->TestTwoSide); + _mesa_ActiveStencilFaceEXT(stencil->ActiveFace + ? GL_BACK : GL_FRONT); + } + /* front state */ + _mesa_StencilFuncSeparate(GL_FRONT, + stencil->Function[0], + stencil->Ref[0], + stencil->ValueMask[0]); + _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]); + _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0], + stencil->ZFailFunc[0], + stencil->ZPassFunc[0]); + /* back state */ + _mesa_StencilFuncSeparate(GL_BACK, + stencil->Function[1], + stencil->Ref[1], + stencil->ValueMask[1]); + _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]); + _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1], + stencil->ZFailFunc[1], + stencil->ZPassFunc[1]); + } + + if (state & META_TEXTURE) { + GLuint u, tgt; + + ASSERT(ctx->Texture.CurrentUnit == 0); + + /* restore texenv for unit[0] */ + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode); + + /* restore texture objects for unit[0] only */ + for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { + _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt], + save->CurrentTexture[tgt]); + } + + /* Re-enable textures, texgen */ + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (save->TexEnabled[u]) { + _mesa_ActiveTextureARB(GL_TEXTURE0 + u); + + if (save->TexEnabled[u] & TEXTURE_1D_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE); + if (save->TexEnabled[u] & TEXTURE_2D_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE); + if (save->TexEnabled[u] & TEXTURE_3D_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE); + if (save->TexEnabled[u] & TEXTURE_CUBE_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE); + if (save->TexEnabled[u] & TEXTURE_RECT_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE); + } + + if (save->TexGenEnabled[u]) { + _mesa_ActiveTextureARB(GL_TEXTURE0 + u); + + if (save->TexGenEnabled[u] & S_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE); + if (save->TexGenEnabled[u] & T_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE); + if (save->TexGenEnabled[u] & R_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE); + if (save->TexGenEnabled[u] & Q_BIT) + _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE); + } + } + + /* restore current unit state */ + _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit); + _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit); + } + + if (state & META_TRANSFORM) { + GLuint activeTexture = ctx->Texture.CurrentUnit; + _mesa_ActiveTextureARB(GL_TEXTURE0); + _mesa_MatrixMode(GL_TEXTURE); + _mesa_LoadMatrixf(save->TextureMatrix); + _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture); + + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_LoadMatrixf(save->ModelviewMatrix); + + _mesa_MatrixMode(GL_PROJECTION); + _mesa_LoadMatrixf(save->ProjectionMatrix); + + _mesa_MatrixMode(save->MatrixMode); + + if (save->ClipPlanesEnabled) { + GLuint i; + for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { + if (save->ClipPlanesEnabled & (1 << i)) { + _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); + } + } + } + } + + if (state & META_VERTEX) { + /* restore vertex buffer object */ + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name); + _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL); + + /* restore vertex array object */ + _mesa_BindVertexArray(save->ArrayObj->Name); + _mesa_reference_array_object(ctx, &save->ArrayObj, NULL); + } + + if (state & META_VIEWPORT) { + if (save->ViewportX != ctx->Viewport.X || + save->ViewportY != ctx->Viewport.Y || + save->ViewportW != ctx->Viewport.Width || + save->ViewportH != ctx->Viewport.Height) { + _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY, + save->ViewportW, save->ViewportH); + } + _mesa_DepthRange(save->DepthNear, save->DepthFar); + } + + /* misc */ + if (save->Lighting) { + _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE); + } +} + + +/** + * Return pointer to temp_texture info. This does some one-time init + * if needed. + */ +static struct temp_texture * +get_temp_texture(GLcontext *ctx) +{ + struct temp_texture *tex = &ctx->Meta->TempTex; + + if (!tex->TexObj) { + /* do one-time init */ + + /* prefer texture rectangle */ + if (ctx->Extensions.NV_texture_rectangle) { + tex->Target = GL_TEXTURE_RECTANGLE; + tex->MaxSize = ctx->Const.MaxTextureRectSize; + tex->NPOT = GL_TRUE; + } + else { + /* use 2D texture, NPOT if possible */ + tex->Target = GL_TEXTURE_2D; + tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1); + tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two; + } + assert(tex->MaxSize > 0); + + _mesa_GenTextures(1, &tex->TexObj); + _mesa_BindTexture(tex->Target, tex->TexObj); + } + + return tex; +} + + +/** + * Compute the width/height of texture needed to draw an image of the + * given size. Return a flag indicating whether the current texture + * can be re-used (glTexSubImage2D) or if a new texture needs to be + * allocated (glTexImage2D). + * Also, compute s/t texcoords for drawing. + * + * \return GL_TRUE if new texture is needed, GL_FALSE otherwise + */ +static GLboolean +alloc_texture(struct temp_texture *tex, + GLsizei width, GLsizei height, GLenum intFormat) +{ + GLboolean newTex = GL_FALSE; + + if (width > tex->Width || + height > tex->Height || + intFormat != tex->IntFormat) { + /* alloc new texture (larger or different format) */ + + if (tex->NPOT) { + /* use non-power of two size */ + tex->Width = width; + tex->Height = height; + } + else { + /* find power of two size */ + GLsizei w, h; + w = h = 16; + while (w < width) + w *= 2; + while (h < height) + h *= 2; + tex->Width = w; + tex->Height = h; + } + + tex->IntFormat = intFormat; + + newTex = GL_TRUE; + } + + /* compute texcoords */ + if (tex->Target == GL_TEXTURE_RECTANGLE) { + tex->Sright = (GLfloat) width; + tex->Ttop = (GLfloat) height; + } + else { + tex->Sright = (GLfloat) width / tex->Width; + tex->Ttop = (GLfloat) height / tex->Height; + } + + return newTex; +} + + +/** + * Setup/load texture for glCopyPixels or glBlitFramebuffer. + */ +static void +setup_copypix_texture(struct temp_texture *tex, + GLboolean newTex, + GLint srcX, GLint srcY, + GLsizei width, GLsizei height, GLenum intFormat, + GLenum filter) +{ + _mesa_BindTexture(tex->Target, tex->TexObj); + _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter); + _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + /* copy framebuffer image to texture */ + if (newTex) { + /* create new tex image */ + if (tex->Width == width && tex->Height == height) { + /* create new tex with framebuffer data */ + _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat, + srcX, srcY, width, height, 0); + } + else { + /* create empty texture */ + _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, + tex->Width, tex->Height, 0, + intFormat, GL_UNSIGNED_BYTE, NULL); + /* load image */ + _mesa_CopyTexSubImage2D(tex->Target, 0, + 0, 0, srcX, srcY, width, height); + } + } + else { + /* replace existing tex image */ + _mesa_CopyTexSubImage2D(tex->Target, 0, + 0, 0, srcX, srcY, width, height); + } +} + + +/** + * Setup/load texture for glDrawPixels. + */ +static void +setup_drawpix_texture(struct temp_texture *tex, + GLboolean newTex, + GLenum texIntFormat, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels) +{ + _mesa_BindTexture(tex->Target, tex->TexObj); + _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + /* copy pixel data to texture */ + if (newTex) { + /* create new tex image */ + if (tex->Width == width && tex->Height == height) { + /* create new tex and load image data */ + _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, + tex->Width, tex->Height, 0, format, type, pixels); + } + else { + /* create empty texture */ + _mesa_TexImage2D(tex->Target, 0, tex->IntFormat, + tex->Width, tex->Height, 0, format, type, NULL); + /* load image */ + _mesa_TexSubImage2D(tex->Target, 0, + 0, 0, width, height, format, type, pixels); + } + } + else { + /* replace existing tex image */ + _mesa_TexSubImage2D(tex->Target, 0, + 0, 0, width, height, format, type, pixels); + } +} + + + +/** + * One-time init for drawing depth pixels. + */ +static void +init_blit_depth_pixels(GLcontext *ctx) +{ + static const char *program = + "!!ARBfp1.0\n" + "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" + "END \n"; + char program2[200]; + struct blit_state *blit = &ctx->Meta->Blit; + struct temp_texture *tex = get_temp_texture(ctx); + const char *texTarget; + + assert(blit->DepthFP == 0); + + /* replace %s with "RECT" or "2D" */ + assert(strlen(program) + 4 < sizeof(program2)); + if (tex->Target == GL_TEXTURE_RECTANGLE) + texTarget = "RECT"; + else + texTarget = "2D"; + _mesa_snprintf(program2, sizeof(program2), program, texTarget); + + _mesa_GenPrograms(1, &blit->DepthFP); + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); + _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(program2), (const GLubyte *) program2); +} + + +/** + * Meta implementation of ctx->Driver.BlitFramebuffer() in terms + * of texture mapping and polygon rendering. + */ +void +_mesa_meta_blit_framebuffer(GLcontext *ctx, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + struct blit_state *blit = &ctx->Meta->Blit; + struct temp_texture *tex = get_temp_texture(ctx); + const GLsizei maxTexSize = tex->MaxSize; + const GLint srcX = MIN2(srcX0, srcX1); + const GLint srcY = MIN2(srcY0, srcY1); + const GLint srcW = abs(srcX1 - srcX0); + const GLint srcH = abs(srcY1 - srcY0); + const GLboolean srcFlipX = srcX1 < srcX0; + const GLboolean srcFlipY = srcY1 < srcY0; + GLfloat verts[4][4]; /* four verts of X,Y,S,T */ + GLboolean newTex; + + if (srcW > maxTexSize || srcH > maxTexSize) { + /* XXX avoid this fallback */ + _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); + return; + } + + if (srcFlipX) { + GLint tmp = dstX0; + dstX0 = dstX1; + dstX1 = tmp; + } + + if (srcFlipY) { + GLint tmp = dstY0; + dstY0 = dstY1; + dstY1 = tmp; + } + + /* only scissor effects blit so save/clear all other relevant state */ + _mesa_meta_begin(ctx, ~META_SCISSOR); + + if (blit->ArrayObj == 0) { + /* one-time setup */ + + /* create vertex array object */ + _mesa_GenVertexArrays(1, &blit->ArrayObj); + _mesa_BindVertexArray(blit->ArrayObj); + + /* create vertex array buffer */ + _mesa_GenBuffersARB(1, &blit->VBO); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), + NULL, GL_DYNAMIC_DRAW_ARB); + + /* setup vertex arrays */ + _mesa_VertexPointer(2, GL_FLOAT, sizeof(verts[0]), + (void *) (0 * sizeof(GLfloat))); + _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(verts[0]), + (void *) (2 * sizeof(GLfloat))); + _mesa_EnableClientState(GL_VERTEX_ARRAY); + _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); + } + else { + _mesa_BindVertexArray(blit->ArrayObj); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO); + } + + newTex = alloc_texture(tex, srcW, srcH, GL_RGBA); + + /* vertex positions/texcoords (after texture allocation!) */ + { + verts[0][0] = (GLfloat) dstX0; + verts[0][1] = (GLfloat) dstY0; + verts[1][0] = (GLfloat) dstX1; + verts[1][1] = (GLfloat) dstY0; + verts[2][0] = (GLfloat) dstX1; + verts[2][1] = (GLfloat) dstY1; + verts[3][0] = (GLfloat) dstX0; + verts[3][1] = (GLfloat) dstY1; + + verts[0][2] = 0.0F; + verts[0][3] = 0.0F; + verts[1][2] = tex->Sright; + verts[1][3] = 0.0F; + verts[2][2] = tex->Sright; + verts[2][3] = tex->Ttop; + verts[3][2] = 0.0F; + verts[3][3] = tex->Ttop; + + /* upload new vertex data */ + _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); + } + + _mesa_Enable(tex->Target); + + if (mask & GL_COLOR_BUFFER_BIT) { + setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH, + GL_RGBA, filter); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + mask &= ~GL_COLOR_BUFFER_BIT; + } + + if (mask & GL_DEPTH_BUFFER_BIT) { + GLuint *tmp = (GLuint *) _mesa_malloc(srcW * srcH * sizeof(GLuint)); + if (tmp) { + if (!blit->DepthFP) + init_blit_depth_pixels(ctx); + + /* maybe change tex format here */ + newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT); + + _mesa_ReadPixels(srcX, srcY, srcW, srcH, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); + + setup_drawpix_texture(tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH, + GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp); + + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP); + _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); + _mesa_DepthFunc(GL_ALWAYS); + _mesa_DepthMask(GL_TRUE); + + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + mask &= ~GL_DEPTH_BUFFER_BIT; + + _mesa_free(tmp); + } + } + + if (mask & GL_STENCIL_BUFFER_BIT) { + /* XXX can't easily do stencil */ + } + + _mesa_Disable(tex->Target); + + _mesa_meta_end(ctx); + + if (mask) { + _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, mask, filter); + } +} + + +/** + * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering. + */ +void +_mesa_meta_clear(GLcontext *ctx, GLbitfield buffers) +{ + struct clear_state *clear = &ctx->Meta->Clear; + GLfloat verts[4][7]; /* four verts of X,Y,Z,R,G,B,A */ + /* save all state but scissor, pixel pack/unpack */ + GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE; + + if (buffers & BUFFER_BITS_COLOR) { + /* if clearing color buffers, don't save/restore colormask */ + metaSave -= META_COLOR_MASK; + } + + _mesa_meta_begin(ctx, metaSave); + + if (clear->ArrayObj == 0) { + /* one-time setup */ + + /* create vertex array object */ + _mesa_GenVertexArrays(1, &clear->ArrayObj); + _mesa_BindVertexArray(clear->ArrayObj); + + /* create vertex array buffer */ + _mesa_GenBuffersARB(1, &clear->VBO); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), + NULL, GL_DYNAMIC_DRAW_ARB); + + /* setup vertex arrays */ + _mesa_VertexPointer(3, GL_FLOAT, sizeof(verts[0]), + (void *) (0 * sizeof(GLfloat))); + _mesa_ColorPointer(4, GL_FLOAT, sizeof(verts[0]), + (void *) (3 * sizeof(GLfloat))); + _mesa_EnableClientState(GL_VERTEX_ARRAY); + _mesa_EnableClientState(GL_COLOR_ARRAY); + } + else { + _mesa_BindVertexArray(clear->ArrayObj); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO); + } + + /* GL_COLOR_BUFFER_BIT */ + if (buffers & BUFFER_BITS_COLOR) { + /* leave colormask, glDrawBuffer state as-is */ + } + else { + ASSERT(metaSave & META_COLOR_MASK); + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + + /* GL_DEPTH_BUFFER_BIT */ + if (buffers & BUFFER_BIT_DEPTH) { + _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE); + _mesa_DepthFunc(GL_ALWAYS); + _mesa_DepthMask(GL_TRUE); + } + else { + assert(!ctx->Depth.Test); + } + + /* GL_STENCIL_BUFFER_BIT */ + if (buffers & BUFFER_BIT_STENCIL) { + _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); + _mesa_StencilOpSeparate(GL_FRONT_AND_BACK, + GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS, + ctx->Stencil.Clear & 0x7fffffff, + ctx->Stencil.WriteMask[0]); + } + else { + assert(!ctx->Stencil.Enabled); + } + + /* vertex positions/colors */ + { + const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin; + const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin; + const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax; + const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax; + const GLfloat z = 1.0 - 2.0 * ctx->Depth.Clear; + GLuint i; + + verts[0][0] = x0; + verts[0][1] = y0; + verts[0][2] = z; + verts[1][0] = x1; + verts[1][1] = y0; + verts[1][2] = z; + verts[2][0] = x1; + verts[2][1] = y1; + verts[2][2] = z; + verts[3][0] = x0; + verts[3][1] = y1; + verts[3][2] = z; + + /* vertex colors */ + for (i = 0; i < 4; i++) { + COPY_4FV(&verts[i][3], ctx->Color.ClearColor); + } + + /* upload new vertex data */ + _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); + } + + /* draw quad */ + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + + _mesa_meta_end(ctx); +} + + +/** + * Meta implementation of ctx->Driver.CopyPixels() in terms + * of texture mapping and polygon rendering. + */ +void +_mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY, + GLsizei width, GLsizei height, + GLint dstX, GLint dstY, GLenum type) +{ + struct copypix_state *copypix = &ctx->Meta->CopyPix; + struct temp_texture *tex = get_temp_texture(ctx); + GLfloat verts[4][5]; /* four verts of X,Y,Z,S,T */ + GLboolean newTex; + GLenum intFormat = GL_RGBA; + + if (type != GL_COLOR || + ctx->_ImageTransferState || + ctx->Fog.Enabled || + width > tex->MaxSize || + height > tex->MaxSize) { + /* XXX avoid this fallback */ + _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type); + return; + } + + /* Most GL state applies to glCopyPixels, but a there's a few things + * we need to override: + */ + _mesa_meta_begin(ctx, (META_RASTERIZATION | + META_SHADER | + META_TEXTURE | + META_TRANSFORM | + META_VERTEX | + META_VIEWPORT)); + + if (copypix->ArrayObj == 0) { + /* one-time setup */ + + /* create vertex array object */ + _mesa_GenVertexArrays(1, ©pix->ArrayObj); + _mesa_BindVertexArray(copypix->ArrayObj); + + /* create vertex array buffer */ + _mesa_GenBuffersARB(1, ©pix->VBO); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), + NULL, GL_DYNAMIC_DRAW_ARB); + + /* setup vertex arrays */ + _mesa_VertexPointer(3, GL_FLOAT, sizeof(verts[0]), + (void *) (0 * sizeof(GLfloat))); + _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(verts[0]), + (void *) (3 * sizeof(GLfloat))); + _mesa_EnableClientState(GL_VERTEX_ARRAY); + _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); + } + else { + _mesa_BindVertexArray(copypix->ArrayObj); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO); + } + + newTex = alloc_texture(tex, width, height, intFormat); + + /* vertex positions, texcoords (after texture allocation!) */ + { + const GLfloat dstX0 = (GLfloat) dstX; + const GLfloat dstY0 = (GLfloat) dstY; + const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX; + const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY; + const GLfloat z = ctx->Current.RasterPos[2]; + + verts[0][0] = dstX0; + verts[0][1] = dstY0; + verts[0][2] = z; + verts[0][3] = 0.0F; + verts[0][4] = 0.0F; + verts[1][0] = dstX1; + verts[1][1] = dstY0; + verts[1][2] = z; + verts[1][3] = tex->Sright; + verts[1][4] = 0.0F; + verts[2][0] = dstX1; + verts[2][1] = dstY1; + verts[2][2] = z; + verts[2][3] = tex->Sright; + verts[2][4] = tex->Ttop; + verts[3][0] = dstX0; + verts[3][1] = dstY1; + verts[3][2] = z; + verts[3][3] = 0.0F; + verts[3][4] = tex->Ttop; + + /* upload new vertex data */ + _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts); + } + + /* Alloc/setup texture */ + setup_copypix_texture(tex, newTex, srcX, srcY, width, height, + GL_RGBA, GL_NEAREST); + + _mesa_Enable(tex->Target); + + /* draw textured quad */ + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + + _mesa_Disable(tex->Target); + + _mesa_meta_end(ctx); +} + + + +/** + * When the glDrawPixels() image size is greater than the max rectangle + * texture size we use this function to break the glDrawPixels() image + * into tiles which fit into the max texture size. + */ +static void +tiled_draw_pixels(GLcontext *ctx, + GLint tileSize, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels) +{ + struct gl_pixelstore_attrib tileUnpack = *unpack; + GLint i, j; + + if (tileUnpack.RowLength == 0) + tileUnpack.RowLength = width; + + for (i = 0; i < width; i += tileSize) { + const GLint tileWidth = MIN2(tileSize, width - i); + const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX); + + tileUnpack.SkipPixels = unpack->SkipPixels + i; + + for (j = 0; j < height; j += tileSize) { + const GLint tileHeight = MIN2(tileSize, height - j); + const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY); + + tileUnpack.SkipRows = unpack->SkipRows + j; + + _mesa_meta_draw_pixels(ctx, tileX, tileY, + tileWidth, tileHeight, + format, type, &tileUnpack, pixels); + } + } +} + + +/** + * One-time init for drawing stencil pixels. + */ +static void +init_draw_stencil_pixels(GLcontext *ctx) +{ + /* This program is run eight times, once for each stencil bit. + * The stencil values to draw are found in an 8-bit alpha texture. + * We read the texture/stencil value and test if bit 'b' is set. + * If the bit is not set, use KIL to kill the fragment. + * Finally, we use the stencil test to update the stencil buffer. + * + * The basic algorithm for checking if a bit is set is: + * if (is_odd(value / (1 << bit))) + * result is one (or non-zero). + * else + * result is zero. + * The program parameter contains three values: + * parm.x = 255 / (1 << bit) + * parm.y = 0.5 + * parm.z = 0.0 + */ + static const char *program = + "!!ARBfp1.0\n" + "PARAM parm = program.local[0]; \n" + "TEMP t; \n" + "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */ + "# t = t * 255 / bit \n" + "MUL t.x, t.a, parm.x; \n" + "# t = (int) t \n" + "FRC t.y, t.x; \n" + "SUB t.x, t.x, t.y; \n" + "# t = t * 0.5 \n" + "MUL t.x, t.x, parm.y; \n" + "# t = fract(t.x) \n" + "FRC t.x, t.x; # if t.x != 0, then the bit is set \n" + "# t.x = (t.x == 0 ? 1 : 0) \n" + "SGE t.x, -t.x, parm.z; \n" + "KIL -t.x; \n" + "# for debug only \n" + "#MOV result.color, t.x; \n" + "END \n"; + char program2[1000]; + struct drawpix_state *drawpix = &ctx->Meta->DrawPix; + struct temp_texture *tex = get_temp_texture(ctx); + const char *texTarget; + + assert(drawpix->StencilFP == 0); + + /* replace %s with "RECT" or "2D" */ + assert(strlen(program) + 4 < sizeof(program2)); + if (tex->Target == GL_TEXTURE_RECTANGLE) + texTarget = "RECT"; + else + texTarget = "2D"; + _mesa_snprintf(program2, sizeof(program2), program, texTarget); + + _mesa_GenPrograms(1, &drawpix->StencilFP); + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); + _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(program2), (const GLubyte *) program2); +} + + +/** + * One-time init for drawing depth pixels. + */ +static void +init_draw_depth_pixels(GLcontext *ctx) +{ + static const char *program = + "!!ARBfp1.0\n" + "PARAM color = program.local[0]; \n" + "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n" + "MOV result.color, color; \n" + "END \n"; + char program2[200]; + struct drawpix_state *drawpix = &ctx->Meta->DrawPix; + struct temp_texture *tex = get_temp_texture(ctx); + const char *texTarget; + + assert(drawpix->DepthFP == 0); + + /* replace %s with "RECT" or "2D" */ + assert(strlen(program) + 4 < sizeof(program2)); + if (tex->Target == GL_TEXTURE_RECTANGLE) + texTarget = "RECT"; + else + texTarget = "2D"; + _mesa_snprintf(program2, sizeof(program2), program, texTarget); + + _mesa_GenPrograms(1, &drawpix->DepthFP); + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); + _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(program2), (const GLubyte *) program2); +} + + +/** + * Meta implementation of ctx->Driver.DrawPixels() in terms + * of texture mapping and polygon rendering. + */ +void +_mesa_meta_draw_pixels(GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels) +{ + struct drawpix_state *drawpix = &ctx->Meta->DrawPix; + struct temp_texture *tex = get_temp_texture(ctx); + const struct gl_pixelstore_attrib unpackSave = ctx->Unpack; + const GLuint origStencilMask = ctx->Stencil.WriteMask[0]; + GLfloat verts[4][5]; /* four verts of X,Y,Z,S,T */ + GLenum texIntFormat; + GLboolean fallback, newTex; + GLbitfield metaExtraSave = 0x0; + GLuint vbo; + + /* + * Determine if we can do the glDrawPixels with texture mapping. + */ + fallback = GL_FALSE; + if (ctx->_ImageTransferState || + ctx->Fog.Enabled) { + fallback = GL_TRUE; + } + + if (_mesa_is_color_format(format)) { + /* use more compact format when possible */ + /* XXX disable special case for GL_LUMINANCE for now to work around + * apparent i965 driver bug (see bug #23670). + */ + if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA) + texIntFormat = format; + else + texIntFormat = GL_RGBA; + } + else if (_mesa_is_stencil_format(format)) { + if (ctx->Extensions.ARB_fragment_program && + ctx->Pixel.IndexShift == 0 && + ctx->Pixel.IndexOffset == 0 && + type == GL_UNSIGNED_BYTE) { + /* We'll store stencil as alpha. This only works for GLubyte + * image data because of how incoming values are mapped to alpha + * in [0,1]. + */ + texIntFormat = GL_ALPHA; + metaExtraSave = (META_COLOR_MASK | + META_DEPTH_TEST | + META_SHADER | + META_STENCIL_TEST); + } + else { + fallback = GL_TRUE; + } + } + else if (_mesa_is_depth_format(format)) { + if (ctx->Extensions.ARB_depth_texture && + ctx->Extensions.ARB_fragment_program) { + texIntFormat = GL_DEPTH_COMPONENT; + metaExtraSave = (META_SHADER); + } + else { + fallback = GL_TRUE; + } + } + else { + fallback = GL_TRUE; + } + + if (fallback) { + _swrast_DrawPixels(ctx, x, y, width, height, + format, type, unpack, pixels); + return; + } + + /* + * Check image size against max texture size, draw as tiles if needed. + */ + if (width > tex->MaxSize || height > tex->MaxSize) { + tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height, + format, type, unpack, pixels); + return; + } + + /* Most GL state applies to glDrawPixels (like blending, stencil, etc), + * but a there's a few things we need to override: + */ + _mesa_meta_begin(ctx, (META_RASTERIZATION | + META_SHADER | + META_TEXTURE | + META_TRANSFORM | + META_VERTEX | + META_VIEWPORT | + metaExtraSave)); + + newTex = alloc_texture(tex, width, height, texIntFormat); + + /* vertex positions, texcoords (after texture allocation!) */ + { + const GLfloat x0 = (GLfloat) x; + const GLfloat y0 = (GLfloat) y; + const GLfloat x1 = x + width * ctx->Pixel.ZoomX; + const GLfloat y1 = y + height * ctx->Pixel.ZoomY; + const GLfloat z = ctx->Current.RasterPos[2]; + + verts[0][0] = x0; + verts[0][1] = y0; + verts[0][2] = z; + verts[0][3] = 0.0F; + verts[0][4] = 0.0F; + verts[1][0] = x1; + verts[1][1] = y0; + verts[1][2] = z; + verts[1][3] = tex->Sright; + verts[1][4] = 0.0F; + verts[2][0] = x1; + verts[2][1] = y1; + verts[2][2] = z; + verts[2][3] = tex->Sright; + verts[2][4] = tex->Ttop; + verts[3][0] = x0; + verts[3][1] = y1; + verts[3][2] = z; + verts[3][3] = 0.0F; + verts[3][4] = tex->Ttop; + } + + if (drawpix->ArrayObj == 0) { + /* one-time setup: create vertex array object */ + _mesa_GenVertexArrays(1, &drawpix->ArrayObj); + } + _mesa_BindVertexArray(drawpix->ArrayObj); + + /* create vertex array buffer */ + _mesa_GenBuffersARB(1, &vbo); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), + verts, GL_DYNAMIC_DRAW_ARB); + + /* setup vertex arrays */ + _mesa_VertexPointer(3, GL_FLOAT, sizeof(verts[0]), + (void *) (0 * sizeof(GLfloat))); + _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(verts[0]), + (void *) (3 * sizeof(GLfloat))); + _mesa_EnableClientState(GL_VERTEX_ARRAY); + _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY); + + /* set given unpack params */ + ctx->Unpack = *unpack; + + _mesa_Enable(tex->Target); + + if (_mesa_is_stencil_format(format)) { + /* Drawing stencil */ + GLint bit; + + if (!drawpix->StencilFP) + init_draw_stencil_pixels(ctx); + + setup_drawpix_texture(tex, newTex, texIntFormat, width, height, + GL_ALPHA, type, pixels); + + _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + + _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE); + + /* set all stencil bits to 0 */ + _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + _mesa_StencilFunc(GL_ALWAYS, 0, 255); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + + /* set stencil bits to 1 where needed */ + _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP); + _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); + + for (bit = 0; bit < ctx->Visual.stencilBits; bit++) { + const GLuint mask = 1 << bit; + if (mask & origStencilMask) { + _mesa_StencilFunc(GL_ALWAYS, mask, mask); + _mesa_StencilMask(mask); + + _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, + 255.0 / mask, 0.5, 0.0, 0.0); + + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + } + } + else if (_mesa_is_depth_format(format)) { + /* Drawing depth */ + if (!drawpix->DepthFP) + init_draw_depth_pixels(ctx); + + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP); + _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE); + + /* polygon color = current raster color */ + _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, + ctx->Current.RasterColor); + + setup_drawpix_texture(tex, newTex, texIntFormat, width, height, + format, type, pixels); + + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + else { + /* Drawing RGBA */ + setup_drawpix_texture(tex, newTex, texIntFormat, width, height, + format, type, pixels); + _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + + _mesa_Disable(tex->Target); + + _mesa_DeleteBuffersARB(1, &vbo); + + /* restore unpack params */ + ctx->Unpack = unpackSave; + + _mesa_meta_end(ctx); +} diff --git a/mesalib/src/mesa/drivers/common/meta.h b/mesalib/src/mesa/drivers/common/meta.h new file mode 100644 index 000000000..b03b64c48 --- /dev/null +++ b/mesalib/src/mesa/drivers/common/meta.h @@ -0,0 +1,81 @@ +/* + * Mesa 3-D graphics library + * Version: 7.6 + * + * Copyright (C) 2009 VMware, Inc. 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 + * BRIAN PAUL 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. + */ + + +#ifndef META_H +#define META_H + + +/** + * Flags passed to _mesa_meta_begin(). + * XXX these flags may evolve... + */ +/*@{*/ +#define META_ALPHA_TEST 0x1 +#define META_BLEND 0x2 /**< includes logicop */ +#define META_COLOR_MASK 0x4 +#define META_DEPTH_TEST 0x8 +#define META_FOG 0x10 +#define META_RASTERIZATION 0x20 +#define META_SCISSOR 0x40 +#define META_SHADER 0x80 +#define META_STENCIL_TEST 0x100 +#define META_TRANSFORM 0x200 /**< modelview, projection */ +#define META_TEXTURE 0x400 +#define META_VERTEX 0x800 +#define META_VIEWPORT 0x1000 +#define META_PIXEL_STORE 0x2000 +#define META_ALL ~0x0 +/*@}*/ + + +extern void +_mesa_meta_init(GLcontext *ctx); + +extern void +_mesa_meta_free(GLcontext *ctx); + +extern void +_mesa_meta_blit_framebuffer(GLcontext *ctx, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter); + +extern void +_mesa_meta_clear(GLcontext *ctx, GLbitfield buffers); + +extern void +_mesa_meta_copy_pixels(GLcontext *ctx, GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type); + +extern void +_mesa_meta_draw_pixels(GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels); + + +#endif /* META_H */ diff --git a/mesalib/src/mesa/drivers/dri/Makefile b/mesalib/src/mesa/drivers/dri/Makefile new file mode 100644 index 000000000..32db09786 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/Makefile @@ -0,0 +1,55 @@ +# src/mesa/drivers/dri/Makefile + +TOP = ../../../.. + +include $(TOP)/configs/current + + + +default: $(TOP)/$(LIB_DIR) subdirs dri.pc + + +$(TOP)/$(LIB_DIR): + -mkdir $(TOP)/$(LIB_DIR) + + +subdirs: + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE)) || exit 1 ; \ + fi \ + done + +pcedit = sed \ + -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \ + -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \ + -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \ + -e 's,@VERSION@,$(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY),' \ + -e 's,@DRI_DRIVER_DIR@,$(DRI_DRIVER_SEARCH_DIR),' \ + -e 's,@DRI_PC_REQ_PRIV@,$(DRI_PC_REQ_PRIV),' + +dri.pc: dri.pc.in + $(pcedit) $< > $@ + + +install: dri.pc + @for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) install) || exit 1 ; \ + fi \ + done + $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL/internal + $(INSTALL) -m 0644 $(TOP)/include/GL/internal/dri_interface.h \ + $(DESTDIR)$(INSTALL_INC_DIR)/GL/internal + $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + $(INSTALL) -m 0644 dri.pc $(DESTDIR)$(INSTALL_LIB_DIR)/pkgconfig + + +clean: + -@for dir in $(DRI_DIRS) ; do \ + if [ -d $$dir ] ; then \ + (cd $$dir && $(MAKE) clean) ; \ + fi \ + done + -rm -f common/*.o + -rm -f *.pc diff --git a/mesalib/src/mesa/drivers/dri/Makefile.template b/mesalib/src/mesa/drivers/dri/Makefile.template new file mode 100644 index 000000000..18dbeba24 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/Makefile.template @@ -0,0 +1,99 @@ +# -*-makefile-*- + +MESA_MODULES = $(TOP)/src/mesa/libmesa.a + +COMMON_GALLIUM_SOURCES = \ + ../common/utils.c \ + ../common/vblank.c \ + ../common/dri_util.c \ + ../common/xmlconfig.c + +COMMON_SOURCES = $(COMMON_GALLIUM_SOURCES) \ + ../../common/driverfuncs.c \ + ../common/texmem.c \ + ../common/drirenderbuffer.c \ + ../common/dri_metaops.c + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ= +WINLIB= +INCLUDES = $(SHARED_INCLUDES) $(EXPAT_INCLUDES) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +else +# miniglx +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) \ + $(PCIACCESS_CFLAGS) + +OBJECTS = $(C_SOURCES:.c=.o) \ + $(MINIGLX_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) +endif + + +### Include directories +SHARED_INCLUDES = \ + -I. \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -Iserver \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/drivers/dri \ + $(LIBDRM_CFLAGS) + + +##### RULES ##### + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $(DRIVER_DEFINES) $< -o $@ + + +##### TARGETS ##### + +default: symlinks depend $(LIBNAME) $(TOP)/$(LIB_DIR)/$(LIBNAME) + + +$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template + $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \ + $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) + + +$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME) + $(INSTALL) $(LIBNAME) $(TOP)/$(LIB_DIR) + + +depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS) + @ echo "running $(MKDEP)" + @ rm -f depend + @ touch depend + @ $(MKDEP) $(MKDEP_OPTIONS) $(DRIVER_DEFINES) $(INCLUDES) $(C_SOURCES) \ + $(ASM_SOURCES) > /dev/null 2>/dev/null + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.so *~ server/*.o $(SYMLINKS) + -rm -f depend depend.bak + + +install: $(LIBNAME) + $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR) + + +-include depend diff --git a/mesalib/src/mesa/drivers/dri/common/depthtmp.h b/mesalib/src/mesa/drivers/dri/common/depthtmp.h new file mode 100644 index 000000000..fd2dab3b4 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/depthtmp.h @@ -0,0 +1,270 @@ + +/* + * Notes: + * 1. These functions plug into the gl_renderbuffer structure. + * 2. The 'values' parameter always points to GLuint values, regardless of + * the actual Z buffer depth. + */ + + +#include "spantmp_common.h" + +#ifndef DBG +#define DBG 0 +#endif + +#ifndef HAVE_HW_DEPTH_SPANS +#define HAVE_HW_DEPTH_SPANS 0 +#endif + +#ifndef HAVE_HW_DEPTH_PIXELS +#define HAVE_HW_DEPTH_PIXELS 0 +#endif + +static void TAG(WriteDepthSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const VALUE_TYPE *depth = (const VALUE_TYPE *) values; + GLint x1; + GLint n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n", + (int)n, (int)x ); + + WRITE_DEPTH_SPAN(); +#else + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + + if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n", + (int)i, (int)n1, (int)x1, mask ); + + if ( mask ) { + for ( ; n1>0 ; i++, x1++, n1-- ) { + if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] ); + } + } else { + for ( ; n1>0 ; i++, x1++, n1-- ) { + WRITE_DEPTH( x1, y, depth[i] ); + } + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_WRITE_UNLOCK(); +} + + +#if HAVE_HW_DEPTH_SPANS +/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */ +static void +TAG(WriteMonoDepthSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, const GLubyte mask[] ) +{ + const GLuint depthVal = *((GLuint *) value); + GLuint depths[MAX_WIDTH]; + GLuint i; + for (i = 0; i < n; i++) + depths[i] = depthVal; + TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask); +} +#else +static void TAG(WriteMonoDepthSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLuint depth = *((GLuint *) value); + GLint x1; + GLint n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + + if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n", + __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth ); + + if ( mask ) { + for ( ; n1>0 ; i++, x1++, n1-- ) { + if ( mask[i] ) WRITE_DEPTH( x1, y, depth ); + } + } else { + for ( ; n1>0 ; x1++, n1-- ) { + WRITE_DEPTH( x1, y, depth ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} +#endif + + +static void TAG(WriteDepthPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], + const GLint y[], + const void *values, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const VALUE_TYPE *depth = (const VALUE_TYPE *) values; + GLuint i; + LOCAL_DEPTH_VARS; + + if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + + WRITE_DEPTH_PIXELS(); +#else + HW_CLIPLOOP() + { + if ( mask ) { + for ( i = 0 ; i < n ; i++ ) { + if ( mask[i] ) { + const int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + WRITE_DEPTH( x[i], fy, depth[i] ); + } + } + } + else { + for ( i = 0 ; i < n ; i++ ) { + const int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + WRITE_DEPTH( x[i], fy, depth[i] ); + } + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_WRITE_UNLOCK(); +} + + +/* Read depth spans and pixels + */ +static void TAG(ReadDepthSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + void *values ) +{ + HW_READ_LOCK() + { + VALUE_TYPE *depth = (VALUE_TYPE *) values; + GLint x1, n1; + LOCAL_DEPTH_VARS; + + y = Y_FLIP( y ); + + if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" ); + +#if HAVE_HW_DEPTH_SPANS + (void) x1; (void) n1; + + READ_DEPTH_SPAN(); +#else + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN( x, y, n, x1, n1, i ); + for ( ; n1>0 ; i++, n1-- ) { + READ_DEPTH( depth[i], x+i, y ); + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_READ_UNLOCK(); +} + +static void TAG(ReadDepthPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + void *values ) +{ + HW_READ_LOCK() + { + VALUE_TYPE *depth = (VALUE_TYPE *) values; + GLuint i; + LOCAL_DEPTH_VARS; + + if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" ); + +#if HAVE_HW_DEPTH_PIXELS + (void) i; + + READ_DEPTH_PIXELS(); +#else + HW_CLIPLOOP() + { + for ( i = 0 ; i < n ;i++ ) { + int fy = Y_FLIP( y[i] ); + if ( CLIPPIXEL( x[i], fy ) ) + READ_DEPTH( depth[i], x[i], fy ); + } + } + HW_ENDCLIPLOOP(); +#endif + } + HW_READ_UNLOCK(); +} + + +/** + * Initialize the given renderbuffer's span routines to point to + * the depth/z functions we generated above. + */ +static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb) +{ + rb->GetRow = TAG(ReadDepthSpan); + rb->GetValues = TAG(ReadDepthPixels); + rb->PutRow = TAG(WriteDepthSpan); + rb->PutRowRGB = NULL; + rb->PutMonoRow = TAG(WriteMonoDepthSpan); + rb->PutValues = TAG(WriteDepthPixels); + rb->PutMonoValues = NULL; +} + + +#if HAVE_HW_DEPTH_SPANS +#undef WRITE_DEPTH_SPAN +#undef WRITE_DEPTH_PIXELS +#undef READ_DEPTH_SPAN +#undef READ_DEPTH_PIXELS +#else +#undef WRITE_DEPTH +#undef READ_DEPTH +#endif +#undef TAG +#undef VALUE_TYPE diff --git a/mesalib/src/mesa/drivers/dri/common/dri_metaops.c b/mesalib/src/mesa/drivers/dri/common/dri_metaops.c new file mode 100644 index 000000000..c7bea07dc --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/dri_metaops.c @@ -0,0 +1,298 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * 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, 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 TUNGSTEN GRAPHICS AND/OR ITS 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. + * + **************************************************************************/ + +#include "main/arrayobj.h" +#include "main/attrib.h" +#include "main/blend.h" +#include "main/bufferobj.h" +#include "main/buffers.h" +#include "main/depth.h" +#include "main/enable.h" +#include "main/matrix.h" +#include "main/macros.h" +#include "main/polygon.h" +#include "main/shaders.h" +#include "main/stencil.h" +#include "main/texstate.h" +#include "main/varray.h" +#include "main/viewport.h" +#include "shader/arbprogram.h" +#include "shader/program.h" +#include "dri_metaops.h" + +void +meta_set_passthrough_transform(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + meta->saved_vp_x = ctx->Viewport.X; + meta->saved_vp_y = ctx->Viewport.Y; + meta->saved_vp_width = ctx->Viewport.Width; + meta->saved_vp_height = ctx->Viewport.Height; + meta->saved_matrix_mode = ctx->Transform.MatrixMode; + + meta->internal_viewport_call = GL_TRUE; + _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height); + meta->internal_viewport_call = GL_FALSE; + + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); + _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1); + + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PushMatrix(); + _mesa_LoadIdentity(); +} + +void +meta_restore_transform(struct dri_metaops *meta) +{ + _mesa_MatrixMode(GL_PROJECTION); + _mesa_PopMatrix(); + _mesa_MatrixMode(GL_MODELVIEW); + _mesa_PopMatrix(); + + _mesa_MatrixMode(meta->saved_matrix_mode); + + meta->internal_viewport_call = GL_TRUE; + _mesa_Viewport(meta->saved_vp_x, meta->saved_vp_y, + meta->saved_vp_width, meta->saved_vp_height); + meta->internal_viewport_call = GL_FALSE; +} + + +/** + * Set up a vertex program to pass through the position and first texcoord + * for pixel path. + */ +void +meta_set_passthrough_vertex_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + static const char *vp = + "!!ARBvp1.0\n" + "TEMP vertexClip;\n" + "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position;\n" + "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position;\n" + "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position;\n" + "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position;\n" + "MOV result.position, vertexClip;\n" + "MOV result.texcoord[0], vertex.texcoord[0];\n" + "MOV result.color, vertex.color;\n" + "END\n"; + + assert(meta->saved_vp == NULL); + + _mesa_reference_vertprog(ctx, &meta->saved_vp, + ctx->VertexProgram.Current); + if (meta->passthrough_vp == NULL) { + GLuint prog_name; + _mesa_GenPrograms(1, &prog_name); + _mesa_BindProgram(GL_VERTEX_PROGRAM_ARB, prog_name); + _mesa_ProgramStringARB(GL_VERTEX_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(vp), (const GLubyte *)vp); + _mesa_reference_vertprog(ctx, &meta->passthrough_vp, + ctx->VertexProgram.Current); + _mesa_DeletePrograms(1, &prog_name); + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + meta->passthrough_vp); + ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, + &meta->passthrough_vp->Base); + + meta->saved_vp_enable = ctx->VertexProgram.Enabled; + _mesa_Enable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Restores the previous vertex program after + * meta_set_passthrough_vertex_program() + */ +void +meta_restore_vertex_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, + meta->saved_vp); + _mesa_reference_vertprog(ctx, &meta->saved_vp, NULL); + ctx->Driver.BindProgram(ctx, GL_VERTEX_PROGRAM_ARB, + &ctx->VertexProgram.Current->Base); + + if (!meta->saved_vp_enable) + _mesa_Disable(GL_VERTEX_PROGRAM_ARB); +} + +/** + * Binds the given program string to GL_FRAGMENT_PROGRAM_ARB, caching the + * program object. + */ +void +meta_set_fragment_program(struct dri_metaops *meta, + struct gl_fragment_program **prog, + const char *prog_string) +{ + GLcontext *ctx = meta->ctx; + assert(meta->saved_fp == NULL); + + _mesa_reference_fragprog(ctx, &meta->saved_fp, + ctx->FragmentProgram.Current); + if (*prog == NULL) { + GLuint prog_name; + _mesa_GenPrograms(1, &prog_name); + _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, prog_name); + _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, + GL_PROGRAM_FORMAT_ASCII_ARB, + strlen(prog_string), (const GLubyte *)prog_string); + _mesa_reference_fragprog(ctx, prog, ctx->FragmentProgram.Current); + /* Note that DeletePrograms unbinds the program on us */ + _mesa_DeletePrograms(1, &prog_name); + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, *prog); + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, &((*prog)->Base)); + + meta->saved_fp_enable = ctx->FragmentProgram.Enabled; + _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB); +} + +/** + * Restores the previous fragment program after + * meta_set_fragment_program() + */ +void +meta_restore_fragment_program(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + FLUSH_VERTICES(ctx, _NEW_PROGRAM); + _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, + meta->saved_fp); + _mesa_reference_fragprog(ctx, &meta->saved_fp, NULL); + ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, + &ctx->FragmentProgram.Current->Base); + + if (!meta->saved_fp_enable) + _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB); +} + +static const float default_texcoords[4][2] = { { 0.0, 0.0 }, + { 1.0, 0.0 }, + { 1.0, 1.0 }, + { 0.0, 1.0 } }; + +void +meta_set_default_texrect(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + struct gl_client_array *old_texcoord_array; + + meta->saved_active_texture = ctx->Texture.CurrentUnit; + if (meta->saved_array_vbo == NULL) { + _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, + ctx->Array.ArrayBufferObj); + } + + old_texcoord_array = &ctx->Array.ArrayObj->TexCoord[0]; + meta->saved_texcoord_type = old_texcoord_array->Type; + meta->saved_texcoord_size = old_texcoord_array->Size; + meta->saved_texcoord_stride = old_texcoord_array->Stride; + meta->saved_texcoord_enable = old_texcoord_array->Enabled; + meta->saved_texcoord_ptr = old_texcoord_array->Ptr; + _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, + old_texcoord_array->BufferObj); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0); + + if (meta->texcoord_vbo == NULL) { + GLuint vbo_name; + + _mesa_GenBuffersARB(1, &vbo_name); + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo_name); + _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(default_texcoords), + default_texcoords, GL_STATIC_DRAW_ARB); + _mesa_reference_buffer_object(ctx, &meta->texcoord_vbo, + ctx->Array.ArrayBufferObj); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->texcoord_vbo->Name); + } + _mesa_TexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), NULL); + + _mesa_Enable(GL_TEXTURE_COORD_ARRAY); +} + +void +meta_restore_texcoords(struct dri_metaops *meta) +{ + GLcontext *ctx = meta->ctx; + + /* Restore the old TexCoordPointer */ + if (meta->saved_texcoord_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->saved_texcoord_vbo->Name); + _mesa_reference_buffer_object(ctx, &meta->saved_texcoord_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + _mesa_TexCoordPointer(meta->saved_texcoord_size, + meta->saved_texcoord_type, + meta->saved_texcoord_stride, + meta->saved_texcoord_ptr); + if (!meta->saved_texcoord_enable) + _mesa_Disable(GL_TEXTURE_COORD_ARRAY); + + _mesa_ClientActiveTextureARB(GL_TEXTURE0 + + meta->saved_active_texture); + + if (meta->saved_array_vbo) { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, + meta->saved_array_vbo->Name); + _mesa_reference_buffer_object(ctx, &meta->saved_array_vbo, NULL); + } else { + _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } +} + + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta) +{ + meta->ctx = ctx; +} + +void meta_destroy_metaops(struct dri_metaops *meta) +{ + +} diff --git a/mesalib/src/mesa/drivers/dri/common/dri_metaops.h b/mesalib/src/mesa/drivers/dri/common/dri_metaops.h new file mode 100644 index 000000000..248714532 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/dri_metaops.h @@ -0,0 +1,81 @@ +/************************************************************************** + * + * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas. + * Copyright 2009 Intel Corporation. + * 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, 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 TUNGSTEN GRAPHICS AND/OR ITS 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. + * + **************************************************************************/ + +#ifndef DRI_METAOPS_H +#define DRI_METAOPS_H + + +struct dri_metaops { + GLcontext *ctx; + GLboolean internal_viewport_call; + struct gl_fragment_program *bitmap_fp; + struct gl_vertex_program *passthrough_vp; + struct gl_buffer_object *texcoord_vbo; + + struct gl_fragment_program *saved_fp; + GLboolean saved_fp_enable; + struct gl_vertex_program *saved_vp; + GLboolean saved_vp_enable; + + struct gl_fragment_program *tex2d_fp; + + GLboolean saved_texcoord_enable; + struct gl_buffer_object *saved_array_vbo, *saved_texcoord_vbo; + GLenum saved_texcoord_type; + GLsizei saved_texcoord_size, saved_texcoord_stride; + const void *saved_texcoord_ptr; + int saved_active_texture; + + GLint saved_vp_x, saved_vp_y; + GLsizei saved_vp_width, saved_vp_height; + GLenum saved_matrix_mode; +}; + + +void meta_set_passthrough_transform(struct dri_metaops *meta); + +void meta_restore_transform(struct dri_metaops *meta); + +void meta_set_passthrough_vertex_program(struct dri_metaops *meta); + +void meta_restore_vertex_program(struct dri_metaops *meta); + +void meta_set_fragment_program(struct dri_metaops *meta, + struct gl_fragment_program **prog, + const char *prog_string); + +void meta_restore_fragment_program(struct dri_metaops *meta); + +void meta_set_default_texrect(struct dri_metaops *meta); + +void meta_restore_texcoords(struct dri_metaops *meta); + +void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta); +void meta_destroy_metaops(struct dri_metaops *meta); + +#endif diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c new file mode 100644 index 000000000..e48e10d7c --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c @@ -0,0 +1,957 @@ +/** + * \file dri_util.c + * DRI utility functions. + * + * This module acts as glue between GLX and the actual hardware driver. A DRI + * driver doesn't really \e have to use any of this - it's optional. But, some + * useful stuff is done here that otherwise would have to be duplicated in most + * drivers. + * + * Basically, these utility functions take care of some of the dirty details of + * screen initialization, context creation, context binding, DRM setup, etc. + * + * These functions are compiled into each DRI driver so libGL.so knows nothing + * about them. + */ + + +#include <assert.h> +#include <stdarg.h> +#include <unistd.h> +#include <sys/mman.h> +#include <stdio.h> + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +#include "main/imports.h" +#define None 0 + +#include "dri_util.h" +#include "drm_sarea.h" +#include "utils.h" + +#ifndef GLX_OML_sync_control +typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator); +#endif + +static void dri_get_drawable(__DRIdrawable *pdp); +static void dri_put_drawable(__DRIdrawable *pdp); + +/** + * This is just a token extension used to signal that the driver + * supports setting a read drawable. + */ +const __DRIextension driReadDrawableExtension = { + __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION +}; + +/** + * Print message to \c stderr if the \c LIBGL_DEBUG environment variable + * is set. + * + * Is called from the drivers. + * + * \param f \c printf like format string. + */ +void +__driUtilMessage(const char *f, ...) +{ + va_list args; + + if (getenv("LIBGL_DEBUG")) { + fprintf(stderr, "libGL: "); + va_start(args, f); + vfprintf(stderr, f, args); + va_end(args); + fprintf(stderr, "\n"); + } +} + +GLint +driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ) +{ + if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1; + if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2; + if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1; + if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2; + + if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0; + + return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1); +} + +/*****************************************************************/ +/** \name Context (un)binding functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Unbind context. + * + * \param scrn the screen. + * \param gc context. + * + * \return \c GL_TRUE on success, or \c GL_FALSE on failure. + * + * \internal + * This function calls __DriverAPIRec::UnbindContext, and then decrements + * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful + * return. + * + * While casting the opaque private pointers associated with the parameters + * into their respective real types it also assures they are not \c NULL. + */ +static int driUnbindContext(__DRIcontext *pcp) +{ + __DRIscreen *psp; + __DRIdrawable *pdp; + __DRIdrawable *prp; + + /* + ** Assume error checking is done properly in glXMakeCurrent before + ** calling driUnbindContext. + */ + + if (pcp == NULL) + return GL_FALSE; + + psp = pcp->driScreenPriv; + pdp = pcp->driDrawablePriv; + prp = pcp->driReadablePriv; + + /* already unbound */ + if (!pdp && !prp) + return GL_TRUE; + /* Let driver unbind drawable from context */ + (*psp->DriverAPI.UnbindContext)(pcp); + + if (pdp->refcount == 0) { + /* ERROR!!! */ + return GL_FALSE; + } + + dri_put_drawable(pdp); + + if (prp != pdp) { + if (prp->refcount == 0) { + /* ERROR!!! */ + return GL_FALSE; + } + + dri_put_drawable(prp); + } + + + /* XXX this is disabled so that if we call SwapBuffers on an unbound + * window we can determine the last context bound to the window and + * use that context's lock. (BrianP, 2-Dec-2000) + */ + pcp->driDrawablePriv = pcp->driReadablePriv = NULL; + +#if 0 + /* Unbind the drawable */ + pdp->driContextPriv = &psp->dummyContextPriv; +#endif + + return GL_TRUE; +} + +/** + * This function takes both a read buffer and a draw buffer. This is needed + * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent + * function. + */ +static int driBindContext(__DRIcontext *pcp, + __DRIdrawable *pdp, + __DRIdrawable *prp) +{ + __DRIscreenPrivate *psp = pcp->driScreenPriv; + + /* Bind the drawable to the context */ + + if (pcp) { + pcp->driDrawablePriv = pdp; + pcp->driReadablePriv = prp; + if (pdp) { + pdp->driContextPriv = pcp; + dri_get_drawable(pdp); + } + if ( prp && pdp != prp ) { + dri_get_drawable(prp); + } + } + + /* + ** Now that we have a context associated with this drawable, we can + ** initialize the drawable information if has not been done before. + */ + + if (!psp->dri2.enabled) { + if (pdp && !pdp->pStamp) { + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + __driUtilUpdateDrawableInfo(pdp); + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + } + if (prp && pdp != prp && !prp->pStamp) { + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + __driUtilUpdateDrawableInfo(prp); + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + } + } + + /* Call device-specific MakeCurrent */ + + return (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp); +} + +/*@}*/ + + +/*****************************************************************/ +/** \name Drawable handling functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Update private drawable information. + * + * \param pdp pointer to the private drawable information to update. + * + * This function basically updates the __DRIdrawablePrivate struct's + * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo. + * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which + * compares the __DRIdrwablePrivate pStamp and lastStamp values. If + * the values are different that means we have to update the clipping + * info. + */ +void +__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp) +{ + __DRIscreenPrivate *psp = pdp->driScreenPriv; + __DRIcontextPrivate *pcp = pdp->driContextPriv; + + if (!pcp + || ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) { + /* ERROR!!! + * ...but we must ignore it. There can be many contexts bound to a + * drawable. + */ + } + + if (pdp->pClipRects) { + _mesa_free(pdp->pClipRects); + pdp->pClipRects = NULL; + } + + if (pdp->pBackClipRects) { + _mesa_free(pdp->pBackClipRects); + pdp->pBackClipRects = NULL; + } + + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); + + if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp, + &pdp->index, &pdp->lastStamp, + &pdp->x, &pdp->y, &pdp->w, &pdp->h, + &pdp->numClipRects, &pdp->pClipRects, + &pdp->backX, + &pdp->backY, + &pdp->numBackClipRects, + &pdp->pBackClipRects, + pdp->loaderPrivate)) { + /* Error -- eg the window may have been destroyed. Keep going + * with no cliprects. + */ + pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */ + pdp->numClipRects = 0; + pdp->pClipRects = NULL; + pdp->numBackClipRects = 0; + pdp->pBackClipRects = NULL; + } + else + pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp); + + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); +} + +/*@}*/ + +/*****************************************************************/ +/** \name GLX callbacks */ +/*****************************************************************/ +/*@{*/ + +static void driReportDamage(__DRIdrawable *pdp, + struct drm_clip_rect *pClipRects, int numClipRects) +{ + __DRIscreen *psp = pdp->driScreenPriv; + + /* Check that we actually have the new damage report method */ + if (psp->damage) { + /* Report the damage. Currently, all our drivers draw + * directly to the front buffer, so we report the damage there + * rather than to the backing storein (if any). + */ + (*psp->damage->reportDamage)(pdp, + pdp->x, pdp->y, + pClipRects, numClipRects, + GL_TRUE, pdp->loaderPrivate); + } +} + + +/** + * Swap buffers. + * + * \param drawablePrivate opaque pointer to the per-drawable private info. + * + * \internal + * This function calls __DRIdrawablePrivate::swapBuffers. + * + * Is called directly from glXSwapBuffers(). + */ +static void driSwapBuffers(__DRIdrawable *dPriv) +{ + __DRIscreen *psp = dPriv->driScreenPriv; + drm_clip_rect_t *rects; + int i; + + psp->DriverAPI.SwapBuffers(dPriv); + + if (!dPriv->numClipRects) + return; + + rects = _mesa_malloc(sizeof(*rects) * dPriv->numClipRects); + + if (!rects) + return; + + for (i = 0; i < dPriv->numClipRects; i++) { + rects[i].x1 = dPriv->pClipRects[i].x1 - dPriv->x; + rects[i].y1 = dPriv->pClipRects[i].y1 - dPriv->y; + rects[i].x2 = dPriv->pClipRects[i].x2 - dPriv->x; + rects[i].y2 = dPriv->pClipRects[i].y2 - dPriv->y; + } + + driReportDamage(dPriv, rects, dPriv->numClipRects); + _mesa_free(rects); +} + +static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv, + int64_t *msc ) +{ + return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc); +} + + +static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc, + int64_t divisor, int64_t remainder, + int64_t * msc, int64_t * sbc) +{ + __DRIswapInfo sInfo; + int status; + + status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc, + divisor, remainder, + msc ); + + /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync + * is supported but GLX_OML_sync_control is not. Therefore, don't return + * an error value if GetSwapInfo() is not implemented. + */ + if ( status == 0 + && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) { + status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo ); + *sbc = sInfo.swap_count; + } + + return status; +} + + +const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = { + { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION }, + driWaitForMSC, + driDrawableGetMSC, +}; + + +static void driCopySubBuffer(__DRIdrawable *dPriv, + int x, int y, int w, int h) +{ + drm_clip_rect_t rect; + + rect.x1 = x; + rect.y1 = dPriv->h - y - h; + rect.x2 = x + w; + rect.y2 = rect.y1 + h; + driReportDamage(dPriv, &rect, 1); + + dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h); +} + +const __DRIcopySubBufferExtension driCopySubBufferExtension = { + { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION }, + driCopySubBuffer +}; + +static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval) +{ + dPriv->swap_interval = interval; +} + +static unsigned int driGetSwapInterval(__DRIdrawable *dPriv) +{ + return dPriv->swap_interval; +} + +const __DRIswapControlExtension driSwapControlExtension = { + { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION }, + driSetSwapInterval, + driGetSwapInterval +}; + + +/** + * This is called via __DRIscreenRec's createNewDrawable pointer. + */ +static __DRIdrawable * +driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, + drm_drawable_t hwDrawable, int renderType, + const int *attrs, void *data) +{ + __DRIdrawable *pdp; + + /* Since pbuffers are not yet supported, no drawable attributes are + * supported either. + */ + (void) attrs; + + pdp = _mesa_malloc(sizeof *pdp); + if (!pdp) { + return NULL; + } + + pdp->loaderPrivate = data; + pdp->hHWDrawable = hwDrawable; + pdp->refcount = 1; + pdp->pStamp = NULL; + pdp->lastStamp = 0; + pdp->index = 0; + pdp->x = 0; + pdp->y = 0; + pdp->w = 0; + pdp->h = 0; + pdp->numClipRects = 0; + pdp->numBackClipRects = 0; + pdp->pClipRects = NULL; + pdp->pBackClipRects = NULL; + pdp->vblSeq = 0; + pdp->vblFlags = 0; + + pdp->driScreenPriv = psp; + pdp->driContextPriv = &psp->dummyContextPriv; + + if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, + renderType == GLX_PIXMAP_BIT)) { + _mesa_free(pdp); + return NULL; + } + + pdp->msc_base = 0; + + /* This special default value is replaced with the configured + * default value when the drawable is first bound to a direct + * rendering context. + */ + pdp->swap_interval = (unsigned)-1; + + return pdp; +} + + +static __DRIdrawable * +dri2CreateNewDrawable(__DRIscreen *screen, + const __DRIconfig *config, + void *loaderPrivate) +{ + __DRIdrawable *pdraw; + + pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, loaderPrivate); + if (!pdraw) + return NULL; + + pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); + pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); + + return pdraw; +} + +static void dri_get_drawable(__DRIdrawable *pdp) +{ + pdp->refcount++; +} + +static void dri_put_drawable(__DRIdrawable *pdp) +{ + __DRIscreenPrivate *psp; + + pdp->refcount--; + if (pdp->refcount) + return; + + if (pdp) { + psp = pdp->driScreenPriv; + (*psp->DriverAPI.DestroyBuffer)(pdp); + if (pdp->pClipRects) { + _mesa_free(pdp->pClipRects); + pdp->pClipRects = NULL; + } + if (pdp->pBackClipRects) { + _mesa_free(pdp->pBackClipRects); + pdp->pBackClipRects = NULL; + } + _mesa_free(pdp); + } +} + +static void +driDestroyDrawable(__DRIdrawable *pdp) +{ + dri_put_drawable(pdp); +} + +/*@}*/ + + +/*****************************************************************/ +/** \name Context handling functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Destroy the per-context private information. + * + * \internal + * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls + * drmDestroyContext(), and finally frees \p contextPrivate. + */ +static void +driDestroyContext(__DRIcontext *pcp) +{ + if (pcp) { + (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp); + _mesa_free(pcp); + } +} + + +/** + * Create the per-drawable private driver information. + * + * \param render_type Type of rendering target. \c GLX_RGBA is the only + * type likely to ever be supported for direct-rendering. + * \param shared Context with which to share textures, etc. or NULL + * + * \returns An opaque pointer to the per-context private information on + * success, or \c NULL on failure. + * + * \internal + * This function allocates and fills a __DRIcontextPrivateRec structure. It + * performs some device independent initialization and passes all the + * relevent information to __DriverAPIRec::CreateContext to create the + * context. + * + */ +static __DRIcontext * +driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, + int render_type, __DRIcontext *shared, + drm_context_t hwContext, void *data) +{ + __DRIcontext *pcp; + void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL; + + pcp = _mesa_malloc(sizeof *pcp); + if (!pcp) + return NULL; + + pcp->driScreenPriv = psp; + pcp->driDrawablePriv = NULL; + + /* When the first context is created for a screen, initialize a "dummy" + * context. + */ + + if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) { + psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context; + psp->dummyContextPriv.driScreenPriv = psp; + psp->dummyContextPriv.driDrawablePriv = NULL; + psp->dummyContextPriv.driverPrivate = NULL; + /* No other fields should be used! */ + } + + pcp->hHWContext = hwContext; + + if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) { + _mesa_free(pcp); + return NULL; + } + + return pcp; +} + + +static __DRIcontext * +dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config, + __DRIcontext *shared, void *data) +{ + return driCreateNewContext(screen, config, 0, shared, 0, data); +} + + +static int +driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask) +{ + return GL_FALSE; +} + +/*@}*/ + + +/*****************************************************************/ +/** \name Screen handling functions */ +/*****************************************************************/ +/*@{*/ + +/** + * Destroy the per-screen private information. + * + * \internal + * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls + * drmClose(), and finally frees \p screenPrivate. + */ +static void driDestroyScreen(__DRIscreen *psp) +{ + if (psp) { + /* No interaction with the X-server is possible at this point. This + * routine is called after XCloseDisplay, so there is no protocol + * stream open to the X-server anymore. + */ + + if (psp->DriverAPI.DestroyScreen) + (*psp->DriverAPI.DestroyScreen)(psp); + + if (!psp->dri2.enabled) { + (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX); + (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize); + (void)drmCloseOnce(psp->fd); + } + + _mesa_free(psp); + } +} + +static void +setupLoaderExtensions(__DRIscreen *psp, + const __DRIextension **extensions) +{ + int i; + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0) + psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0) + psp->damage = (__DRIdamageExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0) + psp->systemTime = (__DRIsystemTimeExtension *) extensions[i]; + if (strcmp(extensions[i]->name, __DRI_DRI2_LOADER) == 0) + psp->dri2.loader = (__DRIdri2LoaderExtension *) extensions[i]; + } +} + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * For legacy DRI. + * + * \param scrn Index of the screen + * \param ddx_version Version of the 2D DDX. This may not be meaningful for + * all drivers. + * \param dri_version Version of the "server-side" DRI. + * \param drm_version Version of the kernel DRM. + * \param frame_buffer Data describing the location and layout of the + * framebuffer. + * \param pSAREA Pointer the the SAREA. + * \param fd Device handle for the DRM. + * \param extensions ?? + * \param driver_modes Returns modes suppoted by the driver + * \param loaderPrivate ?? + * + * \note There is no need to check the minimum API version in this + * function. Since the name of this function is versioned, it is + * impossible for a loader that is too old to even load this driver. + */ +static __DRIscreen * +driCreateNewScreen(int scrn, + const __DRIversion *ddx_version, + const __DRIversion *dri_version, + const __DRIversion *drm_version, + const __DRIframebuffer *frame_buffer, + drmAddress pSAREA, int fd, + const __DRIextension **extensions, + const __DRIconfig ***driver_modes, + void *loaderPrivate) +{ + static const __DRIextension *emptyExtensionList[] = { NULL }; + __DRIscreen *psp; + + psp = _mesa_calloc(sizeof *psp); + if (!psp) + return NULL; + + setupLoaderExtensions(psp, extensions); + + /* + ** NOT_DONE: This is used by the X server to detect when the client + ** has died while holding the drawable lock. The client sets the + ** drawable lock to this value. + */ + psp->drawLockID = 1; + + psp->drm_version = *drm_version; + psp->ddx_version = *ddx_version; + psp->dri_version = *dri_version; + + psp->pSAREA = pSAREA; + psp->lock = (drmLock *) &psp->pSAREA->lock; + + psp->pFB = frame_buffer->base; + psp->fbSize = frame_buffer->size; + psp->fbStride = frame_buffer->stride; + psp->fbWidth = frame_buffer->width; + psp->fbHeight = frame_buffer->height; + psp->devPrivSize = frame_buffer->dev_priv_size; + psp->pDevPriv = frame_buffer->dev_priv; + psp->fbBPP = psp->fbStride * 8 / frame_buffer->width; + + psp->extensions = emptyExtensionList; + psp->fd = fd; + psp->myNum = scrn; + psp->dri2.enabled = GL_FALSE; + + /* + ** Do not init dummy context here; actual initialization will be + ** done when the first DRI context is created. Init screen priv ptr + ** to NULL to let CreateContext routine that it needs to be inited. + */ + psp->dummyContextPriv.driScreenPriv = NULL; + + psp->DriverAPI = driDriverAPI; + + *driver_modes = driDriverAPI.InitScreen(psp); + if (*driver_modes == NULL) { + _mesa_free(psp); + return NULL; + } + + return psp; +} + +/** + * DRI2 + */ +static __DRIscreen * +dri2CreateNewScreen(int scrn, int fd, + const __DRIextension **extensions, + const __DRIconfig ***driver_configs, void *data) +{ + static const __DRIextension *emptyExtensionList[] = { NULL }; + __DRIscreen *psp; + drmVersionPtr version; + + if (driDriverAPI.InitScreen2 == NULL) + return NULL; + + psp = _mesa_calloc(sizeof(*psp)); + if (!psp) + return NULL; + + setupLoaderExtensions(psp, extensions); + + version = drmGetVersion(fd); + if (version) { + psp->drm_version.major = version->version_major; + psp->drm_version.minor = version->version_minor; + psp->drm_version.patch = version->version_patchlevel; + drmFreeVersion(version); + } + + psp->extensions = emptyExtensionList; + psp->fd = fd; + psp->myNum = scrn; + psp->dri2.enabled = GL_TRUE; + + psp->DriverAPI = driDriverAPI; + *driver_configs = driDriverAPI.InitScreen2(psp); + if (*driver_configs == NULL) { + _mesa_free(psp); + return NULL; + } + + psp->DriverAPI = driDriverAPI; + + return psp; +} + +static const __DRIextension **driGetExtensions(__DRIscreen *psp) +{ + return psp->extensions; +} + +/** Core interface */ +const __DRIcoreExtension driCoreExtension = { + { __DRI_CORE, __DRI_CORE_VERSION }, + NULL, + driDestroyScreen, + driGetExtensions, + driGetConfigAttrib, + driIndexConfigAttrib, + NULL, + driDestroyDrawable, + driSwapBuffers, + NULL, + driCopyContext, + driDestroyContext, + driBindContext, + driUnbindContext +}; + +/** Legacy DRI interface */ +const __DRIlegacyExtension driLegacyExtension = { + { __DRI_LEGACY, __DRI_LEGACY_VERSION }, + driCreateNewScreen, + driCreateNewDrawable, + driCreateNewContext, +}; + +/** Legacy DRI interface */ +const __DRIdri2Extension driDRI2Extension = { + { __DRI_DRI2, __DRI_DRI2_VERSION }, + dri2CreateNewScreen, + dri2CreateNewDrawable, + dri2CreateNewContext, +}; + +/* This is the table of extensions that the loader will dlsym() for. */ +PUBLIC const __DRIextension *__driDriverExtensions[] = { + &driCoreExtension.base, + &driLegacyExtension.base, + &driDRI2Extension.base, + NULL +}; + +static int +driFrameTracking(__DRIdrawable *drawable, GLboolean enable) +{ + return GLX_BAD_CONTEXT; +} + +static int +driQueryFrameTracking(__DRIdrawable *dpriv, + int64_t * sbc, int64_t * missedFrames, + float * lastMissedUsage, float * usage) +{ + __DRIswapInfo sInfo; + int status; + int64_t ust; + __DRIscreenPrivate *psp = dpriv->driScreenPriv; + + status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo ); + if ( status == 0 ) { + *sbc = sInfo.swap_count; + *missedFrames = sInfo.swap_missed_count; + *lastMissedUsage = sInfo.swap_missed_usage; + + (*psp->systemTime->getUST)( & ust ); + *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust ); + } + + return status; +} + +const __DRIframeTrackingExtension driFrameTrackingExtension = { + { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION }, + driFrameTracking, + driQueryFrameTracking +}; + +/** + * Calculate amount of swap interval used between GLX buffer swaps. + * + * The usage value, on the range [0,max], is the fraction of total swap + * interval time used between GLX buffer swaps is calculated. + * + * \f$p = t_d / (i * t_r)\f$ + * + * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the + * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time + * required for a single vertical refresh period (as returned by \c + * glXGetMscRateOML). + * + * See the documentation for the GLX_MESA_swap_frame_usage extension for more + * details. + * + * \param dPriv Pointer to the private drawable structure. + * \return If less than a single swap interval time period was required + * between GLX buffer swaps, a number greater than 0 and less than + * 1.0 is returned. If exactly one swap interval time period is + * required, 1.0 is returned, and if more than one is required then + * a number greater than 1.0 will be returned. + * + * \sa glXSwapIntervalSGI glXGetMscRateOML + * + * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it + * be possible to cache the sync rate? + */ +float +driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust, + int64_t current_ust ) +{ + int32_t n; + int32_t d; + int interval; + float usage = 1.0; + __DRIscreenPrivate *psp = dPriv->driScreenPriv; + + if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) { + interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1; + + + /* We want to calculate + * (current_UST - last_swap_UST) / (interval * us_per_refresh). We get + * current_UST by calling __glXGetUST. last_swap_UST is stored in + * dPriv->swap_ust. interval has already been calculated. + * + * The only tricky part is us_per_refresh. us_per_refresh is + * 1000000 / MSC_rate. We know the MSC_rate is n / d. We can flip it + * around and say us_per_refresh = 1000000 * d / n. Since this goes in + * the denominator of the final calculation, we calculate + * (interval * 1000000 * d) and move n into the numerator. + */ + + usage = (current_ust - last_swap_ust); + usage *= n; + usage /= (interval * d); + usage /= 1000000.0; + } + + return usage; +} + +/*@}*/ diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.h b/mesalib/src/mesa/drivers/dri/common/dri_util.h new file mode 100644 index 000000000..c95a5c829 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/dri_util.h @@ -0,0 +1,555 @@ +/* + * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. + * 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, 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 PRECISION INSIGHT AND/OR ITS 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 dri_util.h + * DRI utility functions definitions. + * + * This module acts as glue between GLX and the actual hardware driver. A DRI + * driver doesn't really \e have to use any of this - it's optional. But, some + * useful stuff is done here that otherwise would have to be duplicated in most + * drivers. + * + * Basically, these utility functions take care of some of the dirty details of + * screen initialization, context creation, context binding, DRM setup, etc. + * + * These functions are compiled into each DRI driver so libGL.so knows nothing + * about them. + * + * \sa dri_util.c. + * + * \author Kevin E. Martin <kevin@precisioninsight.com> + * \author Brian Paul <brian@precisioninsight.com> + */ + +#ifndef _DRI_UTIL_H_ +#define _DRI_UTIL_H_ + +#include <GL/gl.h> +#include <drm.h> +#include <drm_sarea.h> +#include <xf86drm.h> +#include "main/glheader.h" +#include "GL/internal/glcore.h" +#include "GL/internal/dri_interface.h" + +#define GLX_BAD_CONTEXT 5 + +typedef struct __DRIswapInfoRec __DRIswapInfo; + +/* Typedefs to avoid rewriting the world. */ +typedef struct __DRIscreenRec __DRIscreenPrivate; +typedef struct __DRIdrawableRec __DRIdrawablePrivate; +typedef struct __DRIcontextRec __DRIcontextPrivate; + +/** + * Extensions. + */ +extern const __DRIlegacyExtension driLegacyExtension; +extern const __DRIcoreExtension driCoreExtension; +extern const __DRIextension driReadDrawableExtension; +extern const __DRIcopySubBufferExtension driCopySubBufferExtension; +extern const __DRIswapControlExtension driSwapControlExtension; +extern const __DRIframeTrackingExtension driFrameTrackingExtension; +extern const __DRImediaStreamCounterExtension driMediaStreamCounterExtension; + +/** + * Used by DRI_VALIDATE_DRAWABLE_INFO + */ +#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(pDrawPriv) \ + do { \ + if (*(pDrawPriv->pStamp) != pDrawPriv->lastStamp) { \ + __driUtilUpdateDrawableInfo(pDrawPriv); \ + } \ + } while (0) + + +/** + * Utility macro to validate the drawable information. + * + * See __DRIdrawable::pStamp and __DRIdrawable::lastStamp. + */ +#define DRI_VALIDATE_DRAWABLE_INFO(psp, pdp) \ +do { \ + while (*(pdp->pStamp) != pdp->lastStamp) { \ + register unsigned int hwContext = psp->pSAREA->lock.lock & \ + ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + DRM_UNLOCK(psp->fd, &psp->pSAREA->lock, hwContext); \ + \ + DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ + DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \ + DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID); \ + \ + DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock, hwContext); \ + } \ +} while (0) + +/** + * Same as above, but for two drawables simultaneously. + * + */ + +#define DRI_VALIDATE_TWO_DRAWABLES_INFO(psp, pdp, prp) \ +do { \ + while (*((pdp)->pStamp) != (pdp)->lastStamp || \ + *((prp)->pStamp) != (prp)->lastStamp) { \ + register unsigned int hwContext = (psp)->pSAREA->lock.lock & \ + ~(DRM_LOCK_HELD | DRM_LOCK_CONT); \ + DRM_UNLOCK((psp)->fd, &(psp)->pSAREA->lock, hwContext); \ + \ + DRM_SPINLOCK(&(psp)->pSAREA->drawable_lock, (psp)->drawLockID); \ + DRI_VALIDATE_DRAWABLE_INFO_ONCE(pdp); \ + DRI_VALIDATE_DRAWABLE_INFO_ONCE(prp); \ + DRM_SPINUNLOCK(&(psp)->pSAREA->drawable_lock, (psp)->drawLockID); \ + \ + DRM_LIGHT_LOCK((psp)->fd, &(psp)->pSAREA->lock, hwContext); \ + } \ +} while (0) + + +/** + * Driver callback functions. + * + * Each DRI driver must have one of these structures with all the pointers set + * to appropriate functions within the driver. + * + * When glXCreateContext() is called, for example, it'll call a helper function + * dri_util.c which in turn will jump through the \a CreateContext pointer in + * this structure. + */ +struct __DriverAPIRec { + const __DRIconfig **(*InitScreen) (__DRIscreen * priv); + + /** + * Screen destruction callback + */ + void (*DestroyScreen)(__DRIscreen *driScrnPriv); + + /** + * Context creation callback + */ + GLboolean (*CreateContext)(const __GLcontextModes *glVis, + __DRIcontext *driContextPriv, + void *sharedContextPrivate); + + /** + * Context destruction callback + */ + void (*DestroyContext)(__DRIcontext *driContextPriv); + + /** + * Buffer (drawable) creation callback + */ + GLboolean (*CreateBuffer)(__DRIscreen *driScrnPriv, + __DRIdrawable *driDrawPriv, + const __GLcontextModes *glVis, + GLboolean pixmapBuffer); + + /** + * Buffer (drawable) destruction callback + */ + void (*DestroyBuffer)(__DRIdrawable *driDrawPriv); + + /** + * Buffer swapping callback + */ + void (*SwapBuffers)(__DRIdrawable *driDrawPriv); + + /** + * Context activation callback + */ + GLboolean (*MakeCurrent)(__DRIcontext *driContextPriv, + __DRIdrawable *driDrawPriv, + __DRIdrawable *driReadPriv); + + /** + * Context unbinding callback + */ + GLboolean (*UnbindContext)(__DRIcontext *driContextPriv); + + /** + * Retrieves statistics about buffer swap operations. Required if + * GLX_OML_sync_control or GLX_MESA_swap_frame_usage is supported. + */ + int (*GetSwapInfo)( __DRIdrawable *dPriv, __DRIswapInfo * sInfo ); + + + /** + * These are required if GLX_OML_sync_control is supported. + */ + /*@{*/ + int (*WaitForMSC)( __DRIdrawable *priv, int64_t target_msc, + int64_t divisor, int64_t remainder, + int64_t * msc ); + int (*WaitForSBC)( __DRIdrawable *priv, int64_t target_sbc, + int64_t * msc, int64_t * sbc ); + + int64_t (*SwapBuffersMSC)( __DRIdrawable *priv, int64_t target_msc, + int64_t divisor, int64_t remainder ); + /*@}*/ + void (*CopySubBuffer)(__DRIdrawable *driDrawPriv, + int x, int y, int w, int h); + + /** + * New version of GetMSC so we can pass drawable data to the low + * level DRM driver (e.g. pipe info). Required if + * GLX_SGI_video_sync or GLX_OML_sync_control is supported. + */ + int (*GetDrawableMSC) ( __DRIscreen * priv, + __DRIdrawable *drawablePrivate, + int64_t *count); + + + + /* DRI2 Entry point */ + const __DRIconfig **(*InitScreen2) (__DRIscreen * priv); +}; + +extern const struct __DriverAPIRec driDriverAPI; + + +struct __DRIswapInfoRec { + /** + * Number of swapBuffers operations that have been *completed*. + */ + uint64_t swap_count; + + /** + * Unadjusted system time of the last buffer swap. This is the time + * when the swap completed, not the time when swapBuffers was called. + */ + int64_t swap_ust; + + /** + * Number of swap operations that occurred after the swap deadline. That + * is if a swap happens more than swap_interval frames after the previous + * swap, it has missed its deadline. If swap_interval is 0, then the + * swap deadline is 1 frame after the previous swap. + */ + uint64_t swap_missed_count; + + /** + * Amount of time used by the last swap that missed its deadline. This + * is calculated as (__glXGetUST() - swap_ust) / (swap_interval * + * time_for_single_vrefresh)). If the actual value of swap_interval is + * 0, then 1 is used instead. If swap_missed_count is non-zero, this + * should be greater-than 1.0. + */ + float swap_missed_usage; +}; + + +/** + * Per-drawable private DRI driver information. + */ +struct __DRIdrawableRec { + /** + * Kernel drawable handle + */ + drm_drawable_t hHWDrawable; + + /** + * Driver's private drawable information. + * + * This structure is opaque. + */ + void *driverPrivate; + + /** + * Private data from the loader. We just hold on to it and pass + * it back when calling into loader provided functions. + */ + void *loaderPrivate; + + /** + * Reference count for number of context's currently bound to this + * drawable. + * + * Once it reaches zero, the drawable can be destroyed. + * + * \note This behavior will change with GLX 1.3. + */ + int refcount; + + /** + * Index of this drawable information in the SAREA. + */ + unsigned int index; + + /** + * Pointer to the "drawable has changed ID" stamp in the SAREA. + */ + unsigned int *pStamp; + + /** + * Last value of the stamp. + * + * If this differs from the value stored at __DRIdrawable::pStamp, + * then the drawable information has been modified by the X server, and the + * drawable information (below) should be retrieved from the X server. + */ + unsigned int lastStamp; + + /** + * \name Drawable + * + * Drawable information used in software fallbacks. + */ + /*@{*/ + int x; + int y; + int w; + int h; + int numClipRects; + drm_clip_rect_t *pClipRects; + /*@}*/ + + /** + * \name Back and depthbuffer + * + * Information about the back and depthbuffer where different from above. + */ + /*@{*/ + int backX; + int backY; + int backClipRectType; + int numBackClipRects; + drm_clip_rect_t *pBackClipRects; + /*@}*/ + + /** + * \name Vertical blank tracking information + * Used for waiting on vertical blank events. + */ + /*@{*/ + unsigned int vblSeq; + unsigned int vblFlags; + /*@}*/ + + /** + * \name Monotonic MSC tracking + * + * Low level driver is responsible for updating msc_base and + * vblSeq values so that higher level code can calculate + * a new msc value or msc target for a WaitMSC call. The new value + * will be: + * msc = msc_base + get_vblank_count() - vblank_base; + * + * And for waiting on a value, core code will use: + * actual_target = target_msc - msc_base + vblank_base; + */ + /*@{*/ + int64_t vblank_base; + int64_t msc_base; + /*@}*/ + + /** + * Pointer to context to which this drawable is currently bound. + */ + __DRIcontext *driContextPriv; + + /** + * Pointer to screen on which this drawable was created. + */ + __DRIscreen *driScreenPriv; + + /** + * Controls swap interval as used by GLX_SGI_swap_control and + * GLX_MESA_swap_control. + */ + unsigned int swap_interval; +}; + +/** + * Per-context private driver information. + */ +struct __DRIcontextRec { + /** + * Kernel context handle used to access the device lock. + */ + drm_context_t hHWContext; + + /** + * Device driver's private context data. This structure is opaque. + */ + void *driverPrivate; + + /** + * Pointer back to the \c __DRIcontext that contains this structure. + */ + __DRIcontext *pctx; + + /** + * Pointer to drawable currently bound to this context for drawing. + */ + __DRIdrawable *driDrawablePriv; + + /** + * Pointer to drawable currently bound to this context for reading. + */ + __DRIdrawable *driReadablePriv; + + /** + * Pointer to screen on which this context was created. + */ + __DRIscreen *driScreenPriv; +}; + +/** + * Per-screen private driver information. + */ +struct __DRIscreenRec { + /** + * Current screen's number + */ + int myNum; + + /** + * Callback functions into the hardware-specific DRI driver code. + */ + struct __DriverAPIRec DriverAPI; + + const __DRIextension **extensions; + /** + * DDX / 2D driver version information. + */ + __DRIversion ddx_version; + + /** + * DRI X extension version information. + */ + __DRIversion dri_version; + + /** + * DRM (kernel module) version information. + */ + __DRIversion drm_version; + + /** + * ID used when the client sets the drawable lock. + * + * The X server uses this value to detect if the client has died while + * holding the drawable lock. + */ + int drawLockID; + + /** + * File descriptor returned when the kernel device driver is opened. + * + * Used to: + * - authenticate client to kernel + * - map the frame buffer, SAREA, etc. + * - close the kernel device driver + */ + int fd; + + /** + * SAREA pointer + * + * Used to access: + * - the device lock + * - the device-independent per-drawable and per-context(?) information + */ + drm_sarea_t *pSAREA; + + /** + * \name Direct frame buffer access information + * Used for software fallbacks. + */ + /*@{*/ + unsigned char *pFB; + int fbSize; + int fbOrigin; + int fbStride; + int fbWidth; + int fbHeight; + int fbBPP; + /*@}*/ + + /** + * \name Device-dependent private information (stored in the SAREA). + * + * This data is accessed by the client driver only. + */ + /*@{*/ + void *pDevPriv; + int devPrivSize; + /*@}*/ + + /** + * Dummy context to which drawables are bound when not bound to any + * other context. + * + * A dummy hHWContext is created for this context, and is used by the GL + * core when a hardware lock is required but the drawable is not currently + * bound (e.g., potentially during a SwapBuffers request). The dummy + * context is created when the first "real" context is created on this + * screen. + */ + __DRIcontext dummyContextPriv; + + /** + * Device-dependent private information (not stored in the SAREA). + * + * This pointer is never touched by the DRI layer. + */ + void *private; + + /** + * Pointer back to the \c __DRIscreen that contains this structure. + */ + __DRIscreen *psc; + + /* Extensions provided by the loader. */ + const __DRIgetDrawableInfoExtension *getDrawableInfo; + const __DRIsystemTimeExtension *systemTime; + const __DRIdamageExtension *damage; + + struct { + /* Flag to indicate that this is a DRI2 screen. Many of the above + * fields will not be valid or initializaed in that case. */ + int enabled; + __DRIdri2LoaderExtension *loader; + } dri2; + + /* The lock actually in use, old sarea or DRI2 */ + drmLock *lock; +}; + +extern void +__driUtilMessage(const char *f, ...); + + +extern void +__driUtilUpdateDrawableInfo(__DRIdrawable *pdp); + +extern float +driCalculateSwapUsage( __DRIdrawable *dPriv, + int64_t last_swap_ust, int64_t current_ust ); + +extern GLint +driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ); + +#endif /* _DRI_UTIL_H_ */ diff --git a/mesalib/src/mesa/drivers/dri/common/drirenderbuffer.c b/mesalib/src/mesa/drivers/dri/common/drirenderbuffer.c new file mode 100644 index 000000000..15af99136 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/drirenderbuffer.c @@ -0,0 +1,217 @@ + +#include "main/mtypes.h" +#include "main/framebuffer.h" +#include "main/renderbuffer.h" +#include "main/imports.h" +#include "drirenderbuffer.h" + + +/** + * This will get called when a window (gl_framebuffer) is resized (probably + * via driUpdateFramebufferSize(), below). + * Just update width, height and internal format fields for now. + * There's usually no memory allocation above because the present + * DRI drivers use statically-allocated full-screen buffers. If that's not + * the case for a DRI driver, a different AllocStorage method should + * be used. + */ +static GLboolean +driRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + return GL_TRUE; +} + + +static void +driDeleteRenderbuffer(struct gl_renderbuffer *rb) +{ + /* don't free rb->Data Chances are it's a memory mapped region for + * the dri drivers. + */ + _mesa_free(rb); +} + + +/** + * Allocate a new driRenderbuffer object. + * Individual drivers are free to implement different versions of + * this function. + * + * At this time, this function can only be used for window-system + * renderbuffers, not user-created RBOs. + * + * \param format Either GL_RGBA, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, + * GL_DEPTH_COMPONENT32, or GL_STENCIL_INDEX8_EXT (for now). + * \param addr address in main memory of the buffer. Probably a memory + * mapped region. + * \param cpp chars or bytes per pixel + * \param offset start of renderbuffer with respect to start of framebuffer + * \param pitch pixels per row + */ +driRenderbuffer * +driNewRenderbuffer(GLenum format, GLvoid *addr, + GLint cpp, GLint offset, GLint pitch, + __DRIdrawablePrivate *dPriv) +{ + driRenderbuffer *drb; + + assert(format == GL_RGBA || + format == GL_RGB5 || + format == GL_RGBA8 || + format == GL_DEPTH_COMPONENT16 || + format == GL_DEPTH_COMPONENT24 || + format == GL_DEPTH_COMPONENT32 || + format == GL_STENCIL_INDEX8_EXT); + + assert(cpp > 0); + assert(pitch > 0); + + drb = _mesa_calloc(sizeof(driRenderbuffer)); + if (drb) { + const GLuint name = 0; + + _mesa_init_renderbuffer(&drb->Base, name); + + /* Make sure we're using a null-valued GetPointer routine */ + assert(drb->Base.GetPointer(NULL, &drb->Base, 0, 0) == NULL); + + drb->Base.InternalFormat = format; + + if (format == GL_RGBA || format == GL_RGB5 || format == GL_RGBA8) { + /* Color */ + drb->Base._BaseFormat = GL_RGBA; + drb->Base.DataType = GL_UNSIGNED_BYTE; + if (format == GL_RGB5) { + drb->Base.RedBits = 5; + drb->Base.GreenBits = 6; + drb->Base.BlueBits = 5; + } + else { + drb->Base.RedBits = + drb->Base.GreenBits = + drb->Base.BlueBits = + drb->Base.AlphaBits = 8; + } + } + else if (format == GL_DEPTH_COMPONENT16) { + /* Depth */ + drb->Base._BaseFormat = GL_DEPTH_COMPONENT; + /* we always Get/Put 32-bit Z values */ + drb->Base.DataType = GL_UNSIGNED_INT; + drb->Base.DepthBits = 16; + } + else if (format == GL_DEPTH_COMPONENT24) { + /* Depth */ + drb->Base._BaseFormat = GL_DEPTH_COMPONENT; + /* we always Get/Put 32-bit Z values */ + drb->Base.DataType = GL_UNSIGNED_INT; + drb->Base.DepthBits = 24; + } + else if (format == GL_DEPTH_COMPONENT32) { + /* Depth */ + drb->Base._BaseFormat = GL_DEPTH_COMPONENT; + /* we always Get/Put 32-bit Z values */ + drb->Base.DataType = GL_UNSIGNED_INT; + drb->Base.DepthBits = 32; + } + else { + /* Stencil */ + ASSERT(format == GL_STENCIL_INDEX8_EXT); + drb->Base._BaseFormat = GL_STENCIL_INDEX; + drb->Base.DataType = GL_UNSIGNED_BYTE; + drb->Base.StencilBits = 8; + } + + /* XXX if we were allocating a user-created renderbuffer, we'd have + * to fill in the Red/Green/Blue/.../Bits values too. + */ + + drb->Base.AllocStorage = driRenderbufferStorage; + drb->Base.Delete = driDeleteRenderbuffer; + + drb->Base.Data = addr; + + /* DRI renderbuffer-specific fields: */ + drb->dPriv = dPriv; + drb->offset = offset; + drb->pitch = pitch; + drb->cpp = cpp; + + /* may be changed if page flipping is active: */ + drb->flippedOffset = offset; + drb->flippedPitch = pitch; + drb->flippedData = addr; + } + return drb; +} + + +/** + * Update the front and back renderbuffers' flippedPitch/Offset/Data fields. + * If stereo, flip both the left and right pairs. + * This is used when we do double buffering via page flipping. + * \param fb the framebuffer we're page flipping + * \param flipped if true, set flipped values, else set non-flipped values + */ +void +driFlipRenderbuffers(struct gl_framebuffer *fb, GLboolean flipped) +{ + const GLuint count = fb->Visual.stereoMode ? 2 : 1; + GLuint lr; /* left or right */ + + /* we shouldn't really call this function if single-buffered, but + * play it safe. + */ + if (!fb->Visual.doubleBufferMode) + return; + + for (lr = 0; lr < count; lr++) { + GLuint frontBuf = (lr == 0) ? BUFFER_FRONT_LEFT : BUFFER_FRONT_RIGHT; + GLuint backBuf = (lr == 0) ? BUFFER_BACK_LEFT : BUFFER_BACK_RIGHT; + driRenderbuffer *front_drb + = (driRenderbuffer *) fb->Attachment[frontBuf].Renderbuffer; + driRenderbuffer *back_drb + = (driRenderbuffer *) fb->Attachment[backBuf].Renderbuffer; + + if (flipped) { + front_drb->flippedOffset = back_drb->offset; + front_drb->flippedPitch = back_drb->pitch; + front_drb->flippedData = back_drb->Base.Data; + back_drb->flippedOffset = front_drb->offset; + back_drb->flippedPitch = front_drb->pitch; + back_drb->flippedData = front_drb->Base.Data; + } + else { + front_drb->flippedOffset = front_drb->offset; + front_drb->flippedPitch = front_drb->pitch; + front_drb->flippedData = front_drb->Base.Data; + back_drb->flippedOffset = back_drb->offset; + back_drb->flippedPitch = back_drb->pitch; + back_drb->flippedData = back_drb->Base.Data; + } + } +} + + +/** + * Check that the gl_framebuffer associated with dPriv is the right size. + * Resize the gl_framebuffer if needed. + * It's expected that the dPriv->driverPrivate member points to a + * gl_framebuffer object. + */ +void +driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv) +{ + struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate; + if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) { + ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h); + /* if the driver needs the hw lock for ResizeBuffers, the drawable + might have changed again by now */ + assert(fb->Width == dPriv->w); + assert(fb->Height == dPriv->h); + } +} diff --git a/mesalib/src/mesa/drivers/dri/common/drirenderbuffer.h b/mesalib/src/mesa/drivers/dri/common/drirenderbuffer.h new file mode 100644 index 000000000..cf55286b3 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/drirenderbuffer.h @@ -0,0 +1,78 @@ + +/** + * A driRenderbuffer is dervied from gl_renderbuffer. + * It describes a color buffer (front or back), a depth buffer, or stencil + * buffer etc. + * Specific to DRI drivers are the offset and pitch fields. + */ + + +#ifndef DRIRENDERBUFFER_H +#define DRIRENDERBUFFER_H + +#include "main/mtypes.h" +#include "dri_util.h" + + +typedef struct { + struct gl_renderbuffer Base; + + /* Chars or bytes per pixel. If Z and Stencil are stored together this + * will typically be 32 whether this a depth or stencil renderbuffer. + */ + GLint cpp; + + /* Buffer position and pitch (row stride). Recall that for today's DRI + * drivers, we have statically allocated color/depth/stencil buffers. + * So this information describes the whole screen, not just a window. + * To address pixels in a window, we need to know the window's position + * and size with respect to the screen. + */ + GLint offset; /* in bytes */ + GLint pitch; /* in pixels */ + + /* If the driver can do page flipping (full-screen double buffering) + * the current front/back buffers may get swapped. + * If page flipping is disabled, these fields will be identical to + * the offset/pitch/Data above. + * If page flipping is enabled, and this is the front(back) renderbuffer, + * flippedOffset/Pitch/Data will have the back(front) renderbuffer's values. + */ + GLint flippedOffset; + GLint flippedPitch; + GLvoid *flippedData; /* mmap'd address of buffer memory, if used */ + + /* Pointer to corresponding __DRIdrawablePrivate. This is used to compute + * the window's position within the framebuffer. + */ + __DRIdrawablePrivate *dPriv; + + /* XXX this is for radeon/r200 only. We should really create a new + * r200Renderbuffer class, derived from this class... not a huge deal. + */ + GLboolean depthHasSurface; + + /** + * A handy flag to know if this is the back color buffer. + * + * \note + * This is currently only used by s3v and tdfx. + */ + GLboolean backBuffer; +} driRenderbuffer; + + +extern driRenderbuffer * +driNewRenderbuffer(GLenum format, GLvoid *addr, + GLint cpp, GLint offset, GLint pitch, + __DRIdrawablePrivate *dPriv); + +extern void +driFlipRenderbuffers(struct gl_framebuffer *fb, GLboolean flipped); + + +extern void +driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv); + + +#endif /* DRIRENDERBUFFER_H */ diff --git a/mesalib/src/mesa/drivers/dri/common/extension_helper.h b/mesalib/src/mesa/drivers/dri/common/extension_helper.h new file mode 100644 index 000000000..40a030ce0 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/extension_helper.h @@ -0,0 +1,6609 @@ +/* DO NOT EDIT - This file generated automatically by extension_helper.py (from Mesa) script */ + +/* + * (C) Copyright IBM Corporation 2005 + * 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, 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 + * 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. + */ + +#include "utils.h" +#include "glapi/dispatch.h" + +#ifndef NULL +# define NULL 0 +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char UniformMatrix3fvARB_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix3fv\0" + "glUniformMatrix3fvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_multisample) +static const char SampleCoverageARB_names[] = + "fi\0" /* Parameter signature */ + "glSampleCoverage\0" + "glSampleCoverageARB\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char ConvolutionFilter1D_names[] = + "iiiiip\0" /* Parameter signature */ + "glConvolutionFilter1D\0" + "glConvolutionFilter1DEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char BeginQueryARB_names[] = + "ii\0" /* Parameter signature */ + "glBeginQuery\0" + "glBeginQueryARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_NV_point_sprite) +static const char PointParameteriNV_names[] = + "ii\0" /* Parameter signature */ + "glPointParameteri\0" + "glPointParameteriNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char GetProgramiv_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramiv\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3sARB_names[] = + "iiii\0" /* Parameter signature */ + "glMultiTexCoord3s\0" + "glMultiTexCoord3sARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3iEXT_names[] = + "iii\0" /* Parameter signature */ + "glSecondaryColor3i\0" + "glSecondaryColor3iEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3fMESA_names[] = + "fff\0" /* Parameter signature */ + "glWindowPos3f\0" + "glWindowPos3fARB\0" + "glWindowPos3fMESA\0" + ""; +#endif + +#if defined(need_GL_SGIS_pixel_texture) +static const char PixelTexGenParameterfvSGIS_names[] = + "ip\0" /* Parameter signature */ + "glPixelTexGenParameterfvSGIS\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char ActiveTextureARB_names[] = + "i\0" /* Parameter signature */ + "glActiveTexture\0" + "glActiveTextureARB\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_blit) +static const char BlitFramebufferEXT_names[] = + "iiiiiiiiii\0" /* Parameter signature */ + "glBlitFramebuffer\0" + "glBlitFramebufferEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4ubvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4ubvNV\0" + ""; +#endif + +#if defined(need_GL_NV_fragment_program) +static const char GetProgramNamedParameterdvNV_names[] = + "iipp\0" /* Parameter signature */ + "glGetProgramNamedParameterdvNV\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char Histogram_names[] = + "iiii\0" /* Parameter signature */ + "glHistogram\0" + "glHistogramEXT\0" + ""; +#endif + +#if defined(need_GL_SGIS_texture4D) +static const char TexImage4DSGIS_names[] = + "iiiiiiiiiip\0" /* Parameter signature */ + "glTexImage4DSGIS\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2dvMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos2dv\0" + "glWindowPos2dvARB\0" + "glWindowPos2dvMESA\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiColor3fVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glReplacementCodeuiColor3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_EXT_blend_equation_separate) || defined(need_GL_ATI_blend_equation_separate) +static const char BlendEquationSeparateEXT_names[] = + "ii\0" /* Parameter signature */ + "glBlendEquationSeparate\0" + "glBlendEquationSeparateEXT\0" + "glBlendEquationSeparateATI\0" + ""; +#endif + +#if defined(need_GL_SGIX_list_priority) +static const char ListParameterfSGIX_names[] = + "iif\0" /* Parameter signature */ + "glListParameterfSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3bEXT_names[] = + "iii\0" /* Parameter signature */ + "glSecondaryColor3b\0" + "glSecondaryColor3bEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord4fColor4fNormal3fVertex4fvSUN_names[] = + "pppp\0" /* Parameter signature */ + "glTexCoord4fColor4fNormal3fVertex4fvSUN\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4svNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4svNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char GetBufferSubDataARB_names[] = + "iiip\0" /* Parameter signature */ + "glGetBufferSubData\0" + "glGetBufferSubDataARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char BufferSubDataARB_names[] = + "iiip\0" /* Parameter signature */ + "glBufferSubData\0" + "glBufferSubDataARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fColor4ubVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glTexCoord2fColor4ubVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char AttachShader_names[] = + "ii\0" /* Parameter signature */ + "glAttachShader\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib2fARB_names[] = + "iff\0" /* Parameter signature */ + "glVertexAttrib2f\0" + "glVertexAttrib2fARB\0" + ""; +#endif + +#if defined(need_GL_MESA_shader_debug) +static const char GetDebugLogLengthMESA_names[] = + "iii\0" /* Parameter signature */ + "glGetDebugLogLengthMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib3fARB_names[] = + "ifff\0" /* Parameter signature */ + "glVertexAttrib3f\0" + "glVertexAttrib3fARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char GetQueryivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetQueryiv\0" + "glGetQueryivARB\0" + ""; +#endif + +#if defined(need_GL_EXT_texture3D) +static const char TexImage3D_names[] = + "iiiiiiiiip\0" /* Parameter signature */ + "glTexImage3D\0" + "glTexImage3DEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiVertex3fvSUN_names[] = + "pp\0" /* Parameter signature */ + "glReplacementCodeuiVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char GetQueryObjectivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetQueryObjectiv\0" + "glGetQueryObjectivARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiTexCoord2fVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glReplacementCodeuiTexCoord2fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression) +static const char CompressedTexSubImage2DARB_names[] = + "iiiiiiiip\0" /* Parameter signature */ + "glCompressedTexSubImage2D\0" + "glCompressedTexSubImage2DARB\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char CombinerOutputNV_names[] = + "iiiiiiiiii\0" /* Parameter signature */ + "glCombinerOutputNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform2fARB_names[] = + "iff\0" /* Parameter signature */ + "glUniform2f\0" + "glUniform2fARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib1svARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib1sv\0" + "glVertexAttrib1svARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs1dvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs1dvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform2ivARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform2iv\0" + "glUniform2ivARB\0" + ""; +#endif + +#if defined(need_GL_HP_image_transform) +static const char GetImageTransformParameterfvHP_names[] = + "iip\0" /* Parameter signature */ + "glGetImageTransformParameterfvHP\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightubvARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightubvARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib1fvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib1fvNV\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char CopyConvolutionFilter1D_names[] = + "iiiii\0" /* Parameter signature */ + "glCopyConvolutionFilter1D\0" + "glCopyConvolutionFilter1DEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiNormal3fVertex3fSUN_names[] = + "iffffff\0" /* Parameter signature */ + "glReplacementCodeuiNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_sync) +static const char DeleteSync_names[] = + "i\0" /* Parameter signature */ + "glDeleteSync\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentMaterialfvSGIX_names[] = + "iip\0" /* Parameter signature */ + "glFragmentMaterialfvSGIX\0" + ""; +#endif + +#if defined(need_GL_EXT_blend_color) +static const char BlendColor_names[] = + "ffff\0" /* Parameter signature */ + "glBlendColor\0" + "glBlendColorEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char UniformMatrix4fvARB_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix4fv\0" + "glUniformMatrix4fvARB\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object) +static const char DeleteVertexArraysAPPLE_names[] = + "ip\0" /* Parameter signature */ + "glDeleteVertexArrays\0" + "glDeleteVertexArraysAPPLE\0" + ""; +#endif + +#if defined(need_GL_SGIX_instruments) +static const char ReadInstrumentsSGIX_names[] = + "i\0" /* Parameter signature */ + "glReadInstrumentsSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_1) +static const char UniformMatrix2x4fv_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix2x4fv\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color4ubVertex3fvSUN_names[] = + "pp\0" /* Parameter signature */ + "glColor4ubVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_texture_array) +static const char FramebufferTextureLayerEXT_names[] = + "iiiii\0" /* Parameter signature */ + "glFramebufferTextureLayer\0" + "glFramebufferTextureLayerEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_list_priority) +static const char GetListParameterfvSGIX_names[] = + "iip\0" /* Parameter signature */ + "glGetListParameterfvSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4NusvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4Nusv\0" + "glVertexAttrib4NusvARB\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4svMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos4svMESA\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char CreateProgramObjectARB_names[] = + "\0" /* Parameter signature */ + "glCreateProgramObjectARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightModelivSGIX_names[] = + "ip\0" /* Parameter signature */ + "glFragmentLightModelivSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_1) +static const char UniformMatrix4x3fv_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix4x3fv\0" + ""; +#endif + +#if defined(need_GL_EXT_texture_object) +static const char PrioritizeTextures_names[] = + "ipp\0" /* Parameter signature */ + "glPrioritizeTextures\0" + "glPrioritizeTexturesEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_async) +static const char AsyncMarkerSGIX_names[] = + "i\0" /* Parameter signature */ + "glAsyncMarkerSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactorubSUN_names[] = + "i\0" /* Parameter signature */ + "glGlobalAlphaFactorubSUN\0" + ""; +#endif + +#if defined(need_GL_MESA_shader_debug) +static const char ClearDebugLogMESA_names[] = + "iii\0" /* Parameter signature */ + "glClearDebugLogMESA\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char ResetHistogram_names[] = + "i\0" /* Parameter signature */ + "glResetHistogram\0" + "glResetHistogramEXT\0" + ""; +#endif + +#if defined(need_GL_NV_fragment_program) +static const char GetProgramNamedParameterfvNV_names[] = + "iipp\0" /* Parameter signature */ + "glGetProgramNamedParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_point_parameters) || defined(need_GL_EXT_point_parameters) || defined(need_GL_SGIS_point_parameters) +static const char PointParameterfEXT_names[] = + "if\0" /* Parameter signature */ + "glPointParameterf\0" + "glPointParameterfARB\0" + "glPointParameterfEXT\0" + "glPointParameterfSGIS\0" + ""; +#endif + +#if defined(need_GL_SGIX_polynomial_ffd) +static const char LoadIdentityDeformationMapSGIX_names[] = + "i\0" /* Parameter signature */ + "glLoadIdentityDeformationMapSGIX\0" + ""; +#endif + +#if defined(need_GL_NV_fence) +static const char GenFencesNV_names[] = + "ip\0" /* Parameter signature */ + "glGenFencesNV\0" + ""; +#endif + +#if defined(need_GL_HP_image_transform) +static const char ImageTransformParameterfHP_names[] = + "iif\0" /* Parameter signature */ + "glImageTransformParameterfHP\0" + ""; +#endif + +#if defined(need_GL_ARB_matrix_palette) +static const char MatrixIndexusvARB_names[] = + "ip\0" /* Parameter signature */ + "glMatrixIndexusvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char DisableVertexAttribArrayARB_names[] = + "i\0" /* Parameter signature */ + "glDisableVertexAttribArray\0" + "glDisableVertexAttribArrayARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char StencilMaskSeparate_names[] = + "ii\0" /* Parameter signature */ + "glStencilMaskSeparate\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char ProgramLocalParameter4dARB_names[] = + "iidddd\0" /* Parameter signature */ + "glProgramLocalParameter4dARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression) +static const char CompressedTexImage3DARB_names[] = + "iiiiiiiip\0" /* Parameter signature */ + "glCompressedTexImage3D\0" + "glCompressedTexImage3DARB\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char GetConvolutionParameteriv_names[] = + "iip\0" /* Parameter signature */ + "glGetConvolutionParameteriv\0" + "glGetConvolutionParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib1fARB_names[] = + "if\0" /* Parameter signature */ + "glVertexAttrib1f\0" + "glVertexAttrib1fARB\0" + ""; +#endif + +#if defined(need_GL_NV_fence) +static const char TestFenceNV_names[] = + "i\0" /* Parameter signature */ + "glTestFenceNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1fvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord1fv\0" + "glMultiTexCoord1fvARB\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char ColorFragmentOp2ATI_names[] = + "iiiiiiiiii\0" /* Parameter signature */ + "glColorFragmentOp2ATI\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char SecondaryColorPointerListIBM_names[] = + "iiipi\0" /* Parameter signature */ + "glSecondaryColorPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_SGIS_pixel_texture) +static const char GetPixelTexGenParameterivSGIS_names[] = + "ip\0" /* Parameter signature */ + "glGetPixelTexGenParameterivSGIS\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4fNV_names[] = + "iffff\0" /* Parameter signature */ + "glVertexAttrib4fNV\0" + ""; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const char ReplacementCodeubSUN_names[] = + "i\0" /* Parameter signature */ + "glReplacementCodeubSUN\0" + ""; +#endif + +#if defined(need_GL_SGIX_async) +static const char FinishAsyncSGIX_names[] = + "p\0" /* Parameter signature */ + "glFinishAsyncSGIX\0" + ""; +#endif + +#if defined(need_GL_MESA_shader_debug) +static const char GetDebugLogMESA_names[] = + "iiiipp\0" /* Parameter signature */ + "glGetDebugLogMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord) +static const char FogCoorddEXT_names[] = + "d\0" /* Parameter signature */ + "glFogCoordd\0" + "glFogCoorddEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color4ubVertex3fSUN_names[] = + "iiiifff\0" /* Parameter signature */ + "glColor4ubVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord) +static const char FogCoordfEXT_names[] = + "f\0" /* Parameter signature */ + "glFogCoordf\0" + "glFogCoordfEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fVertex3fSUN_names[] = + "fffff\0" /* Parameter signature */ + "glTexCoord2fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactoriSUN_names[] = + "i\0" /* Parameter signature */ + "glGlobalAlphaFactoriSUN\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib2dNV_names[] = + "idd\0" /* Parameter signature */ + "glVertexAttrib2dNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char GetProgramInfoLog_names[] = + "iipp\0" /* Parameter signature */ + "glGetProgramInfoLog\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4NbvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4Nbv\0" + "glVertexAttrib4NbvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader) +static const char GetActiveAttribARB_names[] = + "iiipppp\0" /* Parameter signature */ + "glGetActiveAttrib\0" + "glGetActiveAttribARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4ubNV_names[] = + "iiiii\0" /* Parameter signature */ + "glVertexAttrib4ubNV\0" + ""; +#endif + +#if defined(need_GL_APPLE_texture_range) +static const char TextureRangeAPPLE_names[] = + "iip\0" /* Parameter signature */ + "glTextureRangeAPPLE\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fColor4fNormal3fVertex3fSUN_names[] = + "ffffffffffff\0" /* Parameter signature */ + "glTexCoord2fColor4fNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char CombinerParameterfvNV_names[] = + "ip\0" /* Parameter signature */ + "glCombinerParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs3dvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs3dvNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs4fvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs4fvNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_array_range) +static const char VertexArrayRangeNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexArrayRangeNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightiSGIX_names[] = + "iii\0" /* Parameter signature */ + "glFragmentLightiSGIX\0" + ""; +#endif + +#if defined(need_GL_EXT_polygon_offset) +static const char PolygonOffsetEXT_names[] = + "ff\0" /* Parameter signature */ + "glPolygonOffsetEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_async) +static const char PollAsyncSGIX_names[] = + "p\0" /* Parameter signature */ + "glPollAsyncSGIX\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char DeleteFragmentShaderATI_names[] = + "i\0" /* Parameter signature */ + "glDeleteFragmentShaderATI\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fNormal3fVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glTexCoord2fNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix) +static const char MultTransposeMatrixdARB_names[] = + "p\0" /* Parameter signature */ + "glMultTransposeMatrixd\0" + "glMultTransposeMatrixdARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2svMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos2sv\0" + "glWindowPos2svARB\0" + "glWindowPos2svMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression) +static const char CompressedTexImage1DARB_names[] = + "iiiiiip\0" /* Parameter signature */ + "glCompressedTexImage1D\0" + "glCompressedTexImage1DARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib2sNV_names[] = + "iii\0" /* Parameter signature */ + "glVertexAttrib2sNV\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char NormalPointerListIBM_names[] = + "iipi\0" /* Parameter signature */ + "glNormalPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char IndexPointerEXT_names[] = + "iiip\0" /* Parameter signature */ + "glIndexPointerEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char NormalPointerEXT_names[] = + "iiip\0" /* Parameter signature */ + "glNormalPointerEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3dARB_names[] = + "iddd\0" /* Parameter signature */ + "glMultiTexCoord3d\0" + "glMultiTexCoord3dARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2iARB_names[] = + "iii\0" /* Parameter signature */ + "glMultiTexCoord2i\0" + "glMultiTexCoord2iARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN_names[] = + "iffffffff\0" /* Parameter signature */ + "glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2svARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord2sv\0" + "glMultiTexCoord2svARB\0" + ""; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const char ReplacementCodeubvSUN_names[] = + "p\0" /* Parameter signature */ + "glReplacementCodeubvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform3iARB_names[] = + "iiii\0" /* Parameter signature */ + "glUniform3i\0" + "glUniform3iARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char GetFragmentMaterialfvSGIX_names[] = + "iip\0" /* Parameter signature */ + "glGetFragmentMaterialfvSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char GetShaderInfoLog_names[] = + "iipp\0" /* Parameter signature */ + "glGetShaderInfoLog\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightivARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightivARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_instruments) +static const char PollInstrumentsSGIX_names[] = + "p\0" /* Parameter signature */ + "glPollInstrumentsSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactordSUN_names[] = + "d\0" /* Parameter signature */ + "glGlobalAlphaFactordSUN\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs3fvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs3fvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char GenerateMipmapEXT_names[] = + "i\0" /* Parameter signature */ + "glGenerateMipmap\0" + "glGenerateMipmapEXT\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char SetFragmentShaderConstantATI_names[] = + "ip\0" /* Parameter signature */ + "glSetFragmentShaderConstantATI\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char GetMapAttribParameterivNV_names[] = + "iiip\0" /* Parameter signature */ + "glGetMapAttribParameterivNV\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char CreateShaderObjectARB_names[] = + "i\0" /* Parameter signature */ + "glCreateShaderObjectARB\0" + ""; +#endif + +#if defined(need_GL_SGIS_sharpen_texture) +static const char GetSharpenTexFuncSGIS_names[] = + "ip\0" /* Parameter signature */ + "glGetSharpenTexFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char BufferDataARB_names[] = + "iipi\0" /* Parameter signature */ + "glBufferData\0" + "glBufferDataARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_array_range) +static const char FlushVertexArrayRangeNV_names[] = + "\0" /* Parameter signature */ + "glFlushVertexArrayRangeNV\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char SampleMapATI_names[] = + "iii\0" /* Parameter signature */ + "glSampleMapATI\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char VertexPointerEXT_names[] = + "iiiip\0" /* Parameter signature */ + "glVertexPointerEXT\0" + ""; +#endif + +#if defined(need_GL_SGIS_texture_filter4) +static const char GetTexFilterFuncSGIS_names[] = + "iip\0" /* Parameter signature */ + "glGetTexFilterFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char GetCombinerOutputParameterfvNV_names[] = + "iiip\0" /* Parameter signature */ + "glGetCombinerOutputParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_EXT_subtexture) +static const char TexSubImage1D_names[] = + "iiiiiip\0" /* Parameter signature */ + "glTexSubImage1D\0" + "glTexSubImage1DEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib1sARB_names[] = + "ii\0" /* Parameter signature */ + "glVertexAttrib1s\0" + "glVertexAttrib1sARB\0" + ""; +#endif + +#if defined(need_GL_ARB_sync) +static const char FenceSync_names[] = + "ii\0" /* Parameter signature */ + "glFenceSync\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char FinalCombinerInputNV_names[] = + "iiii\0" /* Parameter signature */ + "glFinalCombinerInputNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_flush_raster) +static const char FlushRasterSGIX_names[] = + "\0" /* Parameter signature */ + "glFlushRasterSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiTexCoord2fVertex3fSUN_names[] = + "ifffff\0" /* Parameter signature */ + "glReplacementCodeuiTexCoord2fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform1fARB_names[] = + "if\0" /* Parameter signature */ + "glUniform1f\0" + "glUniform1fARB\0" + ""; +#endif + +#if defined(need_GL_EXT_texture_object) +static const char AreTexturesResident_names[] = + "ipp\0" /* Parameter signature */ + "glAreTexturesResident\0" + "glAreTexturesResidentEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ATI_separate_stencil) +static const char StencilOpSeparate_names[] = + "iiii\0" /* Parameter signature */ + "glStencilOpSeparate\0" + "glStencilOpSeparateATI\0" + ""; +#endif + +#if defined(need_GL_SGI_color_table) +static const char ColorTableParameteriv_names[] = + "iip\0" /* Parameter signature */ + "glColorTableParameteriv\0" + "glColorTableParameterivSGI\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char FogCoordPointerListIBM_names[] = + "iipi\0" /* Parameter signature */ + "glFogCoordPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3dMESA_names[] = + "ddd\0" /* Parameter signature */ + "glWindowPos3d\0" + "glWindowPos3dARB\0" + "glWindowPos3dMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_point_parameters) || defined(need_GL_EXT_point_parameters) || defined(need_GL_SGIS_point_parameters) +static const char PointParameterfvEXT_names[] = + "ip\0" /* Parameter signature */ + "glPointParameterfv\0" + "glPointParameterfvARB\0" + "glPointParameterfvEXT\0" + "glPointParameterfvSGIS\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2fvMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos2fv\0" + "glWindowPos2fvARB\0" + "glWindowPos2fvMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3bvEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3bv\0" + "glSecondaryColor3bvEXT\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char VertexPointerListIBM_names[] = + "iiipi\0" /* Parameter signature */ + "glVertexPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char GetProgramLocalParameterfvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramLocalParameterfvARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentMaterialfSGIX_names[] = + "iif\0" /* Parameter signature */ + "glFragmentMaterialfSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fNormal3fVertex3fSUN_names[] = + "ffffffff\0" /* Parameter signature */ + "glTexCoord2fNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char RenderbufferStorageEXT_names[] = + "iiii\0" /* Parameter signature */ + "glRenderbufferStorage\0" + "glRenderbufferStorageEXT\0" + ""; +#endif + +#if defined(need_GL_NV_fence) +static const char IsFenceNV_names[] = + "i\0" /* Parameter signature */ + "glIsFenceNV\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char AttachObjectARB_names[] = + "ii\0" /* Parameter signature */ + "glAttachObjectARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char GetFragmentLightivSGIX_names[] = + "iip\0" /* Parameter signature */ + "glGetFragmentLightivSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char UniformMatrix2fvARB_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix2fv\0" + "glUniformMatrix2fvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2fARB_names[] = + "iff\0" /* Parameter signature */ + "glMultiTexCoord2f\0" + "glMultiTexCoord2fARB\0" + ""; +#endif + +#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture) +static const char ColorTable_names[] = + "iiiiip\0" /* Parameter signature */ + "glColorTable\0" + "glColorTableSGI\0" + "glColorTableEXT\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char MapControlPointsNV_names[] = + "iiiiiiiip\0" /* Parameter signature */ + "glMapControlPointsNV\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char ConvolutionFilter2D_names[] = + "iiiiiip\0" /* Parameter signature */ + "glConvolutionFilter2D\0" + "glConvolutionFilter2DEXT\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char MapParameterfvNV_names[] = + "iip\0" /* Parameter signature */ + "glMapParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib3dvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib3dv\0" + "glVertexAttrib3dvARB\0" + ""; +#endif + +#if defined(need_GL_PGI_misc_hints) +static const char HintPGI_names[] = + "ii\0" /* Parameter signature */ + "glHintPGI\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char ConvolutionParameteriv_names[] = + "iip\0" /* Parameter signature */ + "glConvolutionParameteriv\0" + "glConvolutionParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_cull_vertex) +static const char CullParameterdvEXT_names[] = + "ip\0" /* Parameter signature */ + "glCullParameterdvEXT\0" + ""; +#endif + +#if defined(need_GL_NV_fragment_program) +static const char ProgramNamedParameter4fNV_names[] = + "iipffff\0" /* Parameter signature */ + "glProgramNamedParameter4fNV\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color3fVertex3fSUN_names[] = + "ffffff\0" /* Parameter signature */ + "glColor3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char ProgramEnvParameter4fvARB_names[] = + "iip\0" /* Parameter signature */ + "glProgramEnvParameter4fvARB\0" + "glProgramParameter4fvNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightModeliSGIX_names[] = + "ii\0" /* Parameter signature */ + "glFragmentLightModeliSGIX\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char ConvolutionParameterfv_names[] = + "iip\0" /* Parameter signature */ + "glConvolutionParameterfv\0" + "glConvolutionParameterfvEXT\0" + ""; +#endif + +#if defined(need_GL_3DFX_tbuffer) +static const char TbufferMask3DFX_names[] = + "i\0" /* Parameter signature */ + "glTbufferMask3DFX\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char LoadProgramNV_names[] = + "iiip\0" /* Parameter signature */ + "glLoadProgramNV\0" + ""; +#endif + +#if defined(need_GL_ARB_sync) +static const char WaitSync_names[] = + "iii\0" /* Parameter signature */ + "glWaitSync\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4fvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4fvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char GetAttachedObjectsARB_names[] = + "iipp\0" /* Parameter signature */ + "glGetAttachedObjectsARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform3fvARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform3fv\0" + "glUniform3fvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_draw_range_elements) +static const char DrawRangeElements_names[] = + "iiiiip\0" /* Parameter signature */ + "glDrawRangeElements\0" + "glDrawRangeElementsEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_sprite) +static const char SpriteParameterfvSGIX_names[] = + "ip\0" /* Parameter signature */ + "glSpriteParameterfvSGIX\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char CheckFramebufferStatusEXT_names[] = + "i\0" /* Parameter signature */ + "glCheckFramebufferStatus\0" + "glCheckFramebufferStatusEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactoruiSUN_names[] = + "i\0" /* Parameter signature */ + "glGlobalAlphaFactoruiSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char GetHandleARB_names[] = + "i\0" /* Parameter signature */ + "glGetHandleARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char GetVertexAttribivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetVertexAttribiv\0" + "glGetVertexAttribivARB\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char GetCombinerInputParameterfvNV_names[] = + "iiiip\0" /* Parameter signature */ + "glGetCombinerInputParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char CreateProgram_names[] = + "\0" /* Parameter signature */ + "glCreateProgram\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix) +static const char LoadTransposeMatrixdARB_names[] = + "p\0" /* Parameter signature */ + "glLoadTransposeMatrixd\0" + "glLoadTransposeMatrixdARB\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char GetMinmax_names[] = + "iiiip\0" /* Parameter signature */ + "glGetMinmax\0" + "glGetMinmaxEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char StencilFuncSeparate_names[] = + "iiii\0" /* Parameter signature */ + "glStencilFuncSeparate\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3sEXT_names[] = + "iii\0" /* Parameter signature */ + "glSecondaryColor3s\0" + "glSecondaryColor3sEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color3fVertex3fvSUN_names[] = + "pp\0" /* Parameter signature */ + "glColor3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactorbSUN_names[] = + "i\0" /* Parameter signature */ + "glGlobalAlphaFactorbSUN\0" + ""; +#endif + +#if defined(need_GL_HP_image_transform) +static const char ImageTransformParameterfvHP_names[] = + "iip\0" /* Parameter signature */ + "glImageTransformParameterfvHP\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4ivARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4iv\0" + "glVertexAttrib4ivARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib3fNV_names[] = + "ifff\0" /* Parameter signature */ + "glVertexAttrib3fNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs2dvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs2dvNV\0" + ""; +#endif + +#if defined(need_GL_EXT_timer_query) +static const char GetQueryObjectui64vEXT_names[] = + "iip\0" /* Parameter signature */ + "glGetQueryObjectui64vEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3fvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord3fv\0" + "glMultiTexCoord3fvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3dEXT_names[] = + "ddd\0" /* Parameter signature */ + "glSecondaryColor3d\0" + "glSecondaryColor3dEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetProgramParameterfvNV_names[] = + "iiip\0" /* Parameter signature */ + "glGetProgramParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char TangentPointerEXT_names[] = + "iip\0" /* Parameter signature */ + "glTangentPointerEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color4fNormal3fVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glColor4fNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_SGIX_instruments) +static const char GetInstrumentsSGIX_names[] = + "\0" /* Parameter signature */ + "glGetInstrumentsSGIX\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char EvalMapsNV_names[] = + "ii\0" /* Parameter signature */ + "glEvalMapsNV\0" + ""; +#endif + +#if defined(need_GL_EXT_subtexture) +static const char TexSubImage2D_names[] = + "iiiiiiiip\0" /* Parameter signature */ + "glTexSubImage2D\0" + "glTexSubImage2DEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightivSGIX_names[] = + "iip\0" /* Parameter signature */ + "glFragmentLightivSGIX\0" + ""; +#endif + +#if defined(need_GL_APPLE_texture_range) +static const char GetTexParameterPointervAPPLE_names[] = + "iip\0" /* Parameter signature */ + "glGetTexParameterPointervAPPLE\0" + ""; +#endif + +#if defined(need_GL_EXT_pixel_transform) +static const char PixelTransformParameterfvEXT_names[] = + "iip\0" /* Parameter signature */ + "glPixelTransformParameterfvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4bvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4bv\0" + "glVertexAttrib4bvARB\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char AlphaFragmentOp2ATI_names[] = + "iiiiiiiii\0" /* Parameter signature */ + "glAlphaFragmentOp2ATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4sARB_names[] = + "iiiii\0" /* Parameter signature */ + "glMultiTexCoord4s\0" + "glMultiTexCoord4sARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char GetFragmentMaterialivSGIX_names[] = + "iip\0" /* Parameter signature */ + "glGetFragmentMaterialivSGIX\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4dMESA_names[] = + "dddd\0" /* Parameter signature */ + "glWindowPos4dMESA\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightPointerARB_names[] = + "iiip\0" /* Parameter signature */ + "glWeightPointerARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2dMESA_names[] = + "dd\0" /* Parameter signature */ + "glWindowPos2d\0" + "glWindowPos2dARB\0" + "glWindowPos2dMESA\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char FramebufferTexture3DEXT_names[] = + "iiiiii\0" /* Parameter signature */ + "glFramebufferTexture3D\0" + "glFramebufferTexture3DEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_blend_minmax) +static const char BlendEquation_names[] = + "i\0" /* Parameter signature */ + "glBlendEquation\0" + "glBlendEquationEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib3dNV_names[] = + "iddd\0" /* Parameter signature */ + "glVertexAttrib3dNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib3dARB_names[] = + "iddd\0" /* Parameter signature */ + "glVertexAttrib3d\0" + "glVertexAttrib3dARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_names[] = + "ppppp\0" /* Parameter signature */ + "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4fARB_names[] = + "iffff\0" /* Parameter signature */ + "glVertexAttrib4f\0" + "glVertexAttrib4fARB\0" + ""; +#endif + +#if defined(need_GL_EXT_index_func) +static const char IndexFuncEXT_names[] = + "if\0" /* Parameter signature */ + "glIndexFuncEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char FramebufferTexture2DEXT_names[] = + "iiiii\0" /* Parameter signature */ + "glFramebufferTexture2D\0" + "glFramebufferTexture2DEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2dvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord2dv\0" + "glMultiTexCoord2dvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_cull_vertex) +static const char CullParameterfvEXT_names[] = + "ip\0" /* Parameter signature */ + "glCullParameterfvEXT\0" + ""; +#endif + +#if defined(need_GL_NV_fragment_program) +static const char ProgramNamedParameter4fvNV_names[] = + "iipp\0" /* Parameter signature */ + "glProgramNamedParameter4fvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColorPointerEXT_names[] = + "iiip\0" /* Parameter signature */ + "glSecondaryColorPointer\0" + "glSecondaryColorPointerEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4fvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4fv\0" + "glVertexAttrib4fvARB\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char ColorPointerListIBM_names[] = + "iiipi\0" /* Parameter signature */ + "glColorPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char GetActiveUniformARB_names[] = + "iiipppp\0" /* Parameter signature */ + "glGetActiveUniform\0" + "glGetActiveUniformARB\0" + ""; +#endif + +#if defined(need_GL_HP_image_transform) +static const char ImageTransformParameteriHP_names[] = + "iii\0" /* Parameter signature */ + "glImageTransformParameteriHP\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1svARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord1sv\0" + "glMultiTexCoord1svARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char EndQueryARB_names[] = + "i\0" /* Parameter signature */ + "glEndQuery\0" + "glEndQueryARB\0" + ""; +#endif + +#if defined(need_GL_NV_fence) +static const char DeleteFencesNV_names[] = + "ip\0" /* Parameter signature */ + "glDeleteFencesNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_polynomial_ffd) +static const char DeformationMap3dSGIX_names[] = + "iddiiddiiddiip\0" /* Parameter signature */ + "glDeformationMap3dSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char IsShader_names[] = + "i\0" /* Parameter signature */ + "glIsShader\0" + ""; +#endif + +#if defined(need_GL_HP_image_transform) +static const char GetImageTransformParameterivHP_names[] = + "iip\0" /* Parameter signature */ + "glGetImageTransformParameterivHP\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4ivMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos4ivMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3svARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord3sv\0" + "glMultiTexCoord3svARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4iARB_names[] = + "iiiii\0" /* Parameter signature */ + "glMultiTexCoord4i\0" + "glMultiTexCoord4iARB\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3ivEXT_names[] = + "p\0" /* Parameter signature */ + "glBinormal3ivEXT\0" + ""; +#endif + +#if defined(need_GL_MESA_resize_buffers) +static const char ResizeBuffersMESA_names[] = + "\0" /* Parameter signature */ + "glResizeBuffersMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char GetUniformivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetUniformiv\0" + "glGetUniformivARB\0" + ""; +#endif + +#if defined(need_GL_SGIS_pixel_texture) +static const char PixelTexGenParameteriSGIS_names[] = + "ii\0" /* Parameter signature */ + "glPixelTexGenParameteriSGIS\0" + ""; +#endif + +#if defined(need_GL_INTEL_parallel_arrays) +static const char VertexPointervINTEL_names[] = + "iip\0" /* Parameter signature */ + "glVertexPointervINTEL\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiColor4fNormal3fVertex3fvSUN_names[] = + "pppp\0" /* Parameter signature */ + "glReplacementCodeuiColor4fNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3uiEXT_names[] = + "iii\0" /* Parameter signature */ + "glSecondaryColor3ui\0" + "glSecondaryColor3uiEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_instruments) +static const char StartInstrumentsSGIX_names[] = + "\0" /* Parameter signature */ + "glStartInstrumentsSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3usvEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3usv\0" + "glSecondaryColor3usvEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib2fvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib2fvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char ProgramLocalParameter4dvARB_names[] = + "iip\0" /* Parameter signature */ + "glProgramLocalParameter4dvARB\0" + ""; +#endif + +#if defined(need_GL_ARB_matrix_palette) +static const char MatrixIndexuivARB_names[] = + "ip\0" /* Parameter signature */ + "glMatrixIndexuivARB\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) +static const char RenderbufferStorageMultisample_names[] = + "iiiii\0" /* Parameter signature */ + "glRenderbufferStorageMultisample\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3sEXT_names[] = + "iii\0" /* Parameter signature */ + "glTangent3sEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactorfSUN_names[] = + "f\0" /* Parameter signature */ + "glGlobalAlphaFactorfSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3iARB_names[] = + "iiii\0" /* Parameter signature */ + "glMultiTexCoord3i\0" + "glMultiTexCoord3iARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char IsProgram_names[] = + "i\0" /* Parameter signature */ + "glIsProgram\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char TexCoordPointerListIBM_names[] = + "iiipi\0" /* Parameter signature */ + "glTexCoordPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactorusSUN_names[] = + "i\0" /* Parameter signature */ + "glGlobalAlphaFactorusSUN\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib2dvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib2dvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char FramebufferRenderbufferEXT_names[] = + "iiii\0" /* Parameter signature */ + "glFramebufferRenderbuffer\0" + "glFramebufferRenderbufferEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib1dvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib1dvNV\0" + ""; +#endif + +#if defined(need_GL_EXT_texture_object) +static const char GenTextures_names[] = + "ip\0" /* Parameter signature */ + "glGenTextures\0" + "glGenTexturesEXT\0" + ""; +#endif + +#if defined(need_GL_NV_fence) +static const char SetFenceNV_names[] = + "ii\0" /* Parameter signature */ + "glSetFenceNV\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char FramebufferTexture1DEXT_names[] = + "iiiii\0" /* Parameter signature */ + "glFramebufferTexture1D\0" + "glFramebufferTexture1DEXT\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char GetCombinerOutputParameterivNV_names[] = + "iiip\0" /* Parameter signature */ + "glGetCombinerOutputParameterivNV\0" + ""; +#endif + +#if defined(need_GL_SGIS_pixel_texture) +static const char PixelTexGenParameterivSGIS_names[] = + "ip\0" /* Parameter signature */ + "glPixelTexGenParameterivSGIS\0" + ""; +#endif + +#if defined(need_GL_EXT_texture_perturb_normal) +static const char TextureNormalEXT_names[] = + "i\0" /* Parameter signature */ + "glTextureNormalEXT\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char IndexPointerListIBM_names[] = + "iipi\0" /* Parameter signature */ + "glIndexPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightfvARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightfvARB\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4fMESA_names[] = + "ffff\0" /* Parameter signature */ + "glWindowPos4fMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3dvMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos3dv\0" + "glWindowPos3dvARB\0" + "glWindowPos3dvMESA\0" + ""; +#endif + +#if defined(need_GL_EXT_timer_query) +static const char GetQueryObjecti64vEXT_names[] = + "iip\0" /* Parameter signature */ + "glGetQueryObjecti64vEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1dARB_names[] = + "id\0" /* Parameter signature */ + "glMultiTexCoord1d\0" + "glMultiTexCoord1dARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_NV_point_sprite) +static const char PointParameterivNV_names[] = + "ip\0" /* Parameter signature */ + "glPointParameteriv\0" + "glPointParameterivNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform2fvARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform2fv\0" + "glUniform2fvARB\0" + ""; +#endif + +#if defined(need_GL_APPLE_flush_buffer_range) +static const char BufferParameteriAPPLE_names[] = + "iii\0" /* Parameter signature */ + "glBufferParameteriAPPLE\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3dvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord3dv\0" + "glMultiTexCoord3dvARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN_names[] = + "pppp\0" /* Parameter signature */ + "glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char DeleteObjectARB_names[] = + "i\0" /* Parameter signature */ + "glDeleteObjectARB\0" + ""; +#endif + +#if defined(need_GL_ARB_matrix_palette) +static const char MatrixIndexPointerARB_names[] = + "iiip\0" /* Parameter signature */ + "glMatrixIndexPointerARB\0" + ""; +#endif + +#if defined(need_GL_NV_fragment_program) +static const char ProgramNamedParameter4dvNV_names[] = + "iipp\0" /* Parameter signature */ + "glProgramNamedParameter4dvNV\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3fvEXT_names[] = + "p\0" /* Parameter signature */ + "glTangent3fvEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_array_object) +static const char GenVertexArrays_names[] = + "ip\0" /* Parameter signature */ + "glGenVertexArrays\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char BindFramebufferEXT_names[] = + "ii\0" /* Parameter signature */ + "glBindFramebuffer\0" + "glBindFramebufferEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_reference_plane) +static const char ReferencePlaneSGIX_names[] = + "p\0" /* Parameter signature */ + "glReferencePlaneSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char ValidateProgramARB_names[] = + "i\0" /* Parameter signature */ + "glValidateProgram\0" + "glValidateProgramARB\0" + ""; +#endif + +#if defined(need_GL_EXT_compiled_vertex_array) +static const char UnlockArraysEXT_names[] = + "\0" /* Parameter signature */ + "glUnlockArraysEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fColor3fVertex3fSUN_names[] = + "ffffffff\0" /* Parameter signature */ + "glTexCoord2fColor3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3fvMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos3fv\0" + "glWindowPos3fvARB\0" + "glWindowPos3fvMESA\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib1svNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib1svNV\0" + ""; +#endif + +#if defined(need_GL_EXT_copy_texture) +static const char CopyTexSubImage3D_names[] = + "iiiiiiiii\0" /* Parameter signature */ + "glCopyTexSubImage3D\0" + "glCopyTexSubImage3DEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib2dARB_names[] = + "idd\0" /* Parameter signature */ + "glVertexAttrib2d\0" + "glVertexAttrib2dARB\0" + ""; +#endif + +#if defined(need_GL_ARB_sync) +static const char GetInteger64v_names[] = + "ip\0" /* Parameter signature */ + "glGetInteger64v\0" + ""; +#endif + +#if defined(need_GL_SGIS_texture_color_mask) +static const char TextureColorMaskSGIS_names[] = + "iiii\0" /* Parameter signature */ + "glTextureColorMaskSGIS\0" + ""; +#endif + +#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture) +static const char GetColorTable_names[] = + "iiip\0" /* Parameter signature */ + "glGetColorTable\0" + "glGetColorTableSGI\0" + "glGetColorTableEXT\0" + ""; +#endif + +#if defined(need_GL_SGI_color_table) +static const char CopyColorTable_names[] = + "iiiii\0" /* Parameter signature */ + "glCopyColorTable\0" + "glCopyColorTableSGI\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char GetHistogramParameterfv_names[] = + "iip\0" /* Parameter signature */ + "glGetHistogramParameterfv\0" + "glGetHistogramParameterfvEXT\0" + ""; +#endif + +#if defined(need_GL_INTEL_parallel_arrays) +static const char ColorPointervINTEL_names[] = + "iip\0" /* Parameter signature */ + "glColorPointervINTEL\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char AlphaFragmentOp1ATI_names[] = + "iiiiii\0" /* Parameter signature */ + "glAlphaFragmentOp1ATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3ivARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord3iv\0" + "glMultiTexCoord3ivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2sARB_names[] = + "iii\0" /* Parameter signature */ + "glMultiTexCoord2s\0" + "glMultiTexCoord2sARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib1dvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib1dv\0" + "glVertexAttrib1dvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_texture_object) +static const char DeleteTextures_names[] = + "ip\0" /* Parameter signature */ + "glDeleteTextures\0" + "glDeleteTexturesEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char TexCoordPointerEXT_names[] = + "iiiip\0" /* Parameter signature */ + "glTexCoordPointerEXT\0" + ""; +#endif + +#if defined(need_GL_SGIS_texture4D) +static const char TexSubImage4DSGIS_names[] = + "iiiiiiiiiiiip\0" /* Parameter signature */ + "glTexSubImage4DSGIS\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners2) +static const char CombinerStageParameterfvNV_names[] = + "iip\0" /* Parameter signature */ + "glCombinerStageParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_instruments) +static const char StopInstrumentsSGIX_names[] = + "i\0" /* Parameter signature */ + "glStopInstrumentsSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord4fColor4fNormal3fVertex4fSUN_names[] = + "fffffffffffffff\0" /* Parameter signature */ + "glTexCoord4fColor4fNormal3fVertex4fSUN\0" + ""; +#endif + +#if defined(need_GL_SGIX_polynomial_ffd) +static const char DeformSGIX_names[] = + "i\0" /* Parameter signature */ + "glDeformSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char GetVertexAttribfvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetVertexAttribfv\0" + "glGetVertexAttribfvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3ivEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3iv\0" + "glSecondaryColor3ivEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_1) +static const char UniformMatrix4x2fv_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix4x2fv\0" + ""; +#endif + +#if defined(need_GL_SGIS_detail_texture) +static const char GetDetailTexFuncSGIS_names[] = + "ip\0" /* Parameter signature */ + "glGetDetailTexFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners2) +static const char GetCombinerStageParameterfvNV_names[] = + "iip\0" /* Parameter signature */ + "glGetCombinerStageParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_array_object) +static const char BindVertexArray_names[] = + "i\0" /* Parameter signature */ + "glBindVertexArray\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color4ubVertex2fvSUN_names[] = + "pp\0" /* Parameter signature */ + "glColor4ubVertex2fvSUN\0" + ""; +#endif + +#if defined(need_GL_SGIS_texture_filter4) +static const char TexFilterFuncSGIS_names[] = + "iiip\0" /* Parameter signature */ + "glTexFilterFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_SGIS_multisample) || defined(need_GL_EXT_multisample) +static const char SampleMaskSGIS_names[] = + "fi\0" /* Parameter signature */ + "glSampleMaskSGIS\0" + "glSampleMaskEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader) +static const char GetAttribLocationARB_names[] = + "ip\0" /* Parameter signature */ + "glGetAttribLocation\0" + "glGetAttribLocationARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4ubvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4ubv\0" + "glVertexAttrib4ubvARB\0" + ""; +#endif + +#if defined(need_GL_SGIS_detail_texture) +static const char DetailTexFuncSGIS_names[] = + "iip\0" /* Parameter signature */ + "glDetailTexFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Normal3fVertex3fSUN_names[] = + "ffffff\0" /* Parameter signature */ + "glNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_EXT_copy_texture) +static const char CopyTexImage2D_names[] = + "iiiiiiii\0" /* Parameter signature */ + "glCopyTexImage2D\0" + "glCopyTexImage2DEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char GetBufferPointervARB_names[] = + "iip\0" /* Parameter signature */ + "glGetBufferPointerv\0" + "glGetBufferPointervARB\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char ProgramEnvParameter4fARB_names[] = + "iiffff\0" /* Parameter signature */ + "glProgramEnvParameter4fARB\0" + "glProgramParameter4fNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform3ivARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform3iv\0" + "glUniform3ivARB\0" + ""; +#endif + +#if defined(need_GL_NV_fence) +static const char GetFenceivNV_names[] = + "iip\0" /* Parameter signature */ + "glGetFenceivNV\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4dvMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos4dvMESA\0" + ""; +#endif + +#if defined(need_GL_EXT_color_subtable) +static const char ColorSubTable_names[] = + "iiiiip\0" /* Parameter signature */ + "glColorSubTable\0" + "glColorSubTableEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4ivARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord4iv\0" + "glMultiTexCoord4ivARB\0" + ""; +#endif + +#if defined(need_GL_EXT_gpu_program_parameters) +static const char ProgramLocalParameters4fvEXT_names[] = + "iiip\0" /* Parameter signature */ + "glProgramLocalParameters4fvEXT\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char GetMapAttribParameterfvNV_names[] = + "iiip\0" /* Parameter signature */ + "glGetMapAttribParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4sARB_names[] = + "iiiii\0" /* Parameter signature */ + "glVertexAttrib4s\0" + "glVertexAttrib4sARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char GetQueryObjectuivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetQueryObjectuiv\0" + "glGetQueryObjectuivARB\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char MapParameterivNV_names[] = + "iip\0" /* Parameter signature */ + "glMapParameterivNV\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char GenRenderbuffersEXT_names[] = + "ip\0" /* Parameter signature */ + "glGenRenderbuffers\0" + "glGenRenderbuffersEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib2dvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib2dv\0" + "glVertexAttrib2dvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char EdgeFlagPointerEXT_names[] = + "iip\0" /* Parameter signature */ + "glEdgeFlagPointerEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs2svNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs2svNV\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightbvARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightbvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib2fvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib2fv\0" + "glVertexAttrib2fvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char GetBufferParameterivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetBufferParameteriv\0" + "glGetBufferParameterivARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_list_priority) +static const char ListParameteriSGIX_names[] = + "iii\0" /* Parameter signature */ + "glListParameteriSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiColor4fNormal3fVertex3fSUN_names[] = + "iffffffffff\0" /* Parameter signature */ + "glReplacementCodeuiColor4fNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_SGIX_instruments) +static const char InstrumentsBufferSGIX_names[] = + "ip\0" /* Parameter signature */ + "glInstrumentsBufferSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4NivARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4Niv\0" + "glVertexAttrib4NivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char GetAttachedShaders_names[] = + "iipp\0" /* Parameter signature */ + "glGetAttachedShaders\0" + ""; +#endif + +#if defined(need_GL_APPLE_vertex_array_object) +static const char GenVertexArraysAPPLE_names[] = + "ip\0" /* Parameter signature */ + "glGenVertexArraysAPPLE\0" + ""; +#endif + +#if defined(need_GL_EXT_gpu_program_parameters) +static const char ProgramEnvParameters4fvEXT_names[] = + "iiip\0" /* Parameter signature */ + "glProgramEnvParameters4fvEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fColor4fNormal3fVertex3fvSUN_names[] = + "pppp\0" /* Parameter signature */ + "glTexCoord2fColor4fNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2iMESA_names[] = + "ii\0" /* Parameter signature */ + "glWindowPos2i\0" + "glWindowPos2iARB\0" + "glWindowPos2iMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3fvEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3fv\0" + "glSecondaryColor3fvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression) +static const char CompressedTexSubImage1DARB_names[] = + "iiiiiip\0" /* Parameter signature */ + "glCompressedTexSubImage1D\0" + "glCompressedTexSubImage1DARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetVertexAttribivNV_names[] = + "iip\0" /* Parameter signature */ + "glGetVertexAttribivNV\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char GetProgramStringARB_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramStringARB\0" + ""; +#endif + +#if defined(need_GL_ATI_envmap_bumpmap) +static const char TexBumpParameterfvATI_names[] = + "ip\0" /* Parameter signature */ + "glTexBumpParameterfvATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char CompileShaderARB_names[] = + "i\0" /* Parameter signature */ + "glCompileShader\0" + "glCompileShaderARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char DeleteShader_names[] = + "i\0" /* Parameter signature */ + "glDeleteShader\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform3fARB_names[] = + "ifff\0" /* Parameter signature */ + "glUniform3f\0" + "glUniform3fARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_list_priority) +static const char ListParameterfvSGIX_names[] = + "iip\0" /* Parameter signature */ + "glListParameterfvSGIX\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3dvEXT_names[] = + "p\0" /* Parameter signature */ + "glTangent3dvEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetVertexAttribfvNV_names[] = + "iip\0" /* Parameter signature */ + "glGetVertexAttribfvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3sMESA_names[] = + "iii\0" /* Parameter signature */ + "glWindowPos3s\0" + "glWindowPos3sARB\0" + "glWindowPos3sMESA\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib2svNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib2svNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs1fvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs1fvNV\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fVertex3fvSUN_names[] = + "pp\0" /* Parameter signature */ + "glTexCoord2fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4sMESA_names[] = + "iiii\0" /* Parameter signature */ + "glWindowPos4sMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4NuivARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4Nuiv\0" + "glVertexAttrib4NuivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char ClientActiveTextureARB_names[] = + "i\0" /* Parameter signature */ + "glClientActiveTexture\0" + "glClientActiveTextureARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_pixel_texture) +static const char PixelTexGenSGIX_names[] = + "i\0" /* Parameter signature */ + "glPixelTexGenSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const char ReplacementCodeusvSUN_names[] = + "p\0" /* Parameter signature */ + "glReplacementCodeusvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform4fARB_names[] = + "iffff\0" /* Parameter signature */ + "glUniform4f\0" + "glUniform4fARB\0" + ""; +#endif + +#if defined(need_GL_ARB_map_buffer_range) +static const char FlushMappedBufferRange_names[] = + "iii\0" /* Parameter signature */ + "glFlushMappedBufferRange\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char IsProgramNV_names[] = + "i\0" /* Parameter signature */ + "glIsProgramARB\0" + "glIsProgramNV\0" + ""; +#endif + +#if defined(need_GL_APPLE_flush_buffer_range) +static const char FlushMappedBufferRangeAPPLE_names[] = + "iii\0" /* Parameter signature */ + "glFlushMappedBufferRangeAPPLE\0" + ""; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const char ReplacementCodePointerSUN_names[] = + "iip\0" /* Parameter signature */ + "glReplacementCodePointerSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char ProgramEnvParameter4dARB_names[] = + "iidddd\0" /* Parameter signature */ + "glProgramEnvParameter4dARB\0" + "glProgramParameter4dNV\0" + ""; +#endif + +#if defined(need_GL_SGI_color_table) +static const char ColorTableParameterfv_names[] = + "iip\0" /* Parameter signature */ + "glColorTableParameterfv\0" + "glColorTableParameterfvSGI\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightModelfSGIX_names[] = + "if\0" /* Parameter signature */ + "glFragmentLightModelfSGIX\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3bvEXT_names[] = + "p\0" /* Parameter signature */ + "glBinormal3bvEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_texture_object) +static const char IsTexture_names[] = + "i\0" /* Parameter signature */ + "glIsTexture\0" + "glIsTextureEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_weighting) +static const char VertexWeightfvEXT_names[] = + "p\0" /* Parameter signature */ + "glVertexWeightfvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib1dARB_names[] = + "id\0" /* Parameter signature */ + "glVertexAttrib1d\0" + "glVertexAttrib1dARB\0" + ""; +#endif + +#if defined(need_GL_HP_image_transform) +static const char ImageTransformParameterivHP_names[] = + "iip\0" /* Parameter signature */ + "glImageTransformParameterivHP\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char DeleteQueriesARB_names[] = + "ip\0" /* Parameter signature */ + "glDeleteQueries\0" + "glDeleteQueriesARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color4ubVertex2fSUN_names[] = + "iiiiff\0" /* Parameter signature */ + "glColor4ubVertex2fSUN\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentColorMaterialSGIX_names[] = + "ii\0" /* Parameter signature */ + "glFragmentColorMaterialSGIX\0" + ""; +#endif + +#if defined(need_GL_ARB_matrix_palette) +static const char CurrentPaletteMatrixARB_names[] = + "i\0" /* Parameter signature */ + "glCurrentPaletteMatrixARB\0" + ""; +#endif + +#if defined(need_GL_SGIS_multisample) || defined(need_GL_EXT_multisample) +static const char SamplePatternSGIS_names[] = + "i\0" /* Parameter signature */ + "glSamplePatternSGIS\0" + "glSamplePatternEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char IsQueryARB_names[] = + "i\0" /* Parameter signature */ + "glIsQuery\0" + "glIsQueryARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiColor4ubVertex3fSUN_names[] = + "iiiiifff\0" /* Parameter signature */ + "glReplacementCodeuiColor4ubVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4usvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4usv\0" + "glVertexAttrib4usvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char LinkProgramARB_names[] = + "i\0" /* Parameter signature */ + "glLinkProgram\0" + "glLinkProgramARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib2fNV_names[] = + "iff\0" /* Parameter signature */ + "glVertexAttrib2fNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char ShaderSourceARB_names[] = + "iipp\0" /* Parameter signature */ + "glShaderSource\0" + "glShaderSourceARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentMaterialiSGIX_names[] = + "iii\0" /* Parameter signature */ + "glFragmentMaterialiSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib3svARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib3sv\0" + "glVertexAttrib3svARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression) +static const char CompressedTexSubImage3DARB_names[] = + "iiiiiiiiiip\0" /* Parameter signature */ + "glCompressedTexSubImage3D\0" + "glCompressedTexSubImage3DARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2ivMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos2iv\0" + "glWindowPos2ivARB\0" + "glWindowPos2ivMESA\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char IsFramebufferEXT_names[] = + "i\0" /* Parameter signature */ + "glIsFramebuffer\0" + "glIsFramebufferEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform4ivARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform4iv\0" + "glUniform4ivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char GetVertexAttribdvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetVertexAttribdv\0" + "glGetVertexAttribdvARB\0" + ""; +#endif + +#if defined(need_GL_ATI_envmap_bumpmap) +static const char TexBumpParameterivATI_names[] = + "ip\0" /* Parameter signature */ + "glTexBumpParameterivATI\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char GetSeparableFilter_names[] = + "iiippp\0" /* Parameter signature */ + "glGetSeparableFilter\0" + "glGetSeparableFilterEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3dEXT_names[] = + "ddd\0" /* Parameter signature */ + "glBinormal3dEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_sprite) +static const char SpriteParameteriSGIX_names[] = + "ii\0" /* Parameter signature */ + "glSpriteParameteriSGIX\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char RequestResidentProgramsNV_names[] = + "ip\0" /* Parameter signature */ + "glRequestResidentProgramsNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_tag_sample_buffer) +static const char TagSampleBufferSGIX_names[] = + "\0" /* Parameter signature */ + "glTagSampleBufferSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const char ReplacementCodeusSUN_names[] = + "i\0" /* Parameter signature */ + "glReplacementCodeusSUN\0" + ""; +#endif + +#if defined(need_GL_SGIX_list_priority) +static const char ListParameterivSGIX_names[] = + "iip\0" /* Parameter signature */ + "glListParameterivSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_multi_draw_arrays) +static const char MultiDrawElementsEXT_names[] = + "ipipi\0" /* Parameter signature */ + "glMultiDrawElements\0" + "glMultiDrawElementsEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform1ivARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform1iv\0" + "glUniform1ivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2sMESA_names[] = + "ii\0" /* Parameter signature */ + "glWindowPos2s\0" + "glWindowPos2sARB\0" + "glWindowPos2sMESA\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightusvARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightusvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord) +static const char FogCoordPointerEXT_names[] = + "iip\0" /* Parameter signature */ + "glFogCoordPointer\0" + "glFogCoordPointerEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_index_material) +static const char IndexMaterialEXT_names[] = + "ii\0" /* Parameter signature */ + "glIndexMaterialEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3ubvEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3ubv\0" + "glSecondaryColor3ubvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4dvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4dv\0" + "glVertexAttrib4dvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader) +static const char BindAttribLocationARB_names[] = + "iip\0" /* Parameter signature */ + "glBindAttribLocation\0" + "glBindAttribLocationARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2dARB_names[] = + "idd\0" /* Parameter signature */ + "glMultiTexCoord2d\0" + "glMultiTexCoord2dARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char ExecuteProgramNV_names[] = + "iip\0" /* Parameter signature */ + "glExecuteProgramNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char LightEnviSGIX_names[] = + "ii\0" /* Parameter signature */ + "glLightEnviSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const char ReplacementCodeuiSUN_names[] = + "i\0" /* Parameter signature */ + "glReplacementCodeuiSUN\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribPointerNV_names[] = + "iiiip\0" /* Parameter signature */ + "glVertexAttribPointerNV\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char GetFramebufferAttachmentParameterivEXT_names[] = + "iiip\0" /* Parameter signature */ + "glGetFramebufferAttachmentParameteriv\0" + "glGetFramebufferAttachmentParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_pixel_transform) +static const char PixelTransformParameterfEXT_names[] = + "iif\0" /* Parameter signature */ + "glPixelTransformParameterfEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4dvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord4dv\0" + "glMultiTexCoord4dvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_pixel_transform) +static const char PixelTransformParameteriEXT_names[] = + "iii\0" /* Parameter signature */ + "glPixelTransformParameteriEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fColor4ubVertex3fSUN_names[] = + "ffiiiifff\0" /* Parameter signature */ + "glTexCoord2fColor4ubVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform1iARB_names[] = + "ii\0" /* Parameter signature */ + "glUniform1i\0" + "glUniform1iARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttribPointerARB_names[] = + "iiiiip\0" /* Parameter signature */ + "glVertexAttribPointer\0" + "glVertexAttribPointerARB\0" + ""; +#endif + +#if defined(need_GL_SGIS_sharpen_texture) +static const char SharpenTexFuncSGIS_names[] = + "iip\0" /* Parameter signature */ + "glSharpenTexFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4fvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord4fv\0" + "glMultiTexCoord4fvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_1) +static const char UniformMatrix2x3fv_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix2x3fv\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char TrackMatrixNV_names[] = + "iiii\0" /* Parameter signature */ + "glTrackMatrixNV\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char CombinerParameteriNV_names[] = + "ii\0" /* Parameter signature */ + "glCombinerParameteriNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_async) +static const char DeleteAsyncMarkersSGIX_names[] = + "ii\0" /* Parameter signature */ + "glDeleteAsyncMarkersSGIX\0" + ""; +#endif + +#if defined(need_GL_SGIX_async) +static const char IsAsyncMarkerSGIX_names[] = + "i\0" /* Parameter signature */ + "glIsAsyncMarkerSGIX\0" + ""; +#endif + +#if defined(need_GL_SGIX_framezoom) +static const char FrameZoomSGIX_names[] = + "i\0" /* Parameter signature */ + "glFrameZoomSGIX\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Normal3fVertex3fvSUN_names[] = + "pp\0" /* Parameter signature */ + "glNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4NsvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4Nsv\0" + "glVertexAttrib4NsvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib3fvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib3fv\0" + "glVertexAttrib3fvARB\0" + ""; +#endif + +#if defined(need_GL_ARB_sync) +static const char GetSynciv_names[] = + "iiipp\0" /* Parameter signature */ + "glGetSynciv\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char DeleteFramebuffersEXT_names[] = + "ip\0" /* Parameter signature */ + "glDeleteFramebuffers\0" + "glDeleteFramebuffersEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const char GlobalAlphaFactorsSUN_names[] = + "i\0" /* Parameter signature */ + "glGlobalAlphaFactorsSUN\0" + ""; +#endif + +#if defined(need_GL_EXT_texture3D) +static const char TexSubImage3D_names[] = + "iiiiiiiiiip\0" /* Parameter signature */ + "glTexSubImage3D\0" + "glTexSubImage3DEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3fEXT_names[] = + "fff\0" /* Parameter signature */ + "glTangent3fEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3uivEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3uiv\0" + "glSecondaryColor3uivEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_matrix_palette) +static const char MatrixIndexubvARB_names[] = + "ip\0" /* Parameter signature */ + "glMatrixIndexubvARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char Color4fNormal3fVertex3fSUN_names[] = + "ffffffffff\0" /* Parameter signature */ + "glColor4fNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_SGIS_pixel_texture) +static const char PixelTexGenParameterfSGIS_names[] = + "if\0" /* Parameter signature */ + "glPixelTexGenParameterfSGIS\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char CreateShader_names[] = + "i\0" /* Parameter signature */ + "glCreateShader\0" + ""; +#endif + +#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture) +static const char GetColorTableParameterfv_names[] = + "iip\0" /* Parameter signature */ + "glGetColorTableParameterfv\0" + "glGetColorTableParameterfvSGI\0" + "glGetColorTableParameterfvEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightModelfvSGIX_names[] = + "ip\0" /* Parameter signature */ + "glFragmentLightModelfvSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord3fARB_names[] = + "ifff\0" /* Parameter signature */ + "glMultiTexCoord3f\0" + "glMultiTexCoord3fARB\0" + ""; +#endif + +#if defined(need_GL_SGIS_pixel_texture) +static const char GetPixelTexGenParameterfvSGIS_names[] = + "ip\0" /* Parameter signature */ + "glGetPixelTexGenParameterfvSGIS\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char GenFramebuffersEXT_names[] = + "ip\0" /* Parameter signature */ + "glGenFramebuffers\0" + "glGenFramebuffersEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetProgramParameterdvNV_names[] = + "iiip\0" /* Parameter signature */ + "glGetProgramParameterdvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object) +static const char IsVertexArrayAPPLE_names[] = + "i\0" /* Parameter signature */ + "glIsVertexArray\0" + "glIsVertexArrayAPPLE\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightfvSGIX_names[] = + "iip\0" /* Parameter signature */ + "glFragmentLightfvSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char DetachShader_names[] = + "ii\0" /* Parameter signature */ + "glDetachShader\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4NubARB_names[] = + "iiiii\0" /* Parameter signature */ + "glVertexAttrib4Nub\0" + "glVertexAttrib4NubARB\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char GetProgramEnvParameterfvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramEnvParameterfvARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetTrackMatrixivNV_names[] = + "iiip\0" /* Parameter signature */ + "glGetTrackMatrixivNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib3svNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib3svNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform4fvARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform4fv\0" + "glUniform4fvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix) +static const char MultTransposeMatrixfARB_names[] = + "p\0" /* Parameter signature */ + "glMultTransposeMatrixf\0" + "glMultTransposeMatrixfARB\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char ColorFragmentOp1ATI_names[] = + "iiiiiii\0" /* Parameter signature */ + "glColorFragmentOp1ATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char GetUniformfvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetUniformfv\0" + "glGetUniformfvARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN_names[] = + "iffffffffffff\0" /* Parameter signature */ + "glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char DetachObjectARB_names[] = + "ii\0" /* Parameter signature */ + "glDetachObjectARB\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char VertexBlendARB_names[] = + "i\0" /* Parameter signature */ + "glVertexBlendARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3iMESA_names[] = + "iii\0" /* Parameter signature */ + "glWindowPos3i\0" + "glWindowPos3iARB\0" + "glWindowPos3iMESA\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char SeparableFilter2D_names[] = + "iiiiiipp\0" /* Parameter signature */ + "glSeparableFilter2D\0" + "glSeparableFilter2DEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiColor4ubVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glReplacementCodeuiColor4ubVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression) +static const char CompressedTexImage2DARB_names[] = + "iiiiiiip\0" /* Parameter signature */ + "glCompressedTexImage2D\0" + "glCompressedTexImage2DARB\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char ArrayElement_names[] = + "i\0" /* Parameter signature */ + "glArrayElement\0" + "glArrayElementEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_depth_bounds_test) +static const char DepthBoundsEXT_names[] = + "dd\0" /* Parameter signature */ + "glDepthBoundsEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char ProgramParameters4fvNV_names[] = + "iiip\0" /* Parameter signature */ + "glProgramParameters4fvNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_polynomial_ffd) +static const char DeformationMap3fSGIX_names[] = + "iffiiffiiffiip\0" /* Parameter signature */ + "glDeformationMap3fSGIX\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetProgramivNV_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramivNV\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char GetMinmaxParameteriv_names[] = + "iip\0" /* Parameter signature */ + "glGetMinmaxParameteriv\0" + "glGetMinmaxParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_copy_texture) +static const char CopyTexImage1D_names[] = + "iiiiiii\0" /* Parameter signature */ + "glCopyTexImage1D\0" + "glCopyTexImage1DEXT\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char AlphaFragmentOp3ATI_names[] = + "iiiiiiiiiiii\0" /* Parameter signature */ + "glAlphaFragmentOp3ATI\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetVertexAttribdvNV_names[] = + "iip\0" /* Parameter signature */ + "glGetVertexAttribdvNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib3fvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib3fvNV\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char GetFinalCombinerInputParameterivNV_names[] = + "iip\0" /* Parameter signature */ + "glGetFinalCombinerInputParameterivNV\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char GetMapParameterivNV_names[] = + "iip\0" /* Parameter signature */ + "glGetMapParameterivNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform4iARB_names[] = + "iiiii\0" /* Parameter signature */ + "glUniform4i\0" + "glUniform4iARB\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char ConvolutionParameteri_names[] = + "iii\0" /* Parameter signature */ + "glConvolutionParameteri\0" + "glConvolutionParameteriEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3sEXT_names[] = + "iii\0" /* Parameter signature */ + "glBinormal3sEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char ConvolutionParameterf_names[] = + "iif\0" /* Parameter signature */ + "glConvolutionParameterf\0" + "glConvolutionParameterfEXT\0" + ""; +#endif + +#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture) +static const char GetColorTableParameteriv_names[] = + "iip\0" /* Parameter signature */ + "glGetColorTableParameteriv\0" + "glGetColorTableParameterivSGI\0" + "glGetColorTableParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char ProgramEnvParameter4dvARB_names[] = + "iip\0" /* Parameter signature */ + "glProgramEnvParameter4dvARB\0" + "glProgramParameter4dvNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs2fvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs2fvNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char UseProgramObjectARB_names[] = + "i\0" /* Parameter signature */ + "glUseProgram\0" + "glUseProgramObjectARB\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char GetMapParameterfvNV_names[] = + "iip\0" /* Parameter signature */ + "glGetMapParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char PassTexCoordATI_names[] = + "iii\0" /* Parameter signature */ + "glPassTexCoordATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char DeleteProgram_names[] = + "i\0" /* Parameter signature */ + "glDeleteProgram\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3ivEXT_names[] = + "p\0" /* Parameter signature */ + "glTangent3ivEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3dEXT_names[] = + "ddd\0" /* Parameter signature */ + "glTangent3dEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3dvEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3dv\0" + "glSecondaryColor3dvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_multi_draw_arrays) +static const char MultiDrawArraysEXT_names[] = + "ippi\0" /* Parameter signature */ + "glMultiDrawArrays\0" + "glMultiDrawArraysEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char BindRenderbufferEXT_names[] = + "ii\0" /* Parameter signature */ + "glBindRenderbuffer\0" + "glBindRenderbufferEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4dARB_names[] = + "idddd\0" /* Parameter signature */ + "glMultiTexCoord4d\0" + "glMultiTexCoord4dARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3usEXT_names[] = + "iii\0" /* Parameter signature */ + "glSecondaryColor3us\0" + "glSecondaryColor3usEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char ProgramLocalParameter4fvARB_names[] = + "iip\0" /* Parameter signature */ + "glProgramLocalParameter4fvARB\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char DeleteProgramsNV_names[] = + "ip\0" /* Parameter signature */ + "glDeleteProgramsARB\0" + "glDeleteProgramsNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1sARB_names[] = + "ii\0" /* Parameter signature */ + "glMultiTexCoord1s\0" + "glMultiTexCoord1sARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiColor3fVertex3fSUN_names[] = + "iffffff\0" /* Parameter signature */ + "glReplacementCodeuiColor3fVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char GetVertexAttribPointervNV_names[] = + "iip\0" /* Parameter signature */ + "glGetVertexAttribPointerv\0" + "glGetVertexAttribPointervARB\0" + "glGetVertexAttribPointervNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1dvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord1dv\0" + "glMultiTexCoord1dvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform2iARB_names[] = + "iii\0" /* Parameter signature */ + "glUniform2i\0" + "glUniform2iARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char GetProgramStringNV_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramStringNV\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char ColorPointerEXT_names[] = + "iiiip\0" /* Parameter signature */ + "glColorPointerEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char MapBufferARB_names[] = + "ii\0" /* Parameter signature */ + "glMapBuffer\0" + "glMapBufferARB\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3svEXT_names[] = + "p\0" /* Parameter signature */ + "glBinormal3svEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_light_texture) +static const char ApplyTextureEXT_names[] = + "i\0" /* Parameter signature */ + "glApplyTextureEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_light_texture) +static const char TextureMaterialEXT_names[] = + "ii\0" /* Parameter signature */ + "glTextureMaterialEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_light_texture) +static const char TextureLightEXT_names[] = + "i\0" /* Parameter signature */ + "glTextureLightEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char ResetMinmax_names[] = + "i\0" /* Parameter signature */ + "glResetMinmax\0" + "glResetMinmaxEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_sprite) +static const char SpriteParameterfSGIX_names[] = + "if\0" /* Parameter signature */ + "glSpriteParameterfSGIX\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4sNV_names[] = + "iiiii\0" /* Parameter signature */ + "glVertexAttrib4sNV\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char GetConvolutionParameterfv_names[] = + "iip\0" /* Parameter signature */ + "glGetConvolutionParameterfv\0" + "glGetConvolutionParameterfvEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs4dvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs4dvNV\0" + ""; +#endif + +#if defined(need_GL_IBM_multimode_draw_arrays) +static const char MultiModeDrawArraysIBM_names[] = + "pppii\0" /* Parameter signature */ + "glMultiModeDrawArraysIBM\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4dARB_names[] = + "idddd\0" /* Parameter signature */ + "glVertexAttrib4d\0" + "glVertexAttrib4dARB\0" + ""; +#endif + +#if defined(need_GL_ATI_envmap_bumpmap) +static const char GetTexBumpParameterfvATI_names[] = + "ip\0" /* Parameter signature */ + "glGetTexBumpParameterfvATI\0" + ""; +#endif + +#if defined(need_GL_NV_fragment_program) +static const char ProgramNamedParameter4dNV_names[] = + "iipdddd\0" /* Parameter signature */ + "glProgramNamedParameter4dNV\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_weighting) +static const char VertexWeightfEXT_names[] = + "f\0" /* Parameter signature */ + "glVertexWeightfEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3fEXT_names[] = + "fff\0" /* Parameter signature */ + "glBinormal3fEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord) +static const char FogCoordfvEXT_names[] = + "p\0" /* Parameter signature */ + "glFogCoordfv\0" + "glFogCoordfvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1ivARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord1iv\0" + "glMultiTexCoord1ivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3ubEXT_names[] = + "iii\0" /* Parameter signature */ + "glSecondaryColor3ub\0" + "glSecondaryColor3ubEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2ivARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord2iv\0" + "glMultiTexCoord2ivARB\0" + ""; +#endif + +#if defined(need_GL_SGIS_fog_function) +static const char FogFuncSGIS_names[] = + "ip\0" /* Parameter signature */ + "glFogFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_EXT_copy_texture) +static const char CopyTexSubImage2D_names[] = + "iiiiiiii\0" /* Parameter signature */ + "glCopyTexSubImage2D\0" + "glCopyTexSubImage2DEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char GetObjectParameterivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetObjectParameterivARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord4fVertex4fSUN_names[] = + "ffffffff\0" /* Parameter signature */ + "glTexCoord4fVertex4fSUN\0" + ""; +#endif + +#if defined(need_GL_APPLE_vertex_array_object) +static const char BindVertexArrayAPPLE_names[] = + "i\0" /* Parameter signature */ + "glBindVertexArrayAPPLE\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char GetProgramLocalParameterdvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramLocalParameterdvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char GetHistogramParameteriv_names[] = + "iip\0" /* Parameter signature */ + "glGetHistogramParameteriv\0" + "glGetHistogramParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1iARB_names[] = + "ii\0" /* Parameter signature */ + "glMultiTexCoord1i\0" + "glMultiTexCoord1iARB\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char GetConvolutionFilter_names[] = + "iiip\0" /* Parameter signature */ + "glGetConvolutionFilter\0" + "glGetConvolutionFilterEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char GetProgramivARB_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_blend_func_separate) || defined(need_GL_INGR_blend_func_separate) +static const char BlendFuncSeparateEXT_names[] = + "iiii\0" /* Parameter signature */ + "glBlendFuncSeparate\0" + "glBlendFuncSeparateEXT\0" + "glBlendFuncSeparateINGR\0" + ""; +#endif + +#if defined(need_GL_ARB_map_buffer_range) +static const char MapBufferRange_names[] = + "iiii\0" /* Parameter signature */ + "glMapBufferRange\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char ProgramParameters4dvNV_names[] = + "iiip\0" /* Parameter signature */ + "glProgramParameters4dvNV\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord2fColor3fVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glTexCoord2fColor3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3dvEXT_names[] = + "p\0" /* Parameter signature */ + "glBinormal3dvEXT\0" + ""; +#endif + +#if defined(need_GL_NV_fence) +static const char FinishFenceNV_names[] = + "i\0" /* Parameter signature */ + "glFinishFenceNV\0" + ""; +#endif + +#if defined(need_GL_SGIS_fog_function) +static const char GetFogFuncSGIS_names[] = + "p\0" /* Parameter signature */ + "glGetFogFuncSGIS\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char GetUniformLocationARB_names[] = + "ip\0" /* Parameter signature */ + "glGetUniformLocation\0" + "glGetUniformLocationARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3fEXT_names[] = + "fff\0" /* Parameter signature */ + "glSecondaryColor3f\0" + "glSecondaryColor3fEXT\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char CombinerInputNV_names[] = + "iiiiii\0" /* Parameter signature */ + "glCombinerInputNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib3sARB_names[] = + "iiii\0" /* Parameter signature */ + "glVertexAttrib3s\0" + "glVertexAttrib3sARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiNormal3fVertex3fvSUN_names[] = + "ppp\0" /* Parameter signature */ + "glReplacementCodeuiNormal3fVertex3fvSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char ProgramStringARB_names[] = + "iiip\0" /* Parameter signature */ + "glProgramStringARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char TexCoord4fVertex4fvSUN_names[] = + "pp\0" /* Parameter signature */ + "glTexCoord4fVertex4fvSUN\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib3sNV_names[] = + "iiii\0" /* Parameter signature */ + "glVertexAttrib3sNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib1fNV_names[] = + "if\0" /* Parameter signature */ + "glVertexAttrib1fNV\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentLightfSGIX_names[] = + "iif\0" /* Parameter signature */ + "glFragmentLightfSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression) +static const char GetCompressedTexImageARB_names[] = + "iip\0" /* Parameter signature */ + "glGetCompressedTexImage\0" + "glGetCompressedTexImageARB\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_weighting) +static const char VertexWeightPointerEXT_names[] = + "iiip\0" /* Parameter signature */ + "glVertexWeightPointerEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char GetHistogram_names[] = + "iiiip\0" /* Parameter signature */ + "glGetHistogram\0" + "glGetHistogramEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_stencil_two_side) +static const char ActiveStencilFaceEXT_names[] = + "i\0" /* Parameter signature */ + "glActiveStencilFaceEXT\0" + ""; +#endif + +#if defined(need_GL_ATI_separate_stencil) +static const char StencilFuncSeparateATI_names[] = + "iiii\0" /* Parameter signature */ + "glStencilFuncSeparateATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char GetShaderSourceARB_names[] = + "iipp\0" /* Parameter signature */ + "glGetShaderSource\0" + "glGetShaderSourceARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_igloo_interface) +static const char IglooInterfaceSGIX_names[] = + "ip\0" /* Parameter signature */ + "glIglooInterfaceSGIX\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4dNV_names[] = + "idddd\0" /* Parameter signature */ + "glVertexAttrib4dNV\0" + ""; +#endif + +#if defined(need_GL_IBM_multimode_draw_arrays) +static const char MultiModeDrawElementsIBM_names[] = + "ppipii\0" /* Parameter signature */ + "glMultiModeDrawElementsIBM\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4svARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord4sv\0" + "glMultiTexCoord4svARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query) +static const char GenQueriesARB_names[] = + "ip\0" /* Parameter signature */ + "glGenQueries\0" + "glGenQueriesARB\0" + ""; +#endif + +#if defined(need_GL_SUN_vertex) +static const char ReplacementCodeuiVertex3fSUN_names[] = + "ifff\0" /* Parameter signature */ + "glReplacementCodeuiVertex3fSUN\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3iEXT_names[] = + "iii\0" /* Parameter signature */ + "glTangent3iEXT\0" + ""; +#endif + +#if defined(need_GL_SUN_mesh_array) +static const char DrawMeshArraysSUN_names[] = + "iiii\0" /* Parameter signature */ + "glDrawMeshArraysSUN\0" + ""; +#endif + +#if defined(need_GL_ARB_sync) +static const char IsSync_names[] = + "i\0" /* Parameter signature */ + "glIsSync\0" + ""; +#endif + +#if defined(need_GL_NV_evaluators) +static const char GetMapControlPointsNV_names[] = + "iiiiiip\0" /* Parameter signature */ + "glGetMapControlPointsNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_draw_buffers) || defined(need_GL_ATI_draw_buffers) +static const char DrawBuffersARB_names[] = + "ip\0" /* Parameter signature */ + "glDrawBuffers\0" + "glDrawBuffersARB\0" + "glDrawBuffersATI\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char ProgramLocalParameter4fARB_names[] = + "iiffff\0" /* Parameter signature */ + "glProgramLocalParameter4fARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_sprite) +static const char SpriteParameterivSGIX_names[] = + "ip\0" /* Parameter signature */ + "glSpriteParameterivSGIX\0" + ""; +#endif + +#if defined(need_GL_EXT_provoking_vertex) +static const char ProvokingVertexEXT_names[] = + "i\0" /* Parameter signature */ + "glProvokingVertexEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord1fARB_names[] = + "if\0" /* Parameter signature */ + "glMultiTexCoord1f\0" + "glMultiTexCoord1fARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs4ubvNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs4ubvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightsvARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightsvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects) +static const char Uniform1fvARB_names[] = + "iip\0" /* Parameter signature */ + "glUniform1fv\0" + "glUniform1fvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_copy_texture) +static const char CopyTexSubImage1D_names[] = + "iiiiii\0" /* Parameter signature */ + "glCopyTexSubImage1D\0" + "glCopyTexSubImage1DEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_texture_object) +static const char BindTexture_names[] = + "ii\0" /* Parameter signature */ + "glBindTexture\0" + "glBindTextureEXT\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char BeginFragmentShaderATI_names[] = + "\0" /* Parameter signature */ + "glBeginFragmentShaderATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord4fARB_names[] = + "iffff\0" /* Parameter signature */ + "glMultiTexCoord4f\0" + "glMultiTexCoord4fARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs3svNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs3svNV\0" + ""; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const char ReplacementCodeuivSUN_names[] = + "p\0" /* Parameter signature */ + "glReplacementCodeuivSUN\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char EnableVertexAttribArrayARB_names[] = + "i\0" /* Parameter signature */ + "glEnableVertexAttribArray\0" + "glEnableVertexAttribArrayARB\0" + ""; +#endif + +#if defined(need_GL_INTEL_parallel_arrays) +static const char NormalPointervINTEL_names[] = + "ip\0" /* Parameter signature */ + "glNormalPointervINTEL\0" + ""; +#endif + +#if defined(need_GL_EXT_convolution) +static const char CopyConvolutionFilter2D_names[] = + "iiiiii\0" /* Parameter signature */ + "glCopyConvolutionFilter2D\0" + "glCopyConvolutionFilter2DEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3ivMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos3iv\0" + "glWindowPos3ivARB\0" + "glWindowPos3ivMESA\0" + ""; +#endif + +#if defined(need_GL_ARB_copy_buffer) +static const char CopyBufferSubData_names[] = + "iiiii\0" /* Parameter signature */ + "glCopyBufferSubData\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char IsBufferARB_names[] = + "i\0" /* Parameter signature */ + "glIsBuffer\0" + "glIsBufferARB\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4iMESA_names[] = + "iiii\0" /* Parameter signature */ + "glWindowPos4iMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4uivARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4uiv\0" + "glVertexAttrib4uivARB\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3bvEXT_names[] = + "p\0" /* Parameter signature */ + "glTangent3bvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_1) +static const char UniformMatrix3x4fv_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix3x4fv\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3fvEXT_names[] = + "p\0" /* Parameter signature */ + "glBinormal3fvEXT\0" + ""; +#endif + +#if defined(need_GL_INTEL_parallel_arrays) +static const char TexCoordPointervINTEL_names[] = + "iip\0" /* Parameter signature */ + "glTexCoordPointervINTEL\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char DeleteBuffersARB_names[] = + "ip\0" /* Parameter signature */ + "glDeleteBuffers\0" + "glDeleteBuffersARB\0" + ""; +#endif + +#if defined(need_GL_MESA_window_pos) +static const char WindowPos4fvMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos4fvMESA\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib1sNV_names[] = + "ii\0" /* Parameter signature */ + "glVertexAttrib1sNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color) +static const char SecondaryColor3svEXT_names[] = + "p\0" /* Parameter signature */ + "glSecondaryColor3sv\0" + "glSecondaryColor3svEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix) +static const char LoadTransposeMatrixfARB_names[] = + "p\0" /* Parameter signature */ + "glLoadTransposeMatrixf\0" + "glLoadTransposeMatrixfARB\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char GetPointerv_names[] = + "ip\0" /* Parameter signature */ + "glGetPointerv\0" + "glGetPointervEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3bEXT_names[] = + "iii\0" /* Parameter signature */ + "glTangent3bEXT\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char CombinerParameterfNV_names[] = + "if\0" /* Parameter signature */ + "glCombinerParameterfNV\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char BindProgramNV_names[] = + "ii\0" /* Parameter signature */ + "glBindProgramARB\0" + "glBindProgramNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4svARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4sv\0" + "glVertexAttrib4svARB\0" + ""; +#endif + +#if defined(need_GL_MESA_shader_debug) +static const char CreateDebugObjectMESA_names[] = + "\0" /* Parameter signature */ + "glCreateDebugObjectMESA\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) +static const char GetShaderiv_names[] = + "iip\0" /* Parameter signature */ + "glGetShaderiv\0" + ""; +#endif + +#if defined(need_GL_ARB_sync) +static const char ClientWaitSync_names[] = + "iii\0" /* Parameter signature */ + "glClientWaitSync\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char BindFragmentShaderATI_names[] = + "i\0" /* Parameter signature */ + "glBindFragmentShaderATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char UnmapBufferARB_names[] = + "i\0" /* Parameter signature */ + "glUnmapBuffer\0" + "glUnmapBufferARB\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char Minmax_names[] = + "iii\0" /* Parameter signature */ + "glMinmax\0" + "glMinmaxEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord) +static const char FogCoorddvEXT_names[] = + "p\0" /* Parameter signature */ + "glFogCoorddv\0" + "glFogCoorddvEXT\0" + ""; +#endif + +#if defined(need_GL_SUNX_constant_data) +static const char FinishTextureSUNX_names[] = + "\0" /* Parameter signature */ + "glFinishTextureSUNX\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char GetFragmentLightfvSGIX_names[] = + "iip\0" /* Parameter signature */ + "glGetFragmentLightfvSGIX\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char GetFinalCombinerInputParameterfvNV_names[] = + "iip\0" /* Parameter signature */ + "glGetFinalCombinerInputParameterfvNV\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char ColorFragmentOp3ATI_names[] = + "iiiiiiiiiiiii\0" /* Parameter signature */ + "glColorFragmentOp3ATI\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib2svARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib2sv\0" + "glVertexAttrib2svARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char AreProgramsResidentNV_names[] = + "ipp\0" /* Parameter signature */ + "glAreProgramsResidentNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos3svMESA_names[] = + "p\0" /* Parameter signature */ + "glWindowPos3sv\0" + "glWindowPos3svARB\0" + "glWindowPos3svMESA\0" + ""; +#endif + +#if defined(need_GL_EXT_color_subtable) +static const char CopyColorSubTable_names[] = + "iiiii\0" /* Parameter signature */ + "glCopyColorSubTable\0" + "glCopyColorSubTableEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightdvARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightdvARB\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char DeleteRenderbuffersEXT_names[] = + "ip\0" /* Parameter signature */ + "glDeleteRenderbuffers\0" + "glDeleteRenderbuffersEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib4NubvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4Nubv\0" + "glVertexAttrib4NubvARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib3dvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib3dvNV\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char GetObjectParameterfvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetObjectParameterfvARB\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const char GetProgramEnvParameterdvARB_names[] = + "iip\0" /* Parameter signature */ + "glGetProgramEnvParameterdvARB\0" + ""; +#endif + +#if defined(need_GL_EXT_compiled_vertex_array) +static const char LockArraysEXT_names[] = + "ii\0" /* Parameter signature */ + "glLockArraysEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_pixel_transform) +static const char PixelTransformParameterivEXT_names[] = + "iip\0" /* Parameter signature */ + "glPixelTransformParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char BinormalPointerEXT_names[] = + "iip\0" /* Parameter signature */ + "glBinormalPointerEXT\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib1dNV_names[] = + "id\0" /* Parameter signature */ + "glVertexAttrib1dNV\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char GetCombinerInputParameterivNV_names[] = + "iiiip\0" /* Parameter signature */ + "glGetCombinerInputParameterivNV\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_3) +static const char MultiTexCoord2fvARB_names[] = + "ip\0" /* Parameter signature */ + "glMultiTexCoord2fv\0" + "glMultiTexCoord2fvARB\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char GetRenderbufferParameterivEXT_names[] = + "iip\0" /* Parameter signature */ + "glGetRenderbufferParameteriv\0" + "glGetRenderbufferParameterivEXT\0" + ""; +#endif + +#if defined(need_GL_NV_register_combiners) +static const char CombinerParameterivNV_names[] = + "ip\0" /* Parameter signature */ + "glCombinerParameterivNV\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char GenFragmentShadersATI_names[] = + "i\0" /* Parameter signature */ + "glGenFragmentShadersATI\0" + ""; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const char DrawArrays_names[] = + "iii\0" /* Parameter signature */ + "glDrawArrays\0" + "glDrawArraysEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const char WeightuivARB_names[] = + "ip\0" /* Parameter signature */ + "glWeightuivARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib2sARB_names[] = + "iii\0" /* Parameter signature */ + "glVertexAttrib2s\0" + "glVertexAttrib2sARB\0" + ""; +#endif + +#if defined(need_GL_SGIX_async) +static const char GenAsyncMarkersSGIX_names[] = + "i\0" /* Parameter signature */ + "glGenAsyncMarkersSGIX\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Tangent3svEXT_names[] = + "p\0" /* Parameter signature */ + "glTangent3svEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_list_priority) +static const char GetListParameterivSGIX_names[] = + "iip\0" /* Parameter signature */ + "glGetListParameterivSGIX\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char BindBufferARB_names[] = + "ii\0" /* Parameter signature */ + "glBindBuffer\0" + "glBindBufferARB\0" + ""; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const char GetInfoLogARB_names[] = + "iipp\0" /* Parameter signature */ + "glGetInfoLogARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs4svNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs4svNV\0" + ""; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const char EdgeFlagPointerListIBM_names[] = + "ipi\0" /* Parameter signature */ + "glEdgeFlagPointerListIBM\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_1) +static const char UniformMatrix3x2fv_names[] = + "iiip\0" /* Parameter signature */ + "glUniformMatrix3x2fv\0" + ""; +#endif + +#if defined(need_GL_EXT_histogram) +static const char GetMinmaxParameterfv_names[] = + "iip\0" /* Parameter signature */ + "glGetMinmaxParameterfv\0" + "glGetMinmaxParameterfvEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) +static const char VertexAttrib1fvARB_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib1fv\0" + "glVertexAttrib1fvARB\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object) +static const char GenBuffersARB_names[] = + "ip\0" /* Parameter signature */ + "glGenBuffers\0" + "glGenBuffersARB\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttribs1svNV_names[] = + "iip\0" /* Parameter signature */ + "glVertexAttribs1svNV\0" + ""; +#endif + +#if defined(need_GL_ATI_envmap_bumpmap) +static const char GetTexBumpParameterivATI_names[] = + "ip\0" /* Parameter signature */ + "glGetTexBumpParameterivATI\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3bEXT_names[] = + "iii\0" /* Parameter signature */ + "glBinormal3bEXT\0" + ""; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const char FragmentMaterialivSGIX_names[] = + "iip\0" /* Parameter signature */ + "glFragmentMaterialivSGIX\0" + ""; +#endif + +#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object) +static const char IsRenderbufferEXT_names[] = + "i\0" /* Parameter signature */ + "glIsRenderbuffer\0" + "glIsRenderbufferEXT\0" + ""; +#endif + +#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program) +static const char GenProgramsNV_names[] = + "ip\0" /* Parameter signature */ + "glGenProgramsARB\0" + "glGenProgramsNV\0" + ""; +#endif + +#if defined(need_GL_NV_vertex_program) +static const char VertexAttrib4dvNV_names[] = + "ip\0" /* Parameter signature */ + "glVertexAttrib4dvNV\0" + ""; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const char EndFragmentShaderATI_names[] = + "\0" /* Parameter signature */ + "glEndFragmentShaderATI\0" + ""; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const char Binormal3iEXT_names[] = + "iii\0" /* Parameter signature */ + "glBinormal3iEXT\0" + ""; +#endif + +#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos) +static const char WindowPos2fMESA_names[] = + "ff\0" /* Parameter signature */ + "glWindowPos2f\0" + "glWindowPos2fARB\0" + "glWindowPos2fMESA\0" + ""; +#endif + +#if defined(need_GL_3DFX_tbuffer) +static const struct dri_extension_function GL_3DFX_tbuffer_functions[] = { + { TbufferMask3DFX_names, TbufferMask3DFX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_APPLE_flush_buffer_range) +static const struct dri_extension_function GL_APPLE_flush_buffer_range_functions[] = { + { BufferParameteriAPPLE_names, BufferParameteriAPPLE_remap_index, -1 }, + { FlushMappedBufferRangeAPPLE_names, FlushMappedBufferRangeAPPLE_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_APPLE_texture_range) +static const struct dri_extension_function GL_APPLE_texture_range_functions[] = { + { TextureRangeAPPLE_names, TextureRangeAPPLE_remap_index, -1 }, + { GetTexParameterPointervAPPLE_names, GetTexParameterPointervAPPLE_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_APPLE_vertex_array_object) +static const struct dri_extension_function GL_APPLE_vertex_array_object_functions[] = { + { DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 }, + { GenVertexArraysAPPLE_names, GenVertexArraysAPPLE_remap_index, -1 }, + { IsVertexArrayAPPLE_names, IsVertexArrayAPPLE_remap_index, -1 }, + { BindVertexArrayAPPLE_names, BindVertexArrayAPPLE_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_copy_buffer) +static const struct dri_extension_function GL_ARB_copy_buffer_functions[] = { + { CopyBufferSubData_names, CopyBufferSubData_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_draw_buffers) +static const struct dri_extension_function GL_ARB_draw_buffers_functions[] = { + { DrawBuffersARB_names, DrawBuffersARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_framebuffer_object) +static const struct dri_extension_function GL_ARB_framebuffer_object_functions[] = { + { BlitFramebufferEXT_names, BlitFramebufferEXT_remap_index, -1 }, + { FramebufferTextureLayerEXT_names, FramebufferTextureLayerEXT_remap_index, -1 }, + { GenerateMipmapEXT_names, GenerateMipmapEXT_remap_index, -1 }, + { RenderbufferStorageEXT_names, RenderbufferStorageEXT_remap_index, -1 }, + { CheckFramebufferStatusEXT_names, CheckFramebufferStatusEXT_remap_index, -1 }, + { FramebufferTexture3DEXT_names, FramebufferTexture3DEXT_remap_index, -1 }, + { FramebufferTexture2DEXT_names, FramebufferTexture2DEXT_remap_index, -1 }, + { RenderbufferStorageMultisample_names, RenderbufferStorageMultisample_remap_index, -1 }, + { FramebufferRenderbufferEXT_names, FramebufferRenderbufferEXT_remap_index, -1 }, + { FramebufferTexture1DEXT_names, FramebufferTexture1DEXT_remap_index, -1 }, + { BindFramebufferEXT_names, BindFramebufferEXT_remap_index, -1 }, + { GenRenderbuffersEXT_names, GenRenderbuffersEXT_remap_index, -1 }, + { IsFramebufferEXT_names, IsFramebufferEXT_remap_index, -1 }, + { GetFramebufferAttachmentParameterivEXT_names, GetFramebufferAttachmentParameterivEXT_remap_index, -1 }, + { DeleteFramebuffersEXT_names, DeleteFramebuffersEXT_remap_index, -1 }, + { GenFramebuffersEXT_names, GenFramebuffersEXT_remap_index, -1 }, + { BindRenderbufferEXT_names, BindRenderbufferEXT_remap_index, -1 }, + { DeleteRenderbuffersEXT_names, DeleteRenderbuffersEXT_remap_index, -1 }, + { GetRenderbufferParameterivEXT_names, GetRenderbufferParameterivEXT_remap_index, -1 }, + { IsRenderbufferEXT_names, IsRenderbufferEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_map_buffer_range) +static const struct dri_extension_function GL_ARB_map_buffer_range_functions[] = { + { FlushMappedBufferRange_names, FlushMappedBufferRange_remap_index, -1 }, + { MapBufferRange_names, MapBufferRange_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_matrix_palette) +static const struct dri_extension_function GL_ARB_matrix_palette_functions[] = { + { MatrixIndexusvARB_names, MatrixIndexusvARB_remap_index, -1 }, + { MatrixIndexuivARB_names, MatrixIndexuivARB_remap_index, -1 }, + { MatrixIndexPointerARB_names, MatrixIndexPointerARB_remap_index, -1 }, + { CurrentPaletteMatrixARB_names, CurrentPaletteMatrixARB_remap_index, -1 }, + { MatrixIndexubvARB_names, MatrixIndexubvARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_multisample) +static const struct dri_extension_function GL_ARB_multisample_functions[] = { + { SampleCoverageARB_names, SampleCoverageARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_occlusion_query) +static const struct dri_extension_function GL_ARB_occlusion_query_functions[] = { + { BeginQueryARB_names, BeginQueryARB_remap_index, -1 }, + { GetQueryivARB_names, GetQueryivARB_remap_index, -1 }, + { GetQueryObjectivARB_names, GetQueryObjectivARB_remap_index, -1 }, + { EndQueryARB_names, EndQueryARB_remap_index, -1 }, + { GetQueryObjectuivARB_names, GetQueryObjectuivARB_remap_index, -1 }, + { DeleteQueriesARB_names, DeleteQueriesARB_remap_index, -1 }, + { IsQueryARB_names, IsQueryARB_remap_index, -1 }, + { GenQueriesARB_names, GenQueriesARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_point_parameters) +static const struct dri_extension_function GL_ARB_point_parameters_functions[] = { + { PointParameterfEXT_names, PointParameterfEXT_remap_index, -1 }, + { PointParameterfvEXT_names, PointParameterfvEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_shader_objects) +static const struct dri_extension_function GL_ARB_shader_objects_functions[] = { + { UniformMatrix3fvARB_names, UniformMatrix3fvARB_remap_index, -1 }, + { Uniform2fARB_names, Uniform2fARB_remap_index, -1 }, + { Uniform2ivARB_names, Uniform2ivARB_remap_index, -1 }, + { UniformMatrix4fvARB_names, UniformMatrix4fvARB_remap_index, -1 }, + { CreateProgramObjectARB_names, CreateProgramObjectARB_remap_index, -1 }, + { Uniform3iARB_names, Uniform3iARB_remap_index, -1 }, + { CreateShaderObjectARB_names, CreateShaderObjectARB_remap_index, -1 }, + { Uniform1fARB_names, Uniform1fARB_remap_index, -1 }, + { AttachObjectARB_names, AttachObjectARB_remap_index, -1 }, + { UniformMatrix2fvARB_names, UniformMatrix2fvARB_remap_index, -1 }, + { GetAttachedObjectsARB_names, GetAttachedObjectsARB_remap_index, -1 }, + { Uniform3fvARB_names, Uniform3fvARB_remap_index, -1 }, + { GetHandleARB_names, GetHandleARB_remap_index, -1 }, + { GetActiveUniformARB_names, GetActiveUniformARB_remap_index, -1 }, + { GetUniformivARB_names, GetUniformivARB_remap_index, -1 }, + { Uniform2fvARB_names, Uniform2fvARB_remap_index, -1 }, + { DeleteObjectARB_names, DeleteObjectARB_remap_index, -1 }, + { ValidateProgramARB_names, ValidateProgramARB_remap_index, -1 }, + { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 }, + { CompileShaderARB_names, CompileShaderARB_remap_index, -1 }, + { Uniform3fARB_names, Uniform3fARB_remap_index, -1 }, + { Uniform4fARB_names, Uniform4fARB_remap_index, -1 }, + { LinkProgramARB_names, LinkProgramARB_remap_index, -1 }, + { ShaderSourceARB_names, ShaderSourceARB_remap_index, -1 }, + { Uniform4ivARB_names, Uniform4ivARB_remap_index, -1 }, + { Uniform1ivARB_names, Uniform1ivARB_remap_index, -1 }, + { Uniform1iARB_names, Uniform1iARB_remap_index, -1 }, + { Uniform4fvARB_names, Uniform4fvARB_remap_index, -1 }, + { GetUniformfvARB_names, GetUniformfvARB_remap_index, -1 }, + { DetachObjectARB_names, DetachObjectARB_remap_index, -1 }, + { Uniform4iARB_names, Uniform4iARB_remap_index, -1 }, + { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 }, + { Uniform2iARB_names, Uniform2iARB_remap_index, -1 }, + { GetObjectParameterivARB_names, GetObjectParameterivARB_remap_index, -1 }, + { GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 }, + { GetShaderSourceARB_names, GetShaderSourceARB_remap_index, -1 }, + { Uniform1fvARB_names, Uniform1fvARB_remap_index, -1 }, + { GetObjectParameterfvARB_names, GetObjectParameterfvARB_remap_index, -1 }, + { GetInfoLogARB_names, GetInfoLogARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_sync) +static const struct dri_extension_function GL_ARB_sync_functions[] = { + { DeleteSync_names, DeleteSync_remap_index, -1 }, + { FenceSync_names, FenceSync_remap_index, -1 }, + { WaitSync_names, WaitSync_remap_index, -1 }, + { GetInteger64v_names, GetInteger64v_remap_index, -1 }, + { GetSynciv_names, GetSynciv_remap_index, -1 }, + { IsSync_names, IsSync_remap_index, -1 }, + { ClientWaitSync_names, ClientWaitSync_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_texture_compression) +static const struct dri_extension_function GL_ARB_texture_compression_functions[] = { + { CompressedTexSubImage2DARB_names, CompressedTexSubImage2DARB_remap_index, -1 }, + { CompressedTexImage3DARB_names, CompressedTexImage3DARB_remap_index, -1 }, + { CompressedTexImage1DARB_names, CompressedTexImage1DARB_remap_index, -1 }, + { CompressedTexSubImage1DARB_names, CompressedTexSubImage1DARB_remap_index, -1 }, + { CompressedTexSubImage3DARB_names, CompressedTexSubImage3DARB_remap_index, -1 }, + { CompressedTexImage2DARB_names, CompressedTexImage2DARB_remap_index, -1 }, + { GetCompressedTexImageARB_names, GetCompressedTexImageARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_transpose_matrix) +static const struct dri_extension_function GL_ARB_transpose_matrix_functions[] = { + { MultTransposeMatrixdARB_names, MultTransposeMatrixdARB_remap_index, -1 }, + { LoadTransposeMatrixdARB_names, LoadTransposeMatrixdARB_remap_index, -1 }, + { MultTransposeMatrixfARB_names, MultTransposeMatrixfARB_remap_index, -1 }, + { LoadTransposeMatrixfARB_names, LoadTransposeMatrixfARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_vertex_array_object) +static const struct dri_extension_function GL_ARB_vertex_array_object_functions[] = { + { DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 }, + { GenVertexArrays_names, GenVertexArrays_remap_index, -1 }, + { BindVertexArray_names, BindVertexArray_remap_index, -1 }, + { IsVertexArrayAPPLE_names, IsVertexArrayAPPLE_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_vertex_blend) +static const struct dri_extension_function GL_ARB_vertex_blend_functions[] = { + { WeightubvARB_names, WeightubvARB_remap_index, -1 }, + { WeightivARB_names, WeightivARB_remap_index, -1 }, + { WeightPointerARB_names, WeightPointerARB_remap_index, -1 }, + { WeightfvARB_names, WeightfvARB_remap_index, -1 }, + { WeightbvARB_names, WeightbvARB_remap_index, -1 }, + { WeightusvARB_names, WeightusvARB_remap_index, -1 }, + { VertexBlendARB_names, VertexBlendARB_remap_index, -1 }, + { WeightsvARB_names, WeightsvARB_remap_index, -1 }, + { WeightdvARB_names, WeightdvARB_remap_index, -1 }, + { WeightuivARB_names, WeightuivARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_vertex_buffer_object) +static const struct dri_extension_function GL_ARB_vertex_buffer_object_functions[] = { + { GetBufferSubDataARB_names, GetBufferSubDataARB_remap_index, -1 }, + { BufferSubDataARB_names, BufferSubDataARB_remap_index, -1 }, + { BufferDataARB_names, BufferDataARB_remap_index, -1 }, + { GetBufferPointervARB_names, GetBufferPointervARB_remap_index, -1 }, + { GetBufferParameterivARB_names, GetBufferParameterivARB_remap_index, -1 }, + { MapBufferARB_names, MapBufferARB_remap_index, -1 }, + { IsBufferARB_names, IsBufferARB_remap_index, -1 }, + { DeleteBuffersARB_names, DeleteBuffersARB_remap_index, -1 }, + { UnmapBufferARB_names, UnmapBufferARB_remap_index, -1 }, + { BindBufferARB_names, BindBufferARB_remap_index, -1 }, + { GenBuffersARB_names, GenBuffersARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_vertex_program) +static const struct dri_extension_function GL_ARB_vertex_program_functions[] = { + { VertexAttrib2fARB_names, VertexAttrib2fARB_remap_index, -1 }, + { VertexAttrib3fARB_names, VertexAttrib3fARB_remap_index, -1 }, + { VertexAttrib1svARB_names, VertexAttrib1svARB_remap_index, -1 }, + { VertexAttrib4NusvARB_names, VertexAttrib4NusvARB_remap_index, -1 }, + { DisableVertexAttribArrayARB_names, DisableVertexAttribArrayARB_remap_index, -1 }, + { ProgramLocalParameter4dARB_names, ProgramLocalParameter4dARB_remap_index, -1 }, + { VertexAttrib1fARB_names, VertexAttrib1fARB_remap_index, -1 }, + { VertexAttrib4NbvARB_names, VertexAttrib4NbvARB_remap_index, -1 }, + { VertexAttrib1sARB_names, VertexAttrib1sARB_remap_index, -1 }, + { GetProgramLocalParameterfvARB_names, GetProgramLocalParameterfvARB_remap_index, -1 }, + { VertexAttrib3dvARB_names, VertexAttrib3dvARB_remap_index, -1 }, + { ProgramEnvParameter4fvARB_names, ProgramEnvParameter4fvARB_remap_index, -1 }, + { GetVertexAttribivARB_names, GetVertexAttribivARB_remap_index, -1 }, + { VertexAttrib4ivARB_names, VertexAttrib4ivARB_remap_index, -1 }, + { VertexAttrib4bvARB_names, VertexAttrib4bvARB_remap_index, -1 }, + { VertexAttrib3dARB_names, VertexAttrib3dARB_remap_index, -1 }, + { VertexAttrib4fARB_names, VertexAttrib4fARB_remap_index, -1 }, + { VertexAttrib4fvARB_names, VertexAttrib4fvARB_remap_index, -1 }, + { ProgramLocalParameter4dvARB_names, ProgramLocalParameter4dvARB_remap_index, -1 }, + { VertexAttrib2dARB_names, VertexAttrib2dARB_remap_index, -1 }, + { VertexAttrib1dvARB_names, VertexAttrib1dvARB_remap_index, -1 }, + { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 }, + { VertexAttrib4ubvARB_names, VertexAttrib4ubvARB_remap_index, -1 }, + { ProgramEnvParameter4fARB_names, ProgramEnvParameter4fARB_remap_index, -1 }, + { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 }, + { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 }, + { VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 }, + { VertexAttrib4NivARB_names, VertexAttrib4NivARB_remap_index, -1 }, + { GetProgramStringARB_names, GetProgramStringARB_remap_index, -1 }, + { VertexAttrib4NuivARB_names, VertexAttrib4NuivARB_remap_index, -1 }, + { IsProgramNV_names, IsProgramNV_remap_index, -1 }, + { ProgramEnvParameter4dARB_names, ProgramEnvParameter4dARB_remap_index, -1 }, + { VertexAttrib1dARB_names, VertexAttrib1dARB_remap_index, -1 }, + { VertexAttrib4usvARB_names, VertexAttrib4usvARB_remap_index, -1 }, + { VertexAttrib3svARB_names, VertexAttrib3svARB_remap_index, -1 }, + { GetVertexAttribdvARB_names, GetVertexAttribdvARB_remap_index, -1 }, + { VertexAttrib4dvARB_names, VertexAttrib4dvARB_remap_index, -1 }, + { VertexAttribPointerARB_names, VertexAttribPointerARB_remap_index, -1 }, + { VertexAttrib4NsvARB_names, VertexAttrib4NsvARB_remap_index, -1 }, + { VertexAttrib3fvARB_names, VertexAttrib3fvARB_remap_index, -1 }, + { VertexAttrib4NubARB_names, VertexAttrib4NubARB_remap_index, -1 }, + { GetProgramEnvParameterfvARB_names, GetProgramEnvParameterfvARB_remap_index, -1 }, + { ProgramEnvParameter4dvARB_names, ProgramEnvParameter4dvARB_remap_index, -1 }, + { ProgramLocalParameter4fvARB_names, ProgramLocalParameter4fvARB_remap_index, -1 }, + { DeleteProgramsNV_names, DeleteProgramsNV_remap_index, -1 }, + { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 }, + { VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 }, + { GetProgramLocalParameterdvARB_names, GetProgramLocalParameterdvARB_remap_index, -1 }, + { GetProgramivARB_names, GetProgramivARB_remap_index, -1 }, + { VertexAttrib3sARB_names, VertexAttrib3sARB_remap_index, -1 }, + { ProgramStringARB_names, ProgramStringARB_remap_index, -1 }, + { ProgramLocalParameter4fARB_names, ProgramLocalParameter4fARB_remap_index, -1 }, + { EnableVertexAttribArrayARB_names, EnableVertexAttribArrayARB_remap_index, -1 }, + { VertexAttrib4uivARB_names, VertexAttrib4uivARB_remap_index, -1 }, + { BindProgramNV_names, BindProgramNV_remap_index, -1 }, + { VertexAttrib4svARB_names, VertexAttrib4svARB_remap_index, -1 }, + { VertexAttrib2svARB_names, VertexAttrib2svARB_remap_index, -1 }, + { VertexAttrib4NubvARB_names, VertexAttrib4NubvARB_remap_index, -1 }, + { GetProgramEnvParameterdvARB_names, GetProgramEnvParameterdvARB_remap_index, -1 }, + { VertexAttrib2sARB_names, VertexAttrib2sARB_remap_index, -1 }, + { VertexAttrib1fvARB_names, VertexAttrib1fvARB_remap_index, -1 }, + { GenProgramsNV_names, GenProgramsNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_vertex_shader) +static const struct dri_extension_function GL_ARB_vertex_shader_functions[] = { + { GetActiveAttribARB_names, GetActiveAttribARB_remap_index, -1 }, + { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 }, + { BindAttribLocationARB_names, BindAttribLocationARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ARB_window_pos) +static const struct dri_extension_function GL_ARB_window_pos_functions[] = { + { WindowPos3fMESA_names, WindowPos3fMESA_remap_index, -1 }, + { WindowPos2dvMESA_names, WindowPos2dvMESA_remap_index, -1 }, + { WindowPos2svMESA_names, WindowPos2svMESA_remap_index, -1 }, + { WindowPos3dMESA_names, WindowPos3dMESA_remap_index, -1 }, + { WindowPos2fvMESA_names, WindowPos2fvMESA_remap_index, -1 }, + { WindowPos2dMESA_names, WindowPos2dMESA_remap_index, -1 }, + { WindowPos3dvMESA_names, WindowPos3dvMESA_remap_index, -1 }, + { WindowPos3fvMESA_names, WindowPos3fvMESA_remap_index, -1 }, + { WindowPos2iMESA_names, WindowPos2iMESA_remap_index, -1 }, + { WindowPos3sMESA_names, WindowPos3sMESA_remap_index, -1 }, + { WindowPos2ivMESA_names, WindowPos2ivMESA_remap_index, -1 }, + { WindowPos2sMESA_names, WindowPos2sMESA_remap_index, -1 }, + { WindowPos3iMESA_names, WindowPos3iMESA_remap_index, -1 }, + { WindowPos3ivMESA_names, WindowPos3ivMESA_remap_index, -1 }, + { WindowPos3svMESA_names, WindowPos3svMESA_remap_index, -1 }, + { WindowPos2fMESA_names, WindowPos2fMESA_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ATI_blend_equation_separate) +static const struct dri_extension_function GL_ATI_blend_equation_separate_functions[] = { + { BlendEquationSeparateEXT_names, BlendEquationSeparateEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ATI_draw_buffers) +static const struct dri_extension_function GL_ATI_draw_buffers_functions[] = { + { DrawBuffersARB_names, DrawBuffersARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ATI_envmap_bumpmap) +static const struct dri_extension_function GL_ATI_envmap_bumpmap_functions[] = { + { TexBumpParameterfvATI_names, TexBumpParameterfvATI_remap_index, -1 }, + { TexBumpParameterivATI_names, TexBumpParameterivATI_remap_index, -1 }, + { GetTexBumpParameterfvATI_names, GetTexBumpParameterfvATI_remap_index, -1 }, + { GetTexBumpParameterivATI_names, GetTexBumpParameterivATI_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ATI_fragment_shader) +static const struct dri_extension_function GL_ATI_fragment_shader_functions[] = { + { ColorFragmentOp2ATI_names, ColorFragmentOp2ATI_remap_index, -1 }, + { DeleteFragmentShaderATI_names, DeleteFragmentShaderATI_remap_index, -1 }, + { SetFragmentShaderConstantATI_names, SetFragmentShaderConstantATI_remap_index, -1 }, + { SampleMapATI_names, SampleMapATI_remap_index, -1 }, + { AlphaFragmentOp2ATI_names, AlphaFragmentOp2ATI_remap_index, -1 }, + { AlphaFragmentOp1ATI_names, AlphaFragmentOp1ATI_remap_index, -1 }, + { ColorFragmentOp1ATI_names, ColorFragmentOp1ATI_remap_index, -1 }, + { AlphaFragmentOp3ATI_names, AlphaFragmentOp3ATI_remap_index, -1 }, + { PassTexCoordATI_names, PassTexCoordATI_remap_index, -1 }, + { BeginFragmentShaderATI_names, BeginFragmentShaderATI_remap_index, -1 }, + { BindFragmentShaderATI_names, BindFragmentShaderATI_remap_index, -1 }, + { ColorFragmentOp3ATI_names, ColorFragmentOp3ATI_remap_index, -1 }, + { GenFragmentShadersATI_names, GenFragmentShadersATI_remap_index, -1 }, + { EndFragmentShaderATI_names, EndFragmentShaderATI_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_ATI_separate_stencil) +static const struct dri_extension_function GL_ATI_separate_stencil_functions[] = { + { StencilOpSeparate_names, StencilOpSeparate_remap_index, -1 }, + { StencilFuncSeparateATI_names, StencilFuncSeparateATI_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_blend_color) +static const struct dri_extension_function GL_EXT_blend_color_functions[] = { + { BlendColor_names, -1, 336 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_blend_equation_separate) +static const struct dri_extension_function GL_EXT_blend_equation_separate_functions[] = { + { BlendEquationSeparateEXT_names, BlendEquationSeparateEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_blend_func_separate) +static const struct dri_extension_function GL_EXT_blend_func_separate_functions[] = { + { BlendFuncSeparateEXT_names, BlendFuncSeparateEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_blend_minmax) +static const struct dri_extension_function GL_EXT_blend_minmax_functions[] = { + { BlendEquation_names, -1, 337 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_color_subtable) +static const struct dri_extension_function GL_EXT_color_subtable_functions[] = { + { ColorSubTable_names, -1, 346 }, + { CopyColorSubTable_names, -1, 347 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_compiled_vertex_array) +static const struct dri_extension_function GL_EXT_compiled_vertex_array_functions[] = { + { UnlockArraysEXT_names, UnlockArraysEXT_remap_index, -1 }, + { LockArraysEXT_names, LockArraysEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_convolution) +static const struct dri_extension_function GL_EXT_convolution_functions[] = { + { ConvolutionFilter1D_names, -1, 348 }, + { CopyConvolutionFilter1D_names, -1, 354 }, + { GetConvolutionParameteriv_names, -1, 358 }, + { ConvolutionFilter2D_names, -1, 349 }, + { ConvolutionParameteriv_names, -1, 353 }, + { ConvolutionParameterfv_names, -1, 351 }, + { GetSeparableFilter_names, -1, 359 }, + { SeparableFilter2D_names, -1, 360 }, + { ConvolutionParameteri_names, -1, 352 }, + { ConvolutionParameterf_names, -1, 350 }, + { GetConvolutionParameterfv_names, -1, 357 }, + { GetConvolutionFilter_names, -1, 356 }, + { CopyConvolutionFilter2D_names, -1, 355 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_coordinate_frame) +static const struct dri_extension_function GL_EXT_coordinate_frame_functions[] = { + { TangentPointerEXT_names, TangentPointerEXT_remap_index, -1 }, + { Binormal3ivEXT_names, Binormal3ivEXT_remap_index, -1 }, + { Tangent3sEXT_names, Tangent3sEXT_remap_index, -1 }, + { Tangent3fvEXT_names, Tangent3fvEXT_remap_index, -1 }, + { Tangent3dvEXT_names, Tangent3dvEXT_remap_index, -1 }, + { Binormal3bvEXT_names, Binormal3bvEXT_remap_index, -1 }, + { Binormal3dEXT_names, Binormal3dEXT_remap_index, -1 }, + { Tangent3fEXT_names, Tangent3fEXT_remap_index, -1 }, + { Binormal3sEXT_names, Binormal3sEXT_remap_index, -1 }, + { Tangent3ivEXT_names, Tangent3ivEXT_remap_index, -1 }, + { Tangent3dEXT_names, Tangent3dEXT_remap_index, -1 }, + { Binormal3svEXT_names, Binormal3svEXT_remap_index, -1 }, + { Binormal3fEXT_names, Binormal3fEXT_remap_index, -1 }, + { Binormal3dvEXT_names, Binormal3dvEXT_remap_index, -1 }, + { Tangent3iEXT_names, Tangent3iEXT_remap_index, -1 }, + { Tangent3bvEXT_names, Tangent3bvEXT_remap_index, -1 }, + { Binormal3fvEXT_names, Binormal3fvEXT_remap_index, -1 }, + { Tangent3bEXT_names, Tangent3bEXT_remap_index, -1 }, + { BinormalPointerEXT_names, BinormalPointerEXT_remap_index, -1 }, + { Tangent3svEXT_names, Tangent3svEXT_remap_index, -1 }, + { Binormal3bEXT_names, Binormal3bEXT_remap_index, -1 }, + { Binormal3iEXT_names, Binormal3iEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_copy_texture) +static const struct dri_extension_function GL_EXT_copy_texture_functions[] = { + { CopyTexSubImage3D_names, -1, 373 }, + { CopyTexImage2D_names, -1, 324 }, + { CopyTexImage1D_names, -1, 323 }, + { CopyTexSubImage2D_names, -1, 326 }, + { CopyTexSubImage1D_names, -1, 325 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_cull_vertex) +static const struct dri_extension_function GL_EXT_cull_vertex_functions[] = { + { CullParameterdvEXT_names, CullParameterdvEXT_remap_index, -1 }, + { CullParameterfvEXT_names, CullParameterfvEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_depth_bounds_test) +static const struct dri_extension_function GL_EXT_depth_bounds_test_functions[] = { + { DepthBoundsEXT_names, DepthBoundsEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_draw_range_elements) +static const struct dri_extension_function GL_EXT_draw_range_elements_functions[] = { + { DrawRangeElements_names, -1, 338 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_fog_coord) +static const struct dri_extension_function GL_EXT_fog_coord_functions[] = { + { FogCoorddEXT_names, FogCoorddEXT_remap_index, -1 }, + { FogCoordfEXT_names, FogCoordfEXT_remap_index, -1 }, + { FogCoordPointerEXT_names, FogCoordPointerEXT_remap_index, -1 }, + { FogCoordfvEXT_names, FogCoordfvEXT_remap_index, -1 }, + { FogCoorddvEXT_names, FogCoorddvEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_framebuffer_blit) +static const struct dri_extension_function GL_EXT_framebuffer_blit_functions[] = { + { BlitFramebufferEXT_names, BlitFramebufferEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_framebuffer_object) +static const struct dri_extension_function GL_EXT_framebuffer_object_functions[] = { + { GenerateMipmapEXT_names, GenerateMipmapEXT_remap_index, -1 }, + { RenderbufferStorageEXT_names, RenderbufferStorageEXT_remap_index, -1 }, + { CheckFramebufferStatusEXT_names, CheckFramebufferStatusEXT_remap_index, -1 }, + { FramebufferTexture3DEXT_names, FramebufferTexture3DEXT_remap_index, -1 }, + { FramebufferTexture2DEXT_names, FramebufferTexture2DEXT_remap_index, -1 }, + { FramebufferRenderbufferEXT_names, FramebufferRenderbufferEXT_remap_index, -1 }, + { FramebufferTexture1DEXT_names, FramebufferTexture1DEXT_remap_index, -1 }, + { BindFramebufferEXT_names, BindFramebufferEXT_remap_index, -1 }, + { GenRenderbuffersEXT_names, GenRenderbuffersEXT_remap_index, -1 }, + { IsFramebufferEXT_names, IsFramebufferEXT_remap_index, -1 }, + { GetFramebufferAttachmentParameterivEXT_names, GetFramebufferAttachmentParameterivEXT_remap_index, -1 }, + { DeleteFramebuffersEXT_names, DeleteFramebuffersEXT_remap_index, -1 }, + { GenFramebuffersEXT_names, GenFramebuffersEXT_remap_index, -1 }, + { BindRenderbufferEXT_names, BindRenderbufferEXT_remap_index, -1 }, + { DeleteRenderbuffersEXT_names, DeleteRenderbuffersEXT_remap_index, -1 }, + { GetRenderbufferParameterivEXT_names, GetRenderbufferParameterivEXT_remap_index, -1 }, + { IsRenderbufferEXT_names, IsRenderbufferEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_gpu_program_parameters) +static const struct dri_extension_function GL_EXT_gpu_program_parameters_functions[] = { + { ProgramLocalParameters4fvEXT_names, ProgramLocalParameters4fvEXT_remap_index, -1 }, + { ProgramEnvParameters4fvEXT_names, ProgramEnvParameters4fvEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_histogram) +static const struct dri_extension_function GL_EXT_histogram_functions[] = { + { Histogram_names, -1, 367 }, + { ResetHistogram_names, -1, 369 }, + { GetMinmax_names, -1, 364 }, + { GetHistogramParameterfv_names, -1, 362 }, + { GetMinmaxParameteriv_names, -1, 366 }, + { ResetMinmax_names, -1, 370 }, + { GetHistogramParameteriv_names, -1, 363 }, + { GetHistogram_names, -1, 361 }, + { Minmax_names, -1, 368 }, + { GetMinmaxParameterfv_names, -1, 365 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_index_func) +static const struct dri_extension_function GL_EXT_index_func_functions[] = { + { IndexFuncEXT_names, IndexFuncEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_index_material) +static const struct dri_extension_function GL_EXT_index_material_functions[] = { + { IndexMaterialEXT_names, IndexMaterialEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_light_texture) +static const struct dri_extension_function GL_EXT_light_texture_functions[] = { + { ApplyTextureEXT_names, ApplyTextureEXT_remap_index, -1 }, + { TextureMaterialEXT_names, TextureMaterialEXT_remap_index, -1 }, + { TextureLightEXT_names, TextureLightEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_multi_draw_arrays) +static const struct dri_extension_function GL_EXT_multi_draw_arrays_functions[] = { + { MultiDrawElementsEXT_names, MultiDrawElementsEXT_remap_index, -1 }, + { MultiDrawArraysEXT_names, MultiDrawArraysEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_multisample) +static const struct dri_extension_function GL_EXT_multisample_functions[] = { + { SampleMaskSGIS_names, SampleMaskSGIS_remap_index, -1 }, + { SamplePatternSGIS_names, SamplePatternSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_paletted_texture) +static const struct dri_extension_function GL_EXT_paletted_texture_functions[] = { + { ColorTable_names, -1, 339 }, + { GetColorTable_names, -1, 343 }, + { GetColorTableParameterfv_names, -1, 344 }, + { GetColorTableParameteriv_names, -1, 345 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_pixel_transform) +static const struct dri_extension_function GL_EXT_pixel_transform_functions[] = { + { PixelTransformParameterfvEXT_names, PixelTransformParameterfvEXT_remap_index, -1 }, + { PixelTransformParameterfEXT_names, PixelTransformParameterfEXT_remap_index, -1 }, + { PixelTransformParameteriEXT_names, PixelTransformParameteriEXT_remap_index, -1 }, + { PixelTransformParameterivEXT_names, PixelTransformParameterivEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_point_parameters) +static const struct dri_extension_function GL_EXT_point_parameters_functions[] = { + { PointParameterfEXT_names, PointParameterfEXT_remap_index, -1 }, + { PointParameterfvEXT_names, PointParameterfvEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_polygon_offset) +static const struct dri_extension_function GL_EXT_polygon_offset_functions[] = { + { PolygonOffsetEXT_names, PolygonOffsetEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_provoking_vertex) +static const struct dri_extension_function GL_EXT_provoking_vertex_functions[] = { + { ProvokingVertexEXT_names, ProvokingVertexEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_secondary_color) +static const struct dri_extension_function GL_EXT_secondary_color_functions[] = { + { SecondaryColor3iEXT_names, SecondaryColor3iEXT_remap_index, -1 }, + { SecondaryColor3bEXT_names, SecondaryColor3bEXT_remap_index, -1 }, + { SecondaryColor3bvEXT_names, SecondaryColor3bvEXT_remap_index, -1 }, + { SecondaryColor3sEXT_names, SecondaryColor3sEXT_remap_index, -1 }, + { SecondaryColor3dEXT_names, SecondaryColor3dEXT_remap_index, -1 }, + { SecondaryColorPointerEXT_names, SecondaryColorPointerEXT_remap_index, -1 }, + { SecondaryColor3uiEXT_names, SecondaryColor3uiEXT_remap_index, -1 }, + { SecondaryColor3usvEXT_names, SecondaryColor3usvEXT_remap_index, -1 }, + { SecondaryColor3ivEXT_names, SecondaryColor3ivEXT_remap_index, -1 }, + { SecondaryColor3fvEXT_names, SecondaryColor3fvEXT_remap_index, -1 }, + { SecondaryColor3ubvEXT_names, SecondaryColor3ubvEXT_remap_index, -1 }, + { SecondaryColor3uivEXT_names, SecondaryColor3uivEXT_remap_index, -1 }, + { SecondaryColor3dvEXT_names, SecondaryColor3dvEXT_remap_index, -1 }, + { SecondaryColor3usEXT_names, SecondaryColor3usEXT_remap_index, -1 }, + { SecondaryColor3ubEXT_names, SecondaryColor3ubEXT_remap_index, -1 }, + { SecondaryColor3fEXT_names, SecondaryColor3fEXT_remap_index, -1 }, + { SecondaryColor3svEXT_names, SecondaryColor3svEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_stencil_two_side) +static const struct dri_extension_function GL_EXT_stencil_two_side_functions[] = { + { ActiveStencilFaceEXT_names, ActiveStencilFaceEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_subtexture) +static const struct dri_extension_function GL_EXT_subtexture_functions[] = { + { TexSubImage1D_names, -1, 332 }, + { TexSubImage2D_names, -1, 333 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_texture3D) +static const struct dri_extension_function GL_EXT_texture3D_functions[] = { + { TexImage3D_names, -1, 371 }, + { TexSubImage3D_names, -1, 372 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_texture_array) +static const struct dri_extension_function GL_EXT_texture_array_functions[] = { + { FramebufferTextureLayerEXT_names, FramebufferTextureLayerEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_texture_object) +static const struct dri_extension_function GL_EXT_texture_object_functions[] = { + { PrioritizeTextures_names, -1, 331 }, + { AreTexturesResident_names, -1, 322 }, + { GenTextures_names, -1, 328 }, + { DeleteTextures_names, -1, 327 }, + { IsTexture_names, -1, 330 }, + { BindTexture_names, -1, 307 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_texture_perturb_normal) +static const struct dri_extension_function GL_EXT_texture_perturb_normal_functions[] = { + { TextureNormalEXT_names, TextureNormalEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_timer_query) +static const struct dri_extension_function GL_EXT_timer_query_functions[] = { + { GetQueryObjectui64vEXT_names, GetQueryObjectui64vEXT_remap_index, -1 }, + { GetQueryObjecti64vEXT_names, GetQueryObjecti64vEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_vertex_array) +static const struct dri_extension_function GL_EXT_vertex_array_functions[] = { + { IndexPointerEXT_names, IndexPointerEXT_remap_index, -1 }, + { NormalPointerEXT_names, NormalPointerEXT_remap_index, -1 }, + { VertexPointerEXT_names, VertexPointerEXT_remap_index, -1 }, + { TexCoordPointerEXT_names, TexCoordPointerEXT_remap_index, -1 }, + { EdgeFlagPointerEXT_names, EdgeFlagPointerEXT_remap_index, -1 }, + { ArrayElement_names, -1, 306 }, + { ColorPointerEXT_names, ColorPointerEXT_remap_index, -1 }, + { GetPointerv_names, -1, 329 }, + { DrawArrays_names, -1, 310 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_EXT_vertex_weighting) +static const struct dri_extension_function GL_EXT_vertex_weighting_functions[] = { + { VertexWeightfvEXT_names, VertexWeightfvEXT_remap_index, -1 }, + { VertexWeightfEXT_names, VertexWeightfEXT_remap_index, -1 }, + { VertexWeightPointerEXT_names, VertexWeightPointerEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_HP_image_transform) +static const struct dri_extension_function GL_HP_image_transform_functions[] = { + { GetImageTransformParameterfvHP_names, GetImageTransformParameterfvHP_remap_index, -1 }, + { ImageTransformParameterfHP_names, ImageTransformParameterfHP_remap_index, -1 }, + { ImageTransformParameterfvHP_names, ImageTransformParameterfvHP_remap_index, -1 }, + { ImageTransformParameteriHP_names, ImageTransformParameteriHP_remap_index, -1 }, + { GetImageTransformParameterivHP_names, GetImageTransformParameterivHP_remap_index, -1 }, + { ImageTransformParameterivHP_names, ImageTransformParameterivHP_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_IBM_multimode_draw_arrays) +static const struct dri_extension_function GL_IBM_multimode_draw_arrays_functions[] = { + { MultiModeDrawArraysIBM_names, MultiModeDrawArraysIBM_remap_index, -1 }, + { MultiModeDrawElementsIBM_names, MultiModeDrawElementsIBM_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_IBM_vertex_array_lists) +static const struct dri_extension_function GL_IBM_vertex_array_lists_functions[] = { + { SecondaryColorPointerListIBM_names, SecondaryColorPointerListIBM_remap_index, -1 }, + { NormalPointerListIBM_names, NormalPointerListIBM_remap_index, -1 }, + { FogCoordPointerListIBM_names, FogCoordPointerListIBM_remap_index, -1 }, + { VertexPointerListIBM_names, VertexPointerListIBM_remap_index, -1 }, + { ColorPointerListIBM_names, ColorPointerListIBM_remap_index, -1 }, + { TexCoordPointerListIBM_names, TexCoordPointerListIBM_remap_index, -1 }, + { IndexPointerListIBM_names, IndexPointerListIBM_remap_index, -1 }, + { EdgeFlagPointerListIBM_names, EdgeFlagPointerListIBM_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_INGR_blend_func_separate) +static const struct dri_extension_function GL_INGR_blend_func_separate_functions[] = { + { BlendFuncSeparateEXT_names, BlendFuncSeparateEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_INTEL_parallel_arrays) +static const struct dri_extension_function GL_INTEL_parallel_arrays_functions[] = { + { VertexPointervINTEL_names, VertexPointervINTEL_remap_index, -1 }, + { ColorPointervINTEL_names, ColorPointervINTEL_remap_index, -1 }, + { NormalPointervINTEL_names, NormalPointervINTEL_remap_index, -1 }, + { TexCoordPointervINTEL_names, TexCoordPointervINTEL_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_MESA_resize_buffers) +static const struct dri_extension_function GL_MESA_resize_buffers_functions[] = { + { ResizeBuffersMESA_names, ResizeBuffersMESA_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_MESA_shader_debug) +static const struct dri_extension_function GL_MESA_shader_debug_functions[] = { + { GetDebugLogLengthMESA_names, GetDebugLogLengthMESA_remap_index, -1 }, + { ClearDebugLogMESA_names, ClearDebugLogMESA_remap_index, -1 }, + { GetDebugLogMESA_names, GetDebugLogMESA_remap_index, -1 }, + { CreateDebugObjectMESA_names, CreateDebugObjectMESA_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_MESA_window_pos) +static const struct dri_extension_function GL_MESA_window_pos_functions[] = { + { WindowPos3fMESA_names, WindowPos3fMESA_remap_index, -1 }, + { WindowPos2dvMESA_names, WindowPos2dvMESA_remap_index, -1 }, + { WindowPos4svMESA_names, WindowPos4svMESA_remap_index, -1 }, + { WindowPos2svMESA_names, WindowPos2svMESA_remap_index, -1 }, + { WindowPos3dMESA_names, WindowPos3dMESA_remap_index, -1 }, + { WindowPos2fvMESA_names, WindowPos2fvMESA_remap_index, -1 }, + { WindowPos4dMESA_names, WindowPos4dMESA_remap_index, -1 }, + { WindowPos2dMESA_names, WindowPos2dMESA_remap_index, -1 }, + { WindowPos4ivMESA_names, WindowPos4ivMESA_remap_index, -1 }, + { WindowPos4fMESA_names, WindowPos4fMESA_remap_index, -1 }, + { WindowPos3dvMESA_names, WindowPos3dvMESA_remap_index, -1 }, + { WindowPos3fvMESA_names, WindowPos3fvMESA_remap_index, -1 }, + { WindowPos4dvMESA_names, WindowPos4dvMESA_remap_index, -1 }, + { WindowPos2iMESA_names, WindowPos2iMESA_remap_index, -1 }, + { WindowPos3sMESA_names, WindowPos3sMESA_remap_index, -1 }, + { WindowPos4sMESA_names, WindowPos4sMESA_remap_index, -1 }, + { WindowPos2ivMESA_names, WindowPos2ivMESA_remap_index, -1 }, + { WindowPos2sMESA_names, WindowPos2sMESA_remap_index, -1 }, + { WindowPos3iMESA_names, WindowPos3iMESA_remap_index, -1 }, + { WindowPos3ivMESA_names, WindowPos3ivMESA_remap_index, -1 }, + { WindowPos4iMESA_names, WindowPos4iMESA_remap_index, -1 }, + { WindowPos4fvMESA_names, WindowPos4fvMESA_remap_index, -1 }, + { WindowPos3svMESA_names, WindowPos3svMESA_remap_index, -1 }, + { WindowPos2fMESA_names, WindowPos2fMESA_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_evaluators) +static const struct dri_extension_function GL_NV_evaluators_functions[] = { + { GetMapAttribParameterivNV_names, GetMapAttribParameterivNV_remap_index, -1 }, + { MapControlPointsNV_names, MapControlPointsNV_remap_index, -1 }, + { MapParameterfvNV_names, MapParameterfvNV_remap_index, -1 }, + { EvalMapsNV_names, EvalMapsNV_remap_index, -1 }, + { GetMapAttribParameterfvNV_names, GetMapAttribParameterfvNV_remap_index, -1 }, + { MapParameterivNV_names, MapParameterivNV_remap_index, -1 }, + { GetMapParameterivNV_names, GetMapParameterivNV_remap_index, -1 }, + { GetMapParameterfvNV_names, GetMapParameterfvNV_remap_index, -1 }, + { GetMapControlPointsNV_names, GetMapControlPointsNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_fence) +static const struct dri_extension_function GL_NV_fence_functions[] = { + { GenFencesNV_names, GenFencesNV_remap_index, -1 }, + { TestFenceNV_names, TestFenceNV_remap_index, -1 }, + { IsFenceNV_names, IsFenceNV_remap_index, -1 }, + { DeleteFencesNV_names, DeleteFencesNV_remap_index, -1 }, + { SetFenceNV_names, SetFenceNV_remap_index, -1 }, + { GetFenceivNV_names, GetFenceivNV_remap_index, -1 }, + { FinishFenceNV_names, FinishFenceNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_fragment_program) +static const struct dri_extension_function GL_NV_fragment_program_functions[] = { + { GetProgramNamedParameterdvNV_names, GetProgramNamedParameterdvNV_remap_index, -1 }, + { GetProgramNamedParameterfvNV_names, GetProgramNamedParameterfvNV_remap_index, -1 }, + { ProgramNamedParameter4fNV_names, ProgramNamedParameter4fNV_remap_index, -1 }, + { ProgramNamedParameter4fvNV_names, ProgramNamedParameter4fvNV_remap_index, -1 }, + { ProgramNamedParameter4dvNV_names, ProgramNamedParameter4dvNV_remap_index, -1 }, + { ProgramNamedParameter4dNV_names, ProgramNamedParameter4dNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_point_sprite) +static const struct dri_extension_function GL_NV_point_sprite_functions[] = { + { PointParameteriNV_names, PointParameteriNV_remap_index, -1 }, + { PointParameterivNV_names, PointParameterivNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_register_combiners) +static const struct dri_extension_function GL_NV_register_combiners_functions[] = { + { CombinerOutputNV_names, CombinerOutputNV_remap_index, -1 }, + { CombinerParameterfvNV_names, CombinerParameterfvNV_remap_index, -1 }, + { GetCombinerOutputParameterfvNV_names, GetCombinerOutputParameterfvNV_remap_index, -1 }, + { FinalCombinerInputNV_names, FinalCombinerInputNV_remap_index, -1 }, + { GetCombinerInputParameterfvNV_names, GetCombinerInputParameterfvNV_remap_index, -1 }, + { GetCombinerOutputParameterivNV_names, GetCombinerOutputParameterivNV_remap_index, -1 }, + { CombinerParameteriNV_names, CombinerParameteriNV_remap_index, -1 }, + { GetFinalCombinerInputParameterivNV_names, GetFinalCombinerInputParameterivNV_remap_index, -1 }, + { CombinerInputNV_names, CombinerInputNV_remap_index, -1 }, + { CombinerParameterfNV_names, CombinerParameterfNV_remap_index, -1 }, + { GetFinalCombinerInputParameterfvNV_names, GetFinalCombinerInputParameterfvNV_remap_index, -1 }, + { GetCombinerInputParameterivNV_names, GetCombinerInputParameterivNV_remap_index, -1 }, + { CombinerParameterivNV_names, CombinerParameterivNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_register_combiners2) +static const struct dri_extension_function GL_NV_register_combiners2_functions[] = { + { CombinerStageParameterfvNV_names, CombinerStageParameterfvNV_remap_index, -1 }, + { GetCombinerStageParameterfvNV_names, GetCombinerStageParameterfvNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_vertex_array_range) +static const struct dri_extension_function GL_NV_vertex_array_range_functions[] = { + { VertexArrayRangeNV_names, VertexArrayRangeNV_remap_index, -1 }, + { FlushVertexArrayRangeNV_names, FlushVertexArrayRangeNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_NV_vertex_program) +static const struct dri_extension_function GL_NV_vertex_program_functions[] = { + { VertexAttrib4ubvNV_names, VertexAttrib4ubvNV_remap_index, -1 }, + { VertexAttrib4svNV_names, VertexAttrib4svNV_remap_index, -1 }, + { VertexAttribs1dvNV_names, VertexAttribs1dvNV_remap_index, -1 }, + { VertexAttrib1fvNV_names, VertexAttrib1fvNV_remap_index, -1 }, + { VertexAttrib4fNV_names, VertexAttrib4fNV_remap_index, -1 }, + { VertexAttrib2dNV_names, VertexAttrib2dNV_remap_index, -1 }, + { VertexAttrib4ubNV_names, VertexAttrib4ubNV_remap_index, -1 }, + { VertexAttribs3dvNV_names, VertexAttribs3dvNV_remap_index, -1 }, + { VertexAttribs4fvNV_names, VertexAttribs4fvNV_remap_index, -1 }, + { VertexAttrib2sNV_names, VertexAttrib2sNV_remap_index, -1 }, + { VertexAttribs3fvNV_names, VertexAttribs3fvNV_remap_index, -1 }, + { ProgramEnvParameter4fvARB_names, ProgramEnvParameter4fvARB_remap_index, -1 }, + { LoadProgramNV_names, LoadProgramNV_remap_index, -1 }, + { VertexAttrib4fvNV_names, VertexAttrib4fvNV_remap_index, -1 }, + { VertexAttrib3fNV_names, VertexAttrib3fNV_remap_index, -1 }, + { VertexAttribs2dvNV_names, VertexAttribs2dvNV_remap_index, -1 }, + { GetProgramParameterfvNV_names, GetProgramParameterfvNV_remap_index, -1 }, + { VertexAttrib3dNV_names, VertexAttrib3dNV_remap_index, -1 }, + { VertexAttrib2fvNV_names, VertexAttrib2fvNV_remap_index, -1 }, + { VertexAttrib2dvNV_names, VertexAttrib2dvNV_remap_index, -1 }, + { VertexAttrib1dvNV_names, VertexAttrib1dvNV_remap_index, -1 }, + { VertexAttrib1svNV_names, VertexAttrib1svNV_remap_index, -1 }, + { ProgramEnvParameter4fARB_names, ProgramEnvParameter4fARB_remap_index, -1 }, + { VertexAttribs2svNV_names, VertexAttribs2svNV_remap_index, -1 }, + { GetVertexAttribivNV_names, GetVertexAttribivNV_remap_index, -1 }, + { GetVertexAttribfvNV_names, GetVertexAttribfvNV_remap_index, -1 }, + { VertexAttrib2svNV_names, VertexAttrib2svNV_remap_index, -1 }, + { VertexAttribs1fvNV_names, VertexAttribs1fvNV_remap_index, -1 }, + { IsProgramNV_names, IsProgramNV_remap_index, -1 }, + { ProgramEnvParameter4dARB_names, ProgramEnvParameter4dARB_remap_index, -1 }, + { VertexAttrib2fNV_names, VertexAttrib2fNV_remap_index, -1 }, + { RequestResidentProgramsNV_names, RequestResidentProgramsNV_remap_index, -1 }, + { ExecuteProgramNV_names, ExecuteProgramNV_remap_index, -1 }, + { VertexAttribPointerNV_names, VertexAttribPointerNV_remap_index, -1 }, + { TrackMatrixNV_names, TrackMatrixNV_remap_index, -1 }, + { GetProgramParameterdvNV_names, GetProgramParameterdvNV_remap_index, -1 }, + { GetTrackMatrixivNV_names, GetTrackMatrixivNV_remap_index, -1 }, + { VertexAttrib3svNV_names, VertexAttrib3svNV_remap_index, -1 }, + { ProgramParameters4fvNV_names, ProgramParameters4fvNV_remap_index, -1 }, + { GetProgramivNV_names, GetProgramivNV_remap_index, -1 }, + { GetVertexAttribdvNV_names, GetVertexAttribdvNV_remap_index, -1 }, + { VertexAttrib3fvNV_names, VertexAttrib3fvNV_remap_index, -1 }, + { ProgramEnvParameter4dvARB_names, ProgramEnvParameter4dvARB_remap_index, -1 }, + { VertexAttribs2fvNV_names, VertexAttribs2fvNV_remap_index, -1 }, + { DeleteProgramsNV_names, DeleteProgramsNV_remap_index, -1 }, + { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 }, + { GetProgramStringNV_names, GetProgramStringNV_remap_index, -1 }, + { VertexAttrib4sNV_names, VertexAttrib4sNV_remap_index, -1 }, + { VertexAttribs4dvNV_names, VertexAttribs4dvNV_remap_index, -1 }, + { ProgramParameters4dvNV_names, ProgramParameters4dvNV_remap_index, -1 }, + { VertexAttrib3sNV_names, VertexAttrib3sNV_remap_index, -1 }, + { VertexAttrib1fNV_names, VertexAttrib1fNV_remap_index, -1 }, + { VertexAttrib4dNV_names, VertexAttrib4dNV_remap_index, -1 }, + { VertexAttribs4ubvNV_names, VertexAttribs4ubvNV_remap_index, -1 }, + { VertexAttribs3svNV_names, VertexAttribs3svNV_remap_index, -1 }, + { VertexAttrib1sNV_names, VertexAttrib1sNV_remap_index, -1 }, + { BindProgramNV_names, BindProgramNV_remap_index, -1 }, + { AreProgramsResidentNV_names, AreProgramsResidentNV_remap_index, -1 }, + { VertexAttrib3dvNV_names, VertexAttrib3dvNV_remap_index, -1 }, + { VertexAttrib1dNV_names, VertexAttrib1dNV_remap_index, -1 }, + { VertexAttribs4svNV_names, VertexAttribs4svNV_remap_index, -1 }, + { VertexAttribs1svNV_names, VertexAttribs1svNV_remap_index, -1 }, + { GenProgramsNV_names, GenProgramsNV_remap_index, -1 }, + { VertexAttrib4dvNV_names, VertexAttrib4dvNV_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_PGI_misc_hints) +static const struct dri_extension_function GL_PGI_misc_hints_functions[] = { + { HintPGI_names, HintPGI_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_detail_texture) +static const struct dri_extension_function GL_SGIS_detail_texture_functions[] = { + { GetDetailTexFuncSGIS_names, GetDetailTexFuncSGIS_remap_index, -1 }, + { DetailTexFuncSGIS_names, DetailTexFuncSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_fog_function) +static const struct dri_extension_function GL_SGIS_fog_function_functions[] = { + { FogFuncSGIS_names, FogFuncSGIS_remap_index, -1 }, + { GetFogFuncSGIS_names, GetFogFuncSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_multisample) +static const struct dri_extension_function GL_SGIS_multisample_functions[] = { + { SampleMaskSGIS_names, SampleMaskSGIS_remap_index, -1 }, + { SamplePatternSGIS_names, SamplePatternSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_pixel_texture) +static const struct dri_extension_function GL_SGIS_pixel_texture_functions[] = { + { PixelTexGenParameterfvSGIS_names, PixelTexGenParameterfvSGIS_remap_index, -1 }, + { GetPixelTexGenParameterivSGIS_names, GetPixelTexGenParameterivSGIS_remap_index, -1 }, + { PixelTexGenParameteriSGIS_names, PixelTexGenParameteriSGIS_remap_index, -1 }, + { PixelTexGenParameterivSGIS_names, PixelTexGenParameterivSGIS_remap_index, -1 }, + { PixelTexGenParameterfSGIS_names, PixelTexGenParameterfSGIS_remap_index, -1 }, + { GetPixelTexGenParameterfvSGIS_names, GetPixelTexGenParameterfvSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_point_parameters) +static const struct dri_extension_function GL_SGIS_point_parameters_functions[] = { + { PointParameterfEXT_names, PointParameterfEXT_remap_index, -1 }, + { PointParameterfvEXT_names, PointParameterfvEXT_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_sharpen_texture) +static const struct dri_extension_function GL_SGIS_sharpen_texture_functions[] = { + { GetSharpenTexFuncSGIS_names, GetSharpenTexFuncSGIS_remap_index, -1 }, + { SharpenTexFuncSGIS_names, SharpenTexFuncSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_texture4D) +static const struct dri_extension_function GL_SGIS_texture4D_functions[] = { + { TexImage4DSGIS_names, TexImage4DSGIS_remap_index, -1 }, + { TexSubImage4DSGIS_names, TexSubImage4DSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_texture_color_mask) +static const struct dri_extension_function GL_SGIS_texture_color_mask_functions[] = { + { TextureColorMaskSGIS_names, TextureColorMaskSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIS_texture_filter4) +static const struct dri_extension_function GL_SGIS_texture_filter4_functions[] = { + { GetTexFilterFuncSGIS_names, GetTexFilterFuncSGIS_remap_index, -1 }, + { TexFilterFuncSGIS_names, TexFilterFuncSGIS_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_async) +static const struct dri_extension_function GL_SGIX_async_functions[] = { + { AsyncMarkerSGIX_names, AsyncMarkerSGIX_remap_index, -1 }, + { FinishAsyncSGIX_names, FinishAsyncSGIX_remap_index, -1 }, + { PollAsyncSGIX_names, PollAsyncSGIX_remap_index, -1 }, + { DeleteAsyncMarkersSGIX_names, DeleteAsyncMarkersSGIX_remap_index, -1 }, + { IsAsyncMarkerSGIX_names, IsAsyncMarkerSGIX_remap_index, -1 }, + { GenAsyncMarkersSGIX_names, GenAsyncMarkersSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_flush_raster) +static const struct dri_extension_function GL_SGIX_flush_raster_functions[] = { + { FlushRasterSGIX_names, FlushRasterSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_fragment_lighting) +static const struct dri_extension_function GL_SGIX_fragment_lighting_functions[] = { + { FragmentMaterialfvSGIX_names, FragmentMaterialfvSGIX_remap_index, -1 }, + { FragmentLightModelivSGIX_names, FragmentLightModelivSGIX_remap_index, -1 }, + { FragmentLightiSGIX_names, FragmentLightiSGIX_remap_index, -1 }, + { GetFragmentMaterialfvSGIX_names, GetFragmentMaterialfvSGIX_remap_index, -1 }, + { FragmentMaterialfSGIX_names, FragmentMaterialfSGIX_remap_index, -1 }, + { GetFragmentLightivSGIX_names, GetFragmentLightivSGIX_remap_index, -1 }, + { FragmentLightModeliSGIX_names, FragmentLightModeliSGIX_remap_index, -1 }, + { FragmentLightivSGIX_names, FragmentLightivSGIX_remap_index, -1 }, + { GetFragmentMaterialivSGIX_names, GetFragmentMaterialivSGIX_remap_index, -1 }, + { FragmentLightModelfSGIX_names, FragmentLightModelfSGIX_remap_index, -1 }, + { FragmentColorMaterialSGIX_names, FragmentColorMaterialSGIX_remap_index, -1 }, + { FragmentMaterialiSGIX_names, FragmentMaterialiSGIX_remap_index, -1 }, + { LightEnviSGIX_names, LightEnviSGIX_remap_index, -1 }, + { FragmentLightModelfvSGIX_names, FragmentLightModelfvSGIX_remap_index, -1 }, + { FragmentLightfvSGIX_names, FragmentLightfvSGIX_remap_index, -1 }, + { FragmentLightfSGIX_names, FragmentLightfSGIX_remap_index, -1 }, + { GetFragmentLightfvSGIX_names, GetFragmentLightfvSGIX_remap_index, -1 }, + { FragmentMaterialivSGIX_names, FragmentMaterialivSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_framezoom) +static const struct dri_extension_function GL_SGIX_framezoom_functions[] = { + { FrameZoomSGIX_names, FrameZoomSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_igloo_interface) +static const struct dri_extension_function GL_SGIX_igloo_interface_functions[] = { + { IglooInterfaceSGIX_names, IglooInterfaceSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_instruments) +static const struct dri_extension_function GL_SGIX_instruments_functions[] = { + { ReadInstrumentsSGIX_names, ReadInstrumentsSGIX_remap_index, -1 }, + { PollInstrumentsSGIX_names, PollInstrumentsSGIX_remap_index, -1 }, + { GetInstrumentsSGIX_names, GetInstrumentsSGIX_remap_index, -1 }, + { StartInstrumentsSGIX_names, StartInstrumentsSGIX_remap_index, -1 }, + { StopInstrumentsSGIX_names, StopInstrumentsSGIX_remap_index, -1 }, + { InstrumentsBufferSGIX_names, InstrumentsBufferSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_list_priority) +static const struct dri_extension_function GL_SGIX_list_priority_functions[] = { + { ListParameterfSGIX_names, ListParameterfSGIX_remap_index, -1 }, + { GetListParameterfvSGIX_names, GetListParameterfvSGIX_remap_index, -1 }, + { ListParameteriSGIX_names, ListParameteriSGIX_remap_index, -1 }, + { ListParameterfvSGIX_names, ListParameterfvSGIX_remap_index, -1 }, + { ListParameterivSGIX_names, ListParameterivSGIX_remap_index, -1 }, + { GetListParameterivSGIX_names, GetListParameterivSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_pixel_texture) +static const struct dri_extension_function GL_SGIX_pixel_texture_functions[] = { + { PixelTexGenSGIX_names, PixelTexGenSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_polynomial_ffd) +static const struct dri_extension_function GL_SGIX_polynomial_ffd_functions[] = { + { LoadIdentityDeformationMapSGIX_names, LoadIdentityDeformationMapSGIX_remap_index, -1 }, + { DeformationMap3dSGIX_names, DeformationMap3dSGIX_remap_index, -1 }, + { DeformSGIX_names, DeformSGIX_remap_index, -1 }, + { DeformationMap3fSGIX_names, DeformationMap3fSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_reference_plane) +static const struct dri_extension_function GL_SGIX_reference_plane_functions[] = { + { ReferencePlaneSGIX_names, ReferencePlaneSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_sprite) +static const struct dri_extension_function GL_SGIX_sprite_functions[] = { + { SpriteParameterfvSGIX_names, SpriteParameterfvSGIX_remap_index, -1 }, + { SpriteParameteriSGIX_names, SpriteParameteriSGIX_remap_index, -1 }, + { SpriteParameterfSGIX_names, SpriteParameterfSGIX_remap_index, -1 }, + { SpriteParameterivSGIX_names, SpriteParameterivSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGIX_tag_sample_buffer) +static const struct dri_extension_function GL_SGIX_tag_sample_buffer_functions[] = { + { TagSampleBufferSGIX_names, TagSampleBufferSGIX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SGI_color_table) +static const struct dri_extension_function GL_SGI_color_table_functions[] = { + { ColorTableParameteriv_names, -1, 341 }, + { ColorTable_names, -1, 339 }, + { GetColorTable_names, -1, 343 }, + { CopyColorTable_names, -1, 342 }, + { ColorTableParameterfv_names, -1, 340 }, + { GetColorTableParameterfv_names, -1, 344 }, + { GetColorTableParameteriv_names, -1, 345 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SUNX_constant_data) +static const struct dri_extension_function GL_SUNX_constant_data_functions[] = { + { FinishTextureSUNX_names, FinishTextureSUNX_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SUN_global_alpha) +static const struct dri_extension_function GL_SUN_global_alpha_functions[] = { + { GlobalAlphaFactorubSUN_names, GlobalAlphaFactorubSUN_remap_index, -1 }, + { GlobalAlphaFactoriSUN_names, GlobalAlphaFactoriSUN_remap_index, -1 }, + { GlobalAlphaFactordSUN_names, GlobalAlphaFactordSUN_remap_index, -1 }, + { GlobalAlphaFactoruiSUN_names, GlobalAlphaFactoruiSUN_remap_index, -1 }, + { GlobalAlphaFactorbSUN_names, GlobalAlphaFactorbSUN_remap_index, -1 }, + { GlobalAlphaFactorfSUN_names, GlobalAlphaFactorfSUN_remap_index, -1 }, + { GlobalAlphaFactorusSUN_names, GlobalAlphaFactorusSUN_remap_index, -1 }, + { GlobalAlphaFactorsSUN_names, GlobalAlphaFactorsSUN_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SUN_mesh_array) +static const struct dri_extension_function GL_SUN_mesh_array_functions[] = { + { DrawMeshArraysSUN_names, DrawMeshArraysSUN_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SUN_triangle_list) +static const struct dri_extension_function GL_SUN_triangle_list_functions[] = { + { ReplacementCodeubSUN_names, ReplacementCodeubSUN_remap_index, -1 }, + { ReplacementCodeubvSUN_names, ReplacementCodeubvSUN_remap_index, -1 }, + { ReplacementCodeusvSUN_names, ReplacementCodeusvSUN_remap_index, -1 }, + { ReplacementCodePointerSUN_names, ReplacementCodePointerSUN_remap_index, -1 }, + { ReplacementCodeusSUN_names, ReplacementCodeusSUN_remap_index, -1 }, + { ReplacementCodeuiSUN_names, ReplacementCodeuiSUN_remap_index, -1 }, + { ReplacementCodeuivSUN_names, ReplacementCodeuivSUN_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_SUN_vertex) +static const struct dri_extension_function GL_SUN_vertex_functions[] = { + { ReplacementCodeuiColor3fVertex3fvSUN_names, ReplacementCodeuiColor3fVertex3fvSUN_remap_index, -1 }, + { TexCoord4fColor4fNormal3fVertex4fvSUN_names, TexCoord4fColor4fNormal3fVertex4fvSUN_remap_index, -1 }, + { TexCoord2fColor4ubVertex3fvSUN_names, TexCoord2fColor4ubVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiVertex3fvSUN_names, ReplacementCodeuiVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiTexCoord2fVertex3fvSUN_names, ReplacementCodeuiTexCoord2fVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiNormal3fVertex3fSUN_names, ReplacementCodeuiNormal3fVertex3fSUN_remap_index, -1 }, + { Color4ubVertex3fvSUN_names, Color4ubVertex3fvSUN_remap_index, -1 }, + { Color4ubVertex3fSUN_names, Color4ubVertex3fSUN_remap_index, -1 }, + { TexCoord2fVertex3fSUN_names, TexCoord2fVertex3fSUN_remap_index, -1 }, + { TexCoord2fColor4fNormal3fVertex3fSUN_names, TexCoord2fColor4fNormal3fVertex3fSUN_remap_index, -1 }, + { TexCoord2fNormal3fVertex3fvSUN_names, TexCoord2fNormal3fVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN_names, ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN_remap_index, -1 }, + { ReplacementCodeuiTexCoord2fVertex3fSUN_names, ReplacementCodeuiTexCoord2fVertex3fSUN_remap_index, -1 }, + { TexCoord2fNormal3fVertex3fSUN_names, TexCoord2fNormal3fVertex3fSUN_remap_index, -1 }, + { Color3fVertex3fSUN_names, Color3fVertex3fSUN_remap_index, -1 }, + { Color3fVertex3fvSUN_names, Color3fVertex3fvSUN_remap_index, -1 }, + { Color4fNormal3fVertex3fvSUN_names, Color4fNormal3fVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_names, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiColor4fNormal3fVertex3fvSUN_names, ReplacementCodeuiColor4fNormal3fVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN_names, ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN_remap_index, -1 }, + { TexCoord2fColor3fVertex3fSUN_names, TexCoord2fColor3fVertex3fSUN_remap_index, -1 }, + { TexCoord4fColor4fNormal3fVertex4fSUN_names, TexCoord4fColor4fNormal3fVertex4fSUN_remap_index, -1 }, + { Color4ubVertex2fvSUN_names, Color4ubVertex2fvSUN_remap_index, -1 }, + { Normal3fVertex3fSUN_names, Normal3fVertex3fSUN_remap_index, -1 }, + { ReplacementCodeuiColor4fNormal3fVertex3fSUN_names, ReplacementCodeuiColor4fNormal3fVertex3fSUN_remap_index, -1 }, + { TexCoord2fColor4fNormal3fVertex3fvSUN_names, TexCoord2fColor4fNormal3fVertex3fvSUN_remap_index, -1 }, + { TexCoord2fVertex3fvSUN_names, TexCoord2fVertex3fvSUN_remap_index, -1 }, + { Color4ubVertex2fSUN_names, Color4ubVertex2fSUN_remap_index, -1 }, + { ReplacementCodeuiColor4ubVertex3fSUN_names, ReplacementCodeuiColor4ubVertex3fSUN_remap_index, -1 }, + { TexCoord2fColor4ubVertex3fSUN_names, TexCoord2fColor4ubVertex3fSUN_remap_index, -1 }, + { Normal3fVertex3fvSUN_names, Normal3fVertex3fvSUN_remap_index, -1 }, + { Color4fNormal3fVertex3fSUN_names, Color4fNormal3fVertex3fSUN_remap_index, -1 }, + { ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN_names, ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN_remap_index, -1 }, + { ReplacementCodeuiColor4ubVertex3fvSUN_names, ReplacementCodeuiColor4ubVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiColor3fVertex3fSUN_names, ReplacementCodeuiColor3fVertex3fSUN_remap_index, -1 }, + { TexCoord4fVertex4fSUN_names, TexCoord4fVertex4fSUN_remap_index, -1 }, + { TexCoord2fColor3fVertex3fvSUN_names, TexCoord2fColor3fVertex3fvSUN_remap_index, -1 }, + { ReplacementCodeuiNormal3fVertex3fvSUN_names, ReplacementCodeuiNormal3fVertex3fvSUN_remap_index, -1 }, + { TexCoord4fVertex4fvSUN_names, TexCoord4fVertex4fvSUN_remap_index, -1 }, + { ReplacementCodeuiVertex3fSUN_names, ReplacementCodeuiVertex3fSUN_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_VERSION_1_3) +static const struct dri_extension_function GL_VERSION_1_3_functions[] = { + { SampleCoverageARB_names, SampleCoverageARB_remap_index, -1 }, + { MultiTexCoord3sARB_names, -1, 398 }, + { ActiveTextureARB_names, -1, 374 }, + { CompressedTexSubImage2DARB_names, CompressedTexSubImage2DARB_remap_index, -1 }, + { CompressedTexImage3DARB_names, CompressedTexImage3DARB_remap_index, -1 }, + { MultiTexCoord1fvARB_names, -1, 379 }, + { MultTransposeMatrixdARB_names, MultTransposeMatrixdARB_remap_index, -1 }, + { CompressedTexImage1DARB_names, CompressedTexImage1DARB_remap_index, -1 }, + { MultiTexCoord3dARB_names, -1, 392 }, + { MultiTexCoord2iARB_names, -1, 388 }, + { MultiTexCoord2svARB_names, -1, 391 }, + { MultiTexCoord2fARB_names, -1, 386 }, + { LoadTransposeMatrixdARB_names, LoadTransposeMatrixdARB_remap_index, -1 }, + { MultiTexCoord3fvARB_names, -1, 395 }, + { MultiTexCoord4sARB_names, -1, 406 }, + { MultiTexCoord2dvARB_names, -1, 385 }, + { MultiTexCoord1svARB_names, -1, 383 }, + { MultiTexCoord3svARB_names, -1, 399 }, + { MultiTexCoord4iARB_names, -1, 404 }, + { MultiTexCoord3iARB_names, -1, 396 }, + { MultiTexCoord1dARB_names, -1, 376 }, + { MultiTexCoord3dvARB_names, -1, 393 }, + { MultiTexCoord3ivARB_names, -1, 397 }, + { MultiTexCoord2sARB_names, -1, 390 }, + { MultiTexCoord4ivARB_names, -1, 405 }, + { CompressedTexSubImage1DARB_names, CompressedTexSubImage1DARB_remap_index, -1 }, + { ClientActiveTextureARB_names, -1, 375 }, + { CompressedTexSubImage3DARB_names, CompressedTexSubImage3DARB_remap_index, -1 }, + { MultiTexCoord2dARB_names, -1, 384 }, + { MultiTexCoord4dvARB_names, -1, 401 }, + { MultiTexCoord4fvARB_names, -1, 403 }, + { MultiTexCoord3fARB_names, -1, 394 }, + { MultTransposeMatrixfARB_names, MultTransposeMatrixfARB_remap_index, -1 }, + { CompressedTexImage2DARB_names, CompressedTexImage2DARB_remap_index, -1 }, + { MultiTexCoord4dARB_names, -1, 400 }, + { MultiTexCoord1sARB_names, -1, 382 }, + { MultiTexCoord1dvARB_names, -1, 377 }, + { MultiTexCoord1ivARB_names, -1, 381 }, + { MultiTexCoord2ivARB_names, -1, 389 }, + { MultiTexCoord1iARB_names, -1, 380 }, + { GetCompressedTexImageARB_names, GetCompressedTexImageARB_remap_index, -1 }, + { MultiTexCoord4svARB_names, -1, 407 }, + { MultiTexCoord1fARB_names, -1, 378 }, + { MultiTexCoord4fARB_names, -1, 402 }, + { LoadTransposeMatrixfARB_names, LoadTransposeMatrixfARB_remap_index, -1 }, + { MultiTexCoord2fvARB_names, -1, 387 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_VERSION_1_4) +static const struct dri_extension_function GL_VERSION_1_4_functions[] = { + { PointParameteriNV_names, PointParameteriNV_remap_index, -1 }, + { SecondaryColor3iEXT_names, SecondaryColor3iEXT_remap_index, -1 }, + { WindowPos3fMESA_names, WindowPos3fMESA_remap_index, -1 }, + { WindowPos2dvMESA_names, WindowPos2dvMESA_remap_index, -1 }, + { SecondaryColor3bEXT_names, SecondaryColor3bEXT_remap_index, -1 }, + { PointParameterfEXT_names, PointParameterfEXT_remap_index, -1 }, + { FogCoorddEXT_names, FogCoorddEXT_remap_index, -1 }, + { FogCoordfEXT_names, FogCoordfEXT_remap_index, -1 }, + { WindowPos2svMESA_names, WindowPos2svMESA_remap_index, -1 }, + { WindowPos3dMESA_names, WindowPos3dMESA_remap_index, -1 }, + { PointParameterfvEXT_names, PointParameterfvEXT_remap_index, -1 }, + { WindowPos2fvMESA_names, WindowPos2fvMESA_remap_index, -1 }, + { SecondaryColor3bvEXT_names, SecondaryColor3bvEXT_remap_index, -1 }, + { SecondaryColor3sEXT_names, SecondaryColor3sEXT_remap_index, -1 }, + { SecondaryColor3dEXT_names, SecondaryColor3dEXT_remap_index, -1 }, + { WindowPos2dMESA_names, WindowPos2dMESA_remap_index, -1 }, + { SecondaryColorPointerEXT_names, SecondaryColorPointerEXT_remap_index, -1 }, + { SecondaryColor3uiEXT_names, SecondaryColor3uiEXT_remap_index, -1 }, + { SecondaryColor3usvEXT_names, SecondaryColor3usvEXT_remap_index, -1 }, + { WindowPos3dvMESA_names, WindowPos3dvMESA_remap_index, -1 }, + { PointParameterivNV_names, PointParameterivNV_remap_index, -1 }, + { WindowPos3fvMESA_names, WindowPos3fvMESA_remap_index, -1 }, + { SecondaryColor3ivEXT_names, SecondaryColor3ivEXT_remap_index, -1 }, + { WindowPos2iMESA_names, WindowPos2iMESA_remap_index, -1 }, + { SecondaryColor3fvEXT_names, SecondaryColor3fvEXT_remap_index, -1 }, + { WindowPos3sMESA_names, WindowPos3sMESA_remap_index, -1 }, + { WindowPos2ivMESA_names, WindowPos2ivMESA_remap_index, -1 }, + { MultiDrawElementsEXT_names, MultiDrawElementsEXT_remap_index, -1 }, + { WindowPos2sMESA_names, WindowPos2sMESA_remap_index, -1 }, + { FogCoordPointerEXT_names, FogCoordPointerEXT_remap_index, -1 }, + { SecondaryColor3ubvEXT_names, SecondaryColor3ubvEXT_remap_index, -1 }, + { SecondaryColor3uivEXT_names, SecondaryColor3uivEXT_remap_index, -1 }, + { WindowPos3iMESA_names, WindowPos3iMESA_remap_index, -1 }, + { SecondaryColor3dvEXT_names, SecondaryColor3dvEXT_remap_index, -1 }, + { MultiDrawArraysEXT_names, MultiDrawArraysEXT_remap_index, -1 }, + { SecondaryColor3usEXT_names, SecondaryColor3usEXT_remap_index, -1 }, + { FogCoordfvEXT_names, FogCoordfvEXT_remap_index, -1 }, + { SecondaryColor3ubEXT_names, SecondaryColor3ubEXT_remap_index, -1 }, + { BlendFuncSeparateEXT_names, BlendFuncSeparateEXT_remap_index, -1 }, + { SecondaryColor3fEXT_names, SecondaryColor3fEXT_remap_index, -1 }, + { WindowPos3ivMESA_names, WindowPos3ivMESA_remap_index, -1 }, + { SecondaryColor3svEXT_names, SecondaryColor3svEXT_remap_index, -1 }, + { FogCoorddvEXT_names, FogCoorddvEXT_remap_index, -1 }, + { WindowPos3svMESA_names, WindowPos3svMESA_remap_index, -1 }, + { WindowPos2fMESA_names, WindowPos2fMESA_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_VERSION_1_5) +static const struct dri_extension_function GL_VERSION_1_5_functions[] = { + { BeginQueryARB_names, BeginQueryARB_remap_index, -1 }, + { GetBufferSubDataARB_names, GetBufferSubDataARB_remap_index, -1 }, + { BufferSubDataARB_names, BufferSubDataARB_remap_index, -1 }, + { GetQueryivARB_names, GetQueryivARB_remap_index, -1 }, + { GetQueryObjectivARB_names, GetQueryObjectivARB_remap_index, -1 }, + { BufferDataARB_names, BufferDataARB_remap_index, -1 }, + { EndQueryARB_names, EndQueryARB_remap_index, -1 }, + { GetBufferPointervARB_names, GetBufferPointervARB_remap_index, -1 }, + { GetQueryObjectuivARB_names, GetQueryObjectuivARB_remap_index, -1 }, + { GetBufferParameterivARB_names, GetBufferParameterivARB_remap_index, -1 }, + { DeleteQueriesARB_names, DeleteQueriesARB_remap_index, -1 }, + { IsQueryARB_names, IsQueryARB_remap_index, -1 }, + { MapBufferARB_names, MapBufferARB_remap_index, -1 }, + { GenQueriesARB_names, GenQueriesARB_remap_index, -1 }, + { IsBufferARB_names, IsBufferARB_remap_index, -1 }, + { DeleteBuffersARB_names, DeleteBuffersARB_remap_index, -1 }, + { UnmapBufferARB_names, UnmapBufferARB_remap_index, -1 }, + { BindBufferARB_names, BindBufferARB_remap_index, -1 }, + { GenBuffersARB_names, GenBuffersARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_VERSION_2_0) +static const struct dri_extension_function GL_VERSION_2_0_functions[] = { + { UniformMatrix3fvARB_names, UniformMatrix3fvARB_remap_index, -1 }, + { GetProgramiv_names, GetProgramiv_remap_index, -1 }, + { BlendEquationSeparateEXT_names, BlendEquationSeparateEXT_remap_index, -1 }, + { AttachShader_names, AttachShader_remap_index, -1 }, + { VertexAttrib2fARB_names, VertexAttrib2fARB_remap_index, -1 }, + { VertexAttrib3fARB_names, VertexAttrib3fARB_remap_index, -1 }, + { Uniform2fARB_names, Uniform2fARB_remap_index, -1 }, + { VertexAttrib1svARB_names, VertexAttrib1svARB_remap_index, -1 }, + { Uniform2ivARB_names, Uniform2ivARB_remap_index, -1 }, + { UniformMatrix4fvARB_names, UniformMatrix4fvARB_remap_index, -1 }, + { VertexAttrib4NusvARB_names, VertexAttrib4NusvARB_remap_index, -1 }, + { DisableVertexAttribArrayARB_names, DisableVertexAttribArrayARB_remap_index, -1 }, + { StencilMaskSeparate_names, StencilMaskSeparate_remap_index, -1 }, + { VertexAttrib1fARB_names, VertexAttrib1fARB_remap_index, -1 }, + { GetProgramInfoLog_names, GetProgramInfoLog_remap_index, -1 }, + { VertexAttrib4NbvARB_names, VertexAttrib4NbvARB_remap_index, -1 }, + { GetActiveAttribARB_names, GetActiveAttribARB_remap_index, -1 }, + { Uniform3iARB_names, Uniform3iARB_remap_index, -1 }, + { GetShaderInfoLog_names, GetShaderInfoLog_remap_index, -1 }, + { VertexAttrib1sARB_names, VertexAttrib1sARB_remap_index, -1 }, + { Uniform1fARB_names, Uniform1fARB_remap_index, -1 }, + { StencilOpSeparate_names, StencilOpSeparate_remap_index, -1 }, + { UniformMatrix2fvARB_names, UniformMatrix2fvARB_remap_index, -1 }, + { VertexAttrib3dvARB_names, VertexAttrib3dvARB_remap_index, -1 }, + { Uniform3fvARB_names, Uniform3fvARB_remap_index, -1 }, + { GetVertexAttribivARB_names, GetVertexAttribivARB_remap_index, -1 }, + { CreateProgram_names, CreateProgram_remap_index, -1 }, + { StencilFuncSeparate_names, StencilFuncSeparate_remap_index, -1 }, + { VertexAttrib4ivARB_names, VertexAttrib4ivARB_remap_index, -1 }, + { VertexAttrib4bvARB_names, VertexAttrib4bvARB_remap_index, -1 }, + { VertexAttrib3dARB_names, VertexAttrib3dARB_remap_index, -1 }, + { VertexAttrib4fARB_names, VertexAttrib4fARB_remap_index, -1 }, + { VertexAttrib4fvARB_names, VertexAttrib4fvARB_remap_index, -1 }, + { GetActiveUniformARB_names, GetActiveUniformARB_remap_index, -1 }, + { IsShader_names, IsShader_remap_index, -1 }, + { GetUniformivARB_names, GetUniformivARB_remap_index, -1 }, + { IsProgram_names, IsProgram_remap_index, -1 }, + { Uniform2fvARB_names, Uniform2fvARB_remap_index, -1 }, + { ValidateProgramARB_names, ValidateProgramARB_remap_index, -1 }, + { VertexAttrib2dARB_names, VertexAttrib2dARB_remap_index, -1 }, + { VertexAttrib1dvARB_names, VertexAttrib1dvARB_remap_index, -1 }, + { GetVertexAttribfvARB_names, GetVertexAttribfvARB_remap_index, -1 }, + { GetAttribLocationARB_names, GetAttribLocationARB_remap_index, -1 }, + { VertexAttrib4ubvARB_names, VertexAttrib4ubvARB_remap_index, -1 }, + { Uniform3ivARB_names, Uniform3ivARB_remap_index, -1 }, + { VertexAttrib4sARB_names, VertexAttrib4sARB_remap_index, -1 }, + { VertexAttrib2dvARB_names, VertexAttrib2dvARB_remap_index, -1 }, + { VertexAttrib2fvARB_names, VertexAttrib2fvARB_remap_index, -1 }, + { VertexAttrib4NivARB_names, VertexAttrib4NivARB_remap_index, -1 }, + { GetAttachedShaders_names, GetAttachedShaders_remap_index, -1 }, + { CompileShaderARB_names, CompileShaderARB_remap_index, -1 }, + { DeleteShader_names, DeleteShader_remap_index, -1 }, + { Uniform3fARB_names, Uniform3fARB_remap_index, -1 }, + { VertexAttrib4NuivARB_names, VertexAttrib4NuivARB_remap_index, -1 }, + { Uniform4fARB_names, Uniform4fARB_remap_index, -1 }, + { VertexAttrib1dARB_names, VertexAttrib1dARB_remap_index, -1 }, + { VertexAttrib4usvARB_names, VertexAttrib4usvARB_remap_index, -1 }, + { LinkProgramARB_names, LinkProgramARB_remap_index, -1 }, + { ShaderSourceARB_names, ShaderSourceARB_remap_index, -1 }, + { VertexAttrib3svARB_names, VertexAttrib3svARB_remap_index, -1 }, + { Uniform4ivARB_names, Uniform4ivARB_remap_index, -1 }, + { GetVertexAttribdvARB_names, GetVertexAttribdvARB_remap_index, -1 }, + { Uniform1ivARB_names, Uniform1ivARB_remap_index, -1 }, + { VertexAttrib4dvARB_names, VertexAttrib4dvARB_remap_index, -1 }, + { BindAttribLocationARB_names, BindAttribLocationARB_remap_index, -1 }, + { Uniform1iARB_names, Uniform1iARB_remap_index, -1 }, + { VertexAttribPointerARB_names, VertexAttribPointerARB_remap_index, -1 }, + { VertexAttrib4NsvARB_names, VertexAttrib4NsvARB_remap_index, -1 }, + { VertexAttrib3fvARB_names, VertexAttrib3fvARB_remap_index, -1 }, + { CreateShader_names, CreateShader_remap_index, -1 }, + { DetachShader_names, DetachShader_remap_index, -1 }, + { VertexAttrib4NubARB_names, VertexAttrib4NubARB_remap_index, -1 }, + { Uniform4fvARB_names, Uniform4fvARB_remap_index, -1 }, + { GetUniformfvARB_names, GetUniformfvARB_remap_index, -1 }, + { Uniform4iARB_names, Uniform4iARB_remap_index, -1 }, + { UseProgramObjectARB_names, UseProgramObjectARB_remap_index, -1 }, + { DeleteProgram_names, DeleteProgram_remap_index, -1 }, + { GetVertexAttribPointervNV_names, GetVertexAttribPointervNV_remap_index, -1 }, + { Uniform2iARB_names, Uniform2iARB_remap_index, -1 }, + { VertexAttrib4dARB_names, VertexAttrib4dARB_remap_index, -1 }, + { GetUniformLocationARB_names, GetUniformLocationARB_remap_index, -1 }, + { VertexAttrib3sARB_names, VertexAttrib3sARB_remap_index, -1 }, + { GetShaderSourceARB_names, GetShaderSourceARB_remap_index, -1 }, + { DrawBuffersARB_names, DrawBuffersARB_remap_index, -1 }, + { Uniform1fvARB_names, Uniform1fvARB_remap_index, -1 }, + { EnableVertexAttribArrayARB_names, EnableVertexAttribArrayARB_remap_index, -1 }, + { VertexAttrib4uivARB_names, VertexAttrib4uivARB_remap_index, -1 }, + { VertexAttrib4svARB_names, VertexAttrib4svARB_remap_index, -1 }, + { GetShaderiv_names, GetShaderiv_remap_index, -1 }, + { VertexAttrib2svARB_names, VertexAttrib2svARB_remap_index, -1 }, + { VertexAttrib4NubvARB_names, VertexAttrib4NubvARB_remap_index, -1 }, + { VertexAttrib2sARB_names, VertexAttrib2sARB_remap_index, -1 }, + { VertexAttrib1fvARB_names, VertexAttrib1fvARB_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + +#if defined(need_GL_VERSION_2_1) +static const struct dri_extension_function GL_VERSION_2_1_functions[] = { + { UniformMatrix2x4fv_names, UniformMatrix2x4fv_remap_index, -1 }, + { UniformMatrix4x3fv_names, UniformMatrix4x3fv_remap_index, -1 }, + { UniformMatrix4x2fv_names, UniformMatrix4x2fv_remap_index, -1 }, + { UniformMatrix2x3fv_names, UniformMatrix2x3fv_remap_index, -1 }, + { UniformMatrix3x4fv_names, UniformMatrix3x4fv_remap_index, -1 }, + { UniformMatrix3x2fv_names, UniformMatrix3x2fv_remap_index, -1 }, + { NULL, 0, 0 } +}; +#endif + diff --git a/mesalib/src/mesa/drivers/dri/common/memops.h b/mesalib/src/mesa/drivers/dri/common/memops.h new file mode 100644 index 000000000..9cd1d8ec3 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/memops.h @@ -0,0 +1,17 @@ +#ifndef DRIMEMSETIO_H +#define DRIMEMSETIO_H +/* +* memset an area in I/O space +* We need to be careful about this on some archs +*/ +static INLINE void drimemsetio(void* address, int c, int size) +{ +#if defined(__powerpc__) || defined(__ia64__) + int i; + for(i=0;i<size;i++) + *((char *)address + i)=c; +#else + memset(address,c,size); +#endif +} +#endif diff --git a/mesalib/src/mesa/drivers/dri/common/mmio.h b/mesalib/src/mesa/drivers/dri/common/mmio.h new file mode 100644 index 000000000..ce95d8c90 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/mmio.h @@ -0,0 +1,62 @@ +/* + * (C) Copyright IBM Corporation 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 + * 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 mmio.h + * Functions for properly handling memory mapped IO on various platforms. + * + * \author Ian Romanick <idr@us.ibm.com> + */ + + +#ifndef MMIO_H +#define MMIO_H + +#include "main/glheader.h" + +#if defined( __powerpc__ ) + +static INLINE uint32_t +read_MMIO_LE32( volatile void * base, unsigned long offset ) +{ + uint32_t val; + + __asm__ __volatile__( "lwbrx %0, %1, %2 ; eieio" + : "=r" (val) + : "b" (base), "r" (offset) ); + return val; +} + +#else + +static INLINE uint32_t +read_MMIO_LE32( volatile void * base, unsigned long offset ) +{ + volatile uint32_t * p = (volatile uint32_t *) (((volatile char *) base) + offset); + return LE32_TO_CPU( p[0] ); +} + +#endif + +#endif /* MMIO_H */ diff --git a/mesalib/src/mesa/drivers/dri/common/mmx.h b/mesalib/src/mesa/drivers/dri/common/mmx.h new file mode 100644 index 000000000..49ce7e3e3 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/mmx.h @@ -0,0 +1,560 @@ +/* mmx.h + + MultiMedia eXtensions GCC interface library for IA32. + + To use this library, simply include this header file + and compile with GCC. You MUST have inlining enabled + in order for mmx_ok() to work; this can be done by + simply using -O on the GCC command line. + + Compiling with -DMMX_TRACE will cause detailed trace + output to be sent to stderr for each mmx operation. + This adds lots of code, and obviously slows execution to + a crawl, but can be very useful for debugging. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT + LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR ANY PARTICULAR PURPOSE. + + 1997-98 by H. Dietz and R. Fisher + + History: + 97-98* R.Fisher Early versions + 980501 R.Fisher Original Release + 980611* H.Dietz Rewrite, correctly implementing inlines, and + R.Fisher including direct register accesses. + 980616 R.Fisher Release of 980611 as 980616. + 980714 R.Fisher Minor corrections to Makefile, etc. + 980715 R.Fisher mmx_ok() now prevents optimizer from using + clobbered values. + mmx_ok() now checks if cpuid instruction is + available before trying to use it. + 980726* R.Fisher mm_support() searches for AMD 3DNow, Cyrix + Extended MMX, and standard MMX. It returns a + value which is positive if any of these are + supported, and can be masked with constants to + see which. mmx_ok() is now a call to this + 980726* R.Fisher Added i2r support for shift functions + 980919 R.Fisher Fixed AMD extended feature recognition bug. + 980921 R.Fisher Added definition/check for _MMX_H. + Added "float s[2]" to mmx_t for use with + 3DNow and EMMX. So same mmx_t can be used. + 981013 R.Fisher Fixed cpuid function 1 bug (looked at wrong reg) + Fixed psllq_i2r error in mmxtest.c + + * Unreleased (internal or interim) versions + + Notes: + It appears that the latest gas has the pand problem fixed, therefore + I'll undefine BROKEN_PAND by default. + String compares may be quicker than the multiple test/jumps in vendor + test sequence in mmx_ok(), but I'm not concerned with that right now. + + Acknowledgments: + Jussi Laako for pointing out the errors ultimately found to be + connected to the failure to notify the optimizer of clobbered values. + Roger Hardiman for reminding us that CPUID isn't everywhere, and that + someone may actually try to use this on a machine without CPUID. + Also for suggesting code for checking this. + Robert Dale for pointing out the AMD recognition bug. + Jimmy Mayfield and Carl Witty for pointing out the Intel recognition + bug. + Carl Witty for pointing out the psllq_i2r test bug. +*/ + +#ifndef _MMX_H +#define _MMX_H + +//#define MMX_TRACE + +/* Warning: at this writing, the version of GAS packaged + with most Linux distributions does not handle the + parallel AND operation mnemonic correctly. If the + symbol BROKEN_PAND is defined, a slower alternative + coding will be used. If execution of mmxtest results + in an illegal instruction fault, define this symbol. +*/ +#undef BROKEN_PAND + + +/* The type of an value that fits in an MMX register + (note that long long constant values MUST be suffixed + by LL and unsigned long long values by ULL, lest + they be truncated by the compiler) +*/ +typedef union { + long long q; /* Quadword (64-bit) value */ + unsigned long long uq; /* Unsigned Quadword */ + int d[2]; /* 2 Doubleword (32-bit) values */ + unsigned int ud[2]; /* 2 Unsigned Doubleword */ + short w[4]; /* 4 Word (16-bit) values */ + unsigned short uw[4]; /* 4 Unsigned Word */ + char b[8]; /* 8 Byte (8-bit) values */ + unsigned char ub[8]; /* 8 Unsigned Byte */ + float s[2]; /* Single-precision (32-bit) value */ +} mmx_t; + +/* Helper functions for the instruction macros that follow... + (note that memory-to-register, m2r, instructions are nearly + as efficient as register-to-register, r2r, instructions; + however, memory-to-memory instructions are really simulated + as a convenience, and are only 1/3 as efficient) +*/ +#ifdef MMX_TRACE + +/* Include the stuff for printing a trace to stderr... +*/ + +#include <stdio.h> + +#define mmx_i2r(op, imm, reg) \ + { \ + mmx_t mmx_trace; \ + mmx_trace = (imm); \ + fprintf(stderr, #op "_i2r(" #imm "=0x%016llx, ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (imm)); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_m2r(op, mem, reg) \ + { \ + mmx_t mmx_trace; \ + mmx_trace = (mem); \ + fprintf(stderr, #op "_m2r(" #mem "=0x%016llx, ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem)); \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #reg "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_r2m(op, reg, mem) \ + { \ + mmx_t mmx_trace; \ + __asm__ __volatile__ ("movq %%" #reg ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #op "_r2m(" #reg "=0x%016llx, ", mmx_trace.q); \ + mmx_trace = (mem); \ + fprintf(stderr, #mem "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=X" (mem) \ + : /* nothing */ ); \ + mmx_trace = (mem); \ + fprintf(stderr, #mem "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_r2r(op, regs, regd) \ + { \ + mmx_t mmx_trace; \ + __asm__ __volatile__ ("movq %%" #regs ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #op "_r2r(" #regs "=0x%016llx, ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %%" #regd ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #regd "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd); \ + __asm__ __volatile__ ("movq %%" #regd ", %0" \ + : "=X" (mmx_trace) \ + : /* nothing */ ); \ + fprintf(stderr, #regd "=0x%016llx\n", mmx_trace.q); \ + } + +#define mmx_m2m(op, mems, memd) \ + { \ + mmx_t mmx_trace; \ + mmx_trace = (mems); \ + fprintf(stderr, #op "_m2m(" #mems "=0x%016llx, ", mmx_trace.q); \ + mmx_trace = (memd); \ + fprintf(stderr, #memd "=0x%016llx) => ", mmx_trace.q); \ + __asm__ __volatile__ ("movq %0, %%mm0\n\t" \ + #op " %1, %%mm0\n\t" \ + "movq %%mm0, %0" \ + : "=X" (memd) \ + : "X" (mems)); \ + mmx_trace = (memd); \ + fprintf(stderr, #memd "=0x%016llx\n", mmx_trace.q); \ + } + +#else + +/* These macros are a lot simpler without the tracing... +*/ + +#define mmx_i2r(op, imm, reg) \ + __asm__ __volatile__ (#op " $" #imm ", %%" #reg \ + : /* nothing */ \ + : /* nothing */); + +#define mmx_m2r(op, mem, reg) \ + __asm__ __volatile__ (#op " %0, %%" #reg \ + : /* nothing */ \ + : "X" (mem)) + +#define mmx_r2m(op, reg, mem) \ + __asm__ __volatile__ (#op " %%" #reg ", %0" \ + : "=X" (mem) \ + : /* nothing */ ) + +#define mmx_r2r(op, regs, regd) \ + __asm__ __volatile__ (#op " %" #regs ", %" #regd) + +#define mmx_m2m(op, mems, memd) \ + __asm__ __volatile__ ("movq %0, %%mm0\n\t" \ + #op " %1, %%mm0\n\t" \ + "movq %%mm0, %0" \ + : "=X" (memd) \ + : "X" (mems)) + +#endif + + +/* 1x64 MOVe Quadword + (this is both a load and a store... + in fact, it is the only way to store) +*/ +#define movq_m2r(var, reg) mmx_m2r(movq, var, reg) +#define movq_r2m(reg, var) mmx_r2m(movq, reg, var) +#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd) +#define movq(vars, vard) \ + __asm__ __volatile__ ("movq %1, %%mm0\n\t" \ + "movq %%mm0, %0" \ + : "=X" (vard) \ + : "X" (vars)) + + +/* 1x32 MOVe Doubleword + (like movq, this is both load and store... + but is most useful for moving things between + mmx registers and ordinary registers) +*/ +#define movd_m2r(var, reg) mmx_m2r(movd, var, reg) +#define movd_r2m(reg, var) mmx_r2m(movd, reg, var) +#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd) +#define movd(vars, vard) \ + __asm__ __volatile__ ("movd %1, %%mm0\n\t" \ + "movd %%mm0, %0" \ + : "=X" (vard) \ + : "X" (vars)) + + +/* 2x32, 4x16, and 8x8 Parallel ADDs +*/ +#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg) +#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd) +#define paddd(vars, vard) mmx_m2m(paddd, vars, vard) + +#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg) +#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd) +#define paddw(vars, vard) mmx_m2m(paddw, vars, vard) + +#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg) +#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd) +#define paddb(vars, vard) mmx_m2m(paddb, vars, vard) + + +/* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic +*/ +#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg) +#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd) +#define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard) + +#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg) +#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd) +#define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard) + + +/* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic +*/ +#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg) +#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd) +#define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard) + +#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg) +#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd) +#define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard) + + +/* 2x32, 4x16, and 8x8 Parallel SUBs +*/ +#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg) +#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd) +#define psubd(vars, vard) mmx_m2m(psubd, vars, vard) + +#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg) +#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd) +#define psubw(vars, vard) mmx_m2m(psubw, vars, vard) + +#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg) +#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd) +#define psubb(vars, vard) mmx_m2m(psubb, vars, vard) + + +/* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic +*/ +#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg) +#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd) +#define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard) + +#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg) +#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd) +#define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard) + + +/* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic +*/ +#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg) +#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd) +#define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard) + +#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg) +#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd) +#define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard) + + +/* 4x16 Parallel MULs giving Low 4x16 portions of results +*/ +#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg) +#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd) +#define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard) + + +/* 4x16 Parallel MULs giving High 4x16 portions of results +*/ +#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg) +#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd) +#define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard) + + +/* 4x16->2x32 Parallel Mul-ADD + (muls like pmullw, then adds adjacent 16-bit fields + in the multiply result to make the final 2x32 result) +*/ +#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg) +#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd) +#define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard) + + +/* 1x64 bitwise AND +*/ +#ifdef BROKEN_PAND +#define pand_m2r(var, reg) \ + { \ + mmx_m2r(pandn, (mmx_t) -1LL, reg); \ + mmx_m2r(pandn, var, reg); \ + } +#define pand_r2r(regs, regd) \ + { \ + mmx_m2r(pandn, (mmx_t) -1LL, regd); \ + mmx_r2r(pandn, regs, regd) \ + } +#define pand(vars, vard) \ + { \ + movq_m2r(vard, mm0); \ + mmx_m2r(pandn, (mmx_t) -1LL, mm0); \ + mmx_m2r(pandn, vars, mm0); \ + movq_r2m(mm0, vard); \ + } +#else +#define pand_m2r(var, reg) mmx_m2r(pand, var, reg) +#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd) +#define pand(vars, vard) mmx_m2m(pand, vars, vard) +#endif + + +/* 1x64 bitwise AND with Not the destination +*/ +#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg) +#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd) +#define pandn(vars, vard) mmx_m2m(pandn, vars, vard) + + +/* 1x64 bitwise OR +*/ +#define por_m2r(var, reg) mmx_m2r(por, var, reg) +#define por_r2r(regs, regd) mmx_r2r(por, regs, regd) +#define por(vars, vard) mmx_m2m(por, vars, vard) + + +/* 1x64 bitwise eXclusive OR +*/ +#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg) +#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd) +#define pxor(vars, vard) mmx_m2m(pxor, vars, vard) + + +/* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality + (resulting fields are either 0 or -1) +*/ +#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg) +#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd) +#define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard) + +#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg) +#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd) +#define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard) + +#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg) +#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd) +#define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard) + + +/* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than + (resulting fields are either 0 or -1) +*/ +#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg) +#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd) +#define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard) + +#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg) +#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd) +#define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard) + +#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg) +#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd) +#define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard) + + +/* 1x64, 2x32, and 4x16 Parallel Shift Left Logical +*/ +#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg) +#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg) +#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd) +#define psllq(vars, vard) mmx_m2m(psllq, vars, vard) + +#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg) +#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg) +#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd) +#define pslld(vars, vard) mmx_m2m(pslld, vars, vard) + +#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg) +#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg) +#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd) +#define psllw(vars, vard) mmx_m2m(psllw, vars, vard) + + +/* 1x64, 2x32, and 4x16 Parallel Shift Right Logical +*/ +#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg) +#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg) +#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd) +#define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard) + +#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg) +#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg) +#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd) +#define psrld(vars, vard) mmx_m2m(psrld, vars, vard) + +#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg) +#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg) +#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd) +#define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard) + + +/* 2x32 and 4x16 Parallel Shift Right Arithmetic +*/ +#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg) +#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg) +#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd) +#define psrad(vars, vard) mmx_m2m(psrad, vars, vard) + +#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg) +#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg) +#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd) +#define psraw(vars, vard) mmx_m2m(psraw, vars, vard) + + +/* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate + (packs source and dest fields into dest in that order) +*/ +#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg) +#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd) +#define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard) + +#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg) +#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd) +#define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard) + + +/* 4x16->8x8 PACK and Unsigned Saturate + (packs source and dest fields into dest in that order) +*/ +#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg) +#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd) +#define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard) + + +/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low + (interleaves low half of dest with low half of source + as padding in each result field) +*/ +#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg) +#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd) +#define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard) + +#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg) +#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd) +#define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard) + +#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg) +#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd) +#define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard) + + +/* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High + (interleaves high half of dest with high half of source + as padding in each result field) +*/ +#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg) +#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd) +#define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard) + +#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg) +#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd) +#define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard) + +#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg) +#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd) +#define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard) + + +/* Empty MMx State + (used to clean-up when going from mmx to float use + of the registers that are shared by both; note that + there is no float-to-mmx operation needed, because + only the float tag word info is corruptible) +*/ +#ifdef MMX_TRACE + +#define emms() \ + { \ + fprintf(stderr, "emms()\n"); \ + __asm__ __volatile__ ("emms"); \ + } + +#else + +#define emms() __asm__ __volatile__ ("emms") + +#endif + +#endif + diff --git a/mesalib/src/mesa/drivers/dri/common/spantmp.h b/mesalib/src/mesa/drivers/dri/common/spantmp.h new file mode 100644 index 000000000..d5608b880 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/spantmp.h @@ -0,0 +1,338 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (C) Copyright IBM Corporation 2002, 2003 + * 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. + * + * Authors: + * Keith Whitwell <keithw@tungstengraphics.com> + * Gareth Hughes <gareth@nvidia.com> + */ + +#include "spantmp_common.h" + +#ifndef DBG +#define DBG 0 +#endif + +#ifndef HW_READ_CLIPLOOP +#define HW_READ_CLIPLOOP() HW_CLIPLOOP() +#endif + +#ifndef HW_WRITE_CLIPLOOP +#define HW_WRITE_CLIPLOOP() HW_CLIPLOOP() +#endif + + +static void TAG(WriteRGBASpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBASpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + +static void TAG(WriteRGBSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + +static void TAG(WriteRGBAPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + GLuint i; + LOCAL_VARS; + + if (DBG) fprintf(stderr, "WriteRGBAPixels\n"); + + HW_WRITE_CLIPLOOP() + { + if (mask) + { + for (i=0;i<n;i++) + { + if (mask[i]) { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_RGBA( x[i], fy, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + } + else + { + for (i=0;i<n;i++) + { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_RGBA( x[i], fy, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + + +static void TAG(WriteMonoRGBASpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte *color = (const GLubyte *) value; + GLint x1; + GLint n1; + LOCAL_VARS; + INIT_MONO_PIXEL(p, color); + + y = Y_FLIP( y ); + + if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n"); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_PIXEL( x1, y, p ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_PIXEL( x1, y, p ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + + +static void TAG(WriteMonoRGBAPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const void *value, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte *color = (const GLubyte *) value; + GLuint i; + LOCAL_VARS; + INIT_MONO_PIXEL(p, color); + + if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n"); + + HW_WRITE_CLIPLOOP() + { + if (mask) + { + for (i=0;i<n;i++) + if (mask[i]) { + int fy = Y_FLIP(y[i]); + if (CLIPPIXEL( x[i], fy )) + WRITE_PIXEL( x[i], fy, p ); + } + } + else + { + for (i=0;i<n;i++) { + int fy = Y_FLIP(y[i]); + if (CLIPPIXEL( x[i], fy )) + WRITE_PIXEL( x[i], fy, p ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + + +static void TAG(ReadRGBASpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + void *values) +{ + HW_READ_LOCK() + { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + GLint x1,n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadRGBASpan\n"); + + HW_READ_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + for (;n1>0;i++,x1++,n1--) + READ_RGBA( rgba[i], x1, y ); + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +} + + +static void TAG(ReadRGBAPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + void *values ) +{ + HW_READ_LOCK() + { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + const GLubyte *mask = NULL; /* remove someday */ + GLuint i; + LOCAL_VARS; + + if (DBG) fprintf(stderr, "ReadRGBAPixels\n"); + + HW_READ_CLIPLOOP() + { + if (mask) + { + for (i=0;i<n;i++) + if (mask[i]) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_RGBA( rgba[i], x[i], fy ); + } + } + else + { + for (i=0;i<n;i++) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_RGBA( rgba[i], x[i], fy ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +} + + +static void TAG(InitPointers)(struct gl_renderbuffer *rb) +{ + rb->PutRow = TAG(WriteRGBASpan); + rb->PutRowRGB = TAG(WriteRGBSpan); + rb->PutMonoRow = TAG(WriteMonoRGBASpan); + rb->PutValues = TAG(WriteRGBAPixels); + rb->PutMonoValues = TAG(WriteMonoRGBAPixels); + rb->GetValues = TAG(ReadRGBAPixels); + rb->GetRow = TAG(ReadRGBASpan); +} + + +#undef WRITE_PIXEL +#undef WRITE_RGBA +#undef READ_RGBA +#undef TAG diff --git a/mesalib/src/mesa/drivers/dri/common/spantmp2.h b/mesalib/src/mesa/drivers/dri/common/spantmp2.h new file mode 100644 index 000000000..89c815722 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/spantmp2.h @@ -0,0 +1,686 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (C) Copyright IBM Corporation 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 spantmp2.h + * + * Template file of span read / write functions. + * + * \author Keith Whitwell <keithw@tungstengraphics.com> + * \author Gareth Hughes <gareth@nvidia.com> + * \author Ian Romanick <idr@us.ibm.com> + */ + +#include "main/colormac.h" +#include "spantmp_common.h" + +#ifndef DBG +#define DBG 0 +#endif + +#ifndef HW_READ_CLIPLOOP +#define HW_READ_CLIPLOOP() HW_CLIPLOOP() +#endif + +#ifndef HW_WRITE_CLIPLOOP +#define HW_WRITE_CLIPLOOP() HW_CLIPLOOP() +#endif + +#if (SPANTMP_PIXEL_FMT == GL_RGB) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5) + +/** + ** GL_RGB, GL_UNSIGNED_SHORT_5_6_5 + **/ + +#ifndef GET_VALUE +#ifndef GET_PTR +#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch) +#endif + +#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y)) +#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v) +#endif /* GET_VALUE */ + +#define INIT_MONO_PIXEL(p, color) \ + p = PACK_COLOR_565( color[0], color[1], color[2] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + PUT_VALUE(_x, _y, ((((int)r & 0xf8) << 8) | \ + (((int)g & 0xfc) << 3) | \ + (((int)b & 0xf8) >> 3))) \ + +#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p) + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = GET_VALUE(_x, _y); \ + rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \ + rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ + rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \ + rgba[3] = 0xff; \ + } while (0) + +#elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_4_4_4_4_REV) + +/** + ** GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV + **/ + +#ifndef GET_VALUE +#ifndef GET_PTR +#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch) +#endif + +#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y)) +#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v) +#endif /* GET_VALUE */ + +#define INIT_MONO_PIXEL(p, color) \ + p = PACK_COLOR_4444(color[3], color[0], color[1], color[2]) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + PUT_VALUE(_x, _y, PACK_COLOR_4444(a, r, g, b)) \ + +#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p) + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = GET_VALUE(_x, _y); \ + rgba[0] = ((p >> 8) & 0xf) * 0x11; \ + rgba[1] = ((p >> 4) & 0xf) * 0x11; \ + rgba[2] = ((p >> 0) & 0xf) * 0x11; \ + rgba[3] = ((p >> 12) & 0xf) * 0x11; \ + } while (0) + + +#elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_1_5_5_5_REV) + +/** + ** GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV + **/ + +#ifndef GET_VALUE +#ifndef GET_PTR +#define GET_PTR(_x, _y) (buf + (_x) * 2 + (_y) * pitch) +#endif + +#define GET_VALUE(_x, _y) *(volatile GLushort *)(GET_PTR(_x, _y)) +#define PUT_VALUE(_x, _y, _v) *(volatile GLushort *)(GET_PTR(_x, _y)) = (_v) +#endif /* GET_VALUE */ + +#define INIT_MONO_PIXEL(p, color) \ + p = PACK_COLOR_1555(color[3], color[0], color[1], color[2]) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + PUT_VALUE(_x, _y, PACK_COLOR_1555(a, r, g, b)) \ + +#define WRITE_PIXEL( _x, _y, p ) PUT_VALUE(_x, _y, p) + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = GET_VALUE(_x, _y); \ + rgba[0] = ((p >> 7) & 0xf8) * 255 / 0xf8; \ + rgba[1] = ((p >> 2) & 0xf8) * 255 / 0xf8; \ + rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \ + rgba[3] = ((p >> 15) & 0x1) * 0xff; \ + } while (0) + +#elif (SPANTMP_PIXEL_FMT == GL_BGRA) && (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV) + +/** + ** GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV + **/ + +#ifndef GET_VALUE +#ifndef GET_PTR +#define GET_PTR(_x, _y) ( buf + (_x) * 4 + (_y) * pitch) +#endif + +#define GET_VALUE(_x, _y) *(volatile GLuint *)(GET_PTR(_x, _y)) +#define PUT_VALUE(_x, _y, _v) *(volatile GLuint *)(GET_PTR(_x, _y)) = (_v) +#endif /* GET_VALUE */ + +# define INIT_MONO_PIXEL(p, color) \ + p = PACK_COLOR_8888(color[3], color[0], color[1], color[2]) + +# define WRITE_RGBA(_x, _y, r, g, b, a) \ + PUT_VALUE(_x, _y, ((r << 16) | \ + (g << 8) | \ + (b << 0) | \ + (a << 24))) + +#define WRITE_PIXEL(_x, _y, p) PUT_VALUE(_x, _y, p) + +# if defined( USE_X86_ASM ) +# define READ_RGBA(rgba, _x, _y) \ + do { \ + GLuint p = GET_VALUE(_x, _y); \ + __asm__ __volatile__( "bswap %0; rorl $8, %0" \ + : "=r" (p) : "0" (p) ); \ + ((GLuint *)rgba)[0] = p; \ + } while (0) +# elif defined( MESA_BIG_ENDIAN ) + /* On PowerPC with GCC 3.4.2 the shift madness below becomes a single + * rotlwi instruction. It also produces good code on SPARC. + */ +# define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLuint p = GET_VALUE(_x, _y); \ + GLuint t = p; \ + *((uint32_t *) rgba) = (t >> 24) | (p << 8); \ + } while (0) +# else +# define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLuint p = GET_VALUE(_x, _y); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ + } while (0) +# endif + +#else +#error SPANTMP_PIXEL_FMT must be set to a valid value! +#endif + + + +/** + ** Assembly routines. + **/ + +#if defined( USE_MMX_ASM ) || defined( USE_SSE_ASM ) +#include "x86/read_rgba_span_x86.h" +#include "x86/common_x86_asm.h" +#endif + +static void TAG(WriteRGBASpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBASpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_RGBA( x1, y, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + +static void TAG(WriteRGBSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values; + GLint x1; + GLint n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteRGBSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_RGBA( x1, y, rgb[i][0], rgb[i][1], rgb[i][2], 255 ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + +static void TAG(WriteRGBAPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values; + GLint i; + LOCAL_VARS; + + if (DBG) fprintf(stderr, "WriteRGBAPixels\n"); + + HW_WRITE_CLIPLOOP() + { + if (mask) + { + for (i=0;i<n;i++) + { + if (mask[i]) { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_RGBA( x[i], fy, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + } + else + { + for (i=0;i<n;i++) + { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_RGBA( x[i], fy, + rgba[i][0], rgba[i][1], + rgba[i][2], rgba[i][3] ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + + +static void TAG(WriteMonoRGBASpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte *color = (const GLubyte *) value; + GLint x1; + GLint n1; + LOCAL_VARS; + INIT_MONO_PIXEL(p, color); + + y = Y_FLIP( y ); + + if (DBG) fprintf(stderr, "WriteMonoRGBASpan\n"); + + HW_WRITE_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_PIXEL( x1, y, p ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_PIXEL( x1, y, p ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + + +static void TAG(WriteMonoRGBAPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const void *value, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte *color = (const GLubyte *) value; + GLint i; + LOCAL_VARS; + INIT_MONO_PIXEL(p, color); + + if (DBG) fprintf(stderr, "WriteMonoRGBAPixels\n"); + + HW_WRITE_CLIPLOOP() + { + if (mask) + { + for (i=0;i<n;i++) + if (mask[i]) { + int fy = Y_FLIP(y[i]); + if (CLIPPIXEL( x[i], fy )) + WRITE_PIXEL( x[i], fy, p ); + } + } + else + { + for (i=0;i<n;i++) { + int fy = Y_FLIP(y[i]); + if (CLIPPIXEL( x[i], fy )) + WRITE_PIXEL( x[i], fy, p ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} + + +static void TAG(ReadRGBASpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, void *values) +{ + HW_READ_LOCK() + { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + GLint x1,n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadRGBASpan\n"); + + HW_READ_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + for (;n1>0;i++,x1++,n1--) + READ_RGBA( rgba[i], x1, y ); + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +} + + +#if defined(GET_PTR) && \ + defined(USE_MMX_ASM) && \ + (((SPANTMP_PIXEL_FMT == GL_BGRA) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)) || \ + ((SPANTMP_PIXEL_FMT == GL_RGB) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5))) +static void TAG2(ReadRGBASpan,_MMX)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, void *values) +{ +#ifndef USE_INNER_EMMS + /* The EMMS instruction is directly in-lined here because using GCC's + * built-in _mm_empty function was found to utterly destroy performance. + */ + __asm__ __volatile__( "emms" ); +#endif + + HW_READ_LOCK() + { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + GLint x1,n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadRGBASpan\n"); + + HW_READ_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + { + const void * src = GET_PTR( x1, y ); +#if (SPANTMP_PIXEL_FMT == GL_RGB) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5) + _generic_read_RGBA_span_RGB565_MMX( src, rgba[i], n1 ); +#else + _generic_read_RGBA_span_BGRA8888_REV_MMX( src, rgba[i], n1 ); +#endif + } + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +#ifndef USE_INNER_EMMS + __asm__ __volatile__( "emms" ); +#endif +} +#endif + + +#if defined(GET_PTR) && \ + defined(USE_SSE_ASM) && \ + (SPANTMP_PIXEL_FMT == GL_BGRA) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV) +static void TAG2(ReadRGBASpan,_SSE2)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + void *values) +{ + HW_READ_LOCK() + { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + GLint x1,n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadRGBASpan\n"); + + HW_READ_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + { + const void * src = GET_PTR( x1, y ); + _generic_read_RGBA_span_BGRA8888_REV_SSE2( src, rgba[i], n1 ); + } + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +} +#endif + +#if defined(GET_PTR) && \ + defined(USE_SSE_ASM) && \ + (SPANTMP_PIXEL_FMT == GL_BGRA) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV) +static void TAG2(ReadRGBASpan,_SSE)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + void *values) +{ +#ifndef USE_INNER_EMMS + /* The EMMS instruction is directly in-lined here because using GCC's + * built-in _mm_empty function was found to utterly destroy performance. + */ + __asm__ __volatile__( "emms" ); +#endif + + HW_READ_LOCK() + { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + GLint x1,n1; + LOCAL_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadRGBASpan\n"); + + HW_READ_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + { + const void * src = GET_PTR( x1, y ); + _generic_read_RGBA_span_BGRA8888_REV_SSE( src, rgba[i], n1 ); + } + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +#ifndef USE_INNER_EMMS + __asm__ __volatile__( "emms" ); +#endif +} +#endif + + +static void TAG(ReadRGBAPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + void *values ) +{ + HW_READ_LOCK() + { + GLubyte (*rgba)[4] = (GLubyte (*)[4]) values; + GLubyte *mask = NULL; /* remove someday */ + GLint i; + LOCAL_VARS; + + if (DBG) fprintf(stderr, "ReadRGBAPixels\n"); + + HW_READ_CLIPLOOP() + { + if (mask) + { + for (i=0;i<n;i++) + if (mask[i]) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_RGBA( rgba[i], x[i], fy ); + } + } + else + { + for (i=0;i<n;i++) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_RGBA( rgba[i], x[i], fy ); + } + } + } + HW_ENDCLIPLOOP(); + } + HW_READ_UNLOCK(); +} + +static void TAG(InitPointers)(struct gl_renderbuffer *rb) +{ + rb->PutRow = TAG(WriteRGBASpan); + rb->PutRowRGB = TAG(WriteRGBSpan); + rb->PutMonoRow = TAG(WriteMonoRGBASpan); + rb->PutValues = TAG(WriteRGBAPixels); + rb->PutMonoValues = TAG(WriteMonoRGBAPixels); + rb->GetValues = TAG(ReadRGBAPixels); + +#if defined(GET_PTR) +#if defined(USE_SSE_ASM) && \ + (SPANTMP_PIXEL_FMT == GL_BGRA) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV) + if ( cpu_has_xmm2 ) { + if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "SSE2" ); + rb->GetRow = TAG2(ReadRGBASpan, _SSE2); + } + else +#endif +#if defined(USE_SSE_ASM) && \ + (SPANTMP_PIXEL_FMT == GL_BGRA) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV) + if ( cpu_has_xmm ) { + if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "SSE" ); + rb->GetRow = TAG2(ReadRGBASpan, _SSE); + } + else +#endif +#if defined(USE_MMX_ASM) && \ + (((SPANTMP_PIXEL_FMT == GL_BGRA) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_INT_8_8_8_8_REV)) || \ + ((SPANTMP_PIXEL_FMT == GL_RGB) && \ + (SPANTMP_PIXEL_TYPE == GL_UNSIGNED_SHORT_5_6_5))) + if ( cpu_has_mmx ) { + if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "MMX" ); + rb->GetRow = TAG2(ReadRGBASpan, _MMX); + } + else +#endif +#endif /* GET_PTR */ + { + if (DBG) fprintf( stderr, "Using %s version of GetRow\n", "C" ); + rb->GetRow = TAG(ReadRGBASpan); + } + +} + + +#undef INIT_MONO_PIXEL +#undef WRITE_PIXEL +#undef WRITE_RGBA +#undef READ_RGBA +#undef TAG +#undef TAG2 +#undef GET_VALUE +#undef PUT_VALUE +#undef GET_PTR +#undef SPANTMP_PIXEL_FMT +#undef SPANTMP_PIXEL_TYPE diff --git a/mesalib/src/mesa/drivers/dri/common/spantmp_common.h b/mesalib/src/mesa/drivers/dri/common/spantmp_common.h new file mode 100644 index 000000000..a4509a569 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/spantmp_common.h @@ -0,0 +1,81 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (C) Copyright IBM Corporation 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 spantmp_common.h + * + * common macros for span read / write functions to be used in the depth, + * stencil and pixel span templates. + */ + +#ifndef HW_WRITE_LOCK +#define HW_WRITE_LOCK() HW_LOCK() +#endif + +#ifndef HW_WRITE_UNLOCK +#define HW_WRITE_UNLOCK() HW_UNLOCK() +#endif + +#ifndef HW_READ_LOCK +#define HW_READ_LOCK() HW_LOCK() +#endif + +#ifndef HW_READ_UNLOCK +#define HW_READ_UNLOCK() HW_UNLOCK() +#endif + +#ifndef HW_CLIPLOOP +#define HW_CLIPLOOP() \ + do { \ + int _nc = dPriv->numClipRects; \ + while ( _nc-- ) { \ + int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \ + int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \ + int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \ + int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; +#endif + +#ifndef HW_ENDCLIPLOOP +#define HW_ENDCLIPLOOP() \ + } \ + } while (0) +#endif + +#ifndef CLIPPIXEL +#define CLIPPIXEL( _x, _y ) \ + ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) +#endif + +#ifndef CLIPSPAN +#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \ + if ( _y < miny || _y >= maxy /*|| _x + n < minx || _x >=maxx*/ ) { \ + _n1 = 0, _x1 = x; \ + } else { \ + _n1 = _n; \ + _x1 = _x; \ + if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \ + if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \ + } +#endif diff --git a/mesalib/src/mesa/drivers/dri/common/stenciltmp.h b/mesalib/src/mesa/drivers/dri/common/stenciltmp.h new file mode 100644 index 000000000..2b10b9ecf --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/stenciltmp.h @@ -0,0 +1,245 @@ + +#include "spantmp_common.h" + +#ifndef DBG +#define DBG 0 +#endif + +#ifndef HAVE_HW_STENCIL_SPANS +#define HAVE_HW_STENCIL_SPANS 0 +#endif + +#ifndef HAVE_HW_STENCIL_PIXELS +#define HAVE_HW_STENCIL_PIXELS 0 +#endif + +static void TAG(WriteStencilSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte *stencil = (const GLubyte *) values; + GLint x1; + GLint n1; + LOCAL_STENCIL_VARS; + + y = Y_FLIP(y); + +#if HAVE_HW_STENCIL_SPANS + (void) x1; (void) n1; + + if (DBG) fprintf(stderr, "WriteStencilSpan 0..%d (x1 %d)\n", + (int)n1, (int)x1); + + WRITE_STENCIL_SPAN(); +#else /* HAVE_HW_STENCIL_SPANS */ + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteStencilSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_STENCIL( x1, y, stencil[i] ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_STENCIL( x1, y, stencil[i] ); + } + } + HW_ENDCLIPLOOP(); +#endif /* !HAVE_HW_STENCIL_SPANS */ + } + HW_WRITE_UNLOCK(); +} + +#if HAVE_HW_STENCIL_SPANS +/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */ +static void +TAG(WriteMonoStencilSpan)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, const GLubyte mask[] ) +{ + const GLuint stenVal = *((GLuint *) value); + GLuint stens[MAX_WIDTH]; + GLuint i; + for (i = 0; i < n; i++) + stens[i] = stenVal; + TAG(WriteStencilSpan)(ctx, rb, n, x, y, stens, mask); +} +#else /* HAVE_HW_STENCIL_SPANS */ +static void TAG(WriteMonoStencilSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const void *value, + const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte stencil = *((const GLubyte *) value); + GLint x1; + GLint n1; + LOCAL_STENCIL_VARS; + + y = Y_FLIP(y); + + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + + if (DBG) fprintf(stderr, "WriteStencilSpan %d..%d (x1 %d)\n", + (int)i, (int)n1, (int)x1); + + if (mask) + { + for (;n1>0;i++,x1++,n1--) + if (mask[i]) + WRITE_STENCIL( x1, y, stencil ); + } + else + { + for (;n1>0;i++,x1++,n1--) + WRITE_STENCIL( x1, y, stencil ); + } + } + HW_ENDCLIPLOOP(); + } + HW_WRITE_UNLOCK(); +} +#endif /* !HAVE_HW_STENCIL_SPANS */ + + +static void TAG(WriteStencilPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const void *values, const GLubyte mask[] ) +{ + HW_WRITE_LOCK() + { + const GLubyte *stencil = (const GLubyte *) values; + GLuint i; + LOCAL_STENCIL_VARS; + + if (DBG) fprintf(stderr, "WriteStencilPixels\n"); + +#if HAVE_HW_STENCIL_PIXELS + (void) i; + + WRITE_STENCIL_PIXELS(); +#else /* HAVE_HW_STENCIL_PIXELS */ + HW_CLIPLOOP() + { + for (i=0;i<n;i++) + { + if (mask[i]) { + const int fy = Y_FLIP(y[i]); + if (CLIPPIXEL(x[i],fy)) + WRITE_STENCIL( x[i], fy, stencil[i] ); + } + } + } + HW_ENDCLIPLOOP(); +#endif /* !HAVE_HW_STENCIL_PIXELS */ + } + HW_WRITE_UNLOCK(); +} + + +/* Read stencil spans and pixels + */ +static void TAG(ReadStencilSpan)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + void *values) +{ + HW_READ_LOCK() + { + GLubyte *stencil = (GLubyte *) values; + GLint x1,n1; + LOCAL_STENCIL_VARS; + + y = Y_FLIP(y); + + if (DBG) fprintf(stderr, "ReadStencilSpan\n"); + +#if HAVE_HW_STENCIL_SPANS + (void) x1; (void) n1; + + READ_STENCIL_SPAN(); +#else /* HAVE_HW_STENCIL_SPANS */ + HW_CLIPLOOP() + { + GLint i = 0; + CLIPSPAN(x,y,n,x1,n1,i); + for (;n1>0;i++,n1--) + READ_STENCIL( stencil[i], (x+i), y ); + } + HW_ENDCLIPLOOP(); +#endif /* !HAVE_HW_STENCIL_SPANS */ + } + HW_READ_UNLOCK(); +} + +static void TAG(ReadStencilPixels)( GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + void *values ) +{ + HW_READ_LOCK() + { + GLubyte *stencil = (GLubyte *) values; + GLuint i; + LOCAL_STENCIL_VARS; + + if (DBG) fprintf(stderr, "ReadStencilPixels\n"); + +#if HAVE_HW_STENCIL_PIXELS + (void) i; + + READ_STENCIL_PIXELS(); +#else /* HAVE_HW_STENCIL_PIXELS */ + HW_CLIPLOOP() + { + for (i=0;i<n;i++) { + int fy = Y_FLIP( y[i] ); + if (CLIPPIXEL( x[i], fy )) + READ_STENCIL( stencil[i], x[i], fy ); + } + } + HW_ENDCLIPLOOP(); +#endif /* !HAVE_HW_STENCIL_PIXELS */ + } + HW_READ_UNLOCK(); +} + + + +/** + * Initialize the given renderbuffer's span routines to point to + * the stencil functions we generated above. + */ +static void TAG(InitStencilPointers)(struct gl_renderbuffer *rb) +{ + rb->GetRow = TAG(ReadStencilSpan); + rb->GetValues = TAG(ReadStencilPixels); + rb->PutRow = TAG(WriteStencilSpan); + rb->PutRowRGB = NULL; + rb->PutMonoRow = TAG(WriteMonoStencilSpan); + rb->PutValues = TAG(WriteStencilPixels); + rb->PutMonoValues = NULL; +} + + +#undef WRITE_STENCIL +#undef READ_STENCIL +#undef TAG diff --git a/mesalib/src/mesa/drivers/dri/common/texmem.c b/mesalib/src/mesa/drivers/dri/common/texmem.c new file mode 100644 index 000000000..b64618a03 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/texmem.c @@ -0,0 +1,1347 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (C) Copyright IBM Corporation 2002, 2003 + * 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. + * + * Authors: + * Ian Romanick <idr@us.ibm.com> + * Keith Whitwell <keithw@tungstengraphics.com> + * Kevin E. Martin <kem@users.sourceforge.net> + * Gareth Hughes <gareth@nvidia.com> + */ + +/** \file texmem.c + * Implements all of the device-independent texture memory management. + * + * Currently, only a simple LRU texture memory management policy is + * implemented. In the (hopefully very near) future, better policies will be + * implemented. The idea is that the DRI should be able to run in one of two + * modes. In the default mode the DRI will dynamically attempt to discover + * the best texture management policy for the running application. In the + * other mode, the user (via some sort of as yet TBD mechanism) will select + * a texture management policy that is known to work well with the + * application. + */ + +#include "texmem.h" +#include "main/simple_list.h" +#include "main/imports.h" +#include "main/macros.h" +#include "main/texformat.h" + +#include <assert.h> + + + +static unsigned dummy_swap_counter; + + +/** + * Calculate \f$\log_2\f$ of a value. This is a particularly poor + * implementation of this function. However, since system performance is in + * no way dependent on this function, the slowness of the implementation is + * irrelevent. + * + * \param n Value whose \f$\log_2\f$ is to be calculated + */ + +static GLuint +driLog2( GLuint n ) +{ + GLuint log2; + + for ( log2 = 1 ; n > 1 ; log2++ ) { + n >>= 1; + } + + return log2; +} + + + + +/** + * Determine if a texture is resident in textureable memory. Depending on + * the driver, this may or may not be on-card memory. It could be AGP memory + * or anyother type of memory from which the hardware can directly read + * texels. + * + * This function is intended to be used as the \c IsTextureResident function + * in the device's \c dd_function_table. + * + * \param ctx GL context pointer (currently unused) + * \param texObj Texture object to be tested + */ + +GLboolean +driIsTextureResident( GLcontext * ctx, + struct gl_texture_object * texObj ) +{ + driTextureObject * t; + + + t = (driTextureObject *) texObj->DriverData; + return( (t != NULL) && (t->memBlock != NULL) ); +} + + + + +/** + * (Re)initialize the global circular LRU list. The last element + * in the array (\a heap->nrRegions) is the sentinal. Keeping it + * at the end of the array allows the other elements of the array + * to be addressed rationally when looking up objects at a particular + * location in texture memory. + * + * \param heap Texture heap to be reset + */ + +static void resetGlobalLRU( driTexHeap * heap ) +{ + drmTextureRegionPtr list = heap->global_regions; + unsigned sz = 1U << heap->logGranularity; + unsigned i; + + for (i = 0 ; (i+1) * sz <= heap->size ; i++) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = heap->nrRegions; + list[i].prev = i-1; + list[i].next = heap->nrRegions; + list[heap->nrRegions].prev = i; + list[heap->nrRegions].next = 0; + heap->global_age[0] = 0; +} + +/** + * Print out debugging information about the local texture LRU. + * + * \param heap Texture heap to be printed + * \param callername Name of calling function + */ +static void printLocalLRU( driTexHeap * heap, const char *callername ) +{ + driTextureObject *t; + unsigned sz = 1U << heap->logGranularity; + + fprintf( stderr, "%s in %s:\nLocal LRU, heap %d:\n", + __FUNCTION__, callername, heap->heapId ); + + foreach ( t, &heap->texture_objects ) { + if (!t->memBlock) + continue; + if (!t->tObj) { + fprintf( stderr, "Placeholder (%p) %d at 0x%x sz 0x%x\n", + (void *)t, + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size ); + } else { + fprintf( stderr, "Texture (%p) at 0x%x sz 0x%x\n", + (void *)t, + t->memBlock->ofs, + t->memBlock->size ); + } + } + foreach ( t, heap->swapped_objects ) { + if (!t->tObj) { + fprintf( stderr, "Swapped Placeholder (%p)\n", (void *)t ); + } else { + fprintf( stderr, "Swapped Texture (%p)\n", (void *)t ); + } + } + + fprintf( stderr, "\n" ); +} + +/** + * Print out debugging information about the global texture LRU. + * + * \param heap Texture heap to be printed + * \param callername Name of calling function + */ +static void printGlobalLRU( driTexHeap * heap, const char *callername ) +{ + drmTextureRegionPtr list = heap->global_regions; + unsigned int i, j; + + fprintf( stderr, "%s in %s:\nGlobal LRU, heap %d list %p:\n", + __FUNCTION__, callername, heap->heapId, (void *)list ); + + for ( i = 0, j = heap->nrRegions ; i < heap->nrRegions ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d in_use %d\n", + j, list[j].age, list[j].next, list[j].prev, list[j].in_use ); + j = list[j].next; + if ( j == heap->nrRegions ) break; + } + + if ( j != heap->nrRegions ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < heap->nrRegions ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d in_use %d\n", + i, list[i].age, list[i].next, list[i].prev, list[i].in_use ); + } + } + + fprintf( stderr, "\n" ); +} + + +/** + * Called by the client whenever it touches a local texture. + * + * \param t Texture object that the client has accessed + */ + +void driUpdateTextureLRU( driTextureObject * t ) +{ + driTexHeap * heap; + drmTextureRegionPtr list; + unsigned shift; + unsigned start; + unsigned end; + unsigned i; + + + heap = t->heap; + if ( heap != NULL ) { + shift = heap->logGranularity; + start = t->memBlock->ofs >> shift; + end = (t->memBlock->ofs + t->memBlock->size - 1) >> shift; + + + heap->local_age = ++heap->global_age[0]; + list = heap->global_regions; + + + /* Update the context's local LRU + */ + + move_to_head( & heap->texture_objects, t ); + + + for (i = start ; i <= end ; i++) { + list[i].age = heap->local_age; + + /* remove_from_list(i) + */ + list[(unsigned)list[i].next].prev = list[i].prev; + list[(unsigned)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) + */ + list[i].prev = heap->nrRegions; + list[i].next = list[heap->nrRegions].next; + list[(unsigned)list[heap->nrRegions].next].prev = i; + list[heap->nrRegions].next = i; + } + + if ( 0 ) { + printGlobalLRU( heap, __FUNCTION__ ); + printLocalLRU( heap, __FUNCTION__ ); + } + } +} + + + + +/** + * Keep track of swapped out texture objects. + * + * \param t Texture object to be "swapped" out of its texture heap + */ + +void driSwapOutTextureObject( driTextureObject * t ) +{ + unsigned face; + + + if ( t->memBlock != NULL ) { + assert( t->heap != NULL ); + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + + if (t->timestamp > t->heap->timestamp) + t->heap->timestamp = t->timestamp; + + t->heap->texture_swaps[0]++; + move_to_tail( t->heap->swapped_objects, t ); + t->heap = NULL; + } + else { + assert( t->heap == NULL ); + } + + + for ( face = 0 ; face < 6 ; face++ ) { + t->dirty_images[face] = ~0; + } +} + + + + +/** + * Destroy hardware state associated with texture \a t. Calls the + * \a destroy_texture_object method associated with the heap from which + * \a t was allocated. + * + * \param t Texture object to be destroyed + */ + +void driDestroyTextureObject( driTextureObject * t ) +{ + driTexHeap * heap; + + + if ( 0 ) { + fprintf( stderr, "[%s:%d] freeing %p (tObj = %p, DriverData = %p)\n", + __FILE__, __LINE__, + (void *)t, + (void *)((t != NULL) ? t->tObj : NULL), + (void *)((t != NULL && t->tObj != NULL) ? t->tObj->DriverData : NULL )); + } + + if ( t != NULL ) { + if ( t->memBlock ) { + heap = t->heap; + assert( heap != NULL ); + + heap->texture_swaps[0]++; + + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + + if (t->timestamp > t->heap->timestamp) + t->heap->timestamp = t->timestamp; + + heap->destroy_texture_object( heap->driverContext, t ); + t->heap = NULL; + } + + if ( t->tObj != NULL ) { + assert( t->tObj->DriverData == t ); + t->tObj->DriverData = NULL; + } + + remove_from_list( t ); + FREE( t ); + } + + if ( 0 ) { + fprintf( stderr, "[%s:%d] done freeing %p\n", __FILE__, __LINE__, (void *)t ); + } +} + + + + +/** + * Update the local heap's representation of texture memory based on + * data in the SAREA. This is done each time it is detected that some other + * direct rendering client has held the lock. This pertains to both our local + * textures and the textures belonging to other clients. Keep track of other + * client's textures by pushing a placeholder texture onto the LRU list -- + * these are denoted by \a tObj being \a NULL. + * + * \param heap Heap whose state is to be updated + * \param offset Byte offset in the heap that has been stolen + * \param size Size, in bytes, of the stolen block + * \param in_use Non-zero if the block is pinned/reserved by the kernel + */ + +static void driTexturesGone( driTexHeap * heap, int offset, int size, + int in_use ) +{ + driTextureObject * t; + driTextureObject * tmp; + + + foreach_s ( t, tmp, & heap->texture_objects ) { + if ( (t->memBlock->ofs < (offset + size)) + && ((t->memBlock->ofs + t->memBlock->size) > offset) ) { + /* It overlaps - kick it out. If the texture object is just a + * place holder, then destroy it all together. Otherwise, mark + * it as being swapped out. + */ + + if ( t->tObj != NULL ) { + driSwapOutTextureObject( t ); + } + else { + driDestroyTextureObject( t ); + } + } + } + + + { + t = (driTextureObject *) CALLOC( heap->texture_object_size ); + if ( t == NULL ) return; + + t->memBlock = mmAllocMem( heap->memory_heap, size, 0, offset ); + if ( t->memBlock == NULL ) { + fprintf( stderr, "Couldn't alloc placeholder: heap %u sz %x ofs %x\n", heap->heapId, + (int)size, (int)offset ); + mmDumpMemInfo( heap->memory_heap ); + FREE(t); + return; + } + t->heap = heap; + if (in_use) + t->reserved = 1; + insert_at_head( & heap->texture_objects, t ); + } +} + + + + +/** + * Called by the client on lock contention to determine whether textures have + * been stolen. If another client has modified a region in which we have + * textures, then we need to figure out which of our textures have been + * removed and update our global LRU. + * + * \param heap Texture heap to be updated + */ + +void driAgeTextures( driTexHeap * heap ) +{ + drmTextureRegionPtr list = heap->global_regions; + unsigned sz = 1U << (heap->logGranularity); + unsigned i, nr = 0; + + + /* Have to go right round from the back to ensure stuff ends up + * LRU in the local list... Fix with a cursor pointer. + */ + + for (i = list[heap->nrRegions].prev ; + i != heap->nrRegions && nr < heap->nrRegions ; + i = list[i].prev, nr++) { + /* If switching texturing schemes, then the SAREA might not have been + * properly cleared, so we need to reset the global texture LRU. + */ + + if ( (i * sz) > heap->size ) { + nr = heap->nrRegions; + break; + } + + if (list[i].age > heap->local_age) + driTexturesGone( heap, i * sz, sz, list[i].in_use); + } + + /* Loop or uninitialized heap detected. Reset. + */ + + if (nr == heap->nrRegions) { + driTexturesGone( heap, 0, heap->size, 0); + resetGlobalLRU( heap ); + } + + if ( 0 ) { + printGlobalLRU( heap, __FUNCTION__ ); + printLocalLRU( heap, __FUNCTION__ ); + } + + heap->local_age = heap->global_age[0]; +} + + + + +#define INDEX_ARRAY_SIZE 6 /* I'm not aware of driver with more than 2 heaps */ + +/** + * Allocate memory from a texture heap to hold a texture object. This + * routine will attempt to allocate memory for the texture from the heaps + * specified by \c heap_array in order. That is, first it will try to + * allocate from \c heap_array[0], then \c heap_array[1], and so on. + * + * \param heap_array Array of pointers to texture heaps to use + * \param nr_heaps Number of heap pointer in \a heap_array + * \param t Texture object for which space is needed + * \return The ID of the heap from which memory was allocated, or -1 if + * memory could not be allocated. + * + * \bug The replacement policy implemented by this function is horrible. + */ + + +int +driAllocateTexture( driTexHeap * const * heap_array, unsigned nr_heaps, + driTextureObject * t ) +{ + driTexHeap * heap; + driTextureObject * temp; + driTextureObject * cursor; + unsigned id; + + + /* In case it already has texture space, initialize heap. This also + * prevents GCC from issuing a warning that heap might be used + * uninitialized. + */ + + heap = t->heap; + + + /* Run through each of the existing heaps and try to allocate a buffer + * to hold the texture. + */ + + for ( id = 0 ; (t->memBlock == NULL) && (id < nr_heaps) ; id++ ) { + heap = heap_array[ id ]; + if ( heap != NULL ) { + t->memBlock = mmAllocMem( heap->memory_heap, t->totalSize, + heap->alignmentShift, 0 ); + } + } + + + /* Kick textures out until the requested texture fits. + */ + + if ( t->memBlock == NULL ) { + unsigned index[INDEX_ARRAY_SIZE]; + unsigned nrGoodHeaps = 0; + + /* Trying to avoid dynamic memory allocation. If you have more + * heaps, increase INDEX_ARRAY_SIZE. I'm not aware of any + * drivers with more than 2 tex heaps. */ + assert( nr_heaps < INDEX_ARRAY_SIZE ); + + /* Sort large enough heaps by duty. Insertion sort should be + * fast enough for such a short array. */ + for ( id = 0 ; id < nr_heaps ; id++ ) { + heap = heap_array[ id ]; + + if ( heap != NULL && t->totalSize <= heap->size ) { + unsigned j; + + for ( j = 0 ; j < nrGoodHeaps; j++ ) { + if ( heap->duty > heap_array[ index[ j ] ]->duty ) + break; + } + + if ( j < nrGoodHeaps ) { + memmove( &index[ j+1 ], &index[ j ], + sizeof(index[ 0 ]) * (nrGoodHeaps - j) ); + } + + index[ j ] = id; + + nrGoodHeaps++; + } + } + + for ( id = 0 ; (t->memBlock == NULL) && (id < nrGoodHeaps) ; id++ ) { + heap = heap_array[ index[ id ] ]; + + for ( cursor = heap->texture_objects.prev, temp = cursor->prev; + cursor != &heap->texture_objects ; + cursor = temp, temp = cursor->prev ) { + + /* The the LRU element. If the texture is bound to one of + * the texture units, then we cannot kick it out. + */ + if ( cursor->bound || cursor->reserved ) { + continue; + } + + if ( cursor->memBlock ) + heap->duty -= cursor->memBlock->size; + + /* If this is a placeholder, there's no need to keep it */ + if (cursor->tObj) + driSwapOutTextureObject( cursor ); + else + driDestroyTextureObject( cursor ); + + t->memBlock = mmAllocMem( heap->memory_heap, t->totalSize, + heap->alignmentShift, 0 ); + + if (t->memBlock) + break; + } + } + + /* Rebalance duties. If a heap kicked more data than its duty, + * then all other heaps get that amount multiplied with their + * relative weight added to their duty. The negative duty is + * reset to 0. In the end all heaps have a duty >= 0. + * + * CAUTION: we must not change the heap pointer here, because it + * is used below to update the texture object. + */ + for ( id = 0 ; id < nr_heaps ; id++ ) + if ( heap_array[ id ] != NULL && heap_array[ id ]->duty < 0) { + int duty = -heap_array[ id ]->duty; + double weight = heap_array[ id ]->weight; + unsigned j; + + for ( j = 0 ; j < nr_heaps ; j++ ) + if ( j != id && heap_array[ j ] != NULL ) { + heap_array[ j ]->duty += (double) duty * + heap_array[ j ]->weight / weight; + } + + heap_array[ id ]->duty = 0; + } + } + + + if ( t->memBlock != NULL ) { + /* id and heap->heapId may or may not be the same value here. + */ + + assert( heap != NULL ); + assert( (t->heap == NULL) || (t->heap == heap) ); + + t->heap = heap; + return heap->heapId; + } + else { + assert( t->heap == NULL ); + + fprintf( stderr, "[%s:%d] unable to allocate texture\n", + __FUNCTION__, __LINE__ ); + return -1; + } +} + + + + + + +/** + * Set the location where the texture-swap counter is stored. + */ + +void +driSetTextureSwapCounterLocation( driTexHeap * heap, unsigned * counter ) +{ + heap->texture_swaps = (counter == NULL) ? & dummy_swap_counter : counter; +} + + + + +/** + * Create a new heap for texture data. + * + * \param heap_id Device-dependent heap identifier. This value + * will returned by driAllocateTexture when memory + * is allocated from this heap. + * \param context Device-dependent driver context. This is + * supplied as the first parameter to the + * \c destroy_tex_obj function. + * \param size Size, in bytes, of the texture region + * \param alignmentShift Alignment requirement for textures. If textures + * must be allocated on a 4096 byte boundry, this + * would be 12. + * \param nr_regions Number of regions into which this texture space + * should be partitioned + * \param global_regions Array of \c drmTextureRegion structures in the SAREA + * \param global_age Pointer to the global texture age in the SAREA + * \param swapped_objects Pointer to the list of texture objects that are + * not in texture memory (i.e., have been swapped + * out). + * \param texture_object_size Size, in bytes, of a device-dependent texture + * object + * \param destroy_tex_obj Function used to destroy a device-dependent + * texture object + * + * \sa driDestroyTextureHeap + */ + +driTexHeap * +driCreateTextureHeap( unsigned heap_id, void * context, unsigned size, + unsigned alignmentShift, unsigned nr_regions, + drmTextureRegionPtr global_regions, unsigned * global_age, + driTextureObject * swapped_objects, + unsigned texture_object_size, + destroy_texture_object_t * destroy_tex_obj + ) +{ + driTexHeap * heap; + unsigned l; + + + if ( 0 ) + fprintf( stderr, "%s( %u, %p, %u, %u, %u )\n", + __FUNCTION__, + heap_id, (void *)context, size, alignmentShift, nr_regions ); + + heap = (driTexHeap *) CALLOC( sizeof( driTexHeap ) ); + if ( heap != NULL ) { + l = driLog2( (size - 1) / nr_regions ); + if ( l < alignmentShift ) + { + l = alignmentShift; + } + + heap->logGranularity = l; + heap->size = size & ~((1L << l) - 1); + + heap->memory_heap = mmInit( 0, heap->size ); + if ( heap->memory_heap != NULL ) { + heap->heapId = heap_id; + heap->driverContext = context; + + heap->alignmentShift = alignmentShift; + heap->nrRegions = nr_regions; + heap->global_regions = global_regions; + heap->global_age = global_age; + heap->swapped_objects = swapped_objects; + heap->texture_object_size = texture_object_size; + heap->destroy_texture_object = destroy_tex_obj; + + /* Force global heap init */ + if (heap->global_age[0] == 0) + heap->local_age = ~0; + else + heap->local_age = 0; + + make_empty_list( & heap->texture_objects ); + driSetTextureSwapCounterLocation( heap, NULL ); + + heap->weight = heap->size; + heap->duty = 0; + } + else { + FREE( heap ); + heap = NULL; + } + } + + + if ( 0 ) + fprintf( stderr, "%s returning %p\n", __FUNCTION__, (void *)heap ); + + return heap; +} + + + + +/** Destroys a texture heap + * + * \param heap Texture heap to be destroyed + */ + +void +driDestroyTextureHeap( driTexHeap * heap ) +{ + driTextureObject * t; + driTextureObject * temp; + + + if ( heap != NULL ) { + foreach_s( t, temp, & heap->texture_objects ) { + driDestroyTextureObject( t ); + } + foreach_s( t, temp, heap->swapped_objects ) { + driDestroyTextureObject( t ); + } + + mmDestroy( heap->memory_heap ); + FREE( heap ); + } +} + + + + +/****************************************************************************/ +/** + * Determine how many texels (including all mipmap levels) would be required + * for a texture map of size \f$2^^\c base_size_log2\f$ would require. + * + * \param base_size_log2 \f$log_2\f$ of the size of a side of the texture + * \param dimensions Number of dimensions of the texture. Either 2 or 3. + * \param faces Number of faces of the texture. Either 1 or 6 (for cube maps). + * \return Number of texels + */ + +static unsigned +texels_this_map_size( int base_size_log2, unsigned dimensions, unsigned faces ) +{ + unsigned texels; + + + assert( (faces == 1) || (faces == 6) ); + assert( (dimensions == 2) || (dimensions == 3) ); + + texels = 0; + if ( base_size_log2 >= 0 ) { + texels = (1U << (dimensions * base_size_log2)); + + /* See http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg03636.html + * for the complete explaination of why this formulation is used. + * Basically, the smaller mipmap levels sum to 0.333 the size of the + * level 0 map. The total size is therefore the size of the map + * multipled by 1.333. The +2 is there to round up. + */ + + texels = (texels * 4 * faces + 2) / 3; + } + + return texels; +} + + + + +struct maps_per_heap { + unsigned c[32]; +}; + +static void +fill_in_maximums( driTexHeap * const * heaps, unsigned nr_heaps, + unsigned max_bytes_per_texel, unsigned max_size, + unsigned mipmaps_at_once, unsigned dimensions, + unsigned faces, struct maps_per_heap * max_textures ) +{ + unsigned heap; + unsigned log2_size; + unsigned mask; + + + /* Determine how many textures of each size can be stored in each + * texture heap. + */ + + for ( heap = 0 ; heap < nr_heaps ; heap++ ) { + if ( heaps[ heap ] == NULL ) { + (void) memset( max_textures[ heap ].c, 0, + sizeof( max_textures[ heap ].c ) ); + continue; + } + + mask = (1U << heaps[ heap ]->logGranularity) - 1; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] heap[%u] = %u bytes, mask = 0x%08x\n", + __FILE__, __LINE__, + heap, heaps[ heap ]->size, mask ); + } + + for ( log2_size = max_size ; log2_size > 0 ; log2_size-- ) { + unsigned total; + + + /* Determine the total number of bytes required by a texture of + * size log2_size. + */ + + total = texels_this_map_size( log2_size, dimensions, faces ) + - texels_this_map_size( log2_size - mipmaps_at_once, + dimensions, faces ); + total *= max_bytes_per_texel; + total = (total + mask) & ~mask; + + /* The number of textures of a given size that will fit in a heap + * is equal to the size of the heap divided by the size of the + * texture. + */ + + max_textures[ heap ].c[ log2_size ] = heaps[ heap ]->size / total; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] max_textures[%u].c[%02u] " + "= 0x%08x / 0x%08x " + "= %u (%u)\n", + __FILE__, __LINE__, + heap, log2_size, + heaps[ heap ]->size, total, + heaps[ heap ]->size / total, + max_textures[ heap ].c[ log2_size ] ); + } + } + } +} + + +static unsigned +get_max_size( unsigned nr_heaps, + unsigned texture_units, + unsigned max_size, + int all_textures_one_heap, + struct maps_per_heap * max_textures ) +{ + unsigned heap; + unsigned log2_size; + + + /* Determine the largest texture size such that a texture of that size + * can be bound to each texture unit at the same time. Some hardware + * may require that all textures be in the same texture heap for + * multitexturing. + */ + + for ( log2_size = max_size ; log2_size > 0 ; log2_size-- ) { + unsigned total = 0; + + for ( heap = 0 ; heap < nr_heaps ; heap++ ) + { + total += max_textures[ heap ].c[ log2_size ]; + + if ( 0 ) { + fprintf( stderr, "[%s:%d] max_textures[%u].c[%02u] = %u, " + "total = %u\n", __FILE__, __LINE__, heap, log2_size, + max_textures[ heap ].c[ log2_size ], total ); + } + + if ( (max_textures[ heap ].c[ log2_size ] >= texture_units) + || (!all_textures_one_heap && (total >= texture_units)) ) { + /* The number of mipmap levels is the log-base-2 of the + * maximum texture size plus 1. If the maximum texture size + * is 1x1, the log-base-2 is 0 and 1 mipmap level (the base + * level) is available. + */ + + return log2_size + 1; + } + } + } + + /* This should NEVER happen. It should always be possible to have at + * *least* a 1x1 texture in memory! + */ + assert( log2_size != 0 ); + return 0; +} + +#define SET_MAX(f,v) \ + do { if ( max_sizes[v] != 0 ) { limits-> f = max_sizes[v]; } } while( 0 ) + +#define SET_MAX_RECT(f,v) \ + do { if ( max_sizes[v] != 0 ) { limits-> f = 1 << (max_sizes[v] - 1); } } while( 0 ) + + +/** + * Given the amount of texture memory, the number of texture units, and the + * maximum size of a texel, calculate the maximum texture size the driver can + * advertise. + * + * \param heaps Texture heaps for this card + * \param nr_heap Number of texture heaps + * \param limits OpenGL contants. MaxTextureUnits must be set. + * \param max_bytes_per_texel Maximum size of a single texel, in bytes + * \param max_2D_size \f$\log_2\f$ of the maximum 2D texture size (i.e., + * 1024x1024 textures, this would be 10) + * \param max_3D_size \f$\log_2\f$ of the maximum 3D texture size (i.e., + * 1024x1024x1024 textures, this would be 10) + * \param max_cube_size \f$\log_2\f$ of the maximum cube texture size (i.e., + * 1024x1024 textures, this would be 10) + * \param max_rect_size \f$\log_2\f$ of the maximum texture rectangle size + * (i.e., 1024x1024 textures, this would be 10). This is a power-of-2 + * even though texture rectangles need not be a power-of-2. + * \param mipmaps_at_once Total number of mipmaps that can be used + * at one time. For most hardware this will be \f$\c max_size + 1\f$. + * For hardware that does not support mipmapping, this will be 1. + * \param all_textures_one_heap True if the hardware requires that all + * textures be in a single texture heap for multitexturing. + * \param allow_larger_textures 0 conservative, 1 calculate limits + * so at least one worst-case texture can fit, 2 just use hw limits. + */ + +void +driCalculateMaxTextureLevels( driTexHeap * const * heaps, + unsigned nr_heaps, + struct gl_constants * limits, + unsigned max_bytes_per_texel, + unsigned max_2D_size, + unsigned max_3D_size, + unsigned max_cube_size, + unsigned max_rect_size, + unsigned mipmaps_at_once, + int all_textures_one_heap, + int allow_larger_textures ) +{ + struct maps_per_heap max_textures[8]; + unsigned i; + const unsigned dimensions[4] = { 2, 3, 2, 2 }; + const unsigned faces[4] = { 1, 1, 6, 1 }; + unsigned max_sizes[4]; + unsigned mipmaps[4]; + + + max_sizes[0] = max_2D_size; + max_sizes[1] = max_3D_size; + max_sizes[2] = max_cube_size; + max_sizes[3] = max_rect_size; + + mipmaps[0] = mipmaps_at_once; + mipmaps[1] = mipmaps_at_once; + mipmaps[2] = mipmaps_at_once; + mipmaps[3] = 1; + + + /* Calculate the maximum number of texture levels in two passes. The + * first pass determines how many textures of each power-of-two size + * (including all mipmap levels for that size) can fit in each texture + * heap. The second pass finds the largest texture size that allows + * a texture of that size to be bound to every texture unit. + */ + + for ( i = 0 ; i < 4 ; i++ ) { + if ( (allow_larger_textures != 2) && (max_sizes[ i ] != 0) ) { + fill_in_maximums( heaps, nr_heaps, max_bytes_per_texel, + max_sizes[ i ], mipmaps[ i ], + dimensions[ i ], faces[ i ], + max_textures ); + + max_sizes[ i ] = get_max_size( nr_heaps, + allow_larger_textures == 1 ? + 1 : limits->MaxTextureUnits, + max_sizes[ i ], + all_textures_one_heap, + max_textures ); + } + else if (max_sizes[ i ] != 0) { + max_sizes[ i ] += 1; + } + } + + SET_MAX( MaxTextureLevels, 0 ); + SET_MAX( Max3DTextureLevels, 1 ); + SET_MAX( MaxCubeTextureLevels, 2 ); + SET_MAX_RECT( MaxTextureRectSize, 3 ); +} + + + + +/** + * Perform initial binding of default textures objects on a per unit, per + * texture target basis. + * + * \param ctx Current OpenGL context + * \param swapped List of swapped-out textures + * \param targets Bit-mask of value texture targets + */ + +void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped, + GLuint targets ) +{ + struct gl_texture_object *texObj; + GLuint tmp = ctx->Texture.CurrentUnit; + unsigned i; + + + for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { + ctx->Texture.CurrentUnit = i; + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_1D) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_1D_INDEX]; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_1D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_2D) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_2D_INDEX]; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_2D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_3D) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_3D_INDEX]; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_3D, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_CUBE) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_CUBE_INDEX]; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_CUBE_MAP_ARB, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + + if ( (targets & DRI_TEXMGR_DO_TEXTURE_RECT) != 0 ) { + texObj = ctx->Texture.Unit[i].CurrentTex[TEXTURE_RECT_INDEX]; + ctx->Driver.BindTexture( ctx, GL_TEXTURE_RECTANGLE_NV, texObj ); + move_to_tail( swapped, (driTextureObject *) texObj->DriverData ); + } + } + + ctx->Texture.CurrentUnit = tmp; +} + + + + +/** + * Verify that the specified texture is in the specificed heap. + * + * \param tex Texture to be tested. + * \param heap Texture memory heap to be tested. + * \return True if the texture is in the heap, false otherwise. + */ + +static GLboolean +check_in_heap( const driTextureObject * tex, const driTexHeap * heap ) +{ +#if 1 + return tex->heap == heap; +#else + driTextureObject * curr; + + foreach( curr, & heap->texture_objects ) { + if ( curr == tex ) { + break; + } + } + + return curr == tex; +#endif +} + + + +/****************************************************************************/ +/** + * Validate the consistency of a set of texture heaps. + * Original version by Keith Whitwell in r200/r200_sanity.c. + */ + +GLboolean +driValidateTextureHeaps( driTexHeap * const * texture_heaps, + unsigned nr_heaps, const driTextureObject * swapped ) +{ + driTextureObject *t; + unsigned i; + + for ( i = 0 ; i < nr_heaps ; i++ ) { + int last_end = 0; + unsigned textures_in_heap = 0; + unsigned blocks_in_mempool = 0; + const driTexHeap * heap = texture_heaps[i]; + const struct mem_block *p = heap->memory_heap; + + /* Check each texture object has a MemBlock, and is linked into + * the correct heap. + * + * Check the texobj base address corresponds to the MemBlock + * range. Check the texobj size (recalculate?) fits within + * the MemBlock. + * + * Count the number of texobj's using this heap. + */ + + foreach ( t, &heap->texture_objects ) { + if ( !check_in_heap( t, heap ) ) { + fprintf( stderr, "%s memory block for texture object @ %p not " + "found in heap #%d\n", + __FUNCTION__, (void *)t, i ); + return GL_FALSE; + } + + + if ( t->totalSize > t->memBlock->size ) { + fprintf( stderr, "%s: Memory block for texture object @ %p is " + "only %u bytes, but %u are required\n", + __FUNCTION__, (void *)t, t->totalSize, t->memBlock->size ); + return GL_FALSE; + } + + textures_in_heap++; + } + + /* Validate the contents of the heap: + * - Ordering + * - Overlaps + * - Bounds + */ + + while ( p != NULL ) { + if (p->reserved) { + fprintf( stderr, "%s: Block (%08x,%x), is reserved?!\n", + __FUNCTION__, p->ofs, p->size ); + return GL_FALSE; + } + + if (p->ofs != last_end) { + fprintf( stderr, "%s: blocks_in_mempool = %d, last_end = %d, p->ofs = %d\n", + __FUNCTION__, blocks_in_mempool, last_end, p->ofs ); + return GL_FALSE; + } + + if (!p->reserved && !p->free) { + blocks_in_mempool++; + } + + last_end = p->ofs + p->size; + p = p->next; + } + + if (textures_in_heap != blocks_in_mempool) { + fprintf( stderr, "%s: Different number of textures objects (%u) and " + "inuse memory blocks (%u)\n", + __FUNCTION__, textures_in_heap, blocks_in_mempool ); + return GL_FALSE; + } + +#if 0 + fprintf( stderr, "%s: textures_in_heap = %u\n", + __FUNCTION__, textures_in_heap ); +#endif + } + + + /* Check swapped texobj's have zero memblocks + */ + i = 0; + foreach ( t, swapped ) { + if ( t->memBlock != NULL ) { + fprintf( stderr, "%s: Swapped texobj %p has non-NULL memblock %p\n", + __FUNCTION__, (void *)t, (void *)t->memBlock ); + return GL_FALSE; + } + i++; + } + +#if 0 + fprintf( stderr, "%s: swapped texture count = %u\n", __FUNCTION__, i ); +#endif + + return GL_TRUE; +} + + + + +/****************************************************************************/ +/** + * Compute which mipmap levels that really need to be sent to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + */ + +void +driCalculateTextureFirstLastLevel( driTextureObject * t ) +{ + struct gl_texture_object * const tObj = t->tObj; + const struct gl_texture_image * const baseImage = + tObj->Image[0][tObj->BaseLevel]; + + /* These must be signed values. MinLod and MaxLod can be negative numbers, + * and having firstLevel and lastLevel as signed prevents the need for + * extra sign checks. + */ + int firstLevel; + int lastLevel; + + /* Yes, this looks overly complicated, but it's all needed. + */ + + switch (tObj->Target) { + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { + /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. + */ + + firstLevel = lastLevel = tObj->BaseLevel; + } + else { + firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + firstLevel = MIN2(firstLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, t->tObj->BaseLevel); + lastLevel = MIN2(lastLevel, t->tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, t->tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + break; + case GL_TEXTURE_RECTANGLE_NV: + case GL_TEXTURE_4D_SGIS: + firstLevel = lastLevel = 0; + break; + default: + return; + } + + /* save these values */ + t->firstLevel = firstLevel; + t->lastLevel = lastLevel; +} + + + + +/** + * \name DRI texture formats. Pointers initialized to either the big- or + * little-endian Mesa formats. + */ +/*@{*/ +const struct gl_texture_format *_dri_texformat_rgba8888 = NULL; +const struct gl_texture_format *_dri_texformat_argb8888 = NULL; +const struct gl_texture_format *_dri_texformat_rgb565 = NULL; +const struct gl_texture_format *_dri_texformat_argb4444 = NULL; +const struct gl_texture_format *_dri_texformat_argb1555 = NULL; +const struct gl_texture_format *_dri_texformat_al88 = NULL; +const struct gl_texture_format *_dri_texformat_a8 = &_mesa_texformat_a8; +const struct gl_texture_format *_dri_texformat_ci8 = &_mesa_texformat_ci8; +const struct gl_texture_format *_dri_texformat_i8 = &_mesa_texformat_i8; +const struct gl_texture_format *_dri_texformat_l8 = &_mesa_texformat_l8; +/*@}*/ + + +/** + * Initialize little endian target, host byte order independent texture formats + */ +void +driInitTextureFormats(void) +{ + const GLuint ui = 1; + const GLubyte littleEndian = *((const GLubyte *) &ui); + + if (littleEndian) { + _dri_texformat_rgba8888 = &_mesa_texformat_rgba8888; + _dri_texformat_argb8888 = &_mesa_texformat_argb8888; + _dri_texformat_rgb565 = &_mesa_texformat_rgb565; + _dri_texformat_argb4444 = &_mesa_texformat_argb4444; + _dri_texformat_argb1555 = &_mesa_texformat_argb1555; + _dri_texformat_al88 = &_mesa_texformat_al88; + } + else { + _dri_texformat_rgba8888 = &_mesa_texformat_rgba8888_rev; + _dri_texformat_argb8888 = &_mesa_texformat_argb8888_rev; + _dri_texformat_rgb565 = &_mesa_texformat_rgb565_rev; + _dri_texformat_argb4444 = &_mesa_texformat_argb4444_rev; + _dri_texformat_argb1555 = &_mesa_texformat_argb1555_rev; + _dri_texformat_al88 = &_mesa_texformat_al88_rev; + } +} diff --git a/mesalib/src/mesa/drivers/dri/common/texmem.h b/mesalib/src/mesa/drivers/dri/common/texmem.h new file mode 100644 index 000000000..9c065da8b --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/texmem.h @@ -0,0 +1,333 @@ +/* + * Copyright 2000-2001 VA Linux Systems, Inc. + * (c) Copyright IBM Corporation 2002 + * 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. + * + * Authors: + * Ian Romanick <idr@us.ibm.com> + * Keith Whitwell <keithw@tungstengraphics.com> + * Kevin E. Martin <kem@users.sourceforge.net> + * Gareth Hughes <gareth@nvidia.com> + */ + +/** \file texmem.h + * Public interface to the DRI texture memory management routines. + * + * \sa texmem.c + */ + +#ifndef DRI_TEXMEM_H +#define DRI_TEXMEM_H + +#include "main/mtypes.h" +#include "main/mm.h" +#include "xf86drm.h" + +struct dri_tex_heap; +typedef struct dri_tex_heap driTexHeap; + +struct dri_texture_object; +typedef struct dri_texture_object driTextureObject; + + +/** + * Base texture object type. Each driver will extend this type with its own + * private data members. + */ + +struct dri_texture_object { + struct dri_texture_object * next; + struct dri_texture_object * prev; + + driTexHeap * heap; /**< Texture heap currently stored in */ + struct gl_texture_object * tObj;/**< Pointer to Mesa texture object + * If NULL, this texture object is a + * "placeholder" object representing + * texture memory in use by another context. + * A placeholder should have a heap and a memBlock. + */ + struct mem_block *memBlock; /**< Memory block containing texture */ + + unsigned reserved; /**< Cannot be swapped out by user contexts. */ + + unsigned bound; /**< Bitmask indicating which tex units + * this texture object is bound to. + * Bit 0 = unit 0, Bit 1 = unit 1, etc + */ + + unsigned totalSize; /**< Total size of the texture, + * including all mipmap levels + */ + + unsigned dirty_images[6]; /**< Flags for whether or not images + * need to be uploaded to local or + * AGP texture space. One flag set + * for each cube face for cubic + * textures. Bit zero corresponds to + * the base-level, which may or may + * not be the level zero mipmap. + */ + + unsigned timestamp; /**< Timestamp used to + * synchronize with 3d engine + * in hardware where textures + * are uploaded directly to + * the framebuffer. + */ + + unsigned firstLevel; /**< Image in \c tObj->Image[0] that + * corresponds to the base-level of + * this texture object. + */ + + unsigned lastLevel; /**< Last image in \c tObj->Image[0] + * used by the + * current LOD settings of + * this texture object. This + * value must be greater than + * or equal to \c firstLevel. + */ +}; + + +typedef void (destroy_texture_object_t)( void * driverContext, + driTextureObject * t ); + +/** + * Client-private representation of texture memory state. + * + * Clients will place one or more of these structs in their driver + * context struct to manage one or more global texture heaps. + */ + +struct dri_tex_heap { + + /** Client-supplied heap identifier + */ + unsigned heapId; + + /** Pointer to the client's private context + */ + void *driverContext; + + /** Total size of the heap, in bytes + */ + unsigned size; + + /** \brief \f$log_2\f$ of size of single heap region + * + * Each context takes memory from the global texture heap in + * \f$2^{logGranularity}\f$ byte blocks. The value of + * \a logGranularity is based on the amount of memory represented + * by the heap and the maximum number of regions in the SAREA. Given + * \a b bytes of texture memory an \a n regions in the SAREA, + * \a logGranularity will be \f$\lfloor\log_2( b / n )\rfloor\f$. + */ + unsigned logGranularity; + + /** \brief Required alignment of allocations in this heap + * + * The alignment shift is supplied to \a mmAllocMem when memory is + * allocated from this heap. The value of \a alignmentShift will + * typically reflect some require of the hardware. This value has + * \b no \b relation to \a logGranularity. \a alignmentShift is a + * per-context value. + * + * \sa mmAllocMem + */ + unsigned alignmentShift; + + /** Number of elements in global list (the SAREA). + */ + unsigned nrRegions; + + /** Pointer to SAREA \a driTexRegion array + */ + drmTextureRegionPtr global_regions; + + /** Pointer to the texture state age (generation number) in the SAREA + */ + unsigned * global_age; + + /** Local age (generation number) of texture state + */ + unsigned local_age; + + /** Memory heap used to manage texture memory represented by + * this texture heap. + */ + struct mem_block * memory_heap; + + /** List of objects that we currently believe to be in texture + * memory. + */ + driTextureObject texture_objects; + + /** Pointer to the list of texture objects that are not in + * texture memory. + */ + driTextureObject * swapped_objects; + + /** Size of the driver-speicific texture object. + */ + unsigned texture_object_size; + + + /** + * \brief Function to destroy driver-specific texture object data. + * + * This function is supplied by the driver so that the texture manager + * can release all resources associated with a texture object. This + * function should only release driver-specific data. That is, + * \a driDestroyTextureObject will release the texture memory + * associated with the texture object, it will release the memory + * for the texture object itself, and it will unlink the texture + * object from the texture object lists. + * + * \param driverContext Pointer to the driver supplied context + * \param t Texture object that is to be destroyed + * \sa driDestroyTextureObject + */ + + destroy_texture_object_t * destroy_texture_object; + + + /** + */ + unsigned * texture_swaps; + + /** + * Timestamp used to synchronize with 3d engine in hardware + * where textures are uploaded directly to the + * framebuffer. + */ + unsigned timestamp; + + /** \brief Kick/upload weight + * + * When not enough free space is available this weight + * influences the choice of the heap from which textures are + * kicked. By default the weight is equal to the heap size. + */ + double weight; + + /** \brief Kick/upload duty + * + * The heap with the highest duty will be chosen for kicking + * textures if not enough free space is available. The duty is + * reduced by the amount of data kicked. Rebalancing of + * negative duties takes the weights into account. + */ + int duty; +}; + + + + +/** + * Called by the client on lock contention to determine whether textures have + * been stolen. If another client has modified a region in which we have + * textures, then we need to figure out which of our textures have been + * removed and update our global LRU. + * + * \param heap Texture heap to be updated + * \hideinitializer + */ + +#define DRI_AGE_TEXTURES( heap ) \ + do { \ + if ( ((heap) != NULL) \ + && ((heap)->local_age != (heap)->global_age[0]) ) \ + driAgeTextures( heap ); \ + } while( 0 ) + + + + +/* This should be called whenever there has been contention on the hardware + * lock. driAgeTextures should not be called directly. Instead, clients + * should use DRI_AGE_TEXTURES, above. + */ + +void driAgeTextures( driTexHeap * heap ); + +void driUpdateTextureLRU( driTextureObject * t ); +void driSwapOutTextureObject( driTextureObject * t ); +void driDestroyTextureObject( driTextureObject * t ); +int driAllocateTexture( driTexHeap * const * heap_array, unsigned nr_heaps, + driTextureObject * t ); + +GLboolean driIsTextureResident( GLcontext * ctx, + struct gl_texture_object * texObj ); + +driTexHeap * driCreateTextureHeap( unsigned heap_id, void * context, + unsigned size, unsigned alignmentShift, unsigned nr_regions, + drmTextureRegionPtr global_regions, unsigned * global_age, + driTextureObject * swapped_objects, unsigned texture_object_size, + destroy_texture_object_t * destroy_tex_obj ); +void driDestroyTextureHeap( driTexHeap * heap ); + +void +driCalculateMaxTextureLevels( driTexHeap * const * heaps, + unsigned nr_heaps, + struct gl_constants * limits, + unsigned max_bytes_per_texel, + unsigned max_2D_size, + unsigned max_3D_size, + unsigned max_cube_size, + unsigned max_rect_size, + unsigned mipmaps_at_once, + int all_textures_one_heap, + int allow_larger_textures ); + +void +driSetTextureSwapCounterLocation( driTexHeap * heap, unsigned * counter ); + +#define DRI_TEXMGR_DO_TEXTURE_1D 0x0001 +#define DRI_TEXMGR_DO_TEXTURE_2D 0x0002 +#define DRI_TEXMGR_DO_TEXTURE_3D 0x0004 +#define DRI_TEXMGR_DO_TEXTURE_CUBE 0x0008 +#define DRI_TEXMGR_DO_TEXTURE_RECT 0x0010 + +void driInitTextureObjects( GLcontext *ctx, driTextureObject * swapped, + GLuint targets ); + +GLboolean driValidateTextureHeaps( driTexHeap * const * texture_heaps, + unsigned nr_heaps, const driTextureObject * swapped ); + +extern void driCalculateTextureFirstLastLevel( driTextureObject * t ); + + +extern const struct gl_texture_format *_dri_texformat_rgba8888; +extern const struct gl_texture_format *_dri_texformat_argb8888; +extern const struct gl_texture_format *_dri_texformat_rgb565; +extern const struct gl_texture_format *_dri_texformat_argb4444; +extern const struct gl_texture_format *_dri_texformat_argb1555; +extern const struct gl_texture_format *_dri_texformat_al88; +extern const struct gl_texture_format *_dri_texformat_a8; +extern const struct gl_texture_format *_dri_texformat_ci8; +extern const struct gl_texture_format *_dri_texformat_i8; +extern const struct gl_texture_format *_dri_texformat_l8; + +extern void driInitTextureFormats( void ); + +#endif /* DRI_TEXMEM_H */ diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c new file mode 100644 index 000000000..66f277c10 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/utils.c @@ -0,0 +1,839 @@ +/* + * (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 "main/mtypes.h" +#include "main/cpuinfo.h" +#include "main/extensions.h" +#include "glapi/dispatch.h" +#include "utils.h" + + +int driDispatchRemapTable[ driDispatchRemapTable_size ]; + + +unsigned +driParseDebugString( 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. + */ +unsigned +driGetRendererString( char * buffer, const char * hardware_name, + const char * driver_date, GLuint agp_mode ) +{ + unsigned offset; + char *cpu; + + 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. + */ + cpu = _mesa_get_cpu_string(); + if (cpu) { + offset += sprintf(buffer + offset, " %s", cpu); + _mesa_free(cpu); + } + + return offset; +} + + + + +#define need_GL_ARB_draw_buffers +#define need_GL_ARB_multisample +#define need_GL_ARB_texture_compression +#define need_GL_ARB_transpose_matrix +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_window_pos +#define need_GL_EXT_compiled_vertex_array +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_polygon_offset +#define need_GL_EXT_texture_object +#define need_GL_EXT_vertex_array +#define need_GL_IBM_multimode_draw_arrays +#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_draw_buffers", GL_ARB_draw_buffers_functions }, + { "GL_ARB_multisample", GL_ARB_multisample_functions }, + { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, + { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions }, + { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_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_multi_draw_arrays", GL_EXT_multi_draw_arrays_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_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_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) { +#if 0 /* this causes noise with egl */ + fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed " + "to add %s!\n", functions[0]); +#endif + } + 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. + */ +GLboolean +driCheckDriDdxDrmVersions3(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; +} + +GLboolean +driCheckDriDdxDrmVersions2(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 */ + if (*y < buffer->_Ymin) { + *height -= (buffer->_Ymin - *y); + *y = buffer->_Ymin; + } + + /* top clipping */ + if (*y + *height > buffer->_Ymax) + *height -= (*y + *height - buffer->_Ymax - 1); + + if (*height <= 0) + return GL_FALSE; + + return GL_TRUE; +} + +/** + * Creates a set of \c __GLcontextModes that a driver will expose. + * + * A set of \c __GLcontextModes will be created based on the supplied + * parameters. The number of modes processed will be 2 * + * \c num_depth_stencil_bits * \c num_db_modes. + * + * For the most part, data is just copied from \c depth_bits, \c stencil_bits, + * \c db_modes, and \c visType into each \c __GLcontextModes element. + * However, the meanings of \c fb_format and \c fb_type require further + * explanation. The \c fb_format specifies which color components are in + * each pixel and what the default order is. For example, \c GL_RGB specifies + * that red, green, blue are available and red is in the "most significant" + * position and blue is in the "least significant". The \c fb_type specifies + * the bit sizes of each component and the actual ordering. For example, if + * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11] + * are the blue value, bits [10:5] are the green value, and bits [4:0] are + * the red value. + * + * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either + * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the + * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or + * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as + * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8 + * still uses 32-bits. + * + * If in doubt, look at the tables used in the function. + * + * \param ptr_to_modes Pointer to a pointer to a linked list of + * \c __GLcontextModes. Upon completion, a pointer to + * the next element to be process will be stored here. + * If the function fails and returns \c GL_FALSE, this + * value will be unmodified, but some elements in the + * linked list may be modified. + * \param fb_format Format of the framebuffer. Currently only \c GL_RGB, + * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported. + * \param fb_type Type of the pixels in the framebuffer. Currently only + * \c GL_UNSIGNED_SHORT_5_6_5, + * \c GL_UNSIGNED_SHORT_5_6_5_REV, + * \c GL_UNSIGNED_INT_8_8_8_8, and + * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported. + * \param depth_bits Array of depth buffer sizes to be exposed. + * \param stencil_bits Array of stencil buffer sizes to be exposed. + * \param num_depth_stencil_bits Number of entries in both \c depth_bits and + * \c stencil_bits. + * \param db_modes Array of buffer swap modes. If an element has a + * value of \c GLX_NONE, then it represents a + * single-buffered mode. Other valid values are + * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and + * \c GLX_SWAP_UNDEFINED_OML. See the + * GLX_OML_swap_method extension spec for more details. + * \param num_db_modes Number of entries in \c db_modes. + * \param msaa_samples Array of msaa sample count. 0 represents a visual + * without a multisample buffer. + * \param num_msaa_modes Number of entries in \c msaa_samples. + * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or + * \c GLX_DIRECT_COLOR. + * + * \returns + * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only + * cause of failure is a bad parameter (i.e., unsupported \c fb_format or + * \c fb_type). + * + * \todo + * There is currently no way to support packed RGB modes (i.e., modes with + * exactly 3 bytes per pixel) or floating-point modes. This could probably + * be done by creating some new, private enums with clever names likes + * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32, + * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it. + */ +__DRIconfig ** +driCreateConfigs(GLenum fb_format, GLenum fb_type, + const uint8_t * depth_bits, const uint8_t * stencil_bits, + unsigned num_depth_stencil_bits, + const GLenum * db_modes, unsigned num_db_modes, + const uint8_t * msaa_samples, unsigned num_msaa_modes) +{ + static const uint8_t bits_table[4][4] = { + /* R G B A */ + { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */ + { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */ + { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */ + { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */ + }; + + static const uint32_t masks_table_rgb[6][4] = { + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ + { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */ + { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */ + }; + + static const uint32_t masks_table_rgba[6][4] = { + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */ + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */ + { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */ + { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */ + }; + + static const uint32_t masks_table_bgr[6][4] = { + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ + { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */ + { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */ + }; + + static const uint32_t masks_table_bgra[6][4] = { + { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */ + { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */ + { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */ + { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */ + { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */ + { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */ + }; + + static const uint8_t bytes_per_pixel[6] = { + 1, /* 3_3_2 */ + 1, /* 2_3_3_REV */ + 2, /* 5_6_5 */ + 2, /* 5_6_5_REV */ + 4, /* 8_8_8_8 */ + 4 /* 8_8_8_8_REV */ + }; + + const uint8_t * bits; + const uint32_t * masks; + int index; + __DRIconfig **configs, **c; + __GLcontextModes *modes; + unsigned i, j, k, h; + unsigned num_modes; + unsigned num_accum_bits = 2; + + switch ( fb_type ) { + case GL_UNSIGNED_BYTE_3_3_2: + index = 0; + break; + case GL_UNSIGNED_BYTE_2_3_3_REV: + index = 1; + break; + case GL_UNSIGNED_SHORT_5_6_5: + index = 2; + break; + case GL_UNSIGNED_SHORT_5_6_5_REV: + index = 3; + break; + case GL_UNSIGNED_INT_8_8_8_8: + index = 4; + break; + case GL_UNSIGNED_INT_8_8_8_8_REV: + index = 5; + break; + default: + fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n", + __FUNCTION__, __LINE__, fb_type ); + return NULL; + } + + + /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and + * the _REV versions. + * + * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA. + */ + + switch ( fb_format ) { + case GL_RGB: + masks = masks_table_rgb[ index ]; + break; + + case GL_RGBA: + masks = masks_table_rgba[ index ]; + break; + + case GL_BGR: + masks = masks_table_bgr[ index ]; + break; + + case GL_BGRA: + masks = masks_table_bgra[ index ]; + break; + + default: + fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n", + __FUNCTION__, __LINE__, fb_format ); + return NULL; + } + + switch ( bytes_per_pixel[ index ] ) { + case 1: + bits = bits_table[0]; + break; + case 2: + bits = bits_table[1]; + break; + default: + bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR)) + ? bits_table[2] + : bits_table[3]; + break; + } + + num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes; + configs = _mesa_calloc((num_modes + 1) * sizeof *configs); + if (configs == NULL) + return NULL; + + c = configs; + for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) { + for ( i = 0 ; i < num_db_modes ; i++ ) { + for ( h = 0 ; h < num_msaa_modes; h++ ) { + for ( j = 0 ; j < num_accum_bits ; j++ ) { + *c = _mesa_malloc (sizeof **c); + modes = &(*c)->modes; + c++; + + memset(modes, 0, sizeof *modes); + modes->redBits = bits[0]; + modes->greenBits = bits[1]; + modes->blueBits = bits[2]; + modes->alphaBits = bits[3]; + modes->redMask = masks[0]; + modes->greenMask = masks[1]; + modes->blueMask = masks[2]; + modes->alphaMask = masks[3]; + modes->rgbBits = modes->redBits + modes->greenBits + + modes->blueBits + modes->alphaBits; + + modes->accumRedBits = 16 * j; + modes->accumGreenBits = 16 * j; + modes->accumBlueBits = 16 * j; + modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0; + modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG; + + modes->stencilBits = stencil_bits[k]; + modes->depthBits = depth_bits[k]; + + modes->transparentPixel = GLX_NONE; + modes->transparentRed = GLX_DONT_CARE; + modes->transparentGreen = GLX_DONT_CARE; + modes->transparentBlue = GLX_DONT_CARE; + modes->transparentAlpha = GLX_DONT_CARE; + modes->transparentIndex = GLX_DONT_CARE; + modes->visualType = GLX_DONT_CARE; + modes->renderType = GLX_RGBA_BIT; + modes->drawableType = GLX_WINDOW_BIT; + modes->rgbMode = GL_TRUE; + + if ( db_modes[i] == GLX_NONE ) { + modes->doubleBufferMode = GL_FALSE; + } + else { + modes->doubleBufferMode = GL_TRUE; + modes->swapMethod = db_modes[i]; + } + + modes->samples = msaa_samples[h]; + modes->sampleBuffers = modes->samples ? 1 : 0; + + + modes->haveAccumBuffer = ((modes->accumRedBits + + modes->accumGreenBits + + modes->accumBlueBits + + modes->accumAlphaBits) > 0); + modes->haveDepthBuffer = (modes->depthBits > 0); + modes->haveStencilBuffer = (modes->stencilBits > 0); + + modes->bindToTextureRgb = GL_TRUE; + modes->bindToTextureRgba = GL_TRUE; + modes->bindToMipmapTexture = GL_FALSE; + modes->bindToTextureTargets = modes->rgbMode ? + __DRI_ATTRIB_TEXTURE_1D_BIT | + __DRI_ATTRIB_TEXTURE_2D_BIT | + __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT : + 0; + } + } + } + } + *c = NULL; + + return configs; +} + +__DRIconfig **driConcatConfigs(__DRIconfig **a, + __DRIconfig **b) +{ + __DRIconfig **all; + int i, j, index; + + i = 0; + while (a[i] != NULL) + i++; + j = 0; + while (b[j] != NULL) + j++; + + all = _mesa_malloc((i + j + 1) * sizeof *all); + index = 0; + for (i = 0; a[i] != NULL; i++) + all[index++] = a[i]; + for (j = 0; b[j] != NULL; j++) + all[index++] = b[j]; + all[index++] = NULL; + + _mesa_free(a); + _mesa_free(b); + + return all; +} + +#define __ATTRIB(attrib, field) \ + { attrib, offsetof(__GLcontextModes, field) } + +static const struct { unsigned int attrib, offset; } attribMap[] = { + __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), + __ATTRIB(__DRI_ATTRIB_LEVEL, level), + __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), + __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), + __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), + __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), + __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), + __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), + __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), + __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), + __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), + __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), + __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), + __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode), + __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), + __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), + __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), + __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), + __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets), + __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), + + /* The struct field doesn't matter here, these are handled by the + * switch in driGetConfigAttribIndex. We need them in the array + * so the iterator includes them though.*/ + __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level), + __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level) +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +static int +driGetConfigAttribIndex(const __DRIconfig *config, + unsigned int index, unsigned int *value) +{ + switch (attribMap[index].attrib) { + case __DRI_ATTRIB_RENDER_TYPE: + if (config->modes.rgbMode) + *value = __DRI_ATTRIB_RGBA_BIT; + else + *value = __DRI_ATTRIB_COLOR_INDEX_BIT; + break; + case __DRI_ATTRIB_CONFIG_CAVEAT: + if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG) + *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG; + else if (config->modes.visualRating == GLX_SLOW_CONFIG) + *value = __DRI_ATTRIB_SLOW_BIT; + else + *value = 0; + break; + case __DRI_ATTRIB_SWAP_METHOD: + break; + + case __DRI_ATTRIB_FLOAT_MODE: + *value = config->modes.floatMode; + break; + + default: + *value = *(unsigned int *) + ((char *) &config->modes + attribMap[index].offset); + + break; + } + + return GL_TRUE; +} + +int +driGetConfigAttrib(const __DRIconfig *config, + unsigned int attrib, unsigned int *value) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(attribMap); i++) + if (attribMap[i].attrib == attrib) + return driGetConfigAttribIndex(config, i, value); + + return GL_FALSE; +} + +int +driIndexConfigAttrib(const __DRIconfig *config, int index, + unsigned int *attrib, unsigned int *value) +{ + if (index >= 0 && index < ARRAY_SIZE(attribMap)) { + *attrib = attribMap[index].attrib; + return driGetConfigAttribIndex(config, index, value); + } + + return GL_FALSE; +} diff --git a/mesalib/src/mesa/drivers/dri/common/utils.h b/mesalib/src/mesa/drivers/dri/common/utils.h new file mode 100644 index 000000000..9e9e5bc22 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/utils.h @@ -0,0 +1,147 @@ +/* + * (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. + * + * Authors: + * Ian Romanick <idr@us.ibm.com> + */ + +#ifndef DRI_DEBUG_H +#define DRI_DEBUG_H + +#include <GL/gl.h> +#include <GL/internal/dri_interface.h> +#include "main/context.h" + +typedef struct __DRIutilversionRec2 __DRIutilversion2; + +struct dri_debug_control { + const char * string; + unsigned flag; +}; + +/** + * Description of the entry-points and parameters for an OpenGL function. + */ +struct dri_extension_function { + /** + * \brief + * Packed string describing the parameter signature and the entry-point + * names. + * + * The parameter signature and the names of the entry-points for this + * function are packed into a single string. The substrings are + * separated by NUL characters. The whole string is terminated by + * two consecutive NUL characters. + */ + const char * strings; + + + /** + * Location in the remap table where the dispatch offset should be + * stored. + */ + int remap_index; + + /** + * Offset of the function in the dispatch table. + */ + int offset; +}; + +/** + * Description of the API for an extension to OpenGL. + */ +struct dri_extension { + /** + * Name of the extension. + */ + const char * name; + + + /** + * Pointer to a list of \c dri_extension_function structures. The list + * is terminated by a structure with a \c NULL + * \c dri_extension_function::strings pointer. + */ + const struct dri_extension_function * functions; +}; + +/** + * Used to store a version which includes a major range instead of a single + * major version number. + */ +struct __DRIutilversionRec2 { + int major_min; /** min allowed Major version number. */ + int major_max; /** max allowed Major version number. */ + int minor; /**< Minor version number. */ + int patch; /**< Patch-level. */ +}; + +extern unsigned driParseDebugString( const char * debug, + const struct dri_debug_control * control ); + +extern unsigned driGetRendererString( char * buffer, + const char * hardware_name, const char * driver_date, GLuint agp_mode ); + +extern void driInitExtensions( GLcontext * ctx, + const struct dri_extension * card_extensions, GLboolean enable_imaging ); + +extern void driInitSingleExtension( GLcontext * ctx, + const struct dri_extension * ext ); + +extern GLboolean driCheckDriDdxDrmVersions2(const char * driver_name, + const __DRIversion * driActual, const __DRIversion * driExpected, + const __DRIversion * ddxActual, const __DRIversion * ddxExpected, + const __DRIversion * drmActual, const __DRIversion * drmExpected); + +extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name, + const __DRIversion * driActual, const __DRIversion * driExpected, + const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected, + const __DRIversion * drmActual, const __DRIversion * drmExpected); + +extern GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height ); + +struct __DRIconfigRec { + __GLcontextModes modes; +}; + +extern __DRIconfig ** +driCreateConfigs(GLenum fb_format, GLenum fb_type, + const uint8_t * depth_bits, const uint8_t * stencil_bits, + unsigned num_depth_stencil_bits, + const GLenum * db_modes, unsigned num_db_modes, + const uint8_t * msaa_samples, unsigned num_msaa_modes); + +__DRIconfig **driConcatConfigs(__DRIconfig **a, + __DRIconfig **b); + +int +driGetConfigAttrib(const __DRIconfig *config, + unsigned int attrib, unsigned int *value); +int +driIndexConfigAttrib(const __DRIconfig *config, int index, + unsigned int *attrib, unsigned int *value); + +#endif /* DRI_DEBUG_H */ diff --git a/mesalib/src/mesa/drivers/dri/common/vblank.c b/mesalib/src/mesa/drivers/dri/common/vblank.c new file mode 100644 index 000000000..12aeaa108 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/vblank.c @@ -0,0 +1,434 @@ +/* -*- mode: c; c-basic-offset: 3 -*- */ +/* + * (c) Copyright IBM Corporation 2002 + * 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. + * + * Authors: + * Ian Romanick <idr@us.ibm.com> + */ + +#include "main/glheader.h" +#include "xf86drm.h" +#include "main/mtypes.h" +#include "main/macros.h" +#include "main/dd.h" +#include "vblank.h" +#include "xmlpool.h" + +static unsigned int msc_to_vblank(__DRIdrawablePrivate * dPriv, int64_t msc) +{ + return (unsigned int)(msc - dPriv->msc_base + dPriv->vblank_base); +} + +static int64_t vblank_to_msc(__DRIdrawablePrivate * dPriv, unsigned int vblank) +{ + return (int64_t)(vblank - dPriv->vblank_base + dPriv->msc_base); +} + + +/****************************************************************************/ +/** + * Get the current MSC refresh counter. + * + * Stores the 64-bit count of vertical refreshes since some (arbitrary) + * point in time in \c count. Unless the value wraps around, which it + * may, it will never decrease for a given drawable. + * + * \warning This function is called from \c glXGetVideoSyncSGI, which expects + * a \c count of type \c unsigned (32-bit), and \c glXGetSyncValuesOML, which + * expects a \c count of type \c int64_t (signed 64-bit). The kernel ioctl + * currently always returns a \c sequence of type \c unsigned. + * + * \param priv Pointer to the DRI screen private struct. + * \param dPriv Pointer to the DRI drawable private struct + * \param count Storage to hold MSC counter. + * \return Zero is returned on success. A negative errno value + * is returned on failure. + */ +int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * dPriv, + int64_t * count) +{ + drmVBlank vbl; + int ret; + + /* Don't wait for anything. Just get the current refresh count. */ + + vbl.request.type = DRM_VBLANK_RELATIVE; + vbl.request.sequence = 0; + if ( dPriv && dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; + + ret = drmWaitVBlank( priv->fd, &vbl ); + + if (dPriv) { + *count = vblank_to_msc(dPriv, vbl.reply.sequence); + } else { + /* Old driver (no knowledge of drawable MSC callback) */ + *count = vbl.reply.sequence; + } + + return ret; +} + +/****************************************************************************/ +/** + * Wait for a specified refresh count. This implements most of the + * functionality of \c glXWaitForMscOML from the GLX_OML_sync_control spec. + * Waits for the \c target_msc refresh. If that has already passed, it + * waits until \f$(MSC \bmod divisor)\f$ is equal to \c remainder. If + * \c target_msc is 0, use the behavior of glXWaitVideoSyncSGI(), which + * omits the initial check against a target MSC value. + * + * This function is actually something of a hack. The problem is that, at + * the time of this writing, none of the existing DRM modules support an + * ioctl that returns a 64-bit count (at least not on 32-bit platforms). + * However, this function exists to support a GLX function that requires + * the use of 64-bit counts. As such, there is a little bit of ugly + * hackery at the end of this function to make the 32-bit count act like + * a 64-bit count. There are still some cases where this will break, but + * I believe it catches the most common cases. + * + * The real solution is to provide an ioctl that uses a 64-bit count. + * + * \param dpy Pointer to the \c Display. + * \param priv Pointer to the DRI drawable private. + * \param target_msc Desired refresh count to wait for. A value of 0 + * means to use the glXWaitVideoSyncSGI() behavior. + * \param divisor MSC divisor if \c target_msc is already reached. + * \param remainder Desired MSC remainder if \c target_msc is already + * reached. + * \param msc Buffer to hold MSC when done waiting. + * + * \return Zero on success or \c GLX_BAD_CONTEXT on failure. + */ + +int driWaitForMSC32( __DRIdrawablePrivate *priv, + int64_t target_msc, int64_t divisor, int64_t remainder, + int64_t * msc ) +{ + drmVBlank vbl; + + + if ( divisor != 0 ) { + int64_t next = target_msc; + int64_t r; + int dont_wait = (target_msc == 0); + + do { + /* dont_wait means we're using the glXWaitVideoSyncSGI() behavior. + * The first time around, just get the current count and proceed + * to the test for (MSC % divisor) == remainder. + */ + vbl.request.type = dont_wait ? DRM_VBLANK_RELATIVE : + DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = next ? msc_to_vblank(priv, next) : 0; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; + + if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { + /* FIXME: This doesn't seem like the right thing to return here. + */ + return GLX_BAD_CONTEXT; + } + + *msc = vblank_to_msc(priv, vbl.reply.sequence); + + if (!dont_wait && *msc == next) + break; + dont_wait = 0; + + /* Assuming the wait-done test fails, the next refresh to wait for + * will be one that satisfies (MSC % divisor) == remainder. The + * value (MSC - (MSC % divisor) + remainder) is the refresh value + * closest to the current value that would satisfy the equation. + * If this refresh has already happened, we add divisor to obtain + * the next refresh after the current one that will satisfy it. + */ + r = ((uint64_t)*msc % divisor); + next = (*msc - r + remainder); + if (next <= *msc) + next += divisor; + + } while (r != remainder); + } + else { + /* If the \c divisor is zero, just wait until the MSC is greater + * than or equal to \c target_msc. + */ + + vbl.request.type = DRM_VBLANK_ABSOLUTE; + vbl.request.sequence = target_msc ? msc_to_vblank(priv, target_msc) : 0; + + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; + + if ( drmWaitVBlank( priv->driScreenPriv->fd, &vbl ) != 0 ) { + /* FIXME: This doesn't seem like the right thing to return here. + */ + return GLX_BAD_CONTEXT; + } + } + + *msc = vblank_to_msc(priv, vbl.reply.sequence); + + if ( *msc < target_msc ) { + *msc += 0x0000000100000000LL; + } + + return 0; +} + + +/****************************************************************************/ +/** + * Gets a set of default vertical-blank-wait flags based on the internal GLX + * API version and several configuration options. + */ + +GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ) +{ + GLuint flags = VBLANK_FLAG_INTERVAL; + int vblank_mode; + + + if ( driCheckOption( optionCache, "vblank_mode", DRI_ENUM ) ) + vblank_mode = driQueryOptioni( optionCache, "vblank_mode" ); + else + vblank_mode = DRI_CONF_VBLANK_DEF_INTERVAL_1; + + switch (vblank_mode) { + case DRI_CONF_VBLANK_NEVER: + flags = 0; + break; + case DRI_CONF_VBLANK_DEF_INTERVAL_0: + break; + case DRI_CONF_VBLANK_DEF_INTERVAL_1: + flags |= VBLANK_FLAG_THROTTLE; + break; + case DRI_CONF_VBLANK_ALWAYS_SYNC: + flags |= VBLANK_FLAG_SYNC; + break; + } + + return flags; +} + + +/****************************************************************************/ +/** + * Wrapper to call \c drmWaitVBlank. The main purpose of this function is to + * wrap the error message logging. The error message should only be logged + * the first time the \c drmWaitVBlank fails. If \c drmWaitVBlank is + * successful, \c vbl_seq will be set the sequence value in the reply. + * + * \param vbl Pointer to drmVBlank packet desribing how to wait. + * \param vbl_seq Location to store the current refresh counter. + * \param fd File descriptor use to call into the DRM. + * \return Zero on success or -1 on failure. + */ + +static int do_wait( drmVBlank * vbl, GLuint * vbl_seq, int fd ) +{ + int ret; + + + ret = drmWaitVBlank( fd, vbl ); + if ( ret != 0 ) { + static GLboolean first_time = GL_TRUE; + + if ( first_time ) { + fprintf(stderr, + "%s: drmWaitVBlank returned %d, IRQs don't seem to be" + " working correctly.\nTry adjusting the vblank_mode" + " configuration parameter.\n", __FUNCTION__, ret); + first_time = GL_FALSE; + } + + return -1; + } + + *vbl_seq = vbl->reply.sequence; + return 0; +} + + +/****************************************************************************/ +/** + * Returns the default swap interval of the given drawable. + */ + +static unsigned +driGetDefaultVBlankInterval( const __DRIdrawablePrivate *priv ) +{ + if ( (priv->vblFlags & (VBLANK_FLAG_THROTTLE | VBLANK_FLAG_SYNC)) != 0 ) { + return 1; + } + else { + return 0; + } +} + + +/****************************************************************************/ +/** + * Sets the default swap interval when the drawable is first bound to a + * direct rendering context. + */ + +void driDrawableInitVBlank( __DRIdrawablePrivate *priv ) +{ + if ( priv->swap_interval == (unsigned)-1 && + !( priv->vblFlags & VBLANK_FLAG_NO_IRQ ) ) { + /* Get current vertical blank sequence */ + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) + vbl.request.type |= DRM_VBLANK_SECONDARY; + vbl.request.sequence = 0; + do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); + priv->vblank_base = priv->vblSeq; + + priv->swap_interval = driGetDefaultVBlankInterval( priv ); + } +} + + +/****************************************************************************/ +/** + * Returns the current swap interval of the given drawable. + */ + +unsigned +driGetVBlankInterval( const __DRIdrawablePrivate *priv ) +{ + if ( (priv->vblFlags & VBLANK_FLAG_INTERVAL) != 0 ) { + /* this must have been initialized when the drawable was first bound + * to a direct rendering context. */ + assert ( priv->swap_interval != (unsigned)-1 ); + + return priv->swap_interval; + } + else + return driGetDefaultVBlankInterval( priv ); +} + + +/****************************************************************************/ +/** + * Returns the current vertical blank sequence number of the given drawable. + */ + +void +driGetCurrentVBlank( __DRIdrawablePrivate *priv ) +{ + drmVBlank vbl; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + vbl.request.sequence = 0; + + (void) do_wait( &vbl, &priv->vblSeq, priv->driScreenPriv->fd ); +} + + +/****************************************************************************/ +/** + * Waits for the vertical blank for use with glXSwapBuffers. + * + * \param missed_deadline Set to \c GL_TRUE if the MSC after waiting is later + * than the "target" based on \c priv->vblFlags. The idea is + * that if \c missed_deadline is set, then the application is + * not achieving its desired framerate. + * \return Zero on success, -1 on error. + */ + +int +driWaitForVBlank( __DRIdrawablePrivate *priv, GLboolean * missed_deadline ) +{ + drmVBlank vbl; + unsigned original_seq; + unsigned deadline; + unsigned interval; + unsigned diff; + + *missed_deadline = GL_FALSE; + if ( (priv->vblFlags & (VBLANK_FLAG_INTERVAL | + VBLANK_FLAG_THROTTLE | + VBLANK_FLAG_SYNC)) == 0 || + (priv->vblFlags & VBLANK_FLAG_NO_IRQ) != 0 ) { + return 0; + } + + + /* VBLANK_FLAG_SYNC means to wait for at least one vertical blank. If + * that flag is not set, do a fake wait for zero vertical blanking + * periods so that we can get the current MSC. + * + * VBLANK_FLAG_INTERVAL and VBLANK_FLAG_THROTTLE mean to wait for at + * least one vertical blank since the last wait. Since do_wait modifies + * priv->vblSeq, we have to save the original value of priv->vblSeq for the + * VBLANK_FLAG_INTERVAL / VBLANK_FLAG_THROTTLE calculation later. + */ + + original_seq = priv->vblSeq; + interval = driGetVBlankInterval(priv); + deadline = original_seq + interval; + + vbl.request.type = DRM_VBLANK_RELATIVE; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + vbl.request.sequence = ((priv->vblFlags & VBLANK_FLAG_SYNC) != 0) ? 1 : 0; + + if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { + return -1; + } + + diff = priv->vblSeq - deadline; + + /* No need to wait again if we've already reached the target */ + if (diff <= (1 << 23)) { + *missed_deadline = (priv->vblFlags & VBLANK_FLAG_SYNC) ? (diff > 0) : + GL_TRUE; + return 0; + } + + /* Wait until the target vertical blank. */ + vbl.request.type = DRM_VBLANK_ABSOLUTE; + if ( priv->vblFlags & VBLANK_FLAG_SECONDARY ) { + vbl.request.type |= DRM_VBLANK_SECONDARY; + } + vbl.request.sequence = deadline; + + if ( do_wait( & vbl, &priv->vblSeq, priv->driScreenPriv->fd ) != 0 ) { + return -1; + } + + diff = priv->vblSeq - deadline; + *missed_deadline = diff > 0 && diff <= (1 << 23); + + return 0; +} diff --git a/mesalib/src/mesa/drivers/dri/common/vblank.h b/mesalib/src/mesa/drivers/dri/common/vblank.h new file mode 100644 index 000000000..8b2c761a1 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/vblank.h @@ -0,0 +1,75 @@ +/* -*- mode: c; c-basic-offset: 3 -*- */ +/* + * (c) Copyright IBM Corporation 2002 + * 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. + * + * Authors: + * Ian Romanick <idr@us.ibm.com> + */ + +#ifndef DRI_VBLANK_H +#define DRI_VBLANK_H + +#include "main/context.h" +#include "dri_util.h" +#include "xmlconfig.h" + +#define VBLANK_FLAG_INTERVAL (1U << 0) /* Respect the swap_interval setting + */ +#define VBLANK_FLAG_THROTTLE (1U << 1) /* Wait 1 refresh since last call. + */ +#define VBLANK_FLAG_SYNC (1U << 2) /* Sync to the next refresh. + */ +#define VBLANK_FLAG_NO_IRQ (1U << 7) /* DRM has no IRQ to wait on. + */ +#define VBLANK_FLAG_SECONDARY (1U << 8) /* Wait for secondary vblank. + */ + +extern int driGetMSC32( __DRIscreenPrivate * priv, int64_t * count ); +extern int driDrawableGetMSC32( __DRIscreenPrivate * priv, + __DRIdrawablePrivate * drawablePrivate, + int64_t * count); +extern int driWaitForMSC32( __DRIdrawablePrivate *priv, + int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * msc ); +extern GLuint driGetDefaultVBlankFlags( const driOptionCache *optionCache ); +extern void driDrawableInitVBlank ( __DRIdrawablePrivate *priv ); +extern unsigned driGetVBlankInterval( const __DRIdrawablePrivate *priv ); +extern void driGetCurrentVBlank( __DRIdrawablePrivate *priv ); +extern int driWaitForVBlank( __DRIdrawablePrivate *priv, + GLboolean * missed_deadline ); + +#undef usleep +#include <unistd.h> /* for usleep() */ +#include <sched.h> /* for sched_yield() */ + +#ifdef linux +#include <sched.h> /* for sched_yield() */ +#endif + +#define DO_USLEEP(nr) \ + do { \ + if (0) fprintf(stderr, "%s: usleep for %u\n", __FUNCTION__, nr ); \ + if (1) usleep( nr ); \ + sched_yield(); \ + } while( 0 ) + +#endif /* DRI_VBLANK_H */ diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.c b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c new file mode 100644 index 000000000..46ba2ffbf --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.c @@ -0,0 +1,1008 @@ +/* + * XML DRI client-side driver configuration + * Copyright (C) 2003 Felix Kuehling + * + * 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 + * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 xmlconfig.c + * \brief Driver-independent client-side part of the XML configuration + * \author Felix Kuehling + */ + +#include "main/glheader.h" + +#include <string.h> +#include <assert.h> +#include <expat.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include "main/imports.h" +#include "dri_util.h" +#include "xmlconfig.h" + +/* + * OS dependent ways of getting the name of the running program + */ +#if (defined(__unix__) || defined(unix)) && !defined(USG) +#include <sys/param.h> +#endif + +#undef GET_PROGRAM_NAME + +#if (defined(__GNU_LIBRARY__) || defined(__GLIBC__)) && !defined(__UCLIBC__) +# if !defined(__GLIBC__) || (__GLIBC__ < 2) +/* These aren't declared in any libc5 header */ +extern char *program_invocation_name, *program_invocation_short_name; +# endif +# define GET_PROGRAM_NAME() program_invocation_short_name +#elif defined(__FreeBSD__) && (__FreeBSD__ >= 2) +# include <osreldate.h> +# if (__FreeBSD_version >= 440000) +# include <stdlib.h> +# define GET_PROGRAM_NAME() getprogname() +# endif +#elif defined(__NetBSD__) && defined(__NetBSD_Version) && (__NetBSD_Version >= 106000100) +# include <stdlib.h> +# define GET_PROGRAM_NAME() getprogname() +#elif defined(__sun) +/* Solaris has getexecname() which returns the full path - return just + the basename to match BSD getprogname() */ +# include <stdlib.h> +# include <libgen.h> +# define GET_PROGRAM_NAME() basename(getexecname()) +#endif + +#if !defined(GET_PROGRAM_NAME) +# if defined(OpenBSD) || defined(NetBSD) || defined(__UCLIBC__) +/* This is a hack. It's said to work on OpenBSD, NetBSD and GNU. + * Rogelio M.Serrano Jr. reported it's also working with UCLIBC. It's + * used as a last resort, if there is no documented facility available. */ +static const char *__getProgramName () { + extern const char *__progname; + char * arg = strrchr(__progname, '/'); + if (arg) + return arg+1; + else + return __progname; +} +# define GET_PROGRAM_NAME() __getProgramName() +# else +# define GET_PROGRAM_NAME() "" +# warning "Per application configuration won't work with your OS version." +# endif +#endif + +/** \brief Find an option in an option cache with the name as key */ +static GLuint findOption (const driOptionCache *cache, const char *name) { + GLuint len = strlen (name); + GLuint size = 1 << cache->tableSize, mask = size - 1; + GLuint hash = 0; + GLuint i, shift; + + /* compute a hash from the variable length name */ + for (i = 0, shift = 0; i < len; ++i, shift = (shift+8) & 31) + hash += (GLuint)name[i] << shift; + hash *= hash; + hash = (hash >> (16-cache->tableSize/2)) & mask; + + /* this is just the starting point of the linear search for the option */ + for (i = 0; i < size; ++i, hash = (hash+1) & mask) { + /* if we hit an empty entry then the option is not defined (yet) */ + if (cache->info[hash].name == 0) + break; + else if (!strcmp (name, cache->info[hash].name)) + break; + } + /* this assertion fails if the hash table is full */ + assert (i < size); + + return hash; +} + +/** \brief Count the real number of options in an option cache */ +static GLuint countOptions (const driOptionCache *cache) { + GLuint size = 1 << cache->tableSize; + GLuint i, count = 0; + for (i = 0; i < size; ++i) + if (cache->info[i].name) + count++; + return count; +} + +/** \brief Like strdup but using MALLOC and with error checking. */ +#define XSTRDUP(dest,source) do { \ + GLuint len = strlen (source); \ + if (!(dest = MALLOC (len+1))) { \ + fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); \ + abort(); \ + } \ + memcpy (dest, source, len+1); \ +} while (0) + +static int compare (const void *a, const void *b) { + return strcmp (*(char *const*)a, *(char *const*)b); +} +/** \brief Binary search in a string array. */ +static GLuint bsearchStr (const XML_Char *name, + const XML_Char *elems[], GLuint count) { + const XML_Char **found; + found = bsearch (&name, elems, count, sizeof (XML_Char *), compare); + if (found) + return found - elems; + else + return count; +} + +/** \brief Locale-independent integer parser. + * + * Works similar to strtol. Leading space is NOT skipped. The input + * number may have an optional sign. Radix is specified by base. If + * base is 0 then decimal is assumed unless the input number is + * prefixed by 0x or 0X for hexadecimal or 0 for octal. After + * returning tail points to the first character that is not part of + * the integer number. If no number was found then tail points to the + * start of the input string. */ +static GLint strToI (const XML_Char *string, const XML_Char **tail, int base) { + GLint radix = base == 0 ? 10 : base; + GLint result = 0; + GLint sign = 1; + GLboolean numberFound = GL_FALSE; + const XML_Char *start = string; + + assert (radix >= 2 && radix <= 36); + + if (*string == '-') { + sign = -1; + string++; + } else if (*string == '+') + string++; + if (base == 0 && *string == '0') { + numberFound = GL_TRUE; + if (*(string+1) == 'x' || *(string+1) == 'X') { + radix = 16; + string += 2; + } else { + radix = 8; + string++; + } + } + do { + GLint digit = -1; + if (radix <= 10) { + if (*string >= '0' && *string < '0' + radix) + digit = *string - '0'; + } else { + if (*string >= '0' && *string <= '9') + digit = *string - '0'; + else if (*string >= 'a' && *string < 'a' + radix - 10) + digit = *string - 'a' + 10; + else if (*string >= 'A' && *string < 'A' + radix - 10) + digit = *string - 'A' + 10; + } + if (digit != -1) { + numberFound = GL_TRUE; + result = radix*result + digit; + string++; + } else + break; + } while (GL_TRUE); + *tail = numberFound ? string : start; + return sign * result; +} + +/** \brief Locale-independent floating-point parser. + * + * Works similar to strtod. Leading space is NOT skipped. The input + * number may have an optional sign. '.' is interpreted as decimal + * point and may occor at most once. Optionally the number may end in + * [eE]<exponent>, where <exponent> is an integer as recognized by + * strToI. In that case the result is number * 10^exponent. After + * returning tail points to the first character that is not part of + * the floating point number. If no number was found then tail points + * to the start of the input string. + * + * Uses two passes for maximum accuracy. */ +static GLfloat strToF (const XML_Char *string, const XML_Char **tail) { + GLint nDigits = 0, pointPos, exponent; + GLfloat sign = 1.0f, result = 0.0f, scale; + const XML_Char *start = string, *numStart; + + /* sign */ + if (*string == '-') { + sign = -1.0f; + string++; + } else if (*string == '+') + string++; + + /* first pass: determine position of decimal point, number of + * digits, exponent and the end of the number. */ + numStart = string; + while (*string >= '0' && *string <= '9') { + string++; + nDigits++; + } + pointPos = nDigits; + if (*string == '.') { + string++; + while (*string >= '0' && *string <= '9') { + string++; + nDigits++; + } + } + if (nDigits == 0) { + /* no digits, no number */ + *tail = start; + return 0.0f; + } + *tail = string; + if (*string == 'e' || *string == 'E') { + const XML_Char *expTail; + exponent = strToI (string+1, &expTail, 10); + if (expTail == string+1) + exponent = 0; + else + *tail = expTail; + } else + exponent = 0; + string = numStart; + + /* scale of the first digit */ + scale = sign * (GLfloat)pow (10.0, (GLdouble)(pointPos-1 + exponent)); + + /* second pass: parse digits */ + do { + if (*string != '.') { + assert (*string >= '0' && *string <= '9'); + result += scale * (GLfloat)(*string - '0'); + scale *= 0.1f; + nDigits--; + } + string++; + } while (nDigits > 0); + + return result; +} + +/** \brief Parse a value of a given type. */ +static GLboolean parseValue (driOptionValue *v, driOptionType type, + const XML_Char *string) { + const XML_Char *tail = NULL; + /* skip leading white-space */ + string += strspn (string, " \f\n\r\t\v"); + switch (type) { + case DRI_BOOL: + if (!strcmp (string, "false")) { + v->_bool = GL_FALSE; + tail = string + 5; + } else if (!strcmp (string, "true")) { + v->_bool = GL_TRUE; + tail = string + 4; + } + else + return GL_FALSE; + break; + case DRI_ENUM: /* enum is just a special integer */ + case DRI_INT: + v->_int = strToI (string, &tail, 0); + break; + case DRI_FLOAT: + v->_float = strToF (string, &tail); + break; + } + + if (tail == string) + return GL_FALSE; /* empty string (or containing only white-space) */ + /* skip trailing white space */ + if (*tail) + tail += strspn (tail, " \f\n\r\t\v"); + if (*tail) + return GL_FALSE; /* something left over that is not part of value */ + + return GL_TRUE; +} + +/** \brief Parse a list of ranges of type info->type. */ +static GLboolean parseRanges (driOptionInfo *info, const XML_Char *string) { + XML_Char *cp, *range; + GLuint nRanges, i; + driOptionRange *ranges; + + XSTRDUP (cp, string); + /* pass 1: determine the number of ranges (number of commas + 1) */ + range = cp; + for (nRanges = 1; *range; ++range) + if (*range == ',') + ++nRanges; + + if ((ranges = MALLOC (nRanges*sizeof(driOptionRange))) == NULL) { + fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); + abort(); + } + + /* pass 2: parse all ranges into preallocated array */ + range = cp; + for (i = 0; i < nRanges; ++i) { + XML_Char *end, *sep; + assert (range); + end = strchr (range, ','); + if (end) + *end = '\0'; + sep = strchr (range, ':'); + if (sep) { /* non-empty interval */ + *sep = '\0'; + if (!parseValue (&ranges[i].start, info->type, range) || + !parseValue (&ranges[i].end, info->type, sep+1)) + break; + if (info->type == DRI_INT && + ranges[i].start._int > ranges[i].end._int) + break; + if (info->type == DRI_FLOAT && + ranges[i].start._float > ranges[i].end._float) + break; + } else { /* empty interval */ + if (!parseValue (&ranges[i].start, info->type, range)) + break; + ranges[i].end = ranges[i].start; + } + if (end) + range = end+1; + else + range = NULL; + } + FREE (cp); + if (i < nRanges) { + FREE (ranges); + return GL_FALSE; + } else + assert (range == NULL); + + info->nRanges = nRanges; + info->ranges = ranges; + return GL_TRUE; +} + +/** \brief Check if a value is in one of info->ranges. */ +static GLboolean checkValue (const driOptionValue *v, const driOptionInfo *info) { + GLuint i; + assert (info->type != DRI_BOOL); /* should be caught by the parser */ + if (info->nRanges == 0) + return GL_TRUE; + switch (info->type) { + case DRI_ENUM: /* enum is just a special integer */ + case DRI_INT: + for (i = 0; i < info->nRanges; ++i) + if (v->_int >= info->ranges[i].start._int && + v->_int <= info->ranges[i].end._int) + return GL_TRUE; + break; + case DRI_FLOAT: + for (i = 0; i < info->nRanges; ++i) + if (v->_float >= info->ranges[i].start._float && + v->_float <= info->ranges[i].end._float) + return GL_TRUE; + break; + default: + assert (0); /* should never happen */ + } + return GL_FALSE; +} + +/** \brief Output a warning message. */ +#define XML_WARNING1(msg) do {\ + __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ +} while (0) +#define XML_WARNING(msg,args...) do { \ + __driUtilMessage ("Warning in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ + args); \ +} while (0) +/** \brief Output an error message. */ +#define XML_ERROR1(msg) do { \ + __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ +} while (0) +#define XML_ERROR(msg,args...) do { \ + __driUtilMessage ("Error in %s line %d, column %d: "msg, data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ + args); \ +} while (0) +/** \brief Output a fatal error message and abort. */ +#define XML_FATAL1(msg) do { \ + fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ + data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser)); \ + abort();\ +} while (0) +#define XML_FATAL(msg,args...) do { \ + fprintf (stderr, "Fatal error in %s line %d, column %d: "msg"\n", \ + data->name, \ + (int) XML_GetCurrentLineNumber(data->parser), \ + (int) XML_GetCurrentColumnNumber(data->parser), \ + args); \ + abort();\ +} while (0) + +/** \brief Parser context for __driConfigOptions. */ +struct OptInfoData { + const char *name; + XML_Parser parser; + driOptionCache *cache; + GLboolean inDriInfo; + GLboolean inSection; + GLboolean inDesc; + GLboolean inOption; + GLboolean inEnum; + int curOption; +}; + +/** \brief Elements in __driConfigOptions. */ +enum OptInfoElem { + OI_DESCRIPTION = 0, OI_DRIINFO, OI_ENUM, OI_OPTION, OI_SECTION, OI_COUNT +}; +static const XML_Char *OptInfoElems[] = { + "description", "driinfo", "enum", "option", "section" +}; + +/** \brief Parse attributes of an enum element. + * + * We're not actually interested in the data. Just make sure this is ok + * for external configuration tools. + */ +static void parseEnumAttr (struct OptInfoData *data, const XML_Char **attr) { + GLuint i; + const XML_Char *value = NULL, *text = NULL; + driOptionValue v; + GLuint opt = data->curOption; + for (i = 0; attr[i]; i += 2) { + if (!strcmp (attr[i], "value")) value = attr[i+1]; + else if (!strcmp (attr[i], "text")) text = attr[i+1]; + else XML_FATAL("illegal enum attribute: %s.", attr[i]); + } + if (!value) XML_FATAL1 ("value attribute missing in enum."); + if (!text) XML_FATAL1 ("text attribute missing in enum."); + if (!parseValue (&v, data->cache->info[opt].type, value)) + XML_FATAL ("illegal enum value: %s.", value); + if (!checkValue (&v, &data->cache->info[opt])) + XML_FATAL ("enum value out of valid range: %s.", value); +} + +/** \brief Parse attributes of a description element. + * + * We're not actually interested in the data. Just make sure this is ok + * for external configuration tools. + */ +static void parseDescAttr (struct OptInfoData *data, const XML_Char **attr) { + GLuint i; + const XML_Char *lang = NULL, *text = NULL; + for (i = 0; attr[i]; i += 2) { + if (!strcmp (attr[i], "lang")) lang = attr[i+1]; + else if (!strcmp (attr[i], "text")) text = attr[i+1]; + else XML_FATAL("illegal description attribute: %s.", attr[i]); + } + if (!lang) XML_FATAL1 ("lang attribute missing in description."); + if (!text) XML_FATAL1 ("text attribute missing in description."); +} + +/** \brief Parse attributes of an option element. */ +static void parseOptInfoAttr (struct OptInfoData *data, const XML_Char **attr) { + enum OptAttr {OA_DEFAULT = 0, OA_NAME, OA_TYPE, OA_VALID, OA_COUNT}; + static const XML_Char *optAttr[] = {"default", "name", "type", "valid"}; + const XML_Char *attrVal[OA_COUNT] = {NULL, NULL, NULL, NULL}; + const char *defaultVal; + driOptionCache *cache = data->cache; + GLuint opt, i; + for (i = 0; attr[i]; i += 2) { + GLuint attrName = bsearchStr (attr[i], optAttr, OA_COUNT); + if (attrName >= OA_COUNT) + XML_FATAL ("illegal option attribute: %s", attr[i]); + attrVal[attrName] = attr[i+1]; + } + if (!attrVal[OA_NAME]) XML_FATAL1 ("name attribute missing in option."); + if (!attrVal[OA_TYPE]) XML_FATAL1 ("type attribute missing in option."); + if (!attrVal[OA_DEFAULT]) XML_FATAL1 ("default attribute missing in option."); + + opt = findOption (cache, attrVal[OA_NAME]); + if (cache->info[opt].name) + XML_FATAL ("option %s redefined.", attrVal[OA_NAME]); + data->curOption = opt; + + XSTRDUP (cache->info[opt].name, attrVal[OA_NAME]); + + if (!strcmp (attrVal[OA_TYPE], "bool")) + cache->info[opt].type = DRI_BOOL; + else if (!strcmp (attrVal[OA_TYPE], "enum")) + cache->info[opt].type = DRI_ENUM; + else if (!strcmp (attrVal[OA_TYPE], "int")) + cache->info[opt].type = DRI_INT; + else if (!strcmp (attrVal[OA_TYPE], "float")) + cache->info[opt].type = DRI_FLOAT; + else + XML_FATAL ("illegal type in option: %s.", attrVal[OA_TYPE]); + + defaultVal = getenv (cache->info[opt].name); + if (defaultVal != NULL) { + /* don't use XML_WARNING, we want the user to see this! */ + fprintf (stderr, + "ATTENTION: default value of option %s overridden by environment.\n", + cache->info[opt].name); + } else + defaultVal = attrVal[OA_DEFAULT]; + if (!parseValue (&cache->values[opt], cache->info[opt].type, defaultVal)) + XML_FATAL ("illegal default value: %s.", defaultVal); + + if (attrVal[OA_VALID]) { + if (cache->info[opt].type == DRI_BOOL) + XML_FATAL1 ("boolean option with valid attribute."); + if (!parseRanges (&cache->info[opt], attrVal[OA_VALID])) + XML_FATAL ("illegal valid attribute: %s.", attrVal[OA_VALID]); + if (!checkValue (&cache->values[opt], &cache->info[opt])) + XML_FATAL ("default value out of valid range '%s': %s.", + attrVal[OA_VALID], defaultVal); + } else if (cache->info[opt].type == DRI_ENUM) { + XML_FATAL1 ("valid attribute missing in option (mandatory for enums)."); + } else { + cache->info[opt].nRanges = 0; + cache->info[opt].ranges = NULL; + } +} + +/** \brief Handler for start element events. */ +static void optInfoStartElem (void *userData, const XML_Char *name, + const XML_Char **attr) { + struct OptInfoData *data = (struct OptInfoData *)userData; + enum OptInfoElem elem = bsearchStr (name, OptInfoElems, OI_COUNT); + switch (elem) { + case OI_DRIINFO: + if (data->inDriInfo) + XML_FATAL1 ("nested <driinfo> elements."); + if (attr[0]) + XML_FATAL1 ("attributes specified on <driinfo> element."); + data->inDriInfo = GL_TRUE; + break; + case OI_SECTION: + if (!data->inDriInfo) + XML_FATAL1 ("<section> must be inside <driinfo>."); + if (data->inSection) + XML_FATAL1 ("nested <section> elements."); + if (attr[0]) + XML_FATAL1 ("attributes specified on <section> element."); + data->inSection = GL_TRUE; + break; + case OI_DESCRIPTION: + if (!data->inSection && !data->inOption) + XML_FATAL1 ("<description> must be inside <description> or <option."); + if (data->inDesc) + XML_FATAL1 ("nested <description> elements."); + data->inDesc = GL_TRUE; + parseDescAttr (data, attr); + break; + case OI_OPTION: + if (!data->inSection) + XML_FATAL1 ("<option> must be inside <section>."); + if (data->inDesc) + XML_FATAL1 ("<option> nested in <description> element."); + if (data->inOption) + XML_FATAL1 ("nested <option> elements."); + data->inOption = GL_TRUE; + parseOptInfoAttr (data, attr); + break; + case OI_ENUM: + if (!(data->inOption && data->inDesc)) + XML_FATAL1 ("<enum> must be inside <option> and <description>."); + if (data->inEnum) + XML_FATAL1 ("nested <enum> elements."); + data->inEnum = GL_TRUE; + parseEnumAttr (data, attr); + break; + default: + XML_FATAL ("unknown element: %s.", name); + } +} + +/** \brief Handler for end element events. */ +static void optInfoEndElem (void *userData, const XML_Char *name) { + struct OptInfoData *data = (struct OptInfoData *)userData; + enum OptInfoElem elem = bsearchStr (name, OptInfoElems, OI_COUNT); + switch (elem) { + case OI_DRIINFO: + data->inDriInfo = GL_FALSE; + break; + case OI_SECTION: + data->inSection = GL_FALSE; + break; + case OI_DESCRIPTION: + data->inDesc = GL_FALSE; + break; + case OI_OPTION: + data->inOption = GL_FALSE; + break; + case OI_ENUM: + data->inEnum = GL_FALSE; + break; + default: + assert (0); /* should have been caught by StartElem */ + } +} + +void driParseOptionInfo (driOptionCache *info, + const char *configOptions, GLuint nConfigOptions) { + XML_Parser p; + int status; + struct OptInfoData userData; + struct OptInfoData *data = &userData; + GLuint realNoptions; + + /* determine hash table size and allocate memory: + * 3/2 of the number of options, rounded up, so there remains always + * at least one free entry. This is needed for detecting undefined + * options in configuration files without getting a hash table overflow. + * Round this up to a power of two. */ + GLuint minSize = (nConfigOptions*3 + 1) / 2; + GLuint size, log2size; + for (size = 1, log2size = 0; size < minSize; size <<= 1, ++log2size); + info->tableSize = log2size; + info->info = CALLOC (size * sizeof (driOptionInfo)); + info->values = CALLOC (size * sizeof (driOptionValue)); + if (info->info == NULL || info->values == NULL) { + fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); + abort(); + } + + p = XML_ParserCreate ("UTF-8"); /* always UTF-8 */ + XML_SetElementHandler (p, optInfoStartElem, optInfoEndElem); + XML_SetUserData (p, data); + + userData.name = "__driConfigOptions"; + userData.parser = p; + userData.cache = info; + userData.inDriInfo = GL_FALSE; + userData.inSection = GL_FALSE; + userData.inDesc = GL_FALSE; + userData.inOption = GL_FALSE; + userData.inEnum = GL_FALSE; + userData.curOption = -1; + + status = XML_Parse (p, configOptions, strlen (configOptions), 1); + if (!status) + XML_FATAL ("%s.", XML_ErrorString(XML_GetErrorCode(p))); + + XML_ParserFree (p); + + /* Check if the actual number of options matches nConfigOptions. + * A mismatch is not fatal (a hash table overflow would be) but we + * want the driver developer's attention anyway. */ + realNoptions = countOptions (info); + if (realNoptions != nConfigOptions) { + fprintf (stderr, + "Error: nConfigOptions (%u) does not match the actual number of options in\n" + " __driConfigOptions (%u).\n", + nConfigOptions, realNoptions); + } +} + +/** \brief Parser context for configuration files. */ +struct OptConfData { + const char *name; + XML_Parser parser; + driOptionCache *cache; + GLint screenNum; + const char *driverName, *execName; + GLuint ignoringDevice; + GLuint ignoringApp; + GLuint inDriConf; + GLuint inDevice; + GLuint inApp; + GLuint inOption; +}; + +/** \brief Elements in configuration files. */ +enum OptConfElem { + OC_APPLICATION = 0, OC_DEVICE, OC_DRICONF, OC_OPTION, OC_COUNT +}; +static const XML_Char *OptConfElems[] = { + "application", "device", "driconf", "option" +}; + +/** \brief Parse attributes of a device element. */ +static void parseDeviceAttr (struct OptConfData *data, const XML_Char **attr) { + GLuint i; + const XML_Char *driver = NULL, *screen = NULL; + for (i = 0; attr[i]; i += 2) { + if (!strcmp (attr[i], "driver")) driver = attr[i+1]; + else if (!strcmp (attr[i], "screen")) screen = attr[i+1]; + else XML_WARNING("unkown device attribute: %s.", attr[i]); + } + if (driver && strcmp (driver, data->driverName)) + data->ignoringDevice = data->inDevice; + else if (screen) { + driOptionValue screenNum; + if (!parseValue (&screenNum, DRI_INT, screen)) + XML_WARNING("illegal screen number: %s.", screen); + else if (screenNum._int != data->screenNum) + data->ignoringDevice = data->inDevice; + } +} + +/** \brief Parse attributes of an application element. */ +static void parseAppAttr (struct OptConfData *data, const XML_Char **attr) { + GLuint i; + const XML_Char *name = NULL, *exec = NULL; + for (i = 0; attr[i]; i += 2) { + if (!strcmp (attr[i], "name")) name = attr[i+1]; + else if (!strcmp (attr[i], "executable")) exec = attr[i+1]; + else XML_WARNING("unkown application attribute: %s.", attr[i]); + } + if (exec && strcmp (exec, data->execName)) + data->ignoringApp = data->inApp; +} + +/** \brief Parse attributes of an option element. */ +static void parseOptConfAttr (struct OptConfData *data, const XML_Char **attr) { + GLuint i; + const XML_Char *name = NULL, *value = NULL; + for (i = 0; attr[i]; i += 2) { + if (!strcmp (attr[i], "name")) name = attr[i+1]; + else if (!strcmp (attr[i], "value")) value = attr[i+1]; + else XML_WARNING("unkown option attribute: %s.", attr[i]); + } + if (!name) XML_WARNING1 ("name attribute missing in option."); + if (!value) XML_WARNING1 ("value attribute missing in option."); + if (name && value) { + driOptionCache *cache = data->cache; + GLuint opt = findOption (cache, name); + if (cache->info[opt].name == NULL) + XML_WARNING ("undefined option: %s.", name); + else if (getenv (cache->info[opt].name)) + /* don't use XML_WARNING, we want the user to see this! */ + fprintf (stderr, "ATTENTION: option value of option %s ignored.\n", + cache->info[opt].name); + else if (!parseValue (&cache->values[opt], cache->info[opt].type, value)) + XML_WARNING ("illegal option value: %s.", value); + } +} + +/** \brief Handler for start element events. */ +static void optConfStartElem (void *userData, const XML_Char *name, + const XML_Char **attr) { + struct OptConfData *data = (struct OptConfData *)userData; + enum OptConfElem elem = bsearchStr (name, OptConfElems, OC_COUNT); + switch (elem) { + case OC_DRICONF: + if (data->inDriConf) + XML_WARNING1 ("nested <driconf> elements."); + if (attr[0]) + XML_WARNING1 ("attributes specified on <driconf> element."); + data->inDriConf++; + break; + case OC_DEVICE: + if (!data->inDriConf) + XML_WARNING1 ("<device> should be inside <driconf>."); + if (data->inDevice) + XML_WARNING1 ("nested <device> elements."); + data->inDevice++; + if (!data->ignoringDevice && !data->ignoringApp) + parseDeviceAttr (data, attr); + break; + case OC_APPLICATION: + if (!data->inDevice) + XML_WARNING1 ("<application> should be inside <device>."); + if (data->inApp) + XML_WARNING1 ("nested <application> elements."); + data->inApp++; + if (!data->ignoringDevice && !data->ignoringApp) + parseAppAttr (data, attr); + break; + case OC_OPTION: + if (!data->inApp) + XML_WARNING1 ("<option> should be inside <application>."); + if (data->inOption) + XML_WARNING1 ("nested <option> elements."); + data->inOption++; + if (!data->ignoringDevice && !data->ignoringApp) + parseOptConfAttr (data, attr); + break; + default: + XML_WARNING ("unknown element: %s.", name); + } +} + +/** \brief Handler for end element events. */ +static void optConfEndElem (void *userData, const XML_Char *name) { + struct OptConfData *data = (struct OptConfData *)userData; + enum OptConfElem elem = bsearchStr (name, OptConfElems, OC_COUNT); + switch (elem) { + case OC_DRICONF: + data->inDriConf--; + break; + case OC_DEVICE: + if (data->inDevice-- == data->ignoringDevice) + data->ignoringDevice = 0; + break; + case OC_APPLICATION: + if (data->inApp-- == data->ignoringApp) + data->ignoringApp = 0; + break; + case OC_OPTION: + data->inOption--; + break; + default: + /* unknown element, warning was produced on start tag */; + } +} + +/** \brief Initialize an option cache based on info */ +static void initOptionCache (driOptionCache *cache, const driOptionCache *info) { + cache->info = info->info; + cache->tableSize = info->tableSize; + cache->values = MALLOC ((1<<info->tableSize) * sizeof (driOptionValue)); + if (cache->values == NULL) { + fprintf (stderr, "%s: %d: out of memory.\n", __FILE__, __LINE__); + abort(); + } + memcpy (cache->values, info->values, + (1<<info->tableSize) * sizeof (driOptionValue)); +} + +/** \brief Parse the named configuration file */ +static void parseOneConfigFile (XML_Parser p) { +#define BUF_SIZE 0x1000 + struct OptConfData *data = (struct OptConfData *)XML_GetUserData (p); + int status; + int fd; + + if ((fd = open (data->name, O_RDONLY)) == -1) { + __driUtilMessage ("Can't open configuration file %s: %s.", + data->name, strerror (errno)); + return; + } + + while (1) { + int bytesRead; + void *buffer = XML_GetBuffer (p, BUF_SIZE); + if (!buffer) { + __driUtilMessage ("Can't allocate parser buffer."); + break; + } + bytesRead = read (fd, buffer, BUF_SIZE); + if (bytesRead == -1) { + __driUtilMessage ("Error reading from configuration file %s: %s.", + data->name, strerror (errno)); + break; + } + status = XML_ParseBuffer (p, bytesRead, bytesRead == 0); + if (!status) { + XML_ERROR ("%s.", XML_ErrorString(XML_GetErrorCode(p))); + break; + } + if (bytesRead == 0) + break; + } + + close (fd); +#undef BUF_SIZE +} + +void driParseConfigFiles (driOptionCache *cache, const driOptionCache *info, + GLint screenNum, const char *driverName) { + char *filenames[2] = {"/etc/drirc", NULL}; + char *home; + GLuint i; + struct OptConfData userData; + + initOptionCache (cache, info); + + userData.cache = cache; + userData.screenNum = screenNum; + userData.driverName = driverName; + userData.execName = GET_PROGRAM_NAME(); + + if ((home = getenv ("HOME"))) { + GLuint len = strlen (home); + filenames[1] = MALLOC (len + 7+1); + if (filenames[1] == NULL) + __driUtilMessage ("Can't allocate memory for %s/.drirc.", home); + else { + memcpy (filenames[1], home, len); + memcpy (filenames[1] + len, "/.drirc", 7+1); + } + } + + for (i = 0; i < 2; ++i) { + XML_Parser p; + if (filenames[i] == NULL) + continue; + + p = XML_ParserCreate (NULL); /* use encoding specified by file */ + XML_SetElementHandler (p, optConfStartElem, optConfEndElem); + XML_SetUserData (p, &userData); + userData.parser = p; + userData.name = filenames[i]; + userData.ignoringDevice = 0; + userData.ignoringApp = 0; + userData.inDriConf = 0; + userData.inDevice = 0; + userData.inApp = 0; + userData.inOption = 0; + + parseOneConfigFile (p); + XML_ParserFree (p); + } + + if (filenames[1]) + FREE (filenames[1]); +} + +void driDestroyOptionInfo (driOptionCache *info) { + driDestroyOptionCache (info); + if (info->info) { + GLuint i, size = 1 << info->tableSize; + for (i = 0; i < size; ++i) { + if (info->info[i].name) { + FREE (info->info[i].name); + if (info->info[i].ranges) + FREE (info->info[i].ranges); + } + } + FREE (info->info); + } +} + +void driDestroyOptionCache (driOptionCache *cache) { + if (cache->values) + FREE (cache->values); +} + +GLboolean driCheckOption (const driOptionCache *cache, const char *name, + driOptionType type) { + GLuint i = findOption (cache, name); + return cache->info[i].name != NULL && cache->info[i].type == type; +} + +GLboolean driQueryOptionb (const driOptionCache *cache, const char *name) { + GLuint i = findOption (cache, name); + /* make sure the option is defined and has the correct type */ + assert (cache->info[i].name != NULL); + assert (cache->info[i].type == DRI_BOOL); + return cache->values[i]._bool; +} + +GLint driQueryOptioni (const driOptionCache *cache, const char *name) { + GLuint i = findOption (cache, name); + /* make sure the option is defined and has the correct type */ + assert (cache->info[i].name != NULL); + assert (cache->info[i].type == DRI_INT || cache->info[i].type == DRI_ENUM); + return cache->values[i]._int; +} + +GLfloat driQueryOptionf (const driOptionCache *cache, const char *name) { + GLuint i = findOption (cache, name); + /* make sure the option is defined and has the correct type */ + assert (cache->info[i].name != NULL); + assert (cache->info[i].type == DRI_FLOAT); + return cache->values[i]._float; +} diff --git a/mesalib/src/mesa/drivers/dri/common/xmlconfig.h b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h new file mode 100644 index 000000000..c363af764 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlconfig.h @@ -0,0 +1,124 @@ +/* + * XML DRI client-side driver configuration + * Copyright (C) 2003 Felix Kuehling + * + * 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 + * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 xmlconfig.h + * \brief Driver-independent client-side part of the XML configuration + * \author Felix Kuehling + */ + +#ifndef __XMLCONFIG_H +#define __XMLCONFIG_H + +/** \brief Option data types */ +typedef enum driOptionType { + DRI_BOOL, DRI_ENUM, DRI_INT, DRI_FLOAT +} driOptionType; + +/** \brief Option value */ +typedef union driOptionValue { + GLboolean _bool; /**< \brief Boolean */ + GLint _int; /**< \brief Integer or Enum */ + GLfloat _float; /**< \brief Floating-point */ +} driOptionValue; + +/** \brief Single range of valid values + * + * For empty ranges (a single value) start == end */ +typedef struct driOptionRange { + driOptionValue start; /**< \brief Start */ + driOptionValue end; /**< \brief End */ +} driOptionRange; + +/** \brief Information about an option */ +typedef struct driOptionInfo { + char *name; /**< \brief Name */ + driOptionType type; /**< \brief Type */ + driOptionRange *ranges; /**< \brief Array of ranges */ + GLuint nRanges; /**< \brief Number of ranges */ +} driOptionInfo; + +/** \brief Option cache + * + * \li One in <driver>Screen caching option info and the default values + * \li One in each <driver>Context with the actual values for that context */ +typedef struct driOptionCache { + driOptionInfo *info; + /**< \brief Array of option infos + * + * Points to the same array in the screen and all contexts */ + driOptionValue *values; + /**< \brief Array of option values + * + * \li Default values in screen + * \li Actual values in contexts + */ + GLuint tableSize; + /**< \brief Size of the arrays + * + * Depending on the hash function this may differ from __driNConfigOptions. + * In the current implementation it's not actually a size but log2(size). + * The value is the same in the screen and all contexts. */ +} driOptionCache; + +/** \brief Parse XML option info from configOptions + * + * To be called in <driver>CreateScreen + * + * \param info pointer to a driOptionCache that will store the option info + * \param configOptions XML document describing available configuration opts + * \param nConfigOptions number of options, used to choose a hash table size + * + * For the option information to be available to external configuration tools + * it must be a public symbol __driConfigOptions. It is also passed as a + * parameter to driParseOptionInfo in order to avoid driver-independent code + * depending on symbols in driver-specific code. */ +void driParseOptionInfo (driOptionCache *info, + const char *configOptions, GLuint nConfigOptions); +/** \brief Initialize option cache from info and parse configuration files + * + * To be called in <driver>CreateContext. screenNum and driverName select + * device sections. */ +void driParseConfigFiles (driOptionCache *cache, const driOptionCache *info, + GLint screenNum, const char *driverName); +/** \brief Destroy option info + * + * To be called in <driver>DestroyScreen */ +void driDestroyOptionInfo (driOptionCache *info); +/** \brief Destroy option cache + * + * To be called in <driver>DestroyContext */ +void driDestroyOptionCache (driOptionCache *cache); + +/** \brief Check if there exists a certain option */ +GLboolean driCheckOption (const driOptionCache *cache, const char *name, + driOptionType type); + +/** \brief Query a boolean option value */ +GLboolean driQueryOptionb (const driOptionCache *cache, const char *name); +/** \brief Query an integer option value */ +GLint driQueryOptioni (const driOptionCache *cache, const char *name); +/** \brief Query a floating-point option value */ +GLfloat driQueryOptionf (const driOptionCache *cache, const char *name); + +#endif diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool.h b/mesalib/src/mesa/drivers/dri/common/xmlpool.h new file mode 100644 index 000000000..587517ea1 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool.h @@ -0,0 +1,98 @@ +/* + * XML DRI client-side driver configuration + * Copyright (C) 2003 Felix Kuehling + * + * 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 + * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 xmlpool.h + * \brief Pool of common options + * \author Felix Kuehling + * + * This file defines macros that can be used to construct + * driConfigOptions in the drivers. Common options are defined in + * xmlpool/t_options.h from which xmlpool/options.h is generated with + * translations. This file defines generic helper macros and includes + * xmlpool/options.h. + */ + +#ifndef __XMLPOOL_H +#define __XMLPOOL_H + +/* + * generic macros + */ + +/** \brief Begin __driConfigOptions */ +#define DRI_CONF_BEGIN \ +"<driinfo>\n" + +/** \brief End __driConfigOptions */ +#define DRI_CONF_END \ +"</driinfo>\n" + +/** \brief Begin a section of related options */ +#define DRI_CONF_SECTION_BEGIN \ +"<section>\n" + +/** \brief End a section of related options */ +#define DRI_CONF_SECTION_END \ +"</section>\n" + +/** \brief Begin an option definition */ +#define DRI_CONF_OPT_BEGIN(name,type,def) \ +"<option name=\""#name"\" type=\""#type"\" default=\""#def"\">\n" + +/** \brief Begin an option definition with qouted default value */ +#define DRI_CONF_OPT_BEGIN_Q(name,type,def) \ +"<option name=\""#name"\" type=\""#type"\" default="#def">\n" + +/** \brief Begin an option definition with restrictions on valid values */ +#define DRI_CONF_OPT_BEGIN_V(name,type,def,valid) \ +"<option name=\""#name"\" type=\""#type"\" default=\""#def"\" valid=\""valid"\">\n" + +/** \brief End an option description */ +#define DRI_CONF_OPT_END \ +"</option>\n" + +/** \brief A verbal description in a specified language (empty version) */ +#define DRI_CONF_DESC(lang,text) \ +"<description lang=\""#lang"\" text=\""text"\"/>\n" + +/** \brief A verbal description in a specified language */ +#define DRI_CONF_DESC_BEGIN(lang,text) \ +"<description lang=\""#lang"\" text=\""text"\">\n" + +/** \brief End a description */ +#define DRI_CONF_DESC_END \ +"</description>\n" + +/** \brief A verbal description of an enum value */ +#define DRI_CONF_ENUM(value,text) \ +"<enum value=\""#value"\" text=\""text"\"/>\n" + + +/* + * Predefined option sections and options with multi-lingual descriptions + * are now automatically generated. + */ +#include "xmlpool/options.h" + +#endif diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile b/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile new file mode 100644 index 000000000..62ec919ea --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/Makefile @@ -0,0 +1,96 @@ +# Convenient makefile for managing translations. + +# Prerequisites: +# - GNU gettext +# - Python + +# Adding new translations +# ----------------------- + +# To start working on a new translation edit the POS=... line +# below. If you want to add for example a french translation, add +# fr.po. + +# Then run "make po" to generate a fresh .po file from translatable +# strings in t_options.h. Now you can edit the new .po file (fr.po in +# the example above) to translate the strings. Please make sure that +# your editor encodes the file in UTF-8. + +# Updating existing translations +# ------------------------------ + +# Run "make po" to update .po files with new translatable strings from +# t_options.h. Now you can edit the .po files you're interested +# in. Please make sure that your editor encodes the file in UTF-8. + +# Updating options.h +# ------------------ + +# Finally run "make" to generate options.h from t_options.h with all +# translations. Now you can rebuild the drivers. Any common options +# used by the drivers will have option descriptions with the latest +# translations. + +# Publishing translations +# ----------------------- + +# To get your translation(s) into Mesa CVS, please send me your +# <lang>.po file. + +# More information: +# - info gettext + +# The set of supported languages. Add languages as needed. +POS=de.po es.po nl.po fr.po sv.po + +# +# Don't change anything below, unless you know what you're doing. +# +LANGS=$(POS:%.po=%) +MOS=$(POS:%.po=%/LC_MESSAGES/options.mo) +POT=xmlpool.pot + +.PHONY: all clean pot po mo + +all: options.h + +# Only intermediate files are cleaned up. options.h is not deleted because +# it's in CVS. +clean: + -rm -f $(POT) *~ + -rm -rf $(LANGS) + +# Default target options.h +options.h: t_options.h mo + python gen_xmlpool.py $(LANGS) > options.h + +# Update .mo files from the corresponding .po files. +mo: + @for mo in $(MOS); do \ + lang=$${mo%%/*}; \ + echo "Updating $$mo from $$lang.po."; \ + mkdir -p $${mo%/*}; \ + msgfmt -o $$mo $$lang.po; \ + done + +# Use this target to create or update .po files with new messages in +# driconf.py. +po: $(POS) + +pot: $(POT) + +# Extract message catalog from driconf.py. +$(POT): t_options.h + xgettext -L C --from-code utf-8 -o $(POT) t_options.h + +# Create or update a .po file for a specific language. +%.po: $(POT) + @if [ -f $@ ]; then \ + echo "Merging new strings from $(POT) into $@."; \ + mv $@ $@~; \ + msgmerge -o $@ $@~ $(POT); \ + else \ + echo "Initializing $@ from $(POT)."; \ + msginit -i $(POT) -o $@~ --locale=$*; \ + sed -e 's/charset=.*\\n/charset=UTF-8\\n/' $@~ > $@; \ + fi diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/de.po b/mesalib/src/mesa/drivers/dri/common/xmlpool/de.po new file mode 100644 index 000000000..4ea82f901 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/de.po @@ -0,0 +1,240 @@ +# German translations for DRI driver options. +# Copyright (C) 2005 Felix Kuehling +# This file is distributed under the same license as the Mesa package. +# Felix Kuehling <fxkuehl@gmx.de>, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: Mesa 6.3\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-04-11 23:19+0200\n" +"PO-Revision-Date: 2005-04-11 01:34+0200\n" +"Last-Translator: Felix Kuehling <fxkuehl@gmx.de>\n" +"Language-Team: German <de@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: t_options.h:53 +msgid "Debugging" +msgstr "Fehlersuche" + +#: t_options.h:57 +msgid "Disable 3D acceleration" +msgstr "3D-Beschleunigung abschalten" + +#: t_options.h:62 +msgid "Show performance boxes" +msgstr "Zeige Performanceboxen" + +#: t_options.h:69 +msgid "Image Quality" +msgstr "Bildqualität" + +#: t_options.h:77 +msgid "Texture color depth" +msgstr "Texturfarbtiefe" + +#: t_options.h:78 +msgid "Prefer frame buffer color depth" +msgstr "Bevorzuge Farbtiefe des Framebuffers" + +#: t_options.h:79 +msgid "Prefer 32 bits per texel" +msgstr "Bevorzuge 32 bits pro Texel" + +#: t_options.h:80 +msgid "Prefer 16 bits per texel" +msgstr "Bevorzuge 16 bits pro Texel" + +#: t_options.h:81 +msgid "Force 16 bits per texel" +msgstr "Erzwinge 16 bits pro Texel" + +#: t_options.h:87 +msgid "Initial maximum value for anisotropic texture filtering" +msgstr "Initialer Maximalwert für anisotropische Texturfilterung" + +#: t_options.h:92 +msgid "Forbid negative texture LOD bias" +msgstr "Verbiete negative Textur-Detailgradverschiebung" + +#: t_options.h:97 +msgid "" +"Enable S3TC texture compression even if software support is not available" +msgstr "" +"Aktiviere S3TC Texturkomprimierung auch wenn die nötige " +"Softwareunterstützung fehlt" + +#: t_options.h:104 +msgid "Initial color reduction method" +msgstr "Initiale Farbreduktionsmethode" + +#: t_options.h:105 +msgid "Round colors" +msgstr "Farben runden" + +#: t_options.h:106 +msgid "Dither colors" +msgstr "Farben rastern" + +#: t_options.h:114 +msgid "Color rounding method" +msgstr "Farbrundungsmethode" + +#: t_options.h:115 +msgid "Round color components downward" +msgstr "Farbkomponenten abrunden" + +#: t_options.h:116 +msgid "Round to nearest color" +msgstr "Zur ähnlichsten Farbe runden" + +#: t_options.h:125 +msgid "Color dithering method" +msgstr "Farbrasterungsmethode" + +#: t_options.h:126 +msgid "Horizontal error diffusion" +msgstr "Horizontale Fehlerstreuung" + +#: t_options.h:127 +msgid "Horizontal error diffusion, reset error at line start" +msgstr "Horizontale Fehlerstreuung, Fehler am Zeilenanfang zurücksetzen" + +#: t_options.h:128 +msgid "Ordered 2D color dithering" +msgstr "Geordnete 2D Farbrasterung" + +#: t_options.h:134 +msgid "Floating point depth buffer" +msgstr "Fließkomma z-Puffer" + +#: t_options.h:140 +msgid "Performance" +msgstr "Leistung" + +#: t_options.h:148 +msgid "TCL mode (Transformation, Clipping, Lighting)" +msgstr "TCL-Modus (Transformation, Clipping, Licht)" + +#: t_options.h:149 +msgid "Use software TCL pipeline" +msgstr "Benutze die Software-TCL-Pipeline" + +#: t_options.h:150 +msgid "Use hardware TCL as first TCL pipeline stage" +msgstr "Benutze Hardware TCL als erste Stufe der TCL-Pipeline" + +#: t_options.h:151 +msgid "Bypass the TCL pipeline" +msgstr "Umgehe die TCL-Pipeline" + +#: t_options.h:152 +msgid "" +"Bypass the TCL pipeline with state-based machine code generated on-the-fly" +msgstr "" +"Umgehe die TCL-Pipeline mit zur Laufzeit erzeugtem, zustandsbasiertem " +"Maschinencode" + +#: t_options.h:161 +msgid "Method to limit rendering latency" +msgstr "Methode zur Begrenzung der Bildverzögerung" + +#: t_options.h:162 +msgid "Busy waiting for the graphics hardware" +msgstr "Aktives Warten auf die Grafikhardware" + +#: t_options.h:163 +msgid "Sleep for brief intervals while waiting for the graphics hardware" +msgstr "Kurze Schlafintervalle beim Warten auf die Grafikhardware" + +#: t_options.h:164 +msgid "Let the graphics hardware emit a software interrupt and sleep" +msgstr "" +"Die Grafikhardware eine Softwareunterbrechnung erzeugen lassen und schlafen" + +#: t_options.h:174 +msgid "Synchronization with vertical refresh (swap intervals)" +msgstr "Synchronisation mit der vertikalen Bildwiederholung" + +#: t_options.h:175 +msgid "Never synchronize with vertical refresh, ignore application's choice" +msgstr "" +"Niemals mit der Bildwiederholung synchronisieren, Anweisungen der Anwendung " +"ignorieren" + +#: t_options.h:176 +msgid "Initial swap interval 0, obey application's choice" +msgstr "Initiales Bildinterval 0, Anweisungen der Anwendung gehorchen" + +#: t_options.h:177 +msgid "Initial swap interval 1, obey application's choice" +msgstr "Initiales Bildinterval 1, Anweisungen der Anwendung gehorchen" + +#: t_options.h:178 +msgid "" +"Always synchronize with vertical refresh, application chooses the minimum " +"swap interval" +msgstr "" +"Immer mit der Bildwiederholung synchronisieren, Anwendung wählt das minimale " +"Bildintervall" + +#: t_options.h:186 +msgid "Use HyperZ to boost performance" +msgstr "HyperZ zur Leistungssteigerung verwenden" + +#: t_options.h:191 +msgid "Number of texture units used" +msgstr "Anzahl der benutzten Textureinheiten" + +#: t_options.h:196 +msgid "Support larger textures not guaranteed to fit into graphics memory" +msgstr "Unterstütze grosse Texturen die evtl. nicht in den Grafikspeicher passen" + +#: t_options.h:197 +msgid "No" +msgstr "Nein" + +#: t_options.h:198 +msgid "At least 1 texture must fit under worst-case assumptions" +msgstr "Mindestens 1 Textur muss auch im schlechtesten Fall Platz haben" + +#: t_options.h:199 +msgid "Announce hardware limits" +msgstr "Benutze Hardware-Limits" + +#: t_options.h:205 +msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" +msgstr "" +"Texturfilterqualität versus -geschwindigkeit, auch bekannt als „brilineare“ " +"Texturfilterung" + +#: t_options.h:213 +msgid "Used types of texture memory" +msgstr "Benutzte Arten von Texturspeicher" + +#: t_options.h:214 +msgid "All available memory" +msgstr "Aller verfügbarer Speicher" + +#: t_options.h:215 +msgid "Only card memory (if available)" +msgstr "Nur Grafikspeicher (falls verfügbar)" + +#: t_options.h:216 +msgid "Only GART (AGP/PCIE) memory (if available)" +msgstr "Nur GART-Speicher (AGP/PCIE) (falls verfügbar)" + +#: t_options.h:224 +msgid "Features that are not hardware-accelerated" +msgstr "Funktionalität, die nicht hardwarebeschleunigt ist" + +#: t_options.h:228 +msgid "Enable extension GL_ARB_vertex_program" +msgstr "Erweiterung GL_ARB_vertex_program aktivieren" + +#: t_options.h:233 +msgid "Enable extension GL_NV_vertex_program" +msgstr "Erweiterung GL_NV_vertex_program aktivieren" diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/es.po b/mesalib/src/mesa/drivers/dri/common/xmlpool/es.po new file mode 100644 index 000000000..82ad177cb --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/es.po @@ -0,0 +1,219 @@ +# translation of es.po to Spanish +# Spanish translations for PACKAGE package. +# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# David <deifo@ono.com>, 2005. +# David Rubio Miguélez <deifo@ono.com>, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: es\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-04-12 12:18+0200\n" +"PO-Revision-Date: 2005-04-12 20:26+0200\n" +"Last-Translator: David Rubio Miguélez <deifo@ono.com>\n" +"Language-Team: Spanish <es@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: KBabel 1.10\n" + +#: t_options.h:53 +msgid "Debugging" +msgstr "Depurando" + +#: t_options.h:57 +msgid "Disable 3D acceleration" +msgstr "Desactivar aceleración 3D" + +#: t_options.h:62 +msgid "Show performance boxes" +msgstr "Mostrar cajas de rendimiento" + +#: t_options.h:69 +msgid "Image Quality" +msgstr "Calidad de imagen" + +#: t_options.h:77 +msgid "Texture color depth" +msgstr "Profundidad de color de textura" + +#: t_options.h:78 +msgid "Prefer frame buffer color depth" +msgstr "Preferir profundidad de color del \"framebuffer\"" + +#: t_options.h:79 +msgid "Prefer 32 bits per texel" +msgstr "Preferir 32 bits por texel" + +#: t_options.h:80 +msgid "Prefer 16 bits per texel" +msgstr "Preferir 16 bits por texel" + +#: t_options.h:81 +msgid "Force 16 bits per texel" +msgstr "Forzar a 16 bits por texel" + +#: t_options.h:87 +msgid "Initial maximum value for anisotropic texture filtering" +msgstr "Valor máximo inicial para filtrado anisotrópico de textura" + +#: t_options.h:92 +msgid "Forbid negative texture LOD bias" +msgstr "Prohibir valores negativos de Nivel De Detalle (LOD) de texturas" + +#: t_options.h:97 +msgid "Enable S3TC texture compression even if software support is not available" +msgstr "Activar la compresión de texturas S3TC incluso si el soporte por software no está disponible" + +#: t_options.h:104 +msgid "Initial color reduction method" +msgstr "Método inicial de reducción de color" + +#: t_options.h:105 +msgid "Round colors" +msgstr "Colores redondeados" + +#: t_options.h:106 +msgid "Dither colors" +msgstr "Colores suavizados" + +#: t_options.h:114 +msgid "Color rounding method" +msgstr "Método de redondeo de colores" + +#: t_options.h:115 +msgid "Round color components downward" +msgstr "Redondear hacia abajo los componentes de color" + +#: t_options.h:116 +msgid "Round to nearest color" +msgstr "Redondear al color más cercano" + +#: t_options.h:125 +msgid "Color dithering method" +msgstr "Método de suavizado de color" + +#: t_options.h:126 +msgid "Horizontal error diffusion" +msgstr "Difusión de error horizontal" + +#: t_options.h:127 +msgid "Horizontal error diffusion, reset error at line start" +msgstr "Difusión de error horizontal, reiniciar error al comienzo de línea" + +#: t_options.h:128 +msgid "Ordered 2D color dithering" +msgstr "Suavizado de color 2D ordenado" + +#: t_options.h:134 +msgid "Floating point depth buffer" +msgstr "Búfer de profundidad en coma flotante" + +#: t_options.h:140 +msgid "Performance" +msgstr "Rendimiento" + +#: t_options.h:148 +msgid "TCL mode (Transformation, Clipping, Lighting)" +msgstr "Modo TCL (Transformación, Recorte, Iluminación)" + +#: t_options.h:149 +msgid "Use software TCL pipeline" +msgstr "Usar tubería TCL por software" + +#: t_options.h:150 +msgid "Use hardware TCL as first TCL pipeline stage" +msgstr "Usar TCL por hardware en la primera fase de la tubería TCL" + +#: t_options.h:151 +msgid "Bypass the TCL pipeline" +msgstr "Pasar por alto la tubería TCL" + +#: t_options.h:152 +msgid "Bypass the TCL pipeline with state-based machine code generated on-the-fly" +msgstr "Pasar por alto la tubería TCL con código máquina basado en estados generado al vuelo" + +#: t_options.h:161 +msgid "Method to limit rendering latency" +msgstr "Método para limitar la latencia de rénder" + +#: t_options.h:162 +msgid "Busy waiting for the graphics hardware" +msgstr "Esperar activamente al hardware gráfico" + +#: t_options.h:163 +msgid "Sleep for brief intervals while waiting for the graphics hardware" +msgstr "Dormir en intervalos cortos mientras se espera al hardware gráfico" + +#: t_options.h:164 +msgid "Let the graphics hardware emit a software interrupt and sleep" +msgstr "Permitir que el hardware gráfico emita una interrupción de software y duerma" + +#: t_options.h:174 +msgid "Synchronization with vertical refresh (swap intervals)" +msgstr "Sincronización con el refresco vertical (intervalos de intercambio)" + +#: t_options.h:175 +msgid "Never synchronize with vertical refresh, ignore application's choice" +msgstr "No sincronizar nunca con el refresco vertical, ignorar la elección de la aplicación" + +#: t_options.h:176 +msgid "Initial swap interval 0, obey application's choice" +msgstr "Intervalo de intercambio inicial 0, obedecer la elección de la aplicación" + +#: t_options.h:177 +msgid "Initial swap interval 1, obey application's choice" +msgstr "Intervalo de intercambio inicial 1, obedecer la elección de la aplicación" + +#: t_options.h:178 +msgid "" +"Always synchronize with vertical refresh, application chooses the minimum " +"swap interval" +msgstr "Sincronizar siempre con el refresco vertical, la aplicación elige el intervalo de intercambio mínimo" + +#: t_options.h:186 +msgid "Use HyperZ to boost performance" +msgstr "Usar HyperZ para potenciar rendimiento" + +#: t_options.h:191 +msgid "Number of texture units used" +msgstr "Número de unidades de textura usadas" + +#: t_options.h:196 +msgid "Enable hack to allow larger textures with texture compression on radeon/r200" +msgstr "Activar \"hack\" para permitir texturas más grandes con compresión de textura activada en la Radeon/r200" + +#: t_options.h:201 +msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" +msgstr "Calidad de filtrado de textura vs. velocidad, alias filtrado \"brilinear\" de textura" + +#: t_options.h:209 +msgid "Used types of texture memory" +msgstr "Tipos de memoria de textura usados" + +#: t_options.h:210 +msgid "All available memory" +msgstr "Toda la memoria disponible" + +#: t_options.h:211 +msgid "Only card memory (if available)" +msgstr "Sólo la memoria de la tarjeta (si disponible)" + +#: t_options.h:212 +msgid "Only GART (AGP/PCIE) memory (if available)" +msgstr "Sólo memoria GART (AGP/PCIE) (si disponible)" + +#: t_options.h:220 +msgid "Features that are not hardware-accelerated" +msgstr "Características no aceleradas por hardware" + +#: t_options.h:224 +msgid "Enable extension GL_ARB_vertex_program" +msgstr "Activar la extensión GL_ARB_vertex_program" + +#: t_options.h:229 +msgid "Enable extension GL_NV_vertex_program" +msgstr "Activar extensión GL_NV_vertex_program" + diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/fr.po b/mesalib/src/mesa/drivers/dri/common/xmlpool/fr.po new file mode 100644 index 000000000..19f3b4a4e --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/fr.po @@ -0,0 +1,225 @@ +# French translations for DRI driver options. +# Copyright (C) 2005 Stephane Marchesin +# This file is distributed under the same license as the Mesa package. +# Stephane Marchesin <marchesin@icps.u-strasbg.fr>, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: Mesa 6.3\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-04-11 23:19+0200\n" +"PO-Revision-Date: 2005-04-11 01:34+0200\n" +"Last-Translator: Stephane Marchesin <marchesin@icps.u-strasbg.fr>\n" +"Language-Team: French <fr@li.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: t_options.h:53 +msgid "Debugging" +msgstr "Debogage" + +#: t_options.h:57 +msgid "Disable 3D acceleration" +msgstr "Désactiver l'accélération 3D" + +#: t_options.h:62 +msgid "Show performance boxes" +msgstr "Afficher les boîtes de performance" + +#: t_options.h:69 +msgid "Image Quality" +msgstr "Qualité d'image" + +#: t_options.h:77 +msgid "Texture color depth" +msgstr "Profondeur de texture" + +#: t_options.h:78 +msgid "Prefer frame buffer color depth" +msgstr "Profondeur de couleur" + +#: t_options.h:79 +msgid "Prefer 32 bits per texel" +msgstr "Préférer 32 bits par texel" + +#: t_options.h:80 +msgid "Prefer 16 bits per texel" +msgstr "Prérérer 16 bits par texel" + +#: t_options.h:81 +msgid "Force 16 bits per texel" +msgstr "Forcer 16 bits par texel" + +#: t_options.h:87 +msgid "Initial maximum value for anisotropic texture filtering" +msgstr "Valeur maximale initiale pour le filtrage anisotropique de texture" + +#: t_options.h:92 +msgid "Forbid negative texture LOD bias" +msgstr "Interdire le LOD bias negatif" + +#: t_options.h:97 +msgid "" +"Enable S3TC texture compression even if software support is not available" +msgstr "" +"Activer la compression de texture S3TC même si le support logiciel est absent" + +#: t_options.h:104 +msgid "Initial color reduction method" +msgstr "Technique de réduction de couleurs" + +#: t_options.h:105 +msgid "Round colors" +msgstr "Arrondir les valeurs de couleur" + +#: t_options.h:106 +msgid "Dither colors" +msgstr "Tramer les couleurs" + +#: t_options.h:114 +msgid "Color rounding method" +msgstr "Méthode d'arrondi des couleurs" + +#: t_options.h:115 +msgid "Round color components downward" +msgstr "Arrondi à l'inférieur" + +#: t_options.h:116 +msgid "Round to nearest color" +msgstr "Arrondi au plus proche" + +#: t_options.h:125 +msgid "Color dithering method" +msgstr "Méthode de tramage" + +#: t_options.h:126 +msgid "Horizontal error diffusion" +msgstr "Diffusion d'erreur horizontale" + +#: t_options.h:127 +msgid "Horizontal error diffusion, reset error at line start" +msgstr "Diffusion d'erreur horizontale, réinitialisé pour chaque ligne" + +#: t_options.h:128 +msgid "Ordered 2D color dithering" +msgstr "Tramage ordonné des couleurs" + +#: t_options.h:134 +msgid "Floating point depth buffer" +msgstr "Z-buffer en virgule flottante" + +#: t_options.h:140 +msgid "Performance" +msgstr "Performance" + +#: t_options.h:148 +msgid "TCL mode (Transformation, Clipping, Lighting)" +msgstr "Mode de TCL (Transformation, Clipping, Eclairage)" + +#: t_options.h:149 +msgid "Use software TCL pipeline" +msgstr "Utiliser un pipeline TCL logiciel" + +#: t_options.h:150 +msgid "Use hardware TCL as first TCL pipeline stage" +msgstr "Utiliser le TCL matériel pour le premier niveau de pipeline" + +#: t_options.h:151 +msgid "Bypass the TCL pipeline" +msgstr "Court-circuiter le pipeline TCL" + +#: t_options.h:152 +msgid "" +"Bypass the TCL pipeline with state-based machine code generated on-the-fly" +msgstr "" +"Court-circuiter le pipeline TCL par une machine à états qui génère le code" +"de TCL à la volée" + +#: t_options.h:161 +msgid "Method to limit rendering latency" +msgstr "Méthode d'attente de la carte graphique" + +#: t_options.h:162 +msgid "Busy waiting for the graphics hardware" +msgstr "Attente active de la carte graphique" + +#: t_options.h:163 +msgid "Sleep for brief intervals while waiting for the graphics hardware" +msgstr "Attente utilisant usleep()" + +#: t_options.h:164 +msgid "Let the graphics hardware emit a software interrupt and sleep" +msgstr "Utiliser les interruptions" + +#: t_options.h:174 +msgid "Synchronization with vertical refresh (swap intervals)" +msgstr "Synchronisation de l'affichage avec le balayage vertical" + +#: t_options.h:175 +msgid "Never synchronize with vertical refresh, ignore application's choice" +msgstr "Ne jamais synchroniser avec le balayage vertical, ignorer le choix de l'application" + +#: t_options.h:176 +msgid "Initial swap interval 0, obey application's choice" +msgstr "Ne pas synchroniser avec le balayage vertical par défaut, mais obéir au choix de l'application" + +#: t_options.h:177 +msgid "Initial swap interval 1, obey application's choice" +msgstr "Synchroniser avec le balayage vertical par défaut, mais obéir au choix de l'application" + +#: t_options.h:178 +msgid "" +"Always synchronize with vertical refresh, application chooses the minimum " +"swap interval" +msgstr "" +"Toujours synchroniser avec le balayage vertical, l'application choisit l'intervalle minimal" + +#: t_options.h:186 +msgid "Use HyperZ to boost performance" +msgstr "Utiliser le HyperZ pour améliorer les performances" + +#: t_options.h:191 +msgid "Number of texture units used" +msgstr "Nombre d'unités de texture" + +#: t_options.h:196 +msgid "" +"Enable hack to allow larger textures with texture compression on radeon/r200" +msgstr "" +"Activer le hack permettant l'utilisation de textures de grande taille avec la " +"compression de textures sur radeon/r200" + +#: t_options.h:201 +msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" +msgstr "" +"Qualité/performance du filtrage trilinéaire de texture (filtrage brilinéaire)" + +#: t_options.h:209 +msgid "Used types of texture memory" +msgstr "Types de mémoire de texture" + +#: t_options.h:210 +msgid "All available memory" +msgstr "Utiliser toute la mémoire disponible" + +#: t_options.h:211 +msgid "Only card memory (if available)" +msgstr "Utiliser uniquement la mémoire graphique (si disponible)" + +#: t_options.h:212 +msgid "Only GART (AGP/PCIE) memory (if available)" +msgstr "Utiliser uniquement la mémoire GART (AGP/PCIE) (si disponible)" + +#: t_options.h:220 +msgid "Features that are not hardware-accelerated" +msgstr "Fonctionnalités ne bénéficiant pas d'une accélération matérielle" + +#: t_options.h:224 +msgid "Enable extension GL_ARB_vertex_program" +msgstr "Activer l'extension GL_ARB_vertex_program" + +#: t_options.h:229 +msgid "Enable extension GL_NV_vertex_program" +msgstr "Activer l'extension GL_NV_vertex_program" diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/nl.po b/mesalib/src/mesa/drivers/dri/common/xmlpool/nl.po new file mode 100644 index 000000000..1e4cf167b --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/nl.po @@ -0,0 +1,230 @@ +# Dutch translations for PACKAGE package. +# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# <manfred.stienstra@dwerg.net>, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-04-12 20:09+0200\n" +"PO-Revision-Date: 2005-04-12 20:09+0200\n" +"Last-Translator: Manfred Stienstra <manfred.stienstra@dwerg.net>\n" +"Language-Team: Dutch <vertaling@nl.linux.org>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: t_options.h:53 +msgid "Debugging" +msgstr "Debuggen" + +#: t_options.h:57 +msgid "Disable 3D acceleration" +msgstr "3D versnelling uitschakelen" + +#: t_options.h:62 +msgid "Show performance boxes" +msgstr "Laat prestatie boxjes zien" + +#: t_options.h:69 +msgid "Image Quality" +msgstr "Beeldkwaliteit" + +#: t_options.h:77 +msgid "Texture color depth" +msgstr "Textuurkleurendiepte" + +#: t_options.h:78 +msgid "Prefer frame buffer color depth" +msgstr "Prefereer kaderbufferkleurdiepte" + +#: t_options.h:79 +msgid "Prefer 32 bits per texel" +msgstr "Prefereer 32 bits per texel" + +#: t_options.h:80 +msgid "Prefer 16 bits per texel" +msgstr "Prefereer 16 bits per texel" + +#: t_options.h:81 +msgid "Force 16 bits per texel" +msgstr "Dwing 16 bits per texel af" + +#: t_options.h:87 +msgid "Initial maximum value for anisotropic texture filtering" +msgstr "Initïele maximum waarde voor anisotrophische textuur filtering" + +#: t_options.h:92 +msgid "Forbid negative texture LOD bias" +msgstr "Verbied negatief niveau detailonderscheid (LOD) van texturen" + +#: t_options.h:97 +msgid "" +"Enable S3TC texture compression even if software support is not available" +msgstr "" +"Schakel S3TC textuurcompressie in, zelfs als softwareondersteuning niet " +"aanwezig is" + +#: t_options.h:104 +msgid "Initial color reduction method" +msgstr "Initïele kleurreductie methode" + +#: t_options.h:105 +msgid "Round colors" +msgstr "Rond kleuren af" + +#: t_options.h:106 +msgid "Dither colors" +msgstr "Rasteriseer kleuren" + +#: t_options.h:114 +msgid "Color rounding method" +msgstr "Kleurafrondingmethode" + +#: t_options.h:115 +msgid "Round color components downward" +msgstr "Rond kleurencomponenten af naar beneden" + +#: t_options.h:116 +msgid "Round to nearest color" +msgstr "Rond af naar dichtsbijzijnde kleur" + +#: t_options.h:125 +msgid "Color dithering method" +msgstr "Kleurrasteriseringsmethode" + +#: t_options.h:126 +msgid "Horizontal error diffusion" +msgstr "Horizontale foutdiffusie" + +#: t_options.h:127 +msgid "Horizontal error diffusion, reset error at line start" +msgstr "Horizontale foutdiffusie, zet fout bij lijnbegin terug" + +#: t_options.h:128 +msgid "Ordered 2D color dithering" +msgstr "Geordende 2D kleurrasterisering" + +#: t_options.h:134 +msgid "Floating point depth buffer" +msgstr "Dieptebuffer als commagetal" + +#: t_options.h:140 +msgid "Performance" +msgstr "Prestatie" + +#: t_options.h:148 +msgid "TCL mode (Transformation, Clipping, Lighting)" +msgstr "TCL-modus (Transformatie, Clipping, Licht)" + +#: t_options.h:149 +msgid "Use software TCL pipeline" +msgstr "Gebruik software TCL pijpleiding" + +#: t_options.h:150 +msgid "Use hardware TCL as first TCL pipeline stage" +msgstr "Gebruik hardware TCL as eerste TCL pijpleiding trap" + +#: t_options.h:151 +msgid "Bypass the TCL pipeline" +msgstr "Omzeil de TCL pijpleiding" + +#: t_options.h:152 +msgid "" +"Bypass the TCL pipeline with state-based machine code generated on-the-fly" +msgstr "" +"Omzeil de TCL pijpleiding met staatgebaseerde machinecode die tijdens " +"executie gegenereerd wordt" + +#: t_options.h:161 +msgid "Method to limit rendering latency" +msgstr "Methode om beeldopbouwvertraging te onderdrukken" + +#: t_options.h:162 +msgid "Busy waiting for the graphics hardware" +msgstr "Actief wachten voor de grafische hardware" + +#: t_options.h:163 +msgid "Sleep for brief intervals while waiting for the graphics hardware" +msgstr "Slaap voor korte intervallen tijdens het wachten op de grafische " +"hardware" + +#: t_options.h:164 +msgid "Let the graphics hardware emit a software interrupt and sleep" +msgstr "Laat de grafische hardware een software onderbreking uitzenden en in " +"slaap vallen" + +#: t_options.h:174 +msgid "Synchronization with vertical refresh (swap intervals)" +msgstr "Synchronisatie met verticale verversing (interval omwisselen)" + +#: t_options.h:175 +msgid "Never synchronize with vertical refresh, ignore application's choice" +msgstr "Nooit synchroniseren met verticale verversing, negeer de keuze van de " +"applicatie" + +#: t_options.h:176 +msgid "Initial swap interval 0, obey application's choice" +msgstr "Initïeel omwisselingsinterval 0, honoreer de keuze van de applicatie" + +#: t_options.h:177 +msgid "Initial swap interval 1, obey application's choice" +msgstr "Initïeel omwisselingsinterval 1, honoreer de keuze van de applicatie" + +#: t_options.h:178 +msgid "" +"Always synchronize with vertical refresh, application chooses the minimum " +"swap interval" +msgstr "" +"Synchroniseer altijd met verticale verversing, de applicatie kiest het " +"minimum omwisselingsinterval" + +#: t_options.h:186 +msgid "Use HyperZ to boost performance" +msgstr "Gebruik HyperZ om de prestaties te verbeteren" + +#: t_options.h:191 +msgid "Number of texture units used" +msgstr "Aantal textuureenheden in gebruik" + +#: t_options.h:196 +msgid "" +"Enable hack to allow larger textures with texture compression on radeon/r200" +msgstr "" +"Schakel hack in om met textuurcompressie grotere texturen toe te staan op " +"een radeon/r200" + +#: t_options.h:201 +msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" +msgstr "Textuurfilterkwaliteit versus -snelheid, ookwel bekend als " +"“brilineaire” textuurfiltering" + +#: t_options.h:209 +msgid "Used types of texture memory" +msgstr "Gebruikte soorten textuurgeheugen" + +#: t_options.h:210 +msgid "All available memory" +msgstr "Al het beschikbaar geheugen" + +#: t_options.h:211 +msgid "Only card memory (if available)" +msgstr "Alleen geheugen op de kaart (als het aanwezig is)" + +#: t_options.h:212 +msgid "Only GART (AGP/PCIE) memory (if available)" +msgstr "Alleen GART (AGP/PCIE) geheugen (als het aanwezig is)" + +#: t_options.h:220 +msgid "Features that are not hardware-accelerated" +msgstr "Eigenschappen die niet hardwareversneld zijn" + +#: t_options.h:224 +msgid "Enable extension GL_ARB_vertex_program" +msgstr "Zet uitbreiding GL_ARB_vertex_program aan" + +#: t_options.h:229 +msgid "Enable extension GL_NV_vertex_program" +msgstr "Zet uitbreiding GL_NV_vertex_program aan" diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/options.h b/mesalib/src/mesa/drivers/dri/common/xmlpool/options.h new file mode 100644 index 000000000..d76595578 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/options.h @@ -0,0 +1,568 @@ +/*********************************************************************** + *** THIS FILE IS GENERATED AUTOMATICALLY. DON'T EDIT! *** + ***********************************************************************/ +/* + * XML DRI client-side driver configuration + * Copyright (C) 2003 Felix Kuehling + * + * 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 + * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 t_options.h + * \brief Templates of common options + * \author Felix Kuehling + * + * This file defines macros for common options that can be used to + * construct driConfigOptions in the drivers. This file is only a + * template containing English descriptions for options wrapped in + * gettext(). xgettext can be used to extract translatable + * strings. These strings can then be translated by anyone familiar + * with GNU gettext. gen_xmlpool.py takes this template and fills in + * all the translations. The result (options.h) is included by + * xmlpool.h which in turn can be included by drivers. + * + * The macros used to describe otions in this file are defined in + * ../xmlpool.h. + */ + +/* This is needed for xgettext to extract translatable strings. + * gen_xmlpool.py will discard this line. */ +/* #include <libintl.h> + * commented out by gen_xmlpool.py */ + +/* + * predefined option sections and options with multi-lingual descriptions + */ + +/** \brief Debugging options */ +#define DRI_CONF_SECTION_DEBUG \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,"Debugging") \ + DRI_CONF_DESC(de,"Fehlersuche") \ + DRI_CONF_DESC(es,"Depurando") \ + DRI_CONF_DESC(nl,"Debuggen") \ + DRI_CONF_DESC(fr,"Debogage") \ + DRI_CONF_DESC(sv,"Felsökning") + +#define DRI_CONF_NO_RAST(def) \ +DRI_CONF_OPT_BEGIN(no_rast,bool,def) \ + DRI_CONF_DESC(en,"Disable 3D acceleration") \ + DRI_CONF_DESC(de,"3D-Beschleunigung abschalten") \ + DRI_CONF_DESC(es,"Desactivar aceleración 3D") \ + DRI_CONF_DESC(nl,"3D versnelling uitschakelen") \ + DRI_CONF_DESC(fr,"Désactiver l'accélération 3D") \ + DRI_CONF_DESC(sv,"Inaktivera 3D-accelerering") \ +DRI_CONF_OPT_END + +#define DRI_CONF_PERFORMANCE_BOXES(def) \ +DRI_CONF_OPT_BEGIN(performance_boxes,bool,def) \ + DRI_CONF_DESC(en,"Show performance boxes") \ + DRI_CONF_DESC(de,"Zeige Performanceboxen") \ + DRI_CONF_DESC(es,"Mostrar cajas de rendimiento") \ + DRI_CONF_DESC(nl,"Laat prestatie boxjes zien") \ + DRI_CONF_DESC(fr,"Afficher les boîtes de performance") \ + DRI_CONF_DESC(sv,"Visa prestandarutor") \ +DRI_CONF_OPT_END + + +/** \brief Texture-related options */ +#define DRI_CONF_SECTION_QUALITY \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,"Image Quality") \ + DRI_CONF_DESC(de,"Bildqualität") \ + DRI_CONF_DESC(es,"Calidad de imagen") \ + DRI_CONF_DESC(nl,"Beeldkwaliteit") \ + DRI_CONF_DESC(fr,"Qualité d'image") \ + DRI_CONF_DESC(sv,"Bildkvalitet") + +#define DRI_CONF_EXCESS_MIPMAP(def) \ +DRI_CONF_OPT_BEGIN(excess_mipmap,bool,def) \ + DRI_CONF_DESC(en,"Enable extra mipmap level") \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_DEPTH_FB 0 +#define DRI_CONF_TEXTURE_DEPTH_32 1 +#define DRI_CONF_TEXTURE_DEPTH_16 2 +#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3 +#define DRI_CONF_TEXTURE_DEPTH(def) \ +DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,"Texture color depth") \ + DRI_CONF_ENUM(0,"Prefer frame buffer color depth") \ + DRI_CONF_ENUM(1,"Prefer 32 bits per texel") \ + DRI_CONF_ENUM(2,"Prefer 16 bits per texel") \ + DRI_CONF_ENUM(3,"Force 16 bits per texel") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Texturfarbtiefe") \ + DRI_CONF_ENUM(0,"Bevorzuge Farbtiefe des Framebuffers") \ + DRI_CONF_ENUM(1,"Bevorzuge 32 bits pro Texel") \ + DRI_CONF_ENUM(2,"Bevorzuge 16 bits pro Texel") \ + DRI_CONF_ENUM(3,"Erzwinge 16 bits pro Texel") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Profundidad de color de textura") \ + DRI_CONF_ENUM(0,"Preferir profundidad de color del ”framebuffer“") \ + DRI_CONF_ENUM(1,"Preferir 32 bits por texel") \ + DRI_CONF_ENUM(2,"Preferir 16 bits por texel") \ + DRI_CONF_ENUM(3,"Forzar a 16 bits por texel") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Textuurkleurendiepte") \ + DRI_CONF_ENUM(0,"Prefereer kaderbufferkleurdiepte") \ + DRI_CONF_ENUM(1,"Prefereer 32 bits per texel") \ + DRI_CONF_ENUM(2,"Prefereer 16 bits per texel") \ + DRI_CONF_ENUM(3,"Dwing 16 bits per texel af") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Profondeur de texture") \ + DRI_CONF_ENUM(0,"Profondeur de couleur") \ + DRI_CONF_ENUM(1,"Préférer 32 bits par texel") \ + DRI_CONF_ENUM(2,"Prérérer 16 bits par texel") \ + DRI_CONF_ENUM(3,"Forcer 16 bits par texel") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Färgdjup för texturer") \ + DRI_CONF_ENUM(0,"Föredra färgdjupet för framebuffer") \ + DRI_CONF_ENUM(1,"Föredra 32 bitar per texel") \ + DRI_CONF_ENUM(2,"Föredra 16 bitar per texel") \ + DRI_CONF_ENUM(3,"Tvinga 16 bitar per texel") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \ +DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \ + DRI_CONF_DESC(en,"Initial maximum value for anisotropic texture filtering") \ + DRI_CONF_DESC(de,"Initialer Maximalwert für anisotropische Texturfilterung") \ + DRI_CONF_DESC(es,"Valor máximo inicial para filtrado anisotrópico de textura") \ + DRI_CONF_DESC(nl,"Initïele maximum waarde voor anisotrophische textuur filtering") \ + DRI_CONF_DESC(fr,"Valeur maximale initiale pour le filtrage anisotropique de texture") \ + DRI_CONF_DESC(sv,"Initialt maximalt värde för anisotropisk texturfiltrering") \ +DRI_CONF_OPT_END + +#define DRI_CONF_NO_NEG_LOD_BIAS(def) \ +DRI_CONF_OPT_BEGIN(no_neg_lod_bias,bool,def) \ + DRI_CONF_DESC(en,"Forbid negative texture LOD bias") \ + DRI_CONF_DESC(de,"Verbiete negative Textur-Detailgradverschiebung") \ + DRI_CONF_DESC(es,"Prohibir valores negativos de Nivel De Detalle (LOD) de texturas") \ + DRI_CONF_DESC(nl,"Verbied negatief niveau detailonderscheid (LOD) van texturen") \ + DRI_CONF_DESC(fr,"Interdire le LOD bias negatif") \ + DRI_CONF_DESC(sv,"Förbjud negativ LOD-kompensation för texturer") \ +DRI_CONF_OPT_END + +#define DRI_CONF_FORCE_S3TC_ENABLE(def) \ +DRI_CONF_OPT_BEGIN(force_s3tc_enable,bool,def) \ + DRI_CONF_DESC(en,"Enable S3TC texture compression even if software support is not available") \ + DRI_CONF_DESC(de,"Aktiviere S3TC Texturkomprimierung auch wenn die nötige Softwareunterstützung fehlt") \ + DRI_CONF_DESC(es,"Activar la compresión de texturas S3TC incluso si el soporte por software no está disponible") \ + DRI_CONF_DESC(nl,"Schakel S3TC textuurcompressie in, zelfs als softwareondersteuning niet aanwezig is") \ + DRI_CONF_DESC(fr,"Activer la compression de texture S3TC même si le support logiciel est absent") \ + DRI_CONF_DESC(sv,"Aktivera S3TC-texturkomprimering även om programvarustöd saknas") \ +DRI_CONF_OPT_END + +#define DRI_CONF_COLOR_REDUCTION_ROUND 0 +#define DRI_CONF_COLOR_REDUCTION_DITHER 1 +#define DRI_CONF_COLOR_REDUCTION(def) \ +DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Initial color reduction method") \ + DRI_CONF_ENUM(0,"Round colors") \ + DRI_CONF_ENUM(1,"Dither colors") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Initiale Farbreduktionsmethode") \ + DRI_CONF_ENUM(0,"Farben runden") \ + DRI_CONF_ENUM(1,"Farben rastern") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Método inicial de reducción de color") \ + DRI_CONF_ENUM(0,"Colores redondeados") \ + DRI_CONF_ENUM(1,"Colores suavizados") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Initïele kleurreductie methode") \ + DRI_CONF_ENUM(0,"Rond kleuren af") \ + DRI_CONF_ENUM(1,"Rasteriseer kleuren") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Technique de réduction de couleurs") \ + DRI_CONF_ENUM(0,"Arrondir les valeurs de couleur") \ + DRI_CONF_ENUM(1,"Tramer les couleurs") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Initial färgminskningsmetod") \ + DRI_CONF_ENUM(0,"Avrunda färger") \ + DRI_CONF_ENUM(1,"Utjämna färger") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_ROUND_TRUNC 0 +#define DRI_CONF_ROUND_ROUND 1 +#define DRI_CONF_ROUND_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,"Color rounding method") \ + DRI_CONF_ENUM(0,"Round color components downward") \ + DRI_CONF_ENUM(1,"Round to nearest color") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Farbrundungsmethode") \ + DRI_CONF_ENUM(0,"Farbkomponenten abrunden") \ + DRI_CONF_ENUM(1,"Zur ähnlichsten Farbe runden") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Método de redondeo de colores") \ + DRI_CONF_ENUM(0,"Redondear hacia abajo los componentes de color") \ + DRI_CONF_ENUM(1,"Redondear al color más cercano") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Kleurafrondingmethode") \ + DRI_CONF_ENUM(0,"Rond kleurencomponenten af naar beneden") \ + DRI_CONF_ENUM(1,"Rond af naar dichtsbijzijnde kleur") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Méthode d'arrondi des couleurs") \ + DRI_CONF_ENUM(0,"Arrondi à l'inférieur") \ + DRI_CONF_ENUM(1,"Arrondi au plus proche") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Färgavrundningsmetod") \ + DRI_CONF_ENUM(0,"Avrunda färdkomponenter nedåt") \ + DRI_CONF_ENUM(1,"Avrunda till närmsta färg") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_DITHER_XERRORDIFF 0 +#define DRI_CONF_DITHER_XERRORDIFFRESET 1 +#define DRI_CONF_DITHER_ORDERED 2 +#define DRI_CONF_DITHER_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Color dithering method") \ + DRI_CONF_ENUM(0,"Horizontal error diffusion") \ + DRI_CONF_ENUM(1,"Horizontal error diffusion, reset error at line start") \ + DRI_CONF_ENUM(2,"Ordered 2D color dithering") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Farbrasterungsmethode") \ + DRI_CONF_ENUM(0,"Horizontale Fehlerstreuung") \ + DRI_CONF_ENUM(1,"Horizontale Fehlerstreuung, Fehler am Zeilenanfang zurücksetzen") \ + DRI_CONF_ENUM(2,"Geordnete 2D Farbrasterung") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Método de suavizado de color") \ + DRI_CONF_ENUM(0,"Difusión de error horizontal") \ + DRI_CONF_ENUM(1,"Difusión de error horizontal, reiniciar error al comienzo de línea") \ + DRI_CONF_ENUM(2,"Suavizado de color 2D ordenado") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Kleurrasteriseringsmethode") \ + DRI_CONF_ENUM(0,"Horizontale foutdiffusie") \ + DRI_CONF_ENUM(1,"Horizontale foutdiffusie, zet fout bij lijnbegin terug") \ + DRI_CONF_ENUM(2,"Geordende 2D kleurrasterisering") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Méthode de tramage") \ + DRI_CONF_ENUM(0,"Diffusion d'erreur horizontale") \ + DRI_CONF_ENUM(1,"Diffusion d'erreur horizontale, réinitialisé pour chaque ligne") \ + DRI_CONF_ENUM(2,"Tramage ordonné des couleurs") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Färgutjämningsmetod") \ + DRI_CONF_ENUM(0,"Horisontell felspridning") \ + DRI_CONF_ENUM(1,"Horisontell felspridning, återställ fel vid radbörjan") \ + DRI_CONF_ENUM(2,"Ordnad 2D-färgutjämning") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_FLOAT_DEPTH(def) \ +DRI_CONF_OPT_BEGIN(float_depth,bool,def) \ + DRI_CONF_DESC(en,"Floating point depth buffer") \ + DRI_CONF_DESC(de,"Fließkomma z-Puffer") \ + DRI_CONF_DESC(es,"Búfer de profundidad en coma flotante") \ + DRI_CONF_DESC(nl,"Dieptebuffer als commagetal") \ + DRI_CONF_DESC(fr,"Z-buffer en virgule flottante") \ + DRI_CONF_DESC(sv,"Buffert för flytande punktdjup") \ +DRI_CONF_OPT_END + +/** \brief Performance-related options */ +#define DRI_CONF_SECTION_PERFORMANCE \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,"Performance") \ + DRI_CONF_DESC(de,"Leistung") \ + DRI_CONF_DESC(es,"Rendimiento") \ + DRI_CONF_DESC(nl,"Prestatie") \ + DRI_CONF_DESC(fr,"Performance") \ + DRI_CONF_DESC(sv,"Prestanda") + +#define DRI_CONF_TCL_SW 0 +#define DRI_CONF_TCL_PIPELINED 1 +#define DRI_CONF_TCL_VTXFMT 2 +#define DRI_CONF_TCL_CODEGEN 3 +#define DRI_CONF_TCL_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,"TCL mode (Transformation, Clipping, Lighting)") \ + DRI_CONF_ENUM(0,"Use software TCL pipeline") \ + DRI_CONF_ENUM(1,"Use hardware TCL as first TCL pipeline stage") \ + DRI_CONF_ENUM(2,"Bypass the TCL pipeline") \ + DRI_CONF_ENUM(3,"Bypass the TCL pipeline with state-based machine code generated on-the-fly") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"TCL-Modus (Transformation, Clipping, Licht)") \ + DRI_CONF_ENUM(0,"Benutze die Software-TCL-Pipeline") \ + DRI_CONF_ENUM(1,"Benutze Hardware TCL als erste Stufe der TCL-Pipeline") \ + DRI_CONF_ENUM(2,"Umgehe die TCL-Pipeline") \ + DRI_CONF_ENUM(3,"Umgehe die TCL-Pipeline mit zur Laufzeit erzeugtem, zustandsbasiertem Maschinencode") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Modo TCL (Transformación, Recorte, Iluminación)") \ + DRI_CONF_ENUM(0,"Usar tubería TCL por software") \ + DRI_CONF_ENUM(1,"Usar TCL por hardware en la primera fase de la tubería TCL") \ + DRI_CONF_ENUM(2,"Pasar por alto la tubería TCL") \ + DRI_CONF_ENUM(3,"Pasar por alto la tubería TCL con código máquina basado en estados generado al vuelo") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"TCL-modus (Transformatie, Clipping, Licht)") \ + DRI_CONF_ENUM(0,"Gebruik software TCL pijpleiding") \ + DRI_CONF_ENUM(1,"Gebruik hardware TCL as eerste TCL pijpleiding trap") \ + DRI_CONF_ENUM(2,"Omzeil de TCL pijpleiding") \ + DRI_CONF_ENUM(3,"Omzeil de TCL pijpleiding met staatgebaseerde machinecode die tijdens executie gegenereerd wordt") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Mode de TCL (Transformation, Clipping, Eclairage)") \ + DRI_CONF_ENUM(0,"Utiliser un pipeline TCL logiciel") \ + DRI_CONF_ENUM(1,"Utiliser le TCL matériel pour le premier niveau de pipeline") \ + DRI_CONF_ENUM(2,"Court-circuiter le pipeline TCL") \ + DRI_CONF_ENUM(3,"Court-circuiter le pipeline TCL par une machine à états qui génère le codede TCL à la volée") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"TCL-läge (Transformation, Clipping, Lighting)") \ + DRI_CONF_ENUM(0,"Använd programvaru-TCL-rörledning") \ + DRI_CONF_ENUM(1,"Använd maskinvaru-TCL som första TCL-rörledningssteg") \ + DRI_CONF_ENUM(2,"Kringgå TCL-rörledningen") \ + DRI_CONF_ENUM(3,"Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_FTHROTTLE_BUSY 0 +#define DRI_CONF_FTHROTTLE_USLEEPS 1 +#define DRI_CONF_FTHROTTLE_IRQS 2 +#define DRI_CONF_FTHROTTLE_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Method to limit rendering latency") \ + DRI_CONF_ENUM(0,"Busy waiting for the graphics hardware") \ + DRI_CONF_ENUM(1,"Sleep for brief intervals while waiting for the graphics hardware") \ + DRI_CONF_ENUM(2,"Let the graphics hardware emit a software interrupt and sleep") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Methode zur Begrenzung der Bildverzögerung") \ + DRI_CONF_ENUM(0,"Aktives Warten auf die Grafikhardware") \ + DRI_CONF_ENUM(1,"Kurze Schlafintervalle beim Warten auf die Grafikhardware") \ + DRI_CONF_ENUM(2,"Die Grafikhardware eine Softwareunterbrechnung erzeugen lassen und schlafen") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Método para limitar la latencia de rénder") \ + DRI_CONF_ENUM(0,"Esperar activamente al hardware gráfico") \ + DRI_CONF_ENUM(1,"Dormir en intervalos cortos mientras se espera al hardware gráfico") \ + DRI_CONF_ENUM(2,"Permitir que el hardware gráfico emita una interrupción de software y duerma") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Methode om beeldopbouwvertraging te onderdrukken") \ + DRI_CONF_ENUM(0,"Actief wachten voor de grafische hardware") \ + DRI_CONF_ENUM(1,"Slaap voor korte intervallen tijdens het wachten op de grafische hardware") \ + DRI_CONF_ENUM(2,"Laat de grafische hardware een software onderbreking uitzenden en in slaap vallen") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Méthode d'attente de la carte graphique") \ + DRI_CONF_ENUM(0,"Attente active de la carte graphique") \ + DRI_CONF_ENUM(1,"Attente utilisant usleep()") \ + DRI_CONF_ENUM(2,"Utiliser les interruptions") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Metod för att begränsa renderingslatens") \ + DRI_CONF_ENUM(0,"Upptagen med att vänta på grafikhårdvaran") \ + DRI_CONF_ENUM(1,"Sov i korta intervall under väntan på grafikhårdvaran") \ + DRI_CONF_ENUM(2,"Låt grafikhårdvaran sända ut ett programvaruavbrott och sov") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_VBLANK_NEVER 0 +#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 +#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 +#define DRI_CONF_VBLANK_ALWAYS_SYNC 3 +#define DRI_CONF_VBLANK_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(vblank_mode,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,"Synchronization with vertical refresh (swap intervals)") \ + DRI_CONF_ENUM(0,"Never synchronize with vertical refresh, ignore application's choice") \ + DRI_CONF_ENUM(1,"Initial swap interval 0, obey application's choice") \ + DRI_CONF_ENUM(2,"Initial swap interval 1, obey application's choice") \ + DRI_CONF_ENUM(3,"Always synchronize with vertical refresh, application chooses the minimum swap interval") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Synchronisation mit der vertikalen Bildwiederholung") \ + DRI_CONF_ENUM(0,"Niemals mit der Bildwiederholung synchronisieren, Anweisungen der Anwendung ignorieren") \ + DRI_CONF_ENUM(1,"Initiales Bildinterval 0, Anweisungen der Anwendung gehorchen") \ + DRI_CONF_ENUM(2,"Initiales Bildinterval 1, Anweisungen der Anwendung gehorchen") \ + DRI_CONF_ENUM(3,"Immer mit der Bildwiederholung synchronisieren, Anwendung wählt das minimale Bildintervall") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Sincronización con el refresco vertical (intervalos de intercambio)") \ + DRI_CONF_ENUM(0,"No sincronizar nunca con el refresco vertical, ignorar la elección de la aplicación") \ + DRI_CONF_ENUM(1,"Intervalo de intercambio inicial 0, obedecer la elección de la aplicación") \ + DRI_CONF_ENUM(2,"Intervalo de intercambio inicial 1, obedecer la elección de la aplicación") \ + DRI_CONF_ENUM(3,"Sincronizar siempre con el refresco vertical, la aplicación elige el intervalo de intercambio mínimo") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Synchronisatie met verticale verversing (interval omwisselen)") \ + DRI_CONF_ENUM(0,"Nooit synchroniseren met verticale verversing, negeer de keuze van de applicatie") \ + DRI_CONF_ENUM(1,"Initïeel omwisselingsinterval 0, honoreer de keuze van de applicatie") \ + DRI_CONF_ENUM(2,"Initïeel omwisselingsinterval 1, honoreer de keuze van de applicatie") \ + DRI_CONF_ENUM(3,"Synchroniseer altijd met verticale verversing, de applicatie kiest het minimum omwisselingsinterval") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Synchronisation de l'affichage avec le balayage vertical") \ + DRI_CONF_ENUM(0,"Ne jamais synchroniser avec le balayage vertical, ignorer le choix de l'application") \ + DRI_CONF_ENUM(1,"Ne pas synchroniser avec le balayage vertical par défaut, mais obéir au choix de l'application") \ + DRI_CONF_ENUM(2,"Synchroniser avec le balayage vertical par défaut, mais obéir au choix de l'application") \ + DRI_CONF_ENUM(3,"Toujours synchroniser avec le balayage vertical, l'application choisit l'intervalle minimal") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Synkronisering med vertikal uppdatering (växlingsintervall)") \ + DRI_CONF_ENUM(0,"Synkronisera aldrig med vertikal uppdatering, ignorera programmets val") \ + DRI_CONF_ENUM(1,"Initialt växlingsintervall 0, följ programmets val") \ + DRI_CONF_ENUM(2,"Initialt växlingsintervall 1, följ programmets val") \ + DRI_CONF_ENUM(3,"Synkronisera alltid med vertikal uppdatering, programmet väljer den minsta växlingsintervallen") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_HYPERZ_DISABLED 0 +#define DRI_CONF_HYPERZ_ENABLED 1 +#define DRI_CONF_HYPERZ(def) \ +DRI_CONF_OPT_BEGIN(hyperz,bool,def) \ + DRI_CONF_DESC(en,"Use HyperZ to boost performance") \ + DRI_CONF_DESC(de,"HyperZ zur Leistungssteigerung verwenden") \ + DRI_CONF_DESC(es,"Usar HyperZ para potenciar rendimiento") \ + DRI_CONF_DESC(nl,"Gebruik HyperZ om de prestaties te verbeteren") \ + DRI_CONF_DESC(fr,"Utiliser le HyperZ pour améliorer les performances") \ + DRI_CONF_DESC(sv,"Använd HyperZ för att maximera prestandan") \ +DRI_CONF_OPT_END + +#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \ +DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \ + DRI_CONF_DESC(en,"Number of texture units used") \ + DRI_CONF_DESC(de,"Anzahl der benutzten Textureinheiten") \ + DRI_CONF_DESC(es,"Número de unidades de textura usadas") \ + DRI_CONF_DESC(nl,"Aantal textuureenheden in gebruik") \ + DRI_CONF_DESC(fr,"Nombre d'unités de texture") \ + DRI_CONF_DESC(sv,"Antal använda texturenheter") \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALLOW_LARGE_TEXTURES(def) \ +DRI_CONF_OPT_BEGIN_V(allow_large_textures,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Support larger textures not guaranteed to fit into graphics memory") \ + DRI_CONF_ENUM(0,"No") \ + DRI_CONF_ENUM(1,"At least 1 texture must fit under worst-case assumptions") \ + DRI_CONF_ENUM(2,"Announce hardware limits") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Unterstütze grosse Texturen die evtl. nicht in den Grafikspeicher passen") \ + DRI_CONF_ENUM(0,"Nein") \ + DRI_CONF_ENUM(1,"Mindestens 1 Textur muss auch im schlechtesten Fall Platz haben") \ + DRI_CONF_ENUM(2,"Benutze Hardware-Limits") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Support larger textures not guaranteed to fit into graphics memory") \ + DRI_CONF_ENUM(0,"No") \ + DRI_CONF_ENUM(1,"At least 1 texture must fit under worst-case assumptions") \ + DRI_CONF_ENUM(2,"Announce hardware limits") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Support larger textures not guaranteed to fit into graphics memory") \ + DRI_CONF_ENUM(0,"No") \ + DRI_CONF_ENUM(1,"At least 1 texture must fit under worst-case assumptions") \ + DRI_CONF_ENUM(2,"Announce hardware limits") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Support larger textures not guaranteed to fit into graphics memory") \ + DRI_CONF_ENUM(0,"No") \ + DRI_CONF_ENUM(1,"At least 1 texture must fit under worst-case assumptions") \ + DRI_CONF_ENUM(2,"Announce hardware limits") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Stöd för större texturer är inte garanterat att passa i grafikminnet") \ + DRI_CONF_ENUM(0,"Nej") \ + DRI_CONF_ENUM(1,"Åtminstone en textur måste passa för antaget sämsta förhållande") \ + DRI_CONF_ENUM(2,"Annonsera hårdvarubegränsningar") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \ +DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \ + DRI_CONF_DESC(en,"Texture filtering quality vs. speed, AKA “brilinear” texture filtering") \ + DRI_CONF_DESC(de,"Texturfilterqualität versus -geschwindigkeit, auch bekannt als „brilineare“ Texturfilterung") \ + DRI_CONF_DESC(es,"Calidad de filtrado de textura vs. velocidad, alias filtrado ”brilinear“ de textura") \ + DRI_CONF_DESC(nl,"Textuurfilterkwaliteit versus -snelheid, ookwel bekend als “brilineaire” textuurfiltering") \ + DRI_CONF_DESC(fr,"Qualité/performance du filtrage trilinéaire de texture (filtrage brilinéaire)") \ + DRI_CONF_DESC(sv,"Texturfiltreringskvalitet mot hastighet, även kallad ”brilinear”-texturfiltrering") \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_HEAPS_ALL 0 +#define DRI_CONF_TEXTURE_HEAPS_CARD 1 +#define DRI_CONF_TEXTURE_HEAPS_GART 2 +#define DRI_CONF_TEXTURE_HEAPS(def) \ +DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,"Used types of texture memory") \ + DRI_CONF_ENUM(0,"All available memory") \ + DRI_CONF_ENUM(1,"Only card memory (if available)") \ + DRI_CONF_ENUM(2,"Only GART (AGP/PCIE) memory (if available)") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(de,"Benutzte Arten von Texturspeicher") \ + DRI_CONF_ENUM(0,"Aller verfügbarer Speicher") \ + DRI_CONF_ENUM(1,"Nur Grafikspeicher (falls verfügbar)") \ + DRI_CONF_ENUM(2,"Nur GART-Speicher (AGP/PCIE) (falls verfügbar)") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(es,"Tipos de memoria de textura usados") \ + DRI_CONF_ENUM(0,"Toda la memoria disponible") \ + DRI_CONF_ENUM(1,"Sólo la memoria de la tarjeta (si disponible)") \ + DRI_CONF_ENUM(2,"Sólo memoria GART (AGP/PCIE) (si disponible)") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(nl,"Gebruikte soorten textuurgeheugen") \ + DRI_CONF_ENUM(0,"Al het beschikbaar geheugen") \ + DRI_CONF_ENUM(1,"Alleen geheugen op de kaart (als het aanwezig is)") \ + DRI_CONF_ENUM(2,"Alleen GART (AGP/PCIE) geheugen (als het aanwezig is)") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(fr,"Types de mémoire de texture") \ + DRI_CONF_ENUM(0,"Utiliser toute la mémoire disponible") \ + DRI_CONF_ENUM(1,"Utiliser uniquement la mémoire graphique (si disponible)") \ + DRI_CONF_ENUM(2,"Utiliser uniquement la mémoire GART (AGP/PCIE) (si disponible)") \ + DRI_CONF_DESC_END \ + DRI_CONF_DESC_BEGIN(sv,"Använda typer av texturminne") \ + DRI_CONF_ENUM(0,"Allt tillgängligt minne") \ + DRI_CONF_ENUM(1,"Endast kortminne (om tillgängligt)") \ + DRI_CONF_ENUM(2,"Endast GART-minne (AGP/PCIE) (om tillgängligt)") \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +/* Options for features that are not done in hardware by the driver (like GL_ARB_vertex_program + On cards where there is no documentation (r200) or on rasterization-only hardware). */ +#define DRI_CONF_SECTION_SOFTWARE \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,"Features that are not hardware-accelerated") \ + DRI_CONF_DESC(de,"Funktionalität, die nicht hardwarebeschleunigt ist") \ + DRI_CONF_DESC(es,"Características no aceleradas por hardware") \ + DRI_CONF_DESC(nl,"Eigenschappen die niet hardwareversneld zijn") \ + DRI_CONF_DESC(fr,"Fonctionnalités ne bénéficiant pas d'une accélération matérielle") \ + DRI_CONF_DESC(sv,"Funktioner som inte är hårdvaruaccelererade") + +#define DRI_CONF_ARB_VERTEX_PROGRAM(def) \ +DRI_CONF_OPT_BEGIN(arb_vertex_program,bool,def) \ + DRI_CONF_DESC(en,"Enable extension GL_ARB_vertex_program") \ + DRI_CONF_DESC(de,"Erweiterung GL_ARB_vertex_program aktivieren") \ + DRI_CONF_DESC(es,"Activar la extensión GL_ARB_vertex_program") \ + DRI_CONF_DESC(nl,"Zet uitbreiding GL_ARB_vertex_program aan") \ + DRI_CONF_DESC(fr,"Activer l'extension GL_ARB_vertex_program") \ + DRI_CONF_DESC(sv,"Aktivera tillägget GL_ARB_vertex_program") \ +DRI_CONF_OPT_END + +#define DRI_CONF_NV_VERTEX_PROGRAM(def) \ +DRI_CONF_OPT_BEGIN(nv_vertex_program,bool,def) \ + DRI_CONF_DESC(en,"Enable extension GL_NV_vertex_program") \ + DRI_CONF_DESC(de,"Erweiterung GL_NV_vertex_program aktivieren") \ + DRI_CONF_DESC(es,"Activar extensión GL_NV_vertex_program") \ + DRI_CONF_DESC(nl,"Zet uitbreiding GL_NV_vertex_program aan") \ + DRI_CONF_DESC(fr,"Activer l'extension GL_NV_vertex_program") \ + DRI_CONF_DESC(sv,"Aktivera tillägget GL_NV_vertex_program") \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALWAYS_FLUSH_BATCH(def) \ +DRI_CONF_OPT_BEGIN(always_flush_batch,bool,def) \ + DRI_CONF_DESC(en,"Enable flushing batchbuffer after each draw call") \ + DRI_CONF_DESC(de,"Enable flushing batchbuffer after each draw call") \ + DRI_CONF_DESC(es,"Enable flushing batchbuffer after each draw call") \ + DRI_CONF_DESC(nl,"Enable flushing batchbuffer after each draw call") \ + DRI_CONF_DESC(fr,"Enable flushing batchbuffer after each draw call") \ + DRI_CONF_DESC(sv,"Enable flushing batchbuffer after each draw call") \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALWAYS_FLUSH_CACHE(def) \ +DRI_CONF_OPT_BEGIN(always_flush_cache,bool,def) \ + DRI_CONF_DESC(en,"Enable flushing GPU caches with each draw call") \ + DRI_CONF_DESC(de,"Enable flushing GPU caches with each draw call") \ + DRI_CONF_DESC(es,"Enable flushing GPU caches with each draw call") \ + DRI_CONF_DESC(nl,"Enable flushing GPU caches with each draw call") \ + DRI_CONF_DESC(fr,"Enable flushing GPU caches with each draw call") \ + DRI_CONF_DESC(sv,"Enable flushing GPU caches with each draw call") \ +DRI_CONF_OPT_END diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/sv.po b/mesalib/src/mesa/drivers/dri/common/xmlpool/sv.po new file mode 100644 index 000000000..ba32b2ff1 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/sv.po @@ -0,0 +1,226 @@ +# Swedish translation of DRI driver options. +# Copyright (C) Free Software Foundation, Inc. +# This file is distributed under the same license as the Mesa package. +# Daniel Nylander <po@danielnylander.se>, 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: Mesa DRI\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-04-11 23:19+0200\n" +"PO-Revision-Date: 2006-09-18 10:56+0100\n" +"Last-Translator: Daniel Nylander <po@danielnylander.se>\n" +"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: t_options.h:53 +msgid "Debugging" +msgstr "Felsökning" + +#: t_options.h:57 +msgid "Disable 3D acceleration" +msgstr "Inaktivera 3D-accelerering" + +#: t_options.h:62 +msgid "Show performance boxes" +msgstr "Visa prestandarutor" + +#: t_options.h:69 +msgid "Image Quality" +msgstr "Bildkvalitet" + +#: t_options.h:77 +msgid "Texture color depth" +msgstr "Färgdjup för texturer" + +#: t_options.h:78 +msgid "Prefer frame buffer color depth" +msgstr "Föredra färgdjupet för framebuffer" + +#: t_options.h:79 +msgid "Prefer 32 bits per texel" +msgstr "Föredra 32 bitar per texel" + +#: t_options.h:80 +msgid "Prefer 16 bits per texel" +msgstr "Föredra 16 bitar per texel" + +#: t_options.h:81 +msgid "Force 16 bits per texel" +msgstr "Tvinga 16 bitar per texel" + +#: t_options.h:87 +msgid "Initial maximum value for anisotropic texture filtering" +msgstr "Initialt maximalt värde för anisotropisk texturfiltrering" + +#: t_options.h:92 +msgid "Forbid negative texture LOD bias" +msgstr "Förbjud negativ LOD-kompensation för texturer" + +#: t_options.h:97 +msgid "Enable S3TC texture compression even if software support is not available" +msgstr "Aktivera S3TC-texturkomprimering även om programvarustöd saknas" + +#: t_options.h:104 +msgid "Initial color reduction method" +msgstr "Initial färgminskningsmetod" + +#: t_options.h:105 +msgid "Round colors" +msgstr "Avrunda färger" + +#: t_options.h:106 +msgid "Dither colors" +msgstr "Utjämna färger" + +#: t_options.h:114 +msgid "Color rounding method" +msgstr "Färgavrundningsmetod" + +#: t_options.h:115 +msgid "Round color components downward" +msgstr "Avrunda färdkomponenter nedåt" + +#: t_options.h:116 +msgid "Round to nearest color" +msgstr "Avrunda till närmsta färg" + +#: t_options.h:125 +msgid "Color dithering method" +msgstr "Färgutjämningsmetod" + +#: t_options.h:126 +msgid "Horizontal error diffusion" +msgstr "Horisontell felspridning" + +#: t_options.h:127 +msgid "Horizontal error diffusion, reset error at line start" +msgstr "Horisontell felspridning, återställ fel vid radbörjan" + +#: t_options.h:128 +msgid "Ordered 2D color dithering" +msgstr "Ordnad 2D-färgutjämning" + +#: t_options.h:134 +msgid "Floating point depth buffer" +msgstr "Buffert för flytande punktdjup" + +#: t_options.h:140 +msgid "Performance" +msgstr "Prestanda" + +#: t_options.h:148 +msgid "TCL mode (Transformation, Clipping, Lighting)" +msgstr "TCL-läge (Transformation, Clipping, Lighting)" + +#: t_options.h:149 +msgid "Use software TCL pipeline" +msgstr "Använd programvaru-TCL-rörledning" + +#: t_options.h:150 +msgid "Use hardware TCL as first TCL pipeline stage" +msgstr "Använd maskinvaru-TCL som första TCL-rörledningssteg" + +#: t_options.h:151 +msgid "Bypass the TCL pipeline" +msgstr "Kringgå TCL-rörledningen" + +#: t_options.h:152 +msgid "Bypass the TCL pipeline with state-based machine code generated on-the-fly" +msgstr "Kringgå TCL-rörledningen med tillståndsbaserad maskinkod som direktgenereras" + +#: t_options.h:161 +msgid "Method to limit rendering latency" +msgstr "Metod för att begränsa renderingslatens" + +#: t_options.h:162 +msgid "Busy waiting for the graphics hardware" +msgstr "Upptagen med att vänta på grafikhårdvaran" + +#: t_options.h:163 +msgid "Sleep for brief intervals while waiting for the graphics hardware" +msgstr "Sov i korta intervall under väntan på grafikhårdvaran" + +#: t_options.h:164 +msgid "Let the graphics hardware emit a software interrupt and sleep" +msgstr "Låt grafikhårdvaran sända ut ett programvaruavbrott och sov" + +#: t_options.h:174 +msgid "Synchronization with vertical refresh (swap intervals)" +msgstr "Synkronisering med vertikal uppdatering (växlingsintervall)" + +#: t_options.h:175 +msgid "Never synchronize with vertical refresh, ignore application's choice" +msgstr "Synkronisera aldrig med vertikal uppdatering, ignorera programmets val" + +#: t_options.h:176 +msgid "Initial swap interval 0, obey application's choice" +msgstr "Initialt växlingsintervall 0, följ programmets val" + +#: t_options.h:177 +msgid "Initial swap interval 1, obey application's choice" +msgstr "Initialt växlingsintervall 1, följ programmets val" + +#: t_options.h:178 +msgid "Always synchronize with vertical refresh, application chooses the minimum swap interval" +msgstr "Synkronisera alltid med vertikal uppdatering, programmet väljer den minsta växlingsintervallen" + +#: t_options.h:186 +msgid "Use HyperZ to boost performance" +msgstr "Använd HyperZ för att maximera prestandan" + +#: t_options.h:191 +msgid "Number of texture units used" +msgstr "Antal använda texturenheter" + +#: t_options.h:196 +msgid "Support larger textures not guaranteed to fit into graphics memory" +msgstr "Stöd för större texturer är inte garanterat att passa i grafikminnet" + +#: t_options.h:197 +msgid "No" +msgstr "Nej" + +#: t_options.h:198 +msgid "At least 1 texture must fit under worst-case assumptions" +msgstr "Åtminstone en textur måste passa för antaget sämsta förhållande" + +#: t_options.h:199 +msgid "Announce hardware limits" +msgstr "Annonsera hårdvarubegränsningar" + +#: t_options.h:205 +msgid "Texture filtering quality vs. speed, AKA “brilinear” texture filtering" +msgstr "Texturfiltreringskvalitet mot hastighet, även kallad \"brilinear\"-texturfiltrering" + +#: t_options.h:213 +msgid "Used types of texture memory" +msgstr "Använda typer av texturminne" + +#: t_options.h:214 +msgid "All available memory" +msgstr "Allt tillgängligt minne" + +#: t_options.h:215 +msgid "Only card memory (if available)" +msgstr "Endast kortminne (om tillgängligt)" + +#: t_options.h:216 +msgid "Only GART (AGP/PCIE) memory (if available)" +msgstr "Endast GART-minne (AGP/PCIE) (om tillgängligt)" + +#: t_options.h:224 +msgid "Features that are not hardware-accelerated" +msgstr "Funktioner som inte är hårdvaruaccelererade" + +#: t_options.h:228 +msgid "Enable extension GL_ARB_vertex_program" +msgstr "Aktivera tillägget GL_ARB_vertex_program" + +#: t_options.h:233 +msgid "Enable extension GL_NV_vertex_program" +msgstr "Aktivera tillägget GL_NV_vertex_program" + diff --git a/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h new file mode 100644 index 000000000..5fd6ec65b --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/xmlpool/t_options.h @@ -0,0 +1,249 @@ +/* + * XML DRI client-side driver configuration + * Copyright (C) 2003 Felix Kuehling + * + * 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 + * FELIX KUEHLING, OR ANY OTHER CONTRIBUTORS 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 t_options.h + * \brief Templates of common options + * \author Felix Kuehling + * + * This file defines macros for common options that can be used to + * construct driConfigOptions in the drivers. This file is only a + * template containing English descriptions for options wrapped in + * gettext(). xgettext can be used to extract translatable + * strings. These strings can then be translated by anyone familiar + * with GNU gettext. gen_xmlpool.py takes this template and fills in + * all the translations. The result (options.h) is included by + * xmlpool.h which in turn can be included by drivers. + * + * The macros used to describe otions in this file are defined in + * ../xmlpool.h. + */ + +/* This is needed for xgettext to extract translatable strings. + * gen_xmlpool.py will discard this line. */ +#include <libintl.h> + +/* + * predefined option sections and options with multi-lingual descriptions + */ + +/** \brief Debugging options */ +#define DRI_CONF_SECTION_DEBUG \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,gettext("Debugging")) + +#define DRI_CONF_NO_RAST(def) \ +DRI_CONF_OPT_BEGIN(no_rast,bool,def) \ + DRI_CONF_DESC(en,gettext("Disable 3D acceleration")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_PERFORMANCE_BOXES(def) \ +DRI_CONF_OPT_BEGIN(performance_boxes,bool,def) \ + DRI_CONF_DESC(en,gettext("Show performance boxes")) \ +DRI_CONF_OPT_END + + +/** \brief Texture-related options */ +#define DRI_CONF_SECTION_QUALITY \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,gettext("Image Quality")) + +#define DRI_CONF_EXCESS_MIPMAP(def) \ +DRI_CONF_OPT_BEGIN(excess_mipmap,bool,def) \ + DRI_CONF_DESC(en,"Enable extra mipmap level") \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_DEPTH_FB 0 +#define DRI_CONF_TEXTURE_DEPTH_32 1 +#define DRI_CONF_TEXTURE_DEPTH_16 2 +#define DRI_CONF_TEXTURE_DEPTH_FORCE_16 3 +#define DRI_CONF_TEXTURE_DEPTH(def) \ +DRI_CONF_OPT_BEGIN_V(texture_depth,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,gettext("Texture color depth")) \ + DRI_CONF_ENUM(0,gettext("Prefer frame buffer color depth")) \ + DRI_CONF_ENUM(1,gettext("Prefer 32 bits per texel")) \ + DRI_CONF_ENUM(2,gettext("Prefer 16 bits per texel")) \ + DRI_CONF_ENUM(3,gettext("Force 16 bits per texel")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_DEF_MAX_ANISOTROPY(def,range) \ +DRI_CONF_OPT_BEGIN_V(def_max_anisotropy,float,def,range) \ + DRI_CONF_DESC(en,gettext("Initial maximum value for anisotropic texture filtering")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_NO_NEG_LOD_BIAS(def) \ +DRI_CONF_OPT_BEGIN(no_neg_lod_bias,bool,def) \ + DRI_CONF_DESC(en,gettext("Forbid negative texture LOD bias")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_FORCE_S3TC_ENABLE(def) \ +DRI_CONF_OPT_BEGIN(force_s3tc_enable,bool,def) \ + DRI_CONF_DESC(en,gettext("Enable S3TC texture compression even if software support is not available")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_COLOR_REDUCTION_ROUND 0 +#define DRI_CONF_COLOR_REDUCTION_DITHER 1 +#define DRI_CONF_COLOR_REDUCTION(def) \ +DRI_CONF_OPT_BEGIN_V(color_reduction,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,gettext("Initial color reduction method")) \ + DRI_CONF_ENUM(0,gettext("Round colors")) \ + DRI_CONF_ENUM(1,gettext("Dither colors")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_ROUND_TRUNC 0 +#define DRI_CONF_ROUND_ROUND 1 +#define DRI_CONF_ROUND_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(round_mode,enum,def,"0:1") \ + DRI_CONF_DESC_BEGIN(en,gettext("Color rounding method")) \ + DRI_CONF_ENUM(0,gettext("Round color components downward")) \ + DRI_CONF_ENUM(1,gettext("Round to nearest color")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_DITHER_XERRORDIFF 0 +#define DRI_CONF_DITHER_XERRORDIFFRESET 1 +#define DRI_CONF_DITHER_ORDERED 2 +#define DRI_CONF_DITHER_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(dither_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,gettext("Color dithering method")) \ + DRI_CONF_ENUM(0,gettext("Horizontal error diffusion")) \ + DRI_CONF_ENUM(1,gettext("Horizontal error diffusion, reset error at line start")) \ + DRI_CONF_ENUM(2,gettext("Ordered 2D color dithering")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_FLOAT_DEPTH(def) \ +DRI_CONF_OPT_BEGIN(float_depth,bool,def) \ + DRI_CONF_DESC(en,gettext("Floating point depth buffer")) \ +DRI_CONF_OPT_END + +/** \brief Performance-related options */ +#define DRI_CONF_SECTION_PERFORMANCE \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,gettext("Performance")) + +#define DRI_CONF_TCL_SW 0 +#define DRI_CONF_TCL_PIPELINED 1 +#define DRI_CONF_TCL_VTXFMT 2 +#define DRI_CONF_TCL_CODEGEN 3 +#define DRI_CONF_TCL_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(tcl_mode,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,gettext("TCL mode (Transformation, Clipping, Lighting)")) \ + DRI_CONF_ENUM(0,gettext("Use software TCL pipeline")) \ + DRI_CONF_ENUM(1,gettext("Use hardware TCL as first TCL pipeline stage")) \ + DRI_CONF_ENUM(2,gettext("Bypass the TCL pipeline")) \ + DRI_CONF_ENUM(3,gettext("Bypass the TCL pipeline with state-based machine code generated on-the-fly")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_FTHROTTLE_BUSY 0 +#define DRI_CONF_FTHROTTLE_USLEEPS 1 +#define DRI_CONF_FTHROTTLE_IRQS 2 +#define DRI_CONF_FTHROTTLE_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(fthrottle_mode,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,gettext("Method to limit rendering latency")) \ + DRI_CONF_ENUM(0,gettext("Busy waiting for the graphics hardware")) \ + DRI_CONF_ENUM(1,gettext("Sleep for brief intervals while waiting for the graphics hardware")) \ + DRI_CONF_ENUM(2,gettext("Let the graphics hardware emit a software interrupt and sleep")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_VBLANK_NEVER 0 +#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 +#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 +#define DRI_CONF_VBLANK_ALWAYS_SYNC 3 +#define DRI_CONF_VBLANK_MODE(def) \ +DRI_CONF_OPT_BEGIN_V(vblank_mode,enum,def,"0:3") \ + DRI_CONF_DESC_BEGIN(en,gettext("Synchronization with vertical refresh (swap intervals)")) \ + DRI_CONF_ENUM(0,gettext("Never synchronize with vertical refresh, ignore application's choice")) \ + DRI_CONF_ENUM(1,gettext("Initial swap interval 0, obey application's choice")) \ + DRI_CONF_ENUM(2,gettext("Initial swap interval 1, obey application's choice")) \ + DRI_CONF_ENUM(3,gettext("Always synchronize with vertical refresh, application chooses the minimum swap interval")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_HYPERZ_DISABLED 0 +#define DRI_CONF_HYPERZ_ENABLED 1 +#define DRI_CONF_HYPERZ(def) \ +DRI_CONF_OPT_BEGIN(hyperz,bool,def) \ + DRI_CONF_DESC(en,gettext("Use HyperZ to boost performance")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_MAX_TEXTURE_UNITS(def,min,max) \ +DRI_CONF_OPT_BEGIN_V(texture_units,int,def, # min ":" # max ) \ + DRI_CONF_DESC(en,gettext("Number of texture units used")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALLOW_LARGE_TEXTURES(def) \ +DRI_CONF_OPT_BEGIN_V(allow_large_textures,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,gettext("Support larger textures not guaranteed to fit into graphics memory")) \ + DRI_CONF_ENUM(0,gettext("No")) \ + DRI_CONF_ENUM(1,gettext("At least 1 texture must fit under worst-case assumptions")) \ + DRI_CONF_ENUM(2,gettext("Announce hardware limits")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_BLEND_QUALITY(def,range) \ +DRI_CONF_OPT_BEGIN_V(texture_blend_quality,float,def,range) \ + DRI_CONF_DESC(en,gettext("Texture filtering quality vs. speed, AKA “brilinear” texture filtering")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_TEXTURE_HEAPS_ALL 0 +#define DRI_CONF_TEXTURE_HEAPS_CARD 1 +#define DRI_CONF_TEXTURE_HEAPS_GART 2 +#define DRI_CONF_TEXTURE_HEAPS(def) \ +DRI_CONF_OPT_BEGIN_V(texture_heaps,enum,def,"0:2") \ + DRI_CONF_DESC_BEGIN(en,gettext("Used types of texture memory")) \ + DRI_CONF_ENUM(0,gettext("All available memory")) \ + DRI_CONF_ENUM(1,gettext("Only card memory (if available)")) \ + DRI_CONF_ENUM(2,gettext("Only GART (AGP/PCIE) memory (if available)")) \ + DRI_CONF_DESC_END \ +DRI_CONF_OPT_END + +/* Options for features that are not done in hardware by the driver (like GL_ARB_vertex_program + On cards where there is no documentation (r200) or on rasterization-only hardware). */ +#define DRI_CONF_SECTION_SOFTWARE \ +DRI_CONF_SECTION_BEGIN \ + DRI_CONF_DESC(en,gettext("Features that are not hardware-accelerated")) + +#define DRI_CONF_ARB_VERTEX_PROGRAM(def) \ +DRI_CONF_OPT_BEGIN(arb_vertex_program,bool,def) \ + DRI_CONF_DESC(en,gettext("Enable extension GL_ARB_vertex_program")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_NV_VERTEX_PROGRAM(def) \ +DRI_CONF_OPT_BEGIN(nv_vertex_program,bool,def) \ + DRI_CONF_DESC(en,gettext("Enable extension GL_NV_vertex_program")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALWAYS_FLUSH_BATCH(def) \ +DRI_CONF_OPT_BEGIN(always_flush_batch,bool,def) \ + DRI_CONF_DESC(en,gettext("Enable flushing batchbuffer after each draw call")) \ +DRI_CONF_OPT_END + +#define DRI_CONF_ALWAYS_FLUSH_CACHE(def) \ +DRI_CONF_OPT_BEGIN(always_flush_cache,bool,def) \ + DRI_CONF_DESC(en,gettext("Enable flushing GPU caches with each draw call")) \ +DRI_CONF_OPT_END diff --git a/mesalib/src/mesa/drivers/dri/dri.pc.in b/mesalib/src/mesa/drivers/dri/dri.pc.in new file mode 100644 index 000000000..695aa6cfd --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/dri.pc.in @@ -0,0 +1,11 @@ +prefix=@INSTALL_DIR@ +exec_prefix=${prefix} +libdir=@INSTALL_LIB_DIR@ +includedir=@INSTALL_INC_DIR@ +dridriverdir=@DRI_DRIVER_DIR@ + +Name: dri +Description: Direct Rendering Infrastructure +Version: @VERSION@ +Requires.private: @DRI_PC_REQ_PRIV@ +Cflags: -I${includedir} diff --git a/mesalib/src/mesa/drivers/dri/swrast/Makefile b/mesalib/src/mesa/drivers/dri/swrast/Makefile new file mode 100644 index 000000000..5f3a4f219 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/swrast/Makefile @@ -0,0 +1,24 @@ +# src/mesa/drivers/dri/swrast/Makefile + +TOP = ../../../../.. +include $(TOP)/configs/current + +LIBNAME = swrast_dri.so + +DRIVER_SOURCES = \ + swrast.c \ + swrast_span.c + +C_SOURCES = \ + $(SWRAST_COMMON_SOURCES) \ + $(DRIVER_SOURCES) + +ASM_SOURCES = + +SWRAST_COMMON_SOURCES = \ + ../../common/driverfuncs.c \ + ../common/utils.c + +include ../Makefile.template + +symlinks: diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c new file mode 100644 index 000000000..a858af30c --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -0,0 +1,754 @@ +/* + * Copyright (C) 2008 George Sapountzis <gsap7@yahoo.gr> + * + * 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 + * BRIAN PAUL 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. + */ + +/* + * DRI software rasterizer + * + * This is the mesa swrast module packaged into a DRI driver structure. + * + * The front-buffer is allocated by the loader. The loader provides read/write + * callbacks for access to the front-buffer. The driver uses a scratch row for + * front-buffer rendering to avoid repeated calls to the loader. + * + * The back-buffer is allocated by the driver and is private. + */ + +#include "main/context.h" +#include "main/extensions.h" +#include "main/framebuffer.h" +#include "main/imports.h" +#include "main/renderbuffer.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "vbo/vbo.h" +#include "drivers/common/driverfuncs.h" +#include "utils.h" + +#include "swrast_priv.h" + + +#define need_GL_VERSION_1_3 +#define need_GL_VERSION_1_4 +#define need_GL_VERSION_1_5 +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 + +/* sw extensions for imaging */ +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_convolution +#define need_GL_EXT_histogram +#define need_GL_SGI_color_table + +/* sw extensions not associated with some GL version */ +#define need_GL_ARB_shader_objects +#define need_GL_ARB_vertex_array_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_sync +#define need_GL_APPLE_vertex_array_object +#define need_GL_ATI_fragment_shader +#define need_GL_ATI_separate_stencil +#define need_GL_EXT_depth_bounds_test +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_framebuffer_blit +#define need_GL_EXT_gpu_program_parameters +#define need_GL_EXT_paletted_texture +#define need_GL_EXT_stencil_two_side +#define need_GL_MESA_resize_buffers +#define need_GL_NV_vertex_program +#define need_GL_NV_fragment_program + +#include "extension_helper.h" + +const struct dri_extension card_extensions[] = +{ + { "GL_VERSION_1_3", GL_VERSION_1_3_functions }, + { "GL_VERSION_1_4", GL_VERSION_1_4_functions }, + { "GL_VERSION_1_5", GL_VERSION_1_5_functions }, + { "GL_VERSION_2_0", GL_VERSION_2_0_functions }, + { "GL_VERSION_2_1", GL_VERSION_2_1_functions }, + + { "GL_EXT_blend_color", GL_EXT_blend_color_functions }, + { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions }, + { "GL_EXT_convolution", GL_EXT_convolution_functions }, + { "GL_EXT_histogram", GL_EXT_histogram_functions }, + { "GL_SGI_color_table", GL_SGI_color_table_functions }, + + { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions }, + { "GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions }, + { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions }, + { "GL_ARB_sync", GL_ARB_sync_functions }, + { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions }, + { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions }, + { "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions }, + { "GL_EXT_depth_bounds_test", GL_EXT_depth_bounds_test_functions }, + { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions }, + { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions }, + { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions }, + { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions }, + { "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions }, + { "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions }, + { "GL_NV_vertex_program", GL_NV_vertex_program_functions }, + { "GL_NV_fragment_program", GL_NV_fragment_program_functions }, + { NULL, NULL } +}; + + +/** + * Screen and config-related functions + */ + +static void +setupLoaderExtensions(__DRIscreen *psp, + const __DRIextension **extensions) +{ + int i; + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_SWRAST_LOADER) == 0) + psp->swrast_loader = (__DRIswrastLoaderExtension *) extensions[i]; + } +} + +static __DRIconfig ** +swrastFillInModes(__DRIscreen *psp, + unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __DRIconfig **configs; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + + /* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't + * support pageflipping at all. + */ + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML + }; + + uint8_t depth_bits_array[4]; + uint8_t stencil_bits_array[4]; + uint8_t msaa_samples_array[1]; + + depth_bits_array[0] = 0; + depth_bits_array[1] = 0; + depth_bits_array[2] = depth_bits; + depth_bits_array[3] = depth_bits; + + /* Just like with the accumulation buffer, always provide some modes + * with a stencil buffer. + */ + stencil_bits_array[0] = 0; + stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits; + stencil_bits_array[2] = 0; + stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits; + + msaa_samples_array[0] = 0; + + depth_buffer_factor = 4; + back_buffer_factor = 2; + + switch (pixel_bits) { + case 8: + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_BYTE_2_3_3_REV; + break; + case 16: + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + break; + case 24: + fb_format = GL_BGR; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case 32: + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + break; + default: + fprintf(stderr, "[%s:%u] bad depth %d\n", __func__, __LINE__, + pixel_bits); + return NULL; + } + + configs = driCreateConfigs(fb_format, fb_type, + depth_bits_array, stencil_bits_array, + depth_buffer_factor, back_buffer_modes, + back_buffer_factor, msaa_samples_array, 1); + if (configs == NULL) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, + __LINE__); + return NULL; + } + + return configs; +} + +static __DRIscreen * +driCreateNewScreen(int scrn, const __DRIextension **extensions, + const __DRIconfig ***driver_configs, void *data) +{ + static const __DRIextension *emptyExtensionList[] = { NULL }; + __DRIscreen *psp; + __DRIconfig **configs8, **configs16, **configs24, **configs32; + + (void) data; + + TRACE; + + psp = _mesa_calloc(sizeof(*psp)); + if (!psp) + return NULL; + + setupLoaderExtensions(psp, extensions); + + psp->num = scrn; + psp->extensions = emptyExtensionList; + + configs8 = swrastFillInModes(psp, 8, 8, 0, 1); + configs16 = swrastFillInModes(psp, 16, 16, 0, 1); + configs24 = swrastFillInModes(psp, 24, 24, 8, 1); + configs32 = swrastFillInModes(psp, 32, 24, 8, 1); + + configs16 = driConcatConfigs(configs8, configs16); + configs24 = driConcatConfigs(configs16, configs24); + *driver_configs = (const __DRIconfig **) + driConcatConfigs(configs24, configs32); + + driInitExtensions( NULL, card_extensions, GL_FALSE ); + + return psp; +} + +static void driDestroyScreen(__DRIscreen *psp) +{ + TRACE; + + if (psp) { + _mesa_free(psp); + } +} + +static const __DRIextension **driGetExtensions(__DRIscreen *psp) +{ + TRACE; + + return psp->extensions; +} + + +/** + * Framebuffer and renderbuffer-related functions. + */ + +static GLuint +choose_pixel_format(const GLvisual *v) +{ + if (v->rgbMode) { + int depth = v->rgbBits; + + if (depth == 32 + && v->redMask == 0xff0000 + && v->greenMask == 0x00ff00 + && v->blueMask == 0x0000ff) + return PF_A8R8G8B8; + else if (depth == 24 + && v->redMask == 0xff0000 + && v->greenMask == 0x00ff00 + && v->blueMask == 0x0000ff) + return PF_X8R8G8B8; + else if (depth == 16 + && v->redMask == 0xf800 + && v->greenMask == 0x07e0 + && v->blueMask == 0x001f) + return PF_R5G6B5; + else if (depth == 8 + && v->redMask == 0x07 + && v->greenMask == 0x38 + && v->blueMask == 0xc0) + return PF_R3G3B2; + } + else { + if (v->indexBits == 8) + return PF_CI8; + } + + _mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ ); + return 0; +} + +static void +swrast_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + TRACE; + + _mesa_free(rb->Data); + _mesa_free(rb); +} + +static GLboolean +swrast_alloc_front_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); + unsigned mask = PITCH_ALIGN_BITS - 1; + + TRACE; + + rb->Data = NULL; + rb->Width = width; + rb->Height = height; + + /* always pad to PITCH_ALIGN_BITS */ + xrb->pitch = ((width * xrb->bpp + mask) & ~mask) / 8; + + return GL_TRUE; +} + +static GLboolean +swrast_alloc_back_storage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); + + TRACE; + + _mesa_free(rb->Data); + + swrast_alloc_front_storage(ctx, rb, internalFormat, width, height); + + rb->Data = _mesa_malloc(height * xrb->pitch); + + return GL_TRUE; +} + +static struct swrast_renderbuffer * +swrast_new_renderbuffer(const GLvisual *visual, GLboolean front) +{ + struct swrast_renderbuffer *xrb = _mesa_calloc(sizeof *xrb); + GLuint pixel_format; + + TRACE; + + if (!xrb) + return NULL; + + _mesa_init_renderbuffer(&xrb->Base, 0); + + pixel_format = choose_pixel_format(visual); + + xrb->Base.Delete = swrast_delete_renderbuffer; + if (front) { + xrb->Base.AllocStorage = swrast_alloc_front_storage; + swrast_set_span_funcs_front(xrb, pixel_format); + } + else { + xrb->Base.AllocStorage = swrast_alloc_back_storage; + swrast_set_span_funcs_back(xrb, pixel_format); + } + + switch (pixel_format) { + case PF_A8R8G8B8: + xrb->Base.InternalFormat = GL_RGBA; + xrb->Base._BaseFormat = GL_RGBA; + xrb->Base.DataType = GL_UNSIGNED_BYTE; + xrb->Base.RedBits = 8 * sizeof(GLubyte); + xrb->Base.GreenBits = 8 * sizeof(GLubyte); + xrb->Base.BlueBits = 8 * sizeof(GLubyte); + xrb->Base.AlphaBits = 8 * sizeof(GLubyte); + xrb->bpp = 32; + break; + case PF_X8R8G8B8: + xrb->Base.InternalFormat = GL_RGB; + xrb->Base._BaseFormat = GL_RGB; + xrb->Base.DataType = GL_UNSIGNED_BYTE; + xrb->Base.RedBits = 8 * sizeof(GLubyte); + xrb->Base.GreenBits = 8 * sizeof(GLubyte); + xrb->Base.BlueBits = 8 * sizeof(GLubyte); + xrb->Base.AlphaBits = 0; + xrb->bpp = 32; + break; + case PF_R5G6B5: + xrb->Base.InternalFormat = GL_RGB; + xrb->Base._BaseFormat = GL_RGB; + xrb->Base.DataType = GL_UNSIGNED_BYTE; + xrb->Base.RedBits = 5 * sizeof(GLubyte); + xrb->Base.GreenBits = 6 * sizeof(GLubyte); + xrb->Base.BlueBits = 5 * sizeof(GLubyte); + xrb->Base.AlphaBits = 0; + xrb->bpp = 16; + break; + case PF_R3G3B2: + xrb->Base.InternalFormat = GL_RGB; + xrb->Base._BaseFormat = GL_RGB; + xrb->Base.DataType = GL_UNSIGNED_BYTE; + xrb->Base.RedBits = 3 * sizeof(GLubyte); + xrb->Base.GreenBits = 3 * sizeof(GLubyte); + xrb->Base.BlueBits = 2 * sizeof(GLubyte); + xrb->Base.AlphaBits = 0; + xrb->bpp = 8; + break; + case PF_CI8: + xrb->Base.InternalFormat = GL_COLOR_INDEX8_EXT; + xrb->Base._BaseFormat = GL_COLOR_INDEX; + xrb->Base.DataType = GL_UNSIGNED_BYTE; + xrb->Base.IndexBits = 8 * sizeof(GLubyte); + xrb->bpp = 8; + break; + default: + return NULL; + } + + return xrb; +} + +static __DRIdrawable * +driCreateNewDrawable(__DRIscreen *screen, + const __DRIconfig *config, void *data) +{ + __DRIdrawable *buf; + struct swrast_renderbuffer *frontrb, *backrb; + + TRACE; + + buf = _mesa_calloc(sizeof *buf); + if (!buf) + return NULL; + + buf->loaderPrivate = data; + + buf->driScreenPriv = screen; + + buf->row = _mesa_malloc(MAX_WIDTH * 4); + + /* basic framebuffer setup */ + _mesa_initialize_framebuffer(&buf->Base, &config->modes); + + /* add front renderbuffer */ + frontrb = swrast_new_renderbuffer(&config->modes, GL_TRUE); + _mesa_add_renderbuffer(&buf->Base, BUFFER_FRONT_LEFT, &frontrb->Base); + + /* add back renderbuffer */ + if (config->modes.doubleBufferMode) { + backrb = swrast_new_renderbuffer(&config->modes, GL_FALSE); + _mesa_add_renderbuffer(&buf->Base, BUFFER_BACK_LEFT, &backrb->Base); + } + + /* add software renderbuffers */ + _mesa_add_soft_renderbuffers(&buf->Base, + GL_FALSE, /* color */ + config->modes.haveDepthBuffer, + config->modes.haveStencilBuffer, + config->modes.haveAccumBuffer, + GL_FALSE, /* alpha */ + GL_FALSE /* aux bufs */); + + return buf; +} + +static void +driDestroyDrawable(__DRIdrawable *buf) +{ + TRACE; + + if (buf) { + struct gl_framebuffer *fb = &buf->Base; + + _mesa_free(buf->row); + + fb->DeletePending = GL_TRUE; + _mesa_reference_framebuffer(&fb, NULL); + } +} + +static void driSwapBuffers(__DRIdrawable *buf) +{ + GET_CURRENT_CONTEXT(ctx); + + struct swrast_renderbuffer *frontrb = + swrast_renderbuffer(buf->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer); + struct swrast_renderbuffer *backrb = + swrast_renderbuffer(buf->Base.Attachment[BUFFER_BACK_LEFT].Renderbuffer); + + __DRIscreen *screen = buf->driScreenPriv; + + TRACE; + + /* check for signle-buffered */ + if (backrb == NULL) + return; + + /* check if swapping currently bound buffer */ + if (ctx && ctx->DrawBuffer == &(buf->Base)) { + /* flush pending rendering */ + _mesa_notifySwapBuffers(ctx); + } + + screen->swrast_loader->putImage(buf, __DRI_SWRAST_IMAGE_OP_SWAP, + 0, 0, + frontrb->Base.Width, + frontrb->Base.Height, + backrb->Base.Data, + buf->loaderPrivate); +} + + +/** + * General device driver functions. + */ + +static void +get_window_size( GLframebuffer *fb, GLsizei *w, GLsizei *h ) +{ + __DRIdrawable *buf = swrast_drawable(fb); + __DRIscreen *screen = buf->driScreenPriv; + int x, y; + + screen->swrast_loader->getDrawableInfo(buf, + &x, &y, w, h, + buf->loaderPrivate); +} + +static void +swrast_check_and_update_window_size( GLcontext *ctx, GLframebuffer *fb ) +{ + GLsizei width, height; + + get_window_size(fb, &width, &height); + if (fb->Width != width || fb->Height != height) { + _mesa_resize_framebuffer(ctx, fb, width, height); + } +} + +static const GLubyte * +get_string(GLcontext *ctx, GLenum pname) +{ + (void) ctx; + switch (pname) { + case GL_VENDOR: + return (const GLubyte *) "Mesa Project"; + case GL_RENDERER: + return (const GLubyte *) "Software Rasterizer"; + default: + return NULL; + } +} + +static void +update_state( GLcontext *ctx, GLuint new_state ) +{ + /* not much to do here - pass it on */ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); +} + +static void +viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + GLframebuffer *draw = ctx->WinSysDrawBuffer; + GLframebuffer *read = ctx->WinSysReadBuffer; + + swrast_check_and_update_window_size(ctx, draw); + swrast_check_and_update_window_size(ctx, read); +} + +static void +swrast_init_driver_functions(struct dd_function_table *driver) +{ + driver->GetString = get_string; + driver->UpdateState = update_state; + driver->GetBufferSize = NULL; + driver->Viewport = viewport; +} + + +/** + * Context-related functions. + */ + +static __DRIcontext * +driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config, + __DRIcontext *shared, void *data) +{ + __DRIcontext *ctx; + GLcontext *mesaCtx; + struct dd_function_table functions; + + TRACE; + + ctx = _mesa_calloc(sizeof *ctx); + if (!ctx) + return NULL; + + ctx->loaderPrivate = data; + + ctx->driScreenPriv = screen; + + /* build table of device driver functions */ + _mesa_init_driver_functions(&functions); + swrast_init_driver_functions(&functions); + + if (!_mesa_initialize_context(&ctx->Base, &config->modes, + shared ? &shared->Base : NULL, + &functions, (void *) ctx)) { + _mesa_free(ctx); + return NULL; + } + + mesaCtx = &ctx->Base; + + /* do bounds checking to prevent segfaults and server crashes! */ + mesaCtx->Const.CheckArrayBounds = GL_TRUE; + + /* create module contexts */ + _swrast_CreateContext( mesaCtx ); + _vbo_CreateContext( mesaCtx ); + _tnl_CreateContext( mesaCtx ); + _swsetup_CreateContext( mesaCtx ); + _swsetup_Wakeup( mesaCtx ); + + /* use default TCL pipeline */ + { + TNLcontext *tnl = TNL_CONTEXT(mesaCtx); + tnl->Driver.RunPipeline = _tnl_run_pipeline; + } + + _mesa_enable_sw_extensions(mesaCtx); + _mesa_enable_1_3_extensions(mesaCtx); + _mesa_enable_1_4_extensions(mesaCtx); + _mesa_enable_1_5_extensions(mesaCtx); + _mesa_enable_2_0_extensions(mesaCtx); + _mesa_enable_2_1_extensions(mesaCtx); + + return ctx; +} + +static void +driDestroyContext(__DRIcontext *ctx) +{ + GLcontext *mesaCtx; + TRACE; + + if (ctx) { + mesaCtx = &ctx->Base; + _swsetup_DestroyContext( mesaCtx ); + _swrast_DestroyContext( mesaCtx ); + _tnl_DestroyContext( mesaCtx ); + _vbo_DestroyContext( mesaCtx ); + _mesa_destroy_context( mesaCtx ); + } +} + +static int +driCopyContext(__DRIcontext *dst, __DRIcontext *src, unsigned long mask) +{ + TRACE; + + _mesa_copy_context(&src->Base, &dst->Base, mask); + return GL_TRUE; +} + +static int driBindContext(__DRIcontext *ctx, + __DRIdrawable *draw, + __DRIdrawable *read) +{ + GLcontext *mesaCtx; + GLframebuffer *mesaDraw; + GLframebuffer *mesaRead; + TRACE; + + if (ctx) { + if (!draw || !read) + return GL_FALSE; + + mesaCtx = &ctx->Base; + mesaDraw = &draw->Base; + mesaRead = &read->Base; + + /* check for same context and buffer */ + if (mesaCtx == _mesa_get_current_context() + && mesaCtx->DrawBuffer == mesaDraw + && mesaCtx->ReadBuffer == mesaRead) { + return GL_TRUE; + } + + _glapi_check_multithread(); + + swrast_check_and_update_window_size(mesaCtx, mesaDraw); + if (read != draw) + swrast_check_and_update_window_size(mesaCtx, mesaRead); + + _mesa_make_current( mesaCtx, + mesaDraw, + mesaRead ); + } + else { + /* unbind */ + _mesa_make_current( NULL, NULL, NULL ); + } + + return GL_TRUE; +} + +static int driUnbindContext(__DRIcontext *ctx) +{ + TRACE; + (void) ctx; + return GL_TRUE; +} + + +static const __DRIcoreExtension driCoreExtension = { + { __DRI_CORE, __DRI_CORE_VERSION }, + NULL, /* driCreateNewScreen */ + driDestroyScreen, + driGetExtensions, + driGetConfigAttrib, + driIndexConfigAttrib, + NULL, /* driCreateNewDrawable */ + driDestroyDrawable, + driSwapBuffers, + driCreateNewContext, + driCopyContext, + driDestroyContext, + driBindContext, + driUnbindContext +}; + +static const __DRIswrastExtension driSWRastExtension = { + { __DRI_SWRAST, __DRI_SWRAST_VERSION }, + driCreateNewScreen, + driCreateNewDrawable +}; + +/* This is the table of extensions that the loader will dlsym() for. */ +PUBLIC const __DRIextension *__driDriverExtensions[] = { + &driCoreExtension.base, + &driSWRastExtension.base, + NULL +}; diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h b/mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h new file mode 100644 index 000000000..1a5fb31d5 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast_priv.h @@ -0,0 +1,144 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2008 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 + * BRIAN PAUL 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. + */ + +/* + * Authors: + * George Sapountzis <gsap7@yahoo.gr> + */ + + +#ifndef _SWRAST_PRIV_H +#define _SWRAST_PRIV_H + +#include <GL/gl.h> +#include <GL/internal/dri_interface.h> +#include "main/mtypes.h" + + +/** + * Debugging + */ +#define DEBUG_CORE 0 +#define DEBUG_SPAN 0 + +#if DEBUG_CORE +#define TRACE _mesa_printf("--> %s\n", __FUNCTION__) +#else +#define TRACE +#endif + +#if DEBUG_SPAN +#define TRACE_SPAN _mesa_printf("--> %s\n", __FUNCTION__) +#else +#define TRACE_SPAN +#endif + + +/** + * Data types + */ +struct __DRIscreenRec { + int num; + + const __DRIextension **extensions; + + const __DRIswrastLoaderExtension *swrast_loader; +}; + +struct __DRIcontextRec { + GLcontext Base; + + void *loaderPrivate; + + __DRIscreen *driScreenPriv; +}; + +struct __DRIdrawableRec { + GLframebuffer Base; + + void *loaderPrivate; + + __DRIscreen *driScreenPriv; + + /* scratch row for optimized front-buffer rendering */ + char *row; +}; + +struct swrast_renderbuffer { + struct gl_renderbuffer Base; + + /* renderbuffer pitch (in bytes) */ + GLuint pitch; + /* bits per pixel of storage */ + GLuint bpp; +}; + +static INLINE __DRIcontext * +swrast_context(GLcontext *ctx) +{ + return (__DRIcontext *) ctx; +} + +static INLINE __DRIdrawable * +swrast_drawable(GLframebuffer *fb) +{ + return (__DRIdrawable *) fb; +} + +static INLINE struct swrast_renderbuffer * +swrast_renderbuffer(struct gl_renderbuffer *rb) +{ + return (struct swrast_renderbuffer *) rb; +} + + +/** + * Pixel formats we support + */ +#define PF_CI8 1 /**< Color Index mode */ +#define PF_A8R8G8B8 2 /**< 32bpp TrueColor: 8-A, 8-R, 8-G, 8-B bits */ +#define PF_R5G6B5 3 /**< 16bpp TrueColor: 5-R, 6-G, 5-B bits */ +#define PF_R3G3B2 4 /**< 8bpp TrueColor: 3-R, 3-G, 2-B bits */ +#define PF_X8R8G8B8 5 /**< 32bpp TrueColor: 8-R, 8-G, 8-B bits */ + +/** + * Renderbuffer pitch alignment (in bits). + * + * The xorg loader requires padding images to 32 bits. However, this should + * become a screen/drawable parameter XXX + */ +#define PITCH_ALIGN_BITS 32 + + +/* swrast_span.c */ + +extern void +swrast_set_span_funcs_back(struct swrast_renderbuffer *xrb, + GLuint pixel_format); + +extern void +swrast_set_span_funcs_front(struct swrast_renderbuffer *xrb, + GLuint pixel_format); + +#endif /* _SWRAST_PRIV_H_ */ diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast_span.c b/mesalib/src/mesa/drivers/dri/swrast/swrast_span.c new file mode 100644 index 000000000..2d3c25dcb --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast_span.c @@ -0,0 +1,439 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2008 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 + * BRIAN PAUL 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. + */ + +/* + * Authors: + * George Sapountzis <gsap7@yahoo.gr> + */ + +#include "swrast_priv.h" + +#define YFLIP(_xrb, Y) ((_xrb)->Base.Height - (Y) - 1) + +/* + * Dithering support takes the "computation" extreme in the "computation vs. + * storage" trade-off. This approach is very simple to implement and any + * computational overhead should be acceptable. XMesa uses table lookups for + * around 8KB of storage overhead per visual. + */ +#define DITHER 1 + +static const GLubyte kernel[16] = { + 0*16, 8*16, 2*16, 10*16, + 12*16, 4*16, 14*16, 6*16, + 3*16, 11*16, 1*16, 9*16, + 15*16, 7*16, 13*16, 5*16, +}; + +#if DITHER +#define DITHER_COMP(X, Y) kernel[((X) & 0x3) | (((Y) & 0x3) << 2)] + +#define DITHER_CLAMP(X) (((X) < CHAN_MAX) ? (X) : CHAN_MAX) +#else +#define DITHER_COMP(X, Y) 0 + +#define DITHER_CLAMP(X) (X) +#endif + + +/* + * Pixel macros shared across front/back buffer span functions. + */ + +/* 32-bit BGRA */ +#define STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) \ + DST[3] = VALUE[ACOMP]; \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP] +#define STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) \ + DST[3] = 0xff; \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP] +#define FETCH_PIXEL_A8R8G8B8(DST, SRC) \ + DST[ACOMP] = SRC[3]; \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0] + + +/* 32-bit BGRX */ +#define STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) \ + DST[3] = 0xff; \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP] +#define STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) \ + DST[3] = 0xff; \ + DST[2] = VALUE[RCOMP]; \ + DST[1] = VALUE[GCOMP]; \ + DST[0] = VALUE[BCOMP] +#define FETCH_PIXEL_X8R8G8B8(DST, SRC) \ + DST[ACOMP] = 0xff; \ + DST[RCOMP] = SRC[2]; \ + DST[GCOMP] = SRC[1]; \ + DST[BCOMP] = SRC[0] + + +/* 16-bit BGR */ +#define STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) \ + do { \ + int d = DITHER_COMP(X, Y) >> 6; \ + GLushort *p = (GLushort *)DST; \ + *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xf8) << 8) | \ + ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xfc) << 3) | \ + ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xf8) >> 3) ); \ + } while(0) +#define FETCH_PIXEL_R5G6B5(DST, SRC) \ + do { \ + GLushort p = *(GLushort *)SRC; \ + DST[ACOMP] = 0xff; \ + DST[RCOMP] = ((p >> 8) & 0xf8) * 255 / 0xf8; \ + DST[GCOMP] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ + DST[BCOMP] = ((p << 3) & 0xf8) * 255 / 0xf8; \ + } while(0) + + +/* 8-bit BGR */ +#define STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) \ + do { \ + int d = DITHER_COMP(X, Y) >> 3; \ + GLubyte *p = (GLubyte *)DST; \ + *p = ( ((DITHER_CLAMP((VALUE[RCOMP]) + d) & 0xe0) >> 5) | \ + ((DITHER_CLAMP((VALUE[GCOMP]) + d) & 0xe0) >> 2) | \ + ((DITHER_CLAMP((VALUE[BCOMP]) + d) & 0xc0) >> 0) ); \ + } while(0) +#define FETCH_PIXEL_R3G3B2(DST, SRC) \ + do { \ + GLubyte p = *(GLubyte *)SRC; \ + DST[ACOMP] = 0xff; \ + DST[RCOMP] = ((p << 5) & 0xe0) * 255 / 0xe0; \ + DST[GCOMP] = ((p << 2) & 0xe0) * 255 / 0xe0; \ + DST[BCOMP] = ((p << 0) & 0xc0) * 255 / 0xc0; \ + } while(0) + + +/* + * Generate code for back-buffer span functions. + */ + +/* 32-bit BGRA */ +#define NAME(FUNC) FUNC##_A8R8G8B8 +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4; +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_A8R8G8B8(DST, SRC) + +#include "swrast/s_spantemp.h" + + +/* 32-bit BGRX */ +#define NAME(FUNC) FUNC##_X8R8G8B8 +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 4; +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_X8R8G8B8(DST, SRC) + +#include "swrast/s_spantemp.h" + + +/* 16-bit BGR */ +#define NAME(FUNC) FUNC##_R5G6B5 +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 2; +#define INC_PIXEL_PTR(P) P += 2 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_R5G6B5(DST, SRC) + +#include "swrast/s_spantemp.h" + + +/* 8-bit BGR */ +#define NAME(FUNC) FUNC##_R3G3B2 +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X) * 1; +#define INC_PIXEL_PTR(P) P += 1 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_R3G3B2(DST, SRC) + +#include "swrast/s_spantemp.h" + + +/* 8-bit color index */ +#define NAME(FUNC) FUNC##_CI8 +#define CI_MODE +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)xrb->Base.Data + YFLIP(xrb, Y) * xrb->pitch + (X); +#define INC_PIXEL_PTR(P) P += 1 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + *DST = VALUE[0] +#define FETCH_PIXEL(DST, SRC) \ + DST = SRC[0] + +#include "swrast/s_spantemp.h" + + +/* + * Generate code for front-buffer span functions. + */ + +/* 32-bit BGRA */ +#define NAME(FUNC) FUNC##_A8R8G8B8_front +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)row; +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_A8R8G8B8(DST, X, Y, VALUE) +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + STORE_PIXEL_RGB_A8R8G8B8(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_A8R8G8B8(DST, SRC) + +#include "swrast_spantemp.h" + + +/* 32-bit BGRX */ +#define NAME(FUNC) FUNC##_X8R8G8B8_front +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)row; +#define INC_PIXEL_PTR(P) P += 4 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_X8R8G8B8(DST, X, Y, VALUE) +#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \ + STORE_PIXEL_RGB_X8R8G8B8(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_X8R8G8B8(DST, SRC) + +#include "swrast_spantemp.h" + + +/* 16-bit BGR */ +#define NAME(FUNC) FUNC##_R5G6B5_front +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)row; +#define INC_PIXEL_PTR(P) P += 2 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_R5G6B5(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_R5G6B5(DST, SRC) + +#include "swrast_spantemp.h" + + +/* 8-bit BGR */ +#define NAME(FUNC) FUNC##_R3G3B2_front +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)row; +#define INC_PIXEL_PTR(P) P += 1 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + STORE_PIXEL_R3G3B2(DST, X, Y, VALUE) +#define FETCH_PIXEL(DST, SRC) \ + FETCH_PIXEL_R3G3B2(DST, SRC) + +#include "swrast_spantemp.h" + + +/* 8-bit color index */ +#define NAME(FUNC) FUNC##_CI8_front +#define CI_MODE +#define RB_TYPE GLubyte +#define SPAN_VARS \ + struct swrast_renderbuffer *xrb = swrast_renderbuffer(rb); +#define INIT_PIXEL_PTR(P, X, Y) \ + GLubyte *P = (GLubyte *)row; +#define INC_PIXEL_PTR(P) P += 1 +#define STORE_PIXEL(DST, X, Y, VALUE) \ + *DST = VALUE[0] +#define FETCH_PIXEL(DST, SRC) \ + DST = SRC[0] + +#include "swrast_spantemp.h" + + +/* + * Back-buffers are malloced memory and always private. + * + * BACK_PIXMAP (not supported) + * BACK_XIMAGE + */ +void +swrast_set_span_funcs_back(struct swrast_renderbuffer *xrb, + GLuint pixel_format) +{ + switch (pixel_format) { + case PF_A8R8G8B8: + xrb->Base.GetRow = get_row_A8R8G8B8; + xrb->Base.GetValues = get_values_A8R8G8B8; + xrb->Base.PutRow = put_row_A8R8G8B8; + xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8; + xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8; + xrb->Base.PutValues = put_values_A8R8G8B8; + xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8; + break; + case PF_X8R8G8B8: + xrb->Base.GetRow = get_row_X8R8G8B8; + xrb->Base.GetValues = get_values_X8R8G8B8; + xrb->Base.PutRow = put_row_X8R8G8B8; + xrb->Base.PutRowRGB = put_row_rgb_X8R8G8B8; + xrb->Base.PutMonoRow = put_mono_row_X8R8G8B8; + xrb->Base.PutValues = put_values_X8R8G8B8; + xrb->Base.PutMonoValues = put_mono_values_X8R8G8B8; + break; + case PF_R5G6B5: + xrb->Base.GetRow = get_row_R5G6B5; + xrb->Base.GetValues = get_values_R5G6B5; + xrb->Base.PutRow = put_row_R5G6B5; + xrb->Base.PutRowRGB = put_row_rgb_R5G6B5; + xrb->Base.PutMonoRow = put_mono_row_R5G6B5; + xrb->Base.PutValues = put_values_R5G6B5; + xrb->Base.PutMonoValues = put_mono_values_R5G6B5; + break; + case PF_R3G3B2: + xrb->Base.GetRow = get_row_R3G3B2; + xrb->Base.GetValues = get_values_R3G3B2; + xrb->Base.PutRow = put_row_R3G3B2; + xrb->Base.PutRowRGB = put_row_rgb_R3G3B2; + xrb->Base.PutMonoRow = put_mono_row_R3G3B2; + xrb->Base.PutValues = put_values_R3G3B2; + xrb->Base.PutMonoValues = put_mono_values_R3G3B2; + break; + case PF_CI8: + xrb->Base.GetRow = get_row_CI8; + xrb->Base.GetValues = get_values_CI8; + xrb->Base.PutRow = put_row_CI8; + xrb->Base.PutMonoRow = put_mono_row_CI8; + xrb->Base.PutValues = put_values_CI8; + xrb->Base.PutMonoValues = put_mono_values_CI8; + break; + default: + assert(0); + return; + } +} + + +/* + * Front-buffers are provided by the loader, the xorg loader uses pixmaps. + * + * WINDOW, An X window + * GLXWINDOW, GLX window + * PIXMAP, GLX pixmap + * PBUFFER GLX Pbuffer + */ +void +swrast_set_span_funcs_front(struct swrast_renderbuffer *xrb, + GLuint pixel_format) +{ + switch (pixel_format) { + case PF_A8R8G8B8: + xrb->Base.GetRow = get_row_A8R8G8B8_front; + xrb->Base.GetValues = get_values_A8R8G8B8_front; + xrb->Base.PutRow = put_row_A8R8G8B8_front; + xrb->Base.PutRowRGB = put_row_rgb_A8R8G8B8_front; + xrb->Base.PutMonoRow = put_mono_row_A8R8G8B8_front; + xrb->Base.PutValues = put_values_A8R8G8B8_front; + xrb->Base.PutMonoValues = put_mono_values_A8R8G8B8_front; + break; + case PF_X8R8G8B8: + xrb->Base.GetRow = get_row_X8R8G8B8_front; + xrb->Base.GetValues = get_values_X8R8G8B8_front; + xrb->Base.PutRow = put_row_X8R8G8B8_front; + xrb->Base.PutRowRGB = put_row_rgb_X8R8G8B8_front; + xrb->Base.PutMonoRow = put_mono_row_X8R8G8B8_front; + xrb->Base.PutValues = put_values_X8R8G8B8_front; + xrb->Base.PutMonoValues = put_mono_values_X8R8G8B8_front; + break; + case PF_R5G6B5: + xrb->Base.GetRow = get_row_R5G6B5_front; + xrb->Base.GetValues = get_values_R5G6B5_front; + xrb->Base.PutRow = put_row_R5G6B5_front; + xrb->Base.PutRowRGB = put_row_rgb_R5G6B5_front; + xrb->Base.PutMonoRow = put_mono_row_R5G6B5_front; + xrb->Base.PutValues = put_values_R5G6B5_front; + xrb->Base.PutMonoValues = put_mono_values_R5G6B5_front; + break; + case PF_R3G3B2: + xrb->Base.GetRow = get_row_R3G3B2_front; + xrb->Base.GetValues = get_values_R3G3B2_front; + xrb->Base.PutRow = put_row_R3G3B2_front; + xrb->Base.PutRowRGB = put_row_rgb_R3G3B2_front; + xrb->Base.PutMonoRow = put_mono_row_R3G3B2_front; + xrb->Base.PutValues = put_values_R3G3B2_front; + xrb->Base.PutMonoValues = put_mono_values_R3G3B2_front; + break; + case PF_CI8: + xrb->Base.GetRow = get_row_CI8_front; + xrb->Base.GetValues = get_values_CI8_front; + xrb->Base.PutRow = put_row_CI8_front; + xrb->Base.PutMonoRow = put_mono_row_CI8_front; + xrb->Base.PutValues = put_values_CI8_front; + xrb->Base.PutMonoValues = put_mono_values_CI8_front; + break; + default: + assert(0); + return; + } +} diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast_spantemp.h b/mesalib/src/mesa/drivers/dri/swrast/swrast_spantemp.h new file mode 100644 index 000000000..e0cb24142 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast_spantemp.h @@ -0,0 +1,328 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.1 + * + * Copyright (C) 1999-2006 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 + * BRIAN PAUL 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. + */ + + +/* + * Modified version of swrast/s_spantemp.h for front-buffer rendering. The + * no-mask paths use a scratch row to avoid repeated calls to the loader. + * + * For the mask paths we always use an array of 4 elements of RB_TYPE. This is + * to satisfy the xorg loader requirement of an image pitch of 32 bits and + * should be ok for other loaders also. + */ + + +#ifndef _SWRAST_SPANTEMP_ONCE +#define _SWRAST_SPANTEMP_ONCE + +static INLINE void +PUT_PIXEL( GLcontext *glCtx, GLint x, GLint y, GLubyte *p ) +{ + __DRIcontext *ctx = swrast_context(glCtx); + __DRIdrawable *draw = swrast_drawable(glCtx->DrawBuffer); + + __DRIscreen *screen = ctx->driScreenPriv; + + screen->swrast_loader->putImage(draw, __DRI_SWRAST_IMAGE_OP_DRAW, + x, y, 1, 1, (char *)p, + draw->loaderPrivate); +} + + +static INLINE void +GET_PIXEL( GLcontext *glCtx, GLint x, GLint y, GLubyte *p ) +{ + __DRIcontext *ctx = swrast_context(glCtx); + __DRIdrawable *read = swrast_drawable(glCtx->ReadBuffer); + + __DRIscreen *screen = ctx->driScreenPriv; + + screen->swrast_loader->getImage(read, x, y, 1, 1, (char *)p, + read->loaderPrivate); +} + +static INLINE void +PUT_ROW( GLcontext *glCtx, GLint x, GLint y, GLuint n, char *row ) +{ + __DRIcontext *ctx = swrast_context(glCtx); + __DRIdrawable *draw = swrast_drawable(glCtx->DrawBuffer); + + __DRIscreen *screen = ctx->driScreenPriv; + + screen->swrast_loader->putImage(draw, __DRI_SWRAST_IMAGE_OP_DRAW, + x, y, n, 1, row, + draw->loaderPrivate); +} + +static INLINE void +GET_ROW( GLcontext *glCtx, GLint x, GLint y, GLuint n, char *row ) +{ + __DRIcontext *ctx = swrast_context(glCtx); + __DRIdrawable *read = swrast_drawable(glCtx->ReadBuffer); + + __DRIscreen *screen = ctx->driScreenPriv; + + screen->swrast_loader->getImage(read, x, y, n, 1, row, + read->loaderPrivate); +} + +#endif /* _SWRAST_SPANTEMP_ONCE */ + + +/* + * Templates for the span/pixel-array write/read functions called via + * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues + * and PutMonoValues functions. + * + * Define the following macros before including this file: + * NAME(BASE) to generate the function name (i.e. add prefix or suffix) + * RB_TYPE the renderbuffer DataType + * CI_MODE if set, color index mode, else RGBA + * SPAN_VARS to declare any local variables + * INIT_PIXEL_PTR(P, X, Y) to initialize a pointer to a pixel + * INC_PIXEL_PTR(P) to increment a pixel pointer by one pixel + * STORE_PIXEL(DST, X, Y, VALUE) to store pixel values in buffer + * FETCH_PIXEL(DST, SRC) to fetch pixel values from buffer + * + * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates + * for the pixels to be stored. This is useful when dithering and probably + * ignored otherwise. + */ + +#include "main/macros.h" + + +#ifdef CI_MODE +#define RB_COMPONENTS 1 +#elif !defined(RB_COMPONENTS) +#define RB_COMPONENTS 4 +#endif + + +static void +NAME(get_row)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, void *values ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif +#ifdef CI_MODE + RB_TYPE *dest = (RB_TYPE *) values; +#else + RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values; +#endif + GLuint i; + char *row = swrast_drawable(ctx->ReadBuffer)->row; + INIT_PIXEL_PTR(pixel, x, y); + GET_ROW( ctx, x, YFLIP(xrb, y), count, row ); + for (i = 0; i < count; i++) { + FETCH_PIXEL(dest[i], pixel); + INC_PIXEL_PTR(pixel); + } + (void) rb; +} + + +static void +NAME(get_values)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], void *values ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif +#ifdef CI_MODE + RB_TYPE *dest = (RB_TYPE *) values; +#else + RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values; +#endif + GLuint i; + for (i = 0; i < count; i++) { + RB_TYPE pixel[4]; + GET_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel); + FETCH_PIXEL(dest[i], pixel); + } + (void) rb; +} + + +static void +NAME(put_row)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values; + GLuint i; + if (mask) { + for (i = 0; i < count; i++) { + if (mask[i]) { + RB_TYPE pixel[4]; + STORE_PIXEL(pixel, x + i, y, src[i]); + PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel); + } + } + } + else { + char *row = swrast_drawable(ctx->DrawBuffer)->row; + INIT_PIXEL_PTR(pixel, x, y); + for (i = 0; i < count; i++) { + STORE_PIXEL(pixel, x + i, y, src[i]); + INC_PIXEL_PTR(pixel); + } + PUT_ROW( ctx, x, YFLIP(xrb, y), count, row ); + } + (void) rb; +} + + +#if !defined(CI_MODE) +static void +NAME(put_row_rgb)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *values, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values; + GLuint i; + if (mask) { + for (i = 0; i < count; i++) { + if (mask[i]) { + RB_TYPE pixel[4]; +#ifdef STORE_PIXEL_RGB + STORE_PIXEL_RGB(pixel, x + i, y, src[i]); +#else + STORE_PIXEL(pixel, x + i, y, src[i]); +#endif + PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel); + } + } + } + else { + char *row = swrast_drawable(ctx->DrawBuffer)->row; + INIT_PIXEL_PTR(pixel, x, y); + for (i = 0; i < count; i++) { +#ifdef STORE_PIXEL_RGB + STORE_PIXEL_RGB(pixel, x + i, y, src[i]); +#else + STORE_PIXEL(pixel, x + i, y, src[i]); +#endif + INC_PIXEL_PTR(pixel); + } + PUT_ROW( ctx, x, YFLIP(xrb, y), count, row ); + } + (void) rb; +} +#endif + + +static void +NAME(put_mono_row)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, GLint x, GLint y, + const void *value, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE *src = (const RB_TYPE *) value; + GLuint i; + if (mask) { + for (i = 0; i < count; i++) { + if (mask[i]) { + RB_TYPE pixel[4]; + STORE_PIXEL(pixel, x + i, y, src); + PUT_PIXEL(ctx, x + i, YFLIP(xrb, y), pixel); + } + } + } + else { + char *row = swrast_drawable(ctx->DrawBuffer)->row; + INIT_PIXEL_PTR(pixel, x, y); + for (i = 0; i < count; i++) { + STORE_PIXEL(pixel, x + i, y, src); + INC_PIXEL_PTR(pixel); + } + PUT_ROW( ctx, x, YFLIP(xrb, y), count, row ); + } + (void) rb; +} + + +static void +NAME(put_values)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *values, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values; + GLuint i; + ASSERT(mask); + for (i = 0; i < count; i++) { + if (mask[i]) { + RB_TYPE pixel[4]; + STORE_PIXEL(pixel, x[i], y[i], src[i]); + PUT_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel); + } + } + (void) rb; +} + + +static void +NAME(put_mono_values)( GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint count, const GLint x[], const GLint y[], + const void *value, const GLubyte mask[] ) +{ +#ifdef SPAN_VARS + SPAN_VARS +#endif + const RB_TYPE *src = (const RB_TYPE *) value; + GLuint i; + ASSERT(mask); + for (i = 0; i < count; i++) { + if (mask[i]) { + RB_TYPE pixel[4]; + STORE_PIXEL(pixel, x[i], y[i], src); + PUT_PIXEL(ctx, x[i], YFLIP(xrb, y[i]), pixel); + } + } + (void) rb; +} + + +#undef NAME +#undef RB_TYPE +#undef RB_COMPONENTS +#undef CI_MODE +#undef SPAN_VARS +#undef INIT_PIXEL_PTR +#undef INC_PIXEL_PTR +#undef STORE_PIXEL +#undef STORE_PIXEL_RGB +#undef FETCH_PIXEL diff --git a/mesalib/src/mesa/drivers/windows/fx/fxopengl.def b/mesalib/src/mesa/drivers/windows/fx/fxopengl.def new file mode 100644 index 000000000..d65b763d2 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/fx/fxopengl.def @@ -0,0 +1,955 @@ +LIBRARY OpenGL32 +DESCRIPTION "Mesa 5.1" +EXPORTS + glAccum + glActiveStencilFaceEXT + glActiveTexture + glActiveTextureARB + glAlphaFunc + glAreProgramsResidentNV + glAreTexturesResident + glAreTexturesResidentEXT + glArrayElement + glArrayElementEXT + glBegin + glBeginQueryARB + glBindBufferARB + glBindProgramARB + glBindProgramNV + glBindTexture + glBindTextureEXT + glBitmap +;glBlendColor +;glBlendColorEXT + glBlendEquation + glBlendEquationEXT + glBlendFunc + glBlendFuncSeparate + glBlendFuncSeparateEXT + glBlendFuncSeparateINGR + glBufferDataARB + glBufferSubDataARB + glCallList + glCallLists + glClear + glClearAccum + glClearColor + glClearDepth + glClearIndex + glClearStencil + glClientActiveTexture + glClientActiveTextureARB + glClipPlane + glColorMask + glColorMaterial + glColorPointer + glColorPointerEXT + glColorSubTable + glColorSubTableEXT + glColorTable + glColorTableEXT + glColorTableParameterfv + glColorTableParameterfvSGI + glColorTableParameteriv + glColorTableParameterivSGI + glColorTableSGI + glColor3b + glColor3bv + glColor3d + glColor3dv + glColor3f + glColor3fv + glColor3i + glColor3iv + glColor3s + glColor3sv + glColor3ub + glColor3ubv + glColor3ui + glColor3uiv + glColor3us + glColor3usv + glColor4b + glColor4bv + glColor4d + glColor4dv + glColor4f + glColor4fv + glColor4i + glColor4iv + glColor4s + glColor4sv + glColor4ub + glColor4ubv + glColor4ui + glColor4uiv + glColor4us + glColor4usv + glCombinerInputNV + glCombinerOutputNV + glCombinerParameterfNV + glCombinerParameterfvNV + glCombinerParameteriNV + glCombinerParameterivNV + glCompressedTexImage1D + glCompressedTexImage1DARB + glCompressedTexImage2D + glCompressedTexImage2DARB + glCompressedTexImage3D + glCompressedTexImage3DARB + glCompressedTexSubImage1D + glCompressedTexSubImage1DARB + glCompressedTexSubImage2D + glCompressedTexSubImage2DARB + glCompressedTexSubImage3D + glCompressedTexSubImage3DARB + glConvolutionFilter1D + glConvolutionFilter1DEXT + glConvolutionFilter2D + glConvolutionFilter2DEXT + glConvolutionParameterf + glConvolutionParameterfEXT + glConvolutionParameterfv + glConvolutionParameterfvEXT + glConvolutionParameteri + glConvolutionParameteriEXT + glConvolutionParameteriv + glConvolutionParameterivEXT + glCopyColorSubTable + glCopyColorSubTableEXT + glCopyColorTable + glCopyColorTableSGI + glCopyConvolutionFilter1D + glCopyConvolutionFilter1DEXT + glCopyConvolutionFilter2D + glCopyConvolutionFilter2DEXT + glCopyPixels + glCopyTexImage1D + glCopyTexImage1DEXT + glCopyTexImage2D + glCopyTexImage2DEXT + glCopyTexSubImage1D + glCopyTexSubImage1DEXT + glCopyTexSubImage2D + glCopyTexSubImage2DEXT + glCopyTexSubImage3D + glCopyTexSubImage3DEXT + glCullFace + glCullParameterdvEXT + glCullParameterfvEXT + glDeleteBuffersARB + glDeleteFencesNV + glDeleteLists + glDeleteProgramsARB + glDeleteProgramsNV + glDeleteQueriesARB + glDeleteTextures + glDeleteTexturesEXT + glDepthBoundsEXT + glDepthFunc + glDepthMask + glDepthRange + glDetailTexFuncSGIS + glDisable + glDisableClientState + glDisableVertexAttribArrayARB + glDrawArrays + glDrawArraysEXT + glDrawBuffer + glDrawElements + glDrawPixels + glDrawRangeElements + glDrawRangeElementsEXT + glEdgeFlag + glEdgeFlagPointer + glEdgeFlagPointerEXT + glEdgeFlagv + glEnable + glEnableClientState + glEnableVertexAttribArrayARB + glEnd + glEndList + glEndQueryARB + glEvalCoord1d + glEvalCoord1dv + glEvalCoord1f + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2dv + glEvalCoord2f + glEvalCoord2fv + glEvalMesh1 + glEvalMesh2 + glEvalPoint1 + glEvalPoint2 + glExecuteProgramNV + glFeedbackBuffer + glFinalCombinerInputNV + glFinish + glFinishFenceNV + glFlush + glFlushRasterSGIX + glFlushVertexArrayRangeNV + glFogCoordd + glFogCoorddEXT + glFogCoorddv + glFogCoorddvEXT + glFogCoordf + glFogCoordfEXT + glFogCoordfv + glFogCoordfvEXT + glFogCoordPointer + glFogCoordPointerEXT + glFogf + glFogfv + glFogi + glFogiv + glFragmentColorMaterialSGIX + glFragmentLightfSGIX + glFragmentLightfvSGIX + glFragmentLightiSGIX + glFragmentLightivSGIX + glFragmentLightModelfSGIX + glFragmentLightModelfvSGIX + glFragmentLightModeliSGIX + glFragmentLightModelivSGIX + glFragmentMaterialfSGIX + glFragmentMaterialfvSGIX + glFragmentMaterialiSGIX + glFragmentMaterialivSGIX + glFrameZoomSGIX + glFrontFace + glFrustum + glGenBuffersARB + glGenFencesNV + glGenLists + glGenProgramsARB + glGenProgramsNV + glGenQueriesARB + glGenTextures + glGenTexturesEXT + glGetBooleanv + glGetBufferParameterivARB + glGetBufferPointervARB + glGetBufferSubDataARB + glGetClipPlane + glGetColorTable + glGetColorTableEXT + glGetColorTableParameterfv + glGetColorTableParameterfvEXT + glGetColorTableParameterfvSGI + glGetColorTableParameteriv + glGetColorTableParameterivEXT + glGetColorTableParameterivSGI + glGetColorTableSGI + glGetCombinerInputParameterfvNV + glGetCombinerInputParameterivNV + glGetCombinerOutputParameterfvNV + glGetCombinerOutputParameterivNV + glGetCompressedTexImage + glGetCompressedTexImageARB + glGetConvolutionFilter + glGetConvolutionFilterEXT + glGetConvolutionParameterfv + glGetConvolutionParameterfvEXT + glGetConvolutionParameteriv + glGetConvolutionParameterivEXT + glGetDetailTexFuncSGIS + glGetDoublev + glGetError + glGetFenceivNV + glGetFinalCombinerInputParameterfvNV + glGetFinalCombinerInputParameterivNV + glGetFloatv + glGetFragmentLightfvSGIX + glGetFragmentLightivSGIX + glGetFragmentMaterialfvSGIX + glGetFragmentMaterialivSGIX + glGetHistogram + glGetHistogramEXT + glGetHistogramParameterfv + glGetHistogramParameterfvEXT + glGetHistogramParameteriv + glGetHistogramParameterivEXT + glGetInstrumentsSGIX + glGetIntegerv + glGetLightfv + glGetLightiv + glGetListParameterfvSGIX + glGetListParameterivSGIX + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetMinmax + glGetMinmaxEXT + glGetMinmaxParameterfv + glGetMinmaxParameterfvEXT + glGetMinmaxParameteriv + glGetMinmaxParameterivEXT + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPixelTexGenParameterfvSGIS + glGetPixelTexGenParameterivSGIS + glGetPointerv + glGetPointervEXT + glGetPolygonStipple + glGetProgramEnvParameterdvARB + glGetProgramEnvParameterfvARB + glGetProgramivARB + glGetProgramivNV + glGetProgramLocalParameterdvARB + glGetProgramLocalParameterfvARB + glGetProgramNamedParameterdvNV + glGetProgramNamedParameterfvNV + glGetProgramParameterdvNV + glGetProgramParameterfvNV + glGetProgramStringARB + glGetProgramStringNV + glGetQueryivARB + glGetQueryObjectivARB + glGetQueryObjectuivARB + glGetSeparableFilter + glGetSeparableFilterEXT + glGetSharpenTexFuncSGIS + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexFilterFuncSGIS + glGetTexGendv + glGetTexGenfv + glGetTexGeniv + glGetTexImage + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glGetTexParameterfv + glGetTexParameteriv + glGetTrackMatrixivNV + glGetVertexAttribdvARB + glGetVertexAttribdvNV + glGetVertexAttribfvARB + glGetVertexAttribfvNV + glGetVertexAttribivARB + glGetVertexAttribivNV + glGetVertexAttribPointervARB + glGetVertexAttribPointervNV + glHint + glHintPGI + glHistogram + glHistogramEXT + glIndexd + glIndexdv + glIndexf + glIndexFuncEXT + glIndexfv + glIndexi + glIndexiv + glIndexMask + glIndexMaterialEXT + glIndexPointer + glIndexPointerEXT + glIndexs + glIndexsv + glIndexub + glIndexubv + glInitNames + glInstrumentsBufferSGIX + glInterleavedArrays + glIsBufferARB + glIsEnabled + glIsFenceNV + glIsList + glIsProgramARB + glIsProgramNV + glIsQueryARB + glIsTexture + glIsTextureEXT + glLightEnviSGIX + glLightf + glLightfv + glLighti + glLightiv + glLightModelf + glLightModelfv + glLightModeli + glLightModeliv + glLineStipple + glLineWidth + glListBase + glListParameterfSGIX + glListParameterfvSGIX + glListParameteriSGIX + glListParameterivSGIX + glLoadIdentity + glLoadMatrixd + glLoadMatrixf + glLoadName + glLoadProgramNV + glLoadTransposeMatrixd + glLoadTransposeMatrixdARB + glLoadTransposeMatrixf + glLoadTransposeMatrixfARB + glLockArraysEXT + glLogicOp + glMapBufferARB + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glMap1d + glMap1f + glMap2d + glMap2f + glMaterialf + glMaterialfv + glMateriali + glMaterialiv + glMatrixMode + glMinmax + glMinmaxEXT + glMultiDrawArrays + glMultiDrawArraysEXT + glMultiDrawElements + glMultiDrawElementsEXT + glMultiModeDrawArraysIBM + glMultiModeDrawElementsIBM + glMultiTexCoord1d + glMultiTexCoord1dARB + glMultiTexCoord1dv + glMultiTexCoord1dvARB + glMultiTexCoord1f + glMultiTexCoord1fARB + glMultiTexCoord1fv + glMultiTexCoord1fvARB + glMultiTexCoord1i + glMultiTexCoord1iARB + glMultiTexCoord1iv + glMultiTexCoord1ivARB + glMultiTexCoord1s + glMultiTexCoord1sARB + glMultiTexCoord1sv + glMultiTexCoord1svARB + glMultiTexCoord2d + glMultiTexCoord2dARB + glMultiTexCoord2dv + glMultiTexCoord2dvARB + glMultiTexCoord2f + glMultiTexCoord2fARB + glMultiTexCoord2fv + glMultiTexCoord2fvARB + glMultiTexCoord2i + glMultiTexCoord2iARB + glMultiTexCoord2iv + glMultiTexCoord2ivARB + glMultiTexCoord2s + glMultiTexCoord2sARB + glMultiTexCoord2sv + glMultiTexCoord2svARB + glMultiTexCoord3d + glMultiTexCoord3dARB + glMultiTexCoord3dv + glMultiTexCoord3dvARB + glMultiTexCoord3f + glMultiTexCoord3fARB + glMultiTexCoord3fv + glMultiTexCoord3fvARB + glMultiTexCoord3i + glMultiTexCoord3iARB + glMultiTexCoord3iv + glMultiTexCoord3ivARB + glMultiTexCoord3s + glMultiTexCoord3sARB + glMultiTexCoord3sv + glMultiTexCoord3svARB + glMultiTexCoord4d + glMultiTexCoord4dARB + glMultiTexCoord4dv + glMultiTexCoord4dvARB + glMultiTexCoord4f + glMultiTexCoord4fARB + glMultiTexCoord4fv + glMultiTexCoord4fvARB + glMultiTexCoord4i + glMultiTexCoord4iARB + glMultiTexCoord4iv + glMultiTexCoord4ivARB + glMultiTexCoord4s + glMultiTexCoord4sARB + glMultiTexCoord4sv + glMultiTexCoord4svARB + glMultMatrixd + glMultMatrixf + glMultTransposeMatrixd + glMultTransposeMatrixdARB + glMultTransposeMatrixf + glMultTransposeMatrixfARB + glNewList + glNormalPointer + glNormalPointerEXT + glNormal3b + glNormal3bv + glNormal3d + glNormal3dv + glNormal3f + glNormal3fv + glNormal3i + glNormal3iv + glNormal3s + glNormal3sv + glOrtho + glPassThrough + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glPixelStoref + glPixelStorei + glPixelTexGenParameterfSGIS + glPixelTexGenParameterfvSGIS + glPixelTexGenParameteriSGIS + glPixelTexGenParameterivSGIS + glPixelTexGenSGIX + glPixelTransferf + glPixelTransferi + glPixelZoom + glPointParameterf + glPointParameterfARB + glPointParameterfEXT + glPointParameterfSGIS + glPointParameterfv + glPointParameterfvARB + glPointParameterfvEXT + glPointParameterfvSGIS + glPointParameteri + glPointParameteriNV + glPointParameteriv + glPointParameterivNV + glPointSize + glPollInstrumentsSGIX + glPolygonMode + glPolygonOffset + glPolygonOffsetEXT + glPolygonStipple + glPopAttrib + glPopClientAttrib + glPopMatrix + glPopName + glPrioritizeTextures + glPrioritizeTexturesEXT + glProgramEnvParameter4dARB + glProgramEnvParameter4dvARB + glProgramEnvParameter4fARB + glProgramEnvParameter4fvARB + glProgramLocalParameter4dARB + glProgramLocalParameter4dvARB + glProgramLocalParameter4fARB + glProgramLocalParameter4fvARB + glProgramNamedParameter4dNV + glProgramNamedParameter4dvNV + glProgramNamedParameter4fNV + glProgramNamedParameter4fvNV + glProgramParameters4dvNV + glProgramParameters4fvNV + glProgramParameter4dNV + glProgramParameter4dvNV + glProgramParameter4fNV + glProgramParameter4fvNV + glProgramStringARB + glPushAttrib + glPushClientAttrib + glPushMatrix + glPushName + glRasterPos2d + glRasterPos2dv + glRasterPos2f + glRasterPos2fv + glRasterPos2i + glRasterPos2iv + glRasterPos2s + glRasterPos2sv + glRasterPos3d + glRasterPos3dv + glRasterPos3f + glRasterPos3fv + glRasterPos3i + glRasterPos3iv + glRasterPos3s + glRasterPos3sv + glRasterPos4d + glRasterPos4dv + glRasterPos4f + glRasterPos4fv + glRasterPos4i + glRasterPos4iv + glRasterPos4s + glRasterPos4sv + glReadBuffer + glReadInstrumentsSGIX + glReadPixels + glRectd + glRectdv + glRectf + glRectfv + glRecti + glRectiv + glRects + glRectsv + glReferencePlaneSGIX + glRenderMode + glRequestResidentProgramsNV + glResetHistogram + glResetHistogramEXT + glResetMinmax + glResetMinmaxEXT + glResizeBuffersMESA + glRotated + glRotatef + glSampleCoverage + glSampleCoverageARB + glSampleMaskEXT + glSampleMaskSGIS + glSamplePatternEXT + glSamplePatternSGIS + glScaled + glScalef + glScissor + glSecondaryColorPointer + glSecondaryColorPointerEXT + glSecondaryColor3b + glSecondaryColor3bEXT + glSecondaryColor3bv + glSecondaryColor3bvEXT + glSecondaryColor3d + glSecondaryColor3dEXT + glSecondaryColor3dv + glSecondaryColor3dvEXT + glSecondaryColor3f + glSecondaryColor3fEXT + glSecondaryColor3fv + glSecondaryColor3fvEXT + glSecondaryColor3i + glSecondaryColor3iEXT + glSecondaryColor3iv + glSecondaryColor3ivEXT + glSecondaryColor3s + glSecondaryColor3sEXT + glSecondaryColor3sv + glSecondaryColor3svEXT + glSecondaryColor3ub + glSecondaryColor3ubEXT + glSecondaryColor3ubv + glSecondaryColor3ubvEXT + glSecondaryColor3ui + glSecondaryColor3uiEXT + glSecondaryColor3uiv + glSecondaryColor3uivEXT + glSecondaryColor3us + glSecondaryColor3usEXT + glSecondaryColor3usv + glSecondaryColor3usvEXT + glSelectBuffer + glSeparableFilter2D + glSeparableFilter2DEXT + glSetFenceNV + glShadeModel + glSharpenTexFuncSGIS + glSpriteParameterfSGIX + glSpriteParameterfvSGIX + glSpriteParameteriSGIX + glSpriteParameterivSGIX + glStartInstrumentsSGIX + glStencilFunc + glStencilMask + glStencilOp + glStopInstrumentsSGIX + glTagSampleBufferSGIX + glTbufferMask3DFX + glTestFenceNV + glTexCoordPointer + glTexCoordPointerEXT + glTexCoord1d + glTexCoord1dv + glTexCoord1f + glTexCoord1fv + glTexCoord1i + glTexCoord1iv + glTexCoord1s + glTexCoord1sv + glTexCoord2d + glTexCoord2dv + glTexCoord2f + glTexCoord2fv + glTexCoord2i + glTexCoord2iv + glTexCoord2s + glTexCoord2sv + glTexCoord3d + glTexCoord3dv + glTexCoord3f + glTexCoord3fv + glTexCoord3i + glTexCoord3iv + glTexCoord3s + glTexCoord3sv + glTexCoord4d + glTexCoord4dv + glTexCoord4f + glTexCoord4fv + glTexCoord4i + glTexCoord4iv + glTexCoord4s + glTexCoord4sv + glTexEnvf + glTexEnvfv + glTexEnvi + glTexEnviv + glTexFilterFuncSGIS + glTexGend + glTexGendv + glTexGenf + glTexGenfv + glTexGeni + glTexGeniv + glTexImage1D + glTexImage2D + glTexImage3D + glTexImage3DEXT + glTexImage4DSGIS + glTexParameterf + glTexParameterfv + glTexParameteri + glTexParameteriv + glTexSubImage1D + glTexSubImage1DEXT + glTexSubImage2D + glTexSubImage2DEXT + glTexSubImage3D + glTexSubImage3DEXT + glTexSubImage4DSGIS + glTrackMatrixNV + glTranslated + glTranslatef + glUnlockArraysEXT + glUnmapBufferARB + glVertexArrayRangeNV + glVertexAttribPointerARB + glVertexAttribPointerNV + glVertexAttribs1dvNV + glVertexAttribs1fvNV + glVertexAttribs1svNV + glVertexAttribs2dvNV + glVertexAttribs2fvNV + glVertexAttribs2svNV + glVertexAttribs3dvNV + glVertexAttribs3fvNV + glVertexAttribs3svNV + glVertexAttribs4dvNV + glVertexAttribs4fvNV + glVertexAttribs4svNV + glVertexAttribs4ubvNV + glVertexAttrib1dARB + glVertexAttrib1dNV + glVertexAttrib1dvARB + glVertexAttrib1dvNV + glVertexAttrib1fARB + glVertexAttrib1fNV + glVertexAttrib1fvARB + glVertexAttrib1fvNV + glVertexAttrib1sARB + glVertexAttrib1sNV + glVertexAttrib1svARB + glVertexAttrib1svNV + glVertexAttrib2dARB + glVertexAttrib2dNV + glVertexAttrib2dvARB + glVertexAttrib2dvNV + glVertexAttrib2fARB + glVertexAttrib2fNV + glVertexAttrib2fvARB + glVertexAttrib2fvNV + glVertexAttrib2sARB + glVertexAttrib2sNV + glVertexAttrib2svARB + glVertexAttrib2svNV + glVertexAttrib3dARB + glVertexAttrib3dNV + glVertexAttrib3dvARB + glVertexAttrib3dvNV + glVertexAttrib3fARB + glVertexAttrib3fNV + glVertexAttrib3fvARB + glVertexAttrib3fvNV + glVertexAttrib3sARB + glVertexAttrib3sNV + glVertexAttrib3svARB + glVertexAttrib3svNV + glVertexAttrib4bvARB + glVertexAttrib4dARB + glVertexAttrib4dNV + glVertexAttrib4dvARB + glVertexAttrib4dvNV + glVertexAttrib4fARB + glVertexAttrib4fNV + glVertexAttrib4fvARB + glVertexAttrib4fvNV + glVertexAttrib4ivARB + glVertexAttrib4NbvARB + glVertexAttrib4NivARB + glVertexAttrib4NsvARB + glVertexAttrib4NubARB + glVertexAttrib4NubvARB + glVertexAttrib4NuivARB + glVertexAttrib4NusvARB + glVertexAttrib4sARB + glVertexAttrib4sNV + glVertexAttrib4svARB + glVertexAttrib4svNV + glVertexAttrib4ubNV + glVertexAttrib4ubvARB + glVertexAttrib4ubvNV + glVertexAttrib4uivARB + glVertexAttrib4usvARB + glVertexPointer + glVertexPointerEXT + glVertexWeightfEXT + glVertexWeightfvEXT + glVertexWeightPointerEXT + glVertex2d + glVertex2dv + glVertex2f + glVertex2fv + glVertex2i + glVertex2iv + glVertex2s + glVertex2sv + glVertex3d + glVertex3dv + glVertex3f + glVertex3fv + glVertex3i + glVertex3iv + glVertex3s + glVertex3sv + glVertex4d + glVertex4dv + glVertex4f + glVertex4fv + glVertex4i + glVertex4iv + glVertex4s + glVertex4sv + glViewport + glWindowPos2d + glWindowPos2dARB + glWindowPos2dMESA + glWindowPos2dv + glWindowPos2dvARB + glWindowPos2dvMESA + glWindowPos2f + glWindowPos2fARB + glWindowPos2fMESA + glWindowPos2fv + glWindowPos2fvARB + glWindowPos2fvMESA + glWindowPos2i + glWindowPos2iARB + glWindowPos2iMESA + glWindowPos2iv + glWindowPos2ivARB + glWindowPos2ivMESA + glWindowPos2s + glWindowPos2sARB + glWindowPos2sMESA + glWindowPos2sv + glWindowPos2svARB + glWindowPos2svMESA + glWindowPos3d + glWindowPos3dARB + glWindowPos3dMESA + glWindowPos3dv + glWindowPos3dvARB + glWindowPos3dvMESA + glWindowPos3f + glWindowPos3fARB + glWindowPos3fMESA + glWindowPos3fv + glWindowPos3fvARB + glWindowPos3fvMESA + glWindowPos3i + glWindowPos3iARB + glWindowPos3iMESA + glWindowPos3iv + glWindowPos3ivARB + glWindowPos3ivMESA + glWindowPos3s + glWindowPos3sARB + glWindowPos3sMESA + glWindowPos3sv + glWindowPos3svARB + glWindowPos3svMESA + glWindowPos4dMESA + glWindowPos4dvMESA + glWindowPos4fMESA + glWindowPos4fvMESA + glWindowPos4iMESA + glWindowPos4ivMESA + glWindowPos4sMESA + glWindowPos4svMESA + fxCloseHardware +;fxGetScreenGeometry + fxMesaCreateBestContext + fxMesaCreateContext + fxMesaDestroyContext + fxMesaGetCurrentContext + fxMesaMakeCurrent + fxMesaSelectCurrentBoard +;fxMesaSetNearFar + fxMesaSwapBuffers + fxMesaUpdateScreenSize + wglChoosePixelFormat + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext + wglDescribeLayerPlane + wglDescribePixelFormat + wglGetCurrentContext + wglGetCurrentDC + wglGetDefaultProcAddress + wglGetLayerPaletteEntries + wglGetPixelFormat + wglGetProcAddress + wglMakeCurrent + wglRealizeLayerPalette + wglSetLayerPaletteEntries + wglSetPixelFormat + wglShareLists + wglSwapBuffers + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + ChoosePixelFormat + DescribePixelFormat + GetPixelFormat + SetPixelFormat + SwapBuffers + DrvCopyContext + DrvCreateContext + DrvCreateLayerContext + DrvDeleteContext + DrvDescribeLayerPlane + DrvDescribePixelFormat + DrvGetLayerPaletteEntries + DrvGetProcAddress + DrvReleaseContext + DrvRealizeLayerPalette + DrvSetContext + DrvSetLayerPaletteEntries + DrvSetPixelFormat + DrvShareLists + DrvSwapBuffers + DrvSwapLayerBuffers + DrvValidateVersion diff --git a/mesalib/src/mesa/drivers/windows/fx/fxwgl.c b/mesalib/src/mesa/drivers/windows/fx/fxwgl.c new file mode 100644 index 000000000..ce76ecd15 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/fx/fxwgl.c @@ -0,0 +1,1307 @@ +/* + * Mesa 3-D graphics library + * Version: 4.0 + * + * Copyright (C) 1999-2001 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 + * BRIAN PAUL 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. + */ + +/* Authors: + * David Bucciarelli + * Brian Paul + * Keith Whitwell + * Hiroshi Morii + * Daniel Borca + */ + +/* fxwgl.c - Microsoft wgl functions emulation for + * 3Dfx VooDoo/Mesa interface + */ + + +#ifdef _WIN32 + +#ifdef __cplusplus +extern "C" { +#endif + +#include <windows.h> +#define GL_GLEXT_PROTOTYPES +#include "GL/gl.h" +#include "GL/glext.h" + +#ifdef __cplusplus +} +#endif + +#include "GL/fxmesa.h" +#include "glheader.h" +#include "glapi.h" +#include "imports.h" +#include "../../glide/fxdrv.h" + +#define MAX_MESA_ATTRS 20 + +#if (_MSC_VER >= 1200) +#pragma warning( push ) +#pragma warning( disable : 4273 ) +#endif + +struct __extensions__ { + PROC proc; + char *name; +}; + +struct __pixelformat__ { + PIXELFORMATDESCRIPTOR pfd; + GLint mesaAttr[MAX_MESA_ATTRS]; +}; + +WINGDIAPI void GLAPIENTRY gl3DfxSetPaletteEXT(GLuint *); +static GLushort gammaTable[3 * 256]; + +struct __pixelformat__ pix[] = { + /* 16bit RGB565 single buffer with depth */ + { + {sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, + PFD_TYPE_RGBA, + 16, + 5, 0, 6, 5, 5, 11, 0, 0, + 0, 0, 0, 0, 0, + 16, + 0, + 0, + PFD_MAIN_PLANE, + 0, 0, 0, 0} + , + {FXMESA_COLORDEPTH, 16, + FXMESA_ALPHA_SIZE, 0, + FXMESA_DEPTH_SIZE, 16, + FXMESA_STENCIL_SIZE, 0, + FXMESA_ACCUM_SIZE, 0, + FXMESA_NONE} + } + , + /* 16bit RGB565 double buffer with depth */ + { + {sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER | PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 16, + 5, 0, 6, 5, 5, 11, 0, 0, + 0, 0, 0, 0, 0, + 16, + 0, + 0, + PFD_MAIN_PLANE, + 0, 0, 0, 0} + , + {FXMESA_COLORDEPTH, 16, + FXMESA_DOUBLEBUFFER, + FXMESA_ALPHA_SIZE, 0, + FXMESA_DEPTH_SIZE, 16, + FXMESA_STENCIL_SIZE, 0, + FXMESA_ACCUM_SIZE, 0, + FXMESA_NONE} + } + , + /* 16bit ARGB1555 single buffer with depth */ + { + {sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, + PFD_TYPE_RGBA, + 16, + 5, 0, 5, 5, 5, 10, 1, 15, + 0, 0, 0, 0, 0, + 16, + 0, + 0, + PFD_MAIN_PLANE, + 0, 0, 0, 0} + , + {FXMESA_COLORDEPTH, 15, + FXMESA_ALPHA_SIZE, 1, + FXMESA_DEPTH_SIZE, 16, + FXMESA_STENCIL_SIZE, 0, + FXMESA_ACCUM_SIZE, 0, + FXMESA_NONE} + } + , + /* 16bit ARGB1555 double buffer with depth */ + { + {sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER | PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 16, + 5, 0, 5, 5, 5, 10, 1, 15, + 0, 0, 0, 0, 0, + 16, + 0, + 0, + PFD_MAIN_PLANE, + 0, 0, 0, 0} + , + {FXMESA_COLORDEPTH, 15, + FXMESA_DOUBLEBUFFER, + FXMESA_ALPHA_SIZE, 1, + FXMESA_DEPTH_SIZE, 16, + FXMESA_STENCIL_SIZE, 0, + FXMESA_ACCUM_SIZE, 0, + FXMESA_NONE} + } + , + /* 32bit ARGB8888 single buffer with depth */ + { + {sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, + PFD_TYPE_RGBA, + 32, + 8, 0, 8, 8, 8, 16, 8, 24, + 0, 0, 0, 0, 0, + 24, + 8, + 0, + PFD_MAIN_PLANE, + 0, 0, 0, 0} + , + {FXMESA_COLORDEPTH, 32, + FXMESA_ALPHA_SIZE, 8, + FXMESA_DEPTH_SIZE, 24, + FXMESA_STENCIL_SIZE, 8, + FXMESA_ACCUM_SIZE, 0, + FXMESA_NONE} + } + , + /* 32bit ARGB8888 double buffer with depth */ + { + {sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | + PFD_DOUBLEBUFFER | PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 32, + 8, 0, 8, 8, 8, 16, 8, 24, + 0, 0, 0, 0, 0, + 24, + 8, + 0, + PFD_MAIN_PLANE, + 0, 0, 0, 0} + , + {FXMESA_COLORDEPTH, 32, + FXMESA_DOUBLEBUFFER, + FXMESA_ALPHA_SIZE, 8, + FXMESA_DEPTH_SIZE, 24, + FXMESA_STENCIL_SIZE, 8, + FXMESA_ACCUM_SIZE, 0, + FXMESA_NONE} + } +}; + +static fxMesaContext ctx = NULL; +static WNDPROC hWNDOldProc; +static int curPFD = 0; +static HDC hDC; +static HWND hWND; + +static GLboolean haveDualHead; + +/* For the in-window-rendering hack */ + +#ifndef GR_CONTROL_RESIZE +/* Apparently GR_CONTROL_RESIZE can be ignored. OK? */ +#define GR_CONTROL_RESIZE -1 +#endif + +static GLboolean gdiWindowHack; +static void *dibSurfacePtr; +static BITMAPINFO *dibBMI; +static HBITMAP dibHBM; +static HWND dibWnd; + +static int +env_check (const char *var, int val) +{ + const char *env = getenv(var); + return (env && (env[0] == val)); +} + +static LRESULT APIENTRY +__wglMonitor (HWND hwnd, UINT message, UINT wParam, LONG lParam) +{ + long ret; /* Now gives the resized window at the end to hWNDOldProc */ + + if (ctx && hwnd == hWND) { + switch (message) { + case WM_PAINT: + case WM_MOVE: + break; + case WM_DISPLAYCHANGE: + case WM_SIZE: +#if 0 + if (wParam != SIZE_MINIMIZED) { + static int moving = 0; + if (!moving) { + if (!FX_grSstControl(GR_CONTROL_RESIZE)) { + moving = 1; + SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE | SWP_NOZORDER); + moving = 0; + if (!FX_grSstControl(GR_CONTROL_RESIZE)) { + /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/ + PostMessage(hWND, WM_CLOSE, 0, 0); + } + } + /* Do the clipping in the glide library */ + grClipWindow(0, 0, FX_grSstScreenWidth(), FX_grSstScreenHeight()); + /* And let the new size set in the context */ + fxMesaUpdateScreenSize(ctx); + } + } +#endif + break; + case WM_ACTIVATE: + break; + case WM_SHOWWINDOW: + break; + case WM_SYSKEYDOWN: + case WM_SYSCHAR: + break; + } + } + + /* Finally call the hWNDOldProc, which handles the resize with the + * now changed window sizes */ + ret = CallWindowProc(hWNDOldProc, hwnd, message, wParam, lParam); + + return ret; +} + +static void +wgl_error (long error) +{ +#define WGL_INVALID_PIXELFORMAT ERROR_INVALID_PIXEL_FORMAT + SetLastError(0xC0000000 /* error severity */ + |0x00070000 /* error facility (who we are) */ + |error); +} + +GLAPI BOOL GLAPIENTRY +wglCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) +{ + return FALSE; +} + +GLAPI HGLRC GLAPIENTRY +wglCreateContext (HDC hdc) +{ + HWND hWnd; + WNDPROC oldProc; + int error; + + if (ctx) { + SetLastError(0); + return NULL; + } + + if (!(hWnd = WindowFromDC(hdc))) { + SetLastError(0); + return NULL; + } + + if (curPFD == 0) { + wgl_error(WGL_INVALID_PIXELFORMAT); + return NULL; + } + + if ((oldProc = (WNDPROC)GetWindowLong(hWnd, GWL_WNDPROC)) != __wglMonitor) { + hWNDOldProc = oldProc; + SetWindowLong(hWnd, GWL_WNDPROC, (LONG)__wglMonitor); + } + + /* always log when debugging, or if user demands */ + if (TDFX_DEBUG || env_check("MESA_FX_INFO", 'r')) { + freopen("MESA.LOG", "w", stderr); + } + + { + RECT cliRect; + ShowWindow(hWnd, SW_SHOWNORMAL); + SetForegroundWindow(hWnd); + Sleep(100); /* a hack for win95 */ + if (env_check("MESA_GLX_FX", 'w') && !(GetWindowLong(hWnd, GWL_STYLE) & WS_POPUP)) { + /* XXX todo - windowed modes */ + error = !(ctx = fxMesaCreateContext((GLuint) hWnd, GR_RESOLUTION_NONE, GR_REFRESH_NONE, pix[curPFD - 1].mesaAttr)); + } else { + GetClientRect(hWnd, &cliRect); + error = !(ctx = fxMesaCreateBestContext((GLuint) hWnd, cliRect.right, cliRect.bottom, pix[curPFD - 1].mesaAttr)); + } + } + + /*if (getenv("SST_DUALHEAD")) + haveDualHead = + ((atoi(getenv("SST_DUALHEAD")) == 1) ? GL_TRUE : GL_FALSE); + else + haveDualHead = GL_FALSE;*/ + + if (error) { + SetLastError(0); + return NULL; + } + + hDC = hdc; + hWND = hWnd; + + /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */ + wglMakeCurrent(hdc, (HGLRC)1); + + return (HGLRC)1; +} + +GLAPI HGLRC GLAPIENTRY +wglCreateLayerContext (HDC hdc, int iLayerPlane) +{ + SetLastError(0); + return NULL; +} + +GLAPI BOOL GLAPIENTRY +wglDeleteContext (HGLRC hglrc) +{ + if (ctx && hglrc == (HGLRC)1) { + + fxMesaDestroyContext(ctx); + + SetWindowLong(WindowFromDC(hDC), GWL_WNDPROC, (LONG) hWNDOldProc); + + ctx = NULL; + hDC = 0; + return TRUE; + } + + SetLastError(0); + + return FALSE; +} + +GLAPI HGLRC GLAPIENTRY +wglGetCurrentContext (VOID) +{ + if (ctx) + return (HGLRC)1; + + SetLastError(0); + return NULL; +} + +GLAPI HDC GLAPIENTRY +wglGetCurrentDC (VOID) +{ + if (ctx) + return hDC; + + SetLastError(0); + return NULL; +} + +GLAPI BOOL GLAPIENTRY +wglSwapIntervalEXT (int interval) +{ + if (ctx == NULL) { + return FALSE; + } + if (interval < 0) { + interval = 0; + } else if (interval > 3) { + interval = 3; + } + ctx->swapInterval = interval; + return TRUE; +} + +GLAPI int GLAPIENTRY +wglGetSwapIntervalEXT (void) +{ + return (ctx == NULL) ? -1 : ctx->swapInterval; +} + +GLAPI BOOL GLAPIENTRY +wglGetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays) +{ + /* gammaTable should be per-context */ + memcpy(arrays, gammaTable, 3 * 256 * sizeof(GLushort)); + return TRUE; +} + +GLAPI BOOL GLAPIENTRY +wglSetDeviceGammaRamp3DFX (HDC hdc, LPVOID arrays) +{ + GLint i, tableSize, inc, index; + GLushort *red, *green, *blue; + FxU32 gammaTableR[256], gammaTableG[256], gammaTableB[256]; + + /* gammaTable should be per-context */ + memcpy(gammaTable, arrays, 3 * 256 * sizeof(GLushort)); + + tableSize = FX_grGetInteger(GR_GAMMA_TABLE_ENTRIES); + inc = 256 / tableSize; + red = (GLushort *)arrays; + green = (GLushort *)arrays + 256; + blue = (GLushort *)arrays + 512; + for (i = 0, index = 0; i < tableSize; i++, index += inc) { + gammaTableR[i] = red[index] >> 8; + gammaTableG[i] = green[index] >> 8; + gammaTableB[i] = blue[index] >> 8; + } + + grLoadGammaTable(tableSize, gammaTableR, gammaTableG, gammaTableB); + + return TRUE; +} + +typedef void *HPBUFFERARB; + +/* WGL_ARB_pixel_format */ +GLAPI BOOL GLAPIENTRY +wglGetPixelFormatAttribivARB (HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + int *piValues) +{ + SetLastError(0); + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglGetPixelFormatAttribfvARB (HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nAttributes, + const int *piAttributes, + FLOAT *pfValues) +{ + SetLastError(0); + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglChoosePixelFormatARB (HDC hdc, + const int *piAttribIList, + const FLOAT *pfAttribFList, + UINT nMaxFormats, + int *piFormats, + UINT *nNumFormats) +{ + SetLastError(0); + return FALSE; +} + +/* WGL_ARB_render_texture */ +GLAPI BOOL GLAPIENTRY +wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer) +{ + SetLastError(0); + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer) +{ + SetLastError(0); + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, + const int *piAttribList) +{ + SetLastError(0); + return FALSE; +} + +/* WGL_ARB_pbuffer */ +GLAPI HPBUFFERARB GLAPIENTRY +wglCreatePbufferARB (HDC hDC, + int iPixelFormat, + int iWidth, + int iHeight, + const int *piAttribList) +{ + SetLastError(0); + return NULL; +} + +GLAPI HDC GLAPIENTRY +wglGetPbufferDCARB (HPBUFFERARB hPbuffer) +{ + SetLastError(0); + return NULL; +} + +GLAPI int GLAPIENTRY +wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC) +{ + SetLastError(0); + return -1; +} + +GLAPI BOOL GLAPIENTRY +wglDestroyPbufferARB (HPBUFFERARB hPbuffer) +{ + SetLastError(0); + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglQueryPbufferARB (HPBUFFERARB hPbuffer, + int iAttribute, + int *piValue) +{ + SetLastError(0); + return FALSE; +} + +GLAPI const char * GLAPIENTRY +wglGetExtensionsStringEXT (void) +{ + return "WGL_3DFX_gamma_control " + "WGL_EXT_swap_control " + "WGL_EXT_extensions_string WGL_ARB_extensions_string" + /*WGL_ARB_pixel_format WGL_ARB_render_texture WGL_ARB_pbuffer*/; +} + +GLAPI const char * GLAPIENTRY +wglGetExtensionsStringARB (HDC hdc) +{ + return wglGetExtensionsStringEXT(); +} + +static struct { + const char *name; + PROC func; +} wgl_ext[] = { + {"wglGetExtensionsStringARB", (PROC)wglGetExtensionsStringARB}, + {"wglGetExtensionsStringEXT", (PROC)wglGetExtensionsStringEXT}, + {"wglSwapIntervalEXT", (PROC)wglSwapIntervalEXT}, + {"wglGetSwapIntervalEXT", (PROC)wglGetSwapIntervalEXT}, + {"wglGetDeviceGammaRamp3DFX", (PROC)wglGetDeviceGammaRamp3DFX}, + {"wglSetDeviceGammaRamp3DFX", (PROC)wglSetDeviceGammaRamp3DFX}, + /* WGL_ARB_pixel_format */ + {"wglGetPixelFormatAttribivARB", (PROC)wglGetPixelFormatAttribivARB}, + {"wglGetPixelFormatAttribfvARB", (PROC)wglGetPixelFormatAttribfvARB}, + {"wglChoosePixelFormatARB", (PROC)wglChoosePixelFormatARB}, + /* WGL_ARB_render_texture */ + {"wglBindTexImageARB", (PROC)wglBindTexImageARB}, + {"wglReleaseTexImageARB", (PROC)wglReleaseTexImageARB}, + {"wglSetPbufferAttribARB", (PROC)wglSetPbufferAttribARB}, + /* WGL_ARB_pbuffer */ + {"wglCreatePbufferARB", (PROC)wglCreatePbufferARB}, + {"wglGetPbufferDCARB", (PROC)wglGetPbufferDCARB}, + {"wglReleasePbufferDCARB", (PROC)wglReleasePbufferDCARB}, + {"wglDestroyPbufferARB", (PROC)wglDestroyPbufferARB}, + {"wglQueryPbufferARB", (PROC)wglQueryPbufferARB}, + {NULL, NULL} +}; + +GLAPI PROC GLAPIENTRY +wglGetProcAddress (LPCSTR lpszProc) +{ + int i; + PROC p = (PROC)_glapi_get_proc_address((const char *)lpszProc); + + /* we can't BlendColor. work around buggy applications */ + if (p && strcmp(lpszProc, "glBlendColor") + && strcmp(lpszProc, "glBlendColorEXT")) + return p; + + for (i = 0; wgl_ext[i].name; i++) { + if (!strcmp(lpszProc, wgl_ext[i].name)) { + return wgl_ext[i].func; + } + } + + SetLastError(0); + return NULL; +} + +GLAPI PROC GLAPIENTRY +wglGetDefaultProcAddress (LPCSTR lpszProc) +{ + SetLastError(0); + return NULL; +} + +GLAPI BOOL GLAPIENTRY +wglMakeCurrent (HDC hdc, HGLRC hglrc) +{ + if ((hdc == NULL) && (hglrc == NULL)) + return TRUE; + + if (!ctx || hglrc != (HGLRC)1 || WindowFromDC(hdc) != hWND) { + SetLastError(0); + return FALSE; + } + + hDC = hdc; + + fxMesaMakeCurrent(ctx); + + return TRUE; +} + +GLAPI BOOL GLAPIENTRY +wglShareLists (HGLRC hglrc1, HGLRC hglrc2) +{ + if (!ctx || hglrc1 != (HGLRC)1 || hglrc1 != hglrc2) { + SetLastError(0); + return FALSE; + } + + return TRUE; +} + +static BOOL +wglUseFontBitmaps_FX (HDC fontDevice, DWORD firstChar, DWORD numChars, + DWORD listBase) +{ + TEXTMETRIC metric; + BITMAPINFO *dibInfo; + HDC bitDevice; + COLORREF tempColor; + int i; + + GetTextMetrics(fontDevice, &metric); + + dibInfo = (BITMAPINFO *)calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1); + dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dibInfo->bmiHeader.biPlanes = 1; + dibInfo->bmiHeader.biBitCount = 1; + dibInfo->bmiHeader.biCompression = BI_RGB; + + bitDevice = CreateCompatibleDC(fontDevice); + + /* Swap fore and back colors so the bitmap has the right polarity */ + tempColor = GetBkColor(bitDevice); + SetBkColor(bitDevice, GetTextColor(bitDevice)); + SetTextColor(bitDevice, tempColor); + + /* Place chars based on base line */ + SetTextAlign(bitDevice, TA_BASELINE); + + for (i = 0; i < (int)numChars; i++) { + SIZE size; + char curChar; + int charWidth, charHeight, bmapWidth, bmapHeight, numBytes, res; + HBITMAP bitObject; + HGDIOBJ origBmap; + unsigned char *bmap; + + curChar = (char)(i + firstChar); /* [koolsmoky] explicit cast */ + + /* Find how high/wide this character is */ + GetTextExtentPoint32(bitDevice, &curChar, 1, &size); + + /* Create the output bitmap */ + charWidth = size.cx; + charHeight = size.cy; + bmapWidth = ((charWidth + 31) / 32) * 32; /* Round up to the next multiple of 32 bits */ + bmapHeight = charHeight; + bitObject = CreateCompatibleBitmap(bitDevice, bmapWidth, bmapHeight); + /*VERIFY(bitObject);*/ + + /* Assign the output bitmap to the device */ + origBmap = SelectObject(bitDevice, bitObject); + + PatBlt(bitDevice, 0, 0, bmapWidth, bmapHeight, BLACKNESS); + + /* Use our source font on the device */ + SelectObject(bitDevice, GetCurrentObject(fontDevice, OBJ_FONT)); + + /* Draw the character */ + TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1); + + /* Unselect our bmap object */ + SelectObject(bitDevice, origBmap); + + /* Convert the display dependant representation to a 1 bit deep DIB */ + numBytes = (bmapWidth * bmapHeight) / 8; + bmap = MALLOC(numBytes); + dibInfo->bmiHeader.biWidth = bmapWidth; + dibInfo->bmiHeader.biHeight = bmapHeight; + res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap, + dibInfo, DIB_RGB_COLORS); + + /* Create the GL object */ + glNewList(i + listBase, GL_COMPILE); + glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent, + charWidth, 0.0, bmap); + glEndList(); + /* CheckGL(); */ + + /* Destroy the bmap object */ + DeleteObject(bitObject); + + /* Deallocate the bitmap data */ + FREE(bmap); + } + + /* Destroy the DC */ + DeleteDC(bitDevice); + + FREE(dibInfo); + + return TRUE; +} + +GLAPI BOOL GLAPIENTRY +wglUseFontBitmapsW (HDC hdc, DWORD first, DWORD count, DWORD listBase) +{ + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglUseFontOutlinesA (HDC hdc, DWORD first, DWORD count, + DWORD listBase, FLOAT deviation, + FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) +{ + SetLastError(0); + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglUseFontOutlinesW (HDC hdc, DWORD first, DWORD count, + DWORD listBase, FLOAT deviation, + FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) +{ + SetLastError(0); + return FALSE; +} + + +GLAPI BOOL GLAPIENTRY +wglSwapLayerBuffers (HDC hdc, UINT fuPlanes) +{ + if (ctx && WindowFromDC(hdc) == hWND) { + fxMesaSwapBuffers(); + + return TRUE; + } + + SetLastError(0); + return FALSE; +} + +static int +pfd_tablen (void) +{ + /* we should take an envvar for `fxMesaSelectCurrentBoard' */ + return (fxMesaSelectCurrentBoard(0) < GR_SSTTYPE_Voodoo4) + ? 2 /* only 16bit entries */ + : sizeof(pix) / sizeof(pix[0]); /* full table */ +} + +GLAPI int GLAPIENTRY +wglChoosePixelFormat (HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd) +{ + int i, best = -1, qt_valid_pix; + PIXELFORMATDESCRIPTOR pfd = *ppfd; + + qt_valid_pix = pfd_tablen(); + +#if 1 || QUAKE2 || GORE + /* QUAKE2: 24+32 */ + /* GORE : 24+16 */ + if ((pfd.cColorBits == 24) || (pfd.cColorBits == 32)) { + /* the first 2 entries are 16bit */ + pfd.cColorBits = (qt_valid_pix > 2) ? 32 : 16; + } + if (pfd.cColorBits == 32) { + pfd.cDepthBits = 24; + } else if (pfd.cColorBits == 16) { + pfd.cDepthBits = 16; + } +#endif + + if (pfd.nSize != sizeof(PIXELFORMATDESCRIPTOR) || pfd.nVersion != 1) { + SetLastError(0); + return 0; + } + + for (i = 0; i < qt_valid_pix; i++) { + if (pfd.cColorBits > 0 && pix[i].pfd.cColorBits != pfd.cColorBits) + continue; + + if ((pfd.dwFlags & PFD_DRAW_TO_WINDOW) + && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) continue; + if ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) + && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) continue; + if ((pfd.dwFlags & PFD_SUPPORT_GDI) + && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI)) continue; + if ((pfd.dwFlags & PFD_SUPPORT_OPENGL) + && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) continue; + if (!(pfd.dwFlags & PFD_DOUBLEBUFFER_DONTCARE) + && ((pfd.dwFlags & PFD_DOUBLEBUFFER) != + (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) continue; +#if 1 /* Doom3 fails here! */ + if (!(pfd.dwFlags & PFD_STEREO_DONTCARE) + && ((pfd.dwFlags & PFD_STEREO) != + (pix[i].pfd.dwFlags & PFD_STEREO))) continue; +#endif + + if (pfd.cDepthBits > 0 && pix[i].pfd.cDepthBits == 0) + continue; /* need depth buffer */ + + if (pfd.cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0) + continue; /* need alpha buffer */ + +#if 0 /* regression bug? */ + if (pfd.cStencilBits > 0 && pix[i].pfd.cStencilBits == 0) + continue; /* need stencil buffer */ +#endif + + if (pfd.iPixelType == pix[i].pfd.iPixelType) { + best = i + 1; + break; + } + } + + if (best == -1) { + FILE *err = fopen("MESA.LOG", "w"); + if (err != NULL) { + fprintf(err, "wglChoosePixelFormat failed\n"); + fprintf(err, "\tnSize = %d\n", ppfd->nSize); + fprintf(err, "\tnVersion = %d\n", ppfd->nVersion); + fprintf(err, "\tdwFlags = %lu\n", ppfd->dwFlags); + fprintf(err, "\tiPixelType = %d\n", ppfd->iPixelType); + fprintf(err, "\tcColorBits = %d\n", ppfd->cColorBits); + fprintf(err, "\tcRedBits = %d\n", ppfd->cRedBits); + fprintf(err, "\tcRedShift = %d\n", ppfd->cRedShift); + fprintf(err, "\tcGreenBits = %d\n", ppfd->cGreenBits); + fprintf(err, "\tcGreenShift = %d\n", ppfd->cGreenShift); + fprintf(err, "\tcBlueBits = %d\n", ppfd->cBlueBits); + fprintf(err, "\tcBlueShift = %d\n", ppfd->cBlueShift); + fprintf(err, "\tcAlphaBits = %d\n", ppfd->cAlphaBits); + fprintf(err, "\tcAlphaShift = %d\n", ppfd->cAlphaShift); + fprintf(err, "\tcAccumBits = %d\n", ppfd->cAccumBits); + fprintf(err, "\tcAccumRedBits = %d\n", ppfd->cAccumRedBits); + fprintf(err, "\tcAccumGreenBits = %d\n", ppfd->cAccumGreenBits); + fprintf(err, "\tcAccumBlueBits = %d\n", ppfd->cAccumBlueBits); + fprintf(err, "\tcAccumAlphaBits = %d\n", ppfd->cAccumAlphaBits); + fprintf(err, "\tcDepthBits = %d\n", ppfd->cDepthBits); + fprintf(err, "\tcStencilBits = %d\n", ppfd->cStencilBits); + fprintf(err, "\tcAuxBuffers = %d\n", ppfd->cAuxBuffers); + fprintf(err, "\tiLayerType = %d\n", ppfd->iLayerType); + fprintf(err, "\tbReserved = %d\n", ppfd->bReserved); + fprintf(err, "\tdwLayerMask = %lu\n", ppfd->dwLayerMask); + fprintf(err, "\tdwVisibleMask = %lu\n", ppfd->dwVisibleMask); + fprintf(err, "\tdwDamageMask = %lu\n", ppfd->dwDamageMask); + fclose(err); + } + + SetLastError(0); + return 0; + } + + return best; +} + +GLAPI int GLAPIENTRY +ChoosePixelFormat (HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd) +{ + + return wglChoosePixelFormat(hdc, ppfd); +} + +GLAPI int GLAPIENTRY +wglDescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd) +{ + int qt_valid_pix; + + qt_valid_pix = pfd_tablen(); + + if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix || + ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) { + SetLastError(0); + return qt_valid_pix; + } + + if (nBytes != 0) + *ppfd = pix[iPixelFormat - 1].pfd; + + return qt_valid_pix; +} + +GLAPI int GLAPIENTRY +DescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd) +{ + return wglDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd); +} + +GLAPI int GLAPIENTRY +wglGetPixelFormat (HDC hdc) +{ + if (curPFD == 0) { + SetLastError(0); + return 0; + } + + return curPFD; +} + +GLAPI int GLAPIENTRY +GetPixelFormat (HDC hdc) +{ + return wglGetPixelFormat(hdc); +} + +GLAPI BOOL GLAPIENTRY +wglSetPixelFormat (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd) +{ + int qt_valid_pix; + + qt_valid_pix = pfd_tablen(); + + if (iPixelFormat < 1 || iPixelFormat > qt_valid_pix) { + if (ppfd == NULL) { + PIXELFORMATDESCRIPTOR my_pfd; + if (!wglDescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &my_pfd)) { + SetLastError(0); + return FALSE; + } + } else if (ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) { + SetLastError(0); + return FALSE; + } + } + curPFD = iPixelFormat; + + return TRUE; +} + +GLAPI BOOL GLAPIENTRY +wglSwapBuffers (HDC hdc) +{ + if (!ctx) { + SetLastError(0); + return FALSE; + } + + fxMesaSwapBuffers(); + + return TRUE; +} + +GLAPI BOOL GLAPIENTRY +SetPixelFormat (HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd) +{ + return wglSetPixelFormat(hdc, iPixelFormat, ppfd); +} + +GLAPI BOOL GLAPIENTRY +SwapBuffers(HDC hdc) +{ + return wglSwapBuffers(hdc); +} + +static FIXED +FixedFromDouble (double d) +{ + struct { + FIXED f; + long l; + } pun; + pun.l = (long)(d * 65536L); + return pun.f; +} + +/* +** This was yanked from windows/gdi/wgl.c +*/ +GLAPI BOOL GLAPIENTRY +wglUseFontBitmapsA (HDC hdc, DWORD first, DWORD count, DWORD listBase) +{ + int i; + GLuint font_list; + DWORD size; + GLYPHMETRICS gm; + HANDLE hBits; + LPSTR lpBits; + MAT2 mat; + int success = TRUE; + + font_list = listBase; + + mat.eM11 = FixedFromDouble(1); + mat.eM12 = FixedFromDouble(0); + mat.eM21 = FixedFromDouble(0); + mat.eM22 = FixedFromDouble(-1); + + memset(&gm, 0, sizeof(gm)); + + /* + ** If we can't get the glyph outline, it may be because this is a fixed + ** font. Try processing it that way. + */ + if (GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) == GDI_ERROR) { + return wglUseFontBitmaps_FX(hdc, first, count, listBase); + } + + /* + ** Otherwise process all desired characters. + */ + for (i = 0; i < count; i++) { + DWORD err; + + glNewList(font_list + i, GL_COMPILE); + + /* allocate space for the bitmap/outline */ + size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, &gm, 0, NULL, &mat); + if (size == GDI_ERROR) { + glEndList(); + err = GetLastError(); + success = FALSE; + continue; + } + + hBits = GlobalAlloc(GHND, size + 1); + lpBits = GlobalLock(hBits); + + err = GetGlyphOutline(hdc, /* handle to device context */ + first + i, /* character to query */ + GGO_BITMAP, /* format of data to return */ + &gm, /* pointer to structure for metrics */ + size, /* size of buffer for data */ + lpBits, /* pointer to buffer for data */ + &mat /* pointer to transformation */ + /* matrix structure */ + ); + + if (err == GDI_ERROR) { + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList(); + err = GetLastError(); + success = FALSE; + continue; + } + + glBitmap(gm.gmBlackBoxX, gm.gmBlackBoxY, + -gm.gmptGlyphOrigin.x, + gm.gmptGlyphOrigin.y, + gm.gmCellIncX, gm.gmCellIncY, + (const GLubyte *)lpBits); + + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList(); + } + + return success; +} + +GLAPI BOOL GLAPIENTRY +wglDescribeLayerPlane (HDC hdc, int iPixelFormat, int iLayerPlane, + UINT nBytes, LPLAYERPLANEDESCRIPTOR ppfd) +{ + SetLastError(0); + return FALSE; +} + +GLAPI int GLAPIENTRY +wglGetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart, + int cEntries, COLORREF *pcr) +{ + SetLastError(0); + return FALSE; +} + +GLAPI BOOL GLAPIENTRY +wglRealizeLayerPalette (HDC hdc, int iLayerPlane, BOOL bRealize) +{ + SetLastError(0); + return FALSE; +} + +GLAPI int GLAPIENTRY +wglSetLayerPaletteEntries (HDC hdc, int iLayerPlane, int iStart, + int cEntries, CONST COLORREF *pcr) +{ + SetLastError(0); + return FALSE; +} + + +/*************************************************************************** + * [dBorca] simplistic ICD implementation, based on ICD code by Gregor Anich + */ + +typedef struct _icdTable { + DWORD size; + PROC table[336]; +} ICDTABLE, *PICDTABLE; + +#ifdef USE_MGL_NAMESPACE +#define GL_FUNC(func) mgl##func +#else +#define GL_FUNC(func) gl##func +#endif + +static ICDTABLE icdTable = { 336, { +#define ICD_ENTRY(func) (PROC)GL_FUNC(func), +#include "../icd/icdlist.h" +#undef ICD_ENTRY +} }; + + +GLAPI BOOL GLAPIENTRY +DrvCopyContext (HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) +{ + return wglCopyContext(hglrcSrc, hglrcDst, mask); +} + + +GLAPI HGLRC GLAPIENTRY +DrvCreateContext (HDC hdc) +{ + return wglCreateContext(hdc); +} + + +GLAPI BOOL GLAPIENTRY +DrvDeleteContext (HGLRC hglrc) +{ + return wglDeleteContext(hglrc); +} + + +GLAPI HGLRC GLAPIENTRY +DrvCreateLayerContext (HDC hdc, int iLayerPlane) +{ + return wglCreateContext(hdc); +} + + +GLAPI PICDTABLE GLAPIENTRY +DrvSetContext (HDC hdc, HGLRC hglrc, void *callback) +{ + return wglMakeCurrent(hdc, hglrc) ? &icdTable : NULL; +} + + +GLAPI BOOL GLAPIENTRY +DrvReleaseContext (HGLRC hglrc) +{ + return TRUE; +} + + +GLAPI BOOL GLAPIENTRY +DrvShareLists (HGLRC hglrc1, HGLRC hglrc2) +{ + return wglShareLists(hglrc1, hglrc2); +} + + +GLAPI BOOL GLAPIENTRY +DrvDescribeLayerPlane (HDC hdc, int iPixelFormat, + int iLayerPlane, UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + return wglDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd); +} + + +GLAPI int GLAPIENTRY +DrvSetLayerPaletteEntries (HDC hdc, int iLayerPlane, + int iStart, int cEntries, CONST COLORREF *pcr) +{ + return wglSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); +} + + +GLAPI int GLAPIENTRY +DrvGetLayerPaletteEntries (HDC hdc, int iLayerPlane, + int iStart, int cEntries, COLORREF *pcr) +{ + return wglGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); +} + + +GLAPI BOOL GLAPIENTRY +DrvRealizeLayerPalette (HDC hdc, int iLayerPlane, BOOL bRealize) +{ + return wglRealizeLayerPalette(hdc, iLayerPlane, bRealize); +} + + +GLAPI BOOL GLAPIENTRY +DrvSwapLayerBuffers (HDC hdc, UINT fuPlanes) +{ + return wglSwapLayerBuffers(hdc, fuPlanes); +} + +GLAPI int GLAPIENTRY +DrvDescribePixelFormat (HDC hdc, int iPixelFormat, UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd) +{ + return wglDescribePixelFormat(hdc, iPixelFormat, nBytes, ppfd); +} + + +GLAPI PROC GLAPIENTRY +DrvGetProcAddress (LPCSTR lpszProc) +{ + return wglGetProcAddress(lpszProc); +} + + +GLAPI BOOL GLAPIENTRY +DrvSetPixelFormat (HDC hdc, int iPixelFormat) +{ + return wglSetPixelFormat(hdc, iPixelFormat, NULL); +} + + +GLAPI BOOL GLAPIENTRY +DrvSwapBuffers (HDC hdc) +{ + return wglSwapBuffers(hdc); +} + + +GLAPI BOOL GLAPIENTRY +DrvValidateVersion (DWORD version) +{ + (void)version; + return TRUE; +} + + +#if (_MSC_VER >= 1200) +#pragma warning( pop ) +#endif + +#endif /* FX */ diff --git a/mesalib/src/mesa/drivers/windows/gdi/colors.h b/mesalib/src/mesa/drivers/windows/gdi/colors.h new file mode 100644 index 000000000..03e512c1f --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gdi/colors.h @@ -0,0 +1,29 @@ +/* Values for wmesa->pixelformat: */ + +#define PF_8A8B8G8R 3 /* 32-bit TrueColor: 8-A, 8-B, 8-G, 8-R */ +#define PF_8R8G8B 4 /* 32-bit TrueColor: 8-R, 8-G, 8-B */ +#define PF_5R6G5B 5 /* 16-bit TrueColor: 5-R, 6-G, 5-B bits */ +#define PF_DITHER8 6 /* Dithered RGB using a lookup table */ +#define PF_LOOKUP 7 /* Undithered RGB using a lookup table */ +#define PF_GRAYSCALE 10 /* Grayscale or StaticGray */ +#define PF_BADFORMAT 11 +#define PF_INDEX8 12 + + +#define BGR8(r,g,b) (unsigned)(((BYTE)((b & 0xc0) | ((g & 0xe0)>>2) | \ + ((r & 0xe0)>>5)))) + +/* Windows uses 5,5,5 for 16-bit */ +#define BGR16(r,g,b) ( (((unsigned short)b ) >> 3) | \ + (((unsigned short)g & 0xf8) << 2) | \ + (((unsigned short)r & 0xf8) << 7) ) + +#define BGR24(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ + ((WORD)((BYTE)(g))<<8))| \ + (((DWORD)(BYTE)(r))<<16))) + +#define BGR32(r,g,b) (unsigned long)((DWORD)(((BYTE)(b)| \ + ((WORD)((BYTE)(g))<<8))| \ + (((DWORD)(BYTE)(r))<<16))) + + diff --git a/mesalib/src/mesa/drivers/windows/gdi/mesa.def b/mesalib/src/mesa/drivers/windows/gdi/mesa.def new file mode 100644 index 000000000..bd3e5b213 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gdi/mesa.def @@ -0,0 +1,979 @@ +; DO NOT EDIT - This file generated automatically by mesadef.py script +;DESCRIPTION 'Mesa (OpenGL work-alike) for Win32' +VERSION 6.5 +; +; Module definition file for Mesa (OPENGL32.DLL) +; +; Note: The OpenGL functions use the STDCALL +; function calling convention. Microsoft's +; OPENGL32 uses this convention and so must the +; Mesa OPENGL32 so that the Mesa DLL can be used +; as a drop-in replacement. +; +; The linker exports STDCALL entry points with +; 'decorated' names; e.g., _glBegin@0, where the +; trailing number is the number of bytes of +; parameter data pushed onto the stack. The +; callee is responsible for popping this data +; off the stack, usually via a RETF n instruction. +; +; However, the Microsoft OPENGL32.DLL does not export +; the decorated names, even though the calling convention +; is STDCALL. So, this module definition file is +; needed to force the Mesa OPENGL32.DLL to export the +; symbols in the same manner as the Microsoft DLL. +; Were it not for this problem, this file would not +; be needed (for the gl* functions) since the entry +; points are compiled with dllexport declspec. +; +; However, this file is still needed to export "internal" +; Mesa symbols for the benefit of the OSMESA32.DLL. +; +EXPORTS + glNewList + glEndList + glCallList + glCallLists + glDeleteLists + glGenLists + glListBase + glBegin + glBitmap + glColor3b + glColor3bv + glColor3d + glColor3dv + glColor3f + glColor3fv + glColor3i + glColor3iv + glColor3s + glColor3sv + glColor3ub + glColor3ubv + glColor3ui + glColor3uiv + glColor3us + glColor3usv + glColor4b + glColor4bv + glColor4d + glColor4dv + glColor4f + glColor4fv + glColor4i + glColor4iv + glColor4s + glColor4sv + glColor4ub + glColor4ubv + glColor4ui + glColor4uiv + glColor4us + glColor4usv + glEdgeFlag + glEdgeFlagv + glEnd + glIndexd + glIndexdv + glIndexf + glIndexfv + glIndexi + glIndexiv + glIndexs + glIndexsv + glNormal3b + glNormal3bv + glNormal3d + glNormal3dv + glNormal3f + glNormal3fv + glNormal3i + glNormal3iv + glNormal3s + glNormal3sv + glRasterPos2d + glRasterPos2dv + glRasterPos2f + glRasterPos2fv + glRasterPos2i + glRasterPos2iv + glRasterPos2s + glRasterPos2sv + glRasterPos3d + glRasterPos3dv + glRasterPos3f + glRasterPos3fv + glRasterPos3i + glRasterPos3iv + glRasterPos3s + glRasterPos3sv + glRasterPos4d + glRasterPos4dv + glRasterPos4f + glRasterPos4fv + glRasterPos4i + glRasterPos4iv + glRasterPos4s + glRasterPos4sv + glRectd + glRectdv + glRectf + glRectfv + glRecti + glRectiv + glRects + glRectsv + glTexCoord1d + glTexCoord1dv + glTexCoord1f + glTexCoord1fv + glTexCoord1i + glTexCoord1iv + glTexCoord1s + glTexCoord1sv + glTexCoord2d + glTexCoord2dv + glTexCoord2f + glTexCoord2fv + glTexCoord2i + glTexCoord2iv + glTexCoord2s + glTexCoord2sv + glTexCoord3d + glTexCoord3dv + glTexCoord3f + glTexCoord3fv + glTexCoord3i + glTexCoord3iv + glTexCoord3s + glTexCoord3sv + glTexCoord4d + glTexCoord4dv + glTexCoord4f + glTexCoord4fv + glTexCoord4i + glTexCoord4iv + glTexCoord4s + glTexCoord4sv + glVertex2d + glVertex2dv + glVertex2f + glVertex2fv + glVertex2i + glVertex2iv + glVertex2s + glVertex2sv + glVertex3d + glVertex3dv + glVertex3f + glVertex3fv + glVertex3i + glVertex3iv + glVertex3s + glVertex3sv + glVertex4d + glVertex4dv + glVertex4f + glVertex4fv + glVertex4i + glVertex4iv + glVertex4s + glVertex4sv + glClipPlane + glColorMaterial + glCullFace + glFogf + glFogfv + glFogi + glFogiv + glFrontFace + glHint + glLightf + glLightfv + glLighti + glLightiv + glLightModelf + glLightModelfv + glLightModeli + glLightModeliv + glLineStipple + glLineWidth + glMaterialf + glMaterialfv + glMateriali + glMaterialiv + glPointSize + glPolygonMode + glPolygonStipple + glScissor + glShadeModel + glTexParameterf + glTexParameterfv + glTexParameteri + glTexParameteriv + glTexImage1D + glTexImage2D + glTexEnvf + glTexEnvfv + glTexEnvi + glTexEnviv + glTexGend + glTexGendv + glTexGenf + glTexGenfv + glTexGeni + glTexGeniv + glFeedbackBuffer + glSelectBuffer + glRenderMode + glInitNames + glLoadName + glPassThrough + glPopName + glPushName + glDrawBuffer + glClear + glClearAccum + glClearIndex + glClearColor + glClearStencil + glClearDepth + glStencilMask + glColorMask + glDepthMask + glIndexMask + glAccum + glDisable + glEnable + glFinish + glFlush + glPopAttrib + glPushAttrib + glMap1d + glMap1f + glMap2d + glMap2f + glMapGrid1d + glMapGrid1f + glMapGrid2d + glMapGrid2f + glEvalCoord1d + glEvalCoord1dv + glEvalCoord1f + glEvalCoord1fv + glEvalCoord2d + glEvalCoord2dv + glEvalCoord2f + glEvalCoord2fv + glEvalMesh1 + glEvalPoint1 + glEvalMesh2 + glEvalPoint2 + glAlphaFunc + glBlendFunc + glLogicOp + glStencilFunc + glStencilOp + glDepthFunc + glPixelZoom + glPixelTransferf + glPixelTransferi + glPixelStoref + glPixelStorei + glPixelMapfv + glPixelMapuiv + glPixelMapusv + glReadBuffer + glCopyPixels + glReadPixels + glDrawPixels + glGetBooleanv + glGetClipPlane + glGetDoublev + glGetError + glGetFloatv + glGetIntegerv + glGetLightfv + glGetLightiv + glGetMapdv + glGetMapfv + glGetMapiv + glGetMaterialfv + glGetMaterialiv + glGetPixelMapfv + glGetPixelMapuiv + glGetPixelMapusv + glGetPolygonStipple + glGetString + glGetTexEnvfv + glGetTexEnviv + glGetTexGendv + glGetTexGenfv + glGetTexGeniv + glGetTexImage + glGetTexParameterfv + glGetTexParameteriv + glGetTexLevelParameterfv + glGetTexLevelParameteriv + glIsEnabled + glIsList + glDepthRange + glFrustum + glLoadIdentity + glLoadMatrixf + glLoadMatrixd + glMatrixMode + glMultMatrixf + glMultMatrixd + glOrtho + glPopMatrix + glPushMatrix + glRotated + glRotatef + glScaled + glScalef + glTranslated + glTranslatef + glViewport + glArrayElement + glColorPointer + glDisableClientState + glDrawArrays + glDrawElements + glEdgeFlagPointer + glEnableClientState + glGetPointerv + glIndexPointer + glInterleavedArrays + glNormalPointer + glTexCoordPointer + glVertexPointer + glPolygonOffset + glCopyTexImage1D + glCopyTexImage2D + glCopyTexSubImage1D + glCopyTexSubImage2D + glTexSubImage1D + glTexSubImage2D + glAreTexturesResident + glBindTexture + glDeleteTextures + glGenTextures + glIsTexture + glPrioritizeTextures + glIndexub + glIndexubv + glPopClientAttrib + glPushClientAttrib + glBlendColor + glBlendEquation + glDrawRangeElements + glColorTable + glColorTableParameterfv + glColorTableParameteriv + glCopyColorTable + glGetColorTable + glGetColorTableParameterfv + glGetColorTableParameteriv + glColorSubTable + glCopyColorSubTable + glConvolutionFilter1D + glConvolutionFilter2D + glConvolutionParameterf + glConvolutionParameterfv + glConvolutionParameteri + glConvolutionParameteriv + glCopyConvolutionFilter1D + glCopyConvolutionFilter2D + glGetConvolutionFilter + glGetConvolutionParameterfv + glGetConvolutionParameteriv + glGetSeparableFilter + glSeparableFilter2D + glGetHistogram + glGetHistogramParameterfv + glGetHistogramParameteriv + glGetMinmax + glGetMinmaxParameterfv + glGetMinmaxParameteriv + glHistogram + glMinmax + glResetHistogram + glResetMinmax + glTexImage3D + glTexSubImage3D + glCopyTexSubImage3D + glActiveTextureARB + glClientActiveTextureARB + glMultiTexCoord1dARB + glMultiTexCoord1dvARB + glMultiTexCoord1fARB + glMultiTexCoord1fvARB + glMultiTexCoord1iARB + glMultiTexCoord1ivARB + glMultiTexCoord1sARB + glMultiTexCoord1svARB + glMultiTexCoord2dARB + glMultiTexCoord2dvARB + glMultiTexCoord2fARB + glMultiTexCoord2fvARB + glMultiTexCoord2iARB + glMultiTexCoord2ivARB + glMultiTexCoord2sARB + glMultiTexCoord2svARB + glMultiTexCoord3dARB + glMultiTexCoord3dvARB + glMultiTexCoord3fARB + glMultiTexCoord3fvARB + glMultiTexCoord3iARB + glMultiTexCoord3ivARB + glMultiTexCoord3sARB + glMultiTexCoord3svARB + glMultiTexCoord4dARB + glMultiTexCoord4dvARB + glMultiTexCoord4fARB + glMultiTexCoord4fvARB + glMultiTexCoord4iARB + glMultiTexCoord4ivARB + glMultiTexCoord4sARB + glMultiTexCoord4svARB + glLoadTransposeMatrixfARB + glLoadTransposeMatrixdARB + glMultTransposeMatrixfARB + glMultTransposeMatrixdARB + glSampleCoverageARB + glCompressedTexImage3DARB + glCompressedTexImage2DARB + glCompressedTexImage1DARB + glCompressedTexSubImage3DARB + glCompressedTexSubImage2DARB + glCompressedTexSubImage1DARB + glGetCompressedTexImageARB + glActiveTexture + glClientActiveTexture + glMultiTexCoord1d + glMultiTexCoord1dv + glMultiTexCoord1f + glMultiTexCoord1fv + glMultiTexCoord1i + glMultiTexCoord1iv + glMultiTexCoord1s + glMultiTexCoord1sv + glMultiTexCoord2d + glMultiTexCoord2dv + glMultiTexCoord2f + glMultiTexCoord2fv + glMultiTexCoord2i + glMultiTexCoord2iv + glMultiTexCoord2s + glMultiTexCoord2sv + glMultiTexCoord3d + glMultiTexCoord3dv + glMultiTexCoord3f + glMultiTexCoord3fv + glMultiTexCoord3i + glMultiTexCoord3iv + glMultiTexCoord3s + glMultiTexCoord3sv + glMultiTexCoord4d + glMultiTexCoord4dv + glMultiTexCoord4f + glMultiTexCoord4fv + glMultiTexCoord4i + glMultiTexCoord4iv + glMultiTexCoord4s + glMultiTexCoord4sv + glLoadTransposeMatrixf + glLoadTransposeMatrixd + glMultTransposeMatrixf + glMultTransposeMatrixd + glSampleCoverage + glCompressedTexImage3D + glCompressedTexImage2D + glCompressedTexImage1D + glCompressedTexSubImage3D + glCompressedTexSubImage2D + glCompressedTexSubImage1D + glGetCompressedTexImage + glBlendColorEXT + glPolygonOffsetEXT + glTexImage3DEXT + glTexSubImage3DEXT + glTexSubImage1DEXT + glTexSubImage2DEXT + glCopyTexImage1DEXT + glCopyTexImage2DEXT + glCopyTexSubImage1DEXT + glCopyTexSubImage2DEXT + glCopyTexSubImage3DEXT + glAreTexturesResidentEXT + glBindTextureEXT + glDeleteTexturesEXT + glGenTexturesEXT + glIsTextureEXT + glPrioritizeTexturesEXT + glArrayElementEXT + glColorPointerEXT + glDrawArraysEXT + glEdgeFlagPointerEXT + glGetPointervEXT + glIndexPointerEXT + glNormalPointerEXT + glTexCoordPointerEXT + glVertexPointerEXT + glBlendEquationEXT + glPointParameterfEXT + glPointParameterfvEXT + glPointParameterfARB + glPointParameterfvARB + glColorTableEXT + glGetColorTableEXT + glGetColorTableParameterivEXT + glGetColorTableParameterfvEXT + glLockArraysEXT + glUnlockArraysEXT + glDrawRangeElementsEXT + glSecondaryColor3bEXT + glSecondaryColor3bvEXT + glSecondaryColor3dEXT + glSecondaryColor3dvEXT + glSecondaryColor3fEXT + glSecondaryColor3fvEXT + glSecondaryColor3iEXT + glSecondaryColor3ivEXT + glSecondaryColor3sEXT + glSecondaryColor3svEXT + glSecondaryColor3ubEXT + glSecondaryColor3ubvEXT + glSecondaryColor3uiEXT + glSecondaryColor3uivEXT + glSecondaryColor3usEXT + glSecondaryColor3usvEXT + glSecondaryColorPointerEXT + glMultiDrawArraysEXT + glMultiDrawElementsEXT + glFogCoordfEXT + glFogCoordfvEXT + glFogCoorddEXT + glFogCoorddvEXT + glFogCoordPointerEXT + glBlendFuncSeparateEXT + glFlushVertexArrayRangeNV + glVertexArrayRangeNV + glCombinerParameterfvNV + glCombinerParameterfNV + glCombinerParameterivNV + glCombinerParameteriNV + glCombinerInputNV + glCombinerOutputNV + glFinalCombinerInputNV + glGetCombinerInputParameterfvNV + glGetCombinerInputParameterivNV + glGetCombinerOutputParameterfvNV + glGetCombinerOutputParameterivNV + glGetFinalCombinerInputParameterfvNV + glGetFinalCombinerInputParameterivNV + glResizeBuffersMESA + glWindowPos2dMESA + glWindowPos2dvMESA + glWindowPos2fMESA + glWindowPos2fvMESA + glWindowPos2iMESA + glWindowPos2ivMESA + glWindowPos2sMESA + glWindowPos2svMESA + glWindowPos3dMESA + glWindowPos3dvMESA + glWindowPos3fMESA + glWindowPos3fvMESA + glWindowPos3iMESA + glWindowPos3ivMESA + glWindowPos3sMESA + glWindowPos3svMESA + glWindowPos4dMESA + glWindowPos4dvMESA + glWindowPos4fMESA + glWindowPos4fvMESA + glWindowPos4iMESA + glWindowPos4ivMESA + glWindowPos4sMESA + glWindowPos4svMESA + glWindowPos2dARB + glWindowPos2fARB + glWindowPos2iARB + glWindowPos2sARB + glWindowPos2dvARB + glWindowPos2fvARB + glWindowPos2ivARB + glWindowPos2svARB + glWindowPos3dARB + glWindowPos3fARB + glWindowPos3iARB + glWindowPos3sARB + glWindowPos3dvARB + glWindowPos3fvARB + glWindowPos3ivARB + glWindowPos3svARB + glAreProgramsResidentNV + glBindProgramNV + glDeleteProgramsNV + glExecuteProgramNV + glGenProgramsNV + glGetProgramParameterdvNV + glGetProgramParameterfvNV + glGetProgramivNV + glGetProgramStringNV + glGetTrackMatrixivNV + glGetVertexAttribdvNV + glGetVertexAttribfvNV + glGetVertexAttribivNV + glGetVertexAttribPointervNV + glIsProgramNV + glLoadProgramNV + glProgramParameter4dNV + glProgramParameter4dvNV + glProgramParameter4fNV + glProgramParameter4fvNV + glProgramParameters4dvNV + glProgramParameters4fvNV + glRequestResidentProgramsNV + glTrackMatrixNV + glVertexAttribPointerNV + glVertexAttrib1dNV + glVertexAttrib1dvNV + glVertexAttrib1fNV + glVertexAttrib1fvNV + glVertexAttrib1sNV + glVertexAttrib1svNV + glVertexAttrib2dNV + glVertexAttrib2dvNV + glVertexAttrib2fNV + glVertexAttrib2fvNV + glVertexAttrib2sNV + glVertexAttrib2svNV + glVertexAttrib3dNV + glVertexAttrib3dvNV + glVertexAttrib3fNV + glVertexAttrib3fvNV + glVertexAttrib3sNV + glVertexAttrib3svNV + glVertexAttrib4dNV + glVertexAttrib4dvNV + glVertexAttrib4fNV + glVertexAttrib4fvNV + glVertexAttrib4sNV + glVertexAttrib4svNV + glVertexAttrib4ubNV + glVertexAttrib4ubvNV + glVertexAttribs1dvNV + glVertexAttribs1fvNV + glVertexAttribs1svNV + glVertexAttribs2dvNV + glVertexAttribs2fvNV + glVertexAttribs2svNV + glVertexAttribs3dvNV + glVertexAttribs3fvNV + glVertexAttribs3svNV + glVertexAttribs4dvNV + glVertexAttribs4fvNV + glVertexAttribs4svNV + glVertexAttribs4ubvNV + glPointParameteriNV + glPointParameterivNV + glFogCoordf + glFogCoordfv + glFogCoordd + glFogCoorddv + glFogCoordPointer + glMultiDrawArrays + glMultiDrawElements + glPointParameterf + glPointParameterfv + glPointParameteri + glPointParameteriv + glSecondaryColor3b + glSecondaryColor3bv + glSecondaryColor3d + glSecondaryColor3dv + glSecondaryColor3f + glSecondaryColor3fv + glSecondaryColor3i + glSecondaryColor3iv + glSecondaryColor3s + glSecondaryColor3sv + glSecondaryColor3ub + glSecondaryColor3ubv + glSecondaryColor3ui + glSecondaryColor3uiv + glSecondaryColor3us + glSecondaryColor3usv + glSecondaryColorPointer + glWindowPos2d + glWindowPos2dv + glWindowPos2f + glWindowPos2fv + glWindowPos2i + glWindowPos2iv + glWindowPos2s + glWindowPos2sv + glWindowPos3d + glWindowPos3dv + glWindowPos3f + glWindowPos3fv + glWindowPos3i + glWindowPos3iv + glWindowPos3s + glWindowPos3sv + glVertexAttrib1sARB + glVertexAttrib1fARB + glVertexAttrib1dARB + glVertexAttrib2sARB + glVertexAttrib2fARB + glVertexAttrib2dARB + glVertexAttrib3sARB + glVertexAttrib3fARB + glVertexAttrib3dARB + glVertexAttrib4sARB + glVertexAttrib4fARB + glVertexAttrib4dARB + glVertexAttrib4NubARB + glVertexAttrib1svARB + glVertexAttrib1fvARB + glVertexAttrib1dvARB + glVertexAttrib2svARB + glVertexAttrib2fvARB + glVertexAttrib2dvARB + glVertexAttrib3svARB + glVertexAttrib3fvARB + glVertexAttrib3dvARB + glVertexAttrib4bvARB + glVertexAttrib4svARB + glVertexAttrib4ivARB + glVertexAttrib4ubvARB + glVertexAttrib4usvARB + glVertexAttrib4uivARB + glVertexAttrib4fvARB + glVertexAttrib4dvARB + glVertexAttrib4NbvARB + glVertexAttrib4NsvARB + glVertexAttrib4NivARB + glVertexAttrib4NubvARB + glVertexAttrib4NusvARB + glVertexAttrib4NuivARB + glVertexAttribPointerARB + glEnableVertexAttribArrayARB + glDisableVertexAttribArrayARB + glProgramStringARB + glBindProgramARB + glDeleteProgramsARB + glGenProgramsARB + glIsProgramARB + glProgramEnvParameter4dARB + glProgramEnvParameter4dvARB + glProgramEnvParameter4fARB + glProgramEnvParameter4fvARB + glProgramLocalParameter4dARB + glProgramLocalParameter4dvARB + glProgramLocalParameter4fARB + glProgramLocalParameter4fvARB + glGetProgramEnvParameterdvARB + glGetProgramEnvParameterfvARB + glGetProgramLocalParameterdvARB + glGetProgramLocalParameterfvARB + glGetProgramivARB + glGetProgramStringARB + glGetVertexAttribdvARB + glGetVertexAttribfvARB + glGetVertexAttribivARB + glGetVertexAttribPointervARB + glProgramNamedParameter4fNV + glProgramNamedParameter4dNV + glProgramNamedParameter4fvNV + glProgramNamedParameter4dvNV + glGetProgramNamedParameterfvNV + glGetProgramNamedParameterdvNV + glBindBufferARB + glBufferDataARB + glBufferSubDataARB + glDeleteBuffersARB + glGenBuffersARB + glGetBufferParameterivARB + glGetBufferPointervARB + glGetBufferSubDataARB + glIsBufferARB + glMapBufferARB + glUnmapBufferARB + glGenQueriesARB + glDeleteQueriesARB + glIsQueryARB + glBeginQueryARB + glEndQueryARB + glGetQueryivARB + glGetQueryObjectivARB + glGetQueryObjectuivARB + glBindBuffer + glBufferData + glBufferSubData + glDeleteBuffers + glGenBuffers + glGetBufferParameteriv + glGetBufferPointerv + glGetBufferSubData + glIsBuffer + glMapBuffer + glUnmapBuffer + glGenQueries + glDeleteQueries + glIsQuery + glBeginQuery + glEndQuery + glGetQueryiv + glGetQueryObjectiv + glGetQueryObjectuiv +; +; WGL API + wglChoosePixelFormat + wglCopyContext + wglCreateContext + wglCreateLayerContext + wglDeleteContext + wglDescribeLayerPlane + wglDescribePixelFormat + wglGetCurrentContext + wglGetCurrentDC + wglGetLayerPaletteEntries + wglGetPixelFormat + wglGetProcAddress + wglMakeCurrent + wglRealizeLayerPalette + wglSetLayerPaletteEntries + wglSetPixelFormat + wglShareLists + wglSwapBuffers + wglSwapLayerBuffers + wglUseFontBitmapsA + wglUseFontBitmapsW + wglUseFontOutlinesA + wglUseFontOutlinesW + wglGetExtensionsStringARB +; +; Mesa internals - mostly for OSMESA + _vbo_CreateContext + _vbo_DestroyContext + _vbo_InvalidateState + _glapi_check_multithread + _glapi_get_context + _glapi_get_proc_address + _mesa_add_soft_renderbuffers + _mesa_add_renderbuffer + _mesa_begin_query + _mesa_buffer_data + _mesa_buffer_get_subdata + _mesa_buffer_map + _mesa_buffer_subdata + _mesa_buffer_unmap + _mesa_bzero + _mesa_calloc + _mesa_choose_tex_format + _mesa_compressed_texture_size + _mesa_create_framebuffer + _mesa_create_visual + _mesa_delete_array_object + _mesa_delete_buffer_object + _mesa_delete_program + _mesa_delete_query + _mesa_delete_texture_object + _mesa_destroy_framebuffer + _mesa_destroy_visual + _mesa_enable_1_3_extensions + _mesa_enable_1_4_extensions + _mesa_enable_1_5_extensions + _mesa_enable_2_0_extensions + _mesa_enable_2_1_extensions + _mesa_enable_sw_extensions + _mesa_end_query + _mesa_error + _mesa_finish_render_texture + _mesa_framebuffer_renderbuffer + _mesa_free + _mesa_free_context_data + _mesa_free_texture_image_data + _mesa_generate_mipmap + _mesa_get_compressed_teximage + _mesa_get_current_context + _mesa_get_teximage + _mesa_init_driver_functions + _mesa_init_glsl_driver_functions + _mesa_init_renderbuffer + _mesa_initialize_context + _mesa_make_current + _mesa_memcpy + _mesa_memset + _mesa_new_array_object + _mesa_new_buffer_object + _mesa_new_framebuffer + _mesa_new_program + _mesa_new_query_object + _mesa_new_renderbuffer + _mesa_new_soft_renderbuffer + _mesa_new_texture_image + _mesa_new_texture_object + _mesa_problem + _mesa_reference_renderbuffer + _mesa_remove_renderbuffer + _mesa_render_texture + _mesa_ResizeBuffersMESA + _mesa_resize_framebuffer + _mesa_store_compressed_teximage1d + _mesa_store_compressed_teximage2d + _mesa_store_compressed_teximage3d + _mesa_store_compressed_texsubimage1d + _mesa_store_compressed_texsubimage2d + _mesa_store_compressed_texsubimage3d + _mesa_store_teximage1d + _mesa_store_teximage2d + _mesa_store_teximage3d + _mesa_store_texsubimage1d + _mesa_store_texsubimage2d + _mesa_store_texsubimage3d + _mesa_strcmp + _mesa_test_proxy_teximage + _mesa_reference_framebuffer + _mesa_update_framebuffer_visual + _mesa_use_program + _mesa_Viewport + _mesa_wait_query + _swrast_Accum + _swrast_Bitmap + _swrast_BlitFramebuffer + _swrast_CopyPixels + _swrast_DrawPixels + _swrast_GetDeviceDriverReference + _swrast_Clear + _swrast_choose_line + _swrast_choose_triangle + _swrast_CopyColorSubTable + _swrast_CopyColorTable + _swrast_CopyConvolutionFilter1D + _swrast_CopyConvolutionFilter2D + _swrast_copy_teximage1d + _swrast_copy_teximage2d + _swrast_copy_texsubimage1d + _swrast_copy_texsubimage2d + _swrast_copy_texsubimage3d + _swrast_CreateContext + _swrast_DestroyContext + _swrast_exec_fragment_program + _swrast_InvalidateState + _swrast_ReadPixels + _swsetup_Wakeup + _swsetup_CreateContext + _swsetup_DestroyContext + _swsetup_InvalidateState + _tnl_CreateContext + _tnl_DestroyContext + _tnl_InvalidateState + _tnl_run_pipeline + _tnl_program_string + _tnl_RasterPos
\ No newline at end of file diff --git a/mesalib/src/mesa/drivers/windows/gdi/wgl.c b/mesalib/src/mesa/drivers/windows/gdi/wgl.c new file mode 100644 index 000000000..8d8087067 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gdi/wgl.c @@ -0,0 +1,707 @@ + +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * File name : wgl.c + * WGL stuff. Added by Oleg Letsinsky, ajl@ultersys.ru + * Some things originated from the 3Dfx WGL functions + */ + +/* + * This file contains the implementation of the wgl* functions for + * Mesa on Windows. Since these functions are provided by Windows in + * GDI/OpenGL, we must supply our versions that work with Mesa here. + */ + + +/* We're essentially building part of GDI here, so define this so that + * we get the right export linkage. */ +#ifdef __MINGW32__ + +#include <stdarg.h> +#include <windef.h> +#include <wincon.h> +#include <winbase.h> + +# if defined(BUILD_GL32) +# define WINGDIAPI __declspec(dllexport) +# else +# define __W32API_USE_DLLIMPORT__ +# endif + +#include <wingdi.h> +#include "GL/mesa_wgl.h" +#include <stdlib.h> + +#else + +#define _GDI32_ +#include <windows.h> + +#endif +#include "config.h" +#include "glapi.h" +#include "GL/wmesa.h" /* protos for wmesa* functions */ + +/* + * Pixel Format Descriptors + */ + +/* Extend the PFD to include DB flag */ +struct __pixelformat__ +{ + PIXELFORMATDESCRIPTOR pfd; + GLboolean doubleBuffered; +}; + + + +/* These are the PFD's supported by this driver. */ +struct __pixelformat__ pfd[] = +{ +#if 0 + /* Double Buffer, alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 8, 24, + 0, 0, 0, 0, 0, + DEFAULT_SOFTWARE_DEPTH_BITS, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_TRUE + }, + /* Single Buffer, alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 8, 24, + 0, 0, 0, 0, 0, + DEFAULT_SOFTWARE_DEPTH_BITS, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_FALSE + }, +#endif + /* Double Buffer, no alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 0, 0, + 0, 0, 0, 0, 0, + DEFAULT_SOFTWARE_DEPTH_BITS, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_TRUE + }, + /* Single Buffer, no alpha */ + { + { + sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL| + PFD_GENERIC_FORMAT, + PFD_TYPE_RGBA, + 24, + 8, 0, + 8, 8, + 8, 16, + 0, 0, + 0, 0, 0, 0, 0, + DEFAULT_SOFTWARE_DEPTH_BITS, 8, + 0, 0, 0, + 0, 0, 0 + }, + GL_FALSE + }, +}; + +int npfd = sizeof(pfd) / sizeof(pfd[0]); + + +/* + * Contexts + */ + +typedef struct { + WMesaContext ctx; +} MesaWglCtx; + +#define MESAWGL_CTX_MAX_COUNT 20 + +static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT]; + +static unsigned ctx_count = 0; +static int ctx_current = -1; +static unsigned curPFD = 0; + +static HDC CurrentHDC = 0; + + +WINGDIAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc) +{ + int i = 0; + if (!ctx_count) { + for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++) { + wgl_ctx[i].ctx = NULL; + } + } + for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) { + if ( wgl_ctx[i].ctx == NULL ) { + wgl_ctx[i].ctx = + WMesaCreateContext(hdc, NULL, (GLboolean)GL_TRUE, + (GLboolean) (pfd[curPFD-1].doubleBuffered ? + GL_TRUE : GL_FALSE), + (GLboolean)(pfd[curPFD-1].pfd.cAlphaBits ? + GL_TRUE : GL_FALSE) ); + if (wgl_ctx[i].ctx == NULL) + break; + ctx_count++; + return ((HGLRC)wgl_ctx[i].ctx); + } + } + SetLastError(0); + return(NULL); +} + +WINGDIAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc) +{ + int i; + for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) { + if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ){ + WMesaMakeCurrent((WMesaContext) hglrc, NULL); + WMesaDestroyContext(wgl_ctx[i].ctx); + wgl_ctx[i].ctx = NULL; + ctx_count--; + return(TRUE); + } + } + SetLastError(0); + return(FALSE); +} + +WINGDIAPI HGLRC GLAPIENTRY wglGetCurrentContext(VOID) +{ + if (ctx_current < 0) + return 0; + else + return (HGLRC) wgl_ctx[ctx_current].ctx; +} + +WINGDIAPI HDC GLAPIENTRY wglGetCurrentDC(VOID) +{ + return CurrentHDC; +} + +WINGDIAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc) +{ + int i; + + CurrentHDC = hdc; + + if (!hdc || !hglrc) { + WMesaMakeCurrent(NULL, NULL); + ctx_current = -1; + return TRUE; + } + + for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) { + if ( wgl_ctx[i].ctx == (WMesaContext) hglrc ) { + WMesaMakeCurrent( (WMesaContext) hglrc, hdc ); + ctx_current = i; + return TRUE; + } + } + return FALSE; +} + + +WINGDIAPI int GLAPIENTRY wglChoosePixelFormat(HDC hdc, + CONST + PIXELFORMATDESCRIPTOR *ppfd) +{ + int i,best = -1,bestdelta = 0x7FFFFFFF,delta; + (void) hdc; + + if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) + { + SetLastError(0); + return(0); + } + for(i = 0; i < npfd;i++) + { + delta = 0; + if( + (ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && + !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW)) + continue; + if( + (ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && + !(pfd[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP)) + continue; + if( + (ppfd->dwFlags & PFD_SUPPORT_GDI) && + !(pfd[i].pfd.dwFlags & PFD_SUPPORT_GDI)) + continue; + if( + (ppfd->dwFlags & PFD_SUPPORT_OPENGL) && + !(pfd[i].pfd.dwFlags & PFD_SUPPORT_OPENGL)) + continue; + if( + !(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && + ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != + (pfd[i].pfd.dwFlags & PFD_DOUBLEBUFFER))) + continue; + if( + !(ppfd->dwFlags & PFD_STEREO_DONTCARE) && + ((ppfd->dwFlags & PFD_STEREO) != + (pfd[i].pfd.dwFlags & PFD_STEREO))) + continue; + if(ppfd->iPixelType != pfd[i].pfd.iPixelType) + delta++; + if(ppfd->cAlphaBits != pfd[i].pfd.cAlphaBits) + delta++; + if(delta < bestdelta) + { + best = i + 1; + bestdelta = delta; + if(bestdelta == 0) + break; + } + } + if(best == -1) + { + SetLastError(0); + return(0); + } + return(best); +} + +WINGDIAPI int GLAPIENTRY wglDescribePixelFormat(HDC hdc, + int iPixelFormat, + UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd) +{ + (void) hdc; + + if(ppfd == NULL) + return(npfd); + if(iPixelFormat < 1 || iPixelFormat > npfd || + nBytes != sizeof(PIXELFORMATDESCRIPTOR)) + { + SetLastError(0); + return(0); + } + *ppfd = pfd[iPixelFormat - 1].pfd; + return(npfd); +} + +WINGDIAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc) +{ + PROC p = (PROC) _glapi_get_proc_address((const char *) lpszProc); + if (p) + return p; + + SetLastError(0); + return(NULL); +} + +WINGDIAPI int GLAPIENTRY wglGetPixelFormat(HDC hdc) +{ + (void) hdc; + if(curPFD == 0) { + SetLastError(0); + return(0); + } + return(curPFD); +} + +WINGDIAPI BOOL GLAPIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat, + const PIXELFORMATDESCRIPTOR *ppfd) +{ + (void) hdc; + + if(iPixelFormat < 1 || iPixelFormat > npfd || + ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) { + SetLastError(0); + return(FALSE); + } + curPFD = iPixelFormat; + return(TRUE); +} + +WINGDIAPI BOOL GLAPIENTRY wglSwapBuffers(HDC hdc) +{ + WMesaSwapBuffers(hdc); + return TRUE; +} + +static FIXED FixedFromDouble(double d) +{ + long l = (long) (d * 65536L); + return *(FIXED *) (void *) &l; +} + + +/* +** This is cribbed from FX/fxwgl.c, and seems to implement support +** for bitmap fonts where the wglUseFontBitmapsA() code implements +** support for outline fonts. In combination they hopefully give +** fairly generic support for fonts. +*/ +static BOOL wglUseFontBitmaps_FX(HDC fontDevice, DWORD firstChar, + DWORD numChars, DWORD listBase) +{ +#define VERIFY(a) a + + TEXTMETRIC metric; + BITMAPINFO *dibInfo; + HDC bitDevice; + COLORREF tempColor; + int i; + + VERIFY(GetTextMetrics(fontDevice, &metric)); + + dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1); + dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + dibInfo->bmiHeader.biPlanes = 1; + dibInfo->bmiHeader.biBitCount = 1; + dibInfo->bmiHeader.biCompression = BI_RGB; + + bitDevice = CreateCompatibleDC(fontDevice); + + /* Swap fore and back colors so the bitmap has the right polarity */ + tempColor = GetBkColor(bitDevice); + SetBkColor(bitDevice, GetTextColor(bitDevice)); + SetTextColor(bitDevice, tempColor); + + /* Place chars based on base line */ + VERIFY(SetTextAlign(bitDevice, TA_BASELINE) != GDI_ERROR ? 1 : 0); + + for(i = 0; i < (int)numChars; i++) { + SIZE size; + char curChar; + int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res; + HBITMAP bitObject; + HGDIOBJ origBmap; + unsigned char *bmap; + + curChar = (char)(i + firstChar); + + /* Find how high/wide this character is */ + VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size)); + + /* Create the output bitmap */ + charWidth = size.cx; + charHeight = size.cy; + /* Round up to the next multiple of 32 bits */ + bmapWidth = ((charWidth + 31) / 32) * 32; + bmapHeight = charHeight; + bitObject = CreateCompatibleBitmap(bitDevice, + bmapWidth, + bmapHeight); + /* VERIFY(bitObject); */ + + /* Assign the output bitmap to the device */ + origBmap = SelectObject(bitDevice, bitObject); + (void) VERIFY(origBmap); + + VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) ); + + /* Use our source font on the device */ + VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT))); + + /* Draw the character */ + VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1)); + + /* Unselect our bmap object */ + VERIFY(SelectObject(bitDevice, origBmap)); + + /* Convert the display dependant representation to a 1 bit deep DIB */ + numBytes = (bmapWidth * bmapHeight) / 8; + bmap = malloc(numBytes); + dibInfo->bmiHeader.biWidth = bmapWidth; + dibInfo->bmiHeader.biHeight = bmapHeight; + res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap, + dibInfo, + DIB_RGB_COLORS); + /* VERIFY(res); */ + + /* Create the GL object */ + glNewList(i + listBase, GL_COMPILE); + glBitmap(bmapWidth, bmapHeight, 0.0, (GLfloat)metric.tmDescent, + (GLfloat)charWidth, 0.0, + bmap); + glEndList(); + /* CheckGL(); */ + + /* Destroy the bmap object */ + DeleteObject(bitObject); + + /* Deallocate the bitmap data */ + free(bmap); + } + + /* Destroy the DC */ + VERIFY(DeleteDC(bitDevice)); + + free(dibInfo); + + return TRUE; +#undef VERIFY +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, + DWORD count, DWORD listBase) +{ + int i; + GLuint font_list; + DWORD size; + GLYPHMETRICS gm; + HANDLE hBits; + LPSTR lpBits; + MAT2 mat; + int success = TRUE; + + if (count == 0) + return FALSE; + + font_list = listBase; + + mat.eM11 = FixedFromDouble(1); + mat.eM12 = FixedFromDouble(0); + mat.eM21 = FixedFromDouble(0); + mat.eM22 = FixedFromDouble(-1); + + memset(&gm,0,sizeof(gm)); + + /* + ** If we can't get the glyph outline, it may be because this is a fixed + ** font. Try processing it that way. + */ + if( GetGlyphOutline(hdc, first, GGO_BITMAP, &gm, 0, NULL, &mat) + == GDI_ERROR ) { + return wglUseFontBitmaps_FX( hdc, first, count, listBase ); + } + + /* + ** Otherwise process all desired characters. + */ + for (i = 0; i < (int)count; i++) { + DWORD err; + + glNewList( font_list+i, GL_COMPILE ); + + /* allocate space for the bitmap/outline */ + size = GetGlyphOutline(hdc, first + i, GGO_BITMAP, + &gm, 0, NULL, &mat); + if (size == GDI_ERROR) { + glEndList( ); + err = GetLastError(); + success = FALSE; + continue; + } + + hBits = GlobalAlloc(GHND, size+1); + lpBits = GlobalLock(hBits); + + err = + GetGlyphOutline(hdc, /* handle to device context */ + first + i, /* character to query */ + GGO_BITMAP, /* format of data to return */ + &gm, /* ptr to structure for metrics*/ + size, /* size of buffer for data */ + lpBits, /* pointer to buffer for data */ + &mat /* pointer to transformation */ + /* matrix structure */ + ); + + if (err == GDI_ERROR) { + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList( ); + err = GetLastError(); + success = FALSE; + continue; + } + + glBitmap(gm.gmBlackBoxX,gm.gmBlackBoxY, + (GLfloat)-gm.gmptGlyphOrigin.x, + (GLfloat)gm.gmptGlyphOrigin.y, + (GLfloat)gm.gmCellIncX, + (GLfloat)gm.gmCellIncY, + (const GLubyte * )lpBits); + + GlobalUnlock(hBits); + GlobalFree(hBits); + + glEndList( ); + } + + return success; +} + +WINGDIAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, + HGLRC hglrc2) +{ + WMesaShareLists((WMesaContext)hglrc1, (WMesaContext)hglrc2); + return(TRUE); +} + + + +/* NOT IMPLEMENTED YET */ +WINGDIAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, + HGLRC hglrcDst, + UINT mask) +{ + (void) hglrcSrc; (void) hglrcDst; (void) mask; + return(FALSE); +} + +WINGDIAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, + int iLayerPlane) +{ + SetLastError(0); + if (iLayerPlane == 0) + return wglCreateContext( hdc ); + return(NULL); +} + + +WINGDIAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase) +{ + (void) hdc; (void) first; (void) count; (void) listBase; + return FALSE; +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) lpgmf; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, + DWORD first, + DWORD count, + DWORD listBase, + FLOAT deviation, + FLOAT extrusion, + int format, + LPGLYPHMETRICSFLOAT lpgmf) +{ + (void) hdc; (void) first; (void) count; + (void) listBase; (void) deviation; (void) extrusion; (void) format; + (void) lpgmf; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, + int iPixelFormat, + int iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + (void) hdc; (void) iPixelFormat; (void) iLayerPlane; + (void) nBytes; (void) plpd; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + CONST COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; + (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WINGDIAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, + int iLayerPlane, + int iStart, + int cEntries, + COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WINGDIAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, + int iLayerPlane, + BOOL bRealize) +{ + (void) hdc; (void) iLayerPlane; (void) bRealize; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, + UINT fuPlanes) +{ + (void) hdc; (void) fuPlanes; + SetLastError(0); + return(FALSE); +} + +WINGDIAPI const char * GLAPIENTRY wglGetExtensionsStringARB(HDC hdc) +{ + return "WGL_ARB_extensions_string"; +} diff --git a/mesalib/src/mesa/drivers/windows/gdi/wmesa.c b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c new file mode 100644 index 000000000..e1971db69 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c @@ -0,0 +1,1681 @@ +/* + * Windows (Win32/Win64) device driver for Mesa + * + */ + +#include "wmesadef.h" +#include "colors.h" +#include <GL/wmesa.h> +#include <winuser.h> +#include "context.h" +#include "extensions.h" +#include "framebuffer.h" +#include "renderbuffer.h" +#include "drivers/common/driverfuncs.h" +#include "vbo/vbo.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + + +/* linked list of our Framebuffers (windows) */ +static WMesaFramebuffer FirstFramebuffer = NULL; + + +/** + * Create a new WMesaFramebuffer object which will correspond to the + * given HDC (Window handle). + */ +WMesaFramebuffer +wmesa_new_framebuffer(HDC hdc, GLvisual *visual) +{ + WMesaFramebuffer pwfb + = (WMesaFramebuffer) malloc(sizeof(struct wmesa_framebuffer)); + if (pwfb) { + _mesa_initialize_framebuffer(&pwfb->Base, visual); + pwfb->hDC = hdc; + /* insert at head of list */ + pwfb->next = FirstFramebuffer; + FirstFramebuffer = pwfb; + } + return pwfb; +} + +/** + * Given an hdc, free the corresponding WMesaFramebuffer + */ +void +wmesa_free_framebuffer(HDC hdc) +{ + WMesaFramebuffer pwfb, prev; + for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { + if (pwfb->hDC == hdc) + break; + prev = pwfb; + } + if (pwfb) { + struct gl_framebuffer *fb; + if (pwfb == FirstFramebuffer) + FirstFramebuffer = pwfb->next; + else + prev->next = pwfb->next; + fb = &pwfb->Base; + _mesa_reference_framebuffer(&fb, NULL); + } +} + +/** + * Given an hdc, return the corresponding WMesaFramebuffer + */ +WMesaFramebuffer +wmesa_lookup_framebuffer(HDC hdc) +{ + WMesaFramebuffer pwfb; + for (pwfb = FirstFramebuffer; pwfb; pwfb = pwfb->next) { + if (pwfb->hDC == hdc) + return pwfb; + } + return NULL; +} + + +/** + * Given a GLframebuffer, return the corresponding WMesaFramebuffer. + */ +static WMesaFramebuffer wmesa_framebuffer(GLframebuffer *fb) +{ + return (WMesaFramebuffer) fb; +} + + +/** + * Given a GLcontext, return the corresponding WMesaContext. + */ +static WMesaContext wmesa_context(const GLcontext *ctx) +{ + return (WMesaContext) ctx; +} + + +/* + * Every driver should implement a GetString function in order to + * return a meaningful GL_RENDERER string. + */ +static const GLubyte *wmesa_get_string(GLcontext *ctx, GLenum name) +{ + return (name == GL_RENDERER) ? + (GLubyte *) "Mesa Windows GDI Driver" : NULL; +} + + +/* + * Determine the pixel format based on the pixel size. + */ +static void wmSetPixelFormat(WMesaFramebuffer pwfb, HDC hDC) +{ + pwfb->cColorBits = GetDeviceCaps(hDC, BITSPIXEL); + + /* Only 16 and 32 bit targets are supported now */ + assert(pwfb->cColorBits == 0 || + pwfb->cColorBits == 16 || + pwfb->cColorBits == 24 || + pwfb->cColorBits == 32); + + switch(pwfb->cColorBits){ + case 8: + pwfb->pixelformat = PF_INDEX8; + break; + case 16: + pwfb->pixelformat = PF_5R6G5B; + break; + case 24: + case 32: + pwfb->pixelformat = PF_8R8G8B; + break; + default: + pwfb->pixelformat = PF_BADFORMAT; + } +} + + +/** + * Create DIB for back buffer. + * We write into this memory with the span routines and then blit it + * to the window on a buffer swap. + */ +BOOL wmCreateBackingStore(WMesaFramebuffer pwfb, long lxSize, long lySize) +{ + HDC hdc = pwfb->hDC; + LPBITMAPINFO pbmi = &(pwfb->bmi); + HDC hic; + + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = lxSize; + pbmi->bmiHeader.biHeight= -lySize; + pbmi->bmiHeader.biPlanes = 1; + pbmi->bmiHeader.biBitCount = GetDeviceCaps(pwfb->hDC, BITSPIXEL); + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = 0; + pbmi->bmiHeader.biClrImportant = 0; + + pwfb->cColorBits = pbmi->bmiHeader.biBitCount; + pwfb->ScanWidth = (lxSize * (pwfb->cColorBits / 8) + 3) & ~3; + + hic = CreateIC("display", NULL, NULL, NULL); + pwfb->dib_hDC = CreateCompatibleDC(hic); + + pwfb->hbmDIB = CreateDIBSection(hic, + &pwfb->bmi, + DIB_RGB_COLORS, + (void **)&(pwfb->pbPixels), + 0, + 0); + pwfb->hOldBitmap = SelectObject(pwfb->dib_hDC, pwfb->hbmDIB); + + DeleteDC(hic); + + wmSetPixelFormat(pwfb, pwfb->hDC); + return TRUE; +} + + +static wmDeleteBackingStore(WMesaFramebuffer pwfb) +{ + if (pwfb->hbmDIB) { + SelectObject(pwfb->dib_hDC, pwfb->hOldBitmap); + DeleteDC(pwfb->dib_hDC); + DeleteObject(pwfb->hbmDIB); + } +} + + +/** + * Find the width and height of the window named by hdc. + */ +static void +get_window_size(HDC hdc, GLuint *width, GLuint *height) +{ + if (WindowFromDC(hdc)) { + RECT rect; + GetClientRect(WindowFromDC(hdc), &rect); + *width = rect.right - rect.left; + *height = rect.bottom - rect.top; + } + else { /* Memory context */ + /* From contributed code - use the size of the desktop + * for the size of a memory context (?) */ + *width = GetDeviceCaps(hdc, HORZRES); + *height = GetDeviceCaps(hdc, VERTRES); + } +} + + +static void +wmesa_get_buffer_size(GLframebuffer *buffer, GLuint *width, GLuint *height) +{ + WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); + get_window_size(pwfb->hDC, width, height); +} + + +static void wmesa_flush(GLcontext *ctx) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->WinSysDrawBuffer); + + if (ctx->Visual.doubleBufferMode == 1) { + BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, + pwfb->dib_hDC, 0, 0, SRCCOPY); + } + else { + /* Do nothing for single buffer */ + } +} + + +/**********************************************************************/ +/***** CLEAR Functions *****/ +/**********************************************************************/ + +/* If we do not implement these, Mesa clears the buffers via the pixel + * span writing interface, which is very slow for a clear operation. + */ + +/* + * Set the color index used to clear the color buffer. + */ +static void clear_index(GLcontext *ctx, GLuint index) +{ + WMesaContext pwc = wmesa_context(ctx); + /* Note that indexed mode is not supported yet */ + pwc->clearColorRef = RGB(0,0,0); +} + +/* + * Set the color used to clear the color buffer. + */ +static void clear_color(GLcontext *ctx, const GLfloat color[4]) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + GLubyte col[3]; + UINT bytesPerPixel = pwfb->cColorBits / 8; + + CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); + pwc->clearColorRef = RGB(col[0], col[1], col[2]); + DeleteObject(pwc->clearPen); + DeleteObject(pwc->clearBrush); + pwc->clearPen = CreatePen(PS_SOLID, 1, pwc->clearColorRef); + pwc->clearBrush = CreateSolidBrush(pwc->clearColorRef); +} + + +/* + * Clear the specified region of the color buffer using the clear color + * or index as specified by one of the two functions above. + * + * This procedure clears either the front and/or the back COLOR buffers. + * Only the "left" buffer is cleared since we are not stereo. + * Clearing of the other non-color buffers is left to the swrast. + */ + +static void clear(GLcontext *ctx, GLbitfield mask) +{ +#define FLIP(Y) (ctx->DrawBuffer->Height - (Y) - 1) + const GLint x = ctx->DrawBuffer->_Xmin; + const GLint y = ctx->DrawBuffer->_Ymin; + const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; + const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; + + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + int done = 0; + + /* Let swrast do all the work if the masks are not set to + * clear all channels. */ + if (ctx->Color.ColorMask[0] != 0xff || + ctx->Color.ColorMask[1] != 0xff || + ctx->Color.ColorMask[2] != 0xff || + ctx->Color.ColorMask[3] != 0xff) { + _swrast_Clear(ctx, mask); + return; + } + + /* Back buffer */ + if (mask & BUFFER_BIT_BACK_LEFT) { + + int i, rowSize; + UINT bytesPerPixel = pwfb->cColorBits / 8; + LPBYTE lpb, clearRow; + LPWORD lpw; + BYTE bColor; + WORD wColor; + BYTE r, g, b; + DWORD dwColor; + LPDWORD lpdw; + + /* Try for a fast clear - clearing entire buffer with a single + * byte value. */ + if (width == ctx->DrawBuffer->Width && + height == ctx->DrawBuffer->Height) { /* entire buffer */ + /* Now check for an easy clear value */ + switch (bytesPerPixel) { + case 1: + bColor = BGR8(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); + memset(pwfb->pbPixels, bColor, + pwfb->ScanWidth * height); + done = 1; + break; + case 2: + wColor = BGR16(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); + if (((wColor >> 8) & 0xff) == (wColor & 0xff)) { + memset(pwfb->pbPixels, wColor & 0xff, + pwfb->ScanWidth * height); + done = 1; + } + break; + case 3: + /* fall through */ + case 4: + if (GetRValue(pwc->clearColorRef) == + GetGValue(pwc->clearColorRef) && + GetRValue(pwc->clearColorRef) == + GetBValue(pwc->clearColorRef)) { + memset(pwfb->pbPixels, + GetRValue(pwc->clearColorRef), + pwfb->ScanWidth * height); + done = 1; + } + break; + default: + break; + } + } /* all */ + + if (!done) { + /* Need to clear a row at a time. Begin by setting the first + * row in the area to be cleared to the clear color. */ + + clearRow = pwfb->pbPixels + + pwfb->ScanWidth * FLIP(y) + + bytesPerPixel * x; + switch (bytesPerPixel) { + case 1: + lpb = clearRow; + bColor = BGR8(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); + memset(lpb, bColor, width); + break; + case 2: + lpw = (LPWORD)clearRow; + wColor = BGR16(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); + for (i=0; i<width; i++) + *lpw++ = wColor; + break; + case 3: + lpb = clearRow; + r = GetRValue(pwc->clearColorRef); + g = GetGValue(pwc->clearColorRef); + b = GetBValue(pwc->clearColorRef); + for (i=0; i<width; i++) { + *lpb++ = b; + *lpb++ = g; + *lpb++ = r; + } + break; + case 4: + lpdw = (LPDWORD)clearRow; + dwColor = BGR32(GetRValue(pwc->clearColorRef), + GetGValue(pwc->clearColorRef), + GetBValue(pwc->clearColorRef)); + for (i=0; i<width; i++) + *lpdw++ = dwColor; + break; + default: + break; + } /* switch */ + + /* copy cleared row to other rows in buffer */ + lpb = clearRow - pwfb->ScanWidth; + rowSize = width * bytesPerPixel; + for (i=1; i<height; i++) { + memcpy(lpb, clearRow, rowSize); + lpb -= pwfb->ScanWidth; + } + } /* not done */ + mask &= ~BUFFER_BIT_BACK_LEFT; + } /* back buffer */ + + /* front buffer */ + if (mask & BUFFER_BIT_FRONT_LEFT) { + HDC DC = pwc->hDC; + HPEN Old_Pen = SelectObject(DC, pwc->clearPen); + HBRUSH Old_Brush = SelectObject(DC, pwc->clearBrush); + Rectangle(DC, + x, + FLIP(y) + 1, + x + width + 1, + FLIP(y) - height + 1); + SelectObject(DC, Old_Pen); + SelectObject(DC, Old_Brush); + mask &= ~BUFFER_BIT_FRONT_LEFT; + } /* front buffer */ + + /* Call swrast if there is anything left to clear (like DEPTH) */ + if (mask) + _swrast_Clear(ctx, mask); + +#undef FLIP +} + + +/**********************************************************************/ +/***** PIXEL Functions *****/ +/**********************************************************************/ + +#define FLIP(Y) (rb->Height - (Y) - 1) + + +/** + ** Front Buffer reading/writing + ** These are slow, but work with all non-indexed visual types. + **/ + +/* Write a horizontal span of RGBA color pixels with a boolean mask. */ +static void write_rgba_span_front(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(pwc->hDC); + CONST BITMAPINFO bmi= + { + { + sizeof(BITMAPINFOHEADER), + n, 1, 1, 32, BI_RGB, 0, 1, 1, 0, 0 + } + }; + HBITMAP bmp=0; + HDC mdc=0; + typedef union + { + unsigned i; + struct { + unsigned b:8, g:8, r:8, a:8; + }; + } BGRA; + BGRA *bgra, c; + int i; + + if (n < 16) { // the value 16 is just guessed + y=FLIP(y); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + SetPixel(pwc->hDC, x+i, y, + RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); + } + else { + for (i=0; i<n; i++) + SetPixel(pwc->hDC, x+i, y, + RGB(rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP])); + } + } + else { + if (!pwfb) { + _mesa_problem(NULL, "wmesa: write_rgba_span_front on unknown hdc"); + return; + } + bgra=malloc(n*sizeof(BGRA)); + if (!bgra) { + _mesa_problem(NULL, "wmesa: write_rgba_span_front: out of memory"); + return; + } + c.a=0; + if (mask) { + for (i=0; i<n; i++) { + if (mask[i]) { + c.r=rgba[i][RCOMP]; + c.g=rgba[i][GCOMP]; + c.b=rgba[i][BCOMP]; + c.a=rgba[i][ACOMP]; + bgra[i]=c; + } + else + bgra[i].i=0; + } + } + else { + for (i=0; i<n; i++) { + c.r=rgba[i][RCOMP]; + c.g=rgba[i][GCOMP]; + c.b=rgba[i][BCOMP]; + c.a=rgba[i][ACOMP]; + bgra[i]=c; + } + } + bmp=CreateBitmap(n, 1, 1, 32, bgra); + mdc=CreateCompatibleDC(pwfb->hDC); + SelectObject(mdc, bmp); + y=FLIP(y); + BitBlt(pwfb->hDC, x, y, n, 1, mdc, 0, 0, SRCCOPY); + SelectObject(mdc, 0); + DeleteObject(bmp); + DeleteDC(mdc); + free(bgra); + } +} + +/* Write a horizontal span of RGB color pixels with a boolean mask. */ +static void write_rgb_span_front(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + GLuint i; + + (void) ctx; + y=FLIP(y); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], + rgb[i][BCOMP])); + } + else { + for (i=0; i<n; i++) + SetPixel(pwc->hDC, x+i, y, RGB(rgb[i][RCOMP], rgb[i][GCOMP], + rgb[i][BCOMP])); + } + +} + +/* + * Write a horizontal span of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_span_front(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLchan color[4], + const GLubyte mask[]) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + COLORREF colorref; + + (void) ctx; + colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]); + y=FLIP(y); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + SetPixel(pwc->hDC, x+i, y, colorref); + } + else + for (i=0; i<n; i++) + SetPixel(pwc->hDC, x+i, y, colorref); + +} + +/* Write an array of RGBA pixels with a boolean mask. */ +static void write_rgba_pixels_front(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const GLubyte rgba[][4], + const GLubyte mask[] ) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + (void) ctx; + for (i=0; i<n; i++) + if (mask[i]) + SetPixel(pwc->hDC, x[i], FLIP(y[i]), + RGB(rgba[i][RCOMP], rgba[i][GCOMP], + rgba[i][BCOMP])); +} + + + +/* + * Write an array of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_pixels_front(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[] ) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + COLORREF colorref; + (void) ctx; + colorref = RGB(color[RCOMP], color[GCOMP], color[BCOMP]); + for (i=0; i<n; i++) + if (mask[i]) + SetPixel(pwc->hDC, x[i], FLIP(y[i]), colorref); +} + +/* Read a horizontal span of color pixels. */ +static void read_rgba_span_front(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + GLubyte rgba[][4] ) +{ + WMesaContext pwc = wmesa_context(ctx); + GLuint i; + COLORREF Color; + y = FLIP(y); + for (i=0; i<n; i++) { + Color = GetPixel(pwc->hDC, x+i, y); + rgba[i][RCOMP] = GetRValue(Color); + rgba[i][GCOMP] = GetGValue(Color); + rgba[i][BCOMP] = GetBValue(Color); + rgba[i][ACOMP] = 255; + } +} + + +/* Read an array of color pixels. */ +static void read_rgba_pixels_front(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4]) +{ + WMesaContext pwc = wmesa_context(ctx); + GLuint i; + COLORREF Color; + for (i=0; i<n; i++) { + GLint y2 = FLIP(y[i]); + Color = GetPixel(pwc->hDC, x[i], y2); + rgba[i][RCOMP] = GetRValue(Color); + rgba[i][GCOMP] = GetGValue(Color); + rgba[i][BCOMP] = GetBValue(Color); + rgba[i][ACOMP] = 255; + } +} + +/*********************************************************************/ + +/* DOUBLE BUFFER 32-bit */ + +#define WMSETPIXEL32(pwc, y, x, r, g, b) { \ +LPDWORD lpdw = ((LPDWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \ +*lpdw = BGR32((r),(g),(b)); } + + + +/* Write a horizontal span of RGBA color pixels with a boolean mask. */ +static void write_rgba_span_32(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + GLuint i; + LPDWORD lpdw; + + (void) ctx; + + y=FLIP(y); + lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + lpdw[i] = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], + rgba[i][BCOMP]); + } + else { + for (i=0; i<n; i++) + *lpdw++ = BGR32(rgba[i][RCOMP], rgba[i][GCOMP], + rgba[i][BCOMP]); + } +} + + +/* Write a horizontal span of RGB color pixels with a boolean mask. */ +static void write_rgb_span_32(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + GLuint i; + LPDWORD lpdw; + + (void) ctx; + + y=FLIP(y); + lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + lpdw[i] = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], + rgb[i][BCOMP]); + } + else { + for (i=0; i<n; i++) + *lpdw++ = BGR32(rgb[i][RCOMP], rgb[i][GCOMP], + rgb[i][BCOMP]); + } +} + +/* + * Write a horizontal span of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_span_32(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLchan color[4], + const GLubyte mask[]) +{ + LPDWORD lpdw; + DWORD pixel; + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + y=FLIP(y); + pixel = BGR32(color[RCOMP], color[GCOMP], color[BCOMP]); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + lpdw[i] = pixel; + } + else + for (i=0; i<n; i++) + *lpdw++ = pixel; + +} + +/* Write an array of RGBA pixels with a boolean mask. */ +static void write_rgba_pixels_32(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + const GLubyte rgba[][4], + const GLubyte mask[]) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + for (i=0; i<n; i++) + if (mask[i]) + WMSETPIXEL32(pwfb, FLIP(y[i]), x[i], + rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); +} + +/* + * Write an array of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_pixels_32(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[]) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + for (i=0; i<n; i++) + if (mask[i]) + WMSETPIXEL32(pwfb, FLIP(y[i]),x[i],color[RCOMP], + color[GCOMP], color[BCOMP]); +} + +/* Read a horizontal span of color pixels. */ +static void read_rgba_span_32(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + GLubyte rgba[][4] ) +{ + GLuint i; + DWORD pixel; + LPDWORD lpdw; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + + y = FLIP(y); + lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + for (i=0; i<n; i++) { + pixel = lpdw[i]; + rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16; + rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8; + rgba[i][BCOMP] = (pixel & 0x000000ff); + rgba[i][ACOMP] = 255; + } +} + + +/* Read an array of color pixels. */ +static void read_rgba_pixels_32(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4]) +{ + GLuint i; + DWORD pixel; + LPDWORD lpdw; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + + for (i=0; i<n; i++) { + GLint y2 = FLIP(y[i]); + lpdw = ((LPDWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i]; + pixel = *lpdw; + rgba[i][RCOMP] = (pixel & 0x00ff0000) >> 16; + rgba[i][GCOMP] = (pixel & 0x0000ff00) >> 8; + rgba[i][BCOMP] = (pixel & 0x000000ff); + rgba[i][ACOMP] = 255; + } +} + + +/*********************************************************************/ + +/* DOUBLE BUFFER 24-bit */ + +#define WMSETPIXEL24(pwc, y, x, r, g, b) { \ +LPBYTE lpb = ((LPBYTE)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (3 * x)); \ +lpb[0] = (b); \ +lpb[1] = (g); \ +lpb[2] = (r); } + +/* Write a horizontal span of RGBA color pixels with a boolean mask. */ +static void write_rgba_span_24(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + GLuint i; + LPBYTE lpb; + + (void) ctx; + + y=FLIP(y); + lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) { + lpb[3*i] = rgba[i][BCOMP]; + lpb[3*i+1] = rgba[i][GCOMP]; + lpb[3*i+2] = rgba[i][RCOMP]; + } + } + else { + for (i=0; i<n; i++) { + *lpb++ = rgba[i][BCOMP]; + *lpb++ = rgba[i][GCOMP]; + *lpb++ = rgba[i][RCOMP]; + } + } +} + + +/* Write a horizontal span of RGB color pixels with a boolean mask. */ +static void write_rgb_span_24(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + GLuint i; + LPBYTE lpb; + + (void) ctx; + + y=FLIP(y); + lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) { + lpb[3*i] = rgb[i][BCOMP]; + lpb[3*i+1] = rgb[i][GCOMP]; + lpb[3*i+2] = rgb[i][RCOMP]; + } + } + else { + for (i=0; i<n; i++) { + *lpb++ = rgb[i][BCOMP]; + *lpb++ = rgb[i][GCOMP]; + *lpb++ = rgb[i][RCOMP]; + } + } +} + +/* + * Write a horizontal span of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_span_24(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLchan color[4], + const GLubyte mask[]) +{ + LPBYTE lpb; + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x); + y=FLIP(y); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) { + lpb[3*i] = color[BCOMP]; + lpb[3*i+1] = color[GCOMP]; + lpb[3*i+2] = color[RCOMP]; + } + } + else + for (i=0; i<n; i++) { + *lpb++ = color[BCOMP]; + *lpb++ = color[GCOMP]; + *lpb++ = color[RCOMP]; + } +} + +/* Write an array of RGBA pixels with a boolean mask. */ +static void write_rgba_pixels_24(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + const GLubyte rgba[][4], + const GLubyte mask[]) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + for (i=0; i<n; i++) + if (mask[i]) + WMSETPIXEL24(pwfb, FLIP(y[i]), x[i], + rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); +} + +/* + * Write an array of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_pixels_24(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[]) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + for (i=0; i<n; i++) + if (mask[i]) + WMSETPIXEL24(pwfb, FLIP(y[i]),x[i],color[RCOMP], + color[GCOMP], color[BCOMP]); +} + +/* Read a horizontal span of color pixels. */ +static void read_rgba_span_24(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + GLubyte rgba[][4] ) +{ + GLuint i; + LPBYTE lpb; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + + y = FLIP(y); + lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y)) + (3 * x); + for (i=0; i<n; i++) { + rgba[i][RCOMP] = lpb[3*i+2]; + rgba[i][GCOMP] = lpb[3*i+1]; + rgba[i][BCOMP] = lpb[3*i]; + rgba[i][ACOMP] = 255; + } +} + + +/* Read an array of color pixels. */ +static void read_rgba_pixels_24(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4]) +{ + GLuint i; + LPBYTE lpb; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + + for (i=0; i<n; i++) { + GLint y2 = FLIP(y[i]); + lpb = ((LPBYTE)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + (3 * x[i]); + rgba[i][RCOMP] = lpb[3*i+2]; + rgba[i][GCOMP] = lpb[3*i+1]; + rgba[i][BCOMP] = lpb[3*i]; + rgba[i][ACOMP] = 255; + } +} + + +/*********************************************************************/ + +/* DOUBLE BUFFER 16-bit */ + +#define WMSETPIXEL16(pwc, y, x, r, g, b) { \ +LPWORD lpw = ((LPWORD)((pwc)->pbPixels + (pwc)->ScanWidth * (y)) + (x)); \ +*lpw = BGR16((r),(g),(b)); } + + + +/* Write a horizontal span of RGBA color pixels with a boolean mask. */ +static void write_rgba_span_16(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + GLuint i; + LPWORD lpw; + + (void) ctx; + + y=FLIP(y); + lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + lpw[i] = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], + rgba[i][BCOMP]); + } + else { + for (i=0; i<n; i++) + *lpw++ = BGR16(rgba[i][RCOMP], rgba[i][GCOMP], + rgba[i][BCOMP]); + } +} + + +/* Write a horizontal span of RGB color pixels with a boolean mask. */ +static void write_rgb_span_16(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], + const GLubyte mask[] ) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + GLuint i; + LPWORD lpw; + + (void) ctx; + + y=FLIP(y); + lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + lpw[i] = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], + rgb[i][BCOMP]); + } + else { + for (i=0; i<n; i++) + *lpw++ = BGR16(rgb[i][RCOMP], rgb[i][GCOMP], + rgb[i][BCOMP]); + } +} + +/* + * Write a horizontal span of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_span_16(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLchan color[4], + const GLubyte mask[]) +{ + LPWORD lpw; + WORD pixel; + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + (void) ctx; + lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + y=FLIP(y); + pixel = BGR16(color[RCOMP], color[GCOMP], color[BCOMP]); + if (mask) { + for (i=0; i<n; i++) + if (mask[i]) + lpw[i] = pixel; + } + else + for (i=0; i<n; i++) + *lpw++ = pixel; + +} + +/* Write an array of RGBA pixels with a boolean mask. */ +static void write_rgba_pixels_16(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + const GLubyte rgba[][4], + const GLubyte mask[]) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + (void) ctx; + for (i=0; i<n; i++) + if (mask[i]) + WMSETPIXEL16(pwfb, FLIP(y[i]), x[i], + rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP]); +} + +/* + * Write an array of pixels with a boolean mask. The current color + * is used for all pixels. + */ +static void write_mono_rgba_pixels_16(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, + const GLint x[], const GLint y[], + const GLchan color[4], + const GLubyte mask[]) +{ + GLuint i; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + (void) ctx; + for (i=0; i<n; i++) + if (mask[i]) + WMSETPIXEL16(pwfb, FLIP(y[i]),x[i],color[RCOMP], + color[GCOMP], color[BCOMP]); +} + +/* Read a horizontal span of color pixels. */ +static void read_rgba_span_16(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + GLubyte rgba[][4] ) +{ + GLuint i, pixel; + LPWORD lpw; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + + y = FLIP(y); + lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y)) + x; + for (i=0; i<n; i++) { + pixel = lpw[i]; + /* Windows uses 5,5,5 for 16-bit */ + rgba[i][RCOMP] = (pixel & 0x7c00) >> 7; + rgba[i][GCOMP] = (pixel & 0x03e0) >> 2; + rgba[i][BCOMP] = (pixel & 0x001f) << 3; + rgba[i][ACOMP] = 255; + } +} + + +/* Read an array of color pixels. */ +static void read_rgba_pixels_16(const GLcontext *ctx, + struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4]) +{ + GLuint i, pixel; + LPWORD lpw; + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(ctx->DrawBuffer); + + for (i=0; i<n; i++) { + GLint y2 = FLIP(y[i]); + lpw = ((LPWORD)(pwfb->pbPixels + pwfb->ScanWidth * y2)) + x[i]; + pixel = *lpw; + /* Windows uses 5,5,5 for 16-bit */ + rgba[i][RCOMP] = (pixel & 0x7c00) >> 7; + rgba[i][GCOMP] = (pixel & 0x03e0) >> 2; + rgba[i][BCOMP] = (pixel & 0x001f) << 3; + rgba[i][ACOMP] = 255; + } +} + + + + +/**********************************************************************/ +/***** BUFFER Functions *****/ +/**********************************************************************/ + + + + +static void +wmesa_delete_renderbuffer(struct gl_renderbuffer *rb) +{ + _mesa_free(rb); +} + + +/** + * This is called by Mesa whenever it determines that the window size + * has changed. Do whatever's needed to cope with that. + */ +static GLboolean +wmesa_renderbuffer_storage(GLcontext *ctx, + struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, + GLuint height) +{ + rb->Width = width; + rb->Height = height; + return GL_TRUE; +} + + +/** + * Plug in the Get/PutRow/Values functions for a renderbuffer depending + * on if we're drawing to the front or back color buffer. + */ +void wmesa_set_renderbuffer_funcs(struct gl_renderbuffer *rb, int pixelformat, + BYTE cColorBits, int double_buffer) +{ + if (double_buffer) { + /* back buffer */ + /* Picking the correct span functions is important because + * the DIB was allocated with the indicated depth. */ + switch(pixelformat) { + case PF_5R6G5B: + rb->PutRow = write_rgba_span_16; + rb->PutRowRGB = write_rgb_span_16; + rb->PutMonoRow = write_mono_rgba_span_16; + rb->PutValues = write_rgba_pixels_16; + rb->PutMonoValues = write_mono_rgba_pixels_16; + rb->GetRow = read_rgba_span_16; + rb->GetValues = read_rgba_pixels_16; + rb->RedBits = 5; + rb->GreenBits = 6; + rb->BlueBits = 5; + break; + case PF_8R8G8B: + if (cColorBits == 24) + { + rb->PutRow = write_rgba_span_24; + rb->PutRowRGB = write_rgb_span_24; + rb->PutMonoRow = write_mono_rgba_span_24; + rb->PutValues = write_rgba_pixels_24; + rb->PutMonoValues = write_mono_rgba_pixels_24; + rb->GetRow = read_rgba_span_24; + rb->GetValues = read_rgba_pixels_24; + rb->RedBits = 8; + rb->GreenBits = 8; + rb->BlueBits = 8; + } + else + { + rb->PutRow = write_rgba_span_32; + rb->PutRowRGB = write_rgb_span_32; + rb->PutMonoRow = write_mono_rgba_span_32; + rb->PutValues = write_rgba_pixels_32; + rb->PutMonoValues = write_mono_rgba_pixels_32; + rb->GetRow = read_rgba_span_32; + rb->GetValues = read_rgba_pixels_32; + rb->RedBits = 8; + rb->GreenBits = 8; + rb->BlueBits = 8; + } + break; + default: + break; + } + } + else { + /* front buffer (actual Windows window) */ + rb->PutRow = write_rgba_span_front; + rb->PutRowRGB = write_rgb_span_front; + rb->PutMonoRow = write_mono_rgba_span_front; + rb->PutValues = write_rgba_pixels_front; + rb->PutMonoValues = write_mono_rgba_pixels_front; + rb->GetRow = read_rgba_span_front; + rb->GetValues = read_rgba_pixels_front; + rb->RedBits = 8; /* XXX fix these (565?) */ + rb->GreenBits = 8; + rb->BlueBits = 8; + } +} + +/** + * Called by ctx->Driver.ResizeBuffers() + * Resize the front/back colorbuffers to match the latest window size. + */ +static void +wmesa_resize_buffers(GLcontext *ctx, GLframebuffer *buffer, + GLuint width, GLuint height) +{ + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_framebuffer(buffer); + + if (pwfb->Base.Width != width || pwfb->Base.Height != height) { + /* Realloc back buffer */ + if (ctx->Visual.doubleBufferMode == 1) { + wmDeleteBackingStore(pwfb); + wmCreateBackingStore(pwfb, width, height); + } + } + _mesa_resize_framebuffer(ctx, buffer, width, height); +} + + +/** + * Called by glViewport. + * This is a good time for us to poll the current window size and adjust + * our renderbuffers to match the current window size. + * Remember, we have no opportunity to respond to conventional + * resize events since the driver has no event loop. + * Thus, we poll. + * MakeCurrent also ends up making a call here, so that ensures + * we get the viewport set correctly, even if the app does not call + * glViewport and relies on the defaults. + */ +static void wmesa_viewport(GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height) +{ + WMesaContext pwc = wmesa_context(ctx); + GLuint new_width, new_height; + + wmesa_get_buffer_size(ctx->WinSysDrawBuffer, &new_width, &new_height); + + /** + * Resize buffers if the window size changed. + */ + wmesa_resize_buffers(ctx, ctx->WinSysDrawBuffer, new_width, new_height); + ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */ +} + + + + +/** + * Called when the driver should update it's state, based on the new_state + * flags. + */ +static void wmesa_update_state(GLcontext *ctx, GLuint new_state) +{ + _swrast_InvalidateState(ctx, new_state); + _swsetup_InvalidateState(ctx, new_state); + _vbo_InvalidateState(ctx, new_state); + _tnl_InvalidateState(ctx, new_state); + + /* TODO - This code is not complete yet because I + * don't know what to do for all state updates. + */ + + if (new_state & _NEW_BUFFERS) { + } +} + + + + + +/**********************************************************************/ +/***** WMESA Functions *****/ +/**********************************************************************/ + +WMesaContext WMesaCreateContext(HDC hDC, + HPALETTE* Pal, + GLboolean rgb_flag, + GLboolean db_flag, + GLboolean alpha_flag) +{ + WMesaContext c; + struct dd_function_table functions; + GLint red_bits, green_bits, blue_bits, alpha_bits; + GLcontext *ctx; + GLvisual *visual; + + (void) Pal; + + /* Indexed mode not supported */ + if (!rgb_flag) + return NULL; + + /* Allocate wmesa context */ + c = CALLOC_STRUCT(wmesa_context); + if (!c) + return NULL; + +#if 0 + /* I do not understand this contributed code */ + /* Support memory and device contexts */ + if(WindowFromDC(hDC) != NULL) { + c->hDC = GetDC(WindowFromDC(hDC)); /* huh ???? */ + } + else { + c->hDC = hDC; + } +#else + c->hDC = hDC; +#endif + + /* Get data for visual */ + /* Dealing with this is actually a bit of overkill because Mesa will end + * up treating all color component size requests less than 8 by using + * a single byte per channel. In addition, the interface to the span + * routines passes colors as an entire byte per channel anyway, so there + * is nothing to be saved by telling the visual to be 16 bits if the device + * is 16 bits. That is, Mesa is going to compute colors down to 8 bits per + * channel anyway. + * But we go through the motions here anyway. + */ + switch (GetDeviceCaps(c->hDC, BITSPIXEL)) { + case 16: + red_bits = green_bits = blue_bits = 5; + alpha_bits = 0; + break; + default: + red_bits = green_bits = blue_bits = 8; + alpha_bits = 8; + break; + } + /* Create visual based on flags */ + visual = _mesa_create_visual(rgb_flag, + db_flag, /* db_flag */ + GL_FALSE, /* stereo */ + red_bits, green_bits, blue_bits, /* color RGB */ + alpha_flag ? alpha_bits : 0, /* color A */ + 0, /* index bits */ + DEFAULT_SOFTWARE_DEPTH_BITS, /* depth_bits */ + 8, /* stencil_bits */ + 16,16,16, /* accum RGB */ + alpha_flag ? 16 : 0, /* accum A */ + 1); /* num samples */ + + if (!visual) { + _mesa_free(c); + return NULL; + } + + /* Set up driver functions */ + _mesa_init_driver_functions(&functions); + functions.GetString = wmesa_get_string; + functions.UpdateState = wmesa_update_state; + functions.GetBufferSize = wmesa_get_buffer_size; + functions.Flush = wmesa_flush; + functions.Clear = clear; + functions.ClearIndex = clear_index; + functions.ClearColor = clear_color; + functions.ResizeBuffers = wmesa_resize_buffers; + functions.Viewport = wmesa_viewport; + + /* initialize the Mesa context data */ + ctx = &c->gl_ctx; + _mesa_initialize_context(ctx, visual, NULL, &functions, (void *)c); + + /* visual no longer needed - it was copied by _mesa_initialize_context() */ + _mesa_destroy_visual(visual); + + _mesa_enable_sw_extensions(ctx); + _mesa_enable_1_3_extensions(ctx); + _mesa_enable_1_4_extensions(ctx); + _mesa_enable_1_5_extensions(ctx); + _mesa_enable_2_0_extensions(ctx); + _mesa_enable_2_1_extensions(ctx); + + /* Initialize the software rasterizer and helper modules. */ + if (!_swrast_CreateContext(ctx) || + !_vbo_CreateContext(ctx) || + !_tnl_CreateContext(ctx) || + !_swsetup_CreateContext(ctx)) { + _mesa_free_context_data(ctx); + _mesa_free(c); + return NULL; + } + _swsetup_Wakeup(ctx); + TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline; + + return c; +} + + +void WMesaDestroyContext( WMesaContext pwc ) +{ + GLcontext *ctx = &pwc->gl_ctx; + WMesaFramebuffer pwfb; + GET_CURRENT_CONTEXT(cur_ctx); + + if (cur_ctx == ctx) { + /* unbind current if deleting current context */ + WMesaMakeCurrent(NULL, NULL); + } + + /* clean up frame buffer resources */ + pwfb = wmesa_lookup_framebuffer(pwc->hDC); + if (pwfb) { + if (ctx->Visual.doubleBufferMode == 1) + wmDeleteBackingStore(pwfb); + wmesa_free_framebuffer(pwc->hDC); + } + + /* Release for device, not memory contexts */ + if (WindowFromDC(pwc->hDC) != NULL) + { + ReleaseDC(WindowFromDC(pwc->hDC), pwc->hDC); + } + DeleteObject(pwc->clearPen); + DeleteObject(pwc->clearBrush); + + _swsetup_DestroyContext(ctx); + _tnl_DestroyContext(ctx); + _vbo_DestroyContext(ctx); + _swrast_DestroyContext(ctx); + + _mesa_free_context_data(ctx); + _mesa_free(pwc); +} + + +/** + * Create a new color renderbuffer. + */ +struct gl_renderbuffer * +wmesa_new_renderbuffer(void) +{ + struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); + if (!rb) + return NULL; + + _mesa_init_renderbuffer(rb, (GLuint)0); + + rb->_BaseFormat = GL_RGBA; + rb->InternalFormat = GL_RGBA; + rb->DataType = CHAN_TYPE; + rb->Delete = wmesa_delete_renderbuffer; + rb->AllocStorage = wmesa_renderbuffer_storage; + return rb; +} + + +void WMesaMakeCurrent(WMesaContext c, HDC hdc) +{ + WMesaFramebuffer pwfb; + + { + /* return if already current */ + GET_CURRENT_CONTEXT(ctx); + WMesaContext pwc = wmesa_context(ctx); + if (pwc && c == pwc && pwc->hDC == hdc) + return; + } + + pwfb = wmesa_lookup_framebuffer(hdc); + + /* Lazy creation of framebuffers */ + if (c && !pwfb && hdc) { + struct gl_renderbuffer *rb; + GLvisual *visual = &c->gl_ctx.Visual; + GLuint width, height; + + get_window_size(hdc, &width, &height); + + c->clearPen = CreatePen(PS_SOLID, 1, 0); + c->clearBrush = CreateSolidBrush(0); + + pwfb = wmesa_new_framebuffer(hdc, visual); + + /* Create back buffer if double buffered */ + if (visual->doubleBufferMode == 1) { + wmCreateBackingStore(pwfb, width, height); + } + + /* make render buffers */ + if (visual->doubleBufferMode == 1) { + rb = wmesa_new_renderbuffer(); + _mesa_add_renderbuffer(&pwfb->Base, BUFFER_BACK_LEFT, rb); + wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 1); + } + rb = wmesa_new_renderbuffer(); + _mesa_add_renderbuffer(&pwfb->Base, BUFFER_FRONT_LEFT, rb); + wmesa_set_renderbuffer_funcs(rb, pwfb->pixelformat, pwfb->cColorBits, 0); + + /* Let Mesa own the Depth, Stencil, and Accum buffers */ + _mesa_add_soft_renderbuffers(&pwfb->Base, + GL_FALSE, /* color */ + visual->depthBits > 0, + visual->stencilBits > 0, + visual->accumRedBits > 0, + visual->alphaBits >0, + GL_FALSE); + } + + if (c && pwfb) + _mesa_make_current(&c->gl_ctx, &pwfb->Base, &pwfb->Base); + else + _mesa_make_current(NULL, NULL, NULL); +} + + +void WMesaSwapBuffers( HDC hdc ) +{ + GET_CURRENT_CONTEXT(ctx); + WMesaContext pwc = wmesa_context(ctx); + WMesaFramebuffer pwfb = wmesa_lookup_framebuffer(hdc); + + if (!pwfb) { + _mesa_problem(NULL, "wmesa: swapbuffers on unknown hdc"); + return; + } + + /* If we're swapping the buffer associated with the current context + * we have to flush any pending rendering commands first. + */ + if (pwc->hDC == hdc) { + _mesa_notifySwapBuffers(ctx); + + BitBlt(pwfb->hDC, 0, 0, pwfb->Base.Width, pwfb->Base.Height, + pwfb->dib_hDC, 0, 0, SRCCOPY); + } + else { + /* XXX for now only allow swapping current window */ + _mesa_problem(NULL, "wmesa: can't swap non-current window"); + } +} + +void WMesaShareLists(WMesaContext ctx_to_share, WMesaContext ctx) +{ + _mesa_share_state(&ctx->gl_ctx, &ctx_to_share->gl_ctx); +} + diff --git a/mesalib/src/mesa/drivers/windows/gdi/wmesadef.h b/mesalib/src/mesa/drivers/windows/gdi/wmesadef.h new file mode 100644 index 000000000..83a42e608 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gdi/wmesadef.h @@ -0,0 +1,43 @@ +#ifndef WMESADEF_H +#define WMESADEF_H +#ifdef __MINGW32__ +#include <windows.h> +#endif +#include "context.h" + + +/** + * The Windows Mesa rendering context, derived from GLcontext. + */ +struct wmesa_context { + GLcontext gl_ctx; /* The core GL/Mesa context */ + HDC hDC; + COLORREF clearColorRef; + HPEN clearPen; + HBRUSH clearBrush; +}; + + +/** + * Windows framebuffer, derived from gl_framebuffer + */ +struct wmesa_framebuffer +{ + struct gl_framebuffer Base; + HDC hDC; + int pixelformat; + GLuint ScanWidth; + BYTE cColorBits; + /* back buffer DIB fields */ + HDC dib_hDC; + BITMAPINFO bmi; + HBITMAP hbmDIB; + HBITMAP hOldBitmap; + PBYTE pbPixels; + struct wmesa_framebuffer *next; +}; + +typedef struct wmesa_framebuffer *WMesaFramebuffer; + + +#endif /* WMESADEF_H */ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/ddlog.c b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.c new file mode 100644 index 000000000..4ae79e2fd --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.c @@ -0,0 +1,192 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Logging functions. +* +****************************************************************************/ + +#define STRICT +#include <windows.h> + +#include "ddlog.h" +#include "gld_driver.h" + +// *********************************************************************** + +static char ddlogbuf[256]; +static FILE* fpDDLog = NULL; // Log file pointer +static char szDDLogName[_MAX_PATH] = {"gldirect.log"}; // Filename of the log +static DDLOG_loggingMethodType ddlogLoggingMethod = DDLOG_NONE; // Default to No Logging +static DDLOG_severityType ddlogDebugLevel; +static BOOL bUIWarning = FALSE; // MessageBox warning ? + +// *********************************************************************** + +void ddlogOpen( + DDLOG_loggingMethodType LoggingMethod, + DDLOG_severityType Severity) +{ + if (fpDDLog != NULL) { + // Tried to re-open the log + ddlogMessage(DDLOG_WARN, "Tried to re-open the log file\n"); + return; + } + + ddlogLoggingMethod = LoggingMethod; + ddlogDebugLevel = Severity; + + if (ddlogLoggingMethod == DDLOG_NORMAL) { + fpDDLog = fopen(szDDLogName, "wt"); + if (fpDDLog == NULL) + return; + } + + ddlogMessage(DDLOG_SYSTEM, "\n"); + ddlogMessage(DDLOG_SYSTEM, "-> Logging Started\n"); +} + +// *********************************************************************** + +void ddlogClose() +{ + // Determine whether the log is already closed + if (fpDDLog == NULL && ddlogLoggingMethod == DDLOG_NORMAL) + return; // Nothing to do. + + ddlogMessage(DDLOG_SYSTEM, "<- Logging Ended\n"); + + if (ddlogLoggingMethod == DDLOG_NORMAL) { + fclose(fpDDLog); + fpDDLog = NULL; + } +} + +// *********************************************************************** + +void ddlogMessage( + DDLOG_severityType severity, + LPSTR message) +{ + char buf[256]; + + // Bail if logging is disabled + if (ddlogLoggingMethod == DDLOG_NONE) + return; + + if (ddlogLoggingMethod == DDLOG_CRASHPROOF) + fpDDLog = fopen(szDDLogName, "at"); + + if (fpDDLog == NULL) + return; + + if (severity >= ddlogDebugLevel) { + sprintf(buf, "DDLog: (%s) %s", ddlogSeverityMessages[severity], message); + fputs(buf, fpDDLog); // Write string to file + OutputDebugString(buf); // Echo to debugger + } + + if (ddlogLoggingMethod == DDLOG_CRASHPROOF) { + fflush(fpDDLog); // Write info to disk + fclose(fpDDLog); + fpDDLog = NULL; + } + + // Popup message box if critical error + if (bUIWarning && severity == DDLOG_CRITICAL) { + MessageBox(NULL, buf, "GLDirect", MB_OK | MB_ICONWARNING | MB_TASKMODAL); + } +} + +// *********************************************************************** + +// Write a string value to the log file +void ddlogError( + DDLOG_severityType severity, + LPSTR message, + HRESULT hResult) +{ +#ifdef _USE_GLD3_WGL + char dxErrStr[1024]; + _gldDriver.GetDXErrorString(hResult, &dxErrStr[0], sizeof(dxErrStr)); + if (FAILED(hResult)) { + sprintf(ddlogbuf, "DDLog: %s %8x:[ %s ]\n", message, hResult, dxErrStr); + } else + sprintf(ddlogbuf, "DDLog: %s\n", message); +#else + if (FAILED(hResult)) { + sprintf(ddlogbuf, "DDLog: %s %8x:[ %s ]\n", message, hResult, DDErrorToString(hResult)); + } else + sprintf(ddlogbuf, "DDLog: %s\n", message); +#endif + ddlogMessage(severity, ddlogbuf); +} + +// *********************************************************************** + +void ddlogPrintf( + DDLOG_severityType severity, + LPSTR message, + ...) +{ + va_list args; + + va_start(args, message); + vsprintf(ddlogbuf, message, args); + va_end(args); + + lstrcat(ddlogbuf, "\n"); + + ddlogMessage(severity, ddlogbuf); +} + +// *********************************************************************** + +void ddlogWarnOption( + BOOL bWarnOption) +{ + bUIWarning = bWarnOption; +} + +// *********************************************************************** + +void ddlogPathOption( + LPSTR szPath) +{ + char szPathName[_MAX_PATH]; + + strcpy(szPathName, szPath); + strcat(szPathName, "\\"); + strcat(szPathName, szDDLogName); + strcpy(szDDLogName, szPathName); +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/ddlog.h b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.h new file mode 100644 index 000000000..d64067e22 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/ddlog.h @@ -0,0 +1,109 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Logging functions. +* +****************************************************************************/ + +#ifndef __DDLOG_H +#define __DDLOG_H + +#include <stdio.h> + +#ifndef _USE_GLD3_WGL +#include "dderrstr.h" // ddraw/d3d error string +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef enum { + DDLOG_NONE = 0, // No log output + DDLOG_NORMAL = 1, // Log is kept open + DDLOG_CRASHPROOF = 2, // Log is closed and flushed + DDLOG_METHOD_FORCE_DWORD = 0x7fffffff, +} DDLOG_loggingMethodType; + +// Denotes type of message sent to the logging functions +typedef enum { + DDLOG_INFO = 0, // Information only + DDLOG_WARN = 1, // Warning only + DDLOG_ERROR = 2, // Notify user of an error + DDLOG_CRITICAL = 3, // Exceptionally severe error + DDLOG_SYSTEM = 4, // System message. Not an error + // but must always be printed. + DDLOG_SEVERITY_FORCE_DWORD = 0x7fffffff, // Make enum dword +} DDLOG_severityType; + +#ifdef _USE_GLD3_WGL +// Synomyms +#define GLDLOG_INFO DDLOG_INFO +#define GLDLOG_WARN DDLOG_WARN +#define GLDLOG_ERROR DDLOG_ERROR +#define GLDLOG_CRITICAL DDLOG_CRITICAL +#define GLDLOG_SYSTEM DDLOG_SYSTEM +#endif + +// The message that will be output to the log +static const char *ddlogSeverityMessages[] = { + "INFO", + "WARN", + "ERROR", + "*CRITICAL*", + "System", +}; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +void ddlogOpen(DDLOG_loggingMethodType LoggingMethod, DDLOG_severityType Severity); +void ddlogClose(); +void ddlogMessage(DDLOG_severityType severity, LPSTR message); +void ddlogError(DDLOG_severityType severity, LPSTR message, HRESULT hResult); +void ddlogPrintf(DDLOG_severityType severity, LPSTR message, ...); +void ddlogWarnOption(BOOL bWarnOption); +void ddlogPathOption(LPSTR szPath); + +#ifdef _USE_GLD3_WGL +// Synomyms +#define gldLogMessage ddlogMessage +#define gldLogError ddlogError +#define gldLogPrintf ddlogPrintf +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c new file mode 100644 index 000000000..e9c23d1cc --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.c @@ -0,0 +1,2214 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Context handling. +* +****************************************************************************/ + +#include "dglcontext.h" + +// Get compile errors without this. KeithH +//#include "scitech.h" // ibool, etc. + +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" + +extern void _gld_mesa_warning(GLcontext *, char *); +extern void _gld_mesa_fatal(GLcontext *, char *); +#endif // _USE_GLD3_WGL + +// TODO: Clean out old DX6-specific code from GLD 2.x CAD driver +// if it is no longer being built as part of GLDirect. (DaveM) + +// *********************************************************************** + +#define GLDERR_NONE 0 +#define GLDERR_MEM 1 +#define GLDERR_DDRAW 2 +#define GLDERR_D3D 3 +#define GLDERR_BPP 4 + +char szResourceWarning[] = +"GLDirect does not have enough video memory resources\n" +"to support the requested OpenGL rendering context.\n\n" +"You may have to reduce the current display resolution\n" +"to obtain satisfactory OpenGL performance.\n"; + +char szDDrawWarning[] = +"GLDirect is unable to initialize DirectDraw for the\n" +"requested OpenGL rendering context.\n\n" +"You will have to check the DirectX control panel\n" +"for further information.\n"; + +char szD3DWarning[] = +"GLDirect is unable to initialize Direct3D for the\n" +"requested OpenGL rendering context.\n\n" +"You may have to change the display mode resolution\n" +"color depth or check the DirectX control panel for\n" +"further information.\n"; + +char szBPPWarning[] = +"GLDirect is unable to use the selected color depth for\n" +"the requested OpenGL rendering context.\n\n" +"You will have to change the display mode resolution\n" +"color depth with the Display Settings control panel.\n"; + +int nContextError = GLDERR_NONE; + +// *********************************************************************** + +#define VENDORID_ATI 0x1002 + +static DWORD devATIRagePro[] = { + 0x4742, // 3D RAGE PRO BGA AGP 1X/2X + 0x4744, // 3D RAGE PRO BGA AGP 1X only + 0x4749, // 3D RAGE PRO BGA PCI 33 MHz + 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz + 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D + 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz + 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz + 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz + 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz + 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D +}; + +static DWORD devATIRageIIplus[] = { + 0x4755, // 3D RAGE II+ + 0x4756, // 3D RAGE IIC PQFP PCI + 0x4757, // 3D RAGE IIC BGA AGP + 0x475A, // 3D RAGE IIC PQFP AGP + 0x4C47, // 3D RAGE LT-G +}; + +// *********************************************************************** + +#ifndef _USE_GLD3_WGL +extern DGL_mesaFuncs mesaFuncs; +#endif + +extern DWORD dwLogging; + +#ifdef GLD_THREADS +#pragma message("compiling DGLCONTEXT.C vars for multi-threaded support") +CRITICAL_SECTION CriticalSection; // for serialized access +DWORD dwTLSCurrentContext = 0xFFFFFFFF; // TLS index for current context +DWORD dwTLSPixelFormat = 0xFFFFFFFF; // TLS index for current pixel format +#endif +HGLRC iCurrentContext = 0; // Index of current context (static) +BOOL bContextReady = FALSE; // Context state ready ? + +DGL_ctx ctxlist[DGL_MAX_CONTEXTS]; // Context list + +// *********************************************************************** + +static BOOL bHaveWin95 = FALSE; +static BOOL bHaveWinNT = FALSE; +static BOOL bHaveWin2K = FALSE; + +/**************************************************************************** +REMARKS: +Detect the installed OS type. +****************************************************************************/ +static void DetectOS(void) +{ + OSVERSIONINFO VersionInformation; + LPOSVERSIONINFO lpVersionInformation = &VersionInformation; + + VersionInformation.dwOSVersionInfoSize = sizeof(VersionInformation); + + GetVersionEx(lpVersionInformation); + + switch (VersionInformation.dwPlatformId) { + case VER_PLATFORM_WIN32_WINDOWS: + bHaveWin95 = TRUE; + bHaveWinNT = FALSE; + bHaveWin2K = FALSE; + break; + case VER_PLATFORM_WIN32_NT: + bHaveWin95 = FALSE; + if (VersionInformation.dwMajorVersion <= 4) { + bHaveWinNT = TRUE; + bHaveWin2K = FALSE; + } + else { + bHaveWinNT = FALSE; + bHaveWin2K = TRUE; + } + break; + case VER_PLATFORM_WIN32s: + bHaveWin95 = FALSE; + bHaveWinNT = FALSE; + bHaveWin2K = FALSE; + break; + } +} + +// *********************************************************************** + +HWND hWndEvent = NULL; // event monitor window +HWND hWndLastActive = NULL; // last active client window +LONG __stdcall GLD_EventWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam); + +// *********************************************************************** + +// Checks if the HGLRC is valid in range of context list. +BOOL dglIsValidContext( + HGLRC a) +{ + return ((int)a > 0 && (int)a <= DGL_MAX_CONTEXTS); +} + +// *********************************************************************** + +// Convert a HGLRC to a pointer into the context list. +DGL_ctx* dglGetContextAddress( + const HGLRC a) +{ + if (dglIsValidContext(a)) + return &ctxlist[(int)a-1]; + return NULL; +} + +// *********************************************************************** + +// Return the current HGLRC (however it may be stored for multi-threading). +HGLRC dglGetCurrentContext(void) +{ +#ifdef GLD_THREADS + HGLRC hGLRC; + // load from thread-specific instance + if (glb.bMultiThreaded) { + // protect against calls from arbitrary threads + __try { + hGLRC = (HGLRC)TlsGetValue(dwTLSCurrentContext); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + hGLRC = iCurrentContext; + } + } + // load from global static var + else { + hGLRC = iCurrentContext; + } + return hGLRC; +#else + return iCurrentContext; +#endif +} + +// *********************************************************************** + +// Set the current HGLRC (however it may be stored for multi-threading). +void dglSetCurrentContext(HGLRC hGLRC) +{ +#ifdef GLD_THREADS + // store in thread-specific instance + if (glb.bMultiThreaded) { + // protect against calls from arbitrary threads + __try { + TlsSetValue(dwTLSCurrentContext, (LPVOID)hGLRC); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + iCurrentContext = hGLRC; + } + } + // store in global static var + else { + iCurrentContext = hGLRC; + } +#else + iCurrentContext = hGLRC; +#endif +} + +// *********************************************************************** + +// Return the current HDC only for a currently active HGLRC. +HDC dglGetCurrentDC(void) +{ + HGLRC hGLRC; + DGL_ctx* lpCtx; + + hGLRC = dglGetCurrentContext(); + if (hGLRC) { + lpCtx = dglGetContextAddress(hGLRC); + return lpCtx->hDC; + } + return 0; +} + +// *********************************************************************** + +void dglInitContextState() +{ + int i; + WNDCLASS wc; + +#ifdef GLD_THREADS + // Allocate thread local storage indexes for current context and pixel format + dwTLSCurrentContext = TlsAlloc(); + dwTLSPixelFormat = TlsAlloc(); +#endif + + dglSetCurrentContext(NULL); // No current rendering context + + // Clear all context data + ZeroMemory(ctxlist, sizeof(ctxlist[0]) * DGL_MAX_CONTEXTS); + + for (i=0; i<DGL_MAX_CONTEXTS; i++) + ctxlist[i].bAllocated = FALSE; // Flag context as unused + + // This section of code crashes the dll in circumstances where the app + // creates and destroys contexts. +/* + // Register the class for our event monitor window + wc.style = 0; + wc.lpfnWndProc = GLD_EventWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = GetModuleHandle(NULL); + wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName = "GLDIRECT"; + RegisterClass(&wc); + + // Create the non-visible window to monitor all broadcast messages + hWndEvent = CreateWindowEx( + WS_EX_TOOLWINDOW,"GLDIRECT","GLDIRECT",WS_POPUP, + 0,0,0,0, + NULL,NULL,GetModuleHandle(NULL),NULL); +*/ + +#ifdef GLD_THREADS + // Create a critical section object for serializing access to + // DirectDraw and DDStereo create/destroy functions in multiple threads + if (glb.bMultiThreaded) + InitializeCriticalSection(&CriticalSection); +#endif + + // Context state is now initialized and ready + bContextReady = TRUE; +} + +// *********************************************************************** + +void dglDeleteContextState() +{ + int i; + static BOOL bOnceIsEnough = FALSE; + + // Only call once, from either DGL_exitDriver(), or DLL_PROCESS_DETACH + if (bOnceIsEnough) + return; + bOnceIsEnough = TRUE; + + for (i=0; i<DGL_MAX_CONTEXTS; i++) { + if (ctxlist[i].bAllocated == TRUE) { + ddlogPrintf(DDLOG_WARN, "** Context %i not deleted - cleaning up.", (i+1)); + dglDeleteContext((HGLRC)(i+1)); + } + } + + // Context state is no longer ready + bContextReady = FALSE; + + // If executed when DLL unloads, DDraw objects may be invalid. + // So catch any page faults with this exception handler. +__try { + + // Release final DirectDraw interfaces + if (glb.bDirectDrawPersistant) { +// RELEASE(glb.lpGlobalPalette); +// RELEASE(glb.lpDepth4); +// RELEASE(glb.lpBack4); +// RELEASE(glb.lpPrimary4); +// RELEASE(glb.lpDD4); + } +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContextState."); +} + + // Destroy our event monitor window + if (hWndEvent) { + DestroyWindow(hWndEvent); + hWndEvent = hWndLastActive = NULL; + } + +#ifdef GLD_THREADS + // Destroy the critical section object + if (glb.bMultiThreaded) + DeleteCriticalSection(&CriticalSection); + + // Release thread local storage indexes for current HGLRC and pixel format + TlsFree(dwTLSPixelFormat); + TlsFree(dwTLSCurrentContext); +#endif +} + +// *********************************************************************** + +// Application Window message handler interception +static LONG __stdcall dglWndProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + DGL_ctx* lpCtx = NULL; + LONG lpfnWndProc = 0L; + int i; + HGLRC hGLRC; + RECT rect; + PAINTSTRUCT ps; + BOOL bQuit = FALSE; + BOOL bMain = FALSE; + LONG rc; + + // Get the window's message handler *before* it is unhooked in WM_DESTROY + + // Is this the main window? + if (hwnd == glb.hWndActive) { + bMain = TRUE; + lpfnWndProc = glb.lpfnWndProc; + } + // Search for DGL context matching window handle + for (i=0; i<DGL_MAX_CONTEXTS; i++) { + if (ctxlist[i].hWnd == hwnd) { + lpCtx = &ctxlist[i]; + lpfnWndProc = lpCtx->lpfnWndProc; + break; + } + } + // Not one of ours... + if (!lpfnWndProc) + return DefWindowProc(hwnd, msg, wParam, lParam); + + // Intercept messages amd process *before* passing on to window + switch (msg) { +#ifdef _USE_GLD3_WGL + case WM_DISPLAYCHANGE: + glb.bPixelformatsDirty = TRUE; + break; +#endif + case WM_ACTIVATEAPP: + glb.bAppActive = (BOOL)wParam; + ddlogPrintf(DDLOG_INFO, "Calling app has been %s", glb.bAppActive ? "activated" : "de-activated"); + break; + case WM_ERASEBKGND: + // Eat the GDI erase event for the GL window + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + lpCtx->bGDIEraseBkgnd = TRUE; + return TRUE; + case WM_PAINT: + // Eat the invalidated update region if render scene is in progress + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + if (lpCtx->bFrameStarted) { + if (GetUpdateRect(hwnd, &rect, FALSE)) { + BeginPaint(hwnd, &ps); + EndPaint(hwnd, &ps); + ValidateRect(hwnd, &rect); + return TRUE; + } + } + break; + } + // Call the appropriate window message handler + rc = CallWindowProc((WNDPROC)lpfnWndProc, hwnd, msg, wParam, lParam); + + // Intercept messages and process *after* passing on to window + switch (msg) { + case WM_QUIT: + case WM_DESTROY: + bQuit = TRUE; + if (lpCtx && lpCtx->bAllocated) { + ddlogPrintf(DDLOG_WARN, "WM_DESTROY detected for HWND=%X, HDC=%X, HGLRC=%d", hwnd, lpCtx->hDC, i+1); + dglDeleteContext((HGLRC)(i+1)); + } + break; +#if 0 + case WM_SIZE: + // Resize surfaces to fit window but not viewport (in case app did not bother) + if (!lpCtx || !lpCtx->bHasBeenCurrent) + break; + w = LOWORD(lParam); + h = HIWORD(lParam); + if (lpCtx->dwWidth < w || lpCtx->dwHeight < h) { + if (!dglWglResizeBuffers(lpCtx->glCtx, TRUE)) + dglWglResizeBuffers(lpCtx->glCtx, FALSE); + } + break; +#endif + } + + // If the main window is quitting, then so should we... + if (bMain && bQuit) { + ddlogPrintf(DDLOG_SYSTEM, "shutting down after WM_DESTROY detected for main HWND=%X", hwnd); + dglDeleteContextState(); + dglExitDriver(); + } + + return rc; +} + +// *********************************************************************** + +// Driver Window message handler +static LONG __stdcall GLD_EventWndProc( + HWND hwnd, + UINT msg, + WPARAM wParam, + LPARAM lParam) +{ + switch (msg) { + // May be sent by splash screen dialog on exit + case WM_ACTIVATE: + if (LOWORD(wParam) == WA_ACTIVE && glb.hWndActive) { + SetForegroundWindow(glb.hWndActive); + return 0; + } + break; + } + return DefWindowProc(hwnd, msg, wParam, lParam); +} + +// *********************************************************************** + +// Intercepted Keyboard handler for detecting hot keys. +LRESULT CALLBACK dglKeyProc( + int code, + WPARAM wParam, + LPARAM lParam) +{ + HWND hWnd, hWndFrame; + HGLRC hGLRC = NULL; + DGL_ctx* lpCtx = NULL; + int cmd = 0, dx1 = 0, dx2 = 0, i; + static BOOL bAltPressed = FALSE; + static BOOL bCtrlPressed = FALSE; + static BOOL bShiftPressed = FALSE; + RECT r, rf, rc; + POINT pt; + BOOL bForceReshape = FALSE; + + return CallNextHookEx(hKeyHook, code, wParam, lParam); +} + +// *********************************************************************** + +HWND hWndMatch; + +// Window handle enumeration procedure. +BOOL CALLBACK dglEnumChildProc( + HWND hWnd, + LPARAM lParam) +{ + RECT rect; + + // Find window handle with matching client rect. + GetClientRect(hWnd, &rect); + if (EqualRect(&rect, (RECT*)lParam)) { + hWndMatch = hWnd; + return FALSE; + } + // Continue with next child window. + return TRUE; +} + +// *********************************************************************** + +// Find window handle with matching client rect. +HWND dglFindWindowRect( + RECT* pRect) +{ + hWndMatch = NULL; + EnumChildWindows(GetForegroundWindow(), dglEnumChildProc, (LPARAM)pRect); + return hWndMatch; +} + +// *********************************************************************** +#ifndef _USE_GLD3_WGL +void dglChooseDisplayMode( + DGL_ctx *lpCtx) +{ + // Note: Choose an exact match if possible. + + int i; + DWORD area; + DWORD bestarea; + DDSURFACEDESC2 *lpDDSD = NULL; // Mode list pointer + DDSURFACEDESC2 *lpBestDDSD = NULL; // Pointer to best + + lpDDSD = glb.lpDisplayModes; + for (i=0; i<glb.nDisplayModeCount; i++, lpDDSD++) { + if ((lpDDSD->dwWidth == lpCtx->dwWidth) && + (lpDDSD->dwHeight == lpCtx->dwHeight)) + goto matched; // Mode has been exactly matched + // Choose modes that are larger in both dimensions than + // the window, but smaller in area than the current best. + if ( (lpDDSD->dwWidth >= lpCtx->dwWidth) && + (lpDDSD->dwHeight >= lpCtx->dwHeight)) + { + if (lpBestDDSD == NULL) { + lpBestDDSD = lpDDSD; + bestarea = lpDDSD->dwWidth * lpDDSD->dwHeight; + continue; + } + area = lpDDSD->dwWidth * lpDDSD->dwHeight; + if (area < bestarea) { + lpBestDDSD = lpDDSD; + bestarea = area; + } + } + } + + // Safety check + if (lpBestDDSD == NULL) { + ddlogMessage(DDLOG_CRITICAL, "dglChooseDisplayMode"); + return; + } + + lpCtx->dwModeWidth = lpBestDDSD->dwWidth; + lpCtx->dwModeHeight = lpBestDDSD->dwHeight; +matched: + ddlogPrintf(DDLOG_INFO, "Matched (%ldx%ld) to (%ldx%ld)", + lpCtx->dwWidth, lpCtx->dwHeight, lpCtx->dwModeWidth, lpCtx->dwModeHeight); +} +#endif // _USE_GLD3_WGL +// *********************************************************************** + +static BOOL IsDevice( + DWORD *lpDeviceIdList, + DWORD dwDeviceId, + int count) +{ + int i; + + for (i=0; i<count; i++) + if (dwDeviceId == lpDeviceIdList[i]) + return TRUE; + + return FALSE; +} + +// *********************************************************************** + +void dglTestForBrokenCards( + DGL_ctx *lpCtx) +{ +#ifndef _GLD3 + DDDEVICEIDENTIFIER dddi; // DX6 device identifier + + // Sanity check. + if (lpCtx == NULL) { + // Testing for broken cards is sensitive area, so we don't want + // anything saying "broken cards" in the error message. ;) + ddlogMessage(DDLOG_ERROR, "Null context passed to TFBC\n"); + return; + } + + if (lpCtx->lpDD4 == NULL) { + // Testing for broken cards is sensitive area, so we don't want + // anything saying "broken cards" in the error message. ;) + ddlogMessage(DDLOG_ERROR, "Null DD4 passed to TFBC\n"); + return; + } + + // Microsoft really fucked up with the GetDeviceIdentifier function + // on Windows 2000, since it locks up on stock driers on the CD. Updated + // drivers from vendors appear to work, but we can't identify the drivers + // without this function!!! For now we skip these tests on Windows 2000. + if ((GetVersion() & 0x80000000UL) == 0) + return; + + // Obtain device info + if (FAILED(IDirectDraw4_GetDeviceIdentifier(lpCtx->lpDD4, &dddi, 0))) + return; + + // Useful info. Log it. + ddlogPrintf(DDLOG_INFO, "DirectDraw: VendorId=0x%x, DeviceId=0x%x", dddi.dwVendorId, dddi.dwDeviceId); + + // Vendor 1: ATI + if (dddi.dwVendorId == VENDORID_ATI) { + // Test A: ATI Rage PRO + if (IsDevice(devATIRagePro, dddi.dwDeviceId, sizeof(devATIRagePro))) + glb.bUseMipmaps = FALSE; + // Test B: ATI Rage II+ + if (IsDevice(devATIRageIIplus, dddi.dwDeviceId, sizeof(devATIRageIIplus))) + glb.bEmulateAlphaTest = TRUE; + } + + // Vendor 2: Matrox + if (dddi.dwVendorId == 0x102B) { + // Test: Matrox G400 stencil buffer support does not work for AutoCAD + if (dddi.dwDeviceId == 0x0525) { + lpCtx->lpPF->pfd.cStencilBits = 0; + if (lpCtx->lpPF->iZBufferPF != -1) { + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitDepth = 0; + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwStencilBitMask = 0; + glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags &= ~DDPF_STENCILBUFFER; + } + } + } +#endif // _GLD3 +} + +// *********************************************************************** + +BOOL dglCreateContextBuffers( + HDC a, + DGL_ctx *lpCtx, + BOOL bFallback) +{ + HRESULT hResult; + + int i; +// HGLRC hGLRC; +// DGL_ctx* lpCtx; + +#ifndef _USE_GLD3_WGL + DWORD dwFlags; + DDSURFACEDESC2 ddsd2; + DDSCAPS2 ddscaps2; + LPDIRECTDRAWCLIPPER lpddClipper; + D3DDEVICEDESC D3DHWDevDesc; // Direct3D Hardware description + D3DDEVICEDESC D3DHELDevDesc; // Direct3D Hardware Emulation Layer +#endif // _USE_GLD3_WGL + + float inv_aspect; + + GLenum bDoubleBuffer; // TRUE if double buffer required + GLenum bDepthBuffer; // TRUE if depth buffer required + + const PIXELFORMATDESCRIPTOR *lpPFD = &lpCtx->lpPF->pfd; + + // Vars for Mesa visual + DWORD dwDepthBits = 0; + DWORD dwStencilBits = 0; + DWORD dwAlphaBits = 0; + DWORD bAlphaSW = GL_FALSE; + DWORD bDouble = GL_FALSE; + + DDSURFACEDESC2 ddsd2DisplayMode; + BOOL bFullScrnWin = FALSE; // fullscreen-size window ? + DDBLTFX ddbltfx; + DWORD dwMemoryType = (bFallback) ? DDSCAPS_SYSTEMMEMORY : glb.dwMemoryType; + BOOL bBogusWindow = FALSE; // non-drawable window ? + DWORD dwColorRef = 0; // GDI background color + RECT rcDst; // GDI window rect + POINT pt; // GDI window point + + // Palette used for creating default global palette + PALETTEENTRY ppe[256]; + +#ifndef _USE_GLD3_WGL + // Vertex buffer description. Used for creation of vertex buffers + D3DVERTEXBUFFERDESC vbufdesc; +#endif // _USE_GLD3_WGL + +#define DDLOG_CRITICAL_OR_WARN (bFallback ? DDLOG_CRITICAL : DDLOG_WARN) + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContextBuffers for HDC=%X", a); + nContextError = GLDERR_NONE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw object creation or DDS start + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // Check for back buffer + bDoubleBuffer = GL_TRUE; //(lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE; + // Since we always do back buffering, check if we emulate front buffering + lpCtx->EmulateSingle = + (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE; +#if 0 // Don't have to mimic MS OpenGL behavior for front-buffering (DaveM) + lpCtx->EmulateSingle |= + (lpPFD->dwFlags & PFD_SUPPORT_GDI) ? TRUE : FALSE; +#endif + + // Check for depth buffer + bDepthBuffer = (lpPFD->cDepthBits) ? GL_TRUE : GL_FALSE; + + lpCtx->bDoubleBuffer = bDoubleBuffer; + lpCtx->bDepthBuffer = bDepthBuffer; + + // Set the Fullscreen flag for the context. +// lpCtx->bFullscreen = glb.bFullscreen; + + // Obtain the dimensions of the rendering window + lpCtx->hDC = a; // Cache DC + lpCtx->hWnd = WindowFromDC(lpCtx->hDC); + // Check for non-window DC = memory DC ? + if (lpCtx->hWnd == NULL) { + // bitmap memory contexts are always single-buffered + lpCtx->EmulateSingle = TRUE; + bBogusWindow = TRUE; + ddlogPrintf(DDLOG_INFO, "Non-Window Memory Device Context"); + if (GetClipBox(lpCtx->hDC, &lpCtx->rcScreenRect) == ERROR) { + ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglCreateContext\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + } + else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) { + bBogusWindow = TRUE; + ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglCreateContext\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + lpCtx->dwWidth = lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left; + lpCtx->dwHeight = lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top; + + ddlogPrintf(DDLOG_INFO, "Input window %X: w=%i, h=%i", + lpCtx->hWnd, lpCtx->dwWidth, lpCtx->dwHeight); + + // What if app only zeroes one dimension instead of both? (DaveM) + if ( (lpCtx->dwWidth == 0) || (lpCtx->dwHeight == 0) ) { + // Make the buffer size something sensible + lpCtx->dwWidth = 8; + lpCtx->dwHeight = 8; + } + + // Set defaults + lpCtx->dwModeWidth = lpCtx->dwWidth; + lpCtx->dwModeHeight = lpCtx->dwHeight; +/* + // Find best display mode for fullscreen + if (glb.bFullscreen || !glb.bPrimary) { + dglChooseDisplayMode(lpCtx); + } +*/ + // Misc initialisation + lpCtx->bCanRender = FALSE; // No rendering allowed yet + lpCtx->bSceneStarted = FALSE; + lpCtx->bFrameStarted = FALSE; + + // Detect OS (specifically 'Windows 2000' or 'Windows XP') + DetectOS(); + + // NOTE: WinNT not supported + ddlogPrintf(DDLOG_INFO, "OS: %s", bHaveWin95 ? "Win9x" : (bHaveWin2K ? "Win2000/XP" : "Unsupported") ); + + // Test for Fullscreen + if (bHaveWin95) { // Problems with fullscreen on Win2K/XP + if ((GetSystemMetrics(SM_CXSCREEN) == lpCtx->dwWidth) && + (GetSystemMetrics(SM_CYSCREEN) == lpCtx->dwHeight)) + { + // Workaround for some apps that crash when going fullscreen. + //lpCtx->bFullscreen = TRUE; + } + + } + +#ifdef _USE_GLD3_WGL + _gldDriver.CreateDrawable(lpCtx, glb.bDirectDrawPersistant, glb.bPersistantBuffers); +#else + // Check if DirectDraw has already been created by original GLRC (DaveM) + if (glb.bDirectDrawPersistant && glb.bDirectDraw) { + lpCtx->lpDD4 = glb.lpDD4; + IDirectDraw4_AddRef(lpCtx->lpDD4); + goto SkipDirectDrawCreate; + } + + // Create DirectDraw object + if (glb.bPrimary) + hResult = DirectDrawCreate(NULL, &lpCtx->lpDD1, NULL); + else { + // A non-primary device is to be used. + // Force context to be Fullscreen, secondary adaptors can not + // be used in a window. + hResult = DirectDrawCreate(&glb.ddGuid, &lpCtx->lpDD1, NULL); + lpCtx->bFullscreen = TRUE; + } + if (FAILED(hResult)) { + MessageBox(NULL, "Unable to initialize DirectDraw", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw interface", hResult); + nContextError = GLDERR_DDRAW; + goto return_with_error; + } + + // Query for DX6 IDirectDraw4. + hResult = IDirectDraw_QueryInterface(lpCtx->lpDD1, + &IID_IDirectDraw4, + (void**)&lpCtx->lpDD4); + if (FAILED(hResult)) { + MessageBox(NULL, "GLDirect requires DirectX 6.0 or above", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create DirectDraw4 interface", hResult); + nContextError = GLDERR_DDRAW; + goto return_with_error; + } + + // Cache DirectDraw interface for subsequent GLRCs + if (glb.bDirectDrawPersistant && !glb.bDirectDraw) { + glb.lpDD4 = lpCtx->lpDD4; + IDirectDraw4_AddRef(glb.lpDD4); + glb.bDirectDraw = TRUE; + } +SkipDirectDrawCreate: + + // Now we have a DD4 interface we can check for broken cards + dglTestForBrokenCards(lpCtx); + + // Test if primary device can use flipping instead of blitting + ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode)); + ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode); + hResult = IDirectDraw4_GetDisplayMode( + lpCtx->lpDD4, + &ddsd2DisplayMode); + if (SUCCEEDED(hResult)) { + if ( (lpCtx->dwWidth == ddsd2DisplayMode.dwWidth) && + (lpCtx->dwHeight == ddsd2DisplayMode.dwHeight) ) { + // We have a fullscreen-size window + bFullScrnWin = TRUE; + // OK to use DirectDraw fullscreen mode ? + if (glb.bPrimary && !glb.bFullscreenBlit && !lpCtx->EmulateSingle && !glb.bDirectDrawPersistant) { + lpCtx->bFullscreen = TRUE; + ddlogMessage(DDLOG_INFO, "Primary upgraded to page flipping.\n"); + } + } + // Cache the display mode dimensions + lpCtx->dwModeWidth = ddsd2DisplayMode.dwWidth; + lpCtx->dwModeHeight = ddsd2DisplayMode.dwHeight; + } + + // Clamp the effective window dimensions to primary surface. + // We need to do this for D3D viewport dimensions even if wide + // surfaces are supported. This also is a good idea for handling + // whacked-out window dimensions passed for non-drawable windows + // like Solid Edge. (DaveM) + if (lpCtx->dwWidth > ddsd2DisplayMode.dwWidth) + lpCtx->dwWidth = ddsd2DisplayMode.dwWidth; + if (lpCtx->dwHeight > ddsd2DisplayMode.dwHeight) + lpCtx->dwHeight = ddsd2DisplayMode.dwHeight; + + // Check for non-RGB desktop resolution + if (!lpCtx->bFullscreen && ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount <= 8) { + ddlogPrintf(DDLOG_CRITICAL_OR_WARN, "Desktop color depth %d bpp not supported", + ddsd2DisplayMode.ddpfPixelFormat.dwRGBBitCount); + nContextError = GLDERR_BPP; + goto return_with_error; + } +#endif // _USE_GLD3_WGL + + ddlogPrintf(DDLOG_INFO, "Window: w=%i, h=%i (%s)", + lpCtx->dwWidth, + lpCtx->dwHeight, + lpCtx->bFullscreen ? "fullscreen" : "windowed"); + +#ifndef _USE_GLD3_WGL + // Obtain ddraw caps + ZeroMemory(&lpCtx->ddCaps, sizeof(DDCAPS)); + lpCtx->ddCaps.dwSize = sizeof(DDCAPS); + if (glb.bHardware) { + // Get HAL caps + IDirectDraw4_GetCaps(lpCtx->lpDD4, &lpCtx->ddCaps, NULL); + } else { + // Get HEL caps + IDirectDraw4_GetCaps(lpCtx->lpDD4, NULL, &lpCtx->ddCaps); + } + + // If this flag is present then we can't default to Mesa + // SW rendering between BeginScene() and EndScene(). + if (lpCtx->ddCaps.dwCaps2 & DDCAPS2_NO2DDURING3DSCENE) { + ddlogMessage(DDLOG_INFO, + "Warning : No 2D allowed during 3D scene.\n"); + } + + // Query for DX6 Direct3D3 interface + hResult = IDirectDraw4_QueryInterface(lpCtx->lpDD4, + &IID_IDirect3D3, + (void**)&lpCtx->lpD3D3); + if (FAILED(hResult)) { + MessageBox(NULL, "Unable to initialize Direct3D", "GLDirect", MB_OK); + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D interface", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // Context creation + if (lpCtx->bFullscreen) { + // FULLSCREEN + + // Disable warning popups when in fullscreen mode + ddlogWarnOption(FALSE); + + // Have to release persistant primary surface if fullscreen mode + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + RELEASE(glb.lpPrimary4); + glb.bDirectDrawPrimary = FALSE; + } + + dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM) + hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, lpCtx->hWnd, dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Exclusive Fullscreen mode", hResult); + goto return_with_error; + } + + hResult = IDirectDraw4_SetDisplayMode(lpCtx->lpDD4, + lpCtx->dwModeWidth, + lpCtx->dwModeHeight, + lpPFD->cColorBits, + 0, + 0); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetDisplayMode failed", hResult); + goto return_with_error; + } + + // ** The display mode has changed, so dont use MessageBox! ** + + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + + if (bDoubleBuffer) { + // Double buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + DDSCAPS_FLIP | + DDSCAPS_COMPLEX | + DDSCAPS_3DDEVICE | + dwMemoryType; + ddsd2.dwBackBufferCount = 1; + + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + // Render target surface + ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct. + ddscaps2.dwCaps = DDSCAPS_BACKBUFFER; + hResult = IDirectDrawSurface4_GetAttachedSurface(lpCtx->lpFront4, &ddscaps2, &lpCtx->lpBack4); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "GetAttachedSurface failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + } else { + // Single buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + //DDSCAPS_3DDEVICE | + dwMemoryType; + + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + lpCtx->lpBack4 = NULL; + } + } else { + // WINDOWED + + // OK to enable warning popups in windowed mode + ddlogWarnOption(glb.bMessageBoxWarnings); + + dwFlags = DDSCL_NORMAL; + if (glb.bMultiThreaded) + dwFlags |= DDSCL_MULTITHREADED; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // fast FPU setup optional (DaveM) + hResult = IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, + lpCtx->hWnd, + dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to set Normal coop level", hResult); + goto return_with_error; + } + // Has Primary surface already been created for original GLRC ? + // Note this can only be applicable for windowed modes + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + lpCtx->lpFront4 = glb.lpPrimary4; + IDirectDrawSurface4_AddRef(lpCtx->lpFront4); + // Update the window on the default clipper + IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + IDirectDrawClipper_Release(lpddClipper); + goto SkipPrimaryCreate; + } + + // Primary surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (primary) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + + // Cache Primary surface for subsequent GLRCs + // Note this can only be applicable to subsequent windowed modes + if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) { + glb.lpPrimary4 = lpCtx->lpFront4; + IDirectDrawSurface4_AddRef(glb.lpPrimary4); + glb.bDirectDrawPrimary = TRUE; + } + + // Clipper object + hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateClipper failed", hResult); + goto return_with_error; + } + hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + if (FAILED(hResult)) { + RELEASE(lpddClipper); + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetHWnd failed", hResult); + goto return_with_error; + } + hResult = IDirectDrawSurface4_SetClipper(lpCtx->lpFront4, lpddClipper); + RELEASE(lpddClipper); // We have finished with it. + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetClipper failed", hResult); + goto return_with_error; + } +SkipPrimaryCreate: + + if (bDoubleBuffer) { + // Render target surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd2.dwWidth = lpCtx->dwWidth; + ddsd2.dwHeight = lpCtx->dwHeight; + ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | + DDSCAPS_OFFSCREENPLAIN | + dwMemoryType; + + // Reserve the entire desktop size for persistant buffers option + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + ddsd2.dwWidth = ddsd2DisplayMode.dwWidth; + ddsd2.dwHeight = ddsd2DisplayMode.dwHeight; + } + // Re-use original back buffer if persistant buffers exist + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpBack4) + hResult = IDirectDrawSurface4_AddRef(lpCtx->lpBack4 = glb.lpBack4); + else + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpBack4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Create Backbuffer failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpBack4) + IDirectDrawSurface4_AddRef(glb.lpBack4 = lpCtx->lpBack4); + } else { + lpCtx->lpBack4 = NULL; + } + } + + // + // Now create the Z-buffer + // + lpCtx->bStencil = FALSE; // Default to no stencil buffer + if (bDepthBuffer && (lpCtx->lpPF->iZBufferPF != -1)) { + // Get z-buffer dimensions from the render target + // Setup the surface desc for the z-buffer. + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | dwMemoryType; + ddsd2.dwWidth = lpCtx->dwWidth; + ddsd2.dwHeight = lpCtx->dwHeight; + memcpy(&ddsd2.ddpfPixelFormat, + &glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF], + sizeof(DDPIXELFORMAT) ); + + // Reserve the entire desktop size for persistant buffers option + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + ddsd2.dwWidth = ddsd2DisplayMode.dwWidth; + ddsd2.dwHeight = ddsd2DisplayMode.dwHeight; + } + + // Create a z-buffer + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4) + hResult = IDirectDrawSurface4_AddRef(lpCtx->lpDepth4 = glb.lpDepth4); + else + hResult = IDirectDraw4_CreateSurface(lpCtx->lpDD4, &ddsd2, &lpCtx->lpDepth4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateSurface (ZBuffer) failed", hResult); + nContextError = GLDERR_MEM; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpDepth4) + IDirectDrawSurface4_AddRef(glb.lpDepth4 = lpCtx->lpDepth4); + else if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpDepth4 && glb.lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(glb.lpBack4, 0, glb.lpDepth4); + + // Attach Zbuffer to render target + TRY(IDirectDrawSurface4_AddAttachedSurface( + bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4, + lpCtx->lpDepth4), + "dglCreateContext: Attach Zbuffer"); + if (glb.lpZBufferPF[lpCtx->lpPF->iZBufferPF].dwFlags & DDPF_STENCILBUFFER) { + lpCtx->bStencil = TRUE; + ddlogMessage(DDLOG_INFO, "Depth buffer has stencil\n"); + } + } + + // Clear all back buffers and Z-buffers in case of memory recycling. + ZeroMemory(&ddbltfx, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + IDirectDrawSurface4_Blt(lpCtx->lpBack4, NULL, NULL, NULL, + DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + if (lpCtx->lpDepth4) + IDirectDrawSurface4_Blt(lpCtx->lpDepth4, NULL, NULL, NULL, + DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); + + // Now that we have a Z-buffer we can create the 3D device + hResult = IDirect3D3_CreateDevice(lpCtx->lpD3D3, + &glb.d3dGuid, + bDoubleBuffer ? lpCtx->lpBack4 : lpCtx->lpFront4, + &lpCtx->lpDev3, + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "Unable to create Direct3D device", hResult); + nContextError = GLDERR_D3D; + goto return_with_error; + } + + // We must do this as soon as the device is created + dglInitStateCaches(lpCtx); + + // Obtain the D3D Device Description + D3DHWDevDesc.dwSize = D3DHELDevDesc.dwSize = sizeof(D3DDEVICEDESC); + TRY(IDirect3DDevice3_GetCaps(lpCtx->lpDev3, + &D3DHWDevDesc, + &D3DHELDevDesc), + "dglCreateContext: GetCaps failed"); + + // Choose the relevant description and cache it in the context. + // We will use this description later for caps checking + memcpy( &lpCtx->D3DDevDesc, + glb.bHardware ? &D3DHWDevDesc : &D3DHELDevDesc, + sizeof(D3DDEVICEDESC)); + + // Now we can examine the texture formats + if (!dglBuildTextureFormatList(lpCtx->lpDev3)) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "dglBuildTextureFormatList failed\n"); + goto return_with_error; + } + + // Get the pixel format of the back buffer + lpCtx->ddpfRender.dwSize = sizeof(lpCtx->ddpfRender); + if (bDoubleBuffer) + hResult = IDirectDrawSurface4_GetPixelFormat( + lpCtx->lpBack4, + &lpCtx->ddpfRender); + else + hResult = IDirectDrawSurface4_GetPixelFormat( + lpCtx->lpFront4, + &lpCtx->ddpfRender); + + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "GetPixelFormat failed", hResult); + goto return_with_error; + } + // Find a pixel packing function suitable for this surface + pxClassifyPixelFormat(&lpCtx->ddpfRender, + &lpCtx->fnPackFunc, + &lpCtx->fnUnpackFunc, + &lpCtx->fnPackSpanFunc); + + // Viewport + hResult = IDirect3D3_CreateViewport(lpCtx->lpD3D3, &lpCtx->lpViewport3, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateViewport failed", hResult); + goto return_with_error; + } + + hResult = IDirect3DDevice3_AddViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "AddViewport failed", hResult); + goto return_with_error; + } + + // Initialise the viewport + // Note screen coordinates are used for viewport clipping since D3D + // transform operations are not used in the GLD CAD driver. (DaveM) + inv_aspect = (float)lpCtx->dwHeight/(float)lpCtx->dwWidth; + + lpCtx->d3dViewport.dwSize = sizeof(lpCtx->d3dViewport); + lpCtx->d3dViewport.dwX = 0; + lpCtx->d3dViewport.dwY = 0; + lpCtx->d3dViewport.dwWidth = lpCtx->dwWidth; + lpCtx->d3dViewport.dwHeight = lpCtx->dwHeight; + lpCtx->d3dViewport.dvClipX = 0; // -1.0f; + lpCtx->d3dViewport.dvClipY = 0; // inv_aspect; + lpCtx->d3dViewport.dvClipWidth = lpCtx->dwWidth; // 2.0f; + lpCtx->d3dViewport.dvClipHeight = lpCtx->dwHeight; // 2.0f * inv_aspect; + lpCtx->d3dViewport.dvMinZ = 0.0f; + lpCtx->d3dViewport.dvMaxZ = 1.0f; + TRY(IDirect3DViewport3_SetViewport2(lpCtx->lpViewport3, &lpCtx->d3dViewport), "dglCreateContext: SetViewport2"); + + hResult = IDirect3DDevice3_SetCurrentViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "SetCurrentViewport failed", hResult); + goto return_with_error; + } + + lpCtx->dwBPP = lpPFD->cColorBits; + lpCtx->iZBufferPF = lpCtx->lpPF->iZBufferPF; + + // Set last texture to NULL + for (i=0; i<MAX_TEXTURE_UNITS; i++) { + lpCtx->ColorOp[i] = D3DTOP_DISABLE; + lpCtx->AlphaOp[i] = D3DTOP_DISABLE; + lpCtx->tObj[i] = NULL; + } + + // Default to perspective correct texture mapping + dglSetRenderState(lpCtx, D3DRENDERSTATE_TEXTUREPERSPECTIVE, TRUE, "TexturePersp"); + + // Set the default culling mode + lpCtx->cullmode = D3DCULL_NONE; + dglSetRenderState(lpCtx, D3DRENDERSTATE_CULLMODE, D3DCULL_NONE, "CullMode"); + + // Disable specular + dglSetRenderState(lpCtx, D3DRENDERSTATE_SPECULARENABLE, FALSE, "SpecularEnable"); + // Disable subpixel correction +// dglSetRenderState(lpCtx, D3DRENDERSTATE_SUBPIXEL, FALSE, "SubpixelEnable"); + // Disable dithering + dglSetRenderState(lpCtx, D3DRENDERSTATE_DITHERENABLE, FALSE, "DitherEnable"); + + // Initialise the primitive caches +// lpCtx->dwNextLineVert = 0; +// lpCtx->dwNextTriVert = 0; + + // Init the global texture palette + lpCtx->lpGlobalPalette = NULL; + + // Init the HW/SW usage counters +// lpCtx->dwHWUsageCount = lpCtx->dwSWUsageCount = 0L; + + // + // Create two D3D vertex buffers. + // One will hold the pre-transformed data with the other one + // being used to hold the post-transformed & clipped verts. + // +#if 0 // never used (DaveM) + vbufdesc.dwSize = sizeof(D3DVERTEXBUFFERDESC); + vbufdesc.dwCaps = D3DVBCAPS_WRITEONLY; + if (glb.bHardware == FALSE) + vbufdesc.dwCaps = D3DVBCAPS_SYSTEMMEMORY; + vbufdesc.dwNumVertices = 32768; // For the time being + + // Source vertex buffer + vbufdesc.dwFVF = DGL_LVERTEX; + hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_vbuf, 0, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(src) failed", hResult); + goto return_with_error; + } + + // Destination vertex buffer + vbufdesc.dwFVF = (glb.bMultitexture == FALSE) ? D3DFVF_TLVERTEX : (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX2); + hResult = IDirect3D3_CreateVertexBuffer(lpCtx->lpD3D3, &vbufdesc, &lpCtx->m_pvbuf, 0, NULL); + if(FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "CreateVertexBuffer(dst) failed", hResult); + goto return_with_error; + } +#endif + +#endif _USE_GLD3_WGL + + // + // Now create the Mesa context + // + + // Create the Mesa visual + if (lpPFD->cDepthBits) + dwDepthBits = 16; + if (lpPFD->cStencilBits) + dwStencilBits = 8; + if (lpPFD->cAlphaBits) { + dwAlphaBits = 8; + bAlphaSW = GL_TRUE; + } + if (lpPFD->dwFlags & PFD_DOUBLEBUFFER) + bDouble = GL_TRUE; +// lpCtx->EmulateSingle = +// (lpPFD->dwFlags & PFD_DOUBLEBUFFER) ? FALSE : TRUE; + +#ifdef _USE_GLD3_WGL + lpCtx->glVis = _mesa_create_visual( + GL_TRUE, // RGB mode + bDouble, /* double buffer */ + GL_FALSE, // stereo + lpPFD->cRedBits, + lpPFD->cGreenBits, + lpPFD->cBlueBits, + dwAlphaBits, + 0, // index bits + dwDepthBits, + dwStencilBits, + lpPFD->cAccumRedBits, // accum bits + lpPFD->cAccumGreenBits, // accum bits + lpPFD->cAccumBlueBits, // accum bits + lpPFD->cAccumAlphaBits, // accum alpha bits + 1 // num samples + ); +#else // _USE_GLD3_WGL + lpCtx->glVis = (*mesaFuncs.gl_create_visual)( + GL_TRUE, // RGB mode + bAlphaSW, // Is an alpha buffer required? + bDouble, // Is an double-buffering required? + GL_FALSE, // stereo + dwDepthBits, // depth_size + dwStencilBits, // stencil_size + lpPFD->cAccumBits, // accum_size + 0, // colour-index bits + lpPFD->cRedBits, // Red bit count + lpPFD->cGreenBits, // Green bit count + lpPFD->cBlueBits, // Blue bit count + dwAlphaBits // Alpha bit count + ); +#endif // _USE_GLD3_WGL + + if (lpCtx->glVis == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_visual failed\n"); + goto return_with_error; + } + +#ifdef _USE_GLD3_WGL + lpCtx->glCtx = _mesa_create_context(lpCtx->glVis, NULL, (void *)lpCtx, GL_TRUE); +#else + // Create the Mesa context + lpCtx->glCtx = (*mesaFuncs.gl_create_context)( + lpCtx->glVis, // Mesa visual + NULL, // share list context + (void *)lpCtx, // Pointer to our driver context + GL_TRUE // Direct context flag + ); +#endif // _USE_GLD3_WGL + + if (lpCtx->glCtx == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_context failed\n"); + goto return_with_error; + } + + // Create the Mesa framebuffer +#ifdef _USE_GLD3_WGL + lpCtx->glBuffer = _mesa_create_framebuffer( + lpCtx->glVis, + lpCtx->glVis->depthBits > 0, + lpCtx->glVis->stencilBits > 0, + lpCtx->glVis->accumRedBits > 0, + GL_FALSE //swalpha + ); +#else + lpCtx->glBuffer = (*mesaFuncs.gl_create_framebuffer)(lpCtx->glVis); +#endif // _USE_GLD3_WGL + + if (lpCtx->glBuffer == NULL) { + ddlogMessage(DDLOG_CRITICAL_OR_WARN, "gl_create_framebuffer failed\n"); + goto return_with_error; + } + +#ifdef _USE_GLD3_WGL + // Init Mesa internals + _swrast_CreateContext( lpCtx->glCtx ); + _vbo_CreateContext( lpCtx->glCtx ); + _tnl_CreateContext( lpCtx->glCtx ); + _swsetup_CreateContext( lpCtx->glCtx ); + + _gldDriver.InitialiseMesa(lpCtx); + + lpCtx->glCtx->imports.warning = _gld_mesa_warning; + lpCtx->glCtx->imports.fatal = _gld_mesa_fatal; + +#else + // Tell Mesa how many texture stages we have + glb.wMaxSimultaneousTextures = lpCtx->D3DDevDesc.wMaxSimultaneousTextures; + // Only use as many Units as the spec requires + if (glb.wMaxSimultaneousTextures > MAX_TEXTURE_UNITS) + glb.wMaxSimultaneousTextures = MAX_TEXTURE_UNITS; + lpCtx->glCtx->Const.MaxTextureUnits = glb.wMaxSimultaneousTextures; + ddlogPrintf(DDLOG_INFO, "Texture stages : %d", glb.wMaxSimultaneousTextures); + + // Set the max texture size. + // NOTE: clamped to a max of 1024 for extra performance! + lpCtx->dwMaxTextureSize = (lpCtx->D3DDevDesc.dwMaxTextureWidth <= 1024) ? lpCtx->D3DDevDesc.dwMaxTextureWidth : 1024; + +// Texture resize takes place elsewhere. KH +// NOTE: This was added to workaround an issue with the Intel app. +#if 0 + lpCtx->glCtx->Const.MaxTextureSize = lpCtx->dwMaxTextureSize; +#else + lpCtx->glCtx->Const.MaxTextureSize = 1024; +#endif + lpCtx->glCtx->Const.MaxDrawBuffers = 1; + + // Setup the Display Driver pointers + dglSetupDDPointers(lpCtx->glCtx); + + // Initialise all the Direct3D renderstates + dglInitStateD3D(lpCtx->glCtx); + +#if 0 + // Signal a reload of texture state on next glBegin + lpCtx->m_texHandleValid = FALSE; + lpCtx->m_mtex = FALSE; + lpCtx->m_texturing = FALSE; +#else + // Set default texture unit state +// dglSetTexture(lpCtx, 0, NULL); +// dglSetTexture(lpCtx, 1, NULL); +#endif + + // + // Set the global texture palette to default values. + // + + // Clear the entire palette + ZeroMemory(ppe, sizeof(PALETTEENTRY) * 256); + + // Fill the palette with a default colour. + // A garish colour is used to catch bugs. Here Magenta is used. + for (i=0; i < 256; i++) { + ppe[i].peRed = 255; + ppe[i].peGreen = 0; + ppe[i].peBlue = 255; + } + + RELEASE(lpCtx->lpGlobalPalette); + + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && glb.lpGlobalPalette) + hResult = IDirectDrawPalette_AddRef(lpCtx->lpGlobalPalette = glb.lpGlobalPalette); + else + hResult = IDirectDraw4_CreatePalette( + lpCtx->lpDD4, + DDPCAPS_INITIALIZE | DDPCAPS_8BIT | DDPCAPS_ALLOW256, + ppe, + &(lpCtx->lpGlobalPalette), + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_ERROR, "Default CreatePalette failed\n", hResult); + lpCtx->lpGlobalPalette = NULL; + goto return_with_error; + } + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers && !glb.lpGlobalPalette) + IDirectDrawPalette_AddRef(glb.lpGlobalPalette = lpCtx->lpGlobalPalette); + +#endif // _USE_GLD3_WGL + + // ** If we have made it to here then we can enable rendering ** + lpCtx->bCanRender = TRUE; + +// ddlogMessage(DDLOG_SYSTEM, "dglCreateContextBuffers succeded\n"); + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; + +return_with_error: + // Clean up before returning. + // This is critical for secondary devices. + + lpCtx->bCanRender = FALSE; + +#ifdef _USE_GLD3_WGL + // Destroy the Mesa context + if (lpCtx->glBuffer) + _mesa_destroy_framebuffer(lpCtx->glBuffer); + if (lpCtx->glCtx) + _mesa_destroy_context(lpCtx->glCtx); + if (lpCtx->glVis) + _mesa_destroy_visual(lpCtx->glVis); + + // Destroy driver data + _gldDriver.DestroyDrawable(lpCtx); +#else + // Destroy the Mesa context + if (lpCtx->glBuffer) + (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer); + if (lpCtx->glCtx) + (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx); + if (lpCtx->glVis) + (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis); + + RELEASE(lpCtx->m_pvbuf); // Release D3D vertex buffer + RELEASE(lpCtx->m_vbuf); // Release D3D vertex buffer + + if (lpCtx->lpViewport3) { + if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + RELEASE(lpCtx->lpViewport3); + lpCtx->lpViewport3 = NULL; + } + + RELEASE(lpCtx->lpDev3); + if (lpCtx->lpDepth4) { + if (lpCtx->lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4); + else + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4); + RELEASE(lpCtx->lpDepth4); + lpCtx->lpDepth4 = NULL; + } + RELEASE(lpCtx->lpBack4); + RELEASE(lpCtx->lpFront4); + else + if (lpCtx->bFullscreen) { + IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4); + IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL); + } + RELEASE(lpCtx->lpD3D3); + RELEASE(lpCtx->lpDD4); + RELEASE(lpCtx->lpDD1); +#endif // _USE_GLD3_WGL + + lpCtx->bAllocated = FALSE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return FALSE; + +#undef DDLOG_CRITICAL_OR_WARN +} + +// *********************************************************************** + +HGLRC dglCreateContext( + HDC a, + const DGL_pixelFormat *lpPF) +{ + int i; + HGLRC hGLRC; + DGL_ctx* lpCtx; + static BOOL bWarnOnce = TRUE; + DWORD dwThreadId = GetCurrentThreadId(); + char szMsg[256]; + HWND hWnd; + LONG lpfnWndProc; + + // Validate license + if (!dglValidate()) + return NULL; + + // Is context state ready ? + if (!bContextReady) + return NULL; + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext for HDC=%X, ThreadId=%X", a, dwThreadId); + + // Find next free context. + // Also ensure that only one Fullscreen context is created at any one time. + hGLRC = 0; // Default to Not Found + for (i=0; i<DGL_MAX_CONTEXTS; i++) { + if (ctxlist[i].bAllocated) { + if (/*glb.bFullscreen && */ctxlist[i].bFullscreen) + break; + } else { + hGLRC = (HGLRC)(i+1); + break; + } + } + + // Bail if no GLRC was found + if (!hGLRC) + return NULL; + + // Set the context pointer + lpCtx = dglGetContextAddress(hGLRC); + // Make sure that context is zeroed before we do anything. + // MFC and C++ apps call wglCreateContext() and wglDeleteContext() multiple times, + // even though only one context is ever used by the app, so keep it clean. (DaveM) + ZeroMemory(lpCtx, sizeof(DGL_ctx)); + lpCtx->bAllocated = TRUE; + // Flag that buffers need creating on next wglMakeCurrent call. + lpCtx->bHasBeenCurrent = FALSE; + lpCtx->lpPF = (DGL_pixelFormat *)lpPF; // cache pixel format + lpCtx->bCanRender = FALSE; + + // Create all the internal resources here, not in dglMakeCurrent(). + // We do a re-size check in dglMakeCurrent in case of re-allocations. (DaveM) + // We now try context allocations twice, first with video memory, + // then again with system memory. This is similar to technique + // used for dglWglResizeBuffers(). (DaveM) + if (lpCtx->bHasBeenCurrent == FALSE) { + if (!dglCreateContextBuffers(a, lpCtx, FALSE)) { + if (glb.bMessageBoxWarnings && bWarnOnce && dwLogging) { + bWarnOnce = FALSE; + switch (nContextError) { + case GLDERR_DDRAW: strcpy(szMsg, szDDrawWarning); break; + case GLDERR_D3D: strcpy(szMsg, szD3DWarning); break; + case GLDERR_MEM: strcpy(szMsg, szResourceWarning); break; + case GLDERR_BPP: strcpy(szMsg, szBPPWarning); break; + default: strcpy(szMsg, ""); + } + if (strlen(szMsg)) + MessageBox(NULL, szMsg, "GLDirect", MB_OK | MB_ICONWARNING); + } + // Only need to try again if memory error + if (nContextError == GLDERR_MEM) { + ddlogPrintf(DDLOG_WARN, "dglCreateContext failed 1st time with video memory"); + } + else { + ddlogPrintf(DDLOG_ERROR, "dglCreateContext failed"); + return NULL; + } + } + } + + // Now that we have a hWnd, we can intercept the WindowProc. + hWnd = lpCtx->hWnd; + if (hWnd) { + // Only hook individual window handler once if not hooked before. + lpfnWndProc = GetWindowLong(hWnd, GWL_WNDPROC); + if (lpfnWndProc != (LONG)dglWndProc) { + lpCtx->lpfnWndProc = lpfnWndProc; + SetWindowLong(hWnd, GWL_WNDPROC, (LONG)dglWndProc); + } + // Find the parent window of the app too. + if (glb.hWndActive == NULL) { + while (hWnd != NULL) { + glb.hWndActive = hWnd; + hWnd = GetParent(hWnd); + } + // Hook the parent window too. + lpfnWndProc = GetWindowLong(glb.hWndActive, GWL_WNDPROC); + if (glb.hWndActive == lpCtx->hWnd) + glb.lpfnWndProc = lpCtx->lpfnWndProc; + else if (lpfnWndProc != (LONG)dglWndProc) + glb.lpfnWndProc = lpfnWndProc; + if (glb.lpfnWndProc) + SetWindowLong(glb.hWndActive, GWL_WNDPROC, (LONG)dglWndProc); + } + } + + ddlogPrintf(DDLOG_SYSTEM, "dglCreateContext succeeded for HGLRC=%d", (int)hGLRC); + + return hGLRC; +} + +// *********************************************************************** +// Make a DirectGL context current +// Used by wgl functions and dgl functions +BOOL dglMakeCurrent( + HDC a, + HGLRC b) +{ + int context; + DGL_ctx* lpCtx; + HWND hWnd; + BOOL bNeedResize = FALSE; + BOOL bWindowChanged, bContextChanged; + LPDIRECTDRAWCLIPPER lpddClipper; + DWORD dwThreadId = GetCurrentThreadId(); + LONG lpfnWndProc; + + // Validate license + if (!dglValidate()) + return FALSE; + + // Is context state ready ? + if (!bContextReady) + return FALSE; + + context = (int)b; // This is as a result of STRICT! + ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: HDC=%X, HGLRC=%d, ThreadId=%X", a, context, dwThreadId); + + // If the HGLRC is NULL then make no context current; + // Ditto if the HDC is NULL either. (DaveM) + if (context == 0 || a == 0) { + // Corresponding Mesa operation +#ifdef _USE_GLD3_WGL + _mesa_make_current(NULL, NULL); +#else + (*mesaFuncs.gl_make_current)(NULL, NULL); +#endif + dglSetCurrentContext(0); + return TRUE; + } + + // Make sure the HGLRC is in range + if ((context > DGL_MAX_CONTEXTS) || (context < 0)) { + ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: HGLRC out of range\n"); + return FALSE; + } + + // Find address of context and make sure that it has been allocated + lpCtx = dglGetContextAddress(b); + if (!lpCtx->bAllocated) { + ddlogMessage(DDLOG_ERROR, "dglMakeCurrent: Context not allocated\n"); +// return FALSE; + return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH + } + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // Check if window has changed + hWnd = (a != lpCtx->hDC) ? WindowFromDC(a) : lpCtx->hWnd; + bWindowChanged = (hWnd != lpCtx->hWnd) ? TRUE : FALSE; + bContextChanged = (b != dglGetCurrentContext()) ? TRUE : FALSE; + + // If the window has changed, make sure the clipper is updated. (DaveM) + if (glb.bDirectDrawPersistant && !lpCtx->bFullscreen && (bWindowChanged || bContextChanged)) { + lpCtx->hWnd = hWnd; +#ifndef _USE_GLD3_WGL + IDirectDrawSurface4_GetClipper(lpCtx->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, lpCtx->hWnd); + IDirectDrawClipper_Release(lpddClipper); +#endif // _USE_GLD3_WGL + } + + // Make sure hDC and hWnd is current. (DaveM) + // Obtain the dimensions of the rendering window + lpCtx->hDC = a; // Cache DC + lpCtx->hWnd = hWnd; + hWndLastActive = hWnd; + + // Check for non-window DC = memory DC ? + if (hWnd == NULL) { + if (GetClipBox(a, &lpCtx->rcScreenRect) == ERROR) { + ddlogMessage(DDLOG_WARN, "GetClipBox failed in dglMakeCurrent\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + } + else if (!GetClientRect(lpCtx->hWnd, &lpCtx->rcScreenRect)) { + ddlogMessage(DDLOG_WARN, "GetClientRect failed in dglMakeCurrent\n"); + SetRect(&lpCtx->rcScreenRect, 0, 0, 0, 0); + } + // Check if buffers need to be re-sized; + // If so, wait until Mesa GL stuff is setup before re-sizing; + if (lpCtx->dwWidth != lpCtx->rcScreenRect.right - lpCtx->rcScreenRect.left || + lpCtx->dwHeight != lpCtx->rcScreenRect.bottom - lpCtx->rcScreenRect.top) + bNeedResize = TRUE; + + // Now we can update our globals + dglSetCurrentContext(b); + + // Corresponding Mesa operation +#ifdef _USE_GLD3_WGL + _mesa_make_current(lpCtx->glCtx, lpCtx->glBuffer); + lpCtx->glCtx->Driver.UpdateState(lpCtx->glCtx, _NEW_ALL); + if (bNeedResize) { + // Resize buffers (Note Mesa GL needs to be setup beforehand); + // Resize Mesa internal buffer too via glViewport() command, + // which subsequently calls dglWglResizeBuffers() too. + lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); + lpCtx->bHasBeenCurrent = TRUE; + } +#else + (*mesaFuncs.gl_make_current)(lpCtx->glCtx, lpCtx->glBuffer); + + dglSetupDDPointers(lpCtx->glCtx); + + // Insure DirectDraw surfaces fit current window DC + if (bNeedResize) { + // Resize buffers (Note Mesa GL needs to be setup beforehand); + // Resize Mesa internal buffer too via glViewport() command, + // which subsequently calls dglWglResizeBuffers() too. + (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); + lpCtx->bHasBeenCurrent = TRUE; + } +#endif // _USE_GLD3_WGL + ddlogPrintf(DDLOG_SYSTEM, "dglMakeCurrent: width = %d, height = %d", lpCtx->dwWidth, lpCtx->dwHeight); + + // We have to clear D3D back buffer and render state if emulated front buffering + // for different window (but not context) like in Solid Edge. + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers + && (bWindowChanged /* || bContextChanged */) && lpCtx->EmulateSingle) { +#ifdef _USE_GLD3_WGL +// IDirect3DDevice8_EndScene(lpCtx->pDev); +// lpCtx->bSceneStarted = FALSE; + lpCtx->glCtx->Driver.Clear(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#else + IDirect3DDevice3_EndScene(lpCtx->lpDev3); + lpCtx->bSceneStarted = FALSE; + dglClearD3D(lpCtx->glCtx, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, + GL_TRUE, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#endif // _USE_GLD3_WGL + } + + // The first time we call MakeCurrent we set the initial viewport size + if (lpCtx->bHasBeenCurrent == FALSE) +#ifdef _USE_GLD3_WGL + lpCtx->glCtx->Driver.Viewport(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#else + (*mesaFuncs.gl_Viewport)(lpCtx->glCtx, 0, 0, lpCtx->dwWidth, lpCtx->dwHeight); +#endif // _USE_GLD3_WGL + lpCtx->bHasBeenCurrent = TRUE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dglDeleteContext( + HGLRC a) +{ + DGL_ctx* lpCtx; + DWORD dwThreadId = GetCurrentThreadId(); + char argstr[256]; + +#if 0 // We have enough trouble throwing exceptions as it is... (DaveM) + // Validate license + if (!dglValidate()) + return FALSE; +#endif + + // Is context state ready ? + if (!bContextReady) + return FALSE; + + ddlogPrintf(DDLOG_SYSTEM, "dglDeleteContext: Deleting context HGLRC=%d, ThreadId=%X", (int)a, dwThreadId); + + // Make sure the HGLRC is in range + if (((int) a> DGL_MAX_CONTEXTS) || ((int)a < 0)) { + ddlogMessage(DDLOG_ERROR, "dglDeleteCurrent: HGLRC out of range\n"); + return FALSE; + } + + // Make sure context is valid + lpCtx = dglGetContextAddress(a); + if (!lpCtx->bAllocated) { + ddlogPrintf(DDLOG_WARN, "Tried to delete unallocated context HGLRC=%d", (int)a); +// return FALSE; + return TRUE; // HACK: Shuts up "WebLab Viewer Pro". KeithH + } + + // Make sure context is de-activated + if (a == dglGetCurrentContext()) { + ddlogPrintf(DDLOG_WARN, "dglDeleteContext: context HGLRC=%d still active", (int)a); + dglMakeCurrent(NULL, NULL); + } + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + + // We are about to destroy all Direct3D objects. + // Therefore we must disable rendering + lpCtx->bCanRender = FALSE; + + // This exception handler was installed to catch some + // particularly nasty apps. Console apps that call exit() + // fall into this catagory (i.e. Win32 Glut). + + // VC cannot successfully implement multiple exception handlers + // if more than one exception occurs. Therefore reverting back to + // single exception handler as Keith originally had it. (DaveM) + +#define WARN_MESSAGE(p) strcpy(argstr, (#p)); +#define SAFE_RELEASE(p) WARN_MESSAGE(p); RELEASE(p); + +__try { +#ifdef _USE_GLD3_WGL + WARN_MESSAGE(gl_destroy_framebuffer); + if (lpCtx->glBuffer) + _mesa_destroy_framebuffer(lpCtx->glBuffer); + WARN_MESSAGE(gl_destroy_context); + if (lpCtx->glCtx) + _mesa_destroy_context(lpCtx->glCtx); + WARN_MESSAGE(gl_destroy_visual); + if (lpCtx->glVis) + _mesa_destroy_visual(lpCtx->glVis); + + _gldDriver.DestroyDrawable(lpCtx); +#else + // Destroy the Mesa context + WARN_MESSAGE(gl_destroy_framebuffer); + if (lpCtx->glBuffer) + (*mesaFuncs.gl_destroy_framebuffer)(lpCtx->glBuffer); + WARN_MESSAGE(gl_destroy_context); + if (lpCtx->glCtx) + (*mesaFuncs.gl_destroy_context)(lpCtx->glCtx); + WARN_MESSAGE(gl_destroy_visual); + if (lpCtx->glVis) + (*mesaFuncs.gl_destroy_visual)(lpCtx->glVis); + + SAFE_RELEASE(lpCtx->m_pvbuf); // release D3D vertex buffer + SAFE_RELEASE(lpCtx->m_vbuf); // release D3D vertex buffer + + // Delete the global palette + SAFE_RELEASE(lpCtx->lpGlobalPalette); + + // Clean up. + if (lpCtx->lpViewport3) { + if (lpCtx->lpDev3) IDirect3DDevice3_DeleteViewport(lpCtx->lpDev3, lpCtx->lpViewport3); + SAFE_RELEASE(lpCtx->lpViewport3); + lpCtx->lpViewport3 = NULL; + } + + SAFE_RELEASE(lpCtx->lpDev3); + if (lpCtx->lpDepth4) { + if (lpCtx->lpBack4) + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpBack4, 0L, lpCtx->lpDepth4); + else + IDirectDrawSurface4_DeleteAttachedSurface(lpCtx->lpFront4, 0L, lpCtx->lpDepth4); + SAFE_RELEASE(lpCtx->lpDepth4); + lpCtx->lpDepth4 = NULL; + } + SAFE_RELEASE(lpCtx->lpBack4); + SAFE_RELEASE(lpCtx->lpFront4); + if (lpCtx->bFullscreen) { + IDirectDraw4_RestoreDisplayMode(lpCtx->lpDD4); + IDirectDraw4_SetCooperativeLevel(lpCtx->lpDD4, NULL, DDSCL_NORMAL); + } + SAFE_RELEASE(lpCtx->lpD3D3); + SAFE_RELEASE(lpCtx->lpDD4); + SAFE_RELEASE(lpCtx->lpDD1); +#endif // _ULSE_GLD3_WGL + +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglDeleteContext: %s", argstr); +} + + // Restore the window message handler because this context may be used + // again by another window with a *different* message handler. (DaveM) + if (lpCtx->lpfnWndProc) { + SetWindowLong(lpCtx->hWnd, GWL_WNDPROC, (LONG)lpCtx->lpfnWndProc); + lpCtx->lpfnWndProc = (LONG)NULL; + } + + lpCtx->bAllocated = FALSE; // This context is now free for use + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dglSwapBuffers( + HDC hDC) +{ + RECT rSrcRect; // Source rectangle + RECT rDstRect; // Destination rectangle + POINT pt; + HRESULT hResult; + + DDBLTFX bltFX; + DWORD dwBlitFlags; + DDBLTFX *lpBltFX; + +// DWORD dwThreadId = GetCurrentThreadId(); + HGLRC hGLRC = dglGetCurrentContext(); + DGL_ctx *lpCtx = dglGetContextAddress(hGLRC); + HWND hWnd; + + HDC hDCAux; // for memory DC + int x,y,w,h; // for memory DC BitBlt + +#if 0 // Perhaps not a good idea. Called too often. KH + // Validate license + if (!dglValidate()) + return FALSE; +#endif + + if (!lpCtx) { + return TRUE; //FALSE; // No current context + } + + if (!lpCtx->bCanRender) { + // Don't return false else some apps will bail. + return TRUE; + } + + hWnd = lpCtx->hWnd; + if (hDC != lpCtx->hDC) { + ddlogPrintf(DDLOG_WARN, "dglSwapBuffers: HDC=%X does not match HDC=%X for HGLRC=%d", hDC, lpCtx->hDC, hGLRC); + hWnd = WindowFromDC(hDC); + } + +#ifndef _USE_GLD3_WGL + // Ensure that the surfaces exist before we tell + // the device to render to them. + IDirectDraw4_RestoreAllSurfaces(lpCtx->lpDD4); + + // Make sure that the vertex caches have been emptied +// dglStateChange(lpCtx); + + // Some OpenGL programs don't issue a glFinish - check for it here. + if (lpCtx->bSceneStarted) { + IDirect3DDevice3_EndScene(lpCtx->lpDev3); + lpCtx->bSceneStarted = FALSE; + } +#endif + +#if 0 + // If the calling app is not active then we don't need to Blit/Flip. + // We can therefore simply return TRUE. + if (!glb.bAppActive) + return TRUE; + // Addendum: This is WRONG! We should bail if the app is *minimized*, + // not merely if the app is just plain 'not active'. + // KeithH, 27/May/2000. +#endif + + // Check for non-window DC = memory DC ? + if (hWnd == NULL) { + if (GetClipBox(hDC, &rSrcRect) == ERROR) + return TRUE; + // Use GDI BitBlt instead from compatible DirectDraw DC + x = rSrcRect.left; + y = rSrcRect.top; + w = rSrcRect.right - rSrcRect.left; + h = rSrcRect.bottom - rSrcRect.top; + + // Ack. DX8 does not have a GetDC() function... + // TODO: Defer to DX7 or DX9 drivers... (DaveM) + return TRUE; + } + + // Bail if window client region is not drawable, like in Solid Edge + if (!IsWindow(hWnd) /* || !IsWindowVisible(hWnd) */ || !GetClientRect(hWnd, &rSrcRect)) + return TRUE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw or DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + +#ifdef _USE_GLD3_WGL + // Notify Mesa of impending swap, so Mesa can flush internal buffers. + _mesa_notifySwapBuffers(lpCtx->glCtx); + // Now perform driver buffer swap + _gldDriver.SwapBuffers(lpCtx, hDC, hWnd); +#else + if (lpCtx->bFullscreen) { + // Sync with retrace if required + if (glb.bWaitForRetrace) { + IDirectDraw4_WaitForVerticalBlank( + lpCtx->lpDD4, + DDWAITVB_BLOCKBEGIN, + 0); + } + + // Perform the fullscreen flip + TRY(IDirectDrawSurface4_Flip( + lpCtx->lpFront4, + NULL, + DDFLIP_WAIT), + "dglSwapBuffers: Flip"); + } else { + // Calculate current window position and size + pt.x = pt.y = 0; + ClientToScreen(hWnd, &pt); + GetClientRect(hWnd, &rDstRect); + if (rDstRect.right > lpCtx->dwModeWidth) + rDstRect.right = lpCtx->dwModeWidth; + if (rDstRect.bottom > lpCtx->dwModeHeight) + rDstRect.bottom = lpCtx->dwModeHeight; + OffsetRect(&rDstRect, pt.x, pt.y); + rSrcRect.left = rSrcRect.top = 0; + rSrcRect.right = lpCtx->dwWidth; + rSrcRect.bottom = lpCtx->dwHeight; + if (rSrcRect.right > lpCtx->dwModeWidth) + rSrcRect.right = lpCtx->dwModeWidth; + if (rSrcRect.bottom > lpCtx->dwModeHeight) + rSrcRect.bottom = lpCtx->dwModeHeight; + + if (glb.bWaitForRetrace) { + // Sync the blit to the vertical retrace + ZeroMemory(&bltFX, sizeof(bltFX)); + bltFX.dwSize = sizeof(bltFX); + bltFX.dwDDFX = DDBLTFX_NOTEARING; + dwBlitFlags = DDBLT_WAIT | DDBLT_DDFX; + lpBltFX = &bltFX; + } else { + dwBlitFlags = DDBLT_WAIT; + lpBltFX = NULL; + } + + // Perform the actual blit + TRY(IDirectDrawSurface4_Blt( + lpCtx->lpFront4, + &rDstRect, + lpCtx->lpBack4, // Blit source + &rSrcRect, + dwBlitFlags, + lpBltFX), + "dglSwapBuffers: Blt"); + } +#endif // _USE_GLD3_WGL + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + // TODO: Re-instate rendering bitmap snapshot feature??? (DaveM) + + // Render frame is completed + ValidateRect(hWnd, NULL); + lpCtx->bFrameStarted = FALSE; + + return TRUE; +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.h b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.h new file mode 100644 index 000000000..5c433b857 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglcontext.h @@ -0,0 +1,281 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: OpenGL context handling. +* +****************************************************************************/ + +#ifndef __DGLCONTEXT_H +#define __DGLCONTEXT_H + +// Disable compiler complaints about DLL linkage +#pragma warning (disable:4273) + +// Macros to control compilation +#ifndef STRICT +#define STRICT +#endif // STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <GL\gl.h> + +#ifdef _USE_GLD3_WGL + #include "dglmacros.h" + #include "dglglobals.h" + #include "pixpack.h" + #include "ddlog.h" + #include "dglpf.h" + #include "context.h" // Mesa context +#else + #include <ddraw.h> + #include <d3d.h> + + #include "dglmacros.h" + #include "dglglobals.h" + #include "pixpack.h" + #include "ddlog.h" + #include "dglpf.h" + #include "d3dvertex.h" + + #include "DirectGL.h" + + #include "context.h" // Mesa context + #include "vb.h" // Mesa vertex buffer +#endif // _USE_GLD3_WGL + +/*---------------------- Macros and type definitions ----------------------*/ + +// TODO: Use a list instead of this constant! +#define DGL_MAX_CONTEXTS 32 + +// Structure for describing an OpenGL context +#ifdef _USE_GLD3_WGL +typedef struct { + BOOL bHasBeenCurrent; + DGL_pixelFormat *lpPF; + + // Pointer to private driver data (this also contains the drawable). + void *glPriv; + + // Mesa vars: + GLcontext *glCtx; // The core Mesa context + GLvisual *glVis; // Describes the color buffer + GLframebuffer *glBuffer; // Ancillary buffers + + GLuint ClearIndex; + GLuint CurrentIndex; + GLubyte ClearColor[4]; + GLubyte CurrentColor[4]; + + BOOL EmulateSingle; // Emulate single-buffering + BOOL bDoubleBuffer; + BOOL bDepthBuffer; + + // Shared driver vars: + BOOL bAllocated; + BOOL bFullscreen; // Is this a fullscreen context? + BOOL bSceneStarted; // Has a lpDev->BeginScene been issued? + BOOL bCanRender; // Flag: states whether rendering is OK + BOOL bFrameStarted; // Has frame update started at all? + BOOL bStencil; // TRUE if this context has stencil + BOOL bGDIEraseBkgnd; // GDI Erase Background command + + // Window information + HWND hWnd; // Window handle + HDC hDC; // Windows' Device Context of the window + DWORD dwWidth; // Window width + DWORD dwHeight; // Window height + DWORD dwBPP; // Window bits-per-pixel; + RECT rcScreenRect; // Screen rectangle + DWORD dwModeWidth; // Display mode width + DWORD dwModeHeight; // Display mode height + float dvClipX; + float dvClipY; + LONG lpfnWndProc; // window message handler function + +} DGL_ctx; + +#define GLD_context DGL_ctx +#define GLD_GET_CONTEXT(c) (GLD_context*)(c)->DriverCtx + +#else // _USE_GLD3_WGL + +typedef struct { + BOOL bHasBeenCurrent; + DGL_pixelFormat *lpPF; + // + // Mesa context vars: + // + GLcontext *glCtx; // The core Mesa context + GLvisual *glVis; // Describes the color buffer + GLframebuffer *glBuffer; // Ancillary buffers + + GLuint ClearIndex; + GLuint CurrentIndex; + GLubyte ClearColor[4]; + GLubyte CurrentColor[4]; + + BOOL EmulateSingle; // Emulate single-buffering + BOOL bDoubleBuffer; + BOOL bDepthBuffer; + int iZBufferPF; // Index of Zbuffer pixel format + + // Vertex buffer: one-to-one correlation with Mesa's vertex buffer. + // This will be filled by our setup function (see d3dvsetup.c) + DGL_TLvertex gWin[VB_SIZE]; // Transformed and lit vertices +// DGL_Lvertex gObj[VB_SIZE]; // Lit vertices in object coordinates. + + // Indices for DrawIndexedPrimitive. + // Clipped quads are drawn seperately, so use VB_SIZE. + // 6 indices are needed to make 2 triangles for each possible quad +// WORD wIndices[(VB_SIZE / 4) * 6]; + WORD wIndices[32768]; + + // + // Device driver vars: + // + BOOL bAllocated; + BOOL bFullscreen; // Is this a fullscreen context? + BOOL bSceneStarted; // Has a lpDev->BeginScene been issued? + BOOL bCanRender; // Flag: states whether rendering is OK + BOOL bFrameStarted; // Has frame update started at all? + + // DirectX COM interfaces, postfixed with the interface number + IDirectDraw *lpDD1; + IDirectDraw4 *lpDD4; + IDirect3D3 *lpD3D3; + IDirect3DDevice3 *lpDev3; + IDirect3DViewport3 *lpViewport3; + IDirectDrawSurface4 *lpFront4; + IDirectDrawSurface4 *lpBack4; + IDirectDrawSurface4 *lpDepth4; + + // Vertex buffers + BOOL bD3DPipeline; // True if using D3D geometry pipeline + IDirect3DVertexBuffer *m_vbuf; // Unprocessed vertices + IDirect3DVertexBuffer *m_pvbuf; // Processed vertices ready to be rendered + + D3DTEXTUREOP ColorOp[MAX_TEXTURE_UNITS]; // Used for re-enabling texturing + D3DTEXTUREOP AlphaOp[MAX_TEXTURE_UNITS]; // Used for re-enabling texturing + struct gl_texture_object *tObj[MAX_TEXTURE_UNITS]; + + DDCAPS ddCaps; // DirectDraw caps + D3DDEVICEDESC D3DDevDesc; // Direct3D Device description + + DDPIXELFORMAT ddpfRender; // Pixel format of the render buffer + DDPIXELFORMAT ddpfDepth; // Pixel format of the depth buffer + + BOOL bStencil; // TRUE is this context has stencil + + PX_packFunc fnPackFunc; // Pixel packing function for SW + PX_unpackFunc fnUnpackFunc; // Pixel unpacking function for SW + PX_packSpanFunc fnPackSpanFunc; // Pixel span packer + + D3DVIEWPORT2 d3dViewport; // D3D Viewport object + + D3DCULL cullmode; // Direct3D cull mode + D3DCOLOR curcolor; // Current color + DWORD dwColorPF; // Current color, in format of target surface + D3DCOLOR d3dClearColor; // Clear color + D3DCOLOR ConstantColor; // For flat shading + DWORD dwClearColorPF; // Clear color, in format of target surface + BOOL bGDIEraseBkgnd; // GDI Erase Background command + + // Primitive caches +// DGL_vertex LineCache[DGL_MAX_LINE_VERTS]; +// DGL_vertex TriCache[DGL_MAX_TRI_VERTS]; +// DWORD dwNextLineVert; +// DWORD dwNextTriVert; + + // Window information + HWND hWnd; // Window handle + HDC hDC; // Windows' Device Context of the window + DWORD dwWidth; // Window width + DWORD dwHeight; // Window height + DWORD dwBPP; // Window bits-per-pixel; + RECT rcScreenRect; // Screen rectangle + DWORD dwModeWidth; // Display mode width + DWORD dwModeHeight; // Display mode height + float dvClipX; + float dvClipY; + LONG lpfnWndProc; // window message handler function + + // Shared texture palette + IDirectDrawPalette *lpGlobalPalette; + + // Usage counters. + // One of these counters will be incremented when we choose + // between hardware and software rendering functions. +// DWORD dwHWUsageCount; // Hardware usage count +// DWORD dwSWUsageCount; // Software usage count + + // Texture state flags. +// BOOL m_texturing; // TRUE is texturing +// BOOL m_mtex; // TRUE if multitexture +// BOOL m_texHandleValid; // TRUE if tex state valid + + // Renderstate caches to ensure no redundant state changes + DWORD dwRS[256]; // Renderstates + DWORD dwTSS[2][24]; // Texture-stage states + LPDIRECT3DTEXTURE2 lpTex[2]; // Texture (1 per stage) + + DWORD dwMaxTextureSize; // Max texture size: + // clamped to 1024. + +} DGL_ctx; +#endif // _USE_GLD3_WGL + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +HHOOK hKeyHook; +LRESULT CALLBACK dglKeyProc(int code,WPARAM wParam,LPARAM lParam); + +void dglInitContextState(); +void dglDeleteContextState(); +BOOL dglIsValidContext(HGLRC a); +DGL_ctx* dglGetContextAddress(const HGLRC a); +HDC dglGetCurrentDC(void); +HGLRC dglGetCurrentContext(void); +HGLRC dglCreateContext(HDC a, const DGL_pixelFormat *lpPF); +BOOL dglMakeCurrent(HDC a, HGLRC b); +BOOL dglDeleteContext(HGLRC a); +BOOL dglSwapBuffers(HDC hDC); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.c b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.c new file mode 100644 index 000000000..c633e3bcf --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.c @@ -0,0 +1,149 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Global variables. +* +****************************************************************************/ + +#include "dglglobals.h" + +// ======================================================================= +// Global Variables +// ======================================================================= + +char szCopyright[] = "Copyright (c) 1998 SciTech Software, Inc."; +char szDllName[] = "Scitech GLDirect"; +char szErrorTitle[] = "GLDirect Error"; + +DGL_globals glb; + +// Shared result variable +HRESULT hResult; + +// *********************************************************************** + +// Patch function for missing function in Mesa +int finite( + double x) +{ + return _finite(x); +}; + +// *********************************************************************** + +void dglInitGlobals() +{ + // Zero all fields just in case + memset(&glb, 0, sizeof(glb)); + + // Set the global defaults + glb.bPrimary = FALSE; // Not the primary device + glb.bHardware = FALSE; // Not a hardware device +// glb.bFullscreen = FALSE; // Not running fullscreen + glb.bSquareTextures = FALSE; // Device does not need sq + glb.bPAL8 = FALSE; // Device cannot do 8bit + glb.dwMemoryType = DDSCAPS_SYSTEMMEMORY; + glb.dwRendering = DGL_RENDER_D3D; + + glb.bWaitForRetrace = TRUE; // Sync to vertical retrace + glb.bFullscreenBlit = FALSE; + + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; // Pixel format list +#ifndef _USE_GLD3_WGL + glb.nZBufferPFCount = 0; + glb.lpZBufferPF = NULL; + glb.nDisplayModeCount = 0; + glb.lpDisplayModes = NULL; + glb.nTextureFormatCount = 0; + glb.lpTextureFormat = NULL; +#endif // _USE_GLD3_WGL + + glb.wMaxSimultaneousTextures = 1; + + // Enable support for multitexture, if available. + glb.bMultitexture = TRUE; + + // Enable support for mipmapping + glb.bUseMipmaps = TRUE; + + // Alpha emulation via chroma key + glb.bEmulateAlphaTest = FALSE; + + // Use Mesa pipeline always (for compatibility) + glb.bForceMesaPipeline = FALSE; + + // Init support for multiple GLRCs + glb.bDirectDraw = FALSE; + glb.bDirectDrawPrimary = FALSE; + glb.bDirect3D = FALSE; + glb.bDirect3DDevice = FALSE; + glb.bDirectDrawStereo = FALSE; + glb.iDirectDrawStereo = 0; + glb.hWndActive = NULL; + // Init DirectX COM interfaces for multiple GLRCs +// glb.lpDD4 = NULL; +// glb.lpPrimary4 = NULL; +// glb.lpBack4 = NULL; +// glb.lpDepth4 = NULL; +// glb.lpGlobalPalette = NULL; + + // Init special support options + glb.bMessageBoxWarnings = TRUE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + + // Do not assume single-precision-only FPU (for compatibility) + glb.bFastFPU = FALSE; + + // Allow hot-key support + glb.bHotKeySupport = TRUE; + + // Default to single-threaded support (for simplicity) + glb.bMultiThreaded = FALSE; + + // Use application-specific customizations (for end-user convenience) + glb.bAppCustomizations = TRUE; + +#ifdef _USE_GLD3_WGL + // Registry/ini-file settings for GLDirect 3.x + glb.dwAdapter = 0; // Primary DX8 adapter + glb.dwTnL = 1; // MesaSW TnL + glb.dwMultisample = 0; // Multisample Off + glb.dwDriver = 2; // Direct3D HW + + // Signal a pixelformat list rebuild + glb.bPixelformatsDirty = TRUE; +#endif +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.h b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.h new file mode 100644 index 000000000..995f1cd5e --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglglobals.h @@ -0,0 +1,198 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Globals. +* +****************************************************************************/ + +#ifndef __DGLGLOBALS_H +#define __DGLGLOBALS_H + +#include "dglcontext.h" +#include "dglpf.h" // Pixel format +#ifndef _USE_GLD3_WGL +#include "d3dtexture.h" +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef enum { + DGL_RENDER_MESASW = 0, + DGL_RENDER_D3D = 1, + DGL_RENDER_FORCE_DWORD = 0x7ffffff, +} DGL_renderType; + +#ifdef _USE_GLD3_WGL + +// Same as DGL_renderType? KeithH +typedef enum { + GLDS_DRIVER_MESA_SW = 0, // Mesa SW rendering + GLDS_DRIVER_REF = 1, // Direct3D Reference Rasteriser + GLDS_DRIVER_HAL = 2, // Direct3D HW rendering +} GLDS_DRIVER; + +typedef enum { + GLDS_TNL_DEFAULT = 0, // Choose best TnL method + GLDS_TNL_MESA = 1, // Mesa TnL + GLDS_TNL_D3DSW = 2, // D3D Software TnL + GLDS_TNL_D3DHW = 3, // D3D Hardware TnL +} GLDS_TNL; + +typedef enum { + GLDS_MULTISAMPLE_NONE = 0, + GLDS_MULTISAMPLE_FASTEST = 1, + GLDS_MULTISAMPLE_NICEST = 2, +} GLDS_MULTISAMPLE; +#endif + +typedef struct { + // Registry settings + char szDDName[MAX_DDDEVICEID_STRING]; // DirectDraw device name + char szD3DName[MAX_DDDEVICEID_STRING]; // Direct3D driver name + BOOL bPrimary; // Is ddraw device the Primary device? + BOOL bHardware; // Is the d3d driver a Hardware driver? +#ifndef _USE_GLD3_WGL + GUID ddGuid; // GUID of the ddraw device + GUID d3dGuid; // GUID of the direct3d driver +#endif // _USE_GLD3_WGL +// BOOL bFullscreen; // Force fullscreen - only useful for primary adaptors. + BOOL bSquareTextures; // Does this driver require square textures? + DWORD dwRendering; // Type of rendering required + + BOOL bWaitForRetrace; // Sync to vertical retrace + BOOL bFullscreenBlit; // Use Blt instead of Flip in fullscreen modes + + // Multitexture + BOOL bMultitexture; + + BOOL bUseMipmaps; + + DWORD dwMemoryType; // Sysmem or Vidmem + + // Global palette + BOOL bPAL8; + DDPIXELFORMAT ddpfPAL8; + + // Multitexture + WORD wMaxSimultaneousTextures; + + // Win32 internals + BOOL bAppActive; // Keep track of Alt-Tab + LONG lpfnWndProc; // WndProc of calling app + + // Pixel Format Descriptior list. + int nPixelFormatCount; + DGL_pixelFormat *lpPF; +#ifndef _USE_GLD3_WGL + // ZBuffer pixel formats + int nZBufferPFCount; // Count of Zbuffer pixel formats + DDPIXELFORMAT *lpZBufferPF; // ZBuffer pixel formats + + // Display modes (for secondary devices) + int nDisplayModeCount; + DDSURFACEDESC2 *lpDisplayModes; + + // Texture pixel formats + int nTextureFormatCount; + DGL_textureFormat *lpTextureFormat; +#endif // _USE_GLD3_WGL + // Alpha emulation via chroma key + BOOL bEmulateAlphaTest; + + // Geom pipeline override. + // If this is set TRUE then the D3D pipeline will never be used, + // and the Mesa pipline will always be used. + BOOL bForceMesaPipeline; + +#ifdef _USE_GLD3_WGL + BOOL bPixelformatsDirty; // Signal a list rebuild +#endif + + // Additional globals to support multiple GL rendering contexts, GLRCs + BOOL bDirectDraw; // DirectDraw interface exists ? + BOOL bDirectDrawPrimary; // DirectDraw primary surface exists ? + BOOL bDirect3D; // Direct3D interface exists ? + BOOL bDirect3DDevice; // Direct3D device exists ? + + BOOL bDirectDrawStereo; // DirectDraw Stereo driver started ? + int iDirectDrawStereo; // DirectDraw Stereo driver reference count + HWND hWndActive; // copy of active window + + // Copies of DirectX COM interfaces for re-referencing across multiple GLRCs +// IDirectDraw4 *lpDD4; // copy of DirectDraw interface +// IDirectDrawSurface4 *lpPrimary4; // copy of DirectDraw primary surface +// IDirectDrawSurface4 *lpBack4; +// IDirectDrawSurface4 *lpDepth4; +// IDirectDrawPalette *lpGlobalPalette; + + // Aids for heavy-duty MFC-windowed OGL apps, like AutoCAD + BOOL bMessageBoxWarnings; // popup message box warning + BOOL bDirectDrawPersistant; // DirectDraw is persisitant + BOOL bPersistantBuffers; // DirectDraw buffers persisitant + + // FPU setup option for CAD precision (AutoCAD) vs GAME speed (Quake) + BOOL bFastFPU; // single-precision-only FPU ? + + // Hot-Key support, like for real-time stereo parallax adjustments + BOOL bHotKeySupport; // hot-key support ? + + // Multi-threaded support, for apps like 3DStudio + BOOL bMultiThreaded; // multi-threaded ? + + // Detect and use app-specific customizations for apps like 3DStudio + BOOL bAppCustomizations; // app customizations ? + +#ifdef _USE_GLD3_WGL + DWORD dwAdapter; // Primary DX8 adapter + DWORD dwTnL; // MesaSW TnL + DWORD dwMultisample; // Multisample Off + DWORD dwDriver; // Direct3D HW + void *pDrvPrivate; // Driver-specific data +#endif + +} DGL_globals; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +DGL_globals glb; + +void dglInitGlobals(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglmacros.h b/mesalib/src/mesa/drivers/windows/gldirect/dglmacros.h new file mode 100644 index 000000000..aed0f2110 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglmacros.h @@ -0,0 +1,91 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Useful generic macros. +* +****************************************************************************/ + +#ifndef __DGLMACROS_H +#define __DGLMACROS_H + +#include <ddraw.h> + +// Define the relevant RELEASE macro depending on C or C++ +#if !defined(__cplusplus) || defined(CINTERFACE) + // Standard C version + #define RELEASE(x) if (x!=NULL) { x->lpVtbl->Release(x); x=NULL; } +#else + // C++ version + #define RELEASE(x) if (x!=NULL) { x->Release(); x=NULL; } +#endif + +// We don't want a message *every* time we call an unsupported function +#define UNSUPPORTED(x) \ + { \ + static BOOL bFirstTime = TRUE; \ + if (bFirstTime) { \ + bFirstTime = FALSE; \ + ddlogError(DDLOG_WARN, (x), DDERR_CURRENTLYNOTAVAIL); \ + } \ + } + +#define DGL_CHECK_CONTEXT \ + if (ctx == NULL) return; + +// Don't render if bCanRender is not TRUE. +#define DGL_CHECK_RENDER \ + if (!dgl->bCanRender) return; + +#if 0 +#define TRY(a,b) (a) +#define TRY_ERR(a,b) (a) +#else +// hResult should be defined in the function +// Return codes should be checked via SUCCEDDED and FAILED macros +#define TRY(a,b) \ + { \ + if (FAILED(hResult=(a))) \ + ddlogError(DDLOG_ERROR, (b), hResult); \ + } + +// hResult is a global +// The label exit_with_error should be defined within the calling scope +#define TRY_ERR(a,b) \ + { \ + if (FAILED(hResult=(a))) { \ + ddlogError(DDLOG_ERROR, (b), hResult); \ + goto exit_with_error; \ + } \ + } +#endif // #if 1 + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglpf.c b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.c new file mode 100644 index 000000000..4cd4d0334 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.c @@ -0,0 +1,620 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ======================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Pixel Formats. +* +****************************************************************************/ + +#include "dglpf.h" + +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" +#endif + +// *********************************************************************** + +char szColorDepthWarning[] = +"GLDirect does not support the current desktop\n\ +color depth.\n\n\ +You may need to change the display resolution to\n\ +16 bits per pixel or higher color depth using\n\ +the Windows Display Settings control panel\n\ +before running this OpenGL application.\n"; + +// *********************************************************************** +// This pixel format will be used as a template when compiling the list +// of pixel formats supported by the hardware. Many fields will be +// filled in at runtime. +// PFD flag defaults are upgraded to match ChoosePixelFormat() -- DaveM +DGL_pixelFormat pfTemplateHW = +{ + { + sizeof(PIXELFORMATDESCRIPTOR), // Size of the data structure + 1, // Structure version - should be 1 + // Flags: + PFD_DRAW_TO_WINDOW | // The buffer can draw to a window or device surface. + PFD_DRAW_TO_BITMAP | // The buffer can draw to a bitmap. (DaveM) + PFD_SUPPORT_GDI | // The buffer supports GDI drawing. (DaveM) + PFD_SUPPORT_OPENGL | // The buffer supports OpenGL drawing. + PFD_DOUBLEBUFFER | // The buffer is double-buffered. + 0, // Placeholder for easy commenting of above flags + PFD_TYPE_RGBA, // Pixel type RGBA. + 16, // Total colour bitplanes (excluding alpha bitplanes) + 5, 0, // Red bits, shift + 5, 5, // Green bits, shift + 5, 10, // Blue bits, shift + 0, 0, // Alpha bits, shift (destination alpha) + 0, // Accumulator bits (total) + 0, 0, 0, 0, // Accumulator bits: Red, Green, Blue, Alpha + 0, // Depth bits + 0, // Stencil bits + 0, // Number of auxiliary buffers + 0, // Layer type + 0, // Specifies the number of overlay and underlay planes. + 0, // Layer mask + 0, // Specifies the transparent color or index of an underlay plane. + 0 // Damage mask + }, + -1, // No depth/stencil buffer +}; + +// *********************************************************************** +// Return the count of the number of bits in a Bit Mask. +int BitCount( + DWORD dw) +{ + int i; + + if (dw == 0) + return 0; // account for non-RGB mode + + for (i=0; dw; dw=dw>>1) + i += (dw & 1); + return i; +} + +// *********************************************************************** + +DWORD BitShift( + DWORD dwMaskIn) +{ + DWORD dwShift, dwMask; + + if (dwMaskIn == 0) + return 0; // account for non-RGB mode + + for (dwShift=0, dwMask=dwMaskIn; !(dwMask&1); dwShift++, dwMask>>=1); + + return dwShift; +} + +// *********************************************************************** + +BOOL IsValidPFD(int iPFD) +{ + DGL_pixelFormat *lpPF; + + // Validate license + if (!dglValidate()) + return FALSE; + + if ((glb.lpPF == NULL) || + (glb.nPixelFormatCount == 0)) + return FALSE; + + // Check PFD range + if ( (iPFD < 1) || (iPFD > glb.nPixelFormatCount) ) { + ddlogMessage(DDLOG_ERROR, "PFD out of range\n"); + return FALSE; // PFD is invalid + } + + // Make a pointer to the pixel format + lpPF = &glb.lpPF[iPFD-1]; + + // Check size + if (lpPF->pfd.nSize != sizeof(PIXELFORMATDESCRIPTOR)) { + ddlogMessage(DDLOG_ERROR, "Bad PFD size\n"); + return FALSE; // PFD is invalid + } + + // Check version + if (lpPF->pfd.nVersion != 1) { + ddlogMessage(DDLOG_ERROR, "PFD is not Version 1\n"); + return FALSE; // PFD is invalid + } + + return TRUE; // PFD is valid +} + +// *********************************************************************** + +#ifndef _USE_GLD3_WGL + +int iEnumCount; // Enumeration count +DWORD dwDisplayBitDepth; // Bit depth of current display mode + +// *********************************************************************** + +HRESULT WINAPI EnumDisplayModesCallback( + DDSURFACEDESC2* pddsd, + void *pvContext) +{ + DWORD dwModeDepth; + DDSURFACEDESC2 *lpDisplayMode; + char buf[32]; + + // Check parameters + if (pddsd == NULL) + return DDENUMRET_CANCEL; + + dwModeDepth = pddsd->ddpfPixelFormat.dwRGBBitCount; + lpDisplayMode = (DDSURFACEDESC2 *)pvContext; + + // Check mode for compatability with device. + if (dwModeDepth != dwDisplayBitDepth) + return DDENUMRET_OK; + + if (lpDisplayMode != NULL) { + memcpy(&lpDisplayMode[iEnumCount], pddsd, sizeof(DDSURFACEDESC2)); + sprintf(buf, TEXT("Mode: %ld x %ld x %ld\n"), + pddsd->dwWidth, pddsd->dwHeight, dwModeDepth); + ddlogMessage(DDLOG_INFO, buf); + } + + iEnumCount++; + + return DDENUMRET_OK; +} + +// *********************************************************************** + +HRESULT CALLBACK d3dEnumZBufferFormatsCallback( + DDPIXELFORMAT* pddpf, + VOID* lpZBufferPF ) +{ + char buf[64]; + + if(pddpf == NULL) + return D3DENUMRET_CANCEL; + + if (pddpf->dwFlags & DDPF_ZBUFFER) { + if (lpZBufferPF == NULL) { + // Pass 1. Merely counting the PF + glb.nZBufferPFCount++; + } else { + // Pass 2. Save the PF + if (pddpf->dwFlags & DDPF_STENCILBUFFER) { + sprintf(buf, " %d: Z=%d S=%d\n", + iEnumCount, + pddpf->dwZBufferBitDepth, + pddpf->dwStencilBitDepth); + } else { + sprintf(buf, " %d: Z=%d S=0\n", + iEnumCount, + pddpf->dwZBufferBitDepth); + } + ddlogMessage(DDLOG_INFO, buf); + + memcpy(&glb.lpZBufferPF[iEnumCount++], + pddpf, + sizeof(DDPIXELFORMAT)); + } + } + + return D3DENUMRET_OK; +} +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +BOOL IsStencilSupportBroken(LPDIRECTDRAW4 lpDD4) +{ + DDDEVICEIDENTIFIER dddi; // DX6 device identifier + BOOL bBroken = FALSE; + + // Microsoft really fucked up with the GetDeviceIdentifier function + // on Windows 2000, since it locks up on stock driers on the CD. Updated + // drivers from vendors appear to work, but we can't identify the drivers + // without this function!!! For now we skip these tests on Windows 2000. + if ((GetVersion() & 0x80000000UL) == 0) + return FALSE; + + // Obtain device info + if (FAILED(IDirectDraw4_GetDeviceIdentifier(lpDD4, &dddi, 0))) + return FALSE; + + // Matrox G400 stencil buffer support does not draw anything in AutoCAD, + // but ordinary Z buffers draw shaded models fine. (DaveM) + if (dddi.dwVendorId == 0x102B) { // Matrox + if (dddi.dwDeviceId == 0x0525) { // G400 + bBroken = TRUE; + } + } + + return bBroken; +} + +// *********************************************************************** + +void dglBuildPixelFormatList() +{ + int i; + char buf[128]; + char cat[8]; + DGL_pixelFormat *lpPF; + +#ifdef _USE_GLD3_WGL + _gldDriver.BuildPixelformatList(); +#else + HRESULT hRes; + IDirectDraw *lpDD1 = NULL; + IDirectDraw4 *lpDD4 = NULL; + IDirect3D3 *lpD3D3 = NULL; + DDSURFACEDESC2 ddsdDisplayMode; + + DWORD dwRb, dwGb, dwBb, dwAb; // Bit counts + DWORD dwRs, dwGs, dwBs, dwAs; // Bit shifts + DWORD dwPixelType; // RGB or color index + + // Set defaults + glb.nPixelFormatCount = 0; + glb.lpPF = NULL; + glb.nZBufferPFCount = 0; + glb.lpZBufferPF = NULL; + glb.nDisplayModeCount = 0; + glb.lpDisplayModes = NULL; + + // + // Examine the hardware for depth and stencil + // + + if (glb.bPrimary) + hRes = DirectDrawCreate(NULL, &lpDD1, NULL); + else + hRes = DirectDrawCreate(&glb.ddGuid, &lpDD1, NULL); + + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: DirectDrawCreate failed", hRes); + return; + } + + // Query for DX6 IDirectDraw4. + hRes = IDirectDraw_QueryInterface( + lpDD1, + &IID_IDirectDraw4, + (void**)&lpDD4); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: QueryInterface (DD4) failed", hRes); + goto clean_up; + } + + + // Retrieve caps of current display mode + ZeroMemory(&ddsdDisplayMode, sizeof(ddsdDisplayMode)); + ddsdDisplayMode.dwSize = sizeof(ddsdDisplayMode); + hRes = IDirectDraw4_GetDisplayMode(lpDD4, &ddsdDisplayMode); + if (FAILED(hRes)) + goto clean_up; + + dwDisplayBitDepth = ddsdDisplayMode.ddpfPixelFormat.dwRGBBitCount; + dwPixelType = (dwDisplayBitDepth <= 8) ? PFD_TYPE_COLORINDEX : PFD_TYPE_RGBA; + dwRb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRBitMask); + dwGb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwGBitMask); + dwBb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwBBitMask); + dwRs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwRBitMask); + dwGs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwGBitMask); + dwBs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwBBitMask); + + if (BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask)) { + dwAb = BitCount(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask); + dwAs = BitShift(ddsdDisplayMode.ddpfPixelFormat.dwRGBAlphaBitMask); + } else { + dwAb = 0; + dwAs = 0; + } + + // Query for available display modes + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "Display Modes:\n"); + + // Pass 1: Determine count + iEnumCount = 0; + hRes = IDirectDraw4_EnumDisplayModes( + lpDD4, + 0, + NULL, + NULL, + EnumDisplayModesCallback); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: EnumDisplayModes failed", hRes); + goto clean_up; + } + if (iEnumCount == 0) { + ddlogMessage(DDLOG_ERROR, "dglBPFL: No display modes found"); + goto clean_up; + } + glb.lpDisplayModes = (DDSURFACEDESC2 *)calloc(iEnumCount, + sizeof(DDSURFACEDESC2)); + if (glb.lpDisplayModes == NULL) { + ddlogMessage(DDLOG_ERROR, "dglBPFL: DDSURFACEDESC2 calloc failed"); + goto clean_up; + } + glb.nDisplayModeCount = iEnumCount; + // Pass 2: Save modes + iEnumCount = 0; + hRes = IDirectDraw4_EnumDisplayModes( + lpDD4, + 0, + NULL, + (void *)glb.lpDisplayModes, + EnumDisplayModesCallback); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: EnumDisplayModes failed", hRes); + goto clean_up; + } + // Query for IDirect3D3 interface + hRes = IDirectDraw4_QueryInterface( + lpDD4, + &IID_IDirect3D3, + (void**)&lpD3D3); + if (FAILED(hRes)) { + ddlogError(DDLOG_ERROR, "dglBPFL: QueryInterface (D3D3) failed", hRes); + goto clean_up; + } + + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "ZBuffer formats:\n"); + + // Pass 1. Count the ZBuffer pixel formats + hRes = IDirect3D3_EnumZBufferFormats( + lpD3D3, + &glb.d3dGuid, + d3dEnumZBufferFormatsCallback, + NULL); + + if (FAILED(hRes)) + goto clean_up; + + if (glb.nZBufferPFCount) { + glb.lpZBufferPF = (DDPIXELFORMAT *)calloc(glb.nZBufferPFCount, + sizeof(DDPIXELFORMAT)); + if(glb.lpZBufferPF == NULL) + goto clean_up; + + // Pass 2. Cache the ZBuffer pixel formats + iEnumCount = 0; // (Used by the enum function) + hRes = IDirect3D3_EnumZBufferFormats( + lpD3D3, + &glb.d3dGuid, + d3dEnumZBufferFormatsCallback, + glb.lpZBufferPF); + + if (FAILED(hRes)) + goto clean_up; + } + + // Remove stencil support for boards which don't work for AutoCAD; + // Matrox G400 does not work, but NVidia TNT2 and ATI Rage128 do... (DaveM) + if (IsStencilSupportBroken(lpDD4)) { + for (i=0; i<iEnumCount; i++) + if (glb.lpZBufferPF[i].dwFlags & DDPF_STENCILBUFFER) + glb.nZBufferPFCount--; + } + + // One each for every ZBuffer pixel format (including no depth buffer) + // Times-two because duplicated for single buffering (as opposed to double) + glb.nPixelFormatCount = 2 * (glb.nZBufferPFCount + 1); + glb.lpPF = (DGL_pixelFormat *)calloc(glb.nPixelFormatCount, + sizeof(DGL_pixelFormat)); + if (glb.lpPF == NULL) + goto clean_up; + // + // Fill in the pixel formats + // Note: Depth buffer bits are really (dwZBufferBitDepth-dwStencilBitDepth) + // but this will pass wierd numbers to the OpenGL app. (?) + // + + pfTemplateHW.pfd.iPixelType = dwPixelType; + pfTemplateHW.pfd.cColorBits = dwDisplayBitDepth; + pfTemplateHW.pfd.cRedBits = dwRb; + pfTemplateHW.pfd.cGreenBits = dwGb; + pfTemplateHW.pfd.cBlueBits = dwBb; + pfTemplateHW.pfd.cAlphaBits = dwAb; + pfTemplateHW.pfd.cRedShift = dwRs; + pfTemplateHW.pfd.cGreenShift = dwGs; + pfTemplateHW.pfd.cBlueShift = dwBs; + pfTemplateHW.pfd.cAlphaShift = dwAs; + + lpPF = glb.lpPF; + + // Fill in the double-buffered pixel formats + for (i=0; i<(glb.nZBufferPFCount + 1); i++, lpPF++) { + memcpy(lpPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + if (i) { + lpPF->iZBufferPF = i-1; + lpPF->pfd.cDepthBits = glb.lpZBufferPF[i-1].dwZBufferBitDepth; + lpPF->pfd.cStencilBits = glb.lpZBufferPF[i-1].dwStencilBitDepth; + } + } + // Fill in the single-buffered pixel formats + for (i=0; i<(glb.nZBufferPFCount + 1); i++, lpPF++) { + memcpy(lpPF, &pfTemplateHW, sizeof(DGL_pixelFormat)); + if (i) { + lpPF->iZBufferPF = i-1; + lpPF->pfd.cDepthBits = glb.lpZBufferPF[i-1].dwZBufferBitDepth; + lpPF->pfd.cStencilBits = glb.lpZBufferPF[i-1].dwStencilBitDepth; + } + // Remove double-buffer flag. Could use XOR instead... + lpPF->pfd.dwFlags &= (~(PFD_DOUBLEBUFFER)); + // Insert GDI flag for single buffered format only. + lpPF->pfd.dwFlags |= PFD_SUPPORT_GDI; + } +#endif // _USE_GLD3_WGL + + // Lets dump the list to the log + // ** Based on "wglinfo" by Nate Robins ** + ddlogMessage(DDLOG_INFO, "\n"); + ddlogMessage(DDLOG_INFO, "Pixel Formats:\n"); + ddlogMessage(DDLOG_INFO, + " visual x bf lv rg d st r g b a ax dp st accum buffs ms\n"); + ddlogMessage(DDLOG_INFO, + " id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n"); + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + for (i=0, lpPF = glb.lpPF; i<glb.nPixelFormatCount; i++, lpPF++) { + sprintf(buf, "0x%02x ", i+1); + + sprintf(cat, "%2d ", lpPF->pfd.cColorBits); + strcat(buf, cat); + if(lpPF->pfd.dwFlags & PFD_DRAW_TO_WINDOW) sprintf(cat, "wn "); + else if(lpPF->pfd.dwFlags & PFD_DRAW_TO_BITMAP) sprintf(cat, "bm "); + else sprintf(cat, ". "); + strcat(buf, cat); + + /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ + sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, "%2d ", lpPF->pfd.cColorBits); + strcat(buf, cat); + + /* bReserved field indicates number of over/underlays */ + if(lpPF->pfd.bReserved) sprintf(cat, " %d ", lpPF->pfd.bReserved); + else sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, " %c ", lpPF->pfd.iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); + strcat(buf, cat); + + sprintf(cat, "%c ", lpPF->pfd.dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); + strcat(buf, cat); + + sprintf(cat, " %c ", lpPF->pfd.dwFlags & PFD_STEREO ? 'y' : '.'); + strcat(buf, cat); + + if(lpPF->pfd.cRedBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cGreenBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cBlueBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAlphaBits && lpPF->pfd.iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", lpPF->pfd.cAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAuxBuffers) sprintf(cat, "%2d ", lpPF->pfd.cAuxBuffers); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cDepthBits) sprintf(cat, "%2d ", lpPF->pfd.cDepthBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cStencilBits) sprintf(cat, "%2d ", lpPF->pfd.cStencilBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumRedBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumGreenBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumBlueBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(lpPF->pfd.cAccumAlphaBits) sprintf(cat, "%2d ", lpPF->pfd.cAccumAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + /* no multisample in Win32 */ + sprintf(cat, " . .\n"); + strcat(buf, cat); + + ddlogMessage(DDLOG_INFO, buf); + } + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + ddlogMessage(DDLOG_INFO, "\n"); + +#ifndef _USE_GLD3_WGL +clean_up: + // Release COM objects + RELEASE(lpD3D3); + RELEASE(lpDD4); + RELEASE(lpDD1); + + // Popup warning message if non RGB color mode + if (dwDisplayBitDepth <= 8) { + ddlogPrintf(DDLOG_WARN, "Current Color Depth %d bpp is not supported", dwDisplayBitDepth); + MessageBox(NULL, szColorDepthWarning, "GLDirect", MB_OK | MB_ICONWARNING); + } +#endif // _USE_GLD3_WGL +} + +// *********************************************************************** + +void dglReleasePixelFormatList() +{ + glb.nPixelFormatCount = 0; + if (glb.lpPF) { + free(glb.lpPF); + glb.lpPF = NULL; + } +#ifndef _USE_GLD3_WGL + glb.nZBufferPFCount = 0; + if (glb.lpZBufferPF) { + free(glb.lpZBufferPF); + glb.lpZBufferPF = NULL; + } + glb.nDisplayModeCount = 0; + if (glb.lpDisplayModes) { + free(glb.lpDisplayModes); + glb.lpDisplayModes = NULL; + } +#endif // _USE_GLD3_WGL +} + +// *********************************************************************** diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglpf.h b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.h new file mode 100644 index 000000000..8a7e38c4b --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglpf.h @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Pixel Formats. +* +****************************************************************************/ + +#ifndef __DGLPF_H +#define __DGLPF_H + +#ifndef STRICT +#define STRICT +#endif // STRICT +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef struct { + PIXELFORMATDESCRIPTOR pfd; // Win32 Pixel Format Descriptor +#ifdef _USE_GLD3_WGL + // Driver-specific data. + // Example: The DX8 driver uses this to hold an index into a + // list of depth-stencil descriptions. + DWORD dwDriverData; +#else + int iZBufferPF; // Index of depth buffer pixel format +#endif +} DGL_pixelFormat; + +#include "dglglobals.h" + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +BOOL IsValidPFD(int iPFD); +void dglBuildPixelFormatList(); +void dglReleasePixelFormatList(); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.c b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.c new file mode 100644 index 000000000..74ecb01a5 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.c @@ -0,0 +1,2964 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: OpenGL window functions (wgl*). +* +****************************************************************************/ + +#include "dglwgl.h" +#ifdef _USE_GLD3_WGL +#include "gld_driver.h" +#endif + +#include "gl/glu.h" // MUST USE MICROSOFT'S GLU32! + +#ifndef _USE_GLD3_WGL +extern DGL_mesaFuncs mesaFuncs; +#endif + +// Need to export wgl* functions if using GLD3, +// otherwise export GLD2 DGL_* functions. +#ifdef _USE_GLD3_WGL +#define _GLD_WGL_EXPORT(a) wgl##a +#else +#define _GLD_WGL_EXPORT(a) DGL_##a +#endif + +// Calls into Mesa 4.x are different +#ifdef _USE_GLD3_WGL +#include "dlist.h" +#include "drawpix.h" +#include "get.h" +#include "matrix.h" +// NOTE: All the _GLD* macros now call the gl* functions direct. +// This ensures that the correct internal pathway is taken. KeithH +#define _GLD_glNewList glNewList +#define _GLD_glBitmap glBitmap +#define _GLD_glEndList glEndList +#define _GLD_glDeleteLists glDeleteLists +#define _GLD_glGetError glGetError +#define _GLD_glTranslatef glTranslatef +#define _GLD_glBegin glBegin +#define _GLD_glVertex2fv glVertex2fv +#define _GLD_glEnd glEnd +#define _GLD_glNormal3f glNormal3f +#define _GLD_glVertex3f glVertex3f +#define _GLD_glVertex3fv glVertex3fv +#else // _USE_GLD3_WGL +#define _GLD_glNewList (*mesaFuncs.glNewList) +#define _GLD_glBitmap (*mesaFuncs.glBitmap) +#define _GLD_glEndList (*mesaFuncs.glEndList) +#define _GLD_glDeleteLists (*mesaFuncs.glDeleteLists) +#define _GLD_glGetError (*mesaFuncs.glGetError) +#define _GLD_glTranslatef (*mesaFuncs.glTranslatef) +#define _GLD_glBegin (*mesaFuncs.glBegin) +#define _GLD_glVertex2fv (*mesaFuncs.glVertex2fv) +#define _GLD_glEnd (*mesaFuncs.glEnd) +#define _GLD_glNormal3f (*mesaFuncs.glNormal3f) +#define _GLD_glVertex3f (*mesaFuncs.glVertex3f) +#define _GLD_glVertex3fv (*mesaFuncs.glVertex3fv) +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +// Emulate SGI DDK calls. +#define __wglMalloc(a) GlobalAlloc(GPTR, (a)) +#define __wglFree(a) GlobalFree((a)) + +// *********************************************************************** + +// Mesa glu.h and MS glu.h call these different things... +//#define GLUtesselator GLUtriangulatorObj +//#define GLU_TESS_VERTEX_DATA GLU_VERTEX_DATA + +// For wglFontOutlines + +typedef GLUtesselator *(APIENTRY *gluNewTessProto)(void); +typedef void (APIENTRY *gluDeleteTessProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessBeginPolygonProto)(GLUtesselator *tess, void *polygon_data); +typedef void (APIENTRY *gluTessBeginContourProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessVertexProto)(GLUtesselator *tess, GLdouble coords[3], void *data); +typedef void (APIENTRY *gluTessEndContourProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessEndPolygonProto)(GLUtesselator *tess); +typedef void (APIENTRY *gluTessPropertyProto)(GLUtesselator *tess, GLenum which, GLdouble value); +typedef void (APIENTRY *gluTessNormalProto)(GLUtesselator *tess, GLdouble x, GLdouble y, GLdouble z); +typedef void (APIENTRY *gluTessCallbackProto)(GLUtesselator *tess, GLenum which, void (CALLBACK *)()); + +static HINSTANCE gluModuleHandle; +static gluNewTessProto gluNewTessProc; +static gluDeleteTessProto gluDeleteTessProc; +static gluTessBeginPolygonProto gluTessBeginPolygonProc; +static gluTessBeginContourProto gluTessBeginContourProc; +static gluTessVertexProto gluTessVertexProc; +static gluTessEndContourProto gluTessEndContourProc; +static gluTessEndPolygonProto gluTessEndPolygonProc; +static gluTessPropertyProto gluTessPropertyProc; +static gluTessNormalProto gluTessNormalProc; +static gluTessCallbackProto gluTessCallbackProc; + +static HFONT hNewFont, hOldFont; +static FLOAT ScaleFactor; + +#define LINE_BUF_QUANT 4000 +#define VERT_BUF_QUANT 4000 + +static FLOAT* LineBuf; +static DWORD LineBufSize; +static DWORD LineBufIndex; +static FLOAT* VertBuf; +static DWORD VertBufSize; +static DWORD VertBufIndex; +static GLenum TessErrorOccurred; + +static int AppendToLineBuf( + FLOAT value); + +static int AppendToVertBuf( + FLOAT value); + +static int DrawGlyph( + UCHAR* glyphBuf, + DWORD glyphSize, + FLOAT chordalDeviation, + FLOAT extrusion, + INT format); + +static void FreeLineBuf(void); + +static void FreeVertBuf(void); + +static long GetWord( + UCHAR** p); + +static long GetDWord( + UCHAR** p); + +static double GetFixed( + UCHAR** p); + +static int InitLineBuf(void); + +static int InitVertBuf(void); + +static HFONT CreateHighResolutionFont( + HDC hDC); + +static int MakeDisplayListFromGlyph( + DWORD listName, + UCHAR* glyphBuf, + DWORD glyphSize, + LPGLYPHMETRICSFLOAT glyphMetricsFloat, + FLOAT chordalDeviation, + FLOAT extrusion, + INT format); + +static BOOL LoadGLUTesselator(void); +static BOOL UnloadGLUTesselator(void); + +static int MakeLinesFromArc( + FLOAT x0, + FLOAT y0, + FLOAT x1, + FLOAT y1, + FLOAT x2, + FLOAT y2, + DWORD vertexCountIndex, + FLOAT chordalDeviationSquared); + +static int MakeLinesFromGlyph( UCHAR* glyphBuf, + DWORD glyphSize, + FLOAT chordalDeviation); + +static int MakeLinesFromTTLine( UCHAR** pp, + DWORD vertexCountIndex, + WORD pointCount); + +static int MakeLinesFromTTPolycurve( UCHAR** pp, + DWORD vertexCountIndex, + FLOAT chordalDeviation); + +static int MakeLinesFromTTPolygon( UCHAR** pp, + FLOAT chordalDeviation); + +static int MakeLinesFromTTQSpline( UCHAR** pp, + DWORD vertexCountIndex, + WORD pointCount, + FLOAT chordalDeviation); + +static void CALLBACK TessCombine( double coords[3], + void* vertex_data[4], + FLOAT weight[4], + void** outData); + +static void CALLBACK TessError( GLenum error); + +static void CALLBACK TessVertexOutData( FLOAT p[3], + GLfloat z); + +// *********************************************************************** + +#ifdef GLD_THREADS +#pragma message("compiling DGLWGL.C vars for multi-threaded support") +extern CRITICAL_SECTION CriticalSection; +extern DWORD dwTLSPixelFormat; // TLS index for current pixel format +#endif +int curPFD = 0; // Current PFD (static) + +// *********************************************************************** + +int dglGetPixelFormat(void) +{ +#ifdef GLD_THREADS + int iPixelFormat; + // get thread-specific instance + if (glb.bMultiThreaded) { + __try { + iPixelFormat = (int)TlsGetValue(dwTLSPixelFormat); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + iPixelFormat = curPFD; + } + } + // get global static var + else { + iPixelFormat = curPFD; + } + return iPixelFormat; +#else + return curPFD; +#endif +} + +// *********************************************************************** + +void dglSetPixelFormat(int iPixelFormat) +{ +#ifdef GLD_THREADS + // set thread-specific instance + if (glb.bMultiThreaded) { + __try { + TlsSetValue(dwTLSPixelFormat, (LPVOID)iPixelFormat); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + curPFD = iPixelFormat; + } + } + // set global static var + else { + curPFD = iPixelFormat; + } +#else + curPFD = iPixelFormat; +#endif +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(ChoosePixelFormat)( + HDC a, + CONST PIXELFORMATDESCRIPTOR *ppfd) +{ + DGL_pixelFormat *lpPF = glb.lpPF; + + PIXELFORMATDESCRIPTOR ppfdBest; + int i; + int bestIndex = -1; + int numPixelFormats; + DWORD dwFlags; + + char buf[128]; + char cat[8]; + + DWORD dwAllFlags = + PFD_DRAW_TO_WINDOW | + PFD_DRAW_TO_BITMAP | + PFD_SUPPORT_GDI | + PFD_SUPPORT_OPENGL | + PFD_GENERIC_FORMAT | + PFD_NEED_PALETTE | + PFD_NEED_SYSTEM_PALETTE | + PFD_DOUBLEBUFFER | + PFD_STEREO | + /*PFD_SWAP_LAYER_BUFFERS |*/ + PFD_DOUBLEBUFFER_DONTCARE | + PFD_STEREO_DONTCARE | + PFD_SWAP_COPY | + PFD_SWAP_EXCHANGE | + PFD_GENERIC_ACCELERATED | + 0; + + // Validate license + if (!dglValidate()) + return 0; + + // List may not be built until dglValidate() is called! KeithH + lpPF = glb.lpPF; + + // + // Lets print the input pixel format to the log + // ** Based on "wglinfo" by Nate Robins ** + // + ddlogMessage(DDLOG_SYSTEM, "ChoosePixelFormat:\n"); + ddlogMessage(DDLOG_INFO, "Input pixel format for ChoosePixelFormat:\n"); + ddlogMessage(DDLOG_INFO, + " visual x bf lv rg d st r g b a ax dp st accum buffs ms\n"); + ddlogMessage(DDLOG_INFO, + " id dep cl sp sz l ci b ro sz sz sz sz bf th cl r g b a ns b\n"); + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + sprintf(buf, " . "); + + sprintf(cat, "%2d ", ppfd->cColorBits); + strcat(buf, cat); + if(ppfd->dwFlags & PFD_DRAW_TO_WINDOW) sprintf(cat, "wn "); + else if(ppfd->dwFlags & PFD_DRAW_TO_BITMAP) sprintf(cat, "bm "); + else sprintf(cat, ". "); + strcat(buf, cat); + + /* should find transparent pixel from LAYERPLANEDESCRIPTOR */ + sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, "%2d ", ppfd->cColorBits); + strcat(buf, cat); + + /* bReserved field indicates number of over/underlays */ + if(ppfd->bReserved) sprintf(cat, " %d ", ppfd->bReserved); + else sprintf(cat, " . "); + strcat(buf, cat); + + sprintf(cat, " %c ", ppfd->iPixelType == PFD_TYPE_RGBA ? 'r' : 'c'); + strcat(buf, cat); + + sprintf(cat, "%c ", ppfd->dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.'); + strcat(buf, cat); + + sprintf(cat, " %c ", ppfd->dwFlags & PFD_STEREO ? 'y' : '.'); + strcat(buf, cat); + + if(ppfd->cRedBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cGreenBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cBlueBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAlphaBits && ppfd->iPixelType == PFD_TYPE_RGBA) + sprintf(cat, "%2d ", ppfd->cAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAuxBuffers) sprintf(cat, "%2d ", ppfd->cAuxBuffers); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cDepthBits) sprintf(cat, "%2d ", ppfd->cDepthBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cStencilBits) sprintf(cat, "%2d ", ppfd->cStencilBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumRedBits) sprintf(cat, "%2d ", ppfd->cAccumRedBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumGreenBits) sprintf(cat, "%2d ", ppfd->cAccumGreenBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumBlueBits) sprintf(cat, "%2d ", ppfd->cAccumBlueBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + if(ppfd->cAccumAlphaBits) sprintf(cat, "%2d ", ppfd->cAccumAlphaBits); + else sprintf(cat, " . "); + strcat(buf, cat); + + /* no multisample in Win32 */ + sprintf(cat, " . .\n"); + strcat(buf, cat); + + ddlogMessage(DDLOG_INFO, buf); + ddlogMessage(DDLOG_INFO, + "-----------------------------------------------------------------\n"); + ddlogMessage(DDLOG_INFO, "\n"); + + // + // Examine the flags for correctness + // + dwFlags = ppfd->dwFlags; + if (dwFlags != (dwFlags & dwAllFlags)) + { + /* error: bad dwFlags */ + ddlogPrintf(DDLOG_WARN, + "ChoosePixelFormat: bad flags (0x%x)", + dwFlags & (~dwAllFlags)); + // Mask illegal flags and continue + dwFlags = dwFlags & dwAllFlags; + } + + switch (ppfd->iPixelType) { + case PFD_TYPE_RGBA: + case PFD_TYPE_COLORINDEX: + break; + default: + /* error: bad iPixelType */ + ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad pixel type\n"); + return 0; + } + + switch (ppfd->iLayerType) { + case PFD_MAIN_PLANE: + case PFD_OVERLAY_PLANE: + case PFD_UNDERLAY_PLANE: + break; + default: + /* error: bad iLayerType */ + ddlogMessage(DDLOG_WARN, "ChoosePixelFormat: bad layer type\n"); + return 0; + } + + numPixelFormats = glb.nPixelFormatCount; + + /* loop through candidate pixel format descriptors */ + for (i=0; i<numPixelFormats; ++i) { + PIXELFORMATDESCRIPTOR ppfdCandidate; + + memcpy(&ppfdCandidate, &lpPF[i].pfd, sizeof(PIXELFORMATDESCRIPTOR)); + + /* + ** Check attributes which must match + */ + if (ppfd->iPixelType != ppfdCandidate.iPixelType) { + continue; + } + + if (ppfd->iLayerType != ppfdCandidate.iLayerType) { + continue; + } + + if (((dwFlags ^ ppfdCandidate.dwFlags) & dwFlags) & + (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP | + PFD_SUPPORT_GDI | PFD_SUPPORT_OPENGL)) + { + continue; + } + + if (!(dwFlags & PFD_DOUBLEBUFFER_DONTCARE)) { + if ((dwFlags & PFD_DOUBLEBUFFER) != + (ppfdCandidate.dwFlags & PFD_DOUBLEBUFFER)) + { + continue; + } + } + +// if (!(dwFlags & PFD_STEREO_DONTCARE)) { + if ((dwFlags & PFD_STEREO) != + (ppfdCandidate.dwFlags & PFD_STEREO)) + { + continue; + } +// } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAlphaBits && !ppfdCandidate.cAlphaBits) { + continue; + } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAccumBits && !ppfdCandidate.cAccumBits) { + continue; + } + + if (ppfd->cDepthBits && !ppfdCandidate.cDepthBits) { + continue; + } + + if (ppfd->cStencilBits && !ppfdCandidate.cStencilBits) { + continue; + } + + if (ppfd->cAuxBuffers && !ppfdCandidate.cAuxBuffers) { + continue; + } + + /* + ** See if candidate is better than the previous best choice + */ + if (bestIndex == -1) { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if ((ppfd->cColorBits > ppfdBest.cColorBits && + ppfdCandidate.cColorBits > ppfdBest.cColorBits) || + (ppfd->cColorBits <= ppfdCandidate.cColorBits && + ppfdCandidate.cColorBits < ppfdBest.cColorBits)) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAlphaBits + && ppfdCandidate.cAlphaBits > ppfdBest.cAlphaBits) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->iPixelType==PFD_TYPE_RGBA + && ppfd->cAccumBits + && ppfdCandidate.cAccumBits > ppfdBest.cAccumBits) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if ((ppfd->cDepthBits > ppfdBest.cDepthBits && + ppfdCandidate.cDepthBits > ppfdBest.cDepthBits) || + (ppfd->cDepthBits <= ppfdCandidate.cDepthBits && + ppfdCandidate.cDepthBits < ppfdBest.cDepthBits)) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->cStencilBits && + ppfdCandidate.cStencilBits > ppfdBest.cStencilBits) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + + if (ppfd->cAuxBuffers && + ppfdCandidate.cAuxBuffers > ppfdBest.cAuxBuffers) + { + ppfdBest = ppfdCandidate; + bestIndex = i; + continue; + } + } + + if (bestIndex != -1) { + ddlogPrintf(DDLOG_SYSTEM, "Pixel Format %d chosen as best match", bestIndex+1); + return bestIndex + 1; + } + + // Return the pixelformat that has the most capabilities. + // ** NOTE: This is only possible due to the way the list + // of pixelformats is built. ** + // Now picks best pixelformat. KeithH + bestIndex = numPixelFormats; // most capable double buffer format + ddlogPrintf(DDLOG_SYSTEM, "Pixel Format %d chosen by default", bestIndex); + return (bestIndex); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(CopyContext)( + HGLRC a, + HGLRC b, + UINT c) +{ + // Validate license + if (!dglValidate()) + return FALSE; + UNSUPPORTED("wglCopyContext") + return FALSE; // Failed +} + +// *********************************************************************** + +HGLRC APIENTRY _GLD_WGL_EXPORT(CreateContext)( + HDC a) +{ + int ipf; + + // Validate license + if (!dglValidate()) + return 0; + + // Check that the current PFD is valid + ipf = dglGetPixelFormat(); + if (!IsValidPFD(ipf)) + return (HGLRC)0; + + return dglCreateContext(a, &glb.lpPF[ipf-1]); +} + +// *********************************************************************** + +HGLRC APIENTRY _GLD_WGL_EXPORT(CreateLayerContext)( + HDC a, + int b) +{ + // Validate license + if (!dglValidate()) + return 0; + + UNSUPPORTED("wglCreateLayerContext") + return NULL; // Failed +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(DeleteContext)( + HGLRC a) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglDeleteContext(a); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(DescribeLayerPlane)( + HDC hDC, + int iPixelFormat, + int iLayerPlane, + UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + UNSUPPORTED("DGL_DescribeLayerPlane") + +// gldLogPrintf(GLDLOG_INFO, "DescribeLayerPlane: %d, %d", iPixelFormat, iLayerPlane); + + return FALSE; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(DescribePixelFormat)( + HDC a, + int b, + UINT c, + LPPIXELFORMATDESCRIPTOR d) +{ + UINT nSize; + + // Validate license + if (!dglValidate()) + return 0; + + if (d == NULL) // Calling app requires max number of PF's + return glb.nPixelFormatCount; + + // The supplied buffer may be larger than the info that we + // will be copying. + if (c > sizeof(PIXELFORMATDESCRIPTOR)) + nSize = sizeof(PIXELFORMATDESCRIPTOR); + else + nSize = c; + + // Setup an empty PFD before doing validation check + memset(d, 0, nSize); + d->nSize = nSize; + d->nVersion = 1; + + if (!IsValidPFD(b)) + return 0; // Bail if PFD index is invalid + + memcpy(d, &glb.lpPF[b-1].pfd, nSize); + + return glb.nPixelFormatCount; +} + +// *********************************************************************** + +HGLRC APIENTRY _GLD_WGL_EXPORT(GetCurrentContext)(void) +{ + // Validate license + if (!dglValidate()) + return 0; + + return dglGetCurrentContext(); +} + +// *********************************************************************** + +HDC APIENTRY _GLD_WGL_EXPORT(GetCurrentDC)(void) +{ + // Validate license + if (!dglValidate()) + return 0; + + return dglGetCurrentDC(); +} + +// *********************************************************************** + +PROC APIENTRY _GLD_WGL_EXPORT(GetDefaultProcAddress)( + LPCSTR a) +{ + // Validate license + if (!dglValidate()) + return NULL; + + UNSUPPORTED("DGL_GetDefaultProcAddress") + return NULL; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(GetLayerPaletteEntries)( + HDC a, + int b, + int c, + int d, + COLORREF *e) +{ + // Validate license + if (!dglValidate()) + return 0; + + UNSUPPORTED("DGL_GetLayerPaletteEntries") + return 0; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(GetPixelFormat)( + HDC a) +{ + // Validate license + if (!dglValidate()) + return 0; + + return dglGetPixelFormat(); +} + +// *********************************************************************** + +PROC APIENTRY _GLD_WGL_EXPORT(GetProcAddress)( + LPCSTR a) +{ + PROC dglGetProcAddressD3D(LPCSTR a); + + // Validate license + if (!dglValidate()) + return NULL; + +#ifdef _USE_GLD3_WGL + return _gldDriver.wglGetProcAddress(a); +#else + return dglGetProcAddressD3D(a); +#endif +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(MakeCurrent)( + HDC a, + HGLRC b) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglMakeCurrent(a, b); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(RealizeLayerPalette)( + HDC a, + int b, + BOOL c) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + UNSUPPORTED("DGL_RealizeLayerPalette") + return FALSE; +} + +// *********************************************************************** + +int APIENTRY _GLD_WGL_EXPORT(SetLayerPaletteEntries)( + HDC a, + int b, + int c, + int d, + CONST COLORREF *e) +{ + // Validate license + if (!dglValidate()) + return 0; + + UNSUPPORTED("DGL_SetLayerPaletteEntries") + return 0; +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(SetPixelFormat)( + HDC a, + int b, + CONST PIXELFORMATDESCRIPTOR *c) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + if (IsValidPFD(b)) { + ddlogPrintf(DDLOG_SYSTEM, "SetPixelFormat: PixelFormat %d has been set", b); + dglSetPixelFormat(b); + return TRUE; + } else { + ddlogPrintf(DDLOG_ERROR, + "SetPixelFormat: PixelFormat %d is invalid and cannot be set", b); + return FALSE; + } +} + +// *********************************************************************** +/* + * Share lists between two gl_context structures. + * This was added for WIN32 WGL function support, since wglShareLists() + * must be called *after* wglCreateContext() with valid GLRCs. (DaveM) + */ +// +// Copied from GLD2.x. KeithH +// +static GLboolean _gldShareLists( + GLcontext *ctx1, + GLcontext *ctx2) +{ + /* Sanity check context pointers */ + if (ctx1 == NULL || ctx2 == NULL) + return GL_FALSE; + /* Sanity check shared list pointers */ + if (ctx1->Shared == NULL || ctx2->Shared == NULL) + return GL_FALSE; + /* Decrement reference count on sharee to release previous list */ + ctx2->Shared->RefCount--; +#if 0 /* 3DStudio exits on this memory release */ + if (ctx2->Shared->RefCount == 0) + free_shared_state(ctx2, ctx2->Shared); +#endif + /* Re-assign list from sharer to sharee and increment reference count */ + ctx2->Shared = ctx1->Shared; + ctx1->Shared->RefCount++; + return GL_TRUE; +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(ShareLists)( + HGLRC a, + HGLRC b) +{ + DGL_ctx *dgl1, *dgl2; + + // Validate license + if (!dglValidate()) + return FALSE; + + // Mesa supports shared lists, but you need to supply the shared + // GL context info when calling gl_create_context(). An auxiliary + // function gl_share_lists() has been added to update the shared + // list info after the GL contexts have been created. (DaveM) + dgl1 = dglGetContextAddress(a); + dgl2 = dglGetContextAddress(b); + if (dgl1->bAllocated && dgl2->bAllocated) { +#ifdef _USE_GLD3_WGL + return _gldShareLists(dgl1->glCtx, dgl2->glCtx); +#else + return (*mesaFuncs.gl_share_lists)(dgl1->glCtx, dgl2->glCtx); +#endif + } + return FALSE; +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(SwapBuffers)( + HDC a) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglSwapBuffers(a); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(SwapLayerBuffers)( + HDC a, + UINT b) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return dglSwapBuffers(a); +} + +// *********************************************************************** + +// *********************************************************************** +// Note: This ResizeBuffers() function may be called from +// either MESA glViewport() or GLD wglMakeCurrent(). + +BOOL dglWglResizeBuffers( + GLcontext *ctx, + BOOL bDefaultDriver) +{ + DGL_ctx *dgl = NULL; + RECT rcScreenRect; + DWORD dwWidth; + DWORD dwHeight; + DDSURFACEDESC2 ddsd2; + DDSCAPS2 ddscaps2; + IDirectDrawClipper *lpddClipper = NULL; + DWORD dwFlags; + HRESULT hResult; + + DWORD dwMemoryType; + + int i; + struct gl_texture_object *tObj; + struct gl_texture_image *image; + + BOOL bWasFullscreen; + BOOL bSaveDesktop; + BOOL bFullScrnWin = FALSE; + DDSURFACEDESC2 ddsd2DisplayMode; + + DDBLTFX ddbltfx; + POINT pt; + RECT rcDst; +#ifdef _USE_GLD3_WGL + GLD_displayMode glddm; +#endif + +#define DDLOG_CRITICAL_OR_WARN (bDefaultDriver ? DDLOG_WARN : DDLOG_CRITICAL) + + // Validate license + if (!dglValidate()) + return FALSE; + + // Sanity checks + if (ctx == NULL) + return FALSE; + dgl = ctx->DriverCtx; + if (dgl == NULL) + return FALSE; + + // Get the window size and calculate its dimensions + if (dgl->hWnd == NULL) { + // Check for non-window DC = memory DC ? + if (GetClipBox(dgl->hDC, &rcScreenRect) == ERROR) + SetRect(&rcScreenRect, 0, 0, 0, 0); + } + else if (!GetClientRect(dgl->hWnd, &rcScreenRect)) + SetRect(&rcScreenRect, 0, 0, 0, 0); + dwWidth = rcScreenRect.right - rcScreenRect.left; + dwHeight = rcScreenRect.bottom - rcScreenRect.top; + CopyRect(&dgl->rcScreenRect, &rcScreenRect); + + // This will occur on Alt-Tab + if ((dwWidth == 0) && (dwHeight == 0)) { + //dgl->bCanRender = FALSE; + return TRUE; // No resize possible! + } + + // Some apps zero only 1 dimension for non-visible window... (DaveM) + if ((dwWidth == 0) || (dwHeight == 0)) { + dwWidth = 8; + dwHeight = 8; + } + + // Test to see if a resize is required. + // Note that the dimensions will be the same if a prior resize attempt failed. + if ((dwWidth == dgl->dwWidth) && (dwHeight == dgl->dwHeight) && bDefaultDriver) { + return TRUE; // No resize required + } + + ddlogPrintf(DDLOG_SYSTEM, "dglResize: %dx%d", dwWidth, dwHeight); +#ifndef _USE_GLD3_WGL + // Work out where we want our surfaces created + dwMemoryType = (bDefaultDriver) ? glb.dwMemoryType : DDSCAPS_SYSTEMMEMORY; +#endif // _USE_GLD3_WGL + + // Note previous fullscreen vs window display status + bWasFullscreen = dgl->bFullscreen; + +#ifdef _USE_GLD3_WGL + if (_gldDriver.GetDisplayMode(dgl, &glddm)) { + if ( (dwWidth == glddm.Width) && + (dwHeight == glddm.Height) ) { + bFullScrnWin = TRUE; + } + if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) { + dgl->bFullscreen = TRUE; + ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n"); + } + else { + dgl->bFullscreen = FALSE; + ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n"); + } + // Cache the display mode dimensions + dgl->dwModeWidth = glddm.Width; + dgl->dwModeHeight = glddm.Height; + } + + // Clamp the effective window dimensions to primary surface. + // We need to do this for D3D viewport dimensions even if wide + // surfaces are supported. This also is a good idea for handling + // whacked-out window dimensions passed for non-drawable windows + // like Solid Edge. (DaveM) + if (dgl->dwWidth > glddm.Width) + dgl->dwWidth = glddm.Width; + if (dgl->dwHeight > glddm.Height) + dgl->dwHeight = glddm.Height; +#else // _USE_GLD3_WGL + // Window resize may have changed to fullscreen + ZeroMemory(&ddsd2DisplayMode, sizeof(ddsd2DisplayMode)); + ddsd2DisplayMode.dwSize = sizeof(ddsd2DisplayMode); + hResult = IDirectDraw4_GetDisplayMode( + dgl->lpDD4, + &ddsd2DisplayMode); + if (SUCCEEDED(hResult)) { + if ( (dwWidth == ddsd2DisplayMode.dwWidth) && + (dwHeight == ddsd2DisplayMode.dwHeight) ) { + bFullScrnWin = TRUE; + } + if (bFullScrnWin && glb.bPrimary && !glb.bFullscreenBlit && !glb.bDirectDrawPersistant) { + dgl->bFullscreen = TRUE; + ddlogMessage(DDLOG_INFO, "Fullscreen window after resize.\n"); + } + else { + dgl->bFullscreen = FALSE; + ddlogMessage(DDLOG_INFO, "Non-Fullscreen window after resize.\n"); + } + // Cache the display mode dimensions + dgl->dwModeWidth = ddsd2DisplayMode.dwWidth; + dgl->dwModeHeight = ddsd2DisplayMode.dwHeight; + } + + // Clamp the effective window dimensions to primary surface. + // We need to do this for D3D viewport dimensions even if wide + // surfaces are supported. This also is a good idea for handling + // whacked-out window dimensions passed for non-drawable windows + // like Solid Edge. (DaveM) + if (dgl->dwWidth > ddsd2DisplayMode.dwWidth) + dgl->dwWidth = ddsd2DisplayMode.dwWidth; + if (dgl->dwHeight > ddsd2DisplayMode.dwHeight) + dgl->dwHeight = ddsd2DisplayMode.dwHeight; +#endif // _USE_GLD3_WGL + + // Note if fullscreen vs window display has changed? + bSaveDesktop = (!bWasFullscreen && !dgl->bFullscreen) ? TRUE : FALSE; + // Save the desktop primary surface from being destroyed + // whenever remaining in windowed mode, since the stereo mode + // switches are expensive... + +#ifndef _USE_GLD3_WGL + // Don't need to re-allocate persistant buffers. (DaveM) + // Though we should clear the back buffers to hide artifacts. + if (glb.bDirectDrawPersistant && glb.bPersistantBuffers) { + dgl->dwWidth = dwWidth; + dgl->dwHeight = dwHeight; + ZeroMemory(&ddbltfx, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = dgl->dwClearColorPF; + IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL, + DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + return TRUE; + } + + // Ensure all rendering is complete + if (ctx->Driver.Finish) + (*ctx->Driver.Finish)(ctx); + if (dgl->bSceneStarted == TRUE) { + IDirect3DDevice3_EndScene(dgl->lpDev3); + dgl->bSceneStarted = FALSE; + } +#endif // _USE_GLD3_WGL + dgl->bCanRender = FALSE; + +#ifdef GLD_THREADS + // Serialize access to DirectDraw and DDS operations + if (glb.bMultiThreaded) + EnterCriticalSection(&CriticalSection); +#endif + +#ifndef _USE_GLD3_WGL + // Release existing surfaces + RELEASE(dgl->lpDev3); + RELEASE(dgl->lpDepth4); + RELEASE(dgl->lpBack4); + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) + ; + else + RELEASE(dgl->lpFront4); +#endif // _USE_GLD3_WGL + dgl->dwWidth = dwWidth; + dgl->dwHeight = dwHeight; + + // Set defaults + dgl->dwModeWidth = dgl->dwWidth; + dgl->dwModeHeight = dgl->dwHeight; + +#ifdef _USE_GLD3_WGL + if (!_gldDriver.ResizeDrawable(dgl, bDefaultDriver, glb.bDirectDrawPersistant, glb.bPersistantBuffers)) + goto cleanup_and_return_with_error; +#else // _USE_GLD3_WGL + + if (dgl->bFullscreen) { + // + // FULLSCREEN + // + + // Disable warning popups when in fullscreen mode + ddlogWarnOption(FALSE); + + // Have to release the persistant DirectDraw primary surface + // if switching to fullscreen mode. So if application wants + // persistant display in fullscreen mode, a fullscreen-size + // window should be used instead via fullscreen-blit option. + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) { + RELEASE(glb.lpPrimary4); + glb.bDirectDrawPrimary = FALSE; + } + + dwFlags = DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // optional + hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4, dgl->hWnd, dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Exclusive Fullscreen mode", hResult); + goto cleanup_and_return_with_error; + } + + hResult = IDirectDraw4_SetDisplayMode(dgl->lpDD4, + dgl->dwModeWidth, + dgl->dwModeHeight, + dgl->dwBPP, + 0, + 0); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetDisplayMode failed", hResult); + goto cleanup_and_return_with_error; + } + + // ** The display mode has changed, so dont use MessageBox! ** + + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + + if (dgl->bDoubleBuffer) { + // Double buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + DDSCAPS_FLIP | + DDSCAPS_COMPLEX | + DDSCAPS_3DDEVICE | + dwMemoryType; + ddsd2.dwBackBufferCount = 1; + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult); + goto cleanup_and_return_with_error; + } + // Render target surface + ZeroMemory(&ddscaps2, sizeof(ddscaps2)); // Clear the entire struct. + ddscaps2.dwCaps = DDSCAPS_BACKBUFFER; + hResult = IDirectDrawSurface4_GetAttachedSurface(dgl->lpFront4, &ddscaps2, &dgl->lpBack4); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: GetAttachedSurface failed", hResult); + goto cleanup_and_return_with_error; + } + } else { + // Single buffered + // Primary surface + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | + //DDSCAPS_3DDEVICE | + dwMemoryType; + + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult); + goto cleanup_and_return_with_error; + } + + dgl->lpBack4 = NULL; + } + } else { + // WINDOWED + + // OK to enable warning popups in windowed mode + ddlogWarnOption(glb.bMessageBoxWarnings); + + // Ditto if persistant DirectDraw primary + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) + goto DoClipperOnly; + + // WINDOWED + dwFlags = DDSCL_NORMAL; + if (glb.bMultiThreaded) + dwFlags |= DDSCL_MULTITHREADED; + if (glb.bFastFPU) + dwFlags |= DDSCL_FPUSETUP; // optional + hResult = IDirectDraw4_SetCooperativeLevel(dgl->lpDD4, + dgl->hWnd, + dwFlags); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Unable to set Normal coop level", hResult); + goto cleanup_and_return_with_error; + } + // Primary surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS; + ddsd2.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpFront4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (primary) failed", hResult); + goto cleanup_and_return_with_error; + } + + // Cache the primary surface for persistant DirectDraw state + if (glb.bDirectDrawPersistant && !glb.bDirectDrawPrimary) { + glb.lpPrimary4 = dgl->lpFront4; + IDirectDrawSurface4_AddRef(glb.lpPrimary4); + glb.bDirectDrawPrimary = TRUE; + } + + // Clipper object + hResult = DirectDrawCreateClipper(0, &lpddClipper, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateClipper failed", hResult); + goto cleanup_and_return_with_error; + } + hResult = IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd); + if (FAILED(hResult)) { + RELEASE(lpddClipper); + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetHWnd failed", hResult); + goto cleanup_and_return_with_error; + } + hResult = IDirectDrawSurface4_SetClipper(dgl->lpFront4, lpddClipper); + RELEASE(lpddClipper); // We have finished with it. + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetClipper failed", hResult); + goto cleanup_and_return_with_error; + } +DoClipperOnly: + // Update the window for the original clipper + if ((glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) || bSaveDesktop) { + IDirectDrawSurface4_GetClipper(dgl->lpFront4, &lpddClipper); + IDirectDrawClipper_SetHWnd(lpddClipper, 0, dgl->hWnd); + RELEASE(lpddClipper); + } + + if (dgl->bDoubleBuffer) { + // Render target surface + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd2.dwWidth = dgl->dwWidth; + ddsd2.dwHeight = dgl->dwHeight; + ddsd2.ddsCaps.dwCaps = DDSCAPS_3DDEVICE | + DDSCAPS_OFFSCREENPLAIN | + dwMemoryType; + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpBack4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Create Backbuffer failed", hResult); + goto cleanup_and_return_with_error; + } + + } else { + dgl->lpBack4 = NULL; + } + } + + // + // Now create the Zbuffer + // + if (dgl->bDepthBuffer) { + // Get z-buffer dimensions from the render target + // Setup the surface desc for the z-buffer. + ZeroMemory(&ddsd2, sizeof(ddsd2)); + ddsd2.dwSize = sizeof(ddsd2); + ddsd2.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; + ddsd2.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | dwMemoryType; + ddsd2.dwWidth = dgl->dwWidth; + ddsd2.dwHeight = dgl->dwHeight; + memcpy(&ddsd2.ddpfPixelFormat, + &glb.lpZBufferPF[dgl->iZBufferPF], + sizeof(DDPIXELFORMAT) ); + + // Create a z-buffer + hResult = IDirectDraw4_CreateSurface(dgl->lpDD4, &ddsd2, &dgl->lpDepth4, NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: CreateSurface (ZBuffer) failed", hResult); + goto cleanup_and_return_with_error; + } + + // Attach Zbuffer to render target + TRY(IDirectDrawSurface4_AddAttachedSurface( + dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4, + dgl->lpDepth4), + "dglResize: Attach Zbuffer"); + + } + + // Clear the newly resized back buffers for the window client area. + ZeroMemory(&ddbltfx, sizeof(ddbltfx)); + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = dgl->dwClearColorPF; + IDirectDrawSurface4_Blt(dgl->lpBack4, &rcScreenRect, NULL, NULL, + DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + + // + // Now that we have a zbuffer we can create the 3D device + // + hResult = IDirect3D3_CreateDevice(dgl->lpD3D3, + bDefaultDriver ? &glb.d3dGuid : &IID_IDirect3DRGBDevice, + dgl->bDoubleBuffer ? dgl->lpBack4 : dgl->lpFront4, + &dgl->lpDev3, + NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: Could not create Direct3D device", hResult); + goto cleanup_and_return_with_error; + } + + // We must do this as soon as the device is created + dglInitStateCaches(dgl); + + // + // Viewport + // + hResult = IDirect3DDevice3_AddViewport(dgl->lpDev3, dgl->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: AddViewport failed", hResult); + goto cleanup_and_return_with_error; + } + + // Initialise the viewport + dgl->d3dViewport.dwSize = sizeof(dgl->d3dViewport); + dgl->d3dViewport.dwX = 0; + dgl->d3dViewport.dwY = 0; + dgl->d3dViewport.dwWidth = dgl->dwWidth; + dgl->d3dViewport.dwHeight = dgl->dwHeight; + dgl->d3dViewport.dvClipX = 0; + dgl->d3dViewport.dvClipY = 0; + dgl->d3dViewport.dvClipWidth = dgl->dwWidth; + dgl->d3dViewport.dvClipHeight = dgl->dwHeight; +// dgl->d3dViewport.dvMinZ = 0.0f; +// dgl->d3dViewport.dvMaxZ = 1.0f; + TRY(IDirect3DViewport3_SetViewport2(dgl->lpViewport3, &dgl->d3dViewport), + "dglResize: SetViewport2"); + + hResult = IDirect3DDevice3_SetCurrentViewport(dgl->lpDev3, dgl->lpViewport3); + if (FAILED(hResult)) { + ddlogError(DDLOG_CRITICAL_OR_WARN, "dglResize: SetCurrentViewport failed", hResult); + goto cleanup_and_return_with_error; + } + + // (Re)Initialise all the Direct3D renderstates + dglInitStateD3D(ctx); + + // Now we have to recreate all of our textures (+ mipmaps). + // Walk over all textures in hash table + // XXX what about the default texture objects (id=0)? + { + struct _mesa_HashTable *textures = ctx->Shared->TexObjects; + GLuint id; + for (id = _mesa_HashFirstEntry(textures); + id; + id = _mesa_HashNextEntry(textures, id)) { + tObj = (struct gl_texture_object *) _mesa_HashLookup(textures, id); + if (tObj->DriverData) { + // We could call our TexImage function directly, but it's + // safer to use the driver pointer. + for (i=0; i<MAX_TEXTURE_LEVELS; i++) { + image = tObj->Image[i]; + if (image) { + switch (tObj->Dimensions){ + case 1: + if (ctx->Driver.TexImage) + (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_1D, tObj, i, image->Format, image); + break; + case 2: + if (ctx->Driver.TexImage) + (*ctx->Driver.TexImage)(ctx, GL_TEXTURE_2D, tObj, i, image->Format, image); + break; + default: + break; + } + } + } + } + } + } + + // Re-Bind each texture Unit + for (i=0; i<glb.wMaxSimultaneousTextures; i++) { + tObj = ctx->Texture.Unit[i].Current; + if (tObj) { + DGL_texture *lpTex = (DGL_texture *)tObj->DriverData; + hResult = dglSetTexture(dgl, i, lpTex ? lpTex->lpTexture : NULL); + if (FAILED(hResult)) { + ddlogError(DDLOG_ERROR, "dglResize: SetTexture failed", hResult); + } + } + } +#endif // _USE_GLD3_WGL + + dgl->bCanRender = TRUE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + // SUCCESS. + return TRUE; + +cleanup_and_return_with_error: + // Relase all interfaces before returning. +#ifdef _USE_GLD3_WGL + _gldDriver.DestroyDrawable(dgl); +#else // _USE_GLD3_WGL + RELEASE(dgl->lpDev3); + RELEASE(dgl->lpDepth4); + RELEASE(dgl->lpBack4); + if (glb.bDirectDrawPersistant && glb.bDirectDrawPrimary) + ; + else + RELEASE(dgl->lpFront4); + +#undef DDLOG_CRITICAL_OR_WARN +#endif // _USE_GLD3_WGL + + // Mark context as not being able to render + dgl->bCanRender = FALSE; + +#ifdef GLD_THREADS + // Release serialized access + if (glb.bMultiThreaded) + LeaveCriticalSection(&CriticalSection); +#endif + + return FALSE; +} + +// *********************************************************************** +// *********************************************************************** +// Support for bitmap fonts. +// *********************************************************************** +// *********************************************************************** + +/***************************************************************************** +** +** InvertGlyphBitmap. +** +** Invert the bitmap so that it suits OpenGL's representation. +** Each row starts on a double word boundary. +** +*****************************************************************************/ + +static void InvertGlyphBitmap( + int w, + int h, + DWORD *fptr, + DWORD *tptr) +{ + int dWordsInRow = (w+31)/32; + int i, j; + DWORD *tmp = tptr; + + if (w <= 0 || h <= 0) { + return; + } + + tptr += ((h-1)*dWordsInRow); + for (i = 0; i < h; i++) { + for (j = 0; j < dWordsInRow; j++) { + *(tptr + j) = *(fptr + j); + } + tptr -= dWordsInRow; + fptr += dWordsInRow; + } +} + +// *********************************************************************** + +/***************************************************************************** + * wglUseFontBitmaps + * + * Converts a subrange of the glyphs in a GDI font to OpenGL display + * lists. + * + * Extended to support any GDI font, not just TrueType fonts. (DaveM) + * + *****************************************************************************/ + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsA)( + HDC hDC, + DWORD first, + DWORD count, + DWORD listBase) +{ + int i, ox, oy, ix, iy; + int w, h; + int iBufSize, iCurBufSize = 0; + DWORD *bitmapBuffer = NULL; + DWORD *invertedBitmapBuffer = NULL; + BOOL bSuccessOrFail = TRUE; + BOOL bTrueType = FALSE; + TEXTMETRIC tm; + GLYPHMETRICS gm; + RASTERIZER_STATUS rs; + MAT2 mat; + SIZE size; + RECT rect; + HDC hDCMem; + HBITMAP hBitmap; + BITMAPINFO bmi; + HFONT hFont; + + // Validate SciTech DirectGL license + if (!dglValidate()) + return FALSE; + + // Set up a unity matrix. + ZeroMemory(&mat, sizeof(mat)); + mat.eM11.value = 1; + mat.eM22.value = 1; + + // Test to see if selected font is TrueType or not + ZeroMemory(&tm, sizeof(tm)); + if (!GetTextMetrics(hDC, &tm)) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Font metrics error\n"); + return (FALSE); + } + bTrueType = (tm.tmPitchAndFamily & TMPF_TRUETYPE) ? TRUE : FALSE; + + // Test to see if TRUE-TYPE capabilities are installed + // (only necessary if TrueType font selected) + ZeroMemory(&rs, sizeof(rs)); + if (bTrueType) { + if (!GetRasterizerCaps (&rs, sizeof (RASTERIZER_STATUS))) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Raster caps error\n"); + return (FALSE); + } + if (!(rs.wFlags & TT_ENABLED)) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: No TrueType caps\n"); + return (FALSE); + } + } + + // Trick to get the current font handle + hFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT)); + SelectObject(hDC, hFont); + + // Have memory device context available for holding bitmaps of font glyphs + hDCMem = CreateCompatibleDC(hDC); + SelectObject(hDCMem, hFont); + SetTextColor(hDCMem, RGB(0xFF, 0xFF, 0xFF)); + SetBkColor(hDCMem, 0); + + for (i = first; (DWORD) i < (first + count); i++) { + // Find out how much space is needed for the bitmap so we can + // Set the buffer size correctly. + if (bTrueType) { + // Use TrueType support to get bitmap size of glyph + iBufSize = GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, + 0, NULL, &mat); + if (iBufSize == GDI_ERROR) { + bSuccessOrFail = FALSE; + break; + } + } + else { + // Use generic GDI support to compute bitmap size of glyph + w = tm.tmMaxCharWidth; + h = tm.tmHeight; + if (GetTextExtentPoint32(hDC, (LPCTSTR)&i, 1, &size)) { + w = size.cx; + h = size.cy; + } + iBufSize = w * h; + // Use DWORD multiple for compatibility + iBufSize += 3; + iBufSize /= 4; + iBufSize *= 4; + } + + // If we need to allocate Larger Buffers, then do so - but allocate + // An extra 50 % so that we don't do too many mallocs ! + if (iBufSize > iCurBufSize) { + if (bitmapBuffer) { + __wglFree(bitmapBuffer); + } + if (invertedBitmapBuffer) { + __wglFree(invertedBitmapBuffer); + } + + iCurBufSize = iBufSize * 2; + bitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize); + invertedBitmapBuffer = (DWORD *) __wglMalloc(iCurBufSize); + + if (bitmapBuffer == NULL || invertedBitmapBuffer == NULL) { + bSuccessOrFail = FALSE; + break; + } + } + + // If we fail to get the Glyph data, delete the display lists + // Created so far and return FALSE. + if (bTrueType) { + // Use TrueType support to get bitmap of glyph + if (GetGlyphOutline(hDC, i, GGO_BITMAP, &gm, + iBufSize, bitmapBuffer, &mat) == GDI_ERROR) { + bSuccessOrFail = FALSE; + break; + } + + // Setup glBitmap parameters for current font glyph + w = gm.gmBlackBoxX; + h = gm.gmBlackBoxY; + ox = gm.gmptGlyphOrigin.x; + oy = gm.gmptGlyphOrigin.y; + ix = gm.gmCellIncX; + iy = gm.gmCellIncY; + } + else { + // Use generic GDI support to create bitmap of glyph + ZeroMemory(bitmapBuffer, iBufSize); + + if (i >= tm.tmFirstChar && i <= tm.tmLastChar) { + // Only create bitmaps for actual font glyphs + hBitmap = CreateBitmap(w, h, 1, 1, NULL); + SelectObject(hDCMem, hBitmap); + // Make bitmap of current font glyph + SetRect(&rect, 0, 0, w, h); + DrawText(hDCMem, (LPCTSTR)&i, 1, &rect, + DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_NOCLIP); + // Make copy of bitmap in our local buffer + ZeroMemory(&bmi, sizeof(bmi)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = w; + bmi.bmiHeader.biHeight = -h; + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 1; + bmi.bmiHeader.biCompression = BI_RGB; + GetDIBits(hDCMem, hBitmap, 0, h, bitmapBuffer, &bmi, 0); + DeleteObject(hBitmap); + } + else { + // Otherwise use empty display list for non-existing glyph + iBufSize = 0; + } + + // Setup glBitmap parameters for current font glyph + ox = 0; + oy = tm.tmDescent; + ix = w; + iy = 0; + } + + // Create an OpenGL display list. + _GLD_glNewList((listBase + i), GL_COMPILE); + + // Some fonts have no data for the space character, yet advertise + // a non-zero size. + if (0 == iBufSize) { + _GLD_glBitmap(0, 0, 0.0f, 0.0f, (GLfloat) ix, (GLfloat) iy, NULL); + } else { + // Invert the Glyph data. + InvertGlyphBitmap(w, h, bitmapBuffer, invertedBitmapBuffer); + + // Render an OpenGL bitmap and invert the origin. + _GLD_glBitmap(w, h, + (GLfloat) ox, (GLfloat) (h-oy), + (GLfloat) ix, (GLfloat) iy, + (GLubyte *) invertedBitmapBuffer); + } + + // Close this display list. + _GLD_glEndList(); + } + + if (bSuccessOrFail == FALSE) { + ddlogMessage(DDLOG_ERROR, "DGL_UseFontBitmaps: Get glyph failed\n"); + _GLD_glDeleteLists((i+listBase), (i-first)); + } + + // Release resources used + DeleteObject(hFont); + DeleteDC(hDCMem); + + if (bitmapBuffer) + __wglFree(bitmapBuffer); + if (invertedBitmapBuffer) + __wglFree(invertedBitmapBuffer); + + return(bSuccessOrFail); +} + +// *********************************************************************** + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontBitmapsW)( + HDC a, + DWORD b, + DWORD c, + DWORD d) +{ + // Validate license + if (!dglValidate()) + return FALSE; + + return _GLD_WGL_EXPORT(UseFontBitmapsA)(a, b, c, d); +} + +// *********************************************************************** +// *********************************************************************** +// Support for outline TrueType fonts. +// *********************************************************************** +// *********************************************************************** + +void * __wglRealloc( + void *oldPtr, + size_t newSize) +{ + void *newPtr = NULL; + + if (newSize != 0) { + newPtr = (void *) GlobalAlloc(GPTR, newSize); + if (oldPtr && newPtr) { + DWORD oldSize = GlobalSize(oldPtr); + + memcpy(newPtr, oldPtr, (oldSize <= newSize ? oldSize : newSize)); + GlobalFree(oldPtr); + } + } else if (oldPtr) { + GlobalFree(oldPtr); + } + if (newPtr == NULL) { + return NULL; /* XXX out of memory error */ + } + return newPtr; +} + +// *********************************************************************** + + +/***************************************************************************** + * wglUseFontOutlinesW + * + * Converts a subrange of the glyphs in a TrueType font to OpenGL display + * lists. + *****************************************************************************/ + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesW)( + IN HDC hDC, + IN DWORD first, + IN DWORD count, + IN DWORD listBase, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format, + OUT LPGLYPHMETRICSFLOAT lpgmf) +{ + return _GLD_WGL_EXPORT(UseFontOutlinesA)(hDC, first, count, listBase, + chordalDeviation, extrusion, format, lpgmf); +} + +/***************************************************************************** + * wglUseFontOutlinesA + * + * Converts a subrange of the glyphs in a TrueType font to OpenGL display + * lists. + *****************************************************************************/ + +BOOL APIENTRY _GLD_WGL_EXPORT(UseFontOutlinesA)( + IN HDC hDC, + IN DWORD first, + IN DWORD count, + IN DWORD listBase, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format, + OUT LPGLYPHMETRICSFLOAT glyphMetricsFloatArray) + { + DWORD glyphIndex; + UCHAR* glyphBuf; + DWORD glyphBufSize; + + + /* + * Flush any previous OpenGL errors. This allows us to check for + * new errors so they can be reported via the function return value. + */ + while (_GLD_glGetError() != GL_NO_ERROR) + ; + + /* + * Make sure that the current font can be sampled accurately. + */ + hNewFont = CreateHighResolutionFont(hDC); + if (!hNewFont) + return FALSE; + + hOldFont = SelectObject(hDC, hNewFont); + if (!hOldFont) + return FALSE; + + /* + * Preallocate a buffer for the outline data, and track its size: + */ + glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = 10240); + if (!glyphBuf) + return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ + + /* + * Process each glyph in the given range: + */ + for (glyphIndex = first; glyphIndex - first < count; ++glyphIndex) + { + GLYPHMETRICS glyphMetrics; + DWORD glyphSize; + static MAT2 matrix = + { + {0, 1}, {0, 0}, + {0, 0}, {0, 1} + }; + LPGLYPHMETRICSFLOAT glyphMetricsFloat = + &glyphMetricsFloatArray[glyphIndex - first]; + + + /* + * Determine how much space is needed to store the glyph's + * outlines. If our glyph buffer isn't large enough, + * resize it. + */ + glyphSize = GetGlyphOutline( hDC, + glyphIndex, + GGO_NATIVE, + &glyphMetrics, + 0, + NULL, + &matrix + ); + if (glyphSize < 0) + return FALSE; /*WGL_STATUS_FAILURE*/ + if (glyphSize > glyphBufSize) + { + __wglFree(glyphBuf); + glyphBuf = (UCHAR*) __wglMalloc(glyphBufSize = glyphSize); + if (!glyphBuf) + return FALSE; /*WGL_STATUS_NOT_ENOUGH_MEMORY*/ + } + + + /* + * Get the glyph's outlines. + */ + if (GetGlyphOutline( hDC, + glyphIndex, + GGO_NATIVE, + &glyphMetrics, + glyphBufSize, + glyphBuf, + &matrix + ) < 0) + { + __wglFree(glyphBuf); + return FALSE; /*WGL_STATUS_FAILURE*/ + } + + glyphMetricsFloat->gmfBlackBoxX = + (FLOAT) glyphMetrics.gmBlackBoxX * ScaleFactor; + glyphMetricsFloat->gmfBlackBoxY = + (FLOAT) glyphMetrics.gmBlackBoxY * ScaleFactor; + glyphMetricsFloat->gmfptGlyphOrigin.x = + (FLOAT) glyphMetrics.gmptGlyphOrigin.x * ScaleFactor; + glyphMetricsFloat->gmfptGlyphOrigin.y = + (FLOAT) glyphMetrics.gmptGlyphOrigin.y * ScaleFactor; + glyphMetricsFloat->gmfCellIncX = + (FLOAT) glyphMetrics.gmCellIncX * ScaleFactor; + glyphMetricsFloat->gmfCellIncY = + (FLOAT) glyphMetrics.gmCellIncY * ScaleFactor; + + /* + * Turn the glyph into a display list: + */ + if (!MakeDisplayListFromGlyph( (glyphIndex - first) + listBase, + glyphBuf, + glyphSize, + glyphMetricsFloat, + chordalDeviation + ScaleFactor, + extrusion, + format)) + { + __wglFree(glyphBuf); + return FALSE; /*WGL_STATUS_FAILURE*/ + } + } + + + /* + * Clean up temporary storage and return. If an error occurred, + * clear all OpenGL error flags and return FAILURE status; + * otherwise just return SUCCESS. + */ + __wglFree(glyphBuf); + + SelectObject(hDC, hOldFont); + + if (_GLD_glGetError() == GL_NO_ERROR) + return TRUE; /*WGL_STATUS_SUCCESS*/ + else + { + while (_GLD_glGetError() != GL_NO_ERROR) + ; + return FALSE; /*WGL_STATUS_FAILURE*/ + } + } + + + +/***************************************************************************** + * CreateHighResolutionFont + * + * Gets metrics for the current font and creates an equivalent font + * scaled to the design units of the font. + * + *****************************************************************************/ + +static HFONT +CreateHighResolutionFont(HDC hDC) + { + UINT otmSize; + OUTLINETEXTMETRIC *otm; + LONG fontHeight, fontWidth, fontUnits; + LOGFONT logFont; + + otmSize = GetOutlineTextMetrics(hDC, 0, NULL); + if (otmSize == 0) + return NULL; + + otm = (OUTLINETEXTMETRIC *) __wglMalloc(otmSize); + if (otm == NULL) + return NULL; + + otm->otmSize = otmSize; + if (GetOutlineTextMetrics(hDC, otmSize, otm) == 0) + return NULL; + + fontHeight = otm->otmTextMetrics.tmHeight - + otm->otmTextMetrics.tmInternalLeading; + fontWidth = otm->otmTextMetrics.tmAveCharWidth; + fontUnits = (LONG) otm->otmEMSquare; + + ScaleFactor = 1.0F / (FLOAT) fontUnits; + + logFont.lfHeight = - ((LONG) fontUnits); + logFont.lfWidth = (LONG) + ((FLOAT) (fontWidth * fontUnits) / (FLOAT) fontHeight); + logFont.lfEscapement = 0; + logFont.lfOrientation = 0; + logFont.lfWeight = otm->otmTextMetrics.tmWeight; + logFont.lfItalic = otm->otmTextMetrics.tmItalic; + logFont.lfUnderline = otm->otmTextMetrics.tmUnderlined; + logFont.lfStrikeOut = otm->otmTextMetrics.tmStruckOut; + logFont.lfCharSet = otm->otmTextMetrics.tmCharSet; + logFont.lfOutPrecision = OUT_OUTLINE_PRECIS; + logFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + logFont.lfQuality = DEFAULT_QUALITY; + logFont.lfPitchAndFamily = + otm->otmTextMetrics.tmPitchAndFamily & 0xf0; + strcpy(logFont.lfFaceName, + (char *)otm + (int)otm->otmpFaceName); + + hNewFont = CreateFontIndirect(&logFont); + if (hNewFont == NULL) + return NULL; + + __wglFree(otm); + + return hNewFont; + } + + + +/***************************************************************************** + * MakeDisplayListFromGlyph + * + * Converts the outline of a glyph to an OpenGL display list. + * + * Return value is nonzero for success, zero for failure. + * + * Does not check for OpenGL errors, so if the caller needs to know about them, + * it should call glGetError(). + *****************************************************************************/ + +static int +MakeDisplayListFromGlyph( IN DWORD listName, + IN UCHAR* glyphBuf, + IN DWORD glyphSize, + IN LPGLYPHMETRICSFLOAT glyphMetricsFloat, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format) + { + int status; + + _GLD_glNewList(listName, GL_COMPILE); + status = DrawGlyph( glyphBuf, + glyphSize, + chordalDeviation, + extrusion, + format); + + _GLD_glTranslatef(glyphMetricsFloat->gmfCellIncX, + glyphMetricsFloat->gmfCellIncY, + 0.0F); + _GLD_glEndList(); + + return status; + } + + + +/***************************************************************************** + * DrawGlyph + * + * Converts the outline of a glyph to OpenGL drawing primitives, tessellating + * as needed, and then draws the glyph. Tessellation of the quadratic splines + * in the outline is controlled by "chordalDeviation", and the drawing + * primitives (lines or polygons) are selected by "format". + * + * Return value is nonzero for success, zero for failure. + * + * Does not check for OpenGL errors, so if the caller needs to know about them, + * it should call glGetError(). + *****************************************************************************/ + +static int +DrawGlyph( IN UCHAR* glyphBuf, + IN DWORD glyphSize, + IN FLOAT chordalDeviation, + IN FLOAT extrusion, + IN INT format) + { + INT status = 0; + FLOAT* p; + DWORD loop; + DWORD point; + GLUtesselator* tess = NULL; + + + /* + * Initialize the global buffer into which we place the outlines: + */ + if (!InitLineBuf()) + goto exit; + + + /* + * Convert the glyph outlines to a set of polyline loops. + * (See MakeLinesFromGlyph() for the format of the loop data + * structure.) + */ + if (!MakeLinesFromGlyph(glyphBuf, glyphSize, chordalDeviation)) + goto exit; + p = LineBuf; + + + /* + * Now draw the loops in the appropriate format: + */ + if (format == WGL_FONT_LINES) + { + /* + * This is the easy case. Just draw the outlines. + */ + for (loop = (DWORD) *p++; loop; --loop) + { + _GLD_glBegin(GL_LINE_LOOP); + for (point = (DWORD) *p++; point; --point) + { + _GLD_glVertex2fv(p); + p += 2; + } + _GLD_glEnd(); + } + status = 1; + } + + else if (format == WGL_FONT_POLYGONS) + { + double v[3]; + FLOAT *save_p = p; + GLfloat z_value; + + /* + * This is the hard case. We have to set up a tessellator + * to convert the outlines into a set of polygonal + * primitives, which the tessellator passes to some + * auxiliary routines for drawing. + */ + if (!LoadGLUTesselator()) + goto exit; + if (!InitVertBuf()) + goto exit; + if (!(tess = gluNewTessProc())) + goto exit; + gluTessCallbackProc(tess, GLU_BEGIN, (void(CALLBACK *)()) _GLD_glBegin); + gluTessCallbackProc(tess, GLU_TESS_VERTEX_DATA, + (void(CALLBACK *)()) TessVertexOutData); + gluTessCallbackProc(tess, GLU_END, (void(CALLBACK *)()) _GLD_glEnd); + gluTessCallbackProc(tess, GLU_ERROR, (void(CALLBACK *)()) TessError); + gluTessCallbackProc(tess, GLU_TESS_COMBINE, (void(CALLBACK *)()) TessCombine); + gluTessNormalProc(tess, 0.0F, 0.0F, 1.0F); + + TessErrorOccurred = 0; + _GLD_glNormal3f(0.0f, 0.0f, 1.0f); + v[2] = 0.0; + z_value = 0.0f; + + gluTessBeginPolygonProc(tess, (void *)*(int *)&z_value); + for (loop = (DWORD) *p++; loop; --loop) + { + gluTessBeginContourProc(tess); + + for (point = (DWORD) *p++; point; --point) + { + v[0] = p[0]; + v[1] = p[1]; + gluTessVertexProc(tess, v, p); + p += 2; + } + + gluTessEndContourProc(tess); + } + gluTessEndPolygonProc(tess); + + status = !TessErrorOccurred; + + /* Extrusion code */ + if (extrusion) { + DWORD loops; + GLfloat thickness = (GLfloat) -extrusion; + FLOAT *vert, *vert2; + DWORD count; + + p = save_p; + loops = (DWORD) *p++; + + for (loop = 0; loop < loops; loop++) { + GLfloat dx, dy, len; + DWORD last; + + count = (DWORD) *p++; + _GLD_glBegin(GL_QUAD_STRIP); + + /* Check if the first and last vertex are identical + * so we don't draw the same quad twice. + */ + vert = p + (count-1)*2; + last = (p[0] == vert[0] && p[1] == vert[1]) ? count-1 : count; + + for (point = 0; point <= last; point++) { + vert = p + 2 * (point % last); + vert2 = p + 2 * ((point+1) % last); + + dx = vert[0] - vert2[0]; + dy = vert[1] - vert2[1]; + len = (GLfloat)sqrt(dx * dx + dy * dy); + + _GLD_glNormal3f(dy / len, -dx / len, 0.0f); + _GLD_glVertex3f((GLfloat) vert[0], + (GLfloat) vert[1], thickness); + _GLD_glVertex3f((GLfloat) vert[0], + (GLfloat) vert[1], 0.0f); + } + + _GLD_glEnd(); + p += count*2; + } + + /* Draw the back face */ + p = save_p; + v[2] = thickness; + _GLD_glNormal3f(0.0f, 0.0f, -1.0f); + gluTessNormalProc(tess, 0.0F, 0.0F, -1.0F); + + gluTessBeginPolygonProc(tess, (void *)*(int *)&thickness); + + for (loop = (DWORD) *p++; loop; --loop) + { + count = (DWORD) *p++; + + gluTessBeginContourProc(tess); + + for (point = 0; point < count; point++) + { + vert = p + ((count-point-1)<<1); + v[0] = vert[0]; + v[1] = vert[1]; + gluTessVertexProc(tess, v, vert); + } + p += count*2; + + gluTessEndContourProc(tess); + } + gluTessEndPolygonProc(tess); + } + +#if DEBUG + if (TessErrorOccurred) + printf("Tessellation error %s\n", + gluErrorString(TessErrorOccurred)); +#endif + } + + +exit: + FreeLineBuf(); + if (tess) + gluDeleteTessProc(tess); + // UnloadGLUTesselator(); + FreeVertBuf(); + return status; + } + + + +/***************************************************************************** + * LoadGLUTesselator + * + * Maps the glu32.dll module and gets function pointers for the + * tesselator functions. + *****************************************************************************/ + +static BOOL +LoadGLUTesselator(void) + { + if (gluModuleHandle != NULL) + return TRUE; + + { + extern HINSTANCE hInstanceOpenGL; + char *gluName = "GLU32.DLL"; +// char name[256]; +// char *ptr; +// int len; + +/* + len = GetModuleFileName(hInstanceOpenGL, name, 255); + if (len != 0) + { + ptr = name+len-1; + while (ptr > name && *ptr != '\\') + ptr--; + if (*ptr == '\\') + ptr++; + if (!stricmp(ptr, "cosmogl.dll")) + { + gluName = "COSMOGLU.DLL"; + } + else if (!stricmp(ptr, "opengl32.dll")) + { + gluName = "GLU32.DLL"; + } + } +*/ + if ((gluModuleHandle = LoadLibrary(gluName)) == NULL) + return FALSE; + } + + if ((gluNewTessProc = (gluNewTessProto) + GetProcAddress(gluModuleHandle, "gluNewTess")) == NULL) + return FALSE; + + if ((gluDeleteTessProc = (gluDeleteTessProto) + GetProcAddress(gluModuleHandle, "gluDeleteTess")) == NULL) + return FALSE; + + if ((gluTessBeginPolygonProc = (gluTessBeginPolygonProto) + GetProcAddress(gluModuleHandle, "gluTessBeginPolygon")) == NULL) + return FALSE; + + if ((gluTessBeginContourProc = (gluTessBeginContourProto) + GetProcAddress(gluModuleHandle, "gluTessBeginContour")) == NULL) + return FALSE; + + if ((gluTessVertexProc = (gluTessVertexProto) + GetProcAddress(gluModuleHandle, "gluTessVertex")) == NULL) + return FALSE; + + if ((gluTessEndContourProc = (gluTessEndContourProto) + GetProcAddress(gluModuleHandle, "gluTessEndContour")) == NULL) + return FALSE; + + if ((gluTessEndPolygonProc = (gluTessEndPolygonProto) + GetProcAddress(gluModuleHandle, "gluTessEndPolygon")) == NULL) + return FALSE; + + if ((gluTessPropertyProc = (gluTessPropertyProto) + GetProcAddress(gluModuleHandle, "gluTessProperty")) == NULL) + return FALSE; + + if ((gluTessNormalProc = (gluTessNormalProto) + GetProcAddress(gluModuleHandle, "gluTessNormal")) == NULL) + return FALSE; + + if ((gluTessCallbackProc = (gluTessCallbackProto) + GetProcAddress(gluModuleHandle, "gluTessCallback")) == NULL) + return FALSE; + + return TRUE; + } + + + +/***************************************************************************** + * UnloadGLUTesselator + * + * Unmaps the glu32.dll module. + *****************************************************************************/ + +static BOOL +UnloadGLUTesselator(void) + { + if (gluModuleHandle != NULL) + if (FreeLibrary(gluModuleHandle) == FALSE) + return FALSE; + gluModuleHandle = NULL; + } + + + +/***************************************************************************** + * TessVertexOut + * + * Used by tessellator to handle output vertexes. + *****************************************************************************/ + +static void CALLBACK +TessVertexOut(FLOAT p[3]) + { + GLfloat v[2]; + + v[0] = p[0] * ScaleFactor; + v[1] = p[1] * ScaleFactor; + _GLD_glVertex2fv(v); + } + +static void CALLBACK +TessVertexOutData(FLOAT p[3], GLfloat z) +{ + GLfloat v[3]; + + v[0] = (GLfloat) p[0]; + v[1] = (GLfloat) p[1]; + v[2] = z; + _GLD_glVertex3fv(v); +} + + +/***************************************************************************** + * TessCombine + * + * Used by tessellator to handle self-intersecting contours and degenerate + * geometry. + *****************************************************************************/ + +static void CALLBACK +TessCombine(double coords[3], + void* vertex_data[4], + FLOAT weight[4], + void** outData) + { + if (!AppendToVertBuf((FLOAT) coords[0]) + || !AppendToVertBuf((FLOAT) coords[1]) + || !AppendToVertBuf((FLOAT) coords[2])) + TessErrorOccurred = GL_OUT_OF_MEMORY; + *outData = VertBuf + (VertBufIndex - 3); + } + + + +/***************************************************************************** + * TessError + * + * Saves the last tessellator error code in the global TessErrorOccurred. + *****************************************************************************/ + +static void CALLBACK +TessError(GLenum error) + { + TessErrorOccurred = error; + } + + + +/***************************************************************************** + * MakeLinesFromGlyph + * + * Converts the outline of a glyph from the TTPOLYGON format to a simple + * array of floating-point values containing one or more loops. + * + * The first element of the output array is a count of the number of loops. + * The loop data follows this count. Each loop consists of a count of the + * number of vertices it contains, followed by the vertices. Each vertex + * is an X and Y coordinate. For example, a single triangle might be + * described by this array: + * + * 1., 3., 0., 0., 1., 0., 0., 1. + * ^ ^ ^ ^ ^ ^ ^ ^ + * #loops #verts x1 y1 x2 y2 x3 y3 + * + * A two-loop glyph would look like this: + * + * 2., 3., 0.,0., 1.,0., 0.,1., 3., .2,.2, .4,.2, .2,.4 + * + * Line segments from the TTPOLYGON are transferred to the output array in + * the obvious way. Quadratic splines in the TTPOLYGON are converted to + * collections of line segments + *****************************************************************************/ + +static int +MakeLinesFromGlyph(IN UCHAR* glyphBuf, + IN DWORD glyphSize, + IN FLOAT chordalDeviation) + { + UCHAR* p; + int status = 0; + + + /* + * Pick up all the polygons (aka loops) that make up the glyph: + */ + if (!AppendToLineBuf(0.0F)) /* loop count at LineBuf[0] */ + goto exit; + + p = glyphBuf; + while (p < glyphBuf + glyphSize) + { + if (!MakeLinesFromTTPolygon(&p, chordalDeviation)) + goto exit; + LineBuf[0] += 1.0F; /* increment loop count */ + } + + status = 1; + +exit: + return status; + } + + + +/***************************************************************************** + * MakeLinesFromTTPolygon + * + * Converts a TTPOLYGONHEADER and its associated curve structures into a + * single polyline loop in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromTTPolygon( IN OUT UCHAR** pp, + IN FLOAT chordalDeviation) + { + DWORD polySize; + UCHAR* polyStart; + DWORD vertexCountIndex; + + /* + * Record where the polygon data begins, and where the loop's + * vertex count resides: + */ + polyStart = *pp; + vertexCountIndex = LineBufIndex; + if (!AppendToLineBuf(0.0F)) + return 0; + + /* + * Extract relevant data from the TTPOLYGONHEADER: + */ + polySize = GetDWord(pp); + if (GetDWord(pp) != TT_POLYGON_TYPE) /* polygon type */ + return 0; + if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first X coord */ + return 0; + if (!AppendToLineBuf((FLOAT) GetFixed(pp))) /* first Y coord */ + return 0; + LineBuf[vertexCountIndex] += 1.0F; + + /* + * Process each of the TTPOLYCURVE structures in the polygon: + */ + while (*pp < polyStart + polySize) + if (!MakeLinesFromTTPolycurve( pp, + vertexCountIndex, + chordalDeviation)) + return 0; + + return 1; + } + + + +/***************************************************************************** + * MakeLinesFromTTPolyCurve + * + * Converts the lines and splines in a single TTPOLYCURVE structure to points + * in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromTTPolycurve( IN OUT UCHAR** pp, + IN DWORD vertexCountIndex, + IN FLOAT chordalDeviation) + { + WORD type; + WORD pointCount; + + + /* + * Pick up the relevant fields of the TTPOLYCURVE structure: + */ + type = (WORD) GetWord(pp); + pointCount = (WORD) GetWord(pp); + + /* + * Convert the "curve" to line segments: + */ + if (type == TT_PRIM_LINE) + return MakeLinesFromTTLine( pp, + vertexCountIndex, + pointCount); + else if (type == TT_PRIM_QSPLINE) + return MakeLinesFromTTQSpline( pp, + vertexCountIndex, + pointCount, + chordalDeviation); + else + return 0; + } + + + +/***************************************************************************** + * MakeLinesFromTTLine + * + * Converts points from the polyline in a TT_PRIM_LINE structure to + * equivalent points in the global LineBuf. + *****************************************************************************/ +static int +MakeLinesFromTTLine( IN OUT UCHAR** pp, + IN DWORD vertexCountIndex, + IN WORD pointCount) + { + /* + * Just copy the line segments into the line buffer (converting + * type as we go): + */ + LineBuf[vertexCountIndex] += pointCount; + while (pointCount--) + { + if (!AppendToLineBuf((FLOAT) GetFixed(pp)) /* X coord */ + || !AppendToLineBuf((FLOAT) GetFixed(pp))) /* Y coord */ + return 0; + } + + return 1; + } + + + +/***************************************************************************** + * MakeLinesFromTTQSpline + * + * Converts points from the poly quadratic spline in a TT_PRIM_QSPLINE + * structure to polyline points in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromTTQSpline( IN OUT UCHAR** pp, + IN DWORD vertexCountIndex, + IN WORD pointCount, + IN FLOAT chordalDeviation) + { + FLOAT x0, y0, x1, y1, x2, y2; + WORD point; + + /* + * Process each of the non-interpolated points in the outline. + * To do this, we need to generate two interpolated points (the + * start and end of the arc) for each non-interpolated point. + * The first interpolated point is always the one most recently + * stored in LineBuf, so we just extract it from there. The + * second interpolated point is either the average of the next + * two points in the QSpline, or the last point in the QSpline + * if only one remains. + */ + for (point = 0; point < pointCount - 1; ++point) + { + x0 = LineBuf[LineBufIndex - 2]; + y0 = LineBuf[LineBufIndex - 1]; + + x1 = (FLOAT) GetFixed(pp); + y1 = (FLOAT) GetFixed(pp); + + if (point == pointCount - 2) + { + /* + * This is the last arc in the QSpline. The final + * point is the end of the arc. + */ + x2 = (FLOAT) GetFixed(pp); + y2 = (FLOAT) GetFixed(pp); + } + else + { + /* + * Peek at the next point in the input to compute + * the end of the arc: + */ + x2 = 0.5F * (x1 + (FLOAT) GetFixed(pp)); + y2 = 0.5F * (y1 + (FLOAT) GetFixed(pp)); + /* + * Push the point back onto the input so it will + * be reused as the next off-curve point: + */ + *pp -= 8; + } + + if (!MakeLinesFromArc( x0, y0, + x1, y1, + x2, y2, + vertexCountIndex, + chordalDeviation * chordalDeviation)) + return 0; + } + + return 1; + } + + + +/***************************************************************************** + * MakeLinesFromArc + * + * Subdivides one arc of a quadratic spline until the chordal deviation + * tolerance requirement is met, then places the resulting set of line + * segments in the global LineBuf. + *****************************************************************************/ + +static int +MakeLinesFromArc( IN FLOAT x0, + IN FLOAT y0, + IN FLOAT x1, + IN FLOAT y1, + IN FLOAT x2, + IN FLOAT y2, + IN DWORD vertexCountIndex, + IN FLOAT chordalDeviationSquared) + { + FLOAT x01; + FLOAT y01; + FLOAT x12; + FLOAT y12; + FLOAT midPointX; + FLOAT midPointY; + FLOAT deltaX; + FLOAT deltaY; + + /* + * Calculate midpoint of the curve by de Casteljau: + */ + x01 = 0.5F * (x0 + x1); + y01 = 0.5F * (y0 + y1); + x12 = 0.5F * (x1 + x2); + y12 = 0.5F * (y1 + y2); + midPointX = 0.5F * (x01 + x12); + midPointY = 0.5F * (y01 + y12); + + + /* + * Estimate chordal deviation by the distance from the midpoint + * of the curve to its non-interpolated control point. If this + * distance is greater than the specified chordal deviation + * constraint, then subdivide. Otherwise, generate polylines + * from the three control points. + */ + deltaX = midPointX - x1; + deltaY = midPointY - y1; + if (deltaX * deltaX + deltaY * deltaY > chordalDeviationSquared) + { + MakeLinesFromArc( x0, y0, + x01, y01, + midPointX, midPointY, + vertexCountIndex, + chordalDeviationSquared); + + MakeLinesFromArc( midPointX, midPointY, + x12, y12, + x2, y2, + vertexCountIndex, + chordalDeviationSquared); + } + else + { + /* + * The "pen" is already at (x0, y0), so we don't need to + * add that point to the LineBuf. + */ + if (!AppendToLineBuf(x1) + || !AppendToLineBuf(y1) + || !AppendToLineBuf(x2) + || !AppendToLineBuf(y2)) + return 0; + LineBuf[vertexCountIndex] += 2.0F; + } + + return 1; + } + + + +/***************************************************************************** + * InitLineBuf + * + * Initializes the global LineBuf and its associated size and current-element + * counters. + *****************************************************************************/ + +static int +InitLineBuf(void) + { + if (!(LineBuf = (FLOAT*) + __wglMalloc((LineBufSize = LINE_BUF_QUANT) * sizeof(FLOAT)))) + return 0; + LineBufIndex = 0; + return 1; + } + + + +/***************************************************************************** + * InitVertBuf + * + * Initializes the global VertBuf and its associated size and current-element + * counters. + *****************************************************************************/ + +static int +InitVertBuf(void) + { + if (!(VertBuf = (FLOAT*) + __wglMalloc((VertBufSize = VERT_BUF_QUANT) * sizeof(FLOAT)))) + return 0; + VertBufIndex = 0; + return 1; + } + + + +/***************************************************************************** + * AppendToLineBuf + * + * Appends one floating-point value to the global LineBuf array. Return value + * is non-zero for success, zero for failure. + *****************************************************************************/ + +static int +AppendToLineBuf(FLOAT value) + { + if (LineBufIndex >= LineBufSize) + { + FLOAT* f; + + f = (FLOAT*) __wglRealloc(LineBuf, + (LineBufSize += LINE_BUF_QUANT) * sizeof(FLOAT)); + if (!f) + return 0; + LineBuf = f; + } + LineBuf[LineBufIndex++] = value; + return 1; + } + + + +/***************************************************************************** + * AppendToVertBuf + * + * Appends one floating-point value to the global VertBuf array. Return value + * is non-zero for success, zero for failure. + * + * Note that we can't realloc this one, because the tessellator is using + * pointers into it. + *****************************************************************************/ + +static int +AppendToVertBuf(FLOAT value) + { + if (VertBufIndex >= VertBufSize) + return 0; + VertBuf[VertBufIndex++] = value; + return 1; + } + + + +/***************************************************************************** + * FreeLineBuf + * + * Cleans up vertex buffer structure. + *****************************************************************************/ + +static void +FreeLineBuf(void) + { + if (LineBuf) + { + __wglFree(LineBuf); + LineBuf = NULL; + } + } + + + +/***************************************************************************** + * FreeVertBuf + * + * Cleans up vertex buffer structure. + *****************************************************************************/ + +static void +FreeVertBuf(void) + { + if (VertBuf) + { + __wglFree(VertBuf); + VertBuf = NULL; + } + } + + + +/***************************************************************************** + * GetWord + * + * Fetch the next 16-bit word from a little-endian byte stream, and increment + * the stream pointer to the next unscanned byte. + *****************************************************************************/ + +static long GetWord(UCHAR** p) + { + long value; + + value = ((*p)[1] << 8) + (*p)[0]; + *p += 2; + return value; + } + + + +/***************************************************************************** + * GetDWord + * + * Fetch the next 32-bit word from a little-endian byte stream, and increment + * the stream pointer to the next unscanned byte. + *****************************************************************************/ + +static long GetDWord(UCHAR** p) + { + long value; + + value = ((*p)[3] << 24) + ((*p)[2] << 16) + ((*p)[1] << 8) + (*p)[0]; + *p += 4; + return value; + } + + + + +/***************************************************************************** + * GetFixed + * + * Fetch the next 32-bit fixed-point value from a little-endian byte stream, + * convert it to floating-point, and increment the stream pointer to the next + * unscanned byte. + *****************************************************************************/ + +static double GetFixed( + UCHAR** p) +{ + long hiBits, loBits; + double value; + + loBits = GetWord(p); + hiBits = GetWord(p); + value = (double) ((hiBits << 16) | loBits) / 65536.0; + + return value * ScaleFactor; +} + +// *********************************************************************** + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.h b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.h new file mode 100644 index 000000000..aac041033 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dglwgl.h @@ -0,0 +1,127 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: OpenGL window functions (wgl*). +* +****************************************************************************/ + +#ifndef __DGLWGL_H +#define __DGLWGL_H + +// Disable compiler complaints about DLL linkage +#pragma warning (disable:4273) + +// Macros to control compilation +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> +#include <GL\gl.h> + +#include "dglcontext.h" +#include "dglglobals.h" +#include "dglmacros.h" +#include "ddlog.h" +#include "dglpf.h" + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef struct { + PROC proc; + char *name; +} DGL_extension; + +#ifndef __MINGW32__ +/* XXX why is this here? + * It should probaby be somewhere in src/mesa/drivers/windows/ + */ +#if defined(_WIN32) && !defined(_WINGDI_) && !defined(_WINGDI_H) && !defined(_GNU_H_WINDOWS32_DEFINES) && !defined(OPENSTEP) && !defined(BUILD_FOR_SNAP) +# define WGL_FONT_LINES 0 +# define WGL_FONT_POLYGONS 1 +#ifndef _GNU_H_WINDOWS32_FUNCTIONS +# ifdef UNICODE +# define wglUseFontBitmaps wglUseFontBitmapsW +# define wglUseFontOutlines wglUseFontOutlinesW +# else +# define wglUseFontBitmaps wglUseFontBitmapsA +# define wglUseFontOutlines wglUseFontOutlinesA +# endif /* !UNICODE */ +#endif /* _GNU_H_WINDOWS32_FUNCTIONS */ +typedef struct tagLAYERPLANEDESCRIPTOR LAYERPLANEDESCRIPTOR, *PLAYERPLANEDESCRIPTOR, *LPLAYERPLANEDESCRIPTOR; +typedef struct _GLYPHMETRICSFLOAT GLYPHMETRICSFLOAT, *PGLYPHMETRICSFLOAT, *LPGLYPHMETRICSFLOAT; +typedef struct tagPIXELFORMATDESCRIPTOR PIXELFORMATDESCRIPTOR, *PPIXELFORMATDESCRIPTOR, *LPPIXELFORMATDESCRIPTOR; +#if !defined(GLX_USE_MESA) +#include <GL/mesa_wgl.h> +#endif +#endif +#endif /* !__MINGW32__ */ + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _USE_GLD3_WGL +int APIENTRY DGL_ChoosePixelFormat(HDC a, CONST PIXELFORMATDESCRIPTOR *ppfd); +BOOL APIENTRY DGL_CopyContext(HGLRC a, HGLRC b, UINT c); +HGLRC APIENTRY DGL_CreateContext(HDC a); +HGLRC APIENTRY DGL_CreateLayerContext(HDC a, int b); +BOOL APIENTRY DGL_DeleteContext(HGLRC a); +BOOL APIENTRY DGL_DescribeLayerPlane(HDC a, int b, int c, UINT d, LPLAYERPLANEDESCRIPTOR e); +int APIENTRY DGL_DescribePixelFormat(HDC a, int b, UINT c, LPPIXELFORMATDESCRIPTOR d); +HGLRC APIENTRY DGL_GetCurrentContext(void); +HDC APIENTRY DGL_GetCurrentDC(void); +PROC APIENTRY DGL_GetDefaultProcAddress(LPCSTR a); +int APIENTRY DGL_GetLayerPaletteEntries(HDC a, int b, int c, int d, COLORREF *e); +int APIENTRY DGL_GetPixelFormat(HDC a); +PROC APIENTRY DGL_GetProcAddress(LPCSTR a); +BOOL APIENTRY DGL_MakeCurrent(HDC a, HGLRC b); +BOOL APIENTRY DGL_RealizeLayerPalette(HDC a, int b, BOOL c); +int APIENTRY DGL_SetLayerPaletteEntries(HDC a, int b, int c, int d, CONST COLORREF *e); +BOOL APIENTRY DGL_SetPixelFormat(HDC a, int b, CONST PIXELFORMATDESCRIPTOR *c); +BOOL APIENTRY DGL_ShareLists(HGLRC a, HGLRC b); +BOOL APIENTRY DGL_SwapBuffers(HDC a); +BOOL APIENTRY DGL_SwapLayerBuffers(HDC a, UINT b); +BOOL APIENTRY DGL_UseFontBitmapsA(HDC a, DWORD b, DWORD c, DWORD d); +BOOL APIENTRY DGL_UseFontBitmapsW(HDC a, DWORD b, DWORD c, DWORD d); +BOOL APIENTRY DGL_UseFontOutlinesA(HDC a, DWORD b, DWORD c, DWORD d, FLOAT e, FLOAT f, int g, LPGLYPHMETRICSFLOAT h); +BOOL APIENTRY DGL_UseFontOutlinesW(HDC a, DWORD b, DWORD c, DWORD d, FLOAT e, FLOAT f, int g, LPGLYPHMETRICSFLOAT h); +#endif //_USE_GLD3_WGL + +BOOL dglWglResizeBuffers(GLcontext *ctx, BOOL bDefaultDriver); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dll_main.c b/mesalib/src/mesa/drivers/windows/gldirect/dll_main.c new file mode 100644 index 000000000..1d7ac64f4 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dll_main.c @@ -0,0 +1,817 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Win32 DllMain functions. +* +****************************************************************************/ + +// INITGUID must only be defined once. +// Don't put it in a shared header file! +// GLD3 uses dxguid.lib, so INITGUID must *not* be used! +#ifndef _USE_GLD3_WGL +#define INITGUID +#endif // _USE_GLD3_WGL + +#include "dllmain.h" + +//#include "snap/graphics.h" +//#include "drvlib/os/os.h" + +#ifdef _USE_GLD3_WGL +typedef void (APIENTRY *LPDGLSPLASHSCREEN)(int, int, char*); +#include "gld_driver.h" +#endif + +// *********************************************************************** + +BOOL bInitialized = FALSE; // callback driver initialized? +BOOL bExited = FALSE; // callback driver exited this instance? +HINSTANCE hInstanceDll = NULL; // DLL instance handle + +static BOOL bDriverValidated = FALSE; // prior validation status +static BOOL bSplashScreen = TRUE; // Splash Screen ? +static BOOL bValidINIFound = FALSE; // Have we found a valid INI file? + +HHOOK hKeyHook = NULL; // global keyboard handler hook + +// Multi-threaded support needs to be reflected in Mesa code. (DaveM) +int _gld_bMultiThreaded = FALSE; + +// *********************************************************************** + +DWORD dwLogging = 0; // Logging flag +DWORD dwDebugLevel = 0; // Log debug level + +char szLogPath[_MAX_PATH] = {"\0"}; // Log file path +char szSNAPPath[_MAX_PATH] = {"\0"}; // SNAP driver path + +#ifndef _USE_GLD3_WGL +DGL_wglFuncs wglFuncs = { + sizeof(DGL_wglFuncs), + DGL_ChoosePixelFormat, + DGL_CopyContext, + DGL_CreateContext, + DGL_CreateLayerContext, + DGL_DeleteContext, + DGL_DescribeLayerPlane, + DGL_DescribePixelFormat, + DGL_GetCurrentContext, + DGL_GetCurrentDC, + DGL_GetDefaultProcAddress, + DGL_GetLayerPaletteEntries, + DGL_GetPixelFormat, + DGL_GetProcAddress, + DGL_MakeCurrent, + DGL_RealizeLayerPalette, + DGL_SetLayerPaletteEntries, + DGL_SetPixelFormat, + DGL_ShareLists, + DGL_SwapBuffers, + DGL_SwapLayerBuffers, + DGL_UseFontBitmapsA, + DGL_UseFontBitmapsW, + DGL_UseFontOutlinesA, + DGL_UseFontOutlinesW, +}; + +DGL_mesaFuncs mesaFuncs = { + sizeof(DGL_mesaFuncs), +}; +#endif // _USE_GLD3_WGL + +// *********************************************************************** + +typedef struct { + DWORD dwDriver; // 0=SciTech SW, 1=Direct3D SW, 2=Direct3D HW + BOOL bMipmapping; // 0=off, 1=on + BOOL bMultitexture; // 0=off, 1=on + BOOL bWaitForRetrace; // 0=off, 1=on + BOOL bFullscreenBlit; // 0=off, 1=on + BOOL bFastFPU; // 0=off, 1=on + BOOL bDirectDrawPersistant;// 0=off, 1=on + BOOL bPersistantBuffers; // 0=off, 1=on + DWORD dwLogging; // 0=off, 1=normal, 2=crash-proof + DWORD dwLoggingSeverity; // 0=all, 1=warnings+errors, 2=errors only + BOOL bMessageBoxWarnings;// 0=off, 1=on + BOOL bMultiThreaded; // 0=off, 1=on + BOOL bAppCustomizations; // 0=off, 1=on + BOOL bHotKeySupport; // 0=off, 1=on + BOOL bSplashScreen; // 0=off, 1=on + +#ifdef _USE_GLD3_WGL + // + // New for GLDirect 3.0 + // + DWORD dwAdapter; // DX8 adpater ordinal + DWORD dwTnL; // Transform & Lighting type + DWORD dwMultisample; // DX8 multisample type +#endif // _USE_GLD3_WGL +} INI_settings; + +static INI_settings ini; + +// *********************************************************************** + +BOOL APIENTRY DGL_initDriver( +#ifdef _USE_GLD3_WGL + void) +{ +#else + DGL_wglFuncs *lpWglFuncs, + DGL_mesaFuncs *lpMesaFuncs) +{ + // Check for valid pointers + if ((lpWglFuncs == NULL) || (lpMesaFuncs == NULL)) + return FALSE; + + // Check for valid structs + if (lpWglFuncs->dwSize != sizeof(DGL_wglFuncs)) { + return FALSE; + } + + // Check for valid structs + if (lpMesaFuncs->dwSize != sizeof(DGL_mesaFuncs)) { + return FALSE; + } + + // Copy the Mesa functions + memcpy(&mesaFuncs, lpMesaFuncs, sizeof(DGL_mesaFuncs)); + + // Pass back the wgl functions + memcpy(lpWglFuncs, &wglFuncs, sizeof(DGL_wglFuncs)); +#endif // _USE_GLD3_WGL + + // Finally initialize the callback driver + if (!dglInitDriver()) + return FALSE; + + return TRUE; +}; + +// *********************************************************************** + +BOOL ReadINIFile( + HINSTANCE hInstance) +{ + char szModuleFilename[MAX_PATH]; + char szSystemDirectory[MAX_PATH]; + const char szSectionName[] = "Config"; + char szINIFile[MAX_PATH]; + int pos; + + // Now using the DLL module handle. KeithH, 24/May/2000. + // Addendum: GetModuleFileName(NULL, ... returns process filename, + // GetModuleFileName(hModule, ... returns DLL filename, + + // Get the dll path and filename. + GetModuleFileName(hInstance, &szModuleFilename[0], MAX_PATH); // NULL for current process + // Get the System directory. + GetSystemDirectory(&szSystemDirectory[0], MAX_PATH); + + // Test to see if DLL is in system directory. + if (strnicmp(szModuleFilename, szSystemDirectory, strlen(szSystemDirectory))==0) { + // DLL *is* in system directory. + // Return FALSE to indicate that registry keys should be read. + return FALSE; + } + + // Compose filename of INI file + strcpy(szINIFile, szModuleFilename); + pos = strlen(szINIFile); + while (szINIFile[pos] != '\\') { + pos--; + } + szINIFile[pos+1] = '\0'; + // Use run-time DLL path for log file too + strcpy(szLogPath, szINIFile); + szLogPath[pos] = '\0'; + // Complete full INI file path + strcat(szINIFile, "gldirect.ini"); + + // Read settings from private INI file. + // Note that defaults are contained in the calls. + ini.dwDriver = GetPrivateProfileInt(szSectionName, "dwDriver", 2, szINIFile); + ini.bMipmapping = GetPrivateProfileInt(szSectionName, "bMipmapping", 1, szINIFile); + ini.bMultitexture = GetPrivateProfileInt(szSectionName, "bMultitexture", 1, szINIFile); + ini.bWaitForRetrace = GetPrivateProfileInt(szSectionName, "bWaitForRetrace", 0, szINIFile); + ini.bFullscreenBlit = GetPrivateProfileInt(szSectionName, "bFullscreenBlit", 0, szINIFile); + ini.bFastFPU = GetPrivateProfileInt(szSectionName, "bFastFPU", 1, szINIFile); + ini.bDirectDrawPersistant = GetPrivateProfileInt(szSectionName, "bPersistantDisplay", 0, szINIFile); + ini.bPersistantBuffers = GetPrivateProfileInt(szSectionName, "bPersistantResources", 0, szINIFile); + ini.dwLogging = GetPrivateProfileInt(szSectionName, "dwLogging", 0, szINIFile); + ini.dwLoggingSeverity = GetPrivateProfileInt(szSectionName, "dwLoggingSeverity", 0, szINIFile); + ini.bMessageBoxWarnings = GetPrivateProfileInt(szSectionName, "bMessageBoxWarnings", 0, szINIFile); + ini.bMultiThreaded = GetPrivateProfileInt(szSectionName, "bMultiThreaded", 0, szINIFile); + ini.bAppCustomizations = GetPrivateProfileInt(szSectionName, "bAppCustomizations", 1, szINIFile); + ini.bHotKeySupport = GetPrivateProfileInt(szSectionName, "bHotKeySupport", 0, szINIFile); + ini.bSplashScreen = GetPrivateProfileInt(szSectionName, "bSplashScreen", 1, szINIFile); + +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + ini.dwAdapter = GetPrivateProfileInt(szSectionName, "dwAdapter", 0, szINIFile); + // dwTnL now defaults to zero (chooses TnL at runtime). KeithH + ini.dwTnL = GetPrivateProfileInt(szSectionName, "dwTnL", 0, szINIFile); + ini.dwMultisample = GetPrivateProfileInt(szSectionName, "dwMultisample", 0, szINIFile); +#endif + + return TRUE; +} + +// *********************************************************************** + +BOOL dllReadRegistry( + HINSTANCE hInstance) +{ + // Read settings from INI file, if available + bValidINIFound = FALSE; + if (ReadINIFile(hInstance)) { + const char *szRendering[3] = { + "SciTech Software Renderer", + "Direct3D MMX Software Renderer", + "Direct3D Hardware Renderer" + }; + // Set globals + glb.bPrimary = 1; + glb.bHardware = (ini.dwDriver == 2) ? 1 : 0; +#ifndef _USE_GLD3_WGL + memset(&glb.ddGuid, 0, sizeof(glb.ddGuid)); + glb.d3dGuid = (ini.dwDriver == 2) ? IID_IDirect3DHALDevice : IID_IDirect3DRGBDevice; +#endif // _USE_GLD3_WGL + strcpy(glb.szDDName, "Primary"); + strcpy(glb.szD3DName, szRendering[ini.dwDriver]); + glb.dwRendering = ini.dwDriver; + glb.bUseMipmaps = ini.bMipmapping; + glb.bMultitexture = ini.bMultitexture; + glb.bWaitForRetrace = ini.bWaitForRetrace; + glb.bFullscreenBlit = ini.bFullscreenBlit; + glb.bFastFPU = ini.bFastFPU; + glb.bDirectDrawPersistant = ini.bDirectDrawPersistant; + glb.bPersistantBuffers = ini.bPersistantBuffers; + dwLogging = ini.dwLogging; + dwDebugLevel = ini.dwLoggingSeverity; + glb.bMessageBoxWarnings = ini.bMessageBoxWarnings; + glb.bMultiThreaded = ini.bMultiThreaded; + glb.bAppCustomizations = ini.bAppCustomizations; + glb.bHotKeySupport = ini.bHotKeySupport; + bSplashScreen = ini.bSplashScreen; +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + glb.dwAdapter = ini.dwAdapter; + glb.dwDriver = ini.dwDriver; + glb.dwTnL = ini.dwTnL; + glb.dwMultisample = ini.dwMultisample; +#endif + bValidINIFound = TRUE; + return TRUE; + } + // Read settings from registry + else { + HKEY hReg; + DWORD cbValSize; + DWORD dwType = REG_SZ; // Registry data type for strings + BOOL bRegistryError; + BOOL bSuccess; + +#define REG_READ_DWORD(a, b) \ + cbValSize = sizeof(b); \ + if (ERROR_SUCCESS != RegQueryValueEx( hReg, (a), \ + NULL, NULL, (LPBYTE)&(b), &cbValSize )) \ + bRegistryError = TRUE; + +#define REG_READ_DEVICEID(a, b) \ + cbValSize = MAX_DDDEVICEID_STRING; \ + if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \ + (LPBYTE)&(b), &cbValSize)) \ + bRegistryError = TRUE; + +#define REG_READ_STRING(a, b) \ + cbValSize = sizeof((b)); \ + if(ERROR_SUCCESS != RegQueryValueEx(hReg, (a), 0, &dwType, \ + (LPBYTE)&(b), &cbValSize)) \ + bRegistryError = TRUE; + + // Read settings from the registry. + + // Open the registry key for the current user if it exists. + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + // Otherwise open the registry key for the local machine. + if (!bSuccess) + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(DIRECTGL_REG_KEY_ROOT, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + if (!bSuccess) + return FALSE; + + bRegistryError = FALSE; + + REG_READ_DWORD(DIRECTGL_REG_SETTING_PRIMARY, glb.bPrimary); + REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_HW, glb.bHardware); +#ifndef _USE_GLD3_WGL + REG_READ_DWORD(DIRECTGL_REG_SETTING_DD_GUID, glb.ddGuid); + REG_READ_DWORD(DIRECTGL_REG_SETTING_D3D_GUID, glb.d3dGuid); +#endif // _USE_GLD3_WGL + REG_READ_DWORD(DIRECTGL_REG_SETTING_LOGGING, dwLogging); + REG_READ_DWORD(DIRECTGL_REG_SETTING_DEBUGLEVEL, dwDebugLevel); + REG_READ_DWORD(DIRECTGL_REG_SETTING_RENDERING, glb.dwRendering); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITEXTURE, glb.bMultitexture); + REG_READ_DWORD(DIRECTGL_REG_SETTING_WAITFORRETRACE, glb.bWaitForRetrace); + REG_READ_DWORD(DIRECTGL_REG_SETTING_FULLSCREENBLIT, glb.bFullscreenBlit); + REG_READ_DWORD(DIRECTGL_REG_SETTING_USEMIPMAPS, glb.bUseMipmaps); + + REG_READ_DEVICEID(DIRECTGL_REG_SETTING_DD_NAME, glb.szDDName); + REG_READ_DEVICEID(DIRECTGL_REG_SETTING_D3D_NAME, glb.szD3DName); + + REG_READ_DWORD(DIRECTGL_REG_SETTING_MSGBOXWARNINGS, glb.bMessageBoxWarnings); + REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTDISPLAY, glb.bDirectDrawPersistant); + REG_READ_DWORD(DIRECTGL_REG_SETTING_PERSISTBUFFERS, glb.bPersistantBuffers); + REG_READ_DWORD(DIRECTGL_REG_SETTING_FASTFPU, glb.bFastFPU); + REG_READ_DWORD(DIRECTGL_REG_SETTING_HOTKEYS, glb.bHotKeySupport); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTITHREAD, glb.bMultiThreaded); + REG_READ_DWORD(DIRECTGL_REG_SETTING_APPCUSTOM, glb.bAppCustomizations); + REG_READ_DWORD(DIRECTGL_REG_SETTING_SPLASHSCREEN, bSplashScreen); + +#ifdef _USE_GLD3_WGL + // New for GLDirect 3.x + glb.dwDriver = glb.dwRendering; + REG_READ_DWORD(DIRECTGL_REG_SETTING_ADAPTER, glb.dwAdapter); + REG_READ_DWORD(DIRECTGL_REG_SETTING_TNL, glb.dwTnL); + REG_READ_DWORD(DIRECTGL_REG_SETTING_MULTISAMPLE, glb.dwMultisample); +#endif + + RegCloseKey(hReg); + + // Open the global registry key for GLDirect + bSuccess = (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, + DIRECTGL_REG_SETTINGS_KEY, + 0, + KEY_READ, + &hReg)); + if (bSuccess) { + // Read the installation path for GLDirect + REG_READ_STRING("InstallLocation",szLogPath); + RegCloseKey(hReg); + } + + if (bRegistryError || !bSuccess) + return FALSE; + else + + return TRUE; + +#undef REG_READ_DWORD +#undef REG_READ_DEVICEID +#undef REG_READ_STRING + } +} + +// *********************************************************************** + +BOOL dllWriteRegistry( + void ) +{ + HKEY hReg; + DWORD dwCreateDisposition, cbValSize; + BOOL bRegistryError = FALSE; + +#define REG_WRITE_DWORD(a, b) \ + cbValSize = sizeof(b); \ + if (ERROR_SUCCESS != RegSetValueEx( hReg, (a), \ + 0, REG_DWORD, (LPBYTE)&(b), cbValSize )) \ + bRegistryError = TRUE; + + if (ERROR_SUCCESS == RegCreateKeyEx( DIRECTGL_REG_KEY_ROOT, DIRECTGL_REG_SETTINGS_KEY, + 0, NULL, 0, KEY_WRITE, NULL, &hReg, + &dwCreateDisposition )) { + RegFlushKey(hReg); // Make sure keys are written to disk + RegCloseKey(hReg); + hReg = NULL; + } + + if (bRegistryError) + return FALSE; + else + return TRUE; + +#undef REG_WRITE_DWORD +} + +// *********************************************************************** + +void dglInitHotKeys(HINSTANCE hInstance) +{ + // Hot-Key support at all? + if (!glb.bHotKeySupport) + return; + + // Install global keyboard interceptor + hKeyHook = SetWindowsHookEx(WH_KEYBOARD, dglKeyProc, hInstance, 0); +} + +// *********************************************************************** + +void dglExitHotKeys(void) +{ + // Hot-Key support at all? + if (!glb.bHotKeySupport) + return; + + // Remove global keyboard interceptor + if (hKeyHook) + UnhookWindowsHookEx(hKeyHook); + hKeyHook = NULL; +} + +// *********************************************************************** + +// Note: This app-customization step must be performed in both the main +// OpenGL32 driver and the callback driver DLLs for multithreading option. +void dglSetAppCustomizations(void) +{ + char szModuleFileName[MAX_PATH]; + int iSize = MAX_PATH; + + // Get the currently loaded EXE filename. + GetModuleFileName(NULL, &szModuleFileName[0], MAX_PATH); // NULL for current process + strupr(szModuleFileName); + iSize = strlen(szModuleFileName); + + // Check for specific EXEs and adjust global settings accordingly + + // NOTE: In GLD3.x "bDirectDrawPersistant" corresponds to IDirect3D8 and + // "bPersistantBuffers" corresponds to IDirect3DDevice8. KeithH + + // Case 1: 3DStudio must be multi-threaded + // Added: Discreet GMAX (3DStudio MAX 4 for gamers. KeithH) + if (strstr(szModuleFileName, "3DSMAX.EXE") + || strstr(szModuleFileName, "3DSVIZ.EXE") + || strstr(szModuleFileName, "GMAX.EXE")) { + glb.bMultiThreaded = TRUE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + return; + } + + // Case 2: Solid Edge must use pre-allocated resources for all GLRCs + if (strstr(szModuleFileName, "PART.EXE") + || strstr(szModuleFileName, "ASSEMBL.EXE") + || strstr(szModuleFileName, "DRAFT.EXE") + || strstr(szModuleFileName, "SMARTVW.EXE") + || strstr(szModuleFileName, "SMETAL.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = FALSE; + return; + } + + // Case 3: Sudden Depth creates and destroys GLRCs on paint commands + if (strstr(szModuleFileName, "SUDDEPTH.EXE") + || strstr(szModuleFileName, "SUDDEMO.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + glb.bFullscreenBlit = TRUE; + return; + } + + // Case 4: StereoGraphics test apps create and destroy GLRCs on paint commands + if (strstr(szModuleFileName, "REDBLUE.EXE") + || strstr(szModuleFileName, "DIAGNOSE.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + + // Case 5: Pipes screen savers share multiple GLRCs for same window + if (strstr(szModuleFileName, "PIPES.SCR") + || (strstr(szModuleFileName, "PIPES") && strstr(szModuleFileName, ".SCR"))) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + + // Case 6: AutoVue uses sub-viewport ops which are temporarily broken in stereo window + if (strstr(szModuleFileName, "AVWIN.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = TRUE; + return; + } + // Case 7: Quake3 is waiting for DDraw objects to be released at exit + if (strstr(szModuleFileName, "QUAKE")) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = FALSE; + glb.bPersistantBuffers = FALSE; + glb.bFullscreenBlit = FALSE; + return; + } + // Case 8: Reflection GLX server is unable to switch contexts at run-time + if (strstr(szModuleFileName, "RX.EXE")) { + glb.bMultiThreaded = FALSE; + glb.bMessageBoxWarnings = FALSE; + return; + } + // Case 9: Original AutoCAD 2000 must share DDraw objects across GLRCs + if (strstr(szModuleFileName, "ACAD.EXE")) { + glb.bFastFPU = FALSE; + if (GetModuleHandle("wopengl6.hdi") != NULL) { + glb.bMultiThreaded = FALSE; + glb.bDirectDrawPersistant = TRUE; + glb.bPersistantBuffers = FALSE; + } + return; + } +} + +// *********************************************************************** + +BOOL dglInitDriver(void) +{ + UCHAR szExeName[MAX_PATH]; + const char *szRendering[] = { + "Mesa Software", + "Direct3D RGB SW", + "Direct3D HW", + }; + static BOOL bWarnOnce = FALSE; + + // Already initialized? + if (bInitialized) + return TRUE; + + // Moved from DllMain DLL_PROCESS_ATTACH: + + // (Re-)Init defaults + dglInitGlobals(); + + // Read registry or INI file settings + if (!dllReadRegistry(hInstanceDll)) { + if (!bWarnOnce) + MessageBox( NULL, "GLDirect has not been configured.\n\n" + "Please run the configuration program\n" + "before using GLDirect with applications.\n", + "GLDirect", MB_OK | MB_ICONWARNING); + bWarnOnce = TRUE; + return FALSE; + } + +#ifdef _USE_GLD3_WGL + // Must do this as early as possible. + // Need to read regkeys/ini-file first though. + gldInitDriverPointers(glb.dwDriver); + + // Create private driver globals + _gldDriver.CreatePrivateGlobals(); +#endif + // Overide settings with application customizations + if (glb.bAppCustomizations) + dglSetAppCustomizations(); + +//#ifndef _USE_GLD3_WGL + // Set the global memory type to either sysmem or vidmem + glb.dwMemoryType = glb.bHardware ? DDSCAPS_VIDEOMEMORY : DDSCAPS_SYSTEMMEMORY; +//#endif + + // Multi-threaded support overides persistant display support + if (glb.bMultiThreaded) + glb.bDirectDrawPersistant = glb.bPersistantBuffers = FALSE; + + // Multi-threaded support needs to be reflected in Mesa code. (DaveM) + _gld_bMultiThreaded = glb.bMultiThreaded; + + // Start logging + ddlogPathOption(szLogPath); + ddlogWarnOption(glb.bMessageBoxWarnings); + ddlogOpen((DDLOG_loggingMethodType)dwLogging, + (DDLOG_severityType)dwDebugLevel); + + // Obtain the name of the calling app + ddlogMessage(DDLOG_SYSTEM, "Driver : SciTech GLDirect 4.0\n"); + GetModuleFileName(NULL, szExeName, sizeof(szExeName)); + ddlogPrintf(DDLOG_SYSTEM, "Executable : %s", szExeName); + + ddlogPrintf(DDLOG_SYSTEM, "DirectDraw device: %s", glb.szDDName); + ddlogPrintf(DDLOG_SYSTEM, "Direct3D driver : %s", glb.szD3DName); + + ddlogPrintf(DDLOG_SYSTEM, "Rendering type : %s", szRendering[glb.dwRendering]); + + ddlogPrintf(DDLOG_SYSTEM, "Multithreaded : %s", glb.bMultiThreaded ? "Enabled" : "Disabled"); + ddlogPrintf(DDLOG_SYSTEM, "Display resources: %s", glb.bDirectDrawPersistant ? "Persistant" : "Instanced"); + ddlogPrintf(DDLOG_SYSTEM, "Buffer resources : %s", glb.bPersistantBuffers ? "Persistant" : "Instanced"); + + dglInitContextState(); + dglBuildPixelFormatList(); + //dglBuildTextureFormatList(); + + // D3D callback driver is now successfully initialized + bInitialized = TRUE; + // D3D callback driver is now ready to be exited + bExited = FALSE; + + return TRUE; +} + +// *********************************************************************** + +void dglExitDriver(void) +{ + + // Only need to clean up once per instance: + // May be called implicitly from DLL_PROCESS_DETACH, + // or explicitly from DGL_exitDriver(). + if (bExited) + return; + bExited = TRUE; + + // DDraw objects may be invalid when DLL unloads. +__try { + + // Clean-up sequence (moved from DLL_PROCESS_DETACH) +#ifndef _USE_GLD3_WGL + dglReleaseTextureFormatList(); +#endif + dglReleasePixelFormatList(); + dglDeleteContextState(); + +#ifdef _USE_GLD3_WGL + _gldDriver.DestroyPrivateGlobals(); +#endif + +} +__except(EXCEPTION_EXECUTE_HANDLER) { + ddlogPrintf(DDLOG_WARN, "Exception raised in dglExitDriver."); +} + + // Close the log file + ddlogClose(); +} + +// *********************************************************************** + +int WINAPI DllMain( + HINSTANCE hInstance, + DWORD fdwReason, + PVOID pvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + // Cache DLL instance handle + hInstanceDll = hInstance; + + // Flag that callback driver has yet to be initialized + bInitialized = bExited = FALSE; + +#ifndef _USE_GLD3_WGL + // Init internal Mesa function pointers + memset(&mesaFuncs, 0, sizeof(DGL_mesaFuncs)); +#endif // _USE_GLD3_WGL + + // Init defaults + dglInitGlobals(); + + // Defer rest of DLL initialization to 1st WGL function call + break; + + case DLL_PROCESS_DETACH: + // Call exit clean-up sequence + dglExitDriver(); + break; + } + + return TRUE; +} + +// *********************************************************************** + +void APIENTRY DGL_exitDriver(void) +{ + // Call exit clean-up sequence + dglExitDriver(); +} + +// *********************************************************************** + +void APIENTRY DGL_reinitDriver(void) +{ + // Force init sequence again + bInitialized = bExited = FALSE; + dglInitDriver(); +} + +// *********************************************************************** + +int WINAPI DllInitialize( + HINSTANCE hInstance, + DWORD fdwReason, + PVOID pvReserved) +{ + // Some Watcom compiled executables require this. + return DllMain(hInstance, fdwReason, pvReserved); +} + +// *********************************************************************** + +void DGL_LoadSplashScreen(int piReg, char* pszUser) +{ + HINSTANCE hSplashDll = NULL; + LPDGLSPLASHSCREEN dglSplashScreen = NULL; + static BOOL bOnce = FALSE; + static int iReg = 0; + static char szUser[255] = {"\0"}; + + // Display splash screen at all? + if (!bSplashScreen) + return; + + // Only display splash screen once + if (bOnce) + return; + bOnce = TRUE; + + // Make local copy of string for passing to DLL + if (pszUser) + strcpy(szUser, pszUser); + iReg = piReg; + + // Load Splash Screen DLL + // (If it fails to load for any reason, we don't care...) + hSplashDll = LoadLibrary("gldsplash.dll"); + if (hSplashDll) { + // Execute the Splash Screen function + dglSplashScreen = (LPDGLSPLASHSCREEN)GetProcAddress(hSplashDll, "GLDSplashScreen"); + if (dglSplashScreen) + (*dglSplashScreen)(1, iReg, szUser); + // Don't unload the DLL since splash screen dialog is modeless now + } +} + +// *********************************************************************** + +BOOL dglValidate() +{ + char *szCaption = "SciTech GLDirect Driver"; + UINT uType = MB_OK | MB_ICONEXCLAMATION; + +#ifdef _USE_GLD3_WGL + // (Re)build pixelformat list + if (glb.bPixelformatsDirty) + _gldDriver.BuildPixelformatList(); +#endif + + // Check to see if we have already validated + if (bDriverValidated && bInitialized) + return TRUE; + + // Since all (most) the WGL functions must be validated at this point, + // this also insure that the callback driver is completely initialized. + if (!bInitialized) + if (!dglInitDriver()) { + MessageBox(NULL, + "The GLDirect driver could not initialize.\n\n" + "Please run the configuration program to\n" + "properly configure the driver, or else\n" + "re-run the installation program.", szCaption, uType); + _exit(1); // Bail + } + + return TRUE; +} + +// *********************************************************************** + diff --git a/mesalib/src/mesa/drivers/windows/gldirect/dllmain.h b/mesalib/src/mesa/drivers/windows/gldirect/dllmain.h new file mode 100644 index 000000000..03343ef7a --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/dllmain.h @@ -0,0 +1,64 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Win32 DllMain functions. +* +****************************************************************************/ + +#ifndef __DLLMAIN_H +#define __DLLMAIN_H + +// Macros to control compilation +#define STRICT +#define WIN32_LEAN_AND_MEAN + +#include <windows.h> + +#ifndef _USE_GLD3_WGL +#include "DirectGL.h" +#endif // _USE_GLD3_WGL + +//#include "gldirect/regkeys.h" +#include "dglglobals.h" +#include "ddlog.h" +#ifndef _USE_GLD3_WGL +#include "d3dtexture.h" +#endif // _USE_GLD3_WGL + +#include "dglwgl.h" + +extern BOOL bInitialized; + +BOOL dglInitDriver(void); +void dglExitDriver(void); + +#endif diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_clip.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_clip.c new file mode 100644 index 000000000..044d2e66f --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_clip.c @@ -0,0 +1,39 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes <gareth@valinux.com> + */ + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_clip.c HACK") + +void _math_test_all_cliptest_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_norm.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_norm.c new file mode 100644 index 000000000..c20362bb2 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_norm.c @@ -0,0 +1,39 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 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 + * BRIAN PAUL 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. + * + * Authors: + * Gareth Hughes <gareth@valinux.com> + */ + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_norm.c HACK") + +void _math_test_all_normal_transform_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_xform.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_xform.c new file mode 100644 index 000000000..73439dc3b --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_debug_xform.c @@ -0,0 +1,41 @@ + +/* + * Mesa 3-D graphics library + * Version: 3.5 + * + * Copyright (C) 1999-2001 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 + * BRIAN PAUL 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. + */ + +/* + * Updated for P6 architecture by Gareth Hughes. + */ + + +#ifdef DEBUG /* This code only used for debugging */ + +// Stub to enable Mesa to build. KeithH +#pragma message("NOTE: Using gld_debug_xform.c HACK") + +void _math_test_all_transform_functions( char *description ) +{ +} + + +#endif /* DEBUG */ diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_dispatch.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_dispatch.c new file mode 100644 index 000000000..e05d767e3 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_dispatch.c @@ -0,0 +1,73 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Thread-aware dispatch table. +* +****************************************************************************/ + +#include "glheader.h" +#include "glapi.h" +#include "glapitable.h" +#include "mtypes.h" +#include "context.h" + +#define KEYWORD1 +#define KEYWORD2 GLAPIENTRY +#if defined(USE_MGL_NAMESPACE) + #define NAME(func) mgl##func +#else + #define NAME(func) gl##func +#endif + +#if 0 +// Altered these to get the dispatch table from +// the current context of the calling thread. +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + (gc->CurrentDispatch->FUNC) ARGS +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + return (gc->CurrentDispatch->FUNC) ARGS +#else // #if 0 +#define DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + (_glapi_Dispatch->FUNC) ARGS +#define RETURN_DISPATCH(FUNC, ARGS, MESSAGE) \ + GET_CURRENT_CONTEXT(gc); \ + return (_glapi_Dispatch->FUNC) ARGS +#endif // #if 0 + +#ifndef GLAPIENTRY +#define GLAPIENTRY +#endif + +#include "glapitemp.h" diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.c b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.c new file mode 100644 index 000000000..f7c575614 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.c @@ -0,0 +1,279 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Driver functions and interfaces +* +****************************************************************************/ + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <windows.h> + +#include "gld_driver.h" +#include "ddlog.h" +#include "glheader.h" + +// For glGetString(). +#include "common_x86_asm.h" + +//--------------------------------------------------------------------------- + +static char *szDriverError = "Driver used before initialisation!"; + +// This holds our dynamically created OpenGL renderer string. +// 256 chars should be plenty - remember that some apps display this. +static char _gldRendererString[256]; + +static char *szVendor = "SciTech Software, Inc."; + +//--------------------------------------------------------------------------- + +extern BOOL gldGetDXErrorString_DX(HRESULT hr, char *buf, int nBufSize); + +extern BOOL gldCreateDrawable_MesaSW(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldResizeDrawable_MesaSW(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldDestroyDrawable_MesaSW(DGL_ctx *ctx); +extern BOOL gldCreatePrivateGlobals_MesaSW(void); +extern BOOL gldDestroyPrivateGlobals_MesaSW(void); +extern BOOL gldBuildPixelformatList_MesaSW(void); +extern BOOL gldInitialiseMesa_MesaSW(DGL_ctx *ctx); +extern BOOL gldSwapBuffers_MesaSW(DGL_ctx *ctx, HDC hDC, HWND hWnd); +extern PROC gldGetProcAddress_MesaSW(LPCSTR a); +extern BOOL gldGetDisplayMode_MesaSW(DGL_ctx *ctx, GLD_displayMode *glddm); + +extern BOOL gldCreateDrawable_DX(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldResizeDrawable_DX(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); +extern BOOL gldDestroyDrawable_DX(DGL_ctx *ctx); +extern BOOL gldCreatePrivateGlobals_DX(void); +extern BOOL gldDestroyPrivateGlobals_DX(void); +extern BOOL gldBuildPixelformatList_DX(void); +extern BOOL gldInitialiseMesa_DX(DGL_ctx *ctx); +extern BOOL gldSwapBuffers_DX(DGL_ctx *ctx, HDC hDC, HWND hWnd); +extern PROC gldGetProcAddress_DX(LPCSTR a); +extern BOOL gldGetDisplayMode_DX(DGL_ctx *ctx, GLD_displayMode *glddm); + +//--------------------------------------------------------------------------- +// NOP functions. Called if proper driver functions are not set. +//--------------------------------------------------------------------------- + +static BOOL _gldDriverError(void) +{ + ddlogMessage(DDLOG_CRITICAL, szDriverError); + return FALSE; +} + +//--------------------------------------------------------------------------- + +static BOOL _GetDXErrorString_ERROR( + HRESULT hr, + char *buf, + int nBufSize) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _CreateDrawable_ERROR( + DGL_ctx *ctx, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _ResizeDrawable_ERROR( + DGL_ctx *ctx, + BOOL bDefaultDriver, + BOOL bPersistantInterface, + BOOL bPersistantBuffers) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _DestroyDrawable_ERROR( + DGL_ctx *ctx) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _CreatePrivateGlobals_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _DestroyPrivateGlobals_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _BuildPixelformatList_ERROR(void) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + + +static BOOL _InitialiseMesa_ERROR( + DGL_ctx *ctx) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static BOOL _SwapBuffers_ERROR( + DGL_ctx *ctx, + HDC hDC, + HWND hWnd) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- + +static PROC _GetProcAddress_ERROR( + LPCSTR a) +{ + _gldDriverError(); + return NULL; +} + +//--------------------------------------------------------------------------- + +static BOOL _GetDisplayMode_ERROR( + DGL_ctx *ctx, + GLD_displayMode *glddm) +{ + return _gldDriverError(); +} + +//--------------------------------------------------------------------------- +// Functions useful to all drivers +//--------------------------------------------------------------------------- + +const GLubyte* _gldGetStringGeneric( + GLcontext *ctx, + GLenum name) +{ + if (!ctx) + return NULL; + + switch (name) { + case GL_RENDERER: + sprintf(_gldRendererString, "GLDirect 4.0 %s%s%s%s (%s %s)", + _mesa_x86_cpu_features ? "/x86" : "", + cpu_has_mmx ? "/MMX" : "", + cpu_has_3dnow ? "/3DNow!" : "", + cpu_has_xmm ? "/SSE" : "", + __DATE__, __TIME__); + return (const GLubyte *) _gldRendererString; + case GL_VENDOR: + return (const GLubyte *) szVendor; + default: + return NULL; + } +} + +//--------------------------------------------------------------------------- +// Global driver function pointers, initially set to functions that +// will report an error when called. +//--------------------------------------------------------------------------- + +GLD_driver _gldDriver = { + _GetDXErrorString_ERROR, + _CreateDrawable_ERROR, + _ResizeDrawable_ERROR, + _DestroyDrawable_ERROR, + _CreatePrivateGlobals_ERROR, + _DestroyPrivateGlobals_ERROR, + _BuildPixelformatList_ERROR, + _InitialiseMesa_ERROR, + _SwapBuffers_ERROR, + _GetProcAddress_ERROR, + _GetDisplayMode_ERROR +}; + +//--------------------------------------------------------------------------- +// Init function. Should be called as soon as regkeys/ini-settings are read. +//--------------------------------------------------------------------------- + +BOOL gldInitDriverPointers( + DWORD dwDriver) +{ + _gldDriver.GetDXErrorString = gldGetDXErrorString_DX; + + if (dwDriver == GLDS_DRIVER_MESA_SW) { + // Mesa Software driver + _gldDriver.CreateDrawable = gldCreateDrawable_MesaSW; + _gldDriver.ResizeDrawable = gldResizeDrawable_MesaSW; + _gldDriver.DestroyDrawable = gldDestroyDrawable_MesaSW; + _gldDriver.CreatePrivateGlobals = gldCreatePrivateGlobals_MesaSW; + _gldDriver.DestroyPrivateGlobals = gldDestroyPrivateGlobals_MesaSW; + _gldDriver.BuildPixelformatList = gldBuildPixelformatList_MesaSW; + _gldDriver.InitialiseMesa = gldInitialiseMesa_MesaSW; + _gldDriver.SwapBuffers = gldSwapBuffers_MesaSW; + _gldDriver.wglGetProcAddress = gldGetProcAddress_MesaSW; + _gldDriver.GetDisplayMode = gldGetDisplayMode_MesaSW; + return TRUE; + } + + if ((dwDriver == GLDS_DRIVER_REF) || (dwDriver == GLDS_DRIVER_HAL)) { + // Direct3D driver, either HW or SW + _gldDriver.CreateDrawable = gldCreateDrawable_DX; + _gldDriver.ResizeDrawable = gldResizeDrawable_DX; + _gldDriver.DestroyDrawable = gldDestroyDrawable_DX; + _gldDriver.CreatePrivateGlobals = gldCreatePrivateGlobals_DX; + _gldDriver.DestroyPrivateGlobals = gldDestroyPrivateGlobals_DX; + _gldDriver.BuildPixelformatList = gldBuildPixelformatList_DX; + _gldDriver.InitialiseMesa = gldInitialiseMesa_DX; + _gldDriver.SwapBuffers = gldSwapBuffers_DX; + _gldDriver.wglGetProcAddress = gldGetProcAddress_DX; + _gldDriver.GetDisplayMode = gldGetDisplayMode_DX; + return TRUE; + }; + + return FALSE; +} + +//--------------------------------------------------------------------------- diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.h b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.h new file mode 100644 index 000000000..01a46a832 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gld_driver.h @@ -0,0 +1,90 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x/2000/XP/XBox (Win32) +* +* Description: Driver functions and interfaces +* +****************************************************************************/ + +#ifndef _GLD_DRIVER_H +#define _GLD_DRIVER_H + +// This file is only useful is we're using the new GLD3 WGL code. +#ifdef _USE_GLD3_WGL + +#include "dglcontext.h" + +// Same as DX8 D3DDISPLAYMODE +typedef struct { + DWORD Width; + DWORD Height; + DWORD Refresh; + DWORD BPP; +} GLD_displayMode; + +typedef struct { + // Returns a string for a given HRESULT error code. + BOOL (*GetDXErrorString)(HRESULT hr, char *buf, int nBufSize); + + // Driver functions for managing drawables. + // Functions must respect persistant buffers / persistant interface. + // NOTE: Persistant interface is: DirectDraw, pre-DX8; Direct3D, DX8 and above. + BOOL (*CreateDrawable)(DGL_ctx *ctx, BOOL bPersistantInterface, BOOL bPersistantBuffers); + BOOL (*ResizeDrawable)(DGL_ctx *ctx, BOOL bDefaultDriver, BOOL bPersistantInterface, BOOL bPersistantBuffers); + BOOL (*DestroyDrawable)(DGL_ctx *ctx); + + // Create/Destroy private globals belonging to driver + BOOL (*CreatePrivateGlobals)(void); + BOOL (*DestroyPrivateGlobals)(void); + + // Build pixelformat list + BOOL (*BuildPixelformatList)(void); + + // Initialise Mesa's driver pointers + BOOL (*InitialiseMesa)(DGL_ctx *ctx); + + // Swap buffers + BOOL (*SwapBuffers)(DGL_ctx *ctx, HDC hDC, HWND hWnd); + + // wglGetProcAddress() + PROC (*wglGetProcAddress)(LPCSTR a); + + BOOL (*GetDisplayMode)(DGL_ctx *ctx, GLD_displayMode *glddm); +} GLD_driver; + +extern GLD_driver _gldDriver; + +BOOL gldInitDriverPointers(DWORD dwDriver); +const GLubyte* _gldGetStringGeneric(GLcontext *ctx, GLenum name); + +#endif // _USE_GLD3_WGL + +#endif // _GLD_DRIVER_H diff --git a/mesalib/src/mesa/drivers/windows/gldirect/gldlame8.c b/mesalib/src/mesa/drivers/windows/gldirect/gldlame8.c new file mode 100644 index 000000000..5ac519c17 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/gldlame8.c @@ -0,0 +1,181 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: GLDirect utility for determining lame boards/drivers. +* +****************************************************************************/ + +#define STRICT +#define WIN32_LEAN_AND_MEAN +#include <d3d8.h> + +/* +Ack. Broken out from gldlame.c because of broken D3D headers. KeithH +*/ + +/**************************************************************************** +REMARKS: +Scans list of DirectDraw devices for specific device IDs. +****************************************************************************/ + +#define VENDORID_ATI 0x1002 + +static DWORD devATIRagePro[] = { + 0x4742, // 3D RAGE PRO BGA AGP 1X/2X + 0x4744, // 3D RAGE PRO BGA AGP 1X only + 0x4749, // 3D RAGE PRO BGA PCI 33 MHz + 0x4750, // 3D RAGE PRO PQFP PCI 33 MHz + 0x4751, // 3D RAGE PRO PQFP PCI 33 MHz limited 3D + 0x4C42, // 3D RAGE LT PRO BGA-312 AGP 133 MHz + 0x4C44, // 3D RAGE LT PRO BGA-312 AGP 66 MHz + 0x4C49, // 3D RAGE LT PRO BGA-312 PCI 33 MHz + 0x4C50, // 3D RAGE LT PRO BGA-256 PCI 33 MHz + 0x4C51, // 3D RAGE LT PRO BGA-256 PCI 33 MHz limited 3D +}; + +static DWORD devATIRageIIplus[] = { + 0x4755, // 3D RAGE II+ + 0x4756, // 3D RAGE IIC PQFP PCI + 0x4757, // 3D RAGE IIC BGA AGP + 0x475A, // 3D RAGE IIC PQFP AGP + 0x4C47, // 3D RAGE LT-G +}; + +static __inline BOOL IsDevice( + DWORD *lpDeviceIdList, + DWORD dwDeviceId, + int count) +{ + int i; + + for (i=0; i<count; i++) + if (dwDeviceId == lpDeviceIdList[i]) + return TRUE; + + return FALSE; +} + +/**************************************************************************** +REMARKS: +Test the Direct3D8 device for "lameness" with respect to GLDirect. +This is done on per-chipset basis, as in GLD CAD driver (DGLCONTEXT.C). +If bTestForWHQL is set then the device is tested to see if it is +certified, and bIsWHQL is set to indicate TRUE or FALSE. Otherwise bIsWHQL +is not set. [WHQL = Windows Hardware Quality Labs] + +NOTE: There is a one- or two-second time penalty incurred in determining + the WHQL certification date. +****************************************************************************/ +BOOL IsThisD3D8Lame( + IDirect3D8 *pD3D, + DWORD dwAdapter, + BOOL bTestForWHQL, + BOOL *bIsWHQL) +{ + DWORD dwFlags = bTestForWHQL ? 0 : D3DENUM_NO_WHQL_LEVEL; + D3DADAPTER_IDENTIFIER8 d3dai; + HRESULT hr; + + hr = IDirect3D8_GetAdapterIdentifier(pD3D, dwAdapter, dwFlags, &d3dai); + if (FAILED(hr)) + return TRUE; // Definitely lame if adapter details can't be obtained! + + if (bTestForWHQL) { + *bIsWHQL = d3dai.WHQLLevel ? TRUE : FALSE; + } + + // Vendor 1: ATI + if (d3dai.VendorId == VENDORID_ATI) { + // Test A: ATI Rage PRO + if (IsDevice(devATIRagePro, d3dai.DeviceId, sizeof(devATIRagePro))) + return TRUE; // bad mipmapping + // Test B: ATI Rage II+ + if (IsDevice(devATIRageIIplus, d3dai.DeviceId, sizeof(devATIRageIIplus))) + return TRUE; // bad HW alpha testing + } + + return FALSE; +} + +/**************************************************************************** +REMARKS: +Test the Direct3DDevice8 device for "lameness" with respect to GLDirect. +This is done by querying for particular caps, as in GLD CPL (CPLMAIN.CPP). +****************************************************************************/ +BOOL IsThisD3D8DeviceLame( + IDirect3DDevice8 *pDev) +{ + D3DCAPS8 d3dCaps; + HRESULT hr; + + hr = IDirect3DDevice8_GetDeviceCaps(pDev, &d3dCaps); + if (FAILED(hr)) + return TRUE; + + // Test 1: Perspective-correct textures + // Any card that cannot do perspective-textures is *exceptionally* lame. + if (!(d3dCaps.TextureCaps & D3DPTEXTURECAPS_PERSPECTIVE)) { + return TRUE; // Lame! + } + + // Test 2: Bilinear filtering + if (!(d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)) { + return TRUE; // Lame! + } + + // Test 3: Mipmapping + if (!(d3dCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)) { + return TRUE; // Lame! + } + + // Test 4: Depth-test modes (?) + + // Test 5: Blend Modes -- Based on DX7 D3DIM MTEXTURE.CPP caps test + + // Accept devices that can do multipass, alpha blending + if( !((d3dCaps.DestBlendCaps & D3DPBLENDCAPS_INVSRCALPHA) && + (d3dCaps.SrcBlendCaps & D3DPBLENDCAPS_SRCALPHA)) ) + return TRUE; + + // Accept devices that can do multipass, color blending + if( !((d3dCaps.DestBlendCaps & D3DPBLENDCAPS_SRCCOLOR) && + (d3dCaps.SrcBlendCaps & D3DPBLENDCAPS_ZERO)) ) + return TRUE; + + // Accept devices that really support multiple textures. + if( !((d3dCaps.MaxTextureBlendStages > 1 ) && + (d3dCaps.MaxSimultaneousTextures > 1 ) && + (d3dCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATE )) ) + return TRUE; + + return FALSE; // Not lame +} diff --git a/mesalib/src/mesa/drivers/windows/gldirect/opengl32.def b/mesalib/src/mesa/drivers/windows/gldirect/opengl32.def new file mode 100644 index 000000000..b213b6e04 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/opengl32.def @@ -0,0 +1,488 @@ +;**************************************************************************** +;* +;* Mesa 3-D graphics library +;* Direct3D Driver Interface +;* +;* ======================================================================== +;* +;* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +;* SCITECH SOFTWARE INC 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. +;* +;* ====================================================================== +;* +;* Language: ANSI C +;* Environment: Windows 9x/2000/XP/XBox (Win32) +;* +;* Description: DLL Module definition file +;* +;****************************************************************************/ + +DESCRIPTION 'GLDirect' + +VERSION 3.0 + +EXPORTS + glAccum=glAccum @1 + glAlphaFunc=glAlphaFunc @2 + glAreTexturesResident=glAreTexturesResident @3 + glArrayElement=glArrayElement @4 + glBegin=glBegin @5 + glBindTexture=glBindTexture @6 + glBitmap=glBitmap @7 + glBlendFunc=glBlendFunc @8 + glCallList=glCallList @9 + glCallLists=glCallLists @10 + glClear=glClear @11 + glClearAccum=glClearAccum @12 + glClearIndex=glClearIndex @13 + glClearColor=glClearColor @14 + glClearDepth=glClearDepth @15 + glClearStencil=glClearStencil @16 + glClipPlane=glClipPlane @17 + glColor3b=glColor3b @18 + glColor3d=glColor3d @19 + glColor3f=glColor3f @20 + glColor3i=glColor3i @21 + glColor3s=glColor3s @22 + glColor3ub=glColor3ub @23 + glColor3ui=glColor3ui @24 + glColor3us=glColor3us @25 + glColor4b=glColor4b @26 + glColor4d=glColor4d @27 + glColor4f=glColor4f @28 + glColor4i=glColor4i @29 + glColor4s=glColor4s @30 + glColor4ub=glColor4ub @31 + glColor4ui=glColor4ui @32 + glColor4us=glColor4us @33 + glColor3bv=glColor3bv @34 + glColor3dv=glColor3dv @35 + glColor3fv=glColor3fv @36 + glColor3iv=glColor3iv @37 + glColor3sv=glColor3sv @38 + glColor3ubv=glColor3ubv @39 + glColor3uiv=glColor3uiv @40 + glColor3usv=glColor3usv @41 + glColor4bv=glColor4bv @42 + glColor4dv=glColor4dv @43 + glColor4fv=glColor4fv @44 + glColor4iv=glColor4iv @45 + glColor4sv=glColor4sv @46 + glColor4ubv=glColor4ubv @47 + glColor4uiv=glColor4uiv @48 + glColor4usv=glColor4usv @49 + glColorMask=glColorMask @50 + glColorMaterial=glColorMaterial @51 + glColorPointer=glColorPointer @52 + glColorTableEXT=glColorTableEXT @53 + glColorSubTableEXT=glColorSubTableEXT @54 + glCopyPixels=glCopyPixels @55 + glCopyTexImage1D=glCopyTexImage1D @56 + glCopyTexImage2D=glCopyTexImage2D @57 + glCopyTexSubImage1D=glCopyTexSubImage1D @58 + glCopyTexSubImage2D=glCopyTexSubImage2D @59 + glCullFace=glCullFace @60 + glDepthFunc=glDepthFunc @61 + glDepthMask=glDepthMask @62 + glDepthRange=glDepthRange @63 + glDeleteLists=glDeleteLists @64 + glDeleteTextures=glDeleteTextures @65 + glDisable=glDisable @66 + glDisableClientState=glDisableClientState @67 + glDrawArrays=glDrawArrays @68 + glDrawBuffer=glDrawBuffer @69 + glDrawElements=glDrawElements @70 + glDrawPixels=glDrawPixels @71 + glEnable=glEnable @72 + glEnableClientState=glEnableClientState @73 + glEnd=glEnd @74 + glEndList=glEndList @75 + glEvalCoord1d=glEvalCoord1d @76 + glEvalCoord1f=glEvalCoord1f @77 + glEvalCoord1dv=glEvalCoord1dv @78 + glEvalCoord1fv=glEvalCoord1fv @79 + glEvalCoord2d=glEvalCoord2d @80 + glEvalCoord2f=glEvalCoord2f @81 + glEvalCoord2dv=glEvalCoord2dv @82 + glEvalCoord2fv=glEvalCoord2fv @83 + glEvalPoint1=glEvalPoint1 @84 + glEvalPoint2=glEvalPoint2 @85 + glEvalMesh1=glEvalMesh1 @86 + glEdgeFlag=glEdgeFlag @87 + glEdgeFlagv=glEdgeFlagv @88 + glEdgeFlagPointer=glEdgeFlagPointer @89 + glEvalMesh2=glEvalMesh2 @90 + glFeedbackBuffer=glFeedbackBuffer @91 + glFinish=glFinish @92 + glFlush=glFlush @93 + glFogf=glFogf @94 + glFogi=glFogi @95 + glFogfv=glFogfv @96 + glFogiv=glFogiv @97 + glFrontFace=glFrontFace @98 + glFrustum=glFrustum @99 + glGenLists=glGenLists @100 + glGenTextures=glGenTextures @101 + glGetBooleanv=glGetBooleanv @102 + glGetClipPlane=glGetClipPlane @103 + glGetColorTableEXT=glGetColorTableEXT @104 + glGetColorTableParameterivEXT=glGetColorTableParameterivEXT @105 + glGetColorTableParameterfvEXT=glGetColorTableParameterfvEXT @106 + glGetDoublev=glGetDoublev @107 + glGetError=glGetError @108 + glGetFloatv=glGetFloatv @109 + glGetIntegerv=glGetIntegerv @110 + glGetLightfv=glGetLightfv @111 + glGetLightiv=glGetLightiv @112 + glGetMapdv=glGetMapdv @113 + glGetMapfv=glGetMapfv @114 + glGetMapiv=glGetMapiv @115 + glGetMaterialfv=glGetMaterialfv @116 + glGetMaterialiv=glGetMaterialiv @117 + glGetPixelMapfv=glGetPixelMapfv @118 + glGetPixelMapuiv=glGetPixelMapuiv @119 + glGetPixelMapusv=glGetPixelMapusv @120 + glGetPointerv=glGetPointerv @121 + glGetPolygonStipple=glGetPolygonStipple @122 + glGetString=glGetString @123 + glGetTexEnvfv=glGetTexEnvfv @124 + glGetTexEnviv=glGetTexEnviv @125 + glGetTexGeniv=glGetTexGeniv @126 + glGetTexGendv=glGetTexGendv @127 + glGetTexGenfv=glGetTexGenfv @128 + glGetTexImage=glGetTexImage @129 + glGetTexLevelParameterfv=glGetTexLevelParameterfv @130 + glGetTexLevelParameteriv=glGetTexLevelParameteriv @131 + glGetTexParameterfv=glGetTexParameterfv @132 + glGetTexParameteriv=glGetTexParameteriv @133 + glHint=glHint @134 + glIndexd=glIndexd @135 + glIndexf=glIndexf @136 + glIndexi=glIndexi @137 + glIndexs=glIndexs @138 + glIndexub=glIndexub @139 + glIndexdv=glIndexdv @140 + glIndexfv=glIndexfv @141 + glIndexiv=glIndexiv @142 + glIndexsv=glIndexsv @143 + glIndexubv=glIndexubv @144 + glIndexMask=glIndexMask @145 + glIndexPointer=glIndexPointer @146 + glInterleavedArrays=glInterleavedArrays @147 + glInitNames=glInitNames @148 + glIsList=glIsList @149 + glIsTexture=glIsTexture @150 + glLightf=glLightf @151 + glLighti=glLighti @152 + glLightfv=glLightfv @153 + glLightiv=glLightiv @154 + glLightModelf=glLightModelf @155 + glLightModeli=glLightModeli @156 + glLightModelfv=glLightModelfv @157 + glLightModeliv=glLightModeliv @158 + glLineWidth=glLineWidth @159 + glLineStipple=glLineStipple @160 + glListBase=glListBase @161 + glLoadIdentity=glLoadIdentity @162 + glLoadMatrixd=glLoadMatrixd @163 + glLoadMatrixf=glLoadMatrixf @164 + glLoadName=glLoadName @165 + glLogicOp=glLogicOp @166 + glMap1d=glMap1d @167 + glMap1f=glMap1f @168 + glMap2d=glMap2d @169 + glMap2f=glMap2f @170 + glMapGrid1d=glMapGrid1d @171 + glMapGrid1f=glMapGrid1f @172 + glMapGrid2d=glMapGrid2d @173 + glMapGrid2f=glMapGrid2f @174 + glMaterialf=glMaterialf @175 + glMateriali=glMateriali @176 + glMaterialfv=glMaterialfv @177 + glMaterialiv=glMaterialiv @178 + glMatrixMode=glMatrixMode @179 + glMultMatrixd=glMultMatrixd @180 + glMultMatrixf=glMultMatrixf @181 + glNewList=glNewList @182 + glNormal3b=glNormal3b @183 + glNormal3d=glNormal3d @184 + glNormal3f=glNormal3f @185 + glNormal3i=glNormal3i @186 + glNormal3s=glNormal3s @187 + glNormal3bv=glNormal3bv @188 + glNormal3dv=glNormal3dv @189 + glNormal3fv=glNormal3fv @190 + glNormal3iv=glNormal3iv @191 + glNormal3sv=glNormal3sv @192 + glNormalPointer=glNormalPointer @193 + glOrtho=glOrtho @194 + glPassThrough=glPassThrough @195 + glPixelMapfv=glPixelMapfv @196 + glPixelMapuiv=glPixelMapuiv @197 + glPixelMapusv=glPixelMapusv @198 + glPixelStoref=glPixelStoref @199 + glPixelStorei=glPixelStorei @200 + glPixelTransferf=glPixelTransferf @201 + glPixelTransferi=glPixelTransferi @202 + glPixelZoom=glPixelZoom @203 + glPointSize=glPointSize @204 + glPolygonMode=glPolygonMode @205 + glPolygonOffset=glPolygonOffset @206 + glPolygonOffsetEXT=glPolygonOffsetEXT @207 + glPolygonStipple=glPolygonStipple @208 + glPopAttrib=glPopAttrib @209 + glPopClientAttrib=glPopClientAttrib @210 + glPopMatrix=glPopMatrix @211 + glPopName=glPopName @212 + glPrioritizeTextures=glPrioritizeTextures @213 + glPushMatrix=glPushMatrix @214 + glRasterPos2d=glRasterPos2d @215 + glRasterPos2f=glRasterPos2f @216 + glRasterPos2i=glRasterPos2i @217 + glRasterPos2s=glRasterPos2s @218 + glRasterPos3d=glRasterPos3d @219 + glRasterPos3f=glRasterPos3f @220 + glRasterPos3i=glRasterPos3i @221 + glRasterPos3s=glRasterPos3s @222 + glRasterPos4d=glRasterPos4d @223 + glRasterPos4f=glRasterPos4f @224 + glRasterPos4i=glRasterPos4i @225 + glRasterPos4s=glRasterPos4s @226 + glRasterPos2dv=glRasterPos2dv @227 + glRasterPos2fv=glRasterPos2fv @228 + glRasterPos2iv=glRasterPos2iv @229 + glRasterPos2sv=glRasterPos2sv @230 + glRasterPos3dv=glRasterPos3dv @231 + glRasterPos3fv=glRasterPos3fv @232 + glRasterPos3iv=glRasterPos3iv @233 + glRasterPos3sv=glRasterPos3sv @234 + glRasterPos4dv=glRasterPos4dv @235 + glRasterPos4fv=glRasterPos4fv @236 + glRasterPos4iv=glRasterPos4iv @237 + glRasterPos4sv=glRasterPos4sv @238 + glReadBuffer=glReadBuffer @239 + glReadPixels=glReadPixels @240 + glRectd=glRectd @241 + glRectf=glRectf @242 + glRecti=glRecti @243 + glRects=glRects @244 + glRectdv=glRectdv @245 + glRectfv=glRectfv @246 + glRectiv=glRectiv @247 + glRectsv=glRectsv @248 + glScissor=glScissor @249 + glIsEnabled=glIsEnabled @250 + glPushAttrib=glPushAttrib @251 + glPushClientAttrib=glPushClientAttrib @252 + glPushName=glPushName @253 + glRenderMode=glRenderMode @254 + glRotated=glRotated @255 + glRotatef=glRotatef @256 + glSelectBuffer=glSelectBuffer @257 + glScaled=glScaled @258 + glScalef=glScalef @259 + glShadeModel=glShadeModel @260 + glStencilFunc=glStencilFunc @261 + glStencilMask=glStencilMask @262 + glStencilOp=glStencilOp @263 + glTexCoord1d=glTexCoord1d @264 + glTexCoord1f=glTexCoord1f @265 + glTexCoord1i=glTexCoord1i @266 + glTexCoord1s=glTexCoord1s @267 + glTexCoord2d=glTexCoord2d @268 + glTexCoord2f=glTexCoord2f @269 + glTexCoord2i=glTexCoord2i @270 + glTexCoord2s=glTexCoord2s @271 + glTexCoord3d=glTexCoord3d @272 + glTexCoord3f=glTexCoord3f @273 + glTexCoord3i=glTexCoord3i @274 + glTexCoord3s=glTexCoord3s @275 + glTexCoord4d=glTexCoord4d @276 + glTexCoord4f=glTexCoord4f @277 + glTexCoord4i=glTexCoord4i @278 + glTexCoord4s=glTexCoord4s @279 + glTexCoord1dv=glTexCoord1dv @280 + glTexCoord1fv=glTexCoord1fv @281 + glTexCoord1iv=glTexCoord1iv @282 + glTexCoord1sv=glTexCoord1sv @283 + glTexCoord2dv=glTexCoord2dv @284 + glTexCoord2fv=glTexCoord2fv @285 + glTexCoord2iv=glTexCoord2iv @286 + glTexCoord2sv=glTexCoord2sv @287 + glTexCoord3dv=glTexCoord3dv @288 + glTexCoord3fv=glTexCoord3fv @289 + glTexCoord3iv=glTexCoord3iv @290 + glTexCoord3sv=glTexCoord3sv @291 + glTexCoord4dv=glTexCoord4dv @292 + glTexCoord4fv=glTexCoord4fv @293 + glTexCoord4iv=glTexCoord4iv @294 + glTexCoord4sv=glTexCoord4sv @295 + glTexCoordPointer=glTexCoordPointer @296 + glTexGend=glTexGend @297 + glTexGenf=glTexGenf @298 + glTexGeni=glTexGeni @299 + glTexGendv=glTexGendv @300 + glTexGeniv=glTexGeniv @301 + glTexGenfv=glTexGenfv @302 + glTexEnvf=glTexEnvf @303 + glTexEnvi=glTexEnvi @304 + glTexEnvfv=glTexEnvfv @305 + glTexEnviv=glTexEnviv @306 + glTexImage1D=glTexImage1D @307 + glTexImage2D=glTexImage2D @308 + glTexParameterf=glTexParameterf @309 + glTexParameteri=glTexParameteri @310 + glTexParameterfv=glTexParameterfv @311 + glTexParameteriv=glTexParameteriv @312 + glTexSubImage1D=glTexSubImage1D @313 + glTexSubImage2D=glTexSubImage2D @314 + glTranslated=glTranslated @315 + glTranslatef=glTranslatef @316 + glVertex2d=glVertex2d @317 + glVertex2f=glVertex2f @318 + glVertex2i=glVertex2i @319 + glVertex2s=glVertex2s @320 + glVertex3d=glVertex3d @321 + glVertex3f=glVertex3f @322 + glVertex3i=glVertex3i @323 + glVertex3s=glVertex3s @324 + glVertex4d=glVertex4d @325 + glVertex4f=glVertex4f @326 + glVertex4i=glVertex4i @327 + glVertex4s=glVertex4s @328 + glVertex2dv=glVertex2dv @329 + glVertex2fv=glVertex2fv @330 + glVertex2iv=glVertex2iv @331 + glVertex2sv=glVertex2sv @332 + glVertex3dv=glVertex3dv @333 + glVertex3fv=glVertex3fv @334 + glVertex3iv=glVertex3iv @335 + glVertex3sv=glVertex3sv @336 + glVertex4dv=glVertex4dv @337 + glVertex4fv=glVertex4fv @338 + glVertex4iv=glVertex4iv @339 + glVertex4sv=glVertex4sv @340 + glVertexPointer=glVertexPointer @341 + glViewport=glViewport @342 + glBlendEquationEXT=glBlendEquationEXT @343 + glBlendColorEXT=glBlendColorEXT @344 + glVertexPointerEXT=glVertexPointerEXT @345 + glNormalPointerEXT=glNormalPointerEXT @346 + glColorPointerEXT=glColorPointerEXT @347 + glIndexPointerEXT=glIndexPointerEXT @348 + glTexCoordPointerEXT=glTexCoordPointerEXT @349 + glEdgeFlagPointerEXT=glEdgeFlagPointerEXT @350 + glGetPointervEXT=glGetPointervEXT @351 + glArrayElementEXT=glArrayElementEXT @352 + glDrawArraysEXT=glDrawArraysEXT @353 + glBindTextureEXT=glBindTextureEXT @354 + glDeleteTexturesEXT=glDeleteTexturesEXT @355 + glGenTexturesEXT=glGenTexturesEXT @356 + glPrioritizeTexturesEXT=glPrioritizeTexturesEXT @357 + glCopyTexSubImage3DEXT=glCopyTexSubImage3DEXT @358 + glTexImage3DEXT=glTexImage3DEXT @359 + glTexSubImage3DEXT=glTexSubImage3DEXT @360 + glWindowPos4fMESA=glWindowPos4fMESA @361 + glWindowPos2iMESA=glWindowPos2iMESA @362 + glWindowPos2sMESA=glWindowPos2sMESA @363 + glWindowPos2fMESA=glWindowPos2fMESA @364 + glWindowPos2dMESA=glWindowPos2dMESA @365 + glWindowPos2ivMESA=glWindowPos2ivMESA @366 + glWindowPos2svMESA=glWindowPos2svMESA @367 + glWindowPos2fvMESA=glWindowPos2fvMESA @368 + glWindowPos2dvMESA=glWindowPos2dvMESA @369 + glWindowPos3iMESA=glWindowPos3iMESA @370 + glWindowPos3sMESA=glWindowPos3sMESA @371 + glWindowPos3fMESA=glWindowPos3fMESA @372 + glWindowPos3dMESA=glWindowPos3dMESA @373 + glWindowPos3ivMESA=glWindowPos3ivMESA @374 + glWindowPos3svMESA=glWindowPos3svMESA @375 + glWindowPos3fvMESA=glWindowPos3fvMESA @376 + glWindowPos3dvMESA=glWindowPos3dvMESA @377 + glWindowPos4iMESA=glWindowPos4iMESA @378 + glWindowPos4sMESA=glWindowPos4sMESA @379 + glWindowPos4dMESA=glWindowPos4dMESA @380 + glWindowPos4ivMESA=glWindowPos4ivMESA @381 + glWindowPos4svMESA=glWindowPos4svMESA @382 + glWindowPos4fvMESA=glWindowPos4fvMESA @383 + glWindowPos4dvMESA=glWindowPos4dvMESA @384 + glResizeBuffersMESA=glResizeBuffersMESA @385 + wglCopyContext=wglCopyContext @386 + wglCreateContext=wglCreateContext @387 + wglCreateLayerContext=wglCreateLayerContext @388 + wglDeleteContext=wglDeleteContext @389 + wglDescribeLayerPlane=wglDescribeLayerPlane @390 + wglGetCurrentContext=wglGetCurrentContext @391 + wglGetCurrentDC=wglGetCurrentDC @392 + wglGetLayerPaletteEntries=wglGetLayerPaletteEntries @393 + wglGetProcAddress=wglGetProcAddress @394 + wglMakeCurrent=wglMakeCurrent @395 + wglRealizeLayerPalette=wglRealizeLayerPalette @396 + wglSetLayerPaletteEntries=wglSetLayerPaletteEntries @397 + wglShareLists=wglShareLists @398 + wglSwapLayerBuffers=wglSwapLayerBuffers @399 + wglUseFontBitmapsA=wglUseFontBitmapsA @400 + wglUseFontBitmapsW=wglUseFontBitmapsW @401 + wglUseFontOutlinesA=wglUseFontOutlinesA @402 + wglUseFontOutlinesW=wglUseFontOutlinesW @403 + ChoosePixelFormat=ChoosePixelFormat @404 + DescribePixelFormat=DescribePixelFormat @405 + GetPixelFormat=GetPixelFormat @406 + SetPixelFormat=SetPixelFormat @407 + SwapBuffers=SwapBuffers @408 + wglChoosePixelFormat=wglChoosePixelFormat @409 + wglDescribePixelFormat=wglDescribePixelFormat @410 + wglGetPixelFormat=wglGetPixelFormat @411 + wglSetPixelFormat=wglSetPixelFormat @412 + wglSwapBuffers=wglSwapBuffers @413 + glActiveTextureARB=glActiveTextureARB @414 + glClientActiveTextureARB=glClientActiveTextureARB @415 + glMultiTexCoord1dARB=glMultiTexCoord1dARB @416 + glMultiTexCoord1dvARB=glMultiTexCoord1dvARB @417 + glMultiTexCoord1fARB=glMultiTexCoord1fARB @418 + glMultiTexCoord1fvARB=glMultiTexCoord1fvARB @419 + glMultiTexCoord1iARB=glMultiTexCoord1iARB @420 + glMultiTexCoord1ivARB=glMultiTexCoord1ivARB @421 + glMultiTexCoord1sARB=glMultiTexCoord1sARB @422 + glMultiTexCoord1svARB=glMultiTexCoord1svARB @423 + glMultiTexCoord2dARB=glMultiTexCoord2dARB @424 + glMultiTexCoord2dvARB=glMultiTexCoord2dvARB @425 + glMultiTexCoord2fARB=glMultiTexCoord2fARB @426 + glMultiTexCoord2fvARB=glMultiTexCoord2fvARB @427 + glMultiTexCoord2iARB=glMultiTexCoord2iARB @428 + glMultiTexCoord2ivARB=glMultiTexCoord2ivARB @429 + glMultiTexCoord2sARB=glMultiTexCoord2sARB @430 + glMultiTexCoord2svARB=glMultiTexCoord2svARB @431 + glMultiTexCoord3dARB=glMultiTexCoord3dARB @432 + glMultiTexCoord3dvARB=glMultiTexCoord3dvARB @433 + glMultiTexCoord3fARB=glMultiTexCoord3fARB @434 + glMultiTexCoord3fvARB=glMultiTexCoord3fvARB @435 + glMultiTexCoord3iARB=glMultiTexCoord3iARB @436 + glMultiTexCoord3ivARB=glMultiTexCoord3ivARB @437 + glMultiTexCoord3sARB=glMultiTexCoord3sARB @438 + glMultiTexCoord3svARB=glMultiTexCoord3svARB @439 + glMultiTexCoord4dARB=glMultiTexCoord4dARB @440 + glMultiTexCoord4dvARB=glMultiTexCoord4dvARB @441 + glMultiTexCoord4fARB=glMultiTexCoord4fARB @442 + glMultiTexCoord4fvARB=glMultiTexCoord4fvARB @443 + glMultiTexCoord4iARB=glMultiTexCoord4iARB @444 + glMultiTexCoord4ivARB=glMultiTexCoord4ivARB @445 + glMultiTexCoord4sARB=glMultiTexCoord4sARB @446 + glMultiTexCoord4svARB=glMultiTexCoord4svARB @447 diff --git a/mesalib/src/mesa/drivers/windows/gldirect/pixpack.h b/mesalib/src/mesa/drivers/windows/gldirect/pixpack.h new file mode 100644 index 000000000..ec848d455 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/gldirect/pixpack.h @@ -0,0 +1,108 @@ +/**************************************************************************** +* +* Mesa 3-D graphics library +* Direct3D Driver Interface +* +* ======================================================================== +* +* Copyright (C) 1991-2004 SciTech Software, Inc. 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 +* SCITECH SOFTWARE INC 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. +* +* ====================================================================== +* +* Language: ANSI C +* Environment: Windows 9x (Win32) +* +* Description: Pixel packing functions. +* +****************************************************************************/ + +#ifndef __PIXPACK_H +#define __PIXPACK_H + +#include <GL\gl.h> +#include <ddraw.h> + +#include "ddlog.h" + +/*---------------------- Macros and type definitions ----------------------*/ + +#define PXAPI + +// Typedef that can be used for pixel packing function pointers. +#define PX_PACK_FUNC(a) void PXAPI (a)(unsigned char *pixdata, void *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_packFunc)(unsigned char *pixdata, void *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +// Typedef that can be used for pixel unpacking function pointers. +#define PX_UNPACK_FUNC(a) void PXAPI (a)(unsigned char *pixdata, void *src, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_unpackFunc)(unsigned char *pixdata, void *src, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +// Typedef that can be used for pixel span packing function pointers. +#define PX_PACK_SPAN_FUNC(a) void PXAPI (a)(GLuint n, unsigned char *pixdata, unsigned char *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2) +typedef void (PXAPI *PX_packSpanFunc)(GLuint n, unsigned char *pixdata, unsigned char *dst, GLenum Format, const LPDDSURFACEDESC2 lpDDSD2); + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { +#endif + +// Function that examines a pixel format and returns the relevent +// pixel-packing function +void PXAPI pxClassifyPixelFormat(const LPDDPIXELFORMAT lpddpf, PX_packFunc *lpPackFn ,PX_unpackFunc *lpUnpackFn, PX_packSpanFunc *lpPackSpanFn); + +// Packing functions +PX_PACK_FUNC(pxPackGeneric); +PX_PACK_FUNC(pxPackRGB555); +PX_PACK_FUNC(pxPackARGB4444); +PX_PACK_FUNC(pxPackARGB1555); +PX_PACK_FUNC(pxPackRGB565); +PX_PACK_FUNC(pxPackRGB332); +PX_PACK_FUNC(pxPackRGB888); +PX_PACK_FUNC(pxPackARGB8888); +PX_PACK_FUNC(pxPackPAL8); + +// Unpacking functions +PX_UNPACK_FUNC(pxUnpackGeneric); +PX_UNPACK_FUNC(pxUnpackRGB555); +PX_UNPACK_FUNC(pxUnpackARGB4444); +PX_UNPACK_FUNC(pxUnpackARGB1555); +PX_UNPACK_FUNC(pxUnpackRGB565); +PX_UNPACK_FUNC(pxUnpackRGB332); +PX_UNPACK_FUNC(pxUnpackRGB888); +PX_UNPACK_FUNC(pxUnpackARGB8888); +PX_UNPACK_FUNC(pxUnpackPAL8); + +// Span Packing functions +PX_PACK_SPAN_FUNC(pxPackSpanGeneric); +PX_PACK_SPAN_FUNC(pxPackSpanRGB555); +PX_PACK_SPAN_FUNC(pxPackSpanARGB4444); +PX_PACK_SPAN_FUNC(pxPackSpanARGB1555); +PX_PACK_SPAN_FUNC(pxPackSpanRGB565); +PX_PACK_SPAN_FUNC(pxPackSpanRGB332); +PX_PACK_SPAN_FUNC(pxPackSpanRGB888); +PX_PACK_SPAN_FUNC(pxPackSpanARGB8888); +PX_PACK_SPAN_FUNC(pxPackSpanPAL8); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mesalib/src/mesa/drivers/windows/icd/icd.c b/mesalib/src/mesa/drivers/windows/icd/icd.c new file mode 100644 index 000000000..4bc6176b1 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/icd/icd.c @@ -0,0 +1,347 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2004 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 + * BRIAN PAUL 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 name: icd.c + * Author: Gregor Anich + * + * ICD (Installable Client Driver) interface. + * Based on the windows GDI/WGL driver. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <windows.h> +#define GL_GLEXT_PROTOTYPES +#include "GL/gl.h" +#include "GL/glext.h" + +#ifdef __cplusplus +} +#endif + +#include <stdio.h> +#include <tchar.h> +#include "GL/wmesa.h" +#include "mtypes.h" +#include "glapi.h" + +#define MAX_MESA_ATTRS 20 + +typedef struct wmesa_context *PWMC; + +typedef struct _icdTable { + DWORD size; + PROC table[336]; +} ICDTABLE, *PICDTABLE; + +#ifdef USE_MGL_NAMESPACE +# define GL_FUNC(func) mgl##func +#else +# define GL_FUNC(func) gl##func +#endif + +static ICDTABLE icdTable = { 336, { +#define ICD_ENTRY(func) (PROC)GL_FUNC(func), +#include "icdlist.h" +#undef ICD_ENTRY +} }; + +struct __pixelformat__ +{ + PIXELFORMATDESCRIPTOR pfd; + GLboolean doubleBuffered; +}; + +struct __pixelformat__ pix[] = +{ + /* Double Buffer, alpha */ + { { sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, 8, 0, 8, 8, 8, 16, 8, 24, + 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 }, + GL_TRUE + }, + /* Single Buffer, alpha */ + { { sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL, /* | PFD_SUPPORT_GDI ? */ + PFD_TYPE_RGBA, + 24, 8, 0, 8, 8, 8, 16, 8, 24, + 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 }, + GL_FALSE + }, + /* Double Buffer, no alpha */ + { { sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER|PFD_SWAP_COPY, + PFD_TYPE_RGBA, + 24, 8, 0, 8, 8, 8, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 }, + GL_TRUE + }, + /* Single Buffer, no alpha */ + { { sizeof(PIXELFORMATDESCRIPTOR), 1, + PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL, /* | PFD_SUPPORT_GDI ? */ + PFD_TYPE_RGBA, + 24, 8, 0, 8, 8, 8, 16, 0, 0, + 0, 0, 0, 0, 0, 16, 8, 0, 0, 0, 0, 0, 0 }, + GL_FALSE + }, +}; + +int qt_pix = sizeof(pix) / sizeof(pix[0]); + +typedef struct { + WMesaContext ctx; + HDC hdc; +} MesaWglCtx; + +#define MESAWGL_CTX_MAX_COUNT 20 + +static MesaWglCtx wgl_ctx[MESAWGL_CTX_MAX_COUNT]; + +static unsigned ctx_count = 0; +static int ctx_current = -1; +static unsigned curPFD = 0; + +WGLAPI BOOL GLAPIENTRY DrvCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask) +{ + (void) hglrcSrc; (void) hglrcDst; (void) mask; + return(FALSE); +} + +WGLAPI HGLRC GLAPIENTRY DrvCreateContext(HDC hdc) +{ + HWND hWnd; + int i = 0; + + if(!(hWnd = WindowFromDC(hdc))) + { + SetLastError(0); + return(NULL); + } + if (!ctx_count) + { + for(i=0;i<MESAWGL_CTX_MAX_COUNT;i++) + { + wgl_ctx[i].ctx = NULL; + wgl_ctx[i].hdc = NULL; + } + } + for( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) + { + if ( wgl_ctx[i].ctx == NULL ) + { + wgl_ctx[i].ctx = WMesaCreateContext( hWnd, NULL, GL_TRUE, + pix[curPFD-1].doubleBuffered, + pix[curPFD-1].pfd.cAlphaBits ? GL_TRUE : GL_FALSE); + if (wgl_ctx[i].ctx == NULL) + break; + wgl_ctx[i].hdc = hdc; + ctx_count++; + return ((HGLRC)wgl_ctx[i].ctx); + } + } + SetLastError(0); + return(NULL); +} + +WGLAPI BOOL GLAPIENTRY DrvDeleteContext(HGLRC hglrc) +{ + int i; + for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) + { + if ( wgl_ctx[i].ctx == (PWMC) hglrc ) + { + WMesaMakeCurrent((PWMC) hglrc); + WMesaDestroyContext(); + wgl_ctx[i].ctx = NULL; + wgl_ctx[i].hdc = NULL; + ctx_count--; + return(TRUE); + } + } + SetLastError(0); + return(FALSE); +} + +WGLAPI HGLRC GLAPIENTRY DrvCreateLayerContext(HDC hdc,int iLayerPlane) +{ + if (iLayerPlane == 0) + return DrvCreateContext(hdc); + SetLastError(0); + return(NULL); +} + +WGLAPI PICDTABLE GLAPIENTRY DrvSetContext(HDC hdc,HGLRC hglrc,void *callback) +{ + int i; + (void) callback; + + /* new code suggested by Andy Sy */ + if (!hdc || !hglrc) { + WMesaMakeCurrent(NULL); + ctx_current = -1; + return NULL; + } + + for ( i = 0; i < MESAWGL_CTX_MAX_COUNT; i++ ) + { + if ( wgl_ctx[i].ctx == (PWMC) hglrc ) + { + wgl_ctx[i].hdc = hdc; + WMesaMakeCurrent( (PWMC) hglrc ); + ctx_current = i; + return &icdTable; + } + } + return NULL; +} + +WGLAPI void GLAPIENTRY DrvReleaseContext(HGLRC hglrc) +{ + (void) hglrc; + WMesaMakeCurrent(NULL); + ctx_current = -1; +} + +WGLAPI BOOL GLAPIENTRY DrvShareLists(HGLRC hglrc1,HGLRC hglrc2) +{ + (void) hglrc1; (void) hglrc2; + return(TRUE); +} + +WGLAPI BOOL GLAPIENTRY DrvDescribeLayerPlane(HDC hdc,int iPixelFormat, + int iLayerPlane,UINT nBytes, + LPLAYERPLANEDESCRIPTOR plpd) +{ + (void) hdc; (void) iPixelFormat; (void) iLayerPlane; (void) nBytes; (void) plpd; + SetLastError(0); + return(FALSE); +} + +WGLAPI int GLAPIENTRY DrvSetLayerPaletteEntries(HDC hdc,int iLayerPlane, + int iStart,int cEntries, + CONST COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WGLAPI int GLAPIENTRY DrvGetLayerPaletteEntries(HDC hdc,int iLayerPlane, + int iStart,int cEntries, + COLORREF *pcr) +{ + (void) hdc; (void) iLayerPlane; (void) iStart; (void) cEntries; (void) pcr; + SetLastError(0); + return(0); +} + +WGLAPI BOOL GLAPIENTRY DrvRealizeLayerPalette(HDC hdc,int iLayerPlane,BOOL bRealize) +{ + (void) hdc; (void) iLayerPlane; (void) bRealize; + SetLastError(0); + return(FALSE); +} + +WGLAPI BOOL GLAPIENTRY DrvSwapLayerBuffers(HDC hdc,UINT fuPlanes) +{ + (void) fuPlanes; + if( !hdc ) + { + WMesaSwapBuffers(); + return(TRUE); + } + SetLastError(0); + return(FALSE); +} + +WGLAPI int GLAPIENTRY DrvDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes, + LPPIXELFORMATDESCRIPTOR ppfd) +{ + int qt_valid_pix; + (void) hdc; + + qt_valid_pix = qt_pix; + if(ppfd == NULL) + return(qt_valid_pix); + if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || nBytes != sizeof(PIXELFORMATDESCRIPTOR)) + { + SetLastError(0); + return(0); + } + *ppfd = pix[iPixelFormat - 1].pfd; + return(qt_valid_pix); +} + +/* +* GetProcAddress - return the address of an appropriate extension +*/ +WGLAPI PROC GLAPIENTRY DrvGetProcAddress(LPCSTR lpszProc) +{ + PROC p = (PROC) (int) _glapi_get_proc_address((const char *) lpszProc); + if (p) + return p; + + SetLastError(0); + return(NULL); +} + +WGLAPI BOOL GLAPIENTRY DrvSetPixelFormat(HDC hdc,int iPixelFormat) +{ + int qt_valid_pix; + (void) hdc; + + qt_valid_pix = qt_pix; + if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix) + { + SetLastError(0); + return(FALSE); + } + curPFD = iPixelFormat; + return(TRUE); +} + +WGLAPI BOOL GLAPIENTRY DrvSwapBuffers(HDC hdc) +{ + (void) hdc; + if (ctx_current < 0) + return FALSE; + + if(wgl_ctx[ctx_current].ctx == NULL) { + SetLastError(0); + return(FALSE); + } + WMesaSwapBuffers(); + return(TRUE); +} + +WGLAPI BOOL GLAPIENTRY DrvValidateVersion(DWORD version) +{ + (void) version; + return TRUE; +} diff --git a/mesalib/src/mesa/drivers/windows/icd/icdlist.h b/mesalib/src/mesa/drivers/windows/icd/icdlist.h new file mode 100644 index 000000000..1318804cf --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/icd/icdlist.h @@ -0,0 +1,336 @@ +ICD_ENTRY(NewList) /* 0 */ +ICD_ENTRY(EndList) /* 1 */ +ICD_ENTRY(CallList) /* 2 */ +ICD_ENTRY(CallLists) /* 3 */ +ICD_ENTRY(DeleteLists) /* 4 */ +ICD_ENTRY(GenLists) /* 5 */ +ICD_ENTRY(ListBase) /* 6 */ +ICD_ENTRY(Begin) /* 7 */ +ICD_ENTRY(Bitmap) /* 8 */ +ICD_ENTRY(Color3b) /* 9 */ +ICD_ENTRY(Color3bv) /* 10 */ +ICD_ENTRY(Color3d) /* 11 */ +ICD_ENTRY(Color3dv) /* 12 */ +ICD_ENTRY(Color3f) /* 13 */ +ICD_ENTRY(Color3fv) /* 14 */ +ICD_ENTRY(Color3i) /* 15 */ +ICD_ENTRY(Color3iv) /* 16 */ +ICD_ENTRY(Color3s) /* 17 */ +ICD_ENTRY(Color3sv) /* 18 */ +ICD_ENTRY(Color3ub) /* 19 */ +ICD_ENTRY(Color3ubv) /* 20 */ +ICD_ENTRY(Color3ui) /* 21 */ +ICD_ENTRY(Color3uiv) /* 22 */ +ICD_ENTRY(Color3us) /* 23 */ +ICD_ENTRY(Color3usv) /* 24 */ +ICD_ENTRY(Color4b) /* 25 */ +ICD_ENTRY(Color4bv) /* 26 */ +ICD_ENTRY(Color4d) /* 27 */ +ICD_ENTRY(Color4dv) /* 28 */ +ICD_ENTRY(Color4f) /* 29 */ +ICD_ENTRY(Color4fv) /* 30 */ +ICD_ENTRY(Color4i) /* 31 */ +ICD_ENTRY(Color4iv) /* 32 */ +ICD_ENTRY(Color4s) /* 33 */ +ICD_ENTRY(Color4sv) /* 34 */ +ICD_ENTRY(Color4ub) /* 35 */ +ICD_ENTRY(Color4ubv) /* 36 */ +ICD_ENTRY(Color4ui) /* 37 */ +ICD_ENTRY(Color4uiv) /* 38 */ +ICD_ENTRY(Color4us) /* 39 */ +ICD_ENTRY(Color4usv) /* 40 */ +ICD_ENTRY(EdgeFlag) /* 41 */ +ICD_ENTRY(EdgeFlagv) /* 42 */ +ICD_ENTRY(End) /* 43 */ +ICD_ENTRY(Indexd) /* 44 */ +ICD_ENTRY(Indexdv) /* 45 */ +ICD_ENTRY(Indexf) /* 46 */ +ICD_ENTRY(Indexfv) /* 47 */ +ICD_ENTRY(Indexi) /* 48 */ +ICD_ENTRY(Indexiv) /* 49 */ +ICD_ENTRY(Indexs) /* 50 */ +ICD_ENTRY(Indexsv) /* 51 */ +ICD_ENTRY(Normal3b) /* 52 */ +ICD_ENTRY(Normal3bv) /* 53 */ +ICD_ENTRY(Normal3d) /* 54 */ +ICD_ENTRY(Normal3dv) /* 55 */ +ICD_ENTRY(Normal3f) /* 56 */ +ICD_ENTRY(Normal3fv) /* 57 */ +ICD_ENTRY(Normal3i) /* 58 */ +ICD_ENTRY(Normal3iv) /* 59 */ +ICD_ENTRY(Normal3s) /* 60 */ +ICD_ENTRY(Normal3sv) /* 61 */ +ICD_ENTRY(RasterPos2d) /* 62 */ +ICD_ENTRY(RasterPos2dv) /* 63 */ +ICD_ENTRY(RasterPos2f) /* 64 */ +ICD_ENTRY(RasterPos2fv) /* 65 */ +ICD_ENTRY(RasterPos2i) /* 66 */ +ICD_ENTRY(RasterPos2iv) /* 67 */ +ICD_ENTRY(RasterPos2s) /* 68 */ +ICD_ENTRY(RasterPos2sv) /* 69 */ +ICD_ENTRY(RasterPos3d) /* 70 */ +ICD_ENTRY(RasterPos3dv) /* 71 */ +ICD_ENTRY(RasterPos3f) /* 72 */ +ICD_ENTRY(RasterPos3fv) /* 73 */ +ICD_ENTRY(RasterPos3i) /* 74 */ +ICD_ENTRY(RasterPos3iv) /* 75 */ +ICD_ENTRY(RasterPos3s) /* 76 */ +ICD_ENTRY(RasterPos3sv) /* 77 */ +ICD_ENTRY(RasterPos4d) /* 78 */ +ICD_ENTRY(RasterPos4dv) /* 79 */ +ICD_ENTRY(RasterPos4f) /* 80 */ +ICD_ENTRY(RasterPos4fv) /* 81 */ +ICD_ENTRY(RasterPos4i) /* 82 */ +ICD_ENTRY(RasterPos4iv) /* 83 */ +ICD_ENTRY(RasterPos4s) /* 84 */ +ICD_ENTRY(RasterPos4sv) /* 85 */ +ICD_ENTRY(Rectd) /* 86 */ +ICD_ENTRY(Rectdv) /* 87 */ +ICD_ENTRY(Rectf) /* 88 */ +ICD_ENTRY(Rectfv) /* 89 */ +ICD_ENTRY(Recti) /* 90 */ +ICD_ENTRY(Rectiv) /* 91 */ +ICD_ENTRY(Rects) /* 92 */ +ICD_ENTRY(Rectsv) /* 93 */ +ICD_ENTRY(TexCoord1d) /* 94 */ +ICD_ENTRY(TexCoord1dv) /* 95 */ +ICD_ENTRY(TexCoord1f) /* 96 */ +ICD_ENTRY(TexCoord1fv) /* 97 */ +ICD_ENTRY(TexCoord1i) /* 98 */ +ICD_ENTRY(TexCoord1iv) /* 99 */ +ICD_ENTRY(TexCoord1s) /* 100 */ +ICD_ENTRY(TexCoord1sv) /* 101 */ +ICD_ENTRY(TexCoord2d) /* 102 */ +ICD_ENTRY(TexCoord2dv) /* 103 */ +ICD_ENTRY(TexCoord2f) /* 104 */ +ICD_ENTRY(TexCoord2fv) /* 105 */ +ICD_ENTRY(TexCoord2i) /* 106 */ +ICD_ENTRY(TexCoord2iv) /* 107 */ +ICD_ENTRY(TexCoord2s) /* 108 */ +ICD_ENTRY(TexCoord2sv) /* 109 */ +ICD_ENTRY(TexCoord3d) /* 110 */ +ICD_ENTRY(TexCoord3dv) /* 111 */ +ICD_ENTRY(TexCoord3f) /* 112 */ +ICD_ENTRY(TexCoord3fv) /* 113 */ +ICD_ENTRY(TexCoord3i) /* 114 */ +ICD_ENTRY(TexCoord3iv) /* 115 */ +ICD_ENTRY(TexCoord3s) /* 116 */ +ICD_ENTRY(TexCoord3sv) /* 117 */ +ICD_ENTRY(TexCoord4d) /* 118 */ +ICD_ENTRY(TexCoord4dv) /* 119 */ +ICD_ENTRY(TexCoord4f) /* 120 */ +ICD_ENTRY(TexCoord4fv) /* 121 */ +ICD_ENTRY(TexCoord4i) /* 122 */ +ICD_ENTRY(TexCoord4iv) /* 123 */ +ICD_ENTRY(TexCoord4s) /* 124 */ +ICD_ENTRY(TexCoord4sv) /* 125 */ +ICD_ENTRY(Vertex2d) /* 126 */ +ICD_ENTRY(Vertex2dv) /* 127 */ +ICD_ENTRY(Vertex2f) /* 128 */ +ICD_ENTRY(Vertex2fv) /* 129 */ +ICD_ENTRY(Vertex2i) /* 130 */ +ICD_ENTRY(Vertex2iv) /* 131 */ +ICD_ENTRY(Vertex2s) /* 132 */ +ICD_ENTRY(Vertex2sv) /* 133 */ +ICD_ENTRY(Vertex3d) /* 134 */ +ICD_ENTRY(Vertex3dv) /* 135 */ +ICD_ENTRY(Vertex3f) /* 136 */ +ICD_ENTRY(Vertex3fv) /* 137 */ +ICD_ENTRY(Vertex3i) /* 138 */ +ICD_ENTRY(Vertex3iv) /* 139 */ +ICD_ENTRY(Vertex3s) /* 140 */ +ICD_ENTRY(Vertex3sv) /* 141 */ +ICD_ENTRY(Vertex4d) /* 142 */ +ICD_ENTRY(Vertex4dv) /* 143 */ +ICD_ENTRY(Vertex4f) /* 144 */ +ICD_ENTRY(Vertex4fv) /* 145 */ +ICD_ENTRY(Vertex4i) /* 146 */ +ICD_ENTRY(Vertex4iv) /* 147 */ +ICD_ENTRY(Vertex4s) /* 148 */ +ICD_ENTRY(Vertex4sv) /* 149 */ +ICD_ENTRY(ClipPlane) /* 150 */ +ICD_ENTRY(ColorMaterial) /* 151 */ +ICD_ENTRY(CullFace) /* 152 */ +ICD_ENTRY(Fogf) /* 153 */ +ICD_ENTRY(Fogfv) /* 154 */ +ICD_ENTRY(Fogi) /* 155 */ +ICD_ENTRY(Fogiv) /* 156 */ +ICD_ENTRY(FrontFace) /* 157 */ +ICD_ENTRY(Hint) /* 158 */ +ICD_ENTRY(Lightf) /* 159 */ +ICD_ENTRY(Lightfv) /* 160 */ +ICD_ENTRY(Lighti) /* 161 */ +ICD_ENTRY(Lightiv) /* 162 */ +ICD_ENTRY(LightModelf) /* 163 */ +ICD_ENTRY(LightModelfv) /* 164 */ +ICD_ENTRY(LightModeli) /* 165 */ +ICD_ENTRY(LightModeliv) /* 166 */ +ICD_ENTRY(LineStipple) /* 167 */ +ICD_ENTRY(LineWidth) /* 168 */ +ICD_ENTRY(Materialf) /* 169 */ +ICD_ENTRY(Materialfv) /* 170 */ +ICD_ENTRY(Materiali) /* 171 */ +ICD_ENTRY(Materialiv) /* 172 */ +ICD_ENTRY(PointSize) /* 173 */ +ICD_ENTRY(PolygonMode) /* 174 */ +ICD_ENTRY(PolygonStipple) /* 175 */ +ICD_ENTRY(Scissor) /* 176 */ +ICD_ENTRY(ShadeModel) /* 177 */ +ICD_ENTRY(TexParameterf) /* 178 */ +ICD_ENTRY(TexParameterfv) /* 179 */ +ICD_ENTRY(TexParameteri) /* 180 */ +ICD_ENTRY(TexParameteriv) /* 181 */ +ICD_ENTRY(TexImage1D) /* 182 */ +ICD_ENTRY(TexImage2D) /* 183 */ +ICD_ENTRY(TexEnvf) /* 184 */ +ICD_ENTRY(TexEnvfv) /* 185 */ +ICD_ENTRY(TexEnvi) /* 186 */ +ICD_ENTRY(TexEnviv) /* 187 */ +ICD_ENTRY(TexGend) /* 188 */ +ICD_ENTRY(TexGendv) /* 189 */ +ICD_ENTRY(TexGenf) /* 190 */ +ICD_ENTRY(TexGenfv) /* 191 */ +ICD_ENTRY(TexGeni) /* 192 */ +ICD_ENTRY(TexGeniv) /* 193 */ +ICD_ENTRY(FeedbackBuffer) /* 194 */ +ICD_ENTRY(SelectBuffer) /* 195 */ +ICD_ENTRY(RenderMode) /* 196 */ +ICD_ENTRY(InitNames) /* 197 */ +ICD_ENTRY(LoadName) /* 198 */ +ICD_ENTRY(PassThrough) /* 199 */ +ICD_ENTRY(PopName) /* 200 */ +ICD_ENTRY(PushName) /* 201 */ +ICD_ENTRY(DrawBuffer) /* 202 */ +ICD_ENTRY(Clear) /* 203 */ +ICD_ENTRY(ClearAccum) /* 204 */ +ICD_ENTRY(ClearIndex) /* 205 */ +ICD_ENTRY(ClearColor) /* 206 */ +ICD_ENTRY(ClearStencil) /* 207 */ +ICD_ENTRY(ClearDepth) /* 208 */ +ICD_ENTRY(StencilMask) /* 209 */ +ICD_ENTRY(ColorMask) /* 210 */ +ICD_ENTRY(DepthMask) /* 211 */ +ICD_ENTRY(IndexMask) /* 212 */ +ICD_ENTRY(Accum) /* 213 */ +ICD_ENTRY(Disable) /* 214 */ +ICD_ENTRY(Enable) /* 215 */ +ICD_ENTRY(Finish) /* 216 */ +ICD_ENTRY(Flush) /* 217 */ +ICD_ENTRY(PopAttrib) /* 218 */ +ICD_ENTRY(PushAttrib) /* 219 */ +ICD_ENTRY(Map1d) /* 220 */ +ICD_ENTRY(Map1f) /* 221 */ +ICD_ENTRY(Map2d) /* 222 */ +ICD_ENTRY(Map2f) /* 223 */ +ICD_ENTRY(MapGrid1d) /* 224 */ +ICD_ENTRY(MapGrid1f) /* 225 */ +ICD_ENTRY(MapGrid2d) /* 226 */ +ICD_ENTRY(MapGrid2f) /* 227 */ +ICD_ENTRY(EvalCoord1d) /* 228 */ +ICD_ENTRY(EvalCoord1dv) /* 229 */ +ICD_ENTRY(EvalCoord1f) /* 230 */ +ICD_ENTRY(EvalCoord1fv) /* 231 */ +ICD_ENTRY(EvalCoord2d) /* 232 */ +ICD_ENTRY(EvalCoord2dv) /* 233 */ +ICD_ENTRY(EvalCoord2f) /* 234 */ +ICD_ENTRY(EvalCoord2fv) /* 235 */ +ICD_ENTRY(EvalMesh1) /* 236 */ +ICD_ENTRY(EvalPoint1) /* 237 */ +ICD_ENTRY(EvalMesh2) /* 238 */ +ICD_ENTRY(EvalPoint2) /* 239 */ +ICD_ENTRY(AlphaFunc) /* 240 */ +ICD_ENTRY(BlendFunc) /* 241 */ +ICD_ENTRY(LogicOp) /* 242 */ +ICD_ENTRY(StencilFunc) /* 243 */ +ICD_ENTRY(StencilOp) /* 244 */ +ICD_ENTRY(DepthFunc) /* 245 */ +ICD_ENTRY(PixelZoom) /* 246 */ +ICD_ENTRY(PixelTransferf) /* 247 */ +ICD_ENTRY(PixelTransferi) /* 248 */ +ICD_ENTRY(PixelStoref) /* 249 */ +ICD_ENTRY(PixelStorei) /* 250 */ +ICD_ENTRY(PixelMapfv) /* 251 */ +ICD_ENTRY(PixelMapuiv) /* 252 */ +ICD_ENTRY(PixelMapusv) /* 253 */ +ICD_ENTRY(ReadBuffer) /* 254 */ +ICD_ENTRY(CopyPixels) /* 255 */ +ICD_ENTRY(ReadPixels) /* 256 */ +ICD_ENTRY(DrawPixels) /* 257 */ +ICD_ENTRY(GetBooleanv) /* 258 */ +ICD_ENTRY(GetClipPlane) /* 259 */ +ICD_ENTRY(GetDoublev) /* 260 */ +ICD_ENTRY(GetError) /* 261 */ +ICD_ENTRY(GetFloatv) /* 262 */ +ICD_ENTRY(GetIntegerv) /* 263 */ +ICD_ENTRY(GetLightfv) /* 264 */ +ICD_ENTRY(GetLightiv) /* 265 */ +ICD_ENTRY(GetMapdv) /* 266 */ +ICD_ENTRY(GetMapfv) /* 267 */ +ICD_ENTRY(GetMapiv) /* 268 */ +ICD_ENTRY(GetMaterialfv) /* 269 */ +ICD_ENTRY(GetMaterialiv) /* 270 */ +ICD_ENTRY(GetPixelMapfv) /* 271 */ +ICD_ENTRY(GetPixelMapuiv) /* 272 */ +ICD_ENTRY(GetPixelMapusv) /* 273 */ +ICD_ENTRY(GetPolygonStipple) /* 274 */ +ICD_ENTRY(GetString) /* 275 */ +ICD_ENTRY(GetTexEnvfv) /* 276 */ +ICD_ENTRY(GetTexEnviv) /* 277 */ +ICD_ENTRY(GetTexGendv) /* 278 */ +ICD_ENTRY(GetTexGenfv) /* 279 */ +ICD_ENTRY(GetTexGeniv) /* 280 */ +ICD_ENTRY(GetTexImage) /* 281 */ +ICD_ENTRY(GetTexParameterfv) /* 282 */ +ICD_ENTRY(GetTexParameteriv) /* 283 */ +ICD_ENTRY(GetTexLevelParameterfv) /* 284 */ +ICD_ENTRY(GetTexLevelParameteriv) /* 285 */ +ICD_ENTRY(IsEnabled) /* 286 */ +ICD_ENTRY(IsList) /* 287 */ +ICD_ENTRY(DepthRange) /* 288 */ +ICD_ENTRY(Frustum) /* 289 */ +ICD_ENTRY(LoadIdentity) /* 290 */ +ICD_ENTRY(LoadMatrixf) /* 291 */ +ICD_ENTRY(LoadMatrixd) /* 292 */ +ICD_ENTRY(MatrixMode) /* 293 */ +ICD_ENTRY(MultMatrixf) /* 294 */ +ICD_ENTRY(MultMatrixd) /* 295 */ +ICD_ENTRY(Ortho) /* 296 */ +ICD_ENTRY(PopMatrix) /* 297 */ +ICD_ENTRY(PushMatrix) /* 298 */ +ICD_ENTRY(Rotated) /* 299 */ +ICD_ENTRY(Rotatef) /* 300 */ +ICD_ENTRY(Scaled) /* 301 */ +ICD_ENTRY(Scalef) /* 302 */ +ICD_ENTRY(Translated) /* 303 */ +ICD_ENTRY(Translatef) /* 304 */ +ICD_ENTRY(Viewport) /* 305 */ +ICD_ENTRY(ArrayElement) /* 306 */ +ICD_ENTRY(BindTexture) /* 307 */ +ICD_ENTRY(ColorPointer) /* 308 */ +ICD_ENTRY(DisableClientState) /* 309 */ +ICD_ENTRY(DrawArrays) /* 310 */ +ICD_ENTRY(DrawElements) /* 311 */ +ICD_ENTRY(EdgeFlagPointer) /* 312 */ +ICD_ENTRY(EnableClientState) /* 313 */ +ICD_ENTRY(IndexPointer) /* 314 */ +ICD_ENTRY(Indexub) /* 315 */ +ICD_ENTRY(Indexubv) /* 316 */ +ICD_ENTRY(InterleavedArrays) /* 317 */ +ICD_ENTRY(NormalPointer) /* 318 */ +ICD_ENTRY(PolygonOffset) /* 319 */ +ICD_ENTRY(TexCoordPointer) /* 320 */ +ICD_ENTRY(VertexPointer) /* 321 */ +ICD_ENTRY(AreTexturesResident) /* 322 */ +ICD_ENTRY(CopyTexImage1D) /* 323 */ +ICD_ENTRY(CopyTexImage2D) /* 324 */ +ICD_ENTRY(CopyTexSubImage1D) /* 325 */ +ICD_ENTRY(CopyTexSubImage2D) /* 326 */ +ICD_ENTRY(DeleteTextures) /* 327 */ +ICD_ENTRY(GenTextures) /* 328 */ +ICD_ENTRY(GetPointerv) /* 329 */ +ICD_ENTRY(IsTexture) /* 330 */ +ICD_ENTRY(PrioritizeTextures) /* 331 */ +ICD_ENTRY(TexSubImage1D) /* 332 */ +ICD_ENTRY(TexSubImage2D) /* 333 */ +ICD_ENTRY(PopClientAttrib) /* 334 */ +ICD_ENTRY(PushClientAttrib) /* 335 */ diff --git a/mesalib/src/mesa/drivers/windows/icd/mesa.def b/mesalib/src/mesa/drivers/windows/icd/mesa.def new file mode 100644 index 000000000..465b380a0 --- /dev/null +++ b/mesalib/src/mesa/drivers/windows/icd/mesa.def @@ -0,0 +1,108 @@ +DESCRIPTION 'Mesa (OpenGL driver) for Win32' +VERSION 6.1 + +EXPORTS +; +; ICD API + DrvCopyContext + DrvCreateContext + DrvCreateLayerContext + DrvDeleteContext + DrvDescribeLayerPlane + DrvDescribePixelFormat + DrvGetLayerPaletteEntries + DrvGetProcAddress + DrvReleaseContext + DrvRealizeLayerPalette + DrvSetContext + DrvSetLayerPaletteEntries + DrvSetPixelFormat + DrvShareLists + DrvSwapBuffers + DrvSwapLayerBuffers + DrvValidateVersion + +; +; Mesa internals - mostly for OSMESA + _vbo_CreateContext + _vbo_DestroyContext + _vbo_InvalidateState + _glapi_get_context + _glapi_get_proc_address + _mesa_buffer_data + _mesa_buffer_map + _mesa_buffer_subdata + _mesa_bzero + _mesa_calloc + _mesa_choose_tex_format + _mesa_compressed_texture_size + _mesa_create_framebuffer + _mesa_create_visual + _mesa_delete_buffer_object + _mesa_delete_texture_object + _mesa_destroy_framebuffer + _mesa_destroy_visual + _mesa_enable_1_3_extensions + _mesa_enable_1_4_extensions + _mesa_enable_1_5_extensions + _mesa_enable_sw_extensions + _mesa_error + _mesa_free + _mesa_free_context_data + _mesa_get_current_context + _mesa_init_default_imports + _mesa_init_driver_functions + _mesa_initialize_context + _mesa_make_current + _mesa_memcpy + _mesa_memset + _mesa_new_buffer_object + _mesa_new_texture_object + _mesa_problem + _mesa_ResizeBuffersMESA + _mesa_store_compressed_teximage1d + _mesa_store_compressed_teximage2d + _mesa_store_compressed_teximage3d + _mesa_store_compressed_texsubimage1d + _mesa_store_compressed_texsubimage2d + _mesa_store_compressed_texsubimage3d + _mesa_store_teximage1d + _mesa_store_teximage2d + _mesa_store_teximage3d + _mesa_store_texsubimage1d + _mesa_store_texsubimage2d + _mesa_store_texsubimage3d + _mesa_strcmp + _mesa_test_proxy_teximage + _mesa_Viewport + _swrast_Accum + _swrast_Bitmap + _swrast_CopyPixels + _swrast_DrawBuffer + _swrast_DrawPixels + _swrast_GetDeviceDriverReference + _swrast_Clear + _swrast_choose_line + _swrast_choose_triangle + _swrast_CopyColorSubTable + _swrast_CopyColorTable + _swrast_CopyConvolutionFilter1D + _swrast_CopyConvolutionFilter2D + _swrast_copy_teximage1d + _swrast_copy_teximage2d + _swrast_copy_texsubimage1d + _swrast_copy_texsubimage2d + _swrast_copy_texsubimage3d + _swrast_CreateContext + _swrast_DestroyContext + _swrast_InvalidateState + _swrast_ReadPixels + _swsetup_Wakeup + _swsetup_CreateContext + _swsetup_DestroyContext + _swsetup_InvalidateState + _tnl_CreateContext + _tnl_DestroyContext + _tnl_InvalidateState + _tnl_MakeCurrent + _tnl_run_pipeline |