/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "GLESv2Validate.h" #include #define LIST_VALID_TEXFORMATS(f) \ f(GL_DEPTH_COMPONENT) \ f(GL_DEPTH_STENCIL) \ f(GL_RED) \ f(GL_RED_INTEGER) \ f(GL_RG) \ f(GL_RGB) \ f(GL_RGBA) \ f(GL_RGBA_INTEGER) \ f(GL_RGB_INTEGER) \ f(GL_RG_INTEGER) \ #define LIST_VALID_TEXTYPES(f) \ f(GL_BYTE) \ f(GL_FLOAT) \ f(GL_FLOAT_32_UNSIGNED_INT_24_8_REV) \ f(GL_HALF_FLOAT) \ f(GL_HALF_FLOAT_OES) \ f(GL_INT) \ f(GL_SHORT) \ f(GL_UNSIGNED_BYTE) \ f(GL_UNSIGNED_INT) \ f(GL_UNSIGNED_INT_10F_11F_11F_REV) \ f(GL_UNSIGNED_INT_2_10_10_10_REV) \ f(GL_UNSIGNED_INT_24_8) \ f(GL_UNSIGNED_INT_5_9_9_9_REV) \ f(GL_UNSIGNED_SHORT) \ f(GL_UNSIGNED_SHORT_4_4_4_4) \ f(GL_UNSIGNED_SHORT_5_5_5_1) \ f(GL_UNSIGNED_SHORT_5_6_5) \ #define LIST_VALID_TEXFORMAT_COMBINATIONS(f) \ f(GL_BGRA8_EXT, GL_BGRA_EXT, GL_UNSIGNED_BYTE) \ f(GL_R8, GL_RED, GL_UNSIGNED_BYTE) \ f(GL_R8_SNORM, GL_RED, GL_BYTE) \ f(GL_R16F, GL_RED, GL_FLOAT) \ f(GL_R16F, GL_RED, GL_HALF_FLOAT) \ f(GL_R32F, GL_RED, GL_FLOAT) \ f(GL_R8UI, GL_RED_INTEGER, GL_UNSIGNED_BYTE) \ f(GL_R8I, GL_RED_INTEGER, GL_BYTE) \ f(GL_R16UI, GL_RED_INTEGER, GL_UNSIGNED_SHORT) \ f(GL_R16I, GL_RED_INTEGER, GL_SHORT) \ f(GL_R32UI, GL_RED_INTEGER, GL_UNSIGNED_INT) \ f(GL_R32I, GL_RED_INTEGER, GL_INT) \ f(GL_RG8, GL_RG, GL_UNSIGNED_BYTE) \ f(GL_RG8_SNORM, GL_RG, GL_BYTE) \ f(GL_RG16F, GL_RG, GL_HALF_FLOAT) \ f(GL_RG16F, GL_RG, GL_FLOAT) \ f(GL_RG32F, GL_RG, GL_FLOAT) \ f(GL_RG8UI, GL_RG_INTEGER, GL_UNSIGNED_BYTE) \ f(GL_RG8I, GL_RG_INTEGER, GL_BYTE) \ f(GL_RG16UI, GL_RG_INTEGER, GL_UNSIGNED_SHORT) \ f(GL_RG16I, GL_RG_INTEGER, GL_SHORT) \ f(GL_RG32UI, GL_RG_INTEGER, GL_UNSIGNED_INT) \ f(GL_RG32I, GL_RG_INTEGER, GL_INT) \ f(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE) \ f(GL_SRGB8, GL_RGB, GL_UNSIGNED_BYTE) \ f(GL_RGB565, GL_RGB, GL_UNSIGNED_BYTE) \ f(GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5) \ f(GL_RGB8_SNORM, GL_RGB, GL_BYTE) \ f(GL_R11F_G11F_B10F, GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV) \ f(GL_R11F_G11F_B10F, GL_RGB, GL_HALF_FLOAT) \ f(GL_R11F_G11F_B10F, GL_RGB, GL_FLOAT) \ f(GL_RGB9_E5, GL_RGB, GL_UNSIGNED_INT_5_9_9_9_REV) \ f(GL_RGB9_E5, GL_RGB, GL_HALF_FLOAT) \ f(GL_RGB9_E5, GL_RGB, GL_FLOAT) \ f(GL_RGB16F, GL_RGB, GL_HALF_FLOAT) \ f(GL_RGB16F, GL_RGB, GL_FLOAT) \ f(GL_RGB32F, GL_RGB, GL_FLOAT) \ f(GL_RGB8UI, GL_RGB_INTEGER, GL_UNSIGNED_BYTE) \ f(GL_RGB8I, GL_RGB_INTEGER, GL_BYTE) \ f(GL_RGB16UI, GL_RGB_INTEGER, GL_UNSIGNED_SHORT) \ f(GL_RGB16I, GL_RGB_INTEGER, GL_SHORT) \ f(GL_RGB32UI, GL_RGB_INTEGER, GL_UNSIGNED_INT) \ f(GL_RGB32I, GL_RGB_INTEGER, GL_INT) \ f(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_RGBA8_SNORM, GL_RGBA, GL_BYTE) \ f(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1) \ f(GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV) \ f(GL_RGBA4, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4) \ f(GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV) \ f(GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT) \ f(GL_RGBA16F, GL_RGBA, GL_FLOAT) \ f(GL_RGBA32F, GL_RGBA, GL_FLOAT) \ f(GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE) \ f(GL_RGBA8I, GL_RGBA_INTEGER, GL_BYTE) \ f(GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV) \ f(GL_RGBA16UI, GL_RGBA_INTEGER, GL_UNSIGNED_SHORT) \ f(GL_RGBA16I, GL_RGBA_INTEGER, GL_SHORT) \ f(GL_RGBA32I, GL_RGBA_INTEGER, GL_INT) \ f(GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT) \ f(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT) \ f(GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT) \ f(GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT) \ f(GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT, GL_FLOAT) \ f(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8) \ f(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV) \ f(GL_COMPRESSED_R11_EAC, GL_RED, GL_FLOAT) \ f(GL_COMPRESSED_SIGNED_R11_EAC, GL_RED, GL_FLOAT) \ f(GL_COMPRESSED_RG11_EAC, GL_RG, GL_FLOAT) \ f(GL_COMPRESSED_SIGNED_RG11_EAC, GL_RG, GL_FLOAT) \ f(GL_COMPRESSED_RGB8_ETC2, GL_RGB, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ETC2, GL_RGB, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA8_ETC2_EAC, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ f(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, GL_RGBA, GL_UNSIGNED_BYTE) \ bool GLESv2Validate::renderbufferParam(GLEScontext* ctx, GLenum pname){ int glesMajorVersion = ctx->getMajorVersion(); switch(pname){ case GL_RENDERBUFFER_WIDTH: case GL_RENDERBUFFER_HEIGHT: case GL_RENDERBUFFER_INTERNAL_FORMAT: case GL_RENDERBUFFER_RED_SIZE: case GL_RENDERBUFFER_GREEN_SIZE: case GL_RENDERBUFFER_BLUE_SIZE: case GL_RENDERBUFFER_ALPHA_SIZE: case GL_RENDERBUFFER_DEPTH_SIZE: case GL_RENDERBUFFER_STENCIL_SIZE: return true; case GL_RENDERBUFFER_SAMPLES: return glesMajorVersion >= 3; } return false; } bool GLESv2Validate::framebufferTarget(GLEScontext* ctx, GLenum target) { int glesMajorVersion = ctx->getMajorVersion(); switch (target) { case GL_FRAMEBUFFER: return true; case GL_DRAW_FRAMEBUFFER: case GL_READ_FRAMEBUFFER: return glesMajorVersion >= 3; } return false; } bool GLESv2Validate::framebufferAttachment(GLEScontext* ctx, GLenum attachment) { int glesMajorVersion = ctx->getMajorVersion(); switch (attachment) { case GL_COLOR_ATTACHMENT0: case GL_DEPTH_ATTACHMENT: case GL_STENCIL_ATTACHMENT: return true; case GL_COLOR_ATTACHMENT1: case GL_COLOR_ATTACHMENT2: case GL_COLOR_ATTACHMENT3: case GL_COLOR_ATTACHMENT4: case GL_COLOR_ATTACHMENT5: case GL_COLOR_ATTACHMENT6: case GL_COLOR_ATTACHMENT7: case GL_COLOR_ATTACHMENT8: case GL_COLOR_ATTACHMENT9: case GL_COLOR_ATTACHMENT10: case GL_COLOR_ATTACHMENT11: case GL_COLOR_ATTACHMENT12: case GL_COLOR_ATTACHMENT13: case GL_COLOR_ATTACHMENT14: case GL_COLOR_ATTACHMENT15: case GL_DEPTH_STENCIL_ATTACHMENT: return glesMajorVersion >= 3; } return false; } bool GLESv2Validate::bufferTarget(GLEScontext* ctx, GLenum target) { int glesMajorVersion = ctx->getMajorVersion(); int glesMinorVersion = ctx->getMinorVersion(); switch (target) { case GL_ARRAY_BUFFER: // Vertex attributes case GL_ELEMENT_ARRAY_BUFFER: // Vertex array indices return true; // GLES 3.0 buffers case GL_COPY_READ_BUFFER: // Buffer copy source case GL_COPY_WRITE_BUFFER: // Buffer copy destination case GL_PIXEL_PACK_BUFFER: // Pixel read target case GL_PIXEL_UNPACK_BUFFER: // Texture data source case GL_TRANSFORM_FEEDBACK_BUFFER: // Transform feedback buffer case GL_UNIFORM_BUFFER: // Uniform block storage return glesMajorVersion >= 3; // GLES 3.1 buffers case GL_ATOMIC_COUNTER_BUFFER: // Atomic counter storage case GL_DISPATCH_INDIRECT_BUFFER: // Indirect compute dispatch commands case GL_DRAW_INDIRECT_BUFFER: // Indirect command arguments case GL_SHADER_STORAGE_BUFFER: // Read-write storage for shaders return glesMajorVersion >= 3 && glesMinorVersion >= 1; case GL_TEXTURE_BUFFER: return glesMajorVersion >= 3 && ((glesMinorVersion == 1 && ctx->getCaps()->textureBufferAny()) || glesMinorVersion > 1 ); default: return false; } } bool GLESv2Validate::bufferUsage(GLEScontext* ctx, GLenum usage) { int glesMajorVersion = ctx->getMajorVersion(); switch(usage) { case GL_STREAM_DRAW: case GL_STATIC_DRAW: case GL_DYNAMIC_DRAW: return true; case GL_STREAM_READ: case GL_STATIC_READ: case GL_DYNAMIC_READ: case GL_STREAM_COPY: case GL_STATIC_COPY: case GL_DYNAMIC_COPY: return glesMajorVersion >= 3; } return false; } bool GLESv2Validate::bufferParam(GLEScontext* ctx, GLenum pname) { int glesMajorVersion = ctx->getMajorVersion(); switch (pname) { case GL_BUFFER_SIZE: case GL_BUFFER_USAGE: return true; case GL_BUFFER_ACCESS_FLAGS: case GL_BUFFER_MAPPED: case GL_BUFFER_MAP_LENGTH: case GL_BUFFER_MAP_OFFSET: return glesMajorVersion >= 3; default: return false; } } bool GLESv2Validate::blendEquationMode(GLEScontext* ctx, GLenum mode){ int glesMajorVersion = ctx->getMajorVersion(); switch (mode) { case GL_FUNC_ADD: case GL_FUNC_SUBTRACT: case GL_FUNC_REVERSE_SUBTRACT: return true; case GL_MIN: case GL_MAX: return glesMajorVersion >= 3; } return false; } bool GLESv2Validate::blendSrc(GLenum s) { switch(s) { case GL_ZERO: case GL_ONE: case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: case GL_DST_COLOR: case GL_ONE_MINUS_DST_COLOR: case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: case GL_DST_ALPHA: case GL_ONE_MINUS_DST_ALPHA: case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: case GL_SRC_ALPHA_SATURATE: return true; } return false; } bool GLESv2Validate::blendDst(GLenum d) { switch(d) { case GL_ZERO: case GL_ONE: case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: case GL_DST_COLOR: case GL_ONE_MINUS_DST_COLOR: case GL_SRC_ALPHA: case GL_ONE_MINUS_SRC_ALPHA: case GL_DST_ALPHA: case GL_ONE_MINUS_DST_ALPHA: case GL_CONSTANT_COLOR: case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: case GL_SRC_ALPHA_SATURATE: return true; } return false; } bool GLESv2Validate::textureTarget(GLEScontext* ctx, GLenum target) { int glesMajorVersion = ctx->getMajorVersion(); int glesMinorVersion = ctx->getMinorVersion(); switch (target) { case GL_TEXTURE_2D: case GL_TEXTURE_CUBE_MAP: return true; case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_3D: return glesMajorVersion >= 3; case GL_TEXTURE_2D_MULTISAMPLE: return glesMajorVersion >= 3 && glesMinorVersion >= 1; case GL_TEXTURE_BUFFER: return glesMajorVersion >= 3 && ( glesMinorVersion > 1 || (glesMinorVersion == 1 && ctx->getCaps()->textureBufferAny())); default: return false; } } bool GLESv2Validate::textureParams(GLEScontext* ctx, GLenum param) { int glesMajorVersion = ctx->getMajorVersion(); int glesMinorVersion = ctx->getMinorVersion(); switch(param) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_MAX_ANISOTROPY_EXT: return true; case GL_TEXTURE_SWIZZLE_R: case GL_TEXTURE_SWIZZLE_G: case GL_TEXTURE_SWIZZLE_B: case GL_TEXTURE_SWIZZLE_A: case GL_TEXTURE_MIN_LOD: case GL_TEXTURE_MAX_LOD: case GL_TEXTURE_BASE_LEVEL: case GL_TEXTURE_MAX_LEVEL: case GL_TEXTURE_COMPARE_MODE: case GL_TEXTURE_COMPARE_FUNC: case GL_TEXTURE_WRAP_R: case GL_TEXTURE_IMMUTABLE_FORMAT: case GL_TEXTURE_IMMUTABLE_LEVELS: return glesMajorVersion >= 3; case GL_DEPTH_STENCIL_TEXTURE_MODE: return glesMajorVersion >= 3 && glesMinorVersion >= 1; default: return false; } } bool GLESv2Validate::hintTargetMode(GLenum target,GLenum mode){ switch(mode) { case GL_FASTEST: case GL_NICEST: case GL_DONT_CARE: break; default: return false; } return target == GL_GENERATE_MIPMAP_HINT || target == GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES; } bool GLESv2Validate::capability(GLenum cap){ switch(cap){ case GL_BLEND: case GL_CULL_FACE: case GL_DEPTH_TEST: case GL_DITHER: case GL_POLYGON_OFFSET_FILL: case GL_SAMPLE_ALPHA_TO_COVERAGE: case GL_SAMPLE_COVERAGE: case GL_SCISSOR_TEST: case GL_STENCIL_TEST: return true; } return false; } bool GLESv2Validate::pixelStoreParam(GLEScontext* ctx, GLenum param){ int glesMajorVersion = ctx->getMajorVersion(); switch(param) { case GL_PACK_ALIGNMENT: case GL_UNPACK_ALIGNMENT: return true; case GL_PACK_ROW_LENGTH: case GL_PACK_SKIP_PIXELS: case GL_PACK_SKIP_ROWS: case GL_UNPACK_ROW_LENGTH: case GL_UNPACK_IMAGE_HEIGHT: case GL_UNPACK_SKIP_PIXELS: case GL_UNPACK_SKIP_ROWS: case GL_UNPACK_SKIP_IMAGES: return glesMajorVersion >= 3; default: return false; } } bool GLESv2Validate::readPixelFrmt(GLenum format){ switch(format) { case GL_ALPHA: case GL_LUMINANCE_ALPHA: case GL_RGB: case GL_RGBA: return true; } return false; } bool GLESv2Validate::shaderType(GLEScontext* ctx, GLenum type){ int glesMajorVersion = ctx->getMajorVersion(); int glesMinorVersion = ctx->getMinorVersion(); switch (type) { case GL_VERTEX_SHADER: case GL_FRAGMENT_SHADER: return true; case GL_COMPUTE_SHADER: return glesMajorVersion >= 3 && glesMinorVersion >= 1; } return false; } bool GLESv2Validate::precisionType(GLenum type){ switch(type){ case GL_LOW_FLOAT: case GL_MEDIUM_FLOAT: case GL_HIGH_FLOAT: case GL_LOW_INT: case GL_MEDIUM_INT: case GL_HIGH_INT: return true; } return false; } bool GLESv2Validate::arrayIndex(GLEScontext * ctx,GLuint index) { return index < (GLuint)ctx->getCaps()->maxVertexAttribs; } #define GL_RED 0x1903 #define GL_RG 0x8227 #define GL_R8 0x8229 #define GL_RG8 0x822B #define GL_R16F 0x822D #define GL_RG16F 0x822F #define GL_RGBA16F 0x881A #define GL_RGB16F 0x881B #define GL_R11F_G11F_B10F 0x8C3A #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B bool GLESv2Validate::pixelType(GLEScontext * ctx,GLenum type) { int glesMajorVersion = ctx->getMajorVersion(); if (glesMajorVersion < 3) { if(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT || type == GL_UNSIGNED_INT_10F_11F_11F_REV) return true; return GLESvalidate::pixelType(ctx, type); } #define GLES3_TYPE_CASE(type) \ case type: \ switch (type) { LIST_VALID_TEXTYPES(GLES3_TYPE_CASE) return glesMajorVersion >= 3; default: break; } return false; } bool GLESv2Validate::pixelFrmt(GLEScontext* ctx,GLenum format) { int glesMajorVersion = ctx->getMajorVersion(); if (glesMajorVersion < 3) { switch (format) { case GL_DEPTH_COMPONENT: // GLES3 compatible // Required in dEQP case GL_RED: case GL_RG: return true; } return GLESvalidate::pixelFrmt(ctx, format); } #define GLES3_FORMAT_CASE(format) \ case format: switch (format) { LIST_VALID_TEXFORMATS(GLES3_FORMAT_CASE) return glesMajorVersion >= 3; default: break; } return GLESvalidate::pixelFrmt(ctx, format); } bool GLESv2Validate::pixelItnlFrmt(GLEScontext* ctx ,GLenum internalformat) { int glesMajorVersion = ctx->getMajorVersion(); switch (internalformat) { case GL_R8: case GL_RG8: case GL_R16F: case GL_RG16F: case GL_RGBA16F: case GL_RGB16F: case GL_R11F_G11F_B10F: case GL_RGB8: case GL_RGBA8: return true; case GL_R8_SNORM: case GL_R32F: case GL_R8UI: case GL_R8I: case GL_R16UI: case GL_R16I: case GL_R32UI: case GL_R32I: case GL_RG8_SNORM: case GL_RG32F: case GL_RG8UI: case GL_RG8I: case GL_RG16UI: case GL_RG16I: case GL_RG32UI: case GL_RG32I: case GL_SRGB8: case GL_RGB565: case GL_RGB8_SNORM: case GL_RGB9_E5: case GL_RGB32F: case GL_RGB8UI: case GL_RGB8I: case GL_RGB16UI: case GL_RGB16I: case GL_RGB32UI: case GL_RGB32I: case GL_SRGB8_ALPHA8: case GL_RGBA8_SNORM: case GL_RGB5_A1: case GL_RGBA4: case GL_RGB10_A2: case GL_RGBA32F: case GL_RGBA8UI: case GL_RGBA8I: case GL_RGB10_A2UI: case GL_RGBA16UI: case GL_RGBA16I: case GL_RGBA32I: case GL_RGBA32UI: case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32F: case GL_DEPTH24_STENCIL8: case GL_DEPTH32F_STENCIL8: case GL_COMPRESSED_R11_EAC: case GL_COMPRESSED_SIGNED_R11_EAC: case GL_COMPRESSED_RG11_EAC: case GL_COMPRESSED_SIGNED_RG11_EAC: case GL_COMPRESSED_RGB8_ETC2: case GL_COMPRESSED_SRGB8_ETC2: case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: case GL_COMPRESSED_RGBA8_ETC2_EAC: case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: if (glesMajorVersion >= 3) { return true; } break; } return pixelFrmt(ctx, internalformat); } bool GLESv2Validate::pixelSizedFrmt(GLEScontext* ctx, GLenum internalformat, GLenum format, GLenum type) { int glesMajorVersion = ctx->getMajorVersion(); if (internalformat == format) { return true; } if (glesMajorVersion < 3) { switch (format) { case GL_RED: switch (type) { case GL_UNSIGNED_BYTE: return internalformat == GL_R8; case GL_HALF_FLOAT: case GL_FLOAT: return internalformat == GL_R16F; case GL_BYTE: return internalformat == GL_R8_SNORM; default: return false; } break; case GL_RG: switch (type) { case GL_UNSIGNED_BYTE: return internalformat == GL_RG8; case GL_HALF_FLOAT: case GL_FLOAT: return internalformat == GL_RG16F; default: return false; } break; case GL_RGB: switch (type) { case GL_HALF_FLOAT: case GL_FLOAT: return internalformat == GL_RGB16F || internalformat == GL_R11F_G11F_B10F; case GL_UNSIGNED_INT_10F_11F_11F_REV: return internalformat == GL_R11F_G11F_B10F; default: return internalformat == GL_RGB8 || internalformat == GL_RGB; } break; case GL_RGBA: switch (type) { case GL_HALF_FLOAT: case GL_FLOAT: return internalformat == GL_RGBA16F; default: return internalformat == GL_RGBA8 || internalformat == GL_RGBA; } break; } } #define VALIDATE_FORMAT_COMBINATION(x, y, z) \ if (internalformat == x && format == y && type == z) return true; \ LIST_VALID_TEXFORMAT_COMBINATIONS(VALIDATE_FORMAT_COMBINATION) return false; } bool GLESv2Validate::isCompressedFormat(GLenum format) { switch (format) { case GL_ETC1_RGB8_OES: case GL_COMPRESSED_R11_EAC: case GL_COMPRESSED_SIGNED_R11_EAC: case GL_COMPRESSED_RG11_EAC: case GL_COMPRESSED_SIGNED_RG11_EAC: case GL_COMPRESSED_RGB8_ETC2: case GL_COMPRESSED_SRGB8_ETC2: case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: case GL_COMPRESSED_RGBA8_ETC2_EAC: case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT: case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: case GL_COMPRESSED_RED_RGTC1_EXT: case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: return true; } return false; } void GLESv2Validate::getCompatibleFormatTypeForInternalFormat(GLenum internalformat, GLenum* format_out, GLenum* type_out) { #define RETURN_COMPATIBLE_FORMAT(x, y, z) \ if (internalformat == x) { \ *format_out = y; \ *type_out = z; \ return; \ } \ LIST_VALID_TEXFORMAT_COMBINATIONS(RETURN_COMPATIBLE_FORMAT) } bool GLESv2Validate::attribName(const GLchar* name){ const GLchar* found = strstr(name,"gl_"); return (!found) || (found != name) ; // attrib name does not start with gl_ } bool GLESv2Validate::attribIndex(int index, int max){ return index >=0 && index < max; } bool GLESv2Validate::programParam(GLEScontext* ctx, GLenum pname){ int glesMajorVersion = ctx->getMajorVersion(); int glesMinorVersion = ctx->getMinorVersion(); switch(pname){ case GL_DELETE_STATUS: case GL_LINK_STATUS: case GL_VALIDATE_STATUS: case GL_INFO_LOG_LENGTH: case GL_ATTACHED_SHADERS: case GL_ACTIVE_ATTRIBUTES: case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: case GL_ACTIVE_UNIFORMS: case GL_ACTIVE_UNIFORM_MAX_LENGTH: return true; case GL_ACTIVE_UNIFORM_BLOCKS: case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: case GL_PROGRAM_BINARY_LENGTH: case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: case GL_TRANSFORM_FEEDBACK_VARYINGS: case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: case GL_PROGRAM_SEPARABLE: return glesMajorVersion >= 3; case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: case GL_COMPUTE_WORK_GROUP_SIZE: return glesMajorVersion >= 3 && glesMinorVersion >= 1; } return false; } bool GLESv2Validate::textureIsCubeMap(GLenum target){ switch(target){ case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return true; } return false; } bool GLESv2Validate::textureTargetEx(GLEScontext* ctx, GLenum textarget) { int glesMajorVersion = ctx->getMajorVersion(); int glesMinorVersion = ctx->getMinorVersion(); switch (textarget) { case GL_TEXTURE_2D_MULTISAMPLE: return glesMajorVersion >= 3 && glesMinorVersion >= 1; default: return GLESvalidate::textureTargetEx(textarget); } } int GLESv2Validate::sizeOfType(GLenum type) { size_t retval = 0; switch(type) { case GL_BYTE: case GL_UNSIGNED_BYTE: retval = 1; break; case GL_SHORT: case GL_UNSIGNED_SHORT: case GL_HALF_FLOAT: case GL_HALF_FLOAT_OES: retval = 2; break; case GL_UNSIGNED_INT: case GL_INT: case GL_FLOAT: case GL_FIXED: case GL_BOOL: retval = 4; break; #ifdef GL_DOUBLE case GL_DOUBLE: retval = 8; break; #endif case GL_FLOAT_VEC2: case GL_INT_VEC2: case GL_UNSIGNED_INT_VEC2: case GL_BOOL_VEC2: retval = 8; break; case GL_INT_VEC3: case GL_UNSIGNED_INT_VEC3: case GL_BOOL_VEC3: case GL_FLOAT_VEC3: retval = 12; break; case GL_FLOAT_VEC4: case GL_BOOL_VEC4: case GL_INT_VEC4: case GL_UNSIGNED_INT_VEC4: case GL_FLOAT_MAT2: retval = 16; break; case GL_FLOAT_MAT3: retval = 36; break; case GL_FLOAT_MAT4: retval = 64; break; case GL_FLOAT_MAT2x3: case GL_FLOAT_MAT3x2: retval = 4 * 6; break; case GL_FLOAT_MAT2x4: case GL_FLOAT_MAT4x2: retval = 4 * 8; break; case GL_FLOAT_MAT3x4: case GL_FLOAT_MAT4x3: retval = 4 * 12; break; case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: retval = 4; break; case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_5_5_5_1: case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: retval = 2; break; case GL_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_10F_11F_11F_REV: case GL_UNSIGNED_INT_5_9_9_9_REV: case GL_UNSIGNED_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_24_8_OES:; retval = 4; break; case GL_FLOAT_32_UNSIGNED_INT_24_8_REV: retval = 4 + 4; break; default: fprintf(stderr, "%s: WARNING: unknown type 0x%x. assuming 32 bits.\n", __FUNCTION__, type); retval = 4; } return retval; }