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.cpp305
1 files changed, 162 insertions, 143 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index 82967aced0..3d73b2c840 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -8,14 +8,16 @@
#include "libANGLE/renderer/d3d/FramebufferD3D.h"
-#include "common/BitSetIterator.h"
-#include "libANGLE/formatutils.h"
+#include "common/bitset_utils.h"
+#include "libANGLE/Context.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/FramebufferAttachment.h"
#include "libANGLE/Surface.h"
-#include "libANGLE/renderer/d3d/RendererD3D.h"
-#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/formatutils.h"
+#include "libANGLE/renderer/ContextImpl.h"
#include "libANGLE/renderer/d3d/RenderTargetD3D.h"
+#include "libANGLE/renderer/d3d/RenderbufferD3D.h"
+#include "libANGLE/renderer/d3d/RendererD3D.h"
#include "libANGLE/renderer/d3d/SurfaceD3D.h"
#include "libANGLE/renderer/d3d/SwapChainD3D.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
@@ -37,19 +39,19 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
{
clearParams.clearColor[i] = false;
}
- clearParams.colorFClearValue = state.getColorClearValue();
- clearParams.colorClearType = GL_FLOAT;
- clearParams.colorMaskRed = blendState.colorMaskRed;
- clearParams.colorMaskGreen = blendState.colorMaskGreen;
- clearParams.colorMaskBlue = blendState.colorMaskBlue;
- clearParams.colorMaskAlpha = blendState.colorMaskAlpha;
- clearParams.clearDepth = false;
- clearParams.depthClearValue = state.getDepthClearValue();
- clearParams.clearStencil = false;
- clearParams.stencilClearValue = state.getStencilClearValue();
+ clearParams.colorF = state.getColorClearValue();
+ clearParams.colorType = GL_FLOAT;
+ clearParams.colorMaskRed = blendState.colorMaskRed;
+ clearParams.colorMaskGreen = blendState.colorMaskGreen;
+ clearParams.colorMaskBlue = blendState.colorMaskBlue;
+ clearParams.colorMaskAlpha = blendState.colorMaskAlpha;
+ clearParams.clearDepth = false;
+ clearParams.depthValue = state.getDepthClearValue();
+ clearParams.clearStencil = false;
+ clearParams.stencilValue = state.getStencilClearValue();
clearParams.stencilWriteMask = state.getDepthStencilState().stencilWritemask;
- clearParams.scissorEnabled = state.isScissorTestEnabled();
- clearParams.scissor = state.getScissor();
+ clearParams.scissorEnabled = state.isScissorTestEnabled();
+ clearParams.scissor = state.getScissor();
const gl::Framebuffer *framebufferObject = state.getDrawFramebuffer();
if (mask & GL_COLOR_BUFFER_BIT)
@@ -65,7 +67,8 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
if (mask & GL_DEPTH_BUFFER_BIT)
{
- if (state.getDepthStencilState().depthMask && framebufferObject->getDepthbuffer() != NULL)
+ if (state.getDepthStencilState().depthMask &&
+ framebufferObject->getDepthbuffer() != nullptr)
{
clearParams.clearDepth = true;
}
@@ -73,7 +76,7 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
if (mask & GL_STENCIL_BUFFER_BIT)
{
- if (framebufferObject->getStencilbuffer() != NULL &&
+ if (framebufferObject->getStencilbuffer() != nullptr &&
framebufferObject->getStencilbuffer()->getStencilSize() > 0)
{
clearParams.clearStencil = true;
@@ -82,10 +85,13 @@ ClearParameters GetClearParameters(const gl::State &state, GLbitfield mask)
return clearParams;
}
-
}
-FramebufferD3D::FramebufferD3D(const gl::Framebuffer::Data &data, RendererD3D *renderer)
+ClearParameters::ClearParameters() = default;
+
+ClearParameters::ClearParameters(const ClearParameters &other) = default;
+
+FramebufferD3D::FramebufferD3D(const gl::FramebufferState &data, RendererD3D *renderer)
: FramebufferImpl(data), mRenderer(renderer)
{
}
@@ -94,20 +100,19 @@ FramebufferD3D::~FramebufferD3D()
{
}
-gl::Error FramebufferD3D::clear(const gl::Data &data, GLbitfield mask)
+gl::Error FramebufferD3D::clear(const gl::Context *context, GLbitfield mask)
{
- const gl::State &state = *data.state;
- ClearParameters clearParams = GetClearParameters(state, mask);
- return clear(data, clearParams);
+ ClearParameters clearParams = GetClearParameters(context->getGLState(), mask);
+ return clearImpl(context, clearParams);
}
-gl::Error FramebufferD3D::clearBufferfv(const gl::Data &data,
+gl::Error FramebufferD3D::clearBufferfv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLfloat *values)
{
// glClearBufferfv can be called to clear the color buffer or depth buffer
- ClearParameters clearParams = GetClearParameters(*data.state, 0);
+ ClearParameters clearParams = GetClearParameters(context->getGLState(), 0);
if (buffer == GL_COLOR)
{
@@ -115,43 +120,43 @@ gl::Error FramebufferD3D::clearBufferfv(const gl::Data &data,
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
- clearParams.colorFClearValue = gl::ColorF(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_FLOAT;
+ clearParams.colorF = gl::ColorF(values[0], values[1], values[2], values[3]);
+ clearParams.colorType = GL_FLOAT;
}
if (buffer == GL_DEPTH)
{
clearParams.clearDepth = true;
- clearParams.depthClearValue = values[0];
+ clearParams.depthValue = values[0];
}
- return clear(data, clearParams);
+ return clearImpl(context, clearParams);
}
-gl::Error FramebufferD3D::clearBufferuiv(const gl::Data &data,
+gl::Error FramebufferD3D::clearBufferuiv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLuint *values)
{
// glClearBufferuiv can only be called to clear a color buffer
- ClearParameters clearParams = GetClearParameters(*data.state, 0);
+ ClearParameters clearParams = GetClearParameters(context->getGLState(), 0);
for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
- clearParams.colorUIClearValue = gl::ColorUI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_UNSIGNED_INT;
+ clearParams.colorUI = gl::ColorUI(values[0], values[1], values[2], values[3]);
+ clearParams.colorType = GL_UNSIGNED_INT;
- return clear(data, clearParams);
+ return clearImpl(context, clearParams);
}
-gl::Error FramebufferD3D::clearBufferiv(const gl::Data &data,
+gl::Error FramebufferD3D::clearBufferiv(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
const GLint *values)
{
// glClearBufferiv can be called to clear the color buffer or stencil buffer
- ClearParameters clearParams = GetClearParameters(*data.state, 0);
+ ClearParameters clearParams = GetClearParameters(context->getGLState(), 0);
if (buffer == GL_COLOR)
{
@@ -159,167 +164,154 @@ gl::Error FramebufferD3D::clearBufferiv(const gl::Data &data,
{
clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
}
- clearParams.colorIClearValue = gl::ColorI(values[0], values[1], values[2], values[3]);
- clearParams.colorClearType = GL_INT;
+ clearParams.colorI = gl::ColorI(values[0], values[1], values[2], values[3]);
+ clearParams.colorType = GL_INT;
}
if (buffer == GL_STENCIL)
{
clearParams.clearStencil = true;
- clearParams.stencilClearValue = values[1];
+ clearParams.stencilValue = values[0];
}
- return clear(data, clearParams);
+ return clearImpl(context, clearParams);
}
-gl::Error FramebufferD3D::clearBufferfi(const gl::Data &data,
+gl::Error FramebufferD3D::clearBufferfi(const gl::Context *context,
GLenum buffer,
GLint drawbuffer,
GLfloat depth,
GLint stencil)
{
// glClearBufferfi can only be called to clear a depth stencil buffer
- ClearParameters clearParams = GetClearParameters(*data.state, 0);
- clearParams.clearDepth = true;
- clearParams.depthClearValue = depth;
- clearParams.clearStencil = true;
- clearParams.stencilClearValue = stencil;
+ ClearParameters clearParams = GetClearParameters(context->getGLState(), 0);
+ clearParams.clearDepth = true;
+ clearParams.depthValue = depth;
+ clearParams.clearStencil = true;
+ clearParams.stencilValue = stencil;
- return clear(data, clearParams);
+ return clearImpl(context, clearParams);
}
-GLenum FramebufferD3D::getImplementationColorReadFormat() const
+GLenum FramebufferD3D::getImplementationColorReadFormat(const gl::Context *context) const
{
- const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment();
+ const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment();
if (readAttachment == nullptr)
{
return GL_NONE;
}
- RenderTargetD3D *attachmentRenderTarget = NULL;
- gl::Error error = readAttachment->getRenderTarget(&attachmentRenderTarget);
+ RenderTargetD3D *attachmentRenderTarget = nullptr;
+ gl::Error error = readAttachment->getRenderTarget(context, &attachmentRenderTarget);
if (error.isError())
{
return GL_NONE;
}
GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
- const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
+ const gl::InternalFormat &implementationFormatInfo =
+ gl::GetSizedInternalFormatInfo(implementationFormat);
- return implementationFormatInfo.format;
+ return implementationFormatInfo.getReadPixelsFormat();
}
-GLenum FramebufferD3D::getImplementationColorReadType() const
+GLenum FramebufferD3D::getImplementationColorReadType(const gl::Context *context) const
{
- const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment();
+ const gl::FramebufferAttachment *readAttachment = mState.getReadAttachment();
if (readAttachment == nullptr)
{
return GL_NONE;
}
- RenderTargetD3D *attachmentRenderTarget = NULL;
- gl::Error error = readAttachment->getRenderTarget(&attachmentRenderTarget);
+ RenderTargetD3D *attachmentRenderTarget = nullptr;
+ gl::Error error = readAttachment->getRenderTarget(context, &attachmentRenderTarget);
if (error.isError())
{
return GL_NONE;
}
GLenum implementationFormat = getRenderTargetImplementationFormat(attachmentRenderTarget);
- const gl::InternalFormat &implementationFormatInfo = gl::GetInternalFormatInfo(implementationFormat);
+ const gl::InternalFormat &implementationFormatInfo =
+ gl::GetSizedInternalFormatInfo(implementationFormat);
- return implementationFormatInfo.type;
+ return implementationFormatInfo.getReadPixelsType(context->getClientVersion());
}
-gl::Error FramebufferD3D::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const
+gl::Error FramebufferD3D::readPixels(const gl::Context *context,
+ const gl::Rectangle &origArea,
+ GLenum format,
+ GLenum type,
+ void *pixels)
{
- const gl::PixelPackState &packState = state.getPackState();
-
- GLenum sizedInternalFormat = gl::GetSizedInternalFormat(format, type);
- const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(sizedInternalFormat);
- GLuint outputPitch =
- sizedFormatInfo.computeRowPitch(type, area.width, packState.alignment, packState.rowLength);
- GLsizei outputSkipBytes = sizedFormatInfo.computeSkipPixels(
- outputPitch, 0, 0, packState.skipRows, packState.skipPixels);
-
- 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,
- GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer)
-{
- bool blitRenderTarget = false;
- if ((mask & GL_COLOR_BUFFER_BIT) &&
- sourceFramebuffer->getReadColorbuffer() != nullptr &&
- mData.getFirstColorAttachment() != nullptr)
+ // Clip read area to framebuffer.
+ const gl::Extents fbSize = getState().getReadAttachment()->getSize();
+ const gl::Rectangle fbRect(0, 0, fbSize.width, fbSize.height);
+ gl::Rectangle area;
+ if (!ClipRectangle(origArea, fbRect, &area))
{
- blitRenderTarget = true;
+ // nothing to read
+ return gl::NoError();
}
- bool blitStencil = false;
- if ((mask & GL_STENCIL_BUFFER_BIT) &&
- sourceFramebuffer->getStencilbuffer() != nullptr &&
- mData.getStencilAttachment() != nullptr)
- {
- blitStencil = true;
- }
+ const gl::PixelPackState &packState = context->getGLState().getPackState();
- bool blitDepth = false;
- if ((mask & GL_DEPTH_BUFFER_BIT) &&
- sourceFramebuffer->getDepthbuffer() != nullptr &&
- mData.getDepthAttachment() != nullptr)
- {
- blitDepth = true;
- }
+ const gl::InternalFormat &sizedFormatInfo = gl::GetInternalFormatInfo(format, type);
- if (blitRenderTarget || blitDepth || blitStencil)
- {
- const gl::Rectangle *scissor = state.isScissorTestEnabled() ? &state.getScissor() : NULL;
- gl::Error error = blit(sourceArea, destArea, scissor, blitRenderTarget, blitDepth, blitStencil,
- filter, sourceFramebuffer);
- if (error.isError())
- {
- return error;
- }
- }
+ GLuint outputPitch = 0;
+ ANGLE_TRY_RESULT(sizedFormatInfo.computeRowPitch(type, origArea.width, packState.alignment,
+ packState.rowLength),
+ outputPitch);
+ GLuint outputSkipBytes = 0;
+ ANGLE_TRY_RESULT(sizedFormatInfo.computeSkipBytes(outputPitch, 0, packState, false),
+ outputSkipBytes);
+ outputSkipBytes +=
+ (area.x - origArea.x) * sizedFormatInfo.pixelBytes + (area.y - origArea.y) * outputPitch;
+
+ return readPixelsImpl(context, area, format, type, outputPitch, packState,
+ reinterpret_cast<uint8_t *>(pixels) + outputSkipBytes);
+}
- return gl::Error(GL_NO_ERROR);
+gl::Error FramebufferD3D::blit(const gl::Context *context,
+ const gl::Rectangle &sourceArea,
+ const gl::Rectangle &destArea,
+ GLbitfield mask,
+ GLenum filter)
+{
+ const auto &glState = context->getGLState();
+ const gl::Framebuffer *sourceFramebuffer = glState.getReadFramebuffer();
+ const gl::Rectangle *scissor = glState.isScissorTestEnabled() ? &glState.getScissor() : nullptr;
+ ANGLE_TRY(blitImpl(context, sourceArea, destArea, scissor, (mask & GL_COLOR_BUFFER_BIT) != 0,
+ (mask & GL_DEPTH_BUFFER_BIT) != 0, (mask & GL_STENCIL_BUFFER_BIT) != 0,
+ filter, sourceFramebuffer));
+
+ return gl::NoError();
}
-bool FramebufferD3D::checkStatus() const
+bool FramebufferD3D::checkStatus(const gl::Context *context) 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)
+ if (mState.getDepthAttachment() != nullptr && mState.getStencilAttachment() != nullptr &&
+ mState.getDepthStencilAttachment() == nullptr)
{
return false;
}
- // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
- const auto &colorAttachments = mData.getColorAttachments();
- for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++)
+ // D3D11 does not allow for overlapping RenderTargetViews.
+ // If WebGL compatibility is enabled, this has already been checked at a higher level.
+ ASSERT(!context->getExtensions().webglCompatibility || mState.colorAttachmentsAreUniqueImages());
+ if (!context->getExtensions().webglCompatibility)
{
- const gl::FramebufferAttachment &attachment = colorAttachments[colorAttachment];
- if (attachment.isAttached())
+ if (!mState.colorAttachmentsAreUniqueImages())
{
- for (size_t prevColorAttachment = 0; prevColorAttachment < colorAttachment; prevColorAttachment++)
- {
- const gl::FramebufferAttachment &prevAttachment = colorAttachments[prevColorAttachment];
- if (prevAttachment.isAttached() &&
- (attachment.id() == prevAttachment.id() &&
- attachment.type() == prevAttachment.type()))
- {
- return false;
- }
- }
+ return false;
}
}
// D3D requires all render targets to have the same dimensions.
- if (!mData.attachmentsHaveSameDimensions())
+ if (!mState.attachmentsHaveSameDimensions())
{
return false;
}
@@ -327,45 +319,52 @@ bool FramebufferD3D::checkStatus() const
return true;
}
-void FramebufferD3D::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
+void FramebufferD3D::syncState(const gl::Context *context,
+ const gl::Framebuffer::DirtyBits &dirtyBits)
{
- bool invalidateColorAttachmentCache = false;
-
if (!mColorAttachmentsForRender.valid())
{
- invalidateColorAttachmentCache = true;
+ return;
}
- for (auto dirtyBit : angle::IterateBitSet(dirtyBits))
+ for (auto dirtyBit : dirtyBits)
{
if ((dirtyBit >= gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0 &&
dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX) ||
dirtyBit == gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS)
{
- invalidateColorAttachmentCache = true;
+ mColorAttachmentsForRender.reset();
}
}
+}
- if (!invalidateColorAttachmentCache)
+const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl::Context *context)
+{
+ gl::DrawBufferMask activeProgramOutputs =
+ context->getContextState().getState().getProgram()->getActiveOutputVariables();
+
+ if (mColorAttachmentsForRender.valid() && mCurrentActiveProgramOutputs == activeProgramOutputs)
{
- return;
+ return mColorAttachmentsForRender.value();
}
// Does not actually free memory
gl::AttachmentList colorAttachmentsForRender;
- const auto &colorAttachments = mData.getColorAttachments();
- const auto &drawBufferStates = mData.getDrawBufferStates();
+ const auto &colorAttachments = mState.getColorAttachments();
+ const auto &drawBufferStates = mState.getDrawBufferStates();
const auto &workarounds = mRenderer->getWorkarounds();
for (size_t attachmentIndex = 0; attachmentIndex < colorAttachments.size(); ++attachmentIndex)
{
- GLenum drawBufferState = drawBufferStates[attachmentIndex];
+ GLenum drawBufferState = drawBufferStates[attachmentIndex];
const gl::FramebufferAttachment &colorAttachment = colorAttachments[attachmentIndex];
- if (colorAttachment.isAttached() && drawBufferState != GL_NONE)
+ if (colorAttachment.isAttached() && drawBufferState != GL_NONE &&
+ activeProgramOutputs[attachmentIndex])
{
- ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
+ ASSERT(drawBufferState == GL_BACK ||
+ drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + attachmentIndex));
colorAttachmentsForRender.push_back(&colorAttachment);
}
else if (!workarounds.mrtPerfWorkaround)
@@ -374,12 +373,32 @@ void FramebufferD3D::syncState(const gl::Framebuffer::DirtyBits &dirtyBits)
}
}
+ // When rendering with no render target on D3D, two bugs lead to incorrect behavior on Intel
+ // drivers < 4815. The rendering samples always pass neglecting discard statements in pixel
+ // shader. We add a dummy texture as render target in such case.
+ if (mRenderer->getWorkarounds().addDummyTextureNoRenderTarget &&
+ colorAttachmentsForRender.empty())
+ {
+ static_assert(static_cast<size_t>(activeProgramOutputs.size()) <= 32,
+ "Size of active program outputs should less or equal than 32.");
+ GLenum i = static_cast<GLenum>(
+ gl::ScanForward(static_cast<uint32_t>(activeProgramOutputs.bits())));
+
+ gl::Texture *dummyTex = nullptr;
+ // TODO(Jamie): Handle error if dummy texture can't be created.
+ ANGLE_SWALLOW_ERR(mRenderer->getIncompleteTexture(context, GL_TEXTURE_2D, &dummyTex));
+ if (dummyTex)
+ {
+ gl::ImageIndex index = gl::ImageIndex::Make2D(0);
+ gl::FramebufferAttachment *dummyAttach = new gl::FramebufferAttachment(
+ context, GL_TEXTURE, GL_COLOR_ATTACHMENT0_EXT + i, index, dummyTex);
+ colorAttachmentsForRender.push_back(dummyAttach);
+ }
+ }
+
mColorAttachmentsForRender = std::move(colorAttachmentsForRender);
-}
+ mCurrentActiveProgramOutputs = activeProgramOutputs;
-const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender() const
-{
- ASSERT(mColorAttachmentsForRender.valid());
return mColorAttachmentsForRender.value();
}