diff options
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp | 294 |
1 files changed, 227 insertions, 67 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp index da01f320c0..186a035902 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp @@ -25,8 +25,7 @@ namespace rx { Framebuffer11::Framebuffer11(const gl::Framebuffer::Data &data, Renderer11 *renderer) - : FramebufferD3D(data, renderer), - mRenderer(renderer) + : FramebufferD3D(data, renderer), mRenderer(renderer) { ASSERT(mRenderer != nullptr); } @@ -43,7 +42,7 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture); - TextureStorage *texStorage = NULL; + TextureStorage *texStorage = nullptr; gl::Error error = textureD3D->getNativeTexture(&texStorage); if (error.isError()) { @@ -52,7 +51,7 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a if (texStorage) { - TextureStorage11 *texStorage11 = TextureStorage11::makeTextureStorage11(texStorage); + TextureStorage11 *texStorage11 = GetAs<TextureStorage11>(texStorage); ASSERT(texStorage11); texStorage11->invalidateSwizzleCacheLevel(attachment->mipLevel()); @@ -64,23 +63,25 @@ static gl::Error InvalidateAttachmentSwizzles(const gl::FramebufferAttachment *a gl::Error Framebuffer11::invalidateSwizzles() const { - for (auto it = mData.mColorAttachments.cbegin(); it != mData.mColorAttachments.cend(); ++it) + for (const auto &colorAttachment : mData.getColorAttachments()) { - gl::FramebufferAttachment *colorAttachment = *it; - gl::Error error = InvalidateAttachmentSwizzles(colorAttachment); - if (error.isError()) + if (colorAttachment.isAttached()) { - return error; + gl::Error error = InvalidateAttachmentSwizzles(&colorAttachment); + if (error.isError()) + { + return error; + } } } - gl::Error error = InvalidateAttachmentSwizzles(mData.mDepthAttachment); + gl::Error error = InvalidateAttachmentSwizzles(mData.getDepthAttachment()); if (error.isError()) { return error; } - error = InvalidateAttachmentSwizzles(mData.mStencilAttachment); + error = InvalidateAttachmentSwizzles(mData.getStencilAttachment()); if (error.isError()) { return error; @@ -89,10 +90,30 @@ gl::Error Framebuffer11::invalidateSwizzles() const return gl::Error(GL_NO_ERROR); } -gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &clearParams) +gl::Error Framebuffer11::clear(const gl::Data &data, const ClearParameters &clearParams) { Clear11 *clearer = mRenderer->getClearer(); - gl::Error error = clearer->clearFramebuffer(clearParams, mData); + gl::Error error(GL_NO_ERROR); + + const gl::FramebufferAttachment *colorAttachment = mData.getFirstColorAttachment(); + if (clearParams.scissorEnabled == true && colorAttachment != nullptr && + UsePresentPathFast(mRenderer, colorAttachment)) + { + // If the current framebuffer is using the default colorbuffer, and present path fast is + // active, and the scissor rect is enabled, then we should invert the scissor rect + // vertically + ClearParameters presentPathFastClearParams = clearParams; + gl::Extents framebufferSize = colorAttachment->getSize(); + presentPathFastClearParams.scissor.y = framebufferSize.height - + presentPathFastClearParams.scissor.y - + presentPathFastClearParams.scissor.height; + error = clearer->clearFramebuffer(presentPathFastClearParams, mData); + } + else + { + error = clearer->clearFramebuffer(clearParams, mData); + } + if (error.isError()) { return error; @@ -107,76 +128,193 @@ gl::Error Framebuffer11::clear(const gl::State &state, const ClearParameters &cl return gl::Error(GL_NO_ERROR); } -static gl::Error getRenderTargetResource(const gl::FramebufferAttachment *colorbuffer, unsigned int *subresourceIndexOut, - ID3D11Texture2D **texture2DOut) +gl::Error Framebuffer11::invalidate(size_t count, const GLenum *attachments) { - ASSERT(colorbuffer); + return invalidateBase(count, attachments, false); +} - RenderTarget11 *renderTarget = NULL; - gl::Error error = d3d11::GetAttachmentRenderTarget(colorbuffer, &renderTarget); - if (error.isError()) +gl::Error Framebuffer11::discard(size_t count, const GLenum *attachments) +{ + return invalidateBase(count, attachments, true); +} + +gl::Error Framebuffer11::invalidateBase(size_t count, const GLenum *attachments, bool useEXTBehavior) const +{ +#if defined(ANGLE_ENABLE_D3D11_1) + ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported(); + + if (!deviceContext1) { - return error; + // DiscardView() is only supported on ID3D11DeviceContext1 + return gl::Error(GL_NO_ERROR); } - ID3D11Resource *renderTargetResource = renderTarget->getTexture(); - ASSERT(renderTargetResource); - - *subresourceIndexOut = renderTarget->getSubresourceIndex(); - *texture2DOut = d3d11::DynamicCastComObject<ID3D11Texture2D>(renderTargetResource); + bool foundDepth = false; + bool foundStencil = false; - if (!(*texture2DOut)) + for (size_t i = 0; i < count; ++i) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the ID3D11Texture2D from a RenderTarget"); - } + switch (attachments[i]) + { + // Handle depth and stencil attachments. Defer discarding until later. + case GL_DEPTH_STENCIL_ATTACHMENT: + foundDepth = true; + foundStencil = true; + break; + case GL_DEPTH_EXT: + case GL_DEPTH_ATTACHMENT: + foundDepth = true; + break; + case GL_STENCIL_EXT: + case GL_STENCIL_ATTACHMENT: + foundStencil = true; + break; + default: + { + // Handle color attachments + ASSERT((attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15) || + (attachments[i] == GL_COLOR)); - return gl::Error(GL_NO_ERROR); -} + RenderTarget11 *renderTarget = nullptr; + ID3D11View *colorView = nullptr; + gl::Error error(GL_NO_ERROR); + size_t colorAttachmentID = 0; -gl::Error Framebuffer11::readPixels(const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, uint8_t *pixels) const -{ - ID3D11Texture2D *colorBufferTexture = NULL; - unsigned int subresourceIndex = 0; + if (attachments[i] == GL_COLOR) + { + colorAttachmentID = 0; + } + else + { + colorAttachmentID = attachments[i] - GL_COLOR_ATTACHMENT0; + } - const gl::FramebufferAttachment *colorbuffer = mData.getReadAttachment(); - ASSERT(colorbuffer); + if (mData.getColorAttachment(static_cast<unsigned int>(colorAttachmentID))) + { + error = mData.getColorAttachment(static_cast<unsigned int>(colorAttachmentID)) + ->getRenderTarget(&renderTarget); + if (error.isError()) + { + return error; + } + + colorView = renderTarget->getRenderTargetView(); + + if (colorView != nullptr) + { + deviceContext1->DiscardView(colorView); + } + } - gl::Error error = getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture); - if (error.isError()) + break; + } + } + } + + bool discardDepth = false; + bool discardStencil = false; + + // The D3D11 renderer uses the same view for depth and stencil buffers, so we must be careful. + if (useEXTBehavior) { - return error; + // In the extension, if the app discards only one of the depth and stencil attachments, but + // those are backed by the same packed_depth_stencil buffer, then both images become undefined. + discardDepth = foundDepth; + + // Don't bother discarding the stencil buffer if the depth buffer will already do it + discardStencil = foundStencil && (!discardDepth || mData.getDepthAttachment() == nullptr); + } + else + { + // In ES 3.0.4, if a specified attachment has base internal format DEPTH_STENCIL but the + // attachments list does not include DEPTH_STENCIL_ATTACHMENT or both DEPTH_ATTACHMENT and + // STENCIL_ATTACHMENT, then only the specified portion of every pixel in the subregion of pixels + // of the DEPTH_STENCIL buffer may be invalidated, and the other portion must be preserved. + discardDepth = (foundDepth && foundStencil) || (foundDepth && (mData.getStencilAttachment() == nullptr)); + discardStencil = (foundStencil && (mData.getDepthAttachment() == nullptr)); } - gl::Buffer *packBuffer = pack.pixelBuffer.get(); - if (packBuffer != NULL) + if (discardDepth && mData.getDepthAttachment()) { - Buffer11 *packBufferStorage = Buffer11::makeBuffer11(packBuffer->getImplementation()); - PackPixelsParams packParams(area, format, type, outputPitch, pack, reinterpret_cast<ptrdiff_t>(pixels)); + RenderTarget11 *renderTarget = nullptr; + ID3D11View *depthView = nullptr; + gl::Error error(GL_NO_ERROR); - error = packBufferStorage->packPixels(colorBufferTexture, subresourceIndex, packParams); + error = mData.getDepthAttachment()->getRenderTarget(&renderTarget); if (error.isError()) { - SafeRelease(colorBufferTexture); return error; } - packBuffer->getIndexRangeCache()->clear(); + depthView = renderTarget->getDepthStencilView(); + + if (depthView != nullptr) + { + deviceContext1->DiscardView(depthView); + } } - else + + if (discardStencil && mData.getStencilAttachment()) { - error = mRenderer->readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, pack, pixels); + RenderTarget11 *renderTarget = nullptr; + ID3D11View *stencilView = nullptr; + gl::Error error(GL_NO_ERROR); + + error = mData.getStencilAttachment()->getRenderTarget(&renderTarget); if (error.isError()) { - SafeRelease(colorBufferTexture); return error; } + + stencilView = renderTarget->getDepthStencilView(); + + if (stencilView != nullptr) + { + deviceContext1->DiscardView(stencilView); + } } +#endif // ANGLE_ENABLE_D3D11_1 - SafeRelease(colorBufferTexture); + return gl::Error(GL_NO_ERROR); +} +gl::Error Framebuffer11::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) +{ + // A no-op implementation conforms to the spec, so don't call UNIMPLEMENTED() return gl::Error(GL_NO_ERROR); } +gl::Error Framebuffer11::readPixelsImpl(const gl::Rectangle &area, + GLenum format, + GLenum type, + size_t outputPitch, + const gl::PixelPackState &pack, + uint8_t *pixels) const +{ + const gl::FramebufferAttachment *readAttachment = mData.getReadAttachment(); + ASSERT(readAttachment); + + gl::Buffer *packBuffer = pack.pixelBuffer.get(); + if (packBuffer != nullptr) + { + if (pack.rowLength != 0 || pack.skipRows != 0 || pack.skipPixels != 0) + { + UNIMPLEMENTED(); + return gl::Error(GL_INVALID_OPERATION, + "Unimplemented pixel store parameters in readPixelsImpl"); + } + + Buffer11 *packBufferStorage = GetImplAs<Buffer11>(packBuffer); + PackPixelsParams packParams(area, format, type, static_cast<GLuint>(outputPitch), pack, + reinterpret_cast<ptrdiff_t>(pixels)); + + return packBufferStorage->packPixels(*readAttachment, packParams); + } + + return mRenderer->readFromAttachment(*readAttachment, area, format, type, + static_cast<GLuint>(outputPitch), pack, pixels); +} + gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, const gl::Framebuffer *sourceFramebuffer) @@ -186,31 +324,53 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getReadColorbuffer(); ASSERT(readBuffer); - RenderTargetD3D *readRenderTarget = NULL; - gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + RenderTargetD3D *readRenderTarget = nullptr; + gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); if (error.isError()) { return error; } ASSERT(readRenderTarget); - for (size_t colorAttachment = 0; colorAttachment < mData.mColorAttachments.size(); colorAttachment++) + const auto &colorAttachments = mData.getColorAttachments(); + const auto &drawBufferStates = mData.getDrawBufferStates(); + + for (size_t colorAttachment = 0; colorAttachment < colorAttachments.size(); colorAttachment++) { - if (mData.mColorAttachments[colorAttachment] != nullptr && - mData.mDrawBufferStates[colorAttachment] != GL_NONE) - { - const gl::FramebufferAttachment *drawBuffer = mData.mColorAttachments[colorAttachment]; + const gl::FramebufferAttachment &drawBuffer = colorAttachments[colorAttachment]; - RenderTargetD3D *drawRenderTarget = NULL; - error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + if (drawBuffer.isAttached() && + drawBufferStates[colorAttachment] != GL_NONE) + { + RenderTargetD3D *drawRenderTarget = nullptr; + error = drawBuffer.getRenderTarget(&drawRenderTarget); if (error.isError()) { return error; } ASSERT(drawRenderTarget); - error = mRenderer->blitRenderbufferRect(sourceArea, destArea, readRenderTarget, drawRenderTarget, - filter, scissor, blitRenderTarget, false, false); + const bool invertColorSource = UsePresentPathFast(mRenderer, readBuffer); + gl::Rectangle actualSourceArea = sourceArea; + if (invertColorSource) + { + RenderTarget11 *readRenderTarget11 = GetAs<RenderTarget11>(readRenderTarget); + actualSourceArea.y = readRenderTarget11->getHeight() - sourceArea.y; + actualSourceArea.height = -sourceArea.height; + } + + const bool invertColorDest = UsePresentPathFast(mRenderer, &drawBuffer); + gl::Rectangle actualDestArea = destArea; + if (invertColorDest) + { + RenderTarget11 *drawRenderTarget11 = GetAs<RenderTarget11>(drawRenderTarget); + actualDestArea.y = drawRenderTarget11->getHeight() - destArea.y; + actualDestArea.height = -destArea.height; + } + + error = mRenderer->blitRenderbufferRect(actualSourceArea, actualDestArea, + readRenderTarget, drawRenderTarget, filter, + scissor, blitRenderTarget, false, false); if (error.isError()) { return error; @@ -221,11 +381,11 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang if (blitDepth || blitStencil) { - gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer(); + const gl::FramebufferAttachment *readBuffer = sourceFramebuffer->getDepthOrStencilbuffer(); ASSERT(readBuffer); - RenderTargetD3D *readRenderTarget = NULL; - gl::Error error = GetAttachmentRenderTarget(readBuffer, &readRenderTarget); + RenderTargetD3D *readRenderTarget = nullptr; + gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); if (error.isError()) { return error; @@ -235,8 +395,8 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment(); ASSERT(drawBuffer); - RenderTargetD3D *drawRenderTarget = NULL; - error = GetAttachmentRenderTarget(drawBuffer, &drawRenderTarget); + RenderTargetD3D *drawRenderTarget = nullptr; + error = drawBuffer->getRenderTarget(&drawRenderTarget); if (error.isError()) { return error; @@ -262,7 +422,7 @@ gl::Error Framebuffer11::blit(const gl::Rectangle &sourceArea, const gl::Rectang GLenum Framebuffer11::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const { - RenderTarget11 *renderTarget11 = RenderTarget11::makeRenderTarget11(renderTarget); + RenderTarget11 *renderTarget11 = GetAs<RenderTarget11>(renderTarget); const d3d11::DXGIFormat &dxgiFormatInfo = d3d11::GetDXGIFormatInfo(renderTarget11->getDXGIFormat()); return dxgiFormatInfo.internalFormat; } |