Commit 8af50078 by Alexis Hetu Committed by Alexis Hétu

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/3320Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 3aa46cbd
......@@ -42,7 +42,7 @@ Framebuffer::~Framebuffer()
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 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
}
else if(IsTextureTarget(type))
{
buffer = context->getTexture(handle)->getRenderbuffer(type);
buffer = context->getTexture(handle)->getRenderbuffer(type, level, layer);
}
else
{
......@@ -67,22 +67,22 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
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)
......
......@@ -35,9 +35,9 @@ public:
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 @@ protected:
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
......
......@@ -68,7 +68,7 @@ GLuint RenderbufferInterface::getStencilSize() const
///// RenderbufferTexture2D Implementation ////////
RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture)
RenderbufferTexture2D::RenderbufferTexture2D(Texture2D *texture, GLint level) : mLevel(level)
{
mTexture2D = texture;
}
......@@ -94,39 +94,39 @@ void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
// 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 @@ 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()
......@@ -162,39 +166,39 @@ void RenderbufferTexture3D::releaseProxy(const Renderbuffer *proxy)
// 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 @@ 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;
}
......@@ -230,39 +234,39 @@ void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
// 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
......
......@@ -62,7 +62,7 @@ public:
class RenderbufferTexture2D : public RenderbufferInterface
{
public:
RenderbufferTexture2D(Texture2D *texture);
RenderbufferTexture2D(Texture2D *texture, GLint level);
virtual ~RenderbufferTexture2D();
......@@ -81,12 +81,13 @@ public:
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 @@ public:
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 @@ public:
private:
gl::BindingPointer<TextureCubeMap> mTextureCubeMap;
GLenum mTarget;
GLint mLevel;
};
// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
......
......@@ -895,7 +895,7 @@ egl::Image *Texture2D::getImage(unsigned int level)
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 @@ Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
if(mColorbufferProxy == NULL)
{
mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this));
mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture2D(this, level));
}
return mColorbufferProxy;
......@@ -1348,7 +1348,7 @@ void TextureCubeMap::generateMipmaps()
}
}
Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level, GLint layer)
{
if(!IsCubemapTextureTarget(target))
{
......@@ -1359,7 +1359,7 @@ Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
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 @@ egl::Image *Texture3D::getImage(unsigned int level)
return image[level];
}
Renderbuffer *Texture3D::getRenderbuffer(GLenum target)
Renderbuffer *Texture3D::getRenderbuffer(GLenum target, GLint level, GLint layer)
{
if(target != getTarget())
{
......@@ -1810,7 +1810,7 @@ Renderbuffer *Texture3D::getRenderbuffer(GLenum target)
if(mColorbufferProxy == NULL)
{
mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this));
mColorbufferProxy = new Renderbuffer(name, new RenderbufferTexture3D(this, level, layer));
}
return mColorbufferProxy;
......
......@@ -112,7 +112,7 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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;
......
......@@ -2305,7 +2305,12 @@ void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GL
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 @@ void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GL
{
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;
}
}
}
......
......@@ -1484,43 +1484,106 @@ GL_APICALL void GL_APIENTRY glFramebufferTextureLayer(GLenum target, GLenum atta
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)
......
......@@ -294,7 +294,7 @@ namespace es2
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.
......
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