Commit 1b2f628a by Alexis Hetu Committed by Alexis Hétu

Multiple color attachments

Adding multiple color attachments to Framebuffer objects. This cl allows setting multiple draw buffers, but there is currently no code exercising that path. These will connected properly to a shader's multiple outputs later. Change-Id: I41d4eadc4518d0b9c1468802c32e622df591e860 Reviewed-on: https://swiftshader-review.googlesource.com/2881Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 5a01c18c
......@@ -68,6 +68,7 @@ enum
{
OUTLINE_RESOLUTION = 4096, // Maximum vertical resolution of the render target
MIPMAP_LEVELS = 14,
MAX_COLOR_ATTACHMENTS = 8,
TEXTURE_IMAGE_UNITS = 16,
VERTEX_TEXTURE_IMAGE_UNITS = 4,
TOTAL_IMAGE_UNITS = TEXTURE_IMAGE_UNITS + VERTEX_TEXTURE_IMAGE_UNITS,
......
......@@ -152,6 +152,12 @@ Context::Context(const egl::Config *config, const Context *shareContext, EGLint
bindRenderbuffer(0);
bindTransformFeedback(0);
mState.readFramebufferColorIndex = 0;
for(int i = 0; i < MAX_COLOR_ATTACHMENTS; ++i)
{
mState.drawFramebufferColorIndices[i] = GL_NONE;
}
mState.currentProgram = 0;
mState.packAlignment = 4;
......@@ -716,6 +722,24 @@ GLuint Context::getRenderbufferName() const
return mState.renderbuffer.name();
}
void Context::setReadFramebufferColorIndex(GLuint index)
{
mState.readFramebufferColorIndex = index;
}
void Context::setDrawFramebufferColorIndices(GLsizei n, const GLenum *bufs)
{
for(int i = 0; i < n; ++i)
{
mState.drawFramebufferColorIndices[i] = ((bufs[i] == GL_BACK) || (bufs[i] == GL_NONE)) ? bufs[i] : i;
}
}
GLuint Context::getReadFramebufferColorIndex() const
{
return mState.readFramebufferColorIndex;
}
GLuint Context::getArrayBufferName() const
{
return mState.arrayBuffer.name();
......@@ -1829,7 +1853,7 @@ template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
case GL_ALPHA_BITS:
{
Framebuffer *framebuffer = getDrawFramebuffer();
Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
if(colorbuffer)
{
......@@ -2467,7 +2491,7 @@ bool Context::applyRenderTarget()
return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
}
egl::Image *renderTarget = framebuffer->getRenderTarget();
egl::Image *renderTarget = framebuffer->getRenderTarget(0);
device->setRenderTarget(renderTarget);
if(renderTarget) renderTarget->release();
......@@ -2997,7 +3021,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
}
}
egl::Image *renderTarget = framebuffer->getRenderTarget();
egl::Image *renderTarget = framebuffer->getRenderTarget(0);
if(!renderTarget)
{
......@@ -3849,10 +3873,10 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if(mask & GL_COLOR_BUFFER_BIT)
{
const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
const bool validReadType = readFramebuffer->getColorbufferType(getReadFramebufferColorIndex()) == GL_TEXTURE_2D ||
readFramebuffer->getColorbufferType(getReadFramebufferColorIndex()) == GL_RENDERBUFFER;
const bool validDrawType = drawFramebuffer->getColorbufferType(0) == GL_TEXTURE_2D ||
drawFramebuffer->getColorbufferType(0) == GL_RENDERBUFFER;
if(!validReadType || !validDrawType)
{
return error(GL_INVALID_OPERATION);
......@@ -3921,8 +3945,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
{
if(blitRenderTarget)
{
egl::Image *readRenderTarget = readFramebuffer->getRenderTarget();
egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
if(flipX)
{
......
......@@ -334,6 +334,8 @@ struct State
GLuint readFramebuffer;
GLuint drawFramebuffer;
GLuint readFramebufferColorIndex;
GLuint drawFramebufferColorIndices[MAX_COLOR_ATTACHMENTS];
gl::BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
GLuint vertexArray;
......@@ -427,6 +429,10 @@ public:
GLuint getDrawFramebufferName() const;
GLuint getRenderbufferName() const;
void setReadFramebufferColorIndex(GLuint index);
void setDrawFramebufferColorIndices(GLsizei n, const GLenum *bufs);
GLuint getReadFramebufferColorIndex() const;
GLuint getActiveQuery(GLenum target) const;
GLuint getArrayBufferName() const;
......
......@@ -24,14 +24,20 @@ namespace es2
Framebuffer::Framebuffer()
{
mColorbufferType = GL_NONE;
for(int i = 0; i < IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; ++i)
{
mColorbufferType[i] = GL_NONE;
}
mDepthbufferType = GL_NONE;
mStencilbufferType = GL_NONE;
}
Framebuffer::~Framebuffer()
{
mColorbufferPointer = NULL;
for(int i = 0; i < IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; ++i)
{
mColorbufferPointer[i] = NULL;
}
mDepthbufferPointer = NULL;
mStencilbufferPointer = NULL;
}
......@@ -61,10 +67,10 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
return buffer;
}
void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index)
{
mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
mColorbufferPointer = lookupRenderbuffer(type, colorbuffer);
mColorbufferType[index] = (colorbuffer != 0) ? type : GL_NONE;
mColorbufferPointer[index] = lookupRenderbuffer(type, colorbuffer);
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
......@@ -81,10 +87,13 @@ void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
void Framebuffer::detachTexture(GLuint texture)
{
if(mColorbufferPointer.name() == texture && IsTextureTarget(mColorbufferType))
for(int i = 0; i < IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; ++i)
{
mColorbufferType = GL_NONE;
mColorbufferPointer = NULL;
if(mColorbufferPointer[i].name() == texture && IsTextureTarget(mColorbufferType[i]))
{
mColorbufferType[i] = GL_NONE;
mColorbufferPointer[i] = NULL;
}
}
if(mDepthbufferPointer.name() == texture && IsTextureTarget(mDepthbufferType))
......@@ -102,10 +111,13 @@ void Framebuffer::detachTexture(GLuint texture)
void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
{
if(mColorbufferPointer.name() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
for(int i = 0; i < IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; ++i)
{
mColorbufferType = GL_NONE;
mColorbufferPointer = NULL;
if(mColorbufferPointer[i].name() == renderbuffer && mColorbufferType[i] == GL_RENDERBUFFER)
{
mColorbufferType[i] = GL_NONE;
mColorbufferPointer[i] = NULL;
}
}
if(mDepthbufferPointer.name() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
......@@ -123,9 +135,9 @@ void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getRenderTarget()
egl::Image *Framebuffer::getRenderTarget(GLuint index)
{
Renderbuffer *colorbuffer = mColorbufferPointer;
Renderbuffer *colorbuffer = mColorbufferPointer[index];
if(colorbuffer)
{
......@@ -135,6 +147,12 @@ egl::Image *Framebuffer::getRenderTarget()
return NULL;
}
egl::Image *Framebuffer::getReadRenderTarget()
{
Context *context = getContext();
return getRenderTarget(context->getReadFramebufferColorIndex());
}
// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getDepthStencil()
......@@ -154,9 +172,15 @@ egl::Image *Framebuffer::getDepthStencil()
return NULL;
}
Renderbuffer *Framebuffer::getColorbuffer()
Renderbuffer *Framebuffer::getColorbuffer(GLuint index)
{
return mColorbufferPointer;
return (index < MAX_COLOR_ATTACHMENTS) ? mColorbufferPointer[index] : (Renderbuffer*)NULL;
}
Renderbuffer *Framebuffer::getReadColorbuffer()
{
Context *context = getContext();
return getColorbuffer(context->getReadFramebufferColorIndex());
}
Renderbuffer *Framebuffer::getDepthbuffer()
......@@ -169,9 +193,9 @@ Renderbuffer *Framebuffer::getStencilbuffer()
return mStencilbufferPointer;
}
GLenum Framebuffer::getColorbufferType()
GLenum Framebuffer::getColorbufferType(GLuint index)
{
return mColorbufferType;
return mColorbufferType[index];
}
GLenum Framebuffer::getDepthbufferType()
......@@ -184,9 +208,9 @@ GLenum Framebuffer::getStencilbufferType()
return mStencilbufferType;
}
GLuint Framebuffer::getColorbufferName()
GLuint Framebuffer::getColorbufferName(GLuint index)
{
return mColorbufferPointer.name();
return mColorbufferPointer[index].name();
}
GLuint Framebuffer::getDepthbufferName()
......@@ -229,53 +253,56 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
height = -1;
samples = -1;
if(mColorbufferType != GL_NONE)
for(int i = 0; i < IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; ++i)
{
Renderbuffer *colorbuffer = getColorbuffer();
if(!colorbuffer)
if(mColorbufferType[i] != GL_NONE)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
Renderbuffer *colorbuffer = getColorbuffer(i);
if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(mColorbufferType == GL_RENDERBUFFER)
{
if(!es2::IsColorRenderable(colorbuffer->getFormat()))
if(!colorbuffer)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else if(IsTextureTarget(mColorbufferType))
{
GLenum format = colorbuffer->getFormat();
if(IsCompressed(format) ||
format == GL_ALPHA ||
format == GL_LUMINANCE ||
format == GL_LUMINANCE_ALPHA)
if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
{
return GL_FRAMEBUFFER_UNSUPPORTED;
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(es2::IsDepthTexture(format) || es2::IsStencilTexture(format))
if(mColorbufferType[i] == GL_RENDERBUFFER)
{
if(!es2::IsColorRenderable(colorbuffer->getFormat()))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else if(IsTextureTarget(mColorbufferType[i]))
{
GLenum format = colorbuffer->getFormat();
if(IsCompressed(format) ||
format == GL_ALPHA ||
format == GL_LUMINANCE ||
format == GL_LUMINANCE_ALPHA)
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
if(es2::IsDepthTexture(format) || es2::IsStencilTexture(format))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
UNREACHABLE();
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
UNREACHABLE();
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
}
}
Renderbuffer *depthbuffer = NULL;
......@@ -401,7 +428,7 @@ GLenum Framebuffer::completeness(int &width, int &height, int &samples)
GLenum Framebuffer::getImplementationColorReadFormat()
{
Renderbuffer *colorbuffer = mColorbufferPointer;
Renderbuffer *colorbuffer = getReadColorbuffer();
if(colorbuffer)
{
......@@ -426,7 +453,7 @@ GLenum Framebuffer::getImplementationColorReadFormat()
GLenum Framebuffer::getImplementationColorReadType()
{
Renderbuffer *colorbuffer = mColorbufferPointer;
Renderbuffer *colorbuffer = getReadColorbuffer();
if(colorbuffer)
{
......@@ -450,13 +477,19 @@ GLenum Framebuffer::getImplementationColorReadType()
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{
mColorbufferPointer = new Renderbuffer(0, colorbuffer);
mColorbufferPointer[0] = new Renderbuffer(0, colorbuffer);
mColorbufferType[0] = GL_RENDERBUFFER;
for(int i = 1; i < IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; ++i)
{
mColorbufferPointer[i] = nullptr;
mColorbufferType[i] = GL_NONE;
}
Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
mDepthbufferPointer = depthStencilRenderbuffer;
mStencilbufferPointer = depthStencilRenderbuffer;
mColorbufferType = GL_RENDERBUFFER;
mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
}
......
......@@ -35,25 +35,27 @@ public:
virtual ~Framebuffer();
void setColorbuffer(GLenum type, GLuint colorbuffer);
void setColorbuffer(GLenum type, GLuint colorbuffer, GLuint index);
void setDepthbuffer(GLenum type, GLuint depthbuffer);
void setStencilbuffer(GLenum type, GLuint stencilbuffer);
void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer);
egl::Image *getRenderTarget();
egl::Image *getRenderTarget(GLuint index);
egl::Image *getReadRenderTarget();
egl::Image *getDepthStencil();
Renderbuffer *getColorbuffer();
Renderbuffer *getColorbuffer(GLuint index);
Renderbuffer *getReadColorbuffer();
Renderbuffer *getDepthbuffer();
Renderbuffer *getStencilbuffer();
GLenum getColorbufferType();
GLenum getColorbufferType(GLuint index);
GLenum getDepthbufferType();
GLenum getStencilbufferType();
GLuint getColorbufferName();
GLuint getColorbufferName(GLuint index);
GLuint getDepthbufferName();
GLuint getStencilbufferName();
......@@ -66,8 +68,8 @@ public:
GLenum getImplementationColorReadType();
protected:
GLenum mColorbufferType;
gl::BindingPointer<Renderbuffer> mColorbufferPointer;
GLenum mColorbufferType[MAX_COLOR_ATTACHMENTS];
gl::BindingPointer<Renderbuffer> mColorbufferPointer[MAX_COLOR_ATTACHMENTS];
GLenum mDepthbufferType;
gl::BindingPointer<Renderbuffer> mDepthbufferPointer;
......
......@@ -700,7 +700,7 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
egl::Image *renderTarget = source->getRenderTarget();
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
{
......@@ -722,8 +722,16 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
if(width != 0 && height != 0)
{
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
copy(renderTarget, sourceRect, format, 0, 0, 0, image[level]);
}
......@@ -743,7 +751,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget();
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
{
......@@ -751,8 +759,16 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_OUT_OF_MEMORY);
}
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
......@@ -1211,7 +1227,7 @@ void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
egl::Image *renderTarget = source->getRenderTarget();
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
{
......@@ -1235,8 +1251,16 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
if(width != 0 && height != 0)
{
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
copy(renderTarget, sourceRect, format, 0, 0, 0, image[face][level]);
}
......@@ -1270,7 +1294,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget();
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
{
......@@ -1278,8 +1302,16 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
return error(GL_OUT_OF_MEMORY);
}
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect(x, y, x + width, y + height, 0);
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, zoffset, image[face][level]);
......@@ -1565,7 +1597,7 @@ void Texture3D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z, GLsizei width, GLsizei height, GLsizei depth, Framebuffer *source)
{
egl::Image *renderTarget = source->getRenderTarget();
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
{
......@@ -1587,8 +1619,16 @@ void Texture3D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLint z,
if(width != 0 && height != 0 && depth != 0)
{
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect(x, y, x + width, y + height, z);
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
for(GLint sliceZ = 0; sliceZ < depth; ++sliceZ, ++sourceRect.slice)
{
copy(renderTarget, sourceRect, format, 0, 0, sliceZ, image[level]);
......@@ -1610,7 +1650,7 @@ void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget();
egl::Image *renderTarget = source->getRenderTarget(0);
if(!renderTarget)
{
......@@ -1618,8 +1658,16 @@ void Texture3D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_OUT_OF_MEMORY);
}
Renderbuffer* renderbuffer = source->getReadColorbuffer();
if(!renderbuffer)
{
ERR("Failed to retrieve the source colorbuffer.");
return;
}
sw::SliceRect sourceRect = {x, y, x + width, y + height, 0};
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
sourceRect.clip(0, 0, renderbuffer->getWidth(), renderbuffer->getHeight());
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, zoffset, image[level]);
......
......@@ -43,7 +43,7 @@ enum
IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 1 << (MIPMAP_LEVELS - 1),
IMPLEMENTATION_MAX_RENDERBUFFER_SIZE = OUTLINE_RESOLUTION,
IMPLEMENTATION_MAX_SAMPLES = 4,
IMPLEMENTATION_MAX_COLOR_ATTACHMENTS = 8,
IMPLEMENTATION_MAX_COLOR_ATTACHMENTS = MAX_COLOR_ATTACHMENTS,
IMPLEMENTATION_MAX_DRAW_BUFFERS = 8,
IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS = 36,
......
......@@ -1247,12 +1247,13 @@ void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x,
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
{
return error(GL_INVALID_OPERATION);
}
es2::Renderbuffer *source = framebuffer->getColorbuffer();
GLenum colorbufferFormat = source->getFormat();
if(!validateColorBufferFormat(internalformat, colorbufferFormat))
......@@ -1328,12 +1329,13 @@ void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
{
return error(GL_INVALID_OPERATION);
}
es2::Renderbuffer *source = framebuffer->getColorbuffer();
GLenum colorbufferFormat = source->getFormat();
es2::Texture *texture = NULL;
......@@ -2188,10 +2190,36 @@ void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuff
return error(GL_INVALID_OPERATION);
}
egl::GLint clientVersion = context->getClientVersion();
switch(attachment)
{
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(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
// fall through
case GL_COLOR_ATTACHMENT0:
framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
{
return error(GL_INVALID_ENUM);
}
framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);
break;
case GL_DEPTH_ATTACHMENT:
framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
......@@ -2294,9 +2322,37 @@ void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GL
return error(GL_INVALID_OPERATION);
}
egl::GLint clientVersion = context->getClientVersion();
switch(attachment)
{
case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
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(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
// fall through
case GL_COLOR_ATTACHMENT0:
if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
{
return error(GL_INVALID_ENUM);
}
framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
break;
case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
}
......@@ -2874,13 +2930,39 @@ void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenu
framebuffer = context->getDrawFramebuffer();
}
egl::GLint clientVersion = context->getClientVersion();
GLenum attachmentType;
GLuint attachmentHandle;
switch(attachment)
{
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(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
// fall through
case GL_COLOR_ATTACHMENT0:
attachmentType = framebuffer->getColorbufferType();
attachmentHandle = framebuffer->getColorbufferName();
if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
{
return error(GL_INVALID_ENUM);
}
attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
break;
case GL_DEPTH_ATTACHMENT:
attachmentType = framebuffer->getDepthbufferType();
......@@ -6681,12 +6763,13 @@ void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffs
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
{
return error(GL_INVALID_OPERATION);
}
es2::Renderbuffer *source = framebuffer->getColorbuffer();
GLenum colorbufferFormat = source->getFormat();
es2::Texture3D *texture = context->getTexture3D();
......@@ -6909,9 +6992,37 @@ void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget,
return error(GL_INVALID_OPERATION);
}
egl::GLint clientVersion = context->getClientVersion();
switch(attachment)
{
case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
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(clientVersion < 3)
{
return error(GL_INVALID_ENUM);
}
// fall through
case GL_COLOR_ATTACHMENT0:
if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
{
return error(GL_INVALID_ENUM);
}
framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
break;
case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
}
......
......@@ -458,37 +458,55 @@ GL_APICALL void GL_APIENTRY glReadBuffer(GLenum src)
es2::Context *context = es2::getContext();
switch(src)
if(context)
{
case GL_BACK:
case GL_NONE:
break;
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((src - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
GLuint readFramebufferName = context->getReadFramebufferName();
switch(src)
{
return error(GL_INVALID_ENUM);
case GL_BACK:
if(readFramebufferName != 0)
{
return error(GL_INVALID_OPERATION);
}
context->setReadFramebufferColorIndex(0);
break;
case GL_NONE:
context->setReadFramebufferColorIndex(GL_INVALID_INDEX);
break;
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:
{
GLuint index = (src - GL_COLOR_ATTACHMENT0);
if(index >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
{
return error(GL_INVALID_ENUM);
}
if(readFramebufferName == 0)
{
return error(GL_INVALID_OPERATION);
}
context->setReadFramebufferColorIndex(index);
}
break;
default:
error(GL_INVALID_ENUM);
}
break;
default:
error(GL_INVALID_ENUM);
}
UNIMPLEMENTED();
}
GL_APICALL void GL_APIENTRY glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices)
......@@ -666,12 +684,13 @@ GL_APICALL void GL_APIENTRY glCopyTexSubImage3D(GLenum target, GLint level, GLin
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if(context->getReadFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1)
es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
{
return error(GL_INVALID_OPERATION);
}
es2::Renderbuffer *source = framebuffer->getColorbuffer();
GLenum colorbufferFormat = source->getFormat();
es2::Texture3D *texture = context->getTexture3D();
......@@ -1063,7 +1082,78 @@ GL_APICALL void GL_APIENTRY glDrawBuffers(GLsizei n, const GLenum *bufs)
{
TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
UNIMPLEMENTED();
if(n < 0 || n > es2::IMPLEMENTATION_MAX_DRAW_BUFFERS)
{
return error(GL_INVALID_VALUE);
}
if(n == 0)
{
return;
}
es2::Context *context = es2::getContext();
if(context)
{
GLuint drawFramebufferName = context->getDrawFramebufferName();
if((drawFramebufferName == 0) && (n != 1))
{
return error(GL_INVALID_OPERATION);
}
for(int i = 0; i < n; ++i)
{
switch(bufs[i])
{
case GL_BACK:
if(drawFramebufferName != 0)
{
return error(GL_INVALID_OPERATION);
}
break;
case GL_NONE:
break;
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:
{
GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0);
if(index >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)
{
return error(GL_INVALID_ENUM);
}
if(index != i)
{
return error(GL_INVALID_OPERATION);
}
if(drawFramebufferName == 0)
{
return error(GL_INVALID_OPERATION);
}
}
break;
default:
return error(GL_INVALID_ENUM);
}
}
context->setDrawFramebufferColorIndices(n, bufs);
}
}
GL_APICALL void GL_APIENTRY glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
......
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