Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  queryutils.cpp   Sprache: C

 
//
// Copyright 2016 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.
//

// queryutils.cpp: Utilities for querying values from GL objects

#include "libANGLE/queryutils.h"

#include <algorithm>

#include "common/utilities.h"

#include "libANGLE/Buffer.h"
#include "libANGLE/Config.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Fence.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/GLES1State.h"
#include "libANGLE/MemoryObject.h"
#include "libANGLE/Program.h"
#include "libANGLE/Renderbuffer.h"
#include "libANGLE/Sampler.h"
#include "libANGLE/Shader.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Texture.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/queryconversions.h"

namespace gl
{

namespace
{

template <bool isPureInteger>
ColorGeneric ConvertToColor(const GLfloat *params)
{
    if (isPureInteger)
    {
        UNREACHABLE();
        return ColorGeneric(ColorI());
    }
    else
    {
        return ColorGeneric(ColorF::fromData(params));
    }
}

template <bool isPureInteger>
ColorGeneric ConvertToColor(const GLint *params)
{
    if (isPureInteger)
    {
        return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
    }
    else
    {
        return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
                                   normalizedToFloat(params[2]), normalizedToFloat(params[3])));
    }
}

template <bool isPureInteger>
ColorGeneric ConvertToColor(const GLuint *params)
{
    if (isPureInteger)
    {
        return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
    }
    else
    {
        UNREACHABLE();
        return ColorGeneric(ColorF());
    }
}

template <bool isPureInteger>
void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
{
    if (isPureInteger)
    {
        UNREACHABLE();
    }
    else
    {
        color.colorF.writeData(outParams);
    }
}

template <bool isPureInteger>
void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
{
    if (isPureInteger)
    {
        outParams[0] = color.colorI.red;
        outParams[1] = color.colorI.green;
        outParams[2] = color.colorI.blue;
        outParams[3] = color.colorI.alpha;
    }
    else
    {
        outParams[0] = floatToNormalized<GLint>(color.colorF.red);
        outParams[1] = floatToNormalized<GLint>(color.colorF.green);
        outParams[2] = floatToNormalized<GLint>(color.colorF.blue);
        outParams[3] = floatToNormalized<GLint>(color.colorF.alpha);
    }
}

template <bool isPureInteger>
void ConvertFromColor(const ColorGeneric &color, GLuint *outParams)
{
    if (isPureInteger)
    {
        constexpr unsigned int kMinValue = 0;

        outParams[0] = std::max(color.colorUI.red, kMinValue);
        outParams[1] = std::max(color.colorUI.green, kMinValue);
        outParams[2] = std::max(color.colorUI.blue, kMinValue);
        outParams[3] = std::max(color.colorUI.alpha, kMinValue);
    }
    else
    {
        UNREACHABLE();
    }
}

template <typename ParamType>
void QueryTexLevelParameterBase(const Texture *texture,
                                TextureTarget target,
                                GLint level,
                                GLenum pname,
                                ParamType *params)
{
    ASSERT(texture != nullptr);
    const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;

    switch (pname)
    {
        case GL_TEXTURE_RED_TYPE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, info->redBits ? info->componentType : GL_NONE);
            break;
        case GL_TEXTURE_GREEN_TYPE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, info->greenBits ? info->componentType : GL_NONE);
            break;
        case GL_TEXTURE_BLUE_TYPE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, info->blueBits ? info->componentType : GL_NONE);
            break;
        case GL_TEXTURE_ALPHA_TYPE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, info->alphaBits ? info->componentType : GL_NONE);
            break;
        case GL_TEXTURE_DEPTH_TYPE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, info->depthBits ? info->componentType : GL_NONE);
            break;
        case GL_TEXTURE_RED_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
            break;
        case GL_TEXTURE_GREEN_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
            break;
        case GL_TEXTURE_BLUE_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
            break;
        case GL_TEXTURE_ALPHA_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
            break;
        case GL_TEXTURE_DEPTH_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
            break;
        case GL_TEXTURE_STENCIL_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
            break;
        case GL_TEXTURE_SHARED_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
            break;
        case GL_TEXTURE_INTERNAL_FORMAT:
            *params = CastFromGLintStateValue<ParamType>(
                pname, info->internalFormat ? info->internalFormat : GL_RGBA);
            break;
        case GL_TEXTURE_WIDTH:
            *params = CastFromGLintStateValue<ParamType>(
                pname, static_cast<uint32_t>(texture->getWidth(target, level)));
            break;
        case GL_TEXTURE_HEIGHT:
            *params = CastFromGLintStateValue<ParamType>(
                pname, static_cast<uint32_t>(texture->getHeight(target, level)));
            break;
        case GL_TEXTURE_DEPTH:
            *params = CastFromGLintStateValue<ParamType>(
                pname, static_cast<uint32_t>(texture->getDepth(target, level)));
            break;
        case GL_TEXTURE_SAMPLES:
            *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
            break;
        case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
            *params = CastFromStateValue<ParamType>(
                pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
            break;
        case GL_TEXTURE_COMPRESSED:
            *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
            break;
        case GL_MEMORY_SIZE_ANGLE:
            *params =
                CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
            break;
        case GL_RESOURCE_INITIALIZED_ANGLE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, texture->initState(GL_NONE, ImageIndex::MakeFromTarget(target, level)) ==
                           InitState::Initialized);
            break;
        case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
            *params = CastFromStateValue<ParamType>(
                pname, static_cast<GLint>(texture->getBuffer().id().value));
            break;
        case GL_TEXTURE_BUFFER_OFFSET:
            *params = CastFromStateValue<ParamType>(
                pname, static_cast<GLint>(texture->getBuffer().getOffset()));
            break;
        case GL_TEXTURE_BUFFER_SIZE:
            *params = CastFromStateValue<ParamType>(
                pname, static_cast<GLint>(GetBoundBufferAvailableSize(texture->getBuffer())));
            break;
        default:
            UNREACHABLE();
            break;
    }
}

