summaryrefslogtreecommitdiffstats
path: root/ANGLE/src/libGLESv2/libGLESv2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ANGLE/src/libGLESv2/libGLESv2.cpp')
-rw-r--r--ANGLE/src/libGLESv2/libGLESv2.cpp508
1 files changed, 458 insertions, 50 deletions
diff --git a/ANGLE/src/libGLESv2/libGLESv2.cpp b/ANGLE/src/libGLESv2/libGLESv2.cpp
index a136bd3..25d083b 100644
--- a/ANGLE/src/libGLESv2/libGLESv2.cpp
+++ b/ANGLE/src/libGLESv2/libGLESv2.cpp
@@ -180,7 +180,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM);
}
@@ -189,7 +189,15 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
if (context)
{
- context->bindFramebuffer(framebuffer);
+ if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindReadFramebuffer(framebuffer);
+ }
+
+ if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindDrawFramebuffer(framebuffer);
+ }
}
}
catch(std::bad_alloc&)
@@ -559,7 +567,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM, 0);
}
@@ -568,7 +576,15 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
if (context)
{
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ }
return framebuffer->completeness();
}
@@ -720,22 +736,107 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
try
{
- if (!gl::IsTextureTarget(target))
+ if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
{
- return error(GL_INVALID_ENUM);
+ return error(GL_INVALID_VALUE);
}
- if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
+ if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
- if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
+ switch (target)
+ {
+ case GL_TEXTURE_2D:
+ if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (width != height)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ switch (internalformat)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if (border != 0)
{
return error(GL_INVALID_VALUE);
}
- return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (!context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ }
+
+ if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (target == GL_TEXTURE_2D)
+ {
+ gl::Texture2D *texture = context->getTexture2D();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+ }
+ else
+ {
+ gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ switch (target)
+ {
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+ break;
+ default: UNREACHABLE();
+ }
+ }
+ }
+
}
catch(std::bad_alloc&)
{
@@ -763,17 +864,95 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
return error(GL_INVALID_VALUE);
}
- if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
+ if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
+ (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
- if (xoffset != 0 || yoffset != 0)
+ switch (format)
{
- return error(GL_INVALID_OPERATION);
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if (width == 0 || height == 0 || data == NULL)
+ {
+ return;
}
- return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (!context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
+ }
+
+ if (imageSize != gl::ComputeCompressedSize(width, height, format))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (xoffset % 4 != 0 || yoffset % 4 != 0)
+ {
+ return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
+ // does not exist unless DXT1 textures are supported.
+ }
+
+ if (target == GL_TEXTURE_2D)
+ {
+ gl::Texture2D *texture = context->getTexture2D();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if ((width % 4 != 0 && width != texture->getWidth()) ||
+ (height % 4 != 0 && height != texture->getHeight()))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+ }
+ else if (gl::IsCubemapTextureTarget(target))
+ {
+ gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if ((width % 4 != 0 && width != texture->getWidth()) ||
+ (height % 4 != 0 && height != texture->getHeight()))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
}
catch(std::bad_alloc&)
{
@@ -834,6 +1013,8 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_LUMINANCE_ALPHA:
case GL_RGB:
case GL_RGBA:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // Compressed textures are not supported here, but if they are unsupported altogether,
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: // a different error is generated than otherwise. That is handled below.
break;
default:
return error(GL_INVALID_VALUE);
@@ -848,8 +1029,31 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (context)
{
- gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
+ if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ if (context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
+ gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -858,6 +1062,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
{
return error(GL_INVALID_OPERATION);
}
+
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
texture->copyImage(level, internalformat, x, y, width, height, source);
}
@@ -870,6 +1079,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copyImage(target, level, internalformat, x, y, width, height, source);
}
else
@@ -916,8 +1130,18 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
if (context)
{
- gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
+ gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -927,6 +1151,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
}
else if (gl::IsCubemapTextureTarget(target))
@@ -938,6 +1167,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
}
else
@@ -1559,7 +1793,8 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
try
{
- if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
+ if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ || renderbuffertarget != GL_RENDERBUFFER)
{
return error(GL_INVALID_ENUM);
}
@@ -1568,9 +1803,20 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
if (context)
{
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ GLuint framebufferHandle = 0;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ framebufferHandle = context->getReadFramebufferHandle();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ framebufferHandle = context->getDrawFramebufferHandle();
+ }
- if (context->getFramebufferHandle() == 0 || !framebuffer)
+ if (framebufferHandle == 0 || !framebuffer)
{
return error(GL_INVALID_OPERATION);
}
@@ -1604,7 +1850,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM);
}
@@ -1636,6 +1882,11 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
return error(GL_INVALID_OPERATION);
}
+ if (tex->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
switch (textarget)
{
case GL_TEXTURE_2D:
@@ -1667,9 +1918,20 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
}
}
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ GLuint framebufferHandle = 0;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ framebufferHandle = context->getReadFramebufferHandle();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ framebufferHandle = context->getDrawFramebufferHandle();
+ }
- if (context->getFramebufferHandle() == 0 || !framebuffer)
+ if (framebufferHandle == 0 || !framebuffer)
{
return error(GL_INVALID_OPERATION);
}
@@ -1770,6 +2032,11 @@ void __stdcall glGenerateMipmap(GLenum target)
return error(GL_INVALID_ENUM);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->generateMipmaps();
}
}
@@ -2225,14 +2492,29 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
if (context)
{
- if (context->getFramebufferHandle() == 0)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_OPERATION);
+ return error(GL_INVALID_ENUM);
}
- if (target != GL_FRAMEBUFFER)
+ gl::Framebuffer *framebuffer = NULL;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_ENUM);
+ if(context->getReadFramebufferHandle() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ framebuffer = context->getReadFramebuffer();
+ }
+ else
+ {
+ if (context->getDrawFramebufferHandle() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ framebuffer = context->getDrawFramebuffer();
}
GLenum attachmentType;
@@ -2240,16 +2522,16 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
switch (attachment)
{
case GL_COLOR_ATTACHMENT0:
- attachmentType = context->getFramebuffer()->getColorbufferType();
- attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
+ attachmentType = framebuffer->getColorbufferType();
+ attachmentHandle = framebuffer->getColorbufferHandle();
break;
case GL_DEPTH_ATTACHMENT:
- attachmentType = context->getFramebuffer()->getDepthbufferType();
- attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
+ attachmentType = framebuffer->getDepthbufferType();
+ attachmentHandle = framebuffer->getDepthbufferHandle();
break;
case GL_STENCIL_ATTACHMENT:
- attachmentType = context->getFramebuffer()->getStencilbufferType();
- attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
+ attachmentType = framebuffer->getStencilbufferType();
+ attachmentHandle = framebuffer->getStencilbufferHandle();
break;
default: return error(GL_INVALID_ENUM);
}
@@ -2508,7 +2790,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_RED_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
}
else
{
@@ -2518,7 +2800,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_GREEN_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
}
else
{
@@ -2528,7 +2810,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_BLUE_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
}
else
{
@@ -2538,7 +2820,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_ALPHA_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
}
else
{
@@ -2548,7 +2830,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_DEPTH_SIZE:
if (renderbuffer->isDepthbuffer())
{
- *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
+ *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
}
else
{
@@ -2558,13 +2840,25 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_STENCIL_SIZE:
if (renderbuffer->isStencilbuffer())
{
- *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
+ *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
}
else
{
*params = 0;
}
break;
+ case GL_RENDERBUFFER_SAMPLES_ANGLE:
+ {
+ if (context->getMaxSupportedSamples() != 0)
+ {
+ *params = renderbuffer->getStorage()->getSamples();
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -2993,7 +3287,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
return error(GL_INVALID_VALUE);
}
- gl::AttributeState attribState = context->getVertexAttribState(index);
+ const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
@@ -3013,7 +3307,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- *params = (GLfloat)attribState.mBoundBuffer;
+ *params = (GLfloat)attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
@@ -3046,7 +3340,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
return error(GL_INVALID_VALUE);
}
- gl::AttributeState attribState = context->getVertexAttribState(index);
+ const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
@@ -3066,7 +3360,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- *params = attribState.mBoundBuffer;
+ *params = attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
@@ -3481,6 +3775,17 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLe
return error(GL_INVALID_OPERATION);
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ break;
+ default:
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
switch (type)
{
@@ -3521,10 +3826,10 @@ void __stdcall glReleaseShaderCompiler(void)
}
}
-void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
- TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
- target, internalformat, width, height);
+ TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, samples, internalformat, width, height);
try
{
@@ -3543,12 +3848,15 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
case GL_RGB5_A1:
case GL_RGB565:
case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
break;
default:
return error(GL_INVALID_ENUM);
}
- if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
+ if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -3557,7 +3865,13 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
if (context)
{
- if (context->getRenderbufferHandle() == 0)
+ if (samples > context->getMaxSupportedSamples())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ GLuint handle = context->getRenderbufferHandle();
+ if (handle == 0)
{
return error(GL_INVALID_OPERATION);
}
@@ -3565,15 +3879,20 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
switch (internalformat)
{
case GL_DEPTH_COMPONENT16:
- context->setRenderbuffer(new gl::Depthbuffer(width, height));
+ context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
break;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
- context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
break;
case GL_STENCIL_INDEX8:
- context->setRenderbuffer(new gl::Stencilbuffer(width, height));
+ context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
+ break;
+ case GL_DEPTH24_STENCIL8_OES:
+ context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
break;
default:
return error(GL_INVALID_ENUM);
@@ -3586,6 +3905,11 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
}
}
+void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
+}
+
void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
{
TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
@@ -3958,6 +4282,18 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
return error(GL_INVALID_ENUM);
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+ break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
default:
return error(GL_INVALID_VALUE);
}
@@ -3971,6 +4307,19 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (context)
{
+ if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ if (context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -4146,6 +4495,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else if (gl::IsCubemapTextureTarget(target))
@@ -4157,6 +4511,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else
@@ -4965,7 +5324,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
if (context)
{
- context->setVertexAttribState(index, context->getArrayBufferHandle(), size, type, (normalized == GL_TRUE), stride, ptr);
+ context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
}
}
catch(std::bad_alloc&)
@@ -4998,6 +5357,54 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
}
+void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
+ "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
+ "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+ srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+ try
+ {
+ switch (filter)
+ {
+ case GL_NEAREST:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
+ {
+ ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
+ {
+ ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
@@ -5027,6 +5434,7 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
static const Extension glExtensions[] =
{
{"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
+ {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
};
for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)