diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/renderer/d3d/FramebufferD3D.cpp | 271 |
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 |