// This function is needed to handle fixed_point data.
// It can be used when some pname need special conversion from int/float/bool to fixed_point.
template <bool isGLfixed, typename QueryT, typename ParamType>
QueryT CastFromSpecialValue(GLenum pname, const ParamType param)
{
    if (isGLfixed)
    {
        return static_cast<QueryT>(ConvertFloatToFixed(CastFromStateValue<GLfloat>(pname, param)));
    }
    else
    {
        return CastFromStateValue<QueryT>(pname, param);
    }
}

template <bool isPureInteger, bool isGLfixed, typename ParamType>
void QueryTexParameterBase(const Context *context,
                           const Texture *texture,
                           GLenum pname,
                           ParamType *params)
{
    ASSERT(texture != nullptr);

    switch (pname)
    {
        case GL_TEXTURE_MAG_FILTER:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
            break;
        case GL_TEXTURE_MIN_FILTER:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
            break;
        case GL_TEXTURE_WRAP_S:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
            break;
        case GL_TEXTURE_WRAP_T:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
            break;
        case GL_TEXTURE_WRAP_R:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
            break;
        case GL_TEXTURE_IMMUTABLE_FORMAT:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
            break;
        case GL_TEXTURE_IMMUTABLE_LEVELS:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
            break;
        case GL_TEXTURE_USAGE_ANGLE:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
            break;
        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
            *params =
                CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxAnisotropy());
            break;
        case GL_TEXTURE_SWIZZLE_R:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
            break;
        case GL_TEXTURE_SWIZZLE_G:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
            break;
        case GL_TEXTURE_SWIZZLE_B:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
            break;
        case GL_TEXTURE_SWIZZLE_A:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
            break;
        case GL_TEXTURE_BASE_LEVEL:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
            break;
        case GL_TEXTURE_MAX_LEVEL:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
            break;
        case GL_TEXTURE_MIN_LOD:
            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMinLod());
            break;
        case GL_TEXTURE_MAX_LOD:
            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxLod());
            break;
        case GL_TEXTURE_COMPARE_MODE:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
            break;
        case GL_TEXTURE_COMPARE_FUNC:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
            break;
        case GL_TEXTURE_SRGB_DECODE_EXT:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
            break;
        case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBOverride());
            break;
        case GL_DEPTH_STENCIL_TEXTURE_MODE:
            *params =
                CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
            break;
        case GL_TEXTURE_CROP_RECT_OES:
        {
            const gl::Rectangle &crop = texture->getCrop();
            params[0]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.x);
            params[1]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.y);
            params[2] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.width);
            params[3] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.height);
            break;
        }
        case GL_GENERATE_MIPMAP:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
            break;
        case GL_MEMORY_SIZE_ANGLE:
            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMemorySize());
            break;
        case GL_TEXTURE_BORDER_COLOR:
            ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
            break;
        case GL_TEXTURE_NATIVE_ID_ANGLE:
            *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getNativeID());
            break;
        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
            *params = CastFromGLintStateValue<ParamType>(
                pname, texture->getImplementationColorReadFormat(context));
            break;
        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, texture->getImplementationColorReadType(context));
            break;
        case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
            *params =
                CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
            break;
        case GL_RESOURCE_INITIALIZED_ANGLE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, texture->initState() == InitState::Initialized);
            break;
        case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
            *params = CastFromGLintStateValue<ParamType>(
                pname, texture->getRequiredTextureImageUnits(context));
            break;
        case GL_TEXTURE_PROTECTED_EXT:
            *params = CastFromGLintStateValue<ParamType>(pname, texture->hasProtectedContent());
            break;
        default:
            UNREACHABLE();
            break;
    }
}

// this function is needed to handle OES_FIXED_POINT.
// Some pname values can take in GLfixed values and may need to be converted
template <bool isGLfixed, typename ReturnType, typename ParamType>
ReturnType ConvertTexParam(GLenum pname, const ParamType param)
{
    if (isGLfixed)
    {
        return CastQueryValueTo<ReturnType>(pname,
                                            ConvertFixedToFloat(static_cast<GLfixed>(param)));
    }
    else
    {
        return CastQueryValueTo<ReturnType>(pname, param);
    }
}

