Commit ebddd1a2 by Clemen Deng Committed by Commit Bot

implement core egl image entry points

Bug: angleproject:2467 Change-Id: Ica943a3972333e90a516aa6960f333cc9c378be2 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1653714Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 169ef353
...@@ -132,11 +132,11 @@ Error ValidateStreamAttribute(const EGLAttrib attribute, ...@@ -132,11 +132,11 @@ Error ValidateStreamAttribute(const EGLAttrib attribute,
return NoError(); return NoError();
} }
Error ValidateCreateImageKHRMipLevelCommon(gl::Context *context, Error ValidateCreateImageMipLevelCommon(gl::Context *context,
const gl::Texture *texture, const gl::Texture *texture,
EGLAttrib level) EGLAttrib level)
{ {
// Note that the spec EGL_KHR_create_image spec does not explicitly specify an error // Note that the spec EGL_create_image spec does not explicitly specify an error
// when the level is outside the base/max level range, but it does mention that the // when the level is outside the base/max level range, but it does mention that the
// level "must be a part of the complete texture object <buffer>". It can be argued // level "must be a part of the complete texture object <buffer>". It can be argued
// that out-of-range levels are not a part of the complete texture. // that out-of-range levels are not a part of the complete texture.
...@@ -1819,25 +1819,17 @@ Error ValidateCompatibleConfigs(const Display *display, ...@@ -1819,25 +1819,17 @@ Error ValidateCompatibleConfigs(const Display *display,
return NoError(); return NoError();
} }
Error ValidateCreateImageKHR(const Display *display, Error ValidateCreateImage(const Display *display,
gl::Context *context, gl::Context *context,
EGLenum target, EGLenum target,
EGLClientBuffer buffer, EGLClientBuffer buffer,
const AttributeMap &attributes) const AttributeMap &attributes)
{ {
ANGLE_TRY(ValidateDisplay(display)); ANGLE_TRY(ValidateDisplay(display));
const DisplayExtensions &displayExtensions = display->getExtensions(); const DisplayExtensions &displayExtensions = display->getExtensions();
if (!displayExtensions.imageBase && !displayExtensions.image)
{
// It is out of spec what happens when calling an extension function when the extension is
// not available.
// EGL_BAD_DISPLAY seems like a reasonable error.
return EglBadDisplay() << "EGL_KHR_image not supported.";
}
// TODO(geofflang): Complete validation from EGL_KHR_image_base: // TODO(geofflang): Complete validation from EGL_KHR_image_base:
// If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> is itself an // If the resource specified by <dpy>, <ctx>, <target>, <buffer> and <attrib_list> is itself an
// EGLImage sibling, the error EGL_BAD_ACCESS is generated. // EGLImage sibling, the error EGL_BAD_ACCESS is generated.
...@@ -1850,7 +1842,7 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1850,7 +1842,7 @@ Error ValidateCreateImageKHR(const Display *display,
switch (attribute) switch (attribute)
{ {
case EGL_IMAGE_PRESERVED_KHR: case EGL_IMAGE_PRESERVED:
switch (value) switch (value)
{ {
case EGL_TRUE: case EGL_TRUE:
...@@ -1859,28 +1851,28 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1859,28 +1851,28 @@ Error ValidateCreateImageKHR(const Display *display,
default: default:
return EglBadParameter() return EglBadParameter()
<< "EGL_IMAGE_PRESERVED_KHR must be EGL_TRUE or EGL_FALSE."; << "EGL_IMAGE_PRESERVED must be EGL_TRUE or EGL_FALSE.";
} }
break; break;
case EGL_GL_TEXTURE_LEVEL_KHR: case EGL_GL_TEXTURE_LEVEL:
if (!displayExtensions.glTexture2DImage && if (!displayExtensions.glTexture2DImage &&
!displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage) !displayExtensions.glTextureCubemapImage && !displayExtensions.glTexture3DImage)
{ {
return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL_KHR cannot be used " return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL cannot be used "
"without KHR_gl_texture_*_image support."; "without KHR_gl_texture_*_image support.";
} }
if (value < 0) if (value < 0)
{ {
return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL_KHR cannot be negative."; return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL cannot be negative.";
} }
break; break;
case EGL_GL_TEXTURE_ZOFFSET_KHR: case EGL_GL_TEXTURE_ZOFFSET:
if (!displayExtensions.glTexture3DImage) if (!displayExtensions.glTexture3DImage)
{ {
return EglBadParameter() << "EGL_GL_TEXTURE_ZOFFSET_KHR cannot be used " return EglBadParameter() << "EGL_GL_TEXTURE_ZOFFSET cannot be used "
"without KHR_gl_texture_3D_image support."; "without KHR_gl_texture_3D_image support.";
} }
break; break;
...@@ -1893,7 +1885,7 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1893,7 +1885,7 @@ Error ValidateCreateImageKHR(const Display *display,
switch (target) switch (target)
{ {
case EGL_GL_TEXTURE_2D_KHR: case EGL_GL_TEXTURE_2D:
{ {
if (!displayExtensions.glTexture2DImage) if (!displayExtensions.glTexture2DImage)
{ {
...@@ -1918,7 +1910,7 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1918,7 +1910,7 @@ Error ValidateCreateImageKHR(const Display *display,
return EglBadAccess() << "texture has a surface bound to it."; return EglBadAccess() << "texture has a surface bound to it.";
} }
EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
if (texture->getWidth(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0 || if (texture->getWidth(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0 ||
texture->getHeight(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0) texture->getHeight(gl::TextureTarget::_2D, static_cast<size_t>(level)) == 0)
{ {
...@@ -1926,16 +1918,16 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1926,16 +1918,16 @@ Error ValidateCreateImageKHR(const Display *display,
<< "target 2D texture does not have a valid size at specified level."; << "target 2D texture does not have a valid size at specified level.";
} }
ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level)); ANGLE_TRY(ValidateCreateImageMipLevelCommon(context, texture, level));
} }
break; break;
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
{ {
if (!displayExtensions.glTextureCubemapImage) if (!displayExtensions.glTextureCubemapImage)
{ {
...@@ -1961,7 +1953,7 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1961,7 +1953,7 @@ Error ValidateCreateImageKHR(const Display *display,
return EglBadAccess() << "texture has a surface bound to it."; return EglBadAccess() << "texture has a surface bound to it.";
} }
EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
gl::TextureTarget cubeMapFace = egl_gl::EGLCubeMapTargetToCubeMapTarget(target); gl::TextureTarget cubeMapFace = egl_gl::EGLCubeMapTargetToCubeMapTarget(target);
if (texture->getWidth(cubeMapFace, static_cast<size_t>(level)) == 0 || if (texture->getWidth(cubeMapFace, static_cast<size_t>(level)) == 0 ||
texture->getHeight(cubeMapFace, static_cast<size_t>(level)) == 0) texture->getHeight(cubeMapFace, static_cast<size_t>(level)) == 0)
...@@ -1970,7 +1962,7 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1970,7 +1962,7 @@ Error ValidateCreateImageKHR(const Display *display,
"size at specified level and face."; "size at specified level and face.";
} }
ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level)); ANGLE_TRY(ValidateCreateImageMipLevelCommon(context, texture, level));
if (level == 0 && !texture->isMipmapComplete() && if (level == 0 && !texture->isMipmapComplete() &&
CubeTextureHasUnspecifiedLevel0Face(texture)) CubeTextureHasUnspecifiedLevel0Face(texture))
...@@ -1982,7 +1974,7 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -1982,7 +1974,7 @@ Error ValidateCreateImageKHR(const Display *display,
} }
break; break;
case EGL_GL_TEXTURE_3D_KHR: case EGL_GL_TEXTURE_3D:
{ {
if (!displayExtensions.glTexture3DImage) if (!displayExtensions.glTexture3DImage)
{ {
...@@ -2007,8 +1999,8 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -2007,8 +1999,8 @@ Error ValidateCreateImageKHR(const Display *display,
return EglBadAccess() << "texture has a surface bound to it."; return EglBadAccess() << "texture has a surface bound to it.";
} }
EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL_KHR, 0); EGLAttrib level = attributes.get(EGL_GL_TEXTURE_LEVEL, 0);
EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET_KHR, 0); EGLAttrib zOffset = attributes.get(EGL_GL_TEXTURE_ZOFFSET, 0);
if (texture->getWidth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 || if (texture->getWidth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
texture->getHeight(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 || texture->getHeight(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0 ||
texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0) texture->getDepth(gl::TextureTarget::_3D, static_cast<size_t>(level)) == 0)
...@@ -2025,20 +2017,20 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -2025,20 +2017,20 @@ Error ValidateCreateImageKHR(const Display *display,
"level."; "level.";
} }
ANGLE_TRY(ValidateCreateImageKHRMipLevelCommon(context, texture, level)); ANGLE_TRY(ValidateCreateImageMipLevelCommon(context, texture, level));
} }
break; break;
case EGL_GL_RENDERBUFFER_KHR: case EGL_GL_RENDERBUFFER:
{ {
if (!displayExtensions.glRenderbufferImage) if (!displayExtensions.glRenderbufferImage)
{ {
return EglBadParameter() << "KHR_gl_renderbuffer_image not supported."; return EglBadParameter() << "KHR_gl_renderbuffer_image not supported.";
} }
if (attributes.contains(EGL_GL_TEXTURE_LEVEL_KHR)) if (attributes.contains(EGL_GL_TEXTURE_LEVEL))
{ {
return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL_KHR cannot be used in " return EglBadParameter() << "EGL_GL_TEXTURE_LEVEL cannot be used in "
"conjunction with a renderbuffer target."; "conjunction with a renderbuffer target.";
} }
...@@ -2084,15 +2076,40 @@ Error ValidateCreateImageKHR(const Display *display, ...@@ -2084,15 +2076,40 @@ Error ValidateCreateImageKHR(const Display *display,
<< "invalid target: 0x" << std::hex << std::uppercase << target; << "invalid target: 0x" << std::hex << std::uppercase << target;
} }
if (attributes.contains(EGL_GL_TEXTURE_ZOFFSET_KHR) && target != EGL_GL_TEXTURE_3D_KHR) if (attributes.contains(EGL_GL_TEXTURE_ZOFFSET) && target != EGL_GL_TEXTURE_3D)
{ {
return EglBadParameter() return EglBadParameter() << "EGL_GL_TEXTURE_ZOFFSET must be used with a 3D texture target.";
<< "EGL_GL_TEXTURE_ZOFFSET_KHR must be used with a 3D texture target.";
} }
return NoError(); return NoError();
} }
Error ValidateDestroyImage(const Display *display, const Image *image)
{
ANGLE_TRY(ValidateImage(display, image));
return NoError();
}
Error ValidateCreateImageKHR(const Display *display,
gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const AttributeMap &attributes)
{
ANGLE_TRY(ValidateDisplay(display));
if (!display->getExtensions().imageBase && !display->getExtensions().image)
{
// It is out of spec what happens when calling an extension function when the extension is
// not available.
// EGL_BAD_DISPLAY seems like a reasonable error.
return EglBadDisplay() << "EGL_KHR_image not supported.";
}
return ValidateCreateImage(display, context, target, buffer, attributes);
}
Error ValidateDestroyImageKHR(const Display *display, const Image *image) Error ValidateDestroyImageKHR(const Display *display, const Image *image)
{ {
ANGLE_TRY(ValidateImage(display, image)); ANGLE_TRY(ValidateImage(display, image));
......
...@@ -85,6 +85,12 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display, ...@@ -85,6 +85,12 @@ Error ValidateCreatePbufferFromClientBuffer(Display *display,
Error ValidateMakeCurrent(Display *display, Surface *draw, Surface *read, gl::Context *context); Error ValidateMakeCurrent(Display *display, Surface *draw, Surface *read, gl::Context *context);
Error ValidateCreateImage(const Display *display,
gl::Context *context,
EGLenum target,
EGLClientBuffer buffer,
const AttributeMap &attributes);
Error ValidateDestroyImage(const Display *display, const Image *image);
Error ValidateCreateImageKHR(const Display *display, Error ValidateCreateImageKHR(const Display *display,
gl::Context *context, gl::Context *context,
EGLenum target, EGLenum target,
......
...@@ -933,12 +933,28 @@ EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy, ...@@ -933,12 +933,28 @@ EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy,
", const EGLAttrib *attrib_list = 0x%016" PRIxPTR ")", ", const EGLAttrib *attrib_list = 0x%016" PRIxPTR ")",
(uintptr_t)dpy, (uintptr_t)ctx, target, (uintptr_t)buffer, (uintptr_t)attrib_list); (uintptr_t)dpy, (uintptr_t)ctx, target, (uintptr_t)buffer, (uintptr_t)attrib_list);
Thread *thread = egl::GetCurrentThread(); Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy); egl::Display *display = static_cast<egl::Display *>(dpy);
gl::Context *context = static_cast<gl::Context *>(ctx);
AttributeMap attributes = AttributeMap::CreateFromIntArray((const EGLint *)attrib_list);
UNIMPLEMENTED(); Error error = ValidateCreateImage(display, context, target, buffer, attributes);
thread->setError(EglBadDisplay() << "eglCreateImage unimplemented.", GetDebug(), if (error.isError())
"eglCreateImage", GetDisplayIfValid(display)); {
return EGL_NO_IMAGE; thread->setError(error, GetDebug(), "eglCreateImage", GetDisplayIfValid(display));
return EGL_NO_IMAGE;
}
Image *image = nullptr;
error = display->createImage(context, target, buffer, attributes, &image);
if (error.isError())
{
thread->setError(error, GetDebug(), "eglCreateImage", GetDisplayIfValid(display));
return EGL_NO_IMAGE;
}
thread->setSuccess();
return static_cast<EGLImage>(image);
} }
EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image) EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image)
...@@ -948,12 +964,19 @@ EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image) ...@@ -948,12 +964,19 @@ EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image)
(uintptr_t)dpy, (uintptr_t)image); (uintptr_t)dpy, (uintptr_t)image);
Thread *thread = egl::GetCurrentThread(); Thread *thread = egl::GetCurrentThread();
egl::Display *display = static_cast<egl::Display *>(dpy); egl::Display *display = static_cast<egl::Display *>(dpy);
Image *eglImage = static_cast<Image *>(image); Image *img = static_cast<Image *>(image);
UNIMPLEMENTED(); Error error = ValidateDestroyImage(display, img);
thread->setError(EglBadDisplay() << "eglDestroyImage unimplemented.", GetDebug(), if (error.isError())
"eglDestroyImage", GetImageIfValid(display, eglImage)); {
return EGL_FALSE; thread->setError(error, GetDebug(), "eglDestroyImage", GetImageIfValid(display, img));
return EGL_FALSE;
}
display->destroyImage(img);
thread->setSuccess();
return EGL_TRUE;
} }
EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplay(EGLenum platform, EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplay(EGLenum platform,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment