X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fcontext.c;h=34da16b88f4f8439e716d2ce18d5b45181988a74;hb=7fe5a8e874b2cae2b1ada3f6aab8ca6766753b1e;hp=f4dc4e3c4daace91a3e6302bb676b4501113b99d;hpb=c717604dc4b5119fa9091241535c3efd1370438c;p=mesa.git diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index f4dc4e3c4da..34da16b88f4 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -83,12 +83,15 @@ #include "api_loopback.h" #include "arrayobj.h" #include "attrib.h" +#include "bbox.h" #include "blend.h" #include "buffers.h" #include "bufferobj.h" +#include "conservativeraster.h" #include "context.h" #include "cpuinfo.h" #include "debug.h" +#include "debug_output.h" #include "depth.h" #include "dlist.h" #include "eval.h" @@ -98,6 +101,7 @@ #include "fog.h" #include "formats.h" #include "framebuffer.h" +#include "glthread.h" #include "hint.h" #include "hash.h" #include "light.h" @@ -106,6 +110,7 @@ #include "matrix.h" #include "multisample.h" #include "performance_monitor.h" +#include "performance_query.h" #include "pipelineobj.h" #include "pixel.h" #include "pixelstore.h" @@ -119,10 +124,12 @@ #include "shared.h" #include "shaderobj.h" #include "shaderimage.h" -#include "util/simple_list.h" -#include "util/strtod.h" #include "state.h" +#include "util/debug.h" +#include "util/disk_cache.h" +#include "util/strtod.h" #include "stencil.h" +#include "shaderimage.h" #include "texcompress_s3tc.h" #include "texstate.h" #include "transformfeedback.h" @@ -130,19 +137,19 @@ #include "varray.h" #include "version.h" #include "viewport.h" -#include "vtxfmt.h" +#include "texturebindless.h" #include "program/program.h" -#include "program/prog_print.h" #include "math/m_matrix.h" #include "main/dispatch.h" /* for _gloffset_COUNT */ -#include "uniforms.h" #include "macros.h" +#include "git_sha1.h" #ifdef USE_SPARC_ASM #include "sparc/sparc.h" #endif -#include "glsl_parser_extras.h" +#include "compiler/glsl_types.h" +#include "compiler/glsl/glsl_parser_extras.h" #include @@ -162,7 +169,7 @@ GLfloat _mesa_ubyte_to_float_color_tab[256]; /** * Swap buffers notification callback. - * + * * \param ctx GL context. * * Called by window system just before swapping buffers. @@ -188,7 +195,7 @@ _mesa_notifySwapBuffers(struct gl_context *ctx) /** * Allocates a struct gl_config structure and initializes it via * _mesa_initialize_visual(). - * + * * \param dbFlag double buffering * \param stereoFlag stereo buffer * \param depthBits requested bits per depth buffer value. Any value in [0, 32] @@ -204,7 +211,7 @@ _mesa_notifySwapBuffers(struct gl_context *ctx) * \param blueBits same as above. * \param alphaBits same as above. * \param numSamples not really used. - * + * * \return pointer to new struct gl_config or NULL if requested parameters * can't be met. * @@ -223,7 +230,7 @@ _mesa_create_visual( GLboolean dbFlag, GLint accumGreenBits, GLint accumBlueBits, GLint accumAlphaBits, - GLint numSamples ) + GLuint numSamples ) { struct gl_config *vis = CALLOC_STRUCT(gl_config); if (vis) { @@ -265,7 +272,7 @@ _mesa_initialize_visual( struct gl_config *vis, GLint accumGreenBits, GLint accumBlueBits, GLint accumAlphaBits, - GLint numSamples ) + GLuint numSamples ) { assert(vis); @@ -316,7 +323,7 @@ _mesa_initialize_visual( struct gl_config *vis, * Destroy a visual and free its memory. * * \param vis visual. - * + * * Frees the visual structure. */ void @@ -386,7 +393,7 @@ one_time_init( struct gl_context *ctx ) _mesa_locale_init(); - _mesa_one_time_init_extension_overrides(); + _mesa_one_time_init_extension_overrides(ctx); _mesa_get_cpu_features(); @@ -396,22 +403,15 @@ one_time_init( struct gl_context *ctx ) atexit(one_time_fini); -#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) +#if defined(DEBUG) if (MESA_VERBOSE != 0) { - _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", - PACKAGE_VERSION, __DATE__, __TIME__); + _mesa_debug(ctx, "Mesa " PACKAGE_VERSION " DEBUG build" MESA_GIT_SHA1 "\n"); } #endif - -#ifdef DEBUG - _mesa_test_formats(); -#endif } /* per-API one-time init */ if (!(api_init_mask & (1 << ctx->API))) { - _mesa_init_get_hash(ctx); - _mesa_init_remap_table(); } @@ -435,7 +435,6 @@ _mesa_init_current(struct gl_context *ctx) } /* redo special cases: */ - ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_WEIGHT], 1.0, 0.0, 0.0, 0.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_NORMAL], 0.0, 0.0, 1.0, 1.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR0], 1.0, 1.0, 1.0, 1.0 ); ASSIGN_4V( ctx->Current.Attrib[VERT_ATTRIB_COLOR1], 0.0, 0.0, 0.0, 1.0 ); @@ -478,6 +477,8 @@ init_program_limits(struct gl_constants *consts, gl_shader_stage stage, prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */ prog->MaxOutputComponents = 0; /* value not used */ break; + case MESA_SHADER_TESS_CTRL: + case MESA_SHADER_TESS_EVAL: case MESA_SHADER_GEOMETRY: prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; @@ -554,7 +555,7 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) /* Constants, may be overriden (usually only reduced) by device drivers */ consts->MaxTextureMbytes = MAX_TEXTURE_MBYTES; - consts->MaxTextureLevels = MAX_TEXTURE_LEVELS; + consts->MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1); consts->Max3DTextureLevels = MAX_3D_TEXTURE_LEVELS; consts->MaxCubeTextureLevels = MAX_CUBE_TEXTURE_LEVELS; consts->MaxTextureRectSize = MAX_TEXTURE_RECT_SIZE; @@ -583,8 +584,8 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) consts->MaxLights = MAX_LIGHTS; consts->MaxShininess = 128.0; consts->MaxSpotExponent = 128.0; - consts->MaxViewportWidth = MAX_VIEWPORT_WIDTH; - consts->MaxViewportHeight = MAX_VIEWPORT_HEIGHT; + consts->MaxViewportWidth = 16384; + consts->MaxViewportHeight = 16384; consts->MinMapBufferAlignment = 64; /* Driver must override these values if ARB_viewport_array is supported. */ @@ -602,7 +603,7 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) /** GL_ARB_shader_storage_buffer_object */ consts->MaxCombinedShaderStorageBlocks = 8; consts->MaxShaderStorageBufferBindings = 8; - consts->MaxShaderStorageBlockSize = 16 * 1024 * 1024; + consts->MaxShaderStorageBlockSize = 128 * 1024 * 1024; /* 2^27 */ consts->ShaderStorageBufferOffsetAlignment = 256; /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */ @@ -633,10 +634,7 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) consts->Program[MESA_SHADER_GEOMETRY].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; consts->MaxGeometryOutputVertices = MAX_GEOMETRY_OUTPUT_VERTICES; consts->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; - - /* Shading language version */ - consts->GLSLVersion = 120; - _mesa_override_glsl_version(consts); + consts->MaxGeometryShaderInvocations = MAX_GEOMETRY_SHADER_INVOCATIONS; #ifdef DEBUG consts->GenerateTemporaryNames = true; @@ -651,11 +649,14 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) consts->UniformBooleanTrue = FLOAT_AS_UNION(1.0f).u; /* GL_ARB_sync */ - consts->MaxServerWaitTimeout = 0x1fff7fffffffULL; + consts->MaxServerWaitTimeout = 0x7fffffff7fffffffULL; /* GL_EXT_provoking_vertex */ consts->QuadsFollowProvokingVertexConvention = GL_TRUE; + /** GL_ARB_viewport_array */ + consts->LayerAndVPIndexProvokingVertex = GL_UNDEFINED_VERTEX; + /* GL_EXT_transform_feedback */ consts->MaxTransformFeedbackBuffers = MAX_FEEDBACK_BUFFERS; consts->MaxTransformFeedbackSeparateComponents = 4 * MAX_FEEDBACK_ATTRIBS; @@ -681,6 +682,9 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) /* GL_ARB_robustness */ consts->ResetStrategy = GL_NO_RESET_NOTIFICATION_ARB; + /* GL_KHR_robustness */ + consts->RobustAccess = GL_FALSE; + /* ES 3.0 or ARB_ES3_compatibility */ consts->MaxElementIndex = 0xffffffffu; @@ -706,7 +710,8 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) consts->MaxComputeWorkGroupSize[0] = 1024; consts->MaxComputeWorkGroupSize[1] = 1024; consts->MaxComputeWorkGroupSize[2] = 64; - consts->MaxComputeWorkGroupInvocations = 1024; + /* Enables compute support for GLES 3.1 if >= 128 */ + consts->MaxComputeWorkGroupInvocations = 0; /** GL_ARB_gpu_shader5 */ consts->MinFragmentInterpolationOffset = MIN_FRAGMENT_INTERPOLATION_OFFSET; @@ -714,6 +719,29 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) /** GL_KHR_context_flush_control */ consts->ContextReleaseBehavior = GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH; + + /** GL_ARB_tessellation_shader */ + consts->MaxTessGenLevel = MAX_TESS_GEN_LEVEL; + consts->MaxPatchVertices = MAX_PATCH_VERTICES; + consts->Program[MESA_SHADER_TESS_CTRL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + consts->Program[MESA_SHADER_TESS_EVAL].MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + consts->MaxTessPatchComponents = MAX_TESS_PATCH_COMPONENTS; + consts->MaxTessControlTotalOutputComponents = MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS; + consts->PrimitiveRestartForPatches = false; + + /** GL_ARB_compute_variable_group_size */ + consts->MaxComputeVariableGroupSize[0] = 512; + consts->MaxComputeVariableGroupSize[1] = 512; + consts->MaxComputeVariableGroupSize[2] = 64; + consts->MaxComputeVariableGroupInvocations = 512; + + /** GL_NV_conservative_raster */ + consts->MaxSubpixelPrecisionBiasBits = 0; + + /** GL_NV_conservative_raster_dilate */ + consts->ConservativeRasterDilateRange[0] = 0.0; + consts->ConservativeRasterDilateRange[1] = 0.0; + consts->ConservativeRasterDilateGranularity = 0.0; } @@ -728,9 +756,9 @@ check_context_limits(struct gl_context *ctx) /* check that we don't exceed the size of various bitfields */ assert(VARYING_SLOT_MAX <= - (8 * sizeof(ctx->VertexProgram._Current->Base.OutputsWritten))); + (8 * sizeof(ctx->VertexProgram._Current->info.outputs_written))); assert(VARYING_SLOT_MAX <= - (8 * sizeof(ctx->FragmentProgram._Current->Base.InputsRead))); + (8 * sizeof(ctx->FragmentProgram._Current->info.inputs_read))); /* shader-related checks */ assert(ctx->Const.Program[MESA_SHADER_FRAGMENT].MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); @@ -754,7 +782,7 @@ check_context_limits(struct gl_context *ctx) /* Texture size checks */ - assert(ctx->Const.MaxTextureLevels <= MAX_TEXTURE_LEVELS); + assert(ctx->Const.MaxTextureSize <= (1 << (MAX_TEXTURE_LEVELS - 1))); assert(ctx->Const.Max3DTextureLevels <= MAX_3D_TEXTURE_LEVELS); assert(ctx->Const.MaxCubeTextureLevels <= MAX_CUBE_TEXTURE_LEVELS); assert(ctx->Const.MaxTextureRectSize <= MAX_TEXTURE_RECT_SIZE); @@ -764,10 +792,8 @@ check_context_limits(struct gl_context *ctx) assert(MAX_TEXTURE_LEVELS >= MAX_CUBE_TEXTURE_LEVELS); /* Max texture size should be <= max viewport size (render to texture) */ - assert((1U << (ctx->Const.MaxTextureLevels - 1)) - <= ctx->Const.MaxViewportWidth); - assert((1U << (ctx->Const.MaxTextureLevels - 1)) - <= ctx->Const.MaxViewportHeight); + assert(ctx->Const.MaxTextureSize <= ctx->Const.MaxViewportWidth); + assert(ctx->Const.MaxTextureSize <= ctx->Const.MaxViewportHeight); assert(ctx->Const.MaxDrawBuffers <= MAX_DRAW_BUFFERS); @@ -800,13 +826,15 @@ init_attrib_groups(struct gl_context *ctx) /* Attribute Groups */ _mesa_init_accum( ctx ); _mesa_init_attrib( ctx ); + _mesa_init_bbox( ctx ); _mesa_init_buffer_objects( ctx ); _mesa_init_color( ctx ); + _mesa_init_conservative_raster( ctx ); _mesa_init_current( ctx ); _mesa_init_depth( ctx ); _mesa_init_debug( ctx ); + _mesa_init_debug_output( ctx ); _mesa_init_display_list( ctx ); - _mesa_init_errors( ctx ); _mesa_init_eval( ctx ); _mesa_init_fbobjects( ctx ); _mesa_init_feedback( ctx ); @@ -818,6 +846,7 @@ init_attrib_groups(struct gl_context *ctx) _mesa_init_matrix( ctx ); _mesa_init_multisample( ctx ); _mesa_init_performance_monitors( ctx ); + _mesa_init_performance_queries( ctx ); _mesa_init_pipeline( ctx ); _mesa_init_pixel( ctx ); _mesa_init_pixelstore( ctx ); @@ -834,13 +863,14 @@ init_attrib_groups(struct gl_context *ctx) _mesa_init_transform_feedback( ctx ); _mesa_init_varray( ctx ); _mesa_init_viewport( ctx ); + _mesa_init_resident_handles( ctx ); if (!_mesa_init_texture( ctx )) return GL_FALSE; - _mesa_init_texture_s3tc( ctx ); - /* Miscellaneous */ + ctx->TileRasterOrderIncreasingX = GL_TRUE; + ctx->TileRasterOrderIncreasingY = GL_TRUE; ctx->NewState = _NEW_ALL; ctx->NewDriverState = ~0; ctx->ErrorValue = GL_NO_ERROR; @@ -978,8 +1008,8 @@ _mesa_new_nop_table(unsigned numEntries) * populated with pointers to "no-op" functions. In turn, the no-op * functions will call nop_handler() above. */ -static struct _glapi_table * -alloc_dispatch_table(void) +struct _glapi_table * +_mesa_alloc_dispatch_table(void) { /* 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 @@ -1051,7 +1081,7 @@ create_beginend_table(const struct gl_context *ctx) { struct _glapi_table *table; - table = alloc_dispatch_table(); + table = _mesa_alloc_dispatch_table(); if (!table) return NULL; @@ -1112,7 +1142,7 @@ _mesa_initialize_dispatch_tables(struct gl_context *ctx) * Note that the driver needs to pass in its dd_function_table here since * we need to at least call driverFunctions->NewTextureObject to create the * default texture objects. - * + * * Called by _mesa_create_context(). * * Performs the imports and exports callback tables initialization, and @@ -1164,6 +1194,8 @@ _mesa_initialize_context(struct gl_context *ctx, /* misc one-time initializations */ one_time_init(ctx); + _mesa_init_shader_compiler_types(); + /* Plug in driver functions and context pointer here. * This is important because when we call alloc_shared_state() below * we'll call ctx->Driver.NewTextureObject() to create the default @@ -1187,12 +1219,22 @@ _mesa_initialize_context(struct gl_context *ctx, if (!init_attrib_groups( ctx )) goto fail; + /* KHR_no_error is likely to crash, overflow memory, etc if an application + * has errors so don't enable it for setuid processes. + */ + if (env_var_as_boolean("MESA_NO_ERROR", false)) { +#if !defined(_WIN32) + if (geteuid() == getuid()) +#endif + ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; + } + /* setup the API dispatch tables with all nop functions */ - ctx->OutsideBeginEnd = alloc_dispatch_table(); + ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table(); if (!ctx->OutsideBeginEnd) goto fail; ctx->Exec = ctx->OutsideBeginEnd; - ctx->CurrentDispatch = ctx->OutsideBeginEnd; + ctx->CurrentClientDispatch = ctx->CurrentServerDispatch = ctx->OutsideBeginEnd; ctx->FragmentProgram._MaintainTexEnvProgram = (getenv("MESA_TEX_PROG") != NULL); @@ -1210,12 +1252,12 @@ _mesa_initialize_context(struct gl_context *ctx, * _mesa_choose_tex_format(). */ memset(&ctx->TextureFormatSupported, GL_TRUE, - sizeof(ctx->TextureFormatSupported)); + sizeof(ctx->TextureFormatSupported)); switch (ctx->API) { case API_OPENGL_COMPAT: ctx->BeginEnd = create_beginend_table(ctx); - ctx->Save = alloc_dispatch_table(); + ctx->Save = _mesa_alloc_dispatch_table(); if (!ctx->BeginEnd || !ctx->Save) goto fail; @@ -1227,14 +1269,16 @@ _mesa_initialize_context(struct gl_context *ctx, * GL_OES_texture_cube_map says * "Initially all texture generation modes are set to REFLECTION_MAP_OES" */ - for (i = 0; i < MAX_TEXTURE_UNITS; i++) { - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; - texUnit->GenS.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenT.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenR.Mode = GL_REFLECTION_MAP_NV; - texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV; - texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV; - texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; + for (i = 0; i < ARRAY_SIZE(ctx->Texture.FixedFuncUnit); i++) { + struct gl_fixedfunc_texture_unit *texUnit = + &ctx->Texture.FixedFuncUnit[i]; + + texUnit->GenS.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenT.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenR.Mode = GL_REFLECTION_MAP_NV; + texUnit->GenS._ModeBit = TEXGEN_REFLECTION_MAP_NV; + texUnit->GenT._ModeBit = TEXGEN_REFLECTION_MAP_NV; + texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; } break; case API_OPENGLES2: @@ -1256,53 +1300,15 @@ fail: } -/** - * Allocate and initialize a struct gl_context structure. - * Note that the driver needs to pass in its dd_function_table here since - * we need to at least call driverFunctions->NewTextureObject to initialize - * the rendering context. - * - * \param api the GL API type to create the context for - * \param visual a struct gl_config pointer (we copy the struct contents) or - * NULL to create a configless context - * \param share_list another context to share display lists with or NULL - * \param driverFunctions points to the dd_function_table into which the - * driver has plugged in all its special functions. - * - * \return pointer to a new __struct gl_contextRec or NULL if error. - */ -struct gl_context * -_mesa_create_context(gl_api api, - const struct gl_config *visual, - struct gl_context *share_list, - const struct dd_function_table *driverFunctions) -{ - struct gl_context *ctx; - - ctx = calloc(1, sizeof(struct gl_context)); - if (!ctx) - return NULL; - - if (_mesa_initialize_context(ctx, api, visual, share_list, - driverFunctions)) { - return ctx; - } - else { - free(ctx); - return NULL; - } -} - - /** * Free the data associated with the given context. - * + * * But doesn't free the struct gl_context struct itself. * * \sa _mesa_initialize_context() and init_attrib_groups(). */ void -_mesa_free_context_data( struct gl_context *ctx ) +_mesa_free_context_data(struct gl_context *ctx, bool destroy_compiler_types) { if (!_mesa_get_current_context()){ /* No current context, but we may need one in order to delete @@ -1317,23 +1323,30 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_reference_framebuffer(&ctx->DrawBuffer, NULL); _mesa_reference_framebuffer(&ctx->ReadBuffer, NULL); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current, NULL); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._Current, NULL); - _mesa_reference_vertprog(ctx, &ctx->VertexProgram._TnlProgram, NULL); + _mesa_reference_program(ctx, &ctx->VertexProgram.Current, NULL); + _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL); + _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, NULL); + + _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL); + _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL); + _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL); - _mesa_reference_geomprog(ctx, &ctx->GeometryProgram._Current, NULL); + _mesa_reference_program(ctx, &ctx->FragmentProgram.Current, NULL); + _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current, NULL); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._Current, NULL); - _mesa_reference_fragprog(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); + _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL); _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL); _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL); + _mesa_reference_vao(ctx, &ctx->Array._EmptyVAO, NULL); + _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL); _mesa_free_attrib_data(ctx); _mesa_free_buffer_objects(ctx); _mesa_free_eval_data( ctx ); _mesa_free_texture_data( ctx ); + _mesa_free_image_textures(ctx); _mesa_free_matrix_data( ctx ); _mesa_free_pipeline_data(ctx); _mesa_free_program_data(ctx); @@ -1343,6 +1356,8 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_free_varray_data(ctx); _mesa_free_transform_feedback(ctx); _mesa_free_performance_monitors(ctx); + _mesa_free_performance_queries(ctx); + _mesa_free_resident_handles(ctx); _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); @@ -1353,6 +1368,8 @@ _mesa_free_context_data( struct gl_context *ctx ) free(ctx->BeginEnd); free(ctx->OutsideBeginEnd); free(ctx->Save); + free(ctx->ContextLost); + free(ctx->MarshalExec); /* Shared context state (display lists, textures, etc) */ _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); @@ -1366,6 +1383,9 @@ _mesa_free_context_data( struct gl_context *ctx ) free(ctx->VersionString); + if (destroy_compiler_types) + _mesa_destroy_shader_compiler_types(); + /* unbind the context if it's currently bound */ if (ctx == _mesa_get_current_context()) { _mesa_make_current(NULL, NULL, NULL); @@ -1377,14 +1397,14 @@ _mesa_free_context_data( struct gl_context *ctx ) * Destroy a struct gl_context structure. * * \param ctx GL context. - * + * * Calls _mesa_free_context_data() and frees the gl_context object itself. */ void _mesa_destroy_context( struct gl_context *ctx ) { if (ctx) { - _mesa_free_context_data(ctx); + _mesa_free_context_data(ctx, true); free( (void *) ctx ); } } @@ -1392,7 +1412,7 @@ _mesa_destroy_context( struct gl_context *ctx ) /** * Copy attribute groups from one context to another. - * + * * \param src source context * \param dst destination context * \param mask bitwise OR of GL_*_BIT flags @@ -1438,16 +1458,8 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst, dst->Hint = src->Hint; } if (mask & GL_LIGHTING_BIT) { - GLuint i; - /* begin with memcpy */ + /* OK to memcpy */ dst->Light = src->Light; - /* fixup linked lists to prevent pointer insanity */ - make_empty_list( &(dst->Light.EnabledList) ); - for (i = 0; i < MAX_LIGHTS; i++) { - if (dst->Light.Light[i].Enabled) { - insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i])); - } - } } if (mask & GL_LINE_BIT) { /* OK to memcpy */ @@ -1513,13 +1525,9 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst, * Check if the given context can render into the given framebuffer * by checking visual attributes. * - * Most of these tests could go away because Mesa is now pretty flexible - * in terms of mixing rendering contexts with framebuffers. As long - * as RGB vs. CI mode agree, we're probably good. - * * \return GL_TRUE if compatible, GL_FALSE otherwise. */ -static GLboolean +static GLboolean check_compatible(const struct gl_context *ctx, const struct gl_framebuffer *buffer) { @@ -1529,32 +1537,18 @@ check_compatible(const struct gl_context *ctx, if (buffer == _mesa_get_incomplete_framebuffer()) return GL_TRUE; -#if 0 - /* disabling this fixes the fgl_glxgears pbuffer demo */ - if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode) - return GL_FALSE; -#endif - if (ctxvis->stereoMode && !bufvis->stereoMode) - return GL_FALSE; - if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer) - return GL_FALSE; - if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer) - return GL_FALSE; - if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer) - return GL_FALSE; - if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask) - return GL_FALSE; - if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask) - return GL_FALSE; - if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask) - return GL_FALSE; -#if 0 - /* disabled (see bug 11161) */ - if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits) - return GL_FALSE; -#endif - if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits) - return GL_FALSE; +#define check_component(foo) \ + if (ctxvis->foo && bufvis->foo && \ + ctxvis->foo != bufvis->foo) \ + return GL_FALSE + + check_component(redMask); + check_component(greenMask); + check_component(blueMask); + check_component(depthBits); + check_component(stencilBits); + +#undef check_component return GL_TRUE; } @@ -1564,8 +1558,8 @@ check_compatible(const struct gl_context *ctx, * Check if the viewport/scissor size has not yet been initialized. * Initialize the size if the given width and height are non-zero. */ -void -_mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) +static void +check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) { if (!ctx->ViewportInitialized && width > 0 && height > 0) { unsigned i; @@ -1585,26 +1579,27 @@ _mesa_check_init_viewport(struct gl_context *ctx, GLuint width, GLuint height) } } + static void handle_first_current(struct gl_context *ctx) { - GLenum buffer; - GLint bufferIndex; - - if (ctx->Version == 0) { + if (ctx->Version == 0 || !ctx->DrawBuffer) { /* probably in the process of tearing down the context */ return; } - ctx->Extensions.String = _mesa_make_extension_string(ctx); - check_context_limits(ctx); + _mesa_update_vertex_processing_mode(ctx); + /* According to GL_MESA_configless_context the default value of * glDrawBuffers depends on the config of the first surface it is bound to. - * For GLES it is always GL_BACK which has a magic interpretation */ + * For GLES it is always GL_BACK which has a magic interpretation. + */ if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) { if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) { + GLenum16 buffer; + if (ctx->DrawBuffer->Visual.doubleBufferMode) buffer = GL_BACK; else @@ -1615,6 +1610,9 @@ handle_first_current(struct gl_context *ctx) } if (ctx->ReadBuffer != _mesa_get_incomplete_framebuffer()) { + gl_buffer_index bufferIndex; + GLenum buffer; + if (ctx->ReadBuffer->Visual.doubleBufferMode) { buffer = GL_BACK; bufferIndex = BUFFER_BACK_LEFT; @@ -1628,6 +1626,23 @@ handle_first_current(struct gl_context *ctx) } } + /* Determine if generic vertex attribute 0 aliases the conventional + * glVertex position. + */ + { + const bool is_forward_compatible_context = + ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; + + /* In OpenGL 3.1 attribute 0 becomes non-magic, just like in OpenGL ES + * 2.0. Note that we cannot just check for API_OPENGL_COMPAT here because + * that will erroneously allow this usage in a 3.0 forward-compatible + * context too. + */ + ctx->_AttribZeroAliasesVertex = (ctx->API == API_OPENGLES + || (ctx->API == API_OPENGL_COMPAT + && !is_forward_compatible_context)); + } + /* We can use this to help debug user's problems. Tell them to set * the MESA_INFO env variable before running their app. Then the * first time each context is made current we'll print some useful @@ -1679,23 +1694,37 @@ _mesa_make_current( struct gl_context *newCtx, } } - if (curCtx && + if (curCtx && (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */ curCtx != newCtx && curCtx->Const.ContextReleaseBehavior == - GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) + GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) { _mesa_flush(curCtx); + } - /* We used to call _glapi_check_multithread() here. Now do it in drivers */ - _glapi_set_context((void *) newCtx); - assert(_mesa_get_current_context() == newCtx); + /* Call this periodically to detect when the user has begun using + * GL rendering from multiple threads. + */ + _glapi_check_multithread(); if (!newCtx) { _glapi_set_dispatch(NULL); /* none current */ + /* We need old ctx to correctly release Draw/ReadBuffer + * and avoid a surface leak in st_renderbuffer_delete. + * Therefore, first drop buffers then set new ctx to NULL. + */ + if (curCtx) { + _mesa_reference_framebuffer(&curCtx->WinSysDrawBuffer, NULL); + _mesa_reference_framebuffer(&curCtx->WinSysReadBuffer, NULL); + } + _glapi_set_context(NULL); + assert(_mesa_get_current_context() == NULL); } else { - _glapi_set_dispatch(newCtx->CurrentDispatch); + _glapi_set_context((void *) newCtx); + assert(_mesa_get_current_context() == newCtx); + _glapi_set_dispatch(newCtx->CurrentClientDispatch); if (drawBuffer && readBuffer) { assert(_mesa_is_winsys_fbo(drawBuffer)); @@ -1717,25 +1746,32 @@ _mesa_make_current( struct gl_context *newCtx, } if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); + /* In _mesa_initialize_window_framebuffer, for single-buffered + * visuals, the ColorReadBuffer is set to be GL_FRONT, even with + * GLES contexts. When calling read_buffer, we verify we are reading + * from GL_BACK in is_legal_es3_readbuffer_enum. But the default is + * incorrect, and certain dEQP tests check this. So fix it here. + */ + if (_mesa_is_gles(newCtx) && + !newCtx->ReadBuffer->Visual.doubleBufferMode) + if (newCtx->ReadBuffer->ColorReadBuffer == GL_FRONT) + newCtx->ReadBuffer->ColorReadBuffer = GL_BACK; } /* XXX only set this flag if we're really changing the draw/read * framebuffer bindings. */ - newCtx->NewState |= _NEW_BUFFERS; + newCtx->NewState |= _NEW_BUFFERS; - if (drawBuffer) { - _mesa_check_init_viewport(newCtx, - drawBuffer->Width, drawBuffer->Height); - } + check_init_viewport(newCtx, drawBuffer->Width, drawBuffer->Height); } if (newCtx->FirstTimeCurrent) { handle_first_current(newCtx); - newCtx->FirstTimeCurrent = GL_FALSE; + newCtx->FirstTimeCurrent = GL_FALSE; } } - + return GL_TRUE; } @@ -1774,7 +1810,7 @@ _mesa_share_state(struct gl_context *ctx, struct gl_context *ctxToShare) /** * \return pointer to the current GL context for this thread. - * + * * Calls _glapi_get_context(). This isn't the fastest way to get the current * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in * context.h. @@ -1789,19 +1825,19 @@ _mesa_get_current_context( void ) /** * Get context's current API dispatch table. * - * It'll either be the immediate-mode execute dispatcher or the display list - * compile dispatcher. - * + * It'll either be the immediate-mode execute dispatcher, the display list + * compile dispatcher, or the thread marshalling dispatcher. + * * \param ctx GL context. * * \return pointer to dispatch_table. * - * Simply returns __struct gl_contextRec::CurrentDispatch. + * Simply returns __struct gl_contextRec::CurrentClientDispatch. */ struct _glapi_table * _mesa_get_dispatch(struct gl_context *ctx) { - return ctx->CurrentDispatch; + return ctx->CurrentClientDispatch; } /*@}*/ @@ -1811,45 +1847,6 @@ _mesa_get_dispatch(struct gl_context *ctx) /** \name Miscellaneous functions */ /**********************************************************************/ /*@{*/ - -/** - * Record an error. - * - * \param ctx GL context. - * \param error error code. - * - * Records the given error code and call the driver's dd_function_table::Error - * function if defined. - * - * \sa - * This is called via _mesa_error(). - */ -void -_mesa_record_error(struct gl_context *ctx, GLenum error) -{ - if (!ctx) - return; - - if (ctx->ErrorValue == GL_NO_ERROR) { - ctx->ErrorValue = error; - } -} - - -/** - * Flush commands and wait for completion. - */ -void -_mesa_finish(struct gl_context *ctx) -{ - FLUSH_VERTICES( ctx, 0 ); - FLUSH_CURRENT( ctx, 0 ); - if (ctx->Driver.Finish) { - ctx->Driver.Finish(ctx); - } -} - - /** * Flush commands. */ @@ -1866,7 +1863,7 @@ _mesa_flush(struct gl_context *ctx) /** - * Execute glFinish(). + * Flush commands and wait for completion. * * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the * dd_function_table::Finish driver callback, if not NULL. @@ -1876,7 +1873,13 @@ _mesa_Finish(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - _mesa_finish(ctx); + + FLUSH_VERTICES(ctx, 0); + FLUSH_CURRENT(ctx, 0); + + if (ctx->Driver.Finish) { + ctx->Driver.Finish(ctx); + } } @@ -1895,193 +1898,4 @@ _mesa_Flush(void) } -/* - * ARB_blend_func_extended - ERRORS section - * "The error INVALID_OPERATION is generated by Begin or any procedure that - * implicitly calls Begin if any draw buffer has a blend function requiring the - * second color input (SRC1_COLOR, ONE_MINUS_SRC1_COLOR, SRC1_ALPHA or - * ONE_MINUS_SRC1_ALPHA), and a framebuffer is bound that has more than - * the value of MAX_DUAL_SOURCE_DRAW_BUFFERS-1 active color attachements." - */ -static GLboolean -_mesa_check_blend_func_error(struct gl_context *ctx) -{ - GLuint i; - for (i = ctx->Const.MaxDualSourceDrawBuffers; - i < ctx->DrawBuffer->_NumColorDrawBuffers; - i++) { - if (ctx->Color.Blend[i]._UsesDualSrc) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "dual source blend on illegal attachment"); - return GL_FALSE; - } - } - return GL_TRUE; -} - -static bool -shader_linked_or_absent(struct gl_context *ctx, - const struct gl_shader_program *shProg, - bool *shader_present, const char *where) -{ - if (shProg) { - *shader_present = true; - - if (!shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(shader not linked)", where); - return false; - } -#if 0 /* not normally enabled */ - { - char errMsg[100]; - if (!_mesa_validate_shader_program(ctx, shProg, errMsg)) { - _mesa_warning(ctx, "Shader program %u is invalid: %s", - shProg->Name, errMsg); - } - } -#endif - } - - return true; -} - -/** - * Prior to drawing anything with glBegin, glDrawArrays, etc. this function - * is called to see if it's valid to render. This involves checking that - * the current shader is valid and the framebuffer is complete. - * It also check the current pipeline object is valid if any. - * If an error is detected it'll be recorded here. - * \return GL_TRUE if OK to render, GL_FALSE if not - */ -GLboolean -_mesa_valid_to_render(struct gl_context *ctx, const char *where) -{ - unsigned i; - - /* This depends on having up to date derived state (shaders) */ - if (ctx->NewState) - _mesa_update_state(ctx); - - if (ctx->API == API_OPENGL_CORE || ctx->API == API_OPENGLES2) { - bool from_glsl_shader[MESA_SHADER_COMPUTE] = { false }; - - for (i = 0; i < MESA_SHADER_COMPUTE; i++) { - if (!shader_linked_or_absent(ctx, ctx->_Shader->CurrentProgram[i], - &from_glsl_shader[i], where)) - return GL_FALSE; - } - - /* In OpenGL Core Profile and OpenGL ES 2.0 / 3.0, there are no assembly - * shaders. Don't check state related to those. - */ - } else { - bool has_vertex_shader = false; - bool has_fragment_shader = false; - - /* In OpenGL Compatibility Profile, there is only vertex shader and - * fragment shader. We take this path also for API_OPENGLES because - * optimizing that path would make the other (more common) paths - * slightly slower. - */ - if (!shader_linked_or_absent(ctx, - ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX], - &has_vertex_shader, where)) - return GL_FALSE; - - if (!shader_linked_or_absent(ctx, - ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT], - &has_fragment_shader, where)) - return GL_FALSE; - - /* Any shader stages that are not supplied by the GLSL shader and have - * assembly shaders enabled must now be validated. - */ - if (!has_vertex_shader - && ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(vertex program not valid)", where); - return GL_FALSE; - } - - if (!has_fragment_shader) { - if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(fragment program not valid)", where); - return GL_FALSE; - } - - /* If drawing to integer-valued color buffers, there must be an - * active fragment shader (GL_EXT_texture_integer). - */ - if (ctx->DrawBuffer && ctx->DrawBuffer->_IntegerColor) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(integer format but no fragment shader)", where); - return GL_FALSE; - } - } - } - - /* A pipeline object is bound */ - if (ctx->_Shader->Name && !ctx->_Shader->Validated) { - /* Error message will be printed inside _mesa_validate_program_pipeline. - */ - if (!_mesa_validate_program_pipeline(ctx, ctx->_Shader, GL_TRUE)) { - return GL_FALSE; - } - } - - /* If a program is active and SSO not in use, check if validation of - * samplers succeeded for the active program. */ - if (ctx->_Shader->ActiveProgram && ctx->_Shader != ctx->Pipeline.Current) { - char errMsg[100]; - if (!_mesa_sampler_uniforms_are_valid(ctx->_Shader->ActiveProgram, - errMsg, 100)) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", errMsg); - return GL_FALSE; - } - } - - if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT, - "%s(incomplete framebuffer)", where); - return GL_FALSE; - } - - if (_mesa_check_blend_func_error(ctx) == GL_FALSE) { - return GL_FALSE; - } - -#ifdef DEBUG - if (ctx->_Shader->Flags & GLSL_LOG) { - struct gl_shader_program **shProg = ctx->_Shader->CurrentProgram; - gl_shader_stage i; - - for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (shProg[i] == NULL || shProg[i]->_Used - || shProg[i]->_LinkedShaders[i] == NULL) - continue; - - /* This is the first time this shader is being used. - * Append shader's constants/uniforms to log file. - * - * Only log data for the program target that matches the shader - * target. It's possible to have a program bound to the vertex - * shader target that also supplied a fragment shader. If that - * program isn't also bound to the fragment shader target we don't - * want to log its fragment data. - */ - _mesa_append_uniforms_to_file(shProg[i]->_LinkedShaders[i]); - } - - for (i = 0; i < MESA_SHADER_STAGES; i++) { - if (shProg[i] != NULL) - shProg[i]->_Used = GL_TRUE; - } - } -#endif - - return GL_TRUE; -} - - /*@}*/