Edit

kc3-lang/angle/src/libANGLE/validationESEXT.cpp

Branch :

  • Show log

    Commit

  • Author : Ethan Lee
    Date : 2019-11-21 11:37:17
    Hash : a825eb70
    Message : Implement BaseVertex draw calls for Vulkan, OpenGL, NULL contexts. This adds support for the following functions: - glDrawElementsBaseVertex - glDrawRangeElementsBaseVertex - glDrawElementsInstancedBaseVertex Bug: angleproject:3582 Bug: angleproject:3402 Bug: angleproject:4166 Change-Id: I83770f62e3a918c0965fd4ca8c7d9e598b8b4154 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1929083 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>

  • src/libANGLE/validationESEXT.cpp
  • //
    // Copyright 2019 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // validationESEXT.cpp: Validation functions for OpenGL ES extension entry points.
    
    #include "libANGLE/validationESEXT_autogen.h"
    
    #include "libANGLE/Context.h"
    #include "libANGLE/ErrorStrings.h"
    #include "libANGLE/validationES.h"
    
    namespace gl
    {
    using namespace err;
    
    namespace
    {
    template <typename ObjectT>
    bool ValidateGetImageFormatAndType(Context *context, ObjectT *obj, GLenum format, GLenum type)
    {
        GLenum implFormat = obj->getImplementationColorReadFormat(context);
        if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE))
        {
            context->validationError(GL_INVALID_ENUM, kInvalidFormat);
            return false;
        }
    
        GLenum implType = obj->getImplementationColorReadType(context);
        if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
        {
            context->validationError(GL_INVALID_ENUM, kInvalidType);
            return false;
        }
    
        // Format/type combinations are not yet validated.
    
        return true;
    }
    
    }  // namespace
    
    bool ValidateGetTexImageANGLE(Context *context,
                                  TextureTarget target,
                                  GLint level,
                                  GLenum format,
                                  GLenum type,
                                  void *pixels)
    {
        if (!context->getExtensions().getImageANGLE)
        {
            context->validationError(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
            return false;
        }
    
        if (!ValidTexture2DDestinationTarget(context, target) &&
            !ValidTexture3DDestinationTarget(context, target))
        {
            context->validationError(GL_INVALID_ENUM, kInvalidTextureTarget);
            return false;
        }
    
        if (level < 0)
        {
            context->validationError(GL_INVALID_VALUE, kNegativeLevel);
            return false;
        }
    
        TextureType textureType = TextureTargetToType(target);
        if (!ValidMipLevel(context, textureType, level))
        {
            context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
            return false;
        }
    
        Texture *texture = context->getTextureByTarget(target);
    
        if (!ValidateGetImageFormatAndType(context, texture, format, type))
        {
            return false;
        }
    
        GLsizei width  = static_cast<GLsizei>(texture->getWidth(target, level));
        GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level));
        if (!ValidatePixelPack(context, format, type, 0, 0, width, height, -1, nullptr, pixels))
        {
            return false;
        }
    
        return true;
    }
    
    bool ValidateGetRenderbufferImageANGLE(Context *context,
                                           GLenum target,
                                           GLenum format,
                                           GLenum type,
                                           void *pixels)
    {
        if (!context->getExtensions().getImageANGLE)
        {
            context->validationError(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
            return false;
        }
    
        if (target != GL_RENDERBUFFER)
        {
            context->validationError(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
            return false;
        }
    
        Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
    
        if (!ValidateGetImageFormatAndType(context, renderbuffer, format, type))
        {
            return false;
        }
    
        GLsizei width  = renderbuffer->getWidth();
        GLsizei height = renderbuffer->getHeight();
        if (!ValidatePixelPack(context, format, type, 0, 0, width, height, -1, nullptr, pixels))
        {
            return false;
        }
    
        return true;
    }
    
    bool ValidateDrawElementsBaseVertexEXT(Context *context,
                                           PrimitiveMode mode,
                                           GLsizei count,
                                           DrawElementsType type,
                                           const void *indices,
                                           GLint basevertex)
    {
        if (!context->getExtensions().drawElementsBaseVertexAny())
        {
            context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
            return false;
        }
    
        return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
    }
    
    bool ValidateDrawElementsInstancedBaseVertexEXT(Context *context,
                                                    PrimitiveMode mode,
                                                    GLsizei count,
                                                    DrawElementsType type,
                                                    const void *indices,
                                                    GLsizei instancecount,
                                                    GLint basevertex)
    {
        if (!context->getExtensions().drawElementsBaseVertexAny())
        {
            context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
            return false;
        }
    
        return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, instancecount);
    }
    
    bool ValidateDrawRangeElementsBaseVertexEXT(Context *context,
                                                PrimitiveMode mode,
                                                GLuint start,
                                                GLuint end,
                                                GLsizei count,
                                                DrawElementsType type,
                                                const void *indices,
                                                GLint basevertex)
    {
        if (!context->getExtensions().drawElementsBaseVertexAny())
        {
            context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
            return false;
        }
    
        if (end < start)
        {
            context->validationError(GL_INVALID_VALUE, kInvalidElementRange);
            return false;
        }
    
        if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
        {
            return false;
        }
    
        // Skip range checks for no-op calls.
        if (count <= 0)
        {
            return true;
        }
    
        // Note that resolving the index range is a bit slow. We should probably optimize this.
        IndexRange indexRange;
        ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
                                                                                 indices, &indexRange));
    
        if (indexRange.end > end || indexRange.start < start)
        {
            // GL spec says that behavior in this case is undefined - generating an error is fine.
            context->validationError(GL_INVALID_OPERATION, kExceedsElementRange);
            return false;
        }
        return true;
    }
    
    bool ValidateMultiDrawElementsBaseVertexEXT(Context *context,
                                                PrimitiveMode mode,
                                                const GLsizei *count,
                                                DrawElementsType type,
                                                const void *const *indices,
                                                GLsizei drawcount,
                                                const GLint *basevertex)
    {
        return true;
    }
    
    bool ValidateDrawElementsBaseVertexOES(Context *context,
                                           PrimitiveMode mode,
                                           GLsizei count,
                                           DrawElementsType type,
                                           const void *indices,
                                           GLint basevertex)
    {
        if (!context->getExtensions().drawElementsBaseVertexAny())
        {
            context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
            return false;
        }
    
        return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
    }
    
    bool ValidateDrawElementsInstancedBaseVertexOES(Context *context,
                                                    PrimitiveMode mode,
                                                    GLsizei count,
                                                    DrawElementsType type,
                                                    const void *indices,
                                                    GLsizei instancecount,
                                                    GLint basevertex)
    {
        if (!context->getExtensions().drawElementsBaseVertexAny())
        {
            context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
            return false;
        }
    
        return ValidateDrawElementsInstancedBase(context, mode, count, type, indices, instancecount);
    }
    
    bool ValidateDrawRangeElementsBaseVertexOES(Context *context,
                                                PrimitiveMode mode,
                                                GLuint start,
                                                GLuint end,
                                                GLsizei count,
                                                DrawElementsType type,
                                                const void *indices,
                                                GLint basevertex)
    {
        if (!context->getExtensions().drawElementsBaseVertexAny())
        {
            context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
            return false;
        }
    
        if (end < start)
        {
            context->validationError(GL_INVALID_VALUE, kInvalidElementRange);
            return false;
        }
    
        if (!ValidateDrawElementsCommon(context, mode, count, type, indices, 0))
        {
            return false;
        }
    
        // Skip range checks for no-op calls.
        if (count <= 0)
        {
            return true;
        }
    
        // Note that resolving the index range is a bit slow. We should probably optimize this.
        IndexRange indexRange;
        ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
                                                                                 indices, &indexRange));
    
        if (indexRange.end > end || indexRange.start < start)
        {
            // GL spec says that behavior in this case is undefined - generating an error is fine.
            context->validationError(GL_INVALID_OPERATION, kExceedsElementRange);
            return false;
        }
        return true;
    }
    }  // namespace gl