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