Hash :
b21e20da
Author :
Date :
2016-07-19T15:35:41
D3D: Validate that all color attachments are unique. The previous logic of only checking the currently enabled draw buffers was incorrect. Also updated the logic to be more lenient and allow multiple slices or mips of the same texture. BUG=483282 Change-Id: I0d406d1a9a96e48342baefbaf11e0c2ecc6d390c Reviewed-on: https://chromium-review.googlesource.com/361533 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Framebuffer.h: Defines the gl::Framebuffer class. Implements GL framebuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
#ifndef LIBANGLE_FRAMEBUFFER_H_
#define LIBANGLE_FRAMEBUFFER_H_
#include <vector>
#include "common/Optional.h"
#include "common/angleutils.h"
#include "libANGLE/Constants.h"
#include "libANGLE/Debug.h"
#include "libANGLE/Error.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/RefCountObject.h"
#include "libANGLE/signal_utils.h"
namespace rx
{
class ContextImpl;
class GLImplFactory;
class FramebufferImpl;
class RenderbufferImpl;
class SurfaceImpl;
}
namespace egl
{
class Surface;
}
namespace gl
{
class Context;
class Framebuffer;
class Renderbuffer;
class State;
class Texture;
class TextureCapsMap;
struct Caps;
class ContextState;
struct Extensions;
struct ImageIndex;
struct Rectangle;
class FramebufferState final : angle::NonCopyable
{
public:
FramebufferState();
explicit FramebufferState(const Caps &caps);
~FramebufferState();
const std::string &getLabel();
const FramebufferAttachment *getAttachment(GLenum attachment) const;
const FramebufferAttachment *getReadAttachment() const;
const FramebufferAttachment *getFirstColorAttachment() const;
const FramebufferAttachment *getDepthOrStencilAttachment() const;
const FramebufferAttachment *getColorAttachment(size_t colorAttachment) const;
const FramebufferAttachment *getDepthAttachment() const;
const FramebufferAttachment *getStencilAttachment() const;
const FramebufferAttachment *getDepthStencilAttachment() const;
const std::vector<GLenum> &getDrawBufferStates() const { return mDrawBufferStates; }
GLenum getReadBufferState() const { return mReadBufferState; }
const std::vector<FramebufferAttachment> &getColorAttachments() const
{
return mColorAttachments;
}
bool attachmentsHaveSameDimensions() const;
bool colorAttachmentsAreUniqueImages() const;
const FramebufferAttachment *getDrawBuffer(size_t drawBufferIdx) const;
size_t getDrawBufferCount() const;
private:
friend class Framebuffer;
std::string mLabel;
std::vector<FramebufferAttachment> mColorAttachments;
FramebufferAttachment mDepthAttachment;
FramebufferAttachment mStencilAttachment;
std::vector<GLenum> mDrawBufferStates;
GLenum mReadBufferState;
};
class Framebuffer final : public LabeledObject, public angle::SignalReceiver
{
public:
Framebuffer(const Caps &caps, rx::GLImplFactory *factory, GLuint id);
Framebuffer(rx::SurfaceImpl *surface);
virtual ~Framebuffer();
void setLabel(const std::string &label) override;
const std::string &getLabel() const override;
rx::FramebufferImpl *getImplementation() const { return mImpl; }
GLuint id() const { return mId; }
void setAttachment(GLenum type,
GLenum binding,
const ImageIndex &textureIndex,
FramebufferAttachmentObject *resource);
void resetAttachment(GLenum binding);
void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer);
const FramebufferAttachment *getColorbuffer(size_t colorAttachment) const;
const FramebufferAttachment *getDepthbuffer() const;
const FramebufferAttachment *getStencilbuffer() const;
const FramebufferAttachment *getDepthStencilBuffer() const;
const FramebufferAttachment *getDepthOrStencilbuffer() const;
const FramebufferAttachment *getReadColorbuffer() const;
GLenum getReadColorbufferType() const;
const FramebufferAttachment *getFirstColorbuffer() const;
const FramebufferAttachment *getAttachment(GLenum attachment) const;
size_t getDrawbufferStateCount() const;
GLenum getDrawBufferState(size_t drawBuffer) const;
const std::vector<GLenum> &getDrawBufferStates() const;
void setDrawBuffers(size_t count, const GLenum *buffers);
const FramebufferAttachment *getDrawBuffer(size_t drawBuffer) const;
bool hasEnabledDrawBuffer() const;
GLenum getReadBufferState() const;
void setReadBuffer(GLenum buffer);
size_t getNumColorBuffers() const;
bool hasDepth() const;
bool hasStencil() const;
bool usingExtendedDrawBuffers() const;
// This method calls checkStatus.
int getSamples(const ContextState &state);
GLenum checkStatus(const ContextState &state);
// Helper for checkStatus == GL_FRAMEBUFFER_COMPLETE.
bool complete(const ContextState &state);
bool hasValidDepthStencil() const;
Error discard(size_t count, const GLenum *attachments);
Error invalidate(size_t count, const GLenum *attachments);
Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area);
Error clear(rx::ContextImpl *context, GLbitfield mask);
Error clearBufferfv(rx::ContextImpl *context,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values);
Error clearBufferuiv(rx::ContextImpl *context,
GLenum buffer,
GLint drawbuffer,
const GLuint *values);
Error clearBufferiv(rx::ContextImpl *context,
GLenum buffer,
GLint drawbuffer,
const GLint *values);
Error clearBufferfi(rx::ContextImpl *context,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil);
GLenum getImplementationColorReadFormat() const;
GLenum getImplementationColorReadType() const;
Error readPixels(rx::ContextImpl *context,
const gl::Rectangle &area,
GLenum format,
GLenum type,
GLvoid *pixels) const;
Error blit(rx::ContextImpl *context,
const Rectangle &sourceArea,
const Rectangle &destArea,
GLbitfield mask,
GLenum filter);
enum DirtyBitType
{
DIRTY_BIT_COLOR_ATTACHMENT_0,
DIRTY_BIT_COLOR_ATTACHMENT_MAX =
DIRTY_BIT_COLOR_ATTACHMENT_0 + gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS,
DIRTY_BIT_DEPTH_ATTACHMENT = DIRTY_BIT_COLOR_ATTACHMENT_MAX,
DIRTY_BIT_STENCIL_ATTACHMENT,
DIRTY_BIT_DRAW_BUFFERS,
DIRTY_BIT_READ_BUFFER,
DIRTY_BIT_UNKNOWN,
DIRTY_BIT_MAX = DIRTY_BIT_UNKNOWN,
};
typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
void syncState();
// angle::SignalReceiver implementation
void signal(angle::SignalToken token) override;
private:
void detachResourceById(GLenum resourceType, GLuint resourceId);
void detachMatchingAttachment(FramebufferAttachment *attachment,
GLenum matchType,
GLuint matchId,
size_t dirtyBit);
GLenum checkStatusImpl(const ContextState &state);
FramebufferState mState;
rx::FramebufferImpl *mImpl;
GLuint mId;
Optional<GLenum> mCachedStatus;
std::vector<angle::ChannelBinding> mDirtyColorAttachmentBindings;
angle::ChannelBinding mDirtyDepthAttachmentBinding;
angle::ChannelBinding mDirtyStencilAttachmentBinding;
DirtyBits mDirtyBits;
};
} // namespace gl
#endif // LIBANGLE_FRAMEBUFFER_H_