template <bool isPureInteger, bool isGLfixed, typename ParamType>
void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
{
    ASSERT(texture != nullptr);

    switch (pname)
    {
        case GL_TEXTURE_WRAP_S:
            texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_WRAP_T:
            texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_WRAP_R:
            texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_MIN_FILTER:
            texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_MAG_FILTER:
            texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_USAGE_ANGLE:
            texture->setUsage(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
            texture->setMaxAnisotropy(context,
                                      ConvertTexParam<isGLfixed, GLfloat>(pname, params[0]));
            break;
        case GL_TEXTURE_COMPARE_MODE:
            texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_COMPARE_FUNC:
            texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_SWIZZLE_R:
            texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_SWIZZLE_G:
            texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_SWIZZLE_B:
            texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_SWIZZLE_A:
            texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_BASE_LEVEL:
        {
            (void)(texture->setBaseLevel(
                context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
            break;
        }
        case GL_TEXTURE_MAX_LEVEL:
            texture->setMaxLevel(context,
                                 clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
            break;
        case GL_TEXTURE_MIN_LOD:
            texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
            break;
        case GL_TEXTURE_MAX_LOD:
            texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
            break;
        case GL_DEPTH_STENCIL_TEXTURE_MODE:
            texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_SRGB_DECODE_EXT:
            texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
            texture->setSRGBOverride(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_CROP_RECT_OES:
            texture->setCrop(gl::Rectangle(ConvertTexParam<isGLfixed, GLint>(pname, params[0]),
                                           ConvertTexParam<isGLfixed, GLint>(pname, params[1]),
                                           ConvertTexParam<isGLfixed, GLint>(pname, params[2]),
                                           ConvertTexParam<isGLfixed, GLint>(pname, params[3])));
            break;
        case GL_GENERATE_MIPMAP:
            texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
            break;
        case GL_TEXTURE_BORDER_COLOR:
            texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
            break;
        case GL_RESOURCE_INITIALIZED_ANGLE:
            texture->setInitState(ConvertToBool(params[0]) ? InitState::Initialized
                                                           : InitState::MayNeedInit);
            break;
        case GL_TEXTURE_PROTECTED_EXT:
            texture->setProtectedContent(context, (params[0] == GL_TRUE));
            break;
        default:
            UNREACHABLE();
            break;
    }
}

template <bool isPureInteger, typename ParamType>
void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
{
    switch (pname)
    {
        case GL_TEXTURE_MIN_FILTER:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
            break;
        case GL_TEXTURE_MAG_FILTER:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
            break;
        case GL_TEXTURE_WRAP_S:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
            break;
        case GL_TEXTURE_WRAP_T:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
            break;
        case GL_TEXTURE_WRAP_R:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
            break;
        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
            *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
            break;
        case GL_TEXTURE_MIN_LOD:
            *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
            break;
        case GL_TEXTURE_MAX_LOD:
            *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
            break;
        case GL_TEXTURE_COMPARE_MODE:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
            break;
        case GL_TEXTURE_COMPARE_FUNC:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
            break;
        case GL_TEXTURE_SRGB_DECODE_EXT:
            *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
            break;
        case GL_TEXTURE_BORDER_COLOR:
            ConvertFromColor<isPureInteger>(sampler->getBorderColor(), params);
            break;
        default:
            UNREACHABLE();
            break;
    }
}

template <bool isPureInteger, typename ParamType>
void SetSamplerParameterBase(Context *context,
                             Sampler *sampler,
                             GLenum pname,
                             const ParamType *params)
{
    switch (pname)
    {
        case GL_TEXTURE_WRAP_S:
            sampler->setWrapS(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_WRAP_T:
            sampler->setWrapT(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_WRAP_R:
            sampler->setWrapR(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_MIN_FILTER:
            sampler->setMinFilter(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_MAG_FILTER:
            sampler->setMagFilter(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_MAX_ANISOTROPY_EXT:
            sampler->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
            break;
        case GL_TEXTURE_COMPARE_MODE:
            sampler->setCompareMode(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_COMPARE_FUNC:
            sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_MIN_LOD:
            sampler->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
            break;
        case GL_TEXTURE_MAX_LOD:
            sampler->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
            break;
        case GL_TEXTURE_SRGB_DECODE_EXT:
            sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
            break;
        case GL_TEXTURE_BORDER_COLOR:
            sampler->setBorderColor(context, ConvertToColor<isPureInteger>(params));
            break;
        default:
            UNREACHABLE();
            break;
    }

    sampler->onStateChange(angle::SubjectMessage::ContentsChanged);
}

// Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
void QueryVertexAttribBase(const VertexAttribute &attrib,
                           const VertexBinding &binding,
                           const CurrentDataType (¤tValueData)[CurrentValueCount],
                           GLenum pname,
                           ParamType *params)
{
    switch (pname)
    {
        case GL_CURRENT_VERTEX_ATTRIB:
            for (size_t i = 0; i < CurrentValueCount; ++i)
            {
                params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
            }
            break;
        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
            *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
            break;
        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
            *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->channelCount);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
            *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
            *params = CastFromGLintStateValue<ParamType>(
                pname, gl::ToGLenum(attrib.format->vertexAttribType));
            break;
        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
            *params =
                CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.format->isNorm()));
            break;
        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
            *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id().value);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
            *params = CastFromStateValue<ParamType>(pname, binding.getDivisor());
            break;
        case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
            *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->isPureInt());
            break;
        case GL_VERTEX_ATTRIB_BINDING:
            *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
            break;
        case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
            *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
            break;
        default:
            UNREACHABLE();
            break;
    }
}

template <typename ParamType>
void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
{
    ASSERT(buffer != nullptr);

    switch (pname)
    {
        case GL_BUFFER_USAGE:
            *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
            break;
        case GL_BUFFER_SIZE:
            *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
            break;
        case GL_BUFFER_ACCESS_FLAGS:
            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
            break;
        case GL_BUFFER_ACCESS_OES:
            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
            break;
        case GL_BUFFER_MAPPED:
            *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
            break;
        case GL_BUFFER_MAP_OFFSET:
            *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
            break;
        case GL_BUFFER_MAP_LENGTH:
            *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
            break;
        case GL_MEMORY_SIZE_ANGLE:
            *params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
            break;
        case GL_BUFFER_IMMUTABLE_STORAGE_EXT:
            *params = CastFromStateValue<ParamType>(pname, buffer->isImmutable());
            break;
        case GL_BUFFER_STORAGE_FLAGS_EXT:
            *params = CastFromGLintStateValue<ParamType>(pname, buffer->getStorageExtUsageFlags());
            break;
        case GL_RESOURCE_INITIALIZED_ANGLE:
            *params = CastFromStateValue<ParamType>(
                pname, ConvertToGLBoolean(buffer->initState() == InitState::Initialized));
            break;
        default:
            UNREACHABLE();
            break;
    }
}

GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
{
    switch (prop)
    {
        case GL_TYPE:
            return clampCast<GLint>(var.type);

        case GL_ARRAY_SIZE:
            // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
            // see GLES 3.1 spec section 7.3.1.1 page 77.
            return clampCast<GLint>(var.getBasicTypeElementCount());

        case GL_NAME_LENGTH:
            // ES31 spec p84: This counts the terminating null char.
            return clampCast<GLint>(var.name.size() + 1u);

        default:
            UNREACHABLE();
            return GL_INVALID_VALUE;
    }
}

GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
{
    const sh::ShaderVariable &variable = program->getInputResource(index);

    switch (prop)
    {
        case GL_TYPE:
        case GL_ARRAY_SIZE:
            return GetCommonVariableProperty(variable, prop);

        case GL_NAME_LENGTH:
            return clampCast<GLint>(program->getInputResourceName(index).size() + 1u);

        case GL_LOCATION:
            return variable.isBuiltIn() ? GL_INVALID_INDEX : variable.location;

        // The query is targeted at the set of active input variables used by the first shader stage
        // of program. If program contains multiple shader stages then input variables from any
        // stage other than the first will not be enumerated. Since we found the variable to get
        // this far, we know it exists in the first attached shader stage.
        case GL_REFERENCED_BY_VERTEX_SHADER:
            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Vertex;
        case GL_REFERENCED_BY_FRAGMENT_SHADER:
            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Fragment;
        case GL_REFERENCED_BY_COMPUTE_SHADER:
            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Compute;
        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
            return program->getState().getFirstAttachedShaderStageType() == ShaderType::Geometry;
        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
            return program->getState().getFirstAttachedShaderStageType() == ShaderType::TessControl;
        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
            return program->getState().getFirstAttachedShaderStageType() ==
                   ShaderType::TessEvaluation;
        case GL_IS_PER_PATCH_EXT:
            return variable.isPatch;

        default:
            UNREACHABLE();
            return GL_INVALID_VALUE;
    }
}

GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
{
    const sh::ShaderVariable &outputVariable = program->getOutputResource(index);

    switch (prop)
    {
        case GL_TYPE:
        case GL_ARRAY_SIZE:
            return GetCommonVariableProperty(outputVariable, prop);

        case GL_NAME_LENGTH:
            return clampCast<GLint>(program->getOutputResourceName(index).size() + 1u);

        case GL_LOCATION:
            return outputVariable.location;

        case GL_LOCATION_INDEX_EXT:
            // EXT_blend_func_extended
            if (program->getState().getLastAttachedShaderStageType() == gl::ShaderType::Fragment)
            {
                return program->getFragDataIndex(outputVariable.name);
            }
            return GL_INVALID_INDEX;

        // The set of active user-defined outputs from the final shader stage in this program. If
        // the final stage is a Fragment Shader, then this represents the fragment outputs that get
        // written to individual color buffers. If the program only contains a Compute Shader, then
        // there are no user-defined outputs.
        case GL_REFERENCED_BY_VERTEX_SHADER:
            return program->getState().getLastAttachedShaderStageType() == ShaderType::Vertex;
        case GL_REFERENCED_BY_FRAGMENT_SHADER:
            return program->getState().getLastAttachedShaderStageType() == ShaderType::Fragment;
        case GL_REFERENCED_BY_COMPUTE_SHADER:
            return program->getState().getLastAttachedShaderStageType() == ShaderType::Compute;
        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
            return program->getState().getLastAttachedShaderStageType() == ShaderType::Geometry;
        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
            return program->getState().getLastAttachedShaderStageType() == ShaderType::TessControl;
        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
            return program->getState().getLastAttachedShaderStageType() ==
                   ShaderType::TessEvaluation;
        case GL_IS_PER_PATCH_EXT:
            return outputVariable.isPatch;

        default:
            UNREACHABLE();
            return GL_INVALID_VALUE;
    }
}

GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
                                                  GLuint index,
                                                  const GLenum prop)
{
    const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
    switch (prop)
    {
        case GL_TYPE:
            return clampCast<GLint>(tfVariable.type);

        case GL_ARRAY_SIZE:
            return clampCast<GLint>(tfVariable.size());

        case GL_NAME_LENGTH:
            return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);

        default:
            UNREACHABLE();
            return GL_INVALID_VALUE;
    }
}

GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
{
    switch (programInterface)
    {
        case GL_PROGRAM_INPUT:
            return clampCast<GLint>(program->getState().getProgramInputs().size());

        case GL_PROGRAM_OUTPUT:
            return clampCast<GLint>(program->getState().getOutputVariables().size());

        case GL_UNIFORM:
            return clampCast<GLint>(program->getState().getUniforms().size());

        case GL_UNIFORM_BLOCK:
            return clampCast<GLint>(program->getState().getUniformBlocks().size());

        case GL_ATOMIC_COUNTER_BUFFER:
            return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());

        case GL_BUFFER_VARIABLE:
            return clampCast<GLint>(program->getState().getBufferVariables().size());

        case GL_SHADER_STORAGE_BLOCK:
            return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());

        case GL_TRANSFORM_FEEDBACK_VARYING:
            return clampCast<GLint>(program->getTransformFeedbackVaryingCount());

        default:
            UNREACHABLE();
            return 0;
    }
}

template <typename T, typename M>
GLint FindMaxSize(const std::vector<T> &resources, M member)
{
    GLint max = 0;
    for (const T &resource : resources)
    {
        max = std::max(max, clampCast<GLint>((resource.*member).size()));
    }
    return max;
}

GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
{
    GLint maxNameLength = 0;
    switch (programInterface)
    {
        case GL_PROGRAM_INPUT:
            maxNameLength = program->getInputResourceMaxNameSize();
            break;

        case GL_PROGRAM_OUTPUT:
            maxNameLength = program->getOutputResourceMaxNameSize();
            break;

        case GL_UNIFORM:
            maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name);
            break;

        case GL_UNIFORM_BLOCK:
            return program->getActiveUniformBlockMaxNameLength();

        case GL_BUFFER_VARIABLE:
            maxNameLength =
                FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
            break;

        case GL_SHADER_STORAGE_BLOCK:
            return program->getActiveShaderStorageBlockMaxNameLength();

        case GL_TRANSFORM_FEEDBACK_VARYING:
            return clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength());

        default:
            UNREACHABLE();
            return 0;
    }
    // This length includes an extra character for the null terminator.
    return (maxNameLength == 0 ? 0 : maxNameLength + 1);
}

GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
{
    switch (programInterface)
    {
        case GL_UNIFORM_BLOCK:
            return FindMaxSize(program->getState().getUniformBlocks(),
                               &InterfaceBlock::memberIndexes);
        case GL_ATOMIC_COUNTER_BUFFER:
            return FindMaxSize(program->getState().getAtomicCounterBuffers(),
                               &AtomicCounterBuffer::memberIndexes);

        case GL_SHADER_STORAGE_BLOCK:
            return FindMaxSize(program->getState().getShaderStorageBlocks(),
                               &InterfaceBlock::memberIndexes);

        default:
            UNREACHABLE();
            return 0;
    }
}

GLenum GetUniformPropertyEnum(GLenum prop)
{
    switch (prop)
    {
        case GL_UNIFORM_TYPE:
            return GL_TYPE;
        case GL_UNIFORM_SIZE:
            return GL_ARRAY_SIZE;
        case GL_UNIFORM_NAME_LENGTH:
            return GL_NAME_LENGTH;
        case GL_UNIFORM_BLOCK_INDEX:
            return GL_BLOCK_INDEX;
        case GL_UNIFORM_OFFSET:
            return GL_OFFSET;
        case GL_UNIFORM_ARRAY_STRIDE:
            return GL_ARRAY_STRIDE;
        case GL_UNIFORM_MATRIX_STRIDE:
            return GL_MATRIX_STRIDE;
        case GL_UNIFORM_IS_ROW_MAJOR:
            return GL_IS_ROW_MAJOR;

        default:
            return prop;
    }
}

