Commit 6e77a645 by Nicolas Capens Committed by Nicolas Capens

Implement EGL_KHR_gl_renderbuffer_image support.

BUG=14610416 Change-Id: I406d356a70c2c3b2a2b6861b7a8c00a01fe5c8cf Reviewed-on: https://swiftshader-review.googlesource.com/1061Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent d71d02a8
...@@ -189,6 +189,7 @@ const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) ...@@ -189,6 +189,7 @@ const char *EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
case EGL_EXTENSIONS: case EGL_EXTENSIONS:
return success("EGL_KHR_gl_texture_2D_image " return success("EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image " "EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
"EGL_KHR_image_base"); "EGL_KHR_image_base");
case EGL_VENDOR: case EGL_VENDOR:
return success("TransGaming Inc."); return success("TransGaming Inc.");
...@@ -1094,6 +1095,8 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu ...@@ -1094,6 +1095,8 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
textureTarget = GL_TEXTURE_CUBE_MAP; textureTarget = GL_TEXTURE_CUBE_MAP;
break; break;
case EGL_GL_RENDERBUFFER_KHR:
break;
default: default:
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
} }
...@@ -1131,35 +1134,62 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu ...@@ -1131,35 +1134,62 @@ EGLImageKHR EGLAPIENTRY eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenu
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
} }
gl::Texture *texture = context->getTexture(name); gl::Image *image = 0;
if(!texture || texture->getTarget() != textureTarget) if(textureTarget != GL_NONE)
{ {
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); gl::Texture *texture = context->getTexture(name);
}
if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling if(!texture || texture->getTarget() != textureTarget)
{ {
return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR); return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
} }
if(textureLevel != 0 && !texture->isSamplerComplete()) if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling
{ {
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR);
} }
if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) if(textureLevel != 0 && !texture->isSamplerComplete())
{ {
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); 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);
}
image = texture->createSharedImage(textureTarget, textureLevel);
} }
else if(target == EGL_GL_RENDERBUFFER_KHR)
{
gl::Renderbuffer *renderbuffer = context->getRenderbuffer(name);
if(!renderbuffer)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
gl::Image *image = texture->getSharedImage(textureTarget, textureLevel); if(renderbuffer->isShared()) // Already an EGLImage sibling
{
return error(EGL_BAD_ACCESS, EGL_NO_IMAGE_KHR);
}
image = renderbuffer->createSharedImage();
}
else UNREACHABLE();
if(!image) if(!image)
{ {
return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR); return error(EGL_BAD_MATCH, EGL_NO_IMAGE_KHR);
} }
if(image->getMultiSampleDepth() > 1)
{
return error(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR);
}
return success((EGLImageKHR)image); return success((EGLImageKHR)image);
} }
catch(std::bad_alloc&) catch(std::bad_alloc&)
......
...@@ -376,7 +376,7 @@ class Context ...@@ -376,7 +376,7 @@ class Context
Program *getProgram(GLuint handle); Program *getProgram(GLuint handle);
virtual Texture *getTexture(GLuint handle); virtual Texture *getTexture(GLuint handle);
Framebuffer *getFramebuffer(GLuint handle); Framebuffer *getFramebuffer(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle); virtual Renderbuffer *getRenderbuffer(GLuint handle);
Query *getQuery(GLuint handle, bool create, GLenum type); Query *getQuery(GLuint handle, bool create, GLenum type);
Buffer *getArrayBuffer(); Buffer *getArrayBuffer();
......
...@@ -39,13 +39,13 @@ namespace gl ...@@ -39,13 +39,13 @@ namespace gl
GLenum getFormat(); GLenum getFormat();
GLenum getType(); GLenum getType();
virtual sw::Format getInternalFormat(); virtual sw::Format getInternalFormat();
int getMultiSampleDepth(); virtual int getMultiSampleDepth();
virtual void addRef(); virtual void addRef();
virtual void release(); virtual void release();
void unbind(); // Break parent ownership and release void unbind(); // Break parent ownership and release
bool isShared() const; virtual bool isShared() const;
void markShared(); void markShared();
static sw::Format selectInternalFormat(GLenum format, GLenum type); static sw::Format selectInternalFormat(GLenum format, GLenum type);
......
...@@ -90,13 +90,25 @@ void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy) ...@@ -90,13 +90,25 @@ void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
mTexture2D->releaseProxy(proxy); mTexture2D->releaseProxy(proxy);
} }
// Increments refcount on surface. // Increments refcount on image.
// caller must release() the returned surface // caller must release() the returned image
Image *RenderbufferTexture2D::getRenderTarget() Image *RenderbufferTexture2D::getRenderTarget()
{ {
return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0); return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
} }
// Increments refcount on image.
// caller must release() the returned image
Image *RenderbufferTexture2D::createSharedImage()
{
return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
}
bool RenderbufferTexture2D::isShared() const
{
return mTexture2D->isShared(GL_TEXTURE_2D, 0);
}
GLsizei RenderbufferTexture2D::getWidth() const GLsizei RenderbufferTexture2D::getWidth() const
{ {
return mTexture2D->getWidth(GL_TEXTURE_2D, 0); return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
...@@ -146,13 +158,25 @@ void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy) ...@@ -146,13 +158,25 @@ void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
mTextureCubeMap->releaseProxy(proxy); mTextureCubeMap->releaseProxy(proxy);
} }
// Increments refcount on surface. // Increments refcount on image.
// caller must release() the returned surface // caller must release() the returned image
Image *RenderbufferTextureCubeMap::getRenderTarget() Image *RenderbufferTextureCubeMap::getRenderTarget()
{ {
return mTextureCubeMap->getRenderTarget(mTarget, 0); return mTextureCubeMap->getRenderTarget(mTarget, 0);
} }
// Increments refcount on image.
// caller must release() the returned image
Image *RenderbufferTextureCubeMap::createSharedImage()
{
return mTextureCubeMap->createSharedImage(mTarget, 0);
}
bool RenderbufferTextureCubeMap::isShared() const
{
return mTextureCubeMap->isShared(mTarget, 0);
}
GLsizei RenderbufferTextureCubeMap::getWidth() const GLsizei RenderbufferTextureCubeMap::getWidth() const
{ {
return mTextureCubeMap->getWidth(mTarget, 0); return mTextureCubeMap->getWidth(mTarget, 0);
...@@ -207,13 +231,25 @@ void Renderbuffer::release() ...@@ -207,13 +231,25 @@ void Renderbuffer::release()
RefCountObject::release(); RefCountObject::release();
} }
// Increments refcount on surface. // Increments refcount on image.
// caller must Release() the returned surface // caller must Release() the returned image
Image *Renderbuffer::getRenderTarget() Image *Renderbuffer::getRenderTarget()
{ {
return mInstance->getRenderTarget(); return mInstance->getRenderTarget();
} }
// Increments refcount on image.
// caller must Release() the returned image
Image *Renderbuffer::createSharedImage()
{
return mInstance->createSharedImage();
}
bool Renderbuffer::isShared() const
{
return mInstance->isShared();
}
GLsizei Renderbuffer::getWidth() const GLsizei Renderbuffer::getWidth() const
{ {
return mInstance->getWidth(); return mInstance->getWidth();
...@@ -290,13 +326,6 @@ RenderbufferStorage::~RenderbufferStorage() ...@@ -290,13 +326,6 @@ RenderbufferStorage::~RenderbufferStorage()
{ {
} }
// Increments refcount on surface.
// caller must Release() the returned surface
Image *RenderbufferStorage::getRenderTarget()
{
return NULL;
}
GLsizei RenderbufferStorage::getWidth() const GLsizei RenderbufferStorage::getWidth() const
{ {
return mWidth; return mWidth;
...@@ -369,8 +398,8 @@ Colorbuffer::~Colorbuffer() ...@@ -369,8 +398,8 @@ Colorbuffer::~Colorbuffer()
} }
} }
// Increments refcount on surface. // Increments refcount on image.
// caller must release() the returned surface // caller must release() the returned image
Image *Colorbuffer::getRenderTarget() Image *Colorbuffer::getRenderTarget()
{ {
if(mRenderTarget) if(mRenderTarget)
...@@ -381,6 +410,24 @@ Image *Colorbuffer::getRenderTarget() ...@@ -381,6 +410,24 @@ Image *Colorbuffer::getRenderTarget()
return mRenderTarget; return mRenderTarget;
} }
// Increments refcount on image.
// caller must release() the returned image
Image *Colorbuffer::createSharedImage()
{
if(mRenderTarget)
{
mRenderTarget->addRef();
mRenderTarget->markShared();
}
return mRenderTarget;
}
bool Colorbuffer::isShared() const
{
return mRenderTarget->isShared();
}
DepthStencilbuffer::DepthStencilbuffer(Image *depthStencil) : mDepthStencil(depthStencil) DepthStencilbuffer::DepthStencilbuffer(Image *depthStencil) : mDepthStencil(depthStencil)
{ {
if(depthStencil) if(depthStencil)
...@@ -429,8 +476,8 @@ DepthStencilbuffer::~DepthStencilbuffer() ...@@ -429,8 +476,8 @@ DepthStencilbuffer::~DepthStencilbuffer()
} }
} }
// Increments refcount on surface. // Increments refcount on image.
// caller must release() the returned surface // caller must release() the returned image
Image *DepthStencilbuffer::getRenderTarget() Image *DepthStencilbuffer::getRenderTarget()
{ {
if(mDepthStencil) if(mDepthStencil)
...@@ -441,6 +488,24 @@ Image *DepthStencilbuffer::getRenderTarget() ...@@ -441,6 +488,24 @@ Image *DepthStencilbuffer::getRenderTarget()
return mDepthStencil; return mDepthStencil;
} }
// Increments refcount on image.
// caller must release() the returned image
Image *DepthStencilbuffer::createSharedImage()
{
if(mDepthStencil)
{
mDepthStencil->addRef();
mDepthStencil->markShared();
}
return mDepthStencil;
}
bool DepthStencilbuffer::isShared() const
{
return mDepthStencil->isShared();
}
Depthbuffer::Depthbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil) Depthbuffer::Depthbuffer(Image *depthStencil) : DepthStencilbuffer(depthStencil)
{ {
if(depthStencil) if(depthStencil)
......
...@@ -42,6 +42,8 @@ public: ...@@ -42,6 +42,8 @@ public:
virtual void releaseProxy(const Renderbuffer *proxy); virtual void releaseProxy(const Renderbuffer *proxy);
virtual Image *getRenderTarget() = 0; virtual Image *getRenderTarget() = 0;
virtual Image *createSharedImage() = 0;
virtual bool isShared() const = 0;
virtual GLsizei getWidth() const = 0; virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0; virtual GLsizei getHeight() const = 0;
...@@ -67,7 +69,9 @@ public: ...@@ -67,7 +69,9 @@ public:
virtual void addProxyRef(const Renderbuffer *proxy); virtual void addProxyRef(const Renderbuffer *proxy);
virtual void releaseProxy(const Renderbuffer *proxy); virtual void releaseProxy(const Renderbuffer *proxy);
Image *getRenderTarget(); virtual Image *getRenderTarget();
virtual Image *createSharedImage();
virtual bool isShared() const;
virtual GLsizei getWidth() const; virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const; virtual GLsizei getHeight() const;
...@@ -89,7 +93,9 @@ public: ...@@ -89,7 +93,9 @@ public:
virtual void addProxyRef(const Renderbuffer *proxy); virtual void addProxyRef(const Renderbuffer *proxy);
virtual void releaseProxy(const Renderbuffer *proxy); virtual void releaseProxy(const Renderbuffer *proxy);
Image *getRenderTarget(); virtual Image *getRenderTarget();
virtual Image *createSharedImage();
virtual bool isShared() const;
virtual GLsizei getWidth() const; virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const; virtual GLsizei getHeight() const;
...@@ -112,7 +118,9 @@ public: ...@@ -112,7 +118,9 @@ public:
virtual ~RenderbufferStorage() = 0; virtual ~RenderbufferStorage() = 0;
virtual Image *getRenderTarget(); virtual Image *getRenderTarget() = 0;
virtual Image *createSharedImage() = 0;
virtual bool isShared() const = 0;
virtual GLsizei getWidth() const; virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const; virtual GLsizei getHeight() const;
...@@ -146,6 +154,8 @@ public: ...@@ -146,6 +154,8 @@ public:
virtual void release(); virtual void release();
Image *getRenderTarget(); Image *getRenderTarget();
virtual Image *createSharedImage();
virtual bool isShared() const;
GLsizei getWidth() const; GLsizei getWidth() const;
GLsizei getHeight() const; GLsizei getHeight() const;
...@@ -174,6 +184,8 @@ public: ...@@ -174,6 +184,8 @@ public:
virtual ~Colorbuffer(); virtual ~Colorbuffer();
virtual Image *getRenderTarget(); virtual Image *getRenderTarget();
virtual Image *createSharedImage();
virtual bool isShared() const;
private: private:
Image *mRenderTarget; Image *mRenderTarget;
...@@ -188,6 +200,8 @@ public: ...@@ -188,6 +200,8 @@ public:
~DepthStencilbuffer(); ~DepthStencilbuffer();
virtual Image *getRenderTarget(); virtual Image *getRenderTarget();
virtual Image *createSharedImage();
virtual bool isShared() const;
protected: protected:
Image *mDepthStencil; Image *mDepthStencil;
......
...@@ -163,7 +163,7 @@ GLfloat Texture::getMaxAnisotropy() const ...@@ -163,7 +163,7 @@ GLfloat Texture::getMaxAnisotropy() const
return mMaxAnisotropy; return mMaxAnisotropy;
} }
Image *Texture::getSharedImage(GLenum target, unsigned int level) Image *Texture::createSharedImage(GLenum target, unsigned int level)
{ {
Image *image = getRenderTarget(target, level); // Increments reference count Image *image = getRenderTarget(target, level); // Increments reference count
......
...@@ -86,7 +86,7 @@ public: ...@@ -86,7 +86,7 @@ public:
virtual Renderbuffer *getRenderbuffer(GLenum target) = 0; virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
virtual Image *getRenderTarget(GLenum target, unsigned int level) = 0; virtual Image *getRenderTarget(GLenum target, unsigned int level) = 0;
virtual Image *getSharedImage(GLenum target, unsigned int level); virtual Image *createSharedImage(GLenum target, unsigned int level);
virtual bool isShared(GLenum target, unsigned int level) const = 0; virtual bool isShared(GLenum target, unsigned int level) const = 0;
virtual void generateMipmaps() = 0; virtual void generateMipmaps() = 0;
......
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