// // Copyright 2019 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // #include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h" #include "libANGLE/Context.h" #include "libANGLE/Error.h" #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/d3d11/Context11.h" #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" namespace rx { ExternalImageSiblingImpl11::ExternalImageSiblingImpl11(Renderer11 *renderer, EGLClientBuffer buffer, const egl::AttributeMap &attribs) : mRenderer(renderer), mBuffer(buffer), mAttribs(attribs) {} ExternalImageSiblingImpl11::~ExternalImageSiblingImpl11() {} egl::Error ExternalImageSiblingImpl11::initialize(const egl::Display *display) { const angle::Format *angleFormat = nullptr; ANGLE_TRY(mRenderer->getD3DTextureInfo(nullptr, static_cast(mBuffer), mAttribs, &mWidth, &mHeight, &mSamples, &mFormat, &angleFormat, &mArraySlice)); ID3D11Texture2D *texture = d3d11::DynamicCastComObject(static_cast(mBuffer)); ASSERT(texture != nullptr); // TextureHelper11 will release texture on destruction. mTexture.set(texture, d3d11::Format::Get(angleFormat->glInternalFormat, mRenderer->getRenderer11DeviceCaps())); D3D11_TEXTURE2D_DESC textureDesc = {}; mTexture.getDesc(&textureDesc); IDXGIResource *resource = d3d11::DynamicCastComObject(mTexture.get()); ASSERT(resource != nullptr); DXGI_USAGE resourceUsage = 0; resource->GetUsage(&resourceUsage); SafeRelease(resource); mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && (resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) && !(resourceUsage & DXGI_USAGE_READ_ONLY); mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) && (resourceUsage & DXGI_USAGE_SHADER_INPUT); mIsTextureArray = (textureDesc.ArraySize > 1); return egl::NoError(); } gl::Format ExternalImageSiblingImpl11::getFormat() const { return mFormat; } bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const { return mIsRenderable; } bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const { return mIsTexturable; } bool ExternalImageSiblingImpl11::isYUV() const { return false; } bool ExternalImageSiblingImpl11::hasProtectedContent() const { return false; } gl::Extents ExternalImageSiblingImpl11::getSize() const { return gl::Extents(mWidth, mHeight, 1); } size_t ExternalImageSiblingImpl11::getSamples() const { return mSamples; } angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget( const gl::Context *context, GLenum binding, const gl::ImageIndex &imageIndex, GLsizei samples, FramebufferAttachmentRenderTarget **rtOut) { ANGLE_TRY(createRenderTarget(context)); *rtOut = mRenderTarget.get(); return angle::Result::Continue; } angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context, GLenum binding, const gl::ImageIndex &imageIndex) { UNREACHABLE(); return angle::Result::Stop; } angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context) { if (mRenderTarget) return angle::Result::Continue; Context11 *context11 = GetImplAs(context); const d3d11::Format &formatInfo = mTexture.getFormatSet(); d3d11::RenderTargetView rtv; if (mIsRenderable) { D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; rtvDesc.Format = formatInfo.rtvFormat; if (mIsTextureArray) { if (mSamples == 0) { rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtvDesc.Texture2DArray.MipSlice = 0; rtvDesc.Texture2DArray.FirstArraySlice = mArraySlice; rtvDesc.Texture2DArray.ArraySize = 1; } else { rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; rtvDesc.Texture2DMSArray.FirstArraySlice = mArraySlice; rtvDesc.Texture2DMSArray.ArraySize = 1; } } else { if (mSamples == 0) { rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; rtvDesc.Texture2D.MipSlice = 0; } else { rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; } } ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv)); rtv.setInternalName("getAttachmentRenderTarget.RTV"); } d3d11::SharedSRV srv; if (mIsTexturable) { D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; srvDesc.Format = formatInfo.srvFormat; if (mIsTextureArray) { if (mSamples == 0) { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; srvDesc.Texture2DArray.MostDetailedMip = 0; srvDesc.Texture2DArray.MipLevels = 1; srvDesc.Texture2DArray.FirstArraySlice = mArraySlice; srvDesc.Texture2DArray.ArraySize = 1; } else { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; srvDesc.Texture2DArray.FirstArraySlice = mArraySlice; srvDesc.Texture2DArray.ArraySize = 1; } } else { if (mSamples == 0) { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MipLevels = 1; } else { srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; } } ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv)); srv.setInternalName("getAttachmentRenderTarget.SRV"); } d3d11::SharedSRV blitSrv = srv.makeCopy(); mRenderTarget = std::make_unique( std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), mFormat.info->internalFormat, formatInfo, mWidth, mHeight, 1, mSamples); return angle::Result::Continue; } } // namespace rx