GLenum GetUniformBlockPropertyEnum(GLenum prop)
{
    switch (prop)
    {
        case GL_UNIFORM_BLOCK_BINDING:
            return GL_BUFFER_BINDING;

        case GL_UNIFORM_BLOCK_DATA_SIZE:
            return GL_BUFFER_DATA_SIZE;

        case GL_UNIFORM_BLOCK_NAME_LENGTH:
            return GL_NAME_LENGTH;

        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
            return GL_NUM_ACTIVE_VARIABLES;

        case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
            return GL_ACTIVE_VARIABLES;

        case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
            return GL_REFERENCED_BY_VERTEX_SHADER;

        case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
            return GL_REFERENCED_BY_FRAGMENT_SHADER;

        default:
            return prop;
    }
}

void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer,
                                             GLenum pname,
                                             GLint *params,
                                             GLsizei bufSize,
                                             GLsizei *outputPosition)

{
    switch (pname)
    {
        case GL_BUFFER_BINDING:
            params[(*outputPosition)++] = buffer.binding;
            break;
        case GL_BUFFER_DATA_SIZE:
            params[(*outputPosition)++] = clampCast<GLint>(buffer.dataSize);
            break;
        case GL_NUM_ACTIVE_VARIABLES:
            params[(*outputPosition)++] = buffer.numActiveVariables();
            break;
        case GL_ACTIVE_VARIABLES:
            for (size_t memberIndex = 0;
                 memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
                 ++memberIndex)
            {
                params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
            }
            break;
        case GL_REFERENCED_BY_VERTEX_SHADER:
            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
            break;
        case GL_REFERENCED_BY_FRAGMENT_SHADER:
            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
            break;
        case GL_REFERENCED_BY_COMPUTE_SHADER:
            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
            break;
        case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
            params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Geometry));
            break;
        case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
            params[(*outputPosition)++] =
                static_cast<GLint>(buffer.isActive(ShaderType::TessControl));
            break;
        case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
            params[(*outputPosition)++] =
                static_cast<GLint>(buffer.isActive(ShaderType::TessEvaluation));
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
                                       GLenum pname,
                                       GLint *params,
                                       GLsizei bufSize,
                                       GLsizei *outputPosition)
{
    if (pname == GL_NAME_LENGTH)
    {
        params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
        return;
    }
    GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
}

void GetUniformBlockResourceProperty(const Program *program,
                                     GLuint blockIndex,
                                     GLenum pname,
                                     GLint *params,
                                     GLsizei bufSize,
                                     GLsizei *outputPosition)

{
    ASSERT(*outputPosition < bufSize);
    const auto &block = program->getUniformBlockByIndex(blockIndex);
    GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
}

void GetShaderStorageBlockResourceProperty(const Program *program,
                                           GLuint blockIndex,
                                           GLenum pname,
                                           GLint *params,
                                           GLsizei bufSize,
                                           GLsizei *outputPosition)

{
    ASSERT(*outputPosition < bufSize);
    const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
    GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
}

void GetAtomicCounterBufferResourceProperty(const Program *program,
                                            GLuint index,
                                            GLenum pname,
                                            GLint *params,
                                            GLsizei bufSize,
                                            GLsizei *outputPosition)

