ExternalImageSiblingImpl11.cpp (7133B)
1 // 2 // Copyright 2019 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 #include "libANGLE/renderer/d3d/d3d11/ExternalImageSiblingImpl11.h" 8 9 #include "libANGLE/Context.h" 10 #include "libANGLE/Error.h" 11 #include "libANGLE/angletypes.h" 12 #include "libANGLE/formatutils.h" 13 #include "libANGLE/renderer/d3d/d3d11/Context11.h" 14 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h" 15 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h" 16 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" 17 18 namespace rx 19 { 20 ExternalImageSiblingImpl11::ExternalImageSiblingImpl11(Renderer11 *renderer, 21 EGLClientBuffer buffer, 22 const egl::AttributeMap &attribs) 23 : mRenderer(renderer), mBuffer(buffer), mAttribs(attribs) 24 {} 25 26 ExternalImageSiblingImpl11::~ExternalImageSiblingImpl11() {} 27 28 egl::Error ExternalImageSiblingImpl11::initialize(const egl::Display *display) 29 { 30 const angle::Format *angleFormat = nullptr; 31 ANGLE_TRY(mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(mBuffer), mAttribs, 32 &mWidth, &mHeight, &mSamples, &mFormat, &angleFormat, 33 &mArraySlice)); 34 ID3D11Texture2D *texture = 35 d3d11::DynamicCastComObject<ID3D11Texture2D>(static_cast<IUnknown *>(mBuffer)); 36 ASSERT(texture != nullptr); 37 // TextureHelper11 will release texture on destruction. 38 mTexture.set(texture, d3d11::Format::Get(angleFormat->glInternalFormat, 39 mRenderer->getRenderer11DeviceCaps())); 40 D3D11_TEXTURE2D_DESC textureDesc = {}; 41 mTexture.getDesc(&textureDesc); 42 43 IDXGIResource *resource = d3d11::DynamicCastComObject<IDXGIResource>(mTexture.get()); 44 ASSERT(resource != nullptr); 45 DXGI_USAGE resourceUsage = 0; 46 resource->GetUsage(&resourceUsage); 47 SafeRelease(resource); 48 49 mIsRenderable = (textureDesc.BindFlags & D3D11_BIND_RENDER_TARGET) && 50 (resourceUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT) && 51 !(resourceUsage & DXGI_USAGE_READ_ONLY); 52 53 mIsTexturable = (textureDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) && 54 (resourceUsage & DXGI_USAGE_SHADER_INPUT); 55 56 mIsTextureArray = (textureDesc.ArraySize > 1); 57 58 return egl::NoError(); 59 } 60 61 gl::Format ExternalImageSiblingImpl11::getFormat() const 62 { 63 return mFormat; 64 } 65 66 bool ExternalImageSiblingImpl11::isRenderable(const gl::Context *context) const 67 { 68 return mIsRenderable; 69 } 70 71 bool ExternalImageSiblingImpl11::isTexturable(const gl::Context *context) const 72 { 73 return mIsTexturable; 74 } 75 76 bool ExternalImageSiblingImpl11::isYUV() const 77 { 78 return false; 79 } 80 81 bool ExternalImageSiblingImpl11::hasProtectedContent() const 82 { 83 return false; 84 } 85 86 gl::Extents ExternalImageSiblingImpl11::getSize() const 87 { 88 return gl::Extents(mWidth, mHeight, 1); 89 } 90 91 size_t ExternalImageSiblingImpl11::getSamples() const 92 { 93 return mSamples; 94 } 95 96 angle::Result ExternalImageSiblingImpl11::getAttachmentRenderTarget( 97 const gl::Context *context, 98 GLenum binding, 99 const gl::ImageIndex &imageIndex, 100 GLsizei samples, 101 FramebufferAttachmentRenderTarget **rtOut) 102 { 103 ANGLE_TRY(createRenderTarget(context)); 104 *rtOut = mRenderTarget.get(); 105 return angle::Result::Continue; 106 } 107 108 angle::Result ExternalImageSiblingImpl11::initializeContents(const gl::Context *context, 109 GLenum binding, 110 const gl::ImageIndex &imageIndex) 111 { 112 UNREACHABLE(); 113 return angle::Result::Stop; 114 } 115 116 angle::Result ExternalImageSiblingImpl11::createRenderTarget(const gl::Context *context) 117 { 118 if (mRenderTarget) 119 return angle::Result::Continue; 120 121 Context11 *context11 = GetImplAs<Context11>(context); 122 const d3d11::Format &formatInfo = mTexture.getFormatSet(); 123 124 d3d11::RenderTargetView rtv; 125 if (mIsRenderable) 126 { 127 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 128 rtvDesc.Format = formatInfo.rtvFormat; 129 if (mIsTextureArray) 130 { 131 if (mSamples == 0) 132 { 133 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; 134 rtvDesc.Texture2DArray.MipSlice = 0; 135 rtvDesc.Texture2DArray.FirstArraySlice = mArraySlice; 136 rtvDesc.Texture2DArray.ArraySize = 1; 137 } 138 else 139 { 140 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY; 141 rtvDesc.Texture2DMSArray.FirstArraySlice = mArraySlice; 142 rtvDesc.Texture2DMSArray.ArraySize = 1; 143 } 144 } 145 else 146 { 147 if (mSamples == 0) 148 { 149 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 150 rtvDesc.Texture2D.MipSlice = 0; 151 } 152 else 153 { 154 rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS; 155 } 156 } 157 158 ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, mTexture.get(), &rtv)); 159 rtv.setInternalName("getAttachmentRenderTarget.RTV"); 160 } 161 162 d3d11::SharedSRV srv; 163 if (mIsTexturable) 164 { 165 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 166 srvDesc.Format = formatInfo.srvFormat; 167 if (mIsTextureArray) 168 { 169 if (mSamples == 0) 170 { 171 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; 172 srvDesc.Texture2DArray.MostDetailedMip = 0; 173 srvDesc.Texture2DArray.MipLevels = 1; 174 srvDesc.Texture2DArray.FirstArraySlice = mArraySlice; 175 srvDesc.Texture2DArray.ArraySize = 1; 176 } 177 else 178 { 179 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY; 180 srvDesc.Texture2DArray.FirstArraySlice = mArraySlice; 181 srvDesc.Texture2DArray.ArraySize = 1; 182 } 183 } 184 else 185 { 186 if (mSamples == 0) 187 { 188 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 189 srvDesc.Texture2D.MostDetailedMip = 0; 190 srvDesc.Texture2D.MipLevels = 1; 191 } 192 else 193 { 194 srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS; 195 } 196 } 197 198 ANGLE_TRY(mRenderer->allocateResource(context11, srvDesc, mTexture.get(), &srv)); 199 srv.setInternalName("getAttachmentRenderTarget.SRV"); 200 } 201 d3d11::SharedSRV blitSrv = srv.makeCopy(); 202 203 mRenderTarget = std::make_unique<TextureRenderTarget11>( 204 std::move(rtv), mTexture, std::move(srv), std::move(blitSrv), mFormat.info->internalFormat, 205 formatInfo, mWidth, mHeight, 1, mSamples); 206 return angle::Result::Continue; 207 } 208 209 } // namespace rx