Commit b676d2d0 by Nicolas Capens Committed by Nicolas Capens

Implement EGL_KHR_gl_texture_2D_image support.

BUG=14610416 Change-Id: I78b958709f92bf41a15a8e85260d09de9c2385e1 Reviewed-on: https://swiftshader-review.googlesource.com/1051Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent d6e03bb6
......@@ -187,7 +187,8 @@ const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
case EGL_CLIENT_APIS:
return success("OpenGL_ES");
case EGL_EXTENSIONS:
return success("EGL_KHR_image_base");
return success("EGL_KHR_gl_texture_2D_image "
"EGL_KHR_image_base");
case EGL_VENDOR:
return success("TransGaming Inc.");
case EGL_VERSION:
......@@ -1079,11 +1080,14 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
switch(target)
{
case EGL_GL_TEXTURE_2D_KHR:
break;
default:
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
EGLenum imagePreserved = EGL_FALSE;
GLuint textureLevel = 0;
if(attrib_list)
{
for(const EGLint *attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
......@@ -1092,6 +1096,10 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
{
imagePreserved = attribute[1];
}
else if(attribute[0] == EGL_GL_TEXTURE_LEVEL_KHR)
{
textureLevel = attribute[1];
}
else
{
return error(EGL_BAD_ATTRIBUTE, EGL_NO_IMAGE_KHR);
......@@ -1099,9 +1107,52 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
}
}
UNIMPLEMENTED(); // FIXME
if(textureLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
}
if(target == EGL_GL_TEXTURE_2D_KHR)
{
GLuint name = (GLuint)buffer;
return success((EGLImageKHR)0);
if(name == 0)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
gl::Texture *texture = context->getTexture(name);
if(!texture || texture->getTarget() != GL_TEXTURE_2D)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
if(texture->isShared(GL_TEXTURE_2D, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
{
return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR);
}
if(textureLevel != 0 && !texture->isSamplerComplete())
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
gl::Image *image = texture->getSharedImage(GL_TEXTURE_2D, textureLevel);
if(!image)
{
return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
}
return success((EGLImageKHR)image);
}
else UNREACHABLE();
}
catch(std::bad_alloc&)
{
......@@ -1122,9 +1173,13 @@ EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
return error(EGL_BAD_DISPLAY, EGL_FALSE);
}
// FIXME
UNIMPLEMENTED();
return error(EGL_BAD_PARAMETER, EGL_FALSE);
if(!image)
{
return error(EGL_BAD_PARAMETER, EGL_FALSE);
}
gl::Image *glImage = static_cast<gl::Image*>(image);
glImage->release();
return success(EGL_TRUE);
}
......
......@@ -374,7 +374,7 @@ class Context
Fence *getFence(GLuint handle);
Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle);
Texture *getTexture(GLuint handle);
virtual Texture *getTexture(GLuint handle);
Framebuffer *getFramebuffer(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
Query *getQuery(GLuint handle, bool create, GLenum type);
......
......@@ -35,6 +35,7 @@ namespace gl
, internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1)
, sw::Surface(getParentResource(parentTexture), width, height, 1, selectInternalFormat(format, type), true, true)
{
shared = false;
referenceCount = 1;
}
......@@ -42,6 +43,7 @@ namespace gl
: parentTexture(parentTexture), width(width), height(height), internalFormat(internalFormat), format(format), type(type), multiSampleDepth(multiSampleDepth)
, sw::Surface(getParentResource(parentTexture), width, height, multiSampleDepth, internalFormat, lockable, renderTarget)
{
shared = false;
referenceCount = 1;
}
......@@ -130,6 +132,16 @@ namespace gl
release();
}
bool Image::isShared() const
{
return shared;
}
void Image::markShared()
{
shared = true;
}
sw::Format Image::selectInternalFormat(GLenum format, GLenum type)
{
#if S3TC_SUPPORT
......
......@@ -45,6 +45,9 @@ namespace gl
virtual void release();
void unbind(); // Break parent ownership and release
bool isShared() const;
void markShared();
static sw::Format selectInternalFormat(GLenum format, GLenum type);
static int bytes(sw::Format format);
......@@ -75,6 +78,7 @@ namespace gl
void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer);
Texture *parentTexture;
bool shared; // Used as an EGLImage
const GLsizei width;
const GLsizei height;
......
......@@ -94,7 +94,7 @@ void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
// caller must release() the returned surface
Image *RenderbufferTexture2D::getRenderTarget()
{
return mTexture2D->getRenderTarget(GL_TEXTURE_2D);
return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
}
GLsizei RenderbufferTexture2D::getWidth() const
......@@ -150,7 +150,7 @@ void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
// caller must release() the returned surface
Image *RenderbufferTextureCubeMap::getRenderTarget()
{
return mTextureCubeMap->getRenderTarget(mTarget);
return mTextureCubeMap->getRenderTarget(mTarget, 0);
}
GLsizei RenderbufferTextureCubeMap::getWidth() const
......
......@@ -163,6 +163,18 @@ GLfloat Texture::getMaxAnisotropy() const
return mMaxAnisotropy;
}
Image *Texture::getSharedImage(GLenum target, unsigned int level)
{
Image *image = getRenderTarget(target, level); // Increments reference count
if(image)
{
image->markShared();
}
return image;
}
void Texture::setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)
{
if(pixels && image)
......@@ -646,16 +658,35 @@ Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
return mColorbufferProxy;
}
Image *Texture2D::getRenderTarget(GLenum target)
Image *Texture2D::getRenderTarget(GLenum target, unsigned int level)
{
ASSERT(target == GL_TEXTURE_2D);
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(image[0])
if(image[level])
{
image[0]->addRef();
image[level]->addRef();
}
return image[0];
return image[level];
}
bool Texture2D::isShared(GLenum target, unsigned int level) const
{
ASSERT(target == GL_TEXTURE_2D);
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
if(mSurface) // Bound to an EGLSurface
{
return true;
}
if(!image[level])
{
return false;
}
return image[level]->isShared();
}
TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
......@@ -1066,18 +1097,34 @@ Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
return mFaceProxies[face];
}
Image *TextureCubeMap::getRenderTarget(GLenum target)
Image *TextureCubeMap::getRenderTarget(GLenum target, unsigned int level)
{
ASSERT(IsCubemapTextureTarget(target));
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
int face = CubeFaceIndex(target);
if(image[face][0])
if(image[face][level])
{
image[face][0]->addRef();
image[face][level]->addRef();
}
return image[face][0];
return image[face][level];
}
bool TextureCubeMap::isShared(GLenum target, unsigned int level) const
{
ASSERT(IsCubemapTextureTarget(target));
ASSERT(level < IMPLEMENTATION_MAX_TEXTURE_LEVELS);
int face = CubeFaceIndex(target);
if(!image[face][level])
{
return false;
}
return image[face][level]->isShared();
}
}
......
......@@ -85,7 +85,9 @@ public:
virtual bool isDepth(GLenum target, GLint level) const = 0;
virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
virtual Image *getRenderTarget(GLenum target) = 0;
virtual Image *getRenderTarget(GLenum target, unsigned int level) = 0;
virtual Image *getSharedImage(GLenum target, unsigned int level);
virtual bool isShared(GLenum target, unsigned int level) const = 0;
virtual void generateMipmaps() = 0;
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
......@@ -145,9 +147,11 @@ public:
virtual void generateMipmaps();
virtual Image *getImage(unsigned int level);
virtual Renderbuffer *getRenderbuffer(GLenum target);
Image *getRenderTarget(GLenum target);
virtual Renderbuffer *getRenderbuffer(GLenum target);
virtual Image *getRenderTarget(GLenum target, unsigned int level);
virtual bool isShared(GLenum target, unsigned int level) const;
Image *getImage(unsigned int level);
private:
bool isMipmapComplete() const;
......@@ -201,7 +205,8 @@ public:
virtual void generateMipmaps();
virtual Renderbuffer *getRenderbuffer(GLenum target);
virtual Image *getRenderTarget(GLenum target);
virtual Image *getRenderTarget(GLenum target, unsigned int level);
virtual bool isShared(GLenum target, unsigned int level) const;
Image *getImage(int face, unsigned int level);
......
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