{
    ASSERT(*outputPosition < bufSize);
    const auto &buffer = program->getState().getAtomicCounterBuffers()[index];
    GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
}

bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
{
    switch (pname)
    {
        case TextureEnvParameter::Mode:
        case TextureEnvParameter::CombineRgb:
        case TextureEnvParameter::CombineAlpha:
        case TextureEnvParameter::Src0Rgb:
        case TextureEnvParameter::Src1Rgb:
        case TextureEnvParameter::Src2Rgb:
        case TextureEnvParameter::Src0Alpha:
        case TextureEnvParameter::Src1Alpha:
        case TextureEnvParameter::Src2Alpha:
        case TextureEnvParameter::Op0Rgb:
        case TextureEnvParameter::Op1Rgb:
        case TextureEnvParameter::Op2Rgb:
        case TextureEnvParameter::Op0Alpha:
        case TextureEnvParameter::Op1Alpha:
        case TextureEnvParameter::Op2Alpha:
        case TextureEnvParameter::PointCoordReplace:
            return true;
        default:
            return false;
    }
}

void GetShaderProgramId(ProgramPipeline *programPipeline, ShaderType shaderType, GLint *params)
{
    ASSERT(params);

    *params = 0;
    if (programPipeline)
    {
        const Program *program = programPipeline->getShaderProgram(shaderType);
        if (program)
        {
            *params = program->id().value;
        }
    }
}

}  // namespace

void QueryFramebufferAttachmentParameteriv(const Context *context,
                                           const Framebuffer *framebuffer,
                                           GLenum attachment,
                                           GLenum pname,
                                           GLint *params)
{
    ASSERT(framebuffer);

    const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);

    if (attachmentObject == nullptr)
    {
        // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
        // is NONE, then querying any other pname will generate INVALID_ENUM.

        // ES 3.0.2 spec pg 235 states that if the attachment type is none,
        // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
        // INVALID_OPERATION for all other pnames

        switch (pname)
        {
            case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
                *params = GL_NONE;
                break;

            case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
                *params = 0;
                break;

            default:
                UNREACHABLE();
                break;
        }

        return;
    }

    switch (pname)
    {
        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
            *params = attachmentObject->type();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
            *params = attachmentObject->id();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
            *params = attachmentObject->mipLevel();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
        {
            TextureTarget face = attachmentObject->cubeMapFace();
            if (face != TextureTarget::InvalidEnum)
            {
                *params = ToGLenum(attachmentObject->cubeMapFace());
            }
            else
            {
                // This happens when the attachment isn't a texture cube map face
                *params = GL_NONE;
            }
        }
        break;

        case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
            *params = attachmentObject->getRedSize();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
            *params = attachmentObject->getGreenSize();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
            *params = attachmentObject->getBlueSize();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
            *params = attachmentObject->getAlphaSize();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
            *params = attachmentObject->getDepthSize();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
            *params = attachmentObject->getStencilSize();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
            *params = attachmentObject->getComponentType();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
            *params = attachmentObject->getColorEncoding();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
            *params = attachmentObject->layer();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
            *params = attachmentObject->getNumViews();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
            *params = attachmentObject->getBaseViewIndex();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
            *params = attachmentObject->isLayered();
            break;

        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
            if (attachmentObject->type() == GL_TEXTURE)
            {
                *params = attachmentObject->getSamples();
            }
            else
            {
                *params = 0;
            }
            break;

        default:
            UNREACHABLE();
            break;
    }
}

void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
{
    QueryBufferParameterBase(buffer, pname, params);
}

void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
{
    QueryBufferParameterBase(buffer, pname, params);
}

void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
{
    switch (pname)
    {
        case GL_BUFFER_MAP_POINTER:
            *params = buffer->getMapPointer();
            break;

        default:
            UNREACHABLE();
            break;
    }
}

void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params)
{
    ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR);

    switch (pname)
    {
        case GL_DELETE_STATUS:
            *params = program->isFlaggedForDeletion();
            return;
        case GL_LINK_STATUS:
            *params = program->isLinked();
            return;
        case GL_COMPLETION_STATUS_KHR:
            if (context->isContextLost())
            {
                *params = GL_TRUE;
            }
            else
            {
                *params = program->isLinking() ? GL_FALSE : GL_TRUE;
            }
            return;
        case GL_VALIDATE_STATUS:
            *params = program->isValidated();
            return;
        case GL_INFO_LOG_LENGTH:
            *params = program->getExecutable().getInfoLogLength();
            return;
        case GL_ATTACHED_SHADERS:
            *params = program->getAttachedShadersCount();
            return;
        case GL_ACTIVE_ATTRIBUTES:
            *params = program->getActiveAttributeCount();
            return;
        case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
            *params = program->getActiveAttributeMaxLength();
            return;
        case GL_ACTIVE_UNIFORMS:
            *params = program->getActiveUniformCount();
            return;
        case GL_ACTIVE_UNIFORM_MAX_LENGTH:
            *params = program->getActiveUniformMaxLength();
            return;
        case GL_PROGRAM_BINARY_LENGTH_OES:
            *params = context->getCaps().programBinaryFormats.empty()
                          ? 0
                          : program->getBinaryLength(context);
            return;
        case GL_ACTIVE_UNIFORM_BLOCKS:
            *params = program->getActiveUniformBlockCount();
            return;
        case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
            *params = program->getActiveUniformBlockMaxNameLength();
            break;
        case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
            *params = program->getTransformFeedbackBufferMode();
            break;
        case GL_TRANSFORM_FEEDBACK_VARYINGS:
            *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
            break;
        case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
            *params = program->getTransformFeedbackVaryingMaxLength();
            break;
        case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
            *params = program->getBinaryRetrievableHint();
            break;
        case GL_PROGRAM_SEPARABLE:
            // From es31cSeparateShaderObjsTests.cpp:
            // ProgramParameteri PROGRAM_SEPARABLE
            // NOTE: The query for PROGRAM_SEPARABLE must query latched
            //       state. In other words, the state of the binary after
            //       it was linked. So in the tests below, the queries
            //       should return the default state GL_FALSE since the
            //       program has no linked binary.
            *params = program->isSeparable() && program->isLinked();
            break;
        case GL_COMPUTE_WORK_GROUP_SIZE:
        {
            const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize();
            params[0]                          = localSize[0];
            params[1]                          = localSize[1];
            params[2]                          = localSize[2];
        }
        break;
        case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
            *params = program->getActiveAtomicCounterBufferCount();
            break;
        case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
            *params = ToGLenum(program->getGeometryShaderInputPrimitiveType());
            break;
        case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
            *params = ToGLenum(program->getGeometryShaderOutputPrimitiveType());
            break;
        case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
            *params = program->getGeometryShaderMaxVertices();
            break;
        case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
            *params = program->getGeometryShaderInvocations();
            break;
        case GL_TESS_CONTROL_OUTPUT_VERTICES_EXT:
            *params = program->getTessControlShaderVertices();
            break;
        case GL_TESS_GEN_MODE_EXT:
            *params = program->getTessGenMode();
            break;
        case GL_TESS_GEN_SPACING_EXT:
            *params = program->getTessGenSpacing() ? program->getTessGenSpacing() : GL_EQUAL;
            break;
        case GL_TESS_GEN_VERTEX_ORDER:
            *params = program->getTessGenVertexOrder() ? program->getTessGenVertexOrder() : GL_CCW;
            break;
        case GL_TESS_GEN_POINT_MODE_EXT:
            *params = program->getTessGenPointMode() ? GL_TRUE : GL_FALSE;
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void QueryRenderbufferiv(const Context *context,
                         const Renderbuffer *renderbuffer,
                         GLenum pname,
                         GLint *params)
{
    ASSERT(renderbuffer != nullptr);

    switch (pname)
    {
        case GL_RENDERBUFFER_WIDTH:
            *params = renderbuffer->getWidth();
            break;
        case GL_RENDERBUFFER_HEIGHT:
            *params = renderbuffer->getHeight();
            break;
        case GL_RENDERBUFFER_INTERNAL_FORMAT:
            // Special case the WebGL 1 DEPTH_STENCIL format.
            if (context->isWebGL1() &&
                renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
            {
                *params = GL_DEPTH_STENCIL;
            }
            else
            {
                *params = renderbuffer->getFormat().info->internalFormat;
            }
            break;
        case GL_RENDERBUFFER_RED_SIZE:
            *params = renderbuffer->getRedSize();
            break;
        case GL_RENDERBUFFER_GREEN_SIZE:
            *params = renderbuffer->getGreenSize();
            break;
        case GL_RENDERBUFFER_BLUE_SIZE:
            *params = renderbuffer->getBlueSize();
            break;
        case GL_RENDERBUFFER_ALPHA_SIZE:
            *params = renderbuffer->getAlphaSize();
            break;
        case GL_RENDERBUFFER_DEPTH_SIZE:
            *params = renderbuffer->getDepthSize();
            break;
        case GL_RENDERBUFFER_STENCIL_SIZE:
            *params = renderbuffer->getStencilSize();
            break;
        case GL_RENDERBUFFER_SAMPLES_ANGLE:
            *params = renderbuffer->getState().getSamples();
            break;
        case GL_MEMORY_SIZE_ANGLE:
            *params = renderbuffer->getMemorySize();
            break;
        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
            *params = static_cast<GLint>(renderbuffer->getImplementationColorReadFormat(context));
            break;
        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
            *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
            break;
        case GL_RESOURCE_INITIALIZED_ANGLE:
            *params = (renderbuffer->initState(GL_NONE, ImageIndex()) == InitState::Initialized);
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
{
    ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);

    switch (pname)
    {
        case GL_SHADER_TYPE:
            *params = static_cast<GLint>(ToGLenum(shader->getType()));
            return;
        case GL_DELETE_STATUS:
            *params = shader->isFlaggedForDeletion();
            return;
        case GL_COMPILE_STATUS:
            *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
            return;
        case GL_COMPLETION_STATUS_KHR:
            if (context->isContextLost())
            {
                *params = GL_TRUE;
            }
            else
            {
                *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
            }
            return;
        case GL_INFO_LOG_LENGTH:
            *params = shader->getInfoLogLength(context);
            return;
        case GL_SHADER_SOURCE_LENGTH:
            *params = shader->getSourceLength();
            return;
        case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
            *params = shader->getTranslatedSourceWithDebugInfoLength(context);
            return;
        default:
            UNREACHABLE();
            break;
    }
}

void QueryTexLevelParameterfv(const Texture *texture,
                              TextureTarget target,
                              GLint level,
                              GLenum pname,
                              GLfloat *params)
{
    QueryTexLevelParameterBase(texture, target, level, pname, params);
}

void QueryTexLevelParameteriv(const Texture *texture,
                              TextureTarget target,
                              GLint level,
                              GLenum pname,
                              GLint *params)
{
    QueryTexLevelParameterBase(texture, target, level, pname, params);
}

void QueryTexParameterfv(const Context *context,
                         const Texture *texture,
                         GLenum pname,
                         GLfloat *params)
{
    QueryTexParameterBase<falsefalse>(context, texture, pname, params);
}

void QueryTexParameterxv(const Context *context,
                         const Texture *texture,
                         GLenum pname,
                         GLfixed *params)
{
    QueryTexParameterBase<falsetrue>(context, texture, pname, params);
}

void QueryTexParameteriv(const Context *context,
                         const Texture *texture,
                         GLenum pname,
                         GLint *params)
{
    QueryTexParameterBase<falsefalse>(context, texture, pname, params);
}

void QueryTexParameterIiv(const Context *context,
                          const Texture *texture,
                          GLenum pname,
                          GLint *params)
{
    QueryTexParameterBase<truefalse>(context, texture, pname, params);
}

void QueryTexParameterIuiv(const Context *context,
                           const Texture *texture,
                           GLenum pname,
                           GLuint *params)
{
    QueryTexParameterBase<truefalse>(context, texture, pname, params);
}

void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
{
    QuerySamplerParameterBase<false>(sampler, pname, params);
}

void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
{
    QuerySamplerParameterBase<false>(sampler, pname, params);
}

void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
{
    QuerySamplerParameterBase<true>(sampler, pname, params);
}

void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
{
    QuerySamplerParameterBase<true>(sampler, pname, params);
}

void QueryVertexAttribfv(const VertexAttribute &attrib,
                         const VertexBinding &binding,
                         const VertexAttribCurrentValueData ¤tValueData,
                         GLenum pname,
                         GLfloat *params)
{
    QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
}

void QueryVertexAttribiv(const VertexAttribute &attrib,
                         const VertexBinding &binding,
                         const VertexAttribCurrentValueData ¤tValueData,
                         GLenum pname,
                         GLint *params)
{
    QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
}

void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
{
    switch (pname)
    {
        case GL_VERTEX_ATTRIB_ARRAY_POINTER:
            *pointer = const_cast<void *>(attrib.pointer);
            break;

        default:
            UNREACHABLE();
            break;
    }
}

void QueryVertexAttribIiv(const VertexAttribute &attrib,
                          const VertexBinding &binding,
                          const VertexAttribCurrentValueData ¤tValueData,
                          GLenum pname,
                          GLint *params)
{
    QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
}

void QueryVertexAttribIuiv(const VertexAttribute &attrib,
                           const VertexBinding &binding,
                           const VertexAttribCurrentValueData ¤tValueData,
                           GLenum pname,
                           GLuint *params)
{
    QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
                          params);
}

void QueryActiveUniformBlockiv(const Program *program,
                               UniformBlockIndex uniformBlockIndex,
                               GLenum pname,
                               GLint *params)
{
    GLenum prop = GetUniformBlockPropertyEnum(pname);
    QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
                           std::numeric_limits<GLsizei>::max(), nullptr, params);
}

void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
{
    switch (pname)
    {
        case GL_NUM_SAMPLE_COUNTS:
            if (bufSize != 0)
            {
                *params = clampCast<GLint>(format.sampleCounts.size());
            }
            break;

        case GL_SAMPLES:
        {
            size_t returnCount   = std::min<size_t>(bufSize, format.sampleCounts.size());
            auto sampleReverseIt = format.sampleCounts.rbegin();
            for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
            {
                params[sampleIndex] = *sampleReverseIt++;
            }
        }
        break;

        default:
            UNREACHABLE();
            break;
    }
}

void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
{
    ASSERT(framebuffer);

    switch (pname)
    {
        case GL_FRAMEBUFFER_DEFAULT_WIDTH:
            *params = framebuffer->getDefaultWidth();
            break;
        case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
            *params = framebuffer->getDefaultHeight();
            break;
        case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
            *params = framebuffer->getDefaultSamples();
            break;
        case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
            *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
            break;
        case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
            *params = framebuffer->getDefaultLayers();
            break;
        case GL_FRAMEBUFFER_FLIP_Y_MESA:
            *params = ConvertToGLBoolean(framebuffer->getFlipY());
            break;
        default:
            UNREACHABLE();
            break;
    }
}

angle::Result QuerySynciv(const Context *context,
                          const Sync *sync,
                          GLenum pname,
                          GLsizei bufSize,
                          GLsizei *length,
                          GLint *values)
{
    ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);

    // All queries return one value, exit early if the buffer can't fit anything.
    if (bufSize < 1)
    {
        if (length != nullptr)
        {
            *length = 0;
        }
        return angle::Result::Continue;
    }

    switch (pname)
    {
        case GL_OBJECT_TYPE:
            *values = clampCast<GLint>(GL_SYNC_FENCE);
            break;
        case GL_SYNC_CONDITION:
            *values = clampCast<GLint>(sync->getCondition());
            break;
        case GL_SYNC_FLAGS:
            *values = clampCast<GLint>(sync->getFlags());
            break;
        case GL_SYNC_STATUS:
            if (context->isContextLost())
            {
                *values = GL_SIGNALED;
            }
            else
            {
                ANGLE_TRY(sync->getStatus(context, values));
            }
            break;

        default:
            UNREACHABLE();
            break;
    }

    if (length != nullptr)
    {
        *length = 1;
    }

    return angle::Result::Continue;
}

void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param)
{
    SetTexParameterBase<falsetrue>(context, texture, pname, ¶m);
}

void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params)
{
    SetTexParameterBase<falsetrue>(context, texture, pname, params);
}

void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
{
    SetTexParameterBase<falsefalse>(context, texture, pname, ¶m);
}

void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
{
    SetTexParameterBase<falsefalse>(context, texture, pname, params);
}

void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
{
    SetTexParameterBase<falsefalse>(context, texture, pname, ¶m);
}

void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
{
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.26 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge