michael@0: #include "precompiled.h" michael@0: // michael@0: // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: // michael@0: michael@0: // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions. michael@0: michael@0: #include "common/version.h" michael@0: michael@0: #include michael@0: michael@0: #include "libGLESv2/main.h" michael@0: #include "libGLESv2/utilities.h" michael@0: #include "libGLESv2/Buffer.h" michael@0: #include "libGLESv2/Fence.h" michael@0: #include "libGLESv2/Framebuffer.h" michael@0: #include "libGLESv2/Renderbuffer.h" michael@0: #include "libGLESv2/Program.h" michael@0: #include "libGLESv2/ProgramBinary.h" michael@0: #include "libGLESv2/Texture.h" michael@0: #include "libGLESv2/Query.h" michael@0: #include "libGLESv2/Context.h" michael@0: michael@0: bool validImageSize(GLint level, GLsizei width, GLsizei height) michael@0: { michael@0: if (level < 0 || width < 0 || height < 0) michael@0: { michael@0: return false; michael@0: } michael@0: michael@0: if (gl::getContext() && gl::getContext()->supportsNonPower2Texture()) michael@0: { michael@0: return true; michael@0: } michael@0: michael@0: if (level == 0) michael@0: { michael@0: return true; michael@0: } michael@0: michael@0: if (gl::isPow2(width) && gl::isPow2(height)) michael@0: { michael@0: return true; michael@0: } michael@0: michael@0: return false; michael@0: } michael@0: michael@0: // Verify that format/type are one of the combinations from table 3.4. michael@0: bool checkTextureFormatType(GLenum format, GLenum type) michael@0: { michael@0: // validate by itself (used as secondary key below) michael@0: switch (format) michael@0: { michael@0: case GL_RGBA: michael@0: case GL_BGRA_EXT: michael@0: case GL_RGB: michael@0: case GL_ALPHA: michael@0: case GL_LUMINANCE: michael@0: case GL_LUMINANCE_ALPHA: michael@0: case GL_DEPTH_COMPONENT: michael@0: case GL_DEPTH_STENCIL_OES: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM, false); michael@0: } michael@0: michael@0: // invalid -> sets INVALID_ENUM michael@0: // invalid + combination -> sets INVALID_OPERATION michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: switch (format) michael@0: { michael@0: case GL_RGBA: michael@0: case GL_BGRA_EXT: michael@0: case GL_RGB: michael@0: case GL_ALPHA: michael@0: case GL_LUMINANCE: michael@0: case GL_LUMINANCE_ALPHA: michael@0: return true; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: case GL_FLOAT: michael@0: case GL_HALF_FLOAT_OES: michael@0: switch (format) michael@0: { michael@0: case GL_RGBA: michael@0: case GL_RGB: michael@0: case GL_ALPHA: michael@0: case GL_LUMINANCE: michael@0: case GL_LUMINANCE_ALPHA: michael@0: return true; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: case GL_UNSIGNED_SHORT_4_4_4_4: michael@0: case GL_UNSIGNED_SHORT_5_5_5_1: michael@0: switch (format) michael@0: { michael@0: case GL_RGBA: michael@0: return true; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: case GL_UNSIGNED_SHORT_5_6_5: michael@0: switch (format) michael@0: { michael@0: case GL_RGB: michael@0: return true; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: case GL_UNSIGNED_SHORT: michael@0: case GL_UNSIGNED_INT: michael@0: switch (format) michael@0: { michael@0: case GL_DEPTH_COMPONENT: michael@0: return true; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: case GL_UNSIGNED_INT_24_8_OES: michael@0: switch (format) michael@0: { michael@0: case GL_DEPTH_STENCIL_OES: michael@0: return true; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM, false); michael@0: } michael@0: } michael@0: michael@0: bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height, michael@0: GLint xoffset, GLint yoffset, GLint level, GLenum format, GLenum type, michael@0: gl::Texture2D *texture) michael@0: { michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: if (compressed != texture->isCompressed(level)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: if (format != GL_NONE) michael@0: { michael@0: GLenum internalformat = gl::ConvertSizedInternalFormat(format, type); michael@0: if (internalformat != texture->getInternalFormat(level)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: } michael@0: michael@0: if (compressed) michael@0: { michael@0: if ((width % 4 != 0 && width != texture->getWidth(0)) || michael@0: (height % 4 != 0 && height != texture->getHeight(0))) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: } michael@0: michael@0: if (xoffset + width > texture->getWidth(level) || michael@0: yoffset + height > texture->getHeight(level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE, false); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height, michael@0: GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, GLenum type, michael@0: gl::TextureCubeMap *texture) michael@0: { michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: if (compressed != texture->isCompressed(target, level)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: michael@0: if (format != GL_NONE) michael@0: { michael@0: GLenum internalformat = gl::ConvertSizedInternalFormat(format, type); michael@0: if (internalformat != texture->getInternalFormat(target, level)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: } michael@0: michael@0: if (compressed) michael@0: { michael@0: if ((width % 4 != 0 && width != texture->getWidth(target, 0)) || michael@0: (height % 4 != 0 && height != texture->getHeight(target, 0))) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, false); michael@0: } michael@0: } michael@0: michael@0: if (xoffset + width > texture->getWidth(target, level) || michael@0: yoffset + height > texture->getHeight(target, level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE, false); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: // check for combinations of format and type that are valid for ReadPixels michael@0: bool validReadFormatType(GLenum format, GLenum type) michael@0: { michael@0: switch (format) michael@0: { michael@0: case GL_RGBA: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: break; michael@0: default: michael@0: return false; michael@0: } michael@0: break; michael@0: case GL_BGRA_EXT: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: michael@0: case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: michael@0: break; michael@0: default: michael@0: return false; michael@0: } michael@0: break; michael@0: default: michael@0: return false; michael@0: } michael@0: return true; michael@0: } michael@0: michael@0: extern "C" michael@0: { michael@0: michael@0: void __stdcall glActiveTexture(GLenum texture) michael@0: { michael@0: EVENT("(GLenum texture = 0x%X)", texture); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: context->setActiveSampler(texture - GL_TEXTURE0); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glAttachShader(GLuint program, GLuint shader) michael@0: { michael@0: EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: if (context->getProgram(shader)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: if (!programObject->attachShader(shaderObject)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBeginQueryEXT(GLenum target, GLuint id) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLuint %d)", target, id); michael@0: michael@0: try michael@0: { michael@0: switch (target) michael@0: { michael@0: case GL_ANY_SAMPLES_PASSED_EXT: michael@0: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (id == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->beginQuery(target, id); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) michael@0: { michael@0: EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: if (strncmp(name, "gl_", 3) == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: programObject->bindAttributeLocation(index, name); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBindBuffer(GLenum target, GLuint buffer) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (target) michael@0: { michael@0: case GL_ARRAY_BUFFER: michael@0: context->bindArrayBuffer(buffer); michael@0: return; michael@0: case GL_ELEMENT_ARRAY_BUFFER: michael@0: context->bindElementArrayBuffer(buffer); michael@0: return; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); michael@0: michael@0: try michael@0: { michael@0: if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) michael@0: { michael@0: context->bindReadFramebuffer(framebuffer); michael@0: } michael@0: michael@0: if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) michael@0: { michael@0: context->bindDrawFramebuffer(framebuffer); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); michael@0: michael@0: try michael@0: { michael@0: if (target != GL_RENDERBUFFER) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->bindRenderbuffer(renderbuffer); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBindTexture(GLenum target, GLuint texture) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Texture *textureObject = context->getTexture(texture); michael@0: michael@0: if (textureObject && textureObject->getTarget() != target && texture != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: context->bindTexture2D(texture); michael@0: return; michael@0: case GL_TEXTURE_CUBE_MAP: michael@0: context->bindTextureCubeMap(texture); michael@0: return; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) michael@0: { michael@0: EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", michael@0: red, green, blue, alpha); michael@0: michael@0: try michael@0: { michael@0: gl::Context* context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha)); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBlendEquation(GLenum mode) michael@0: { michael@0: glBlendEquationSeparate(mode, mode); michael@0: } michael@0: michael@0: void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) michael@0: { michael@0: EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); michael@0: michael@0: try michael@0: { michael@0: switch (modeRGB) michael@0: { michael@0: case GL_FUNC_ADD: michael@0: case GL_FUNC_SUBTRACT: michael@0: case GL_FUNC_REVERSE_SUBTRACT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (modeAlpha) michael@0: { michael@0: case GL_FUNC_ADD: michael@0: case GL_FUNC_SUBTRACT: michael@0: case GL_FUNC_REVERSE_SUBTRACT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setBlendEquation(modeRGB, modeAlpha); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor) michael@0: { michael@0: glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); michael@0: } michael@0: michael@0: void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) michael@0: { michael@0: EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", michael@0: srcRGB, dstRGB, srcAlpha, dstAlpha); michael@0: michael@0: try michael@0: { michael@0: switch (srcRGB) michael@0: { michael@0: case GL_ZERO: michael@0: case GL_ONE: michael@0: case GL_SRC_COLOR: michael@0: case GL_ONE_MINUS_SRC_COLOR: michael@0: case GL_DST_COLOR: michael@0: case GL_ONE_MINUS_DST_COLOR: michael@0: case GL_SRC_ALPHA: michael@0: case GL_ONE_MINUS_SRC_ALPHA: michael@0: case GL_DST_ALPHA: michael@0: case GL_ONE_MINUS_DST_ALPHA: michael@0: case GL_CONSTANT_COLOR: michael@0: case GL_ONE_MINUS_CONSTANT_COLOR: michael@0: case GL_CONSTANT_ALPHA: michael@0: case GL_ONE_MINUS_CONSTANT_ALPHA: michael@0: case GL_SRC_ALPHA_SATURATE: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (dstRGB) michael@0: { michael@0: case GL_ZERO: michael@0: case GL_ONE: michael@0: case GL_SRC_COLOR: michael@0: case GL_ONE_MINUS_SRC_COLOR: michael@0: case GL_DST_COLOR: michael@0: case GL_ONE_MINUS_DST_COLOR: michael@0: case GL_SRC_ALPHA: michael@0: case GL_ONE_MINUS_SRC_ALPHA: michael@0: case GL_DST_ALPHA: michael@0: case GL_ONE_MINUS_DST_ALPHA: michael@0: case GL_CONSTANT_COLOR: michael@0: case GL_ONE_MINUS_CONSTANT_COLOR: michael@0: case GL_CONSTANT_ALPHA: michael@0: case GL_ONE_MINUS_CONSTANT_ALPHA: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (srcAlpha) michael@0: { michael@0: case GL_ZERO: michael@0: case GL_ONE: michael@0: case GL_SRC_COLOR: michael@0: case GL_ONE_MINUS_SRC_COLOR: michael@0: case GL_DST_COLOR: michael@0: case GL_ONE_MINUS_DST_COLOR: michael@0: case GL_SRC_ALPHA: michael@0: case GL_ONE_MINUS_SRC_ALPHA: michael@0: case GL_DST_ALPHA: michael@0: case GL_ONE_MINUS_DST_ALPHA: michael@0: case GL_CONSTANT_COLOR: michael@0: case GL_ONE_MINUS_CONSTANT_COLOR: michael@0: case GL_CONSTANT_ALPHA: michael@0: case GL_ONE_MINUS_CONSTANT_ALPHA: michael@0: case GL_SRC_ALPHA_SATURATE: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (dstAlpha) michael@0: { michael@0: case GL_ZERO: michael@0: case GL_ONE: michael@0: case GL_SRC_COLOR: michael@0: case GL_ONE_MINUS_SRC_COLOR: michael@0: case GL_DST_COLOR: michael@0: case GL_ONE_MINUS_DST_COLOR: michael@0: case GL_SRC_ALPHA: michael@0: case GL_ONE_MINUS_SRC_ALPHA: michael@0: case GL_DST_ALPHA: michael@0: case GL_ONE_MINUS_DST_ALPHA: michael@0: case GL_CONSTANT_COLOR: michael@0: case GL_ONE_MINUS_CONSTANT_COLOR: michael@0: case GL_CONSTANT_ALPHA: michael@0: case GL_ONE_MINUS_CONSTANT_ALPHA: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR || michael@0: dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR); michael@0: michael@0: bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA || michael@0: dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA); michael@0: michael@0: if (constantColorUsed && constantAlphaUsed) michael@0: { michael@0: ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL"); michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", michael@0: target, size, data, usage); michael@0: michael@0: try michael@0: { michael@0: if (size < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (usage) michael@0: { michael@0: case GL_STREAM_DRAW: michael@0: case GL_STATIC_DRAW: michael@0: case GL_DYNAMIC_DRAW: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Buffer *buffer; michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_ARRAY_BUFFER: michael@0: buffer = context->getArrayBuffer(); michael@0: break; michael@0: case GL_ELEMENT_ARRAY_BUFFER: michael@0: buffer = context->getElementArrayBuffer(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (!buffer) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: buffer->bufferData(data, size, usage); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", michael@0: target, offset, size, data); michael@0: michael@0: try michael@0: { michael@0: if (size < 0 || offset < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (data == NULL) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Buffer *buffer; michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_ARRAY_BUFFER: michael@0: buffer = context->getArrayBuffer(); michael@0: break; michael@0: case GL_ELEMENT_ARRAY_BUFFER: michael@0: buffer = context->getElementArrayBuffer(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (!buffer) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if ((size_t)size + offset > buffer->size()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: buffer->bufferSubData(data, size, offset); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: GLenum __stdcall glCheckFramebufferStatus(GLenum target) michael@0: { michael@0: EVENT("(GLenum target = 0x%X)", target); michael@0: michael@0: try michael@0: { michael@0: if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM, 0); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Framebuffer *framebuffer = NULL; michael@0: if (target == GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: framebuffer = context->getReadFramebuffer(); michael@0: } michael@0: else michael@0: { michael@0: framebuffer = context->getDrawFramebuffer(); michael@0: } michael@0: michael@0: return framebuffer->completeness(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, 0); michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: void __stdcall glClear(GLbitfield mask) michael@0: { michael@0: EVENT("(GLbitfield mask = %X)", mask); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->clear(mask); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) michael@0: { michael@0: EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", michael@0: red, green, blue, alpha); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setClearColor(red, green, blue, alpha); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glClearDepthf(GLclampf depth) michael@0: { michael@0: EVENT("(GLclampf depth = %f)", depth); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setClearDepth(depth); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glClearStencil(GLint s) michael@0: { michael@0: EVENT("(GLint s = %d)", s); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setClearStencil(s); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) michael@0: { michael@0: EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", michael@0: red, green, blue, alpha); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glCompileShader(GLuint shader) michael@0: { michael@0: EVENT("(GLuint shader = %d)", shader); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: if (context->getProgram(shader)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: shaderObject->compile(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, michael@0: GLint border, GLsizei imageSize, const GLvoid* data) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " michael@0: "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", michael@0: target, level, internalformat, width, height, border, imageSize, data); michael@0: michael@0: try michael@0: { michael@0: if (!validImageSize(level, width, height) || border != 0 || imageSize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (internalformat) michael@0: { michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (border != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (width != 1 && width != 2 && width % 4 != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (height != 1 && height != 2 && height % 4 != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (level > context->getMaximumTextureLevel()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: if (width > (context->getMaximumTextureDimension() >> level) || michael@0: height > (context->getMaximumTextureDimension() >> level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: michael@0: if (width != height) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (width > (context->getMaximumCubeTextureDimension() >> level) || michael@0: height > (context->getMaximumCubeTextureDimension() >> level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (internalformat) { michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: if (!context->supportsDXT1Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: if (!context->supportsDXT3Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: if (!context->supportsDXT5Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed michael@0: } michael@0: break; michael@0: default: UNREACHABLE(); michael@0: } michael@0: michael@0: if (imageSize != gl::ComputeCompressedSize(width, height, internalformat)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (target == GL_TEXTURE_2D) michael@0: { michael@0: gl::Texture2D *texture = context->getTexture2D(); michael@0: michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texture->setCompressedImage(level, internalformat, width, height, imageSize, data); michael@0: } michael@0: else michael@0: { michael@0: gl::TextureCubeMap *texture = context->getTextureCubeMap(); michael@0: michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: michael@0: texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); michael@0: break; michael@0: default: UNREACHABLE(); michael@0: } michael@0: } michael@0: } michael@0: michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, michael@0: GLenum format, GLsizei imageSize, const GLvoid* data) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " michael@0: "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " michael@0: "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", michael@0: target, level, xoffset, yoffset, width, height, format, imageSize, data); michael@0: michael@0: try michael@0: { michael@0: if (!gl::IsInternalTextureTarget(target)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (format) michael@0: { michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (width == 0 || height == 0 || data == NULL) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (level > context->getMaximumTextureLevel()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (format) { michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: if (!context->supportsDXT1Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: if (!context->supportsDXT3Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: if (!context->supportsDXT5Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed michael@0: } michael@0: break; michael@0: default: UNREACHABLE(); michael@0: } michael@0: michael@0: if (imageSize != gl::ComputeCompressedSize(width, height, format)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (xoffset % 4 != 0 || yoffset % 4 != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction michael@0: // does not exist unless DXT textures are supported. michael@0: } michael@0: michael@0: if (target == GL_TEXTURE_2D) michael@0: { michael@0: gl::Texture2D *texture = context->getTexture2D(); michael@0: if (validateSubImageParams2D(true, width, height, xoffset, yoffset, level, format, GL_NONE, texture)) michael@0: { michael@0: texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); michael@0: } michael@0: } michael@0: else if (gl::IsCubemapTextureTarget(target)) michael@0: { michael@0: gl::TextureCubeMap *texture = context->getTextureCubeMap(); michael@0: if (validateSubImageParamsCube(true, width, height, xoffset, yoffset, target, level, format, GL_NONE, texture)) michael@0: { michael@0: texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); michael@0: } michael@0: } michael@0: else michael@0: { michael@0: UNREACHABLE(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " michael@0: "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", michael@0: target, level, internalformat, x, y, width, height, border); michael@0: michael@0: try michael@0: { michael@0: if (!validImageSize(level, width, height)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (border != 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (level > context->getMaximumTextureLevel()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: if (width > (context->getMaximumTextureDimension() >> level) || michael@0: height > (context->getMaximumTextureDimension() >> level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: michael@0: if (width != height) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (width > (context->getMaximumCubeTextureDimension() >> level) || michael@0: height > (context->getMaximumCubeTextureDimension() >> level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Framebuffer *framebuffer = context->getReadFramebuffer(); michael@0: michael@0: if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) michael@0: { michael@0: return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); michael@0: } michael@0: michael@0: if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::Renderbuffer *source = framebuffer->getReadColorbuffer(); michael@0: GLenum colorbufferFormat = source->getInternalFormat(); michael@0: michael@0: // [OpenGL ES 2.0.24] table 3.9 michael@0: switch (internalformat) michael@0: { michael@0: case GL_ALPHA: michael@0: if (colorbufferFormat != GL_ALPHA8_EXT && michael@0: colorbufferFormat != GL_RGBA4 && michael@0: colorbufferFormat != GL_RGB5_A1 && michael@0: colorbufferFormat != GL_BGRA8_EXT && michael@0: colorbufferFormat != GL_RGBA8_OES) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_LUMINANCE: michael@0: case GL_RGB: michael@0: if (colorbufferFormat != GL_RGB565 && michael@0: colorbufferFormat != GL_RGB8_OES && michael@0: colorbufferFormat != GL_RGBA4 && michael@0: colorbufferFormat != GL_RGB5_A1 && michael@0: colorbufferFormat != GL_BGRA8_EXT && michael@0: colorbufferFormat != GL_RGBA8_OES) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_LUMINANCE_ALPHA: michael@0: case GL_RGBA: michael@0: if (colorbufferFormat != GL_RGBA4 && michael@0: colorbufferFormat != GL_RGB5_A1 && michael@0: colorbufferFormat != GL_BGRA8_EXT && michael@0: colorbufferFormat != GL_RGBA8_OES) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: if (context->supportsDXT1Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: if (context->supportsDXT3Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: if (context->supportsDXT5Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_DEPTH_COMPONENT: michael@0: case GL_DEPTH_COMPONENT16: michael@0: case GL_DEPTH_COMPONENT32_OES: michael@0: case GL_DEPTH_STENCIL_OES: michael@0: case GL_DEPTH24_STENCIL8_OES: michael@0: if (context->supportsDepthTextures()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (target == GL_TEXTURE_2D) michael@0: { michael@0: gl::Texture2D *texture = context->getTexture2D(); michael@0: michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texture->copyImage(level, internalformat, x, y, width, height, framebuffer); michael@0: } michael@0: else if (gl::IsCubemapTextureTarget(target)) michael@0: { michael@0: gl::TextureCubeMap *texture = context->getTextureCubeMap(); michael@0: michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); michael@0: } michael@0: else UNREACHABLE(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " michael@0: "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", michael@0: target, level, xoffset, yoffset, x, y, width, height); michael@0: michael@0: try michael@0: { michael@0: if (!gl::IsInternalTextureTarget(target)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (std::numeric_limits::max() - xoffset < width || std::numeric_limits::max() - yoffset < height) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (width == 0 || height == 0) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (level > context->getMaximumTextureLevel()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Framebuffer *framebuffer = context->getReadFramebuffer(); michael@0: michael@0: if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) michael@0: { michael@0: return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); michael@0: } michael@0: michael@0: if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::Renderbuffer *source = framebuffer->getReadColorbuffer(); michael@0: GLenum colorbufferFormat = source->getInternalFormat(); michael@0: gl::Texture *texture = NULL; michael@0: GLenum textureFormat = GL_RGBA; michael@0: michael@0: if (target == GL_TEXTURE_2D) michael@0: { michael@0: gl::Texture2D *tex2d = context->getTexture2D(); michael@0: michael@0: if (!validateSubImageParams2D(false, width, height, xoffset, yoffset, level, GL_NONE, GL_NONE, tex2d)) michael@0: { michael@0: return; // error already registered by validateSubImageParams michael@0: } michael@0: textureFormat = gl::ExtractFormat(tex2d->getInternalFormat(level)); michael@0: texture = tex2d; michael@0: } michael@0: else if (gl::IsCubemapTextureTarget(target)) michael@0: { michael@0: gl::TextureCubeMap *texcube = context->getTextureCubeMap(); michael@0: michael@0: if (!validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, GL_NONE, GL_NONE, texcube)) michael@0: { michael@0: return; // error already registered by validateSubImageParams michael@0: } michael@0: textureFormat = gl::ExtractFormat(texcube->getInternalFormat(target, level)); michael@0: texture = texcube; michael@0: } michael@0: else UNREACHABLE(); michael@0: michael@0: // [OpenGL ES 2.0.24] table 3.9 michael@0: switch (textureFormat) michael@0: { michael@0: case GL_ALPHA: michael@0: if (colorbufferFormat != GL_ALPHA8_EXT && michael@0: colorbufferFormat != GL_RGBA4 && michael@0: colorbufferFormat != GL_RGB5_A1 && michael@0: colorbufferFormat != GL_RGBA8_OES) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_LUMINANCE: michael@0: case GL_RGB: michael@0: if (colorbufferFormat != GL_RGB565 && michael@0: colorbufferFormat != GL_RGB8_OES && michael@0: colorbufferFormat != GL_RGBA4 && michael@0: colorbufferFormat != GL_RGB5_A1 && michael@0: colorbufferFormat != GL_RGBA8_OES) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_LUMINANCE_ALPHA: michael@0: case GL_RGBA: michael@0: if (colorbufferFormat != GL_RGBA4 && michael@0: colorbufferFormat != GL_RGB5_A1 && michael@0: colorbufferFormat != GL_RGBA8_OES) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: case GL_DEPTH_COMPONENT: michael@0: case GL_DEPTH_STENCIL_OES: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer); michael@0: } michael@0: } michael@0: michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: GLuint __stdcall glCreateProgram(void) michael@0: { michael@0: EVENT("()"); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: return context->createProgram(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, 0); michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: GLuint __stdcall glCreateShader(GLenum type) michael@0: { michael@0: EVENT("(GLenum type = 0x%X)", type); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (type) michael@0: { michael@0: case GL_FRAGMENT_SHADER: michael@0: case GL_VERTEX_SHADER: michael@0: return context->createShader(type); michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM, 0); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, 0); michael@0: } michael@0: michael@0: return 0; michael@0: } michael@0: michael@0: void __stdcall glCullFace(GLenum mode) michael@0: { michael@0: EVENT("(GLenum mode = 0x%X)", mode); michael@0: michael@0: try michael@0: { michael@0: switch (mode) michael@0: { michael@0: case GL_FRONT: michael@0: case GL_BACK: michael@0: case GL_FRONT_AND_BACK: michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setCullMode(mode); michael@0: } michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) michael@0: { michael@0: EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: context->deleteBuffer(buffers[i]); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) michael@0: { michael@0: EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: context->deleteFence(fences[i]); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) michael@0: { michael@0: EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: if (framebuffers[i] != 0) michael@0: { michael@0: context->deleteFramebuffer(framebuffers[i]); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteProgram(GLuint program) michael@0: { michael@0: EVENT("(GLuint program = %d)", program); michael@0: michael@0: try michael@0: { michael@0: if (program == 0) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (!context->getProgram(program)) michael@0: { michael@0: if(context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: context->deleteProgram(program); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) michael@0: { michael@0: EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: context->deleteQuery(ids[i]); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) michael@0: { michael@0: EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: context->deleteRenderbuffer(renderbuffers[i]); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteShader(GLuint shader) michael@0: { michael@0: EVENT("(GLuint shader = %d)", shader); michael@0: michael@0: try michael@0: { michael@0: if (shader == 0) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (!context->getShader(shader)) michael@0: { michael@0: if(context->getProgram(shader)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: context->deleteShader(shader); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) michael@0: { michael@0: EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: if (textures[i] != 0) michael@0: { michael@0: context->deleteTexture(textures[i]); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDepthFunc(GLenum func) michael@0: { michael@0: EVENT("(GLenum func = 0x%X)", func); michael@0: michael@0: try michael@0: { michael@0: switch (func) michael@0: { michael@0: case GL_NEVER: michael@0: case GL_ALWAYS: michael@0: case GL_LESS: michael@0: case GL_LEQUAL: michael@0: case GL_EQUAL: michael@0: case GL_GREATER: michael@0: case GL_GEQUAL: michael@0: case GL_NOTEQUAL: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setDepthFunc(func); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDepthMask(GLboolean flag) michael@0: { michael@0: EVENT("(GLboolean flag = %d)", flag); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setDepthMask(flag != GL_FALSE); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) michael@0: { michael@0: EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setDepthRange(zNear, zFar); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDetachShader(GLuint program, GLuint shader) michael@0: { michael@0: EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: michael@0: gl::Program *programObject = context->getProgram(program); michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!programObject) michael@0: { michael@0: gl::Shader *shaderByProgramHandle; michael@0: shaderByProgramHandle = context->getShader(program); michael@0: if (!shaderByProgramHandle) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: gl::Program *programByShaderHandle = context->getProgram(shader); michael@0: if (!programByShaderHandle) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: michael@0: if (!programObject->detachShader(shaderObject)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDisable(GLenum cap) michael@0: { michael@0: EVENT("(GLenum cap = 0x%X)", cap); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (cap) michael@0: { michael@0: case GL_CULL_FACE: context->setCullFace(false); break; michael@0: case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(false); break; michael@0: case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break; michael@0: case GL_SAMPLE_COVERAGE: context->setSampleCoverage(false); break; michael@0: case GL_SCISSOR_TEST: context->setScissorTest(false); break; michael@0: case GL_STENCIL_TEST: context->setStencilTest(false); break; michael@0: case GL_DEPTH_TEST: context->setDepthTest(false); break; michael@0: case GL_BLEND: context->setBlend(false); break; michael@0: case GL_DITHER: context->setDither(false); break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDisableVertexAttribArray(GLuint index) michael@0: { michael@0: EVENT("(GLuint index = %d)", index); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setEnableVertexAttribArray(index, false); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) michael@0: { michael@0: EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); michael@0: michael@0: try michael@0: { michael@0: if (count < 0 || first < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->drawArrays(mode, first, count, 0); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) michael@0: { michael@0: EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount); michael@0: michael@0: try michael@0: { michael@0: if (count < 0 || first < 0 || primcount < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (primcount > 0) michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->drawArrays(mode, first, count, primcount); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) michael@0: { michael@0: EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", michael@0: mode, count, type, indices); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_UNSIGNED_SHORT: michael@0: break; michael@0: case GL_UNSIGNED_INT: michael@0: if (!context->supports32bitIndices()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: context->drawElements(mode, count, type, indices, 0); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) michael@0: { michael@0: EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)", michael@0: mode, count, type, indices, primcount); michael@0: michael@0: try michael@0: { michael@0: if (count < 0 || primcount < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (primcount > 0) michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_UNSIGNED_SHORT: michael@0: break; michael@0: case GL_UNSIGNED_INT: michael@0: if (!context->supports32bitIndices()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: context->drawElements(mode, count, type, indices, primcount); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glEnable(GLenum cap) michael@0: { michael@0: EVENT("(GLenum cap = 0x%X)", cap); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (cap) michael@0: { michael@0: case GL_CULL_FACE: context->setCullFace(true); break; michael@0: case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFill(true); break; michael@0: case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break; michael@0: case GL_SAMPLE_COVERAGE: context->setSampleCoverage(true); break; michael@0: case GL_SCISSOR_TEST: context->setScissorTest(true); break; michael@0: case GL_STENCIL_TEST: context->setStencilTest(true); break; michael@0: case GL_DEPTH_TEST: context->setDepthTest(true); break; michael@0: case GL_BLEND: context->setBlend(true); break; michael@0: case GL_DITHER: context->setDither(true); break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glEnableVertexAttribArray(GLuint index) michael@0: { michael@0: EVENT("(GLuint index = %d)", index); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setEnableVertexAttribArray(index, true); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glEndQueryEXT(GLenum target) michael@0: { michael@0: EVENT("GLenum target = 0x%X)", target); michael@0: michael@0: try michael@0: { michael@0: switch (target) michael@0: { michael@0: case GL_ANY_SAMPLES_PASSED_EXT: michael@0: case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->endQuery(target); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glFinishFenceNV(GLuint fence) michael@0: { michael@0: EVENT("(GLuint fence = %d)", fence); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Fence* fenceObject = context->getFence(fence); michael@0: michael@0: if (fenceObject == NULL) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: fenceObject->finishFence(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glFinish(void) michael@0: { michael@0: EVENT("()"); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->sync(true); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glFlush(void) michael@0: { michael@0: EVENT("()"); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->sync(false); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " michael@0: "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); michael@0: michael@0: try michael@0: { michael@0: if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) michael@0: || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Framebuffer *framebuffer = NULL; michael@0: GLuint framebufferHandle = 0; michael@0: if (target == GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: framebuffer = context->getReadFramebuffer(); michael@0: framebufferHandle = context->getReadFramebufferHandle(); michael@0: } michael@0: else michael@0: { michael@0: framebuffer = context->getDrawFramebuffer(); michael@0: framebufferHandle = context->getDrawFramebufferHandle(); michael@0: } michael@0: michael@0: if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) michael@0: { michael@0: const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); michael@0: michael@0: if (colorAttachment >= context->getMaximumRenderTargets()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer); michael@0: } michael@0: else michael@0: { michael@0: switch (attachment) michael@0: { michael@0: case GL_DEPTH_ATTACHMENT: michael@0: framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer); michael@0: break; michael@0: case GL_STENCIL_ATTACHMENT: michael@0: framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " michael@0: "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); michael@0: michael@0: try michael@0: { michael@0: if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) michael@0: { michael@0: const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); michael@0: michael@0: if (colorAttachment >= context->getMaximumRenderTargets()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: else michael@0: { michael@0: switch (attachment) michael@0: { michael@0: case GL_DEPTH_ATTACHMENT: michael@0: case GL_STENCIL_ATTACHMENT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: michael@0: if (texture == 0) michael@0: { michael@0: textarget = GL_NONE; michael@0: } michael@0: else michael@0: { michael@0: gl::Texture *tex = context->getTexture(texture); michael@0: michael@0: if (tex == NULL) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: switch (textarget) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: { michael@0: if (tex->getTarget() != GL_TEXTURE_2D) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: gl::Texture2D *tex2d = static_cast(tex); michael@0: if (tex2d->isCompressed(0)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: } michael@0: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: michael@0: { michael@0: if (tex->getTarget() != GL_TEXTURE_CUBE_MAP) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: gl::TextureCubeMap *texcube = static_cast(tex); michael@0: if (texcube->isCompressed(textarget, level)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: } michael@0: michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (level != 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: gl::Framebuffer *framebuffer = NULL; michael@0: GLuint framebufferHandle = 0; michael@0: if (target == GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: framebuffer = context->getReadFramebuffer(); michael@0: framebufferHandle = context->getReadFramebufferHandle(); michael@0: } michael@0: else michael@0: { michael@0: framebuffer = context->getDrawFramebuffer(); michael@0: framebufferHandle = context->getDrawFramebufferHandle(); michael@0: } michael@0: michael@0: if (framebufferHandle == 0 || !framebuffer) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) michael@0: { michael@0: const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); michael@0: michael@0: if (colorAttachment >= context->getMaximumRenderTargets()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: framebuffer->setColorbuffer(colorAttachment, textarget, texture); michael@0: } michael@0: else michael@0: { michael@0: switch (attachment) michael@0: { michael@0: case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break; michael@0: case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glFrontFace(GLenum mode) michael@0: { michael@0: EVENT("(GLenum mode = 0x%X)", mode); michael@0: michael@0: try michael@0: { michael@0: switch (mode) michael@0: { michael@0: case GL_CW: michael@0: case GL_CCW: michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setFrontFace(mode); michael@0: } michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) michael@0: { michael@0: EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: buffers[i] = context->createBuffer(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGenerateMipmap(GLenum target) michael@0: { michael@0: EVENT("(GLenum target = 0x%X)", target); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: { michael@0: gl::Texture2D *tex2d = context->getTexture2D(); michael@0: michael@0: if (tex2d->isCompressed(0)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: if (tex2d->isDepth(0)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: tex2d->generateMipmaps(); michael@0: break; michael@0: } michael@0: michael@0: case GL_TEXTURE_CUBE_MAP: michael@0: { michael@0: gl::TextureCubeMap *texcube = context->getTextureCubeMap(); michael@0: michael@0: if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texcube->generateMipmaps(); michael@0: break; michael@0: } michael@0: michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) michael@0: { michael@0: EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: fences[i] = context->createFence(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) michael@0: { michael@0: EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: framebuffers[i] = context->createFramebuffer(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) michael@0: { michael@0: EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: ids[i] = context->createQuery(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) michael@0: { michael@0: EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: renderbuffers[i] = context->createRenderbuffer(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGenTextures(GLsizei n, GLuint* textures) michael@0: { michael@0: EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); michael@0: michael@0: try michael@0: { michael@0: if (n < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: for (int i = 0; i < n; i++) michael@0: { michael@0: textures[i] = context->createTexture(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) michael@0: { michael@0: EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " michael@0: "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)", michael@0: program, index, bufsize, length, size, type, name); michael@0: michael@0: try michael@0: { michael@0: if (bufsize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: if (index >= (GLuint)programObject->getActiveAttributeCount()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: programObject->getActiveAttribute(index, bufsize, length, size, type, name); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) michael@0: { michael@0: EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " michael@0: "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", michael@0: program, index, bufsize, length, size, type, name); michael@0: michael@0: try michael@0: { michael@0: if (bufsize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: if (index >= (GLuint)programObject->getActiveUniformCount()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: programObject->getActiveUniform(index, bufsize, length, size, type, name); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) michael@0: { michael@0: EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", michael@0: program, maxcount, count, shaders); michael@0: michael@0: try michael@0: { michael@0: if (maxcount < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: return programObject->getAttachedShaders(maxcount, count, shaders); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) michael@0: { michael@0: EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, -1); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE, -1); michael@0: } michael@0: } michael@0: michael@0: gl::ProgramBinary *programBinary = programObject->getProgramBinary(); michael@0: if (!programObject->isLinked() || !programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, -1); michael@0: } michael@0: michael@0: return programBinary->getAttributeLocation(name); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, -1); michael@0: } michael@0: michael@0: return -1; michael@0: } michael@0: michael@0: void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) michael@0: { michael@0: EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (!(context->getBooleanv(pname, params))) michael@0: { michael@0: GLenum nativeType; michael@0: unsigned int numParams = 0; michael@0: if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) michael@0: return gl::error(GL_INVALID_ENUM); michael@0: michael@0: if (numParams == 0) michael@0: return; // it is known that the pname is valid, but there are no parameters to return michael@0: michael@0: if (nativeType == GL_FLOAT) michael@0: { michael@0: GLfloat *floatParams = NULL; michael@0: floatParams = new GLfloat[numParams]; michael@0: michael@0: context->getFloatv(pname, floatParams); michael@0: michael@0: for (unsigned int i = 0; i < numParams; ++i) michael@0: { michael@0: if (floatParams[i] == 0.0f) michael@0: params[i] = GL_FALSE; michael@0: else michael@0: params[i] = GL_TRUE; michael@0: } michael@0: michael@0: delete [] floatParams; michael@0: } michael@0: else if (nativeType == GL_INT) michael@0: { michael@0: GLint *intParams = NULL; michael@0: intParams = new GLint[numParams]; michael@0: michael@0: context->getIntegerv(pname, intParams); michael@0: michael@0: for (unsigned int i = 0; i < numParams; ++i) michael@0: { michael@0: if (intParams[i] == 0) michael@0: params[i] = GL_FALSE; michael@0: else michael@0: params[i] = GL_TRUE; michael@0: } michael@0: michael@0: delete [] intParams; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Buffer *buffer; michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_ARRAY_BUFFER: michael@0: buffer = context->getArrayBuffer(); michael@0: break; michael@0: case GL_ELEMENT_ARRAY_BUFFER: michael@0: buffer = context->getElementArrayBuffer(); michael@0: break; michael@0: default: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (!buffer) michael@0: { michael@0: // A null buffer means that "0" is bound to the requested buffer target michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_BUFFER_USAGE: michael@0: *params = buffer->usage(); michael@0: break; michael@0: case GL_BUFFER_SIZE: michael@0: *params = buffer->size(); michael@0: break; michael@0: default: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: GLenum __stdcall glGetError(void) michael@0: { michael@0: EVENT("()"); michael@0: michael@0: gl::Context *context = gl::getContext(); michael@0: michael@0: if (context) michael@0: { michael@0: return context->getError(); michael@0: } michael@0: michael@0: return GL_NO_ERROR; michael@0: } michael@0: michael@0: void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) michael@0: { michael@0: EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params); michael@0: michael@0: try michael@0: { michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Fence *fenceObject = context->getFence(fence); michael@0: michael@0: if (fenceObject == NULL) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: fenceObject->getFenceiv(pname, params); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetFloatv(GLenum pname, GLfloat* params) michael@0: { michael@0: EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (!(context->getFloatv(pname, params))) michael@0: { michael@0: GLenum nativeType; michael@0: unsigned int numParams = 0; michael@0: if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) michael@0: return gl::error(GL_INVALID_ENUM); michael@0: michael@0: if (numParams == 0) michael@0: return; // it is known that the pname is valid, but that there are no parameters to return. michael@0: michael@0: if (nativeType == GL_BOOL) michael@0: { michael@0: GLboolean *boolParams = NULL; michael@0: boolParams = new GLboolean[numParams]; michael@0: michael@0: context->getBooleanv(pname, boolParams); michael@0: michael@0: for (unsigned int i = 0; i < numParams; ++i) michael@0: { michael@0: if (boolParams[i] == GL_FALSE) michael@0: params[i] = 0.0f; michael@0: else michael@0: params[i] = 1.0f; michael@0: } michael@0: michael@0: delete [] boolParams; michael@0: } michael@0: else if (nativeType == GL_INT) michael@0: { michael@0: GLint *intParams = NULL; michael@0: intParams = new GLint[numParams]; michael@0: michael@0: context->getIntegerv(pname, intParams); michael@0: michael@0: for (unsigned int i = 0; i < numParams; ++i) michael@0: { michael@0: params[i] = (GLfloat)intParams[i]; michael@0: } michael@0: michael@0: delete [] intParams; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", michael@0: target, attachment, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Framebuffer *framebuffer = NULL; michael@0: if (target == GL_READ_FRAMEBUFFER_ANGLE) michael@0: { michael@0: if(context->getReadFramebufferHandle() == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: framebuffer = context->getReadFramebuffer(); michael@0: } michael@0: else michael@0: { michael@0: if (context->getDrawFramebufferHandle() == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: framebuffer = context->getDrawFramebuffer(); michael@0: } michael@0: michael@0: GLenum attachmentType; michael@0: GLuint attachmentHandle; michael@0: michael@0: if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) michael@0: { michael@0: const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); michael@0: michael@0: if (colorAttachment >= context->getMaximumRenderTargets()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: attachmentType = framebuffer->getColorbufferType(colorAttachment); michael@0: attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment); michael@0: } michael@0: else michael@0: { michael@0: switch (attachment) michael@0: { michael@0: case GL_DEPTH_ATTACHMENT: michael@0: attachmentType = framebuffer->getDepthbufferType(); michael@0: attachmentHandle = framebuffer->getDepthbufferHandle(); michael@0: break; michael@0: case GL_STENCIL_ATTACHMENT: michael@0: attachmentType = framebuffer->getStencilbufferType(); michael@0: attachmentHandle = framebuffer->getStencilbufferHandle(); michael@0: break; michael@0: default: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: michael@0: GLenum attachmentObjectType; // Type category michael@0: if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER) michael@0: { michael@0: attachmentObjectType = attachmentType; michael@0: } michael@0: else if (gl::IsInternalTextureTarget(attachmentType)) michael@0: { michael@0: attachmentObjectType = GL_TEXTURE; michael@0: } michael@0: else michael@0: { michael@0: UNREACHABLE(); michael@0: return; michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: michael@0: *params = attachmentObjectType; michael@0: break; michael@0: case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: michael@0: if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE) michael@0: { michael@0: *params = attachmentHandle; michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: michael@0: if (attachmentObjectType == GL_TEXTURE) michael@0: { michael@0: *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0 michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: michael@0: if (attachmentObjectType == GL_TEXTURE) michael@0: { michael@0: if (gl::IsCubemapTextureTarget(attachmentType)) michael@0: { michael@0: *params = attachmentType; michael@0: } michael@0: else michael@0: { michael@0: *params = 0; michael@0: } michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: GLenum __stdcall glGetGraphicsResetStatusEXT(void) michael@0: { michael@0: EVENT("()"); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getContext(); michael@0: michael@0: if (context) michael@0: { michael@0: return context->getResetStatus(); michael@0: } michael@0: michael@0: return GL_NO_ERROR; michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return GL_OUT_OF_MEMORY; michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetIntegerv(GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (!(context->getIntegerv(pname, params))) michael@0: { michael@0: GLenum nativeType; michael@0: unsigned int numParams = 0; michael@0: if (!context->getQueryParameterInfo(pname, &nativeType, &numParams)) michael@0: return gl::error(GL_INVALID_ENUM); michael@0: michael@0: if (numParams == 0) michael@0: return; // it is known that pname is valid, but there are no parameters to return michael@0: michael@0: if (nativeType == GL_BOOL) michael@0: { michael@0: GLboolean *boolParams = NULL; michael@0: boolParams = new GLboolean[numParams]; michael@0: michael@0: context->getBooleanv(pname, boolParams); michael@0: michael@0: for (unsigned int i = 0; i < numParams; ++i) michael@0: { michael@0: if (boolParams[i] == GL_FALSE) michael@0: params[i] = 0; michael@0: else michael@0: params[i] = 1; michael@0: } michael@0: michael@0: delete [] boolParams; michael@0: } michael@0: else if (nativeType == GL_FLOAT) michael@0: { michael@0: GLfloat *floatParams = NULL; michael@0: floatParams = new GLfloat[numParams]; michael@0: michael@0: context->getFloatv(pname, floatParams); michael@0: michael@0: for (unsigned int i = 0; i < numParams; ++i) michael@0: { michael@0: if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) michael@0: { michael@0: params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f); michael@0: } michael@0: else michael@0: params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5)); michael@0: } michael@0: michael@0: delete [] floatParams; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_DELETE_STATUS: michael@0: *params = programObject->isFlaggedForDeletion(); michael@0: return; michael@0: case GL_LINK_STATUS: michael@0: *params = programObject->isLinked(); michael@0: return; michael@0: case GL_VALIDATE_STATUS: michael@0: *params = programObject->isValidated(); michael@0: return; michael@0: case GL_INFO_LOG_LENGTH: michael@0: *params = programObject->getInfoLogLength(); michael@0: return; michael@0: case GL_ATTACHED_SHADERS: michael@0: *params = programObject->getAttachedShadersCount(); michael@0: return; michael@0: case GL_ACTIVE_ATTRIBUTES: michael@0: *params = programObject->getActiveAttributeCount(); michael@0: return; michael@0: case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: michael@0: *params = programObject->getActiveAttributeMaxLength(); michael@0: return; michael@0: case GL_ACTIVE_UNIFORMS: michael@0: *params = programObject->getActiveUniformCount(); michael@0: return; michael@0: case GL_ACTIVE_UNIFORM_MAX_LENGTH: michael@0: *params = programObject->getActiveUniformMaxLength(); michael@0: return; michael@0: case GL_PROGRAM_BINARY_LENGTH_OES: michael@0: *params = programObject->getProgramBinaryLength(); michael@0: return; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) michael@0: { michael@0: EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", michael@0: program, bufsize, length, infolog); michael@0: michael@0: try michael@0: { michael@0: if (bufsize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: programObject->getInfoLog(bufsize, length, infolog); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) michael@0: { michael@0: EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params); michael@0: michael@0: try michael@0: { michael@0: switch (pname) michael@0: { michael@0: case GL_CURRENT_QUERY_EXT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: params[0] = context->getActiveQuery(target); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) michael@0: { michael@0: EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); michael@0: michael@0: try michael@0: { michael@0: switch (pname) michael@0: { michael@0: case GL_QUERY_RESULT_EXT: michael@0: case GL_QUERY_RESULT_AVAILABLE_EXT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Query *queryObject = context->getQuery(id, false, GL_NONE); michael@0: michael@0: if (!queryObject) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (context->getActiveQuery(queryObject->getType()) == id) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: switch(pname) michael@0: { michael@0: case GL_QUERY_RESULT_EXT: michael@0: params[0] = queryObject->getResult(); michael@0: break; michael@0: case GL_QUERY_RESULT_AVAILABLE_EXT: michael@0: params[0] = queryObject->isResultAvailable(); michael@0: break; michael@0: default: michael@0: ASSERT(false); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (target != GL_RENDERBUFFER) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (context->getRenderbufferHandle() == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle()); michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; michael@0: case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; michael@0: case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break; michael@0: case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; michael@0: case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; michael@0: case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; michael@0: case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; michael@0: case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; michael@0: case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; michael@0: case GL_RENDERBUFFER_SAMPLES_ANGLE: michael@0: if (context->getMaxSupportedSamples() != 0) michael@0: { michael@0: *params = renderbuffer->getSamples(); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_SHADER_TYPE: michael@0: *params = shaderObject->getType(); michael@0: return; michael@0: case GL_DELETE_STATUS: michael@0: *params = shaderObject->isFlaggedForDeletion(); michael@0: return; michael@0: case GL_COMPILE_STATUS: michael@0: *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE; michael@0: return; michael@0: case GL_INFO_LOG_LENGTH: michael@0: *params = shaderObject->getInfoLogLength(); michael@0: return; michael@0: case GL_SHADER_SOURCE_LENGTH: michael@0: *params = shaderObject->getSourceLength(); michael@0: return; michael@0: case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: michael@0: *params = shaderObject->getTranslatedSourceLength(); michael@0: return; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) michael@0: { michael@0: EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", michael@0: shader, bufsize, length, infolog); michael@0: michael@0: try michael@0: { michael@0: if (bufsize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: shaderObject->getInfoLog(bufsize, length, infolog); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) michael@0: { michael@0: EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", michael@0: shadertype, precisiontype, range, precision); michael@0: michael@0: try michael@0: { michael@0: switch (shadertype) michael@0: { michael@0: case GL_VERTEX_SHADER: michael@0: case GL_FRAGMENT_SHADER: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (precisiontype) michael@0: { michael@0: case GL_LOW_FLOAT: michael@0: case GL_MEDIUM_FLOAT: michael@0: case GL_HIGH_FLOAT: michael@0: // Assume IEEE 754 precision michael@0: range[0] = 127; michael@0: range[1] = 127; michael@0: *precision = 23; michael@0: break; michael@0: case GL_LOW_INT: michael@0: case GL_MEDIUM_INT: michael@0: case GL_HIGH_INT: michael@0: // Some (most) hardware only supports single-precision floating-point numbers, michael@0: // which can accurately represent integers up to +/-16777216 michael@0: range[0] = 24; michael@0: range[1] = 24; michael@0: *precision = 0; michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) michael@0: { michael@0: EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", michael@0: shader, bufsize, length, source); michael@0: michael@0: try michael@0: { michael@0: if (bufsize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: shaderObject->getSource(bufsize, length, source); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) michael@0: { michael@0: EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", michael@0: shader, bufsize, length, source); michael@0: michael@0: try michael@0: { michael@0: if (bufsize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: shaderObject->getTranslatedSource(bufsize, length, source); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: const GLubyte* __stdcall glGetString(GLenum name) michael@0: { michael@0: EVENT("(GLenum name = 0x%X)", name); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: switch (name) michael@0: { michael@0: case GL_VENDOR: michael@0: return (GLubyte*)"Google Inc."; michael@0: case GL_RENDERER: michael@0: return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE"); michael@0: case GL_VERSION: michael@0: return (GLubyte*)"OpenGL ES 2.0 (ANGLE " VERSION_STRING ")"; michael@0: case GL_SHADING_LANGUAGE_VERSION: michael@0: return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")"; michael@0: case GL_EXTENSIONS: michael@0: return (GLubyte*)((context != NULL) ? context->getExtensionString() : ""); michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Texture *texture; michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: texture = context->getTexture2D(); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP: michael@0: texture = context->getTextureCubeMap(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_TEXTURE_MAG_FILTER: michael@0: *params = (GLfloat)texture->getMagFilter(); michael@0: break; michael@0: case GL_TEXTURE_MIN_FILTER: michael@0: *params = (GLfloat)texture->getMinFilter(); michael@0: break; michael@0: case GL_TEXTURE_WRAP_S: michael@0: *params = (GLfloat)texture->getWrapS(); michael@0: break; michael@0: case GL_TEXTURE_WRAP_T: michael@0: *params = (GLfloat)texture->getWrapT(); michael@0: break; michael@0: case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: michael@0: *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE); michael@0: break; michael@0: case GL_TEXTURE_USAGE_ANGLE: michael@0: *params = (GLfloat)texture->getUsage(); michael@0: break; michael@0: case GL_TEXTURE_MAX_ANISOTROPY_EXT: michael@0: if (!context->supportsTextureFilterAnisotropy()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: *params = (GLfloat)texture->getMaxAnisotropy(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Texture *texture; michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: texture = context->getTexture2D(); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP: michael@0: texture = context->getTextureCubeMap(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_TEXTURE_MAG_FILTER: michael@0: *params = texture->getMagFilter(); michael@0: break; michael@0: case GL_TEXTURE_MIN_FILTER: michael@0: *params = texture->getMinFilter(); michael@0: break; michael@0: case GL_TEXTURE_WRAP_S: michael@0: *params = texture->getWrapS(); michael@0: break; michael@0: case GL_TEXTURE_WRAP_T: michael@0: *params = texture->getWrapT(); michael@0: break; michael@0: case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: michael@0: *params = texture->isImmutable() ? GL_TRUE : GL_FALSE; michael@0: break; michael@0: case GL_TEXTURE_USAGE_ANGLE: michael@0: *params = texture->getUsage(); michael@0: break; michael@0: case GL_TEXTURE_MAX_ANISOTROPY_EXT: michael@0: if (!context->supportsTextureFilterAnisotropy()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: *params = (GLint)texture->getMaxAnisotropy(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) michael@0: { michael@0: EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)", michael@0: program, location, bufSize, params); michael@0: michael@0: try michael@0: { michael@0: if (bufSize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (program == 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject || !programObject->isLinked()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::ProgramBinary *programBinary = programObject->getProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->getUniformfv(location, &bufSize, params)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) michael@0: { michael@0: EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (program == 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject || !programObject->isLinked()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::ProgramBinary *programBinary = programObject->getProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->getUniformfv(location, NULL, params)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) michael@0: { michael@0: EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", michael@0: program, location, bufSize, params); michael@0: michael@0: try michael@0: { michael@0: if (bufSize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (program == 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject || !programObject->isLinked()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::ProgramBinary *programBinary = programObject->getProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->getUniformiv(location, &bufSize, params)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) michael@0: { michael@0: EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (program == 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject || !programObject->isLinked()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::ProgramBinary *programBinary = programObject->getProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->getUniformiv(location, NULL, params)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) michael@0: { michael@0: EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (strstr(name, "gl_") == name) michael@0: { michael@0: return -1; michael@0: } michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, -1); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE, -1); michael@0: } michael@0: } michael@0: michael@0: gl::ProgramBinary *programBinary = programObject->getProgramBinary(); michael@0: if (!programObject->isLinked() || !programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, -1); michael@0: } michael@0: michael@0: return programBinary->getUniformLocation(name); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, -1); michael@0: } michael@0: michael@0: return -1; michael@0: } michael@0: michael@0: void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) michael@0: { michael@0: EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: const gl::VertexAttribute &attribState = context->getVertexAttribState(index); michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_VERTEX_ATTRIB_ARRAY_ENABLED: michael@0: *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_SIZE: michael@0: *params = (GLfloat)attribState.mSize; michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_STRIDE: michael@0: *params = (GLfloat)attribState.mStride; michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_TYPE: michael@0: *params = (GLfloat)attribState.mType; michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: michael@0: *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE); michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: michael@0: *params = (GLfloat)attribState.mBoundBuffer.id(); michael@0: break; michael@0: case GL_CURRENT_VERTEX_ATTRIB: michael@0: for (int i = 0; i < 4; ++i) michael@0: { michael@0: params[i] = attribState.mCurrentValue[i]; michael@0: } michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: michael@0: *params = (GLfloat)attribState.mDivisor; michael@0: break; michael@0: default: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) michael@0: { michael@0: EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: const gl::VertexAttribute &attribState = context->getVertexAttribState(index); michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_VERTEX_ATTRIB_ARRAY_ENABLED: michael@0: *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_SIZE: michael@0: *params = attribState.mSize; michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_STRIDE: michael@0: *params = attribState.mStride; michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_TYPE: michael@0: *params = attribState.mType; michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: michael@0: *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE); michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: michael@0: *params = attribState.mBoundBuffer.id(); michael@0: break; michael@0: case GL_CURRENT_VERTEX_ATTRIB: michael@0: for (int i = 0; i < 4; ++i) michael@0: { michael@0: float currentValue = attribState.mCurrentValue[i]; michael@0: params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f)); michael@0: } michael@0: break; michael@0: case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: michael@0: *params = (GLint)attribState.mDivisor; michael@0: break; michael@0: default: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) michael@0: { michael@0: EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: *pointer = const_cast(context->getVertexAttribPointer(index)); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glHint(GLenum target, GLenum mode) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); michael@0: michael@0: try michael@0: { michael@0: switch (mode) michael@0: { michael@0: case GL_FASTEST: michael@0: case GL_NICEST: michael@0: case GL_DONT_CARE: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: switch (target) michael@0: { michael@0: case GL_GENERATE_MIPMAP_HINT: michael@0: if (context) context->setGenerateMipmapHint(mode); michael@0: break; michael@0: case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: michael@0: if (context) context->setFragmentShaderDerivativeHint(mode); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: GLboolean __stdcall glIsBuffer(GLuint buffer) michael@0: { michael@0: EVENT("(GLuint buffer = %d)", buffer); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context && buffer) michael@0: { michael@0: gl::Buffer *bufferObject = context->getBuffer(buffer); michael@0: michael@0: if (bufferObject) michael@0: { michael@0: return GL_TRUE; michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsEnabled(GLenum cap) michael@0: { michael@0: EVENT("(GLenum cap = 0x%X)", cap); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (cap) michael@0: { michael@0: case GL_CULL_FACE: return context->isCullFaceEnabled(); michael@0: case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); michael@0: case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); michael@0: case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); michael@0: case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); michael@0: case GL_STENCIL_TEST: return context->isStencilTestEnabled(); michael@0: case GL_DEPTH_TEST: return context->isDepthTestEnabled(); michael@0: case GL_BLEND: return context->isBlendEnabled(); michael@0: case GL_DITHER: return context->isDitherEnabled(); michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM, false); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, false); michael@0: } michael@0: michael@0: return false; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsFenceNV(GLuint fence) michael@0: { michael@0: EVENT("(GLuint fence = %d)", fence); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Fence *fenceObject = context->getFence(fence); michael@0: michael@0: if (fenceObject == NULL) michael@0: { michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: return fenceObject->isFence(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) michael@0: { michael@0: EVENT("(GLuint framebuffer = %d)", framebuffer); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context && framebuffer) michael@0: { michael@0: gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer); michael@0: michael@0: if (framebufferObject) michael@0: { michael@0: return GL_TRUE; michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsProgram(GLuint program) michael@0: { michael@0: EVENT("(GLuint program = %d)", program); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context && program) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (programObject) michael@0: { michael@0: return GL_TRUE; michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsQueryEXT(GLuint id) michael@0: { michael@0: EVENT("(GLuint id = %d)", id); michael@0: michael@0: try michael@0: { michael@0: if (id == 0) michael@0: { michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Query *queryObject = context->getQuery(id, false, GL_NONE); michael@0: michael@0: if (queryObject) michael@0: { michael@0: return GL_TRUE; michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) michael@0: { michael@0: EVENT("(GLuint renderbuffer = %d)", renderbuffer); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context && renderbuffer) michael@0: { michael@0: gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); michael@0: michael@0: if (renderbufferObject) michael@0: { michael@0: return GL_TRUE; michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsShader(GLuint shader) michael@0: { michael@0: EVENT("(GLuint shader = %d)", shader); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context && shader) michael@0: { michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (shaderObject) michael@0: { michael@0: return GL_TRUE; michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: GLboolean __stdcall glIsTexture(GLuint texture) michael@0: { michael@0: EVENT("(GLuint texture = %d)", texture); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context && texture) michael@0: { michael@0: gl::Texture *textureObject = context->getTexture(texture); michael@0: michael@0: if (textureObject) michael@0: { michael@0: return GL_TRUE; michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); michael@0: } michael@0: michael@0: return GL_FALSE; michael@0: } michael@0: michael@0: void __stdcall glLineWidth(GLfloat width) michael@0: { michael@0: EVENT("(GLfloat width = %f)", width); michael@0: michael@0: try michael@0: { michael@0: if (width <= 0.0f) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setLineWidth(width); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glLinkProgram(GLuint program) michael@0: { michael@0: EVENT("(GLuint program = %d)", program); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: context->linkProgram(program); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glPixelStorei(GLenum pname, GLint param) michael@0: { michael@0: EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (pname) michael@0: { michael@0: case GL_UNPACK_ALIGNMENT: michael@0: if (param != 1 && param != 2 && param != 4 && param != 8) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: context->setUnpackAlignment(param); michael@0: break; michael@0: michael@0: case GL_PACK_ALIGNMENT: michael@0: if (param != 1 && param != 2 && param != 4 && param != 8) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: context->setPackAlignment(param); michael@0: break; michael@0: michael@0: case GL_PACK_REVERSE_ROW_ORDER_ANGLE: michael@0: context->setPackReverseRowOrder(param != 0); michael@0: break; michael@0: michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) michael@0: { michael@0: EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setPolygonOffsetParams(factor, units); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, michael@0: GLenum format, GLenum type, GLsizei bufSize, michael@0: GLvoid *data) michael@0: { michael@0: EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " michael@0: "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)", michael@0: x, y, width, height, format, type, bufSize, data); michael@0: michael@0: try michael@0: { michael@0: if (width < 0 || height < 0 || bufSize < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLenum currentFormat, currentType; michael@0: michael@0: // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound, michael@0: // and attempting to read back if that's the case is an error. The error will be registered michael@0: // by getCurrentReadFormat. michael@0: if (!context->getCurrentReadFormatType(¤tFormat, ¤tType)) michael@0: return; michael@0: michael@0: if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: context->readPixels(x, y, width, height, format, type, &bufSize, data); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, michael@0: GLenum format, GLenum type, GLvoid* pixels) michael@0: { michael@0: EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " michael@0: "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)", michael@0: x, y, width, height, format, type, pixels); michael@0: michael@0: try michael@0: { michael@0: if (width < 0 || height < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLenum currentFormat, currentType; michael@0: michael@0: // Failure in getCurrentReadFormatType indicates that no color attachment is currently bound, michael@0: // and attempting to read back if that's the case is an error. The error will be registered michael@0: // by getCurrentReadFormat. michael@0: if (!context->getCurrentReadFormatType(¤tFormat, ¤tType)) michael@0: return; michael@0: michael@0: if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: context->readPixels(x, y, width, height, format, type, NULL, pixels); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glReleaseShaderCompiler(void) michael@0: { michael@0: EVENT("()"); michael@0: michael@0: try michael@0: { michael@0: gl::Shader::releaseCompiler(); michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", michael@0: target, samples, internalformat, width, height); michael@0: michael@0: try michael@0: { michael@0: switch (target) michael@0: { michael@0: case GL_RENDERBUFFER: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (width < 0 || height < 0 || samples < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (width > context->getMaximumRenderbufferDimension() || michael@0: height > context->getMaximumRenderbufferDimension() || michael@0: samples > context->getMaxSupportedSamples()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: GLuint handle = context->getRenderbufferHandle(); michael@0: if (handle == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: switch (internalformat) michael@0: { michael@0: case GL_DEPTH_COMPONENT16: michael@0: case GL_RGBA4: michael@0: case GL_RGB5_A1: michael@0: case GL_RGB565: michael@0: case GL_RGB8_OES: michael@0: case GL_RGBA8_OES: michael@0: case GL_STENCIL_INDEX8: michael@0: case GL_DEPTH24_STENCIL8_OES: michael@0: context->setRenderbufferStorage(width, height, internalformat, samples); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) michael@0: { michael@0: glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height); michael@0: } michael@0: michael@0: void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) michael@0: { michael@0: EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert); michael@0: michael@0: try michael@0: { michael@0: gl::Context* context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glSetFenceNV(GLuint fence, GLenum condition) michael@0: { michael@0: EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); michael@0: michael@0: try michael@0: { michael@0: if (condition != GL_ALL_COMPLETED_NV) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Fence *fenceObject = context->getFence(fence); michael@0: michael@0: if (fenceObject == NULL) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: fenceObject->setFence(condition); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) michael@0: { michael@0: EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); michael@0: michael@0: try michael@0: { michael@0: if (width < 0 || height < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context* context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setScissorParams(x, y, width, height); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) michael@0: { michael@0: EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " michael@0: "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", michael@0: n, shaders, binaryformat, binary, length); michael@0: michael@0: try michael@0: { michael@0: // No binary shader formats are supported. michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) michael@0: { michael@0: EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", michael@0: shader, count, string, length); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Shader *shaderObject = context->getShader(shader); michael@0: michael@0: if (!shaderObject) michael@0: { michael@0: if (context->getProgram(shader)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: shaderObject->setSource(count, string, length); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask) michael@0: { michael@0: glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); michael@0: } michael@0: michael@0: void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) michael@0: { michael@0: EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); michael@0: michael@0: try michael@0: { michael@0: switch (face) michael@0: { michael@0: case GL_FRONT: michael@0: case GL_BACK: michael@0: case GL_FRONT_AND_BACK: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (func) michael@0: { michael@0: case GL_NEVER: michael@0: case GL_ALWAYS: michael@0: case GL_LESS: michael@0: case GL_LEQUAL: michael@0: case GL_EQUAL: michael@0: case GL_GEQUAL: michael@0: case GL_GREATER: michael@0: case GL_NOTEQUAL: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (face == GL_FRONT || face == GL_FRONT_AND_BACK) michael@0: { michael@0: context->setStencilParams(func, ref, mask); michael@0: } michael@0: michael@0: if (face == GL_BACK || face == GL_FRONT_AND_BACK) michael@0: { michael@0: context->setStencilBackParams(func, ref, mask); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glStencilMask(GLuint mask) michael@0: { michael@0: glStencilMaskSeparate(GL_FRONT_AND_BACK, mask); michael@0: } michael@0: michael@0: void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) michael@0: { michael@0: EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); michael@0: michael@0: try michael@0: { michael@0: switch (face) michael@0: { michael@0: case GL_FRONT: michael@0: case GL_BACK: michael@0: case GL_FRONT_AND_BACK: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (face == GL_FRONT || face == GL_FRONT_AND_BACK) michael@0: { michael@0: context->setStencilWritemask(mask); michael@0: } michael@0: michael@0: if (face == GL_BACK || face == GL_FRONT_AND_BACK) michael@0: { michael@0: context->setStencilBackWritemask(mask); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) michael@0: { michael@0: glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); michael@0: } michael@0: michael@0: void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) michael@0: { michael@0: EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", michael@0: face, fail, zfail, zpass); michael@0: michael@0: try michael@0: { michael@0: switch (face) michael@0: { michael@0: case GL_FRONT: michael@0: case GL_BACK: michael@0: case GL_FRONT_AND_BACK: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (fail) michael@0: { michael@0: case GL_ZERO: michael@0: case GL_KEEP: michael@0: case GL_REPLACE: michael@0: case GL_INCR: michael@0: case GL_DECR: michael@0: case GL_INVERT: michael@0: case GL_INCR_WRAP: michael@0: case GL_DECR_WRAP: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (zfail) michael@0: { michael@0: case GL_ZERO: michael@0: case GL_KEEP: michael@0: case GL_REPLACE: michael@0: case GL_INCR: michael@0: case GL_DECR: michael@0: case GL_INVERT: michael@0: case GL_INCR_WRAP: michael@0: case GL_DECR_WRAP: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (zpass) michael@0: { michael@0: case GL_ZERO: michael@0: case GL_KEEP: michael@0: case GL_REPLACE: michael@0: case GL_INCR: michael@0: case GL_DECR: michael@0: case GL_INVERT: michael@0: case GL_INCR_WRAP: michael@0: case GL_DECR_WRAP: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (face == GL_FRONT || face == GL_FRONT_AND_BACK) michael@0: { michael@0: context->setStencilOperations(fail, zfail, zpass); michael@0: } michael@0: michael@0: if (face == GL_BACK || face == GL_FRONT_AND_BACK) michael@0: { michael@0: context->setStencilBackOperations(fail, zfail, zpass); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: GLboolean __stdcall glTestFenceNV(GLuint fence) michael@0: { michael@0: EVENT("(GLuint fence = %d)", fence); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Fence *fenceObject = context->getFence(fence); michael@0: michael@0: if (fenceObject == NULL) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION, GL_TRUE); michael@0: } michael@0: michael@0: return fenceObject->testFence(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: michael@0: return GL_TRUE; michael@0: } michael@0: michael@0: void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, michael@0: GLint border, GLenum format, GLenum type, const GLvoid* pixels) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " michael@0: "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", michael@0: target, level, internalformat, width, height, border, format, type, pixels); michael@0: michael@0: try michael@0: { michael@0: if (!validImageSize(level, width, height)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (internalformat != GLint(format)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: // validate by itself (used as secondary key below) michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_UNSIGNED_SHORT_5_6_5: michael@0: case GL_UNSIGNED_SHORT_4_4_4_4: michael@0: case GL_UNSIGNED_SHORT_5_5_5_1: michael@0: case GL_UNSIGNED_SHORT: michael@0: case GL_UNSIGNED_INT: michael@0: case GL_UNSIGNED_INT_24_8_OES: michael@0: case GL_HALF_FLOAT_OES: michael@0: case GL_FLOAT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: // validate + combinations michael@0: // - invalid -> sets INVALID_ENUM michael@0: // - invalid + combination -> sets INVALID_OPERATION michael@0: switch (format) michael@0: { michael@0: case GL_ALPHA: michael@0: case GL_LUMINANCE: michael@0: case GL_LUMINANCE_ALPHA: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_FLOAT: michael@0: case GL_HALF_FLOAT_OES: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_RGB: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_UNSIGNED_SHORT_5_6_5: michael@0: case GL_FLOAT: michael@0: case GL_HALF_FLOAT_OES: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_RGBA: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_UNSIGNED_SHORT_4_4_4_4: michael@0: case GL_UNSIGNED_SHORT_5_5_5_1: michael@0: case GL_FLOAT: michael@0: case GL_HALF_FLOAT_OES: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_BGRA_EXT: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_BYTE: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: break; michael@0: case GL_DEPTH_COMPONENT: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_SHORT: michael@0: case GL_UNSIGNED_INT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: case GL_DEPTH_STENCIL_OES: michael@0: switch (type) michael@0: { michael@0: case GL_UNSIGNED_INT_24_8_OES: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (border != 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (level > context->getMaximumTextureLevel()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: if (width > (context->getMaximumTextureDimension() >> level) || michael@0: height > (context->getMaximumTextureDimension() >> level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: michael@0: if (width != height) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (width > (context->getMaximumCubeTextureDimension() >> level) || michael@0: height > (context->getMaximumCubeTextureDimension() >> level)) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (format) { michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: if (context->supportsDXT1Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: if (context->supportsDXT3Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: if (context->supportsDXT5Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_DEPTH_COMPONENT: michael@0: case GL_DEPTH_STENCIL_OES: michael@0: if (!context->supportsDepthTextures()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: if (target != GL_TEXTURE_2D) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: // OES_depth_texture supports loading depth data and multiple levels, michael@0: // but ANGLE_depth_texture does not michael@0: if (pixels != NULL || level != 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: michael@0: if (type == GL_FLOAT) michael@0: { michael@0: if (!context->supportsFloat32Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: else if (type == GL_HALF_FLOAT_OES) michael@0: { michael@0: if (!context->supportsFloat16Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: michael@0: if (target == GL_TEXTURE_2D) michael@0: { michael@0: gl::Texture2D *texture = context->getTexture2D(); michael@0: michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: } michael@0: else michael@0: { michael@0: gl::TextureCubeMap *texture = context->getTextureCubeMap(); michael@0: michael@0: if (!texture) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: michael@0: texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: michael@0: texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: michael@0: texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: michael@0: texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: michael@0: texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: michael@0: texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: break; michael@0: default: UNREACHABLE(); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Texture *texture; michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: texture = context->getTexture2D(); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP: michael@0: texture = context->getTextureCubeMap(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_TEXTURE_WRAP_S: michael@0: if (!texture->setWrapS((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_WRAP_T: michael@0: if (!texture->setWrapT((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_MIN_FILTER: michael@0: if (!texture->setMinFilter((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_MAG_FILTER: michael@0: if (!texture->setMagFilter((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_USAGE_ANGLE: michael@0: if (!texture->setUsage((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_MAX_ANISOTROPY_EXT: michael@0: if (!context->supportsTextureFilterAnisotropy()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy())) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) michael@0: { michael@0: glTexParameterf(target, pname, (GLfloat)*params); michael@0: } michael@0: michael@0: void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Texture *texture; michael@0: michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: texture = context->getTexture2D(); michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP: michael@0: texture = context->getTextureCubeMap(); michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: switch (pname) michael@0: { michael@0: case GL_TEXTURE_WRAP_S: michael@0: if (!texture->setWrapS((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_WRAP_T: michael@0: if (!texture->setWrapT((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_MIN_FILTER: michael@0: if (!texture->setMinFilter((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_MAG_FILTER: michael@0: if (!texture->setMagFilter((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_USAGE_ANGLE: michael@0: if (!texture->setUsage((GLenum)param)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_MAX_ANISOTROPY_EXT: michael@0: if (!context->supportsTextureFilterAnisotropy()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy())) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params) michael@0: { michael@0: glTexParameteri(target, pname, *params); michael@0: } michael@0: michael@0: void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", michael@0: target, levels, internalformat, width, height); michael@0: michael@0: try michael@0: { michael@0: if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (width < 1 || height < 1 || levels < 1) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (target == GL_TEXTURE_CUBE_MAP && width != height) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: GLenum format = gl::ExtractFormat(internalformat); michael@0: GLenum type = gl::ExtractType(internalformat); michael@0: michael@0: if (format == GL_NONE || type == GL_NONE) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: switch (target) michael@0: { michael@0: case GL_TEXTURE_2D: michael@0: if (width > context->getMaximumTextureDimension() || michael@0: height > context->getMaximumTextureDimension()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: case GL_TEXTURE_CUBE_MAP: michael@0: if (width > context->getMaximumCubeTextureDimension() || michael@0: height > context->getMaximumCubeTextureDimension()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (levels != 1 && !context->supportsNonPower2Texture()) michael@0: { michael@0: if (!gl::isPow2(width) || !gl::isPow2(height)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: michael@0: switch (internalformat) michael@0: { michael@0: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: michael@0: if (!context->supportsDXT1Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: michael@0: if (!context->supportsDXT3Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: michael@0: if (!context->supportsDXT5Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_RGBA32F_EXT: michael@0: case GL_RGB32F_EXT: michael@0: case GL_ALPHA32F_EXT: michael@0: case GL_LUMINANCE32F_EXT: michael@0: case GL_LUMINANCE_ALPHA32F_EXT: michael@0: if (!context->supportsFloat32Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_RGBA16F_EXT: michael@0: case GL_RGB16F_EXT: michael@0: case GL_ALPHA16F_EXT: michael@0: case GL_LUMINANCE16F_EXT: michael@0: case GL_LUMINANCE_ALPHA16F_EXT: michael@0: if (!context->supportsFloat16Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: break; michael@0: case GL_DEPTH_COMPONENT16: michael@0: case GL_DEPTH_COMPONENT32_OES: michael@0: case GL_DEPTH24_STENCIL8_OES: michael@0: if (!context->supportsDepthTextures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: if (target != GL_TEXTURE_2D) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: // ANGLE_depth_texture only supports 1-level textures michael@0: if (levels != 1) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: michael@0: if (target == GL_TEXTURE_2D) michael@0: { michael@0: gl::Texture2D *texture = context->getTexture2D(); michael@0: michael@0: if (!texture || texture->id() == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texture->storage(levels, internalformat, width, height); michael@0: } michael@0: else if (target == GL_TEXTURE_CUBE_MAP) michael@0: { michael@0: gl::TextureCubeMap *texture = context->getTextureCubeMap(); michael@0: michael@0: if (!texture || texture->id() == 0) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (texture->isImmutable()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: texture->storage(levels, internalformat, width); michael@0: } michael@0: else UNREACHABLE(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, michael@0: GLenum format, GLenum type, const GLvoid* pixels) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " michael@0: "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " michael@0: "const GLvoid* pixels = 0x%0.8p)", michael@0: target, level, xoffset, yoffset, width, height, format, type, pixels); michael@0: michael@0: try michael@0: { michael@0: if (!gl::IsInternalTextureTarget(target)) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (std::numeric_limits::max() - xoffset < width || std::numeric_limits::max() - yoffset < height) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (!checkTextureFormatType(format, type)) michael@0: { michael@0: return; // error is set by helper function michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (level > context->getMaximumTextureLevel()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (format == GL_FLOAT) michael@0: { michael@0: if (!context->supportsFloat32Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: else if (format == GL_HALF_FLOAT_OES) michael@0: { michael@0: if (!context->supportsFloat16Textures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: } michael@0: else if (gl::IsDepthTexture(format)) michael@0: { michael@0: if (!context->supportsDepthTextures()) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: if (target != GL_TEXTURE_2D) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: // OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (width == 0 || height == 0 || pixels == NULL) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: if (target == GL_TEXTURE_2D) michael@0: { michael@0: gl::Texture2D *texture = context->getTexture2D(); michael@0: if (validateSubImageParams2D(false, width, height, xoffset, yoffset, level, format, type, texture)) michael@0: { michael@0: texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: } michael@0: } michael@0: else if (gl::IsCubemapTextureTarget(target)) michael@0: { michael@0: gl::TextureCubeMap *texture = context->getTextureCubeMap(); michael@0: if (validateSubImageParamsCube(false, width, height, xoffset, yoffset, target, level, format, type, texture)) michael@0: { michael@0: texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); michael@0: } michael@0: } michael@0: else michael@0: { michael@0: UNREACHABLE(); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform1f(GLint location, GLfloat x) michael@0: { michael@0: glUniform1fv(location, 1, &x); michael@0: } michael@0: michael@0: void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform1fv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform1i(GLint location, GLint x) michael@0: { michael@0: glUniform1iv(location, 1, &x); michael@0: } michael@0: michael@0: void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform1iv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) michael@0: { michael@0: GLfloat xy[2] = {x, y}; michael@0: michael@0: glUniform2fv(location, 1, (GLfloat*)&xy); michael@0: } michael@0: michael@0: void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform2fv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform2i(GLint location, GLint x, GLint y) michael@0: { michael@0: GLint xy[4] = {x, y}; michael@0: michael@0: glUniform2iv(location, 1, (GLint*)&xy); michael@0: } michael@0: michael@0: void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform2iv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) michael@0: { michael@0: GLfloat xyz[3] = {x, y, z}; michael@0: michael@0: glUniform3fv(location, 1, (GLfloat*)&xyz); michael@0: } michael@0: michael@0: void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform3fv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) michael@0: { michael@0: GLint xyz[3] = {x, y, z}; michael@0: michael@0: glUniform3iv(location, 1, (GLint*)&xyz); michael@0: } michael@0: michael@0: void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform3iv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) michael@0: { michael@0: GLfloat xyzw[4] = {x, y, z, w}; michael@0: michael@0: glUniform4fv(location, 1, (GLfloat*)&xyzw); michael@0: } michael@0: michael@0: void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform4fv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) michael@0: { michael@0: GLint xyzw[4] = {x, y, z, w}; michael@0: michael@0: glUniform4iv(location, 1, (GLint*)&xyzw); michael@0: } michael@0: michael@0: void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); michael@0: michael@0: try michael@0: { michael@0: if (count < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniform4iv(location, count, v)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", michael@0: location, count, transpose, value); michael@0: michael@0: try michael@0: { michael@0: if (count < 0 || transpose != GL_FALSE) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniformMatrix2fv(location, count, value)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", michael@0: location, count, transpose, value); michael@0: michael@0: try michael@0: { michael@0: if (count < 0 || transpose != GL_FALSE) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniformMatrix3fv(location, count, value)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) michael@0: { michael@0: EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", michael@0: location, count, transpose, value); michael@0: michael@0: try michael@0: { michael@0: if (count < 0 || transpose != GL_FALSE) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (location == -1) michael@0: { michael@0: return; michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->setUniformMatrix4fv(location, count, value)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glUseProgram(GLuint program) michael@0: { michael@0: EVENT("(GLuint program = %d)", program); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject && program != 0) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: if (program != 0 && !programObject->isLinked()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: context->useProgram(program); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glValidateProgram(GLuint program) michael@0: { michael@0: EVENT("(GLuint program = %d)", program); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: if (context->getShader(program)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: else michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: } michael@0: michael@0: programObject->validate(); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) michael@0: { michael@0: EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLfloat vals[4] = { x, 0, 0, 1 }; michael@0: context->setVertexAttrib(index, vals); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) michael@0: { michael@0: EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLfloat vals[4] = { values[0], 0, 0, 1 }; michael@0: context->setVertexAttrib(index, vals); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) michael@0: { michael@0: EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLfloat vals[4] = { x, y, 0, 1 }; michael@0: context->setVertexAttrib(index, vals); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) michael@0: { michael@0: EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLfloat vals[4] = { values[0], values[1], 0, 1 }; michael@0: context->setVertexAttrib(index, vals); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) michael@0: { michael@0: EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLfloat vals[4] = { x, y, z, 1 }; michael@0: context->setVertexAttrib(index, vals); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) michael@0: { michael@0: EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLfloat vals[4] = { values[0], values[1], values[2], 1 }; michael@0: context->setVertexAttrib(index, vals); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) michael@0: { michael@0: EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: GLfloat vals[4] = { x, y, z, w }; michael@0: context->setVertexAttrib(index, vals); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) michael@0: { michael@0: EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setVertexAttrib(index, values); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) michael@0: { michael@0: EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setVertexAttribDivisor(index, divisor); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) michael@0: { michael@0: EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " michael@0: "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", michael@0: index, size, type, normalized, stride, ptr); michael@0: michael@0: try michael@0: { michael@0: if (index >= gl::MAX_VERTEX_ATTRIBS) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (size < 1 || size > 4) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: switch (type) michael@0: { michael@0: case GL_BYTE: michael@0: case GL_UNSIGNED_BYTE: michael@0: case GL_SHORT: michael@0: case GL_UNSIGNED_SHORT: michael@0: case GL_FIXED: michael@0: case GL_FLOAT: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if (stride < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) michael@0: { michael@0: EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); michael@0: michael@0: try michael@0: { michael@0: if (width < 0 || height < 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: context->setViewportParams(x, y, width, height); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, michael@0: GLbitfield mask, GLenum filter) michael@0: { michael@0: EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " michael@0: "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " michael@0: "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", michael@0: srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); michael@0: michael@0: try michael@0: { michael@0: switch (filter) michael@0: { michael@0: case GL_NEAREST: michael@0: break; michael@0: default: michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0) michael@0: { michael@0: ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation"); michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle()) michael@0: { michael@0: ERR("Blits with the same source and destination framebuffer are not supported by this implementation."); michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, michael@0: GLint border, GLenum format, GLenum type, const GLvoid* pixels) michael@0: { michael@0: EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " michael@0: "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, " michael@0: "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)", michael@0: target, level, internalformat, width, height, depth, border, format, type, pixels); michael@0: michael@0: try michael@0: { michael@0: UNIMPLEMENTED(); // FIXME michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, michael@0: GLenum *binaryFormat, void *binary) michael@0: { michael@0: EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)", michael@0: program, bufSize, length, binaryFormat, binary); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject || !programObject->isLinked()) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: gl::ProgramBinary *programBinary = programObject->getProgramBinary(); michael@0: michael@0: if (!programBinary) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (!programBinary->save(binary, bufSize, length)) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: *binaryFormat = GL_PROGRAM_BINARY_ANGLE; michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, michael@0: const void *binary, GLint length) michael@0: { michael@0: EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", michael@0: program, binaryFormat, binary, length); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (binaryFormat != GL_PROGRAM_BINARY_ANGLE) michael@0: { michael@0: return gl::error(GL_INVALID_ENUM); michael@0: } michael@0: michael@0: gl::Program *programObject = context->getProgram(program); michael@0: michael@0: if (!programObject) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: context->setProgramBinary(program, binary, length); michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) michael@0: { michael@0: EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets()) michael@0: { michael@0: return gl::error(GL_INVALID_VALUE); michael@0: } michael@0: michael@0: if (context->getDrawFramebufferHandle() == 0) michael@0: { michael@0: if (n != 1) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: michael@0: if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: else michael@0: { michael@0: for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) michael@0: { michael@0: const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment; michael@0: if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment) michael@0: { michael@0: return gl::error(GL_INVALID_OPERATION); michael@0: } michael@0: } michael@0: } michael@0: michael@0: gl::Framebuffer *framebuffer = context->getDrawFramebuffer(); michael@0: michael@0: for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) michael@0: { michael@0: framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]); michael@0: } michael@0: michael@0: for (int colorAttachment = n; colorAttachment < (int)context->getMaximumRenderTargets(); colorAttachment++) michael@0: { michael@0: framebuffer->setDrawBufferState(colorAttachment, GL_NONE); michael@0: } michael@0: } michael@0: } michael@0: catch (std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY); michael@0: } michael@0: } michael@0: michael@0: __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname) michael@0: { michael@0: struct Extension michael@0: { michael@0: const char *name; michael@0: __eglMustCastToProperFunctionPointerType address; michael@0: }; michael@0: michael@0: static const Extension glExtensions[] = michael@0: { michael@0: {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES}, michael@0: {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE}, michael@0: {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE}, michael@0: {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV}, michael@0: {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV}, michael@0: {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV}, michael@0: {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV}, michael@0: {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV}, michael@0: {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV}, michael@0: {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV}, michael@0: {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE}, michael@0: {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT}, michael@0: {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT}, michael@0: {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT}, michael@0: {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT}, michael@0: {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT}, michael@0: {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT}, michael@0: {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT}, michael@0: {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT}, michael@0: {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT}, michael@0: {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT}, michael@0: {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT}, michael@0: {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT}, michael@0: {"glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)glDrawBuffersEXT}, michael@0: {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE}, michael@0: {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE}, michael@0: {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE}, michael@0: {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES}, michael@0: {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, }; michael@0: michael@0: for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++) michael@0: { michael@0: if (strcmp(procname, glExtensions[ext].name) == 0) michael@0: { michael@0: return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address; michael@0: } michael@0: } michael@0: michael@0: return NULL; michael@0: } michael@0: michael@0: // Non-public functions used by EGL michael@0: michael@0: bool __stdcall glBindTexImage(egl::Surface *surface) michael@0: { michael@0: EVENT("(egl::Surface* surface = 0x%0.8p)", michael@0: surface); michael@0: michael@0: try michael@0: { michael@0: gl::Context *context = gl::getNonLostContext(); michael@0: michael@0: if (context) michael@0: { michael@0: gl::Texture2D *textureObject = context->getTexture2D(); michael@0: michael@0: if (textureObject->isImmutable()) michael@0: { michael@0: return false; michael@0: } michael@0: michael@0: if (textureObject) michael@0: { michael@0: textureObject->bindTexImage(surface); michael@0: } michael@0: } michael@0: } michael@0: catch(std::bad_alloc&) michael@0: { michael@0: return gl::error(GL_OUT_OF_MEMORY, false); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: michael@0: }