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/d3d11/RenderTarget11.h" 12 #include "libGLESv2/renderer/d3d11/Renderer11.h" 13 14 #include "libGLESv2/renderer/d3d11/renderer11_utils.h" 15 #include "libGLESv2/renderer/d3d11/formatutils11.h" 16 #include "libGLESv2/main.h" 17 18 namespace rx 19 { 20 21 static bool getTextureProperties(ID3D11Resource *resource, unsigned int *mipLevels, unsigned int *samples) 22 { 23 ID3D11Texture1D *texture1D = d3d11::DynamicCastComObject<ID3D11Texture1D>(resource); 24 if (texture1D) 25 { 26 D3D11_TEXTURE1D_DESC texDesc; 27 texture1D->GetDesc(&texDesc); 28 SafeRelease(texture1D); 29 30 *mipLevels = texDesc.MipLevels; 31 *samples = 0; 32 33 return true; 34 } 35 36 ID3D11Texture2D *texture2D = d3d11::DynamicCastComObject<ID3D11Texture2D>(resource); 37 if (texture2D) 38 { 39 D3D11_TEXTURE2D_DESC texDesc; 40 texture2D->GetDesc(&texDesc); 41 SafeRelease(texture2D); 42 43 *mipLevels = texDesc.MipLevels; 44 *samples = texDesc.SampleDesc.Count > 1 ? texDesc.SampleDesc.Count : 0; 45 46 return true; 47 } 48 49 ID3D11Texture3D *texture3D = d3d11::DynamicCastComObject<ID3D11Texture3D>(resource); 50 if (texture3D) 51 { 52 D3D11_TEXTURE3D_DESC texDesc; 53 texture3D->GetDesc(&texDesc); 54 SafeRelease(texture3D); 55 56 *mipLevels = texDesc.MipLevels; 57 *samples = 0; 58 59 return true; 60 } 61 62 return false; 63 } 64 65 static unsigned int getRTVSubresourceIndex(ID3D11Resource *resource, ID3D11RenderTargetView *view) 66 { 67 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 68 view->GetDesc(&rtvDesc); 69 70 unsigned int mipSlice = 0; 71 unsigned int arraySlice = 0; 72 73 switch (rtvDesc.ViewDimension) 74 { 75 case D3D11_RTV_DIMENSION_TEXTURE1D: 76 mipSlice = rtvDesc.Texture1D.MipSlice; 77 arraySlice = 0; 78 break; 79 80 case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: 81 mipSlice = rtvDesc.Texture1DArray.MipSlice; 82 arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; 83 break; 84 85 case D3D11_RTV_DIMENSION_TEXTURE2D: 86 mipSlice = rtvDesc.Texture2D.MipSlice; 87 arraySlice = 0; 88 break; 89 90 case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: 91 mipSlice = rtvDesc.Texture2DArray.MipSlice; 92 arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; 93 break; 94 95 case D3D11_RTV_DIMENSION_TEXTURE2DMS: 96 mipSlice = 0; 97 arraySlice = 0; 98 break; 99 100 case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: 101 mipSlice = 0; 102 arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; 103 break; 104 105 case D3D11_RTV_DIMENSION_TEXTURE3D: 106 mipSlice = rtvDesc.Texture3D.MipSlice; 107 arraySlice = 0; 108 break; 109 110 case D3D11_RTV_DIMENSION_UNKNOWN: 111 case D3D11_RTV_DIMENSION_BUFFER: 112 UNIMPLEMENTED(); 113 break; 114 115 default: 116 UNREACHABLE(); 117 break; 118 } 119 120 unsigned int mipLevels, samples; 121 getTextureProperties(resource, &mipLevels, &samples); 122 123 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); 124 } 125 126 static unsigned int getDSVSubresourceIndex(ID3D11Resource *resource, ID3D11DepthStencilView *view) 127 { 128 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 129 view->GetDesc(&dsvDesc); 130 131 unsigned int mipSlice = 0; 132 unsigned int arraySlice = 0; 133 134 switch (dsvDesc.ViewDimension) 135 { 136 case D3D11_DSV_DIMENSION_TEXTURE1D: 137 mipSlice = dsvDesc.Texture1D.MipSlice; 138 arraySlice = 0; 139 break; 140 141 case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: 142 mipSlice = dsvDesc.Texture1DArray.MipSlice; 143 arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; 144 break; 145 146 case D3D11_DSV_DIMENSION_TEXTURE2D: 147 mipSlice = dsvDesc.Texture2D.MipSlice; 148 arraySlice = 0; 149 break; 150 151 case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: 152 mipSlice = dsvDesc.Texture2DArray.MipSlice; 153 arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; 154 break; 155 156 case D3D11_DSV_DIMENSION_TEXTURE2DMS: 157 mipSlice = 0; 158 arraySlice = 0; 159 break; 160 161 case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: 162 mipSlice = 0; 163 arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; 164 break; 165 166 case D3D11_DSV_DIMENSION_UNKNOWN: 167 UNIMPLEMENTED(); 168 break; 169 170 default: 171 UNREACHABLE(); 172 break; 173 } 174 175 unsigned int mipLevels, samples; 176 getTextureProperties(resource, &mipLevels, &samples); 177 178 return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); 179 } 180 181 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Resource *resource, 182 ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) 183 { 184 mRenderer = Renderer11::makeRenderer11(renderer); 185 186 mTexture = resource; 187 if (mTexture) 188 { 189 mTexture->AddRef(); 190 } 191 192 mRenderTarget = rtv; 193 if (mRenderTarget) 194 { 195 mRenderTarget->AddRef(); 196 } 197 198 mDepthStencil = NULL; 199 200 mShaderResource = srv; 201 if (mShaderResource) 202 { 203 mShaderResource->AddRef(); 204 } 205 206 mSubresourceIndex = 0; 207 208 if (mRenderTarget && mTexture) 209 { 210 D3D11_RENDER_TARGET_VIEW_DESC desc; 211 mRenderTarget->GetDesc(&desc); 212 213 unsigned int mipLevels, samples; 214 getTextureProperties(mTexture, &mipLevels, &samples); 215 216 mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); 217 mWidth = width; 218 mHeight = height; 219 mDepth = depth; 220 mSamples = samples; 221 222 mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); 223 mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); 224 } 225 } 226 227 RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Resource *resource, 228 ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height, GLsizei depth) 229 { 230 mRenderer = Renderer11::makeRenderer11(renderer); 231 232 mTexture = resource; 233 if (mTexture) 234 { 235 mTexture->AddRef(); 236 } 237 238 mRenderTarget = NULL; 239 240 mDepthStencil = dsv; 241 if (mDepthStencil) 242 { 243 mDepthStencil->AddRef(); 244 } 245 246 mShaderResource = srv; 247 if (mShaderResource) 248 { 249 mShaderResource->AddRef(); 250 } 251 252 mSubresourceIndex = 0; 253 254 if (mDepthStencil && mTexture) 255 { 256 D3D11_DEPTH_STENCIL_VIEW_DESC desc; 257 mDepthStencil->GetDesc(&desc); 258 259 unsigned int mipLevels, samples; 260 getTextureProperties(mTexture, &mipLevels, &samples); 261 262 mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); 263 mWidth = width; 264 mHeight = height; 265 mDepth = depth; 266 mSamples = samples; 267 268 mInternalFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); 269 mActualFormat = d3d11_gl::GetInternalFormat(desc.Format, renderer->getCurrentClientVersion()); 270 } 271 } 272 273 RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum internalFormat, GLsizei samples) 274 { 275 mRenderer = Renderer11::makeRenderer11(renderer); 276 mTexture = NULL; 277 mRenderTarget = NULL; 278 mDepthStencil = NULL; 279 mShaderResource = NULL; 280 281 GLuint clientVersion = mRenderer->getCurrentClientVersion(); 282 283 DXGI_FORMAT texFormat = gl_d3d11::GetTexFormat(internalFormat, clientVersion); 284 DXGI_FORMAT srvFormat = gl_d3d11::GetSRVFormat(internalFormat, clientVersion); 285 DXGI_FORMAT rtvFormat = gl_d3d11::GetRTVFormat(internalFormat, clientVersion); 286 DXGI_FORMAT dsvFormat = gl_d3d11::GetDSVFormat(internalFormat, clientVersion); 287 288 DXGI_FORMAT multisampleFormat = (dsvFormat != DXGI_FORMAT_UNKNOWN ? dsvFormat : rtvFormat); 289 int supportedSamples = mRenderer->getNearestSupportedSamples(multisampleFormat, samples); 290 if (supportedSamples < 0) 291 { 292 gl::error(GL_OUT_OF_MEMORY); 293 return; 294 } 295 296 if (width > 0 && height > 0) 297 { 298 // Create texture resource 299 D3D11_TEXTURE2D_DESC desc; 300 desc.Width = width; 301 desc.Height = height; 302 desc.MipLevels = 1; 303 desc.ArraySize = 1; 304 desc.Format = texFormat; 305 desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; 306 desc.SampleDesc.Quality = 0; 307 desc.Usage = D3D11_USAGE_DEFAULT; 308 desc.CPUAccessFlags = 0; 309 desc.MiscFlags = 0; 310 311 // If a rendertarget or depthstencil format exists for this texture format, 312 // we'll flag it to allow binding that way. Shader resource views are a little 313 // more complicated. 314 bool bindRTV = false, bindDSV = false, bindSRV = false; 315 bindRTV = (rtvFormat != DXGI_FORMAT_UNKNOWN); 316 bindDSV = (dsvFormat != DXGI_FORMAT_UNKNOWN); 317 if (srvFormat != DXGI_FORMAT_UNKNOWN) 318 { 319 // Multisample targets flagged for binding as depth stencil cannot also be 320 // flagged for binding as SRV, so make certain not to add the SRV flag for 321 // these targets. 322 bindSRV = !(dsvFormat != DXGI_FORMAT_UNKNOWN && desc.SampleDesc.Count > 1); 323 } 324 325 desc.BindFlags = (bindRTV ? D3D11_BIND_RENDER_TARGET : 0) | 326 (bindDSV ? D3D11_BIND_DEPTH_STENCIL : 0) | 327 (bindSRV ? D3D11_BIND_SHADER_RESOURCE : 0); 328 329 ID3D11Device *device = mRenderer->getDevice(); 330 ID3D11Texture2D *texture = NULL; 331 HRESULT result = device->CreateTexture2D(&desc, NULL, &texture); 332 mTexture = texture; 333 334 if (result == E_OUTOFMEMORY) 335 { 336 gl::error(GL_OUT_OF_MEMORY); 337 return; 338 } 339 ASSERT(SUCCEEDED(result)); 340 341 if (bindSRV) 342 { 343 D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; 344 srvDesc.Format = srvFormat; 345 srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; 346 srvDesc.Texture2D.MostDetailedMip = 0; 347 srvDesc.Texture2D.MipLevels = 1; 348 result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); 349 350 if (result == E_OUTOFMEMORY) 351 { 352 SafeRelease(mTexture); 353 gl::error(GL_OUT_OF_MEMORY); 354 return; 355 } 356 ASSERT(SUCCEEDED(result)); 357 } 358 359 if (bindDSV) 360 { 361 D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; 362 dsvDesc.Format = dsvFormat; 363 dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; 364 dsvDesc.Texture2D.MipSlice = 0; 365 dsvDesc.Flags = 0; 366 result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil); 367 368 if (result == E_OUTOFMEMORY) 369 { 370 SafeRelease(mTexture); 371 SafeRelease(mShaderResource); 372 gl::error(GL_OUT_OF_MEMORY); 373 return; 374 } 375 ASSERT(SUCCEEDED(result)); 376 } 377 378 if (bindRTV) 379 { 380 D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; 381 rtvDesc.Format = rtvFormat; 382 rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; 383 rtvDesc.Texture2D.MipSlice = 0; 384 result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); 385 386 if (result == E_OUTOFMEMORY) 387 { 388 SafeRelease(mTexture); 389 SafeRelease(mShaderResource); 390 SafeRelease(mDepthStencil); 391 gl::error(GL_OUT_OF_MEMORY); 392 return; 393 } 394 ASSERT(SUCCEEDED(result)); 395 396 if (gl_d3d11::RequiresTextureDataInitialization(internalFormat)) 397 { 398 ID3D11DeviceContext *context = mRenderer->getDeviceContext(); 399 400 const float clearValues[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; 401 context->ClearRenderTargetView(mRenderTarget, clearValues); 402 } 403 } 404 } 405 406 mWidth = width; 407 mHeight = height; 408 mDepth = 1; 409 mInternalFormat = internalFormat; 410 mSamples = supportedSamples; 411 mActualFormat = d3d11_gl::GetInternalFormat(texFormat, renderer->getCurrentClientVersion()); 412 mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); 413 } 414 415 RenderTarget11::~RenderTarget11() 416 { 417 SafeRelease(mTexture); 418 SafeRelease(mRenderTarget); 419 SafeRelease(mDepthStencil); 420 SafeRelease(mShaderResource); 421 } 422 423 RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) 424 { 425 ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target)); 426 return static_cast<rx::RenderTarget11*>(target); 427 } 428 429 void RenderTarget11::invalidate(GLint x, GLint y, GLsizei width, GLsizei height) 430 { 431 // Currently a no-op 432 } 433 434 ID3D11Resource *RenderTarget11::getTexture() const 435 { 436 return mTexture; 437 } 438 439 ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const 440 { 441 return mRenderTarget; 442 } 443 444 ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const 445 { 446 return mDepthStencil; 447 } 448 449 ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const 450 { 451 return mShaderResource; 452 } 453 454 unsigned int RenderTarget11::getSubresourceIndex() const 455 { 456 return mSubresourceIndex; 457 } 458 459 } 460