Commit 888081d5 by Jamie Madill Committed by Commit Bot

D3D11: Refactor dependent Framebuffer state changes.

Previously, when a state change would cause a Texture to recreate its storage specific to D3D11, we would use a dependent notification from RenderTarget11 to Framebuffer11 to re-check internal dirty bits. In this new method, we instead set dirty bits on the gl::Frambuffer directly. This also means we use fewer internal objects for these notifications, because we share the same structures between the D3D11 back-end notifications and the top-level notifications we use for Robust init and Framebuffer completeness. This also allows us to get rid of one "if" that we check on every draw call in D3D11. This also introduces a dirty bits guard concept - a shadow set of dirty bits that is checked in dependent state changes to ensure that extra bits aren't set inside syncState. This also implements Framebuffer dirty bits for the D3D9 back-end. This has the side effect of cleaning up the "null colorbuffer" D3D9 workaround. Bug: angleproject:2372 Change-Id: Ie346d39030f4f6df583d735685b0babea4e745a8 Reviewed-on: https://chromium-review.googlesource.com/936691Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent 92e4e079
...@@ -1773,7 +1773,7 @@ void Framebuffer::updateAttachment(const Context *context, ...@@ -1773,7 +1773,7 @@ void Framebuffer::updateAttachment(const Context *context,
multiviewLayout, viewportOffsets); multiviewLayout, viewportOffsets);
mDirtyBits.set(dirtyBit); mDirtyBits.set(dirtyBit);
mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit); mState.mResourceNeedsInit.set(dirtyBit, attachment->initState() == InitState::MayNeedInit);
onDirtyBinding->bind(resource); onDirtyBinding->bind(resource ? resource->getSubject() : nullptr);
} }
void Framebuffer::resetAttachment(const Context *context, GLenum binding) void Framebuffer::resetAttachment(const Context *context, GLenum binding)
...@@ -1785,12 +1785,14 @@ void Framebuffer::syncState(const Context *context) ...@@ -1785,12 +1785,14 @@ void Framebuffer::syncState(const Context *context)
{ {
if (mDirtyBits.any()) if (mDirtyBits.any())
{ {
mDirtyBitsGuard = mDirtyBits;
mImpl->syncState(context, mDirtyBits); mImpl->syncState(context, mDirtyBits);
mDirtyBits.reset(); mDirtyBits.reset();
if (mId != 0) if (mId != 0)
{ {
mCachedStatus.reset(); mCachedStatus.reset();
} }
mDirtyBitsGuard.reset();
} }
} }
...@@ -1798,6 +1800,14 @@ void Framebuffer::onSubjectStateChange(const Context *context, ...@@ -1798,6 +1800,14 @@ void Framebuffer::onSubjectStateChange(const Context *context,
angle::SubjectIndex index, angle::SubjectIndex index,
angle::SubjectMessage message) angle::SubjectMessage message)
{ {
if (message == angle::SubjectMessage::DEPENDENT_DIRTY_BITS)
{
ASSERT(!mDirtyBitsGuard.valid() || mDirtyBitsGuard.value().test(index));
mDirtyBits.set(index);
context->getGLState().setFramebufferDirty(this);
return;
}
// Only reset the cached status if this is not the default framebuffer. The default framebuffer // Only reset the cached status if this is not the default framebuffer. The default framebuffer
// will still use this channel to mark itself dirty. // will still use this channel to mark itself dirty.
if (mId != 0) if (mId != 0)
......
...@@ -391,6 +391,10 @@ class Framebuffer final : public LabeledObject, public angle::ObserverInterface ...@@ -391,6 +391,10 @@ class Framebuffer final : public LabeledObject, public angle::ObserverInterface
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
// The dirty bits guard is checked when we get a dependent state change message. We verify that
// we don't set a dirty bit that isn't already set, when inside the dirty bits syncState.
Optional<DirtyBits> mDirtyBitsGuard;
// A cache of attached textures for quick validation of feedback loops. // A cache of attached textures for quick validation of feedback loops.
mutable Optional<std::set<const FramebufferAttachmentObject *>> mAttachedTextures; mutable Optional<std::set<const FramebufferAttachmentObject *>> mAttachedTextures;
}; };
......
...@@ -353,6 +353,16 @@ Error FramebufferAttachmentObject::getAttachmentRenderTarget( ...@@ -353,6 +353,16 @@ Error FramebufferAttachmentObject::getAttachmentRenderTarget(
return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut); return getAttachmentImpl()->getAttachmentRenderTarget(context, binding, imageIndex, rtOut);
} }
void FramebufferAttachmentObject::onStateChange(const gl::Context *context) const
{
return getAttachmentImpl()->onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
}
angle::Subject *FramebufferAttachmentObject::getSubject() const
{
return getAttachmentImpl();
}
Error FramebufferAttachmentObject::initializeContents(const Context *context, Error FramebufferAttachmentObject::initializeContents(const Context *context,
const ImageIndex &imageIndex) const ImageIndex &imageIndex)
{ {
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include "libANGLE/angletypes.h" #include "libANGLE/angletypes.h"
#include "libANGLE/Error.h" #include "libANGLE/Error.h"
#include "libANGLE/ImageIndex.h" #include "libANGLE/ImageIndex.h"
#include "libANGLE/signal_utils.h"
namespace egl namespace egl
{ {
...@@ -36,6 +35,11 @@ class FramebufferAttachmentRenderTarget : angle::NonCopyable ...@@ -36,6 +35,11 @@ class FramebufferAttachmentRenderTarget : angle::NonCopyable
class FramebufferAttachmentObjectImpl; class FramebufferAttachmentObjectImpl;
} }
namespace angle
{
class Subject;
} // namespace angle
namespace gl namespace gl
{ {
class FramebufferAttachmentObject; class FramebufferAttachmentObject;
...@@ -180,7 +184,7 @@ class FramebufferAttachment final ...@@ -180,7 +184,7 @@ class FramebufferAttachment final
}; };
// A base class for objects that FBO Attachments may point to. // A base class for objects that FBO Attachments may point to.
class FramebufferAttachmentObject : public angle::Subject class FramebufferAttachmentObject
{ {
public: public:
FramebufferAttachmentObject(); FramebufferAttachmentObject();
...@@ -206,6 +210,9 @@ class FramebufferAttachmentObject : public angle::Subject ...@@ -206,6 +210,9 @@ class FramebufferAttachmentObject : public angle::Subject
Error initializeContents(const Context *context, const ImageIndex &imageIndex); Error initializeContents(const Context *context, const ImageIndex &imageIndex);
void onStateChange(const gl::Context *context) const;
angle::Subject *getSubject() const;
protected: protected:
virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0; virtual rx::FramebufferAttachmentObjectImpl *getAttachmentImpl() const = 0;
}; };
......
...@@ -109,7 +109,7 @@ Error Renderbuffer::setStorage(const Context *context, ...@@ -109,7 +109,7 @@ Error Renderbuffer::setStorage(const Context *context,
mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat), mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
0, InitState::MayNeedInit); 0, InitState::MayNeedInit);
onStateChange(context, angle::SubjectMessage::STATE_CHANGE); onStateChange(context);
return NoError(); return NoError();
} }
...@@ -126,7 +126,7 @@ Error Renderbuffer::setStorageMultisample(const Context *context, ...@@ -126,7 +126,7 @@ Error Renderbuffer::setStorageMultisample(const Context *context,
mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat), mState.update(static_cast<GLsizei>(width), static_cast<GLsizei>(height), Format(internalformat),
static_cast<GLsizei>(samples), InitState::MayNeedInit); static_cast<GLsizei>(samples), InitState::MayNeedInit);
onStateChange(context, angle::SubjectMessage::STATE_CHANGE); onStateChange(context);
return NoError(); return NoError();
} }
...@@ -140,7 +140,7 @@ Error Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image ...@@ -140,7 +140,7 @@ Error Renderbuffer::setStorageEGLImageTarget(const Context *context, egl::Image
mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()), mState.update(static_cast<GLsizei>(image->getWidth()), static_cast<GLsizei>(image->getHeight()),
Format(image->getFormat()), 0, image->sourceInitState()); Format(image->getFormat()), 0, image->sourceInitState());
onStateChange(context, angle::SubjectMessage::STATE_CHANGE); onStateChange(context);
return NoError(); return NoError();
} }
......
...@@ -2320,7 +2320,7 @@ void State::syncProgramTextures(const Context *context) ...@@ -2320,7 +2320,7 @@ void State::syncProgramTextures(const Context *context)
} }
// Bind the texture unconditionally, to recieve completeness change notifications. // Bind the texture unconditionally, to recieve completeness change notifications.
mCompleteTextureBindings[textureUnitIndex].bind(texture); mCompleteTextureBindings[textureUnitIndex].bind(texture->getSubject());
mActiveTexturesMask.set(textureUnitIndex); mActiveTexturesMask.set(textureUnitIndex);
newActiveTextures.set(textureUnitIndex); newActiveTextures.set(textureUnitIndex);
...@@ -2404,6 +2404,18 @@ void State::setObjectDirty(GLenum target) ...@@ -2404,6 +2404,18 @@ void State::setObjectDirty(GLenum target)
} }
} }
void State::setFramebufferDirty(const Framebuffer *framebuffer) const
{
if (framebuffer == mReadFramebuffer)
{
mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
}
if (framebuffer == mDrawFramebuffer)
{
mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
}
}
void State::onProgramExecutableChange(Program *program) void State::onProgramExecutableChange(Program *program)
{ {
// OpenGL Spec: // OpenGL Spec:
......
...@@ -444,6 +444,7 @@ class State : public angle::ObserverInterface, angle::NonCopyable ...@@ -444,6 +444,7 @@ class State : public angle::ObserverInterface, angle::NonCopyable
void syncDirtyObjects(const Context *context, const DirtyObjects &bitset); void syncDirtyObjects(const Context *context, const DirtyObjects &bitset);
void syncDirtyObject(const Context *context, GLenum target); void syncDirtyObject(const Context *context, GLenum target);
void setObjectDirty(GLenum target); void setObjectDirty(GLenum target);
void setFramebufferDirty(const Framebuffer *framebuffer) const;
// This actually clears the current value dirty bits. // This actually clears the current value dirty bits.
// TODO(jmadill): Pass mutable dirty bits into Impl. // TODO(jmadill): Pass mutable dirty bits into Impl.
...@@ -601,7 +602,7 @@ class State : public angle::ObserverInterface, angle::NonCopyable ...@@ -601,7 +602,7 @@ class State : public angle::ObserverInterface, angle::NonCopyable
bool mProgramBinaryCacheEnabled; bool mProgramBinaryCacheEnabled;
DirtyBits mDirtyBits; DirtyBits mDirtyBits;
DirtyObjects mDirtyObjects; mutable DirtyObjects mDirtyObjects;
mutable AttributesMask mDirtyCurrentValues; mutable AttributesMask mDirtyCurrentValues;
}; };
......
...@@ -156,7 +156,7 @@ void Surface::postSwap(const gl::Context *context) ...@@ -156,7 +156,7 @@ void Surface::postSwap(const gl::Context *context)
if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED) if (mRobustResourceInitialization && mSwapBehavior != EGL_BUFFER_PRESERVED)
{ {
mInitState = gl::InitState::MayNeedInit; mInitState = gl::InitState::MayNeedInit;
onStateChange(context, angle::SubjectMessage::STATE_CHANGE); onStateChange(context);
} }
} }
......
...@@ -916,7 +916,7 @@ egl::Stream *Texture::getBoundStream() const ...@@ -916,7 +916,7 @@ egl::Stream *Texture::getBoundStream() const
void Texture::signalDirty(const Context *context, InitState initState) void Texture::signalDirty(const Context *context, InitState initState)
{ {
mState.mInitState = initState; mState.mInitState = initState;
onStateChange(context, angle::SubjectMessage::STATE_CHANGE); onStateChange(context);
invalidateCompletenessCache(); invalidateCompletenessCache();
} }
......
...@@ -12,11 +12,12 @@ ...@@ -12,11 +12,12 @@
#define LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_ #define LIBANGLE_RENDERER_FRAMEBUFFER_ATTACHMENT_OBJECT_IMPL_H_
#include "libANGLE/FramebufferAttachment.h" #include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/signal_utils.h"
namespace rx namespace rx
{ {
class FramebufferAttachmentObjectImpl : angle::NonCopyable class FramebufferAttachmentObjectImpl : public angle::Subject
{ {
public: public:
FramebufferAttachmentObjectImpl() {} FramebufferAttachmentObjectImpl() {}
......
...@@ -80,7 +80,10 @@ gl::Error EGLImageD3D::copyToLocalRendertarget(const gl::Context *context) ...@@ -80,7 +80,10 @@ gl::Error EGLImageD3D::copyToLocalRendertarget(const gl::Context *context)
ANGLE_TRY(getRenderTarget(context, &curRenderTarget)); ANGLE_TRY(getRenderTarget(context, &curRenderTarget));
// This only currently applies do D3D11, where it invalidates FBOs with this Image attached. // This only currently applies do D3D11, where it invalidates FBOs with this Image attached.
curRenderTarget->signalDirty(context); for (egl::ImageSibling *target : mState.targets)
{
target->getSubject()->onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
}
return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget); return mRenderer->createRenderTargetCopy(curRenderTarget, &mRenderTarget);
} }
......
...@@ -34,9 +34,6 @@ class RenderTargetD3D : public FramebufferAttachmentRenderTarget ...@@ -34,9 +34,6 @@ class RenderTargetD3D : public FramebufferAttachmentRenderTarget
virtual unsigned int getSerial() const; virtual unsigned int getSerial() const;
static unsigned int issueSerials(unsigned int count); static unsigned int issueSerials(unsigned int count);
// Only currently applies to D3D11.
virtual void signalDirty(const gl::Context *context) {}
private: private:
const unsigned int mSerial; const unsigned int mSerial;
static unsigned int mCurrentSerial; static unsigned int mCurrentSerial;
......
...@@ -112,9 +112,9 @@ gl::Error RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context, ...@@ -112,9 +112,9 @@ gl::Error RenderbufferD3D::getAttachmentRenderTarget(const gl::Context *context,
void RenderbufferD3D::deleteRenderTarget(const gl::Context *context) void RenderbufferD3D::deleteRenderTarget(const gl::Context *context)
{ {
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
if (mRenderTarget) if (mRenderTarget)
{ {
mRenderTarget->signalDirty(context);
SafeDelete(mRenderTarget); SafeDelete(mRenderTarget);
} }
} }
......
...@@ -653,6 +653,9 @@ gl::Error TextureD3D::releaseTexStorage(const gl::Context *context) ...@@ -653,6 +653,9 @@ gl::Error TextureD3D::releaseTexStorage(const gl::Context *context)
{ {
return gl::NoError(); return gl::NoError();
} }
onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
auto err = mTexStorage->onDestroy(context); auto err = mTexStorage->onDestroy(context);
SafeDelete(mTexStorage); SafeDelete(mTexStorage);
return err; return err;
...@@ -1249,6 +1252,8 @@ gl::Error TextureD3D_2D::bindTexImage(const gl::Context *context, egl::Surface * ...@@ -1249,6 +1252,8 @@ gl::Error TextureD3D_2D::bindTexImage(const gl::Context *context, egl::Surface *
mDirtyImages = false; mDirtyImages = false;
mImageArray[0]->markClean(); mImageArray[0]->markClean();
mTexStorage->setSubject(this);
return gl::NoError(); return gl::NoError();
} }
...@@ -1437,6 +1442,7 @@ gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget, ...@@ -1437,6 +1442,7 @@ gl::Error TextureD3D_2D::createCompleteStorage(bool renderTarget,
// TODO(geofflang): Determine if the texture creation succeeded // TODO(geofflang): Determine if the texture creation succeeded
outStorage->reset(mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height, outStorage->reset(mRenderer->createTextureStorage2D(internalFormat, renderTarget, width, height,
levels, hintLevelZeroOnly)); levels, hintLevelZeroOnly));
(*outStorage)->setSubject(this);
return gl::NoError(); return gl::NoError();
} }
...@@ -1456,6 +1462,8 @@ gl::Error TextureD3D_2D::setCompleteTexStorage(const gl::Context *context, ...@@ -1456,6 +1462,8 @@ gl::Error TextureD3D_2D::setCompleteTexStorage(const gl::Context *context,
ANGLE_TRY(releaseTexStorage(context)); ANGLE_TRY(releaseTexStorage(context));
mTexStorage = newCompleteTexStorage; mTexStorage = newCompleteTexStorage;
mTexStorage->setSubject(this);
mDirtyImages = true; mDirtyImages = true;
return gl::NoError(); return gl::NoError();
......
...@@ -23,6 +23,11 @@ struct Box; ...@@ -23,6 +23,11 @@ struct Box;
struct PixelUnpackState; struct PixelUnpackState;
} // namespace gl } // namespace gl
namespace angle
{
class Subject;
} // namespace angle
namespace rx namespace rx
{ {
class SwapChainD3D; class SwapChainD3D;
...@@ -32,7 +37,7 @@ class ImageD3D; ...@@ -32,7 +37,7 @@ class ImageD3D;
class TextureStorage : angle::NonCopyable class TextureStorage : angle::NonCopyable
{ {
public: public:
TextureStorage() {} TextureStorage() : mSubject(nullptr) {}
virtual ~TextureStorage() {} virtual ~TextureStorage() {}
virtual gl::Error onDestroy(const gl::Context *context); virtual gl::Error onDestroy(const gl::Context *context);
...@@ -62,6 +67,12 @@ class TextureStorage : angle::NonCopyable ...@@ -62,6 +67,12 @@ class TextureStorage : angle::NonCopyable
// This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) might override it. // This is a no-op for most implementations of TextureStorage. Some (e.g. TextureStorage11_2D) might override it.
virtual gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context, virtual gl::Error useLevelZeroWorkaroundTexture(const gl::Context *context,
bool useLevelZeroTexture); bool useLevelZeroTexture);
// Only used for D3D11.
void setSubject(const angle::Subject *subject);
protected:
const angle::Subject *mSubject;
}; };
inline gl::Error TextureStorage::onDestroy(const gl::Context *context) inline gl::Error TextureStorage::onDestroy(const gl::Context *context)
...@@ -75,6 +86,11 @@ inline gl::Error TextureStorage::useLevelZeroWorkaroundTexture(const gl::Context ...@@ -75,6 +86,11 @@ inline gl::Error TextureStorage::useLevelZeroWorkaroundTexture(const gl::Context
return gl::NoError(); return gl::NoError();
} }
inline void TextureStorage::setSubject(const angle::Subject *subject)
{
mSubject = subject;
}
using TexStoragePointer = angle::UniqueObjectPointer<TextureStorage, gl::Context>; using TexStoragePointer = angle::UniqueObjectPointer<TextureStorage, gl::Context>;
} // namespace rx } // namespace rx
......
...@@ -56,8 +56,7 @@ gl::Error MarkAttachmentsDirty(const gl::Context *context, ...@@ -56,8 +56,7 @@ gl::Error MarkAttachmentsDirty(const gl::Context *context,
void UpdateCachedRenderTarget(const gl::Context *context, void UpdateCachedRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *attachment, const gl::FramebufferAttachment *attachment,
RenderTarget11 *&cachedRenderTarget, RenderTarget11 *&cachedRenderTarget)
angle::ObserverBinding *channelBinding)
{ {
RenderTarget11 *newRenderTarget = nullptr; RenderTarget11 *newRenderTarget = nullptr;
if (attachment) if (attachment)
...@@ -71,24 +70,16 @@ void UpdateCachedRenderTarget(const gl::Context *context, ...@@ -71,24 +70,16 @@ void UpdateCachedRenderTarget(const gl::Context *context,
} }
if (newRenderTarget != cachedRenderTarget) if (newRenderTarget != cachedRenderTarget)
{ {
channelBinding->bind(newRenderTarget);
cachedRenderTarget = newRenderTarget; cachedRenderTarget = newRenderTarget;
} }
} }
} // anonymous namespace } // anonymous namespace
Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer) Framebuffer11::Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer)
: FramebufferD3D(data, renderer), : FramebufferD3D(data, renderer), mRenderer(renderer), mCachedDepthStencilRenderTarget(nullptr)
mRenderer(renderer),
mCachedDepthStencilRenderTarget(nullptr),
mDepthStencilRenderTargetDirty(this, gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS)
{ {
ASSERT(mRenderer != nullptr); ASSERT(mRenderer != nullptr);
mCachedColorRenderTargets.fill(nullptr); mCachedColorRenderTargets.fill(nullptr);
for (size_t colorIndex = 0; colorIndex < data.getColorAttachments().size(); ++colorIndex)
{
mColorRenderTargetsDirty.emplace_back(this, colorIndex);
}
} }
Framebuffer11::~Framebuffer11() Framebuffer11::~Framebuffer11()
...@@ -390,23 +381,19 @@ GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *rende ...@@ -390,23 +381,19 @@ GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *rende
void Framebuffer11::updateColorRenderTarget(const gl::Context *context, size_t colorIndex) void Framebuffer11::updateColorRenderTarget(const gl::Context *context, size_t colorIndex)
{ {
UpdateCachedRenderTarget(context, mState.getColorAttachment(colorIndex), UpdateCachedRenderTarget(context, mState.getColorAttachment(colorIndex),
mCachedColorRenderTargets[colorIndex], mCachedColorRenderTargets[colorIndex]);
&mColorRenderTargetsDirty[colorIndex]);
} }
void Framebuffer11::updateDepthStencilRenderTarget(const gl::Context *context) void Framebuffer11::updateDepthStencilRenderTarget(const gl::Context *context)
{ {
UpdateCachedRenderTarget(context, mState.getDepthOrStencilAttachment(), UpdateCachedRenderTarget(context, mState.getDepthOrStencilAttachment(),
mCachedDepthStencilRenderTarget, &mDepthStencilRenderTargetDirty); mCachedDepthStencilRenderTarget);
} }
void Framebuffer11::syncState(const gl::Context *context, void Framebuffer11::syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) const gl::Framebuffer::DirtyBits &dirtyBits)
{ {
const auto &mergedDirtyBits = dirtyBits | mInternalDirtyBits; for (auto dirtyBit : dirtyBits)
mInternalDirtyBits.reset();
for (auto dirtyBit : mergedDirtyBits)
{ {
switch (dirtyBit) switch (dirtyBit)
{ {
...@@ -434,9 +421,6 @@ void Framebuffer11::syncState(const gl::Context *context, ...@@ -434,9 +421,6 @@ void Framebuffer11::syncState(const gl::Context *context,
} }
} }
// We should not have dirtied any additional state during our sync.
ASSERT(!mInternalDirtyBits.any());
FramebufferD3D::syncState(context, dirtyBits); FramebufferD3D::syncState(context, dirtyBits);
// Call this last to allow the state manager to take advantage of the cached render targets. // Call this last to allow the state manager to take advantage of the cached render targets.
...@@ -449,27 +433,6 @@ void Framebuffer11::syncState(const gl::Context *context, ...@@ -449,27 +433,6 @@ void Framebuffer11::syncState(const gl::Context *context,
} }
} }
void Framebuffer11::onSubjectStateChange(const gl::Context *context,
angle::SubjectIndex index,
angle::SubjectMessage message)
{
if (index == gl::IMPLEMENTATION_MAX_FRAMEBUFFER_ATTACHMENTS)
{
// Stencil is redundant in this case.
mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT);
mCachedDepthStencilRenderTarget = nullptr;
}
else
{
mInternalDirtyBits.set(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 + index);
mCachedColorRenderTargets[index] = nullptr;
}
// Notify the context we need to re-validate the RenderTarget.
// TODO(jmadill): Check that we're the active draw framebuffer.
mRenderer->getStateManager()->invalidateRenderTarget();
}
gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
{ {
const gl::FramebufferAttachment *attachment = mState.getFirstNonNullAttachment(); const gl::FramebufferAttachment *attachment = mState.getFirstNonNullAttachment();
...@@ -480,19 +443,8 @@ gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const ...@@ -480,19 +443,8 @@ gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
return gl::NoError(); return gl::NoError();
} }
bool Framebuffer11::hasAnyInternalDirtyBit() const
{
return mInternalDirtyBits.any();
}
void Framebuffer11::syncInternalState(const gl::Context *context)
{
syncState(context, gl::Framebuffer::DirtyBits());
}
RenderTarget11 *Framebuffer11::getFirstRenderTarget() const RenderTarget11 *Framebuffer11::getFirstRenderTarget() const
{ {
ASSERT(mInternalDirtyBits.none());
for (auto *renderTarget : mCachedColorRenderTargets) for (auto *renderTarget : mCachedColorRenderTargets)
{ {
if (renderTarget) if (renderTarget)
......
...@@ -17,7 +17,7 @@ namespace rx ...@@ -17,7 +17,7 @@ namespace rx
{ {
class Renderer11; class Renderer11;
class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface class Framebuffer11 : public FramebufferD3D
{ {
public: public:
Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer); Framebuffer11(const gl::FramebufferState &data, Renderer11 *renderer);
...@@ -38,7 +38,7 @@ class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface ...@@ -38,7 +38,7 @@ class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface
void syncState(const gl::Context *context, void syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override; const gl::Framebuffer::DirtyBits &dirtyBits) override;
const RenderTargetArray &getCachedColorRenderTargets() const const RenderTargetArray11 &getCachedColorRenderTargets() const
{ {
return mCachedColorRenderTargets; return mCachedColorRenderTargets;
} }
...@@ -49,14 +49,6 @@ class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface ...@@ -49,14 +49,6 @@ class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface
RenderTarget11 *getFirstRenderTarget() const; RenderTarget11 *getFirstRenderTarget() const;
bool hasAnyInternalDirtyBit() const;
void syncInternalState(const gl::Context *context);
// Observer implementation.
void onSubjectStateChange(const gl::Context *context,
angle::SubjectIndex index,
angle::SubjectMessage message) override;
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override; gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
private: private:
...@@ -93,15 +85,10 @@ class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface ...@@ -93,15 +85,10 @@ class Framebuffer11 : public FramebufferD3D, public angle::ObserverInterface
void updateDepthStencilRenderTarget(const gl::Context *context); void updateDepthStencilRenderTarget(const gl::Context *context);
Renderer11 *const mRenderer; Renderer11 *const mRenderer;
RenderTargetArray mCachedColorRenderTargets; RenderTargetArray11 mCachedColorRenderTargets;
RenderTarget11 *mCachedDepthStencilRenderTarget; RenderTarget11 *mCachedDepthStencilRenderTarget;
std::vector<angle::ObserverBinding> mColorRenderTargetsDirty;
angle::ObserverBinding mDepthStencilRenderTargetDirty;
gl::Framebuffer::DirtyBits mInternalDirtyBits;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_ #endif // LIBANGLE_RENDERER_D3D_D3D11_FRAMBUFFER11_H_
...@@ -200,15 +200,6 @@ RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(form ...@@ -200,15 +200,6 @@ RenderTarget11::RenderTarget11(const d3d11::Format &formatSet) : mFormatSet(form
RenderTarget11::~RenderTarget11() RenderTarget11::~RenderTarget11()
{ {
ASSERT(!hasObservers());
}
void RenderTarget11::signalDirty(const gl::Context *context)
{
onStateChange(context, angle::SubjectMessage::STATE_CHANGE);
// Clear the list. We can't do this in the receiver because it would mutate during iteration.
resetObservers();
} }
TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv, TextureRenderTarget11::TextureRenderTarget11(d3d11::RenderTargetView &&rtv,
......
...@@ -20,7 +20,7 @@ namespace rx ...@@ -20,7 +20,7 @@ namespace rx
class SwapChain11; class SwapChain11;
class Renderer11; class Renderer11;
class RenderTarget11 : public RenderTargetD3D, public angle::Subject class RenderTarget11 : public RenderTargetD3D
{ {
public: public:
RenderTarget11(const d3d11::Format &formatSet); RenderTarget11(const d3d11::Format &formatSet);
...@@ -34,8 +34,6 @@ class RenderTarget11 : public RenderTargetD3D, public angle::Subject ...@@ -34,8 +34,6 @@ class RenderTarget11 : public RenderTargetD3D, public angle::Subject
virtual unsigned int getSubresourceIndex() const = 0; virtual unsigned int getSubresourceIndex() const = 0;
void signalDirty(const gl::Context *context) override;
const d3d11::Format &getFormatSet() const { return mFormatSet; } const d3d11::Format &getFormatSet() const { return mFormatSet; }
protected: protected:
......
...@@ -1751,7 +1751,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb ...@@ -1751,7 +1751,6 @@ gl::Error StateManager11::syncFramebuffer(const gl::Context *context, gl::Frameb
// this will not report any gl error but will cause the calling method to return. // this will not report any gl error but will cause the calling method to return.
if (framebuffer->id() == 0) if (framebuffer->id() == 0)
{ {
ASSERT(!framebuffer11->hasAnyInternalDirtyBit());
const gl::Extents &size = framebuffer->getFirstColorbuffer()->getSize(); const gl::Extents &size = framebuffer->getFirstColorbuffer()->getSize();
if (size.width == 0 || size.height == 0) if (size.width == 0 || size.height == 0)
{ {
...@@ -1983,12 +1982,6 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod ...@@ -1983,12 +1982,6 @@ gl::Error StateManager11::updateState(const gl::Context *context, GLenum drawMod
Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer); Framebuffer11 *framebuffer11 = GetImplAs<Framebuffer11>(framebuffer);
ANGLE_TRY(framebuffer11->markAttachmentsDirty(context)); ANGLE_TRY(framebuffer11->markAttachmentsDirty(context));
if (framebuffer11->hasAnyInternalDirtyBit())
{
ASSERT(framebuffer->id() != 0);
framebuffer11->syncInternalState(context);
}
bool pointDrawMode = (drawMode == GL_POINTS); bool pointDrawMode = (drawMode == GL_POINTS);
if (pointDrawMode != mCurRasterState.pointDrawMode) if (pointDrawMode != mCurRasterState.pointDrawMode)
{ {
......
...@@ -30,40 +30,6 @@ ...@@ -30,40 +30,6 @@
namespace rx namespace rx
{ {
namespace
{
void InvalidateRenderTarget(const gl::Context *context, RenderTarget11 *renderTarget)
{
if (renderTarget)
{
renderTarget->signalDirty(context);
}
}
RenderTarget11 *GetRenderTarget(std::unique_ptr<RenderTarget11> *pointer)
{
return pointer->get();
}
template <typename KeyT>
RenderTarget11 *GetRenderTarget(std::pair<KeyT, std::unique_ptr<RenderTarget11>> *pair)
{
return pair->second.get();
}
template <typename T>
void InvalidateRenderTargetContainer(const gl::Context *context, T *renderTargetContainer)
{
for (auto &rt : *renderTargetContainer)
{
InvalidateRenderTarget(context, GetRenderTarget(&rt));
}
}
} // anonymous namespace
TextureStorage11::SamplerKey::SamplerKey() TextureStorage11::SamplerKey::SamplerKey()
: baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false) : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false)
{ {
...@@ -928,10 +894,6 @@ gl::Error TextureStorage11_2D::onDestroy(const gl::Context *context) ...@@ -928,10 +894,6 @@ gl::Error TextureStorage11_2D::onDestroy(const gl::Context *context)
mRenderer->getStateManager()->invalidateBoundViews(); mRenderer->getStateManager()->invalidateBoundViews();
} }
// Invalidate RenderTargets.
InvalidateRenderTargetContainer(context, &mRenderTarget);
InvalidateRenderTarget(context, mLevelZeroRenderTarget.get());
return gl::NoError(); return gl::NoError();
} }
...@@ -1024,18 +986,8 @@ gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context * ...@@ -1024,18 +986,8 @@ gl::Error TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *
if (lastSetting != mUseLevelZeroTexture) if (lastSetting != mUseLevelZeroTexture)
{ {
// Mark everything as dirty to be conservative. ASSERT(mSubject);
if (mLevelZeroRenderTarget) mSubject->onStateChange(context, angle::SubjectMessage::DEPENDENT_DIRTY_BITS);
{
mLevelZeroRenderTarget->signalDirty(context);
}
for (auto &renderTarget : mRenderTarget)
{
if (renderTarget)
{
renderTarget->signalDirty(context);
}
}
} }
return gl::NoError(); return gl::NoError();
...@@ -1892,12 +1844,6 @@ gl::Error TextureStorage11_Cube::onDestroy(const gl::Context *context) ...@@ -1892,12 +1844,6 @@ gl::Error TextureStorage11_Cube::onDestroy(const gl::Context *context)
} }
} }
for (auto &faceRenderTargets : mRenderTarget)
{
InvalidateRenderTargetContainer(context, &faceRenderTargets);
}
InvalidateRenderTargetContainer(context, &mLevelZeroRenderTarget);
return gl::NoError(); return gl::NoError();
} }
...@@ -2542,9 +2488,6 @@ gl::Error TextureStorage11_3D::onDestroy(const gl::Context *context) ...@@ -2542,9 +2488,6 @@ gl::Error TextureStorage11_3D::onDestroy(const gl::Context *context)
} }
} }
InvalidateRenderTargetContainer(context, &mLevelRenderTargets);
InvalidateRenderTargetContainer(context, &mLevelLayerRenderTargets);
return gl::NoError(); return gl::NoError();
} }
...@@ -2868,8 +2811,6 @@ gl::Error TextureStorage11_2DArray::onDestroy(const gl::Context *context) ...@@ -2868,8 +2811,6 @@ gl::Error TextureStorage11_2DArray::onDestroy(const gl::Context *context)
} }
mAssociatedImages.clear(); mAssociatedImages.clear();
InvalidateRenderTargetContainer(context, &mRenderTargets);
return gl::NoError(); return gl::NoError();
} }
...@@ -3249,7 +3190,6 @@ TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *rende ...@@ -3249,7 +3190,6 @@ TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *rende
gl::Error TextureStorage11_2DMultisample::onDestroy(const gl::Context *context) gl::Error TextureStorage11_2DMultisample::onDestroy(const gl::Context *context)
{ {
InvalidateRenderTarget(context, mRenderTarget.get());
mRenderTarget.reset(); mRenderTarget.reset();
return gl::NoError(); return gl::NoError();
} }
......
...@@ -33,7 +33,7 @@ class Renderer11; ...@@ -33,7 +33,7 @@ class Renderer11;
class RenderTarget11; class RenderTarget11;
struct Renderer11DeviceCaps; struct Renderer11DeviceCaps;
using RenderTargetArray = std::array<RenderTarget11 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>; using RenderTargetArray11 = std::array<RenderTarget11 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
using RTVArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>; using RTVArray = std::array<ID3D11RenderTargetView *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d11 namespace gl_d3d11
......
...@@ -24,11 +24,33 @@ ...@@ -24,11 +24,33 @@
namespace rx namespace rx
{ {
namespace
{
void UpdateCachedRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *attachment,
RenderTarget9 *&cachedRenderTarget)
{
RenderTarget9 *newRenderTarget = nullptr;
if (attachment)
{
// TODO(jmadill): Don't swallow this error.
gl::Error error = attachment->getRenderTarget(context, &newRenderTarget);
if (error.isError())
{
ERR() << "Internal rendertarget error: " << error;
}
}
if (newRenderTarget != cachedRenderTarget)
{
cachedRenderTarget = newRenderTarget;
}
}
} // anonymous namespace
Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer) Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer)
: FramebufferD3D(data, renderer), mRenderer(renderer) : FramebufferD3D(data, renderer), mRenderer(renderer), mCachedDepthStencilRenderTarget(nullptr)
{ {
ASSERT(mRenderer != nullptr); ASSERT(mRenderer != nullptr);
mCachedColorRenderTargets.fill(nullptr);
} }
Framebuffer9::~Framebuffer9() Framebuffer9::~Framebuffer9()
...@@ -61,10 +83,8 @@ gl::Error Framebuffer9::invalidateSub(const gl::Context *context, ...@@ -61,10 +83,8 @@ gl::Error Framebuffer9::invalidateSub(const gl::Context *context,
gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams) gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams)
{ {
const gl::FramebufferAttachment *colorAttachment = mState.getColorAttachment(0); ANGLE_TRY(mRenderer->applyRenderTarget(context, mCachedColorRenderTargets[0],
const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment(); mCachedDepthStencilRenderTarget));
ANGLE_TRY(mRenderer->applyRenderTarget(context, colorAttachment, depthStencilAttachment));
const gl::State &glState = context->getGLState(); const gl::State &glState = context->getGLState();
float nearZ = glState.getNearPlane(); float nearZ = glState.getNearPlane();
...@@ -74,7 +94,8 @@ gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParamet ...@@ -74,7 +94,8 @@ gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParamet
mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled());
return mRenderer->clear(context, clearParams, colorAttachment, depthStencilAttachment); return mRenderer->clear(context, clearParams, mCachedColorRenderTargets[0],
mCachedDepthStencilRenderTarget);
} }
gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context, gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
...@@ -111,15 +132,17 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context, ...@@ -111,15 +132,17 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context,
HRESULT result; HRESULT result;
IDirect3DSurface9 *systemSurface = nullptr; IDirect3DSurface9 *systemSurface = nullptr;
bool directToPixels = !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() && bool directToPixels =
area.x == 0 && area.y == 0 && !pack.reverseRowOrder && pack.alignment <= 4 && mRenderer->getShareHandleSupport() &&
static_cast<UINT>(area.width) == desc.Width && static_cast<UINT>(area.height) == desc.Height && area.x == 0 && area.y == 0 && static_cast<UINT>(area.width) == desc.Width &&
desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; static_cast<UINT>(area.height) == desc.Height && desc.Format == D3DFMT_A8R8G8B8 &&
format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
if (directToPixels) if (directToPixels)
{ {
// Use the pixels ptr as a shared handle to write directly into client's memory // Use the pixels ptr as a shared handle to write directly into client's memory
result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
D3DPOOL_SYSTEMMEM, &systemSurface, reinterpret_cast<void**>(&pixels)); D3DPOOL_SYSTEMMEM, &systemSurface,
reinterpret_cast<void **>(&pixels));
if (FAILED(result)) if (FAILED(result))
{ {
// Try again without the shared handle // Try again without the shared handle
...@@ -408,4 +431,50 @@ gl::Error Framebuffer9::getSamplePosition(size_t index, GLfloat *xy) const ...@@ -408,4 +431,50 @@ gl::Error Framebuffer9::getSamplePosition(size_t index, GLfloat *xy) const
return gl::InternalError() << "getSamplePosition is unsupported to d3d9."; return gl::InternalError() << "getSamplePosition is unsupported to d3d9.";
} }
void Framebuffer9::syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits)
{
FramebufferD3D::syncState(context, dirtyBits);
for (auto dirtyBit : dirtyBits)
{
switch (dirtyBit)
{
case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
updateDepthStencilRenderTarget(context);
break;
case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
break;
case gl::Framebuffer::DIRTY_BIT_DEFAULT_WIDTH:
case gl::Framebuffer::DIRTY_BIT_DEFAULT_HEIGHT:
case gl::Framebuffer::DIRTY_BIT_DEFAULT_SAMPLES:
case gl::Framebuffer::DIRTY_BIT_DEFAULT_FIXED_SAMPLE_LOCATIONS:
break;
default:
{
ASSERT(gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 == 0 &&
dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
size_t colorIndex =
static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
updateColorRenderTarget(context, colorIndex);
break;
}
}
}
}
void Framebuffer9::updateColorRenderTarget(const gl::Context *context, size_t colorIndex)
{
UpdateCachedRenderTarget(context, mState.getColorAttachment(colorIndex),
mCachedColorRenderTargets[colorIndex]);
}
void Framebuffer9::updateDepthStencilRenderTarget(const gl::Context *context)
{
UpdateCachedRenderTarget(context, mState.getDepthOrStencilAttachment(),
mCachedDepthStencilRenderTarget);
}
} // namespace rx } // namespace rx
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_ #define LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
#include "libANGLE/renderer/d3d/FramebufferD3D.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h"
#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
namespace rx namespace rx
{ {
...@@ -32,6 +33,19 @@ class Framebuffer9 : public FramebufferD3D ...@@ -32,6 +33,19 @@ class Framebuffer9 : public FramebufferD3D
gl::Error getSamplePosition(size_t index, GLfloat *xy) const override; gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
void syncState(const gl::Context *context,
const gl::Framebuffer::DirtyBits &dirtyBits) override;
const RenderTargetArray9 &getCachedColorRenderTargets() const
{
return mCachedColorRenderTargets;
}
const RenderTarget9 *getCachedDepthStencilRenderTarget() const
{
return mCachedDepthStencilRenderTarget;
}
private: private:
gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override; gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override;
...@@ -55,9 +69,15 @@ class Framebuffer9 : public FramebufferD3D ...@@ -55,9 +69,15 @@ class Framebuffer9 : public FramebufferD3D
GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override; GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override;
void updateColorRenderTarget(const gl::Context *context, size_t colorIndex);
void updateDepthStencilRenderTarget(const gl::Context *context);
Renderer9 *const mRenderer; Renderer9 *const mRenderer;
RenderTargetArray9 mCachedColorRenderTargets;
RenderTarget9 *mCachedDepthStencilRenderTarget;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_ #endif // LIBANGLE_RENDERER_D3D_D3D9_FRAMBUFFER9_H_
...@@ -36,6 +36,7 @@ class Blit9; ...@@ -36,6 +36,7 @@ class Blit9;
class Context9; class Context9;
class IndexDataManager; class IndexDataManager;
class ProgramD3D; class ProgramD3D;
class RenderTarget9;
class StreamingIndexBufferInterface; class StreamingIndexBufferInterface;
class StaticIndexBufferInterface; class StaticIndexBufferInterface;
class VertexDataManager; class VertexDataManager;
...@@ -139,10 +140,9 @@ class Renderer9 : public RendererD3D ...@@ -139,10 +140,9 @@ class Renderer9 : public RendererD3D
GLenum frontFace, GLenum frontFace,
bool ignoreViewport); bool ignoreViewport);
gl::Error applyRenderTarget(const gl::Context *context, const gl::Framebuffer *frameBuffer);
gl::Error applyRenderTarget(const gl::Context *context, gl::Error applyRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *colorAttachment, const RenderTarget9 *colorRenderTarget,
const gl::FramebufferAttachment *depthStencilAttachment); const RenderTarget9 *depthStencilRenderTarget);
gl::Error applyUniforms(ProgramD3D *programD3D); gl::Error applyUniforms(ProgramD3D *programD3D);
bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize);
gl::Error applyVertexBuffer(const gl::Context *context, gl::Error applyVertexBuffer(const gl::Context *context,
...@@ -160,8 +160,8 @@ class Renderer9 : public RendererD3D ...@@ -160,8 +160,8 @@ class Renderer9 : public RendererD3D
gl::Error clear(const gl::Context *context, gl::Error clear(const gl::Context *context,
const ClearParameters &clearParams, const ClearParameters &clearParams,
const gl::FramebufferAttachment *colorBuffer, const RenderTarget9 *colorRenderTarget,
const gl::FramebufferAttachment *depthStencilBuffer); const RenderTarget9 *depthStencilRenderTarget);
void markAllStateDirty(); void markAllStateDirty();
...@@ -436,9 +436,9 @@ class Renderer9 : public RendererD3D ...@@ -436,9 +436,9 @@ class Renderer9 : public RendererD3D
gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB); gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB);
gl::Error getNullColorbuffer(const gl::Context *context, gl::Error getNullColorRenderTarget(const gl::Context *context,
const gl::FramebufferAttachment *depthbuffer, const RenderTarget9 *depthRenderTarget,
const gl::FramebufferAttachment **outColorBuffer); const RenderTarget9 **outColorRenderTarget);
D3DPOOL getBufferPool(DWORD usage) const; D3DPOOL getBufferPool(DWORD usage) const;
...@@ -523,13 +523,16 @@ class Renderer9 : public RendererD3D ...@@ -523,13 +523,16 @@ class Renderer9 : public RendererD3D
{ {
NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12
}; };
struct NullColorbufferCacheEntry struct NullRenderTargetCacheEntry
{ {
UINT lruCount; UINT lruCount;
int width; int width;
int height; int height;
gl::FramebufferAttachment *buffer; RenderTarget9 *renderTarget;
} mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES]; };
std::array<NullRenderTargetCacheEntry, NUM_NULL_COLORBUFFER_CACHE_ENTRIES>
mNullRenderTargetCache;
UINT mMaxNullColorbufferLRU; UINT mMaxNullColorbufferLRU;
std::vector<TranslatedAttribute> mTranslatedAttribCache; std::vector<TranslatedAttribute> mTranslatedAttribCache;
......
...@@ -24,6 +24,8 @@ namespace rx ...@@ -24,6 +24,8 @@ namespace rx
{ {
class RenderTarget9; class RenderTarget9;
using RenderTargetArray9 = std::array<RenderTarget9 *, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>;
namespace gl_d3d9 namespace gl_d3d9
{ {
......
...@@ -28,6 +28,7 @@ using SubjectIndex = size_t; ...@@ -28,6 +28,7 @@ using SubjectIndex = size_t;
enum class SubjectMessage enum class SubjectMessage
{ {
STATE_CHANGE, STATE_CHANGE,
DEPENDENT_DIRTY_BITS,
}; };
// The observing class inherits from this interface class. // The observing class inherits from this interface class.
......
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