Commit 13773b26 by Jamie Madill

Store value types for FBO attachments.

This prevents us from re-allocating FBO attachments every set. This change requires quite a bit of refactoring. BUG=angleproject:963 Change-Id: Iafa4e4a0f3dd66c9e7452e0e96a0cbb9753487bb Reviewed-on: https://chromium-review.googlesource.com/263489Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent b6bda4af
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "common/angleutils.h" #include "common/angleutils.h"
#include "libANGLE/Constants.h" #include "libANGLE/Constants.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/RefCountObject.h" #include "libANGLE/RefCountObject.h"
namespace rx namespace rx
...@@ -32,7 +33,6 @@ class Surface; ...@@ -32,7 +33,6 @@ class Surface;
namespace gl namespace gl
{ {
class FramebufferAttachment;
class Renderbuffer; class Renderbuffer;
class State; class State;
class Texture; class Texture;
...@@ -43,8 +43,6 @@ struct Extensions; ...@@ -43,8 +43,6 @@ struct Extensions;
struct ImageIndex; struct ImageIndex;
struct Rectangle; struct Rectangle;
typedef std::vector<const FramebufferAttachment *> AttachmentList;
class Framebuffer class Framebuffer
{ {
public: public:
...@@ -64,7 +62,7 @@ class Framebuffer ...@@ -64,7 +62,7 @@ class Framebuffer
const FramebufferAttachment *getDepthStencilAttachment() const; const FramebufferAttachment *getDepthStencilAttachment() const;
const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; } const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; }
const std::vector<FramebufferAttachment *> &getColorAttachments() const { return mColorAttachments; } const std::vector<FramebufferAttachment> &getColorAttachments() const { return mColorAttachments; }
private: private:
friend class Framebuffer; friend class Framebuffer;
...@@ -73,9 +71,9 @@ class Framebuffer ...@@ -73,9 +71,9 @@ class Framebuffer
FramebufferAttachment *getStencilAttachment(); FramebufferAttachment *getStencilAttachment();
FramebufferAttachment *getDepthStencilAttachment(); FramebufferAttachment *getDepthStencilAttachment();
std::vector<FramebufferAttachment *> mColorAttachments; std::vector<FramebufferAttachment> mColorAttachments;
FramebufferAttachment *mDepthAttachment; FramebufferAttachment mDepthAttachment;
FramebufferAttachment *mStencilAttachment; FramebufferAttachment mStencilAttachment;
std::vector<GLenum> mDrawBufferStates; std::vector<GLenum> mDrawBufferStates;
GLenum mReadBufferState; GLenum mReadBufferState;
...@@ -89,9 +87,11 @@ class Framebuffer ...@@ -89,9 +87,11 @@ class Framebuffer
GLuint id() const { return mId; } GLuint id() const { return mId; }
void setTextureAttachment(GLenum attachment, Texture *texture, const ImageIndex &imageIndex); void setAttachment(GLenum type,
void setRenderbufferAttachment(GLenum attachment, Renderbuffer *renderbuffer); GLenum binding,
void setNULLAttachment(GLenum attachment); const ImageIndex &textureIndex,
FramebufferAttachmentObject *resource);
void resetAttachment(GLenum binding);
void detachTexture(GLuint texture); void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer); void detachRenderbuffer(GLuint renderbuffer);
...@@ -109,7 +109,6 @@ class Framebuffer ...@@ -109,7 +109,6 @@ class Framebuffer
GLenum getReadColorbufferType() const; GLenum getReadColorbufferType() const;
const FramebufferAttachment *getFirstColorbuffer() const; const FramebufferAttachment *getFirstColorbuffer() const;
FramebufferAttachment *getAttachment(GLenum attachment);
const FramebufferAttachment *getAttachment(GLenum attachment) const; const FramebufferAttachment *getAttachment(GLenum attachment) const;
GLenum getDrawBufferState(unsigned int colorAttachment) const; GLenum getDrawBufferState(unsigned int colorAttachment) const;
...@@ -144,7 +143,6 @@ class Framebuffer ...@@ -144,7 +143,6 @@ class Framebuffer
GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer); GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer);
protected: protected:
void setAttachment(GLenum attachment, FramebufferAttachment *attachmentObj);
void detachResourceById(GLenum resourceType, GLuint resourceId); void detachResourceById(GLenum resourceType, GLuint resourceId);
Data mData; Data mData;
......
...@@ -43,6 +43,12 @@ FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Ta ...@@ -43,6 +43,12 @@ FramebufferAttachment::Target &FramebufferAttachment::Target::operator=(const Ta
////// FramebufferAttachment Implementation ////// ////// FramebufferAttachment Implementation //////
FramebufferAttachment::FramebufferAttachment()
: mType(GL_NONE),
mTarget(GL_NONE, ImageIndex::MakeInvalid())
{
}
FramebufferAttachment::FramebufferAttachment(GLenum type, FramebufferAttachment::FramebufferAttachment(GLenum type,
GLenum binding, GLenum binding,
const ImageIndex &textureIndex, const ImageIndex &textureIndex,
...@@ -53,6 +59,25 @@ FramebufferAttachment::FramebufferAttachment(GLenum type, ...@@ -53,6 +59,25 @@ FramebufferAttachment::FramebufferAttachment(GLenum type,
mResource.set(resource); mResource.set(resource);
} }
void FramebufferAttachment::detach()
{
mType = GL_NONE;
mResource.set(nullptr);
// not technically necessary, could omit for performance
mTarget = Target(GL_NONE, ImageIndex::MakeInvalid());
}
void FramebufferAttachment::attach(GLenum type,
GLenum binding,
const ImageIndex &textureIndex,
FramebufferAttachmentObject *resource)
{
mType = type;
mTarget = Target(binding, textureIndex);
mResource.set(resource);
}
FramebufferAttachment::~FramebufferAttachment() FramebufferAttachment::~FramebufferAttachment()
{ {
mResource.set(nullptr); mResource.set(nullptr);
......
...@@ -35,6 +35,8 @@ class Texture; ...@@ -35,6 +35,8 @@ class Texture;
class FramebufferAttachment final : angle::NonCopyable class FramebufferAttachment final : angle::NonCopyable
{ {
public: public:
FramebufferAttachment();
FramebufferAttachment(GLenum type, FramebufferAttachment(GLenum type,
GLenum binding, GLenum binding,
const ImageIndex &textureIndex, const ImageIndex &textureIndex,
...@@ -62,6 +64,12 @@ class FramebufferAttachment final : angle::NonCopyable ...@@ -62,6 +64,12 @@ class FramebufferAttachment final : angle::NonCopyable
ImageIndex mTextureIndex; ImageIndex mTextureIndex;
}; };
void detach();
void attach(GLenum type,
GLenum binding,
const ImageIndex &textureIndex,
FramebufferAttachmentObject *resource);
// Helper methods // Helper methods
GLuint getRedSize() const; GLuint getRedSize() const;
GLuint getGreenSize() const; GLuint getGreenSize() const;
...@@ -89,6 +97,7 @@ class FramebufferAttachment final : angle::NonCopyable ...@@ -89,6 +97,7 @@ class FramebufferAttachment final : angle::NonCopyable
GLenum getInternalFormat() const; GLenum getInternalFormat() const;
GLsizei getSamples() const; GLsizei getSamples() const;
GLenum type() const { return mType; } GLenum type() const { return mType; }
bool isAttached() const { return mType != GL_NONE; }
Renderbuffer *getRenderbuffer() const; Renderbuffer *getRenderbuffer() const;
Texture *getTexture() const; Texture *getTexture() const;
......
...@@ -324,15 +324,15 @@ GLenum FramebufferD3D::checkStatus() const ...@@ -324,15 +324,15 @@ GLenum FramebufferD3D::checkStatus() const
const auto &colorAttachments = mData.getColorAttachments(); const auto &colorAttachments = mData.getColorAttachments();
for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
{ {
const gl::FramebufferAttachment *attachment = colorAttachments[colorAttachment]; const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachment];
if (attachment != nullptr) if (attachment.isAttached())
{ {
for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++) for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++)
{ {
const gl::FramebufferAttachment *prevAttachment = colorAttachments[prevColorAttachment]; const gl::FramebufferAttachment &prevAttachment = colorAttachments[prevColorAttachment];
if (prevAttachment != nullptr && if (prevAttachment.isAttached() &&
(attachment->id() == prevAttachment->id() && (attachment.id() == prevAttachment.id() &&
attachment->type() == prevAttachment->type())) attachment.type() == prevAttachment.type()))
{ {
return GL_FRAMEBUFFER_UNSUPPORTED; return GL_FRAMEBUFFER_UNSUPPORTED;
} }
...@@ -355,15 +355,16 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const Wor ...@@ -355,15 +355,16 @@ const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const Wor
const auto &colorAttachments = mData.getColorAttachments(); const auto &colorAttachments = mData.getColorAttachments();
const auto &drawBufferStates = mData.getDrawBufferStates(); const auto &drawBufferStates = mData.getDrawBufferStates();
for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex) for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
{ {
GLenum drawBufferState = drawBufferStates[attachmentIndex]; GLenum drawBufferState = drawBufferStates[attachmentIndex];
const gl::FramebufferAttachment *colorAttachment = colorAttachments[attachmentIndex]; const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex];
if (colorAttachment != nullptr && drawBufferState != GL_NONE) if (colorAttachment.isAttached() && drawBufferState != GL_NONE)
{ {
ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex)); ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
mColorAttachmentsForRender.push_back(colorAttachment); mColorAttachmentsForRender.push_back(&colorAttachment);
} }
else if (!workarounds.mrtPerfWorkaround) else if (!workarounds.mrtPerfWorkaround)
{ {
......
...@@ -19,6 +19,9 @@ namespace gl ...@@ -19,6 +19,9 @@ namespace gl
{ {
class FramebufferAttachment; class FramebufferAttachment;
struct PixelPackState; struct PixelPackState;
typedef std::vector<const FramebufferAttachment *> AttachmentList;
} }
namespace rx namespace rx
......
...@@ -253,27 +253,27 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl ...@@ -253,27 +253,27 @@ gl::Error Clear11::clearFramebuffer(const ClearParameters &clearParams, const gl
for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
{ {
const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachment];
if (clearParams.clearColor[colorAttachment] && if (clearParams.clearColor[colorAttachment] &&
colorAttachments[colorAttachment] != nullptr && attachment.isAttached() &&
drawBufferStates[colorAttachment] != GL_NONE) drawBufferStates[colorAttachment] != GL_NONE)
{ {
const gl::FramebufferAttachment *attachment = colorAttachments[colorAttachment];
RenderTarget11 *renderTarget = NULL; RenderTarget11 *renderTarget = NULL;
gl::Error error = d3d11::GetAttachmentRenderTarget(attachment, &renderTarget); gl::Error error = d3d11::GetAttachmentRenderTarget(&attachment, &renderTarget);
if (error.isError()) if (error.isError())
{ {
return error; return error;
} }
const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment->getInternalFormat()); const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(attachment.getInternalFormat());
if (clearParams.colorClearType == GL_FLOAT && if (clearParams.colorClearType == GL_FLOAT &&
!(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED)) !(formatInfo.componentType == GL_FLOAT || formatInfo.componentType == GL_UNSIGNED_NORMALIZED || formatInfo.componentType == GL_SIGNED_NORMALIZED))
{ {
ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-" ERR("It is undefined behaviour to clear a render buffer which is not normalized fixed point or floating-"
"point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment, "point to floating point values (color attachment %u has internal format 0x%X).", colorAttachment,
attachment->getInternalFormat()); attachment.getInternalFormat());
} }
if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) && if ((formatInfo.redBits == 0 || !clearParams.colorMaskRed) &&
......
...@@ -64,12 +64,15 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a ...@@ -64,12 +64,15 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a
gl::Error Framebuffer11::invalidateSwizzles() const gl::Error Framebuffer11::invalidateSwizzles() const
{ {
for (const auto *colorAttachment : mData.getColorAttachments()) for (const auto &colorAttachment : mData.getColorAttachments())
{ {
gl::Error error = InvalidateAttachmentSwizzles(colorAttachment); if (colorAttachment.isAttached())
if (error.isError())
{ {
return error; gl::Error error = InvalidateAttachmentSwizzles(&colorAttachment);
if (error.isError())
{
return error;
}
} }
} }
...@@ -185,7 +188,7 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang ...@@ -185,7 +188,7 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang
const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getReadColorbuffer(); const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getReadColorbuffer();
ASSERT(readBuffer); ASSERT(readBuffer);
RenderTargetD3D *readRenderTarget = NULL; RenderTargetD3D *readRenderTarget = nullptr;
gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget); gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget);
if (error.isError()) if (error.isError())
{ {
...@@ -195,15 +198,16 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang ...@@ -195,15 +198,16 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang
const auto &colorAttachments = mData.getColorAttachments(); const auto &colorAttachments = mData.getColorAttachments();
const auto &drawBufferStates = mData.getDrawBufferStates(); const auto &drawBufferStates = mData.getDrawBufferStates();
for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
{ {
if (colorAttachments[colorAttachment] != nullptr && const gl::FramebufferAttachment &drawBuffer = colorAttachments[colorAttachment];
if (drawBuffer.isAttached() &&
drawBufferStates[colorAttachment] != GL_NONE) drawBufferStates[colorAttachment] != GL_NONE)
{ {
const gl::FramebufferAttachment *drawBuffer = colorAttachments[colorAttachment]; RenderTargetD3D *drawRenderTarget = nullptr;
error = GetAttachmentRenderTarget(&drawBuffer, &drawRenderTarget);
RenderTargetD3D *drawRenderTarget = NULL;
error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget);
if (error.isError()) if (error.isError())
{ {
return error; return error;
......
...@@ -636,8 +636,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint ...@@ -636,8 +636,8 @@ bool ValidateBlitFramebufferParameters(gl::Context *context, GLint srcX0, GLint
{ {
if (mask & masks[i]) if (mask & masks[i])
{ {
gl::FramebufferAttachment *readBuffer = readFramebuffer->getAttachment(attachments[i]); const gl::FramebufferAttachment *readBuffer = readFramebuffer->getAttachment(attachments[i]);
gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getAttachment(attachments[i]); const gl::FramebufferAttachment *drawBuffer = drawFramebuffer->getAttachment(attachments[i]);
if (readBuffer && drawBuffer) if (readBuffer && drawBuffer)
{ {
......
...@@ -1342,11 +1342,11 @@ void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu ...@@ -1342,11 +1342,11 @@ void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
if (renderbuffer != 0) if (renderbuffer != 0)
{ {
Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
framebuffer->setRenderbufferAttachment(attachment, renderbufferObject); framebuffer->setAttachment(GL_RENDERBUFFER, attachment, gl::ImageIndex::MakeInvalid(), renderbufferObject);
} }
else else
{ {
framebuffer->setNULLAttachment(attachment); framebuffer->resetAttachment(attachment);
} }
} }
} }
...@@ -1383,11 +1383,11 @@ void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum t ...@@ -1383,11 +1383,11 @@ void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
index = ImageIndex::MakeCube(textarget, level); index = ImageIndex::MakeCube(textarget, level);
} }
framebuffer->setTextureAttachment(attachment, textureObj, index); framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObj);
} }
else else
{ {
framebuffer->setNULLAttachment(attachment); framebuffer->resetAttachment(attachment);
} }
} }
} }
......
...@@ -763,11 +763,11 @@ void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuin ...@@ -763,11 +763,11 @@ void GL_APIENTRY FramebufferTextureLayer(GLenum target, GLenum attachment, GLuin
index = ImageIndex::Make2DArray(level, layer); index = ImageIndex::Make2DArray(level, layer);
} }
framebuffer->setTextureAttachment(attachment, textureObject, index); framebuffer->setAttachment(GL_TEXTURE, attachment, index, textureObject);
} }
else else
{ {
framebuffer->setNULLAttachment(attachment); framebuffer->resetAttachment(attachment);
} }
} }
} }
......
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