X-Git-Url: https://git.libre-soc.org/?p=mesa.git;a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fcontext.c;h=be2e7df5824e0f75f31ba441083871e66de57445;hp=fe527a0ae29ba42ac479dac33756b834c68dccc0;hb=34fe561895bed253070b7dadaa86b4473ad7b51a;hpb=1b3cbcc7beded588a53d7c67bf0e25db05bf8d1e diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index fe527a0ae29..be2e7df5824 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -77,7 +77,7 @@ #include "glheader.h" -#include "imports.h" + #include "accum.h" #include "api_exec.h" #include "api_loopback.h" @@ -87,6 +87,7 @@ #include "blend.h" #include "buffers.h" #include "bufferobj.h" +#include "conservativeraster.h" #include "context.h" #include "cpuinfo.h" #include "debug.h" @@ -123,9 +124,12 @@ #include "shared.h" #include "shaderobj.h" #include "shaderimage.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" @@ -138,14 +142,17 @@ #include "math/m_matrix.h" #include "main/dispatch.h" /* for _gloffset_COUNT */ #include "macros.h" +#include "git_sha1.h" #ifdef USE_SPARC_ASM #include "sparc/sparc.h" #endif #include "compiler/glsl_types.h" +#include "compiler/glsl/builtin_functions.h" #include "compiler/glsl/glsl_parser_extras.h" #include +#include "util/u_memory.h" #ifndef MESA_VERBOSE @@ -175,7 +182,7 @@ _mesa_notifySwapBuffers(struct gl_context *ctx) { if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS) _mesa_debug(ctx, "SwapBuffers\n"); - FLUSH_CURRENT( ctx, 0 ); + FLUSH_VERTICES(ctx, 0); if (ctx->Driver.Flush) { ctx->Driver.Flush(ctx); } @@ -199,7 +206,6 @@ _mesa_notifySwapBuffers(struct gl_context *ctx) * \param stencilBits requested minimum bits per stencil buffer value * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number * of bits per color component in accum buffer. - * \param indexBits number of bits per pixel if \p rgbFlag is GL_FALSE * \param redBits number of bits per color component in frame buffer for RGB(A) * mode. We always use 8 in core Mesa though. * \param greenBits same as above. @@ -225,7 +231,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) { @@ -267,7 +273,7 @@ _mesa_initialize_visual( struct gl_config *vis, GLint accumGreenBits, GLint accumBlueBits, GLint accumAlphaBits, - GLint numSamples ) + GLuint numSamples ) { assert(vis); @@ -282,7 +288,6 @@ _mesa_initialize_visual( struct gl_config *vis, assert(accumBlueBits >= 0); assert(accumAlphaBits >= 0); - vis->rgbMode = GL_TRUE; vis->doubleBufferMode = dbFlag; vis->stereoMode = stereoFlag; @@ -292,7 +297,6 @@ _mesa_initialize_visual( struct gl_config *vis, vis->alphaBits = alphaBits; vis->rgbBits = redBits + greenBits + blueBits; - vis->indexBits = 0; vis->depthBits = depthBits; vis->stencilBits = stencilBits; @@ -301,10 +305,6 @@ _mesa_initialize_visual( struct gl_config *vis, vis->accumBlueBits = accumBlueBits; vis->accumAlphaBits = accumAlphaBits; - vis->haveAccumBuffer = accumRedBits > 0; - vis->haveDepthBuffer = depthBits > 0; - vis->haveStencilBuffer = stencilBits > 0; - vis->numAuxBuffers = 0; vis->level = 0; vis->sampleBuffers = numSamples > 0 ? 1 : 0; @@ -340,14 +340,6 @@ _mesa_destroy_visual( struct gl_config *vis ) /*@{*/ -/** - * One-time initialization mutex lock. - * - * \sa Used by one_time_init(). - */ -mtx_t OneTimeLock = _MTX_INITIALIZER_NP; - - /** * Calls all the various one-time-fini functions in Mesa */ @@ -355,65 +347,73 @@ mtx_t OneTimeLock = _MTX_INITIALIZER_NP; static void one_time_fini(void) { - _mesa_destroy_shader_compiler(); + glsl_type_singleton_decref(); _mesa_locale_fini(); } /** - * Calls all the various one-time-init functions in Mesa. - * - * While holding a global mutex lock, calls several initialization functions, - * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is - * defined. - * - * \sa _math_init(). + * Calls all the various one-time-init functions in Mesa */ + static void -one_time_init( struct gl_context *ctx ) +one_time_init(void) { - static GLbitfield api_init_mask = 0x0; + GLuint i; - mtx_lock(&OneTimeLock); + STATIC_ASSERT(sizeof(GLbyte) == 1); + STATIC_ASSERT(sizeof(GLubyte) == 1); + STATIC_ASSERT(sizeof(GLshort) == 2); + STATIC_ASSERT(sizeof(GLushort) == 2); + STATIC_ASSERT(sizeof(GLint) == 4); + STATIC_ASSERT(sizeof(GLuint) == 4); - /* truly one-time init */ - if (!api_init_mask) { - GLuint i; + _mesa_locale_init(); - STATIC_ASSERT(sizeof(GLbyte) == 1); - STATIC_ASSERT(sizeof(GLubyte) == 1); - STATIC_ASSERT(sizeof(GLshort) == 2); - STATIC_ASSERT(sizeof(GLushort) == 2); - STATIC_ASSERT(sizeof(GLint) == 4); - STATIC_ASSERT(sizeof(GLuint) == 4); + _mesa_one_time_init_extension_overrides(); - _mesa_locale_init(); + _mesa_get_cpu_features(); - _mesa_one_time_init_extension_overrides(); + for (i = 0; i < 256; i++) { + _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; + } - _mesa_get_cpu_features(); + atexit(one_time_fini); - for (i = 0; i < 256; i++) { - _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; - } +#if defined(DEBUG) + if (MESA_VERBOSE != 0) { + _mesa_debug(NULL, "Mesa " PACKAGE_VERSION " DEBUG build" MESA_GIT_SHA1 "\n"); + } +#endif - atexit(one_time_fini); + /* Take a glsl type reference for the duration of libGL's life to avoid + * unecessary creation/destruction of glsl types. + */ + glsl_type_singleton_init_or_ref(); -#if defined(DEBUG) && defined(__DATE__) && defined(__TIME__) - if (MESA_VERBOSE != 0) { - _mesa_debug(ctx, "Mesa %s DEBUG build %s %s\n", - PACKAGE_VERSION, __DATE__, __TIME__); - } -#endif - } + _mesa_init_remap_table(); +} - /* per-API one-time init */ - if (!(api_init_mask & (1 << ctx->API))) { - _mesa_init_remap_table(); - } +/** + * One-time initialization flag + * + * \sa Used by _mesa_initialize(). + */ +static once_flag init_once = ONCE_FLAG_INIT; - api_init_mask |= 1 << ctx->API; - mtx_unlock(&OneTimeLock); +/** + * Calls all the various one-time-init functions in Mesa. + * + * While holding a global mutex lock, calls several initialization functions, + * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is + * defined. + * + * \sa _math_init(). + */ +void +_mesa_initialize(void) +{ + call_once(&init_once, one_time_init); } @@ -431,7 +431,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 ); @@ -552,7 +551,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; @@ -613,6 +612,19 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) consts->MaxProgramMatrices = MAX_PROGRAM_MATRICES; consts->MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; + /* Set the absolute minimum possible GLSL version. API_OPENGL_CORE can + * mean an OpenGL 3.0 forward-compatible context, so that implies a minimum + * possible version of 1.30. Otherwise, the minimum possible version 1.20. + * Since Mesa unconditionally advertises GL_ARB_shading_language_100 and + * GL_ARB_shader_objects, every driver has GLSL 1.20... even if they don't + * advertise any extensions to enable any shader stages (e.g., + * GL_ARB_vertex_shader). + */ + consts->GLSLVersion = api == API_OPENGL_CORE ? 130 : 120; + consts->GLSLVersionCompat = consts->GLSLVersion; + + consts->GLSLLowerConstArrays = true; + /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that * gl_VertexID is implemented using a native hardware register with OpenGL * semantics. @@ -631,10 +643,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; @@ -649,7 +658,7 @@ _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; @@ -734,6 +743,16 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) 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; + + consts->glBeginEndBufferSize = 512 * 1024; } @@ -774,7 +793,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); @@ -784,10 +803,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); @@ -823,6 +840,7 @@ init_attrib_groups(struct gl_context *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 ); @@ -861,9 +879,9 @@ init_attrib_groups(struct gl_context *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; @@ -932,7 +950,7 @@ nop_handler(const char *name) if (ctx) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid call)", name); } -#if defined(DEBUG) +#ifndef NDEBUG else if (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG")) { fprintf(stderr, "GL User Error: gl%s called without a rendering context\n", @@ -1185,7 +1203,7 @@ _mesa_initialize_context(struct gl_context *ctx, _mesa_override_gl_version(ctx); /* misc one-time initializations */ - one_time_init(ctx); + _mesa_initialize(); /* Plug in driver functions and context pointer here. * This is important because when we call alloc_shared_state() below @@ -1213,7 +1231,7 @@ _mesa_initialize_context(struct gl_context *ctx, /* KHR_no_error is likely to crash, overflow memory, etc if an application * has errors so don't enable it for setuid processes. */ - if (getenv("MESA_NO_ERROR")) { + if (env_var_as_boolean("MESA_NO_ERROR", false)) { #if !defined(_WIN32) if (geteuid() == getuid()) #endif @@ -1260,8 +1278,10 @@ _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]; + 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; @@ -1297,7 +1317,7 @@ fail: * \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) { if (!_mesa_get_current_context()){ /* No current context, but we may need one in order to delete @@ -1324,13 +1344,18 @@ _mesa_free_context_data( struct gl_context *ctx ) _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL); _mesa_reference_program(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); @@ -1367,10 +1392,20 @@ _mesa_free_context_data( struct gl_context *ctx ) free(ctx->VersionString); + ralloc_free(ctx->SoftFP64); + /* unbind the context if it's currently bound */ if (ctx == _mesa_get_current_context()) { _mesa_make_current(NULL, NULL, NULL); } + + /* Do this after unbinding context to ensure any thread is finished. */ + if (ctx->shader_builtin_ref) { + _mesa_glsl_builtin_functions_decref(); + ctx->shader_builtin_ref = false; + } + + free(ctx->Const.SpirVExtensions); } @@ -1523,9 +1558,12 @@ check_compatible(const struct gl_context *ctx, ctxvis->foo != bufvis->foo) \ return GL_FALSE - check_component(redMask); - check_component(greenMask); - check_component(blueMask); + check_component(redShift); + check_component(greenShift); + check_component(blueShift); + check_component(redBits); + check_component(greenBits); + check_component(blueBits); check_component(depthBits); check_component(stencilBits); @@ -1539,8 +1577,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; @@ -1569,17 +1607,17 @@ handle_first_current(struct gl_context *ctx) 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. */ if (!ctx->HasConfig && _mesa_is_desktop_gl(ctx)) { if (ctx->DrawBuffer != _mesa_get_incomplete_framebuffer()) { - GLenum buffer; + GLenum16 buffer; if (ctx->DrawBuffer->Visual.doubleBufferMode) buffer = GL_BACK; @@ -1607,6 +1645,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 @@ -1667,7 +1722,10 @@ _mesa_make_current( struct gl_context *newCtx, _mesa_flush(curCtx); } - /* We used to call _glapi_check_multithread() here. Now do it in drivers */ + /* 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 */ @@ -1704,6 +1762,7 @@ _mesa_make_current( struct gl_context *newCtx, * changed since the last time this FBO was bound). */ _mesa_update_draw_buffers(newCtx); + _mesa_update_allow_draw_out_of_order(newCtx); } if (!newCtx->ReadBuffer || _mesa_is_winsys_fbo(newCtx->ReadBuffer)) { _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer); @@ -1724,8 +1783,7 @@ _mesa_make_current( struct gl_context *newCtx, */ newCtx->NewState |= _NEW_BUFFERS; - _mesa_check_init_viewport(newCtx, - drawBuffer->Width, drawBuffer->Height); + check_init_viewport(newCtx, drawBuffer->Width, drawBuffer->Height); } if (newCtx->FirstTimeCurrent) { @@ -1809,31 +1867,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. */ @@ -1841,7 +1874,6 @@ void _mesa_flush(struct gl_context *ctx) { FLUSH_VERTICES( ctx, 0 ); - FLUSH_CURRENT( ctx, 0 ); if (ctx->Driver.Flush) { ctx->Driver.Flush(ctx); } @@ -1862,7 +1894,6 @@ _mesa_Finish(void) ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, 0); - FLUSH_CURRENT(ctx, 0); if (ctx->Driver.Finish) { ctx->Driver.Finish(ctx);