Commit 490cdca4 by Nicolas Capens Committed by Nicolas Capens

Eliminate GL framebuffers.

Bug 18591036 Change-Id: I6d9c408032583bb77c8b9f69da544f8d96ee3e4c Reviewed-on: https://swiftshader-review.googlesource.com/1552Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 54768f09
......@@ -18,7 +18,6 @@
#include "mathutil.h"
#include "utilities.h"
#include "Fence.h"
#include "Framebuffer.h"
#include "Program.h"
#include "Query.h"
#include "Renderbuffer.h"
......
// SwiftShader Software Renderer
//
// Copyright(c) 2005-2013 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
// Framebuffer.cpp: Implements the Framebuffer class. Implements GL framebuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
#include "Framebuffer.h"
#include "main.h"
#include "Renderbuffer.h"
#include "Texture.h"
#include "utilities.h"
namespace es2
{
Framebuffer::Framebuffer()
{
mColorbufferType = GL_NONE;
mDepthbufferType = GL_NONE;
mStencilbufferType = GL_NONE;
}
Framebuffer::~Framebuffer()
{
mColorbufferPointer.set(NULL);
mDepthbufferPointer.set(NULL);
mStencilbufferPointer.set(NULL);
}
Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
{
Context *context = getContext();
Renderbuffer *buffer = NULL;
if(type == GL_NONE)
{
buffer = NULL;
}
else if(type == GL_RENDERBUFFER)
{
//buffer = context->getRenderbuffer(handle);
}
else if(IsTextureTarget(type))
{
//buffer = context->getTexture(handle)->getRenderbuffer(type);
}
else
{
UNREACHABLE();
}
return buffer;
}
void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
{
mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
{
mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
}
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
{
mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
}
void Framebuffer::detachTexture(GLuint texture)
{
if(mColorbufferPointer.id() == texture && IsTextureTarget(mColorbufferType))
{
mColorbufferType = GL_NONE;
mColorbufferPointer.set(NULL);
}
if(mDepthbufferPointer.id() == texture && IsTextureTarget(mDepthbufferType))
{
mDepthbufferType = GL_NONE;
mDepthbufferPointer.set(NULL);
}
if(mStencilbufferPointer.id() == texture && IsTextureTarget(mStencilbufferType))
{
mStencilbufferType = GL_NONE;
mStencilbufferPointer.set(NULL);
}
}
void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
{
if(mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
{
mColorbufferType = GL_NONE;
mColorbufferPointer.set(NULL);
}
if(mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
{
mDepthbufferType = GL_NONE;
mDepthbufferPointer.set(NULL);
}
if(mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
{
mStencilbufferType = GL_NONE;
mStencilbufferPointer.set(NULL);
}
}
// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getRenderTarget()
{
Renderbuffer *colorbuffer = mColorbufferPointer.get();
if(colorbuffer)
{
return colorbuffer->getRenderTarget();
}
return NULL;
}
// Increments refcount on surface.
// caller must Release() the returned surface
egl::Image *Framebuffer::getDepthStencil()
{
Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
if(!depthstencilbuffer)
{
depthstencilbuffer = mStencilbufferPointer.get();
}
if(depthstencilbuffer)
{
return depthstencilbuffer->getRenderTarget();
}
return NULL;
}
Renderbuffer *Framebuffer::getColorbuffer()
{
return mColorbufferPointer.get();
}
Renderbuffer *Framebuffer::getDepthbuffer()
{
return mDepthbufferPointer.get();
}
Renderbuffer *Framebuffer::getStencilbuffer()
{
return mStencilbufferPointer.get();
}
GLenum Framebuffer::getColorbufferType()
{
return mColorbufferType;
}
GLenum Framebuffer::getDepthbufferType()
{
return mDepthbufferType;
}
GLenum Framebuffer::getStencilbufferType()
{
return mStencilbufferType;
}
GLuint Framebuffer::getColorbufferHandle()
{
return mColorbufferPointer.id();
}
GLuint Framebuffer::getDepthbufferHandle()
{
return mDepthbufferPointer.id();
}
GLuint Framebuffer::getStencilbufferHandle()
{
return mStencilbufferPointer.id();
}
bool Framebuffer::hasStencil()
{
if(mStencilbufferType != GL_NONE)
{
Renderbuffer *stencilbufferObject = getStencilbuffer();
if(stencilbufferObject)
{
return stencilbufferObject->getStencilSize() > 0;
}
}
return false;
}
GLenum Framebuffer::completeness()
{
int width;
int height;
int samples;
return completeness(width, height, samples);
}
GLenum Framebuffer::completeness(int &width, int &height, int &samples)
{
width = -1;
height = -1;
samples = -1;
if(mColorbufferType != GL_NONE)
{
Renderbuffer *colorbuffer = getColorbuffer();
if(!colorbuffer)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(mColorbufferType == GL_RENDERBUFFER)
{
if(!es2::IsColorRenderable(colorbuffer->getFormat()))
{
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)
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
if(es2::IsDepthTexture(format) || es2::IsStencilTexture(format))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
UNREACHABLE();
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
samples = colorbuffer->getSamples();
}
Renderbuffer *depthbuffer = NULL;
Renderbuffer *stencilbuffer = NULL;
if(mDepthbufferType != GL_NONE)
{
depthbuffer = getDepthbuffer();
if(!depthbuffer)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(mDepthbufferType == GL_RENDERBUFFER)
{
if(!es2::IsDepthRenderable(depthbuffer->getFormat()))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else if(IsTextureTarget(mDepthbufferType))
{
if(!es2::IsDepthTexture(depthbuffer->getFormat()))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
UNREACHABLE();
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(width == -1 || height == -1)
{
width = depthbuffer->getWidth();
height = depthbuffer->getHeight();
samples = depthbuffer->getSamples();
}
else if(width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
else if(samples != depthbuffer->getSamples())
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
}
if(mStencilbufferType != GL_NONE)
{
stencilbuffer = getStencilbuffer();
if(!stencilbuffer)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(mStencilbufferType == GL_RENDERBUFFER)
{
if(!es2::IsStencilRenderable(stencilbuffer->getFormat()))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else if(IsTextureTarget(mStencilbufferType))
{
GLenum internalformat = stencilbuffer->getFormat();
if(!es2::IsStencilTexture(internalformat))
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
}
else
{
UNREACHABLE();
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
if(width == -1 || height == -1)
{
width = stencilbuffer->getWidth();
height = stencilbuffer->getHeight();
samples = stencilbuffer->getSamples();
}
else if(width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
else if(samples != stencilbuffer->getSamples())
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
}
// If we have both a depth and stencil buffer, they must refer to the same object
// since we only support packed_depth_stencil and not separate depth and stencil
if(depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
// We need to have at least one attachment to be complete
if(width == -1 || height == -1)
{
return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
}
return GL_FRAMEBUFFER_COMPLETE;
}
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
{
mColorbufferPointer.set(new Renderbuffer(0, colorbuffer));
Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
mDepthbufferPointer.set(depthStencilRenderbuffer);
mStencilbufferPointer.set(depthStencilRenderbuffer);
mColorbufferType = GL_RENDERBUFFER;
mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
}
GLenum DefaultFramebuffer::completeness()
{
// The default framebuffer should always be complete
ASSERT(Framebuffer::completeness() == GL_FRAMEBUFFER_COMPLETE);
return GL_FRAMEBUFFER_COMPLETE;
}
}
// SwiftShader Software Renderer
//
// Copyright(c) 2005-2013 TransGaming Inc.
//
// All rights reserved. No part of this software may be copied, distributed, transmitted,
// transcribed, stored in a retrieval system, translated into any human or computer
// language by any means, or disclosed to third parties without the explicit written
// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
// or implied, including but not limited to any patent rights, are granted to you.
//
// Framebuffer.h: Defines the Framebuffer class. Implements GL framebuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
#ifndef LIBGLESV2_FRAMEBUFFER_H_
#define LIBGLESV2_FRAMEBUFFER_H_
#include "RefCountObject.h"
#include "Image.hpp"
#define GL_APICALL
#include <GLES2/gl2.h>
namespace es2
{
class Renderbuffer;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
class DepthStencilbuffer;
class Framebuffer
{
public:
Framebuffer();
virtual ~Framebuffer();
void setColorbuffer(GLenum type, GLuint colorbuffer);
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 *getDepthStencil();
Renderbuffer *getColorbuffer();
Renderbuffer *getDepthbuffer();
Renderbuffer *getStencilbuffer();
GLenum getColorbufferType();
GLenum getDepthbufferType();
GLenum getStencilbufferType();
GLuint getColorbufferHandle();
GLuint getDepthbufferHandle();
GLuint getStencilbufferHandle();
bool hasStencil();
virtual GLenum completeness();
GLenum completeness(int &width, int &height, int &samples);
protected:
GLenum mColorbufferType;
BindingPointer<Renderbuffer> mColorbufferPointer;
GLenum mDepthbufferType;
BindingPointer<Renderbuffer> mDepthbufferPointer;
GLenum mStencilbufferType;
BindingPointer<Renderbuffer> mStencilbufferPointer;
private:
Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
};
class DefaultFramebuffer : public Framebuffer
{
public:
DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
virtual GLenum completeness();
};
}
#endif // LIBGLESV2_FRAMEBUFFER_H_
......@@ -17,7 +17,6 @@
#include "main.h"
#include "mathutil.h"
#include "Framebuffer.h"
#include "Device.hpp"
#include "libEGL/Display.h"
#include "libEGL/Surface.h"
......@@ -431,67 +430,6 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, image[level]);
}
void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if(image[level])
{
image[level]->unbind();
}
image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
if(!image[level])
{
return error(GL_OUT_OF_MEMORY);
}
if(width != 0 && height != 0)
{
sw::Rect sourceRect = {x, y, x + width, y + height};
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
copy(renderTarget, sourceRect, format, 0, 0, image[level]);
}
renderTarget->release();
}
void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
if(!image[level])
{
return error(GL_INVALID_OPERATION);
}
if(xoffset + width > image[level]->getWidth() || yoffset + height > image[level]->getHeight())
{
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
sw::Rect sourceRect = {x, y, x + width, y + height};
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
copy(renderTarget, sourceRect, image[level]->getFormat(), xoffset, yoffset, image[level]);
renderTarget->release();
}
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
bool Texture2D::isSamplerComplete() const
{
......@@ -925,41 +863,6 @@ void TextureCubeMap::setImage(GLenum target, GLint level, GLsizei width, GLsizei
Texture::setImage(format, type, unpackAlignment, pixels, image[face][level]);
}
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
int face = CubeFaceIndex(target);
if(image[face][level])
{
image[face][level]->unbind();
}
image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE);
if(!image[face][level])
{
return error(GL_OUT_OF_MEMORY);
}
if(width != 0 && height != 0)
{
sw::Rect sourceRect = {x, y, x + width, y + height};
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
copy(renderTarget, sourceRect, format, 0, 0, image[face][level]);
}
renderTarget->release();
}
Image *TextureCubeMap::getImage(int face, unsigned int level)
{
return image[face][level];
......@@ -970,38 +873,6 @@ Image *TextureCubeMap::getImage(GLenum face, unsigned int level)
return image[CubeFaceIndex(face)][level];
}
void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
int face = CubeFaceIndex(target);
if(!image[face][level])
{
return error(GL_INVALID_OPERATION);
}
GLsizei size = image[face][level]->getWidth();
if(xoffset + width > size || yoffset + height > size)
{
return error(GL_INVALID_VALUE);
}
egl::Image *renderTarget = source->getRenderTarget();
if(!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
sw::Rect sourceRect = {x, y, x + width, y + height};
sourceRect.clip(0, 0, source->getColorbuffer()->getWidth(), source->getColorbuffer()->getHeight());
copy(renderTarget, sourceRect, image[face][level]->getFormat(), xoffset, yoffset, image[face][level]);
renderTarget->release();
}
void TextureCubeMap::generateMipmaps()
{
if(!isCubeComplete())
......
......@@ -89,8 +89,7 @@ public:
virtual bool isShared(GLenum target, unsigned int level) const = 0;
virtual void generateMipmaps() = 0;
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;
protected:
void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);
......@@ -133,8 +132,6 @@ public:
void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
virtual bool isSamplerComplete() const;
virtual bool isCompressed(GLenum target, GLint level) const;
......@@ -188,8 +185,6 @@ public:
void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
virtual bool isSamplerComplete() const;
virtual bool isCompressed(GLenum target, GLint level) const;
......
......@@ -164,7 +164,6 @@ copy "$(OutDir)libRAD.dll" "$(ProjectDir)..\..\..\lib\$(Configuration)\"</Comman
<ClCompile Include="..\common\debug.cpp" />
<ClCompile Include="Device.cpp" />
<ClCompile Include="Fence.cpp" />
<ClCompile Include="Framebuffer.cpp" />
<ClCompile Include="HandleAllocator.cpp" />
<ClCompile Include="Image.cpp" />
<ClCompile Include="libRAD.cpp" />
......@@ -185,7 +184,6 @@ copy "$(OutDir)libRAD.dll" "$(ProjectDir)..\..\..\lib\$(Configuration)\"</Comman
<ClInclude Include="Context.h" />
<ClInclude Include="Device.hpp" />
<ClInclude Include="Fence.h" />
<ClInclude Include="Framebuffer.h" />
<ClInclude Include="HandleAllocator.h" />
<ClInclude Include="Image.hpp" />
<ClInclude Include="main.h" />
......
......@@ -20,9 +20,6 @@
<ClCompile Include="Fence.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Framebuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="HandleAllocator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
......@@ -67,9 +64,6 @@
<ClInclude Include="Fence.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Framebuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="HandleAllocator.h">
<Filter>Header Files</Filter>
</ClInclude>
......
......@@ -13,7 +13,6 @@
#include "main.h"
#include "Framebuffer.h"
#include "libEGL/Surface.h"
#include "Common/Thread.hpp"
#include "Common/SharedLibrary.hpp"
......
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