Esempio n. 1
0
static void
set_viewport_no_notify(struct gl_context *ctx, unsigned idx,
                       GLfloat x, GLfloat y,
                       GLfloat width, GLfloat height)
{
   /* clamp width and height to the implementation dependent range */
   width  = MIN2(width, (GLfloat) ctx->Const.MaxViewportWidth);
   height = MIN2(height, (GLfloat) ctx->Const.MaxViewportHeight);

   /* The GL_ARB_viewport_array spec says:
    *
    *     "The location of the viewport's bottom-left corner, given by (x,y),
    *     are clamped to be within the implementation-dependent viewport
    *     bounds range.  The viewport bounds range [min, max] tuple may be
    *     determined by calling GetFloatv with the symbolic constant
    *     VIEWPORT_BOUNDS_RANGE (see section 6.1)."
    */
   if (ctx->Extensions.ARB_viewport_array ||
       (ctx->Extensions.OES_viewport_array &&
        _mesa_is_gles31(ctx))) {
      x = CLAMP(x,
                ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max);
      y = CLAMP(y,
                ctx->Const.ViewportBounds.Min, ctx->Const.ViewportBounds.Max);
   }

   if (ctx->ViewportArray[idx].X == x &&
       ctx->ViewportArray[idx].Width == width &&
       ctx->ViewportArray[idx].Y == y &&
       ctx->ViewportArray[idx].Height == height)
      return;

   FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT);
   ctx->NewDriverState |= ctx->DriverFlags.NewViewport;

   ctx->ViewportArray[idx].X = x;
   ctx->ViewportArray[idx].Width = width;
   ctx->ViewportArray[idx].Y = y;
   ctx->ViewportArray[idx].Height = height;
}
static GLboolean
valid_draw_indirect(struct gl_context *ctx,
                    GLenum mode, const GLvoid *indirect,
                    GLsizei size, const char *name)
{
   const uint64_t end = (uint64_t) (uintptr_t) indirect + size;

   /* OpenGL ES 3.1 spec. section 10.5:
    *
    *      "DrawArraysIndirect requires that all data sourced for the
    *      command, including the DrawArraysIndirectCommand
    *      structure,  be in buffer objects,  and may not be called when
    *      the default vertex array object is bound."
    */
   if (ctx->Array.VAO == ctx->Array.DefaultVAO) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "(no VAO bound)");
      return GL_FALSE;
   }

   /* From OpenGL ES 3.1 spec. section 10.5:
    *     "An INVALID_OPERATION error is generated if zero is bound to
    *     VERTEX_ARRAY_BINDING, DRAW_INDIRECT_BUFFER or to any enabled
    *     vertex array."
    *
    * Here we check that for each enabled vertex array we have a vertex
    * buffer bound.
    */
   if (_mesa_is_gles31(ctx) &&
       ctx->Array.VAO->_Enabled != ctx->Array.VAO->VertexAttribBufferMask) {
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(No VBO bound)", name);
      return GL_FALSE;
   }

   if (!_mesa_valid_prim_mode(ctx, mode, name))
      return GL_FALSE;

   /* OpenGL ES 3.1 specification, section 10.5:
    *
    *      "An INVALID_OPERATION error is generated if
    *      transform feedback is active and not paused."
    */
   if (_mesa_is_gles31(ctx) && !ctx->Extensions.OES_geometry_shader &&
       _mesa_is_xfb_active_and_unpaused(ctx)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(TransformFeedback is active and not paused)", name);
   }

   /* From OpenGL version 4.4. section 10.5
    * and OpenGL ES 3.1, section 10.6:
    *
    *      "An INVALID_VALUE error is generated if indirect is not a
    *       multiple of the size, in basic machine units, of uint."
    */
   if ((GLsizeiptr)indirect & (sizeof(GLuint) - 1)) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "%s(indirect is not aligned)", name);
      return GL_FALSE;
   }

   if (!_mesa_is_bufferobj(ctx->DrawIndirectBuffer)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s: no buffer bound to DRAW_INDIRECT_BUFFER", name);
      return GL_FALSE;
   }

   if (_mesa_check_disallowed_mapping(ctx->DrawIndirectBuffer)) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(DRAW_INDIRECT_BUFFER is mapped)", name);
      return GL_FALSE;
   }

   /* From the ARB_draw_indirect specification:
    * "An INVALID_OPERATION error is generated if the commands source data
    *  beyond the end of the buffer object [...]"
    */
   if (ctx->DrawIndirectBuffer->Size < end) {
      _mesa_error(ctx, GL_INVALID_OPERATION,
                  "%s(DRAW_INDIRECT_BUFFER too small)", name);
      return GL_FALSE;
   }

   if (!check_valid_to_render(ctx, name))
      return GL_FALSE;

   return GL_TRUE;
}
Esempio n. 3
0
/* Handles the cases where either ARB_internalformat_query or
 * ARB_internalformat_query2 have to return an error.
 */
