glFramebufferTextureLayer API implementation 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>
diff --git a/src/OpenGL/libGLESv2/Framebuffer.cpp b/src/OpenGL/libGLESv2/Framebuffer.cpp index c6c30fb..451263d 100644 --- a/src/OpenGL/libGLESv2/Framebuffer.cpp +++ b/src/OpenGL/libGLESv2/Framebuffer.cpp
@@ -42,7 +42,7 @@ 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; @@ -57,7 +57,7 @@ } else if(IsTextureTarget(type)) { - buffer = context->getTexture(handle)->getRenderbuffer(type); + buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer); } else { @@ -67,22 +67,22 @@ 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)
diff --git a/src/OpenGL/libGLESv2/Framebuffer.h b/src/OpenGL/libGLESv2/Framebuffer.h index b423e63..8db2ad7 100644 --- a/src/OpenGL/libGLESv2/Framebuffer.h +++ b/src/OpenGL/libGLESv2/Framebuffer.h
@@ -35,9 +35,9 @@ virtual ~Framebuffer(); - void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index); - void setDepthbuffer(GLenum type, GLuint depthbuffer); - void setStencilbuffer(GLenum type, GLuint stencilbuffer); + void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index, GLint level = 0, GLint layer = 0); + void setDepthbuffer(GLenum type, GLuint depthbuffer, GLint level = 0, GLint layer = 0); + void setStencilbuffer(GLenum type, GLuint stencilbuffer, GLint level = 0, GLint layer = 0); void detachTexture(GLuint texture); void detachRenderbuffer(GLuint renderbuffer); @@ -78,7 +78,7 @@ gl::BindingPointer<Renderbuffer> mStencilbufferPointer; private: - Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const; + Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle, GLint level, GLint layer) const; }; class DefaultFramebuffer : public Framebuffer
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.cpp b/src/OpenGL/libGLESv2/Renderbuffer.cpp index 2fae03f..3d8cc3e 100644 --- a/src/OpenGL/libGLESv2/Renderbuffer.cpp +++ b/src/OpenGL/libGLESv2/Renderbuffer.cpp
@@ -68,7 +68,7 @@ ///// RenderbufferTexture2D Implementation //////// -RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture) +RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLint level) : mLevel(level) { mTexture2D = texture; } @@ -94,39 +94,39 @@ // 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 @@ -136,9 +136,13 @@ ///// 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() @@ -162,39 +166,39 @@ // 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 @@ -204,7 +208,7 @@ ///// RenderbufferTextureCubeMap Implementation //////// -RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target) +RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level) : mTarget(target), mLevel(level) { mTextureCubeMap = texture; } @@ -230,39 +234,39 @@ // 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
diff --git a/src/OpenGL/libGLESv2/Renderbuffer.h b/src/OpenGL/libGLESv2/Renderbuffer.h index 1ab0908..0bea04f 100644 --- a/src/OpenGL/libGLESv2/Renderbuffer.h +++ b/src/OpenGL/libGLESv2/Renderbuffer.h
@@ -62,7 +62,7 @@ class RenderbufferTexture2D : public RenderbufferInterface { public: - RenderbufferTexture2D(Texture2D *texture); + RenderbufferTexture2D(Texture2D *texture, GLint level); virtual ~RenderbufferTexture2D(); @@ -81,12 +81,13 @@ private: gl::BindingPointer<Texture2D> mTexture2D; + GLint mLevel; }; class RenderbufferTexture3D : public RenderbufferInterface { public: - RenderbufferTexture3D(Texture3D *texture); + RenderbufferTexture3D(Texture3D *texture, GLint level, GLint layer); virtual ~RenderbufferTexture3D(); @@ -105,12 +106,14 @@ private: gl::BindingPointer<Texture3D> mTexture3D; + GLint mLevel; + GLint mLayer; }; class RenderbufferTextureCubeMap : public RenderbufferInterface { public: - RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target); + RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target, GLint level); virtual ~RenderbufferTextureCubeMap(); @@ -130,6 +133,7 @@ private: gl::BindingPointer<TextureCubeMap> mTextureCubeMap; GLenum mTarget; + GLint mLevel; }; // A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
diff --git a/src/OpenGL/libGLESv2/Texture.cpp b/src/OpenGL/libGLESv2/Texture.cpp index 9c4ebce..6f686b8 100644 --- a/src/OpenGL/libGLESv2/Texture.cpp +++ b/src/OpenGL/libGLESv2/Texture.cpp
@@ -895,7 +895,7 @@ return image[level]; } -Renderbuffer *Texture2D::getRenderbuffer(GLenum target) +Renderbuffer *Texture2D::getRenderbuffer(GLenum target, GLint level, GLint layer) { if(target != GL_TEXTURE_2D) { @@ -904,7 +904,7 @@ if(mColorbufferProxy == NULL) { - mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this)); + mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this, level)); } return mColorbufferProxy; @@ -1348,7 +1348,7 @@ } } -Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target) +Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level, GLint layer) { if(!IsCubemapTextureTarget(target)) { @@ -1359,7 +1359,7 @@ if(mFaceProxies[face] == NULL) { - mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target)); + mFaceProxies[face] = new Renderbuffer(name, new RenderbufferTextureCubeMap(this, target, level)); } return mFaceProxies[face]; @@ -1801,7 +1801,7 @@ return image[level]; } -Renderbuffer *Texture3D::getRenderbuffer(GLenum target) +Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level, GLint layer) { if(target != getTarget()) { @@ -1810,7 +1810,7 @@ if(mColorbufferProxy == NULL) { - mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this)); + mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level, layer)); } return mColorbufferProxy;
diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h index 1e4cae0..d2207e4 100644 --- a/src/OpenGL/libGLESv2/Texture.h +++ b/src/OpenGL/libGLESv2/Texture.h
@@ -112,7 +112,7 @@ virtual bool isCompressed(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, GLint level, GLint layer) = 0; virtual egl::Image *getRenderTarget(GLenum target, unsigned int level) = 0; virtual egl::Image *createSharedImage(GLenum target, unsigned int level); virtual bool isShared(GLenum target, unsigned int level) const = 0; @@ -187,7 +187,7 @@ virtual void generateMipmaps(); - virtual Renderbuffer *getRenderbuffer(GLenum target); + virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer); virtual egl::Image *getRenderTarget(GLenum target, unsigned int level); virtual bool isShared(GLenum target, unsigned int level) const; @@ -243,7 +243,7 @@ virtual void generateMipmaps(); - virtual Renderbuffer *getRenderbuffer(GLenum target); + virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer); virtual egl::Image *getRenderTarget(GLenum target, unsigned int level); virtual bool isShared(GLenum target, unsigned int level) const; @@ -304,7 +304,7 @@ virtual void generateMipmaps(); - virtual Renderbuffer *getRenderbuffer(GLenum target); + virtual Renderbuffer *getRenderbuffer(GLenum target, GLint level, GLint layer); virtual egl::Image *getRenderTarget(GLenum target, unsigned int level); virtual bool isShared(GLenum target, unsigned int level) const;
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp index e458c43..5bb662f 100644 --- a/src/OpenGL/libGLESv2/libGLESv2.cpp +++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -2305,7 +2305,12 @@ return error(GL_INVALID_ENUM); } - if(level != 0) + if((level != 0) && (context->getClientVersion() < 3)) + { + return error(GL_INVALID_VALUE); + } + + if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) { return error(GL_INVALID_VALUE); } @@ -2358,10 +2363,10 @@ { return error(GL_INVALID_ENUM); } - framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0); + framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level); break; - case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break; - case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break; + case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level); break; + case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break; } } }
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp index fb61088..3e1aafd 100644 --- a/src/OpenGL/libGLESv2/libGLESv3.cpp +++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1484,43 +1484,106 @@ TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %d, GLint level = %d, GLint layer = %d)", target, attachment, texture, level, layer); - switch(target) + if(texture != 0 && layer < 0 || level < 0) { - case GL_DRAW_FRAMEBUFFER: - case GL_READ_FRAMEBUFFER: - case GL_FRAMEBUFFER: - break; - default: - return error(GL_INVALID_ENUM); + return error(GL_INVALID_VALUE); } - switch(attachment) - { - case GL_COLOR_ATTACHMENT0: - case GL_COLOR_ATTACHMENT1: - case GL_COLOR_ATTACHMENT2: - case GL_COLOR_ATTACHMENT3: - case GL_COLOR_ATTACHMENT4: - case GL_COLOR_ATTACHMENT5: - case GL_COLOR_ATTACHMENT6: - case GL_COLOR_ATTACHMENT7: - case GL_COLOR_ATTACHMENT8: - case GL_COLOR_ATTACHMENT9: - case GL_COLOR_ATTACHMENT10: - case GL_COLOR_ATTACHMENT11: - case GL_COLOR_ATTACHMENT12: - case GL_COLOR_ATTACHMENT13: - case GL_COLOR_ATTACHMENT14: - case GL_COLOR_ATTACHMENT15: - case GL_DEPTH_ATTACHMENT: - case GL_STENCIL_ATTACHMENT: - case GL_DEPTH_STENCIL_ATTACHMENT: - break; - default: - return error(GL_INVALID_ENUM); - } + es2::Context *context = es2::getContext(); - UNIMPLEMENTED(); + if(context) + { + Texture* textureObject = context->getTexture(texture); + if(texture != 0) + { + if(!textureObject) + { + return error(GL_INVALID_VALUE); + } + + switch(textureObject->getTarget()) + { + case GL_TEXTURE_3D: + case GL_TEXTURE_2D_ARRAY: + if(layer >= es2::IMPLEMENTATION_MAX_TEXTURE_SIZE || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) + { + return error(GL_INVALID_VALUE); + } + break; + default: + return error(GL_INVALID_OPERATION); + } + + if(textureObject->isCompressed(target, level)) + { + return error(GL_INVALID_OPERATION); + } + } + + es2::Framebuffer *framebuffer = nullptr; + switch(target) + { + case GL_DRAW_FRAMEBUFFER: + case GL_FRAMEBUFFER: + framebuffer = context->getDrawFramebuffer(); + break; + case GL_READ_FRAMEBUFFER: + framebuffer = context->getReadFramebuffer(); + break; + default: + return error(GL_INVALID_ENUM); + } + + switch(attachment) + { + case GL_COLOR_ATTACHMENT0: + case GL_COLOR_ATTACHMENT1: + case GL_COLOR_ATTACHMENT2: + case GL_COLOR_ATTACHMENT3: + case GL_COLOR_ATTACHMENT4: + case GL_COLOR_ATTACHMENT5: + case GL_COLOR_ATTACHMENT6: + case GL_COLOR_ATTACHMENT7: + case GL_COLOR_ATTACHMENT8: + case GL_COLOR_ATTACHMENT9: + case GL_COLOR_ATTACHMENT10: + case GL_COLOR_ATTACHMENT11: + case GL_COLOR_ATTACHMENT12: + case GL_COLOR_ATTACHMENT13: + case GL_COLOR_ATTACHMENT14: + case GL_COLOR_ATTACHMENT15: + if(!framebuffer || framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0) == 0) + { + return error(GL_INVALID_OPERATION); + } + framebuffer->setColorbuffer(target, texture, attachment - GL_COLOR_ATTACHMENT0, layer, level); + break; + case GL_DEPTH_ATTACHMENT: + if(!framebuffer || framebuffer->getDepthbufferName() == 0) + { + return error(GL_INVALID_OPERATION); + } + framebuffer->setDepthbuffer(target, texture, layer, level); + break; + case GL_STENCIL_ATTACHMENT: + if(!framebuffer || framebuffer->getStencilbufferName() == 0) + { + return error(GL_INVALID_OPERATION); + } + framebuffer->setStencilbuffer(target, texture, layer, level); + break; + case GL_DEPTH_STENCIL_ATTACHMENT: + if(!framebuffer || framebuffer->getDepthbufferName() == 0 || framebuffer->getStencilbufferName() == 0) + { + return error(GL_INVALID_OPERATION); + } + framebuffer->setDepthbuffer(target, texture, layer, level); + framebuffer->setStencilbuffer(target, texture, layer, level); + break; + default: + return error(GL_INVALID_ENUM); + } + } } GL_APICALL void *GL_APIENTRY glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access)
diff --git a/src/OpenGL/libGLESv2/utilities.cpp b/src/OpenGL/libGLESv2/utilities.cpp index 4f63086..e9b7e78 100644 --- a/src/OpenGL/libGLESv2/utilities.cpp +++ b/src/OpenGL/libGLESv2/utilities.cpp
@@ -294,7 +294,7 @@ bool IsTextureTarget(GLenum target) { - return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target); + return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target) || target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY; } // Verify that format/type are one of the combinations from table 3.4.