1 #include "precompiled.h" 2 // 3 // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 // 7 8 // RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers 9 // retained by Renderbuffers. 10 11 #include "libGLESv2/renderer/RenderTarget11.h" 12 #include "libGLESv2/renderer/Renderer11.h" 13 14 #include "libGLESv2/renderer/renderer11_utils.h" 15 #include "libGLESv2/main.h" 16 17 namespace rx 18 { 19 20 static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view) 21 { 22 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 23 view->GetDesc(&rtvDesc); 24 25 D3D11_TEXTURE2D_DESC texDesc; 26 texture->GetDesc(&texDesc); 27 28 unsigned int mipSlice = 0; 29 unsigned int arraySlice = 0; 30 unsigned int mipLevels = texDesc.MipLevels; 31 32 switch (rtvDesc.ViewDimension) 33 { 34 case D3D11_RTV_DIMENSION_TEXTURE1D: 35 mipSlice = rtvDesc.Texture1D.MipSlice; 36 arraySlice = 0; 37 break; 38 39 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: 40 mipSlice = rtvDesc.Texture1DArray.MipSlice; 41 arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; 42 break; 43 44 case D3D11_RTV_DIMENSION_TEXTURE2D: 45 mipSlice = rtvDesc.Texture2D.MipSlice; 46 arraySlice = 0; 47 break; 48 49 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: 50 mipSlice = rtvDesc.Texture2DArray.MipSlice; 51 arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; 52 break; 53 54 case D3D11_RTV_DIMENSION_TEXTURE2DMS: 55 mipSlice = 0; 56 arraySlice = 0; 57 break; 58 59 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: 60 mipSlice = 0; 61 arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; 62 break; 63 64 case D3D11_RTV_DIMENSION_TEXTURE3D: 65 mipSlice = rtvDesc.Texture3D.MipSlice; 66 arraySlice = 0; 67 break; 68 69 case D3D11_RTV_DIMENSION_UNKNOWN: 70 case D3D11_RTV_DIMENSION_BUFFER: 71 UNIMPLEMENTED(); 72 break; 73 74 default: 75 UNREACHABLE(); 76 break; 77 } 78 79 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); 80 } 81 82 static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view) 83 { 84 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 85 view->GetDesc(&dsvDesc); 86 87 D3D11_TEXTURE2D_DESC texDesc; 88 texture->GetDesc(&texDesc); 89 90 unsigned int mipSlice = 0; 91 unsigned int arraySlice = 0; 92 unsigned int mipLevels = texDesc.MipLevels; 93 94 switch (dsvDesc.ViewDimension) 95 { 96 case D3D11_DSV_DIMENSION_TEXTURE1D: 97 mipSlice = dsvDesc.Texture1D.MipSlice; 98 arraySlice = 0; 99 break; 100 101 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: 102 mipSlice = dsvDesc.Texture1DArray.MipSlice; 103 arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; 104 break; 105 106 case D3D11_DSV_DIMENSION_TEXTURE2D: 107 mipSlice = dsvDesc.Texture2D.MipSlice; 108 arraySlice = 0; 109 break; 110 111 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: 112 mipSlice = dsvDesc.Texture2DArray.MipSlice; 113 arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; 114 break; 115 116 case D3D11_DSV_DIMENSION_TEXTURE2DMS: 117 mipSlice = 0; 118 arraySlice = 0; 119 break; 120 121 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: 122 mipSlice = 0; 123 arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; 124 break; 125 126 case D3D11_RTV_DIMENSION_UNKNOWN: 127 UNIMPLEMENTED(); 128 break; 129 130 default: 131 UNREACHABLE(); 132 break; 133 } 134 135 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); 136 } 137 138 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) 139 { 140 mRenderer = Renderer11::makeRenderer11(renderer); 141 mTexture = tex; 142 mRenderTarget = rtv; 143 mDepthStencil = NULL; 144 mShaderResource = srv; 145 mSubresourceIndex = 0; 146 147 if (mRenderTarget && mTexture) 148 { 149 D3D11_RENDER_TARGET_VIEW_DESC desc; 150 mRenderTarget->GetDesc(&desc); 151 152 D3D11_TEXTURE2D_DESC texDesc; 153 mTexture->GetDesc(&texDesc); 154 155 mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); 156 mWidth = width; 157 mHeight = height; 158 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; 159 160 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); 161 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); 162 } 163 } 164 165 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) 166 { 167 mRenderer = Renderer11::makeRenderer11(renderer); 168 mTexture = tex; 169 mRenderTarget = NULL; 170 mDepthStencil = dsv; 171 mShaderResource = srv; 172 mSubresourceIndex = 0; 173 174 if (mDepthStencil && mTexture) 175 { 176 D3D11_DEPTH_STENCIL_VIEW_DESC desc; 177 mDepthStencil->GetDesc(&desc); 178 179 D3D11_TEXTURE2D_DESC texDesc; 180 mTexture->GetDesc(&texDesc); 181 182 mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); 183 mWidth = width; 184 mHeight = height; 185 mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; 186 187 mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); 188 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); 189 } 190 } 191 192 RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth) 193 { 194 mRenderer = Renderer11::makeRenderer11(renderer); 195 mTexture = NULL; 196 mRenderTarget = NULL; 197 mDepthStencil = NULL; 198 mShaderResource = NULL; 199 200 DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format); 201 202 int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); 203 if (supportedSamples < 0) 204 { 205 gl::error(GL_OUT_OF_MEMORY); 206 return; 207 } 208 209 if (width > 0 && height > 0) 210 { 211 // Create texture resource 212 D3D11_TEXTURE2D_DESC desc; 213 desc.Width = width; 214 desc.Height = height; 215 desc.MipLevels = 1; 216 desc.ArraySize = 1; 217 desc.Format = requestedFormat; 218 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; 219 desc.SampleDesc.Quality = 0; 220 desc.Usage = D3D11_USAGE_DEFAULT; 221 desc.CPUAccessFlags = 0; 222 desc.MiscFlags = 0; 223 desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)); 224 225 ID3D11Device *device = mRenderer->getDevice(); 226 HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); 227 228 if (result == E_OUTOFMEMORY) 229 { 230 gl::error(GL_OUT_OF_MEMORY); 231 return; 232 } 233 ASSERT(SUCCEEDED(result)); 234 235 if (depth) 236 { 237 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 238 dsvDesc.Format = requestedFormat; 239 dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; 240 dsvDesc.Texture2D.MipSlice = 0; 241 dsvDesc.Flags = 0; 242 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil); 243 244 if (result == E_OUTOFMEMORY) 245 { 246 mTexture->Release(); 247 mTexture = NULL; 248 gl::error(GL_OUT_OF_MEMORY); 249 } 250 ASSERT(SUCCEEDED(result)); 251 } 252 else 253 { 254 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 255 rtvDesc.Format = requestedFormat; 256 rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; 257 rtvDesc.Texture2D.MipSlice = 0; 258 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); 259 260 if (result == E_OUTOFMEMORY) 261 { 262 mTexture->Release(); 263 mTexture = NULL; 264 gl::error(GL_OUT_OF_MEMORY); 265 return; 266 } 267 ASSERT(SUCCEEDED(result)); 268 269 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 270 srvDesc.Format = requestedFormat; 271 srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; 272 srvDesc.Texture2D.MostDetailedMip = 0; 273 srvDesc.Texture2D.MipLevels = 1; 274 result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); 275 276 if (result == E_OUTOFMEMORY) 277 { 278 mTexture->Release(); 279 mTexture = NULL; 280 mRenderTarget->Release(); 281 mRenderTarget = NULL; 282 gl::error(GL_OUT_OF_MEMORY); 283 return; 284 } 285 ASSERT(SUCCEEDED(result)); 286 } 287 } 288 289 mWidth = width; 290 mHeight = height; 291 mInternalFormat = format; 292 mSamples = supportedSamples; 293 mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat); 294 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); 295 } 296 297 RenderTarget11::~RenderTarget11() 298 { 299 if (mTexture) 300 { 301 mTexture->Release(); 302 mTexture = NULL; 303 } 304 305 if (mRenderTarget) 306 { 307 mRenderTarget->Release(); 308 mRenderTarget = NULL; 309 } 310 311 if (mDepthStencil) 312 { 313 mDepthStencil->Release(); 314 mDepthStencil = NULL; 315 } 316 317 if (mShaderResource) 318 { 319 mShaderResource->Release(); 320 mShaderResource = NULL; 321 } 322 } 323 324 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) 325 { 326 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target)); 327 return static_cast<rx::RenderTarget11*>(target); 328 } 329 330 ID3D11Texture2D *RenderTarget11::getTexture() const 331 { 332 return mTexture; 333 } 334 335 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const 336 { 337 return mRenderTarget; 338 } 339 340 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const 341 { 342 return mDepthStencil; 343 } 344 345 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const 346 { 347 return mShaderResource; 348 } 349 350 unsigned int RenderTarget11::getSubresourceIndex() const 351 { 352 return mSubresourceIndex; 353 } 354 355 } 356