Implemented API level of glFramebufferTextureLayer.
All functions should now be adapted to handle level
and layer, all the way to RenderbufferTexture3D,
where layer is still unimplemented.
Change-Id: Id5fe94f998ee517ae84cb0d6e60d535cc7891fe3
Reviewed-on: https://swiftshader-review.googlesource.com/3320
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
mStencilbufferPointer = NULL;
}
-Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
+Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const
{
Context *context = getContext();
Renderbuffer *buffer = NULL;
}
else if(IsTextureTarget(type))
{
- buffer = context->getTexture(handle)->getRenderbuffer(type);
+ buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer);
}
else
{
return buffer;
}
-void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index)
+void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level, GLint layer)
{
mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
- mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer);
+ mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer, level, layer);
}
-void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
+void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level, GLint layer)
{
mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
- mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer);
+ mDepthbufferPointer = lookupRenderbuffer(type, depthbuffer, level, layer);
}
-void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
+void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level, GLint layer)
{
mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
- mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer);
+ mStencilbufferPointer = lookupRenderbuffer(type, stencilbuffer, level, layer);
}
void Framebuffer::detachTexture(GLuint texture)
\r
virtual ~Framebuffer();\r
\r
- void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index);\r
- void setDepthbuffer(GLenum type, GLuint depthbuffer);\r
- void setStencilbuffer(GLenum type, GLuint stencilbuffer);\r
+ void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level = 0, GLint layer = 0);\r
+ void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level = 0, GLint layer = 0);\r
+ void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0);\r
\r
void detachTexture(GLuint texture);\r
void detachRenderbuffer(GLuint renderbuffer);\r
gl::BindingPointer<Renderbuffer> mStencilbufferPointer;\r
\r
private:\r
- Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;\r
+ Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const;\r
};\r
\r
class DefaultFramebuffer : public Framebuffer\r
///// RenderbufferTexture2D Implementation ////////
-RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
+RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLint level) : mLevel(level)
{
mTexture2D = texture;
}
// caller must release() the returned image
egl::Image *RenderbufferTexture2D::getRenderTarget()
{
- return mTexture2D->getRenderTarget(GL_TEXTURE_2D, 0);
+ return mTexture2D->getRenderTarget(GL_TEXTURE_2D, mLevel);
}
// Increments refcount on image.
// caller must release() the returned image
egl::Image *RenderbufferTexture2D::createSharedImage()
{
- return mTexture2D->createSharedImage(GL_TEXTURE_2D, 0);
+ return mTexture2D->createSharedImage(GL_TEXTURE_2D, mLevel);
}
bool RenderbufferTexture2D::isShared() const
{
- return mTexture2D->isShared(GL_TEXTURE_2D, 0);
+ return mTexture2D->isShared(GL_TEXTURE_2D, mLevel);
}
GLsizei RenderbufferTexture2D::getWidth() const
{
- return mTexture2D->getWidth(GL_TEXTURE_2D, 0);
+ return mTexture2D->getWidth(GL_TEXTURE_2D, mLevel);
}
GLsizei RenderbufferTexture2D::getHeight() const
{
- return mTexture2D->getHeight(GL_TEXTURE_2D, 0);
+ return mTexture2D->getHeight(GL_TEXTURE_2D, mLevel);
}
GLenum RenderbufferTexture2D::getFormat() const
{
- return mTexture2D->getFormat(GL_TEXTURE_2D, 0);
+ return mTexture2D->getFormat(GL_TEXTURE_2D, mLevel);
}
sw::Format RenderbufferTexture2D::getInternalFormat() const
{
- return mTexture2D->getInternalFormat(GL_TEXTURE_2D, 0);
+ return mTexture2D->getInternalFormat(GL_TEXTURE_2D, mLevel);
}
GLsizei RenderbufferTexture2D::getSamples() const
///// RenderbufferTexture3D Implementation ////////
-RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture)
+RenderbufferTexture3D::RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer) : mLevel(level), mLayer(layer)
{
mTexture3D = texture;
+ if(mLayer != 0)
+ {
+ UNIMPLEMENTED();
+ }
}
RenderbufferTexture3D::~RenderbufferTexture3D()
// caller must release() the returned image
egl::Image *RenderbufferTexture3D::getRenderTarget()
{
- return mTexture3D->getRenderTarget(mTexture3D->getTarget(), 0);
+ return mTexture3D->getRenderTarget(mTexture3D->getTarget(), mLevel);
}
// Increments refcount on image.
// caller must release() the returned image
egl::Image *RenderbufferTexture3D::createSharedImage()
{
- return mTexture3D->createSharedImage(mTexture3D->getTarget(), 0);
+ return mTexture3D->createSharedImage(mTexture3D->getTarget(), mLevel);
}
bool RenderbufferTexture3D::isShared() const
{
- return mTexture3D->isShared(mTexture3D->getTarget(), 0);
+ return mTexture3D->isShared(mTexture3D->getTarget(), mLevel);
}
GLsizei RenderbufferTexture3D::getWidth() const
{
- return mTexture3D->getWidth(mTexture3D->getTarget(), 0);
+ return mTexture3D->getWidth(mTexture3D->getTarget(), mLevel);
}
GLsizei RenderbufferTexture3D::getHeight() const
{
- return mTexture3D->getHeight(mTexture3D->getTarget(), 0);
+ return mTexture3D->getHeight(mTexture3D->getTarget(), mLevel);
}
GLenum RenderbufferTexture3D::getFormat() const
{
- return mTexture3D->getFormat(mTexture3D->getTarget(), 0);
+ return mTexture3D->getFormat(mTexture3D->getTarget(), mLevel);
}
sw::Format RenderbufferTexture3D::getInternalFormat() const
{
- return mTexture3D->getInternalFormat(mTexture3D->getTarget(), 0);
+ return mTexture3D->getInternalFormat(mTexture3D->getTarget(), mLevel);
}
GLsizei RenderbufferTexture3D::getSamples() const
///// RenderbufferTextureCubeMap Implementation ////////
-RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target)
+RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level) : mTarget(target), mLevel(level)
{
mTextureCubeMap = texture;
}
// caller must release() the returned image
egl::Image *RenderbufferTextureCubeMap::getRenderTarget()
{
- return mTextureCubeMap->getRenderTarget(mTarget, 0);
+ return mTextureCubeMap->getRenderTarget(mTarget, mLevel);
}
// Increments refcount on image.
// caller must release() the returned image
egl::Image *RenderbufferTextureCubeMap::createSharedImage()
{
- return mTextureCubeMap->createSharedImage(mTarget, 0);
+ return mTextureCubeMap->createSharedImage(mTarget, mLevel);
}
bool RenderbufferTextureCubeMap::isShared() const
{
- return mTextureCubeMap->isShared(mTarget, 0);
+ return mTextureCubeMap->isShared(mTarget, mLevel);
}
GLsizei RenderbufferTextureCubeMap::getWidth() const
{
- return mTextureCubeMap->getWidth(mTarget, 0);
+ return mTextureCubeMap->getWidth(mTarget, mLevel);
}
GLsizei RenderbufferTextureCubeMap::getHeight() const
{
- return mTextureCubeMap->getHeight(mTarget, 0);
+ return mTextureCubeMap->getHeight(mTarget, mLevel);
}
GLenum RenderbufferTextureCubeMap::getFormat() const
{
- return mTextureCubeMap->getFormat(mTarget, 0);
+ return mTextureCubeMap->getFormat(mTarget, mLevel);
}
sw::Format RenderbufferTextureCubeMap::getInternalFormat() const
{
- return mTextureCubeMap->getInternalFormat(mTarget, 0);
+ return mTextureCubeMap->getInternalFormat(mTarget, mLevel);
}
GLsizei RenderbufferTextureCubeMap::getSamples() const
class RenderbufferTexture2D : public RenderbufferInterface\r
{\r
public:\r
- RenderbufferTexture2D(Texture2D *texture);\r
+ RenderbufferTexture2D(Texture2D *texture, GLint level);\r
\r
virtual ~RenderbufferTexture2D();\r
\r
\r
private:\r
gl::BindingPointer<Texture2D> mTexture2D;\r
+ GLint mLevel;\r
};\r
\r
class RenderbufferTexture3D : public RenderbufferInterface\r
{\r
public:\r
- RenderbufferTexture3D(Texture3D *texture);\r
+ RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer);\r
\r
virtual ~RenderbufferTexture3D();\r
\r
\r
private:\r
gl::BindingPointer<Texture3D> mTexture3D;\r
+ GLint mLevel;\r
+ GLint mLayer;\r
};\r
\r
class RenderbufferTextureCubeMap : public RenderbufferInterface\r
{\r
public:\r
- RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target);\r
+ RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level);\r
\r
virtual ~RenderbufferTextureCubeMap();\r
\r
private:\r
gl::BindingPointer<TextureCubeMap> mTextureCubeMap;\r
GLenum mTarget;\r
+ GLint mLevel;\r
};\r
\r
// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage\r
return image[level];\r
}\r
\r
-Renderbuffer *Texture2D::getRenderbuffer(GLenum target)\r
+Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level, GLint layer)\r
{\r
if(target != GL_TEXTURE_2D)\r
{\r
\r
if(mColorbufferProxy == NULL)\r
{\r
- mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));\r
+ mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this, level));\r
}\r
\r
return mColorbufferProxy;\r
}\r
}\r
\r
-Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)\r
+Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level, GLint layer)\r
{\r
if(!IsCubemapTextureTarget(target))\r
{\r
\r
if(mFaceProxies[face] == NULL)\r
{\r
- mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target));\r
+ mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target, level));\r
}\r
\r
return mFaceProxies[face];\r
return image[level];\r
}\r
\r
-Renderbuffer *Texture3D::getRenderbuffer(GLenum target)\r
+Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level, GLint layer)\r
{\r
if(target != getTarget())\r
{\r
\r
if(mColorbufferProxy == NULL)\r
{\r
- mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this));\r
+ mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level, layer));\r
}\r
\r
return mColorbufferProxy;\r
virtual bool isCompressed(GLenum target, GLint level) const = 0;\r
virtual bool isDepth(GLenum target, GLint level) const = 0;\r
\r
- virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;\r
+ virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer) = 0;\r
virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0;\r
virtual egl::Image *createSharedImage(GLenum target, unsigned int level);\r
virtual bool isShared(GLenum target, unsigned int level) const = 0;\r
\r
virtual void generateMipmaps();\r
\r
- virtual Renderbuffer *getRenderbuffer(GLenum target);\r
+ virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);\r
virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);\r
virtual bool isShared(GLenum target, unsigned int level) const;\r
\r
\r
virtual void generateMipmaps();\r
\r
- virtual Renderbuffer *getRenderbuffer(GLenum target);\r
+ virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);\r
virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);\r
virtual bool isShared(GLenum target, unsigned int level) const;\r
\r
\r
virtual void generateMipmaps();\r
\r
- virtual Renderbuffer *getRenderbuffer(GLenum target);\r
+ virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer);\r
virtual egl::Image *getRenderTarget(GLenum target, unsigned int level);\r
virtual bool isShared(GLenum target, unsigned int level) const;\r
\r
return error(GL_INVALID_ENUM);\r
}\r
\r
- if(level != 0)\r
+ if((level != 0) && (context->getClientVersion() < 3))\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+\r
+ if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))\r
{\r
return error(GL_INVALID_VALUE);\r
}\r
{\r
return error(GL_INVALID_ENUM);\r
}\r
- framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);\r
+ framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);\r
break;\r
- case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;\r
- case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;\r
+ case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level); break;\r
+ case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;\r
}\r
}\r
}\r
TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %d, GLint level = %d, GLint layer = %d)",\r
target, attachment, texture, level, layer);\r
\r
- switch(target)\r
+ if(texture != 0 && layer < 0 || level < 0)\r
{\r
- case GL_DRAW_FRAMEBUFFER:\r
- case GL_READ_FRAMEBUFFER:\r
- case GL_FRAMEBUFFER:\r
- break;\r
- default:\r
- return error(GL_INVALID_ENUM);\r
+ return error(GL_INVALID_VALUE);\r
}\r
\r
- switch(attachment)\r
- {\r
- case GL_COLOR_ATTACHMENT0:\r
- case GL_COLOR_ATTACHMENT1:\r
- case GL_COLOR_ATTACHMENT2:\r
- case GL_COLOR_ATTACHMENT3:\r
- case GL_COLOR_ATTACHMENT4:\r
- case GL_COLOR_ATTACHMENT5:\r
- case GL_COLOR_ATTACHMENT6:\r
- case GL_COLOR_ATTACHMENT7:\r
- case GL_COLOR_ATTACHMENT8:\r
- case GL_COLOR_ATTACHMENT9:\r
- case GL_COLOR_ATTACHMENT10:\r
- case GL_COLOR_ATTACHMENT11:\r
- case GL_COLOR_ATTACHMENT12:\r
- case GL_COLOR_ATTACHMENT13:\r
- case GL_COLOR_ATTACHMENT14:\r
- case GL_COLOR_ATTACHMENT15:\r
- case GL_DEPTH_ATTACHMENT:\r
- case GL_STENCIL_ATTACHMENT:\r
- case GL_DEPTH_STENCIL_ATTACHMENT:\r
- break;\r
- default:\r
- return error(GL_INVALID_ENUM);\r
- }\r
+ es2::Context *context = es2::getContext();\r
\r
- UNIMPLEMENTED();\r
+ if(context)\r
+ {\r
+ Texture* textureObject = context->getTexture(texture);\r
+ if(texture != 0)\r
+ {\r
+ if(!textureObject)\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+\r
+ switch(textureObject->getTarget())\r
+ {\r
+ case GL_TEXTURE_3D:\r
+ case GL_TEXTURE_2D_ARRAY:\r
+ if(layer >= es2::IMPLEMENTATION_MAX_TEXTURE_SIZE || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))\r
+ {\r
+ return error(GL_INVALID_VALUE);\r
+ }\r
+ break;\r
+ default:\r
+ return error(GL_INVALID_OPERATION);\r
+ }\r
+\r
+ if(textureObject->isCompressed(target, level))\r
+ {\r
+ return error(GL_INVALID_OPERATION);\r
+ }\r
+ }\r
+\r
+ es2::Framebuffer *framebuffer = nullptr;\r
+ switch(target)\r
+ {\r
+ case GL_DRAW_FRAMEBUFFER:\r
+ case GL_FRAMEBUFFER:\r
+ framebuffer = context->getDrawFramebuffer();\r
+ break;\r
+ case GL_READ_FRAMEBUFFER:\r
+ framebuffer = context->getReadFramebuffer();\r
+ break;\r
+ default:\r
+ return error(GL_INVALID_ENUM);\r
+ }\r
+\r
+ switch(attachment)\r
+ {\r
+ case GL_COLOR_ATTACHMENT0:\r
+ case GL_COLOR_ATTACHMENT1:\r
+ case GL_COLOR_ATTACHMENT2:\r
+ case GL_COLOR_ATTACHMENT3:\r
+ case GL_COLOR_ATTACHMENT4:\r
+ case GL_COLOR_ATTACHMENT5:\r
+ case GL_COLOR_ATTACHMENT6:\r
+ case GL_COLOR_ATTACHMENT7:\r
+ case GL_COLOR_ATTACHMENT8:\r
+ case GL_COLOR_ATTACHMENT9:\r
+ case GL_COLOR_ATTACHMENT10:\r
+ case GL_COLOR_ATTACHMENT11:\r
+ case GL_COLOR_ATTACHMENT12:\r
+ case GL_COLOR_ATTACHMENT13:\r
+ case GL_COLOR_ATTACHMENT14:\r
+ case GL_COLOR_ATTACHMENT15:\r
+ if(!framebuffer || framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0) == 0)\r
+ {\r
+ return error(GL_INVALID_OPERATION);\r
+ }\r
+ framebuffer->setColorbuffer(target, texture, attachment - GL_COLOR_ATTACHMENT0, layer, level);\r
+ break;\r
+ case GL_DEPTH_ATTACHMENT:\r
+ if(!framebuffer || framebuffer->getDepthbufferName() == 0)\r
+ {\r
+ return error(GL_INVALID_OPERATION);\r
+ }\r
+ framebuffer->setDepthbuffer(target, texture, layer, level);\r
+ break;\r
+ case GL_STENCIL_ATTACHMENT:\r
+ if(!framebuffer || framebuffer->getStencilbufferName() == 0)\r
+ {\r
+ return error(GL_INVALID_OPERATION);\r
+ }\r
+ framebuffer->setStencilbuffer(target, texture, layer, level);\r
+ break;\r
+ case GL_DEPTH_STENCIL_ATTACHMENT:\r
+ if(!framebuffer || framebuffer->getDepthbufferName() == 0 || framebuffer->getStencilbufferName() == 0)\r
+ {\r
+ return error(GL_INVALID_OPERATION);\r
+ }\r
+ framebuffer->setDepthbuffer(target, texture, layer, level);\r
+ framebuffer->setStencilbuffer(target, texture, layer, level);\r
+ break;\r
+ default:\r
+ return error(GL_INVALID_ENUM);\r
+ }\r
+ }\r
}\r
\r
GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)\r
\r
bool IsTextureTarget(GLenum target)\r
{\r
- return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target);\r
+ return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY;\r
}\r
\r
// Verify that format/type are one of the combinations from table 3.4.\r