summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp271
1 files changed, 97 insertions, 174 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index 1a4734b269..82967aced0 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -8,6 +8,7 @@
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
+#include "common/BitSetIterator.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
@@ -53,7 +54,7 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer();
if (mask & GL_COLOR_BUFFER_BIT)
{
- if (framebufferObject->hasEnabledColorAttachment())
+ if (framebufferObject->hasEnabledDrawBuffer())
{
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
@@ -85,67 +86,28 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
}
FramebufferD3D::FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer)
- : FramebufferImpl(data),
- mRenderer(renderer),
- mColorAttachmentsForRender(mData.mColorAttachments.size(), nullptr),
- mInvalidateColorAttachmentCache(true)
+ : FramebufferImpl(data), mRenderer(renderer)
{
- ASSERT(mRenderer != nullptr);
}
FramebufferD3D::~FramebufferD3D()
{
}
-void FramebufferD3D::setColorAttachment(size_t, const gl::FramebufferAttachment *)
-{
- mInvalidateColorAttachmentCache = true;
-}
-
-void FramebufferD3D::setDepthAttachment(const gl::FramebufferAttachment *)
-{
-}
-
-void FramebufferD3D::setStencilAttachment(const gl::FramebufferAttachment *)
-{
-}
-
-void FramebufferD3D::setDepthStencilAttachment(const gl::FramebufferAttachment *)
-{
-}
-
-void FramebufferD3D::setDrawBuffers(size_t, const GLenum *)
-{
- mInvalidateColorAttachmentCache = true;
-}
-
-void FramebufferD3D::setReadBuffer(GLenum)
-{
-}
-
-gl::Error FramebufferD3D::invalidate(size_t, const GLenum *)
-{
- // No-op in D3D
- return gl::Error(GL_NO_ERROR);
-}
-
-gl::Error FramebufferD3D::invalidateSub(size_t, const GLenum *, const gl::Rectangle &)
-{
- // No-op in D3D
- return gl::Error(GL_NO_ERROR);
-}
-
gl::Error FramebufferD3D::clear(const gl::Data &data, GLbitfield mask)
{
const gl::State &state = *data.state;
ClearParameters clearParams = GetClearParameters(state, mask);
- return clear(state, clearParams);
+ return clear(data, clearParams);
}
-gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
+gl::Error FramebufferD3D::clearBufferfv(const gl::Data &data,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values)
{
// glClearBufferfv can be called to clear the color buffer or depth buffer
- ClearParameters clearParams = GetClearParameters(state, 0);
+ ClearParameters clearParams = GetClearParameters(*data.state, 0);
if (buffer == GL_COLOR)
{
@@ -163,13 +125,16 @@ gl::Error FramebufferD3D::clearBufferfv(const gl::State &state, GLenum buffer, G
clearParams.depthClearValue = values[0];
}
- return clear(state, clearParams);
+ return clear(data, clearParams);
}
-gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
+gl::Error FramebufferD3D::clearBufferuiv(const gl::Data &data,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values)
{
// glClearBufferuiv can only be called to clear a color buffer
- ClearParameters clearParams = GetClearParameters(state, 0);
+ ClearParameters clearParams = GetClearParameters(*data.state, 0);
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
@@ -177,13 +142,16 @@ gl::Error FramebufferD3D::clearBufferuiv(const gl::State &state, GLenum buffer,
clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
clearParams.colorClearType = GL_UNSIGNED_INT;
- return clear(state, clearParams);
+ return clear(data, clearParams);
}
-gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
+gl::Error FramebufferD3D::clearBufferiv(const gl::Data &data,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values)
{
// glClearBufferiv can be called to clear the color buffer or stencil buffer
- ClearParameters clearParams = GetClearParameters(state, 0);
+ ClearParameters clearParams = GetClearParameters(*data.state, 0);
if (buffer == GL_COLOR)
{
@@ -201,19 +169,23 @@ gl::Error FramebufferD3D::clearBufferiv(const gl::State &state, GLenum buffer, G
clearParams.stencilClearValue = values[1];
}
- return clear(state, clearParams);
+ return clear(data, clearParams);
}
-gl::Error FramebufferD3D::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+gl::Error FramebufferD3D::clearBufferfi(const gl::Data &data,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
{
// glClearBufferfi can only be called to clear a depth stencil buffer
- ClearParameters clearParams = GetClearParameters(state, 0);
+ ClearParameters clearParams = GetClearParameters(*data.state, 0);
clearParams.clearDepth = true;
clearParams.depthClearValue = depth;
clearParams.clearStencil = true;
clearParams.stencilClearValue = stencil;
- return clear(state, clearParams);
+ return clear(data, clearParams);
}
GLenum FramebufferD3D::getImplementationColorReadFormat() const
@@ -226,7 +198,7 @@ GLenum FramebufferD3D::getImplementationColorReadFormat() const
}
RenderTargetD3D *attachmentRenderTarget = NULL;
- gl::Error error = GetAttachmentRenderTarget(readAttachment, &attachmentRenderTarget);
+ gl::Error error = readAttachment->getRenderTarget(&attachmentRenderTarget);
if (error.isError())
{
return GL_NONE;
@@ -248,7 +220,7 @@ GLenum FramebufferD3D::getImplementationColorReadType() const
}
RenderTargetD3D *attachmentRenderTarget = NULL;
- gl::Error error = GetAttachmentRenderTarget(readAttachment, &attachmentRenderTarget);
+ gl::Error error = readAttachment->getRenderTarget(&attachmentRenderTarget);
if (error.isError())
{
return GL_NONE;
@@ -264,17 +236,15 @@ gl::Error FramebufferD3D::readPixels(const gl::State &state, const gl::Rectangle
{
const gl::PixelPackState &packState = state.getPackState();
- if (packState.rowLength != 0 || packState.skipRows != 0 || packState.skipPixels != 0)
- {
- UNIMPLEMENTED();
- return gl::Error(GL_INVALID_OPERATION, "invalid pixel store parameters in readPixels");
- }
-
GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type);
const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
- GLuint outputPitch = sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, 0);
+ GLuint outputPitch =
+ sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength);
+ GLsizei outputSkipBytes = sizedFormatInfo.computeSkipPixels(
+ outputPitch, 0, 0, packState.skipRows, packState.skipPixels);
- return readPixels(area, format, type, outputPitch, packState, reinterpret_cast<uint8_t*>(pixels));
+ return readPixelsImpl(area, format, type, outputPitch, packState,
+ reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes);
}
gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
@@ -291,7 +261,7 @@ gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sour
bool blitStencil = false;
if ((mask & GL_STENCIL_BUFFER_BIT) &&
sourceFramebuffer->getStencilbuffer() != nullptr &&
- mData.mStencilAttachment != nullptr)
+ mData.getStencilAttachment() != nullptr)
{
blitStencil = true;
}
@@ -299,7 +269,7 @@ gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sour
bool blitDepth = false;
if ((mask & GL_DEPTH_BUFFER_BIT) &&
sourceFramebuffer->getDepthbuffer() != nullptr &&
- mData.mDepthAttachment != nullptr)
+ mData.getDepthAttachment() != nullptr)
{
blitDepth = true;
}
@@ -318,146 +288,99 @@ gl::Error FramebufferD3D::blit(const gl::State &state, const gl::Rectangle &sour
return gl::Error(GL_NO_ERROR);
}
-GLenum FramebufferD3D::checkStatus() const
+bool FramebufferD3D::checkStatus() const
{
+ // 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 (mData.getDepthAttachment() != nullptr && mData.getStencilAttachment() != nullptr &&
+ mData.getDepthStencilAttachment() == nullptr)
+ {
+ return false;
+ }
+
// D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
- for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); colorAttachment++)
+ const auto &colorAttachments = mData.getColorAttachments();
+ for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
{
- const gl::FramebufferAttachment *attachment = mData.mColorAttachments[colorAttachment];
- if (attachment != nullptr)
+ const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachment];
+ if (attachment.isAttached())
{
for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++)
{
- const gl::FramebufferAttachment *prevAttachment = mData.mColorAttachments[prevColorAttachment];
- if (prevAttachment != nullptr &&
- (attachment->id() == prevAttachment->id() &&
- attachment->type() == prevAttachment->type()))
+ const gl::FramebufferAttachment &prevAttachment = colorAttachments[prevColorAttachment];
+ if (prevAttachment.isAttached() &&
+ (attachment.id() == prevAttachment.id() &&
+ attachment.type() == prevAttachment.type()))
{
- return GL_FRAMEBUFFER_UNSUPPORTED;
+ return false;
}
}
}
}
- return GL_FRAMEBUFFER_COMPLETE;
+ // D3D requires all render targets to have the same dimensions.
+ if (!mData.attachmentsHaveSameDimensions())
+ {
+ return false;
+ }
+
+ return true;
}
-const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const Workarounds &workarounds) const
+void FramebufferD3D::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
{
- if (!workarounds.mrtPerfWorkaround)
- {
- return mData.mColorAttachments;
- }
+ bool invalidateColorAttachmentCache = false;
- if (!mInvalidateColorAttachmentCache)
+ if (!mColorAttachmentsForRender.valid())
{
- return mColorAttachmentsForRender;
+ invalidateColorAttachmentCache = true;
}
- // Does not actually free memory
- mColorAttachmentsForRender.clear();
-
- for (size_t attachmentIndex = 0; attachmentIndex < mData.mColorAttachments.size(); ++attachmentIndex)
+ for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
{
- GLenum drawBufferState = mData.mDrawBufferStates[attachmentIndex];
- gl::FramebufferAttachment *colorAttachment = mData.mColorAttachments[attachmentIndex];
-
- if (colorAttachment != nullptr && drawBufferState != GL_NONE)
+ if ((dirtyBit >= gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 &&
+ dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) ||
+ dirtyBit == gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS)
{
- ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
- mColorAttachmentsForRender.push_back(colorAttachment);
+ invalidateColorAttachmentCache = true;
}
}
- mInvalidateColorAttachmentCache = false;
- return mColorAttachmentsForRender;
-}
-
-gl::Error GetAttachmentRenderTarget(const gl::FramebufferAttachment *attachment, RenderTargetD3D **outRT)
-{
- if (attachment->type() == GL_TEXTURE)
- {
- gl::Texture *texture = attachment->getTexture();
- ASSERT(texture);
- TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
- const gl::ImageIndex *index = attachment->getTextureImageIndex();
- ASSERT(index);
- return textureD3D->getRenderTarget(*index, outRT);
- }
- else if (attachment->type() == GL_RENDERBUFFER)
+ if (!invalidateColorAttachmentCache)
{
- gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
- ASSERT(renderbuffer);
- RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
- *outRT = renderbufferD3D->getRenderTarget();
- return gl::Error(GL_NO_ERROR);
+ return;
}
- else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
- {
- const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
- const egl::Surface *surface = defaultAttachment->getSurface();
- ASSERT(surface);
- const SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
- ASSERT(surfaceD3D);
- if (defaultAttachment->getBinding() == GL_BACK)
- {
- *outRT = surfaceD3D->getSwapChain()->getColorRenderTarget();
- }
- else
- {
- *outRT = surfaceD3D->getSwapChain()->getDepthStencilRenderTarget();
- }
- return gl::Error(GL_NO_ERROR);
- }
- else
- {
- UNREACHABLE();
- return gl::Error(GL_INVALID_OPERATION);
- }
-}
+ // Does not actually free memory
+ gl::AttachmentList colorAttachmentsForRender;
-// Note: RenderTarget serials should ideally be in the RenderTargets themselves.
-unsigned int GetAttachmentSerial(const gl::FramebufferAttachment *attachment)
-{
- if (attachment->type() == GL_TEXTURE)
- {
- gl::Texture *texture = attachment->getTexture();
- ASSERT(texture);
- TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
- const gl::ImageIndex *index = attachment->getTextureImageIndex();
- ASSERT(index);
- return textureD3D->getRenderTargetSerial(*index);
- }
- else if (attachment->type() == GL_RENDERBUFFER)
- {
- gl::Renderbuffer *renderbuffer = attachment->getRenderbuffer();
- ASSERT(renderbuffer);
- RenderbufferD3D *renderbufferD3D = RenderbufferD3D::makeRenderbufferD3D(renderbuffer->getImplementation());
- return renderbufferD3D->getRenderTargetSerial();
- }
- else if (attachment->type() == GL_FRAMEBUFFER_DEFAULT)
+ const auto &colorAttachments = mData.getColorAttachments();
+ const auto &drawBufferStates = mData.getDrawBufferStates();
+ const auto &workarounds = mRenderer->getWorkarounds();
+
+ for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
{
- const gl::DefaultAttachment *defaultAttachment = static_cast<const gl::DefaultAttachment *>(attachment);
- const egl::Surface *surface = defaultAttachment->getSurface();
- ASSERT(surface);
- const SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
- ASSERT(surfaceD3D);
+ GLenum drawBufferState = drawBufferStates[attachmentIndex];
+ const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex];
- if (defaultAttachment->getBinding() == GL_BACK)
+ if (colorAttachment.isAttached() && drawBufferState != GL_NONE)
{
- return surfaceD3D->getSwapChain()->getColorRenderTarget()->getSerial();
+ ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
+ colorAttachmentsForRender.push_back(&colorAttachment);
}
- else
+ else if (!workarounds.mrtPerfWorkaround)
{
- return surfaceD3D->getSwapChain()->getDepthStencilRenderTarget()->getSerial();
+ colorAttachmentsForRender.push_back(nullptr);
}
}
- else
- {
- UNREACHABLE();
- return 0;
- }
+
+ mColorAttachmentsForRender = std::move(colorAttachmentsForRender);
}
+const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender() const
+{
+ ASSERT(mColorAttachmentsForRender.valid());
+ return mColorAttachmentsForRender.value();
}
+
+} // namespace rx