static bool
_legal_parameters(struct gl_context *ctx, GLenum target, GLenum internalformat,
                  GLenum pname, GLsizei bufSize, GLint *params)

{
   bool query2 = _mesa_has_ARB_internalformat_query2(ctx);

   /* The ARB_internalformat_query2 spec says:
    *
    *    "The INVALID_ENUM error is generated if the <target> parameter to
    *    GetInternalformati*v is not one of the targets listed in Table 6.xx.
    */
   switch(target){
   case GL_TEXTURE_1D:
   case GL_TEXTURE_1D_ARRAY:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_2D_ARRAY:
   case GL_TEXTURE_3D:
   case GL_TEXTURE_CUBE_MAP:
   case GL_TEXTURE_CUBE_MAP_ARRAY:
   case GL_TEXTURE_RECTANGLE:
   case GL_TEXTURE_BUFFER:
      if (!query2) {
         /* The ARB_internalformat_query spec says:
          *
          *     "If the <target> parameter to GetInternalformativ is not one of
          *      TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY
          *      or RENDERBUFFER then an INVALID_ENUM error is generated.
          */
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "glGetInternalformativ(target=%s)",
                     _mesa_enum_to_string(target));

         return false;
      }
      break;

   case GL_RENDERBUFFER:
      break;

   case GL_TEXTURE_2D_MULTISAMPLE:
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
      /* The non-existence of ARB_texture_multisample is treated in
       * ARB_internalformat_query implementation like an error.
       */
      if (!query2 &&
          !(_mesa_has_ARB_texture_multisample(ctx) || _mesa_is_gles31(ctx))) {
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "glGetInternalformativ(target=%s)",
                     _mesa_enum_to_string(target));

         return false;
      }
      break;

   default:
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetInternalformativ(target=%s)",
                  _mesa_enum_to_string(target));
      return false;
   }


   /* The ARB_internalformat_query2 spec says:
    *
    *     "The INVALID_ENUM error is generated if the <pname> parameter is
    *     not one of the listed possibilities.
    */
   switch(pname){
   case GL_SAMPLES:
   case GL_NUM_SAMPLE_COUNTS:
      break;

   case GL_SRGB_DECODE_ARB:
      /* The ARB_internalformat_query2 spec says:
       *
       *     "If ARB_texture_sRGB_decode or EXT_texture_sRGB_decode or
       *     equivalent functionality is not supported, queries for the
       *     SRGB_DECODE_ARB <pname> set the INVALID_ENUM error.
       */
      if (!_mesa_has_EXT_texture_sRGB_decode(ctx)) {
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "glGetInternalformativ(pname=%s)",
                     _mesa_enum_to_string(pname));
         return false;
      }
      /* fallthrough */
   case GL_INTERNALFORMAT_SUPPORTED:
   case GL_INTERNALFORMAT_PREFERRED:
   case GL_INTERNALFORMAT_RED_SIZE:
   case GL_INTERNALFORMAT_GREEN_SIZE:
   case GL_INTERNALFORMAT_BLUE_SIZE:
   case GL_INTERNALFORMAT_ALPHA_SIZE:
   case GL_INTERNALFORMAT_DEPTH_SIZE:
   case GL_INTERNALFORMAT_STENCIL_SIZE:
   case GL_INTERNALFORMAT_SHARED_SIZE:
   case GL_INTERNALFORMAT_RED_TYPE:
   case GL_INTERNALFORMAT_GREEN_TYPE:
   case GL_INTERNALFORMAT_BLUE_TYPE:
   case GL_INTERNALFORMAT_ALPHA_TYPE:
   case GL_INTERNALFORMAT_DEPTH_TYPE:
   case GL_INTERNALFORMAT_STENCIL_TYPE:
   case GL_MAX_WIDTH:
   case GL_MAX_HEIGHT:
   case GL_MAX_DEPTH:
   case GL_MAX_LAYERS:
   case GL_MAX_COMBINED_DIMENSIONS:
   case GL_COLOR_COMPONENTS:
   case GL_DEPTH_COMPONENTS:
   case GL_STENCIL_COMPONENTS:
   case GL_COLOR_RENDERABLE:
   case GL_DEPTH_RENDERABLE:
   case GL_STENCIL_RENDERABLE:
   case GL_FRAMEBUFFER_RENDERABLE:
   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
   case GL_FRAMEBUFFER_BLEND:
   case GL_READ_PIXELS:
   case GL_READ_PIXELS_FORMAT:
   case GL_READ_PIXELS_TYPE:
   case GL_TEXTURE_IMAGE_FORMAT:
   case GL_TEXTURE_IMAGE_TYPE:
   case GL_GET_TEXTURE_IMAGE_FORMAT:
   case GL_GET_TEXTURE_IMAGE_TYPE:
   case GL_MIPMAP:
   case GL_MANUAL_GENERATE_MIPMAP:
   case GL_AUTO_GENERATE_MIPMAP:
   case GL_COLOR_ENCODING:
   case GL_SRGB_READ:
   case GL_SRGB_WRITE:
   case GL_FILTER:
   case GL_VERTEX_TEXTURE:
   case GL_TESS_CONTROL_TEXTURE:
   case GL_TESS_EVALUATION_TEXTURE:
   case GL_GEOMETRY_TEXTURE:
   case GL_FRAGMENT_TEXTURE:
   case GL_COMPUTE_TEXTURE:
   case GL_TEXTURE_SHADOW:
   case GL_TEXTURE_GATHER:
   case GL_TEXTURE_GATHER_SHADOW:
   case GL_SHADER_IMAGE_LOAD:
   case GL_SHADER_IMAGE_STORE:
   case GL_SHADER_IMAGE_ATOMIC:
   case GL_IMAGE_TEXEL_SIZE:
   case GL_IMAGE_COMPATIBILITY_CLASS:
   case GL_IMAGE_PIXEL_FORMAT:
   case GL_IMAGE_PIXEL_TYPE:
   case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_TEST:
   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_TEST:
   case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE:
   case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
   case GL_TEXTURE_COMPRESSED:
   case GL_TEXTURE_COMPRESSED_BLOCK_WIDTH:
   case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT:
   case GL_TEXTURE_COMPRESSED_BLOCK_SIZE:
   case GL_CLEAR_BUFFER:
   case GL_TEXTURE_VIEW:
   case GL_VIEW_COMPATIBILITY_CLASS:
      /* The ARB_internalformat_query spec says:
       *
       *     "If the <pname> parameter to GetInternalformativ is not SAMPLES
       *     or NUM_SAMPLE_COUNTS, then an INVALID_ENUM error is generated."
       */
      if (!query2) {
         _mesa_error(ctx, GL_INVALID_ENUM,
                     "glGetInternalformativ(pname=%s)",
                     _mesa_enum_to_string(pname));

         return false;
      }
      break;

   default:
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetInternalformativ(pname=%s)",
                  _mesa_enum_to_string(pname));
      return false;
   }

   /* The ARB_internalformat_query spec says:
    *
    *     "If the <bufSize> parameter to GetInternalformativ is negative, then
    *     an INVALID_VALUE error is generated."
    *
    * Nothing is said in ARB_internalformat_query2 but we assume the same.
    */
   if (bufSize < 0) {
      _mesa_error(ctx, GL_INVALID_VALUE,
                  "glGetInternalformativ(target=%s)",
                  _mesa_enum_to_string(target));
      return false;
   }

   /* The ARB_internalformat_query spec says:
    *
    *     "If the <internalformat> parameter to GetInternalformativ is not
    *     color-, depth- or stencil-renderable, then an INVALID_ENUM error is
    *     generated."
    */
   if (!query2 && !_is_renderable(ctx, internalformat)) {
      _mesa_error(ctx, GL_INVALID_ENUM,
                  "glGetInternalformativ(internalformat=%s)",
                  _mesa_enum_to_string(internalformat));
      return false;
   }

   return true;
}
Esempio n. 4
0
static bool
_is_target_supported(struct gl_context *ctx, GLenum target)
{
   /* The ARB_internalformat_query2 spec says:
    *
    *     "if a particular type of <target> is not supported by the
    *     implementation the "unsupported" answer should be given.
    *     This is not an error."
    *
    * For OpenGL ES, queries can only be used with GL_RENDERBUFFER or MS.
    */
   switch(target){
   case GL_TEXTURE_1D:
   case GL_TEXTURE_2D:
   case GL_TEXTURE_3D:
      if (!_mesa_is_desktop_gl(ctx))
         return false;
      break;

   case GL_TEXTURE_1D_ARRAY:
      if (!_mesa_has_EXT_texture_array(ctx))
         return false;
      break;

   case GL_TEXTURE_2D_ARRAY:
      if (!_mesa_has_EXT_texture_array(ctx))
         return false;
      break;

   case GL_TEXTURE_CUBE_MAP:
      if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx))
         return false;
      break;

   case GL_TEXTURE_CUBE_MAP_ARRAY:
      if (!_mesa_has_ARB_texture_cube_map_array(ctx))
         return false;
      break;

   case GL_TEXTURE_RECTANGLE:
      if (!_mesa_has_ARB_texture_rectangle(ctx))
          return false;
      break;

   case GL_TEXTURE_BUFFER:
      if (!_mesa_has_ARB_texture_buffer_object(ctx))
         return false;
      break;

   case GL_RENDERBUFFER:
      if (!(_mesa_has_ARB_framebuffer_object(ctx) ||
            _mesa_is_gles3(ctx)))
         return false;
      break;

   case GL_TEXTURE_2D_MULTISAMPLE:
   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
      if (!(_mesa_has_ARB_texture_multisample(ctx) ||
            _mesa_is_gles31(ctx)))
         return false;
      break;

   default:
      unreachable("invalid target");
   }

   return true;
}