101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2016 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg#include <stdbool.h>
2501e04c3fSmrg#include "context.h"
2601e04c3fSmrg#include "debug_output.h"
2701e04c3fSmrg#include "get.h"
2801e04c3fSmrg#include "mtypes.h"
2901e04c3fSmrg#include "macros.h"
3001e04c3fSmrg#include "main/dispatch.h" /* for _gloffset_COUNT */
3101e04c3fSmrg
3201e04c3fSmrgstatic void GLAPIENTRY
3301e04c3fSmrg_context_lost_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize,
3401e04c3fSmrg                        GLsizei *length, GLint *values)
3501e04c3fSmrg{
3601e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
3701e04c3fSmrg   if (ctx)
3801e04c3fSmrg      _mesa_error(ctx, GL_CONTEXT_LOST, "GetSynciv(invalid call)");
3901e04c3fSmrg
4001e04c3fSmrg   if (pname == GL_SYNC_STATUS && bufSize >= 1)
4101e04c3fSmrg      *values = GL_SIGNALED;
4201e04c3fSmrg}
4301e04c3fSmrg
4401e04c3fSmrgstatic void GLAPIENTRY
4501e04c3fSmrg_context_lost_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params)
4601e04c3fSmrg{
4701e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
4801e04c3fSmrg   if (ctx)
4901e04c3fSmrg      _mesa_error(ctx, GL_CONTEXT_LOST, "GetQueryObjectuiv(context lost)");
5001e04c3fSmrg
5101e04c3fSmrg   if (pname == GL_QUERY_RESULT_AVAILABLE)
5201e04c3fSmrg      *params = GL_TRUE;
5301e04c3fSmrg}
5401e04c3fSmrg
5501e04c3fSmrgstatic int
5601e04c3fSmrgcontext_lost_nop_handler(void)
5701e04c3fSmrg{
5801e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
5901e04c3fSmrg   if (ctx)
6001e04c3fSmrg      _mesa_error(ctx, GL_CONTEXT_LOST, "context lost");
6101e04c3fSmrg
6201e04c3fSmrg   return 0;
6301e04c3fSmrg}
6401e04c3fSmrg
6501e04c3fSmrgvoid
6601e04c3fSmrg_mesa_set_context_lost_dispatch(struct gl_context *ctx)
6701e04c3fSmrg{
6801e04c3fSmrg   if (ctx->ContextLost == NULL) {
6901e04c3fSmrg      int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT);
7001e04c3fSmrg
7101e04c3fSmrg      ctx->ContextLost = malloc(numEntries * sizeof(_glapi_proc));
7201e04c3fSmrg      if (!ctx->ContextLost)
7301e04c3fSmrg         return;
7401e04c3fSmrg
7501e04c3fSmrg      _glapi_proc *entry = (_glapi_proc *) ctx->ContextLost;
7601e04c3fSmrg      unsigned i;
7701e04c3fSmrg      for (i = 0; i < numEntries; i++)
7801e04c3fSmrg         entry[i] = (_glapi_proc) context_lost_nop_handler;
7901e04c3fSmrg
8001e04c3fSmrg      /* The ARB_robustness specification says:
8101e04c3fSmrg       *
8201e04c3fSmrg       *    "* GetError and GetGraphicsResetStatus behave normally following a
8301e04c3fSmrg       *       graphics reset, so that the application can determine a reset
8401e04c3fSmrg       *       has occurred, and when it is safe to destroy and recreate the
8501e04c3fSmrg       *       context.
8601e04c3fSmrg       *
8701e04c3fSmrg       *     * Any commands which might cause a polling application to block
8801e04c3fSmrg       *       indefinitely will generate a CONTEXT_LOST error, but will also
8901e04c3fSmrg       *       return a value indicating completion to the application. Such
9001e04c3fSmrg       *       commands include:
9101e04c3fSmrg       *
9201e04c3fSmrg       *        + GetSynciv with <pname> SYNC_STATUS ignores the other
9301e04c3fSmrg       *          parameters and returns SIGNALED in <values>.
9401e04c3fSmrg       *
9501e04c3fSmrg       *        + GetQueryObjectuiv with <pname> QUERY_RESULT_AVAILABLE
9601e04c3fSmrg       *          ignores the other parameters and returns TRUE in <params>."
9701e04c3fSmrg       */
9801e04c3fSmrg      SET_GetError(ctx->ContextLost, _mesa_GetError);
9901e04c3fSmrg      SET_GetGraphicsResetStatusARB(ctx->ContextLost, _mesa_GetGraphicsResetStatusARB);
10001e04c3fSmrg      SET_GetSynciv(ctx->ContextLost, _context_lost_GetSynciv);
10101e04c3fSmrg      SET_GetQueryObjectuiv(ctx->ContextLost, _context_lost_GetQueryObjectuiv);
10201e04c3fSmrg   }
10301e04c3fSmrg
10401e04c3fSmrg   ctx->CurrentServerDispatch = ctx->ContextLost;
10501e04c3fSmrg   _glapi_set_dispatch(ctx->CurrentServerDispatch);
10601e04c3fSmrg}
10701e04c3fSmrg
10801e04c3fSmrg/**
10901e04c3fSmrg * Returns an error code specified by GL_ARB_robustness, or GL_NO_ERROR.
11001e04c3fSmrg * \return current context status
11101e04c3fSmrg */
11201e04c3fSmrgGLenum GLAPIENTRY
11301e04c3fSmrg_mesa_GetGraphicsResetStatusARB( void )
11401e04c3fSmrg{
11501e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
11601e04c3fSmrg   GLenum status = GL_NO_ERROR;
11701e04c3fSmrg
11801e04c3fSmrg   /* The ARB_robustness specification says:
11901e04c3fSmrg    *
12001e04c3fSmrg    *     "If the reset notification behavior is NO_RESET_NOTIFICATION_ARB,
12101e04c3fSmrg    *     then the implementation will never deliver notification of reset
12201e04c3fSmrg    *     events, and GetGraphicsResetStatusARB will always return NO_ERROR."
12301e04c3fSmrg    */
12401e04c3fSmrg   if (ctx->Const.ResetStrategy == GL_NO_RESET_NOTIFICATION_ARB) {
12501e04c3fSmrg      if (MESA_VERBOSE & VERBOSE_API)
12601e04c3fSmrg         _mesa_debug(ctx,
12701e04c3fSmrg                     "glGetGraphicsResetStatusARB always returns GL_NO_ERROR "
12801e04c3fSmrg                     "because reset notifictation was not requested at context "
12901e04c3fSmrg                     "creation.\n");
13001e04c3fSmrg
13101e04c3fSmrg      return GL_NO_ERROR;
13201e04c3fSmrg   }
13301e04c3fSmrg
13401e04c3fSmrg   if (ctx->Driver.GetGraphicsResetStatus) {
13501e04c3fSmrg      /* Query the reset status of this context from the driver core.
13601e04c3fSmrg       */
13701e04c3fSmrg      status = ctx->Driver.GetGraphicsResetStatus(ctx);
13801e04c3fSmrg
13901e04c3fSmrg      simple_mtx_lock(&ctx->Shared->Mutex);
14001e04c3fSmrg
14101e04c3fSmrg      /* If this context has not been affected by a GPU reset, check to see if
14201e04c3fSmrg       * some other context in the share group has been affected by a reset.
14301e04c3fSmrg       * If another context saw a reset but this context did not, assume that
14401e04c3fSmrg       * this context was not guilty.
14501e04c3fSmrg       */
14601e04c3fSmrg      if (status != GL_NO_ERROR) {
14701e04c3fSmrg         ctx->Shared->ShareGroupReset = true;
14801e04c3fSmrg         ctx->Shared->DisjointOperation = true;
14901e04c3fSmrg      } else if (ctx->Shared->ShareGroupReset && !ctx->ShareGroupReset) {
15001e04c3fSmrg         status = GL_INNOCENT_CONTEXT_RESET_ARB;
15101e04c3fSmrg      }
15201e04c3fSmrg
15301e04c3fSmrg      ctx->ShareGroupReset = ctx->Shared->ShareGroupReset;
15401e04c3fSmrg      simple_mtx_unlock(&ctx->Shared->Mutex);
15501e04c3fSmrg   }
15601e04c3fSmrg
15701e04c3fSmrg   if (status != GL_NO_ERROR)
15801e04c3fSmrg      _mesa_set_context_lost_dispatch(ctx);
15901e04c3fSmrg
16001e04c3fSmrg   if (!ctx->Driver.GetGraphicsResetStatus && (MESA_VERBOSE & VERBOSE_API))
16101e04c3fSmrg      _mesa_debug(ctx,
16201e04c3fSmrg                  "glGetGraphicsResetStatusARB always returns GL_NO_ERROR "
16301e04c3fSmrg                  "because the driver doesn't track reset status.\n");
16401e04c3fSmrg
16501e04c3fSmrg   return status;
16601e04c3fSmrg}
167