X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fcontext.c;h=0d1f71c7142450318da3d6ce7c8a090927efbf85;hb=43b05b8fac68784bc8d61851125bd49783e5ebd0;hp=0508378b7becbb9b970d3e5419fa5810b863bc59;hpb=406df38a6673cb7d19ce652f71fac1047b2279d0;p=mesa.git diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 0508378b7be..0d1f71c7142 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -1,6 +1,5 @@ /* * Mesa 3-D graphics library - * Version: 7.3 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * Copyright (C) 2008 VMware, Inc. All Rights Reserved. @@ -18,9 +17,10 @@ * 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. + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. */ /** @@ -77,10 +77,10 @@ #include "glheader.h" -#include "mfeatures.h" #include "imports.h" #include "accum.h" #include "api_exec.h" +#include "api_loopback.h" #include "arrayobj.h" #include "attrib.h" #include "blend.h" @@ -105,6 +105,7 @@ #include "macros.h" #include "matrix.h" #include "multisample.h" +#include "performance_monitor.h" #include "pixel.h" #include "pixelstore.h" #include "points.h" @@ -343,23 +344,17 @@ dummy_enum_func(void) { gl_buffer_index bi = BUFFER_FRONT_LEFT; gl_face_index fi = FACE_POS_X; - gl_frag_attrib fa = FRAG_ATTRIB_WPOS; gl_frag_result fr = FRAG_RESULT_DEPTH; gl_texture_index ti = TEXTURE_2D_ARRAY_INDEX; gl_vert_attrib va = VERT_ATTRIB_POS; - gl_vert_result vr = VERT_RESULT_HPOS; - gl_geom_attrib ga = GEOM_ATTRIB_POSITION; - gl_geom_result gr = GEOM_RESULT_POS; + gl_varying_slot vs = VARYING_SLOT_POS; (void) bi; (void) fi; - (void) fa; (void) fr; (void) ti; (void) va; - (void) vr; - (void) ga; - (void) gr; + (void) vs; } @@ -409,7 +404,7 @@ one_time_init( struct gl_context *ctx ) #if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) if (MESA_VERBOSE != 0) { _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", - MESA_VERSION_STRING, __DATE__, __TIME__); + PACKAGE_VERSION, __DATE__, __TIME__); } #endif @@ -484,18 +479,24 @@ init_program_limits(struct gl_context *ctx, GLenum type, prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; prog->MaxUniformComponents = 4 * MAX_UNIFORMS; + prog->MaxInputComponents = 0; /* value not used */ + prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */ break; case GL_FRAGMENT_PROGRAM_ARB: prog->MaxParameters = MAX_NV_FRAGMENT_PROGRAM_PARAMS; prog->MaxAttribs = MAX_NV_FRAGMENT_PROGRAM_INPUTS; prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; prog->MaxUniformComponents = 4 * MAX_UNIFORMS; + prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */ + prog->MaxOutputComponents = 0; /* value not used */ break; case MESA_GEOMETRY_PROGRAM: prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; prog->MaxUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS; + prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */ + prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */ break; default: assert(0 && "Bad program type in init_program_limits()"); @@ -557,12 +558,13 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; ctx->Const.MaxArrayTextureLayers = MAX_ARRAY_TEXTURE_LAYERS; ctx->Const.MaxTextureCoordUnits = MAX_TEXTURE_COORD_UNITS; - ctx->Const.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + ctx->Const.FragmentProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxTextureUnits = MIN2(ctx->Const.MaxTextureCoordUnits, - ctx->Const.MaxTextureImageUnits); + ctx->Const.FragmentProgram.MaxTextureImageUnits); ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY; ctx->Const.MaxTextureLodBias = MAX_TEXTURE_LOD_BIAS; ctx->Const.MaxTextureBufferSize = 65536; + ctx->Const.TextureBufferOffsetAlignment = 1; ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE; ctx->Const.SubPixelBits = SUB_PIXEL_BITS; ctx->Const.MinPointSize = MIN_POINT_SIZE; @@ -575,7 +577,6 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MinLineWidthAA = MIN_LINE_WIDTH; ctx->Const.MaxLineWidthAA = MAX_LINE_WIDTH; ctx->Const.LineWidthGranularity = (GLfloat) LINE_WIDTH_GRANULARITY; - ctx->Const.MaxColorTableSize = MAX_COLOR_TABLE_SIZE; ctx->Const.MaxClipPlanes = 6; ctx->Const.MaxLights = MAX_LIGHTS; ctx->Const.MaxShininess = 128.0; @@ -605,12 +606,10 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxColorAttachments = MAX_COLOR_ATTACHMENTS; ctx->Const.MaxRenderbufferSize = MAX_RENDERBUFFER_SIZE; - ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + ctx->Const.VertexProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; ctx->Const.MaxVarying = 16; /* old limit not to break tnl and swrast */ - ctx->Const.MaxGeometryTextureImageUnits = MAX_GEOMETRY_TEXTURE_IMAGE_UNITS; - ctx->Const.MaxVertexVaryingComponents = MAX_VERTEX_VARYING_COMPONENTS; - ctx->Const.MaxGeometryVaryingComponents = MAX_GEOMETRY_VARYING_COMPONENTS; + ctx->Const.GeometryProgram.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES; ctx->Const.MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; @@ -630,7 +629,7 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxSamples = 0; /* GL_ARB_sync */ - ctx->Const.MaxServerWaitTimeout = (GLuint64) ~0; + ctx->Const.MaxServerWaitTimeout = 0x1fff7fffffffULL; /* GL_ATI_envmap_bumpmap */ ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS; @@ -644,18 +643,32 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS; ctx->Const.MaxVertexStreams = 1; - /* GL 3.2: hard-coded for now: */ - ctx->Const.ProfileMask = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; + /* GL 3.2 */ + ctx->Const.ProfileMask = ctx->API == API_OPENGL_CORE + ? GL_CONTEXT_CORE_PROFILE_BIT + : GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; /** GL_EXT_gpu_shader4 */ ctx->Const.MinProgramTexelOffset = -8; ctx->Const.MaxProgramTexelOffset = 7; + /* GL_ARB_texture_gather */ + ctx->Const.MinProgramTextureGatherOffset = -8; + ctx->Const.MaxProgramTextureGatherOffset = 7; + /* GL_ARB_robustness */ ctx->Const.ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB; /* PrimitiveRestart */ ctx->Const.PrimitiveRestartInSoftware = GL_FALSE; + + /* ES 3.0 or ARB_ES3_compatibility */ + ctx->Const.MaxElementIndex = 0xffffffffu; + + /* GL_ARB_texture_multisample */ + ctx->Const.MaxColorTextureSamples = 1; + ctx->Const.MaxDepthTextureSamples = 1; + ctx->Const.MaxIntegerSamples = 1; } @@ -667,32 +680,30 @@ static void check_context_limits(struct gl_context *ctx) { /* check that we don't exceed the size of various bitfields */ - assert(VERT_RESULT_MAX <= + assert(VARYING_SLOT_MAX <= (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten))); - assert(FRAG_ATTRIB_MAX <= + assert(VARYING_SLOT_MAX <= (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead))); - assert(MAX_COMBINED_TEXTURE_IMAGE_UNITS <= 8 * sizeof(GLbitfield)); - /* shader-related checks */ assert(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); assert(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); /* Texture unit checks */ - assert(ctx->Const.MaxTextureImageUnits > 0); - assert(ctx->Const.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); + assert(ctx->Const.FragmentProgram.MaxTextureImageUnits > 0); + assert(ctx->Const.FragmentProgram.MaxTextureImageUnits <= MAX_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureCoordUnits > 0); assert(ctx->Const.MaxTextureCoordUnits <= MAX_TEXTURE_COORD_UNITS); assert(ctx->Const.MaxTextureUnits > 0); assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_COORD_UNITS); - assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.MaxTextureImageUnits, + assert(ctx->Const.MaxTextureUnits == MIN2(ctx->Const.FragmentProgram.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits)); assert(ctx->Const.MaxCombinedTextureImageUnits > 0); assert(ctx->Const.MaxCombinedTextureImageUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); assert(ctx->Const.MaxTextureCoordUnits <= MAX_COMBINED_TEXTURE_IMAGE_UNITS); /* number of coord units cannot be greater than number of image units */ - assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.MaxTextureImageUnits); + assert(ctx->Const.MaxTextureCoordUnits <= ctx->Const.FragmentProgram.MaxTextureImageUnits); /* Texture size checks */ @@ -758,6 +769,7 @@ init_attrib_groups(struct gl_context *ctx) _mesa_init_lighting( ctx ); _mesa_init_matrix( ctx ); _mesa_init_multisample( ctx ); + _mesa_init_performance_monitors( ctx ); _mesa_init_pixel( ctx ); _mesa_init_pixelstore( ctx ); _mesa_init_point( ctx ); @@ -832,7 +844,7 @@ _mesa_generic_nop(void) * Allocate and initialize a new dispatch table. */ struct _glapi_table * -_mesa_alloc_dispatch_table(int size) +_mesa_alloc_dispatch_table() { /* Find the larger of Mesa's dispatch table and libGL's dispatch table. * In practice, this'll be the same for stand-alone Mesa. But for DRI @@ -842,9 +854,6 @@ _mesa_alloc_dispatch_table(int size) GLint numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); struct _glapi_table *table; - /* should never happen, but just in case */ - numEntries = MAX2(numEntries, size); - table = malloc(numEntries * sizeof(_glapi_proc)); if (table) { _glapi_proc *entry = (_glapi_proc *) table; @@ -856,6 +865,90 @@ _mesa_alloc_dispatch_table(int size) return table; } +/** + * Creates a minimal dispatch table for use within glBegin()/glEnd(). + * + * This ensures that we generate GL_INVALID_OPERATION errors from most + * functions, since the set of functions that are valid within Begin/End is + * very small. + * + * From the GL 1.0 specification section 2.6.3, "GL Commands within + * Begin/End" + * + * "The only GL commands that are allowed within any Begin/End pairs are + * the commands for specifying vertex coordinates, vertex color, normal + * coordinates, and texture coordinates (Vertex, Color, Index, Normal, + * TexCoord), EvalCoord and EvalPoint commands (see section 5.1), + * commands for specifying lighting material parameters (Material + * commands see section 2.12.2), display list invocation commands + * (CallList and CallLists see section 5.4), and the EdgeFlag + * command. Executing Begin after Begin has already been executed but + * before an End is issued generates the INVALID OPERATION error, as does + * executing End without a previous corresponding Begin. Executing any + * other GL command within Begin/End results in the error INVALID + * OPERATION." + * + * The table entries for specifying vertex attributes are set up by + * install_vtxfmt() and _mesa_loopback_init_api_table(), and End() and dlists + * are set by install_vtxfmt() as well. + */ +static struct _glapi_table * +create_beginend_table(const struct gl_context *ctx) +{ + struct _glapi_table *table; + + table = _mesa_alloc_dispatch_table(); + if (!table) + return NULL; + + /* Fill in functions which return a value, since they should return some + * specific value even if they emit a GL_INVALID_OPERATION error from them + * being called within glBegin()/glEnd(). + */ +#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec)) + + COPY_DISPATCH(GenLists); + COPY_DISPATCH(IsProgram); + COPY_DISPATCH(IsVertexArray); + COPY_DISPATCH(IsBuffer); + COPY_DISPATCH(IsEnabled); + COPY_DISPATCH(IsEnabledi); + COPY_DISPATCH(IsRenderbuffer); + COPY_DISPATCH(IsFramebuffer); + COPY_DISPATCH(CheckFramebufferStatus); + COPY_DISPATCH(RenderMode); + COPY_DISPATCH(GetString); + COPY_DISPATCH(GetStringi); + COPY_DISPATCH(GetPointerv); + COPY_DISPATCH(IsQuery); + COPY_DISPATCH(IsSampler); + COPY_DISPATCH(IsSync); + COPY_DISPATCH(IsTexture); + COPY_DISPATCH(IsTransformFeedback); + COPY_DISPATCH(DeleteQueries); + COPY_DISPATCH(AreTexturesResident); + COPY_DISPATCH(FenceSync); + COPY_DISPATCH(ClientWaitSync); + COPY_DISPATCH(MapBuffer); + COPY_DISPATCH(UnmapBuffer); + COPY_DISPATCH(MapBufferRange); + COPY_DISPATCH(ObjectPurgeableAPPLE); + COPY_DISPATCH(ObjectUnpurgeableAPPLE); + + _mesa_loopback_init_api_table(ctx, table); + + return table; +} + +void +_mesa_initialize_dispatch_tables(struct gl_context *ctx) +{ + /* Do the code-generated setup of the exec table in api_exec.c. */ + _mesa_initialize_exec_table(ctx); + + if (ctx->Save) + _mesa_initialize_save_table(ctx); +} /** * Initialize a struct gl_context struct (rendering context). @@ -930,19 +1023,15 @@ _mesa_initialize_context(struct gl_context *ctx, _mesa_reference_shared_state(ctx, &ctx->Shared, shared); - if (!init_attrib_groups( ctx )) { - _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); - return GL_FALSE; - } - - /* setup the API dispatch tables */ - ctx->Exec = _mesa_create_exec_table(ctx); + if (!init_attrib_groups( ctx )) + goto fail; - if (!ctx->Exec) { - _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); - return GL_FALSE; - } - ctx->CurrentDispatch = ctx->Exec; + /* setup the API dispatch tables with all nop functions */ + ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table(); + if (!ctx->OutsideBeginEnd) + goto fail; + ctx->Exec = ctx->OutsideBeginEnd; + ctx->CurrentDispatch = ctx->OutsideBeginEnd; ctx->FragmentProgram._MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL); @@ -963,15 +1052,12 @@ _mesa_initialize_context(struct gl_context *ctx, sizeof(ctx->TextureFormatSupported)); switch (ctx->API) { - case API_OPENGL: - ctx->Save = _mesa_create_save_table(ctx); - if (!ctx->Save) { - _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); - free(ctx->Exec); - return GL_FALSE; - } + case API_OPENGL_COMPAT: + ctx->BeginEnd = create_beginend_table(ctx); + ctx->Save = _mesa_alloc_dispatch_table(); + if (!ctx->BeginEnd || !ctx->Save) + goto fail; - _mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt ); /* fall-through */ case API_OPENGL_CORE: break; @@ -993,13 +1079,19 @@ _mesa_initialize_context(struct gl_context *ctx, case API_OPENGLES2: ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; - ctx->Point.PointSprite = GL_TRUE; /* always on for ES 2.x */ break; } ctx->FirstTimeCurrent = GL_TRUE; return GL_TRUE; + +fail: + _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); + free(ctx->BeginEnd); + free(ctx->Exec); + free(ctx->Save); + return GL_FALSE; } @@ -1096,6 +1188,7 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj, NULL); /* free dispatch tables */ + free(ctx->BeginEnd); free(ctx->Exec); free(ctx->Save); @@ -1308,25 +1401,6 @@ check_compatible(const struct gl_context *ctx, } -/** - * Do one-time initialization for the given framebuffer. Specifically, - * ask the driver for the window's current size and update the framebuffer - * object to match. - * Really, the device driver should totally take care of this. - */ -static void -initialize_framebuffer_size(struct gl_context *ctx, struct gl_framebuffer *fb) -{ - GLuint width, height; - if (ctx->Driver.GetBufferSize) { - ctx->Driver.GetBufferSize(fb, &width, &height); - if (ctx->Driver.ResizeBuffers) - ctx->Driver.ResizeBuffers(ctx, fb, width, height); - fb->Initialized = GL_TRUE; - } -} - - /** * Check if the viewport/scissor size has not yet been initialized. * Initialize the size if the given width and height are non-zero. @@ -1429,32 +1503,6 @@ _mesa_make_current( struct gl_context *newCtx, */ newCtx->NewState |= _NEW_BUFFERS; -#if 1 - /* We want to get rid of these lines: */ - if (!drawBuffer->Initialized) { - initialize_framebuffer_size(newCtx, drawBuffer); - } - if (readBuffer != drawBuffer && !readBuffer->Initialized) { - initialize_framebuffer_size(newCtx, readBuffer); - } - - _mesa_resizebuffers(newCtx); -#else - /* We want the drawBuffer and readBuffer to be initialized by - * the driver. - * This generally means the Width and Height match the actual - * window size and the renderbuffers (both hardware and software - * based) are allocated to match. The later can generally be - * done with a call to _mesa_resize_framebuffer(). - * - * It's theoretically possible for a buffer to have zero width - * or height, but for now, assert check that the driver did what's - * expected of it. - */ - ASSERT(drawBuffer->Width > 0); - ASSERT(drawBuffer->Height > 0); -#endif - if (drawBuffer) { _mesa_check_init_viewport(newCtx, drawBuffer->Width, drawBuffer->Height); @@ -1462,7 +1510,7 @@ _mesa_make_current( struct gl_context *newCtx, } if (newCtx->FirstTimeCurrent) { - _mesa_compute_version(newCtx); + assert(newCtx->Version > 0); newCtx->Extensions.String = _mesa_make_extension_string(newCtx); @@ -1578,11 +1626,6 @@ _mesa_record_error(struct gl_context *ctx, GLenum error) if (ctx->ErrorValue == GL_NO_ERROR) { ctx->ErrorValue = error; } - - /* Call device driver's error handler, if any. This is used on the Mac. */ - if (ctx->Driver.Error) { - ctx->Driver.Error(ctx); - } } @@ -1645,18 +1688,6 @@ _mesa_Flush(void) } -/** - * Set mvp_with_dp4 flag. If a driver has a preference for DP4 over - * MUL/MAD, or vice versa, call this function to register that. - * Otherwise we default to MUL/MAD. - */ -void -_mesa_set_mvp_with_dp4( struct gl_context *ctx, - GLboolean flag ) -{ - ctx->mvp_with_dp4 = flag; -} - /* * ARB_blend_func_extended - ERRORS section * "The error INVALID_OPERATION is generated by Begin or any procedure that